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