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;
75 //First 32 bits contain
77 // timestamp (remaining)
80 timestamp
= *((uint32_t *)(got
+i
));
81 parityBits
= *((uint32_t *)(got
+i
+4));
84 uint32_t next_timestamp
= (*((uint32_t *)(got
+i
+9))) & 0x7fffffff;
86 tagToReader
= timestamp
& 0x80000000;
87 timestamp
&= 0x7fffffff;
90 first_timestamp
= timestamp
;
93 // Break and stick with current result if buffer was not completely full
94 if (frame
[0] == 0x44 && frame
[1] == 0x44 && frame
[2] == 0x44 && frame
[3] == 0x44) break;
98 if(len
)//We have some data to display
102 for(j
= 0; j
< len
; j
++)
104 oddparity
= 0x01 ^ xorbits_8(frame
[j
] & 0xFF);
106 if (tagToReader
&& (oddparity
!= ((parityBits
>> (len
- j
- 1)) & 0x01))) {
107 sprintf(line
+(j
*4), "%02x! ", frame
[j
]);
109 sprintf(line
+(j
*4), "%02x ", frame
[j
]);
114 if (ShowWaitCycles
) {
115 sprintf(line
, "fdt (Frame Delay Time): %d", (next_timestamp
- timestamp
));
124 if(!tagToReader
&& len
== 4) {
125 // Rough guess that this is a command from the reader
126 // For iClass the command byte is not part of the CRC
127 ComputeCrc14443(CRC_ICLASS
, &frame
[1], len
-3, &b1
, &b2
);
130 // For other data.. CRC might not be applicable (UPDATE commands etc.)
131 ComputeCrc14443(CRC_ICLASS
, frame
, len
-2, &b1
, &b2
);
134 if (b1
!= frame
[len
-2] || b2
!= frame
[len
-1]) {
135 crc
= (tagToReader
& (len
< 8)) ? "" : " !crc";
140 EndOfTransmissionTimestamp
= (*((uint32_t *)(got
+i
))) & 0x7fffffff;
142 // Not implemented for iclass on the ARM-side
143 //if (!ShowWaitCycles) i += 9;
145 PrintAndLog(" %9d | %9d | %s | %s %s",
146 (timestamp
- first_timestamp
),
147 (EndOfTransmissionTimestamp
- first_timestamp
),
148 (len
?(tagToReader
? "Tag" : "Rdr"):" "),
154 int CmdHFiClassListOld(const char *Cmd
)
157 GetFromBigBuf(got
,sizeof(got
),0);
159 PrintAndLog("recorded activity:");
160 PrintAndLog(" ETU :rssi: who bytes");
161 PrintAndLog("---------+----+----+-----------");
172 int timestamp
= *((uint32_t *)(got
+i
));
173 if (timestamp
& 0x80000000) {
174 timestamp
&= 0x7fffffff;
183 int parityBits
= *((uint32_t *)(got
+i
+4));
184 // 4 bytes of additional information...
185 // maximum of 32 additional parity bit information
188 // at each quarter bit period we can send power level (16 levels)
189 // or each half bit period in 256 levels.
197 if (i
+ len
>= 1900) {
201 uint8_t *frame
= (got
+i
+9);
203 // Break and stick with current result if buffer was not completely full
204 if (frame
[0] == 0x44 && frame
[1] == 0x44 && frame
[3] == 0x44) { break; }
206 char line
[1000] = "";
208 for (j
= 0; j
< len
; j
++) {
209 int oddparity
= 0x01;
213 oddparity
^= (((frame
[j
] & 0xFF) >> k
) & 0x01);
216 //if((parityBits >> (len - j - 1)) & 0x01) {
217 if (isResponse
&& (oddparity
!= ((parityBits
>> (len
- j
- 1)) & 0x01))) {
218 sprintf(line
+(j
*4), "%02x! ", frame
[j
]);
221 sprintf(line
+(j
*4), "%02x ", frame
[j
]);
229 for (j
= 0; j
< (len
- 1); j
++) {
230 // gives problems... search for the reason..
231 /*if(frame[j] == 0xAA) {
234 crc = "[1] Two drops close after each other";
237 crc = "[2] Potential SOC with a drop in second half of bitperiod";
240 crc = "[3] Segment Z after segment X is not possible";
243 crc = "[4] Parity bit of a fully received byte was wrong";
246 crc = "[?] Unknown error";
253 if (strlen(crc
)==0) {
254 if(!isResponse
&& len
== 4) {
255 // Rough guess that this is a command from the reader
256 // For iClass the command byte is not part of the CRC
257 ComputeCrc14443(CRC_ICLASS
, &frame
[1], len
-3, &b1
, &b2
);
260 // For other data.. CRC might not be applicable (UPDATE commands etc.)
261 ComputeCrc14443(CRC_ICLASS
, frame
, len
-2, &b1
, &b2
);
263 //printf("%1x %1x",(unsigned)b1,(unsigned)b2);
264 if (b1
!= frame
[len
-2] || b2
!= frame
[len
-1]) {
265 crc
= (isResponse
& (len
< 8)) ? "" : " !crc";
274 char metricString
[100];
276 sprintf(metricString
, "%3d", metric
);
278 strcpy(metricString
, " ");
281 PrintAndLog(" +%7d: %s: %s %s %s",
282 (prev
< 0 ? 0 : (timestamp
- prev
)),
284 (isResponse
? "TAG" : " "), line
, crc
);
292 /*void iso14a_set_timeout(uint32_t timeout) {
293 UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_SET_TIMEOUT, 0, timeout}};
297 int CmdHFiClassSnoop(const char *Cmd
)
299 UsbCommand c
= {CMD_SNOOP_ICLASS
};
304 int CmdHFiClassSim(const char *Cmd
)
307 uint8_t CSN
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
310 PrintAndLog("Usage: hf iclass sim [0 <CSN>] | x");
311 PrintAndLog(" options");
312 PrintAndLog(" 0 <CSN> simulate the given CSN");
313 PrintAndLog(" 1 simulate default CSN");
314 PrintAndLog(" 2 iterate CSNs, gather MACs");
315 PrintAndLog(" sample: hf iclass sim 0 031FEC8AF7FF12E0");
316 PrintAndLog(" sample: hf iclass sim 2");
320 simType
= param_get8(Cmd
, 0);
324 if (param_gethex(Cmd
, 1, CSN
, 16)) {
325 PrintAndLog("A CSN should consist of 16 HEX symbols");
328 PrintAndLog("--simtype:%02x csn:%s", simType
, sprint_hex(CSN
, 8));
333 PrintAndLog("Undefined simptype %d", simType
);
336 uint8_t numberOfCSNs
=0;
338 UsbCommand c
= {CMD_SIMULATE_TAG_ICLASS
, {simType
,numberOfCSNs
}};
339 memcpy(c
.d
.asBytes
, CSN
, 8);
343 c
.arg
[1] = 10;//10 CSNs
345 /* Order Simulated CSN HASH1 Recovered key bytes */
346 /* 1 */ 0x00,0x0B,0x0F,0xFF,0xF7,0xFF,0x12,0xE0,// 0101000045014545 00,01 45
347 /* 2 */ 0x03,0x0B,0x0E,0xFE,0xF7,0xFF,0x12,0xE0,// 0202000045014545 02
348 /* 3 */ 0x04,0x0D,0x0D,0xFD,0xF7,0xFF,0x12,0xE0,// 0303000045014545 03
349 /* 4 */ 0x04,0x0F,0x0F,0xF7,0xF7,0xFF,0x12,0xE0,// 0901000045014545 09
350 /* 5 */ 0x01,0x13,0x10,0xF4,0xF7,0xFF,0x12,0xE0,// 0C00000045014545 0C
351 /* 6 */ 0x02,0x14,0x10,0xF2,0xF7,0xFF,0x12,0xE0,// 0E00000045014545 0E
352 /* 7 */ 0x05,0x17,0x10,0xEC,0xF7,0xFF,0x12,0xE0,// 1400000045014545 14
353 /* 8 */ 0x00,0x6B,0x6F,0xDF,0xF7,0xFF,0x12,0xE0,// 2121000045014545 21
354 /* 9 */ 0x03,0x6B,0x6E,0xDE,0xF7,0xFF,0x12,0xE0,// 2222000045014545 22
355 /* 10 */ 0x04,0x6D,0x6D,0xDD,0xF7,0xFF,0x12,0xE0,// 2323000045014545 23
356 /* 11 */ 0x00,0x4F,0x4B,0x43,0xF7,0xFF,0x12,0xE0,// 3D45000045014545 3D
357 /* 12 */ 0x00,0x4B,0x4F,0x3F,0xF7,0xFF,0x12,0xE0,// 4141000045014545 41
358 /* 13 */ 0x03,0x4B,0x4E,0x3E,0xF7,0xFF,0x12,0xE0,// 4242000045014545 42
359 /* 14 */ 0x04,0x4D,0x4D,0x3D,0xF7,0xFF,0x12,0xE0,// 4343000045014545 43
360 /* 15 */ 0x04,0x37,0x37,0x7F,0xF7,0xFF,0x12,0xE0,// 0159000045014545 59
361 /* 16 */ 0x00,0x2B,0x2F,0x9F,0xF7,0xFF,0x12,0xE0,// 6161000045014545 61
362 /* 17 */ 0x03,0x2B,0x2E,0x9E,0xF7,0xFF,0x12,0xE0,// 6262000045014545 62
363 /* 18 */ 0x04,0x2D,0x2D,0x9D,0xF7,0xFF,0x12,0xE0,// 6363000045014545 63
364 /* 19 */ 0x00,0x27,0x23,0xBB,0xF7,0xFF,0x12,0xE0,// 456D000045014545 6D
365 /* 20 */ 0x02,0x52,0xAA,0x80,0xF7,0xFF,0x12,0xE0,// 0066000045014545 66
366 /* 21 */ 0x00,0x5C,0xA6,0x80,0xF7,0xFF,0x12,0xE0,// 006A000045014545 6A
367 /* 22 */ 0x01,0x5F,0xA4,0x80,0xF7,0xFF,0x12,0xE0,// 006C000045014545 6C
368 /* 23 */ 0x06,0x5E,0xA2,0x80,0xF7,0xFF,0x12,0xE0,// 006E000045014545 6E
369 /* 24 */ 0x02,0x0E,0x0E,0xFC,0xF7,0xFF,0x12,0xE0,// 0402000045014545 04
370 /* 25 */ 0x05,0x0D,0x0E,0xFA,0xF7,0xFF,0x12,0xE0,// 0602000045014545 06
371 /* 26 */ 0x06,0x0F,0x0D,0xF9,0xF7,0xFF,0x12,0xE0,// 0703000045014545 07
372 /* 27 */ 0x00,0x01,0x05,0x1D,0xF7,0xFF,0x12,0xE0,// 630B000045014545 0B
373 /* 28 */ 0x02,0x07,0x01,0x1D,0xF7,0xFF,0x12,0xE0,// 630F000045014545 0F
374 /* 29 */ 0x04,0x7F,0x7F,0xA7,0xF7,0xFF,0x12,0xE0,// 5911000045014545 11
375 /* 30 */ 0x04,0x60,0x6E,0xE8,0xF7,0xFF,0x12,0xE0,// 1822000045014545 18
377 memcpy(c
.d
.asBytes
, csns
, sizeof(c
.d
.asBytes
));
383 /*UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
385 uint8_t isOK = resp->arg[0] & 0xff;
386 PrintAndLog("isOk:%02x", isOK);
388 PrintAndLog("Command execute timeout");
394 int CmdHFiClassReader(const char *Cmd
)
396 uint8_t readerType
= 0;
399 PrintAndLog("Usage: hf iclass reader <reader type>");
400 PrintAndLog(" sample: hf iclass reader 0");
404 readerType
= param_get8(Cmd
, 0);
405 PrintAndLog("--readertype:%02x", readerType
);
407 UsbCommand c
= {CMD_READER_ICLASS
, {readerType
}};
408 //memcpy(c.d.asBytes, CSN, 8);
411 /*UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
413 uint8_t isOK = resp->arg[0] & 0xff;
414 PrintAndLog("isOk:%02x", isOK);
416 PrintAndLog("Command execute timeout");
422 static command_t CommandTable
[] =
424 {"help", CmdHelp
, 1, "This help"},
425 {"list", CmdHFiClassList
, 0, "List iClass history"},
426 {"snoop", CmdHFiClassSnoop
, 0, "Eavesdrop iClass communication"},
427 {"sim", CmdHFiClassSim
, 0, "Simulate iClass tag"},
428 {"reader", CmdHFiClassReader
, 0, "Read an iClass tag"},
429 {NULL
, NULL
, 0, NULL
}
432 int CmdHFiClass(const char *Cmd
)
434 CmdsParse(CommandTable
, Cmd
);
438 int CmdHelp(const char *Cmd
)
440 CmdsHelp(CommandTable
);