]> cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhfmfdes.c
chg: moved to header file
[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 : %s",GetVersionStr(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] = {0x00};
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] = {0x00};
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 char * GetVersionStr(uint8_t major, uint8_t minor){
247
248 static char buf[30] = {0x00};
249 char *retStr = buf;
250
251 if ( major == 0x00)
252 sprintf(retStr,"%d.%d (Desfire MF3ICD40)", major, minor);
253 else if ( major == 0x01 && minor == 0x00)
254 sprintf(retStr,"%d.%d (Desfire EV1)", major, minor);
255 else if ( major == 0x12 && minor == 0x00)
256 sprintf(retStr,"%d.%d (Desfire EV2)", major, minor);
257 else
258 sprintf(retStr,"%d.%d (Unknown)", major, minor);
259 return buf;
260 }
261
262 void GetKeySettings( uint8_t *aid){
263
264 char messStr[512] = {0x00};
265 char *str = messStr;
266 uint8_t isOK = 0;
267 uint32_t options = NONE;
268 UsbCommand c;
269 UsbCommand resp;
270
271 //memset(messStr, 0x00, 512);
272
273 c.cmd = CMD_MIFARE_DESFIRE;
274
275 if ( aid == NULL ){
276 PrintAndLog(" CMK - PICC, Card Master Key settings ");
277 PrintAndLog("");
278 c.arg[CMDPOS] = (INIT | DISCONNECT);
279 c.arg[LENPOS] = 0x01;
280 c.d.asBytes[0] = GET_KEY_SETTINGS; // 0x45
281 SendCommand(&c);
282 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;}
283 isOK = resp.arg[0] & 0xff;
284 if ( !isOK ){
285 PrintAndLog(" Can't select master application");
286 return;
287 }
288
289 str = (resp.d.asBytes[3] & (1 << 3 )) ? "YES":"NO";
290 PrintAndLog(" [0x08] Configuration changeable : %s", str);
291 str = (resp.d.asBytes[3] & (1 << 2 )) ? "NO":"YES";
292 PrintAndLog(" [0x04] CMK required for create/delete : %s",str);
293 str = (resp.d.asBytes[3] & (1 << 1 )) ? "NO":"YES";
294 PrintAndLog(" [0x02] Directory list access with CMK : %s",str);
295 str = (resp.d.asBytes[3] & (1 << 0 )) ? "YES" : "NO";
296 PrintAndLog(" [0x01] CMK is changeable : %s", str);
297
298 c.arg[LENPOS] = 0x02; //LEN
299 c.d.asBytes[0] = GET_KEY_VERSION; //0x64
300 c.d.asBytes[1] = 0x00;
301 SendCommand(&c);
302 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {
303 return;
304 }
305 isOK = resp.arg[0] & 0xff;
306 if ( !isOK ){
307 PrintAndLog(" Can't read key-version");
308 return;
309 }
310 PrintAndLog("");
311 PrintAndLog(" Max number of keys : %d", resp.d.asBytes[4]);
312 PrintAndLog(" Master key Version : %d (0x%02x)", resp.d.asBytes[3], resp.d.asBytes[3]);
313 PrintAndLog(" ----------------------------------------------------------");
314
315 c.arg[LENPOS] = 0x02; //LEN
316 c.d.asBytes[0] = AUTHENTICATE; //0x0A
317 c.d.asBytes[1] = 0x00; // KEY 0
318 SendCommand(&c);
319 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;}
320 isOK = resp.d.asBytes[2] & 0xff;
321 PrintAndLog(" [0x0A] Authenticate : %s", ( isOK==0xAE ) ? "NO":"YES");
322
323 c.d.asBytes[0] = AUTHENTICATE_ISO; //0x1A
324 SendCommand(&c);
325 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;}
326 isOK = resp.d.asBytes[2] & 0xff;
327 PrintAndLog(" [0x1A] Authenticate ISO : %s", ( isOK==0xAE ) ? "NO":"YES");
328
329 c.d.asBytes[0] = AUTHENTICATE_AES; //0xAA
330 SendCommand(&c);
331 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;}
332 isOK = resp.d.asBytes[2] & 0xff;
333 PrintAndLog(" [0xAA] Authenticate AES : %s", ( isOK==0xAE ) ? "NO":"YES");
334 PrintAndLog("");
335 PrintAndLog(" ----------------------------------------------------------");
336
337 } else {
338 PrintAndLog(" AMK - Application Master Key settings");
339
340 // SELECT AID
341 c.arg[0] = (INIT | CLEARTRACE);
342 c.arg[LENPOS] = 0x04;
343 c.d.asBytes[0] = SELECT_APPLICATION; // 0x5a
344 memcpy(c.d.asBytes+1, aid, 3);
345 SendCommand(&c);
346
347 if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
348 PrintAndLog(" Timed-out");
349 return;
350 }
351 isOK = resp.arg[0] & 0xff;
352 if ( !isOK ){
353 PrintAndLog(" Can't select AID: %s",sprint_hex(aid,3));
354 return;
355 }
356
357 // KEY SETTINGS
358 options = NONE;
359 c.arg[0] = options;
360 c.arg[LENPOS] = 0x01;
361 c.d.asBytes[0] = GET_KEY_SETTINGS; // 0x45
362 SendCommand(&c);
363 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
364 return;
365 }
366 isOK = resp.arg[0] & 0xff;
367 if ( !isOK ){
368 PrintAndLog(" Can't read Application Master key settings");
369 } else {
370 // Access rights.
371 uint8_t rights = (resp.d.asBytes[3] >> 4 & 0xff);
372 switch (rights){
373 case 0x00:
374 str = "AMK authentication is necessary to change any key (default)";
375 break;
376 case 0x0e:
377 str = "Authentication with the key to be changed (same KeyNo) is necessary to change a key";
378 break;
379 case 0x0f:
380 str = "All keys (except AMK,see Bit0) within this application are frozen";
381 break;
382 default:
383 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.";
384 break;
385 }
386 PrintAndLog("Changekey Access rights");
387 PrintAndLog("-- %s",str);
388 PrintAndLog("");
389 // same as CMK
390 str = (resp.d.asBytes[3] & (1 << 3 )) ? "YES":"NO";
391 PrintAndLog(" 0x08 Configuration changeable : %s", str);
392 str = (resp.d.asBytes[3] & (1 << 2 )) ? "NO":"YES";
393 PrintAndLog(" 0x04 AMK required for create/delete : %s",str);
394 str = (resp.d.asBytes[3] & (1 << 1 )) ? "NO":"YES";
395 PrintAndLog(" 0x02 Directory list access with AMK : %s",str);
396 str = (resp.d.asBytes[3] & (1 << 0 )) ? "YES" : "NO";
397 PrintAndLog(" 0x01 AMK is changeable : %s", str);
398 }
399
400 // KEY VERSION - AMK
401 c.arg[0] = NONE;
402 c.arg[LENPOS] = 0x02;
403 c.d.asBytes[0] = GET_KEY_VERSION; //0x64
404 c.d.asBytes[1] = 0x00;
405 SendCommand(&c);
406 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
407 PrintAndLog(" Timed-out");
408 return;
409 }
410
411 int numOfKeys;
412
413 isOK = resp.arg[0] & 0xff;
414 if ( !isOK ){
415 PrintAndLog(" Can't read Application Master key version. Trying all keys");
416 numOfKeys = MAX_NUM_KEYS;
417 }
418 else{
419 numOfKeys = resp.d.asBytes[4];
420 PrintAndLog("");
421 PrintAndLog(" Max number of keys : %d", numOfKeys );
422 PrintAndLog(" Application Master key Version : %d (0x%02x)", resp.d.asBytes[3], resp.d.asBytes[3]);
423 PrintAndLog("-------------------------------------------------------------");
424 }
425
426 // LOOP over numOfKeys that we got before.
427 // From 0x01 to numOfKeys. We already got 0x00. (AMK)
428 for(int i=0x01; i<=0x0f; ++i){
429
430 }
431
432
433 }
434 }
435
436 int CmdHF14ADesEnumApplications(const char *Cmd){
437
438 uint8_t isOK = 0x00;
439 uint8_t aid[3];
440 uint32_t options = (INIT | DISCONNECT);
441
442 UsbCommand c = {CMD_MIFARE_DESFIRE, {options , 0x01 }};
443 c.d.asBytes[0] = GET_APPLICATION_IDS; //0x6a
444
445 SendCommand(&c);
446 UsbCommand resp;
447
448 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
449 return 0;
450 }
451 isOK = resp.arg[0] & 0xff;
452 if ( !isOK ){
453 PrintAndLog("Command unsuccessful");
454 return 0;
455 }
456 PrintAndLog("");
457 PrintAndLog("-- Desfire Enumerate Applications ---------------------------");
458 PrintAndLog("-------------------------------------------------------------");
459
460 UsbCommand respAid;
461 UsbCommand respFiles;
462
463 uint8_t num = 0;
464 int max = resp.arg[1] -3 -2;
465
466 for(int i=3; i<=max; i+=3){
467 PrintAndLog(" Aid %d : %02X %02X %02X ",num ,resp.d.asBytes[i],resp.d.asBytes[i+1],resp.d.asBytes[i+2]);
468 num++;
469
470 aid[0] = resp.d.asBytes[i];
471 aid[1] = resp.d.asBytes[i+1];
472 aid[2] = resp.d.asBytes[i+2];
473 GetKeySettings(aid);
474
475 // Select Application
476 c.arg[CMDPOS] = INIT;
477 c.arg[LENPOS] = 0x04;
478 c.d.asBytes[0] = SELECT_APPLICATION; // 0x5a
479 c.d.asBytes[1] = resp.d.asBytes[i];
480 c.d.asBytes[2] = resp.d.asBytes[i+1];
481 c.d.asBytes[3] = resp.d.asBytes[i+2];
482 SendCommand(&c);
483
484 if (!WaitForResponseTimeout(CMD_ACK,&respAid,1500) ) {
485 PrintAndLog(" Timed-out");
486 continue;
487 }
488 isOK = respAid.d.asBytes[2] & 0xff;
489 if ( isOK != 0x00 ){
490 PrintAndLog(" Can't select AID: %s",sprint_hex(resp.d.asBytes+i,3));
491 continue;
492 }
493
494 // Get File IDs
495 c.arg[CMDPOS] = NONE;
496 c.arg[LENPOS] = 0x01;
497 c.d.asBytes[0] = GET_FILE_IDS; // 0x6f
498 SendCommand(&c);
499
500 if ( !WaitForResponseTimeout(CMD_ACK,&respFiles,1500) ) {
501 PrintAndLog(" Timed-out");
502 continue;
503 } else {
504 isOK = respFiles.d.asBytes[2] & 0xff;
505 if ( !isOK ){
506 PrintAndLog(" Can't get file ids ");
507 } else {
508 int respfileLen = resp.arg[1]-3-2;
509 for (int j=0; j< respfileLen; ++j){
510 PrintAndLog(" Fileid %d :", resp.d.asBytes[j+3]);
511 }
512 }
513 }
514
515 // Get ISO File IDs
516 c.arg[CMDPOS] = DISCONNECT;
517 c.arg[LENPOS] = 0x01;
518 c.d.asBytes[0] = GET_ISOFILE_IDS; // 0x61
519 SendCommand(&c);
520
521 if ( !WaitForResponseTimeout(CMD_ACK,&respFiles,1500) ) {
522 PrintAndLog(" Timed-out");
523 continue;
524 } else {
525 isOK = respFiles.d.asBytes[2] & 0xff;
526 if ( !isOK ){
527 PrintAndLog(" Can't get ISO file ids ");
528 } else {
529 int respfileLen = resp.arg[1]-3-2;
530 for (int j=0; j< respfileLen; ++j){
531 PrintAndLog(" ISO Fileid %d :", resp.d.asBytes[j+3]);
532 }
533 }
534 }
535
536
537 }
538 PrintAndLog("-------------------------------------------------------------");
539
540
541 return 1;
542 }
543
544 // MIAFRE DesFire Authentication
545 //
546 #define BUFSIZE 256
547 int CmdHF14ADesAuth(const char *Cmd){
548
549 // NR DESC KEYLENGHT
550 // ------------------------
551 // 1 = DES 8
552 // 2 = 3DES 16
553 // 3 = 3K 3DES 24
554 // 4 = AES 16
555
556 uint8_t keylength = 8;
557 unsigned char key[24];
558
559 if (strlen(Cmd)<3) {
560 PrintAndLog("Usage: hf mfdes auth <1|2|3> <1|2|3|4> <keyno> <key> ");
561 PrintAndLog(" Auth modes");
562 PrintAndLog(" 1 = normal, 2 = iso, 3 = aes");
563 PrintAndLog(" Crypto");
564 PrintAndLog(" 1 = DES 2 = 3DES 3 = 3K3DES 4 = AES");
565 PrintAndLog("");
566 PrintAndLog(" sample: hf mfdes auth 1 1 0 11223344");
567 PrintAndLog(" sample: hf mfdes auth 3 4 0 404142434445464748494a4b4c4d4e4f");
568 return 0;
569 }
570 uint8_t cmdAuthMode = param_get8(Cmd,0);
571 uint8_t cmdAuthAlgo = param_get8(Cmd,1);
572 uint8_t cmdKeyNo = param_get8(Cmd,2);
573
574 switch (cmdAuthMode)
575 {
576 case 1:
577 if ( cmdAuthAlgo != 1 && cmdAuthAlgo != 2) {
578 PrintAndLog("Crypto algo not valid for the auth mode");
579 return 1;
580 }
581 break;
582 case 2:
583 if ( cmdAuthAlgo != 1 && cmdAuthAlgo != 2 && cmdAuthAlgo != 3) {
584 PrintAndLog("Crypto algo not valid for the auth mode");
585 return 1;
586 }
587 break;
588 case 3:
589 if ( cmdAuthAlgo != 4) {
590 PrintAndLog("Crypto algo not valid for the auth mode");
591 return 1;
592 }
593 break;
594 default:
595 PrintAndLog("Wrong Auth mode");
596 return 1;
597 break;
598 }
599
600 switch (cmdAuthAlgo){
601 case 2:
602 keylength = 16;
603 PrintAndLog("3DES selected");
604 break;
605 case 3:
606 keylength = 24;
607 PrintAndLog("3 key 3DES selected");
608 break;
609 case 4:
610 keylength = 16;
611 PrintAndLog("AES selected");
612 break;
613 default:
614 cmdAuthAlgo = 1;
615 keylength = 8;
616 PrintAndLog("DES selected");
617 break;
618 }
619
620 // key
621 if (param_gethex(Cmd, 3, key, keylength*2)) {
622 PrintAndLog("Key must include %d HEX symbols", keylength);
623 return 1;
624 }
625 // algo, nyckellängd,
626 UsbCommand c = {CMD_MIFARE_DESFIRE_AUTH1, { cmdAuthMode, cmdAuthAlgo, cmdKeyNo }};
627
628 c.d.asBytes[0] = keylength;
629 memcpy(c.d.asBytes+1, key, keylength);
630 clearCommandBuffer();
631 SendCommand(&c);
632 UsbCommand resp;
633
634 if (!WaitForResponseTimeout(CMD_ACK,&resp,3000)) {
635 PrintAndLog("Client command execute timeout");
636 return 0;
637 }
638
639 uint8_t isOK = resp.arg[0] & 0xff;
640 if ( isOK) {
641 uint8_t * data= resp.d.asBytes;
642
643 PrintAndLog(" Key :%s",sprint_hex(key, keylength));
644 PrintAndLog(" SESSION :%s",sprint_hex(data, keylength));
645 PrintAndLog("-------------------------------------------------------------");
646 //PrintAndLog(" Expected :B5 21 9E E8 1A A7 49 9D 21 96 68 7E 13 97 38 56");
647 } else{
648 PrintAndLog("Client command failed.");
649 }
650 PrintAndLog("-------------------------------------------------------------");
651 return 1;
652 }
653
654
655 static command_t CommandTable[] = {
656 {"help", CmdHelp, 1, "This help"},
657 {"info", CmdHF14ADesInfo, 0, "Get MIFARE DesFire information"},
658 {"enum", CmdHF14ADesEnumApplications,0, "Tries enumerate all applications"},
659 {"auth", CmdHF14ADesAuth, 0, "Tries a MIFARE DesFire Authentication"},
660 {"rdbl", CmdHF14ADesRb, 0, "Read MIFARE DesFire block"},
661 {"wrbl", CmdHF14ADesWb, 0, "write MIFARE DesFire block"},
662 {NULL, NULL, 0, NULL}
663 };
664
665 int CmdHFMFDes(const char *Cmd) {
666 // flush
667 clearCommandBuffer();
668 CmdsParse(CommandTable, Cmd);
669 return 0;
670 }
671
672 int CmdHelp(const char *Cmd) {
673 CmdsHelp(CommandTable);
674 return 0;
675 }
676
677
Impressum, Datenschutz