]> git.zerfleddert.de Git - proxmark3-svn/blame - client/cmdhfmfdes.c
ADD @pwpiwi 's fixes for "HF 14B" commands.
[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 <openssl/des.h>
16#include "loclass/des.h"
f38a1528 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"
5e336f53 27#include "cmdhf14a.h"
28
f38a1528 29
f6c18637 30uint8_t CMDPOS = 0;
31uint8_t LENPOS = 1;
f38a1528 32
95e63594 33uint8_t key_zero_data[16] = { 0x00 };
34uint8_t key_ones_data[16] = { 0x01 };
f38a1528 35uint8_t key_defa_data[16] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
f6c18637 36uint8_t key_picc_data[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f };
f38a1528 37
38static int CmdHelp(const char *Cmd);
f38a1528 39
40int 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
89int 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
137int CmdHF14ADesInfo(const char *Cmd){
138
313ee67e 139 UsbCommand c = {CMD_MIFARE_DESFIRE_INFO};
f38a1528 140 SendCommand(&c);
141 UsbCommand resp;
142
313ee67e 143 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
f38a1528 144 PrintAndLog("Command execute timeout");
145 return 0;
313ee67e 146 }
147 uint8_t isOK = resp.arg[0] & 0xff;
148 if ( !isOK ){
3d93d4f9 149 PrintAndLog("Command unsuccessful");
313ee67e 150 return 0;
f38a1528 151 }
f6c18637 152 PrintAndLog("");
153 PrintAndLog("-- Desfire Information --------------------------------------");
f38a1528 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]);
f6c18637 158 PrintAndLog(" -----------------------------------------------------------");
f38a1528 159 PrintAndLog(" Hardware Information");
5e336f53 160 PrintAndLog(" Vendor Id : %s", getTagInfo(resp.d.asBytes[7]));
f38a1528 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]));
f6c18637 166 PrintAndLog(" -----------------------------------------------------------");
f38a1528 167 PrintAndLog(" Software Information");
5e336f53 168 PrintAndLog(" Vendor Id : %s", getTagInfo(resp.d.asBytes[14]));
f38a1528 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
f6c18637 176 // Master Key settings
177 GetKeySettings(NULL);
313ee67e 178
f6c18637 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);
313ee67e 185 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
186 return 0;
187 }
188
f38a1528 189 uint8_t tmp[3];
313ee67e 190 memcpy(tmp, resp.d.asBytes+3,3);
f38a1528 191
f6c18637 192 PrintAndLog(" Available free memory on card : %d bytes", le24toh( tmp ));
f38a1528 193 PrintAndLog("-------------------------------------------------------------");
3d93d4f9 194
f38a1528 195 /*
75465377 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
f38a1528 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
f6c18637 207
f38a1528 208 */
209
f38a1528 210 return 1;
211}
212
f38a1528 213/*
214 The 7 MSBits (= n) code the storage size itself based on 2^n,
215 the LSBit is set to '0' if the size is exactly 2^n
216 and set to '1' if the storage size is between 2^n and 2^(n+1).
217 For this version of DESFire the 7 MSBits are set to 0x0C (2^12 = 4096) and the LSBit is '0'.
218*/
219char * GetCardSizeStr( uint8_t fsize ){
220
221 static char buf[30];
222 char *retStr = buf;
223
224 uint16_t usize = 1 << ((fsize >>1) + 1);
225 uint16_t lsize = 1 << (fsize >>1);
226
227 // is LSB set?
0ec548dc 228 if ( fsize & 1 )
f38a1528 229 sprintf(retStr, "0x%02X (%d - %d bytes)",fsize, usize, lsize);
230 else
231 sprintf(retStr, "0x%02X (%d bytes)", fsize, lsize);
232 return buf;
233}
234
235char * GetProtocolStr(uint8_t id){
236
237 static char buf[30];
238 char *retStr = buf;
239
240 if ( id == 0x05)
241 sprintf(retStr,"0x%02X (ISO 14443-3, 14443-4)", id);
242 else
0ec548dc 243 sprintf(retStr,"0x%02X (Unknown)", id);
f38a1528 244 return buf;
245}
246
f6c18637 247void GetKeySettings( uint8_t *aid){
3d93d4f9 248
f6c18637 249 char messStr[512] = {0x00};
250 char *str = messStr;
251 uint8_t isOK = 0;
252 uint32_t options = NONE;
253 UsbCommand c;
254 UsbCommand resp;
255
256 //memset(messStr, 0x00, 512);
75465377 257
f6c18637 258 c.cmd = CMD_MIFARE_DESFIRE;
259
260 if ( aid == NULL ){
261 PrintAndLog(" CMK - PICC, Card Master Key settings ");
262 PrintAndLog("");
263 c.arg[CMDPOS] = (INIT | DISCONNECT);
264 c.arg[LENPOS] = 0x01;
265 c.d.asBytes[0] = GET_KEY_SETTINGS; // 0x45
266 SendCommand(&c);
267 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;}
268 isOK = resp.arg[0] & 0xff;
269 if ( !isOK ){
270 PrintAndLog(" Can't select master application");
271 return;
272 }
273
274 str = (resp.d.asBytes[3] & (1 << 3 )) ? "YES":"NO";
275 PrintAndLog(" [0x08] Configuration changeable : %s", str);
276 str = (resp.d.asBytes[3] & (1 << 2 )) ? "NO":"YES";
277 PrintAndLog(" [0x04] CMK required for create/delete : %s",str);
278 str = (resp.d.asBytes[3] & (1 << 1 )) ? "NO":"YES";
279 PrintAndLog(" [0x02] Directory list access with CMK : %s",str);
280 str = (resp.d.asBytes[3] & (1 << 0 )) ? "YES" : "NO";
281 PrintAndLog(" [0x01] CMK is changeable : %s", str);
282
283 c.arg[LENPOS] = 0x02; //LEN
284 c.d.asBytes[0] = GET_KEY_VERSION; //0x64
285 c.d.asBytes[1] = 0x00;
286 SendCommand(&c);
287 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {
288 return;
289 }
290 isOK = resp.arg[0] & 0xff;
291 if ( !isOK ){
292 PrintAndLog(" Can't read key-version");
293 return;
294 }
295 PrintAndLog("");
296 PrintAndLog(" Max number of keys : %d", resp.d.asBytes[4]);
297 PrintAndLog(" Master key Version : %d (0x%02x)", resp.d.asBytes[3], resp.d.asBytes[3]);
298 PrintAndLog(" ----------------------------------------------------------");
299
300 c.arg[LENPOS] = 0x02; //LEN
301 c.d.asBytes[0] = AUTHENTICATE; //0x0A
302 c.d.asBytes[1] = 0x00; // KEY 0
303 SendCommand(&c);
304 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;}
305 isOK = resp.d.asBytes[2] & 0xff;
306 PrintAndLog(" [0x0A] Authenticate : %s", ( isOK==0xAE ) ? "NO":"YES");
307
308 c.d.asBytes[0] = AUTHENTICATE_ISO; //0x1A
309 SendCommand(&c);
310 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;}
311 isOK = resp.d.asBytes[2] & 0xff;
312 PrintAndLog(" [0x1A] Authenticate ISO : %s", ( isOK==0xAE ) ? "NO":"YES");
313
314 c.d.asBytes[0] = AUTHENTICATE_AES; //0xAA
315 SendCommand(&c);
316 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;}
317 isOK = resp.d.asBytes[2] & 0xff;
318 PrintAndLog(" [0xAA] Authenticate AES : %s", ( isOK==0xAE ) ? "NO":"YES");
319 PrintAndLog("");
320 PrintAndLog(" ----------------------------------------------------------");
321
322 } else {
323 PrintAndLog(" AMK - Application Master Key settings");
324
325 // SELECT AID
326 c.arg[0] = (INIT | CLEARTRACE);
327 c.arg[LENPOS] = 0x04;
328 c.d.asBytes[0] = SELECT_APPLICATION; // 0x5a
329 memcpy(c.d.asBytes+1, aid, 3);
330 SendCommand(&c);
331
332 if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
333 PrintAndLog(" Timed-out");
334 return;
335 }
336 isOK = resp.arg[0] & 0xff;
337 if ( !isOK ){
338 PrintAndLog(" Can't select AID: %s",sprint_hex(aid,3));
339 return;
340 }
341
342 // KEY SETTINGS
343 options = NONE;
344 c.arg[0] = options;
345 c.arg[LENPOS] = 0x01;
346 c.d.asBytes[0] = GET_KEY_SETTINGS; // 0x45
347 SendCommand(&c);
348 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
349 return;
350 }
351 isOK = resp.arg[0] & 0xff;
352 if ( !isOK ){
353 PrintAndLog(" Can't read Application Master key settings");
354 } else {
355 // Access rights.
356 uint8_t rights = (resp.d.asBytes[3] >> 4 && 0xff);
357 switch (rights){
358 case 0x00:
359 str = "AMK authentication is necessary to change any key (default)";
360 break;
361 case 0x0e:
362 str = "Authentication with the key to be changed (same KeyNo) is necessary to change a key";
363 break;
364 case 0x0f:
365 str = "All keys (except AMK,see Bit0) within this application are frozen";
366 break;
367 default:
368 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.";
369 break;
370 }
371 PrintAndLog("Changekey Access rights");
372 PrintAndLog("-- %s",str);
373 PrintAndLog("");
374 // same as CMK
375 str = (resp.d.asBytes[3] & (1 << 3 )) ? "YES":"NO";
376 PrintAndLog(" 0x08 Configuration changeable : %s", str);
377 str = (resp.d.asBytes[3] & (1 << 2 )) ? "NO":"YES";
378 PrintAndLog(" 0x04 AMK required for create/delete : %s",str);
379 str = (resp.d.asBytes[3] & (1 << 1 )) ? "NO":"YES";
380 PrintAndLog(" 0x02 Directory list access with AMK : %s",str);
381 str = (resp.d.asBytes[3] & (1 << 0 )) ? "YES" : "NO";
382 PrintAndLog(" 0x01 AMK is changeable : %s", str);
383 }
384
385 // KEY VERSION - AMK
386 c.arg[0] = NONE;
387 c.arg[LENPOS] = 0x02;
388 c.d.asBytes[0] = GET_KEY_VERSION; //0x64
389 c.d.asBytes[1] = 0x00;
390 SendCommand(&c);
391 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
392 PrintAndLog(" Timed-out");
393 return;
394 }
395
396 int numOfKeys;
397
398 isOK = resp.arg[0] & 0xff;
399 if ( !isOK ){
400 PrintAndLog(" Can't read Application Master key version. Trying all keys");
401 numOfKeys = MAX_NUM_KEYS;
402 }
403 else{
404 numOfKeys = resp.d.asBytes[4];
405 PrintAndLog("");
406 PrintAndLog(" Max number of keys : %d", numOfKeys );
407 PrintAndLog(" Application Master key Version : %d (0x%02x)", resp.d.asBytes[3], resp.d.asBytes[3]);
408 PrintAndLog("-------------------------------------------------------------");
409 }
410
411 // LOOP over numOfKeys that we got before.
412 // From 0x01 to numOfKeys. We already got 0x00. (AMK)
413 for(int i=0x01; i<=0x0f; ++i){
414
415 }
416
417
418 }
419}
420
421int CmdHF14ADesEnumApplications(const char *Cmd){
422
423 uint8_t isOK = 0x00;
424 uint8_t aid[3];
425 uint32_t options = (INIT | DISCONNECT);
75465377 426
427 UsbCommand c = {CMD_MIFARE_DESFIRE, {options , 0x01 }};
428 c.d.asBytes[0] = GET_APPLICATION_IDS; //0x6a
f6c18637 429
3d93d4f9 430 SendCommand(&c);
431 UsbCommand resp;
432
433 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
434 return 0;
435 }
f6c18637 436 isOK = resp.arg[0] & 0xff;
3d93d4f9 437 if ( !isOK ){
438 PrintAndLog("Command unsuccessful");
439 return 0;
440 }
f6c18637 441 PrintAndLog("");
442 PrintAndLog("-- Desfire Enumerate Applications ---------------------------");
3d93d4f9 443 PrintAndLog("-------------------------------------------------------------");
444
75465377 445 UsbCommand respAid;
446 UsbCommand respFiles;
3d93d4f9 447
448 uint8_t num = 0;
449 int max = resp.arg[1] -3 -2;
450
451 for(int i=3; i<=max; i+=3){
75465377 452 PrintAndLog(" Aid %d : %02X %02X %02X ",num ,resp.d.asBytes[i],resp.d.asBytes[i+1],resp.d.asBytes[i+2]);
3d93d4f9 453 num++;
454
f6c18637 455 aid[0] = resp.d.asBytes[i];
456 aid[1] = resp.d.asBytes[i+1];
457 aid[2] = resp.d.asBytes[i+2];
458 GetKeySettings(aid);
459
460 // Select Application
461 c.arg[CMDPOS] = INIT;
462 c.arg[LENPOS] = 0x04;
463 c.d.asBytes[0] = SELECT_APPLICATION; // 0x5a
464 c.d.asBytes[1] = resp.d.asBytes[i];
465 c.d.asBytes[2] = resp.d.asBytes[i+1];
466 c.d.asBytes[3] = resp.d.asBytes[i+2];
467 SendCommand(&c);
75465377 468
469 if (!WaitForResponseTimeout(CMD_ACK,&respAid,1500) ) {
470 PrintAndLog(" Timed-out");
471 continue;
472 }
f6c18637 473 isOK = respAid.d.asBytes[2] & 0xff;
474 if ( isOK != 0x00 ){
75465377 475 PrintAndLog(" Can't select AID: %s",sprint_hex(resp.d.asBytes+i,3));
476 continue;
477 }
478
f6c18637 479 // Get File IDs
480 c.arg[CMDPOS] = NONE;
481 c.arg[LENPOS] = 0x01;
482 c.d.asBytes[0] = GET_FILE_IDS; // 0x6f
483 SendCommand(&c);
75465377 484
485 if ( !WaitForResponseTimeout(CMD_ACK,&respFiles,1500) ) {
486 PrintAndLog(" Timed-out");
487 continue;
488 } else {
f6c18637 489 isOK = respFiles.d.asBytes[2] & 0xff;
75465377 490 if ( !isOK ){
f6c18637 491 PrintAndLog(" Can't get file ids ");
492 } else {
493 int respfileLen = resp.arg[1]-3-2;
494 for (int j=0; j< respfileLen; ++j){
495 PrintAndLog(" Fileid %d :", resp.d.asBytes[j+3]);
496 }
75465377 497 }
f6c18637 498 }
499
500 // Get ISO File IDs
501 c.arg[CMDPOS] = DISCONNECT;
502 c.arg[LENPOS] = 0x01;
503 c.d.asBytes[0] = GET_ISOFILE_IDS; // 0x61
504 SendCommand(&c);
3d93d4f9 505
f6c18637 506 if ( !WaitForResponseTimeout(CMD_ACK,&respFiles,1500) ) {
507 PrintAndLog(" Timed-out");
508 continue;
509 } else {
510 isOK = respFiles.d.asBytes[2] & 0xff;
511 if ( !isOK ){
512 PrintAndLog(" Can't get ISO file ids ");
513 } else {
514 int respfileLen = resp.arg[1]-3-2;
515 for (int j=0; j< respfileLen; ++j){
516 PrintAndLog(" ISO Fileid %d :", resp.d.asBytes[j+3]);
517 }
75465377 518 }
519 }
3d93d4f9 520
f6c18637 521
3d93d4f9 522 }
523 PrintAndLog("-------------------------------------------------------------");
524
525
f38a1528 526 return 1;
527}
528
f38a1528 529// MIAFRE DesFire Authentication
530//
f6c18637 531#define BUFSIZE 256
f38a1528 532int CmdHF14ADesAuth(const char *Cmd){
533
534 // NR DESC KEYLENGHT
535 // ------------------------
536 // 1 = DES 8
537 // 2 = 3DES 16
538 // 3 = 3K 3DES 24
539 // 4 = AES 16
f6c18637 540
f38a1528 541 uint8_t keylength = 8;
f6c18637 542 unsigned char key[24];
f38a1528 543
544 if (strlen(Cmd)<3) {
545 PrintAndLog("Usage: hf mfdes auth <1|2|3> <1|2|3|4> <keyno> <key> ");
f6c18637 546 PrintAndLog(" Auth modes");
547 PrintAndLog(" 1 = normal, 2 = iso, 3 = aes");
548 PrintAndLog(" Crypto");
549 PrintAndLog(" 1 = DES 2 = 3DES 3 = 3K3DES 4 = AES");
550 PrintAndLog("");
f38a1528 551 PrintAndLog(" sample: hf mfdes auth 1 1 0 11223344");
f6c18637 552 PrintAndLog(" sample: hf mfdes auth 3 4 0 404142434445464748494a4b4c4d4e4f");
f38a1528 553 return 0;
554 }
555 uint8_t cmdAuthMode = param_get8(Cmd,0);
556 uint8_t cmdAuthAlgo = param_get8(Cmd,1);
557 uint8_t cmdKeyNo = param_get8(Cmd,2);
558
559 switch (cmdAuthMode)
560 {
561 case 1:
562 if ( cmdAuthAlgo != 1 && cmdAuthAlgo != 2) {
563 PrintAndLog("Crypto algo not valid for the auth mode");
564 return 1;
565 }
566 break;
567 case 2:
568 if ( cmdAuthAlgo != 1 && cmdAuthAlgo != 2 && cmdAuthAlgo != 3) {
569 PrintAndLog("Crypto algo not valid for the auth mode");
570 return 1;
571 }
572 break;
573 case 3:
574 if ( cmdAuthAlgo != 4) {
575 PrintAndLog("Crypto algo not valid for the auth mode");
576 return 1;
577 }
578 break;
579 default:
580 PrintAndLog("Wrong Auth mode");
581 return 1;
582 break;
583 }
584
585 switch (cmdAuthAlgo){
586 case 2:
587 keylength = 16;
588 PrintAndLog("3DES selected");
589 break;
590 case 3:
591 keylength = 24;
592 PrintAndLog("3 key 3DES selected");
593 break;
594 case 4:
595 keylength = 16;
596 PrintAndLog("AES selected");
597 break;
598 default:
599 cmdAuthAlgo = 1;
600 keylength = 8;
601 PrintAndLog("DES selected");
602 break;
603 }
604
605 // key
606 if (param_gethex(Cmd, 3, key, keylength*2)) {
607 PrintAndLog("Key must include %d HEX symbols", keylength);
608 return 1;
609 }
610