From e78c563e454bd9877a8559b2f7f13930cc51f051 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 4 Aug 2021 20:01:11 +0300 Subject: [PATCH 1/5] encode with padding sketch --- client/src/cmdhfmfdes.c | 2 -- client/src/mifare/desfirecore.c | 11 ++++++----- client/src/mifare/desfirecrypto.c | 1 + client/src/mifare/desfirecrypto.h | 1 + client/src/mifare/desfiresecurechan.c | 13 +++++++++++-- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 0dd003987..ee0f3e190 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -2628,14 +2628,12 @@ static int CmdHF14ADesSetConfiguration(const char *Cmd) { return res; } - DesfireSetCommMode(&dctx, DCMEncryptedPlain); res = DesfireSetConfiguration(&dctx, paramid, param, paramlen); if (res == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "Set configuration 0x%02x " _GREEN_("ok") " ", paramid); } else { PrintAndLogEx(FAILED, "Set configuration 0x%02x " _RED_("failed") " ", paramid); } - DesfireSetCommMode(&dctx, DCMEncrypted); DropField(); return res; diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index fda847a6d..10c4dff42 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -2545,7 +2545,7 @@ int DesfireSetConfiguration(DesfireContext *dctx, uint8_t paramid, uint8_t *para size_t datalen = 1 + paramlen; - // add crc + /*// add crc if (dctx->secureChannel == DACd40) { iso14443a_crc_append(&data[1], datalen - 1); datalen += 2; @@ -2553,11 +2553,12 @@ int DesfireSetConfiguration(DesfireContext *dctx, uint8_t paramid, uint8_t *para desfire_crc32_append(cdata, datalen + 1); datalen += 4; } - +*/ // dynamic length - if (paramid == 0x02) { - data[datalen] = 0x80; - datalen++; + if (paramid == 0x02 && dctx->commMode == DCMEncrypted) { + dctx->commMode = DCMEncryptedWithPadding; + //data[datalen] = 0x80; + //datalen++; } // send command diff --git a/client/src/mifare/desfirecrypto.c b/client/src/mifare/desfirecrypto.c index 8feecd39c..366995a06 100644 --- a/client/src/mifare/desfirecrypto.c +++ b/client/src/mifare/desfirecrypto.c @@ -429,6 +429,7 @@ uint8_t DesfireCommModeToFileCommMode(DesfireCommunicationMode comm_mode) { fmode = 0x01; break; case DCMEncrypted: + case DCMEncryptedWithPadding: case DCMEncryptedPlain: fmode = 0x11; break; diff --git a/client/src/mifare/desfirecrypto.h b/client/src/mifare/desfirecrypto.h index f336a2448..9fa379049 100644 --- a/client/src/mifare/desfirecrypto.h +++ b/client/src/mifare/desfirecrypto.h @@ -58,6 +58,7 @@ typedef enum { DCMPlain, DCMMACed, DCMEncrypted, + DCMEncryptedWithPadding, DCMEncryptedPlain } DesfireCommunicationMode; diff --git a/client/src/mifare/desfiresecurechan.c b/client/src/mifare/desfiresecurechan.c index b33287a00..383e8fdf9 100644 --- a/client/src/mifare/desfiresecurechan.c +++ b/client/src/mifare/desfiresecurechan.c @@ -260,16 +260,24 @@ static void DesfireSecureChannelEncodeEV1(DesfireContext *ctx, uint8_t cmd, uint memcpy(&dstdata[srcdatalen], cmac, DesfireGetMACLength(ctx)); *dstdatalen = srcdatalen + DesfireGetMACLength(ctx); } - } else if (ctx->commMode == DCMEncrypted) { - rlen = padded_data_length(srcdatalen + 4 - hdrlen, desfire_get_key_block_length(ctx->keyType)); + } else if (ctx->commMode == DCMEncrypted || ctx->commMode == DCMEncryptedWithPadding) { + uint8_t paddinglen = (ctx->commMode == DCMEncryptedWithPadding) ? 1 : 0; + rlen = padded_data_length(srcdatalen + 4 + paddinglen - hdrlen, desfire_get_key_block_length(ctx->keyType)); data[0] = cmd; + + // crc memcpy(&data[1], srcdata, srcdatalen); desfire_crc32_append(data, srcdatalen + 1); + + // add padding + if (paddinglen > 0) + data[srcdatalen + 1 + 4] = 0x80; memcpy(dstdata, srcdata, hdrlen); DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, &data[1 + hdrlen], rlen, &dstdata[hdrlen], true); *dstdatalen = hdrlen + rlen; + ctx->commMode = DCMEncrypted; } else if (ctx->commMode == DCMEncryptedPlain) { if (srcdatalen <= hdrlen) return; @@ -374,6 +382,7 @@ static void DesfireSecureChannelDecodeD40(DesfireContext *ctx, uint8_t *srcdata, break; } case DCMEncrypted: + case DCMEncryptedWithPadding: if (srcdatalen < desfire_get_key_block_length(ctx->keyType)) { memcpy(dstdata, srcdata, srcdatalen); *dstdatalen = srcdatalen; From c125c10e312f0600b69efa059a1782ae43b091cd Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 4 Aug 2021 22:36:38 +0300 Subject: [PATCH 2/5] d40 + padding --- client/src/mifare/desfiresecurechan.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/client/src/mifare/desfiresecurechan.c b/client/src/mifare/desfiresecurechan.c index 383e8fdf9..4b042a146 100644 --- a/client/src/mifare/desfiresecurechan.c +++ b/client/src/mifare/desfiresecurechan.c @@ -211,13 +211,18 @@ static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint memcpy(&dstdata[srcdatalen], mac, DesfireGetMACLength(ctx)); *dstdatalen = rlen; } - } else if (ctx->commMode == DCMEncrypted) { + } else if (ctx->commMode == DCMEncrypted || ctx->commMode == DCMEncryptedWithPadding) { if (srcdatalen <= hdrlen) return; - - rlen = padded_data_length(srcdatalen + 2 - hdrlen, desfire_get_key_block_length(ctx->keyType)) + hdrlen; // 2 - crc16 + + uint8_t paddinglen = (ctx->commMode == DCMEncryptedWithPadding) ? 1 : 0; + rlen = padded_data_length(srcdatalen + 2 + paddinglen - hdrlen, desfire_get_key_block_length(ctx->keyType)) + hdrlen; // 2 - crc16 memcpy(data, &srcdata[hdrlen], srcdatalen - hdrlen); iso14443a_crc_append(data, srcdatalen - hdrlen); + + // add padding + if (paddinglen > 0) + data[srcdatalen + 1 + 2] = 0x80; memcpy(dstdata, srcdata, hdrlen); //PrintAndLogEx(INFO, "src[%d]: %s", srcdatalen - hdrlen + 2, sprint_hex(data, srcdatalen - hdrlen + 2)); @@ -306,7 +311,7 @@ static void DesfireSecureChannelEncodeEV2(DesfireContext *ctx, uint8_t cmd, uint memcpy(&dstdata[srcdatalen], cmac, DesfireGetMACLength(ctx)); *dstdatalen = srcdatalen + DesfireGetMACLength(ctx); - } else if (ctx->commMode == DCMEncrypted) { + } else if (ctx->commMode == DCMEncrypted || ctx->commMode == DCMEncryptedWithPadding) { memcpy(dstdata, srcdata, hdrlen); if (srcdatalen > hdrlen) { From 7046675403ff0c7fab152160cf6002c753d512c7 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 4 Aug 2021 23:13:57 +0300 Subject: [PATCH 3/5] d40 fix --- client/src/mifare/desfiresecurechan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/mifare/desfiresecurechan.c b/client/src/mifare/desfiresecurechan.c index 4b042a146..14bc3ab18 100644 --- a/client/src/mifare/desfiresecurechan.c +++ b/client/src/mifare/desfiresecurechan.c @@ -222,7 +222,7 @@ static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint // add padding if (paddinglen > 0) - data[srcdatalen + 1 + 2] = 0x80; + data[srcdatalen - hdrlen + 2] = 0x80; memcpy(dstdata, srcdata, hdrlen); //PrintAndLogEx(INFO, "src[%d]: %s", srcdatalen - hdrlen + 2, sprint_hex(data, srcdatalen - hdrlen + 2)); From 2432908e08dbccbdc478072832210cc691f7af68 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 4 Aug 2021 23:39:25 +0300 Subject: [PATCH 4/5] ev2 enc with padding - ok --- client/src/mifare/desfiresecurechan.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/client/src/mifare/desfiresecurechan.c b/client/src/mifare/desfiresecurechan.c index 14bc3ab18..992006c9b 100644 --- a/client/src/mifare/desfiresecurechan.c +++ b/client/src/mifare/desfiresecurechan.c @@ -329,6 +329,7 @@ static void DesfireSecureChannelEncodeEV2(DesfireContext *ctx, uint8_t cmd, uint memcpy(&dstdata[hdrlen + rlen], cmac, DesfireGetMACLength(ctx)); *dstdatalen = hdrlen + rlen + DesfireGetMACLength(ctx); + ctx->commMode = DCMEncrypted; } else if (ctx->commMode == DCMEncryptedPlain) { if (srcdatalen <= hdrlen) return; @@ -442,7 +443,7 @@ static void DesfireSecureChannelDecodeEV1(DesfireContext *ctx, uint8_t *srcdata, if (GetAPDULogging()) PrintAndLogEx(INFO, "Received MAC OK"); } - } else if (ctx->commMode == DCMEncrypted) { + } else if (ctx->commMode == DCMEncrypted || ctx->commMode == DCMEncryptedWithPadding) { if (srcdatalen < desfire_get_key_block_length(ctx->keyType)) { memcpy(dstdata, srcdata, srcdatalen); *dstdatalen = srcdatalen; @@ -473,8 +474,6 @@ static void DesfireSecureChannelDecodeEV2(DesfireContext *ctx, uint8_t *srcdata, *dstdatalen = srcdatalen; uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; - // if comm mode = plain --> response with MAC - // if request is not zero length --> response MAC if (ctx->commMode == DCMMACed) { if (srcdatalen < DesfireGetMACLength(ctx)) { memcpy(dstdata, srcdata, srcdatalen); @@ -494,7 +493,7 @@ static void DesfireSecureChannelDecodeEV2(DesfireContext *ctx, uint8_t *srcdata, if (GetAPDULogging()) PrintAndLogEx(INFO, "Received MAC OK"); } - } else if (ctx->commMode == DCMEncrypted) { + } else if (ctx->commMode == DCMEncrypted || ctx->commMode == DCMEncryptedWithPadding) { if (srcdatalen < DesfireGetMACLength(ctx)) { memcpy(dstdata, srcdata, srcdatalen); *dstdatalen = srcdatalen; From 91b1026f6d6736c5f59edad57c49f3907634d1bb Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 4 Aug 2021 23:51:09 +0300 Subject: [PATCH 5/5] remove comments --- client/src/mifare/desfirecore.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 10c4dff42..abce6e7e9 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -2544,22 +2544,9 @@ int DesfireSetConfiguration(DesfireContext *dctx, uint8_t paramid, uint8_t *para memcpy(&data[1], param, paramlen); size_t datalen = 1 + paramlen; - - /*// add crc - if (dctx->secureChannel == DACd40) { - iso14443a_crc_append(&data[1], datalen - 1); - datalen += 2; - } else { - desfire_crc32_append(cdata, datalen + 1); - datalen += 4; - } -*/ // dynamic length - if (paramid == 0x02 && dctx->commMode == DCMEncrypted) { + if (paramid == 0x02 && dctx->commMode == DCMEncrypted) dctx->commMode = DCMEncryptedWithPadding; - //data[datalen] = 0x80; - //datalen++; - } // send command uint8_t resp[257] = {0};