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