]> git.zerfleddert.de Git - proxmark3-svn/blame - client/cmdhficlass.c
FIX: a shot at fixing the "_" underscore problem in fileutils.c. This one uses _ifde...
[proxmark3-svn] / client / cmdhficlass.c
CommitLineData
cee5a30d 1//-----------------------------------------------------------------------------
2// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>, Hagen Fritsch
3// Copyright (C) 2011 Gerhard de Koning Gans
f38a1528 4// Copyright (C) 2014 Midnitesnake & Andy Davies & Martin Holst Swende
cee5a30d 5//
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
8// the license.
9//-----------------------------------------------------------------------------
10// High frequency iClass commands
11//-----------------------------------------------------------------------------
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
9f6e9d15 16#include <sys/stat.h>
cee5a30d 17#include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type
18#include "data.h"
902cb3c0 19#include "proxmark3.h"
cee5a30d 20#include "ui.h"
21#include "cmdparser.h"
22#include "cmdhficlass.h"
f38a1528 23#include "../include/common.h"
14006804 24#include "util.h"
17cba269 25#include "cmdmain.h"
f38a1528 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"
cee5a30d 32
33static int CmdHelp(const char *Cmd);
34
17cba269
MHS
35int xorbits_8(uint8_t val)
36{
37 uint8_t res = val ^ (val >> 1); //1st pass
38 res = res ^ (res >> 1); // 2nd pass
39 res = res ^ (res >> 2); // 3rd pass
40 res = res ^ (res >> 4); // 4th pass
41 return res & 1;
42}
43
cee5a30d 44int CmdHFiClassList(const char *Cmd)
17cba269 45{
17cba269
MHS
46 bool ShowWaitCycles = false;
47 char param = param_getchar(Cmd, 0);
48
49 if (param != 0) {
50 PrintAndLog("List data in trace buffer.");
51 PrintAndLog("Usage: hf iclass list");
52 PrintAndLog("h - help");
53 PrintAndLog("sample: hf iclass list");
54 return 0;
55 }
56
3bc3598e 57// for the time being. Need better Bigbuf handling.
58#define TRACE_SIZE 3000
59
60 uint8_t trace[TRACE_SIZE];
61 GetFromBigBuf(trace, TRACE_SIZE, 0);
17cba269
MHS
62 WaitForResponse(CMD_ACK,NULL);
63
64 PrintAndLog("Recorded Activity");
65 PrintAndLog("");
66 PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer");
67 PrintAndLog("All times are in carrier periods (1/13.56Mhz)");
68 PrintAndLog("");
3bc3598e 69 PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC ");
70 PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------------");
71
72 uint16_t tracepos = 0;
73 uint16_t duration;
74 uint16_t data_len;
75 uint16_t parity_len;
76 bool isResponse;
17cba269 77 uint32_t timestamp;
3bc3598e 78 uint32_t first_timestamp;
79 uint32_t EndOfTransmissionTimestamp;
80
81 for (;;) {
17cba269 82
3bc3598e 83 if(tracepos >= TRACE_SIZE) {
84 break;
85 }
17cba269 86
3bc3598e 87 timestamp = *((uint32_t *)(trace + tracepos));
88 if(tracepos == 0) {
17cba269
MHS
89 first_timestamp = timestamp;
90 }
91
3bc3598e 92 // Break and stick with current result if buffer was not completely full
93 if (timestamp == 0x44444444) break;
94
95 tracepos += 4;
96 duration = *((uint16_t *)(trace + tracepos));
97 tracepos += 2;
98 data_len = *((uint16_t *)(trace + tracepos));
99 tracepos += 2;
100
101 if (data_len & 0x8000) {
102 data_len &= 0x7fff;
103 isResponse = true;
104 } else {
105 isResponse = false;
17cba269
MHS
106 }
107
3bc3598e 108 parity_len = (data_len-1)/8 + 1;
17cba269 109
3bc3598e 110 if (tracepos + data_len + parity_len >= TRACE_SIZE) {
111 break;
17cba269 112 }
3bc3598e 113
114 uint8_t *frame = trace + tracepos;
115 tracepos += data_len;
116 uint8_t *parityBytes = trace + tracepos;
117 tracepos += parity_len;
118
119 char line[16][110];
120 for (int j = 0; j < data_len; j++) {
cee5a30d 121 int oddparity = 0x01;
122 int k;
123
124 for (k=0;k<8;k++) {
125 oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
126 }
127
3bc3598e 128 uint8_t parityBits = parityBytes[j>>3];
129 if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
130 sprintf(line[j/16]+((j%16)*4), "%02x! ", frame[j]);
131 } else {
132 sprintf(line[j/16]+((j%16)*4), "%02x ", frame[j]);
133 }
cee5a30d 134
3bc3598e 135 }
cee5a30d 136
3bc3598e 137 char *crc = "";
138 if (data_len > 2) {
139 uint8_t b1, b2;
140 if(!isResponse && data_len == 4 ) {
cee5a30d 141 // Rough guess that this is a command from the reader
142 // For iClass the command byte is not part of the CRC
3bc3598e 143 ComputeCrc14443(CRC_ICLASS, &frame[1], data_len-3, &b1, &b2);
144 if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
145 crc = "!crc";
146 }
cee5a30d 147 }
148 else {
149 // For other data.. CRC might not be applicable (UPDATE commands etc.)
3bc3598e 150 ComputeCrc14443(CRC_ICLASS, frame, data_len-2, &b1, &b2);
151 if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
152 crc = "!crc";
153 }
154 }
155 }
cee5a30d 156
3bc3598e 157 EndOfTransmissionTimestamp = timestamp + duration;
158
159 int num_lines = (data_len - 1)/16 + 1;
160 for (int j = 0; j < num_lines; j++) {
161 if (j == 0) {
162 PrintAndLog(" %9d | %9d | %s | %-64s| %s",
163 (timestamp - first_timestamp),
164 (EndOfTransmissionTimestamp - first_timestamp),
165 (isResponse ? "Tag" : "Rdr"),
166 line[j],
167 (j == num_lines-1)?crc:"");
168 } else {
169 PrintAndLog(" | | | %-64s| %s",
170 line[j],
171 (j == num_lines-1)?crc:"");
172 }
173 }
174
175 bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
176
177 if (ShowWaitCycles && !isResponse && next_isResponse) {
178 uint32_t next_timestamp = *((uint32_t *)(trace + tracepos));
179 if (next_timestamp != 0x44444444) {
180 PrintAndLog(" %9d | %9d | %s | fdt (Frame Delay Time): %d",
181 (EndOfTransmissionTimestamp - first_timestamp),
182 (next_timestamp - first_timestamp),
183 " ",
184 (next_timestamp - EndOfTransmissionTimestamp));
185 }
186 }
187
188 }
189
cee5a30d 190 return 0;
191}
192
cee5a30d 193int CmdHFiClassSnoop(const char *Cmd)
194{
195 UsbCommand c = {CMD_SNOOP_ICLASS};
196 SendCommand(&c);
197 return 0;
198}
a501c82b 199#define NUM_CSNS 15
1e262141 200int CmdHFiClassSim(const char *Cmd)
201{
202 uint8_t simType = 0;
203 uint8_t CSN[8] = {0, 0, 0, 0, 0, 0, 0, 0};
204
17cba269
MHS
205 if (strlen(Cmd)<1) {
206 PrintAndLog("Usage: hf iclass sim [0 <CSN>] | x");
207 PrintAndLog(" options");
208 PrintAndLog(" 0 <CSN> simulate the given CSN");
209 PrintAndLog(" 1 simulate default CSN");
210 PrintAndLog(" 2 iterate CSNs, gather MACs");
1e262141 211 PrintAndLog(" sample: hf iclass sim 0 031FEC8AF7FF12E0");
17cba269 212 PrintAndLog(" sample: hf iclass sim 2");
1e262141 213 return 0;
214 }
215
216 simType = param_get8(Cmd, 0);
17cba269
MHS
217
218 if(simType == 0)
219 {
220 if (param_gethex(Cmd, 1, CSN, 16)) {
221 PrintAndLog("A CSN should consist of 16 HEX symbols");
222 return 1;
223 }
224 PrintAndLog("--simtype:%02x csn:%s", simType, sprint_hex(CSN, 8));
225
226 }
77abe781 227 if(simType > 2)
17cba269
MHS
228 {
229 PrintAndLog("Undefined simptype %d", simType);
230 return 1;
1e262141 231 }
17cba269 232 uint8_t numberOfCSNs=0;
1e262141 233
9f6e9d15
MHS
234 if(simType == 2)
235 {
a501c82b 236 UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,NUM_CSNS}};
9f6e9d15 237 UsbCommand resp = {0};
17cba269 238
f5ed4d12 239 /*uint8_t csns[8 * NUM_CSNS] = {
240 0x00,0x0B,0x0F,0xFF,0xF7,0xFF,0x12,0xE0 ,
241 0x00,0x13,0x94,0x7e,0x76,0xff,0x12,0xe0 ,
242 0x2a,0x99,0xac,0x79,0xec,0xff,0x12,0xe0 ,
243 0x17,0x12,0x01,0xfd,0xf7,0xff,0x12,0xe0 ,
244 0xcd,0x56,0x01,0x7c,0x6f,0xff,0x12,0xe0 ,
245 0x4b,0x5e,0x0b,0x72,0xef,0xff,0x12,0xe0 ,
246 0x00,0x73,0xd8,0x75,0x58,0xff,0x12,0xe0 ,
247 0x0c,0x90,0x32,0xf3,0x5d,0xff,0x12,0xe0 };
248*/
249
a501c82b 250 uint8_t csns[8*NUM_CSNS] = {
251 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0,
252 0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0,
253 0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0,
254 0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0,
255 0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0,
256 0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0,
257 0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0,
258 0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0,
259 0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0,
260 0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0,
261 0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0,
262 0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0,
263 0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0,
264 0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0,
265 0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 };
266
267 memcpy(c.d.asBytes, csns, 8*NUM_CSNS);
9f6e9d15
MHS
268
269 SendCommand(&c);
270 if (!WaitForResponseTimeout(CMD_ACK, &resp, -1)) {
271 PrintAndLog("Command timed out");
272 return 0;
273 }
1e262141 274
77abe781 275 uint8_t num_mac_responses = resp.arg[1];
a501c82b 276 PrintAndLog("Mac responses: %d MACs obtained (should be %d)", num_mac_responses, NUM_CSNS);
9f6e9d15 277
a501c82b 278 size_t datalen = NUM_CSNS*24;
9f6e9d15
MHS
279 /*
280 * Now, time to dump to file. We'll use this format:
77abe781 281 * <8-byte CSN><8-byte CC><4 byte NR><4 byte MAC>....
9f6e9d15 282 * So, it should wind up as
77abe781
MHS
283 * 8 * 24 bytes.
284 *
285 * The returndata from the pm3 is on the following format
286 * <4 byte NR><4 byte MAC>
287 * CC are all zeroes, CSN is the same as was sent in
9f6e9d15 288 **/
77abe781
MHS
289 void* dump = malloc(datalen);
290 memset(dump,0,datalen);//<-- Need zeroes for the CC-field
9f6e9d15 291 uint8_t i = 0;
a501c82b 292 for(i = 0 ; i < NUM_CSNS ; i++)
9f6e9d15 293 {
77abe781
MHS
294 memcpy(dump+i*24, csns+i*8,8); //CSN
295 //8 zero bytes here...
296 //Then comes NR_MAC (eight bytes from the response)
297 memcpy(dump+i*24+16,resp.d.asBytes+i*8,8);
1e262141 298
9f6e9d15
MHS
299 }
300 /** Now, save to dumpfile **/
77abe781
MHS
301 saveFile("iclass_mac_attack", "bin", dump,datalen);
302 free(dump);
9f6e9d15
MHS
303 }else
304 {
305 UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,numberOfCSNs}};
306 memcpy(c.d.asBytes, CSN, 8);
307 SendCommand(&c);
308 }
f38a1528 309
1e262141 310 return 0;
311}
312
313int CmdHFiClassReader(const char *Cmd)
f38a1528 314{
315 UsbCommand c = {CMD_READER_ICLASS, {0}};
316 SendCommand(&c);
317 UsbCommand resp;
318 while(!ukbhit()){
319 if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
320 uint8_t isOK = resp.arg[0] & 0xff;
321 uint8_t * data = resp.d.asBytes;
322
323 PrintAndLog("isOk:%02x", isOK);
324
325 if(isOK > 0)
326 {
327 PrintAndLog("CSN: %s",sprint_hex(data,8));
328 }
329 if(isOK >= 1)
330 {
331 PrintAndLog("CC: %s",sprint_hex(data+8,8));
332 }else{
333 PrintAndLog("No CC obtained");
334 }
335 } else {
336 PrintAndLog("Command execute timeout");
337 }
338 }
339
340 return 0;
341}
342
343int CmdHFiClassReader_Replay(const char *Cmd)
1e262141 344{
345 uint8_t readerType = 0;
f38a1528 346 uint8_t MAC[4]={0x00, 0x00, 0x00, 0x00};
1e262141 347
348 if (strlen(Cmd)<1) {
f38a1528 349 PrintAndLog("Usage: hf iclass replay <MAC>");
350 PrintAndLog(" sample: hf iclass replay 00112233");
1e262141 351 return 0;
c3963755 352 }
1e262141 353
f38a1528 354 if (param_gethex(Cmd, 0, MAC, 8)) {
355 PrintAndLog("MAC must include 8 HEX symbols");
356 return 1;
357 }
358
359 UsbCommand c = {CMD_READER_ICLASS_REPLAY, {readerType}};
360 memcpy(c.d.asBytes, MAC, 4);
361 SendCommand(&c);
362
363 return 0;
364}
365
366int CmdHFiClassReader_Dump(const char *Cmd)
367{
368 uint8_t readerType = 0;
369 uint8_t MAC[4]={0x00,0x00,0x00,0x00};
370 uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
371 uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
372 uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
373 //uint8_t CC_temp[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
374 uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
375 uint8_t keytable[128] = {0};
376 int elite = 0;
377 uint8_t *used_key;
378 int i;
379 if (strlen(Cmd)<1)
380 {
381 PrintAndLog("Usage: hf iclass dump <Key> [e]");
382 PrintAndLog(" Key - A 16 byte master key");
383 PrintAndLog(" e - If 'e' is specified, the key is interpreted as the 16 byte");
384 PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack");
385 PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format");
386 PrintAndLog(" sample: hf iclass dump 0011223344556677");
387
388
389 return 0;
390 }
391
fecd8202 392 if (param_gethex(Cmd, 0, KEY, 16))
393 {
f38a1528 394 PrintAndLog("KEY must include 16 HEX symbols");
395 return 1;
396 }
9b82de75 397
f38a1528 398 if (param_getchar(Cmd, 1) == 'e')
399 {
400 PrintAndLog("Elite switch on");
401 elite = 1;
402
403 //calc h2
404 hash2(KEY, keytable);
405 printarr_human_readable("keytable", keytable, 128);
406
407 }
408
f5ed4d12 409 UsbCommand resp;
410 uint8_t key_sel[8] = {0};
411 uint8_t key_sel_p[8] = { 0 };
412
413 //HACK -- Below is for testing without access to a tag
414 uint8_t fake_dummy_test = false;
415 if(fake_dummy_test)
416 {
417 uint8_t xdata[16] = {0x01,0x02,0x03,0x04,0xF7,0xFF,0x12,0xE0, //CSN from http://www.proxmark.org/forum/viewtopic.php?pid=11230#p11230
418 0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; // Just a random CC. Would be good to add a real testcase here
419 memcpy(resp.d.asBytes,xdata, 16);
420 resp.arg[0] = 2;
421 }
422
423 //End hack
424
f38a1528 425
426 UsbCommand c = {CMD_READER_ICLASS, {0}};
427 c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE;
f5ed4d12 428 if(!fake_dummy_test)
1e262141 429 SendCommand(&c);
f38a1528 430
f5ed4d12 431
432
433 if (fake_dummy_test || WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
f38a1528 434 uint8_t isOK = resp.arg[0] & 0xff;
435 uint8_t * data = resp.d.asBytes;
436
437 memcpy(CSN,data,8);
438 memcpy(CCNR,data+8,8);
439
440 PrintAndLog("isOk:%02x", isOK);
441
442 if(isOK > 0)
443 {
444 PrintAndLog("CSN: %s",sprint_hex(CSN,8));
445 }
446 if(isOK > 1)
447 {
448 if(elite)
449 {
f38a1528 450 //Get the key index (hash1)
451 uint8_t key_index[8] = {0};
452
453 hash1(CSN, key_index);
454 printvar("hash1", key_index,8);
455 for(i = 0; i < 8 ; i++)
456 key_sel[i] = keytable[key_index[i]] & 0xFF;
f5ed4d12 457 PrintAndLog("Pre-fortified 'permuted' HS key that would be needed by an iclass reader to talk to above CSN:");
f38a1528 458 printvar("k_sel", key_sel,8);
459 //Permute from iclass format to standard format
460 permutekey_rev(key_sel,key_sel_p);
461 used_key = key_sel_p;
462 }else{
463 //Perhaps this should also be permuted to std format?
464 // Something like the code below? I have no std system
465 // to test this with /Martin
466
467 //uint8_t key_sel_p[8] = { 0 };
468 //permutekey_rev(KEY,key_sel_p);
469 //used_key = key_sel_p;
470
471 used_key = KEY;
472
473 }
f5ed4d12 474
475 PrintAndLog("Pre-fortified key that would be needed by the OmniKey reader to talk to above CSN:");
f38a1528 476 printvar("Used key",used_key,8);
477 diversifyKey(CSN,used_key, div_key);
f5ed4d12 478 PrintAndLog("Hash0, a.k.a diversified key, that is computed using Ksel and stored in the card (Block 3):");
f38a1528 479 printvar("Div key", div_key, 8);
480 printvar("CC_NR:",CCNR,12);
481 doMAC(CCNR,12,div_key, MAC);
482 printvar("MAC", MAC, 4);
483
484 UsbCommand d = {CMD_READER_ICLASS_REPLAY, {readerType}};
485 memcpy(d.d.asBytes, MAC, 4);
f5ed4d12 486 if(!fake_dummy_test) SendCommand(&d);
f38a1528 487
488 }else{
489 PrintAndLog("Failed to obtain CC! Aborting");
490 }
491 } else {
492 PrintAndLog("Command execute timeout");
493 }
494
495 return 0;
496}
1e262141 497
f38a1528 498int CmdHFiClass_iso14443A_write(const char *Cmd)
499{
500 uint8_t readerType = 0;
501 uint8_t MAC[4]={0x00,0x00,0x00,0x00};
502 uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
503 uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
504 uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
505 uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
506
507 uint8_t blockNo=0;
508 uint8_t bldata[8]={0};
509
510 if (strlen(Cmd)<3)
511 {
512 PrintAndLog("Usage: hf iclass write <Key> <Block> <Data>");
513 PrintAndLog(" sample: hf iclass write 0011223344556677 10 AAAAAAAAAAAAAAAA");
514 return 0;
515 }
516
517 if (param_gethex(Cmd, 0, KEY, 16))
518 {
519 PrintAndLog("KEY must include 16 HEX symbols");
520 return 1;
521 }
522
523 blockNo = param_get8(Cmd, 1);
524 if (blockNo>32)
525 {
526 PrintAndLog("Error: Maximum number of blocks is 32 for iClass 2K Cards!");
fecd8202 527 return 1;
f38a1528 528 }
529 if (param_gethex(Cmd, 2, bldata, 8))
530 {
531 PrintAndLog("Block data must include 8 HEX symbols");
532 return 1;
533 }
534
535 UsbCommand c = {CMD_ICLASS_ISO14443A_WRITE, {0}};
536 SendCommand(&c);
537 UsbCommand resp;
538
539 if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
540 uint8_t isOK = resp.arg[0] & 0xff;
541 uint8_t * data = resp.d.asBytes;
542
543 memcpy(CSN,data,8);
544 memcpy(CCNR,data+8,8);
545 PrintAndLog("DEBUG: %s",sprint_hex(CSN,8));
546 PrintAndLog("DEBUG: %s",sprint_hex(CCNR,8));
1e262141 547 PrintAndLog("isOk:%02x", isOK);
548 } else {
549 PrintAndLog("Command execute timeout");
f38a1528 550 }
551
552 diversifyKey(CSN,KEY, div_key);
553
554 PrintAndLog("Div Key: %s",sprint_hex(div_key,8));
555 doMAC(CCNR, 12,div_key, MAC);
556
557 UsbCommand c2 = {CMD_ICLASS_ISO14443A_WRITE, {readerType,blockNo}};
558 memcpy(c2.d.asBytes, bldata, 8);
559 memcpy(c2.d.asBytes+8, MAC, 4);
560 SendCommand(&c2);
561
562 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
563 uint8_t isOK = resp.arg[0] & 0xff;
564 uint8_t * data = resp.d.asBytes;
1e262141 565
f38a1528 566 if (isOK)
567 PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4));
568 else
569 PrintAndLog("isOk:%02x", isOK);
570 } else {
571 PrintAndLog("Command execute timeout");
572 }
1e262141 573 return 0;
574}
575
f38a1528 576
cee5a30d 577static command_t CommandTable[] =
578{
579 {"help", CmdHelp, 1, "This help"},
580 {"list", CmdHFiClassList, 0, "List iClass history"},
581 {"snoop", CmdHFiClassSnoop, 0, "Eavesdrop iClass communication"},
1e262141 582 {"sim", CmdHFiClassSim, 0, "Simulate iClass tag"},
fecd8202 583 {"reader",CmdHFiClassReader, 0, "Read an iClass tag"},
584 {"replay",CmdHFiClassReader_Replay, 0, "Read an iClass tag via Reply Attack"},
585 {"dump", CmdHFiClassReader_Dump, 0, "Authenticate and Dump iClass tag"},
586 {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"},
f38a1528 587 {"replay", CmdHFiClassReader_Replay, 0, "Read an iClass tag via Reply Attack"},
588 {"dump", CmdHFiClassReader_Dump, 0, "Authenticate and Dump iClass tag"},
589 {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"},
cee5a30d 590 {NULL, NULL, 0, NULL}
591};
592
593int CmdHFiClass(const char *Cmd)
594{
595 CmdsParse(CommandTable, Cmd);
596 return 0;
597}
598
599int CmdHelp(const char *Cmd)
600{
601 CmdsHelp(CommandTable);
9f6e9d15
MHS
602 return 0;
603}
Impressum, Datenschutz