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 "proxmark3.h"
21 #include "cmdparser.h"
22 #include "cmdhficlass.h"
26 #include "loclass/des.h"
27 #include "loclass/cipherutils.h"
28 #include "loclass/cipher.h"
29 #include "loclass/ikeys.h"
30 #include "loclass/elite_crack.h"
31 #include "loclass/fileutils.h"
32 #include "protocols.h"
35 static int CmdHelp(const char *Cmd
);
37 int xorbits_8(uint8_t val
)
39 uint8_t res
= val
^ (val
>> 1); //1st pass
40 res
= res
^ (res
>> 1); // 2nd pass
41 res
= res
^ (res
>> 2); // 3rd pass
42 res
= res
^ (res
>> 4); // 4th pass
46 int CmdHFiClassList(const char *Cmd
)
48 PrintAndLog("Deprecated command, use 'hf list iclass' instead");
52 int CmdHFiClassSnoop(const char *Cmd
)
54 UsbCommand c
= {CMD_SNOOP_ICLASS
};
58 int usage_hf_iclass_sim()
60 PrintAndLog("Usage: hf iclass sim <option> [CSN]");
61 PrintAndLog(" options");
62 PrintAndLog(" 0 <CSN> simulate the given CSN");
63 PrintAndLog(" 1 simulate default CSN");
64 PrintAndLog(" 2 Reader-attack, gather reader responses to extract elite key");
65 PrintAndLog(" 3 Full simulation using emulator memory (see 'hf iclass eload')");
66 PrintAndLog(" example: hf iclass sim 0 031FEC8AF7FF12E0");
67 PrintAndLog(" example: hf iclass sim 2");
68 PrintAndLog(" example: hf iclass eload 'tagdump.bin'");
69 PrintAndLog(" hf iclass sim 3");
74 int CmdHFiClassSim(const char *Cmd
)
77 uint8_t CSN
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
80 return usage_hf_iclass_sim();
82 simType
= param_get8ex(Cmd
, 0, 0, 10);
86 if (param_gethex(Cmd
, 1, CSN
, 16)) {
87 PrintAndLog("A CSN should consist of 16 HEX symbols");
88 return usage_hf_iclass_sim();
91 PrintAndLog("--simtype:%02x csn:%s", simType
, sprint_hex(CSN
, 8));
95 PrintAndLog("Undefined simptype %d", simType
);
96 return usage_hf_iclass_sim();
99 uint8_t numberOfCSNs
=0;
102 UsbCommand c
= {CMD_SIMULATE_TAG_ICLASS
, {simType
,NUM_CSNS
}};
103 UsbCommand resp
= {0};
105 uint8_t csns
[8*NUM_CSNS
] = {
106 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0,
107 0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0,
108 0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0,
109 0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0,
110 0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0,
111 0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0,
112 0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0,
113 0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0,
114 0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0,
115 0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0,
116 0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0,
117 0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0,
118 0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0,
119 0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0,
120 0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 };
122 memcpy(c
.d
.asBytes
, csns
, 8*NUM_CSNS
);
125 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, -1)) {
126 PrintAndLog("Command timed out");
130 uint8_t num_mac_responses
= resp
.arg
[1];
131 PrintAndLog("Mac responses: %d MACs obtained (should be %d)", num_mac_responses
,NUM_CSNS
);
133 size_t datalen
= NUM_CSNS
*24;
135 * Now, time to dump to file. We'll use this format:
136 * <8-byte CSN><8-byte CC><4 byte NR><4 byte MAC>....
137 * So, it should wind up as
140 * The returndata from the pm3 is on the following format
141 * <4 byte NR><4 byte MAC>
142 * CC are all zeroes, CSN is the same as was sent in
144 void* dump
= malloc(datalen
);
145 memset(dump
,0,datalen
);//<-- Need zeroes for the CC-field
147 for(i
= 0 ; i
< NUM_CSNS
; i
++)
149 memcpy(dump
+i
*24, csns
+i
*8,8); //CSN
150 //8 zero bytes here...
151 //Then comes NR_MAC (eight bytes from the response)
152 memcpy(dump
+i
*24+16,resp
.d
.asBytes
+i
*8,8);
155 /** Now, save to dumpfile **/
156 saveFile("iclass_mac_attack", "bin", dump
,datalen
);
160 UsbCommand c
= {CMD_SIMULATE_TAG_ICLASS
, {simType
,numberOfCSNs
}};
161 memcpy(c
.d
.asBytes
, CSN
, 8);
168 int HFiClassReader(const char *Cmd
, bool loop
, bool verbose
)
170 bool tagFound
= false;
171 UsbCommand c
= {CMD_READER_ICLASS
, {FLAG_ICLASS_READER_CSN
|
172 FLAG_ICLASS_READER_CONF
|FLAG_ICLASS_READER_AA
}};
173 if (!loop
) c
.arg
[0] |= FLAG_ICLASS_READER_ONLY_ONCE
| FLAG_ICLASS_READER_ONE_TRY
;
177 if (WaitForResponseTimeout(CMD_ACK
,&resp
, 4500)) {
178 uint8_t readStatus
= resp
.arg
[0] & 0xff;
179 uint8_t *data
= resp
.d
.asBytes
;
182 PrintAndLog("Readstatus:%02x", readStatus
);
183 if( readStatus
== 0){
185 if (verbose
) PrintAndLog("Quitting...");
188 if( readStatus
& FLAG_ICLASS_READER_CSN
){
189 PrintAndLog("CSN: %s",sprint_hex(data
,8));
192 if( readStatus
& FLAG_ICLASS_READER_CC
) PrintAndLog("CC: %s",sprint_hex(data
+16,8));
193 if( readStatus
& FLAG_ICLASS_READER_CONF
){
194 printIclassDumpInfo(data
);
196 if (tagFound
&& !loop
) return 1;
198 if (verbose
) PrintAndLog("Command execute timeout");
206 int CmdHFiClassReader(const char *Cmd
)
208 return HFiClassReader(Cmd
, true, true);
211 int CmdHFiClassReader_Replay(const char *Cmd
)
213 uint8_t readerType
= 0;
214 uint8_t MAC
[4]={0x00, 0x00, 0x00, 0x00};
217 PrintAndLog("Usage: hf iclass replay <MAC>");
218 PrintAndLog(" sample: hf iclass replay 00112233");
222 if (param_gethex(Cmd
, 0, MAC
, 8)) {
223 PrintAndLog("MAC must include 8 HEX symbols");
227 UsbCommand c
= {CMD_READER_ICLASS_REPLAY
, {readerType
}};
228 memcpy(c
.d
.asBytes
, MAC
, 4);
234 int CmdHFiClassReader_Dump(const char *Cmd
)
236 uint8_t readerType
= 0;
237 uint8_t MAC
[4]={0x00,0x00,0x00,0x00};
238 uint8_t KEY
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
239 uint8_t CSN
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
240 uint8_t CCNR
[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
241 //uint8_t CC_temp[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
242 uint8_t div_key
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
243 uint8_t keytable
[128] = {0};
249 PrintAndLog("Usage: hf iclass dump <Key> [e]");
250 PrintAndLog(" Key - A 16 byte master key");
251 PrintAndLog(" e - If 'e' is specified, the key is interpreted as the 16 byte");
252 PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack");
253 PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format");
254 PrintAndLog(" sample: hf iclass dump 0011223344556677");
260 if (param_gethex(Cmd
, 0, KEY
, 16))
262 PrintAndLog("KEY must include 16 HEX symbols");
266 if (param_getchar(Cmd
, 1) == 'e')
268 PrintAndLog("Elite switch on");
272 hash2(KEY
, keytable
);
273 printarr_human_readable("keytable", keytable
, 128);
278 uint8_t key_sel
[8] = {0};
279 uint8_t key_sel_p
[8] = { 0 };
281 UsbCommand c
= {CMD_READER_ICLASS
, {0}};
282 c
.arg
[0] = FLAG_ICLASS_READER_ONLY_ONCE
| FLAG_ICLASS_READER_CC
;
287 if (!WaitForResponseTimeout(CMD_ACK
,&resp
,4500))
289 PrintAndLog("Command execute timeout");
293 uint8_t isOK
= resp
.arg
[0] & 0xff;
294 uint8_t * data
= resp
.d
.asBytes
;
297 memcpy(CCNR
,data
+16,8);
299 PrintAndLog("isOk:%02x", isOK
);
303 PrintAndLog("CSN: %s",sprint_hex(CSN
,8));
306 PrintAndLog("Failed to obtain CC! Aborting");
313 //Get the key index (hash1)
314 uint8_t key_index
[8] = {0};
316 hash1(CSN
, key_index
);
317 printvar("hash1", key_index
,8);
318 for(i
= 0; i
< 8 ; i
++)
319 key_sel
[i
] = keytable
[key_index
[i
]] & 0xFF;
320 PrintAndLog("Pre-fortified 'permuted' HS key that would be needed by an iclass reader to talk to above CSN:");
321 printvar("k_sel", key_sel
,8);
322 //Permute from iclass format to standard format
323 permutekey_rev(key_sel
,key_sel_p
);
324 used_key
= key_sel_p
;
329 PrintAndLog("Pre-fortified key that would be needed by the OmniKey reader to talk to above CSN:");
330 printvar("Used key",used_key
,8);
331 diversifyKey(CSN
,used_key
, div_key
);
332 PrintAndLog("Hash0, a.k.a diversified key, that is computed using Ksel and stored in the card (Block 3):");
333 printvar("Div key", div_key
, 8);
334 printvar("CC_NR:",CCNR
,12);
335 doMAC(CCNR
,div_key
, MAC
);
336 printvar("MAC", MAC
, 4);
338 uint8_t iclass_data
[32000] = {0};
339 uint32_t iclass_datalen
= 0;
340 uint32_t iclass_blocksFailed
= 0;//Set to 1 if dump was incomplete
342 UsbCommand d
= {CMD_READER_ICLASS_REPLAY
, {readerType
}};
343 memcpy(d
.d
.asBytes
, MAC
, 4);
344 clearCommandBuffer();
346 PrintAndLog("Waiting for device to dump data. Press button on device and key on keyboard to abort...");
351 printf("\naborted via keyboard!\n");
354 if(WaitForResponseTimeout(CMD_ACK
,&resp
,4500))
356 uint32_t dataLength
= resp
.arg
[0];
357 iclass_blocksFailed
|= resp
.arg
[1];
360 PrintAndLog("Got %d bytes data (total so far %d)" ,dataLength
,iclass_datalen
);
361 memcpy(iclass_data
+iclass_datalen
, resp
.d
.asBytes
,dataLength
);
362 iclass_datalen
+= dataLength
;
364 {//Last transfer, datalength 0 means the dump is finished
365 PrintAndLog("Dumped %d bytes of data from tag. ", iclass_datalen
);
366 if(iclass_blocksFailed
)
368 PrintAndLog("OBS! Some blocks failed to be dumped correctly!");
370 if(iclass_datalen
> 0)
372 char filename
[100] = {0};
373 //create a preferred filename
374 snprintf(filename
, 100,"iclass_tagdump-%02x%02x%02x%02x%02x%02x%02x%02x",
375 CSN
[0],CSN
[1],CSN
[2],CSN
[3],
376 CSN
[4],CSN
[5],CSN
[6],CSN
[7]);
377 //Place the div_key in block 3
378 memcpy(iclass_data
+(3*8), div_key
, 8);
379 saveFile(filename
,"bin",iclass_data
, iclass_datalen
);
381 //Aaaand we're finished
391 int hf_iclass_eload_usage()
393 PrintAndLog("Loads iclass tag-dump into emulator memory on device");
394 PrintAndLog("Usage: hf iclass eload f <filename>");
396 PrintAndLog("Example: hf iclass eload f iclass_tagdump-aa162d30f8ff12f1.bin");
401 int iclassEmlSetMem(uint8_t *data
, int blockNum
, int blocksCount
) {
402 UsbCommand c
= {CMD_MIFARE_EML_MEMSET
, {blockNum
, blocksCount
, 0}};
403 memcpy(c
.d
.asBytes
, data
, blocksCount
* 16);
407 int CmdHFiClassELoad(const char *Cmd
)
410 char opt
= param_getchar(Cmd
, 0);
411 if (strlen(Cmd
)<1 || opt
== 'h')
412 return hf_iclass_eload_usage();
414 //File handling and reading
416 char filename
[FILE_PATH_SIZE
];
417 if(opt
== 'f' && param_getstr(Cmd
, 1, filename
) > 0)
419 f
= fopen(filename
, "rb");
421 return hf_iclass_eload_usage();
425 PrintAndLog("Failed to read from file '%s'", filename
);
429 fseek(f
, 0, SEEK_END
);
430 long fsize
= ftell(f
);
431 fseek(f
, 0, SEEK_SET
);
433 uint8_t *dump
= malloc(fsize
);
436 size_t bytes_read
= fread(dump
, 1, fsize
, f
);
439 printIclassDumpInfo(dump
);
442 if (bytes_read
< fsize
)
444 prnlog("Error, could only read %d bytes (should be %d)",bytes_read
, fsize
);
449 uint32_t bytes_sent
= 0;
450 uint32_t bytes_remaining
= bytes_read
;
452 while(bytes_remaining
> 0){
453 uint32_t bytes_in_packet
= MIN(USB_CMD_DATA_SIZE
, bytes_remaining
);
454 UsbCommand c
= {CMD_ICLASS_EML_MEMSET
, {bytes_sent
,bytes_in_packet
,0}};
455 memcpy(c
.d
.asBytes
, dump
, bytes_in_packet
);
457 bytes_remaining
-= bytes_in_packet
;
458 bytes_sent
+= bytes_in_packet
;
461 PrintAndLog("Sent %d bytes of data to device emulator memory", bytes_sent
);
465 int usage_hf_iclass_decrypt()
467 PrintAndLog("Usage: hf iclass decrypt f <tagdump> o ");
469 PrintAndLog("OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside");
470 PrintAndLog("in the working directory. The file should be 16 bytes binary data");
472 PrintAndLog("example: hf iclass decrypt f tagdump_12312342343.bin");
474 PrintAndLog("OBS! This is pretty stupid implementation, it tries to decrypt every block after block 6. ");
475 PrintAndLog("Correct behaviour would be to decrypt only the application areas where the key is valid,");
476 PrintAndLog("which is defined by the configuration block.");
480 int readKeyfile(const char *filename
, size_t len
, uint8_t* buffer
)
482 FILE *f
= fopen(filename
, "rb");
484 PrintAndLog("Failed to read from file '%s'", filename
);
487 fseek(f
, 0, SEEK_END
);
488 long fsize
= ftell(f
);
489 fseek(f
, 0, SEEK_SET
);
490 size_t bytes_read
= fread(buffer
, 1, len
, f
);
494 PrintAndLog("Warning, file size is %d, expected %d", fsize
, len
);
497 if(bytes_read
!= len
)
499 PrintAndLog("Warning, could only read %d bytes, expected %d" ,bytes_read
, len
);
505 int CmdHFiClassDecrypt(const char *Cmd
)
507 uint8_t key
[16] = { 0 };
508 if(readKeyfile("iclass_decryptionkey.bin", 16, key
))
510 usage_hf_iclass_decrypt();
513 PrintAndLog("Decryption file found... ");
514 char opt
= param_getchar(Cmd
, 0);
515 if (strlen(Cmd
)<1 || opt
== 'h')
516 return usage_hf_iclass_decrypt();
518 //Open the tagdump-file
520 char filename
[FILE_PATH_SIZE
];
521 if(opt
== 'f' && param_getstr(Cmd
, 1, filename
) > 0)
523 f
= fopen(filename
, "rb");
525 return usage_hf_iclass_decrypt();
528 fseek(f
, 0, SEEK_END
);
529 long fsize
= ftell(f
);
530 fseek(f
, 0, SEEK_SET
);
531 uint8_t enc_dump
[8] = {0};
532 uint8_t *decrypted
= malloc(fsize
);
533 des3_context ctx
= { DES_DECRYPT
,{ 0 } };
534 des3_set2key_dec( &ctx
, key
);
535 size_t bytes_read
= fread(enc_dump
, 1, 8, f
);
537 //Use the first block (CSN) for filename
538 char outfilename
[FILE_PATH_SIZE
] = { 0 };
539 snprintf(outfilename
,FILE_PATH_SIZE
,"iclass_tagdump-%02x%02x%02x%02x%02x%02x%02x%02x-decrypted",
540 enc_dump
[0],enc_dump
[1],enc_dump
[2],enc_dump
[3],
541 enc_dump
[4],enc_dump
[5],enc_dump
[6],enc_dump
[7]);
544 while(bytes_read
== 8)
548 memcpy(decrypted
+(blocknum
*8), enc_dump
, 8);
550 des3_crypt_ecb(&ctx
, enc_dump
,decrypted
+(blocknum
*8) );
552 printvar("decrypted block", decrypted
+(blocknum
*8), 8);
553 bytes_read
= fread(enc_dump
, 1, 8, f
);
558 saveFile(outfilename
,"bin", decrypted
, blocknum
*8);
563 int CmdHFiClass_iso14443A_write(const char *Cmd
)
565 uint8_t readerType
= 0;
566 uint8_t MAC
[4]={0x00,0x00,0x00,0x00};
567 uint8_t KEY
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
568 uint8_t CSN
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
569 uint8_t CCNR
[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
570 uint8_t div_key
[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
573 uint8_t bldata
[8]={0};
577 PrintAndLog("Usage: hf iclass write <Key> <Block> <Data>");
578 PrintAndLog(" sample: hf iclass write 0011223344556677 10 AAAAAAAAAAAAAAAA");
582 if (param_gethex(Cmd
, 0, KEY
, 16))
584 PrintAndLog("KEY must include 16 HEX symbols");
588 blockNo
= param_get8(Cmd
, 1);
591 PrintAndLog("Error: Maximum number of blocks is 32 for iClass 2K Cards!");
594 if (param_gethex(Cmd
, 2, bldata
, 8))
596 PrintAndLog("Block data must include 8 HEX symbols");
600 UsbCommand c
= {CMD_ICLASS_ISO14443A_WRITE
, {0}};
604 if (WaitForResponseTimeout(CMD_ACK
,&resp
,4500)) {
605 uint8_t isOK
= resp
.arg
[0] & 0xff;
606 uint8_t * data
= resp
.d
.asBytes
;
609 memcpy(CCNR
,data
+8,8);
610 PrintAndLog("DEBUG: %s",sprint_hex(CSN
,8));
611 PrintAndLog("DEBUG: %s",sprint_hex(CCNR
,8));
612 PrintAndLog("isOk:%02x", isOK
);
614 PrintAndLog("Command execute timeout");
617 diversifyKey(CSN
,KEY
, div_key
);
619 PrintAndLog("Div Key: %s",sprint_hex(div_key
,8));
620 doMAC(CCNR
, div_key
, MAC
);
622 UsbCommand c2
= {CMD_ICLASS_ISO14443A_WRITE
, {readerType
,blockNo
}};
623 memcpy(c2
.d
.asBytes
, bldata
, 8);
624 memcpy(c2
.d
.asBytes
+8, MAC
, 4);
627 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
628 uint8_t isOK
= resp
.arg
[0] & 0xff;
629 uint8_t * data
= resp
.d
.asBytes
;
632 PrintAndLog("isOk:%02x data:%s", isOK
, sprint_hex(data
, 4));
634 PrintAndLog("isOk:%02x", isOK
);
636 PrintAndLog("Command execute timeout");
640 int CmdHFiClass_loclass(const char *Cmd
)
642 char opt
= param_getchar(Cmd
, 0);
644 if (strlen(Cmd
)<1 || opt
== 'h') {
645 PrintAndLog("Usage: hf iclass loclass [options]");
646 PrintAndLog("Options:");
647 PrintAndLog("h Show this help");
648 PrintAndLog("t Perform self-test");
649 PrintAndLog("f <filename> Bruteforce iclass dumpfile");
650 PrintAndLog(" An iclass dumpfile is assumed to consist of an arbitrary number of");
651 PrintAndLog(" malicious CSNs, and their protocol responses");
652 PrintAndLog(" The the binary format of the file is expected to be as follows: ");
653 PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
654 PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
655 PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
656 PrintAndLog(" ... totalling N*24 bytes");
659 char fileName
[255] = {0};
662 if(param_getstr(Cmd
, 1, fileName
) > 0)
664 return bruteforceFileNoKeys(fileName
);
667 PrintAndLog("You must specify a filename");
672 int errors
= testCipherUtils();
674 errors
+= doKeyTests(0);
675 errors
+= testElite();
678 prnlog("OBS! There were errors!!!");
686 static command_t CommandTable
[] =
688 {"help", CmdHelp
, 1, "This help"},
689 {"list", CmdHFiClassList
, 0, "[Deprecated] List iClass history"},
690 {"snoop", CmdHFiClassSnoop
, 0, "Eavesdrop iClass communication"},
691 {"sim", CmdHFiClassSim
, 0, "Simulate iClass tag"},
692 {"reader",CmdHFiClassReader
, 0, "Read an iClass tag"},
693 {"replay",CmdHFiClassReader_Replay
, 0, "Read an iClass tag via Reply Attack"},
694 {"dump", CmdHFiClassReader_Dump
, 0, "Authenticate and Dump iClass tag"},
695 // {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"},
696 {"loclass", CmdHFiClass_loclass
, 1, "Use loclass to perform bruteforce of reader attack dump"},
697 {"eload", CmdHFiClassELoad
, 0, "[experimental] Load data into iclass emulator memory"},
698 {"decrypt", CmdHFiClassDecrypt
, 1, "Decrypt tagdump" },
699 {NULL
, NULL
, 0, NULL
}
702 int CmdHFiClass(const char *Cmd
)
704 CmdsParse(CommandTable
, Cmd
);
708 int CmdHelp(const char *Cmd
)
710 CmdsHelp(CommandTable
);