]> cvs.zerfleddert.de Git - proxmark3-svn/blame - client/cmdhfmfdes.c
ADD: `analyse nuid` - generates NUID 4byte from a UID 7byte. Mifare Classic Ev1...
[proxmark3-svn] / client / cmdhfmfdes.c
CommitLineData
f38a1528 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>
0ec548dc 15#include "loclass/des.h"
f38a1528 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"
5e336f53 26#include "cmdhf14a.h"
27
f38a1528 28
f6c18637 29uint8_t CMDPOS = 0;
30uint8_t LENPOS = 1;
f38a1528 31
95e63594 32uint8_t key_zero_data[16] = { 0x00 };
33uint8_t key_ones_data[16] = { 0x01 };
f38a1528 34uint8_t key_defa_data[16] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
f6c18637 35uint8_t key_picc_data[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f };
f38a1528 36
37static int CmdHelp(const char *Cmd);
f38a1528 38
39int 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
88int 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
136int CmdHF14ADesInfo(const char *Cmd){
137
313ee67e 138 UsbCommand c = {CMD_MIFARE_DESFIRE_INFO};
f38a1528 139 SendCommand(&c);
140 UsbCommand resp;
141
313ee67e 142 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
f38a1528 143 PrintAndLog("Command execute timeout");
144 return 0;
313ee67e 145 }
146 uint8_t isOK = resp.arg[0] & 0xff;
147 if ( !isOK ){
3d93d4f9 148 PrintAndLog("Command unsuccessful");
313ee67e 149 return 0;
f38a1528 150 }
f6c18637 151 PrintAndLog("");
152 PrintAndLog("-- Desfire Information --------------------------------------");
f38a1528 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]);
f6c18637 157 PrintAndLog(" -----------------------------------------------------------");
f38a1528 158 PrintAndLog(" Hardware Information");
5e336f53 159 PrintAndLog(" Vendor Id : %s", getTagInfo(resp.d.asBytes[7]));
f38a1528 160 PrintAndLog(" Type : 0x%02X",resp.d.asBytes[8]);
161 PrintAndLog(" Subtype : 0x%02X",resp.d.asBytes[9]);
288c6845 162 PrintAndLog(" Version : %s",GetVersionStr(resp.d.asBytes[10], resp.d.asBytes[11]) );
f38a1528 163 PrintAndLog(" Storage size : %s",GetCardSizeStr(resp.d.asBytes[12]));
164 PrintAndLog(" Protocol : %s",GetProtocolStr(resp.d.asBytes[13]));
f6c18637 165 PrintAndLog(" -----------------------------------------------------------");
f38a1528 166 PrintAndLog(" Software Information");
5e336f53 167 PrintAndLog(" Vendor Id : %s", getTagInfo(resp.d.asBytes[14]));
f38a1528 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
f6c18637 175 // Master Key settings
176 GetKeySettings(NULL);
313ee67e 177
f6c18637 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);
313ee67e 184 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
185 return 0;
186 }
187
f38a1528 188 uint8_t tmp[3];
313ee67e 189 memcpy(tmp, resp.d.asBytes+3,3);
f38a1528 190
f6c18637 191 PrintAndLog(" Available free memory on card : %d bytes", le24toh( tmp ));
f38a1528 192 PrintAndLog("-------------------------------------------------------------");
3d93d4f9 193
f38a1528 194 /*
75465377 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
f38a1528 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
f6c18637 206
f38a1528 207 */
208
f38a1528 209 return 1;
210}
211
f38a1528 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*/
218char * GetCardSizeStr( uint8_t fsize ){
219
288c6845 220 static char buf[30] = {0x00};
f38a1528 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?
0ec548dc 227 if ( fsize & 1 )
f38a1528 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
234char * GetProtocolStr(uint8_t id){
235
288c6845 236 static char buf[30] = {0x00};
f38a1528 237 char *retStr = buf;
238
239 if ( id == 0x05)
240 sprintf(retStr,"0x%02X (ISO 14443-3, 14443-4)", id);
241 else
0ec548dc 242 sprintf(retStr,"0x%02X (Unknown)", id);
f38a1528 243 return buf;
244}
245
288c6845 246char * GetVersionStr(uint8_t major, uint8_t minor){
247
248 static char buf[30] = {0x00};
249 char *retStr = buf;
250
d118e70f 251 if ( major == 0x00)
288c6845 252 sprintf(retStr,"%d.%d (Desfire MF3ICD40)", major, minor);
f3cbb7bc 253 else if ( major == 0x01 && minor == 0x00)
288c6845 254 sprintf(retStr,"%d.%d (Desfire EV1)", major, minor);
d118e70f 255 else if ( major == 0x12 && minor == 0x00)
288c6845 256 sprintf(retStr,"%d.%d (Desfire EV2)", major, minor);
257 else
258 sprintf(retStr,"%d.%d (Unknown)", major, minor);
259 return buf;
260}
261
f6c18637 262void GetKeySettings( uint8_t *aid){
3d93d4f9 263
f6c18637 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);
75465377 272
f6c18637 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.
33db7351 371 uint8_t rights = (resp.d.asBytes[3] >> 4 & 0xff);
f6c18637 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
436int CmdHF14ADesEnumApplications(const char *Cmd){
437
438 uint8_t isOK = 0x00;
439 uint8_t aid[3];
440 uint32_t options = (INIT | DISCONNECT);
75465377 441
442 UsbCommand c = {CMD_MIFARE_DESFIRE, {options , 0x01 }};
443 c.d.asBytes[0] = GET_APPLICATION_IDS; //0x6a
f6c18637 444
3d93d4f9 445 SendCommand(&c);
446 UsbCommand resp;
447
448 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
449 return 0;
450 }
f6c18637 451 isOK = resp.arg[0] & 0xff;
3d93d4f9 452 if ( !isOK ){
453 PrintAndLog("Command unsuccessful");
454 return 0;
455 }
f6c18637 456 PrintAndLog("");
457 PrintAndLog("-- Desfire Enumerate Applications ---------------------------");
3d93d4f9 458 PrintAndLog("-------------------------------------------------------------");
459
75465377 460 UsbCommand respAid;
461 UsbCommand respFiles;
3d93d4f9 462
463 uint8_t num = 0;
464 int max = resp.arg[1] -3 -2;
465
466 for(int i=3; i<=max; i+=3){
75465377 467 PrintAndLog(" Aid %d : %02X %02X %02X ",num ,resp.d.asBytes[i],resp.d.asBytes[i+1],resp.d.asBytes[i+2]);
3d93d4f9 468 num++;
469
f6c18637 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);
75465377 483
484 if (!WaitForResponseTimeout(CMD_ACK,&respAid,1500) ) {
485 PrintAndLog(" Timed-out");
486 continue;
487 }
f6c18637 488 isOK = respAid.d.asBytes[2] & 0xff;
489 if ( isOK != 0x00 ){
75465377 490 PrintAndLog(" Can't select AID: %s",sprint_hex(resp.d.asBytes+i,3));
491 continue;
492 }
493
f6c18637 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);
75465377 499
500 if ( !WaitForResponseTimeout(CMD_ACK,&respFiles,1500) ) {
501 PrintAndLog(" Timed-out");
502 continue;
503 } else {
f6c18637 504 isOK = respFiles.d.asBytes[2] & 0xff;
75465377 505 if ( !isOK ){
f6c18637 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 }
75465377 512 }
f6c18637 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);
3d93d4f9 520
f6c18637 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 }
75465377 533 }
534 }
3d93d4f9 535
f6c18637 536
3d93d4f9 537 }
538 PrintAndLog("-------------------------------------------------------------");
539
540
f38a1528 541 return 1;
542}
543
f38a1528 544// MIAFRE DesFire Authentication
545//
f6c18637 546#define BUFSIZE 256
f38a1528 547int 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
f6c18637 555
f38a1528 556 uint8_t keylength = 8;
f6c18637 557 unsigned char key[24];
f38a1528 558
559 if (strlen(Cmd)<3) {
560 PrintAndLog("Usage: hf mfdes auth <1|2|3> <1|2|3|4> <keyno> <key> ");
f6c18637 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("");
f38a1528 566 PrintAndLog(" sample: hf mfdes auth 1 1 0 11223344");
f6c18637 567 PrintAndLog(" sample: hf mfdes auth 3 4 0 404142434445464748494a4b4c4d4e4f");
f38a1528 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