1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>, Hagen Fritsch
3 // Copyright (C) 2011 Gerhard de Koning Gans
5 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
6 // at your option, any later version. See the LICENSE.txt file for the text of
8 //-----------------------------------------------------------------------------
9 // High frequency iClass commands
10 //-----------------------------------------------------------------------------
15 #include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type
17 //#include "proxusb.h"
18 #include "proxmark3.h"
20 #include "cmdparser.h"
21 #include "cmdhficlass.h"
26 static int CmdHelp(const char *Cmd
);
28 int xorbits_8(uint8_t val
)
30 uint8_t res
= val
^ (val
>> 1); //1st pass
31 res
= res
^ (res
>> 1); // 2nd pass
32 res
= res
^ (res
>> 2); // 3rd pass
33 res
= res
^ (res
>> 4); // 4th pass
37 int CmdHFiClassList(const char *Cmd
)
40 bool ShowWaitCycles
= false;
41 char param
= param_getchar(Cmd
, 0);
44 PrintAndLog("List data in trace buffer.");
45 PrintAndLog("Usage: hf iclass list");
46 PrintAndLog("h - help");
47 PrintAndLog("sample: hf iclass list");
52 GetFromBigBuf(got
,sizeof(got
),0);
53 WaitForResponse(CMD_ACK
,NULL
);
55 PrintAndLog("Recorded Activity");
57 PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer");
58 PrintAndLog("All times are in carrier periods (1/13.56Mhz)");
60 PrintAndLog(" Start | End | Src | Data");
61 PrintAndLog("-----------|-----------|-----|--------");
64 uint32_t first_timestamp
= 0;
70 uint32_t EndOfTransmissionTimestamp
= 0;
72 uint8_t empty
[4] = {0x44,0x44,0x44,0x44};
76 //First 32 bits contain
78 // timestamp (remaining)
81 timestamp
= *((uint32_t *)(got
+i
));
82 parityBits
= *((uint32_t *)(got
+i
+4));
85 uint32_t next_timestamp
= (*((uint32_t *)(got
+i
+9))) & 0x7fffffff;
87 tagToReader
= timestamp
& 0x80000000;
88 timestamp
&= 0x7fffffff;
91 first_timestamp
= timestamp
;
94 // Break and stick with current result if buffer
95 // was not completely full
96 if(memcmp(frame
,empty
,sizeof(empty
))) break;
100 if(len
)//We have some data to display
104 for(j
= 0; j
< len
; j
++)
106 oddparity
= 0x01 ^ xorbits_8(frame
[j
] & 0xFF);
108 if (tagToReader
&& (oddparity
!= ((parityBits
>> (len
- j
- 1)) & 0x01))) {
109 sprintf(line
+(j
*4), "%02x! ", frame
[j
]);
111 sprintf(line
+(j
*4), "%02x ", frame
[j
]);
116 if (ShowWaitCycles
) {
117 sprintf(line
, "fdt (Frame Delay Time): %d", (next_timestamp
- timestamp
));
126 if(!tagToReader
&& len
== 4) {
127 // Rough guess that this is a command from the reader
128 // For iClass the command byte is not part of the CRC
129 ComputeCrc14443(CRC_ICLASS
, &frame
[1], len
-3, &b1
, &b2
);
132 // For other data.. CRC might not be applicable (UPDATE commands etc.)
133 ComputeCrc14443(CRC_ICLASS
, frame
, len
-2, &b1
, &b2
);
136 if (b1
!= frame
[len
-2] || b2
!= frame
[len
-1]) {
137 crc
= (tagToReader
& (len
< 8)) ? "" : " !crc";
142 EndOfTransmissionTimestamp
= (*((uint32_t *)(got
+i
))) & 0x7fffffff;
144 // Not implemented for iclass on the ARM-side
145 //if (!ShowWaitCycles) i += 9;
147 PrintAndLog(" %9d | %9d | %s | %s %s",
148 (timestamp
- first_timestamp
),
149 (EndOfTransmissionTimestamp
- first_timestamp
),
150 (len
?(tagToReader
? "Tag" : "Rdr"):" "),
156 int CmdHFiClassListOld(const char *Cmd
)
159 GetFromBigBuf(got
,sizeof(got
),0);
161 PrintAndLog("recorded activity:");
162 PrintAndLog(" ETU :rssi: who bytes");
163 PrintAndLog("---------+----+----+-----------");
174 int timestamp
= *((uint32_t *)(got
+i
));
175 if (timestamp
& 0x80000000) {
176 timestamp
&= 0x7fffffff;
185 int parityBits
= *((uint32_t *)(got
+i
+4));
186 // 4 bytes of additional information...
187 // maximum of 32 additional parity bit information
190 // at each quarter bit period we can send power level (16 levels)
191 // or each half bit period in 256 levels.
199 if (i
+ len
>= 1900) {
203 uint8_t *frame
= (got
+i
+9);
205 // Break and stick with current result if buffer was not completely full
206 if (frame
[0] == 0x44 && frame
[1] == 0x44 && frame
[3] == 0x44) { break; }
208 char line
[1000] = "";
210 for (j
= 0; j
< len
; j
++) {
211 int oddparity
= 0x01;
215 oddparity
^= (((frame
[j
] & 0xFF) >> k
) & 0x01);
218 //if((parityBits >> (len - j - 1)) & 0x01) {
219 if (isResponse
&& (oddparity
!= ((parityBits
>> (len
- j
- 1)) & 0x01))) {
220 sprintf(line
+(j
*4), "%02x! ", frame
[j
]);
223 sprintf(line
+(j
*4), "%02x ", frame
[j
]);
231 for (j
= 0; j
< (len
- 1); j
++) {
232 // gives problems... search for the reason..
233 /*if(frame[j] == 0xAA) {
236 crc = "[1] Two drops close after each other";
239 crc = "[2] Potential SOC with a drop in second half of bitperiod";
242 crc = "[3] Segment Z after segment X is not possible";
245 crc = "[4] Parity bit of a fully received byte was wrong";
248 crc = "[?] Unknown error";
255 if (strlen(crc
)==0) {
256 if(!isResponse
&& len
== 4) {
257 // Rough guess that this is a command from the reader
258 // For iClass the command byte is not part of the CRC
259 ComputeCrc14443(CRC_ICLASS
, &frame
[1], len
-3, &b1
, &b2
);
262 // For other data.. CRC might not be applicable (UPDATE commands etc.)
263 ComputeCrc14443(CRC_ICLASS
, frame
, len
-2, &b1
, &b2
);
265 //printf("%1x %1x",(unsigned)b1,(unsigned)b2);
266 if (b1
!= frame
[len
-2] || b2
!= frame
[len
-1]) {
267 crc
= (isResponse
& (len
< 8)) ? "" : " !crc";
276 char metricString
[100];
278 sprintf(metricString
, "%3d", metric
);
280 strcpy(metricString
, " ");
283 PrintAndLog(" +%7d: %s: %s %s %s",
284 (prev
< 0 ? 0 : (timestamp
- prev
)),
286 (isResponse
? "TAG" : " "), line
, crc
);
294 /*void iso14a_set_timeout(uint32_t timeout) {
295 UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_SET_TIMEOUT, 0, timeout}};
299 int CmdHFiClassSnoop(const char *Cmd
)
301 UsbCommand c
= {CMD_SNOOP_ICLASS
};
306 int CmdHFiClassSim(const char *Cmd
)
309 uint8_t CSN
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
312 PrintAndLog("Usage: hf iclass sim [0 <CSN>] | x");
313 PrintAndLog(" options");
314 PrintAndLog(" 0 <CSN> simulate the given CSN");
315 PrintAndLog(" 1 simulate default CSN");
316 PrintAndLog(" 2 iterate CSNs, gather MACs");
317 PrintAndLog(" sample: hf iclass sim 0 031FEC8AF7FF12E0");
318 PrintAndLog(" sample: hf iclass sim 2");
322 simType
= param_get8(Cmd
, 0);
326 if (param_gethex(Cmd
, 1, CSN
, 16)) {
327 PrintAndLog("A CSN should consist of 16 HEX symbols");
330 PrintAndLog("--simtype:%02x csn:%s", simType
, sprint_hex(CSN
, 8));
335 PrintAndLog("Undefined simptype %d", simType
);
338 uint8_t numberOfCSNs
=0;
340 UsbCommand c
= {CMD_SIMULATE_TAG_ICLASS
, {simType
,numberOfCSNs
}};
341 memcpy(c
.d
.asBytes
, CSN
, 8);
345 c
.arg
[1] = 10;//10 CSNs
347 /* Order Simulated CSN HASH1 Recovered key bytes */
348 /* 1 */ 0x00,0x0B,0x0F,0xFF,0xF7,0xFF,0x12,0xE0,// 0101000045014545 00,01 45
349 /* 2 */ 0x03,0x0B,0x0E,0xFE,0xF7,0xFF,0x12,0xE0,// 0202000045014545 02
350 /* 3 */ 0x04,0x0D,0x0D,0xFD,0xF7,0xFF,0x12,0xE0,// 0303000045014545 03
351 /* 4 */ 0x04,0x0F,0x0F,0xF7,0xF7,0xFF,0x12,0xE0,// 0901000045014545 09
352 /* 5 */ 0x01,0x13,0x10,0xF4,0xF7,0xFF,0x12,0xE0,// 0C00000045014545 0C
353 /* 6 */ 0x02,0x14,0x10,0xF2,0xF7,0xFF,0x12,0xE0,// 0E00000045014545 0E
354 /* 7 */ 0x05,0x17,0x10,0xEC,0xF7,0xFF,0x12,0xE0,// 1400000045014545 14
355 /* 8 */ 0x00,0x6B,0x6F,0xDF,0xF7,0xFF,0x12,0xE0,// 2121000045014545 21
356 /* 9 */ 0x03,0x6B,0x6E,0xDE,0xF7,0xFF,0x12,0xE0,// 2222000045014545 22
357 /* 10 */ 0x04,0x6D,0x6D,0xDD,0xF7,0xFF,0x12,0xE0,// 2323000045014545 23
358 /* 11 */ 0x00,0x4F,0x4B,0x43,0xF7,0xFF,0x12,0xE0,// 3D45000045014545 3D
359 /* 12 */ 0x00,0x4B,0x4F,0x3F,0xF7,0xFF,0x12,0xE0,// 4141000045014545 41
360 /* 13 */ 0x03,0x4B,0x4E,0x3E,0xF7,0xFF,0x12,0xE0,// 4242000045014545 42
361 /* 14 */ 0x04,0x4D,0x4D,0x3D,0xF7,0xFF,0x12,0xE0,// 4343000045014545 43
362 /* 15 */ 0x04,0x37,0x37,0x7F,0xF7,0xFF,0x12,0xE0,// 0159000045014545 59
363 /* 16 */ 0x00,0x2B,0x2F,0x9F,0xF7,0xFF,0x12,0xE0,// 6161000045014545 61
364 /* 17 */ 0x03,0x2B,0x2E,0x9E,0xF7,0xFF,0x12,0xE0,// 6262000045014545 62
365 /* 18 */ 0x04,0x2D,0x2D,0x9D,0xF7,0xFF,0x12,0xE0,// 6363000045014545 63
366 /* 19 */ 0x00,0x27,0x23,0xBB,0xF7,0xFF,0x12,0xE0,// 456D000045014545 6D
367 /* 20 */ 0x02,0x52,0xAA,0x80,0xF7,0xFF,0x12,0xE0,// 0066000045014545 66
368 /* 21 */ 0x00,0x5C,0xA6,0x80,0xF7,0xFF,0x12,0xE0,// 006A000045014545 6A
369 /* 22 */ 0x01,0x5F,0xA4,0x80,0xF7,0xFF,0x12,0xE0,// 006C000045014545 6C
370 /* 23 */ 0x06,0x5E,0xA2,0x80,0xF7,0xFF,0x12,0xE0,// 006E000045014545 6E
371 /* 24 */ 0x02,0x0E,0x0E,0xFC,0xF7,0xFF,0x12,0xE0,// 0402000045014545 04
372 /* 25 */ 0x05,0x0D,0x0E,0xFA,0xF7,0xFF,0x12,0xE0,// 0602000045014545 06
373 /* 26 */ 0x06,0x0F,0x0D,0xF9,0xF7,0xFF,0x12,0xE0,// 0703000045014545 07
374 /* 27 */ 0x00,0x01,0x05,0x1D,0xF7,0xFF,0x12,0xE0,// 630B000045014545 0B
375 /* 28 */ 0x02,0x07,0x01,0x1D,0xF7,0xFF,0x12,0xE0,// 630F000045014545 0F
376 /* 29 */ 0x04,0x7F,0x7F,0xA7,0xF7,0xFF,0x12,0xE0,// 5911000045014545 11
377 /* 30 */ 0x04,0x60,0x6E,0xE8,0xF7,0xFF,0x12,0xE0,// 1822000045014545 18
379 memcpy(c
.d
.asBytes
, csns
, sizeof(c
.d
.asBytes
));
385 /*UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
387 uint8_t isOK = resp->arg[0] & 0xff;
388 PrintAndLog("isOk:%02x", isOK);
390 PrintAndLog("Command execute timeout");
396 int CmdHFiClassReader(const char *Cmd
)
398 uint8_t readerType
= 0;
401 PrintAndLog("Usage: hf iclass reader <reader type>");
402 PrintAndLog(" sample: hf iclass reader 0");
406 readerType
= param_get8(Cmd
, 0);
407 PrintAndLog("--readertype:%02x", readerType
);
409 UsbCommand c
= {CMD_READER_ICLASS
, {readerType
}};
410 //memcpy(c.d.asBytes, CSN, 8);
413 /*UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
415 uint8_t isOK = resp->arg[0] & 0xff;
416 PrintAndLog("isOk:%02x", isOK);
418 PrintAndLog("Command execute timeout");
424 static command_t CommandTable
[] =
426 {"help", CmdHelp
, 1, "This help"},
427 {"list", CmdHFiClassList
, 0, "List iClass history"},
428 {"snoop", CmdHFiClassSnoop
, 0, "Eavesdrop iClass communication"},
429 {"sim", CmdHFiClassSim
, 0, "Simulate iClass tag"},
430 {"reader", CmdHFiClassReader
, 0, "Read an iClass tag"},
431 {NULL
, NULL
, 0, NULL
}
434 int CmdHFiClass(const char *Cmd
)
436 CmdsParse(CommandTable
, Cmd
);
440 int CmdHelp(const char *Cmd
)
442 CmdsHelp(CommandTable
);