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
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 //-----------------------------------------------------------------------------
16 #include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type
18 //#include "proxusb.h"
19 #include "proxmark3.h"
21 #include "cmdparser.h"
22 #include "cmdhficlass.h"
25 #include "loclass/des.h"
26 #include "loclass/cipherutils.h"
27 #include "loclass/cipher.h"
28 #include "loclass/ikeys.h"
30 static int CmdHelp(const char *Cmd
);
32 int CmdHFiClassList(const char *Cmd
)
35 GetFromBigBuf(got
,sizeof(got
),0);
37 PrintAndLog("recorded activity:");
38 PrintAndLog(" ETU :rssi: who bytes");
39 PrintAndLog("---------+----+----+-----------");
50 int timestamp
= *((uint32_t *)(got
+i
));
51 if (timestamp
& 0x80000000) {
52 timestamp
&= 0x7fffffff;
59 int parityBits
= *((uint32_t *)(got
+i
+4));
60 // 4 bytes of additional information...
61 // maximum of 32 additional parity bit information
64 // at each quarter bit period we can send power level (16 levels)
65 // or each half bit period in 256 levels.
73 if (i
+ len
>= 1900) {
77 uint8_t *frame
= (got
+i
+9);
79 // Break and stick with current result if buffer was not completely full
80 if (frame
[0] == 0x44 && frame
[1] == 0x44 && frame
[3] == 0x44) { break; }
84 for (j
= 0; j
< len
; j
++) {
89 oddparity
^= (((frame
[j
] & 0xFF) >> k
) & 0x01);
92 //if((parityBits >> (len - j - 1)) & 0x01) {
93 if (isResponse
&& (oddparity
!= ((parityBits
>> (len
- j
- 1)) & 0x01))) {
94 sprintf(line
+(j
*4), "%02x! ", frame
[j
]);
97 sprintf(line
+(j
*4), "%02x ", frame
[j
]);
105 for (j
= 0; j
< (len
- 1); j
++) {
106 // gives problems... search for the reason..
107 /*if(frame[j] == 0xAA) {
110 crc = "[1] Two drops close after each other";
113 crc = "[2] Potential SOC with a drop in second half of bitperiod";
116 crc = "[3] Segment Z after segment X is not possible";
119 crc = "[4] Parity bit of a fully received byte was wrong";
122 crc = "[?] Unknown error";
129 if (strlen(crc
)==0) {
130 if(!isResponse
&& len
== 4) {
131 // Rough guess that this is a command from the reader
132 // For iClass the command byte is not part of the CRC
133 ComputeCrc14443(CRC_ICLASS
, &frame
[1], len
-3, &b1
, &b2
);
136 // For other data.. CRC might not be applicable (UPDATE commands etc.)
137 ComputeCrc14443(CRC_ICLASS
, frame
, len
-2, &b1
, &b2
);
139 //printf("%1x %1x",(unsigned)b1,(unsigned)b2);
140 if (b1
!= frame
[len
-2] || b2
!= frame
[len
-1]) {
141 crc
= (isResponse
& (len
< 8)) ? "" : " !crc";
150 char metricString
[100];
152 sprintf(metricString
, "%3d", metric
);
154 strcpy(metricString
, " ");
157 PrintAndLog(" +%7d: %s: %s %s %s",
158 (prev
< 0 ? 0 : (timestamp
- prev
)),
160 (isResponse
? "TAG" : " "), line
, crc
);
168 int CmdHFiClassSnoop(const char *Cmd
)
170 UsbCommand c
= {CMD_SNOOP_ICLASS
};
175 int CmdHFiClassSim(const char *Cmd
)
178 uint8_t CSN
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
181 PrintAndLog("Usage: hf iclass sim <sim type> <CSN (16 hex symbols)>");
182 PrintAndLog(" sample: hf iclass sim 0 031FEC8AF7FF12E0");
186 simType
= param_get8(Cmd
, 0);
187 if (param_gethex(Cmd
, 1, CSN
, 16)) {
188 PrintAndLog("A CSN should consist of 16 HEX symbols");
191 PrintAndLog("--simtype:%02x csn:%s", simType
, sprint_hex(CSN
, 8));
193 UsbCommand c
= {CMD_SIMULATE_TAG_ICLASS
, {simType
}};
194 memcpy(c
.d
.asBytes
, CSN
, 8);
200 int CmdHFiClassReader(const char *Cmd
)
202 uint8_t readerType
= 0;
205 PrintAndLog("Usage: hf iclass reader <reader type>");
206 PrintAndLog(" sample: hf iclass reader 0");
210 readerType
= param_get8(Cmd
, 0);
211 PrintAndLog("--readertype:%02x", readerType
);
213 UsbCommand c
= {CMD_READER_ICLASS
, {readerType
}};
219 int CmdHFiClassReader_Replay(const char *Cmd
)
221 uint8_t readerType
= 0;
222 uint8_t MAC
[4]={0x00, 0x00, 0x00, 0x00};
225 PrintAndLog("Usage: hf iclass replay <MAC>");
226 PrintAndLog(" sample: hf iclass replay 00112233");
230 if (param_gethex(Cmd
, 0, MAC
, 8)) {
231 PrintAndLog("MAC must include 8 HEX symbols");
235 UsbCommand c
= {CMD_READER_ICLASS_REPLAY
, {readerType
}};
236 memcpy(c
.d
.asBytes
, MAC
, 4);
242 int CmdHFiClassReader_Dump(const char *Cmd
)
244 uint8_t readerType
= 0;
245 uint8_t MAC
[4]={0x00,0x00,0x00,0x00};
246 uint8_t KEY
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
247 uint8_t CSN
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
248 uint8_t CCNR
[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
249 //uint8_t CC_temp[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
250 uint8_t result
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
251 uint8_t div_key
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
253 uint64_t crypted_id
=0;
257 //PrintAndLog("Usage: hf iclass dump <Key> <CSN> <CC>");
258 //PrintAndLog(" sample: hf iclass dump 0011223344556677 aabbccddeeffgghh FFFFFFFFFFFFFFFF");
259 PrintAndLog("Usage: hf iclass dump <Key>");
260 PrintAndLog(" sample: hf iclass dump 0011223344556677");
264 if (param_gethex(Cmd
, 0, KEY
, 16))
266 PrintAndLog("KEY must include 16 HEX symbols");
270 /*if (param_gethex(Cmd, 1, CSN, 16))
272 PrintAndLog("CSN must include 16 HEX symbols");
275 if (param_gethex(Cmd, 2, CC_temp, 16))
277 PrintAndLog("CC must include 16 HEX symbols");
281 UsbCommand c
= {CMD_ICLASS_ISO14443A_GETPUBLIC
, {0}};
282 //memcpy(c.d.asBytes, MAC, 4);
286 if (WaitForResponseTimeout(CMD_ACK
,&resp
,4500)) {
287 uint8_t isOK
= resp
.arg
[0] & 0xff;
288 uint8_t * data
= resp
.d
.asBytes
;
291 memcpy(CCNR
,data
+8,8);
292 PrintAndLog("DEBUG: %s",sprint_hex(CSN
,8));
293 PrintAndLog("DEBUG: %s",sprint_hex(CCNR
,8));
294 PrintAndLog("isOk:%02x", isOK
);
296 PrintAndLog("Command execute timeout");
300 //memcpy(CCNR,CC_temp,8);
301 des_setkey_enc( &ctx_enc
, KEY
);
302 des_crypt_ecb(&ctx_enc
,CSN
,result
);
303 PrintAndLog("DES Key: %s",sprint_hex(result
,8));
305 crypted_id
= bytes_to_num(result
,8);
306 uint64_t x
= (crypted_id
& 0xFFFF000000000000 );
307 pushbackSixBitByte(&newz
, getSixBitByte(crypted_id
,0),7);
308 pushbackSixBitByte(&newz
, getSixBitByte(crypted_id
,1),6);
309 pushbackSixBitByte(&newz
, getSixBitByte(crypted_id
,2),5);
310 pushbackSixBitByte(&newz
, getSixBitByte(crypted_id
,3),4);
311 pushbackSixBitByte(&newz
, getSixBitByte(crypted_id
,4),3);
312 pushbackSixBitByte(&newz
, getSixBitByte(crypted_id
,5),2);
313 pushbackSixBitByte(&newz
, getSixBitByte(crypted_id
,6),1);
314 pushbackSixBitByte(&newz
, getSixBitByte(crypted_id
,7),0);
317 num_to_bytes(crypted_id
,8,result
);
318 PrintAndLog("DESr Key: %s",sprint_hex(result
,8));
319 hash0(crypted_id
,div_key
);
320 PrintAndLog("Div Key: %s",sprint_hex(div_key
,8));
321 calc_iclass_mac(CCNR
,12,div_key
,MAC
);
323 UsbCommand d
= {CMD_READER_ICLASS_REPLAY
, {readerType
}};
324 memcpy(d
.d
.asBytes
, MAC
, 4);
330 int CmdHFiClass_iso14443A_write(const char *Cmd
)
332 uint8_t readerType
= 0;
333 uint8_t MAC
[4]={0x00,0x00,0x00,0x00};
334 uint8_t KEY
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
335 uint8_t CSN
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
336 uint8_t CCNR
[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
337 uint8_t CC_temp
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
338 uint8_t result
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
339 uint8_t div_key
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
341 uint64_t crypted_id
=0;
343 uint8_t bldata
[8]={0};
347 PrintAndLog("Usage: hf iclass write <Key> <Block> <Data>");
348 PrintAndLog(" sample: hf iclass write 0011223344556677 10 AAAAAAAAAAAAAAAA");
352 if (param_gethex(Cmd
, 0, KEY
, 16))
354 PrintAndLog("KEY must include 16 HEX symbols");
358 blockNo
= param_get8(Cmd
, 1);
361 PrintAndLog("Error: Maximum number of blocks is 32 for iClass 2K Cards!");
364 if (param_gethex(Cmd
, 2, bldata
, 8))
366 PrintAndLog("Block data must include 8 HEX symbols");
370 UsbCommand c
= {CMD_ICLASS_ISO14443A_GETPUBLIC
, {0}};
371 //memcpy(c.d.asBytes, MAC, 4);
375 if (WaitForResponseTimeout(CMD_ACK
,&resp
,4500)) {
376 uint8_t isOK
= resp
.arg
[0] & 0xff;
377 uint8_t * data
= resp
.d
.asBytes
;
380 memcpy(CCNR
,data
+8,8);
381 PrintAndLog("DEBUG: %s",sprint_hex(CSN
,8));
382 PrintAndLog("DEBUG: %s",sprint_hex(CCNR
,8));
383 PrintAndLog("isOk:%02x", isOK
);
385 PrintAndLog("Command execute timeout");
388 des_setkey_enc( &ctx_enc
, KEY
);
389 des_crypt_ecb(&ctx_enc
,CSN
,result
);
390 PrintAndLog("DES Key: %s",sprint_hex(result
,8));
392 crypted_id
= bytes_to_num(result
,8);
393 uint64_t x
= (crypted_id
& 0xFFFF000000000000 );
394 pushbackSixBitByte(&newz
, getSixBitByte(crypted_id
,0),7);
395 pushbackSixBitByte(&newz
, getSixBitByte(crypted_id
,1),6);
396 pushbackSixBitByte(&newz
, getSixBitByte(crypted_id
,2),5);
397 pushbackSixBitByte(&newz
, getSixBitByte(crypted_id
,3),4);
398 pushbackSixBitByte(&newz
, getSixBitByte(crypted_id
,4),3);
399 pushbackSixBitByte(&newz
, getSixBitByte(crypted_id
,5),2);
400 pushbackSixBitByte(&newz
, getSixBitByte(crypted_id
,6),1);
401 pushbackSixBitByte(&newz
, getSixBitByte(crypted_id
,7),0);
404 num_to_bytes(crypted_id
,8,result
);
405 PrintAndLog("DESr Key: %s",sprint_hex(result
,8));
406 hash0(crypted_id
,div_key
);
407 PrintAndLog("Div Key: %s",sprint_hex(div_key
,8));
408 calc_iclass_mac(CCNR
,12,div_key
,MAC
);
410 UsbCommand c
= {CMD_ICLASS_ISO14443A_WRITE
, {readerType
,blockNo
}};
411 memcpy(c
.d
.asBytes
, bldata
, 8);
412 memcpy(c
.d
.asBytes
+8, MAC
, 4);
416 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
417 uint8_t isOK
= resp
.arg
[0] & 0xff;
418 uint8_t * data
= resp
.d
.asBytes
;
421 PrintAndLog("isOk:%02x data:%s", isOK
, sprint_hex(data
, 4));
423 PrintAndLog("isOk:%02x", isOK
);
425 PrintAndLog("Command execute timeout");
431 static command_t CommandTable
[] =
433 {"help", CmdHelp
, 1, "This help"},
434 {"list", CmdHFiClassList
, 0, "List iClass history"},
435 {"snoop", CmdHFiClassSnoop
, 0, "Eavesdrop iClass communication"},
436 {"sim", CmdHFiClassSim
, 0, "Simulate iClass tag"},
437 {"reader",CmdHFiClassReader
, 0, "Read an iClass tag"},
438 {"replay",CmdHFiClassReader_Replay
, 0, "Read an iClass tag via Reply Attack"},
439 {"dump", CmdHFiClassReader_Dump
, 0, "Authenticate and Dump iClass tag"},
440 {"write", CmdHFiClass_iso14443A_write
, 0, "Authenticate and Write iClass block"},
441 {NULL
, NULL
, 0, NULL
}
444 int CmdHFiClass(const char *Cmd
)
446 CmdsParse(CommandTable
, Cmd
);
450 int CmdHelp(const char *Cmd
)
452 CmdsHelp(CommandTable
);