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