]> cvs.zerfleddert.de Git - proxmark3-svn/blame_incremental - client/cmdhfmfdes.c
Merge pull request #4 from gcohen55/ubuntu_makefile
[proxmark3-svn] / client / cmdhfmfdes.c
... / ...
CommitLineData
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
30uint8_t CMDPOS = 0;
31uint8_t LENPOS = 1;
32
33uint8_t key_zero_data[16] = { 0x00 };
34uint8_t key_ones_data[16] = { 0x01 };
35uint8_t key_defa_data[16] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
36uint8_t key_picc_data[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f };
37
38static int CmdHelp(const char *Cmd);
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
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", getTagInfo(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", getTagInfo(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/*
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?
228 if ( fsize & 1 )
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
243 sprintf(retStr,"0x%02X (Unknown)", id);
244 return buf;
245}
246
247void GetKeySettings( uint8_t *aid){
248
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);
257
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);
426
427 UsbCommand c = {CMD_MIFARE_DESFIRE, {options , 0x01 }};
428 c.d.asBytes[0] = GET_APPLICATION_IDS; //0x6a
429
430 SendCommand(&c);
431 UsbCommand resp;
432
433 if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
434 return 0;
435 }
436 isOK = resp.arg[0] & 0xff;
437 if ( !isOK ){
438 PrintAndLog("Command unsuccessful");
439 return 0;
440 }
441 PrintAndLog("");
442 PrintAndLog("-- Desfire Enumerate Applications ---------------------------");
443 PrintAndLog("-------------------------------------------------------------");
444
445 UsbCommand respAid;
446 UsbCommand respFiles;
447
448 uint8_t num = 0;
449 int max = resp.arg[1] -3 -2;
450
451 for(int i=3; i<=max; i+=3){
452 PrintAndLog(" Aid %d : %02X %02X %02X ",num ,resp.d.asBytes[i],resp.d.asBytes[i+1],resp.d.asBytes[i+2]);
453 num++;
454
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);
468
469 if (!WaitForResponseTimeout(CMD_ACK,&respAid,1500) ) {
470 PrintAndLog(" Timed-out");
471 continue;
472 }
473 isOK = respAid.d.asBytes[2] & 0xff;
474 if ( isOK != 0x00 ){
475 PrintAndLog(" Can't select AID: %s",sprint_hex(resp.d.asBytes+i,3));
476 continue;
477 }
478
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);
484
485 if ( !WaitForResponseTimeout(CMD_ACK,&respFiles,1500) ) {
486 PrintAndLog(" Timed-out");
487 continue;
488 } else {
489 isOK = respFiles.d.asBytes[2] & 0xff;
490 if ( !isOK ){
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 }
497 }
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);
505
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 }
518 }
519 }
520
521
522 }
523 PrintAndLog("-------------------------------------------------------------");
524
525
526 return 1;
527}
528
529// MIAFRE DesFire Authentication
530//
531#define BUFSIZE 256
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
540
541 uint8_t keylength = 8;
542 unsigned char key[24];
543
544 if (strlen(Cmd)<3) {
545 PrintAndLog("Usage: hf mfdes auth <1|2|3> <1|2|3|4> <keyno> <key> ");
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("");
551 PrintAndLog(" sample: hf mfdes auth 1 1 0 11223344");
552 PrintAndLog(" sample: hf mfdes auth 3 4 0 404142434445464748494a4b4c4d4e4f");
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