]> git.zerfleddert.de Git - proxmark3-svn/blame - client/cmdhficlass.c
Merge branch 'master' into topaz
[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"
902cb3c0 19#include "proxmark3.h"
cee5a30d 20#include "ui.h"
21#include "cmdparser.h"
22#include "cmdhficlass.h"
23#include "common.h"
14006804 24#include "util.h"
17cba269 25#include "cmdmain.h"
a66fca86
AD
26#include "loclass/des.h"
27#include "loclass/cipherutils.h"
28#include "loclass/cipher.h"
29#include "loclass/ikeys.h"
3ad48540
MHS
30#include "loclass/elite_crack.h"
31#include "loclass/fileutils.h"
1defcf60 32#include "protocols.h"
caaf9618 33#include "usb_cmd.h"
cee5a30d 34
35static int CmdHelp(const char *Cmd);
36
17cba269
MHS
37int xorbits_8(uint8_t val)
38{
53444513
MHS
39 uint8_t res = val ^ (val >> 1); //1st pass
40 res = res ^ (res >> 1); // 2nd pass
41 res = res ^ (res >> 2); // 3rd pass
42 res = res ^ (res >> 4); // 4th pass
43 return res & 1;
17cba269
MHS
44}
45
cee5a30d 46int CmdHFiClassList(const char *Cmd)
17cba269 47{
4c3de57a 48 PrintAndLog("Deprecated command, use 'hf list iclass' instead");
17cba269
MHS
49 return 0;
50}
51
cee5a30d 52int CmdHFiClassSnoop(const char *Cmd)
53{
53444513
MHS
54 UsbCommand c = {CMD_SNOOP_ICLASS};
55 SendCommand(&c);
56 return 0;
cee5a30d 57}
41524d8a
MHS
58int usage_hf_iclass_sim()
59{
60 PrintAndLog("Usage: hf iclass sim <option> [CSN]");
61 PrintAndLog(" options");
62 PrintAndLog(" 0 <CSN> simulate the given CSN");
63 PrintAndLog(" 1 simulate default CSN");
64 PrintAndLog(" 2 Reader-attack, gather reader responses to extract elite key");
65 PrintAndLog(" 3 Full simulation using emulator memory (see 'hf iclass eload')");
66 PrintAndLog(" example: hf iclass sim 0 031FEC8AF7FF12E0");
67 PrintAndLog(" example: hf iclass sim 2");
68 PrintAndLog(" example: hf iclass eload 'tagdump.bin'");
69 PrintAndLog(" hf iclass sim 3");
70 return 0;
71}
72
6116c796 73#define NUM_CSNS 15
1e262141 74int CmdHFiClassSim(const char *Cmd)
75{
53444513
MHS
76 uint8_t simType = 0;
77 uint8_t CSN[8] = {0, 0, 0, 0, 0, 0, 0, 0};
78
79 if (strlen(Cmd)<1) {
1defcf60 80 return usage_hf_iclass_sim();
53444513 81 }
1defcf60 82 simType = param_get8ex(Cmd, 0, 0, 10);
53444513
MHS
83
84 if(simType == 0)
85 {
86 if (param_gethex(Cmd, 1, CSN, 16)) {
87 PrintAndLog("A CSN should consist of 16 HEX symbols");
41524d8a 88 return usage_hf_iclass_sim();
53444513 89 }
53444513 90
41524d8a 91 PrintAndLog("--simtype:%02x csn:%s", simType, sprint_hex(CSN, 8));
53444513 92 }
41524d8a 93 if(simType > 3)
53444513
MHS
94 {
95 PrintAndLog("Undefined simptype %d", simType);
41524d8a 96 return usage_hf_iclass_sim();
53444513 97 }
1e262141 98
41524d8a 99 uint8_t numberOfCSNs=0;
9f6e9d15
MHS
100 if(simType == 2)
101 {
6116c796 102 UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,NUM_CSNS}};
9f6e9d15 103 UsbCommand resp = {0};
17cba269 104
53444513
MHS
105 uint8_t csns[8*NUM_CSNS] = {
106 0x00, 0x0B, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0,
107 0x00, 0x04, 0x0E, 0x08, 0xF7, 0xFF, 0x12, 0xE0,
108 0x00, 0x09, 0x0D, 0x05, 0xF7, 0xFF, 0x12, 0xE0,
109 0x00, 0x0A, 0x0C, 0x06, 0xF7, 0xFF, 0x12, 0xE0,
110 0x00, 0x0F, 0x0B, 0x03, 0xF7, 0xFF, 0x12, 0xE0,
111 0x00, 0x08, 0x0A, 0x0C, 0xF7, 0xFF, 0x12, 0xE0,
112 0x00, 0x0D, 0x09, 0x09, 0xF7, 0xFF, 0x12, 0xE0,
113 0x00, 0x0E, 0x08, 0x0A, 0xF7, 0xFF, 0x12, 0xE0,
114 0x00, 0x03, 0x07, 0x17, 0xF7, 0xFF, 0x12, 0xE0,
115 0x00, 0x3C, 0x06, 0xE0, 0xF7, 0xFF, 0x12, 0xE0,
116 0x00, 0x01, 0x05, 0x1D, 0xF7, 0xFF, 0x12, 0xE0,
117 0x00, 0x02, 0x04, 0x1E, 0xF7, 0xFF, 0x12, 0xE0,
118 0x00, 0x07, 0x03, 0x1B, 0xF7, 0xFF, 0x12, 0xE0,
119 0x00, 0x00, 0x02, 0x24, 0xF7, 0xFF, 0x12, 0xE0,
120 0x00, 0x05, 0x01, 0x21, 0xF7, 0xFF, 0x12, 0xE0 };
6116c796
MHS
121
122 memcpy(c.d.asBytes, csns, 8*NUM_CSNS);
9f6e9d15
MHS
123
124 SendCommand(&c);
125 if (!WaitForResponseTimeout(CMD_ACK, &resp, -1)) {
126 PrintAndLog("Command timed out");
127 return 0;
128 }
1e262141 129
77abe781 130 uint8_t num_mac_responses = resp.arg[1];
6116c796 131 PrintAndLog("Mac responses: %d MACs obtained (should be %d)", num_mac_responses,NUM_CSNS);
9f6e9d15 132
6116c796 133 size_t datalen = NUM_CSNS*24;
9f6e9d15
MHS
134 /*
135 * Now, time to dump to file. We'll use this format:
77abe781 136 * <8-byte CSN><8-byte CC><4 byte NR><4 byte MAC>....
9f6e9d15 137 * So, it should wind up as
77abe781
MHS
138 * 8 * 24 bytes.
139 *
140 * The returndata from the pm3 is on the following format
141 * <4 byte NR><4 byte MAC>
142 * CC are all zeroes, CSN is the same as was sent in
9f6e9d15 143 **/
77abe781
MHS
144 void* dump = malloc(datalen);
145 memset(dump,0,datalen);//<-- Need zeroes for the CC-field
9f6e9d15 146 uint8_t i = 0;
6116c796 147 for(i = 0 ; i < NUM_CSNS ; i++)
9f6e9d15 148 {
77abe781
MHS
149 memcpy(dump+i*24, csns+i*8,8); //CSN
150 //8 zero bytes here...
151 //Then comes NR_MAC (eight bytes from the response)
152 memcpy(dump+i*24+16,resp.d.asBytes+i*8,8);
1e262141 153
9f6e9d15
MHS
154 }
155 /** Now, save to dumpfile **/
77abe781
MHS
156 saveFile("iclass_mac_attack", "bin", dump,datalen);
157 free(dump);
9f6e9d15
MHS
158 }else
159 {
160 UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType,numberOfCSNs}};
161 memcpy(c.d.asBytes, CSN, 8);
162 SendCommand(&c);
163 }
1e262141 164
53444513 165 return 0;
1e262141 166}
167
6ce0e538 168int HFiClassReader(const char *Cmd, bool loop, bool verbose)
1e262141 169{
6ce0e538 170 bool tagFound = false;
caaf9618
MHS
171 UsbCommand c = {CMD_READER_ICLASS, {FLAG_ICLASS_READER_CSN|
172 FLAG_ICLASS_READER_CONF|FLAG_ICLASS_READER_AA}};
6ce0e538 173 if (!loop) c.arg[0] |= FLAG_ICLASS_READER_ONLY_ONCE | FLAG_ICLASS_READER_ONE_TRY;
53444513
MHS
174 SendCommand(&c);
175 UsbCommand resp;
176 while(!ukbhit()){
6ce0e538 177 if (WaitForResponseTimeout(CMD_ACK,&resp, 4500)) {
178 uint8_t readStatus = resp.arg[0] & 0xff;
179 uint8_t *data = resp.d.asBytes;
53444513 180
6ce0e538 181 if (verbose)
182 PrintAndLog("Readstatus:%02x", readStatus);
caaf9618 183 if( readStatus == 0){
53444513 184 //Aborted
6ce0e538 185 if (verbose) PrintAndLog("Quitting...");
53444513
MHS
186 return 0;
187 }
6ce0e538 188 if( readStatus & FLAG_ICLASS_READER_CSN){
189 PrintAndLog("CSN: %s",sprint_hex(data,8));
190 tagFound = true;
191 }
caaf9618
MHS
192 if( readStatus & FLAG_ICLASS_READER_CC) PrintAndLog("CC: %s",sprint_hex(data+16,8));
193 if( readStatus & FLAG_ICLASS_READER_CONF){
194 printIclassDumpInfo(data);
53444513 195 }
6ce0e538 196 if (tagFound && !loop) return 1;
53444513 197 } else {
6ce0e538 198 if (verbose) PrintAndLog("Command execute timeout");
53444513 199 }
6ce0e538 200 if (!loop) break;
53444513 201 }
53444513 202 return 0;
6ce0e538 203
204}
205
206int CmdHFiClassReader(const char *Cmd)
207{
208 return HFiClassReader(Cmd, true, true);
c3963755 209}
210
211int CmdHFiClassReader_Replay(const char *Cmd)
212{
53444513
MHS
213 uint8_t readerType = 0;
214 uint8_t MAC[4]={0x00, 0x00, 0x00, 0x00};
c3963755 215
53444513
MHS
216 if (strlen(Cmd)<1) {
217 PrintAndLog("Usage: hf iclass replay <MAC>");
218 PrintAndLog(" sample: hf iclass replay 00112233");
219 return 0;
220 }
c3963755 221
53444513
MHS
222 if (param_gethex(Cmd, 0, MAC, 8)) {
223 PrintAndLog("MAC must include 8 HEX symbols");
224 return 1;
225 }
c3963755 226
53444513
MHS
227 UsbCommand c = {CMD_READER_ICLASS_REPLAY, {readerType}};
228 memcpy(c.d.asBytes, MAC, 4);
229 SendCommand(&c);
1e262141 230
53444513 231 return 0;
1e262141 232}
233
a66fca86
AD
234int CmdHFiClassReader_Dump(const char *Cmd)
235{
53444513
MHS
236 uint8_t readerType = 0;
237 uint8_t MAC[4]={0x00,0x00,0x00,0x00};
238 uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
239 uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
240 uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
241 //uint8_t CC_temp[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
242 uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
243 uint8_t keytable[128] = {0};
244 int elite = 0;
245 uint8_t *used_key;
246 int i;
247 if (strlen(Cmd)<1)
248 {
249 PrintAndLog("Usage: hf iclass dump <Key> [e]");
250 PrintAndLog(" Key - A 16 byte master key");
251 PrintAndLog(" e - If 'e' is specified, the key is interpreted as the 16 byte");
252 PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack");
253 PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format");
254 PrintAndLog(" sample: hf iclass dump 0011223344556677");
255
256
257 return 0;
258 }
259
260 if (param_gethex(Cmd, 0, KEY, 16))
261 {
262 PrintAndLog("KEY must include 16 HEX symbols");
263 return 1;
264 }
265
266 if (param_getchar(Cmd, 1) == 'e')
267 {
268 PrintAndLog("Elite switch on");
269 elite = 1;
270
271 //calc h2
272 hash2(KEY, keytable);
273 printarr_human_readable("keytable", keytable, 128);
274
275 }
276
277 UsbCommand resp;
278 uint8_t key_sel[8] = {0};
279 uint8_t key_sel_p[8] = { 0 };
280
281 UsbCommand c = {CMD_READER_ICLASS, {0}};
caaf9618 282 c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_CC;
53444513
MHS
283 SendCommand(&c);
284
285
286
287 if (!WaitForResponseTimeout(CMD_ACK,&resp,4500))
288 {
289 PrintAndLog("Command execute timeout");
290 return 0;
291 }
26c0d833 292
cb29e00a
MHS
293 uint8_t isOK = resp.arg[0] & 0xff;
294 uint8_t * data = resp.d.asBytes;
3ad48540 295
cb29e00a 296 memcpy(CSN,data,8);
caaf9618 297 memcpy(CCNR,data+16,8);
a66fca86 298
cb29e00a 299 PrintAndLog("isOk:%02x", isOK);
9e28ee9f 300
cb29e00a
MHS
301 if(isOK > 0)
302 {
303 PrintAndLog("CSN: %s",sprint_hex(CSN,8));
304 }
305 if(isOK <= 1){
306 PrintAndLog("Failed to obtain CC! Aborting");
307 return 0;
308 }
309 //Status 2 or higher
9e28ee9f 310
cb29e00a
MHS
311 if(elite)
312 {
313 //Get the key index (hash1)
314 uint8_t key_index[8] = {0};
315
316 hash1(CSN, key_index);
317 printvar("hash1", key_index,8);
318 for(i = 0; i < 8 ; i++)
319 key_sel[i] = keytable[key_index[i]] & 0xFF;
320 PrintAndLog("Pre-fortified 'permuted' HS key that would be needed by an iclass reader to talk to above CSN:");
321 printvar("k_sel", key_sel,8);
322 //Permute from iclass format to standard format
323 permutekey_rev(key_sel,key_sel_p);
324 used_key = key_sel_p;
325 }else{
326 used_key = KEY;
327 }
9b82de75 328
cb29e00a
MHS
329 PrintAndLog("Pre-fortified key that would be needed by the OmniKey reader to talk to above CSN:");
330 printvar("Used key",used_key,8);
331 diversifyKey(CSN,used_key, div_key);
332 PrintAndLog("Hash0, a.k.a diversified key, that is computed using Ksel and stored in the card (Block 3):");
333 printvar("Div key", div_key, 8);
334 printvar("CC_NR:",CCNR,12);
1defcf60 335 doMAC(CCNR,div_key, MAC);
cb29e00a
MHS
336 printvar("MAC", MAC, 4);
337
338 uint8_t iclass_data[32000] = {0};
428d6221
MHS
339 uint32_t iclass_datalen = 0;
340 uint32_t iclass_blocksFailed = 0;//Set to 1 if dump was incomplete
cb29e00a
MHS
341
342 UsbCommand d = {CMD_READER_ICLASS_REPLAY, {readerType}};
343 memcpy(d.d.asBytes, MAC, 4);
344 clearCommandBuffer();
345 SendCommand(&d);
346 PrintAndLog("Waiting for device to dump data. Press button on device and key on keyboard to abort...");
347 while (true) {
348 printf(".");
349 if (ukbhit()) {
350 getchar();
351 printf("\naborted via keyboard!\n");
352 break;
353 }
354 if(WaitForResponseTimeout(CMD_ACK,&resp,4500))
355 {
428d6221 356 uint32_t dataLength = resp.arg[0];
cb29e00a 357 iclass_blocksFailed |= resp.arg[1];
cb29e00a
MHS
358 if(dataLength > 0)
359 {
428d6221 360 PrintAndLog("Got %d bytes data (total so far %d)" ,dataLength,iclass_datalen);
0e6c7336 361 memcpy(iclass_data+iclass_datalen, resp.d.asBytes,dataLength);
cb29e00a
MHS
362 iclass_datalen += dataLength;
363 }else
364 {//Last transfer, datalength 0 means the dump is finished
365 PrintAndLog("Dumped %d bytes of data from tag. ", iclass_datalen);
366 if(iclass_blocksFailed)
367 {
368 PrintAndLog("OBS! Some blocks failed to be dumped correctly!");
369 }
370 if(iclass_datalen > 0)
371 {
372 char filename[100] = {0};
373 //create a preferred filename
374 snprintf(filename, 100,"iclass_tagdump-%02x%02x%02x%02x%02x%02x%02x%02x",
375 CSN[0],CSN[1],CSN[2],CSN[3],
53444513 376 CSN[4],CSN[5],CSN[6],CSN[7]);
b67f7ec3
MHS
377 //Place the div_key in block 3
378 memcpy(iclass_data+(3*8), div_key, 8);
cb29e00a 379 saveFile(filename,"bin",iclass_data, iclass_datalen );
cb29e00a
MHS
380 }
381 //Aaaand we're finished
382 return 0;
383 }
384 }
385 }
0eea34a2 386
1e262141 387
53444513 388 return 0;
1e262141 389}
390
7781a656
MHS
391int hf_iclass_eload_usage()
392{
393 PrintAndLog("Loads iclass tag-dump into emulator memory on device");
394 PrintAndLog("Usage: hf iclass eload f <filename>");
395 PrintAndLog("");
396 PrintAndLog("Example: hf iclass eload f iclass_tagdump-aa162d30f8ff12f1.bin");
397 return 0;
398
399}
400
401int iclassEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
402 UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNum, blocksCount, 0}};
403 memcpy(c.d.asBytes, data, blocksCount * 16);
404 SendCommand(&c);
405 return 0;
406}
407int CmdHFiClassELoad(const char *Cmd)
408{
409
410 char opt = param_getchar(Cmd, 0);
411 if (strlen(Cmd)<1 || opt == 'h')
412 return hf_iclass_eload_usage();
413
414 //File handling and reading
415 FILE *f;
416 char filename[FILE_PATH_SIZE];
417 if(opt == 'f' && param_getstr(Cmd, 1, filename) > 0)
418 {
419 f = fopen(filename, "rb");
420 }else{
421 return hf_iclass_eload_usage();
422 }
423
424 if(!f) {
425 PrintAndLog("Failed to read from file '%s'", filename);
426 return 1;
427 }
428
429 fseek(f, 0, SEEK_END);
430 long fsize = ftell(f);
431 fseek(f, 0, SEEK_SET);
432
433 uint8_t *dump = malloc(fsize);
1defcf60
MHS
434
435
7781a656
MHS
436 size_t bytes_read = fread(dump, 1, fsize, f);
437 fclose(f);
438
1defcf60 439 printIclassDumpInfo(dump);
7781a656
MHS
440 //Validate
441
442 if (bytes_read < fsize)
443 {
444 prnlog("Error, could only read %d bytes (should be %d)",bytes_read, fsize );
445 free(dump);
446 return 1;
447 }
448 //Send to device
449 uint32_t bytes_sent = 0;
450 uint32_t bytes_remaining = bytes_read;
451
452 while(bytes_remaining > 0){
453 uint32_t bytes_in_packet = MIN(USB_CMD_DATA_SIZE, bytes_remaining);
454 UsbCommand c = {CMD_ICLASS_EML_MEMSET, {bytes_sent,bytes_in_packet,0}};
455 memcpy(c.d.asBytes, dump, bytes_in_packet);
456 SendCommand(&c);
457 bytes_remaining -= bytes_in_packet;
458 bytes_sent += bytes_in_packet;
459 }
460 free(dump);
461 PrintAndLog("Sent %d bytes of data to device emulator memory", bytes_sent);
462 return 0;
463}
464
41524d8a
MHS
465int usage_hf_iclass_decrypt()
466{
467 PrintAndLog("Usage: hf iclass decrypt f <tagdump> o ");
468 PrintAndLog("");
9a9bcea8 469 PrintAndLog("OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside");
41524d8a 470 PrintAndLog("in the working directory. The file should be 16 bytes binary data");
9a9bcea8 471 PrintAndLog("");
1defcf60 472 PrintAndLog("example: hf iclass decrypt f tagdump_12312342343.bin");
41524d8a 473 PrintAndLog("");
9a9bcea8 474 PrintAndLog("OBS! This is pretty stupid implementation, it tries to decrypt every block after block 6. ");
41524d8a
MHS
475 PrintAndLog("Correct behaviour would be to decrypt only the application areas where the key is valid,");
476 PrintAndLog("which is defined by the configuration block.");
477 return 1;
478}
479
480int readKeyfile(const char *filename, size_t len, uint8_t* buffer)
481{
482 FILE *f = fopen(filename, "rb");
483 if(!f) {
484 PrintAndLog("Failed to read from file '%s'", filename);
485 return 1;
486 }
487 fseek(f, 0, SEEK_END);
488 long fsize = ftell(f);
489 fseek(f, 0, SEEK_SET);
490 size_t bytes_read = fread(buffer, 1, len, f);
491 fclose(f);
492 if(fsize != len)
493 {
494 PrintAndLog("Warning, file size is %d, expected %d", fsize, len);
495 return 1;
496 }
497 if(bytes_read != len)
498 {
499 PrintAndLog("Warning, could only read %d bytes, expected %d" ,bytes_read, len);
500 return 1;
501 }
502 return 0;
503}
504
505int CmdHFiClassDecrypt(const char *Cmd)
506{
507 uint8_t key[16] = { 0 };
508 if(readKeyfile("iclass_decryptionkey.bin", 16, key))
509 {
510 usage_hf_iclass_decrypt();
511 return 1;
512 }
513 PrintAndLog("Decryption file found... ");
514 char opt = param_getchar(Cmd, 0);
515 if (strlen(Cmd)<1 || opt == 'h')
516 return usage_hf_iclass_decrypt();
517
518 //Open the tagdump-file
519 FILE *f;
520 char filename[FILE_PATH_SIZE];
521 if(opt == 'f' && param_getstr(Cmd, 1, filename) > 0)
522 {
523 f = fopen(filename, "rb");
524 }else{
525 return usage_hf_iclass_decrypt();
526 }
527
528 fseek(f, 0, SEEK_END);
529 long fsize = ftell(f);
530 fseek(f, 0, SEEK_SET);
531 uint8_t enc_dump[8] = {0};
532 uint8_t *decrypted = malloc(fsize);
533 des3_context ctx = { DES_DECRYPT ,{ 0 } };
534 des3_set2key_dec( &ctx, key);
535 size_t bytes_read = fread(enc_dump, 1, 8, f);
536
537 //Use the first block (CSN) for filename
538 char outfilename[FILE_PATH_SIZE] = { 0 };
539 snprintf(outfilename,FILE_PATH_SIZE,"iclass_tagdump-%02x%02x%02x%02x%02x%02x%02x%02x-decrypted",
540 enc_dump[0],enc_dump[1],enc_dump[2],enc_dump[3],
541 enc_dump[4],enc_dump[5],enc_dump[6],enc_dump[7]);
542
543 size_t blocknum =0;
544 while(bytes_read == 8)
545 {
9a9bcea8 546 if(blocknum < 7)
41524d8a
MHS
547 {
548 memcpy(decrypted+(blocknum*8), enc_dump, 8);
549 }else{
550 des3_crypt_ecb(&ctx, enc_dump,decrypted +(blocknum*8) );
551 }
552 printvar("decrypted block", decrypted +(blocknum*8), 8);
553 bytes_read = fread(enc_dump, 1, 8, f);
554 blocknum++;
555 }
556 fclose(f);
557
558 saveFile(outfilename,"bin", decrypted, blocknum*8);
559
560 return 0;
561}
7781a656 562
fecd8202 563int CmdHFiClass_iso14443A_write(const char *Cmd)
564{
53444513
MHS
565 uint8_t readerType = 0;
566 uint8_t MAC[4]={0x00,0x00,0x00,0x00};
567 uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
568 uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
569 uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
570 uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
571
572 uint8_t blockNo=0;
573 uint8_t bldata[8]={0};
574
575 if (strlen(Cmd)<3)
576 {
577 PrintAndLog("Usage: hf iclass write <Key> <Block> <Data>");
578 PrintAndLog(" sample: hf iclass write 0011223344556677 10 AAAAAAAAAAAAAAAA");
579 return 0;
580 }
581
582 if (param_gethex(Cmd, 0, KEY, 16))
583 {
584 PrintAndLog("KEY must include 16 HEX symbols");
585 return 1;
586 }
587
588 blockNo = param_get8(Cmd, 1);
589 if (blockNo>32)
590 {
591 PrintAndLog("Error: Maximum number of blocks is 32 for iClass 2K Cards!");
592 return 1;
593 }
594 if (param_gethex(Cmd, 2, bldata, 8))
595 {
596 PrintAndLog("Block data must include 8 HEX symbols");
597 return 1;
598 }
599
600 UsbCommand c = {CMD_ICLASS_ISO14443A_WRITE, {0}};
601 SendCommand(&c);
602 UsbCommand resp;
603
604 if (WaitForResponseTimeout(CMD_ACK,&resp,4500)) {
605 uint8_t isOK = resp.arg[0] & 0xff;
606 uint8_t * data = resp.d.asBytes;
607
608 memcpy(CSN,data,8);
609 memcpy(CCNR,data+8,8);
610 PrintAndLog("DEBUG: %s",sprint_hex(CSN,8));
611 PrintAndLog("DEBUG: %s",sprint_hex(CCNR,8));
612 PrintAndLog("isOk:%02x", isOK);
613 } else {
614 PrintAndLog("Command execute timeout");
615 }
616
617 diversifyKey(CSN,KEY, div_key);
618
619 PrintAndLog("Div Key: %s",sprint_hex(div_key,8));
1defcf60 620 doMAC(CCNR, div_key, MAC);
53444513
MHS
621
622 UsbCommand c2 = {CMD_ICLASS_ISO14443A_WRITE, {readerType,blockNo}};
623 memcpy(c2.d.asBytes, bldata, 8);
624 memcpy(c2.d.asBytes+8, MAC, 4);
625 SendCommand(&c2);
626
627 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
628 uint8_t isOK = resp.arg[0] & 0xff;
629 uint8_t * data = resp.d.asBytes;
630
631 if (isOK)
632 PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4));
633 else
634 PrintAndLog("isOk:%02x", isOK);
635 } else {
636 PrintAndLog("Command execute timeout");
637 }
638 return 0;
a66fca86 639}
6f101995
MHS
640int CmdHFiClass_loclass(const char *Cmd)
641{
642 char opt = param_getchar(Cmd, 0);
643
644 if (strlen(Cmd)<1 || opt == 'h') {
645 PrintAndLog("Usage: hf iclass loclass [options]");
646 PrintAndLog("Options:");
647 PrintAndLog("h Show this help");
648 PrintAndLog("t Perform self-test");
649 PrintAndLog("f <filename> Bruteforce iclass dumpfile");
650 PrintAndLog(" An iclass dumpfile is assumed to consist of an arbitrary number of");
651 PrintAndLog(" malicious CSNs, and their protocol responses");
652 PrintAndLog(" The the binary format of the file is expected to be as follows: ");
653 PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
654 PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
655 PrintAndLog(" <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
656 PrintAndLog(" ... totalling N*24 bytes");
657 return 0;
658 }
659 char fileName[255] = {0};
660 if(opt == 'f')
661 {
53444513
MHS
662 if(param_getstr(Cmd, 1, fileName) > 0)
663 {
664 return bruteforceFileNoKeys(fileName);
665 }else
666 {
667 PrintAndLog("You must specify a filename");
668 }
6f101995
MHS
669 }
670 else if(opt == 't')
671 {
672 int errors = testCipherUtils();
673 errors += testMAC();
674 errors += doKeyTests(0);
675 errors += testElite();
676 if(errors)
677 {
678 prnlog("OBS! There were errors!!!");
679 }
680 return errors;
681 }
a66fca86 682
6f101995
MHS
683 return 0;
684}
c3963755 685
cee5a30d 686static command_t CommandTable[] =
687{
6f101995
MHS
688 {"help", CmdHelp, 1, "This help"},
689 {"list", CmdHFiClassList, 0, "[Deprecated] List iClass history"},
690 {"snoop", CmdHFiClassSnoop, 0, "Eavesdrop iClass communication"},
691 {"sim", CmdHFiClassSim, 0, "Simulate iClass tag"},
692 {"reader",CmdHFiClassReader, 0, "Read an iClass tag"},
693 {"replay",CmdHFiClassReader_Replay, 0, "Read an iClass tag via Reply Attack"},
694 {"dump", CmdHFiClassReader_Dump, 0, "Authenticate and Dump iClass tag"},
a4749080 695// {"write", CmdHFiClass_iso14443A_write, 0, "Authenticate and Write iClass block"},
6f101995 696 {"loclass", CmdHFiClass_loclass, 1, "Use loclass to perform bruteforce of reader attack dump"},
7781a656 697 {"eload", CmdHFiClassELoad, 0, "[experimental] Load data into iclass emulator memory"},
41524d8a 698 {"decrypt", CmdHFiClassDecrypt, 1, "Decrypt tagdump" },
6f101995 699 {NULL, NULL, 0, NULL}
cee5a30d 700};
701
702int CmdHFiClass(const char *Cmd)
703{
53444513
MHS
704 CmdsParse(CommandTable, Cmd);
705 return 0;
cee5a30d 706}
707
708int CmdHelp(const char *Cmd)
709{
53444513
MHS
710 CmdsHelp(CommandTable);
711 return 0;
cee5a30d 712}
Impressum, Datenschutz