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