From d8a8c015bcfe7a4368671f05361511b3e9b24d2d Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 11 Jul 2021 18:14:27 +0300 Subject: [PATCH] channel d40/encode works --- client/src/cmdhfmfdes.c | 5 ++++- client/src/mifare/desfirecrypto.c | 9 ++++++--- client/src/mifare/desfiresecurechan.c | 22 ++++++++++++++-------- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 6f63e7a5b..88152b932 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -5029,6 +5029,8 @@ static int CmdDesGetSessionParameters(CLIParserContext *ctx, DesfireContext *dct int commmode = defaultCommMode; int commset = defaultCommSet; int secchann = defaultSecureChannel; + if (securechannel) + secchann = *securechannel; if (keynoid) { keynum = arg_get_int_def(ctx, keynoid, keynum); @@ -5079,6 +5081,7 @@ static int CmdDesGetSessionParameters(CLIParserContext *ctx, DesfireContext *dct } if (schannid) { + if (CLIGetOptionList(arg_get_str(ctx, schannid), DesfireSecureChannelOpts, &secchann)) return PM3_ESOFT; } @@ -5187,7 +5190,7 @@ static int CmdHF14ADesChKeySettings(const char *Cmd) { bool verbose = arg_get_lit(ctx, 2); DesfireContext dctx; - int securechann = DCMPlain; + int securechann = DCMEncrypted; uint32_t appid = 0x000000; int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, &appid); if (res) { diff --git a/client/src/mifare/desfirecrypto.c b/client/src/mifare/desfirecrypto.c index 04c6d7dfb..d3955f92d 100644 --- a/client/src/mifare/desfirecrypto.c +++ b/client/src/mifare/desfirecrypto.c @@ -215,8 +215,11 @@ void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *s uint8_t data[1024] = {0}; uint8_t xiv[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; - if (ctx->secureChannel == DACd40) + bool xencode = encode; + if (ctx->secureChannel == DACd40) { memset(ctx->IV, 0, DESFIRE_MAX_CRYPTO_BLOCK_SIZE); + xencode = false; + } size_t block_size = desfire_get_key_block_length(ctx->keyType); @@ -228,9 +231,9 @@ void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *s size_t offset = 0; while (offset < srcdatalen) { if (use_session_key) - DesfireCryptoEncDecSingleBlock(ctx->sessionKeyMAC, ctx->keyType, srcdata + offset, data + offset, xiv, encode, encode); + DesfireCryptoEncDecSingleBlock(ctx->sessionKeyMAC, ctx->keyType, srcdata + offset, data + offset, xiv, encode, xencode); else - DesfireCryptoEncDecSingleBlock(ctx->key, ctx->keyType, srcdata + offset, data + offset, xiv, encode, encode); + DesfireCryptoEncDecSingleBlock(ctx->key, ctx->keyType, srcdata + offset, data + offset, xiv, encode, xencode); offset += block_size; } diff --git a/client/src/mifare/desfiresecurechan.c b/client/src/mifare/desfiresecurechan.c index 607a42f25..4104b32ef 100644 --- a/client/src/mifare/desfiresecurechan.c +++ b/client/src/mifare/desfiresecurechan.c @@ -46,6 +46,7 @@ AllowedChannelModesS AllowedChannelModes[] = { {MFDES_COMMIT_READER_ID, DACd40, DCCNative, DCMMACed}, {MFDES_GET_UID, DACd40, DCCNative, DCMEncrypted}, + {MFDES_CHANGE_KEY_SETTINGS, DACd40, DCCNative, DCMEncrypted}, {MFDES_READ_DATA, DACd40, DCCNative, DCMEncrypted}, {MFDES_WRITE_DATA, DACd40, DCCNative, DCMEncrypted}, @@ -56,6 +57,7 @@ AllowedChannelModesS AllowedChannelModes[] = { {MFDES_GET_KEY_SETTINGS, DACEV1, DCCNative, DCMMACed}, {MFDES_GET_UID, DACEV1, DCCNative, DCMEncrypted}, + {MFDES_CHANGE_KEY_SETTINGS, DACEV1, DCCNative, DCMEncrypted}, }; static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) { @@ -74,10 +76,9 @@ static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint if (srcdatalen == 0) break; - rlen = padded_data_length(srcdatalen, desfire_get_key_block_length(ctx->keyType)); + rlen = srcdatalen + DesfireGetMACLength(ctx); memcpy(data, srcdata, srcdatalen); - memset(ctx->IV, 0, sizeof(ctx->IV)); - DesfireCryptoEncDec(ctx, true, data, rlen, NULL, true); + DesfireCryptoEncDec(ctx, true, data, srcdatalen, NULL, true); memcpy(dstdata, srcdata, srcdatalen); memcpy(&dstdata[srcdatalen], ctx->IV, 4); *dstdatalen = rlen; @@ -89,7 +90,6 @@ static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint rlen = padded_data_length(srcdatalen + 2, desfire_get_key_block_length(ctx->keyType)); // 2 - crc16 memcpy(data, srcdata, srcdatalen); compute_crc(CRC_14443_A, data, srcdatalen, &data[srcdatalen], &data[srcdatalen + 1]); - memset(ctx->IV, 0, sizeof(ctx->IV)); DesfireCryptoEncDec(ctx, true, data, rlen, dstdata, true); *dstdatalen = rlen; break; @@ -100,7 +100,8 @@ static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint static void DesfireSecureChannelEncodeEV1(DesfireContext *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) { uint8_t data[1024] = {0}; - + size_t rlen = 0; + // we calc MAC anyway // if encypted channel and no data - we only calc MAC if (ctx->commMode == DCMPlain || ctx->commMode == DCMMACed || (ctx->commMode == DCMEncrypted && srcdatalen == 0)) { @@ -110,14 +111,19 @@ static void DesfireSecureChannelEncodeEV1(DesfireContext *ctx, uint8_t cmd, uint DesfireCryptoCMAC(ctx, data, srcdatalen + 1, cmac); memcpy(dstdata, srcdata, srcdatalen); + *dstdatalen = srcdatalen; if (srcdatalen != 0 && ctx->commMode == DCMMACed) { memcpy(&dstdata[srcdatalen], cmac, DesfireGetMACLength(ctx)); *dstdatalen = srcdatalen + DesfireGetMACLength(ctx); } } else if (ctx->commMode == DCMEncrypted) { - - - + rlen = padded_data_length(srcdatalen + 4, desfire_get_key_block_length(ctx->keyType)); + memcpy(data, srcdata, srcdatalen); + desfire_crc32_append(data, srcdatalen); + PrintAndLogEx(INFO, "decoded[%d]: %s", rlen, sprint_hex(data, rlen)); + DesfireCryptoEncDec(ctx, true, data, rlen, dstdata, true); + + *dstdatalen = rlen; } else { memcpy(dstdata, srcdata, srcdatalen); *dstdatalen = srcdatalen;