From f074386413006c6402b218e0fee3be9065725b9f Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 30 Jul 2021 14:45:26 +0300 Subject: [PATCH] ev2 iv calc --- client/src/mifare/desfirecore.c | 12 +++++------- client/src/mifare/desfirecrypto.c | 28 +++++++++++++++++++++++++-- client/src/mifare/desfirecrypto.h | 5 ++--- client/src/mifare/desfiresecurechan.c | 18 +++++++++++++++++ 4 files changed, 51 insertions(+), 12 deletions(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 1f540a7ac..2598634dc 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -303,10 +303,9 @@ void DesfirePrintContext(DesfireContext *ctx) { desfire_get_key_block_length(ctx->keyType), sprint_hex(ctx->IV, desfire_get_key_block_length(ctx->keyType))); if (ctx->secureChannel == DACEV2) { - PrintAndLogEx(INFO, " TI: %s cnTX: 0x%08x cnRx: 0x%08x", + PrintAndLogEx(INFO, " TI: %s cmdCntr: 0x%08x", sprint_hex(ctx->TI, 4), - ctx->cntrTx, - ctx->cntrRx); + ctx->cmdCntr); } } @@ -1096,7 +1095,7 @@ static int DesfireAuthenticateEV2(DesfireContext *dctx, DesfireSecureChannel sec // Let's send our auth command uint8_t cdata[2] = {dctx->keyNum, 0x00}; - int res = DesfireExchangeEx(false, dctx, subcommand, cdata, sizeof(cdata), &respcode, recv_data, &recv_len, false, 0); + int res = DesfireExchangeEx(false, dctx, subcommand, cdata, (firstauth) ? sizeof(cdata) : 1, &respcode, recv_data, &recv_len, false, 0); if (res != PM3_SUCCESS) { return 1; } @@ -1175,7 +1174,7 @@ PrintAndLogEx(INFO, "IV : %s", sprint_hex(IV, CRYPTO_AES_BLOCK_SIZE)); uint8_t data[32] = {0}; - if (aes_decode(IV, key, recv_data, data, CRYPTO_AES_BLOCK_SIZE * 2)) + if (aes_decode(IV, key, recv_data, data, recv_len)) return 10; PrintAndLogEx(INFO, "data : %s", sprint_hex(data, CRYPTO_AES_BLOCK_SIZE * 2)); @@ -1200,8 +1199,7 @@ PrintAndLogEx(INFO, "Generated_RndA : %s", sprint_hex(&data[4], CRYPTO_AES_BLOCK } if (firstauth) { - dctx->cntrRx = 0; - dctx->cntrTx = 0; + dctx->cmdCntr = 0; memcpy(dctx->TI, data, 4); } memset(dctx->IV, 0, DESFIRE_MAX_KEY_SIZE); diff --git a/client/src/mifare/desfirecrypto.c b/client/src/mifare/desfirecrypto.c index cf26fe22d..0e65f5787 100644 --- a/client/src/mifare/desfirecrypto.c +++ b/client/src/mifare/desfirecrypto.c @@ -58,8 +58,7 @@ void DesfireClearSession(DesfireContext *ctx) { memset(ctx->lastIV, 0, sizeof(ctx->lastIV)); ctx->lastCommand = 0; ctx->lastRequestZeroLen = false; - ctx->cntrTx = 0; - ctx->cntrRx = 0; + ctx->cmdCntr = 0; memset(ctx->TI, 0, sizeof(ctx->TI)); } @@ -219,6 +218,10 @@ void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *s if (ctx->secureChannel == DACd40) { memset(ctx->IV, 0, DESFIRE_MAX_CRYPTO_BLOCK_SIZE); } + + if (ctx->secureChannel == DACEV2) { + DesfireEV2FillIV(ctx, dir_to_send, NULL); + } size_t block_size = desfire_get_key_block_length(ctx->keyType); @@ -417,6 +420,27 @@ void DesfireGenSessionKeyEV2(uint8_t *key, uint8_t *rndA, uint8_t *rndB, bool en memcpy(sessionkey, cmac, CRYPTO_AES_BLOCK_SIZE); } +void DesfireEV2FillIV(DesfireContext *ctx, bool send, uint8_t *iv) { + uint8_t xiv[CRYPTO_AES_BLOCK_SIZE] = {0}; + + if (send) { + xiv[0] = 0xa5; + xiv[1] = 0x5a; + } else { + xiv[0] = 0x5a; + xiv[1] = 0xa5; + } + + memcpy(xiv + 2, ctx->TI, 4); + Uint2byteToMemLe(xiv + 2 + 4, ctx->cmdCntr); + + if (iv == NULL) + memcpy(ctx->IV, xiv, CRYPTO_AES_BLOCK_SIZE); + else + memcpy(iv, xiv, CRYPTO_AES_BLOCK_SIZE); +} + + 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 b8ba977fd..4caff1fb9 100644 --- a/client/src/mifare/desfirecrypto.h +++ b/client/src/mifare/desfirecrypto.h @@ -82,9 +82,7 @@ typedef struct DesfireContextS { uint8_t lastIV[DESFIRE_MAX_KEY_SIZE]; uint8_t lastCommand; bool lastRequestZeroLen; - //mf4Session_t AESSession; - uint16_t cntrTx; // for AES - uint16_t cntrRx; // for AES + uint16_t cmdCntr; // for AES uint8_t TI[4]; // for AES } DesfireContext; @@ -110,6 +108,7 @@ DesfireCommunicationMode DesfireFileCommModeToCommMode(uint8_t file_comm_mode); uint8_t DesfireCommModeToFileCommMode(DesfireCommunicationMode comm_mode); void DesfireGenSessionKeyEV2(uint8_t *key, uint8_t *rndA, uint8_t *rndB, bool enckey, uint8_t *sessionkey); +void DesfireEV2FillIV(DesfireContext *ctx, bool send, uint8_t *iv); 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); diff --git a/client/src/mifare/desfiresecurechan.c b/client/src/mifare/desfiresecurechan.c index 7e20b9f1a..81efe69ac 100644 --- a/client/src/mifare/desfiresecurechan.c +++ b/client/src/mifare/desfiresecurechan.c @@ -24,6 +24,7 @@ #include "mifare/desfire_crypto.h" static const uint8_t CommandsCanUseAnyChannel[] = { + MFDES_S_ADDITIONAL_FRAME, MFDES_READ_DATA, MFDES_WRITE_DATA, MFDES_GET_VALUE, @@ -116,6 +117,9 @@ static const AllowedChannelModesS AllowedChannelModes[] = { {MFDES_CHANGE_KEY, DACEV1, DCCNative, DCMEncryptedPlain}, {MFDES_CHANGE_KEY_EV2, DACEV1, DCCNative, DCMEncryptedPlain}, + + {MFDES_AUTHENTICATE_EV2F, DACEV2, DCCNative, DCMPlain}, + {MFDES_AUTHENTICATE_EV2NF, DACEV2, DCCNative, DCMPlain}, }; #define CMD_HEADER_LEN_ALL 0xffff @@ -239,6 +243,13 @@ static void DesfireSecureChannelEncodeEV1(DesfireContext *ctx, uint8_t cmd, uint } } +static void DesfireSecureChannelEncodeEV2(DesfireContext *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) { + memcpy(dstdata, srcdata, srcdatalen); + *dstdatalen = srcdatalen; + + ctx->cmdCntr++; +} + void DesfireSecureChannelEncode(DesfireContext *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) { ctx->lastCommand = cmd; ctx->lastRequestZeroLen = (srcdatalen <= DesfireGetCmdHeaderLen(cmd)); @@ -251,6 +262,7 @@ void DesfireSecureChannelEncode(DesfireContext *ctx, uint8_t cmd, uint8_t *srcda DesfireSecureChannelEncodeEV1(ctx, cmd, srcdata, srcdatalen, dstdata, dstdatalen); break; case DACEV2: + DesfireSecureChannelEncodeEV2(ctx, cmd, srcdata, srcdatalen, dstdata, dstdatalen); break; case DACNone: memcpy(dstdata, srcdata, srcdatalen); @@ -361,6 +373,11 @@ static void DesfireSecureChannelDecodeEV1(DesfireContext *ctx, uint8_t *srcdata, } } +static void DesfireSecureChannelDecodeEV2(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t respcode, uint8_t *dstdata, size_t *dstdatalen) { + memcpy(dstdata, srcdata, srcdatalen); + *dstdatalen = srcdatalen; +} + void DesfireSecureChannelDecode(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t respcode, uint8_t *dstdata, size_t *dstdatalen) { switch (ctx->secureChannel) { case DACd40: @@ -370,6 +387,7 @@ void DesfireSecureChannelDecode(DesfireContext *ctx, uint8_t *srcdata, size_t sr DesfireSecureChannelDecodeEV1(ctx, srcdata, srcdatalen, respcode, dstdata, dstdatalen); break; case DACEV2: + DesfireSecureChannelDecodeEV2(ctx, srcdata, srcdatalen, respcode, dstdata, dstdatalen); break; case DACNone: memcpy(dstdata, srcdata, srcdatalen);