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