1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>, Hagen Fritsch
3 // Copyright (C) 2011 Gerhard de Koning Gans
4 // Copyright (C) 2014 Midnitesnake & Andy Davies & Martin Holst Swende
6 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
7 // at your option, any later version. See the LICENSE.txt file for the text of
9 //-----------------------------------------------------------------------------
10 // High frequency iClass commands
11 //-----------------------------------------------------------------------------
17 #include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type
19 //#include "proxusb.h"
20 #include "proxmark3.h"
22 #include "cmdparser.h"
23 #include "cmdhficlass.h"
27 #include "loclass/des.h"
28 #include "loclass/cipherutils.h"
29 #include "loclass/cipher.h"
30 #include "loclass/ikeys.h"
31 #include "loclass/elite_crack.h"
32 #include "loclass/fileutils.h"
34 static int CmdHelp(const char *Cmd
);
36 int xorbits_8(uint8_t val
)
38 uint8_t res
= val
^ (val
>> 1); //1st pass
39 res
= res
^ (res
>> 1); // 2nd pass
40 res
= res
^ (res
>> 2); // 3rd pass
41 res
= res
^ (res
>> 4); // 4th pass
45 int CmdHFiClassList(const char *Cmd
)
48 bool ShowWaitCycles
= false;
49 char param
= param_getchar(Cmd
, 0);
52 PrintAndLog("List data in trace buffer.");
53 PrintAndLog("Usage: hf iclass list");
54 PrintAndLog("h - help");
55 PrintAndLog("sample: hf iclass list");
60 GetFromBigBuf(got
,sizeof(got
),0);
61 WaitForResponse(CMD_ACK
,NULL
);
63 PrintAndLog("Recorded Activity");
65 PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer");
66 PrintAndLog("All times are in carrier periods (1/13.56Mhz)");
68 PrintAndLog(" Start | End | Src | Data");
69 PrintAndLog("-----------|-----------|-----|--------");
72 uint32_t first_timestamp
= 0;
78 uint32_t EndOfTransmissionTimestamp
= 0;
83 //First 32 bits contain
85 // timestamp (remaining)
88 timestamp
= *((uint32_t *)(got
+i
));
89 parityBits
= *((uint32_t *)(got
+i
+4));
92 uint32_t next_timestamp
= (*((uint32_t *)(got
+i
+9))) & 0x7fffffff;
94 tagToReader
= timestamp
& 0x80000000;
95 timestamp
&= 0x7fffffff;
98 first_timestamp
= timestamp
;
101 // Break and stick with current result idf buffer was not completely full
102 if (frame
[0] == 0x44 && frame
[1] == 0x44 && frame
[2] == 0x44 && frame
[3] == 0x44) break;
104 char line
[1000] = "";
106 if(len
)//We have some data to display
110 for(j
= 0; j
< len
; j
++)
112 oddparity
= 0x01 ^ xorbits_8(frame
[j
] & 0xFF);
114 if (tagToReader
&& (oddparity
!= ((parityBits
>> (len
- j
- 1)) & 0x01))) {
115 sprintf(line
+(j
*4), "%02x! ", frame
[j
]);
117 sprintf(line
+(j
*4), "%02x ", frame
[j
]);
122 if (ShowWaitCycles
) {
123 sprintf(line
, "fdt (Frame Delay Time): %d", (next_timestamp
- timestamp
));
132 if(!tagToReader
&& len
== 4) {
133 // Rough guess that this is a command from the reader
134 // For iClass the command byte is not part of the CRC
135 ComputeCrc14443(CRC_ICLASS
, &frame
[1], len
-3, &b1
, &b2
);
138 // For other data.. CRC might not be applicable (UPDATE commands etc.)
139 ComputeCrc14443(CRC_ICLASS
, frame
, len
-2, &b1
, &b2
);
142 if (b1
!= frame
[len
-2] || b2
!= frame
[len
-1]) {
143 crc
= (tagToReader
& (len
< 8)) ? "" : " !crc";
148 EndOfTransmissionTimestamp
= (*((uint32_t *)(got
+i
))) & 0x7fffffff;
150 // Not implemented for iclass on the ARM-side
151 //if (!ShowWaitCycles) i += 9;
153 PrintAndLog(" %9d | %9d | %s | %s %s",
154 (timestamp
- first_timestamp
),
155 (EndOfTransmissionTimestamp
- first_timestamp
),
156 (len
?(tagToReader
? "Tag" : "Rdr"):" "),
162 int CmdHFiClassListOld(const char *Cmd
)
165 GetFromBigBuf(got
,sizeof(got
),0);
167 PrintAndLog("recorded activity:");
168 PrintAndLog(" ETU :rssi: who bytes");
169 PrintAndLog("---------+----+----+-----------");
180 int timestamp
= *((uint32_t *)(got
+i
));
181 if (timestamp
& 0x80000000) {
182 timestamp
&= 0x7fffffff;
191 int parityBits
= *((uint32_t *)(got
+i
+4));
192 // 4 bytes of additional information...
193 // maximum of 32 additional parity bit information
196 // at each quarter bit period we can send power level (16 levels)
197 // or each half bit period in 256 levels.
205 if (i
+ len
>= 1900) {
209 uint8_t *frame
= (got
+i
+9);
211 // Break and stick with current result if buffer was not completely full
212 if (frame
[0] == 0x44 && frame
[1] == 0x44 && frame
[3] == 0x44) { break; }
214 char line
[1000] = "";
216 for (j
= 0; j
< len
; j
++) {
217 int oddparity
= 0x01;
221 oddparity
^= (((frame
[j
] & 0xFF) >> k
) & 0x01);
224 //if((parityBits >> (len - j - 1)) & 0x01) {
225 if (isResponse
&& (oddparity
!= ((parityBits
>> (len
- j
- 1)) & 0x01))) {
226 sprintf(line
+(j
*4), "%02x! ", frame
[j
]);
229 sprintf(line
+(j
*4), "%02x ", frame
[j
]);
237 for (j
= 0; j
< (len
- 1); j
++) {
238 // gives problems... search for the reason..
239 /*if(frame[j] == 0xAA) {
242 crc = "[1] Two drops close after each other";
245 crc = "[2] Potential SOC with a drop in second half of bitperiod";
248 crc = "[3] Segment Z after segment X is not possible";
251 crc = "[4] Parity bit of a fully received byte was wrong";
254 crc = "[?] Unknown error";
261 if (strlen(crc
)==0) {
262 if(!isResponse
&& len
== 4) {
263 // Rough guess that this is a command from the reader
264 // For iClass the command byte is not part of the CRC
265 ComputeCrc14443(CRC_ICLASS
, &frame
[1], len
-3, &b1
, &b2
);
268 // For other data.. CRC might not be applicable (UPDATE commands etc.)
269 ComputeCrc14443(CRC_ICLASS
, frame
, len
-2, &b1
, &b2
);
271 //printf("%1x %1x",(unsigned)b1,(unsigned)b2);
272 if (b1
!= frame
[len
-2] || b2
!= frame
[len
-1]) {
273 crc
= (isResponse
& (len
< 8)) ? "" : " !crc";
282 char metricString
[100];
284 sprintf(metricString
, "%3d", metric
);
286 strcpy(metricString
, " ");
289 PrintAndLog(" +%7d: %s: %s %s %s",
290 (prev
< 0 ? 0 : (timestamp
- prev
)),
292 (isResponse
? "TAG" : " "), line
, crc
);
300 int CmdHFiClassSnoop(const char *Cmd
)
302 UsbCommand c
= {CMD_SNOOP_ICLASS
};
307 int CmdHFiClassSim(const char *Cmd
)
310 uint8_t CSN
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
313 PrintAndLog("Usage: hf iclass sim [0 <CSN>] | x");
314 PrintAndLog(" options");
315 PrintAndLog(" 0 <CSN> simulate the given CSN");
316 PrintAndLog(" 1 simulate default CSN");
317 PrintAndLog(" 2 iterate CSNs, gather MACs");
318 PrintAndLog(" sample: hf iclass sim 0 031FEC8AF7FF12E0");
319 PrintAndLog(" sample: hf iclass sim 2");
323 simType
= param_get8(Cmd
, 0);
327 if (param_gethex(Cmd
, 1, CSN
, 16)) {
328 PrintAndLog("A CSN should consist of 16 HEX symbols");
331 PrintAndLog("--simtype:%02x csn:%s", simType
, sprint_hex(CSN
, 8));
336 PrintAndLog("Undefined simptype %d", simType
);
339 uint8_t numberOfCSNs
=0;
343 UsbCommand c
= {CMD_SIMULATE_TAG_ICLASS
, {simType
,NUM_CSNS
}};
344 UsbCommand resp
= {0};
346 /*uint8_t csns[8 * NUM_CSNS] = {
347 0x00,0x0B,0x0F,0xFF,0xF7,0xFF,0x12,0xE0 ,
348 0x00,0x13,0x94,0x7e,0x76,0xff,0x12,0xe0 ,
349 0x2a,0x99,0xac,0x79,0xec,0xff,0x12,0xe0 ,
350 0x17,0x12,0x01,0xfd,0xf7,0xff,0x12,0xe0 ,
351 0xcd,0x56,0x01,0x7c,0x6f,0xff,0x12,0xe0 ,
352 0x4b,0x5e,0x0b,0x72,0xef,0xff,0x12,0xe0 ,
353 0x00,0x73,0xd8,0x75,0x58,0xff,0x12,0xe0 ,
354 0x0c,0x90,0x32,0xf3,0x5d,0xff,0x12,0xe0 };
357 uint8_t csns
[8*NUM_CSNS
] = {
358 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0,
359 0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0,
360 0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0,
361 0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0,
362 0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0,
363 0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0,
364 0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0,
365 0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0,
366 0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0,
367 0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0,
368 0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0,
369 0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0,
370 0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0,
371 0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0,
372 0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 };
374 memcpy(c
.d
.asBytes
, csns
, 8*NUM_CSNS
);
377 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, -1)) {
378 PrintAndLog("Command timed out");
382 uint8_t num_mac_responses
= resp
.arg
[1];
383 PrintAndLog("Mac responses: %d MACs obtained (should be %d)", num_mac_responses
,NUM_CSNS
);
385 size_t datalen
= NUM_CSNS
*24;
387 * Now, time to dump to file. We'll use this format:
388 * <8-byte CSN><8-byte CC><4 byte NR><4 byte MAC>....
389 * So, it should wind up as
392 * The returndata from the pm3 is on the following format
393 * <4 byte NR><4 byte MAC>
394 * CC are all zeroes, CSN is the same as was sent in
396 void* dump
= malloc(datalen
);
397 memset(dump
,0,datalen
);//<-- Need zeroes for the CC-field
399 for(i
= 0 ; i
< NUM_CSNS
; i
++)
401 memcpy(dump
+i
*24, csns
+i
*8,8); //CSN
402 //8 zero bytes here...
403 //Then comes NR_MAC (eight bytes from the response)
404 memcpy(dump
+i
*24+16,resp
.d
.asBytes
+i
*8,8);
407 /** Now, save to dumpfile **/
408 saveFile("iclass_mac_attack", "bin", dump
,datalen
);
412 UsbCommand c
= {CMD_SIMULATE_TAG_ICLASS
, {simType
,numberOfCSNs
}};
413 memcpy(c
.d
.asBytes
, CSN
, 8);
420 int CmdHFiClassReader(const char *Cmd
)
422 UsbCommand c
= {CMD_READER_ICLASS
, {0}};
426 if (WaitForResponseTimeout(CMD_ACK
,&resp
,4500)) {
427 uint8_t isOK
= resp
.arg
[0] & 0xff;
428 uint8_t * data
= resp
.d
.asBytes
;
430 PrintAndLog("isOk:%02x", isOK
);
434 PrintAndLog("CSN: %s",sprint_hex(data
,8));
438 PrintAndLog("CC: %s",sprint_hex(data
+8,8));
440 PrintAndLog("No CC obtained");
443 PrintAndLog("Command execute timeout");
450 int CmdHFiClassReader_Replay(const char *Cmd
)
452 uint8_t readerType
= 0;
453 uint8_t MAC
[4]={0x00, 0x00, 0x00, 0x00};
456 PrintAndLog("Usage: hf iclass replay <MAC>");
457 PrintAndLog(" sample: hf iclass replay 00112233");
461 if (param_gethex(Cmd
, 0, MAC
, 8)) {
462 PrintAndLog("MAC must include 8 HEX symbols");
466 UsbCommand c
= {CMD_READER_ICLASS_REPLAY
, {readerType
}};
467 memcpy(c
.d
.asBytes
, MAC
, 4);
473 int CmdHFiClassReader_Dump(const char *Cmd
)
475 uint8_t readerType
= 0;
476 uint8_t MAC
[4]={0x00,0x00,0x00,0x00};
477 uint8_t KEY
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
478 uint8_t CSN
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
479 uint8_t CCNR
[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
480 //uint8_t CC_temp[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
481 uint8_t div_key
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
482 uint8_t keytable
[128] = {0};
488 PrintAndLog("Usage: hf iclass dump <Key> [e]");
489 PrintAndLog(" Key - A 16 byte master key");
490 PrintAndLog(" e - If 'e' is specified, the key is interpreted as the 16 byte");
491 PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack");
492 PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format");
493 PrintAndLog(" sample: hf iclass dump 0011223344556677");
499 if (param_gethex(Cmd
, 0, KEY
, 16))
501 PrintAndLog("KEY must include 16 HEX symbols");
505 if (param_getchar(Cmd
, 1) == 'e')
507 PrintAndLog("Elite switch on");
511 hash2(KEY
, keytable
);
512 printarr_human_readable("keytable", keytable
, 128);
517 uint8_t key_sel
[8] = {0};
518 uint8_t key_sel_p
[8] = { 0 };
520 //HACK -- Below is for testing without access to a tag
521 uint8_t xdata
[16] = {0x01,0x02,0x03,0x04,0xF7,0xFF,0x12,0xE0, //CSN from http://www.proxmark.org/forum/viewtopic.php?pid=11230#p11230
522 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; // Just a random CC. Would be good to add a real testcase here
523 memcpy(resp
.d
.asBytes
,xdata
, 16);
525 uint8_t fake_dummy_test
= false;
529 UsbCommand c
= {CMD_READER_ICLASS
, {0}};
530 c
.arg
[0] = FLAG_ICLASS_READER_ONLY_ONCE
;
536 if (fake_dummy_test
|| WaitForResponseTimeout(CMD_ACK
,&resp
,4500)) {
537 uint8_t isOK
= resp
.arg
[0] & 0xff;
538 uint8_t * data
= resp
.d
.asBytes
;
541 memcpy(CCNR
,data
+8,8);
543 PrintAndLog("isOk:%02x", isOK
);
547 PrintAndLog("CSN: %s",sprint_hex(CSN
,8));
553 //Get the key index (hash1)
554 uint8_t key_index
[8] = {0};
556 hash1(CSN
, key_index
);
557 printvar("hash1", key_index
,8);
558 for(i
= 0; i
< 8 ; i
++)
559 key_sel
[i
] = keytable
[key_index
[i
]] & 0xFF;
560 PrintAndLog("Pre-fortified 'permuted' HS key that would be needed by an iclass reader to talk to above CSN:");
561 printvar("k_sel", key_sel
,8);
562 //Permute from iclass format to standard format
563 permutekey_rev(key_sel
,key_sel_p
);
564 used_key
= key_sel_p
;
566 //Perhaps this should also be permuted to std format?
567 // Something like the code below? I have no std system
568 // to test this with /Martin
570 //uint8_t key_sel_p[8] = { 0 };
571 //permutekey_rev(KEY,key_sel_p);
572 //used_key = key_sel_p;
578 PrintAndLog("Pre-fortified key that would be needed by the OmniKey reader to talk to above CSN:");
579 printvar("Used key",used_key
,8);
580 diversifyKey(CSN
,used_key
, div_key
);
581 PrintAndLog("Hash0, a.k.a diversified key, that is computed using Ksel and stored in the card (Block 3):");
582 printvar("Div key", div_key
, 8);
583 printvar("CC_NR:",CCNR
,12);
584 doMAC(CCNR
,12,div_key
, MAC
);
585 printvar("MAC", MAC
, 4);
587 UsbCommand d
= {CMD_READER_ICLASS_REPLAY
, {readerType
}};
588 memcpy(d
.d
.asBytes
, MAC
, 4);
589 if(!fake_dummy_test
) SendCommand(&d
);
592 PrintAndLog("Failed to obtain CC! Aborting");
595 PrintAndLog("Command execute timeout");
601 int CmdHFiClass_iso14443A_write(const char *Cmd
)
603 uint8_t readerType
= 0;
604 uint8_t MAC
[4]={0x00,0x00,0x00,0x00};
605 uint8_t KEY
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
606 uint8_t CSN
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
607 uint8_t CCNR
[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
608 uint8_t div_key
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
611 uint8_t bldata
[8]={0};
615 PrintAndLog("Usage: hf iclass write <Key> <Block> <Data>");
616 PrintAndLog(" sample: hf iclass write 0011223344556677 10 AAAAAAAAAAAAAAAA");
620 if (param_gethex(Cmd
, 0, KEY
, 16))
622 PrintAndLog("KEY must include 16 HEX symbols");
626 blockNo
= param_get8(Cmd
, 1);
629 PrintAndLog("Error: Maximum number of blocks is 32 for iClass 2K Cards!");
632 if (param_gethex(Cmd
, 2, bldata
, 8))
634 PrintAndLog("Block data must include 8 HEX symbols");
638 UsbCommand c
= {CMD_ICLASS_ISO14443A_WRITE
, {0}};
642 if (WaitForResponseTimeout(CMD_ACK
,&resp
,4500)) {
643 uint8_t isOK
= resp
.arg
[0] & 0xff;
644 uint8_t * data
= resp
.d
.asBytes
;
647 memcpy(CCNR
,data
+8,8);
648 PrintAndLog("DEBUG: %s",sprint_hex(CSN
,8));
649 PrintAndLog("DEBUG: %s",sprint_hex(CCNR
,8));
650 PrintAndLog("isOk:%02x", isOK
);
652 PrintAndLog("Command execute timeout");
655 diversifyKey(CSN
,KEY
, div_key
);
657 PrintAndLog("Div Key: %s",sprint_hex(div_key
,8));
658 doMAC(CCNR
, 12,div_key
, MAC
);
660 UsbCommand c2
= {CMD_ICLASS_ISO14443A_WRITE
, {readerType
,blockNo
}};
661 memcpy(c2
.d
.asBytes
, bldata
, 8);
662 memcpy(c2
.d
.asBytes
+8, MAC
, 4);
665 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
666 uint8_t isOK
= resp
.arg
[0] & 0xff;
667 uint8_t * data
= resp
.d
.asBytes
;
670 PrintAndLog("isOk:%02x data:%s", isOK
, sprint_hex(data
, 4));
672 PrintAndLog("isOk:%02x", isOK
);
674 PrintAndLog("Command execute timeout");
680 static command_t CommandTable
[] =
682 {"help", CmdHelp
, 1, "This help"},
683 {"list", CmdHFiClassList
, 0, "List iClass history"},
684 {"snoop", CmdHFiClassSnoop
, 0, "Eavesdrop iClass communication"},
685 {"sim", CmdHFiClassSim
, 0, "Simulate iClass tag"},
686 {"reader",CmdHFiClassReader
, 0, "Read an iClass tag"},
687 {"replay",CmdHFiClassReader_Replay
, 0, "Read an iClass tag via Reply Attack"},
688 {"dump", CmdHFiClassReader_Dump
, 0, "Authenticate and Dump iClass tag"},
689 {"write", CmdHFiClass_iso14443A_write
, 0, "Authenticate and Write iClass block"},
690 {NULL
, NULL
, 0, NULL
}
693 int CmdHFiClass(const char *Cmd
)
695 CmdsParse(CommandTable
, Cmd
);
699 int CmdHelp(const char *Cmd
)
701 CmdsHelp(CommandTable
);