From 84f470a5964bc3d64e74df74c56af48781999925 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 7 Aug 2021 11:45:09 +0300 Subject: [PATCH 01/22] remove subkey gen --- client/src/mifare/desfirecore.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 0a2edd8e5..b1cf61b9c 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -1220,12 +1220,6 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec memcpy(&dctx->sessionKeyEnc[8], dctx->sessionKeyEnc, 8); } - if (secureChannel == DACEV1) { - cmac_generate_subkeys(&sesskey, MCD_RECEIVE); - //key->cmac_sk1 and key->cmac_sk2 - //memcpy(dctx->sessionKeyEnc, sesskey.data, desfire_get_key_length(dctx->keyType)); - } - memset(dctx->IV, 0, DESFIRE_MAX_KEY_SIZE); dctx->secureChannel = secureChannel; memcpy(dctx->sessionKeyMAC, dctx->sessionKeyEnc, desfire_get_key_length(dctx->keyType)); From 9b999b7d2c155244cf58856780c0ec5c71a9559e Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 7 Aug 2021 11:53:34 +0300 Subject: [PATCH 02/22] remove old session key gen --- client/src/mifare/desfirecore.c | 11 ++++------- client/src/mifare/desfirecore.h | 1 - 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index b1cf61b9c..af29df827 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -30,7 +30,6 @@ #include "iso7816/apduinfo.h" // APDU manipulation / errorcodes #include "iso7816/iso7816core.h" // APDU logging #include "util_posix.h" // msleep -#include "mifare/desfire_crypto.h" #include "desfiresecurechan.h" #include "mifare/mad.h" #include "mifare/aiddesfire.h" @@ -1174,11 +1173,6 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec // Part 4 memcpy(encRndA, recv_data, rndlen); - struct desfire_key sesskey = {0}; - - Desfire_session_key_new(RndA, RndB, key, &sesskey); - memcpy(dctx->sessionKeyEnc, sesskey.data, desfire_get_key_length(dctx->keyType)); - //PrintAndLogEx(INFO, "encRndA : %s", sprint_hex(encRndA, rndlen)); //PrintAndLogEx(INFO, "IV : %s", sprint_hex(IV, rndlen)); if (dctx->keyType == T_DES) { @@ -1200,6 +1194,9 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, rndlen, IV, encRndA, encRndA); } + // generate session key from rnda and rndb. before rol(RndA)! + DesfireGenSessionKeyEV1(RndA, RndB, dctx->keyType, dctx->sessionKeyEnc); + rol(RndA, rndlen); //PrintAndLogEx(INFO, "Expected_RndA : %s", sprint_hex(RndA, rndlen)); //PrintAndLogEx(INFO, "Generated_RndA : %s", sprint_hex(encRndA, rndlen)); @@ -1212,7 +1209,7 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec return 11; } } - + // If the 3Des key first 8 bytes = 2nd 8 Bytes then we are really using Singe Des // As such we need to set the session key such that the 2nd 8 bytes = 1st 8 Bytes if (dctx->keyType == T_3DES) { diff --git a/client/src/mifare/desfirecore.h b/client/src/mifare/desfirecore.h index a03e489eb..833c1f8b3 100644 --- a/client/src/mifare/desfirecore.h +++ b/client/src/mifare/desfirecore.h @@ -16,7 +16,6 @@ #include "common.h" #include "cliparser.h" #include "mifare/desfirecrypto.h" -#include "mifare/desfire_crypto.h" #include "mifare/mifare4.h" #define DESFIRE_TX_FRAME_MAX_LEN 54 From ee7438bfc138835908f319b363e6b66a2f48c035 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 7 Aug 2021 12:20:05 +0300 Subject: [PATCH 03/22] move functions, get rid of some deendences --- client/src/mifare/desfire_crypto.c | 39 ------------------------ client/src/mifare/desfire_crypto.h | 6 ---- client/src/mifare/desfirecrypto.c | 43 +++++++++++++++++++++++++-- client/src/mifare/desfirecrypto.h | 7 ++++- client/src/mifare/desfiresecurechan.c | 1 - 5 files changed, 47 insertions(+), 49 deletions(-) diff --git a/client/src/mifare/desfire_crypto.c b/client/src/mifare/desfire_crypto.c index fd3cb427d..b0bbc62b7 100644 --- a/client/src/mifare/desfire_crypto.c +++ b/client/src/mifare/desfire_crypto.c @@ -53,20 +53,6 @@ static inline void update_key_schedules(desfirekey_t key) { // } } -int desfire_get_key_length(enum DESFIRE_CRYPTOALGO key_type) { - switch (key_type) { - case T_DES: - return 8; - case T_3DES: - return 16; - case T_3K3DES: - return 24; - case T_AES: - return 16; - } - return 0; -} - /******************************************************************************/ void tdes_nxp_receive(const void *in, void *out, size_t length, const void *key, unsigned char iv[8], int keymode) { @@ -382,21 +368,6 @@ void mifare_kdf_an10922(const desfirekey_t key, const uint8_t *data, size_t len) free(buffer); } -size_t desfire_get_key_block_length(enum DESFIRE_CRYPTOALGO key_type) { - size_t block_size = 8; - switch (key_type) { - case T_DES: - case T_3DES: - case T_3K3DES: - block_size = 8; - break; - case T_AES: - block_size = 16; - break; - } - return block_size; -} - size_t key_block_size(const desfirekey_t key) { if (key == NULL) { return 0; @@ -422,16 +393,6 @@ static size_t key_macing_length(const desfirekey_t key) { return mac_length; } -/* - * Size required to store nbytes of data in a buffer of size n*block_size. - */ -size_t padded_data_length(const size_t nbytes, const size_t block_size) { - if ((!nbytes) || (nbytes % block_size)) - return ((nbytes / block_size) + 1) * block_size; - else - return nbytes; -} - /* * Buffer size required to MAC nbytes of data */ diff --git a/client/src/mifare/desfire_crypto.h b/client/src/mifare/desfire_crypto.h index c4c879ef3..160af81bd 100644 --- a/client/src/mifare/desfire_crypto.h +++ b/client/src/mifare/desfire_crypto.h @@ -74,16 +74,11 @@ typedef enum { /* Error code managed by the library */ #define CRYPTO_ERROR 0x01 -int desfire_get_key_length(enum DESFIRE_CRYPTOALGO key_type); -size_t desfire_get_key_block_length(enum DESFIRE_CRYPTOALGO key_type); - enum DESFIRE_AUTH_SCHEME { AS_LEGACY, AS_NEW }; - - #define DESFIRE_KEY(key) ((struct desfire_key *) key) struct desfire_key { enum DESFIRE_CRYPTOALGO type; @@ -139,7 +134,6 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes void mifare_cypher_single_block(desfirekey_t key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size); void mifare_cypher_blocks_chained(desfiretag_t tag, desfirekey_t key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation); size_t key_block_size(const desfirekey_t key); -size_t padded_data_length(const size_t nbytes, const size_t block_size); size_t maced_data_length(const desfirekey_t key, const size_t nbytes); size_t enciphered_data_length(const desfiretag_t tag, const size_t nbytes, int communication_settings); void cmac_generate_subkeys(desfirekey_t key, MifareCryptoDirection direction); diff --git a/client/src/mifare/desfirecrypto.c b/client/src/mifare/desfirecrypto.c index 366995a06..af94d479d 100644 --- a/client/src/mifare/desfirecrypto.c +++ b/client/src/mifare/desfirecrypto.c @@ -31,7 +31,7 @@ #include "crc16.h" // crc16 ccitt #include "crc32.h" #include "commonutil.h" -#include "mifare/desfire_crypto.h" +#include "crypto/libpcrypto.h" void DesfireClearContext(DesfireContext *ctx) { ctx->keyNum = 0; @@ -96,7 +96,7 @@ bool DesfireIsAuthenticated(DesfireContext *dctx) { } size_t DesfireGetMACLength(DesfireContext *ctx) { - size_t mac_length = MAC_LENGTH; + size_t mac_length = DESFIRE_MAC_LENGTH; switch (ctx->secureChannel) { case DACNone: mac_length = 0; @@ -536,6 +536,45 @@ int DesfireEV2CalcCMAC(DesfireContext *ctx, uint8_t cmd, uint8_t *data, size_t d return aes_cmac8(NULL, ctx->sessionKeyMAC, mdata, mac, mdatalen); } +int desfire_get_key_length(DesfireCryptoAlgorythm key_type) { + switch (key_type) { + case T_DES: + return 8; + case T_3DES: + return 16; + case T_3K3DES: + return 24; + case T_AES: + return 16; + } + return 0; +} + +size_t desfire_get_key_block_length(DesfireCryptoAlgorythm key_type) { + size_t block_size = 8; + switch (key_type) { + case T_DES: + case T_3DES: + case T_3K3DES: + block_size = 8; + break; + case T_AES: + block_size = 16; + break; + } + return block_size; +} + +/* + * Size required to store nbytes of data in a buffer of size n*block_size. + */ +size_t padded_data_length(const size_t nbytes, const size_t block_size) { + if ((!nbytes) || (nbytes % block_size)) + return ((nbytes / block_size) + 1) * block_size; + else + return nbytes; +} + void desfire_crc32(const uint8_t *data, const size_t len, uint8_t *crc) { crc32_ex(data, len, crc); } diff --git a/client/src/mifare/desfirecrypto.h b/client/src/mifare/desfirecrypto.h index 9fa379049..37d56bf82 100644 --- a/client/src/mifare/desfirecrypto.h +++ b/client/src/mifare/desfirecrypto.h @@ -22,12 +22,13 @@ #define __DESFIRECRYPTO_H #include "common.h" -#include "mifare/mifare4.h" #define CRYPTO_AES_BLOCK_SIZE 16 #define MAX_CRYPTO_BLOCK_SIZE 16 #define DESFIRE_MAX_CRYPTO_BLOCK_SIZE 16 #define DESFIRE_MAX_KEY_SIZE 24 +#define DESFIRE_MAC_LENGTH 4 +#define DESFIRE_CMAC_LENGTH 8 #define DESFIRE_GET_ISO_STATUS(x) ( ((uint16_t)(0x91<<8)) + (uint16_t)x ) @@ -125,6 +126,10 @@ void DesfireGenSessionKeyEV2(uint8_t *key, uint8_t *rndA, uint8_t *rndB, bool en void DesfireEV2FillIV(DesfireContext *ctx, bool ivforcommand, uint8_t *iv); int DesfireEV2CalcCMAC(DesfireContext *ctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *mac); +int desfire_get_key_length(DesfireCryptoAlgorythm key_type); +size_t desfire_get_key_block_length(DesfireCryptoAlgorythm key_type); +size_t padded_data_length(const size_t nbytes, const size_t block_size); + void desfire_crc32(const uint8_t *data, const size_t len, uint8_t *crc); void desfire_crc32_append(uint8_t *data, const size_t len); bool desfire_crc32_check(uint8_t *data, const size_t len, uint8_t *crc); diff --git a/client/src/mifare/desfiresecurechan.c b/client/src/mifare/desfiresecurechan.c index ced1fd073..03106f24e 100644 --- a/client/src/mifare/desfiresecurechan.c +++ b/client/src/mifare/desfiresecurechan.c @@ -21,7 +21,6 @@ #include "crc32.h" #include "commonutil.h" #include "protocols.h" -#include "mifare/desfire_crypto.h" static const uint8_t CommandsCanUseAnyChannel[] = { MFDES_S_ADDITIONAL_FRAME, From e21010905cb23cfc97991b4c58b30b799caf1735 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 7 Aug 2021 12:54:59 +0300 Subject: [PATCH 04/22] add crytolib --- client/src/mifare/desfirecrypto.h | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/mifare/desfirecrypto.h b/client/src/mifare/desfirecrypto.h index 37d56bf82..fd4d2f0a5 100644 --- a/client/src/mifare/desfirecrypto.h +++ b/client/src/mifare/desfirecrypto.h @@ -22,6 +22,7 @@ #define __DESFIRECRYPTO_H #include "common.h" +#include "crypto/libpcrypto.h" #define CRYPTO_AES_BLOCK_SIZE 16 #define MAX_CRYPTO_BLOCK_SIZE 16 From efd3a887aeda4a5c0c53a3200e6c55fb575481f4 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 7 Aug 2021 13:42:47 +0300 Subject: [PATCH 05/22] remove some old cryto code --- client/src/mifare/desfirecore.c | 24 +++++++++++++++--------- client/src/mifare/desfirecore.h | 2 +- client/src/mifare/desfiresecurechan.h | 1 - 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index af29df827..86c3e23e7 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -1045,7 +1045,7 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec // Part 3 - if (dctx->keyType == T_AES) { + /*if (dctx->keyType == T_AES) { if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) { return 5; } @@ -1059,7 +1059,8 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec tdes_nxp_receive(encRndB, RndB, rndlen, key->data, IV, 2); else if (dctx->keyType == T_3K3DES) { tdes_nxp_receive(encRndB, RndB, rndlen, key->data, IV, 3); - } + }*/ + DesfireCryptoEncDecEx(dctx, DCOMainKey, encRndB, rndlen, RndB, false, false, IV); if (g_debugMode > 1) { PrintAndLogEx(DEBUG, "encRndB: %s", sprint_hex(encRndB, 8)); @@ -1073,6 +1074,8 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec uint8_t encRndA[16] = {0x00}; // - Encrypt our response + if (secureChannel == DACd40) + memset(IV, 0, DESFIRE_MAX_CRYPTO_BLOCK_SIZE); if (secureChannel == DACd40) { if (dctx->keyType == T_DES) { des_decrypt(encRndA, RndA, key->data); @@ -1173,9 +1176,9 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec // Part 4 memcpy(encRndA, recv_data, rndlen); - //PrintAndLogEx(INFO, "encRndA : %s", sprint_hex(encRndA, rndlen)); - //PrintAndLogEx(INFO, "IV : %s", sprint_hex(IV, rndlen)); - if (dctx->keyType == T_DES) { + PrintAndLogEx(INFO, "encRndA : %s", sprint_hex(encRndA, rndlen)); + PrintAndLogEx(INFO, "IV : %s", sprint_hex(IV, rndlen)); + /*if (dctx->keyType == T_DES) { if (secureChannel == DACd40) des_decrypt(encRndA, encRndA, key->data); if (secureChannel == DACEV1) @@ -1192,14 +1195,17 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec return 10; } mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, rndlen, IV, encRndA, encRndA); - } - + }*/ + if (secureChannel == DACd40) + memset(IV, 0, DESFIRE_MAX_CRYPTO_BLOCK_SIZE); + DesfireCryptoEncDecEx(dctx, DCOMainKey, encRndA, rndlen, encRndA, false, false, IV); + // generate session key from rnda and rndb. before rol(RndA)! DesfireGenSessionKeyEV1(RndA, RndB, dctx->keyType, dctx->sessionKeyEnc); rol(RndA, rndlen); - //PrintAndLogEx(INFO, "Expected_RndA : %s", sprint_hex(RndA, rndlen)); - //PrintAndLogEx(INFO, "Generated_RndA : %s", sprint_hex(encRndA, rndlen)); + PrintAndLogEx(INFO, "Expected_RndA : %s", sprint_hex(RndA, rndlen)); + PrintAndLogEx(INFO, "Generated_RndA : %s", sprint_hex(encRndA, rndlen)); for (uint32_t x = 0; x < rndlen; x++) { if (RndA[x] != encRndA[x]) { if (g_debugMode > 1) { diff --git a/client/src/mifare/desfirecore.h b/client/src/mifare/desfirecore.h index 833c1f8b3..0e8ad26b7 100644 --- a/client/src/mifare/desfirecore.h +++ b/client/src/mifare/desfirecore.h @@ -16,7 +16,7 @@ #include "common.h" #include "cliparser.h" #include "mifare/desfirecrypto.h" -#include "mifare/mifare4.h" +#include "mifare/desfire_crypto.h" #define DESFIRE_TX_FRAME_MAX_LEN 54 diff --git a/client/src/mifare/desfiresecurechan.h b/client/src/mifare/desfiresecurechan.h index 235e3a41b..77b84bafc 100644 --- a/client/src/mifare/desfiresecurechan.h +++ b/client/src/mifare/desfiresecurechan.h @@ -16,7 +16,6 @@ #include "common.h" #include "mifare/desfirecore.h" #include "mifare/desfirecrypto.h" -#include "mifare/desfire_crypto.h" #include "mifare/mifare4.h" typedef struct { From 88756eef79565613d8f2fd084eb5825e0837813f Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 7 Aug 2021 13:54:43 +0300 Subject: [PATCH 06/22] auth concet --- client/src/mifare/desfirecore.c | 85 +++++---------------------------- 1 file changed, 13 insertions(+), 72 deletions(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 86c3e23e7..17d944865 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -1074,85 +1074,26 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec uint8_t encRndA[16] = {0x00}; // - Encrypt our response - if (secureChannel == DACd40) - memset(IV, 0, DESFIRE_MAX_CRYPTO_BLOCK_SIZE); if (secureChannel == DACd40) { - if (dctx->keyType == T_DES) { - des_decrypt(encRndA, RndA, key->data); - memcpy(both, encRndA, rndlen); - - for (uint32_t x = 0; x < rndlen; x++) { - rotRndB[x] = rotRndB[x] ^ encRndA[x]; - } - - des_decrypt(encRndB, rotRndB, key->data); - memcpy(both + rndlen, encRndB, rndlen); - } else if (dctx->keyType == T_3DES) { - des3_decrypt(encRndA, RndA, key->data, 2); - memcpy(both, encRndA, rndlen); - - for (uint32_t x = 0; x < rndlen; x++) { - rotRndB[x] = rotRndB[x] ^ encRndA[x]; - } - - des3_decrypt(encRndB, rotRndB, key->data, 2); - memcpy(both + rndlen, encRndB, rndlen); - } - } else if (secureChannel == DACEV1 && dctx->keyType != T_AES) { - if (dctx->keyType == T_DES) { - uint8_t tmp[16] = {0x00}; - memcpy(tmp, RndA, rndlen); - memcpy(tmp + rndlen, rotRndB, rndlen); - if (g_debugMode > 1) { - PrintAndLogEx(DEBUG, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); - PrintAndLogEx(DEBUG, "Both: %s", sprint_hex(tmp, 16)); - } - des_encrypt_cbc(both, tmp, 16, key->data, IV); - if (g_debugMode > 1) { - PrintAndLogEx(DEBUG, "EncBoth: %s", sprint_hex(both, 16)); - } - } else if (dctx->keyType == T_3DES) { - uint8_t tmp[16] = {0x00}; - memcpy(tmp, RndA, rndlen); - memcpy(tmp + rndlen, rotRndB, rndlen); - if (g_debugMode > 1) { - PrintAndLogEx(DEBUG, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); - PrintAndLogEx(DEBUG, "Both: %s", sprint_hex(tmp, 16)); - } - tdes_nxp_send(tmp, both, 16, key->data, IV, 2); - if (g_debugMode > 1) { - PrintAndLogEx(DEBUG, "EncBoth: %s", sprint_hex(both, 16)); - } - } else if (dctx->keyType == T_3K3DES) { - uint8_t tmp[32] = {0x00}; - memcpy(tmp, RndA, rndlen); - memcpy(tmp + rndlen, rotRndB, rndlen); - if (g_debugMode > 1) { - PrintAndLogEx(DEBUG, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); - PrintAndLogEx(DEBUG, "Both3k3: %s", sprint_hex(tmp, 32)); - } - tdes_nxp_send(tmp, both, 32, key->data, IV, 3); - if (g_debugMode > 1) { - PrintAndLogEx(DEBUG, "EncBoth: %s", sprint_hex(both, 32)); - } - } - } else if (secureChannel == DACEV1 && dctx->keyType == T_AES) { + memset(IV, 0, DESFIRE_MAX_CRYPTO_BLOCK_SIZE); + DesfireCryptoEncDecEx(dctx, DCOMainKey, RndA, rndlen, encRndA, true, true, IV); + + memcpy(both, encRndA, rndlen); + bin_xor(rotRndB, encRndA, rndlen); + + memset(IV, 0, DESFIRE_MAX_CRYPTO_BLOCK_SIZE); + DesfireCryptoEncDecEx(dctx, DCOMainKey, rotRndB, rndlen, encRndB, true, true, IV); + + memcpy(both + rndlen, encRndB, rndlen); + } else if (secureChannel == DACEV1) { uint8_t tmp[32] = {0x00}; memcpy(tmp, RndA, rndlen); memcpy(tmp + rndlen, rotRndB, rndlen); if (g_debugMode > 1) { PrintAndLogEx(DEBUG, "rotRndB: %s", sprint_hex(rotRndB, rndlen)); - PrintAndLogEx(DEBUG, "Both3k3: %s", sprint_hex(tmp, 32)); - } - if (dctx->keyType == T_AES) { - if (mbedtls_aes_setkey_enc(&ctx, key->data, 128) != 0) { - return 6; - } - mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, 32, IV, tmp, both); - if (g_debugMode > 1) { - PrintAndLogEx(DEBUG, "EncBoth: %s", sprint_hex(both, 32)); - } + PrintAndLogEx(DEBUG, "Both : %s", sprint_hex(tmp, 32)); } + DesfireCryptoEncDecEx(dctx, DCOMainKey, tmp, rndlen * 2, both, true, true, IV); } uint32_t bothlen = 16; From ce39985d19bbbe20c6148e896ab0174bb463cb77 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 7 Aug 2021 13:57:50 +0300 Subject: [PATCH 07/22] remove debug --- client/src/mifare/desfirecore.c | 42 ++++----------------------------- 1 file changed, 5 insertions(+), 37 deletions(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 17d944865..cc0c2405f 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -1045,21 +1045,6 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec // Part 3 - /*if (dctx->keyType == T_AES) { - if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) { - return 5; - } - mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, rndlen, IV, encRndB, RndB); - } else if (dctx->keyType == T_DES) { - if (secureChannel == DACd40) - des_decrypt(RndB, encRndB, key->data); - if (secureChannel == DACEV1) - des_decrypt_cbc(RndB, encRndB, rndlen, key->data, IV); - } else if (dctx->keyType == T_3DES) - tdes_nxp_receive(encRndB, RndB, rndlen, key->data, IV, 2); - else if (dctx->keyType == T_3K3DES) { - tdes_nxp_receive(encRndB, RndB, rndlen, key->data, IV, 3); - }*/ DesfireCryptoEncDecEx(dctx, DCOMainKey, encRndB, rndlen, RndB, false, false, IV); if (g_debugMode > 1) { @@ -1117,26 +1102,9 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec // Part 4 memcpy(encRndA, recv_data, rndlen); - PrintAndLogEx(INFO, "encRndA : %s", sprint_hex(encRndA, rndlen)); - PrintAndLogEx(INFO, "IV : %s", sprint_hex(IV, rndlen)); - /*if (dctx->keyType == T_DES) { - if (secureChannel == DACd40) - des_decrypt(encRndA, encRndA, key->data); - if (secureChannel == DACEV1) - des_decrypt_cbc(encRndA, encRndA, rndlen, key->data, IV); - } else if (dctx->keyType == T_3DES) - if (secureChannel == DACd40) - des3_decrypt(encRndA, encRndA, key->data, 2); - else - tdes_nxp_receive(encRndA, encRndA, rndlen, key->data, IV, 2); - else if (dctx->keyType == T_3K3DES) - tdes_nxp_receive(encRndA, encRndA, rndlen, key->data, IV, 3); - else if (dctx->keyType == T_AES) { - if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) { - return 10; - } - mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, rndlen, IV, encRndA, encRndA); - }*/ + //PrintAndLogEx(INFO, "encRndA : %s", sprint_hex(encRndA, rndlen)); + //PrintAndLogEx(INFO, "IV : %s", sprint_hex(IV, rndlen)); + if (secureChannel == DACd40) memset(IV, 0, DESFIRE_MAX_CRYPTO_BLOCK_SIZE); DesfireCryptoEncDecEx(dctx, DCOMainKey, encRndA, rndlen, encRndA, false, false, IV); @@ -1145,8 +1113,8 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec DesfireGenSessionKeyEV1(RndA, RndB, dctx->keyType, dctx->sessionKeyEnc); rol(RndA, rndlen); - PrintAndLogEx(INFO, "Expected_RndA : %s", sprint_hex(RndA, rndlen)); - PrintAndLogEx(INFO, "Generated_RndA : %s", sprint_hex(encRndA, rndlen)); + //PrintAndLogEx(INFO, "Expected_RndA : %s", sprint_hex(RndA, rndlen)); + //PrintAndLogEx(INFO, "Generated_RndA : %s", sprint_hex(encRndA, rndlen)); for (uint32_t x = 0; x < rndlen; x++) { if (RndA[x] != encRndA[x]) { if (g_debugMode > 1) { From 7ea7e4b3649fdf31ff155924d5d16c19dea8b332 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 7 Aug 2021 14:53:23 +0300 Subject: [PATCH 08/22] fix --- client/src/mifare/desfire_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/mifare/desfire_crypto.c b/client/src/mifare/desfire_crypto.c index b0bbc62b7..7ee2f542c 100644 --- a/client/src/mifare/desfire_crypto.c +++ b/client/src/mifare/desfire_crypto.c @@ -320,7 +320,6 @@ void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t le // This function is almot like cmac(...). but with some key differences. void mifare_kdf_an10922(const desfirekey_t key, const uint8_t *data, size_t len) { int kbs = key_block_size(key); - int kbs2 = kbs * 2; if (key == NULL || kbs == 0 || data == NULL || len < 1 || len > 31) { return; } @@ -328,6 +327,7 @@ void mifare_kdf_an10922(const desfirekey_t key, const uint8_t *data, size_t len) // AES uses 16 byte IV if (kbs < 16) kbs = 16; + int kbs2 = kbs * 2; cmac_generate_subkeys(key, MCD_SEND); From 02194f3e437c0931e37f7b29f898bec3da330821 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 7 Aug 2021 16:16:41 +0300 Subject: [PATCH 09/22] aes cmac subkeys test --- client/src/mifare/desfirecrypto.c | 39 ++++++++++++++++++++++++- client/src/mifare/desfirecrypto.h | 4 ++- client/src/mifare/desfiretest.c | 47 +++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 2 deletions(-) diff --git a/client/src/mifare/desfirecrypto.c b/client/src/mifare/desfirecrypto.c index af94d479d..2df705dd2 100644 --- a/client/src/mifare/desfirecrypto.c +++ b/client/src/mifare/desfirecrypto.c @@ -262,7 +262,7 @@ void DesfireCryptoEncDec(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, u DesfireCryptoEncDecEx(ctx, key_type, srcdata, srcdatalen, dstdata, dir_to_send, xencode, NULL); } -static void DesfireCMACGenerateSubkeys(DesfireContext *ctx, uint8_t *sk1, uint8_t *sk2) { +void DesfireCMACGenerateSubkeys(DesfireContext *ctx, uint8_t *sk1, uint8_t *sk2) { int kbs = desfire_get_key_block_length(ctx->keyType); const uint8_t R = (kbs == 8) ? 0x1B : 0x87; @@ -323,6 +323,43 @@ void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *data, size_t len, uint8_t * memcpy(cmac, ctx->IV, kbs); } +// This function is almot like cmac(...). but with some key differences. +void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len) { + int kbs = desfire_get_key_block_length(ctx->keyType); // 8 or 16 + if (ctx == NULL || kbs == 0 || data == NULL || len < 1 || len > 31) { + return; + } + + // AES uses 16 byte IV + if (kbs < CRYPTO_AES_BLOCK_SIZE) + kbs = CRYPTO_AES_BLOCK_SIZE; + int kbs2 = kbs * 2; + + uint8_t sk1[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; + uint8_t sk2[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; + DesfireCMACGenerateSubkeys(ctx, sk1, sk2); + + // reserv atleast 32bytes. + uint8_t buffer[DESFIRE_MAX_CRYPTO_BLOCK_SIZE * 2] = {0}; + + buffer[0] = 0x01; + memcpy(&buffer[1], data, len++); + + if (len != (kbs2)) { + buffer[len++] = 0x80; + while (len % kbs2) { + buffer[len++] = 0x00; + } + bin_xor(buffer + kbs, sk2, kbs); + } else { + bin_xor(buffer + kbs, sk1, kbs); + } + + aes_encode(NULL, ctx->key, buffer, buffer, kbs2); + + memcpy(ctx->key, buffer + kbs, kbs); +} + void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorythm keytype, uint8_t version) { if (keytype == T_AES) return; diff --git a/client/src/mifare/desfirecrypto.h b/client/src/mifare/desfirecrypto.h index fd4d2f0a5..9ac0b5c71 100644 --- a/client/src/mifare/desfirecrypto.h +++ b/client/src/mifare/desfirecrypto.h @@ -110,8 +110,10 @@ size_t DesfireSearchCRCPos(uint8_t *data, size_t datalen, uint8_t respcode, uint void DesfireCryptoEncDec(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode); void DesfireCryptoEncDecEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool dir_to_send, bool encode, uint8_t *iv); +void DesfireCMACGenerateSubkeys(DesfireContext *ctx, uint8_t *sk1, uint8_t *sk2); void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *cmac); - +void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len); + void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorythm keytype, uint8_t version); uint8_t DesfireDESKeyGetVersion(uint8_t *key); diff --git a/client/src/mifare/desfiretest.c b/client/src/mifare/desfiretest.c index 9972a6793..8720961ad 100644 --- a/client/src/mifare/desfiretest.c +++ b/client/src/mifare/desfiretest.c @@ -78,6 +78,51 @@ static bool TestCRC32(void) { return res; } +static bool TestCMACSubkeys(void) { + bool res = true; + + uint8_t key[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; + + uint8_t sk1[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; + uint8_t sk2[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; + DesfireContext dctx; + DesfireSetKey(&dctx, 0, T_AES, key); + memcpy(dctx.sessionKeyMAC, key, sizeof(key)); + + DesfireCMACGenerateSubkeys(&dctx, sk1, sk2); + + uint8_t sk1test[] = {0xFB, 0xC9, 0xF7, 0x5C, 0x94, 0x13, 0xC0, 0x41, 0xDF, 0xEE, 0x45, 0x2D, 0x3F, 0x07, 0x06, 0xD1}; + uint8_t sk2test[] = {0xF7, 0x93, 0xEE, 0xB9, 0x28, 0x27, 0x80, 0x83, 0xBF, 0xDC, 0x8A, 0x5A, 0x7E, 0x0E, 0x0D, 0x25}; + + res = res && (memcmp(sk1, sk1test, sizeof(sk1test)) == 0); + res = res && (memcmp(sk2, sk2test, sizeof(sk2test)) == 0); + + if (res) + PrintAndLogEx(INFO, "CMAC subkeys...... " _GREEN_("passed")); + else + PrintAndLogEx(ERR, "CMAC subkeys...... " _RED_("fail")); + + return res; +} + +static bool TestAn10922KDFAES(void) { + bool res = true; + + uint8_t key[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; + + DesfireContext dctx; + DesfireSetKey(&dctx, 0, T_AES, key); + memcpy(dctx.sessionKeyMAC, key, sizeof(key)); + + + if (res) + PrintAndLogEx(INFO, "AES An10922....... " _GREEN_("passed")); + else + PrintAndLogEx(ERR, "AES An10922....... " _RED_("fail")); + + return res; +} + // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/TDES_CMAC.pdf static bool TestCMAC3TDEA(void) { bool res = true; @@ -336,6 +381,8 @@ bool DesfireTest(bool verbose) { res = res && TestCRC16(); res = res && TestCRC32(); + res = res && TestCMACSubkeys(); + res = res && TestAn10922KDFAES(); res = res && TestCMAC3TDEA(); res = res && TestCMAC2TDEA(); res = res && TestCMACDES(); From 7aad0087625d2e36b6554d3209bd985140b6c280 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 7 Aug 2021 16:27:39 +0300 Subject: [PATCH 10/22] fix key path for cmac subkeys --- client/src/mifare/desfirecrypto.c | 32 ++++++++++++++++++++----------- client/src/mifare/desfirecrypto.h | 3 ++- client/src/mifare/desfiretest.c | 3 +-- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/client/src/mifare/desfirecrypto.c b/client/src/mifare/desfirecrypto.c index 2df705dd2..86d0a9bac 100644 --- a/client/src/mifare/desfirecrypto.c +++ b/client/src/mifare/desfirecrypto.c @@ -151,6 +151,17 @@ size_t DesfireSearchCRCPos(uint8_t *data, size_t datalen, uint8_t respcode, uint return crcposfound; } +uint8_t *DesfireGetKey(DesfireContext *ctx, DesfireCryptoOpKeyType key_type) { + if (key_type == DCOSessionKeyMac) { + return ctx->sessionKeyMAC; + } else if (key_type == DCOSessionKeyEnc) { + return ctx->sessionKeyEnc; + } + + return ctx->key; +} + + static void DesfireCryptoEncDecSingleBlock(uint8_t *key, DesfireCryptoAlgorythm keyType, uint8_t *data, uint8_t *dstdata, uint8_t *ivect, bool dir_to_send, bool encode) { size_t block_size = desfire_get_key_block_length(keyType); uint8_t sdata[MAX_CRYPTO_BLOCK_SIZE] = {0}; @@ -232,15 +243,14 @@ void DesfireCryptoEncDecEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, else memcpy(xiv, iv, block_size); + uint8_t *key = DesfireGetKey(ctx, key_type); + if (key == NULL) + return; + size_t offset = 0; while (offset < srcdatalen) { - if (key_type == DCOSessionKeyMac) { - DesfireCryptoEncDecSingleBlock(ctx->sessionKeyMAC, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode); - } else if (key_type == DCOSessionKeyEnc) { - DesfireCryptoEncDecSingleBlock(ctx->sessionKeyEnc, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode); - } else { - DesfireCryptoEncDecSingleBlock(ctx->key, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode); - } + DesfireCryptoEncDecSingleBlock(key, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode); + offset += block_size; } @@ -262,7 +272,7 @@ void DesfireCryptoEncDec(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, u DesfireCryptoEncDecEx(ctx, key_type, srcdata, srcdatalen, dstdata, dir_to_send, xencode, NULL); } -void DesfireCMACGenerateSubkeys(DesfireContext *ctx, uint8_t *sk1, uint8_t *sk2) { +void DesfireCMACGenerateSubkeys(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *sk1, uint8_t *sk2) { int kbs = desfire_get_key_block_length(ctx->keyType); const uint8_t R = (kbs == 8) ? 0x1B : 0x87; @@ -272,7 +282,7 @@ void DesfireCMACGenerateSubkeys(DesfireContext *ctx, uint8_t *sk1, uint8_t *sk2) uint8_t ivect[kbs]; memset(ivect, 0, kbs); - DesfireCryptoEncDecEx(ctx, DCOSessionKeyMac, l, kbs, l, true, true, ivect); + DesfireCryptoEncDecEx(ctx, key_type, l, kbs, l, true, true, ivect); bool txor = false; @@ -303,7 +313,7 @@ void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *data, size_t len, uint8_t * uint8_t sk1[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; uint8_t sk2[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; - DesfireCMACGenerateSubkeys(ctx, sk1, sk2); + DesfireCMACGenerateSubkeys(ctx, DCOSessionKeyMac, sk1, sk2); memcpy(buffer, data, len); @@ -337,7 +347,7 @@ void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len) { uint8_t sk1[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; uint8_t sk2[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; - DesfireCMACGenerateSubkeys(ctx, sk1, sk2); + DesfireCMACGenerateSubkeys(ctx, DCOMainKey, sk1, sk2); // reserv atleast 32bytes. uint8_t buffer[DESFIRE_MAX_CRYPTO_BLOCK_SIZE * 2] = {0}; diff --git a/client/src/mifare/desfirecrypto.h b/client/src/mifare/desfirecrypto.h index 9ac0b5c71..e28c14cb6 100644 --- a/client/src/mifare/desfirecrypto.h +++ b/client/src/mifare/desfirecrypto.h @@ -108,9 +108,10 @@ size_t DesfireGetMACLength(DesfireContext *ctx); size_t DesfireSearchCRCPos(uint8_t *data, size_t datalen, uint8_t respcode, uint8_t crclen); +uint8_t *DesfireGetKey(DesfireContext *ctx, DesfireCryptoOpKeyType key_type); void DesfireCryptoEncDec(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode); void DesfireCryptoEncDecEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool dir_to_send, bool encode, uint8_t *iv); -void DesfireCMACGenerateSubkeys(DesfireContext *ctx, uint8_t *sk1, uint8_t *sk2); +void DesfireCMACGenerateSubkeys(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *sk1, uint8_t *sk2); void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *cmac); void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len); diff --git a/client/src/mifare/desfiretest.c b/client/src/mifare/desfiretest.c index 8720961ad..b0a720e92 100644 --- a/client/src/mifare/desfiretest.c +++ b/client/src/mifare/desfiretest.c @@ -87,9 +87,8 @@ static bool TestCMACSubkeys(void) { uint8_t sk2[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; DesfireContext dctx; DesfireSetKey(&dctx, 0, T_AES, key); - memcpy(dctx.sessionKeyMAC, key, sizeof(key)); - DesfireCMACGenerateSubkeys(&dctx, sk1, sk2); + DesfireCMACGenerateSubkeys(&dctx, DCOMainKey, sk1, sk2); uint8_t sk1test[] = {0xFB, 0xC9, 0xF7, 0x5C, 0x94, 0x13, 0xC0, 0x41, 0xDF, 0xEE, 0x45, 0x2D, 0x3F, 0x07, 0x06, 0xD1}; uint8_t sk2test[] = {0xF7, 0x93, 0xEE, 0xB9, 0x28, 0x27, 0x80, 0x83, 0xBF, 0xDC, 0x8A, 0x5A, 0x7E, 0x0E, 0x0D, 0x25}; From 4a2a23c6e2f0c0f8ceb9fab1d20199696c89843c Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 7 Aug 2021 20:26:49 +0300 Subject: [PATCH 11/22] kdf an10922 test --- client/src/mifare/desfiretest.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/src/mifare/desfiretest.c b/client/src/mifare/desfiretest.c index b0a720e92..65d56a907 100644 --- a/client/src/mifare/desfiretest.c +++ b/client/src/mifare/desfiretest.c @@ -104,6 +104,8 @@ static bool TestCMACSubkeys(void) { return res; } +// https://www.nxp.com/docs/en/application-note/AN10922.pdf +// page 8 static bool TestAn10922KDFAES(void) { bool res = true; @@ -113,6 +115,11 @@ static bool TestAn10922KDFAES(void) { DesfireSetKey(&dctx, 0, T_AES, key); memcpy(dctx.sessionKeyMAC, key, sizeof(key)); + uint8_t kdfInput[] = {0x04, 0x78, 0x2E, 0x21, 0x80, 0x1D, 0x80, 0x30, 0x42, 0xF5, 0x4E, 0x58, 0x50, 0x20, 0x41, 0x62, 0x75}; + MifareKdfAn10922(&dctx, kdfInput, sizeof(kdfInput)); + + uint8_t dkey[] = {0xA8, 0xDD, 0x63, 0xA3, 0xB8, 0x9D, 0x54, 0xB3, 0x7C, 0xA8, 0x02, 0x47, 0x3F, 0xDA, 0x91, 0x75}; + res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0); if (res) PrintAndLogEx(INFO, "AES An10922....... " _GREEN_("passed")); From 2fb3385d909775645d26b8450e2e9ce272e93a48 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 7 Aug 2021 22:03:48 +0300 Subject: [PATCH 12/22] test subkeys - 2tdea, 3tdea --- client/src/mifare/desfiretest.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/client/src/mifare/desfiretest.c b/client/src/mifare/desfiretest.c index 65d56a907..0a9e6598d 100644 --- a/client/src/mifare/desfiretest.c +++ b/client/src/mifare/desfiretest.c @@ -86,6 +86,7 @@ static bool TestCMACSubkeys(void) { uint8_t sk1[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; uint8_t sk2[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; DesfireContext dctx; + // AES DesfireSetKey(&dctx, 0, T_AES, key); DesfireCMACGenerateSubkeys(&dctx, DCOMainKey, sk1, sk2); @@ -96,6 +97,29 @@ static bool TestCMACSubkeys(void) { res = res && (memcmp(sk1, sk1test, sizeof(sk1test)) == 0); res = res && (memcmp(sk2, sk2test, sizeof(sk2test)) == 0); + // 2tdea + DesfireSetKey(&dctx, 0, T_3DES, key); + + DesfireCMACGenerateSubkeys(&dctx, DCOMainKey, sk1, sk2); + + uint8_t sk1_2tdea[] = {0xF6, 0x12, 0xEB, 0x32, 0xE4, 0x60, 0x35, 0xF3}; + uint8_t sk2_2tdea[] = {0xEC, 0x25, 0xD6, 0x65, 0xC8, 0xC0, 0x6B, 0xFD}; + + res = res && (memcmp(sk1, sk1_2tdea, sizeof(sk1_2tdea)) == 0); + res = res && (memcmp(sk2, sk2_2tdea, sizeof(sk2_2tdea)) == 0); + + // 3tdea + uint8_t key3[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; + DesfireSetKey(&dctx, 0, T_3K3DES, key3); + + DesfireCMACGenerateSubkeys(&dctx, DCOMainKey, sk1, sk2); + + uint8_t sk1_3tdea[] = {0xA3, 0xED, 0x58, 0xF8, 0xE6, 0x94, 0x1B, 0xCA}; + uint8_t sk2_3tdea[] = {0x47, 0xDA, 0xB1, 0xF1, 0xCD, 0x28, 0x37, 0x8F}; + + res = res && (memcmp(sk1, sk1_3tdea, sizeof(sk1_3tdea)) == 0); + res = res && (memcmp(sk2, sk2_3tdea, sizeof(sk2_3tdea)) == 0); + if (res) PrintAndLogEx(INFO, "CMAC subkeys...... " _GREEN_("passed")); else From 94bb6d389b09917396d0b728c7b752ca51799d1a Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 7 Aug 2021 22:07:24 +0300 Subject: [PATCH 13/22] add source --- client/src/mifare/desfiretest.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/mifare/desfiretest.c b/client/src/mifare/desfiretest.c index 0a9e6598d..7e049bf8b 100644 --- a/client/src/mifare/desfiretest.c +++ b/client/src/mifare/desfiretest.c @@ -78,6 +78,7 @@ static bool TestCRC32(void) { return res; } +// https://www.nxp.com/docs/en/application-note/AN10922.pdf static bool TestCMACSubkeys(void) { bool res = true; From e4a72b11e861a0fd0ea5256a44a1683e537ccf4f Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 8 Aug 2021 17:54:16 +0300 Subject: [PATCH 14/22] cmac add minimum len --- client/src/mifare/desfirecrypto.c | 18 +++++++++++++----- client/src/mifare/desfirecrypto.h | 1 + 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/client/src/mifare/desfirecrypto.c b/client/src/mifare/desfirecrypto.c index 86d0a9bac..c43a856cb 100644 --- a/client/src/mifare/desfirecrypto.c +++ b/client/src/mifare/desfirecrypto.c @@ -303,7 +303,7 @@ void DesfireCMACGenerateSubkeys(DesfireContext *ctx, DesfireCryptoOpKeyType key_ } } -void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *data, size_t len, uint8_t *cmac) { +void DesfireCryptoCMACEx(DesfireContext *ctx, uint8_t *data, size_t len, size_t minlen, uint8_t *cmac) { int kbs = desfire_get_key_block_length(ctx->keyType); if (kbs == 0) return; @@ -317,9 +317,9 @@ void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *data, size_t len, uint8_t * memcpy(buffer, data, len); - if ((!len) || (len % kbs)) { + if ((!len) || (len % kbs) || (len < minlen)) { buffer[len++] = 0x80; - while (len % kbs) { + while (len % kbs || len < minlen) { buffer[len++] = 0x00; } bin_xor(buffer + len - kbs, sk2, kbs); @@ -333,6 +333,10 @@ void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *data, size_t len, uint8_t * memcpy(cmac, ctx->IV, kbs); } +void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *data, size_t len, uint8_t *cmac) { + DesfireCryptoCMACEx(ctx, data, len, 0, cmac); +} + // This function is almot like cmac(...). but with some key differences. void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len) { int kbs = desfire_get_key_block_length(ctx->keyType); // 8 or 16 @@ -355,7 +359,11 @@ void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len) { buffer[0] = 0x01; memcpy(&buffer[1], data, len++); - if (len != (kbs2)) { + uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; + DesfireCryptoCMACEx(ctx, buffer, len, kbs2, cmac); + memcpy(ctx->key, cmac, kbs); + + /*if (len != (kbs2)) { buffer[len++] = 0x80; while (len % kbs2) { buffer[len++] = 0x00; @@ -367,7 +375,7 @@ void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len) { aes_encode(NULL, ctx->key, buffer, buffer, kbs2); - memcpy(ctx->key, buffer + kbs, kbs); + memcpy(ctx->key, buffer + kbs, kbs);*/ } void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorythm keytype, uint8_t version) { diff --git a/client/src/mifare/desfirecrypto.h b/client/src/mifare/desfirecrypto.h index e28c14cb6..33c8eba0f 100644 --- a/client/src/mifare/desfirecrypto.h +++ b/client/src/mifare/desfirecrypto.h @@ -113,6 +113,7 @@ void DesfireCryptoEncDec(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, u void DesfireCryptoEncDecEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool dir_to_send, bool encode, uint8_t *iv); void DesfireCMACGenerateSubkeys(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *sk1, uint8_t *sk2); void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *cmac); +void DesfireCryptoCMACEx(DesfireContext *ctx, uint8_t *data, size_t len, size_t minlen, uint8_t *cmac); void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len); void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorythm keytype, uint8_t version); From a86f3322631569f2f1743372f850198269a5daf0 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 8 Aug 2021 18:33:35 +0300 Subject: [PATCH 15/22] cmac 2tdea works --- client/src/mifare/desfirecrypto.c | 50 ++++++++++++++----------------- client/src/mifare/desfiretest.c | 24 +++++++++++++++ 2 files changed, 47 insertions(+), 27 deletions(-) diff --git a/client/src/mifare/desfirecrypto.c b/client/src/mifare/desfirecrypto.c index c43a856cb..dd9bbaec6 100644 --- a/client/src/mifare/desfirecrypto.c +++ b/client/src/mifare/desfirecrypto.c @@ -344,38 +344,34 @@ void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len) { return; } - // AES uses 16 byte IV - if (kbs < CRYPTO_AES_BLOCK_SIZE) - kbs = CRYPTO_AES_BLOCK_SIZE; - int kbs2 = kbs * 2; - - uint8_t sk1[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; - uint8_t sk2[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; - DesfireCMACGenerateSubkeys(ctx, DCOMainKey, sk1, sk2); - - // reserv atleast 32bytes. + uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; uint8_t buffer[DESFIRE_MAX_CRYPTO_BLOCK_SIZE * 2] = {0}; - buffer[0] = 0x01; - memcpy(&buffer[1], data, len++); + if (ctx->keyType == T_AES) { + // AES uses 16 byte IV + if (kbs < CRYPTO_AES_BLOCK_SIZE) + kbs = CRYPTO_AES_BLOCK_SIZE; - uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; - DesfireCryptoCMACEx(ctx, buffer, len, kbs2, cmac); - memcpy(ctx->key, cmac, kbs); + buffer[0] = 0x01; + memcpy(&buffer[1], data, len++); - /*if (len != (kbs2)) { - buffer[len++] = 0x80; - while (len % kbs2) { - buffer[len++] = 0x00; - } - bin_xor(buffer + kbs, sk2, kbs); - } else { - bin_xor(buffer + kbs, sk1, kbs); + DesfireCryptoCMACEx(ctx, buffer, len, kbs * 2, cmac); + memcpy(ctx->key, cmac, kbs); + } else if (ctx->keyType == T_3DES) { + buffer[0] = 0x21; + memcpy(&buffer[1], data, len); + + DesfireClearIV(ctx); + DesfireCryptoCMACEx(ctx, buffer, len + 1, kbs * 2, cmac); + + buffer[0] = 0x22; + memcpy(&buffer[1], data, len); + + DesfireClearIV(ctx); + DesfireCryptoCMACEx(ctx, buffer, len + 1, kbs * 2, &cmac[kbs]); + + memcpy(ctx->key, cmac, kbs * 2); } - - aes_encode(NULL, ctx->key, buffer, buffer, kbs2); - - memcpy(ctx->key, buffer + kbs, kbs);*/ } void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorythm keytype, uint8_t version) { diff --git a/client/src/mifare/desfiretest.c b/client/src/mifare/desfiretest.c index 7e049bf8b..a74f8682f 100644 --- a/client/src/mifare/desfiretest.c +++ b/client/src/mifare/desfiretest.c @@ -154,6 +154,29 @@ static bool TestAn10922KDFAES(void) { return res; } +static bool TestAn10922KDF2TDEA(void) { + bool res = true; + + uint8_t key[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; + + DesfireContext dctx; + DesfireSetKey(&dctx, 0, T_3DES, key); + memcpy(dctx.sessionKeyMAC, key, sizeof(key)); + + uint8_t kdfInput[] = {0x04, 0x78, 0x2E, 0x21, 0x80, 0x1D, 0x80, 0x30, 0x42, 0xF5, 0x4E, 0x58, 0x50, 0x20, 0x41}; + MifareKdfAn10922(&dctx, kdfInput, sizeof(kdfInput)); + + uint8_t dkey[] = {0x16, 0xF8, 0x59, 0x7C, 0x9E, 0x89, 0x10, 0xC8, 0x6B, 0x96, 0x48, 0xD0, 0x06, 0x10, 0x7D, 0xD7}; + res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0); + + if (res) + PrintAndLogEx(INFO, "2TDEA An10922..... " _GREEN_("passed")); + else + PrintAndLogEx(ERR, "2TDEA An10922..... " _RED_("fail")); + + return res; +} + // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/TDES_CMAC.pdf static bool TestCMAC3TDEA(void) { bool res = true; @@ -414,6 +437,7 @@ bool DesfireTest(bool verbose) { res = res && TestCRC32(); res = res && TestCMACSubkeys(); res = res && TestAn10922KDFAES(); + res = res && TestAn10922KDF2TDEA(); res = res && TestCMAC3TDEA(); res = res && TestCMAC2TDEA(); res = res && TestCMACDES(); From 455b9a4e38d8932c1d8fd2bbe30854a5af29bd5b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 8 Aug 2021 18:42:54 +0300 Subject: [PATCH 16/22] an10922 3tdea works --- client/src/mifare/desfirecrypto.c | 24 ++++++++++++++++++++-- client/src/mifare/desfiretest.c | 33 +++++++++++++++++++++++++++---- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/client/src/mifare/desfirecrypto.c b/client/src/mifare/desfirecrypto.c index dd9bbaec6..26586ad3a 100644 --- a/client/src/mifare/desfirecrypto.c +++ b/client/src/mifare/desfirecrypto.c @@ -344,8 +344,8 @@ void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len) { return; } - uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; - uint8_t buffer[DESFIRE_MAX_CRYPTO_BLOCK_SIZE * 2] = {0}; + uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE * 3] = {0}; + uint8_t buffer[DESFIRE_MAX_CRYPTO_BLOCK_SIZE * 3] = {0}; if (ctx->keyType == T_AES) { // AES uses 16 byte IV @@ -371,6 +371,26 @@ void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len) { DesfireCryptoCMACEx(ctx, buffer, len + 1, kbs * 2, &cmac[kbs]); memcpy(ctx->key, cmac, kbs * 2); + } else if (ctx->keyType == T_3K3DES) { + buffer[0] = 0x31; + memcpy(&buffer[1], data, len); + + DesfireClearIV(ctx); + DesfireCryptoCMACEx(ctx, buffer, len + 1, kbs * 2, cmac); + + buffer[0] = 0x32; + memcpy(&buffer[1], data, len); + + DesfireClearIV(ctx); + DesfireCryptoCMACEx(ctx, buffer, len + 1, kbs * 2, &cmac[kbs]); + + buffer[0] = 0x33; + memcpy(&buffer[1], data, len); + + DesfireClearIV(ctx); + DesfireCryptoCMACEx(ctx, buffer, len + 1, kbs * 2, &cmac[kbs * 2]); + + memcpy(ctx->key, cmac, kbs * 3); } } diff --git a/client/src/mifare/desfiretest.c b/client/src/mifare/desfiretest.c index a74f8682f..119805e29 100644 --- a/client/src/mifare/desfiretest.c +++ b/client/src/mifare/desfiretest.c @@ -147,9 +147,9 @@ static bool TestAn10922KDFAES(void) { res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0); if (res) - PrintAndLogEx(INFO, "AES An10922....... " _GREEN_("passed")); + PrintAndLogEx(INFO, "An10922 AES....... " _GREEN_("passed")); else - PrintAndLogEx(ERR, "AES An10922....... " _RED_("fail")); + PrintAndLogEx(ERR, "An10922 AES....... " _RED_("fail")); return res; } @@ -170,9 +170,33 @@ static bool TestAn10922KDF2TDEA(void) { res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0); if (res) - PrintAndLogEx(INFO, "2TDEA An10922..... " _GREEN_("passed")); + PrintAndLogEx(INFO, "An10922 2TDEA..... " _GREEN_("passed")); else - PrintAndLogEx(ERR, "2TDEA An10922..... " _RED_("fail")); + PrintAndLogEx(ERR, "An10922 2TDEA..... " _RED_("fail")); + + return res; +} + +static bool TestAn10922KDF3TDEA(void) { + bool res = true; + + uint8_t key[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; + + DesfireContext dctx; + DesfireSetKey(&dctx, 0, T_3K3DES, key); + memcpy(dctx.sessionKeyMAC, key, sizeof(key)); + + uint8_t kdfInput[] = {0x04, 0x78, 0x2E, 0x21, 0x80, 0x1D, 0x80, 0x30, 0x42, 0xF5, 0x4E, 0x58, 0x50}; + MifareKdfAn10922(&dctx, kdfInput, sizeof(kdfInput)); + + uint8_t dkey[] = {0x2F, 0x0D, 0xD0, 0x36, 0x75, 0xD3, 0xFB, 0x9A, 0x57, 0x05, 0xAB, 0x0B, 0xDA, 0x91, 0xCA, 0x0B, + 0x55, 0xB8, 0xE0, 0x7F, 0xCD, 0xBF, 0x10, 0xEC}; + res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0); + + if (res) + PrintAndLogEx(INFO, "An10922 3TDEA..... " _GREEN_("passed")); + else + PrintAndLogEx(ERR, "An10922 3TDEA..... " _RED_("fail")); return res; } @@ -438,6 +462,7 @@ bool DesfireTest(bool verbose) { res = res && TestCMACSubkeys(); res = res && TestAn10922KDFAES(); res = res && TestAn10922KDF2TDEA(); + res = res && TestAn10922KDF3TDEA(); res = res && TestCMAC3TDEA(); res = res && TestCMAC2TDEA(); res = res && TestCMACDES(); From 0ef41b7b783a7e95aee2c5098618a16a64712e5d Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 8 Aug 2021 19:15:06 +0300 Subject: [PATCH 17/22] add masterkey for kdf --- client/src/mifare/desfirecore.c | 11 +++++------ client/src/mifare/desfirecrypto.c | 25 ++++++++++++++----------- client/src/mifare/desfirecrypto.h | 6 ++++-- client/src/mifare/desfiretest.c | 9 +++------ 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index cc0c2405f..886a52d2d 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -985,8 +985,8 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec } if (dctx->kdfAlgo == MFDES_KDF_ALGO_AN10922) { - mifare_kdf_an10922(key, dctx->kdfInput, dctx->kdfInputLen); - PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key))); + MifareKdfAn10922(dctx, DCOMasterKey, dctx->kdfInput, dctx->kdfInputLen); + PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(dctx->key, desfire_get_key_block_length(dctx->keyType))); } else if (dctx->kdfAlgo == MFDES_KDF_ALGO_GALLAGHER) { // We will overrite any provided KDF input since a gallagher specific KDF was requested. dctx->kdfInputLen = 11; @@ -995,10 +995,9 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec PrintAndLogEx(FAILED, "Could not generate Gallagher KDF input"); }*/ - mifare_kdf_an10922(key, dctx->kdfInput, dctx->kdfInputLen); - PrintAndLogEx(DEBUG, " KDF Input: " _YELLOW_("%s"), sprint_hex(dctx->kdfInput, dctx->kdfInputLen)); - PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(key->data, key_block_size(key))); - + MifareKdfAn10922(dctx, DCOMasterKey, dctx->kdfInput, dctx->kdfInputLen); + PrintAndLogEx(INFO, " Derrived key: " _GREEN_("%s"), sprint_hex(dctx->key, desfire_get_key_block_length(dctx->keyType))); + PrintAndLogEx(INFO, " KDF Input: " _YELLOW_("%s"), sprint_hex(dctx->kdfInput, dctx->kdfInputLen)); } uint8_t subcommand = MFDES_AUTHENTICATE; diff --git a/client/src/mifare/desfirecrypto.c b/client/src/mifare/desfirecrypto.c index 26586ad3a..4bd6582b4 100644 --- a/client/src/mifare/desfirecrypto.c +++ b/client/src/mifare/desfirecrypto.c @@ -74,6 +74,7 @@ void DesfireSetKey(DesfireContext *ctx, uint8_t keyNum, enum DESFIRE_CRYPTOALGO ctx->keyNum = keyNum; ctx->keyType = keyType; memcpy(ctx->key, key, desfire_get_key_length(keyType)); + memcpy(ctx->masterKey, key, desfire_get_key_length(keyType)); } void DesfireSetCommandSet(DesfireContext *ctx, DesfireCommandSet cmdSet) { @@ -156,6 +157,8 @@ uint8_t *DesfireGetKey(DesfireContext *ctx, DesfireCryptoOpKeyType key_type) { return ctx->sessionKeyMAC; } else if (key_type == DCOSessionKeyEnc) { return ctx->sessionKeyEnc; + } else if (key_type == DCOMasterKey) { + return ctx->masterKey; } return ctx->key; @@ -303,7 +306,7 @@ void DesfireCMACGenerateSubkeys(DesfireContext *ctx, DesfireCryptoOpKeyType key_ } } -void DesfireCryptoCMACEx(DesfireContext *ctx, uint8_t *data, size_t len, size_t minlen, uint8_t *cmac) { +void DesfireCryptoCMACEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *data, size_t len, size_t minlen, uint8_t *cmac) { int kbs = desfire_get_key_block_length(ctx->keyType); if (kbs == 0) return; @@ -313,7 +316,7 @@ void DesfireCryptoCMACEx(DesfireContext *ctx, uint8_t *data, size_t len, size_t uint8_t sk1[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; uint8_t sk2[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; - DesfireCMACGenerateSubkeys(ctx, DCOSessionKeyMac, sk1, sk2); + DesfireCMACGenerateSubkeys(ctx, key_type, sk1, sk2); memcpy(buffer, data, len); @@ -327,18 +330,18 @@ void DesfireCryptoCMACEx(DesfireContext *ctx, uint8_t *data, size_t len, size_t bin_xor(buffer + len - kbs, sk1, kbs); } - DesfireCryptoEncDec(ctx, DCOSessionKeyMac, buffer, len, NULL, true); + DesfireCryptoEncDec(ctx, key_type, buffer, len, NULL, true); if (cmac != NULL) memcpy(cmac, ctx->IV, kbs); } void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *data, size_t len, uint8_t *cmac) { - DesfireCryptoCMACEx(ctx, data, len, 0, cmac); + DesfireCryptoCMACEx(ctx, DCOSessionKeyMac, data, len, 0, cmac); } // This function is almot like cmac(...). but with some key differences. -void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len) { +void MifareKdfAn10922(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, const uint8_t *data, size_t len) { int kbs = desfire_get_key_block_length(ctx->keyType); // 8 or 16 if (ctx == NULL || kbs == 0 || data == NULL || len < 1 || len > 31) { return; @@ -355,20 +358,20 @@ void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len) { buffer[0] = 0x01; memcpy(&buffer[1], data, len++); - DesfireCryptoCMACEx(ctx, buffer, len, kbs * 2, cmac); + DesfireCryptoCMACEx(ctx, key_type, buffer, len, kbs * 2, cmac); memcpy(ctx->key, cmac, kbs); } else if (ctx->keyType == T_3DES) { buffer[0] = 0x21; memcpy(&buffer[1], data, len); DesfireClearIV(ctx); - DesfireCryptoCMACEx(ctx, buffer, len + 1, kbs * 2, cmac); + DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, cmac); buffer[0] = 0x22; memcpy(&buffer[1], data, len); DesfireClearIV(ctx); - DesfireCryptoCMACEx(ctx, buffer, len + 1, kbs * 2, &cmac[kbs]); + DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, &cmac[kbs]); memcpy(ctx->key, cmac, kbs * 2); } else if (ctx->keyType == T_3K3DES) { @@ -376,19 +379,19 @@ void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len) { memcpy(&buffer[1], data, len); DesfireClearIV(ctx); - DesfireCryptoCMACEx(ctx, buffer, len + 1, kbs * 2, cmac); + DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, cmac); buffer[0] = 0x32; memcpy(&buffer[1], data, len); DesfireClearIV(ctx); - DesfireCryptoCMACEx(ctx, buffer, len + 1, kbs * 2, &cmac[kbs]); + DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, &cmac[kbs]); buffer[0] = 0x33; memcpy(&buffer[1], data, len); DesfireClearIV(ctx); - DesfireCryptoCMACEx(ctx, buffer, len + 1, kbs * 2, &cmac[kbs * 2]); + DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, &cmac[kbs * 2]); memcpy(ctx->key, cmac, kbs * 3); } diff --git a/client/src/mifare/desfirecrypto.h b/client/src/mifare/desfirecrypto.h index 33c8eba0f..113996ece 100644 --- a/client/src/mifare/desfirecrypto.h +++ b/client/src/mifare/desfirecrypto.h @@ -65,6 +65,7 @@ typedef enum { } DesfireCommunicationMode; typedef enum { + DCOMasterKey, DCOMainKey, DCOSessionKeyMac, DCOSessionKeyEnc @@ -74,6 +75,7 @@ typedef struct DesfireContextS { uint8_t keyNum; DesfireCryptoAlgorythm keyType; // des/2tdea/3tdea/aes uint8_t key[DESFIRE_MAX_KEY_SIZE]; + uint8_t masterKey[DESFIRE_MAX_KEY_SIZE]; // source for kdf // KDF finction uint8_t kdfAlgo; @@ -113,8 +115,8 @@ void DesfireCryptoEncDec(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, u void DesfireCryptoEncDecEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool dir_to_send, bool encode, uint8_t *iv); void DesfireCMACGenerateSubkeys(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *sk1, uint8_t *sk2); void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *cmac); -void DesfireCryptoCMACEx(DesfireContext *ctx, uint8_t *data, size_t len, size_t minlen, uint8_t *cmac); -void MifareKdfAn10922(DesfireContext *ctx, const uint8_t *data, size_t len); +void DesfireCryptoCMACEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *data, size_t len, size_t minlen, uint8_t *cmac); +void MifareKdfAn10922(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, const uint8_t *data, size_t len); void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorythm keytype, uint8_t version); uint8_t DesfireDESKeyGetVersion(uint8_t *key); diff --git a/client/src/mifare/desfiretest.c b/client/src/mifare/desfiretest.c index 119805e29..1f3425246 100644 --- a/client/src/mifare/desfiretest.c +++ b/client/src/mifare/desfiretest.c @@ -138,10 +138,9 @@ static bool TestAn10922KDFAES(void) { DesfireContext dctx; DesfireSetKey(&dctx, 0, T_AES, key); - memcpy(dctx.sessionKeyMAC, key, sizeof(key)); uint8_t kdfInput[] = {0x04, 0x78, 0x2E, 0x21, 0x80, 0x1D, 0x80, 0x30, 0x42, 0xF5, 0x4E, 0x58, 0x50, 0x20, 0x41, 0x62, 0x75}; - MifareKdfAn10922(&dctx, kdfInput, sizeof(kdfInput)); + MifareKdfAn10922(&dctx, DCOMainKey, kdfInput, sizeof(kdfInput)); uint8_t dkey[] = {0xA8, 0xDD, 0x63, 0xA3, 0xB8, 0x9D, 0x54, 0xB3, 0x7C, 0xA8, 0x02, 0x47, 0x3F, 0xDA, 0x91, 0x75}; res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0); @@ -161,10 +160,9 @@ static bool TestAn10922KDF2TDEA(void) { DesfireContext dctx; DesfireSetKey(&dctx, 0, T_3DES, key); - memcpy(dctx.sessionKeyMAC, key, sizeof(key)); uint8_t kdfInput[] = {0x04, 0x78, 0x2E, 0x21, 0x80, 0x1D, 0x80, 0x30, 0x42, 0xF5, 0x4E, 0x58, 0x50, 0x20, 0x41}; - MifareKdfAn10922(&dctx, kdfInput, sizeof(kdfInput)); + MifareKdfAn10922(&dctx, DCOMainKey, kdfInput, sizeof(kdfInput)); uint8_t dkey[] = {0x16, 0xF8, 0x59, 0x7C, 0x9E, 0x89, 0x10, 0xC8, 0x6B, 0x96, 0x48, 0xD0, 0x06, 0x10, 0x7D, 0xD7}; res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0); @@ -184,10 +182,9 @@ static bool TestAn10922KDF3TDEA(void) { DesfireContext dctx; DesfireSetKey(&dctx, 0, T_3K3DES, key); - memcpy(dctx.sessionKeyMAC, key, sizeof(key)); uint8_t kdfInput[] = {0x04, 0x78, 0x2E, 0x21, 0x80, 0x1D, 0x80, 0x30, 0x42, 0xF5, 0x4E, 0x58, 0x50}; - MifareKdfAn10922(&dctx, kdfInput, sizeof(kdfInput)); + MifareKdfAn10922(&dctx, DCOMainKey, kdfInput, sizeof(kdfInput)); uint8_t dkey[] = {0x2F, 0x0D, 0xD0, 0x36, 0x75, 0xD3, 0xFB, 0x9A, 0x57, 0x05, 0xAB, 0x0B, 0xDA, 0x91, 0xCA, 0x0B, 0x55, 0xB8, 0xE0, 0x7F, 0xCD, 0xBF, 0x10, 0xEC}; From 9e3cc6826ccaa5c5d243693e293a44288c3acba0 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 8 Aug 2021 19:27:31 +0300 Subject: [PATCH 18/22] add AID for kdf --- client/src/mifare/desfirecore.c | 10 +++++++--- client/src/mifare/desfirecrypto.c | 4 ++++ client/src/mifare/desfirecrypto.h | 4 ++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 886a52d2d..82ad47e99 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -20,6 +20,7 @@ #include #include #include "commonutil.h" +#include "generator.h" #include "aes.h" #include "ui.h" #include "crc.h" @@ -788,6 +789,7 @@ int DesfireSelectAID(DesfireContext *ctx, uint8_t *aid1, uint8_t *aid2) { DesfireClearSession(ctx); ctx->appSelected = (aid1[0] != 0x00 || aid1[1] != 0x00 || aid1[2] != 0x00); + ctx->selectedAID = DesfireAIDByteToUint(aid1); return PM3_SUCCESS; } @@ -825,6 +827,7 @@ int DesfireSelectAIDHexNoFieldOn(DesfireContext *ctx, uint32_t aid) { DesfireClearSession(ctx); ctx->appSelected = (aid != 0x000000); + ctx->selectedAID = aid; return PM3_SUCCESS; } @@ -991,13 +994,13 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec // We will overrite any provided KDF input since a gallagher specific KDF was requested. dctx->kdfInputLen = 11; - /*if (mfdes_kdf_input_gallagher(tag->info.uid, tag->info.uidlen, dctx->keyNum, tag->selected_application, dctx->kdfInput, &dctx->kdfInputLen) != PM3_SUCCESS) { + if (mfdes_kdf_input_gallagher(dctx->uid, dctx->uidlen, dctx->keyNum, dctx->selectedAID, dctx->kdfInput, &dctx->kdfInputLen) != PM3_SUCCESS) { PrintAndLogEx(FAILED, "Could not generate Gallagher KDF input"); - }*/ + } + PrintAndLogEx(INFO, " KDF Input: " _YELLOW_("%s"), sprint_hex(dctx->kdfInput, dctx->kdfInputLen)); MifareKdfAn10922(dctx, DCOMasterKey, dctx->kdfInput, dctx->kdfInputLen); PrintAndLogEx(INFO, " Derrived key: " _GREEN_("%s"), sprint_hex(dctx->key, desfire_get_key_block_length(dctx->keyType))); - PrintAndLogEx(INFO, " KDF Input: " _YELLOW_("%s"), sprint_hex(dctx->kdfInput, dctx->kdfInputLen)); } uint8_t subcommand = MFDES_AUTHENTICATE; @@ -2547,6 +2550,7 @@ int DesfireISOSelectEx(DesfireContext *dctx, bool fieldon, DesfireISOSelectContr DesfireClearSession(dctx); dctx->appSelected = !((cntr == ISSMFDFEF && datalen == 0) || (cntr == ISSEFByFileID && datalen == 2 && data[0] == 0 && data[1] == 0)); + dctx->selectedAID = 0; return res; } diff --git a/client/src/mifare/desfirecrypto.c b/client/src/mifare/desfirecrypto.c index 4bd6582b4..14d725678 100644 --- a/client/src/mifare/desfirecrypto.c +++ b/client/src/mifare/desfirecrypto.c @@ -43,6 +43,10 @@ void DesfireClearContext(DesfireContext *ctx) { ctx->commMode = DCMNone; ctx->appSelected = false; + ctx->selectedAID = 0; + + memset(ctx->uid, 0, sizeof(ctx->uid)); + ctx->uidlen = 0; ctx->kdfAlgo = 0; ctx->kdfInputLen = 0; diff --git a/client/src/mifare/desfirecrypto.h b/client/src/mifare/desfirecrypto.h index 113996ece..e5a7643e8 100644 --- a/client/src/mifare/desfirecrypto.h +++ b/client/src/mifare/desfirecrypto.h @@ -87,6 +87,10 @@ typedef struct DesfireContextS { DesfireCommunicationMode commMode; // plain/mac/enc bool appSelected; // for iso auth + uint32_t selectedAID; + + uint8_t uid[10]; + uint8_t uidlen; uint8_t IV[DESFIRE_MAX_KEY_SIZE]; uint8_t sessionKeyMAC[DESFIRE_MAX_KEY_SIZE]; From 797d878eb45d45a80780bc5d6d739bf466eb6c5d Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 8 Aug 2021 19:31:08 +0300 Subject: [PATCH 19/22] remove desfire_crypto --- client/src/mifare/desfirecore.c | 18 +----------------- client/src/mifare/desfirecore.h | 1 - 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 82ad47e99..f6e4e8e99 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -959,8 +959,6 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec if (secureChannel == DACNone) return PM3_SUCCESS; - mbedtls_aes_context ctx; - uint8_t keybytes[24] = {0}; // Crypt constants uint8_t IV[16] = {0}; @@ -973,20 +971,6 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec // Part 1 memcpy(keybytes, dctx->key, desfire_get_key_length(dctx->keyType)); - struct desfire_key dkey = {0}; - desfirekey_t key = &dkey; - - if (dctx->keyType == T_AES) { - mbedtls_aes_init(&ctx); - Desfire_aes_key_new(keybytes, key); - } else if (dctx->keyType == T_3DES) { - Desfire_3des_key_new_with_version(keybytes, key); - } else if (dctx->keyType == T_DES) { - Desfire_des_key_new(keybytes, key); - } else if (dctx->keyType == T_3K3DES) { - Desfire_3k3des_key_new_with_version(keybytes, key); - } - if (dctx->kdfAlgo == MFDES_KDF_ALGO_AN10922) { MifareKdfAn10922(dctx, DCOMasterKey, dctx->kdfInput, dctx->kdfInputLen); PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(dctx->key, desfire_get_key_block_length(dctx->keyType))); @@ -1130,7 +1114,7 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec // If the 3Des key first 8 bytes = 2nd 8 Bytes then we are really using Singe Des // As such we need to set the session key such that the 2nd 8 bytes = 1st 8 Bytes if (dctx->keyType == T_3DES) { - if (memcmp(key->data, &key->data[8], 8) == 0) + if (memcmp(dctx->key, &dctx->key[8], 8) == 0) memcpy(&dctx->sessionKeyEnc[8], dctx->sessionKeyEnc, 8); } diff --git a/client/src/mifare/desfirecore.h b/client/src/mifare/desfirecore.h index 0e8ad26b7..bad18c13b 100644 --- a/client/src/mifare/desfirecore.h +++ b/client/src/mifare/desfirecore.h @@ -16,7 +16,6 @@ #include "common.h" #include "cliparser.h" #include "mifare/desfirecrypto.h" -#include "mifare/desfire_crypto.h" #define DESFIRE_TX_FRAME_MAX_LEN 54 From f9b8ef5a6d11dd535730c7792b915da7155022c8 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 8 Aug 2021 22:42:15 +0300 Subject: [PATCH 20/22] move kdf part --- client/src/mifare/desfirecore.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index f6e4e8e99..9e5fdcd09 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -971,22 +971,6 @@ static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel sec // Part 1 memcpy(keybytes, dctx->key, desfire_get_key_length(dctx->keyType)); - if (dctx->kdfAlgo == MFDES_KDF_ALGO_AN10922) { - MifareKdfAn10922(dctx, DCOMasterKey, dctx->kdfInput, dctx->kdfInputLen); - PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(dctx->key, desfire_get_key_block_length(dctx->keyType))); - } else if (dctx->kdfAlgo == MFDES_KDF_ALGO_GALLAGHER) { - // We will overrite any provided KDF input since a gallagher specific KDF was requested. - dctx->kdfInputLen = 11; - - if (mfdes_kdf_input_gallagher(dctx->uid, dctx->uidlen, dctx->keyNum, dctx->selectedAID, dctx->kdfInput, &dctx->kdfInputLen) != PM3_SUCCESS) { - PrintAndLogEx(FAILED, "Could not generate Gallagher KDF input"); - } - PrintAndLogEx(INFO, " KDF Input: " _YELLOW_("%s"), sprint_hex(dctx->kdfInput, dctx->kdfInputLen)); - - MifareKdfAn10922(dctx, DCOMasterKey, dctx->kdfInput, dctx->kdfInputLen); - PrintAndLogEx(INFO, " Derrived key: " _GREEN_("%s"), sprint_hex(dctx->key, desfire_get_key_block_length(dctx->keyType))); - } - uint8_t subcommand = MFDES_AUTHENTICATE; if (secureChannel == DACEV1) { if (dctx->keyType == T_AES) @@ -1312,6 +1296,22 @@ static int DesfireAuthenticateISO(DesfireContext *dctx, DesfireSecureChannel sec } int DesfireAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool verbose) { + if (dctx->kdfAlgo == MFDES_KDF_ALGO_AN10922) { + MifareKdfAn10922(dctx, DCOMasterKey, dctx->kdfInput, dctx->kdfInputLen); + PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(dctx->key, desfire_get_key_block_length(dctx->keyType))); + } else if (dctx->kdfAlgo == MFDES_KDF_ALGO_GALLAGHER) { + // We will overrite any provided KDF input since a gallagher specific KDF was requested. + dctx->kdfInputLen = 11; + + if (mfdes_kdf_input_gallagher(dctx->uid, dctx->uidlen, dctx->keyNum, dctx->selectedAID, dctx->kdfInput, &dctx->kdfInputLen) != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "Could not generate Gallagher KDF input"); + } + PrintAndLogEx(INFO, " KDF Input: " _YELLOW_("%s"), sprint_hex(dctx->kdfInput, dctx->kdfInputLen)); + + MifareKdfAn10922(dctx, DCOMasterKey, dctx->kdfInput, dctx->kdfInputLen); + PrintAndLogEx(INFO, " Derrived key: " _GREEN_("%s"), sprint_hex(dctx->key, desfire_get_key_block_length(dctx->keyType))); + } + if (dctx->cmdSet == DCCISO && secureChannel != DACEV2) return DesfireAuthenticateISO(dctx, secureChannel, verbose); From ccf31fef901d523f649515cb658ef547ed008e0d Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 8 Aug 2021 23:02:45 +0300 Subject: [PATCH 21/22] get uid for kdf --- client/src/mifare/desfirecore.c | 24 ++++++++++++++++++++++-- client/src/mifare/desfirecore.h | 2 ++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 9e5fdcd09..a9d02779f 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -335,13 +335,16 @@ void DesfirePrintContext(DesfireContext *ctx) { sprint_hex(ctx->key, desfire_get_key_length(ctx->keyType))); - if (ctx->kdfAlgo != MFDES_KDF_ALGO_NONE) + if (ctx->kdfAlgo != MFDES_KDF_ALGO_NONE) { PrintAndLogEx(INFO, "KDF algo: %s KDF input[%d]: %s", CLIGetOptionListStr(DesfireKDFAlgoOpts, ctx->kdfAlgo), ctx->kdfInputLen, sprint_hex(ctx->kdfInput, ctx->kdfInputLen)); + PrintAndLogEx(INFO, "AID: %06x UID[%d]: %s", ctx->selectedAID, ctx->uidlen, sprint_hex(ctx->uid, ctx->uidlen)); + } PrintAndLogEx(INFO, "Secure channel: %s Command set: %s Communication mode: %s", CLIGetOptionListStr(DesfireSecureChannelOpts, ctx->secureChannel), CLIGetOptionListStr(DesfireCommandSetOpts, ctx->cmdSet), CLIGetOptionListStr(DesfireCommunicationModeOpts, ctx->commMode)); + if (DesfireIsAuthenticated(ctx)) { PrintAndLogEx(INFO, "Session key MAC [%d]: %s ", @@ -847,10 +850,13 @@ void DesfirePrintAIDFunctions(uint32_t appid) { } } - int DesfireSelectAndAuthenticateEx(DesfireContext *dctx, DesfireSecureChannel secureChannel, uint32_t aid, bool noauth, bool verbose) { if (verbose) DesfirePrintContext(dctx); + + // needs card uid for diversification + if (dctx->kdfAlgo == MFDES_KDF_ALGO_GALLAGHER) + DesfireGetCardUID(dctx); bool isosw = false; if (dctx->cmdSet == DCCISO) { @@ -2644,6 +2650,20 @@ int DesfireISOAppendRecord(DesfireContext *dctx, uint8_t fileid, uint8_t *data, return res; } +int DesfireGetCardUID(DesfireContext *ctx) { + iso14a_card_select_t card = {0}; + int res = Hf14443_4aGetCardData(&card); + DropField(); + if (res != PM3_SUCCESS) { + return PM3_ESOFT; + } + + memcpy(ctx->uid, card.uid, card.uidlen); + ctx->uidlen = card.uidlen; + + return PM3_SUCCESS; +} + int DesfireSelectEx(DesfireContext *ctx, bool fieldon, DesfireISOSelectWay way, uint32_t id, char *dfname) { uint8_t resp[250] = {0}; size_t resplen = 0; diff --git a/client/src/mifare/desfirecore.h b/client/src/mifare/desfirecore.h index bad18c13b..c912f6239 100644 --- a/client/src/mifare/desfirecore.h +++ b/client/src/mifare/desfirecore.h @@ -166,6 +166,8 @@ int DesfireSelectAIDHex(DesfireContext *ctx, uint32_t aid1, bool select_two, uin int DesfireSelectAIDHexNoFieldOn(DesfireContext *ctx, uint32_t aid); void DesfirePrintAIDFunctions(uint32_t appid); +int DesfireGetCardUID(DesfireContext *ctx); + int DesfireSelectEx(DesfireContext *ctx, bool fieldon, DesfireISOSelectWay way, uint32_t id, char *dfname); int DesfireSelect(DesfireContext *ctx, DesfireISOSelectWay way, uint32_t id, char *dfname); From c4d35700a1591d0ddf4ede997d0012a86611f455 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 8 Aug 2021 23:48:07 +0300 Subject: [PATCH 22/22] fix some kdf parts --- client/src/mifare/desfirecore.c | 18 ++++++++++++------ client/src/mifare/desfirecrypto.c | 6 +++--- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index a9d02779f..42eb206ba 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -1312,10 +1312,10 @@ int DesfireAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel if (mfdes_kdf_input_gallagher(dctx->uid, dctx->uidlen, dctx->keyNum, dctx->selectedAID, dctx->kdfInput, &dctx->kdfInputLen) != PM3_SUCCESS) { PrintAndLogEx(FAILED, "Could not generate Gallagher KDF input"); } - PrintAndLogEx(INFO, " KDF Input: " _YELLOW_("%s"), sprint_hex(dctx->kdfInput, dctx->kdfInputLen)); + PrintAndLogEx(DEBUG, " KDF Input: " _YELLOW_("%s"), sprint_hex(dctx->kdfInput, dctx->kdfInputLen)); MifareKdfAn10922(dctx, DCOMasterKey, dctx->kdfInput, dctx->kdfInputLen); - PrintAndLogEx(INFO, " Derrived key: " _GREEN_("%s"), sprint_hex(dctx->key, desfire_get_key_block_length(dctx->keyType))); + PrintAndLogEx(DEBUG, " Derrived key: " _GREEN_("%s"), sprint_hex(dctx->key, desfire_get_key_block_length(dctx->keyType))); } if (dctx->cmdSet == DCCISO && secureChannel != DACEV2) @@ -2652,12 +2652,18 @@ int DesfireISOAppendRecord(DesfireContext *dctx, uint8_t fileid, uint8_t *data, int DesfireGetCardUID(DesfireContext *ctx) { iso14a_card_select_t card = {0}; - int res = Hf14443_4aGetCardData(&card); - DropField(); - if (res != PM3_SUCCESS) { + + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); + PacketResponseNG resp; + WaitForResponse(CMD_ACK, &resp); + + memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); + uint64_t select_status = resp.oldarg[0]; + + if (select_status == 0 || select_status == 2 || select_status == 3) { return PM3_ESOFT; } - + memcpy(ctx->uid, card.uid, card.uidlen); ctx->uidlen = card.uidlen; diff --git a/client/src/mifare/desfirecrypto.c b/client/src/mifare/desfirecrypto.c index 14d725678..db559e850 100644 --- a/client/src/mifare/desfirecrypto.c +++ b/client/src/mifare/desfirecrypto.c @@ -315,7 +315,7 @@ void DesfireCryptoCMACEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, u if (kbs == 0) return; - uint8_t buffer[padded_data_length(len, kbs)]; + uint8_t buffer[padded_data_length(MAX(minlen, len) + 1, kbs)]; memset(buffer, 0, sizeof(buffer)); uint8_t sk1[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; @@ -360,9 +360,9 @@ void MifareKdfAn10922(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, cons kbs = CRYPTO_AES_BLOCK_SIZE; buffer[0] = 0x01; - memcpy(&buffer[1], data, len++); + memcpy(&buffer[1], data, len); - DesfireCryptoCMACEx(ctx, key_type, buffer, len, kbs * 2, cmac); + DesfireCryptoCMACEx(ctx, key_type, buffer, len + 1, kbs * 2, cmac); memcpy(ctx->key, cmac, kbs); } else if (ctx->keyType == T_3DES) { buffer[0] = 0x21;