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