]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhfmfdes.c
NEW: HF MFU SETPWD - set password to a Ultralight C tag.
[proxmark3-svn] / client / cmdhfmfdes.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2014 Iceman
3 //
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
6 // the license.
7 //-----------------------------------------------------------------------------
8 // High frequency MIFARE Desfire commands
9 //-----------------------------------------------------------------------------
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <ctype.h>
15 //#include <openssl/des.h>
16 #include "loclass/des.h"
17 #include "cmdmain.h"
18 #include "proxmark3.h"
19 #include "../include/common.h"
20 #include "../include/mifare.h"
21 #include "../common/iso14443crc.h"
22 #include "data.h"
23 #include "ui.h"
24 #include "cmdparser.h"
25 #include "util.h"
26 #include "cmdhfmfdes.h"
27
28 uint8_t CMDPOS = 0;
29 uint8_t LENPOS = 1;
30
31 uint8_t key_zero_data[16] = { 0x00 };
32 uint8_t key_ones_data[16] = { 0x01 };
33 uint8_t key_defa_data[16] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
34 uint8_t key_picc_data[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f };
35
36 static int CmdHelp(const char *Cmd);
37 static void xor(unsigned char * dst, unsigned char * src, size_t len);
38 static int32_t le24toh (uint8_t data[3]);
39
40
41 int CmdHF14ADesWb(const char *Cmd)
42 {
43 /* uint8_t blockNo = 0;
44 uint8_t keyType = 0;
45 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
46 uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
47
48 char cmdp = 0x00;
49
50 if (strlen(Cmd)<3) {
51 PrintAndLog("Usage: hf mf wrbl <block number> <key A/B> <key (12 hex symbols)> <block data (32 hex symbols)>");
52 PrintAndLog(" sample: hf mf wrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F");
53 return 0;
54 }
55
56 blockNo = param_get8(Cmd, 0);
57 cmdp = param_getchar(Cmd, 1);
58 if (cmdp == 0x00) {
59 PrintAndLog("Key type must be A or B");
60 return 1;
61 }
62 if (cmdp != 'A' && cmdp != 'a') keyType = 1;
63 if (param_gethex(Cmd, 2, key, 12)) {
64 PrintAndLog("Key must include 12 HEX symbols");
65 return 1;
66 }
67 if (param_gethex(Cmd, 3, bldata, 32)) {
68 PrintAndLog("Block data must include 32 HEX symbols");
69 return 1;
70 }
71 PrintAndLog("--block no:%02x key type:%02x key:%s", blockNo, keyType, sprint_hex(key, 6));
72 PrintAndLog("--data: %s", sprint_hex(bldata, 16));
73
74 UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}};
75 memcpy(c.d.asBytes, key, 6);
76 memcpy(c.d.asBytes + 10, bldata, 16);
77 SendCommand(&c);
78
79 UsbCommand resp;
80 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
81 uint8_t isOK = resp.arg[0] & 0xff;
82 PrintAndLog("isOk:%02x", isOK);
83 } else {
84 PrintAndLog("Command execute timeout");
85 }
86 */
87 return 0;
88 }
89
90 int CmdHF14ADesRb(const char *Cmd)
91 {
92 // uint8_t blockNo = 0;
93 // uint8_t keyType = 0;
94 // uint8_t key[6] = {0, 0, 0, 0, 0, 0};
95
96 // char cmdp = 0x00;
97
98
99 // if (strlen(Cmd)<3) {
100 // PrintAndLog("Usage: hf mf rdbl <block number> <key A/B> <key (12 hex symbols)>");
101 // PrintAndLog(" sample: hf mf rdbl 0 A FFFFFFFFFFFF ");
102 // return 0;
103 // }
104
105 // blockNo = param_get8(Cmd, 0);
106 // cmdp = param_getchar(Cmd, 1);
107 // if (cmdp == 0x00) {
108 // PrintAndLog("Key type must be A or B");
109 // return 1;
110 // }
111 // if (cmdp != 'A' && cmdp != 'a') keyType = 1;
112 // if (param_gethex(Cmd, 2, key, 12)) {
113 // PrintAndLog("Key must include 12 HEX symbols");
114 // return 1;
115 // }
116 // PrintAndLog("--block no:%02x key type:%02x key:%s ", blockNo, keyType, sprint_hex(key, 6));
117
118 // UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};
119 // memcpy(c.d.asBytes, key, 6);
120 // SendCommand(&c);
121
122 // UsbCommand resp;
123 // if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
124 // uint8_t isOK = resp.arg[0] & 0xff;
125 // uint8_t * data = resp.d.asBytes;
126
127 // if (isOK)
128 // PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 16));
129 // else
130 // PrintAndLog("isOk:%02x", isOK);
131 // } else {
132 // PrintAndLog("Command execute timeout");
133 // }
134
135 return 0;
136 }
137
138 int CmdHF14ADesInfo(const char *Cmd){
139
140 UsbCommand c = {CMD_MIFARE_DESFIRE_INFO};
141 SendCommand(&c);
142 UsbCommand resp;
143
144 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
145 PrintAndLog("Command execute timeout");
146 return 0;
147 }
148 uint8_t isOK = resp.arg[0] & 0xff;
149 if ( !isOK ){
150 PrintAndLog("Command unsuccessful");
151 return 0;
152 }
153 PrintAndLog("");
154 PrintAndLog("-- Desfire Information --------------------------------------");
155 PrintAndLog("-------------------------------------------------------------");
156 PrintAndLog(" UID : %s",sprint_hex(resp.d.asBytes, 7));
157 PrintAndLog(" Batch number : %s",sprint_hex(resp.d.asBytes+28,5));
158 PrintAndLog(" Production date : week %02x, 20%02x",resp.d.asBytes[33], resp.d.asBytes[34]);
159 PrintAndLog(" -----------------------------------------------------------");
160 PrintAndLog(" Hardware Information");
161 PrintAndLog(" Vendor Id : %s", GetVendorStr(resp.d.asBytes[7]));
162 PrintAndLog(" Type : 0x%02X",resp.d.asBytes[8]);
163 PrintAndLog(" Subtype : 0x%02X",resp.d.asBytes[9]);
164 PrintAndLog(" Version : %d.%d",resp.d.asBytes[10], resp.d.asBytes[11]);
165 PrintAndLog(" Storage size : %s",GetCardSizeStr(resp.d.asBytes[12]));
166 PrintAndLog(" Protocol : %s",GetProtocolStr(resp.d.asBytes[13]));
167 PrintAndLog(" -----------------------------------------------------------");
168 PrintAndLog(" Software Information");
169 PrintAndLog(" Vendor Id : %s",GetVendorStr(resp.d.asBytes[14]));
170 PrintAndLog(" Type : 0x%02X",resp.d.asBytes[15]);
171 PrintAndLog(" Subtype : 0x%02X",resp.d.asBytes[16]);
172 PrintAndLog(" Version : %d.%d",resp.d.asBytes[17], resp.d.asBytes[18]);
173 PrintAndLog(" storage size : %s", GetCardSizeStr(resp.d.asBytes[19]));
174 PrintAndLog(" Protocol : %s", GetProtocolStr(resp.d.asBytes[20]));
175 PrintAndLog("-------------------------------------------------------------");
176
177 // Master Key settings
178 GetKeySettings(NULL);
179
180 // Free memory on card
181 c.cmd = CMD_MIFARE_DESFIRE;
182 c.arg[0] = (INIT | DISCONNECT);
183 c.arg[1] = 0x01;
184 c.d.asBytes[0] = GET_FREE_MEMORY;
185 SendCommand(&c);
186 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
187 return 0;
188 }
189
190 uint8_t tmp[3];
191 memcpy(tmp, resp.d.asBytes+3,3);
192
193 PrintAndLog(" Available free memory on card : %d bytes", le24toh( tmp ));
194 PrintAndLog("-------------------------------------------------------------");
195
196 /*
197 Card Master key (CMK) 0x00 AID = 00 00 00 (card level)
198 Application Master Key (AMK) 0x00 AID != 00 00 00
199 Application keys (APK) 0x01-0x0D
200 Application free 0x0E
201 Application never 0x0F
202
203 ACCESS RIGHTS:
204 keys 0,1,2,3 C
205 keys 4,5,6,7 RW
206 keys 8,9,10,11 W
207 keys 12,13,14,15 R
208
209 */
210
211 return 1;
212 }
213
214 char * GetVendorStr( uint8_t id){
215 static char buf[30];
216 char *retStr = buf;
217
218 if ( id == 0x04 )
219 sprintf(retStr, "0x%02X (NXP)",id);
220 else
221 sprintf(retStr,"0x%02X (Unknown)",id);
222 return buf;
223 }
224
225 /*
226 The 7 MSBits (= n) code the storage size itself based on 2^n,
227 the LSBit is set to '0' if the size is exactly 2^n
228 and set to '1' if the storage size is between 2^n and 2^(n+1).
229 For this version of DESFire the 7 MSBits are set to 0x0C (2^12 = 4096) and the LSBit is '0'.
230 */
231 char * GetCardSizeStr( uint8_t fsize ){
232
233 static char buf[30];
234 char *retStr = buf;
235
236 uint16_t usize = 1 << ((fsize >>1) + 1);
237 uint16_t lsize = 1 << (fsize >>1);
238
239 // is LSB set?
240 if ( fsize & 1 )
241 sprintf(retStr, "0x%02X (%d - %d bytes)",fsize, usize, lsize);
242 else
243 sprintf(retStr, "0x%02X (%d bytes)", fsize, lsize);
244 return buf;
245 }
246
247 char * GetProtocolStr(uint8_t id){
248
249 static char buf[30];
250 char *retStr = buf;
251
252 if ( id == 0x05)
253 sprintf(retStr,"0x%02X (ISO 14443-3, 14443-4)", id);
254 else
255 sprintf(retStr,"0x%02X (Unknown)", id);
256 return buf;
257 }
258
259 void GetKeySettings( uint8_t *aid){
260
261 char messStr[512] = {0x00};
262 char *str = messStr;
263 uint8_t isOK = 0;
264 uint32_t options = NONE;
265 UsbCommand c;
266 UsbCommand resp;
267
268 //memset(messStr, 0x00, 512);
269
270 c.cmd = CMD_MIFARE_DESFIRE;
271
272 if ( aid == NULL ){
273 PrintAndLog(" CMK - PICC, Card Master Key settings ");
274 PrintAndLog("");
275 c.arg[CMDPOS] = (INIT | DISCONNECT);
276 c.arg[LENPOS] = 0x01;
277 c.d.asBytes[0] = GET_KEY_SETTINGS; // 0x45
278 SendCommand(&c);
279 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;}
280 isOK = resp.arg[0] & 0xff;
281 if ( !isOK ){
282 PrintAndLog(" Can't select master application");
283 return;
284 }
285
286 str = (resp.d.asBytes[3] & (1 << 3 )) ? "YES":"NO";
287 PrintAndLog(" [0x08] Configuration changeable : %s", str);
288 str = (resp.d.asBytes[3] & (1 << 2 )) ? "NO":"YES";
289 PrintAndLog(" [0x04] CMK required for create/delete : %s",str);
290 str = (resp.d.asBytes[3] & (1 << 1 )) ? "NO":"YES";
291 PrintAndLog(" [0x02] Directory list access with CMK : %s",str);
292 str = (resp.d.asBytes[3] & (1 << 0 )) ? "YES" : "NO";
293 PrintAndLog(" [0x01] CMK is changeable : %s", str);
294
295 c.arg[LENPOS] = 0x02; //LEN
296 c.d.asBytes[0] = GET_KEY_VERSION; //0x64
297 c.d.asBytes[1] = 0x00;
298 SendCommand(&c);
299 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {
300 return;
301 }
302 isOK = resp.arg[0] & 0xff;
303 if ( !isOK ){
304 PrintAndLog(" Can't read key-version");
305 return;
306 }
307 PrintAndLog("");
308 PrintAndLog(" Max number of keys : %d", resp.d.asBytes[4]);
309 PrintAndLog(" Master key Version : %d (0x%02x)", resp.d.asBytes[3], resp.d.asBytes[3]);
310 PrintAndLog(" ----------------------------------------------------------");
311
312 c.arg[LENPOS] = 0x02; //LEN
313 c.d.asBytes[0] = AUTHENTICATE; //0x0A
314 c.d.asBytes[1] = 0x00; // KEY 0
315 SendCommand(&c);
316 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;}
317 isOK = resp.d.asBytes[2] & 0xff;
318 PrintAndLog(" [0x0A] Authenticate : %s", ( isOK==0xAE ) ? "NO":"YES");
319
320 c.d.asBytes[0] = AUTHENTICATE_ISO; //0x1A
321 SendCommand(&c);
322 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;}
323 isOK = resp.d.asBytes[2] & 0xff;
324 PrintAndLog(" [0x1A] Authenticate ISO : %s", ( isOK==0xAE ) ? "NO":"YES");
325
326 c.d.asBytes[0] = AUTHENTICATE_AES; //0xAA
327 SendCommand(&c);
328 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;}
329 isOK = resp.d.asBytes[2] & 0xff;
330 PrintAndLog(" [0xAA] Authenticate AES : %s", ( isOK==0xAE ) ? "NO":"YES");
331 PrintAndLog("");
332 PrintAndLog(" ----------------------------------------------------------");
333
334 } else {
335 PrintAndLog(" AMK - Application Master Key settings");
336
337 // SELECT AID
338 c.arg[0] = (INIT | CLEARTRACE);
339 c.arg[LENPOS] = 0x04;
340 c.d.asBytes[0] = SELECT_APPLICATION; // 0x5a
341 memcpy(c.d.asBytes+1, aid, 3);
342 SendCommand(&c);
343
344 if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
345 PrintAndLog(" Timed-out");
346 return;
347 }
348 isOK = resp.arg[0] & 0xff;
349 if ( !isOK ){
350 PrintAndLog(" Can't select AID: %s",sprint_hex(aid,3));
351 return;
352 }
353
354 // KEY SETTINGS
355 options = NONE;
356 c.arg[0] = options;
357 c.arg[LENPOS] = 0x01;
358 c.d.asBytes[0] = GET_KEY_SETTINGS; // 0x45
359 SendCommand(&c);
360 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
361 return;
362 }
363 isOK = resp.arg[0] & 0xff;
364 if ( !isOK ){
365 PrintAndLog(" Can't read Application Master key settings");
366 } else {
367 // Access rights.
368 uint8_t rights = (resp.d.asBytes[3] >> 4 && 0xff);
369 switch (rights){
370 case 0x00:
371 str = "AMK authentication is necessary to change any key (default)";
372 break;
373 case 0x0e:
374 str = "Authentication with the key to be changed (same KeyNo) is necessary to change a key";
375 break;
376 case 0x0f:
377 str = "All keys (except AMK,see Bit0) within this application are frozen";
378 break;
379 default:
380 str = "Authentication with the specified key is necessary to change any ley. A change key and a PICC master key (CMK) can only be changed after authentication with the master key. For keys other then the master or change key, an authentication with the same key is needed.";
381 break;
382 }
383 PrintAndLog("Changekey Access rights");
384 PrintAndLog("-- %s",str);
385 PrintAndLog("");
386 // same as CMK
387 str = (resp.d.asBytes[3] & (1 << 3 )) ? "YES":"NO";
388 PrintAndLog(" 0x08 Configuration changeable : %s", str);
389 str = (resp.d.asBytes[3] & (1 << 2 )) ? "NO":"YES";
390 PrintAndLog(" 0x04 AMK required for create/delete : %s",str);
391 str = (resp.d.asBytes[3] & (1 << 1 )) ? "NO":"YES";
392 PrintAndLog(" 0x02 Directory list access with AMK : %s",str);
393 str = (resp.d.asBytes[3] & (1 << 0 )) ? "YES" : "NO";
394 PrintAndLog(" 0x01 AMK is changeable : %s", str);
395 }
396
397 // KEY VERSION - AMK
398 c.arg[0] = NONE;
399 c.arg[LENPOS] = 0x02;
400 c.d.asBytes[0] = GET_KEY_VERSION; //0x64
401 c.d.asBytes[1] = 0x00;
402 SendCommand(&c);
403 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
404 PrintAndLog(" Timed-out");
405 return;
406 }
407
408 int numOfKeys;
409
410 isOK = resp.arg[0] & 0xff;
411 if ( !isOK ){
412 PrintAndLog(" Can't read Application Master key version. Trying all keys");
413 numOfKeys = MAX_NUM_KEYS;
414 }
415 else{
416 numOfKeys = resp.d.asBytes[4];
417 PrintAndLog("");
418 PrintAndLog(" Max number of keys : %d", numOfKeys );
419 PrintAndLog(" Application Master key Version : %d (0x%02x)", resp.d.asBytes[3], resp.d.asBytes[3]);
420 PrintAndLog("-------------------------------------------------------------");
421 }
422
423 // LOOP over numOfKeys that we got before.
424 // From 0x01 to numOfKeys. We already got 0x00. (AMK)
425 for(int i=0x01; i<=0x0f; ++i){
426
427 }
428
429
430 }
431 }
432
433 int CmdHF14ADesEnumApplications(const char *Cmd){
434
435 uint8_t isOK = 0x00;
436 uint8_t aid[3];
437 uint32_t options = (INIT | DISCONNECT);
438
439 UsbCommand c = {CMD_MIFARE_DESFIRE, {options , 0x01 }};
440 c.d.asBytes[0] = GET_APPLICATION_IDS; //0x6a
441
442 SendCommand(&c);
443 UsbCommand resp;
444
445 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
446 return 0;
447 }
448 isOK = resp.arg[0] & 0xff;
449 if ( !isOK ){
450 PrintAndLog("Command unsuccessful");
451 return 0;
452 }
453 PrintAndLog("");
454 PrintAndLog("-- Desfire Enumerate Applications ---------------------------");
455 PrintAndLog("-------------------------------------------------------------");
456
457 UsbCommand respAid;
458 UsbCommand respFiles;
459
460 uint8_t num = 0;
461 int max = resp.arg[1] -3 -2;
462
463 for(int i=3; i<=max; i+=3){
464 PrintAndLog(" Aid %d : %02X %02X %02X ",num ,resp.d.asBytes[i],resp.d.asBytes[i+1],resp.d.asBytes[i+2]);
465 num++;
466
467 aid[0] = resp.d.asBytes[i];
468 aid[1] = resp.d.asBytes[i+1];
469 aid[2] = resp.d.asBytes[i+2];
470 GetKeySettings(aid);
471
472 // Select Application
473 c.arg[CMDPOS] = INIT;
474 c.arg[LENPOS] = 0x04;
475 c.d.asBytes[0] = SELECT_APPLICATION; // 0x5a
476 c.d.asBytes[1] = resp.d.asBytes[i];
477 c.d.asBytes[2] = resp.d.asBytes[i+1];
478 c.d.asBytes[3] = resp.d.asBytes[i+2];
479 SendCommand(&c);
480
481 if (!WaitForResponseTimeout(CMD_ACK,&respAid,1500) ) {
482 PrintAndLog(" Timed-out");
483 continue;
484 }
485 isOK = respAid.d.asBytes[2] & 0xff;
486 if ( isOK != 0x00 ){
487 PrintAndLog(" Can't select AID: %s",sprint_hex(resp.d.asBytes+i,3));
488 continue;
489 }
490
491 // Get File IDs
492 c.arg[CMDPOS] = NONE;
493 c.arg[LENPOS] = 0x01;
494 c.d.asBytes[0] = GET_FILE_IDS; // 0x6f
495 SendCommand(&c);
496
497 if ( !WaitForResponseTimeout(CMD_ACK,&respFiles,1500) ) {
498 PrintAndLog(" Timed-out");
499 continue;
500 } else {
501 isOK = respFiles.d.asBytes[2] & 0xff;
502 if ( !isOK ){
503 PrintAndLog(" Can't get file ids ");
504 } else {
505 int respfileLen = resp.arg[1]-3-2;
506 for (int j=0; j< respfileLen; ++j){
507 PrintAndLog(" Fileid %d :", resp.d.asBytes[j+3]);
508 }
509 }
510 }
511
512 // Get ISO File IDs
513 c.arg[CMDPOS] = DISCONNECT;
514 c.arg[LENPOS] = 0x01;
515 c.d.asBytes[0] = GET_ISOFILE_IDS; // 0x61
516 SendCommand(&c);
517
518 if ( !WaitForResponseTimeout(CMD_ACK,&respFiles,1500) ) {
519 PrintAndLog(" Timed-out");
520 continue;
521 } else {
522 isOK = respFiles.d.asBytes[2] & 0xff;
523 if ( !isOK ){
524 PrintAndLog(" Can't get ISO file ids ");
525 } else {
526 int respfileLen = resp.arg[1]-3-2;
527 for (int j=0; j< respfileLen; ++j){
528 PrintAndLog(" ISO Fileid %d :", resp.d.asBytes[j+3]);
529 }
530 }
531 }
532
533
534 }
535 PrintAndLog("-------------------------------------------------------------");
536
537
538 return 1;
539 }
540
541 // MIAFRE DesFire Authentication
542 //
543 #define BUFSIZE 256
544 int CmdHF14ADesAuth(const char *Cmd){
545
546 // NR DESC KEYLENGHT
547 // ------------------------
548 // 1 = DES 8
549 // 2 = 3DES 16
550 // 3 = 3K 3DES 24
551 // 4 = AES 16
552
553 uint8_t keylength = 8;
554 unsigned char key[24];
555
556 if (strlen(Cmd)<3) {
557 PrintAndLog("Usage: hf mfdes auth <1|2|3> <1|2|3|4> <keyno> <key> ");
558 PrintAndLog(" Auth modes");
559 PrintAndLog(" 1 = normal, 2 = iso, 3 = aes");
560 PrintAndLog(" Crypto");
561 PrintAndLog(" 1 = DES 2 = 3DES 3 = 3K3DES 4 = AES");
562 PrintAndLog("");
563 PrintAndLog(" sample: hf mfdes auth 1 1 0 11223344");
564 PrintAndLog(" sample: hf mfdes auth 3 4 0 404142434445464748494a4b4c4d4e4f");
565 return 0;
566 }
567 uint8_t cmdAuthMode = param_get8(Cmd,0);
568 uint8_t cmdAuthAlgo = param_get8(Cmd,1);
569 uint8_t cmdKeyNo = param_get8(Cmd,2);
570
571 switch (cmdAuthMode)
572 {
573 case 1:
574 if ( cmdAuthAlgo != 1 && cmdAuthAlgo != 2) {
575 PrintAndLog("Crypto algo not valid for the auth mode");
576 return 1;
577 }
578 break;
579 case 2:
580 if ( cmdAuthAlgo != 1 && cmdAuthAlgo != 2 && cmdAuthAlgo != 3) {
581 PrintAndLog("Crypto algo not valid for the auth mode");
582 return 1;
583 }
584 break;
585 case 3:
586 if ( cmdAuthAlgo != 4) {
587 PrintAndLog("Crypto algo not valid for the auth mode");
588 return 1;
589 }
590 break;
591 default:
592 PrintAndLog("Wrong Auth mode");
593 return 1;
594 break;
595 }
596
597 switch (cmdAuthAlgo){
598 case 2:
599 keylength = 16;
600 PrintAndLog("3DES selected");
601 break;
602 case 3:
603 keylength = 24;
604 PrintAndLog("3 key 3DES selected");
605 break;
606 case 4:
607 keylength = 16;
608 PrintAndLog("AES selected");
609 break;
610 default:
611 cmdAuthAlgo = 1;
612 keylength = 8;
613 PrintAndLog("DES selected");
614 break;
615 }
616
617 // key
618 if (param_gethex(Cmd, 3, key, keylength*2)) {
619 PrintAndLog("Key must include %d HEX symbols", keylength);
620 return 1;
621 }
622 // algo, nyckellängd,
623 UsbCommand c = {CMD_MIFARE_DESFIRE_AUTH1, { cmdAuthMode, cmdAuthAlgo, cmdKeyNo }};
624
625 c.d.asBytes[0] = keylength;
626 memcpy(c.d.asBytes+1, key, keylength);
627
628 SendCommand(&c);
629 UsbCommand resp;
630
631 if (!WaitForResponseTimeout(CMD_ACK,&resp,3000)) {
632 PrintAndLog("Client command execute timeout");
633 return 0;
634 }
635
636 uint8_t isOK = resp.arg[0] & 0xff;
637 if ( isOK) {
638 uint8_t * data= resp.d.asBytes;
639
640 PrintAndLog(" Key :%s",sprint_hex(key, keylength));
641 PrintAndLog(" SESSION :%s",sprint_hex(data, keylength));
642 PrintAndLog("-------------------------------------------------------------");
643 //PrintAndLog(" Expected :B5 21 9E E8 1A A7 49 9D 21 96 68 7E 13 97 38 56");
644 } else{
645 PrintAndLog("Client command failed.");
646 }
647 PrintAndLog("-------------------------------------------------------------");
648 return 1;
649 }
650
651
652 static void xor(unsigned char * dst, unsigned char * src, size_t len) {
653 for( ; len > 0; len--,dst++,src++)
654 *dst ^= *src;
655 }
656
657 static int32_t le24toh (uint8_t data[3]) {
658 return (data[2] << 16) | (data[1] << 8) | data[0];
659 }
660
661 static command_t CommandTable[] =
662 {
663 {"help", CmdHelp, 1, "This help"},
664 {"auth", CmdHF14ADesAuth, 0, "Tries a MIFARE DesFire Authentication"},
665 {"rb", CmdHF14ADesRb, 0, "Read MIFARE DesFire block"},
666 {"wb", CmdHF14ADesWb, 0, "write MIFARE DesFire block"},
667 {"info", CmdHF14ADesInfo, 0, "Get MIFARE DesFire information"},
668 {"enum", CmdHF14ADesEnumApplications,0, "Tries enumerate all applications"},
669 {NULL, NULL, 0, NULL}
670 };
671
672 int CmdHFMFDes(const char *Cmd)
673 {
674 // flush
675 WaitForResponseTimeout(CMD_ACK,NULL,100);
676 CmdsParse(CommandTable, Cmd);
677 return 0;
678 }
679
680 int CmdHelp(const char *Cmd)
681 {
682 CmdsHelp(CommandTable);
683 return 0;
684 }
685
686
Impressum, Datenschutz