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