1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
16 // High frequency MIFARE Desfire commands
17 //-----------------------------------------------------------------------------
18 // Code heavily modified by B.Kerler :)
20 #include "cmdhfmfdes.h"
23 #include "commonutil.h" // ARRAYLEN
24 #include "cmdparser.h" // command_t
29 #include "crypto/libpcrypto.h"
30 #include "protocols.h"
32 #include "cliparser.h"
33 #include "iso7816/apduinfo.h" // APDU manipulation / errorcodes
34 #include "iso7816/iso7816core.h" // APDU logging
35 #include "util_posix.h" // msleep
36 #include "mifare/desfirecore.h"
37 #include "mifare/desfiretest.h"
38 #include "mifare/desfiresecurechan.h"
39 #include "mifare/mifaredefault.h" // default keys
40 #include "crapto1/crapto1.h"
41 #include "fileutils.h"
42 //#include "nfc/ndef.h" // NDEF
43 #include "mifare/mad.h"
44 #include "mifare/mifaredefault.h"
45 #include "generator.h"
46 #include "mifare/aiddesfire.h"
49 #define MAX_KEY_LEN 24
50 #define MAX_KEYS_LIST_LEN 1024
52 #define status(x) ( ((uint16_t)(0x91 << 8)) + (uint16_t)x )
54 static uint8_t desdefaultkeys[3][8] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, //Official
55 {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47},
56 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}
59 static uint8_t aesdefaultkeys[5][16] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, //Official, TRF7970A
60 {0x79, 0x70, 0x25, 0x53, 0x79, 0x70, 0x25, 0x53, 0x79, 0x70, 0x25, 0x53, 0x79, 0x70, 0x25, 0x53}, // TRF7970A
61 {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}, // TRF7970A
62 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},
63 {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f}
66 static uint8_t k3kdefaultkeys[1][24] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
68 typedef struct mfdes_authinput
{
77 } PACKED mfdes_authinput_t
;
79 typedef struct mfdes_auth_res
{
80 uint8_t sessionkeylen
;
81 uint8_t sessionkey
[24];
82 } PACKED mfdes_auth_res_t
;
84 typedef struct mfdes_data
{
89 } PACKED mfdes_data_t
;
91 typedef struct mfdes_info_res
{
98 } PACKED mfdes_info_res_t
;
100 typedef struct mfdes_value
{
103 } PACKED mfdes_value_t
;
105 typedef struct mfdes_file
{
107 uint8_t fid
[2]; //03E1
109 uint8_t access_rights
[2]; ///EEEE
110 uint8_t filesize
[3]; //0F0000
111 } PACKED mfdes_file_t
;
113 typedef struct mfdes_linear
{
115 uint8_t fid
[2]; //03E1
117 uint8_t access_rights
[2]; ///EEEE
118 uint8_t recordsize
[3];
119 uint8_t maxnumrecords
[3];
120 } PACKED mfdes_linear_t
;
122 typedef struct mfdes_value_file
{
125 uint8_t access_rights
[2]; ///EEEE
126 uint8_t lowerlimit
[4];
127 uint8_t upperlimit
[4];
129 uint8_t limitedcreditenabled
;
130 } PACKED mfdes_value_file_t
;
153 DESFIRE_UNKNOWN_PROD
= 0,
155 DESFIRE_LIGHT_PHYSICAL
,
156 DESFIRE_MICROCONTROLLER
,
161 typedef struct dfname
{
167 typedef struct aidhdr
{
180 static const mfdesCommonAID_t commonAids
[] = {
182 { "\xf4\x81\x2f", "Gallagher card data application" },
183 { "\xf4\x81\x20", "Gallagher card application directory" }, // Can be 0xF48120 - 0xF4812B, but I've only ever seen 0xF48120
186 static int CmdHelp(const char *Cmd
);
188 static int CLIGetUint32Hex(CLIParserContext
*ctx
, uint8_t paramnum
, uint32_t defaultValue
, uint32_t *value
, bool *valuePresent
, uint8_t nlen
, const char *lengthErrorStr
) {
189 *value
= defaultValue
;
190 if (valuePresent
!= NULL
)
191 *valuePresent
= false;
193 int res
= arg_get_u32_hexstr_def_nlen(ctx
, paramnum
, defaultValue
, value
, nlen
, true);
195 if (valuePresent
!= NULL
)
196 *valuePresent
= (res
== 1);
199 PrintAndLogEx(ERR
, lengthErrorStr
);
210 The 7 MSBits (= n) code the storage size itself based on 2^n,
211 the LSBit is set to '0' if the size is exactly 2^n
212 and set to '1' if the storage size is between 2^n and 2^(n+1).
213 For this version of DESFire the 7 MSBits are set to 0x0C (2^12 = 4096) and the LSBit is '0'.
215 static char *getCardSizeStr(uint8_t fsize
) {
217 static char buf
[40] = {0x00};
220 uint16_t usize
= 1 << (((uint16_t)fsize
>> 1) + 1);
221 uint16_t lsize
= 1 << ((uint16_t)fsize
>> 1);
225 snprintf(retStr
, sizeof(buf
), "0x%02X ( " _GREEN_("%d - %d bytes") " )", fsize
, usize
, lsize
);
227 snprintf(retStr
, sizeof(buf
), "0x%02X ( " _GREEN_("%d bytes") " )", fsize
, lsize
);
231 static char *getProtocolStr(uint8_t id
, bool hw
) {
233 static char buf
[50] = {0x00};
237 snprintf(retStr
, sizeof(buf
), "0x%02X ( " _YELLOW_("ISO 14443-3 MIFARE, 14443-4") " )", id
);
238 } else if (id
== 0x05) {
240 snprintf(retStr
, sizeof(buf
), "0x%02X ( " _YELLOW_("ISO 14443-2, 14443-3") " )", id
);
242 snprintf(retStr
, sizeof(buf
), "0x%02X ( " _YELLOW_("ISO 14443-3, 14443-4") " )", id
);
244 snprintf(retStr
, sizeof(buf
), "0x%02X ( " _YELLOW_("Unknown") " )", id
);
249 static char *getVersionStr(uint8_t type
, uint8_t major
, uint8_t minor
) {
251 static char buf
[40] = {0x00};
254 if (type
== 0x01 && major
== 0x00)
255 snprintf(retStr
, sizeof(buf
), "%x.%x ( " _GREEN_("DESFire MF3ICD40") " )", major
, minor
);
256 else if (major
== 0x10 && minor
== 0x00)
257 snprintf(retStr
, sizeof(buf
), "%x.%x ( " _GREEN_("NTAG413DNA") " )", major
, minor
);
258 else if (type
== 0x01 && major
== 0x01 && minor
== 0x00)
259 snprintf(retStr
, sizeof(buf
), "%x.%x ( " _GREEN_("DESFire EV1") " )", major
, minor
);
260 else if (type
== 0x01 && major
== 0x12 && minor
== 0x00)
261 snprintf(retStr
, sizeof(buf
), "%x.%x ( " _GREEN_("DESFire EV2") " )", major
, minor
);
262 else if (type
== 0x01 && major
== 0x22 && minor
== 0x00)
263 snprintf(retStr
, sizeof(buf
), "%x.%x ( " _GREEN_("DESFire EV2 XL") " )", major
, minor
);
264 else if (type
== 0x01 && major
== 0x42 && minor
== 0x00)
265 snprintf(retStr
, sizeof(buf
), "%x.%x ( " _GREEN_("DESFire EV2") " )", major
, minor
);
266 else if (type
== 0x01 && major
== 0x33 && minor
== 0x00)
267 snprintf(retStr
, sizeof(buf
), "%x.%x ( " _GREEN_("DESFire EV3") " )", major
, minor
);
268 else if (type
== 0x01 && major
== 0x30 && minor
== 0x00)
269 snprintf(retStr
, sizeof(buf
), "%x.%x ( " _GREEN_("DESFire Light") " )", major
, minor
);
270 else if (type
== 0x02 && major
== 0x11 && minor
== 0x00)
271 snprintf(retStr
, sizeof(buf
), "%x.%x ( " _GREEN_("Plus EV1") " )", major
, minor
);
272 else if (type
== 0x02 && major
== 0x22 && minor
== 0x00)
273 snprintf(retStr
, sizeof(buf
), "%x.%x ( " _GREEN_("Plus EV2") " )", major
, minor
);
275 snprintf(retStr
, sizeof(buf
), "%x.%x ( " _YELLOW_("Unknown") " )", major
, minor
);
278 //04 01 01 01 00 1A 05
281 static char *getTypeStr(uint8_t type
) {
283 static char buf
[40] = {0x00};
288 snprintf(retStr
, sizeof(buf
), "0x%02X ( " _YELLOW_("DESFire") " )", type
);
291 snprintf(retStr
, sizeof(buf
), "0x%02X ( " _YELLOW_("Plus") " )", type
);
294 snprintf(retStr
, sizeof(buf
), "0x%02X ( " _YELLOW_("Ultralight") " )", type
);
297 snprintf(retStr
, sizeof(buf
), "0x%02X ( " _YELLOW_("NTAG") " )", type
);
300 snprintf(retStr
, sizeof(buf
), "0x%02X ( " _YELLOW_("Smartcard") " )", type
);
309 static char noCommentStr
[1] = { 0x00 };
310 static const char *getAidCommentStr(uint8_t *aid
) {
311 for (int i
= 0; i
< ARRAYLEN(commonAids
); i
++) {
312 if (memcmp(aid
, commonAids
[i
].aid
, 3) == 0) {
313 return commonAids
[i
].comment
;
319 static nxp_cardtype_t
getCardType(uint8_t type
, uint8_t major
, uint8_t minor
) {
322 if (type
== 0x01 && major
== 0x00 && minor
== 0x02)
323 return DESFIRE_MF3ICD40
;
326 if (type
== 0x01 && major
== 0x01 && minor
== 0x00)
330 if (type
== 0x01 && major
== 0x12 && minor
== 0x00)
333 if (type
== 0x01 && major
== 0x22 && minor
== 0x00)
334 return DESFIRE_EV2_XL
;
337 if (type
== 0x01 && major
== 0x33 && minor
== 0x00)
341 if (type
== 0x08 && major
== 0x30 && minor
== 0x00)
342 return DESFIRE_LIGHT
;
344 // combo card DESFire / EMV
345 if (type
== 0x81 && major
== 0x42 && minor
== 0x00)
349 if (type
== 0x02 && major
== 0x11 && minor
== 0x00)
353 if (type
== 0x02 && major
== 0x22 && minor
== 0x00)
357 if (major
== 0x10 && minor
== 0x00)
361 if (type
== 0x04 && major
== 0x30 && minor
== 0x00)
364 return DESFIRE_UNKNOWN
;
367 // ref: https://www.nxp.com/docs/en/application-note/AN12343.pdf p7
368 static nxp_producttype_t
getProductType(const uint8_t *versionhw
) {
370 uint8_t product
= versionhw
[2];
373 return DESFIRE_PHYSICAL
;
375 return DESFIRE_LIGHT_PHYSICAL
;
376 if (product
== 0x81 || product
== 0x83)
377 return DESFIRE_MICROCONTROLLER
;
379 return DESFIRE_JAVACARD
;
382 return DESFIRE_UNKNOWN_PROD
;
385 static const char *getProductTypeStr(const uint8_t *versionhw
) {
387 uint8_t product
= versionhw
[2];
390 return "MIFARE DESFire native IC (physical card)";
392 return "MIFARE DESFire Light native IC (physical card)";
393 if (product
== 0x81 || product
== 0x83)
394 return "MIFARE DESFire implementation on microcontroller (physical card)";
396 return "MIFARE DESFire applet on Java card / secure element";
398 return "MIFARE DESFire HCE (MIFARE 2GO)";
399 return "UNKNOWN PROD";
402 static int mfdes_get_info(mfdes_info_res_t
*info
) {
404 PacketResponseNG resp
;
405 SendCommandNG(CMD_HF_DESFIRE_INFO
, NULL
, 0);
406 if (WaitForResponseTimeout(CMD_HF_DESFIRE_INFO
, &resp
, 1500) == false) {
407 PrintAndLogEx(WARNING
, "Command execute timeout");
412 memcpy(info
, resp
.data
.asBytes
, sizeof(mfdes_info_res_t
));
414 if (resp
.status
!= PM3_SUCCESS
) {
416 switch (info
->isOK
) {
418 PrintAndLogEx(WARNING
, "Can't select card");
421 PrintAndLogEx(WARNING
, "Card is most likely not DESFire. Wrong size UID");
425 PrintAndLogEx(WARNING
, _RED_("Command unsuccessful"));
435 int desfire_print_signature(uint8_t *uid
, uint8_t uidlen
, uint8_t *signature
, size_t signature_len
) {
438 PrintAndLogEx(DEBUG
, "UID=NULL");
441 if (signature
== NULL
) {
442 PrintAndLogEx(DEBUG
, "SIGNATURE=NULL");
445 // ref: MIFARE Desfire Originality Signature Validation
446 // See tools/recover_pk.py to recover Pk from UIDs and signatures
447 #define PUBLIC_DESFIRE_ECDA_KEYLEN 57
448 const ecdsa_publickey_t nxp_desfire_public_keys
[] = {
449 {"NTAG424DNA, DESFire Ev2", "048A9B380AF2EE1B98DC417FECC263F8449C7625CECE82D9B916C992DA209D68422B81EC20B65A66B5102A61596AF3379200599316A00A1410"},
450 {"NTAG413DNA, DESFire Ev1", "04BB5D514F7050025C7D0F397310360EEC91EAF792E96FC7E0F496CB4E669D414F877B7B27901FE67C2E3B33CD39D1C797715189AC951C2ADD"},
451 {"DESFire Ev2", "04B304DC4C615F5326FE9383DDEC9AA892DF3A57FA7FFB3276192BC0EAA252ED45A865E3B093A3D0DCE5BE29E92F1392CE7DE321E3E5C52B3A"},
452 {"DESFire Ev3", "041DB46C145D0A36539C6544BD6D9B0AA62FF91EC48CBC6ABAE36E0089A46F0D08C8A715EA40A63313B92E90DDC1730230E0458A33276FB743"},
453 {"NTAG424DNA, NTAG424DNATT, DESFire Light Ev2", "04B304DC4C615F5326FE9383DDEC9AA892DF3A57FA7FFB3276192BC0EAA252ED45A865E3B093A3D0DCE5BE29E92F1392CE7DE321E3E5C52B3B"},
454 {"DESFire Light", "040E98E117AAA36457F43173DC920A8757267F44CE4EC5ADD3C54075571AEBBF7B942A9774A1D94AD02572427E5AE0A2DD36591B1FB34FCF3D"},
455 {"MIFARE Plus Ev1", "044409ADC42F91A8394066BA83D872FB1D16803734E911170412DDF8BAD1A4DADFD0416291AFE1C748253925DA39A5F39A1C557FFACD34C62E"},
456 {"MIFARE Plus Ev2", "04BB49AE4447E6B1B6D21C098C1538B594A11A4A1DBF3D5E673DEACDEB3CC512D1C08AFA1A2768CE20A200BACD2DC7804CD7523A0131ABF607"},
457 {"DESFire Ev2 XL", "04CD5D45E50B1502F0BA4656FF37669597E7E183251150F9574CC8DA56BF01C7ABE019E29FEA48F9CE22C3EA4029A765E1BC95A89543BAD1BC"},
458 {"MIFARE Plus Troika", "040F732E0EA7DF2B38F791BF89425BF7DCDF3EE4D976669E3831F324FF15751BD52AFF1782F72FF2731EEAD5F63ABE7D126E03C856FFB942AF"},
463 bool is_valid
= false;
465 for (i
= 0; i
< ARRAYLEN(nxp_desfire_public_keys
); i
++) {
468 uint8_t key
[PUBLIC_DESFIRE_ECDA_KEYLEN
];
469 param_gethex_to_eol(nxp_desfire_public_keys
[i
].value
, 0, key
, PUBLIC_DESFIRE_ECDA_KEYLEN
, &dl
);
471 int res
= ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP224R1
, key
, uid
, uidlen
, signature
, signature_len
, false);
472 is_valid
= (res
== 0);
476 // PrintAndLogEx(NORMAL, "");
477 // PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature"));
478 if (is_valid
== false || i
== ARRAYLEN(nxp_desfire_public_keys
)) {
479 PrintAndLogEx(INFO
, " Elliptic curve parameters: NID_secp224r1");
480 PrintAndLogEx(INFO
, " TAG IC Signature: %s", sprint_hex_inrow(signature
, 16));
481 PrintAndLogEx(INFO
, " : %s", sprint_hex_inrow(signature
+ 16, 16));
482 PrintAndLogEx(INFO
, " : %s", sprint_hex_inrow(signature
+ 32, 16));
483 PrintAndLogEx(INFO
, " : %s", sprint_hex_inrow(signature
+ 48, signature_len
- 48));
484 PrintAndLogEx(SUCCESS
, " Signature verification: " _RED_("failed"));
488 PrintAndLogEx(INFO
, " IC signature public key name: " _GREEN_("%s"), nxp_desfire_public_keys
[i
].desc
);
489 PrintAndLogEx(INFO
, "IC signature public key value: %.32s", nxp_desfire_public_keys
[i
].value
);
490 PrintAndLogEx(INFO
, " : %.32s", nxp_desfire_public_keys
[i
].value
+ 32);
491 PrintAndLogEx(INFO
, " : %.32s", nxp_desfire_public_keys
[i
].value
+ 64);
492 PrintAndLogEx(INFO
, " : %.32s", nxp_desfire_public_keys
[i
].value
+ 96);
493 PrintAndLogEx(INFO
, " Elliptic curve parameters: NID_secp224r1");
494 PrintAndLogEx(INFO
, " TAG IC Signature: %s", sprint_hex_inrow(signature
, 16));
495 PrintAndLogEx(INFO
, " : %s", sprint_hex_inrow(signature
+ 16, 16));
496 PrintAndLogEx(INFO
, " : %s", sprint_hex_inrow(signature
+ 32, 16));
497 PrintAndLogEx(INFO
, " : %s", sprint_hex_inrow(signature
+ 48, signature_len
- 48));
498 PrintAndLogEx(SUCCESS
, " Signature verification: " _GREEN_("successful"));
502 static void swap24(uint8_t *data
) {
503 if (data
== NULL
) return;
504 uint8_t tmp
= data
[0];
509 // default parameters
510 static uint8_t defaultKeyNum
= 0;
511 static DesfireCryptoAlgorithm defaultAlgoId
= T_DES
;
512 static uint8_t defaultKey
[DESFIRE_MAX_KEY_SIZE
] = {0};
513 static int defaultKdfAlgo
= MFDES_KDF_ALGO_NONE
;
514 static int defaultKdfInputLen
= 0;
515 static uint8_t defaultKdfInput
[50] = {0};
516 static DesfireSecureChannel defaultSecureChannel
= DACEV1
;
517 static DesfireCommandSet defaultCommSet
= DCCNativeISO
;
518 static DesfireCommunicationMode defaultCommMode
= DCMPlain
;
519 static uint32_t transactionCounter
= 0;
521 static int CmdDesGetSessionParameters(CLIParserContext
*ctx
, DesfireContext_t
*dctx
,
522 uint8_t keynoid
, uint8_t algoid
, uint8_t keyid
,
523 uint8_t kdfid
, uint8_t kdfiid
,
524 uint8_t cmodeid
, uint8_t ccsetid
, uint8_t schannid
,
528 DesfireCommunicationMode defcommmode
,
530 DesfireISOSelectWay
*selectway
) {
532 uint8_t keynum
= defaultKeyNum
;
533 int algores
= defaultAlgoId
;
534 uint8_t key
[DESFIRE_MAX_KEY_SIZE
] = {0};
535 memcpy(key
, defaultKey
, DESFIRE_MAX_KEY_SIZE
);
537 int kdfAlgo
= defaultKdfAlgo
;
539 int kdfInputLen
= defaultKdfInputLen
;
540 uint8_t kdfInput
[50] = {0};
541 memcpy(kdfInput
, defaultKdfInput
, defaultKdfInputLen
);
543 int commmode
= defaultCommMode
;
544 if (defcommmode
!= DCMNone
)
545 commmode
= defcommmode
;
547 int commset
= defaultCommSet
;
548 int secchann
= defaultSecureChannel
;
551 keynum
= arg_get_int_def(ctx
, keynoid
, keynum
);
555 if (CLIGetOptionList(arg_get_str(ctx
, algoid
), DesfireAlgoOpts
, &algores
)) {
562 uint8_t keydata
[200] = {0};
563 if (CLIParamHexToBuf(arg_get_str(ctx
, keyid
), keydata
, sizeof(keydata
), &keylen
)) {
567 if (keylen
&& keylen
!= desfire_get_key_length(algores
)) {
568 PrintAndLogEx(ERR
, "%s key must have %d bytes length instead of %d.", CLIGetOptionListStr(DesfireAlgoOpts
, algores
), desfire_get_key_length(algores
), keylen
);
573 memcpy(key
, keydata
, keylen
);
578 if (CLIGetOptionList(arg_get_str(ctx
, kdfid
), DesfireKDFAlgoOpts
, &kdfAlgo
)) {
584 int datalen
= kdfInputLen
;
585 uint8_t data
[200] = {0};
586 if (CLIParamHexToBuf(arg_get_str(ctx
, kdfiid
), data
, sizeof(data
), &datalen
)) {
591 kdfInputLen
= datalen
;
592 memcpy(kdfInput
, data
, datalen
);
597 if (CLIGetOptionList(arg_get_str(ctx
, cmodeid
), DesfireCommunicationModeOpts
, &commmode
))
602 if (CLIGetOptionList(arg_get_str(ctx
, ccsetid
), DesfireCommandSetOpts
, &commset
))
608 if (CLIGetOptionList(arg_get_str(ctx
, schannid
), DesfireSecureChannelOpts
, &secchann
))
614 if (CLIGetUint32Hex(ctx
, appid
, 0x000000, id
, NULL
, 3, "AID must have 3 bytes length"))
617 *selectway
= ISW6bAID
;
620 if (appisoid
&& id
) {
621 uint32_t xisoid
= 0x0000;
622 bool isoidpresent
= false;
623 if (CLIGetUint32Hex(ctx
, appisoid
, 0x0000, &xisoid
, &isoidpresent
, 2, "Application ISO ID (for EF) must have 2 bytes length"))
627 *id
= xisoid
& 0xffff;
629 *selectway
= ISWIsoID
;
633 DesfireSetKey(dctx
, keynum
, algores
, key
);
634 DesfireSetKdf(dctx
, kdfAlgo
, kdfInput
, kdfInputLen
);
635 DesfireSetCommandSet(dctx
, commset
);
636 DesfireSetCommMode(dctx
, commmode
);
638 *securechannel
= secchann
;
643 static int CmdHF14ADesDefault(const char *Cmd
) {
644 CLIParserContext
*ctx
;
645 CLIParserInit(&ctx
, "hf mfdes default",
646 "Set default parameters for access to MIFARE DESfire card.",
647 "hf mfdes default -n 0 -t des -k 0000000000000000 --kdf none -> save to the default parameters");
651 arg_int0("n", "keyno", "<dec>", "Key number"),
652 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
653 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
654 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
655 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
656 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
657 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
658 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
661 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
663 DesfireContext_t dctx
;
664 int securechann
= defaultSecureChannel
;
665 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, &securechann
, DCMNone
, NULL
, NULL
);
673 defaultKeyNum
= dctx
.keyNum
;
674 defaultAlgoId
= dctx
.keyType
;
675 memcpy(defaultKey
, dctx
.key
, DESFIRE_MAX_KEY_SIZE
);
676 defaultKdfAlgo
= dctx
.kdfAlgo
;
677 defaultKdfInputLen
= dctx
.kdfInputLen
;
678 memcpy(defaultKdfInput
, dctx
.kdfInput
, sizeof(dctx
.kdfInput
));
679 defaultSecureChannel
= securechann
;
680 defaultCommSet
= dctx
.cmdSet
;
681 defaultCommMode
= dctx
.commMode
;
683 PrintAndLogEx(INFO
, "-----------" _CYAN_("Default parameters") "---------------------------------");
685 PrintAndLogEx(INFO
, "Key Num : %d", defaultKeyNum
);
686 PrintAndLogEx(INFO
, "Algo : %s", CLIGetOptionListStr(DesfireAlgoOpts
, defaultAlgoId
));
687 PrintAndLogEx(INFO
, "Key : %s", sprint_hex(defaultKey
, desfire_get_key_length(defaultAlgoId
)));
688 PrintAndLogEx(INFO
, "KDF algo : %s", CLIGetOptionListStr(DesfireKDFAlgoOpts
, defaultKdfAlgo
));
689 PrintAndLogEx(INFO
, "KDF input : [%d] %s", defaultKdfInputLen
, sprint_hex(defaultKdfInput
, defaultKdfInputLen
));
690 PrintAndLogEx(INFO
, "Secure chan : %s", CLIGetOptionListStr(DesfireSecureChannelOpts
, defaultSecureChannel
));
691 PrintAndLogEx(INFO
, "Command set : %s", CLIGetOptionListStr(DesfireCommandSetOpts
, defaultCommSet
));
692 PrintAndLogEx(INFO
, "Comm mode : %s", CLIGetOptionListStr(DesfireCommunicationModeOpts
, defaultCommMode
));
697 static int CmdHF14ADesInfo(const char *Cmd
) {
698 CLIParserContext
*ctx
;
699 CLIParserInit(&ctx
, "hf mfdes info",
700 "Get info from MIFARE DESfire tags",
707 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
710 SetAPDULogging(false);
713 mfdes_info_res_t info
;
714 int res
= mfdes_get_info(&info
);
715 if (res
!= PM3_SUCCESS
) {
720 nxp_cardtype_t cardtype
= getCardType(info
.versionHW
[1], info
.versionHW
[3], info
.versionHW
[4]);
721 if (cardtype
== PLUS_EV1
) {
722 PrintAndLogEx(INFO
, "Card seems to be MIFARE Plus EV1. Try " _YELLOW_("`hf mfp info`"));
727 if (cardtype
== PLUS_EV2
) {
728 PrintAndLogEx(INFO
, "Card seems to be MIFARE Plus EV2. Try " _YELLOW_("`hf mfp info`"));
733 if (cardtype
== NTAG424
) {
734 PrintAndLogEx(INFO
, "Card seems to be NTAG 424. Try " _YELLOW_("`hf ntag424 info`"));
739 if (cardtype
== DESFIRE_UNKNOWN
) {
740 PrintAndLogEx(INFO
, "HW Version.. %s", sprint_hex_inrow(info
.versionHW
, sizeof(info
.versionHW
)));
741 PrintAndLogEx(INFO
, "SW Version.. %s", sprint_hex_inrow(info
.versionSW
, sizeof(info
.versionSW
)));
742 PrintAndLogEx(INFO
, "Version data identification failed. Report to Iceman!");
747 PrintAndLogEx(NORMAL
, "");
748 PrintAndLogEx(INFO
, "---------------------------------- " _CYAN_("Tag Information") " ----------------------------------");
749 PrintAndLogEx(SUCCESS
, " UID: " _GREEN_("%s"), sprint_hex(info
.uid
, info
.uidlen
));
750 PrintAndLogEx(SUCCESS
, " Batch number: " _GREEN_("%s"), sprint_hex(info
.details
+ 7, 5));
751 PrintAndLogEx(SUCCESS
, " Production date: week " _GREEN_("%02x") " / " _GREEN_("20%02x"), info
.details
[12], info
.details
[13]);
753 nxp_producttype_t prodtype
= getProductType(info
.versionHW
);
754 if (prodtype
!= DESFIRE_UNKNOWN_PROD
) {
755 PrintAndLogEx(SUCCESS
, " Product type: %s", getProductTypeStr(info
.versionHW
));
758 PrintAndLogEx(NORMAL
, "");
759 PrintAndLogEx(INFO
, "--- " _CYAN_("Hardware Information"));
760 PrintAndLogEx(INFO
, " raw: %s", sprint_hex_inrow(info
.versionHW
, sizeof(info
.versionHW
)));
762 PrintAndLogEx(INFO
, " Vendor Id: " _YELLOW_("%s"), getTagInfo(info
.versionHW
[0]));
763 PrintAndLogEx(INFO
, " Type: %s", getTypeStr(info
.versionHW
[1]));
764 PrintAndLogEx(INFO
, " Subtype: " _YELLOW_("0x%02X"), info
.versionHW
[2]);
765 PrintAndLogEx(INFO
, " Version: %s", getVersionStr(info
.versionHW
[1], info
.versionHW
[3], info
.versionHW
[4]));
766 PrintAndLogEx(INFO
, " Storage size: %s", getCardSizeStr(info
.versionHW
[5]));
767 PrintAndLogEx(INFO
, " Protocol: %s", getProtocolStr(info
.versionHW
[6], true));
768 PrintAndLogEx(NORMAL
, "");
769 PrintAndLogEx(INFO
, "--- " _CYAN_("Software Information"));
770 PrintAndLogEx(INFO
, " raw: %s", sprint_hex_inrow(info
.versionSW
, sizeof(info
.versionSW
)));
771 PrintAndLogEx(INFO
, " Vendor Id: " _YELLOW_("%s"), getTagInfo(info
.versionSW
[0]));
772 PrintAndLogEx(INFO
, " Type: %s", getTypeStr(info
.versionSW
[1]));
773 PrintAndLogEx(INFO
, " Subtype: " _YELLOW_("0x%02X"), info
.versionSW
[2]);
774 PrintAndLogEx(INFO
, " Version: " _YELLOW_("%d.%d"), info
.versionSW
[3], info
.versionSW
[4]);
775 PrintAndLogEx(INFO
, " Storage size: %s", getCardSizeStr(info
.versionSW
[5]));
776 PrintAndLogEx(INFO
, " Protocol: %s", getProtocolStr(info
.versionSW
[6], false));
777 PrintAndLogEx(NORMAL
, "");
778 PrintAndLogEx(INFO
, "--------------------------------- " _CYAN_("Card capabilities") " ---------------------------------");
779 uint8_t major
= info
.versionSW
[3];
780 uint8_t minor
= info
.versionSW
[4];
781 if (major
== 0 && minor
== 4)
782 PrintAndLogEx(INFO
, "\t0.4 - DESFire MF3ICD40, No support for APDU (only native commands)");
783 if (major
== 0 && minor
== 5)
784 PrintAndLogEx(INFO
, "\t0.5 - DESFire MF3ICD40, Support for wrapping commands inside ISO 7816 style APDUs");
785 if (major
== 0 && minor
== 6)
786 PrintAndLogEx(INFO
, "\t0.6 - DESFire MF3ICD40, Add ISO/IEC 7816 command set compatibility");
787 if (major
== 1 && minor
== 3)
788 PrintAndLogEx(INFO
, "\t1.3 - DESFire Ev1 MF3ICD21/41/81, Support extended APDU commands, EAL4+");
789 if (major
== 1 && minor
== 4)
790 PrintAndLogEx(INFO
, "\t1.4 - DESFire Ev1 MF3ICD21/41/81, EAL4+");
791 if (major
== 2 && minor
== 0)
792 PrintAndLogEx(INFO
, "\t2.0 - DESFire Ev2, Originality check, proximity check, EAL5");
793 if (major
== 2 && minor
== 2)
794 PrintAndLogEx(INFO
, "\t2.2 - DESFire Ev2 XL, Originality check, proximity check, EAL5");
795 if (major
== 3 && minor
== 0)
796 PrintAndLogEx(INFO
, "\t3.0 - DESFire Ev3, Originality check, proximity check, badass EAL6 ?");
798 if (major
== 0 && minor
== 2)
799 PrintAndLogEx(INFO
, "\t0.2 - DESFire Light, Originality check, ");
801 DesfireContext_t dctx
= {0};
802 dctx
.commMode
= DCMPlain
;
803 dctx
.cmdSet
= DCCNative
;
805 res
= DesfireAnticollision(false);
806 if (res
!= PM3_SUCCESS
) {
811 if (cardtype
== DESFIRE_EV2
|| cardtype
== DESFIRE_EV2_XL
||
812 cardtype
== DESFIRE_LIGHT
||
813 cardtype
== DESFIRE_EV3
||
814 cardtype
== NTAG413DNA
) {
815 // Signature originality check
816 uint8_t signature
[250] = {0}; // must be 56
817 size_t signature_len
= 0;
819 PrintAndLogEx(NORMAL
, "");
820 PrintAndLogEx(INFO
, "--- " _CYAN_("Tag Signature"));
821 res
= DesfireReadSignature(&dctx
, 0x00, signature
, &signature_len
);
822 if (res
== PM3_SUCCESS
) {
823 if (signature_len
== 56)
824 desfire_print_signature(info
.uid
, info
.uidlen
, signature
, signature_len
);
826 PrintAndLogEx(WARNING
, "--- GetSignature returned wrong signature length: %zu", signature_len
);
828 PrintAndLogEx(WARNING
, "--- Card doesn't support GetSignature cmd");
832 PICCInfo_t PICCInfo
= {0};
834 uint8_t aidbuf
[250] = {0};
835 size_t aidbuflen
= 0;
836 res
= DesfireGetAIDList(&dctx
, aidbuf
, &aidbuflen
);
837 if (res
== PM3_SUCCESS
) {
838 PICCInfo
.appCount
= aidbuflen
/ 3;
842 PrintAndLogEx(NORMAL
, "");
843 PrintAndLogEx(SUCCESS
, "--- " _CYAN_("AID list"));
844 PrintAndLogEx(SUCCESS
, "AIDs: " NOLF
);
845 for (int i
= 0; i
< aidbuflen
; i
+= 3)
846 PrintAndLogEx(NORMAL
, "%s %06x" NOLF
, (i
== 0) ? "" : ",", DesfireAIDByteToUint(&aidbuf
[i
]));
847 PrintAndLogEx(NORMAL
, "\n");
850 DesfireFillPICCInfo(&dctx
, &PICCInfo
, true);
851 DesfirePrintPICCInfo(&dctx
, &PICCInfo
);
853 if (cardtype
!= DESFIRE_LIGHT
) {
854 // Free memory on card
855 PrintAndLogEx(NORMAL
, "");
856 PrintAndLogEx(INFO
, "--- " _CYAN_("Free memory"));
857 if (PICCInfo
.freemem
!= 0xffffffff) {
858 PrintAndLogEx(SUCCESS
, " Available free memory on card : " _GREEN_("%d bytes"), PICCInfo
.freemem
);
860 PrintAndLogEx(SUCCESS
, " Card doesn't support 'free mem' cmd");
864 if (cardtype
== DESFIRE_LIGHT
) {
865 PrintAndLogEx(NORMAL
, "");
866 PrintAndLogEx(INFO
, "--- " _CYAN_("Desfire Light info"));
868 if (DesfireSelect(&dctx
, ISWIsoID
, 0xdf01, NULL
) == PM3_SUCCESS
) {
869 PrintAndLogEx(SUCCESS
, " Card have " _GREEN_("default (0xdf01)") " iso id for application");
871 if (DesfireCheckAuthCmd(ISWIsoID
, 0xdf01, 0, MFDES_AUTHENTICATE_EV2F
, false)) {
872 PrintAndLogEx(SUCCESS
, " Card in the " _GREEN_("AES") " mode");
873 } else if (DesfireCheckAuthCmd(ISWIsoID
, 0xdf01, 0, MFDES_AUTHENTICATE_EV2F
, true)) {
874 PrintAndLogEx(SUCCESS
, " Card in the " _GREEN_("LRP") " mode");
877 PrintAndLogEx(SUCCESS
, " Card have " _RED_("not a default") " iso id for application");
880 if (DesfireCheckAuthCmd(ISWIsoID
, 0x3f00, 1, MFDES_AUTHENTICATE_EV2F
, true)) {
881 PrintAndLogEx(SUCCESS
, " Card have " _GREEN_("LRP") " key in the MF/key1");
885 PrintAndLogEx(NORMAL
, "");
887 iso14a_card_select_t card
;
888 res
= SelectCard14443A_4(true, false, &card
);
889 if (res
== PM3_SUCCESS
) {
890 static const uint8_t STANDALONE_DESFIRE
[] = { 0x75, 0x77, 0x81, 0x02 };
891 static const uint8_t JCOP_DESFIRE
[] = { 0x75, 0xf7, 0xb1, 0x02 };
892 static const uint8_t JCOP3_DESFIRE
[] = { 0x78, 0x77, 0x71, 0x02 };
894 if (card
.sak
== 0x20) {
896 if (card
.ats_len
>= 5) {
897 if (0 == memcmp(card
.ats
+ 1, STANDALONE_DESFIRE
, 4)) {
898 PrintAndLogEx(INFO
, "Standalone DESFire");
900 if (0 == memcmp(card
.ats
+ 1, JCOP_DESFIRE
, 4)) {
901 PrintAndLogEx(INFO
, "JCOP DESFire");
904 if (card
.ats_len
== 4) {
905 if (0 == memcmp(card
.ats
+ 1, JCOP3_DESFIRE
, 4)) {
906 PrintAndLogEx(INFO
, "JCOP3 DESFire");
913 Card Master key (CMK) 0x00 AID = 00 00 00 (card level)
914 Application Master Key (AMK) 0x00 AID != 00 00 00
915 Application keys (APK) 0x01-0x0D
916 Application free 0x0E
917 Application never 0x0F
931 static void DesFill2bPattern(
932 uint8_t deskeyList
[MAX_KEYS_LIST_LEN
][8], uint32_t *deskeyListLen
,
933 uint8_t aeskeyList
[MAX_KEYS_LIST_LEN
][16], uint32_t *aeskeyListLen
,
934 uint8_t k3kkeyList
[MAX_KEYS_LIST_LEN
][24], uint32_t *k3kkeyListLen
, uint32_t *startPattern
) {
936 for (uint32_t pt
= *startPattern
; pt
< 0x10000; pt
++) {
937 if (*deskeyListLen
!= MAX_KEYS_LIST_LEN
) {
938 deskeyList
[*deskeyListLen
][0] = (pt
>> 8) & 0xff;
939 deskeyList
[*deskeyListLen
][1] = pt
& 0xff;
940 memcpy(&deskeyList
[*deskeyListLen
][2], &deskeyList
[*deskeyListLen
][0], 2);
941 memcpy(&deskeyList
[*deskeyListLen
][4], &deskeyList
[*deskeyListLen
][0], 4);
944 if (*aeskeyListLen
!= MAX_KEYS_LIST_LEN
) {
945 aeskeyList
[*aeskeyListLen
][0] = (pt
>> 8) & 0xff;
946 aeskeyList
[*aeskeyListLen
][1] = pt
& 0xff;
947 memcpy(&aeskeyList
[*aeskeyListLen
][2], &aeskeyList
[*aeskeyListLen
][0], 2);
948 memcpy(&aeskeyList
[*aeskeyListLen
][4], &aeskeyList
[*aeskeyListLen
][0], 4);
949 memcpy(&aeskeyList
[*aeskeyListLen
][8], &aeskeyList
[*aeskeyListLen
][0], 8);
952 if (*k3kkeyListLen
!= MAX_KEYS_LIST_LEN
) {
953 k3kkeyList
[*k3kkeyListLen
][0] = (pt
>> 8) & 0xff;
954 k3kkeyList
[*k3kkeyListLen
][1] = pt
& 0xff;
955 memcpy(&k3kkeyList
[*k3kkeyListLen
][2], &k3kkeyList
[*k3kkeyListLen
][0], 2);
956 memcpy(&k3kkeyList
[*k3kkeyListLen
][4], &k3kkeyList
[*k3kkeyListLen
][0], 4);
957 memcpy(&k3kkeyList
[*k3kkeyListLen
][8], &k3kkeyList
[*k3kkeyListLen
][0], 8);
958 memcpy(&k3kkeyList
[*k3kkeyListLen
][16], &k3kkeyList
[*k3kkeyListLen
][0], 4);
963 if ((*deskeyListLen
== MAX_KEYS_LIST_LEN
) &&
964 (*aeskeyListLen
== MAX_KEYS_LIST_LEN
) &&
965 (*k3kkeyListLen
== MAX_KEYS_LIST_LEN
)) {
972 static int AuthCheckDesfire(DesfireContext_t
*dctx
,
973 DesfireSecureChannel secureChannel
,
975 uint8_t deskeyList
[MAX_KEYS_LIST_LEN
][8], uint32_t deskeyListLen
,
976 uint8_t aeskeyList
[MAX_KEYS_LIST_LEN
][16], uint32_t aeskeyListLen
,
977 uint8_t k3kkeyList
[MAX_KEYS_LIST_LEN
][24], uint32_t k3kkeyListLen
,
978 uint8_t cmdKdfAlgo
, uint8_t kdfInputLen
, uint8_t *kdfInput
,
979 uint8_t foundKeys
[4][0xE][24 + 1],
983 uint32_t curaid
= (aid
[0] & 0xFF) + ((aid
[1] & 0xFF) << 8) + ((aid
[2] & 0xFF) << 16);
985 int res
= DesfireSelectAIDHex(dctx
, curaid
, false, 0);
986 if (res
!= PM3_SUCCESS
) {
987 PrintAndLogEx(ERR
, "AID 0x%06X does not exist.", curaid
);
992 int usedkeys
[0xF] = {0};
998 uint8_t data
[250] = {0};
1001 res
= DesfireGetKeySettings(dctx
, data
, &datalen
);
1002 if (res
!= PM3_SUCCESS
&& datalen
< 2) {
1003 PrintAndLogEx(ERR
, "Could not get key settings");
1006 uint8_t num_keys
= data
[1];
1007 switch (num_keys
>> 6) {
1022 // always check master key
1026 FileList_t fileList
= {{0}};
1027 size_t filescount
= 0;
1028 bool isopresent
= 0;
1029 res
= DesfireFillFileList(dctx
, fileList
, &filescount
, &isopresent
);
1030 if (res
== PM3_SUCCESS
) {
1031 if (filescount
> 0) {
1032 for (int i
= 0; i
< filescount
; i
++) {
1033 if (fileList
[i
].fileSettings
.rAccess
< 0x0e)
1034 usedkeys
[fileList
[i
].fileSettings
.rAccess
] = 1;
1035 if (fileList
[i
].fileSettings
.wAccess
< 0x0e)
1036 usedkeys
[fileList
[i
].fileSettings
.wAccess
] = 1;
1037 if (fileList
[i
].fileSettings
.rwAccess
< 0x0e)
1038 usedkeys
[fileList
[i
].fileSettings
.rwAccess
] = 1;
1039 if (fileList
[i
].fileSettings
.chAccess
< 0x0e)
1040 usedkeys
[fileList
[i
].fileSettings
.chAccess
] = 1;
1043 for (int i
= 0; i
< 0xE; i
++)
1047 for (int i
= 0; i
< 0xE; i
++)
1053 PrintAndLogEx(INFO
, "Check: %s %s %s %s " NOLF
, (des
) ? "DES" : "", (tdes
) ? "2TDEA" : "", (k3kdes
) ? "3TDEA" : "", (aes
) ? "AES" : "");
1054 PrintAndLogEx(NORMAL
, "keys: " NOLF
);
1055 for (int i
= 0; i
< 0xE; i
++)
1056 if (usedkeys
[i
] == 1)
1057 PrintAndLogEx(NORMAL
, "%02x " NOLF
, i
);
1058 PrintAndLogEx(NORMAL
, "");
1061 bool badlen
= false;
1065 for (uint8_t keyno
= 0; keyno
< 0xE; keyno
++) {
1067 if (usedkeys
[keyno
] == 1 && foundKeys
[0][keyno
][0] == 0) {
1068 for (uint32_t curkey
= 0; curkey
< deskeyListLen
; curkey
++) {
1069 DesfireSetKeyNoClear(dctx
, keyno
, T_DES
, deskeyList
[curkey
]);
1070 res
= DesfireAuthenticate(dctx
, secureChannel
, false);
1071 if (res
== PM3_SUCCESS
) {
1072 PrintAndLogEx(SUCCESS
, "AID 0x%06X, Found DES Key %02u : " _GREEN_("%s"), curaid
, keyno
, sprint_hex(deskeyList
[curkey
], 8));
1073 foundKeys
[0][keyno
][0] = 0x01;
1075 memcpy(&foundKeys
[0][keyno
][1], deskeyList
[curkey
], 8);
1077 } else if (res
< 7) {
1080 res
= DesfireSelectAIDHex(dctx
, curaid
, false, 0);
1081 if (res
!= PM3_SUCCESS
) {
1087 if (badlen
== true) {
1097 for (uint8_t keyno
= 0; keyno
< 0xE; keyno
++) {
1099 if (usedkeys
[keyno
] == 1 && foundKeys
[1][keyno
][0] == 0) {
1100 for (uint32_t curkey
= 0; curkey
< aeskeyListLen
; curkey
++) {
1101 DesfireSetKeyNoClear(dctx
, keyno
, T_3DES
, aeskeyList
[curkey
]);
1102 res
= DesfireAuthenticate(dctx
, secureChannel
, false);
1103 if (res
== PM3_SUCCESS
) {
1104 PrintAndLogEx(SUCCESS
, "AID 0x%06X, Found 2TDEA Key %02u : " _GREEN_("%s"), curaid
, keyno
, sprint_hex(aeskeyList
[curkey
], 16));
1105 foundKeys
[1][keyno
][0] = 0x01;
1107 memcpy(&foundKeys
[1][keyno
][1], aeskeyList
[curkey
], 16);
1109 } else if (res
< 7) {
1112 res
= DesfireSelectAIDHex(dctx
, curaid
, false, 0);
1113 if (res
!= PM3_SUCCESS
) {
1119 if (badlen
== true) {
1129 for (uint8_t keyno
= 0; keyno
< 0xE; keyno
++) {
1131 if (usedkeys
[keyno
] == 1 && foundKeys
[2][keyno
][0] == 0) {
1132 for (uint32_t curkey
= 0; curkey
< aeskeyListLen
; curkey
++) {
1133 DesfireSetKeyNoClear(dctx
, keyno
, T_AES
, aeskeyList
[curkey
]);
1134 res
= DesfireAuthenticate(dctx
, secureChannel
, false);
1135 if (res
== PM3_SUCCESS
) {
1136 PrintAndLogEx(SUCCESS
, "AID 0x%06X, Found AES Key %02u : " _GREEN_("%s"), curaid
, keyno
, sprint_hex(aeskeyList
[curkey
], 16));
1137 foundKeys
[2][keyno
][0] = 0x01;
1139 memcpy(&foundKeys
[2][keyno
][1], aeskeyList
[curkey
], 16);
1141 } else if (res
< 7) {
1144 res
= DesfireSelectAIDHex(dctx
, curaid
, false, 0);
1145 if (res
!= PM3_SUCCESS
) {
1151 if (badlen
== true) {
1161 for (uint8_t keyno
= 0; keyno
< 0xE; keyno
++) {
1163 if (usedkeys
[keyno
] == 1 && foundKeys
[3][keyno
][0] == 0) {
1164 for (uint32_t curkey
= 0; curkey
< k3kkeyListLen
; curkey
++) {
1165 DesfireSetKeyNoClear(dctx
, keyno
, T_3K3DES
, k3kkeyList
[curkey
]);
1166 res
= DesfireAuthenticate(dctx
, secureChannel
, false);
1167 if (res
== PM3_SUCCESS
) {
1168 PrintAndLogEx(SUCCESS
, "AID 0x%06X, Found 3TDEA Key %02u : " _GREEN_("%s"), curaid
, keyno
, sprint_hex(k3kkeyList
[curkey
], 24));
1169 foundKeys
[3][keyno
][0] = 0x01;
1171 memcpy(&foundKeys
[3][keyno
][1], k3kkeyList
[curkey
], 16);
1173 } else if (res
< 7) {
1176 res
= DesfireSelectAIDHex(dctx
, curaid
, false, 0);
1177 if (res
!= PM3_SUCCESS
) {
1184 if (badlen
== true) {
1194 static int CmdHF14aDesChk(const char *Cmd
) {
1196 uint8_t deskeyList
[MAX_KEYS_LIST_LEN
][8] = {{0}};
1197 uint8_t aeskeyList
[MAX_KEYS_LIST_LEN
][16] = {{0}};
1198 uint8_t k3kkeyList
[MAX_KEYS_LIST_LEN
][MAX_KEY_LEN
] = {{0}};
1199 uint32_t deskeyListLen
= 0;
1200 uint32_t aeskeyListLen
= 0;
1201 uint32_t k3kkeyListLen
= 0;
1202 uint8_t foundKeys
[4][0xE][24 + 1] = {{{0}}};
1204 CLIParserContext
*ctx
;
1205 CLIParserInit(&ctx
, "hf mfdes chk",
1206 "Checks keys with MIFARE DESFire card.",
1207 "hf mfdes chk --aid 123456 -k 000102030405060708090a0b0c0d0e0f -> check key on aid 0x123456\n"
1208 "hf mfdes chk -d mfdes_default_keys -> check keys against all existing aid on card\n"
1209 "hf mfdes chk -d mfdes_default_keys --aid 123456 -> check keys against aid 0x123456\n"
1210 "hf mfdes chk --aid 123456 --pattern1b -j keys -> check all 1-byte keys pattern on aid 0x123456 and save found keys to `keys.json`\n"
1211 "hf mfdes chk --aid 123456 --pattern2b --startp2b FA00 -> check all 2-byte keys pattern on aid 0x123456. Start from key FA00FA00...FA00");
1213 void *argtable
[] = {
1215 arg_str0(NULL
, "aid", "<hex>", "Use specific AID (3 hex bytes, big endian)"),
1216 arg_str0("k", "key", "<hex>", "Key for checking (HEX 16 bytes)"),
1217 arg_str0("d", "dict", "<fn>", "Dictionary file with keys"),
1218 arg_lit0(NULL
, "pattern1b", "Check all 1-byte combinations of key (0000...0000, 0101...0101, 0202...0202, ...)"),
1219 arg_lit0(NULL
, "pattern2b", "Check all 2-byte combinations of key (0000...0000, 0001...0001, 0002...0002, ...)"),
1220 arg_str0(NULL
, "startp2b", "<pattern>", "Start key (2-byte HEX) for 2-byte search (use with `--pattern2b`)"),
1221 arg_str0("j", "json", "<fn>", "Json file name to save keys"),
1222 arg_lit0("v", "verbose", "Verbose output"),
1223 arg_int0(NULL
, "kdf", "<0|1|2>", "Key Derivation Function (KDF) (0=None, 1=AN10922, 2=Gallagher)"),
1224 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
1225 arg_lit0("a", "apdu", "Show APDU requests and responses"),
1228 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
1230 bool APDULogging
= arg_get_lit(ctx
, 11);
1233 uint8_t aid
[3] = {0};
1234 CLIGetHexWithReturn(ctx
, 1, aid
, &aidlength
);
1236 uint8_t vkey
[16] = {0};
1238 CLIGetHexWithReturn(ctx
, 2, vkey
, &vkeylen
);
1242 memcpy(&deskeyList
[deskeyListLen
], vkey
, 8);
1244 } else if (vkeylen
== 16) {
1245 memcpy(&aeskeyList
[aeskeyListLen
], vkey
, 16);
1247 } else if (vkeylen
== 24) {
1248 memcpy(&k3kkeyList
[k3kkeyListLen
], vkey
, 16);
1251 PrintAndLogEx(ERR
, "Specified key must have 8, 16 or 24 bytes length.");
1257 uint8_t dict_filename
[FILE_PATH_SIZE
+ 2] = {0};
1258 int dict_filenamelen
= 0;
1259 if (CLIParamStrToBuf(arg_get_str(ctx
, 3), dict_filename
, FILE_PATH_SIZE
, &dict_filenamelen
)) {
1260 PrintAndLogEx(FAILED
, "File name too long or invalid.");
1265 bool pattern1b
= arg_get_lit(ctx
, 4);
1266 bool pattern2b
= arg_get_lit(ctx
, 5);
1268 if (pattern1b
&& pattern2b
) {
1269 PrintAndLogEx(ERR
, "Pattern search mode must be 2-byte or 1-byte only.");
1274 if (dict_filenamelen
&& (pattern1b
|| pattern2b
)) {
1275 PrintAndLogEx(ERR
, "Pattern search mode and dictionary mode can't be used in one command.");
1280 uint32_t startPattern
= 0x0000;
1281 uint8_t vpattern
[2];
1282 int vpatternlen
= 0;
1283 CLIGetHexWithReturn(ctx
, 6, vpattern
, &vpatternlen
);
1284 if (vpatternlen
> 0) {
1285 if (vpatternlen
<= 2) {
1286 startPattern
= (vpattern
[0] << 8) + vpattern
[1];
1288 PrintAndLogEx(ERR
, "Pattern must be 2-byte length.");
1293 PrintAndLogEx(WARNING
, "Pattern entered, but search mode not is 2-byte search.");
1296 uint8_t jsonname
[250] = {0};
1297 int jsonnamelen
= 0;
1298 if (CLIParamStrToBuf(arg_get_str(ctx
, 7), jsonname
, sizeof(jsonname
), &jsonnamelen
)) {
1299 PrintAndLogEx(ERR
, "Invalid json name.");
1303 jsonname
[jsonnamelen
] = 0;
1305 bool verbose
= arg_get_lit(ctx
, 8);
1308 uint8_t cmdKDFAlgo
= arg_get_int_def(ctx
, 9, 0);
1310 uint8_t kdfInput
[31] = {0};
1311 int kdfInputLen
= 0;
1312 CLIGetHexWithReturn(ctx
, 10, kdfInput
, &kdfInputLen
);
1315 SetAPDULogging(APDULogging
);
1317 // 1-byte pattern search mode
1319 for (uint32_t i
= 0; i
< 0x100; i
++)
1320 memset(aeskeyList
[i
], i
, 16);
1321 for (uint32_t i
= 0; i
< 0x100; i
++)
1322 memset(deskeyList
[i
], i
, 8);
1323 for (uint32_t i
= 0; i
< 0x100; i
++)
1324 memset(k3kkeyList
[i
], i
, 24);
1325 aeskeyListLen
= 0x100;
1326 deskeyListLen
= 0x100;
1327 k3kkeyListLen
= 0x100;
1330 // 2-byte pattern search mode
1332 DesFill2bPattern(deskeyList
, &deskeyListLen
, aeskeyList
, &aeskeyListLen
, k3kkeyList
, &k3kkeyListLen
, &startPattern
);
1336 size_t endFilePosition
= 0;
1337 if (dict_filenamelen
) {
1339 res
= loadFileDICTIONARYEx((char *)dict_filename
, deskeyList
, sizeof(deskeyList
), NULL
, 8, &deskeyListLen
, 0, &endFilePosition
, true);
1340 if (res
== PM3_SUCCESS
&& endFilePosition
)
1341 PrintAndLogEx(SUCCESS
, "First part of des dictionary successfully loaded.");
1343 endFilePosition
= 0;
1344 res
= loadFileDICTIONARYEx((char *)dict_filename
, aeskeyList
, sizeof(aeskeyList
), NULL
, 16, &aeskeyListLen
, 0, &endFilePosition
, true);
1345 if (res
== PM3_SUCCESS
&& endFilePosition
)
1346 PrintAndLogEx(SUCCESS
, "First part of aes dictionary successfully loaded.");
1348 endFilePosition
= 0;
1349 res
= loadFileDICTIONARYEx((char *)dict_filename
, k3kkeyList
, sizeof(k3kkeyList
), NULL
, 24, &k3kkeyListLen
, 0, &endFilePosition
, true);
1350 if (res
== PM3_SUCCESS
&& endFilePosition
)
1351 PrintAndLogEx(SUCCESS
, "First part of k3kdes dictionary successfully loaded.");
1353 endFilePosition
= 0;
1356 if (aeskeyListLen
== 0 && deskeyListLen
== 0 && k3kkeyListLen
== 0) {
1357 PrintAndLogEx(ERR
, "No keys provided. Nothing to check.");
1361 if (aeskeyListLen
!= 0) {
1362 PrintAndLogEx(INFO
, "Loaded " _YELLOW_("%"PRIu32
) " aes keys", aeskeyListLen
);
1365 if (deskeyListLen
!= 0) {
1366 PrintAndLogEx(INFO
, "Loaded " _YELLOW_("%"PRIu32
) " des keys", deskeyListLen
);
1369 if (k3kkeyListLen
!= 0) {
1370 PrintAndLogEx(INFO
, "Loaded " _YELLOW_("%"PRIu32
) " k3kdes keys", k3kkeyListLen
);
1373 if (verbose
== false)
1374 PrintAndLogEx(INFO
, "Search keys:");
1376 bool result
= false;
1377 uint8_t app_ids
[78] = {0};
1378 size_t app_ids_len
= 0;
1380 clearCommandBuffer();
1382 DesfireContext_t dctx
;
1383 DesfireSetKdf(&dctx
, cmdKDFAlgo
, kdfInput
, kdfInputLen
);
1384 DesfireSetCommandSet(&dctx
, DCCNativeISO
);
1385 DesfireSetCommMode(&dctx
, DCMPlain
);
1386 DesfireSecureChannel secureChannel
= DACEV1
;
1388 // save card UID to dctx
1389 DesfireGetCardUID(&dctx
);
1391 res
= DesfireSelectAIDHex(&dctx
, 0x000000, false, 0);
1392 if (res
!= PM3_SUCCESS
) {
1393 PrintAndLogEx(ERR
, "Can't select PICC level.");
1399 res
= DesfireGetAIDList(&dctx
, app_ids
, &app_ids_len
);
1400 if (res
!= PM3_SUCCESS
) {
1401 PrintAndLogEx(ERR
, "Can't get list of applications on tag");
1406 if (aidlength
!= 0) {
1407 memcpy(&app_ids
[0], aid
, 3);
1411 for (uint32_t x
= 0; x
< app_ids_len
/ 3; x
++) {
1413 uint32_t curaid
= (app_ids
[x
* 3] & 0xFF) + ((app_ids
[(x
* 3) + 1] & 0xFF) << 8) + ((app_ids
[(x
* 3) + 2] & 0xFF) << 16);
1414 PrintAndLogEx(ERR
, "Checking aid 0x%06X...", curaid
);
1416 res
= AuthCheckDesfire(&dctx
, secureChannel
, &app_ids
[x
* 3], deskeyList
, deskeyListLen
, aeskeyList
, aeskeyListLen
, k3kkeyList
, k3kkeyListLen
, cmdKDFAlgo
, kdfInputLen
, kdfInput
, foundKeys
, &result
, (verbose
== false));
1417 if (res
== PM3_EOPABORTED
) {
1421 if (pattern2b
&& startPattern
< 0x10000) {
1422 if (verbose
== false) {
1423 PrintAndLogEx(NORMAL
, "p" NOLF
);
1429 DesFill2bPattern(deskeyList
, &deskeyListLen
, aeskeyList
, &aeskeyListLen
, k3kkeyList
, &k3kkeyListLen
, &startPattern
);
1433 if (dict_filenamelen
) {
1434 if (verbose
== false) {
1435 PrintAndLogEx(NORMAL
, "d" NOLF
);
1438 uint32_t keycnt
= 0;
1439 res
= loadFileDICTIONARYEx((char *)dict_filename
, deskeyList
, sizeof(deskeyList
), NULL
, 16, &keycnt
, endFilePosition
, &endFilePosition
, false);
1440 if (res
== PM3_SUCCESS
&& endFilePosition
) {
1441 deskeyListLen
= keycnt
;
1445 res
= loadFileDICTIONARYEx((char *)dict_filename
, aeskeyList
, sizeof(aeskeyList
), NULL
, 16, &keycnt
, endFilePosition
, &endFilePosition
, false);
1446 if (res
== PM3_SUCCESS
&& endFilePosition
) {
1447 aeskeyListLen
= keycnt
;
1451 res
= loadFileDICTIONARYEx((char *)dict_filename
, k3kkeyList
, sizeof(k3kkeyList
), NULL
, 16, &keycnt
, endFilePosition
, &endFilePosition
, false);
1452 if (res
== PM3_SUCCESS
&& endFilePosition
) {
1453 k3kkeyListLen
= keycnt
;
1459 if (verbose
== false) {
1460 PrintAndLogEx(NORMAL
, "");
1463 // save keys to json
1464 if ((jsonnamelen
> 0) && result
) {
1466 // MIFARE DESFire info
1467 SendCommandMIX(CMD_HF_ISO14443A_READER
, ISO14A_CONNECT
, 0, 0, NULL
, 0);
1469 PacketResponseNG resp
;
1470 WaitForResponse(CMD_ACK
, &resp
);
1472 iso14a_card_select_t card
;
1473 memcpy(&card
, (iso14a_card_select_t
*)resp
.data
.asBytes
, sizeof(iso14a_card_select_t
));
1475 uint64_t select_status
= resp
.oldarg
[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
1477 uint8_t data
[10 + 1 + 2 + 1 + 256 + (4 * 0xE * (24 + 1))] = {0};
1479 if (select_status
== 1 || select_status
== 2) {
1480 memcpy(data
, card
.uid
, card
.uidlen
);
1481 data
[10] = card
.sak
;
1482 data
[11] = card
.atqa
[1];
1483 data
[12] = card
.atqa
[0];
1484 atslen
= card
.ats_len
;
1486 memcpy(&data
[14], card
.ats
, atslen
);
1489 // length: UID(10b)+SAK(1b)+ATQA(2b)+ATSlen(1b)+ATS(atslen)+foundKeys[2][64][AES_KEY_LEN + 1]
1490 memcpy(&data
[14 + atslen
], foundKeys
, 4 * 0xE * (24 + 1));
1491 saveFileJSON((char *)jsonname
, jsfMfDesfireKeys
, data
, 0xE, NULL
);
1498 static int CmdHF14ADesList(const char *Cmd
) {
1499 return CmdTraceListAlias(Cmd
, "hf mfdes", "des -c");
1502 static int DesfireAuthCheck(DesfireContext_t
*dctx
, DesfireISOSelectWay way
, uint32_t appID
, DesfireSecureChannel secureChannel
, uint8_t *key
) {
1503 DesfireSetKeyNoClear(dctx
, dctx
->keyNum
, dctx
->keyType
, key
);
1505 int res
= DesfireAuthenticate(dctx
, secureChannel
, false);
1506 if (res
== PM3_SUCCESS
) {
1507 memcpy(dctx
->key
, key
, desfire_get_key_length(dctx
->keyType
));
1509 } else if (res
< 7) {
1511 res
= DesfireSelect(dctx
, way
, appID
, NULL
);
1512 if (res
!= PM3_SUCCESS
) {
1521 static int CmdHF14aDesDetect(const char *Cmd
) {
1522 CLIParserContext
*ctx
;
1523 CLIParserInit(&ctx
, "hf mfdes detect",
1524 "Detect key type and tries to find one from the list.",
1525 "hf mfdes detect -> detect key 0 from PICC level\n"
1526 "hf mfdes detect --schann d40 -> detect key 0 from PICC level via secure channel D40\n"
1527 "hf mfdes detect --dict mfdes_default_keys -> detect key 0 from PICC level with help of the standard dictionary\n"
1528 "hf mfdes detect --aid 123456 -n 2 --save -> detect key 2 from app 123456 and if succeed - save params to defaults (`default` command)\n"
1529 "hf mfdes detect --isoid df01 --save -> detect key 0 and save to defaults with card in the LRP mode");
1531 void *argtable
[] = {
1533 arg_lit0("a", "apdu", "Show APDU requests and responses"),
1534 arg_lit0("v", "verbose", "Verbose output"),
1535 arg_int0("n", "keyno", "<dec>", "Key number"),
1536 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
1537 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
1538 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
1539 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
1540 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
1541 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
1542 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
1543 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
1544 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)."),
1545 arg_str0(NULL
, "dict", "<fn>", "Dictionary file name with keys"),
1546 arg_lit0(NULL
, "save", "Save found key and parameters to defaults"),
1549 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
1551 bool APDULogging
= arg_get_lit(ctx
, 1);
1552 bool verbose
= arg_get_lit(ctx
, 2);
1554 DesfireContext_t dctx
;
1555 int securechann
= defaultSecureChannel
;
1556 uint32_t id
= 0x000000;
1557 DesfireISOSelectWay selectway
= ISW6bAID
;
1558 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann
, DCMMACed
, &id
, &selectway
);
1564 uint8_t dict_filename
[FILE_PATH_SIZE
+ 2] = {0};
1565 int dict_filenamelen
= 0;
1566 if (CLIParamStrToBuf(arg_get_str(ctx
, 13), dict_filename
, FILE_PATH_SIZE
, &dict_filenamelen
)) {
1567 PrintAndLogEx(FAILED
, "File name too long or invalid.");
1572 bool save
= arg_get_lit(ctx
, 14);
1574 SetAPDULogging(APDULogging
);
1577 // no auth and fill KDF if needs
1578 res
= DesfireSelectAndAuthenticateAppW(&dctx
, securechann
, selectway
, id
, true, verbose
);
1579 if (res
!= PM3_SUCCESS
) {
1581 PrintAndLogEx(FAILED
, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway
, id
), res
, DesfireAuthErrorToStr(res
));
1585 bool keytypes
[4] = {0};
1586 bool uselrp
= false;
1588 uint8_t data
[250] = {0};
1590 res
= DesfireGetKeySettings(&dctx
, data
, &datalen
);
1591 if (res
== PM3_SUCCESS
&& datalen
>= 2) {
1592 uint8_t num_keys
= data
[1];
1593 switch (num_keys
>> 6) {
1595 keytypes
[T_DES
] = true;
1596 keytypes
[T_3DES
] = true;
1599 keytypes
[T_3K3DES
] = true;
1602 keytypes
[T_AES
] = true;
1608 // if fail - check auth commands
1609 AuthCommandsChk_t authCmdCheck
= {0};
1610 DesfireCheckAuthCommands(selectway
, id
, NULL
, 0, &authCmdCheck
);
1611 if (authCmdCheck
.checked
) {
1612 if (authCmdCheck
.auth
) {
1613 keytypes
[T_DES
] = true;
1614 keytypes
[T_3DES
] = true;
1616 if (authCmdCheck
.authISO
) {
1617 keytypes
[T_3K3DES
] = true;
1620 if (authCmdCheck
.authAES
|| authCmdCheck
.authEV2
) {
1621 keytypes
[T_AES
] = true;
1623 if (authCmdCheck
.authLRP
) {
1624 keytypes
[T_AES
] = true;
1626 securechann
= DACLRP
;
1629 // if nothing helps - we check DES only
1630 keytypes
[T_DES
] = true;
1633 res
= DesfireSelectAndAuthenticateAppW(&dctx
, securechann
, selectway
, id
, true, verbose
);
1634 if (res
!= PM3_SUCCESS
) {
1636 PrintAndLogEx(FAILED
, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway
, id
), res
, DesfireAuthErrorToStr(res
));
1642 if (DesfireMFSelected(selectway
, id
))
1643 PrintAndLogEx(INFO
, "Check PICC key num: %d (0x%02x)", dctx
.keyNum
, dctx
.keyNum
);
1645 PrintAndLogEx(INFO
, "Check: %s key num: %d (0x%02x)", DesfireWayIDStr(selectway
, id
), dctx
.keyNum
, dctx
.keyNum
);
1646 PrintAndLogEx(INFO
, "keys: DES: %s 2TDEA: %s 3TDEA: %s AES: %s LRP: %s",
1647 keytypes
[T_DES
] ? _GREEN_("YES") : _RED_("NO"),
1648 keytypes
[T_3DES
] ? _GREEN_("YES") : _RED_("NO"),
1649 keytypes
[T_3K3DES
] ? _GREEN_("YES") : _RED_("NO"),
1650 keytypes
[T_AES
] ? _GREEN_("YES") : _RED_("NO"),
1651 uselrp
? _GREEN_("YES") : _RED_("NO")
1657 size_t errcount
= 0;
1658 for (uint8_t ktype
= T_DES
; ktype
<= T_AES
; ktype
++) {
1659 if (!keytypes
[ktype
])
1661 dctx
.keyType
= ktype
;
1663 PrintAndLogEx(INFO
, "Scan key type: %s", CLIGetOptionListStr(DesfireAlgoOpts
, dctx
.keyType
));
1665 if (dict_filenamelen
== 0) {
1666 // keys from mifaredefault.h
1667 for (int i
= 0; i
< g_mifare_plus_default_keys_len
; i
++) {
1668 uint8_t key
[DESFIRE_MAX_KEY_SIZE
] = {0};
1669 if (hex_to_bytes(g_mifare_plus_default_keys
[i
], key
, 16) != 16)
1671 if (ktype
== T_3K3DES
)
1672 memcpy(&key
[16], key
, 8);
1674 res
= DesfireAuthCheck(&dctx
, selectway
, id
, securechann
, key
);
1675 if (res
== PM3_SUCCESS
) {
1677 break; // all the params already in the dctx
1681 PrintAndLogEx(ERR
, "Can't select AID. There is no connection with card.");
1684 break; // we can't select app after invalid 1st auth stages
1687 if (errcount
> 10) {
1689 PrintAndLogEx(ERR
, "Too much errors (%zu) from card", errcount
);
1698 uint8_t keyList
[MAX_KEYS_LIST_LEN
* MAX_KEY_LEN
] = {0};
1699 uint32_t keyListLen
= 0;
1700 size_t keylen
= desfire_get_key_length(dctx
.keyType
);
1701 size_t endFilePosition
= 0;
1704 res
= loadFileDICTIONARYEx((char *)dict_filename
, keyList
, sizeof(keyList
), NULL
, keylen
, &keyListLen
, endFilePosition
, &endFilePosition
, verbose
);
1705 if (res
!= 1 && res
!= PM3_SUCCESS
)
1708 for (int i
= 0; i
< keyListLen
; i
++) {
1709 res
= DesfireAuthCheck(&dctx
, selectway
, id
, securechann
, &keyList
[i
* keylen
]);
1710 if (res
== PM3_SUCCESS
) {
1712 break; // all the params already in the dctx
1716 PrintAndLogEx(ERR
, "Can't select AID. There is no connection with card.");
1719 break; // we can't select app after invalid 1st auth stages
1722 if (errcount
> 10) {
1724 PrintAndLogEx(ERR
, "Too much errors (%zu) from card", errcount
);
1732 if (endFilePosition
== 0)
1742 if (DesfireMFSelected(selectway
, id
))
1743 PrintAndLogEx(INFO
, _GREEN_("Found") " key num: %d (0x%02x)", dctx
.keyNum
, dctx
.keyNum
);
1745 PrintAndLogEx(INFO
, "Found key for: %s key num: %d (0x%02x)", DesfireWayIDStr(selectway
, id
), dctx
.keyNum
, dctx
.keyNum
);
1747 PrintAndLogEx(INFO
, "channel " _GREEN_("%s") " key " _GREEN_("%s") " [%d]: " _GREEN_("%s"),
1748 CLIGetOptionListStr(DesfireSecureChannelOpts
, securechann
),
1749 CLIGetOptionListStr(DesfireAlgoOpts
, dctx
.keyType
),
1750 desfire_get_key_length(dctx
.keyType
),
1751 sprint_hex(dctx
.key
, desfire_get_key_length(dctx
.keyType
)));
1754 PrintAndLogEx(INFO
, "Key " _RED_("not found"));
1759 if (found
&& save
) {
1760 defaultKeyNum
= dctx
.keyNum
;
1761 defaultAlgoId
= dctx
.keyType
;
1762 memcpy(defaultKey
, dctx
.key
, DESFIRE_MAX_KEY_SIZE
);
1763 defaultKdfAlgo
= dctx
.kdfAlgo
;
1764 defaultKdfInputLen
= dctx
.kdfInputLen
;
1765 memcpy(defaultKdfInput
, dctx
.kdfInput
, sizeof(dctx
.kdfInput
));
1766 defaultSecureChannel
= securechann
;
1767 defaultCommSet
= dctx
.cmdSet
;
1769 PrintAndLogEx(INFO
, "-----------" _CYAN_("Default parameters") "---------------------------------");
1771 PrintAndLogEx(INFO
, "Key Num : %d", defaultKeyNum
);
1772 PrintAndLogEx(INFO
, "Algo : %s", CLIGetOptionListStr(DesfireAlgoOpts
, defaultAlgoId
));
1773 PrintAndLogEx(INFO
, "Key : %s", sprint_hex(defaultKey
, desfire_get_key_length(defaultAlgoId
)));
1774 PrintAndLogEx(INFO
, "KDF algo : %s", CLIGetOptionListStr(DesfireKDFAlgoOpts
, defaultKdfAlgo
));
1775 PrintAndLogEx(INFO
, "KDF input : [%d] %s", defaultKdfInputLen
, sprint_hex(defaultKdfInput
, defaultKdfInputLen
));
1776 PrintAndLogEx(INFO
, "Secure chan : %s", CLIGetOptionListStr(DesfireSecureChannelOpts
, defaultSecureChannel
));
1777 PrintAndLogEx(INFO
, "Command set : %s", CLIGetOptionListStr(DesfireCommandSetOpts
, defaultCommSet
));
1778 PrintAndLogEx(INFO
, _GREEN_("Saved"));
1784 // https://www.nxp.com/docs/en/application-note/AN10787.pdf
1785 // MIFARE Application Directory (MAD)
1786 // test cardholder data 0a53616d706c656d616e00475068696c697000826d00d054656c2b312f313233342f3536373800
1787 static int CmdHF14aDesMAD(const char *Cmd
) {
1788 CLIParserContext
*ctx
;
1789 CLIParserInit(&ctx
, "hf mfdes mad",
1790 "Reads and prints MIFARE Application directory (MAD).",
1791 "MAD consists of one file with issuer info (AID ffffff) and several files with AID in the special format `faaaav` (a - MAD ID, v - multiple AID over one MAD ID)\n"
1792 "The MIFARE DESFire Card Master Key settings have to allow the MIFARE DESFire command GetApplicationIDs without authentication (from datasheet)\n"
1794 "hf mfdes mad -> shows MAD data\n"
1795 "hf mfdes mad -v -> shows MAD parsed and raw data\n"
1796 "hf mfdes mad -a e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows MAD data with custom AID and key");
1798 void *argtable
[] = {
1800 arg_lit0("a", "apdu", "Show APDU requests and responses"),
1801 arg_lit0("v", "verbose", "Verbose output"),
1802 arg_int0("n", "keyno", "<dec>", "Key number"),
1803 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
1804 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
1805 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
1806 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
1807 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
1808 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
1809 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
1810 arg_str0(NULL
, "aid", "<hex>", "Application ID of issuer info file, (3 hex bytes, big endian), (non-standard feature!)"),
1811 arg_lit0(NULL
, "auth", "Authenticate to get info from GetApplicationIDs command (non-standard feature!)"),
1814 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
1817 bool APDULogging
= arg_get_lit(ctx
, 1);
1818 bool verbose
= arg_get_lit(ctx
, 2);
1820 DesfireContext_t dctx
;
1821 int securechann
= defaultSecureChannel
;
1822 uint32_t appid
= 0x000000;
1823 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann
, DCMPlain
, &appid
, NULL
);
1829 bool authen
= arg_get_lit(ctx
, 12);
1831 SetAPDULogging(APDULogging
);
1834 res
= DesfireSelectAndAuthenticateEx(&dctx
, securechann
, appid
, !authen
, verbose
);
1835 if (res
!= PM3_SUCCESS
) {
1840 PICCInfo_t PICCInfo
= {0};
1841 AppListS AppList
= {{0}};
1842 DesfireFillAppList(&dctx
, &PICCInfo
, AppList
, false, false, false); // no deep scan, no scan files
1844 PrintAndLogEx(SUCCESS
, "# Applications... " _GREEN_("%zu"), PICCInfo
.appCount
);
1845 if (PICCInfo
.freemem
== 0xffffffff) {
1846 PrintAndLogEx(SUCCESS
, "Free memory...... " _YELLOW_("n/a"));
1848 PrintAndLogEx(SUCCESS
, "Free memory...... " _GREEN_("%d") " bytes", PICCInfo
.freemem
);
1851 if ((PICCInfo
.keySettings
& (1 << 1)) == 0) {
1852 PrintAndLogEx(WARNING
, "Directory list access with CMK... ( " _RED_("Enabled") " )");
1853 PrintAndLogEx(HINT
, "Try to read MAD with Card Master Key (CMK)");
1856 PrintAndLogEx(SUCCESS
, "----------------------------------------- " _CYAN_("MAD") " ------------------------------------------");
1857 bool foundFFFFFF
= false;
1858 for (int i
= 0; i
< PICCInfo
.appCount
; i
++) {
1859 if (AppList
[i
].appNum
== 0xffffff) {
1865 PrintAndLogEx(SUCCESS
, _CYAN_("Issuer"));
1868 res
= DesfireSelectAIDHexNoFieldOn(&dctx
, 0xffffff);
1869 if (res
== PM3_SUCCESS
) {
1870 uint32_t madver
= 0;
1871 res
= DesfireValueFileOperations(&dctx
, 0x00, MFDES_GET_VALUE
, &madver
);
1872 if (res
!= PM3_SUCCESS
) {
1873 PrintAndLogEx(SUCCESS
, "MAD version... " _RED_("n/a"));
1876 PrintAndLogEx(SUCCESS
, "MAD version... " _GREEN_("3"));
1878 PrintAndLogEx(WARNING
, "MAD version... " _YELLOW_("%d"), madver
);
1881 uint8_t data
[250] = {0};
1884 res
= DesfireReadFile(&dctx
, 01, 0x000000, 0, data
, &datalen
);
1885 if (res
!= PM3_SUCCESS
) {
1886 PrintAndLogEx(SUCCESS
, "Card Holder... " _RED_("n/a"));
1889 PrintAndLogEx(SUCCESS
, "Card Holder... ");
1891 print_buffer_with_offset(data
, datalen
, 0, true);
1892 PrintAndLogEx(NORMAL
, "");
1894 MADCardHolderInfoDecode(data
, datalen
, verbose
);
1895 PrintAndLogEx(NORMAL
, "");
1897 PrintAndLogEx(SUCCESS
, "Card Holder... " _YELLOW_("none"));
1901 res
= DesfireReadFile(&dctx
, 02, 0x000000, 0, data
, &datalen
);
1902 if (res
!= PM3_SUCCESS
) {
1903 PrintAndLogEx(SUCCESS
, "Card Publisher: " _RED_("n/a"));
1906 PrintAndLogEx(SUCCESS
, "Card Publisher: ");
1907 print_buffer_with_offset(data
, datalen
, 0, true);
1908 PrintAndLogEx(NORMAL
, "");
1910 PrintAndLogEx(SUCCESS
, "Card Publisher: " _YELLOW_("none"));
1914 PrintAndLogEx(WARNING
, _RED_("Can't select") " issuer information app (0xffffff).");
1917 PrintAndLogEx(WARNING
, "Issuer information " _RED_("not found") " on the card.");
1920 size_t madappcount
= 0;
1921 PrintAndLogEx(SUCCESS
, "");
1922 PrintAndLogEx(SUCCESS
, _CYAN_("Applications"));
1923 for (int i
= 0; i
< PICCInfo
.appCount
; i
++) {
1924 if ((AppList
[i
].appNum
& 0xf00000) == 0xf00000) {
1925 DesfirePrintMADAID(AppList
[i
].appNum
, verbose
);
1927 // read file 0, 1, 2
1928 res
= DesfireSelectAIDHexNoFieldOn(&dctx
, AppList
[i
].appNum
);
1929 if (res
== PM3_SUCCESS
) {
1930 uint8_t buf
[APDU_RES_LEN
] = {0};
1933 res
= DesfireGetFileIDList(&dctx
, buf
, &buflen
);
1934 if (res
!= PM3_SUCCESS
) {
1935 PrintAndLogEx(ERR
, "Desfire GetFileIDList command " _RED_("error") ". Result: %d", res
);
1941 for (int j
= 0; j
< buflen
; j
++) {
1942 PrintAndLogEx(INFO
, " File ID... %02x", buf
[j
]);
1951 if (madappcount
== 0) {
1952 PrintAndLogEx(SUCCESS
, "There is no MAD applications on the card");
1961 static int CmdHF14ADesSelectApp(const char *Cmd
) {
1962 CLIParserContext
*ctx
;
1963 CLIParserInit(&ctx
, "hf mfdes selectapp",
1964 "Select application on the card. It selects app if it is a valid one or returns an error.",
1965 "hf mfdes selectapp --aid 123456 -> select application 123456\n"
1966 "hf mfdes selectapp --mf -> select master file (PICC level)\n"
1967 "hf mfdes selectapp --dfname aid123456 -> select application aid123456 by DF name\n"
1968 "hf mfdes selectapp --isoid 1111 -> select application 1111 by ISO ID\n"
1969 "hf mfdes selectapp --isoid 1111 --fileisoid 2222 -> select application 1111 file 2222 by ISO ID\n"
1970 "hf mfdes selectapp --isoid 01df --fileisoid 00ef -> select file 00 on the Desfire Light");
1972 void *argtable
[] = {
1974 arg_lit0("a", "apdu", "Show APDU requests and responses"),
1975 arg_lit0("v", "verbose", "Verbose output"),
1976 arg_int0("n", "keyno", "<dec>", "Key number"),
1977 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
1978 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
1979 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
1980 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
1981 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
1982 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
1983 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
1984 arg_str0(NULL
, "aid", "<hex>", "Application ID of application for some parameters (3 hex bytes, big endian)"),
1985 arg_str0(NULL
, "dfname", "<str>", "Application DF Name (string, max 16 chars). Selects application via ISO SELECT command"),
1986 arg_lit0(NULL
, "mf", "Select MF (master file) via ISO channel"),
1987 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
1988 arg_str0(NULL
, "fileisoid", "<hex>", "Select file inside application by ISO ID (ISO DF ID) (2 hex bytes, big endian)."),
1991 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
1993 bool APDULogging
= arg_get_lit(ctx
, 1);
1994 bool verbose
= arg_get_lit(ctx
, 2);
1996 DesfireContext_t dctx
;
1997 int securechann
= defaultSecureChannel
;
1998 uint32_t appid
= 0x000000;
1999 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann
, DCMPlain
, &appid
, NULL
);
2005 uint8_t dfname
[32] = {0};
2007 CLIGetStrWithReturn(ctx
, 12, dfname
, &dfnamelen
);
2009 bool selectmf
= arg_get_lit(ctx
, 13);
2011 uint32_t isoid
= 0x0000;
2012 bool isoidpresent
= false;
2013 if (CLIGetUint32Hex(ctx
, 14, 0x0000, &isoid
, &isoidpresent
, 2, "ISO ID for EF or DF must have 2 bytes length")) {
2018 uint32_t fileisoid
= 0x0000;
2019 bool fileisoidpresent
= false;
2020 if (CLIGetUint32Hex(ctx
, 15, 0x0000, &fileisoid
, &fileisoidpresent
, 2, "ISO ID for EF or DF must have 2 bytes length")) {
2025 SetAPDULogging(APDULogging
);
2028 uint8_t resp
[250] = {0};
2032 res
= DesfireISOSelect(&dctx
, ISSMFDFEF
, NULL
, 0, resp
, &resplen
);
2033 if (res
!= PM3_SUCCESS
) {
2035 PrintAndLogEx(FAILED
, "ISO Select MF " _RED_("failed"));
2040 PrintAndLogEx(FAILED
, "Application " _CYAN_("FCI template") " [%zu]%s", resplen
, sprint_hex(resp
, resplen
));
2042 PrintAndLogEx(SUCCESS
, "PICC MF selected " _GREEN_("succesfully"));
2043 } else if (isoidpresent
) {
2044 uint8_t data
[2] = {0};
2045 Uint2byteToMemLe(data
, isoid
);
2046 res
= DesfireISOSelect(&dctx
, ISSMFDFEF
, data
, 2, resp
, &resplen
);
2047 if (res
!= PM3_SUCCESS
) {
2049 PrintAndLogEx(FAILED
, "ISO Select DF 0x%04x " _RED_("failed"), isoid
);
2054 PrintAndLogEx(FAILED
, "Application " _CYAN_("FCI template") " [%zu]%s", resplen
, sprint_hex(resp
, resplen
));
2056 PrintAndLogEx(SUCCESS
, "PICC DF 0x%04x selected " _GREEN_("succesfully"), isoid
);
2057 } else if (dctx
.cmdSet
== DCCISO
|| dfnamelen
> 0) {
2059 res
= DesfireISOSelectDF(&dctx
, (char *)dfname
, resp
, &resplen
);
2061 res
= DesfireISOSelect(&dctx
, ISSMFDFEF
, NULL
, 0, resp
, &resplen
);
2062 if (res
!= PM3_SUCCESS
) {
2064 PrintAndLogEx(FAILED
, "ISO Select application `%s` " _RED_("failed"), (char *)dfname
);
2069 PrintAndLogEx(FAILED
, "Application " _CYAN_("FCI template") " [%zu]%s", resplen
, sprint_hex(resp
, resplen
));
2072 PrintAndLogEx(SUCCESS
, "Application `%s` selected " _GREEN_("succesfully"), (char *)dfname
);
2074 PrintAndLogEx(SUCCESS
, "PICC MF selected " _GREEN_("succesfully"));
2076 res
= DesfireSelectAndAuthenticateEx(&dctx
, securechann
, appid
, true, verbose
);
2077 if (res
!= PM3_SUCCESS
) {
2079 PrintAndLogEx(FAILED
, "Select application 0x%06x " _RED_("failed") " ", appid
);
2083 PrintAndLogEx(SUCCESS
, "Application 0x%06x selected " _GREEN_("succesfully") " ", appid
);
2086 if (fileisoidpresent
) {
2087 res
= DesfireSelectEx(&dctx
, false, ISWIsoID
, fileisoid
, NULL
);
2088 if (res
!= PM3_SUCCESS
) {
2090 PrintAndLogEx(FAILED
, "Select file 0x%04x " _RED_("failed") " ", fileisoid
);
2094 PrintAndLogEx(SUCCESS
, "File 0x%04x selected " _GREEN_("succesfully") " ", fileisoid
);
2101 static int CmdHF14ADesBruteApps(const char *Cmd
) {
2102 CLIParserContext
*ctx
;
2103 CLIParserInit(&ctx
, "hf mfdes bruteaid",
2104 "Recover AIDs by bruteforce.\n"
2105 "WARNING: This command takes a loooong time",
2106 "hf mfdes bruteaid -> Search all apps\n"
2107 "hf mfdes bruteaid --start F0000F -i 16 -> Search MAD range manually");
2109 void *argtable
[] = {
2111 arg_str0(NULL
, "start", "<hex>", "Starting App ID as hex bytes (3 bytes, big endian)"),
2112 arg_str0(NULL
, "end", "<hex>", "Last App ID as hex bytes (3 bytes, big endian)"),
2113 arg_int0("i", "step", "<dec>", "Increment step when bruteforcing"),
2114 arg_lit0("m", "mad", "Only bruteforce the MAD range"),
2117 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
2119 DesfireContext_t dctx
;
2120 int securechann
= defaultSecureChannel
;
2121 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &securechann
, DCMNone
, NULL
, NULL
);
2127 uint8_t startAid
[3] = {0};
2128 uint8_t endAid
[3] = {0xFF, 0xFF, 0xFF};
2131 CLIGetHexWithReturn(ctx
, 1, startAid
, &startLen
);
2132 CLIGetHexWithReturn(ctx
, 2, endAid
, &endLen
);
2133 uint32_t idIncrement
= arg_get_int_def(ctx
, 3, 1);
2134 bool mad
= arg_get_lit(ctx
, 4);
2139 res
= DesfireSelectAIDHex(&dctx
, 0x000000, false, 0);
2140 if (res
!= PM3_SUCCESS
) {
2142 PrintAndLogEx(FAILED
, "Desfire PICC level select " _RED_("failed") ". Maybe wrong card or no card in the field.");
2146 // TODO: We need to check the tag version, EV1 should stop after 26 apps are found
2153 uint32_t idStart
= DesfireAIDByteToUint(startAid
);
2154 uint32_t idEnd
= DesfireAIDByteToUint(endAid
);
2155 if (idStart
> idEnd
) {
2156 PrintAndLogEx(ERR
, "Start should be lower than end. start: %06x end: %06x", idStart
, idEnd
);
2159 PrintAndLogEx(INFO
, "Bruteforce from %06x to %06x", idStart
, idEnd
);
2160 PrintAndLogEx(INFO
, "Enumerating through all AIDs manually, this will take a while!");
2161 for (uint32_t id
= idStart
; id
<= idEnd
&& id
>= idStart
; id
+= idIncrement
) {
2162 if (kbd_enter_pressed()) break;
2164 int progress
= ((id
- idStart
) * 100) / ((idEnd
- idStart
));
2165 PrintAndLogEx(INPLACE
, "Progress: %d %%, current AID: %06X", progress
, id
);
2167 res
= DesfireSelectAIDHexNoFieldOn(&dctx
, id
);
2169 if (res
== PM3_SUCCESS
) {
2170 printf("\33[2K\r"); // clear current line before printing
2171 PrintAndLogEx(SUCCESS
, "Got new APPID %06X", id
);
2175 PrintAndLogEx(NORMAL
, "");
2176 PrintAndLogEx(SUCCESS
, _GREEN_("Done"));
2181 // MIAFRE DESFire Authentication
2183 // NR DESC KEYLENGHT
2184 // ------------------------
2189 static int CmdHF14ADesAuth(const char *Cmd
) {
2190 CLIParserContext
*ctx
;
2191 CLIParserInit(&ctx
, "hf mfdes auth",
2192 "Select application on the card. It selects app if it is a valid one or returns an error.",
2193 "hf mfdes auth -n 0 -t des -k 0000000000000000 --kdf none -> select PICC level and authenticate with key num=0, key type=des, key=00..00 and key derivation = none\n"
2194 "hf mfdes auth -n 0 -t aes -k 00000000000000000000000000000000 -> select PICC level and authenticate with key num=0, key type=aes, key=00..00 and key derivation = none\n"
2195 "hf mfdes auth -n 0 -t des -k 0000000000000000 --save -> select PICC level and authenticate and in case of successful authentication - save channel parameters to defaults\n"
2196 "hf mfdes auth --aid 123456 -> select application 123456 and authenticate via parameters from `default` command");
2198 void *argtable
[] = {
2200 arg_lit0("a", "apdu", "Show APDU requests and responses"),
2201 arg_lit0("v", "verbose", "Verbose output"),
2202 arg_int0("n", "keyno", "<dec>", "Key number"),
2203 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
2204 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
2205 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
2206 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
2207 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
2208 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
2209 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
2210 arg_str0(NULL
, "aid", "<hex>", "Application ID of application for some parameters (3 hex bytes, big endian)"),
2211 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
2212 arg_lit0(NULL
, "save", "saves channels parameters to defaults if authentication succeeds"),
2215 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
2217 bool APDULogging
= arg_get_lit(ctx
, 1);
2218 bool verbose
= arg_get_lit(ctx
, 2);
2220 DesfireContext_t dctx
;
2221 int securechann
= defaultSecureChannel
;
2222 uint32_t id
= 0x000000;
2223 DesfireISOSelectWay selectway
= ISW6bAID
;
2224 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann
, DCMPlain
, &id
, &selectway
);
2230 bool save
= arg_get_lit(ctx
, 13);
2232 SetAPDULogging(APDULogging
);
2235 res
= DesfireSelectAndAuthenticateAppW(&dctx
, securechann
, selectway
, id
, false, verbose
);
2236 if (res
!= PM3_SUCCESS
) {
2238 PrintAndLogEx(FAILED
, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway
, id
), res
, DesfireAuthErrorToStr(res
));
2242 if (DesfireMFSelected(selectway
, id
))
2243 PrintAndLogEx(SUCCESS
, "PICC selected and authenticated " _GREEN_("succesfully"));
2245 PrintAndLogEx(SUCCESS
, "Application " _CYAN_("%s") " selected and authenticated " _GREEN_("succesfully"), DesfireWayIDStr(selectway
, id
));
2247 PrintAndLogEx(SUCCESS
, _CYAN_("Context: "));
2248 DesfirePrintContext(&dctx
);
2251 defaultKeyNum
= dctx
.keyNum
;
2252 defaultAlgoId
= dctx
.keyType
;
2253 memcpy(defaultKey
, dctx
.key
, DESFIRE_MAX_KEY_SIZE
);
2254 defaultKdfAlgo
= dctx
.kdfAlgo
;
2255 defaultKdfInputLen
= dctx
.kdfInputLen
;
2256 memcpy(defaultKdfInput
, dctx
.kdfInput
, sizeof(dctx
.kdfInput
));
2257 defaultSecureChannel
= securechann
;
2258 defaultCommSet
= dctx
.cmdSet
;
2259 defaultCommMode
= dctx
.commMode
;
2261 PrintAndLogEx(SUCCESS
, "Context saved to defaults " _GREEN_("succesfully") ". You can check them by command " _YELLOW_("hf mfdes default"));
2268 static int CmdHF14ADesSetConfiguration(const char *Cmd
) {
2269 CLIParserContext
*ctx
;
2270 CLIParserInit(&ctx
, "hf mfdes setconfig",
2271 "Set card configuration. \n"
2272 "WARNING! Danger zone!\n"
2273 "Needs to provide card's master key and works if not blocked by config.",
2274 "More about options MF2DLHX0.pdf.\n"
2276 " 00h PICC configuration.\n"
2277 " 02h ATS update.\n"
2279 " 04h Secure Messaging Configuration.\n"
2280 " 05h Capability data. (here change for LRP in the Desfire Light [enable 00000000010000000000])\n"
2281 " 06h DF Name renaming (one-time)\n"
2282 " 08h File renaming (one-time)\n"
2283 " 09h Value file configuration (one-time)\n"
2284 " 0Ah Failed authentication counter setting [disable 00ffffffff]\n"
2285 " 0Bh HW configuration\n"
2287 "hf mfdes setconfig --param 03 --data 0428 -> set SAK\n"
2288 "hf mfdes setconfig --param 02 --data 0875778102637264 -> set ATS (first byte - length)\n"
2289 "hf mfdes setconfig --isoid df01 -t aes --schann ev2 --param 05 --data 00000000020000000000 -> set LRP mode enable for Desfire Light\n"
2290 "hf mfdes setconfig --isoid df01 -t aes --schann ev2 --param 0a --data 00ffffffff -> Disable failed auth counters for Desfire Light\n"
2291 "hf mfdes setconfig --isoid df01 -t aes --schann lrp --param 0a --data 00ffffffff -> Disable failed auth counters for Desfire Light via lrp");
2293 void *argtable
[] = {
2295 arg_lit0("a", "apdu", "Show APDU requests and responses"),
2296 arg_lit0("v", "verbose", "Verbose output"),
2297 arg_int0("n", "keyno", "<dec>", "Key number"),
2298 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
2299 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
2300 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
2301 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
2302 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
2303 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
2304 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
2305 arg_str0(NULL
, "aid", "<hex>", "Application ID of application for some parameters (3 hex bytes, big endian)"),
2306 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)."),
2307 arg_str0("p", "param", "<hex>", "Parameter id (1 hex byte)"),
2308 arg_str0("d", "data", "<hex>", "Data for parameter (1..30 hex bytes)"),
2311 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
2313 bool APDULogging
= arg_get_lit(ctx
, 1);
2314 bool verbose
= arg_get_lit(ctx
, 2);
2316 DesfireContext_t dctx
;
2317 int securechann
= defaultSecureChannel
;
2318 uint32_t id
= 0x000000;
2319 DesfireISOSelectWay selectway
= ISW6bAID
;
2320 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann
, DCMEncrypted
, &id
, &selectway
);
2326 uint32_t paramid
= 0;
2327 if (CLIGetUint32Hex(ctx
, 13, 0, ¶mid
, NULL
, 1, "Parameter ID must have 1 bytes length")) {
2332 uint8_t param
[250] = {0};
2333 int paramlen
= sizeof(param
);
2334 CLIGetHexWithReturn(ctx
, 14, param
, ¶mlen
);
2335 if (paramlen
== 0) {
2336 PrintAndLogEx(ERR
, "Parameter must have a data.");
2340 if (paramlen
> 50) {
2341 PrintAndLogEx(ERR
, "Parameter data length must be less than 50 instead of %d.", paramlen
);
2346 SetAPDULogging(APDULogging
);
2350 if (DesfireMFSelected(selectway
, id
)) {
2351 PrintAndLogEx(INFO
, _CYAN_("PICC") " param ID: 0x%02x param[%d]: %s",
2354 sprint_hex(param
, paramlen
)
2357 PrintAndLogEx(INFO
, _CYAN_("%s %06x") " param ID: 0x%02x param[%d]: %s",
2358 DesfireSelectWayToStr(selectway
),
2362 sprint_hex(param
, paramlen
)
2367 res
= DesfireSelectAndAuthenticateAppW(&dctx
, securechann
, selectway
, id
, false, verbose
);
2368 if (res
!= PM3_SUCCESS
) {
2370 PrintAndLogEx(FAILED
, "Select or authentication ( %s ) Result [%d] %s %s",
2371 DesfireWayIDStr(selectway
, id
),
2373 DesfireAuthErrorToStr(res
),
2379 res
= DesfireSetConfiguration(&dctx
, paramid
, param
, paramlen
);
2380 if (res
== PM3_SUCCESS
) {
2381 PrintAndLogEx(SUCCESS
, "Set configuration 0x%02x ( %s )", paramid
, _GREEN_("ok"));
2383 PrintAndLogEx(FAILED
, "Set configuration 0x%02x ( %s )", paramid
, _RED_("failed"));
2390 static int CmdHF14ADesChangeKey(const char *Cmd
) {
2391 CLIParserContext
*ctx
;
2392 CLIParserInit(&ctx
, "hf mfdes changekey",
2393 "Change PICC/Application key. Needs to provide keynum/key for a valid authentication (may get from default parameters).",
2394 "Change crypto algorithm for PICC key is possible, \n"
2395 "but for APP keys crypto algorithm is set by createapp command and can't be changed wo application delete\n"
2397 "hf mfdes changekey --aid 123456 -> execute with default factory setup. change des key 0 in the app 123456 from 00..00 to 00..00\n"
2398 "hf mfdes changekey --isoid df01 -t aes --schann lrp --newkeyno 01 -> change key 01 via lrp channel"
2399 "hf mfdes changekey -t des --newalgo aes --newkey 11223344556677889900112233445566 --newver a5 -> change card master key to AES one\n"
2400 "hf mfdes changekey --aid 123456 -t aes --key 00000000000000000000000000000000 --newkey 11223344556677889900112233445566 -> change app master key\n"
2401 "hf mfdes changekey --aid 123456 -t des -n 0 --newkeyno 1 --oldkey 5555555555555555 --newkey 1122334455667788 -> change key 1 with auth from key 0\n"
2402 "hf mfdes changekey --aid 123456 -t 3tdea --newkey 112233445566778899001122334455667788990011223344 -> change 3tdea key 0 from default 00..00 to provided");
2404 void *argtable
[] = {
2406 arg_lit0("a", "apdu", "Show APDU requests and responses"),
2407 arg_lit0("v", "verbose", "Verbose output"),
2408 arg_int0("n", "keyno", "<dec>", "Key number"),
2409 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
2410 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
2411 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
2412 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
2413 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
2414 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
2415 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
2416 arg_str0(NULL
, "aid", "<hex>", "Application ID of application (3 hex bytes, big endian)"),
2417 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)."),
2418 arg_str0(NULL
, "oldalgo", "<DES|2TDEA|3TDEA|AES>", "Old key crypto algorithm"),
2419 arg_str0(NULL
, "oldkey", "<old key>", "Old key (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
2420 arg_int0(NULL
, "newkeyno", "<dec>", "Key number for change"),
2421 arg_str0(NULL
, "newalgo", "<DES|2TDEA|3TDEA|AES>", "New key crypto algorithm"),
2422 arg_str0(NULL
, "newkey", "<hex>", "New key (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
2423 arg_str0(NULL
, "newver", "<hex>", "Version of new key (1 hex byte)"),
2426 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
2428 bool APDULogging
= arg_get_lit(ctx
, 1);
2429 bool verbose
= arg_get_lit(ctx
, 2);
2431 DesfireContext_t dctx
;
2432 int securechann
= defaultSecureChannel
;
2433 uint32_t id
= 0x000000;
2434 DesfireISOSelectWay selectway
= ISW6bAID
;
2435 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann
, DCMEncrypted
, &id
, &selectway
);
2441 int oldkeytype
= dctx
.keyType
;
2442 if (CLIGetOptionList(arg_get_str(ctx
, 13), DesfireAlgoOpts
, &oldkeytype
)) {
2447 uint8_t oldkey
[DESFIRE_MAX_KEY_SIZE
] = {0};
2448 uint8_t keydata
[200] = {0};
2449 int oldkeylen
= sizeof(keydata
);
2450 CLIGetHexWithReturn(ctx
, 14, keydata
, &oldkeylen
);
2451 if (oldkeylen
&& oldkeylen
!= desfire_get_key_length(oldkeytype
)) {
2452 PrintAndLogEx(ERR
, "%s old key must have %d bytes length instead of %d.", CLIGetOptionListStr(DesfireAlgoOpts
, oldkeytype
), desfire_get_key_length(oldkeytype
), oldkeylen
);
2457 memcpy(oldkey
, keydata
, oldkeylen
);
2459 uint8_t newkeynum
= arg_get_int_def(ctx
, 15, 0);
2461 int newkeytype
= oldkeytype
;
2462 if (CLIGetOptionList(arg_get_str(ctx
, 16), DesfireAlgoOpts
, &newkeytype
)) {
2467 uint8_t newkey
[DESFIRE_MAX_KEY_SIZE
] = {0};
2468 memset(keydata
, 0x00, sizeof(keydata
));
2469 int keylen
= sizeof(keydata
);
2470 CLIGetHexWithReturn(ctx
, 17, keydata
, &keylen
);
2471 if (keylen
&& keylen
!= desfire_get_key_length(newkeytype
)) {
2472 PrintAndLogEx(ERR
, "%s new key must have %d bytes length instead of %d.", CLIGetOptionListStr(DesfireAlgoOpts
, newkeytype
), desfire_get_key_length(newkeytype
), keylen
);
2477 memcpy(newkey
, keydata
, keylen
);
2479 uint32_t newkeyver
= 0x100;
2480 if (CLIGetUint32Hex(ctx
, 18, 0x100, &newkeyver
, NULL
, 1, "Key version must have 1 bytes length")) {
2485 SetAPDULogging(APDULogging
);
2488 // if we change the same key
2489 if (oldkeylen
== 0 && newkeynum
== dctx
.keyNum
) {
2490 oldkeytype
= dctx
.keyType
;
2491 memcpy(oldkey
, dctx
.key
, desfire_get_key_length(dctx
.keyType
));
2494 if (DesfireMFSelected(selectway
, id
)) {
2496 PrintAndLogEx(WARNING
, "Changing the PICC level keys");
2497 PrintAndLogEx(INFO
, _CYAN_("Changing PICC key"));
2499 PrintAndLogEx(INFO
, _CYAN_("Changing key for ") _YELLOW_("%s"), DesfireWayIDStr(selectway
, id
));
2502 PrintAndLogEx(INFO
, "auth key %d: %s [%d] %s", dctx
.keyNum
, CLIGetOptionListStr(DesfireAlgoOpts
, dctx
.keyType
), desfire_get_key_length(dctx
.keyType
), sprint_hex(dctx
.key
, desfire_get_key_length(dctx
.keyType
)));
2503 PrintAndLogEx(INFO
, "changing key number " _YELLOW_("0x%02x") " (%d)", newkeynum
, newkeynum
);
2504 PrintAndLogEx(INFO
, "old key: %s [%d] %s", CLIGetOptionListStr(DesfireAlgoOpts
, oldkeytype
), desfire_get_key_length(oldkeytype
), sprint_hex(oldkey
, desfire_get_key_length(oldkeytype
)));
2505 PrintAndLogEx(INFO
, "new key: %s [%d] %s", CLIGetOptionListStr(DesfireAlgoOpts
, newkeytype
), desfire_get_key_length(newkeytype
), sprint_hex(newkey
, desfire_get_key_length(newkeytype
)));
2506 if (newkeyver
< 0x100 || newkeytype
== T_AES
)
2507 PrintAndLogEx(INFO
, "new key version: 0x%02x", newkeyver
& 0x00);
2509 res
= DesfireSelectAndAuthenticateAppW(&dctx
, securechann
, selectway
, id
, false, verbose
);
2510 if (res
!= PM3_SUCCESS
) {
2512 PrintAndLogEx(FAILED
, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway
, id
), res
, DesfireAuthErrorToStr(res
));
2516 DesfireSetCommMode(&dctx
, DCMEncryptedPlain
);
2517 res
= DesfireChangeKey(&dctx
, (DesfireMFSelected(selectway
, id
)) && (newkeynum
== 0) && (dctx
.keyNum
== 0), newkeynum
, newkeytype
, newkeyver
, newkey
, oldkeytype
, oldkey
, true);
2518 if (res
== PM3_SUCCESS
) {
2519 PrintAndLogEx(SUCCESS
, "Change key ( " _GREEN_("ok") " )");
2521 PrintAndLogEx(FAILED
, "Change key ( " _RED_("failed") " )");
2523 DesfireSetCommMode(&dctx
, DCMEncrypted
);
2529 static int CmdHF14ADesCreateApp(const char *Cmd
) {
2530 CLIParserContext
*ctx
;
2531 CLIParserInit(&ctx
, "hf mfdes createapp",
2532 "Create application. Master key needs to be provided.",
2533 "option rawdata have priority over the rest settings, and options ks1 and ks2 have priority over corresponded key settings\n"
2535 "KeySetting 1 (AMK Setting, ks1):\n"\
2536 " 0: Allow change master key. 1 - allow, 0 - frozen\n"\
2537 " 1: Free Directory list access without master key\n"\
2538 " 0: AMK auth needed for GetFileSettings and GetKeySettings\n"\
2539 " 1: No AMK auth needed for GetFileIDs, GetISOFileIDs, GetFileSettings, GetKeySettings\n"\
2540 " 2: Free create/delete without master key\n"\
2541 " 0: CreateFile/DeleteFile only with AMK auth\n"\
2542 " 1: CreateFile/DeleteFile always\n"\
2543 " 3: Configuration changeable\n"\
2544 " 0: Configuration frozen\n"\
2545 " 1: Configuration changeable if authenticated with AMK (default)\n"\
2546 " 4-7: ChangeKey Access Rights\n"\
2547 " 0: Application master key needed (default)\n"\
2548 " 0x1..0xD: Auth with specific key needed to change any key\n"\
2549 " 0xE: Auth with the key to be changed (same KeyNo) is necessary to change a key\n"\
2550 " 0xF: All Keys within this application are frozen\n"\
2552 "KeySetting 2 (ks2):\n"\
2553 " 0..3: Number of keys stored within the application (max. 14 keys)\n"\
2554 " 4: ks3 is present\n"\
2555 " 5: Use of 2 byte ISO FID, 0: No, 1: Yes\n"\
2556 " 6..7: Crypto Method 00: DES|2TDEA, 01: 3TDEA, 10: AES, 11: RFU\n"\
2558 " 2E = with FID, DES|2TDEA, 14 keys\n"\
2559 " 6E = with FID, 3TDEA, 14 keys\n"\
2560 " AE = with FID, AES, 14 keys\n"\
2562 "hf mfdes createapp --rawdata 5634122F2E4523616964313233343536 -> execute create by rawdata\n"\
2563 "hf mfdes createapp --aid 123456 --fid 2345 --dfname aid123456 -> app aid, iso file id, and iso df name is specified\n"
2564 "hf mfdes createapp --aid 123456 --fid 2345 --dfname aid123456 --dstalgo aes -> with algorithm for key AES");
2566 void *argtable
[] = {
2568 arg_lit0("a", "apdu", "Show APDU requests and responses"),
2569 arg_lit0("v", "verbose", "Verbose output"),
2570 arg_int0("n", "keyno", "<dec>", "Key number"),
2571 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
2572 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
2573 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
2574 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
2575 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
2576 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
2577 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
2578 arg_str0(NULL
, "rawdata", "<hex>", "Raw data that sends to command"),
2579 arg_str0(NULL
, "aid", "<hex>", "Application ID for create. Mandatory. (3 hex bytes, big endian)"),
2580 arg_str0(NULL
, "fid", "<hex>", "ISO file ID. Forbidden values: 0000 3F00, 3FFF, FFFF. (2 hex bytes, big endian)"),
2581 arg_str0(NULL
, "dfname", "<string>", "ISO DF Name (1..16 chars)"),
2582 arg_str0(NULL
, "dfhex", "<hex>", "ISO DF Name as hex (1..16 bytes)"),
2583 arg_str0(NULL
, "ks1", "<hex>", "Key settings 1 (1 hex byte). Application Master Key Settings (def: 0x0F)"),
2584 arg_str0(NULL
, "ks2", "<hex>", "Key settings 2 (1 hex byte). (def: 0x0E)"),
2585 arg_str0(NULL
, "dstalgo", "<DES|2TDEA|3TDEA|AES>", "Application key crypt algo (def: DES)"),
2586 arg_int0(NULL
, "numkeys", "<dec>", "Number of keys 0x00..0x0e (def: 0x0E)"),
2587 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
2590 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
2592 bool APDULogging
= arg_get_lit(ctx
, 1);
2593 bool verbose
= arg_get_lit(ctx
, 2);
2595 DesfireContext_t dctx
;
2596 int securechann
= defaultSecureChannel
;
2597 uint32_t appid
= 0x000000;
2598 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 12, 0, &securechann
, DCMMACed
, &appid
, NULL
);
2604 uint8_t rawdata
[250] = {0};
2605 int rawdatalen
= sizeof(rawdata
);
2606 CLIGetHexWithReturn(ctx
, 11, rawdata
, &rawdatalen
);
2608 uint32_t fileid
= 0x0000;
2609 bool fileidpresent
= false;
2610 if (CLIGetUint32Hex(ctx
, 13, 0x0000, &fileid
, &fileidpresent
, 2, "ISO file ID must have 2 bytes length")) {
2615 uint8_t dfname
[250] = {0};
2617 CLIGetStrWithReturn(ctx
, 14, dfname
, &dfnamelen
);
2619 if (dfnamelen
== 0) { // no text DF Name supplied
2621 CLIGetHexWithReturn(ctx
, 15, dfname
, &dfnamelen
);
2624 uint32_t ks1
= 0x0f;
2625 if (CLIGetUint32Hex(ctx
, 16, 0x0f, &ks1
, NULL
, 1, "Key settings 1 must have 1 byte length")) {
2630 uint32_t ks2
= 0x0e;
2631 bool ks2present
= false;
2632 if (CLIGetUint32Hex(ctx
, 17, 0x0e, &ks2
, &ks2present
, 1, "Key settings 2 must have 1 byte length")) {
2637 int dstalgo
= T_DES
;
2638 if (CLIGetOptionList(arg_get_str(ctx
, 18), DesfireAlgoOpts
, &dstalgo
)) {
2643 int keycount
= arg_get_int_def(ctx
, 19, 0x0e);
2644 bool noauth
= arg_get_lit(ctx
, 20);
2646 SetAPDULogging(APDULogging
);
2649 if (rawdatalen
== 0 && appid
== 0x000000) {
2650 PrintAndLogEx(ERR
, "Creating the root aid (0x000000) is " _RED_("forbidden"));
2654 if (rawdatalen
== 0 && (fileidpresent
|| (ks2
& 0x20) != 0) && fileid
== 0x0000) {
2655 PrintAndLogEx(ERR
, "Creating the application with ISO file ID 0x0000 is " _RED_("forbidden"));
2659 if (keycount
> 0x0e || keycount
< 1) {
2660 PrintAndLogEx(ERR
, "Key count must be in the range 1..14");
2664 if (dfnamelen
> 16) {
2665 PrintAndLogEx(ERR
, "DF name must be a maximum of 16 bytes in length");
2669 res
= DesfireSelectAndAuthenticateEx(&dctx
, securechann
, 0x000000, noauth
, verbose
);
2670 if (res
!= PM3_SUCCESS
) {
2675 uint8_t data
[250] = {0};
2677 if (rawdatalen
> 0) {
2678 memcpy(data
, rawdata
, rawdatalen
);
2679 datalen
= rawdatalen
;
2681 DesfireAIDUintToByte(appid
, &data
[0]);
2682 data
[3] = ks1
& 0xff;
2683 data
[4] = ks2
& 0xff;
2688 data
[4] |= keycount
& 0x0f;
2690 uint8_t kt
= DesfireKeyAlgoToType(dstalgo
);
2692 data
[4] |= (kt
& 0x03) << 6;
2696 if (fileidpresent
|| (data
[4] & 0x20) != 0) {
2697 Uint2byteToMemLe(&data
[5], fileid
);
2698 data
[4] |= 0x20; // set bit FileID in the ks2
2699 memcpy(&data
[7], dfname
, dfnamelen
);
2700 datalen
= 7 + dfnamelen
;
2705 PrintAndLogEx(INFO
, "---------------------------");
2706 PrintAndLogEx(INFO
, _CYAN_("Creating Application using:"));
2707 PrintAndLogEx(INFO
, "AID 0x%02X%02X%02X", data
[2], data
[1], data
[0]);
2708 PrintAndLogEx(INFO
, "Key Set 1 0x%02X", data
[3]);
2709 PrintAndLogEx(INFO
, "Key Set 2 0x%02X", data
[4]);
2710 PrintAndLogEx(INFO
, "ISO file ID %s", (data
[4] & 0x20) ? "enabled" : "disabled");
2711 if ((data
[4] & 0x20)) {
2712 PrintAndLogEx(INFO
, "ISO file ID 0x%04x", MemLeToUint2byte(&data
[5]));
2713 PrintAndLogEx(INFO
, "DF Name[%02d] %s | %s\n", dfnamelen
, sprint_ascii(dfname
, dfnamelen
), sprint_hex(dfname
, dfnamelen
));
2715 PrintKeySettings(data
[3], data
[4], true, true);
2716 PrintAndLogEx(INFO
, "---------------------------");
2719 res
= DesfireCreateApplication(&dctx
, data
, datalen
);
2720 if (res
!= PM3_SUCCESS
) {
2721 PrintAndLogEx(ERR
, "Desfire CreateApplication command " _RED_("error") ". Result: %d", res
);
2726 PrintAndLogEx(SUCCESS
, "Desfire application %06x successfully " _GREEN_("created"), appid
);
2732 static int CmdHF14ADesDeleteApp(const char *Cmd
) {
2733 CLIParserContext
*ctx
;
2734 CLIParserInit(&ctx
, "hf mfdes deleteapp",
2735 "Delete application by its 3-byte AID. Master key needs to be provided. ",
2736 "hf mfdes deleteapp --aid 123456 -> execute with default factory setup");
2738 void *argtable
[] = {
2740 arg_lit0("a", "apdu", "Show APDU requests and responses"),
2741 arg_lit0("v", "verbose", "Verbose output"),
2742 arg_int0("n", "keyno", "<dec>", "Key number"),
2743 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
2744 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
2745 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
2746 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
2747 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
2748 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
2749 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
2750 arg_str0(NULL
, "aid", "<hex>", "Application ID to delete (3 hex bytes, big endian)"),
2753 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
2755 bool APDULogging
= arg_get_lit(ctx
, 1);
2756 bool verbose
= arg_get_lit(ctx
, 2);
2758 DesfireContext_t dctx
;
2759 int securechann
= defaultSecureChannel
;
2760 uint32_t appid
= 0x000000;
2761 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann
, DCMMACed
, &appid
, NULL
);
2767 SetAPDULogging(APDULogging
);
2770 if (appid
== 0x000000) {
2771 PrintAndLogEx(WARNING
, "Deleting the root aid (0x000000) is " _RED_("forbidden"));
2775 res
= DesfireSelectAndAuthenticate(&dctx
, securechann
, 0x000000, verbose
);
2776 if (res
!= PM3_SUCCESS
) {
2781 res
= DesfireDeleteApplication(&dctx
, appid
);
2782 if (res
!= PM3_SUCCESS
) {
2783 PrintAndLogEx(ERR
, "Desfire DeleteApplication command " _RED_("error") ". Result: %d", res
);
2788 PrintAndLogEx(SUCCESS
, "Desfire application %06x " _GREEN_("deleted"), appid
);
2794 static int CmdHF14ADesGetUID(const char *Cmd
) {
2795 CLIParserContext
*ctx
;
2796 CLIParserInit(&ctx
, "hf mfdes getuid",
2797 "Get UID from card. Get the real UID if the random UID bit is on and get the same UID as in anticollision if not. Any card's key needs to be provided. ",
2798 "hf mfdes getuid -> execute with default factory setup\n"
2799 "hf mfdes getuid --isoid df01 -t aes --schan lrp -> for desfire lights default settings");
2801 void *argtable
[] = {
2803 arg_lit0("a", "apdu", "Show APDU requests and responses"),
2804 arg_lit0("v", "verbose", "Verbose output"),
2805 arg_int0("n", "keyno", "<dec>", "Key number"),
2806 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
2807 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
2808 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
2809 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
2810 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
2811 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
2812 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
2813 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
2814 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
2817 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
2819 bool APDULogging
= arg_get_lit(ctx
, 1);
2820 bool verbose
= arg_get_lit(ctx
, 2);
2822 DesfireContext_t dctx
;
2823 int securechann
= defaultSecureChannel
;
2824 uint32_t id
= 0x000000;
2825 DesfireISOSelectWay selectway
= ISW6bAID
;
2826 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann
, DCMEncrypted
, &id
, &selectway
);
2832 SetAPDULogging(APDULogging
);
2835 res
= DesfireSelectAndAuthenticateAppW(&dctx
, securechann
, selectway
, id
, false, verbose
);
2836 if (res
!= PM3_SUCCESS
) {
2838 PrintAndLogEx(FAILED
, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway
, id
), res
, DesfireAuthErrorToStr(res
));
2842 uint8_t buf
[APDU_RES_LEN
] = {0};
2845 res
= DesfireGetUID(&dctx
, buf
, &buflen
);
2846 if (res
!= PM3_SUCCESS
) {
2847 PrintAndLogEx(ERR
, "Desfire GetUID command " _RED_("error") ". Result: %d", res
);
2853 PrintAndLogEx(SUCCESS
, "received data[%zu]: %s", buflen
, sprint_hex(buf
, buflen
));
2857 PrintAndLogEx(SUCCESS
, "Desfire UID[%zu]: " _GREEN_("%s"), buflen
, sprint_hex(buf
, buflen
));
2859 if (buf
[1] == 0x04) {
2860 PrintAndLogEx(SUCCESS
, "Desfire UID4: " _GREEN_("%s"), sprint_hex(&buf
[2], 4));
2861 } else if (buf
[1] == 0x0a) {
2862 PrintAndLogEx(SUCCESS
, "Desfire UID10: " _GREEN_("%s"), sprint_hex(&buf
[2], 10));
2864 PrintAndLogEx(WARNING
, "Card returned wrong uid length: %d (0x%02x)", buf
[1], buf
[1]);
2868 PrintAndLogEx(WARNING
, "Card returned no data");
2875 static int CmdHF14ADesFormatPICC(const char *Cmd
) {
2876 CLIParserContext
*ctx
;
2877 CLIParserInit(&ctx
, "hf mfdes formatpicc",
2878 "Format card. Can be done only if enabled in the configuration. Master key needs to be provided. ",
2879 "hf mfdes formatpicc -> execute with default factory setup");
2881 void *argtable
[] = {
2883 arg_lit0("a", "apdu", "Show APDU requests and responses"),
2884 arg_lit0("v", "verbose", "Verbose output"),
2885 arg_int0("n", "keyno", "<dec>", "Key number"),
2886 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
2887 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
2888 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
2889 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
2890 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
2891 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
2892 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
2893 arg_str0(NULL
, "aid", "<hex>", "Application ID of delegated application (3 hex bytes, big endian)"),
2896 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
2898 bool APDULogging
= arg_get_lit(ctx
, 1);
2899 bool verbose
= arg_get_lit(ctx
, 2);
2901 DesfireContext_t dctx
;
2902 int securechann
= defaultSecureChannel
;
2903 uint32_t appid
= 0x000000;
2904 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann
, DCMMACed
, &appid
, NULL
);
2910 SetAPDULogging(APDULogging
);
2913 res
= DesfireSelectAndAuthenticate(&dctx
, securechann
, appid
, verbose
);
2914 if (res
!= PM3_SUCCESS
) {
2919 res
= DesfireFormatPICC(&dctx
);
2920 if (res
!= PM3_SUCCESS
) {
2921 PrintAndLogEx(ERR
, "Desfire FormatPICC command " _RED_("error") ". Result: %d", res
);
2926 PrintAndLogEx(SUCCESS
, "Desfire format: " _GREEN_("done"));
2932 static int CmdHF14ADesGetFreeMem(const char *Cmd
) {
2933 CLIParserContext
*ctx
;
2934 CLIParserInit(&ctx
, "hf mfdes getfreemem",
2935 "Get card's free memory. Can be done with or without authentication. Master key may be provided.",
2936 "hf mfdes getfreemem -> execute with default factory setup");
2938 void *argtable
[] = {
2940 arg_lit0("a", "apdu", "Show APDU requests and responses"),
2941 arg_lit0("v", "verbose", "Verbose output"),
2942 arg_int0("n", "keyno", "<dec>", "Key number"),
2943 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
2944 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
2945 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
2946 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
2947 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
2948 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
2949 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
2950 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
2953 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
2955 bool APDULogging
= arg_get_lit(ctx
, 1);
2956 bool verbose
= arg_get_lit(ctx
, 2);
2958 bool noauth
= arg_get_lit(ctx
, 11);
2960 DesfireContext_t dctx
;
2961 int securechann
= defaultSecureChannel
;
2962 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, &securechann
, (noauth
) ? DCMPlain
: DCMMACed
, NULL
, NULL
);
2968 SetAPDULogging(APDULogging
);
2971 res
= DesfireSelectAndAuthenticateEx(&dctx
, securechann
, 0x000000, noauth
, verbose
);
2972 if (res
!= PM3_SUCCESS
) {
2977 uint32_t freemem
= 0;
2979 res
= DesfireGetFreeMem(&dctx
, &freemem
);
2980 if (res
!= PM3_SUCCESS
) {
2981 PrintAndLogEx(ERR
, "Desfire GetFreeMem command " _RED_("error") ". Result: %d", res
);
2986 PrintAndLogEx(SUCCESS
, "Free memory [0x%06x] %d bytes", freemem
, freemem
);
2992 static int CmdHF14ADesChKeySettings(const char *Cmd
) {
2993 CLIParserContext
*ctx
;
2994 CLIParserInit(&ctx
, "hf mfdes chkeysettings",
2995 "Change key settings for card level or application level.\n"
2996 "WARNING: card level changes may block the card!",
2997 "hf mfdes chkeysettings -d 0f -> set picc key settings with default key/channel setup\n"\
2998 "hf mfdes chkeysettings --aid 123456 -d 0f -> set app 123456 key settings with default key/channel setup");
3000 void *argtable
[] = {
3002 arg_lit0("a", "apdu", "Show APDU requests and responses"),
3003 arg_lit0("v", "verbose", "Verbose output"),
3004 arg_int0("n", "keyno", "<dec>", "Key number"),
3005 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
3006 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
3007 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
3008 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
3009 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
3010 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
3011 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
3012 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
3013 arg_str0("d", "data", "<HEX>", "Key settings (1 hex byte)"),
3016 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
3018 bool APDULogging
= arg_get_lit(ctx
, 1);
3019 bool verbose
= arg_get_lit(ctx
, 2);
3021 DesfireContext_t dctx
;
3022 int securechann
= defaultSecureChannel
;
3023 uint32_t appid
= 0x000000;
3024 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann
, DCMEncrypted
, &appid
, NULL
);
3030 uint32_t ksett32
= 0;
3031 if (CLIGetUint32Hex(ctx
, 12, 0x0f, &ksett32
, NULL
, 1, "Key settings must have 1 byte length")) {
3036 SetAPDULogging(APDULogging
);
3040 PrintAndLogEx(SUCCESS
, "\nNew key settings:");
3041 PrintKeySettings(ksett32
, 0, (appid
!= 0x000000), false);
3044 res
= DesfireSelectAndAuthenticate(&dctx
, securechann
, appid
, verbose
);
3045 if (res
!= PM3_SUCCESS
) {
3050 uint8_t keysett
= ksett32
& 0xff;
3051 res
= DesfireChangeKeySettings(&dctx
, &keysett
, 1);
3052 if (res
!= PM3_SUCCESS
) {
3053 PrintAndLogEx(ERR
, "Desfire ChangeKeySettings command " _RED_("error") ". Result: %d", res
);
3058 PrintAndLogEx(INFO
, "Key settings " _GREEN_("changed"));
3064 static int CmdHF14ADesGetKeyVersions(const char *Cmd
) {
3065 CLIParserContext
*ctx
;
3066 CLIParserInit(&ctx
, "hf mfdes getkeyversions",
3067 "Get key versions for card level or application level.",
3068 "--keynum parameter: App level: key number. PICC level: 00..0d - keys count, 21..23 vc keys, default 0x00.\n"\
3069 "hf mfdes getkeyversions --keynum 00 -> get picc master key version with default key/channel setup\n"\
3070 "hf mfdes getkeyversions --aid 123456 --keynum 0d -> get app 123456 all key versions with default key/channel setup\n"
3071 "hf mfdes getkeyversions --aid 123456 --keynum 0d --no-auth -> get key version without authentication");
3073 void *argtable
[] = {
3075 arg_lit0("a", "apdu", "Show APDU requests and responses"),
3076 arg_lit0("v", "verbose", "Verbose output"),
3077 arg_int0("n", "keyno", "<dec>", "Key number for authentication"),
3078 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
3079 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
3080 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
3081 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
3082 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
3083 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
3084 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
3085 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
3086 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)."),
3087 arg_str0(NULL
, "keynum", "<hex>", "Key number/count (1 hex byte). (def: 0x00)"),
3088 arg_str0(NULL
, "keyset", "<hex>", "Keyset number (1 hex byte)"),
3089 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
3092 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
3094 bool APDULogging
= arg_get_lit(ctx
, 1);
3095 bool verbose
= arg_get_lit(ctx
, 2);
3096 bool noauth
= arg_get_lit(ctx
, 15);
3098 DesfireContext_t dctx
;
3099 int securechann
= defaultSecureChannel
;
3100 uint32_t id
= 0x000000;
3101 DesfireISOSelectWay selectway
= ISW6bAID
;
3102 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann
, DCMMACed
, &id
, &selectway
);
3108 uint32_t keynum32
= 0x00;
3109 if (CLIGetUint32Hex(ctx
, 13, 0x00, &keynum32
, NULL
, 1, "Key number must have 1 byte length")) {
3114 uint32_t keysetnum32
= 0x00;
3115 bool keysetpresent
= false;
3116 if (CLIGetUint32Hex(ctx
, 14, 0x00, &keysetnum32
, &keysetpresent
, 1, "Keyset number must have 1 byte length")) {
3121 if (keysetpresent
&& DesfireMFSelected(selectway
, id
)) {
3122 PrintAndLogEx(WARNING
, "Keyset only at Application level");
3123 keysetpresent
= false;
3126 SetAPDULogging(APDULogging
);
3129 res
= DesfireSelectAndAuthenticateAppW(&dctx
, securechann
, selectway
, id
, noauth
, verbose
);
3130 if (res
!= PM3_SUCCESS
) {
3132 PrintAndLogEx(FAILED
, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway
, id
), res
, DesfireAuthErrorToStr(res
));
3136 uint8_t buf
[APDU_RES_LEN
] = {0};
3139 uint8_t data
[2] = {0};
3140 data
[0] = keynum32
& 0xff;
3141 if (keysetpresent
) {
3143 data
[1] = keysetnum32
& 0xff;
3146 res
= DesfireGetKeyVersion(&dctx
, data
, (keysetpresent
) ? 2 : 1, buf
, &buflen
);
3147 if (res
!= PM3_SUCCESS
) {
3148 PrintAndLogEx(ERR
, "Desfire GetKeyVersion command " _RED_("error") ". Result: %d", res
);
3154 PrintAndLogEx(INFO
, "GetKeyVersion[%zu]: %s", buflen
, sprint_hex(buf
, buflen
));
3157 PrintAndLogEx(INFO
, "----------------------- " _CYAN_("Key Versions") " -----------------------");
3158 for (int i
= 0; i
< buflen
; i
++)
3159 PrintAndLogEx(INFO
, "Key 0x%02x version 0x%02x", i
, buf
[i
]);
3161 PrintAndLogEx(INFO
, "No key versions returned.");
3168 static int CmdHF14ADesGetKeySettings(const char *Cmd
) {
3169 CLIParserContext
*ctx
;
3170 CLIParserInit(&ctx
, "hf mfdes getkeysettings",
3171 "Get key settings for card level or application level.",
3172 "hf mfdes getkeysettings -> get picc key settings with default key/channel setup\n"\
3173 "hf mfdes getkeysettings --aid 123456 -> get app 123456 key settings with default key/channel setup");
3175 void *argtable
[] = {
3177 arg_lit0("a", "apdu", "Show APDU requests and responses"),
3178 arg_lit0("v", "verbose", "Verbose output"),
3179 arg_int0("n", "keyno", "<dec>", "Key number"),
3180 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
3181 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
3182 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
3183 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
3184 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
3185 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
3186 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
3187 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
3190 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
3192 bool APDULogging
= arg_get_lit(ctx
, 1);
3193 bool verbose
= arg_get_lit(ctx
, 2);
3195 DesfireContext_t dctx
;
3196 int securechann
= defaultSecureChannel
;
3197 uint32_t appid
= 0x000000;
3198 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann
, DCMMACed
, &appid
, NULL
);
3204 SetAPDULogging(APDULogging
);
3207 res
= DesfireSelectAndAuthenticate(&dctx
, securechann
, appid
, verbose
);
3208 if (res
!= PM3_SUCCESS
) {
3213 uint8_t buf
[APDU_RES_LEN
] = {0};
3216 res
= DesfireGetKeySettings(&dctx
, buf
, &buflen
);
3217 if (res
!= PM3_SUCCESS
) {
3218 PrintAndLogEx(ERR
, "Desfire GetKeySettings command " _RED_("error") ". Result: %d", res
);
3224 PrintAndLogEx(INFO
, "GetKeySettings[%zu]: %s", buflen
, sprint_hex(buf
, buflen
));
3227 PrintAndLogEx(ERR
, "Command GetKeySettings returned wrong length: %zu", buflen
);
3232 PrintAndLogEx(INFO
, "----------------------- " _CYAN_("Key settings") " -----------------------");
3233 PrintKeySettings(buf
[0], buf
[1], (appid
!= 0x000000), true);
3235 PrintAndLogEx(INFO
, "ak ver: %d", buf
[2]);
3237 PrintAndLogEx(INFO
, "num keysets: %d", buf
[3]);
3239 PrintAndLogEx(INFO
, "max keysize: %d", buf
[4]);
3241 PrintAndLogEx(INFO
, "app key settings: 0x%02x", buf
[5]);
3247 static int CmdHF14ADesGetAIDs(const char *Cmd
) {
3248 CLIParserContext
*ctx
;
3249 CLIParserInit(&ctx
, "hf mfdes getaids",
3250 "Get Application IDs list from card. Master key needs to be provided or flag --no-auth set.",
3251 "hf mfdes getaids -n 0 -t des -k 0000000000000000 --kdf none -> execute with default factory setup");
3253 void *argtable
[] = {
3255 arg_lit0("a", "apdu", "Show APDU requests and responses"),
3256 arg_lit0("v", "verbose", "Verbose output"),
3257 arg_int0("n", "keyno", "<dec>", "Key number"),
3258 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
3259 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
3260 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
3261 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
3262 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
3263 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
3264 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
3265 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
3268 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
3270 bool APDULogging
= arg_get_lit(ctx
, 1);
3271 bool verbose
= arg_get_lit(ctx
, 2);
3272 bool noauth
= arg_get_lit(ctx
, 11);
3274 DesfireContext_t dctx
;
3275 int securechann
= defaultSecureChannel
;
3276 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, &securechann
, DCMMACed
, NULL
, NULL
);
3282 SetAPDULogging(APDULogging
);
3285 res
= DesfireSelectAndAuthenticateEx(&dctx
, securechann
, 0x000000, noauth
, verbose
);
3286 if (res
!= PM3_SUCCESS
) {
3291 uint8_t buf
[APDU_RES_LEN
] = {0};
3294 res
= DesfireGetAIDList(&dctx
, buf
, &buflen
);
3295 if (res
!= PM3_SUCCESS
) {
3296 PrintAndLogEx(ERR
, "Desfire GetAIDList command " _RED_("error") ". Result: %d", res
);
3302 PrintAndLogEx(INFO
, "---- " _CYAN_("AID list") " ----");
3303 for (int i
= 0; i
< buflen
; i
+= 3) {
3304 const char *commentStr
= getAidCommentStr(&buf
[i
]);
3305 if ((void *) commentStr
== &noCommentStr
)
3306 PrintAndLogEx(INFO
, "AID: %06x", DesfireAIDByteToUint(&buf
[i
]));
3308 PrintAndLogEx(INFO
, "AID: %06x (%s)", DesfireAIDByteToUint(&buf
[i
]), commentStr
);
3311 PrintAndLogEx(INFO
, "There is no applications on the card");
3318 static int CmdHF14ADesGetAppNames(const char *Cmd
) {
3319 CLIParserContext
*ctx
;
3320 CLIParserInit(&ctx
, "hf mfdes getappnames",
3321 "Get Application IDs, ISO IDs and DF names from card. Master key needs to be provided or flag --no-auth set.",
3322 "hf mfdes getappnames -n 0 -t des -k 0000000000000000 --kdf none -> execute with default factory setup");
3324 void *argtable
[] = {
3326 arg_lit0("a", "apdu", "Show APDU requests and responses"),
3327 arg_lit0("v", "verbose", "Verbose output"),
3328 arg_int0("n", "keyno", "<dec>", "Key number"),
3329 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
3330 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
3331 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
3332 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
3333 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
3334 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
3335 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
3336 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
3339 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
3341 bool APDULogging
= arg_get_lit(ctx
, 1);
3342 bool verbose
= arg_get_lit(ctx
, 2);
3343 bool noauth
= arg_get_lit(ctx
, 11);
3345 DesfireContext_t dctx
;
3346 int securechann
= defaultSecureChannel
;
3347 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, &securechann
, DCMMACed
, NULL
, NULL
);
3353 SetAPDULogging(APDULogging
);
3356 res
= DesfireSelectAndAuthenticateEx(&dctx
, securechann
, 0x000000, noauth
, verbose
);
3357 if (res
!= PM3_SUCCESS
) {
3362 uint8_t buf
[APDU_RES_LEN
] = {0};
3365 // result bytes: 3, 2, 1-16. total record size = 24
3366 res
= DesfireGetDFList(&dctx
, buf
, &buflen
);
3367 if (res
!= PM3_SUCCESS
) {
3368 PrintAndLogEx(ERR
, "Desfire GetDFList command " _RED_("error") ". Result: %d", res
);
3374 PrintAndLogEx(INFO
, "----------------------- " _CYAN_("File list") " -----------------------");
3375 for (int i
= 0; i
< buflen
; i
++)
3376 PrintAndLogEx(INFO
, "AID: %06x ISO file id: %02x%02x ISO DF name[%zu]: %s",
3377 DesfireAIDByteToUint(&buf
[i
* 24 + 1]),
3378 buf
[i
* 24 + 1 + 3], buf
[i
* 24 + 1 + 4],
3379 strlen((char *)&buf
[i
* 24 + 1 + 5]),
3380 &buf
[i
* 24 + 1 + 5]);
3382 PrintAndLogEx(INFO
, "There is no applications on the card");
3389 static int CmdHF14ADesGetFileIDs(const char *Cmd
) {
3390 CLIParserContext
*ctx
;
3391 CLIParserInit(&ctx
, "hf mfdes getfileids",
3392 "Get File IDs list from card. Master key needs to be provided or flag --no-auth set.",
3393 "hf mfdes getfileids --aid 123456 -> execute with defaults from `default` command\n"
3394 "hf mfdes getfileids -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 -> execute with default factory setup");
3396 void *argtable
[] = {
3398 arg_lit0("a", "apdu", "Show APDU requests and responses"),
3399 arg_lit0("v", "verbose", "Verbose output"),
3400 arg_int0("n", "keyno", "<dec>", "Key number"),
3401 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
3402 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
3403 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
3404 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
3405 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
3406 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
3407 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
3408 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
3409 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)."),
3410 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
3413 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
3415 bool APDULogging
= arg_get_lit(ctx
, 1);
3416 bool verbose
= arg_get_lit(ctx
, 2);
3417 bool noauth
= arg_get_lit(ctx
, 13);
3419 DesfireContext_t dctx
;
3420 int securechann
= defaultSecureChannel
;
3421 uint32_t id
= 0x000000;
3422 DesfireISOSelectWay selectway
= ISW6bAID
;
3423 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann
, DCMMACed
, &id
, &selectway
);
3429 SetAPDULogging(APDULogging
);
3432 res
= DesfireSelectAndAuthenticateAppW(&dctx
, securechann
, selectway
, id
, noauth
, verbose
);
3433 if (res
!= PM3_SUCCESS
) {
3435 PrintAndLogEx(FAILED
, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway
, id
), res
, DesfireAuthErrorToStr(res
));
3439 uint8_t buf
[APDU_RES_LEN
] = {0};
3442 res
= DesfireGetFileIDList(&dctx
, buf
, &buflen
);
3443 if (res
!= PM3_SUCCESS
) {
3444 PrintAndLogEx(ERR
, "Desfire GetFileIDList command " _RED_("error") ". Result: %d", res
);
3450 PrintAndLogEx(INFO
, "---- " _CYAN_("File ID list") " ----");
3451 for (int i
= 0; i
< buflen
; i
++)
3452 PrintAndLogEx(INFO
, "File ID: %02x", buf
[i
]);
3454 PrintAndLogEx(INFO
, "There is no files in the application %06x", id
);
3461 static int CmdHF14ADesGetFileISOIDs(const char *Cmd
) {
3462 CLIParserContext
*ctx
;
3463 CLIParserInit(&ctx
, "hf mfdes getfileisoids",
3464 "Get File IDs list from card. Master key needs to be provided or flag --no-auth set.",
3465 "hf mfdes getfileisoids --aid 123456 -> execute with defaults from `default` command\n"
3466 "hf mfdes getfileisoids -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 -> execute with default factory setup\n"
3467 "hf mfdes getfileisoids --isoid df01 -> get iso file ids from Desfire Light with factory card settings\n"
3468 "hf mfdes getfileisoids --isoid df01 --schann lrp -t aes -> get iso file ids from Desfire Light via lrp channel with default key authentication");
3470 void *argtable
[] = {
3472 arg_lit0("a", "apdu", "Show APDU requests and responses"),
3473 arg_lit0("v", "verbose", "Verbose output"),
3474 arg_int0("n", "keyno", "<dec>", "Key number"),
3475 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
3476 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
3477 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
3478 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
3479 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
3480 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
3481 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
3482 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
3483 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)."),
3484 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
3487 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
3489 bool APDULogging
= arg_get_lit(ctx
, 1);
3490 bool verbose
= arg_get_lit(ctx
, 2);
3491 bool noauth
= arg_get_lit(ctx
, 13);
3493 DesfireContext_t dctx
;
3494 int securechann
= defaultSecureChannel
;
3495 uint32_t id
= 0x000000;
3496 DesfireISOSelectWay selectway
= ISW6bAID
;
3497 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann
, DCMMACed
, &id
, &selectway
);
3503 SetAPDULogging(APDULogging
);
3506 res
= DesfireSelectAndAuthenticateAppW(&dctx
, securechann
, selectway
, id
, noauth
, verbose
);
3507 if (res
!= PM3_SUCCESS
) {
3509 PrintAndLogEx(FAILED
, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway
, id
), res
, DesfireAuthErrorToStr(res
));
3513 uint8_t buf
[APDU_RES_LEN
] = {0};
3516 res
= DesfireGetFileISOIDList(&dctx
, buf
, &buflen
);
3517 if (res
!= PM3_SUCCESS
) {
3518 PrintAndLogEx(ERR
, "Desfire GetFileISOIDList command " _RED_("error") ". Result: %d", res
);
3524 PrintAndLogEx(INFO
, "---- " _CYAN_("File ISO ID list") " ----");
3525 for (int i
= 0; i
< buflen
; i
+= 2)
3526 PrintAndLogEx(INFO
, "File ID: %04x", MemLeToUint2byte(&buf
[i
]));
3528 PrintAndLogEx(INFO
, "There is no files in the application %06x", id
);
3535 static int CmdHF14ADesGetFileSettings(const char *Cmd
) {
3536 CLIParserContext
*ctx
;
3537 CLIParserInit(&ctx
, "hf mfdes getfilesettings",
3538 "Get File Settings from file from application. Master key needs to be provided or flag --no-auth set (depend on cards settings).",
3539 "hf mfdes getfilesettings --aid 123456 --fid 01 -> execute with defaults from `default` command\n"
3540 "hf mfdes getfilesettings --isoid df01 --fid 00 --no-auth -> get file settings with select by iso id\n"
3541 "hf mfdes getfilesettings -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 -> execute with default factory setup");
3543 void *argtable
[] = {
3545 arg_lit0("a", "apdu", "Show APDU requests and responses"),
3546 arg_lit0("v", "verbose", "Verbose output"),
3547 arg_int0("n", "keyno", "<dec>", "Key number"),
3548 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
3549 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
3550 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
3551 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
3552 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
3553 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
3554 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
3555 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
3556 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
3557 arg_str0(NULL
, "fid", "<hex>", "File ID (1 hex byte). (def: 1)"),
3558 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
3561 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
3563 bool APDULogging
= arg_get_lit(ctx
, 1);
3564 bool verbose
= arg_get_lit(ctx
, 2);
3565 bool noauth
= arg_get_lit(ctx
, 14);
3567 DesfireContext_t dctx
;
3568 int securechann
= defaultSecureChannel
;
3569 uint32_t id
= 0x000000;
3570 DesfireISOSelectWay selectway
= ISW6bAID
;
3571 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann
, DCMMACed
, &id
, &selectway
);
3577 uint32_t fileid
= 1;
3578 if (CLIGetUint32Hex(ctx
, 13, 1, &fileid
, NULL
, 1, "File ID must have 1 byte length")) {
3583 SetAPDULogging(APDULogging
);
3586 res
= DesfireSelectAndAuthenticateAppW(&dctx
, securechann
, selectway
, id
, noauth
, verbose
);
3587 if (res
!= PM3_SUCCESS
) {
3589 PrintAndLogEx(FAILED
, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway
, id
), res
, DesfireAuthErrorToStr(res
));
3593 uint8_t buf
[APDU_RES_LEN
] = {0};
3596 res
= DesfireGetFileSettings(&dctx
, fileid
, buf
, &buflen
);
3597 if (res
!= PM3_SUCCESS
) {
3598 PrintAndLogEx(ERR
, "Desfire GetFileSettings command " _RED_("error") ". Result: %d", res
);
3604 PrintAndLogEx(INFO
, "%s file %02x settings[%zu]: %s", DesfireWayIDStr(selectway
, id
), fileid
, buflen
, sprint_hex(buf
, buflen
));
3606 DesfirePrintFileSettings(buf
, buflen
);
3608 PrintAndLogEx(NORMAL
, "");
3613 static int DesfireCreateFileParameters(
3614 CLIParserContext
*ctx
,
3615 uint8_t pfileid
, uint8_t pisofileid
,
3616 uint8_t amodeid
, uint8_t frightsid
,
3617 uint8_t r_modeid
, uint8_t w_modeid
, uint8_t rw_modeid
, uint8_t ch_modeid
,
3618 uint8_t *data
, size_t *datalen
) {
3622 uint32_t fileid
= 1;
3624 if (CLIGetUint32Hex(ctx
, pfileid
, 1, &fileid
, NULL
, 1, "File ID must have 1 byte length"))
3628 uint32_t isofileid
= 0;
3630 if (CLIGetUint32Hex(ctx
, pisofileid
, 0, &isofileid
, NULL
, 2, "ISO file ID must have 2 bytes length"))
3637 if (isofileid
> 0) {
3638 Uint2byteToMemLe(&data
[1], isofileid
);
3642 uint8_t *settings
= &data
[*datalen
];
3645 int cmode
= DCMNone
;
3647 if (CLIGetOptionList(arg_get_str(ctx
, amodeid
), DesfireCommunicationModeOpts
, &cmode
)) {
3651 if (cmode
== DCMPlain
)
3653 if (cmode
== DCMMACed
)
3655 if (cmode
== DCMEncrypted
)
3661 uint32_t frights
= 0xeeee;
3662 bool userawfrights
= false;
3664 if (CLIGetUint32Hex(ctx
, frightsid
, 0xeeee, &frights
, &userawfrights
, 2, "File rights must have 2 bytes length")) {
3668 settings
[1] = frights
& 0xff;
3669 settings
[2] = (frights
>> 8) & 0xff;
3671 if (userawfrights
== false) {
3674 if (CLIGetOptionList(arg_get_str(ctx
, r_modeid
), DesfireFileAccessModeOpts
, &r_mode
))
3680 if (CLIGetOptionList(arg_get_str(ctx
, w_modeid
), DesfireFileAccessModeOpts
, &w_mode
))
3686 if (CLIGetOptionList(arg_get_str(ctx
, rw_modeid
), DesfireFileAccessModeOpts
, &rw_mode
))
3692 if (CLIGetOptionList(arg_get_str(ctx
, ch_modeid
), DesfireFileAccessModeOpts
, &ch_mode
))
3696 DesfireEncodeFileAcessMode(&settings
[1], r_mode
, w_mode
, rw_mode
, ch_mode
) ;
3703 static int CmdHF14ADesChFileSettings(const char *Cmd
) {
3704 CLIParserContext
*ctx
;
3705 CLIParserInit(&ctx
, "hf mfdes chfilesettings",
3706 "Get File Settings from file from application. Master key needs to be provided or flag --no-auth set (depend on cards settings).",
3707 "hf mfdes chfilesettings --aid 123456 --fid 01 --amode plain --rrights free --wrights free --rwrights free --chrights key0 -> change file settings app=123456, file=01 with defaults from `default` command\n"
3708 "hf mfdes chfilesettings -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 --rawdata 00EEEE -> execute with default factory setup\n"
3709 "hf mfdes chfilesettings --aid 123456 --fid 01 --rawdata 810000021f112f22 -> change file settings with additional rights for keys 1 and 2\n"
3710 "hf mfdes chfilesettings --isoid df01 --fid 00 --amode plain --rawrights eee0 --schann lrp -t aes -> change file settings via lrp channel");
3712 void *argtable
[] = {
3714 arg_lit0("a", "apdu", "Show APDU requests and responses"),
3715 arg_lit0("v", "verbose", "Verbose output"),
3716 arg_int0("n", "keyno", "<dec>", "Key number"),
3717 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
3718 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
3719 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
3720 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
3721 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
3722 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
3723 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
3724 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
3725 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
3726 arg_str0(NULL
, "fid", "<hex>", "File ID (1 hex byte)"),
3727 arg_str0(NULL
, "rawdata", "<hex>", "File settings (HEX > 5 bytes). Have priority over the other settings"),
3728 arg_str0(NULL
, "amode", "<plain|mac|encrypt>", "File access mode"),
3729 arg_str0(NULL
, "rawrights", "<hex>", "Access rights for file (2 hex bytes) R/W/RW/Chg, 0x0 - 0xD Key, 0xE Free, 0xF Denied"),
3730 arg_str0(NULL
, "rrights", "<key0..13|free|deny>", "Read file access mode: the specified key, free, deny"),
3731 arg_str0(NULL
, "wrights", "<key0..13|free|deny>", "Write file access mode: the specified key, free, deny"),
3732 arg_str0(NULL
, "rwrights", "<key0..13|free|deny>", "Read/Write file access mode: the specified key, free, deny"),
3733 arg_str0(NULL
, "chrights", "<key0..13|free|deny>", "Change file settings access mode: the specified key, free, deny"),
3734 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
3737 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
3739 bool APDULogging
= arg_get_lit(ctx
, 1);
3740 bool verbose
= arg_get_lit(ctx
, 2);
3741 bool noauth
= arg_get_lit(ctx
, 21);
3743 DesfireContext_t dctx
;
3744 int securechann
= defaultSecureChannel
;
3745 uint32_t id
= 0x000000;
3746 DesfireISOSelectWay selectway
= ISW6bAID
;
3747 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann
, DCMEncrypted
, &id
, &selectway
);
3753 uint8_t data
[250] = {0};
3754 uint8_t *settings
= &data
[1];
3757 res
= DesfireCreateFileParameters(ctx
, 13, 0, 15, 16, 17, 18, 19, 20, data
, &datalen
);
3763 uint8_t sdata
[250] = {0};
3764 int sdatalen
= sizeof(sdata
);
3765 CLIGetHexWithReturn(ctx
, 14, sdata
, &sdatalen
);
3771 if (sdatalen
> 18) {
3772 PrintAndLogEx(ERR
, "File settings length must be less than 18 instead of %d.", sdatalen
);
3777 // rawdata have priority over all the rest methods
3779 memcpy(settings
, sdata
, sdatalen
);
3780 datalen
= 1 + sdatalen
;
3783 SetAPDULogging(APDULogging
);
3786 uint8_t fileid
= data
[0];
3788 res
= DesfireSelectAndAuthenticateAppW(&dctx
, securechann
, selectway
, id
, noauth
, verbose
);
3789 if (res
!= PM3_SUCCESS
) {
3791 PrintAndLogEx(FAILED
, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway
, id
), res
, DesfireAuthErrorToStr(res
));
3795 uint8_t buf
[APDU_RES_LEN
] = {0};
3798 // check current file settings
3799 DesfireCommunicationMode commMode
= dctx
.commMode
;
3800 DesfireSetCommMode(&dctx
, DCMMACed
);
3801 res
= DesfireGetFileSettings(&dctx
, fileid
, buf
, &buflen
);
3802 if (res
== PM3_SUCCESS
&& buflen
> 5) {
3803 uint8_t chright
= 0;
3804 DesfireDecodeFileAcessMode(&buf
[2], NULL
, NULL
, NULL
, &chright
) ;
3806 PrintAndLogEx(INFO
, "Current access right for change file settings: %s", GetDesfireAccessRightStr(chright
));
3808 if (chright
== 0x0f)
3809 PrintAndLogEx(WARNING
, "Change file settings disabled");
3811 if (chright
== 0x0e && (!(commMode
== DCMPlain
|| commMode
== DCMMACed
|| noauth
)))
3812 PrintAndLogEx(WARNING
, "File settings have free access for change. Change command must be sent via plain communications mode or without authentication (--no-auth option)");
3814 if (chright
< 0x0e && dctx
.keyNum
!= chright
)
3815 PrintAndLogEx(WARNING
, "File settings must be changed with auth key=0x%02x but current auth with key 0x%02x", chright
, dctx
.keyNum
);
3817 if (chright
< 0x0e && commMode
!= DCMEncrypted
)
3818 PrintAndLogEx(WARNING
, "File settings must be changed via encryted (full) communication mode");
3820 DesfireSetCommMode(&dctx
, commMode
);
3822 // print the new file settings
3824 PrintAndLogEx(INFO
, "%s file %02x settings[%zu]: %s", DesfireWayIDStr(selectway
, id
), fileid
, datalen
- 1, sprint_hex(settings
, datalen
- 1));
3826 DesfirePrintSetFileSettings(settings
, datalen
- 1);
3828 // set file settings
3830 res
= DesfireChangeFileSettings(&dctx
, data
, datalen
);
3831 if (res
!= PM3_SUCCESS
) {
3832 PrintAndLogEx(ERR
, "Desfire ChangeFileSettings command " _RED_("error") ". Result: %d", res
);
3837 PrintAndLogEx(SUCCESS
, "File settings changed " _GREEN_("successfully"));
3843 static int CmdHF14ADesCreateFile(const char *Cmd
) {
3844 CLIParserContext
*ctx
;
3845 CLIParserInit(&ctx
, "hf mfdes createfile",
3846 "Create Standard/Backup file in the application. Application master key needs to be provided or flag --no-auth set (depend on application settings).",
3847 "--rawtype/--rawdata have priority over the other settings. and with these parameters you can create any file. file id comes from parameters, all the rest data must be in the --rawdata parameter\n"
3848 "--rawrights have priority over the separate rights settings.\n"
3849 "Key/mode/etc of the authentication depends on application settings\n"
3850 "hf mfdes createfile --aid 123456 --fid 01 --isofid 0001 --size 000010 -> create file with iso id. Authentication with defaults from `default` command\n"
3851 "hf mfdes createfile --aid 123456 --fid 01 --rawtype 01 --rawdata 000100EEEE000100 -> create file via sending rawdata to the card. Can be used to create any type of file. Authentication with defaults from `default` command\n"
3852 "hf mfdes createfile --aid 123456 --fid 01 --amode plain --rrights free --wrights free --rwrights free --chrights key0 -> create file app=123456, file=01 and mentioned rights with defaults from `default` command\n"
3853 "hf mfdes createfile -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 --rawtype 00 --rawdata 00EEEE000100 -> execute with default factory setup");
3855 void *argtable
[] = {
3857 arg_lit0("a", "apdu", "Show APDU requests and responses"),
3858 arg_lit0("v", "verbose", "Verbose output"),
3859 arg_int0("n", "keyno", "<dec>", "Key number"),
3860 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
3861 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
3862 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
3863 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
3864 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
3865 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
3866 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
3867 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
3868 arg_str0(NULL
, "fid", "<hex>", "File ID (1 hex byte)"),
3869 arg_str0(NULL
, "isofid", "<hex>", "ISO File ID (2 hex bytes)"),
3870 arg_str0(NULL
, "rawtype", "<hex>", "Raw file type (1 hex byte)"),
3871 arg_str0(NULL
, "rawdata", "<hex>", "Raw file settings (hex > 5 bytes)"),
3872 arg_str0(NULL
, "amode", "<plain|mac|encrypt>", "File access mode"),
3873 arg_str0(NULL
, "rawrights", "<hex>", "Access rights for file (2 hex bytes) R/W/RW/Chg, 0x0 - 0xD Key, 0xE Free, 0xF Denied"),
3874 arg_str0(NULL
, "rrights", "<key0..key13|free|deny>", "Read file access mode: the specified key, free, deny"),
3875 arg_str0(NULL
, "wrights", "<key0..key13|free|deny>", "Write file access mode: the specified key, free, deny"),
3876 arg_str0(NULL
, "rwrights", "<key0..key13|free|deny>", "Read/Write file access mode: the specified key, free, deny"),
3877 arg_str0(NULL
, "chrights", "<key0..key13|free|deny>", "Change file settings access mode: the specified key, free, deny"),
3878 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
3879 arg_str0(NULL
, "size", "<hex>", "File size (3 hex bytes, big endian)"),
3880 arg_lit0(NULL
, "backup", "Create backupfile instead of standard file"),
3883 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
3885 bool APDULogging
= arg_get_lit(ctx
, 1);
3886 bool verbose
= arg_get_lit(ctx
, 2);
3887 bool noauth
= arg_get_lit(ctx
, 22);
3888 bool backup
= arg_get_lit(ctx
, 24);
3889 uint8_t filetype
= (backup
) ? 0x01 : 0x00; // backup / standard data file
3891 DesfireContext_t dctx
;
3892 int securechann
= defaultSecureChannel
;
3893 uint32_t appid
= 0x000000;
3894 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann
, DCMMACed
, &appid
, NULL
);
3900 if (appid
== 0x000000) {
3901 PrintAndLogEx(ERR
, "Can't create files at card level.");
3906 uint8_t data
[250] = {0};
3909 res
= DesfireCreateFileParameters(ctx
, 12, 13, 16, 17, 18, 19, 20, 21, data
, &datalen
);
3915 uint32_t rawftype
= 0x00;
3916 bool useraw
= false;
3917 if (CLIGetUint32Hex(ctx
, 14, 0x00, &rawftype
, &useraw
, 1, "Raw file type must have 1 byte length")) {
3922 uint8_t sdata
[250] = {0};
3923 int sdatalen
= sizeof(sdata
);
3924 CLIGetHexWithReturn(ctx
, 15, sdata
, &sdatalen
);
3925 if (sdatalen
> 20) {
3926 PrintAndLogEx(ERR
, "Rawdata length must be less than 20 bytes instead of %d.", sdatalen
);
3931 if (useraw
&& sdatalen
> 0) {
3932 filetype
= rawftype
;
3933 memcpy(&data
[1], sdata
, sdatalen
);
3934 datalen
= 1 + sdatalen
;
3939 if (useraw
== false) {
3940 uint32_t filesize
= 0;
3941 if (CLIGetUint32Hex(ctx
, 23, 0, &filesize
, NULL
, 3, "File size must have 3 bytes length")) {
3946 if (filesize
== 0) {
3947 PrintAndLogEx(ERR
, "File size must be greater than 0");
3952 Uint3byteToMemLe(&data
[datalen
], filesize
);
3956 SetAPDULogging(APDULogging
);
3959 res
= DesfireSelectAndAuthenticateEx(&dctx
, securechann
, appid
, noauth
, verbose
);
3960 if (res
!= PM3_SUCCESS
) {
3966 PrintAndLogEx(INFO
, "App: %06x. File num: 0x%02x type: 0x%02x data[%zu]: %s", appid
, data
[0], filetype
, datalen
, sprint_hex(data
, datalen
));
3967 DesfirePrintCreateFileSettings(filetype
, data
, datalen
);
3970 res
= DesfireCreateFile(&dctx
, filetype
, data
, datalen
, useraw
== false); // check length only if we nont use raw mode
3971 if (res
!= PM3_SUCCESS
) {
3972 PrintAndLogEx(ERR
, "Desfire CreateFile command " _RED_("error") ". Result: %d", res
);
3977 PrintAndLogEx(SUCCESS
, "%s file %02x in the app %06x created " _GREEN_("successfully"), GetDesfireFileType(filetype
), data
[0], appid
);
3983 static int CmdHF14ADesCreateValueFile(const char *Cmd
) {
3984 CLIParserContext
*ctx
;
3985 CLIParserInit(&ctx
, "hf mfdes createvaluefile",
3986 "Create Value file in the application. Application master key needs to be provided or flag --no-auth set (depend on application settings).",
3987 "--rawrights have priority over the separate rights settings.\n"
3988 "Key/mode/etc of the authentication depends on application settings\n"
3989 "hf mfdes createvaluefile --aid 123456 --fid 01 --lower 00000010 --upper 00010000 --value 00000100 -> create file with parameters. Rights from default. Authentication with defaults from `default` command\n"
3990 "hf mfdes createvaluefile --aid 123456 --fid 01 --amode plain --rrights free --wrights free --rwrights free --chrights key0 -> create file app=123456, file=01 and mentioned rights with defaults from `default` command\n"
3991 "hf mfdes createvaluefile -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 -> execute with default factory setup");
3993 void *argtable
[] = {
3995 arg_lit0("a", "apdu", "Show APDU requests and responses"),
3996 arg_lit0("v", "verbose", "Verbose output"),
3997 arg_int0("n", "keyno", "<dec>", "Key number"),
3998 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
3999 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
4000 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
4001 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
4002 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
4003 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
4004 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
4005 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
4006 arg_str0(NULL
, "fid", "<hex>", "File ID (1 hex byte)"),
4007 arg_str0(NULL
, "amode", "<plain|mac|encrypt>", "File access mode"),
4008 arg_str0(NULL
, "rawrights", "<hex>", "Access rights for file (2 hex bytes) R/W/RW/Chg, 0x0 - 0xD Key, 0xE Free, 0xF Denied"),
4009 arg_str0(NULL
, "rrights", "<key0..key13|free|deny>", "Read file access mode: the specified key, free, deny"),
4010 arg_str0(NULL
, "wrights", "<key0..key13|free|deny>", "Write file access mode: the specified key, free, deny"),
4011 arg_str0(NULL
, "rwrights", "<key0..key13|free|deny>", "Read/Write file access mode: the specified key, free, deny"),
4012 arg_str0(NULL
, "chrights", "<key0..key13|free|deny>", "Change file settings access mode: the specified key, free, deny"),
4013 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
4014 arg_str0(NULL
, "lower", "<hex>", "Lower limit (4 hex bytes, big endian)"),
4015 arg_str0(NULL
, "upper", "<hex>", "Upper limit (4 hex bytes, big endian)"),
4016 arg_str0(NULL
, "value", "<hex>", "Value (4 hex bytes, big endian)"),
4017 arg_int0(NULL
, "lcredit", "<dec>", "Limited Credit enabled (Bit 0 = Limited Credit, 1 = FreeValue)"),
4020 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
4022 bool APDULogging
= arg_get_lit(ctx
, 1);
4023 bool verbose
= arg_get_lit(ctx
, 2);
4024 bool noauth
= arg_get_lit(ctx
, 19);
4026 uint8_t filetype
= 0x02; // value file
4028 DesfireContext_t dctx
;
4029 int securechann
= defaultSecureChannel
;
4030 uint32_t appid
= 0x000000;
4031 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann
, DCMMACed
, &appid
, NULL
);
4037 if (appid
== 0x000000) {
4038 PrintAndLogEx(ERR
, "Can't create files at card level.");
4043 uint8_t data
[250] = {0};
4046 res
= DesfireCreateFileParameters(ctx
, 12, 0, 13, 14, 15, 16, 17, 18, data
, &datalen
);
4052 uint32_t lowerlimit
= 0;
4053 if (CLIGetUint32Hex(ctx
, 20, 0, &lowerlimit
, NULL
, 4, "Lower limit value must have 4 bytes length")) {
4058 uint32_t upperlimit
= 0;
4059 if (CLIGetUint32Hex(ctx
, 21, 0, &upperlimit
, NULL
, 4, "Upper limit value must have 4 bytes length")) {
4065 if (CLIGetUint32Hex(ctx
, 22, 0, &value
, NULL
, 4, "Value must have 4 bytes length")) {
4070 uint32_t lcredit
= arg_get_int_def(ctx
, 23, 0);
4072 SetAPDULogging(APDULogging
);
4076 Uint4byteToMemLe(&data
[datalen
], lowerlimit
);
4078 Uint4byteToMemLe(&data
[datalen
], upperlimit
);
4080 Uint4byteToMemLe(&data
[datalen
], value
);
4082 data
[datalen
] = lcredit
;
4085 res
= DesfireSelectAndAuthenticateEx(&dctx
, securechann
, appid
, noauth
, verbose
);
4086 if (res
!= PM3_SUCCESS
) {
4092 PrintAndLogEx(INFO
, "App: %06x. File num: 0x%02x type: 0x%02x data[%zu]: %s", appid
, data
[0], filetype
, datalen
, sprint_hex(data
, datalen
));
4093 DesfirePrintCreateFileSettings(filetype
, data
, datalen
);
4096 res
= DesfireCreateFile(&dctx
, filetype
, data
, datalen
, true);
4097 if (res
!= PM3_SUCCESS
) {
4098 PrintAndLogEx(ERR
, "Desfire CreateFile command " _RED_("error") ". Result: %d", res
);
4103 PrintAndLogEx(SUCCESS
, "Value file %02x in the app %06x created " _GREEN_("successfully"), data
[0], appid
);
4109 static int CmdHF14ADesCreateRecordFile(const char *Cmd
) {
4110 CLIParserContext
*ctx
;
4111 CLIParserInit(&ctx
, "hf mfdes createrecordfile",
4112 "Create Linear/Cyclic Record file in the application. Application master key needs to be provided or flag --no-auth set (depend on application settings).",
4113 "--rawrights have priority over the separate rights settings.\n"
4114 "Key/mode/etc of the authentication depends on application settings\n"
4115 "hf mfdes createrecordfile --aid 123456 --fid 01 --size 000010 --maxrecord 000010 --cyclic -> create cyclic record file with parameters. Rights from default. Authentication with defaults from `default` command\n"
4116 "hf mfdes createrecordfile --aid 123456 --fid 01 --amode plain --rrights free --wrights free --rwrights free --chrights key0 --size 000010 --maxrecord 000010 -> create linear record file app=123456, file=01 and mentioned rights with defaults from `default` command\n"
4117 "hf mfdes createrecordfile -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 --size 000010 --maxrecord 000010 -> execute with default factory setup");
4119 void *argtable
[] = {
4121 arg_lit0("a", "apdu", "Show APDU requests and responses"),
4122 arg_lit0("v", "verbose", "Verbose output"),
4123 arg_int0("n", "keyno", "<dec>", "Key number"),
4124 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
4125 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
4126 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
4127 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
4128 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
4129 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
4130 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
4131 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
4132 arg_str0(NULL
, "fid", "<hex>", "File ID (1 hex byte)"),
4133 arg_str0(NULL
, "isofid", "<hex>", "ISO File ID (2 hex bytes)"),
4134 arg_str0(NULL
, "amode", "<plain|mac|encrypt>", "File access mode"),
4135 arg_str0(NULL
, "rawrights", "<hex>", "Access rights for file (2 hex bytes) R/W/RW/Chg, 0x0 - 0xD Key, 0xE Free, 0xF Denied"),
4136 arg_str0(NULL
, "rrights", "<key0..key13|free|deny>", "Read file access mode: the specified key, free, deny"),
4137 arg_str0(NULL
, "wrights", "<key0..key13|free|deny>", "Write file access mode: the specified key, free, deny"),
4138 arg_str0(NULL
, "rwrights", "<key0..key13|free|deny>", "Read/Write file access mode: the specified key, free, deny"),
4139 arg_str0(NULL
, "chrights", "<key0..key13|free|deny>", "Change file settings access mode: the specified key, free, deny"),
4140 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
4141 arg_str0(NULL
, "size", "<hex>", "Record size (3 hex bytes, big endian, 000001 to FFFFFF)"),
4142 arg_str0(NULL
, "maxrecord", "<hex>", "Max. Number of Records (3 hex bytes, big endian)"),
4143 arg_lit0(NULL
, "cyclic", "Create cyclic record file instead of linear record file"),
4146 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
4148 bool APDULogging
= arg_get_lit(ctx
, 1);
4149 bool verbose
= arg_get_lit(ctx
, 2);
4150 bool noauth
= arg_get_lit(ctx
, 20);
4152 bool cyclic
= arg_get_lit(ctx
, 23);
4153 uint8_t filetype
= (cyclic
) ? 0x04 : 0x03; // linear(03) / cyclic(04) record file
4155 DesfireContext_t dctx
;
4156 int securechann
= defaultSecureChannel
;
4157 uint32_t appid
= 0x000000;
4158 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann
, DCMMACed
, &appid
, NULL
);
4164 if (appid
== 0x000000) {
4165 PrintAndLogEx(ERR
, "Can't create files at card level.");
4170 uint8_t data
[250] = {0};
4173 res
= DesfireCreateFileParameters(ctx
, 12, 13, 14, 15, 16, 17, 18, 19, data
, &datalen
);
4180 if (CLIGetUint32Hex(ctx
, 21, 0, &size
, NULL
, 3, "Record size must have 3 bytes length")) {
4185 uint32_t maxrecord
= 0;
4186 if (CLIGetUint32Hex(ctx
, 22, 0, &maxrecord
, NULL
, 3, "Max number of records must have 3 bytes length")) {
4191 SetAPDULogging(APDULogging
);
4195 Uint3byteToMemLe(&data
[datalen
], size
);
4197 Uint3byteToMemLe(&data
[datalen
], maxrecord
);
4200 res
= DesfireSelectAndAuthenticateEx(&dctx
, securechann
, appid
, noauth
, verbose
);
4201 if (res
!= PM3_SUCCESS
) {
4207 PrintAndLogEx(INFO
, "App: %06x. File num: 0x%02x type: 0x%02x data[%zu]: %s", appid
, data
[0], filetype
, datalen
, sprint_hex(data
, datalen
));
4208 DesfirePrintCreateFileSettings(filetype
, data
, datalen
);
4211 res
= DesfireCreateFile(&dctx
, filetype
, data
, datalen
, true);
4212 if (res
!= PM3_SUCCESS
) {
4213 PrintAndLogEx(ERR
, "Desfire CreateFile command " _RED_("error") ". Result: %d", res
);
4218 PrintAndLogEx(SUCCESS
, "%s file %02x in the app %06x created " _GREEN_("successfully"), GetDesfireFileType(filetype
), data
[0], appid
);
4224 static int CmdHF14ADesCreateTrMACFile(const char *Cmd
) {
4225 CLIParserContext
*ctx
;
4226 CLIParserInit(&ctx
, "hf mfdes createmacfile",
4227 "Create Transaction MAC file in the application. Application master key needs to be provided or flag --no-auth set (depend on application settings).",
4228 "--rawrights have priority over the separate rights settings.\n"
4229 "Key/mode/etc of the authentication depends on application settings\n"
4230 "Write right should be always 0xF. Read-write right should be 0xF if you not need to submit CommitReaderID command each time transaction starts\n"
4232 "hf mfdes createmacfile --aid 123456 --fid 01 --rawrights 0FF0 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file with parameters. Rights from default. Authentication with defaults from `default` command\n"
4233 "hf mfdes createmacfile --aid 123456 --fid 01 --amode plain --rrights free --wrights deny --rwrights free --chrights key0 --mackey 00112233445566778899aabbccddeeff -> create file app=123456, file=01, with key, and mentioned rights with defaults from `default` command\n"
4234 "hf mfdes createmacfile -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 -> execute with default factory setup. key and keyver == 0x00..00\n"
4235 "hf mfdes createmacfile --isoid df01 --fid 0f --schann lrp -t aes --rawrights 0FF0 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file via lrp channel\n"
4236 "hf mfdes createmacfile --isoid df01 --fid 0f --schann lrp -t aes --rawrights 0F10 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file via lrp channel with CommitReaderID command enable");
4238 void *argtable
[] = {
4240 arg_lit0("a", "apdu", "Show APDU requests and responses"),
4241 arg_lit0("v", "verbose", "Verbose output"),
4242 arg_int0("n", "keyno", "<dec>", "Key number"),
4243 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
4244 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
4245 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
4246 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
4247 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
4248 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
4249 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
4250 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
4251 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
4252 arg_str0(NULL
, "fid", "<hex>", "File ID (1 hex byte)"),
4253 arg_str0(NULL
, "amode", "<plain|mac|encrypt>", "File access mode"),
4254 arg_str0(NULL
, "rawrights", "<hex>", "Access rights for file (2 hex bytes) R/W/RW/Chg, 0x0 - 0xD Key, 0xE Free, 0xF Denied"),
4255 arg_str0(NULL
, "rrights", "<key0..key13|free|deny>", "Read file access mode: the specified key, free, deny"),
4256 arg_str0(NULL
, "wrights", "<key0..key13|free|deny>", "Write file access mode: the specified key, free, deny"),
4257 arg_str0(NULL
, "rwrights", "<key0..key13|free|deny>", "Read/Write file access mode: the specified key, free, deny"),
4258 arg_str0(NULL
, "chrights", "<key0..key13|free|deny>", "Change file settings access mode: the specified key, free, deny"),
4259 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
4260 arg_str0(NULL
, "mackey", "<hex>", "AES-128 key for MAC (16 hex bytes, big endian). (def: all zeros)"),
4261 arg_str0(NULL
, "mackeyver", "<hex>", "AES key version for MAC (1 hex byte). (def: 0x0)"),
4264 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
4266 bool APDULogging
= arg_get_lit(ctx
, 1);
4267 bool verbose
= arg_get_lit(ctx
, 2);
4268 bool noauth
= arg_get_lit(ctx
, 20);
4270 uint8_t filetype
= 0x05; // transaction mac file
4272 DesfireContext_t dctx
;
4273 int securechann
= defaultSecureChannel
;
4274 uint32_t id
= 0x000000;
4275 DesfireISOSelectWay selectway
= ISW6bAID
;
4276 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann
, DCMEncrypted
, &id
, &selectway
);
4282 if (DesfireMFSelected(selectway
, id
)) {
4283 PrintAndLogEx(ERR
, "Can't create files at card level.");
4288 uint8_t data
[250] = {0};
4291 res
= DesfireCreateFileParameters(ctx
, 13, 0, 14, 15, 16, 17, 18, 19, data
, &datalen
);
4297 uint8_t sdata
[250] = {0};
4298 int sdatalen
= sizeof(sdata
);
4299 CLIGetHexWithReturn(ctx
, 21, sdata
, &sdatalen
);
4300 if (sdatalen
!= 0 && sdatalen
!= 16) {
4301 PrintAndLogEx(ERR
, "AES-128 key must be 16 bytes instead of %d.", sdatalen
);
4306 uint32_t keyver
= 0x00;
4307 if (CLIGetUint32Hex(ctx
, 22, 0x00, &keyver
, NULL
, 1, "Key version must have 1 bytes length")) {
4312 SetAPDULogging(APDULogging
);
4315 data
[datalen
] = 0x02; // AES key
4318 memcpy(&data
[datalen
], sdata
, sdatalen
);
4320 data
[datalen
] = keyver
& 0xff;
4323 res
= DesfireSelectAndAuthenticateAppW(&dctx
, securechann
, selectway
, id
, noauth
, verbose
);
4324 if (res
!= PM3_SUCCESS
) {
4326 PrintAndLogEx(FAILED
, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway
, id
), res
, DesfireAuthErrorToStr(res
));
4331 PrintAndLogEx(INFO
, "%s. File num: 0x%02x type: 0x%02x data[%zu]: %s", DesfireWayIDStr(selectway
, id
), data
[0], filetype
, datalen
, sprint_hex(data
, datalen
));
4333 DesfirePrintCreateFileSettings(filetype
, data
, datalen
);
4335 res
= DesfireCreateFile(&dctx
, filetype
, data
, datalen
, true);
4336 if (res
!= PM3_SUCCESS
) {
4337 PrintAndLogEx(ERR
, "Desfire CreateFile command " _RED_("error") ". Result: %d", res
);
4342 PrintAndLogEx(SUCCESS
, "%s file %02x in the %s created " _GREEN_("successfully"), GetDesfireFileType(filetype
), data
[0], DesfireWayIDStr(selectway
, id
));
4348 static int CmdHF14ADesDeleteFile(const char *Cmd
) {
4349 CLIParserContext
*ctx
;
4350 CLIParserInit(&ctx
, "hf mfdes deletefile",
4351 "Delete file from application. Master key needs to be provided or flag --no-auth set (depend on cards settings).",
4352 "hf mfdes deletefile --aid 123456 --fid 01 -> delete file for: app=123456, file=01 with defaults from `default` command\n"
4353 "hf mfdes deletefile --isoid df01 --fid 0f --schann lrp -t aes -> delete file for lrp channel");
4355 void *argtable
[] = {
4357 arg_lit0("a", "apdu", "Show APDU requests and responses"),
4358 arg_lit0("v", "verbose", "Verbose output"),
4359 arg_int0("n", "keyno", "<dec>", "Key number"),
4360 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
4361 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
4362 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
4363 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
4364 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
4365 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
4366 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
4367 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
4368 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
4369 arg_str0(NULL
, "fid", "<hex>", "File ID (1 hex byte)"),
4370 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
4373 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
4375 bool APDULogging
= arg_get_lit(ctx
, 1);
4376 bool verbose
= arg_get_lit(ctx
, 2);
4377 bool noauth
= arg_get_lit(ctx
, 14);
4379 DesfireContext_t dctx
;
4380 int securechann
= defaultSecureChannel
;
4381 uint32_t id
= 0x000000;
4382 DesfireISOSelectWay selectway
= ISW6bAID
;
4383 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann
, DCMMACed
, &id
, &selectway
);
4390 if (CLIGetUint32Hex(ctx
, 13, 1, &fnum
, NULL
, 1, "File ID must have 1 byte length")) {
4395 SetAPDULogging(APDULogging
);
4399 PrintAndLogEx(ERR
, "File number range is invalid (exp 0x00 - 0x1f), got 0x%02x", fnum
);
4403 res
= DesfireSelectAndAuthenticateAppW(&dctx
, securechann
, selectway
, id
, noauth
, verbose
);
4404 if (res
!= PM3_SUCCESS
) {
4406 PrintAndLogEx(FAILED
, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway
, id
), res
, DesfireAuthErrorToStr(res
));
4410 res
= DesfireDeleteFile(&dctx
, fnum
);
4411 if (res
!= PM3_SUCCESS
) {
4412 PrintAndLogEx(ERR
, "Desfire DeleteFile command " _RED_("error") ". Result: %d", res
);
4417 PrintAndLogEx(SUCCESS
, "File %02x in the %s deleted " _GREEN_("successfully"), fnum
, DesfireWayIDStr(selectway
, id
));
4423 static int CmdHF14ADesValueOperations(const char *Cmd
) {
4424 CLIParserContext
*ctx
;
4425 CLIParserInit(&ctx
, "hf mfdes value",
4426 "Get File Settings from file from application. Master key needs to be provided or flag --no-auth set (depend on cards settings).",
4427 "hf mfdes value --aid 123456 --fid 01 -> get value app=123456, file=01 with defaults from `default` command\n"
4428 "hf mfdes value --aid 123456 --fid 01 --op credit -d 00000001 -> credit value app=123456, file=01 with defaults from `default` command\n"
4429 "hf mfdes value -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 -> get value with default factory setup\n"
4430 "hf mfdes val --isoid df01 --fid 03 --schann lrp -t aes -n 1 --op credit --d 00000001 -m encrypt -> credit value in the lrp encrypted mode\n"
4431 "hf mfdes val --isoid df01 --fid 03 --schann lrp -t aes -n 1 --op get -m plain -> get value in plain (nevertheless of mode) works for desfire light (look SetConfiguration option 0x09)");
4433 void *argtable
[] = {
4435 arg_lit0("a", "apdu", "Show APDU requests and responses"),
4436 arg_lit0("v", "verbose", "Verbose output"),
4437 arg_int0("n", "keyno", "<dec>", "Key number"),
4438 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
4439 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
4440 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
4441 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
4442 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
4443 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
4444 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
4445 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
4446 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
4447 arg_str0(NULL
, "fid", "<hex>", "File ID (1 hex byte)"),
4448 arg_str0("o", "op", "<get/credit/limcredit/debit/clear>", "Operation: get(default)/credit/limcredit(limited credit)/debit/clear. Operation clear: get-getopt-debit to min value"),
4449 arg_str0("d", "data", "<hex>", "Value for operation (HEX 4 bytes)"),
4450 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
4453 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
4455 bool APDULogging
= arg_get_lit(ctx
, 1);
4456 bool verbose
= arg_get_lit(ctx
, 2);
4457 bool noauth
= arg_get_lit(ctx
, 16);
4459 DesfireContext_t dctx
;
4460 int securechann
= defaultSecureChannel
;
4461 uint32_t id
= 0x000000;
4462 DesfireISOSelectWay selectway
= ISW6bAID
;
4463 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann
, DCMMACed
, &id
, &selectway
);
4469 uint32_t fileid
= 1;
4470 if (CLIGetUint32Hex(ctx
, 13, 1, &fileid
, NULL
, 1, "File ID must have 1 byte length")) {
4475 int op
= MFDES_GET_VALUE
;
4476 if (CLIGetOptionList(arg_get_str(ctx
, 14), DesfireValueFileOperOpts
, &op
)) {
4482 if (CLIGetUint32Hex(ctx
, 15, 0, &value
, NULL
, 4, "Value must have 4 byte length")) {
4487 SetAPDULogging(APDULogging
);
4490 // iso chaining works in the lrp mode
4491 dctx
.isoChaining
|= (dctx
.secureChannel
== DACLRP
);
4494 res
= DesfireSelectAndAuthenticateAppW(&dctx
, securechann
, selectway
, id
, noauth
, verbose
);
4495 if (res
!= PM3_SUCCESS
) {
4497 PrintAndLogEx(FAILED
, "Select or authentication ( %s )" _RED_("failed") " Result [%d] %s", DesfireWayIDStr(selectway
, id
), res
, DesfireAuthErrorToStr(res
));
4502 PrintAndLogEx(INFO
, "%s file %02x operation: %s value: 0x%08x", DesfireWayIDStr(selectway
, id
), fileid
, CLIGetOptionListStr(DesfireValueFileOperOpts
, op
), value
);
4505 res
= DesfireValueFileOperations(&dctx
, fileid
, op
, &value
);
4506 if (res
!= PM3_SUCCESS
) {
4507 PrintAndLogEx(ERR
, "Desfire ValueFileOperations (0x%02x) command ( " _RED_("error") " ) Result: %d", op
, res
);
4512 PrintAndLogEx(INFO
, "Operation ( %s )" _GREEN_("ok"), CLIGetOptionListStr(DesfireValueFileOperOpts
, op
));
4514 if (op
== MFDES_GET_VALUE
) {
4515 PrintAndLogEx(SUCCESS
, "Value: " _GREEN_("%d (0x%08x)"), value
, value
);
4517 DesfireSetCommMode(&dctx
, DCMMACed
);
4518 res
= DesfireCommitTransaction(&dctx
, false, 0);
4519 if (res
!= PM3_SUCCESS
) {
4520 PrintAndLogEx(ERR
, "Desfire CommitTransaction command ( " _RED_("error") ") Result: %d", res
);
4525 PrintAndLogEx(INFO
, "Commit ( " _GREEN_("ok") " )");
4527 PrintAndLogEx(SUCCESS
, "Value changed " _GREEN_("successfully"));
4530 res
= DesfireValueFileOperations(&dctx
, fileid
, MFDES_GET_VALUE
, &value
);
4531 if (res
!= PM3_SUCCESS
) {
4532 PrintAndLogEx(ERR
, "Desfire GetValue command ( " _RED_("error") ") Result: %d", res
);
4537 PrintAndLogEx(INFO
, "current value: 0x%08x", value
);
4539 uint8_t buf
[250] = {0};
4542 res
= DesfireGetFileSettings(&dctx
, fileid
, buf
, &buflen
);
4543 if (res
!= PM3_SUCCESS
) {
4544 PrintAndLogEx(ERR
, "Desfire GetFileSettings command ( " _RED_("error") " ) Result: %d", res
);
4550 PrintAndLogEx(INFO
, "file settings[%zu]: %s", buflen
, sprint_hex(buf
, buflen
));
4552 if (buflen
< 8 || buf
[0] != 0x02) {
4553 PrintAndLogEx(ERR
, "Desfire GetFileSettings command returns " _RED_("wrong") " data");
4558 uint32_t minvalue
= MemLeToUint4byte(&buf
[4]);
4559 uint32_t delta
= (value
> minvalue
) ? value
- minvalue
: 0;
4561 PrintAndLogEx(INFO
, "minimum value: 0x%08x", minvalue
);
4562 PrintAndLogEx(INFO
, "delta value : 0x%08x", delta
);
4566 res
= DesfireValueFileOperations(&dctx
, fileid
, MFDES_DEBIT
, &delta
);
4567 if (res
!= PM3_SUCCESS
) {
4568 PrintAndLogEx(ERR
, "Desfire Debit operation ( " _RED_("error") " ) Result: %d", res
);
4574 PrintAndLogEx(INFO
, "Value debited");
4576 DesfireSetCommMode(&dctx
, DCMMACed
);
4577 res
= DesfireCommitTransaction(&dctx
, false, 0);
4578 if (res
!= PM3_SUCCESS
) {
4579 PrintAndLogEx(ERR
, "Desfire CommitTransaction command ( " _RED_("error") " ) Result: %d", res
);
4585 PrintAndLogEx(INFO
, "Transaction committed");
4588 PrintAndLogEx(INFO
, "Nothing to clear. Value already in the minimum level.");
4591 PrintAndLogEx(SUCCESS
, "Value cleared " _GREEN_("successfully"));
4598 static int CmdHF14ADesClearRecordFile(const char *Cmd
) {
4599 CLIParserContext
*ctx
;
4600 CLIParserInit(&ctx
, "hf mfdes clearrecfile",
4601 "Clear record file. Master key needs to be provided or flag --no-auth set (depend on cards settings).",
4602 "hf mfdes clearrecfile --aid 123456 --fid 01 -> clear record file for: app=123456, file=01 with defaults from `default` command\n"
4603 "hf mfdes clearrecfile --isoid df01 --fid 01 --schann lrp -t aes -n 3 -> clear record file for lrp channel with key number 3");
4605 void *argtable
[] = {
4607 arg_lit0("a", "apdu", "Show APDU requests and responses"),
4608 arg_lit0("v", "verbose", "Verbose output"),
4609 arg_int0("n", "keyno", "<dec>", "Key number"),
4610 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
4611 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
4612 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
4613 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
4614 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
4615 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
4616 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
4617 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
4618 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
4619 arg_str0(NULL
, "fid", "<hex>", "File ID for clearing (1 hex byte)"),
4620 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
4623 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
4625 bool APDULogging
= arg_get_lit(ctx
, 1);
4626 bool verbose
= arg_get_lit(ctx
, 2);
4627 bool noauth
= arg_get_lit(ctx
, 14);
4629 DesfireContext_t dctx
;
4630 int securechann
= defaultSecureChannel
;
4631 uint32_t id
= 0x000000;
4632 DesfireISOSelectWay selectway
= ISW6bAID
;
4633 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann
, DCMMACed
, &id
, &selectway
);
4640 if (CLIGetUint32Hex(ctx
, 13, 1, &fnum
, NULL
, 1, "File ID must have 1 byte length")) {
4645 SetAPDULogging(APDULogging
);
4649 PrintAndLogEx(ERR
, "File number range is invalid (exp 0x00 - 0x1f), got 0x%02x", fnum
);
4653 res
= DesfireSelectAndAuthenticateAppW(&dctx
, securechann
, selectway
, id
, noauth
, verbose
);
4654 if (res
!= PM3_SUCCESS
) {
4656 PrintAndLogEx(FAILED
, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway
, id
), res
, DesfireAuthErrorToStr(res
));
4660 res
= DesfireClearRecordFile(&dctx
, fnum
);
4661 if (res
!= PM3_SUCCESS
) {
4662 PrintAndLogEx(ERR
, "Desfire ClearRecordFile command " _RED_("error") ". Result: %d", res
);
4668 PrintAndLogEx(INFO
, "File cleared");
4670 DesfireSetCommMode(&dctx
, DCMMACed
);
4671 res
= DesfireCommitTransaction(&dctx
, false, 0);
4672 if (res
!= PM3_SUCCESS
) {
4673 PrintAndLogEx(ERR
, "Desfire CommitTransaction command " _RED_("error") ". Result: %d", res
);
4679 PrintAndLogEx(INFO
, "Transaction committed");
4681 PrintAndLogEx(SUCCESS
, "File %02x in the %s cleared " _GREEN_("successfully"), fnum
, DesfireWayIDStr(selectway
, id
));
4687 static int DesfileReadISOFileAndPrint(DesfireContext_t
*dctx
,
4688 bool select_current_file
, uint8_t fnum
,
4689 uint16_t fisoid
, int filetype
,
4690 uint32_t offset
, uint32_t length
,
4691 bool noauth
, bool verbose
) {
4693 if (filetype
== RFTAuto
) {
4694 PrintAndLogEx(ERR
, "ISO mode needs to specify file type");
4698 if (filetype
== RFTValue
) {
4699 PrintAndLogEx(ERR
, "ISO mode can't read Value file type");
4703 if (filetype
== RFTMAC
) {
4704 PrintAndLogEx(ERR
, "ISO mode can't read Transaction MAC file type");
4708 if (select_current_file
)
4709 PrintAndLogEx(INFO
, "------------------------------- " _CYAN_("File ISO %04x data") " -------------------------------", fisoid
);
4711 PrintAndLogEx(INFO
, "---------------------------- " _CYAN_("File ISO short %02x data") " ----------------------------", fnum
);
4713 uint8_t resp
[2048] = {0};
4717 if (filetype
== RFTData
) {
4718 res
= DesfireISOReadBinary(dctx
, !select_current_file
, (select_current_file
) ? 0x00 : fnum
, offset
, length
, resp
, &resplen
);
4719 if (res
!= PM3_SUCCESS
) {
4720 PrintAndLogEx(ERR
, "Desfire ISOReadBinary command " _RED_("error") ". Result: %d", res
);
4726 if (select_current_file
)
4727 PrintAndLogEx(SUCCESS
, "Read %zu bytes from file 0x%04x offset %u", resplen
, fisoid
, offset
);
4729 PrintAndLogEx(SUCCESS
, "Read %zu bytes from file 0x%02x offset %u", resplen
, fnum
, offset
);
4730 print_buffer_with_offset(resp
, resplen
, offset
, true);
4732 if (select_current_file
)
4733 PrintAndLogEx(SUCCESS
, "Read operation returned no data from file %04x", fisoid
);
4735 PrintAndLogEx(SUCCESS
, "Read operation returned no data from file %02x", fnum
);
4739 if (filetype
== RFTRecord
) {
4741 res
= DesfireISOReadRecords(dctx
, offset
, false, (select_current_file
) ? 0x00 : fnum
, 0, resp
, &resplen
);
4742 if (res
!= PM3_SUCCESS
) {
4743 PrintAndLogEx(ERR
, "Desfire ISOReadRecords (one record) command " _RED_("error") ". Result: %d", res
);
4750 PrintAndLogEx(INFO
, "Record length %zu", reclen
);
4753 res
= DesfireISOReadRecords(dctx
, offset
, true, (select_current_file
) ? 0x00 : fnum
, 0, resp
, &resplen
);
4754 if (res
!= PM3_SUCCESS
) {
4755 PrintAndLogEx(ERR
, "Desfire ISOReadRecords (one record) command " _RED_("error") ". Result: %d", res
);
4762 size_t reccount
= resplen
/ reclen
;
4763 if (select_current_file
)
4764 PrintAndLogEx(SUCCESS
, "Read %zu bytes from file 0x%04x from record %d record count %zu record length %zu", resplen
, fisoid
, offset
, reccount
, reclen
);
4766 PrintAndLogEx(SUCCESS
, "Read %zu bytes from file 0x%02x from record %d record count %zu record length %zu", resplen
, fnum
, offset
, reccount
, reclen
);
4768 PrintAndLogEx(SUCCESS
, "Lastest record at the bottom.");
4769 for (int i
= 0; i
< reccount
; i
++) {
4771 PrintAndLogEx(SUCCESS
, "Record %zu", reccount
- (i
+ offset
+ 1));
4772 print_buffer_with_offset(&resp
[i
* reclen
], reclen
, offset
, (i
== 0));
4775 if (select_current_file
)
4776 PrintAndLogEx(SUCCESS
, "Read operation returned no data from file %04x", fisoid
);
4778 PrintAndLogEx(SUCCESS
, "Read operation returned no data from file %02x", fnum
);
4785 static int DesfileReadFileAndPrint(DesfireContext_t
*dctx
,
4786 uint8_t fnum
, int filetype
,
4787 uint32_t offset
, uint32_t length
,
4788 uint32_t maxdatafilelength
, bool noauth
, bool verbose
) {
4791 // length of record for record file
4794 // iso chaining works in the lrp mode
4795 dctx
->isoChaining
|= (dctx
->secureChannel
== DACLRP
);
4797 // get file settings
4798 if (filetype
== RFTAuto
) {
4799 FileSettings_t fsettings
;
4801 DesfireCommunicationMode commMode
= dctx
->commMode
;
4802 DesfireSetCommMode(dctx
, DCMMACed
);
4803 res
= DesfireFileSettingsStruct(dctx
, fnum
, &fsettings
);
4804 DesfireSetCommMode(dctx
, commMode
);
4806 if (res
== PM3_SUCCESS
) {
4807 switch (fsettings
.fileType
) {
4814 filetype
= RFTValue
;
4819 filetype
= RFTRecord
;
4820 reclen
= fsettings
.recordSize
;
4832 commMode
= fsettings
.commMode
;
4833 // lrp needs to point exact mode
4834 if (dctx
->secureChannel
== DACLRP
) {
4835 // read right == free
4836 if (fsettings
.rAccess
== 0xe)
4837 commMode
= DCMPlain
;
4838 // get value access == free
4839 if (filetype
== RFTValue
&& (fsettings
.limitedCredit
& 0x02) != 0)
4840 commMode
= DCMPlain
;
4844 if (filetype
== RFTData
&& maxdatafilelength
&& (maxdatafilelength
< fsettings
.fileSize
)) {
4845 length
= maxdatafilelength
;
4848 DesfireSetCommMode(dctx
, commMode
);
4850 if (fsettings
.fileCommMode
!= 0 && noauth
)
4851 PrintAndLogEx(WARNING
, "File needs communication mode `%s` but there is no authentication", CLIGetOptionListStr(DesfireCommunicationModeOpts
, fsettings
.commMode
));
4853 if ((fsettings
.rAccess
< 0x0e && fsettings
.rAccess
!= dctx
->keyNum
) && (fsettings
.rwAccess
< 0x0e && fsettings
.rwAccess
!= dctx
->keyNum
))
4854 PrintAndLogEx(WARNING
, "File needs to be authenticated with key 0x%02x or 0x%02x but current authentication key is 0x%02x", fsettings
.rAccess
, fsettings
.rwAccess
, dctx
->keyNum
);
4856 if (fsettings
.rAccess
== 0x0f && fsettings
.rwAccess
== 0x0f)
4857 PrintAndLogEx(WARNING
, "File access denied. All read access rights is 0x0F");
4860 PrintAndLogEx(INFO
, _CYAN_("File type:") " %s Option: %s comm mode: %s",
4861 GetDesfireFileType(fsettings
.fileType
),
4862 CLIGetOptionListStr(DesfireReadFileTypeOpts
, filetype
),
4863 CLIGetOptionListStr(DesfireCommunicationModeOpts
, fsettings
.commMode
)
4867 PrintAndLogEx(WARNING
, "GetFileSettings error. Can't get file type.");
4871 PrintAndLogEx(INFO
, "------------------------------- " _CYAN_("File %02x data") " -------------------------------", fnum
);
4873 uint8_t *resp
= calloc(DESFIRE_BUFFER_SIZE
, 1);
4875 PrintAndLogEx(ERR
, "Desfire calloc " _RED_("error"));
4881 if (filetype
== RFTData
) {
4882 res
= DesfireReadFile(dctx
, fnum
, offset
, length
, resp
, &resplen
);
4883 if (res
!= PM3_SUCCESS
) {
4884 PrintAndLogEx(ERR
, "Desfire ReadFile command " _RED_("error") ". Result: %d", res
);
4891 PrintAndLogEx(SUCCESS
, "Read %zu bytes from file 0x%02x offset %u", resplen
, fnum
, offset
);
4892 print_buffer_with_offset(resp
, resplen
, offset
, true);
4894 PrintAndLogEx(SUCCESS
, "Read operation returned no data from file %d", fnum
);
4898 if (filetype
== RFTValue
) {
4900 res
= DesfireValueFileOperations(dctx
, fnum
, MFDES_GET_VALUE
, &value
);
4901 if (res
!= PM3_SUCCESS
) {
4902 PrintAndLogEx(ERR
, "Desfire GetValue operation " _RED_("error") ". Result: %d", res
);
4907 PrintAndLogEx(SUCCESS
, "Read file 0x%02x value: %d (0x%08x)", fnum
, value
, value
);
4910 if (filetype
== RFTRecord
) {
4913 res
= DesfireReadRecords(dctx
, fnum
, offset
, 1, resp
, &resplen
);
4914 if (res
!= PM3_SUCCESS
) {
4915 PrintAndLogEx(ERR
, "Desfire ReadRecords (len=1) command " _RED_("error") ". Result: %d", res
);
4924 PrintAndLogEx(INFO
, "Record length %zu", reclen
);
4926 // if we got one record via the DesfireReadRecords before -- we not need to get it 2nd time
4927 if (length
!= 1 || resplen
== 0) {
4928 res
= DesfireReadRecords(dctx
, fnum
, offset
, length
, resp
, &resplen
);
4929 if (res
!= PM3_SUCCESS
) {
4930 PrintAndLogEx(ERR
, "Desfire ReadRecords command " _RED_("error") ". Result: %d", res
);
4937 if (resplen
> 0 && reclen
> 0) {
4938 size_t reccount
= resplen
/ reclen
;
4939 PrintAndLogEx(SUCCESS
, "Read %zu bytes from file 0x%02x from record %d record count %zu record length %zu", resplen
, fnum
, offset
, reccount
, reclen
);
4941 PrintAndLogEx(SUCCESS
, "Lastest record at the bottom.");
4944 for (int i
= 0; i
< reccount
; i
++) {
4946 PrintAndLogEx(SUCCESS
, "Record %zu", reccount
- (i
+ offset
+ 1));
4948 print_buffer_with_offset(&resp
[i
* reclen
], reclen
, offset
, (i
== 0));
4951 PrintAndLogEx(SUCCESS
, "Read operation returned no data from file %d", fnum
);
4955 if (filetype
== RFTMAC
) {
4956 res
= DesfireReadFile(dctx
, fnum
, 0, 0, resp
, &resplen
);
4957 if (res
!= PM3_SUCCESS
) {
4958 PrintAndLogEx(ERR
, "Desfire ReadFile command " _RED_("error") ". Result: %d", res
);
4965 if (resplen
!= 12) {
4966 PrintAndLogEx(WARNING
, "Read wrong %zu bytes from file 0x%02x offset %u", resplen
, fnum
, offset
);
4967 print_buffer_with_offset(resp
, resplen
, offset
, true);
4969 uint32_t cnt
= MemLeToUint4byte(&resp
[0]);
4970 transactionCounter
= cnt
;
4971 if (dctx
->secureChannel
!= DACLRP
) {
4972 PrintAndLogEx(SUCCESS
, "Transaction counter: %d (0x%08x)", cnt
, cnt
);
4974 // For composing TMC the two subparts are concatenated as follows: actTMC || sesTMC. Both subparts are represented LSB first.
4975 // MF2DLHX0.pdf, 10.3.2.1 Transaction MAC Counter, page 41
4976 uint32_t actTMC
= MemLeToUint2byte(&resp
[0]);
4977 uint32_t sessTMC
= MemLeToUint2byte(&resp
[2]);
4978 PrintAndLogEx(SUCCESS
, "Session tr counter : %d (0x%04x)", sessTMC
, sessTMC
);
4979 PrintAndLogEx(SUCCESS
, "Actual tr counter : %d (0x%04x)", actTMC
, actTMC
);
4981 PrintAndLogEx(SUCCESS
, "Transaction MAC : %s", sprint_hex(&resp
[4], 8));
4984 PrintAndLogEx(SUCCESS
, "Read operation returned no data from file %d", fnum
);
4992 static int CmdHF14ADesReadData(const char *Cmd
) {
4993 CLIParserContext
*ctx
;
4994 CLIParserInit(&ctx
, "hf mfdes read",
4995 "Read data from file. Key needs to be provided or flag --no-auth set (depend on file settings).",
4996 "It reads file via all command sets. \n"
4997 "For ISO command set it can be read by specifying full 2-byte iso id or 1-byte short iso id (first byte of the full iso id). ISO id lays in the data in BIG ENDIAN format.\n"
4998 "ISO record commands: offset - record number (0-current, 1..ff-number, 1-lastest), length - if 0 - all records, if 1 - one\n"
5000 "hf mfdes read --aid 123456 --fid 01 -> read file: app=123456, file=01, offset=0, all the data. use default channel settings from `default` command\n"
5001 "hf mfdes read --aid 123456 --fid 01 --type record --offset 000000 --length 000001 -> read one last record from record file. use default channel settings from `default` command\n"
5002 "hf mfdes read --aid 123456 --fid 10 --type data -c iso -> read file via ISO channel: app=123456, short iso id=10, offset=0.\n"
5003 "hf mfdes read --aid 123456 --fileisoid 1000 --type data -c iso -> read file via ISO channel: app=123456, iso id=1000, offset=0. Select via native ISO wrapper\n"
5004 "hf mfdes read --isoid 0102 --fileisoid 1000 --type data -c iso -> read file via ISO channel: app iso id=0102, iso id=1000, offset=0. Select via ISO commands\n"
5005 "hf mfdes read --isoid 0102 --fileisoid 1100 --type record -c iso --offset 000005 --length 000001 -> get one record (number 5) from file 1100 via iso commands\n"
5006 "hf mfdes read --isoid 0102 --fileisoid 1100 --type record -c iso --offset 000005 --length 000000 -> get all record (from 5 to 1) from file 1100 via iso commands\n"
5007 "hf mfdes read --isoid df01 --fid 00 --schann lrp -t aes --length 000010 -> read via lrp channel\n"
5008 "hf mfdes read --isoid df01 --fid 00 --schann ev2 -t aes --length 000010 --isochain -> read Desfire Light via ev2 channel");
5010 void *argtable
[] = {
5012 arg_lit0("a", "apdu", "Show APDU requests and responses"),
5013 arg_lit0("v", "verbose", "Verbose output"),
5014 arg_int0("n", "keyno", "<dec>", "Key number"),
5015 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
5016 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
5017 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
5018 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
5019 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
5020 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
5021 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
5022 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
5023 arg_str0(NULL
, "fid", "<hex>", "File ID (1 hex byte)"),
5024 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
5025 arg_str0(NULL
, "type", "<auto|data|value|record|mac>", "File Type, Auto - check file settings and then read. (def: auto)"),
5026 arg_str0("o", "offset", "<hex>", "File Offset (3 hex bytes, big endian). For records - record number (0 - lastest record). (def: 0)"),
5027 arg_str0("l", "length", "<hex>", "Length to read (3 hex bytes, big endian -> 000000 = Read all data). For records - records count (0 - all). (def: 0)"),
5028 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
5029 arg_str0(NULL
, "fileisoid", "<hex>", "File ISO ID (ISO DF ID) (2 hex bytes, big endian). Works only for ISO read commands"),
5030 arg_lit0(NULL
, "isochain", "use iso chaining commands. Switched on by default if secure channel = lrp"),
5033 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
5035 bool APDULogging
= arg_get_lit(ctx
, 1);
5036 bool verbose
= arg_get_lit(ctx
, 2);
5037 bool noauth
= arg_get_lit(ctx
, 13);
5039 DesfireContext_t dctx
;
5040 int securechann
= defaultSecureChannel
;
5041 uint32_t id
= 0x000000;
5042 DesfireISOSelectWay selectway
= ISW6bAID
;
5043 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 17, &securechann
, DCMMACed
, &id
, &selectway
);
5050 if (CLIGetUint32Hex(ctx
, 12, 1, &fnum
, NULL
, 1, "File ID must have 1 byte length")) {
5056 if (CLIGetOptionList(arg_get_str(ctx
, 14), DesfireReadFileTypeOpts
, &op
)) {
5061 uint32_t offset
= 0;
5062 if (CLIGetUint32Hex(ctx
, 15, 0, &offset
, NULL
, 3, "Offset must have 3 byte length")) {
5067 uint32_t length
= 0;
5068 if (CLIGetUint32Hex(ctx
, 16, 0, &length
, NULL
, 3, "Length parameter must have 3 byte length")) {
5073 uint32_t fileisoid
= 0x0000;
5074 bool fileisoidpresent
= false;
5075 if (CLIGetUint32Hex(ctx
, 18, 0x0000, &fileisoid
, &fileisoidpresent
, 2, "File ISO ID (for DF) must have 2 bytes length")) {
5080 dctx
.isoChaining
= arg_get_lit(ctx
, 19);
5082 SetAPDULogging(APDULogging
);
5086 PrintAndLogEx(ERR
, "File number range is invalid (exp 0x00 - 0x1f), got 0x%02x", fnum
);
5090 res
= DesfireSelectAndAuthenticateW(&dctx
, securechann
, selectway
, id
, fileisoidpresent
, fileisoid
, noauth
, verbose
);
5091 if (res
!= PM3_SUCCESS
) {
5093 PrintAndLogEx(FAILED
, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway
, id
), res
, DesfireAuthErrorToStr(res
));
5097 if (dctx
.cmdSet
!= DCCISO
)
5098 res
= DesfileReadFileAndPrint(&dctx
, fnum
, op
, offset
, length
, 0, noauth
, verbose
);
5100 res
= DesfileReadISOFileAndPrint(&dctx
, fileisoidpresent
, fnum
, fileisoid
, op
, offset
, length
, noauth
, verbose
);
5106 static int DesfileWriteISOFile(DesfireContext_t
*dctx
,
5107 bool select_current_file
, uint8_t fnum
,
5108 uint16_t fisoid
, int filetype
,
5109 uint32_t offset
, uint8_t *data
,
5110 uint32_t datalen
, bool verbose
) {
5112 if (filetype
== RFTAuto
) {
5113 PrintAndLogEx(ERR
, "ISO mode needs to specify file type");
5117 if (filetype
== RFTValue
) {
5118 PrintAndLogEx(ERR
, "ISO mode can't write Value file type");
5122 if (filetype
== RFTMAC
) {
5123 PrintAndLogEx(ERR
, "ISO mode can't write Transaction MAC file type");
5127 if (dctx
->commMode
!= DCMPlain
) {
5128 PrintAndLogEx(ERR
, "ISO mode can write only in plain mode");
5133 if (filetype
== RFTData
) {
5134 res
= DesfireISOUpdateBinary(dctx
, !select_current_file
, (select_current_file
) ? 0x00 : fnum
, offset
, data
, datalen
);
5135 if (res
!= PM3_SUCCESS
) {
5136 PrintAndLogEx(ERR
, "Desfire ISOUpdateBinary command " _RED_("error") ". Result: %d", res
);
5140 if (select_current_file
)
5141 PrintAndLogEx(INFO
, "Write data file %04x " _GREEN_("success"), fisoid
);
5143 PrintAndLogEx(INFO
, "Write data file %02x " _GREEN_("success"), fnum
);
5146 if (filetype
== RFTRecord
) {
5147 res
= DesfireISOAppendRecord(dctx
, (select_current_file
) ? 0x00 : fnum
, data
, datalen
);
5148 if (res
!= PM3_SUCCESS
) {
5149 PrintAndLogEx(ERR
, "Desfire WriteRecord command " _RED_("error") ". Result: %d", res
);
5152 if (select_current_file
)
5153 PrintAndLogEx(INFO
, "Write record to file %04x " _GREEN_("success"), fisoid
);
5155 PrintAndLogEx(INFO
, "Write record to file %02x " _GREEN_("success"), fnum
);
5161 static int CmdHF14ADesWriteData(const char *Cmd
) {
5162 CLIParserContext
*ctx
;
5163 CLIParserInit(&ctx
, "hf mfdes write",
5164 "Write data from file. Key needs to be provided or flag --no-auth set (depend on file settings).",
5165 "In the mode with CommitReaderID to decode previous reader id command needs to read transaction counter via dump/read command and specify --trkey\n"
5167 "hf mfdes write --aid 123456 --fid 01 -d 01020304 -> AID 123456, file=01, offset=0, get file type from card. use default channel settings from `default` command\n"
5168 "hf mfdes write --aid 123456 --fid 01 --type data -d 01020304 --0ffset 000100 -> write data to std file with offset 0x100\n"
5169 "hf mfdes write --aid 123456 --fid 01 --type data -d 01020304 --commit -> write data to backup file with commit\n"
5170 "hf mfdes write --aid 123456 --fid 01 --type value -d 00000001 -> increment value file\n"
5171 "hf mfdes write --aid 123456 --fid 01 --type value -d 00000001 --debit -> decrement value file\n"
5172 "hf mfdes write --aid 123456 --fid 01 -d 01020304 -> write data to file with `auto` type\n"
5173 "hf mfdes write --aid 123456 --fid 01 --type record -d 01020304 -> write data to record file\n"
5174 "hf mfdes write --aid 123456 --fid 01 --type record -d 01020304 --updaterec 0 -> update record in the record file. record 0 - lastest record.\n"
5175 "hf mfdes write --aid 123456 --fid 01 --type record --offset 000000 -d 11223344 -> write record to record file. use default channel settings from `default` command\n"
5176 "hf mfdes write --isoid 1234 --fileisoid 1000 --type data -c iso -d 01020304 -> write data to std/backup file via iso commandset\n"
5177 "hf mfdes write --isoid 1234 --fileisoid 2000 --type record -c iso -d 01020304 -> send record to record file via iso commandset\n"
5178 "hf mfdes write --aid 123456 --fid 01 -d 01020304 --readerid 010203 -> write data to file with CommitReaderID command before write and CommitTransaction after write\n"
5179 "hf mfdes write --isoid df01 --fid 04 -d 01020304 --trkey 00112233445566778899aabbccddeeff --readerid 5532 -t aes --schann lrp -> advanced CommitReaderID via lrp channel sample");
5181 void *argtable
[] = {
5183 arg_lit0("a", "apdu", "Show APDU requests and responses"),
5184 arg_lit0("v", "verbose", "Verbose output"),
5185 arg_int0("n", "keyno", "<dec>", "Key number"),
5186 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
5187 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
5188 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
5189 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
5190 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
5191 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
5192 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
5193 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
5194 arg_str0(NULL
, "fid", "<hex>", "File ID (1 hex byte)"),
5195 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
5196 arg_str0(NULL
, "type", "<auto|data|value|record|mac>", "File Type, Auto - check file settings and then write. (def: auto)"),
5197 arg_str0("o", "offset", "<hex>", "File Offset (3 hex bytes, big endian). For records - record number (0 - lastest record). (def: 0)"),
5198 arg_str0("d", "data", "<hex>", "data for write (data/record file), credit/debit(value file)"),
5199 arg_lit0(NULL
, "debit", "use for value file debit operation instead of credit"),
5200 arg_lit0(NULL
, "commit", "commit needs for backup file only. For the other file types and in the `auto` mode - command set it automatically"),
5201 arg_int0(NULL
, "updaterec", "<dec>", "Record number for update record command. Updates record instead of write. Lastest record - 0"),
5202 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
5203 arg_str0(NULL
, "fileisoid", "<hex>", "File ISO ID (ISO DF ID) (2 hex bytes, big endian). Works only for ISO write commands"),
5204 arg_str0(NULL
, "readerid", "<hex>", "reader id for CommitReaderID command. If present - the command issued before write command"),
5205 arg_str0(NULL
, "trkey", "<hex>", "key for decode previous reader id"),
5208 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
5210 bool APDULogging
= arg_get_lit(ctx
, 1);
5211 bool verbose
= arg_get_lit(ctx
, 2);
5212 bool noauth
= arg_get_lit(ctx
, 13);
5214 DesfireContext_t dctx
;
5215 int securechann
= defaultSecureChannel
;
5216 uint32_t id
= 0x000000;
5217 DesfireISOSelectWay selectway
= ISW6bAID
;
5218 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 20, &securechann
, DCMMACed
, &id
, &selectway
);
5225 if (CLIGetUint32Hex(ctx
, 12, 1, &fnum
, NULL
, 1, "File ID must have 1 byte length")) {
5231 if (CLIGetOptionList(arg_get_str(ctx
, 14), DesfireReadFileTypeOpts
, &op
)) {
5236 uint32_t offset
= 0;
5237 if (CLIGetUint32Hex(ctx
, 15, 0, &offset
, NULL
, 3, "Offset must have 3 byte length")) {
5242 uint8_t data
[1024] = {0};
5243 int datalen
= sizeof(data
);
5244 CLIGetHexWithReturn(ctx
, 16, data
, &datalen
);
5246 PrintAndLogEx(ERR
, "Data for write must be present.");
5251 bool debit
= arg_get_lit(ctx
, 17);
5252 bool commit
= arg_get_lit(ctx
, 18);
5254 int updaterecno
= arg_get_int_def(ctx
, 19, -1);
5256 uint32_t fileisoid
= 0x0000;
5257 bool fileisoidpresent
= false;
5258 if (CLIGetUint32Hex(ctx
, 21, 0x0000, &fileisoid
, &fileisoidpresent
, 2, "File ISO ID (for DF) must have 2 bytes length")) {
5263 uint8_t readerid
[250] = {0};
5264 int readeridlen
= sizeof(readerid
);
5265 CLIGetHexWithReturn(ctx
, 22, readerid
, &readeridlen
);
5266 if (readeridlen
> 16) {
5267 PrintAndLogEx(ERR
, "ReaderID must be up to 16 bytes length.");
5272 uint8_t trkey
[250] = {0};
5273 int trkeylen
= sizeof(trkey
);
5274 CLIGetHexWithReturn(ctx
, 23, trkey
, &trkeylen
);
5275 if (trkeylen
> 0 && trkeylen
!= 16) {
5276 PrintAndLogEx(ERR
, "Transaction key must be 16 bytes length.");
5281 SetAPDULogging(APDULogging
);
5285 PrintAndLogEx(ERR
, "File number range is invalid (exp 0x00 - 0x1f), got 0x%02x", fnum
);
5291 DesfireGetCardUID(&dctx
);
5293 res
= DesfireSelectAndAuthenticateW(&dctx
, securechann
, selectway
, id
, fileisoidpresent
, fileisoid
, noauth
, verbose
);
5294 if (res
!= PM3_SUCCESS
) {
5296 PrintAndLogEx(FAILED
, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway
, id
), res
, DesfireAuthErrorToStr(res
));
5301 if (dctx
.cmdSet
== DCCISO
) {
5302 if (op
== RFTRecord
&& updaterecno
>= 0) {
5303 PrintAndLogEx(ERR
, "ISO mode can't update record. Only append.");
5308 res
= DesfileWriteISOFile(&dctx
, fileisoidpresent
, fnum
, fileisoid
, op
, offset
, data
, datalen
, verbose
);
5313 // get file settings
5314 if (op
== RFTAuto
) {
5315 FileSettings_t fsettings
;
5317 DesfireCommunicationMode commMode
= dctx
.commMode
;
5318 DesfireSetCommMode(&dctx
, DCMMACed
);
5319 res
= DesfireFileSettingsStruct(&dctx
, fnum
, &fsettings
);
5320 DesfireSetCommMode(&dctx
, commMode
);
5322 if (res
== PM3_SUCCESS
) {
5323 switch (fsettings
.fileType
) {
5328 commit
= (fsettings
.fileType
== 0x01);
5340 if (datalen
> fsettings
.recordSize
)
5341 PrintAndLogEx(WARNING
, "Record size (%d) " _RED_("is less") " than data length (%d)", fsettings
.recordSize
, datalen
);
5354 DesfireSetCommMode(&dctx
, fsettings
.commMode
);
5356 if (fsettings
.fileCommMode
!= 0 && noauth
)
5357 PrintAndLogEx(WARNING
, "File needs communication mode `%s` but there is no authentication", CLIGetOptionListStr(DesfireCommunicationModeOpts
, fsettings
.commMode
));
5359 if ((fsettings
.rAccess
< 0x0e && fsettings
.rAccess
!= dctx
.keyNum
) && (fsettings
.rwAccess
< 0x0e && fsettings
.rwAccess
!= dctx
.keyNum
))
5360 PrintAndLogEx(WARNING
, "File needs to be authenticated with key 0x%02x or 0x%02x but current authentication key is 0x%02x", fsettings
.rAccess
, fsettings
.rwAccess
, dctx
.keyNum
);
5362 if (fsettings
.rAccess
== 0x0f && fsettings
.rwAccess
== 0x0f)
5363 PrintAndLogEx(WARNING
, "File access denied. All read access rights is 0x0f.");
5366 PrintAndLogEx(INFO
, "Got file type: %s. Option: %s. comm mode: %s",
5367 GetDesfireFileType(fsettings
.fileType
),
5368 CLIGetOptionListStr(DesfireReadFileTypeOpts
, op
),
5369 CLIGetOptionListStr(DesfireCommunicationModeOpts
, fsettings
.commMode
));
5371 PrintAndLogEx(WARNING
, "GetFileSettings error. Can't get file type.");
5375 // CommitReaderID command
5376 bool readeridpushed
= false;
5377 if (readeridlen
> 0) {
5378 uint8_t resp
[250] = {0};
5381 DesfireCommunicationMode commMode
= dctx
.commMode
;
5382 DesfireSetCommMode(&dctx
, DCMMACed
);
5383 res
= DesfireCommitReaderID(&dctx
, readerid
, readeridlen
, resp
, &resplen
);
5384 DesfireSetCommMode(&dctx
, commMode
);
5386 if (res
== PM3_SUCCESS
) {
5387 PrintAndLogEx(INFO
, _GREEN_("Commit Reader ID: "));
5388 PrintAndLogEx(INFO
, "Prev reader id encoded [%zu]: %s", resplen
, sprint_hex(resp
, resplen
));
5391 uint8_t prevReaderID
[CRYPTO_AES_BLOCK_SIZE
] = {0};
5392 DesfireDecodePrevReaderID(&dctx
, trkey
, transactionCounter
, resp
, prevReaderID
);
5393 PrintAndLogEx(INFO
, "Prev reader id: %s", sprint_hex(prevReaderID
, CRYPTO_AES_BLOCK_SIZE
));
5396 readeridpushed
= true;
5398 PrintAndLogEx(INFO
, "CommitReaderID ( " _GREEN_("ok") " )");
5400 PrintAndLogEx(WARNING
, "Desfire CommitReaderID command " _RED_("error") ". Result: %d", res
);
5403 // iso chaining works in the lrp mode
5404 dctx
.isoChaining
|= (dctx
.secureChannel
== DACLRP
);
5407 if (op
== RFTData
) {
5408 res
= DesfireWriteFile(&dctx
, fnum
, offset
, datalen
, data
);
5409 if (res
!= PM3_SUCCESS
) {
5410 PrintAndLogEx(ERR
, "Desfire WriteFile command " _RED_("error") ". Result: %d", res
);
5416 PrintAndLogEx(INFO
, "Write data file %02x " _GREEN_("success"), fnum
);
5419 if (op
== RFTValue
) {
5421 PrintAndLogEx(ERR
, "Value " _RED_("should be") " 4 byte length instead of %d", datalen
);
5426 uint32_t value
= MemBeToUint4byte(data
);
5427 uint8_t vop
= (debit
) ? MFDES_DEBIT
: MFDES_CREDIT
;
5428 res
= DesfireValueFileOperations(&dctx
, fnum
, vop
, &value
);
5429 if (res
!= PM3_SUCCESS
) {
5430 PrintAndLogEx(ERR
, "Desfire %s operation " _RED_("error") ". Result: %d", CLIGetOptionListStr(DesfireValueFileOperOpts
, vop
), res
);
5436 PrintAndLogEx(INFO
, "%s value file %02x (%s) " _GREEN_("success"), (debit
) ? "Debit" : "Credit", fnum
, CLIGetOptionListStr(DesfireValueFileOperOpts
, vop
));
5440 if (op
== RFTRecord
) {
5441 if (updaterecno
< 0) {
5442 res
= DesfireWriteRecord(&dctx
, fnum
, offset
, datalen
, data
);
5443 if (res
!= PM3_SUCCESS
) {
5444 PrintAndLogEx(ERR
, "Desfire WriteRecord command " _RED_("error") ". Result: %d", res
);
5449 PrintAndLogEx(INFO
, "Write record file %02x " _GREEN_("success"), fnum
);
5451 res
= DesfireUpdateRecord(&dctx
, fnum
, updaterecno
, offset
, datalen
, data
);
5452 if (res
!= PM3_SUCCESS
) {
5453 PrintAndLogEx(ERR
, "Desfire UpdateRecord command " _RED_("error") ". Result: %d", res
);
5458 PrintAndLogEx(INFO
, "Update record %06x in the file %02x " _GREEN_("success"), updaterecno
, fnum
);
5465 PrintAndLogEx(ERR
, "Can't " _RED_("write") " to transaction MAC file");
5471 if (commit
|| readeridpushed
) {
5472 uint8_t resp
[250] = {0};
5474 DesfireSetCommMode(&dctx
, DCMMACed
);
5475 res
= DesfireCommitTransactionEx(&dctx
, readeridpushed
, 0x01, resp
, &resplen
);
5476 if (res
!= PM3_SUCCESS
) {
5477 PrintAndLogEx(ERR
, "Desfire CommitTransaction command " _RED_("error") ". Result: %d", res
);
5484 PrintAndLogEx(INFO
, "TMC and TMV[%zu]: %s", resplen
, sprint_hex(resp
, resplen
));
5485 PrintAndLogEx(INFO
, "Commit ( " _GREEN_("ok") " )");
5488 if (resplen
== 4 + 8) {
5489 PrintAndLogEx(INFO
, _GREEN_("Commit result:"));
5490 uint32_t cnt
= MemLeToUint4byte(&resp
[0]);
5491 transactionCounter
= cnt
;
5492 if (dctx
.secureChannel
!= DACLRP
) {
5493 PrintAndLogEx(SUCCESS
, "Transaction counter: %d (0x%08x)", cnt
, cnt
);
5495 // For composing TMC the two subparts are concatenated as follows: actTMC || sesTMC. Both subparts are represented LSB first.
5496 // MF2DLHX0.pdf, 10.3.2.1 Transaction MAC Counter, page 41
5497 uint32_t actTMC
= MemLeToUint2byte(&resp
[0]);
5498 uint32_t sessTMC
= MemLeToUint2byte(&resp
[2]);
5499 PrintAndLogEx(SUCCESS
, "Session tr counter : %d (0x%04x)", sessTMC
, sessTMC
);
5500 PrintAndLogEx(SUCCESS
, "Actual tr counter : %d (0x%04x)", actTMC
, actTMC
);
5502 PrintAndLogEx(SUCCESS
, "Transaction MAC : %s", sprint_hex(&resp
[4], 8));
5506 PrintAndLogEx(INFO
, "Write %s file %02x " _GREEN_("success"), CLIGetOptionListStr(DesfireReadFileTypeOpts
, op
), fnum
);
5512 static int CmdHF14ADesLsFiles(const char *Cmd
) {
5513 CLIParserContext
*ctx
;
5514 CLIParserInit(&ctx
, "hf mfdes lsfiles",
5515 "This commands List files inside application AID / ISOID.\n"
5516 "Master key needs to be provided or flag --no-auth set (depend on cards settings).",
5517 "hf mfdes lsfiles --aid 123456 -> AID 123456, list files using `default` command creds\n"
5518 "hf mfdes lsfiles --isoid df01 --no-auth -> list files for DESFire light");
5520 void *argtable
[] = {
5522 arg_lit0("a", "apdu", "Show APDU requests and responses"),
5523 arg_lit0("v", "verbose", "Verbose output"),
5524 arg_int0("n", "keyno", "<dec>", "Key number"),
5525 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
5526 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
5527 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
5528 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
5529 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
5530 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
5531 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
5532 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
5533 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
5534 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
5537 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
5539 bool APDULogging
= arg_get_lit(ctx
, 1);
5540 bool verbose
= arg_get_lit(ctx
, 2);
5541 bool noauth
= arg_get_lit(ctx
, 13);
5543 DesfireContext_t dctx
;
5544 int securechann
= defaultSecureChannel
;
5545 uint32_t id
= 0x000000;
5546 DesfireISOSelectWay selectway
= ISW6bAID
;
5547 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann
, DCMMACed
, &id
, &selectway
);
5553 SetAPDULogging(APDULogging
);
5556 res
= DesfireSelectAndAuthenticateAppW(&dctx
, securechann
, selectway
, id
, noauth
, verbose
);
5557 if (res
!= PM3_SUCCESS
) {
5559 PrintAndLogEx(FAILED
, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway
, id
), res
, DesfireAuthErrorToStr(res
));
5563 FileList_t FileList
= {{0}};
5564 size_t filescount
= 0;
5565 bool isopresent
= false;
5566 res
= DesfireFillFileList(&dctx
, FileList
, &filescount
, &isopresent
);
5567 if (res
!= PM3_SUCCESS
) {
5572 if (filescount
== 0) {
5573 PrintAndLogEx(INFO
, "There is no files in the %s", DesfireWayIDStr(selectway
, id
));
5578 PrintAndLogEx(INFO
, "------------------------------------------ " _CYAN_("File list") " -----------------------------------------------------");
5579 for (int i
= 0; i
< filescount
; i
++)
5580 DesfirePrintFileSettingsTable((i
== 0), FileList
[i
].fileNum
, isopresent
, FileList
[i
].fileISONum
, &FileList
[i
].fileSettings
);
5586 static int CmdHF14ADesLsApp(const char *Cmd
) {
5587 CLIParserContext
*ctx
;
5588 CLIParserInit(&ctx
, "hf mfdes lsapp",
5589 "Show application list. Master key needs to be provided or flag --no-auth set (depend on cards settings).",
5590 "hf mfdes lsapp -> show application list with defaults from `default` command\n"
5591 "hf mfdes lsapp --files -> show application list and show each file type/settings/etc");
5593 void *argtable
[] = {
5595 arg_lit0("a", "apdu", "Show APDU requests and responses"),
5596 arg_lit0("v", "verbose", "Verbose output"),
5597 arg_int0("n", "keyno", "<dec>", "Key number"),
5598 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
5599 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
5600 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
5601 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
5602 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
5603 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
5604 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
5605 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
5606 arg_lit0(NULL
, "no-deep", "not to check authentication commands that avail for any application"),
5607 arg_lit0(NULL
, "files", "scan files and print file settings"),
5610 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
5612 bool APDULogging
= arg_get_lit(ctx
, 1);
5613 bool verbose
= arg_get_lit(ctx
, 2);
5614 bool noauth
= arg_get_lit(ctx
, 11);
5615 bool nodeep
= arg_get_lit(ctx
, 12);
5616 bool scanfiles
= arg_get_lit(ctx
, 13);
5618 DesfireContext_t dctx
;
5619 int securechann
= defaultSecureChannel
;
5620 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, &securechann
, (noauth
) ? DCMPlain
: DCMMACed
, NULL
, NULL
);
5626 SetAPDULogging(APDULogging
);
5629 PrintAndLogEx(INPLACE
, _YELLOW_("It may take up to 15 seconds. Processing...."));
5631 res
= DesfireSelectAndAuthenticateEx(&dctx
, securechann
, 0x000000, noauth
, verbose
);
5632 if (res
!= PM3_SUCCESS
) {
5637 PICCInfo_t PICCInfo
= {0};
5638 AppListS AppList
= {{0}};
5639 DesfireFillAppList(&dctx
, &PICCInfo
, AppList
, !nodeep
, scanfiles
, true);
5641 printf("\33[2K\r"); // clear current line before printing
5642 PrintAndLogEx(NORMAL
, "");
5645 DesfirePrintPICCInfo(&dctx
, &PICCInfo
);
5646 DesfirePrintAppList(&dctx
, &PICCInfo
, AppList
);
5652 static int CmdHF14ADesDump(const char *Cmd
) {
5653 CLIParserContext
*ctx
;
5654 CLIParserInit(&ctx
, "hf mfdes dump",
5655 "For each application show fil list and then file content. Key needs to be provided for authentication or flag --no-auth set (depend on cards settings).",
5656 "hf mfdes dump --aid 123456 -> show file dump for: app=123456 with channel defaults from `default` command/n"
5657 "hf mfdes dump --isoid df01 --schann lrp -t aes --length 000090 -> lrp default settings with length limit");
5659 void *argtable
[] = {
5661 arg_lit0("a", "apdu", "Show APDU requests and responses"),
5662 arg_lit0("v", "verbose", "Verbose output"),
5663 arg_int0("n", "keyno", "<dec>", "Key number"),
5664 arg_str0("t", "algo", "<DES|2TDEA|3TDEA|AES>", "Crypt algo"),
5665 arg_str0("k", "key", "<hex>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
5666 arg_str0(NULL
, "kdf", "<none|AN10922|gallagher>", "Key Derivation Function (KDF)"),
5667 arg_str0("i", "kdfi", "<hex>", "KDF input (1-31 hex bytes)"),
5668 arg_str0("m", "cmode", "<plain|mac|encrypt>", "Communicaton mode"),
5669 arg_str0("c", "ccset", "<native|niso|iso>", "Communicaton command set"),
5670 arg_str0(NULL
, "schann", "<d40|ev1|ev2|lrp>", "Secure channel"),
5671 arg_str0(NULL
, "aid", "<hex>", "Application ID (3 hex bytes, big endian)"),
5672 arg_str0(NULL
, "isoid", "<hex>", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)"),
5673 arg_str0("l", "length", "<hex>", "Maximum length for read data files (3 hex bytes, big endian)"),
5674 arg_lit0(NULL
, "no-auth", "Execute without authentication"),
5677 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
5679 bool APDULogging
= arg_get_lit(ctx
, 1);
5680 bool verbose
= arg_get_lit(ctx
, 2);
5681 bool noauth
= arg_get_lit(ctx
, 14);
5683 DesfireContext_t dctx
;
5684 int securechann
= defaultSecureChannel
;
5685 uint32_t id
= 0x000000;
5686 DesfireISOSelectWay selectway
= ISW6bAID
;
5687 int res
= CmdDesGetSessionParameters(ctx
, &dctx
, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann
, (noauth
) ? DCMPlain
: DCMMACed
, &id
, &selectway
);
5693 uint32_t maxlength
= 0;
5694 if (CLIGetUint32Hex(ctx
, 13, 0, &maxlength
, NULL
, 3, "Length parameter must have 3 byte length")) {
5699 SetAPDULogging(APDULogging
);
5702 res
= DesfireSelectAndAuthenticateAppW(&dctx
, securechann
, selectway
, id
, noauth
, verbose
);
5703 if (res
!= PM3_SUCCESS
) {
5705 PrintAndLogEx(FAILED
, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway
, id
), res
, DesfireAuthErrorToStr(res
));
5709 FileList_t FileList
= {{0}};
5710 size_t filescount
= 0;
5711 bool isopresent
= false;
5712 res
= DesfireFillFileList(&dctx
, FileList
, &filescount
, &isopresent
);
5713 if (res
!= PM3_SUCCESS
) {
5718 PrintAndLogEx(NORMAL
, "");
5719 PrintAndLogEx(SUCCESS
, "Application " _CYAN_("%s") " have " _GREEN_("%zu") " files", DesfireWayIDStr(selectway
, id
), filescount
);
5721 if (selectway
== ISW6bAID
)
5722 DesfirePrintAIDFunctions(id
);
5724 if (filescount
== 0) {
5725 PrintAndLogEx(INFO
, "There is no files in the application %s", DesfireWayIDStr(selectway
, id
));
5731 for (int i
= 0; i
< filescount
; i
++) {
5732 if (res
!= PM3_SUCCESS
) {
5733 DesfireSetCommMode(&dctx
, DCMPlain
);
5734 res
= DesfireSelectAndAuthenticateAppW(&dctx
, securechann
, selectway
, id
, noauth
, verbose
);
5735 if (res
!= PM3_SUCCESS
) {
5741 PrintAndLogEx(NORMAL
, "");
5742 PrintAndLogEx(INFO
, "--------------------------------- " _CYAN_("File %02x") " ----------------------------------", FileList
[i
].fileNum
);
5743 PrintAndLogEx(SUCCESS
, "File ID : " _GREEN_("%02x"), FileList
[i
].fileNum
);
5745 if (FileList
[i
].fileISONum
!= 0)
5746 PrintAndLogEx(SUCCESS
, "File ISO ID : %04x", FileList
[i
].fileISONum
);
5748 PrintAndLogEx(SUCCESS
, "File ISO ID : " _YELLOW_("n/a"));
5750 DesfirePrintFileSettingsExtended(&FileList
[i
].fileSettings
);
5752 res
= DesfileReadFileAndPrint(&dctx
, FileList
[i
].fileNum
, RFTAuto
, 0, 0, maxlength
, noauth
, verbose
);
5759 static int CmdHF14ADesTest(const char *Cmd
) {
5760 CLIParserContext
*ctx
;
5761 CLIParserInit(&ctx
, "hf mfdes test",
5762 "Regression crypto tests",
5765 void *argtable
[] = {
5769 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
5775 static command_t CommandTable
[] = {
5776 {"help", CmdHelp
, AlwaysAvailable
, "This help"},
5777 {"list", CmdHF14ADesList
, AlwaysAvailable
, "List DESFire (ISO 14443A) history"},
5778 {"-----------", CmdHelp
, IfPm3Iso14443a
, "---------------------- " _CYAN_("General") " ----------------------"},
5779 {"auth", CmdHF14ADesAuth
, IfPm3Iso14443a
, "MIFARE DesFire Authentication"},
5780 {"chk", CmdHF14aDesChk
, IfPm3Iso14443a
, "Check keys"},
5781 {"default", CmdHF14ADesDefault
, IfPm3Iso14443a
, "Set defaults for all the commands"},
5782 {"detect", CmdHF14aDesDetect
, IfPm3Iso14443a
, "Detect key type and tries to find one from the list"},
5783 {"formatpicc", CmdHF14ADesFormatPICC
, IfPm3Iso14443a
, "Format PICC"},
5784 {"freemem", CmdHF14ADesGetFreeMem
, IfPm3Iso14443a
, "Get free memory size"},
5785 {"getuid", CmdHF14ADesGetUID
, IfPm3Iso14443a
, "Get uid from card"},
5786 {"info", CmdHF14ADesInfo
, IfPm3Iso14443a
, "Tag information"},
5787 {"mad", CmdHF14aDesMAD
, IfPm3Iso14443a
, "Prints MAD records / files from the card"},
5788 {"setconfig", CmdHF14ADesSetConfiguration
, IfPm3Iso14443a
, "Set card configuration"},
5789 {"-----------", CmdHelp
, IfPm3Iso14443a
, "-------------------- " _CYAN_("Applications") " -------------------"},
5790 {"lsapp", CmdHF14ADesLsApp
, IfPm3Iso14443a
, "Show all applications with files list"},
5791 {"getaids", CmdHF14ADesGetAIDs
, IfPm3Iso14443a
, "Get Application IDs list"},
5792 {"getappnames", CmdHF14ADesGetAppNames
, IfPm3Iso14443a
, "Get Applications list"},
5793 {"bruteaid", CmdHF14ADesBruteApps
, IfPm3Iso14443a
, "Recover AIDs by bruteforce"},
5794 {"createapp", CmdHF14ADesCreateApp
, IfPm3Iso14443a
, "Create Application"},
5795 {"deleteapp", CmdHF14ADesDeleteApp
, IfPm3Iso14443a
, "Delete Application"},
5796 {"selectapp", CmdHF14ADesSelectApp
, IfPm3Iso14443a
, "Select Application ID"},
5797 {"-----------", CmdHelp
, IfPm3Iso14443a
, "------------------------ " _CYAN_("Keys") " -----------------------"},
5798 {"changekey", CmdHF14ADesChangeKey
, IfPm3Iso14443a
, "Change Key"},
5799 {"chkeysettings", CmdHF14ADesChKeySettings
, IfPm3Iso14443a
, "Change Key Settings"},
5800 {"getkeysettings", CmdHF14ADesGetKeySettings
, IfPm3Iso14443a
, "Get Key Settings"},
5801 {"getkeyversions", CmdHF14ADesGetKeyVersions
, IfPm3Iso14443a
, "Get Key Versions"},
5802 {"-----------", CmdHelp
, IfPm3Iso14443a
, "----------------------- " _CYAN_("Files") " -----------------------"},
5803 {"getfileids", CmdHF14ADesGetFileIDs
, IfPm3Iso14443a
, "Get File IDs list"},
5804 {"getfileisoids", CmdHF14ADesGetFileISOIDs
, IfPm3Iso14443a
, "Get File ISO IDs list"},
5805 {"lsfiles", CmdHF14ADesLsFiles
, IfPm3Iso14443a
, "Show all files list"},
5806 {"dump", CmdHF14ADesDump
, IfPm3Iso14443a
, "Dump all files"},
5807 {"createfile", CmdHF14ADesCreateFile
, IfPm3Iso14443a
, "Create Standard/Backup File"},
5808 {"createvaluefile", CmdHF14ADesCreateValueFile
, IfPm3Iso14443a
, "Create Value File"},
5809 {"createrecordfile", CmdHF14ADesCreateRecordFile
, IfPm3Iso14443a
, "Create Linear/Cyclic Record File"},
5810 {"createmacfile", CmdHF14ADesCreateTrMACFile
, IfPm3Iso14443a
, "Create Transaction MAC File"},
5811 {"deletefile", CmdHF14ADesDeleteFile
, IfPm3Iso14443a
, "Delete File"},
5812 {"getfilesettings", CmdHF14ADesGetFileSettings
, IfPm3Iso14443a
, "Get file settings"},
5813 {"chfilesettings", CmdHF14ADesChFileSettings
, IfPm3Iso14443a
, "Change file settings"},
5814 {"read", CmdHF14ADesReadData
, IfPm3Iso14443a
, "Read data from standard/backup/record/value/mac file"},
5815 {"write", CmdHF14ADesWriteData
, IfPm3Iso14443a
, "Write data to standard/backup/record/value file"},
5816 {"value", CmdHF14ADesValueOperations
, IfPm3Iso14443a
, "Operations with value file (get/credit/limited credit/debit/clear)"},
5817 {"clearrecfile", CmdHF14ADesClearRecordFile
, IfPm3Iso14443a
, "Clear record File"},
5818 {"-----------", CmdHelp
, IfPm3Iso14443a
, "----------------------- " _CYAN_("System") " -----------------------"},
5819 {"test", CmdHF14ADesTest
, AlwaysAvailable
, "Regression crypto tests"},
5820 {NULL
, NULL
, NULL
, NULL
}
5823 static int CmdHelp(const char *Cmd
) {
5824 (void)Cmd
; // Cmd is not used so far
5825 CmdsHelp(CommandTable
);
5829 int CmdHFMFDes(const char *Cmd
) {
5830 clearCommandBuffer();
5831 return CmdsParse(CommandTable
, Cmd
);