From f827b85cdae793c15b8671afb1fce119c6a1c0f5 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 24 Dec 2021 11:46:16 +0200 Subject: [PATCH 1/5] low level dynamic memory --- client/src/mifare/desfirecore.c | 30 ++++++++++++++++++++++-------- client/src/mifare/desfirecore.h | 1 + 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index a95bd8d94..fa50753b5 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -530,7 +530,9 @@ static int DesfireExchangeNative(bool activate_field, DesfireContext_t *ctx, uin if (respcode) *respcode = 0xff; - uint8_t buf[255 * 5] = {0x00}; + uint8_t *buf = calloc(DESFIRE_BUFFER_SIZE, 1); + if (buf == NULL) + return PM3_EMALLOC; uint32_t buflen = 0; uint32_t pos = 0; uint32_t i = 1; @@ -560,10 +562,11 @@ static int DesfireExchangeNative(bool activate_field, DesfireContext_t *ctx, uin cdata[sendindx] = MFDES_ADDITIONAL_FRAME; } - res = DESFIRESendRaw(activate_field, &cdata[sendindx], sendlen, buf, sizeof(buf), &buflen, &rcode); + res = DESFIRESendRaw(activate_field, &cdata[sendindx], sendlen, buf, DESFIRE_BUFFER_SIZE, &buflen, &rcode); if (res != PM3_SUCCESS) { uint16_t ssw = DESFIRE_GET_ISO_STATUS(rcode); PrintAndLogEx(DEBUG, "error DESFIRESendRaw %s", DesfireGetErrorString(res, &ssw)); + free(buf); return res; } @@ -594,13 +597,14 @@ static int DesfireExchangeNative(bool activate_field, DesfireContext_t *ctx, uin if (resplen) *resplen = pos; } + free(buf); return PM3_SUCCESS; } while (rcode == MFDES_ADDITIONAL_FRAME) { cdata[0] = MFDES_ADDITIONAL_FRAME; //0xAF - res = DESFIRESendRaw(false, cdata, 1, buf, sizeof(buf), &buflen, &rcode); + res = DESFIRESendRaw(false, cdata, 1, buf, DESFIRE_BUFFER_SIZE, &buflen, &rcode); if (res != PM3_SUCCESS) { uint16_t ssw = DESFIRE_GET_ISO_STATUS(rcode); PrintAndLogEx(DEBUG, "error DESFIRESendRaw %s", DesfireGetErrorString(res, &ssw)); @@ -627,6 +631,7 @@ static int DesfireExchangeNative(bool activate_field, DesfireContext_t *ctx, uin if (resplen) *resplen = (splitbysize) ? i : pos; + free(buf); return PM3_SUCCESS; } @@ -637,7 +642,9 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx, *respcode = 0xff; uint16_t sw = 0; - uint8_t buf[255 * 5] = {0x00}; + uint8_t *buf = calloc(DESFIRE_BUFFER_SIZE, 1); + if (buf == NULL) + return PM3_EMALLOC; uint32_t buflen = 0; uint32_t pos = 0; uint32_t i = 1; @@ -663,9 +670,10 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx, if (sentdatalen > 0) apdu.INS = MFDES_ADDITIONAL_FRAME; - res = DESFIRESendApdu(activate_field, apdu, buf, sizeof(buf), &buflen, &sw); + res = DESFIRESendApdu(activate_field, apdu, buf, DESFIRE_BUFFER_SIZE, &buflen, &sw); if (res != PM3_SUCCESS) { PrintAndLogEx(DEBUG, "error DESFIRESendApdu %s", DesfireGetErrorString(res, &sw)); + free(buf); return res; } @@ -696,6 +704,7 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx, if (resplen) *resplen = pos; } + free(buf); return PM3_SUCCESS; } @@ -707,9 +716,10 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx, apdu.P2 = 0; apdu.data = NULL; - res = DESFIRESendApdu(false, apdu, buf, sizeof(buf), &buflen, &sw); + res = DESFIRESendApdu(false, apdu, buf, DESFIRE_BUFFER_SIZE, &buflen, &sw); if (res != PM3_SUCCESS) { PrintAndLogEx(DEBUG, "error DESFIRESendApdu %s", DesfireGetErrorString(res, &sw)); + free(buf); return res; } @@ -733,17 +743,21 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx, if (resplen) *resplen = (splitbysize) ? i : pos; + free(buf); return PM3_SUCCESS; } static int DesfireExchangeISO(bool activate_field, DesfireContext_t *ctx, sAPDU_t apdu, uint16_t le, uint8_t *resp, size_t *resplen, uint16_t *sw) { - uint8_t data[1050] = {0}; + uint8_t *data = calloc(DESFIRE_BUFFER_SIZE, 1); + if (data == NULL) + return PM3_EMALLOC; uint32_t datalen = 0; - int res = DESFIRESendApduEx(activate_field, apdu, le, data, sizeof(data), &datalen, sw); + int res = DESFIRESendApduEx(activate_field, apdu, le, data, DESFIRE_BUFFER_SIZE, &datalen, sw); if (res == PM3_SUCCESS) DesfireSecureChannelDecode(ctx, data, datalen, 0, resp, resplen); + free(data); return res; } diff --git a/client/src/mifare/desfirecore.h b/client/src/mifare/desfirecore.h index 5cdcb3c26..f66c83981 100644 --- a/client/src/mifare/desfirecore.h +++ b/client/src/mifare/desfirecore.h @@ -18,6 +18,7 @@ #include "mifare/desfirecrypto.h" #define DESFIRE_TX_FRAME_MAX_LEN 54 +#define DESFIRE_BUFFER_SIZE 65538 enum DesfireISOSelectControlEnum { ISSMFDFEF = 0x00, From 02316e5fc36c619bbc70c82f78d39e043faea06e Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 24 Dec 2021 11:51:23 +0200 Subject: [PATCH 2/5] DesfireExchangeEx dyn memory --- client/src/mifare/desfirecore.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index fa50753b5..844b92223 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -799,7 +799,9 @@ int DesfireExchangeEx(bool activate_field, DesfireContext_t *ctx, uint8_t cmd, u if (!PrintChannelModeWarning(cmd, ctx->secureChannel, ctx->cmdSet, ctx->commMode)) DesfirePrintContext(ctx); - uint8_t databuf[250 * 5] = {0}; + uint8_t *databuf = calloc(DESFIRE_BUFFER_SIZE, 1); + if (databuf == NULL) + return PM3_EMALLOC; size_t databuflen = 0; switch (ctx->cmdSet) { @@ -828,10 +830,12 @@ int DesfireExchangeEx(bool activate_field, DesfireContext_t *ctx, uint8_t cmd, u } break; case DCCISO: + free(databuf); return PM3_EAPDU_FAIL; break; } + free(databuf); return res; } From 74fc0a236cd53248e806a98ac6b349f507fc3ba5 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 24 Dec 2021 12:27:01 +0200 Subject: [PATCH 3/5] dynamic mem encoders/decoders --- client/src/mifare/desfiresecurechan.c | 54 +++++++++++++++++++++------ 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/client/src/mifare/desfiresecurechan.c b/client/src/mifare/desfiresecurechan.c index 307e75158..d7c4b1600 100644 --- a/client/src/mifare/desfiresecurechan.c +++ b/client/src/mifare/desfiresecurechan.c @@ -267,7 +267,9 @@ static bool DesfireISOChannelValidCmd(uint8_t cmd) { } static void DesfireSecureChannelEncodeD40(DesfireContext_t *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) { - uint8_t data[1024] = {0}; + uint8_t *data = calloc(DESFIRE_BUFFER_SIZE, 1); + if (data == NULL) + return; size_t rlen = 0; memcpy(dstdata, srcdata, srcdatalen); @@ -278,8 +280,10 @@ static void DesfireSecureChannelEncodeD40(DesfireContext_t *ctx, uint8_t cmd, ui hdrlen = srcdatalen; if (ctx->commMode == DCMMACed || (ctx->commMode == DCMEncrypted && srcdatalen <= hdrlen)) { - if (srcdatalen == 0) + if (srcdatalen == 0) { + free(data); return; + } rlen = srcdatalen + DesfireGetMACLength(ctx); @@ -294,8 +298,10 @@ static void DesfireSecureChannelEncodeD40(DesfireContext_t *ctx, uint8_t cmd, ui *dstdatalen = rlen; } } else if (ctx->commMode == DCMEncrypted || ctx->commMode == DCMEncryptedWithPadding) { - if (srcdatalen <= hdrlen) + if (srcdatalen <= hdrlen) { + free(data); return; + } 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 @@ -312,8 +318,10 @@ static void DesfireSecureChannelEncodeD40(DesfireContext_t *ctx, uint8_t cmd, ui *dstdatalen = rlen; } else if (ctx->commMode == DCMEncryptedPlain) { - if (srcdatalen == 0 || srcdatalen <= hdrlen) + if (srcdatalen == 0 || srcdatalen <= hdrlen) { + free(data); return; + } rlen = padded_data_length(srcdatalen - hdrlen, desfire_get_key_block_length(ctx->keyType)) + hdrlen; memcpy(data, srcdata, srcdatalen); @@ -322,10 +330,13 @@ static void DesfireSecureChannelEncodeD40(DesfireContext_t *ctx, uint8_t cmd, ui *dstdatalen = rlen; ctx->commMode = DCMEncrypted; } + free(data); } static void DesfireSecureChannelEncodeEV1(DesfireContext_t *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) { - uint8_t data[1024] = {0}; + uint8_t *data = calloc(DESFIRE_BUFFER_SIZE, 1); + if (data == NULL) + return; size_t rlen = 0; memcpy(dstdata, srcdata, srcdatalen); @@ -368,8 +379,10 @@ static void DesfireSecureChannelEncodeEV1(DesfireContext_t *ctx, uint8_t cmd, ui *dstdatalen = hdrlen + rlen; ctx->commMode = DCMEncrypted; } else if (ctx->commMode == DCMEncryptedPlain) { - if (srcdatalen <= hdrlen) + if (srcdatalen <= hdrlen) { + free(data); return; + } memcpy(dstdata, srcdata, hdrlen); memcpy(data, &srcdata[hdrlen], srcdatalen); @@ -378,10 +391,13 @@ static void DesfireSecureChannelEncodeEV1(DesfireContext_t *ctx, uint8_t cmd, ui *dstdatalen = hdrlen + rlen; ctx->commMode = DCMEncrypted; } + free(data); } static void DesfireSecureChannelEncodeEV2(DesfireContext_t *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) { - uint8_t data[1050] = {0}; + uint8_t *data = calloc(DESFIRE_BUFFER_SIZE, 1); + if (data == NULL) + return; size_t rlen = 0; memcpy(dstdata, srcdata, srcdatalen); @@ -417,10 +433,13 @@ static void DesfireSecureChannelEncodeEV2(DesfireContext_t *ctx, uint8_t cmd, ui *dstdatalen = hdrlen + rlen + DesfireGetMACLength(ctx); ctx->commMode = DCMEncrypted; } + free(data); } static void DesfireSecureChannelEncodeLRP(DesfireContext_t *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) { - uint8_t data[1050] = {0}; + uint8_t *data = calloc(DESFIRE_BUFFER_SIZE, 1); + if (data == NULL) + return; size_t rlen = 0; memcpy(dstdata, srcdata, srcdatalen); @@ -455,6 +474,7 @@ static void DesfireSecureChannelEncodeLRP(DesfireContext_t *ctx, uint8_t cmd, ui *dstdatalen = hdrlen + rlen + DesfireGetMACLength(ctx); ctx->commMode = DCMEncrypted; } + free(data); } void DesfireSecureChannelEncode(DesfireContext_t *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) { @@ -482,7 +502,9 @@ void DesfireSecureChannelEncode(DesfireContext_t *ctx, uint8_t cmd, uint8_t *src } static void DesfireSecureChannelDecodeD40(DesfireContext_t *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t respcode, uint8_t *dstdata, size_t *dstdatalen) { - uint8_t data[1024] = {0}; + uint8_t *data = calloc(DESFIRE_BUFFER_SIZE, 1); + if (data == NULL) + return; size_t rlen = 0; memcpy(dstdata, srcdata, srcdatalen); @@ -514,6 +536,7 @@ static void DesfireSecureChannelDecodeD40(DesfireContext_t *ctx, uint8_t *srcdat if (srcdatalen < desfire_get_key_block_length(ctx->keyType)) { memcpy(dstdata, srcdata, srcdatalen); *dstdatalen = srcdatalen; + free(data); return; } @@ -535,10 +558,13 @@ static void DesfireSecureChannelDecodeD40(DesfireContext_t *ctx, uint8_t *srcdat *dstdatalen = srcdatalen; break; } + free(data); } static void DesfireSecureChannelDecodeEV1(DesfireContext_t *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t respcode, uint8_t *dstdata, size_t *dstdatalen) { - uint8_t data[1024] = {0}; + uint8_t *data = calloc(DESFIRE_BUFFER_SIZE, 1); + if (data == NULL) + return; // if comm mode = plain --> response with MAC // if request is not zero length --> response MAC @@ -546,6 +572,7 @@ static void DesfireSecureChannelDecodeEV1(DesfireContext_t *ctx, uint8_t *srcdat if (srcdatalen < DesfireGetMACLength(ctx)) { memcpy(dstdata, srcdata, srcdatalen); *dstdatalen = srcdatalen; + free(data); return; } @@ -569,6 +596,7 @@ static void DesfireSecureChannelDecodeEV1(DesfireContext_t *ctx, uint8_t *srcdat if (srcdatalen < desfire_get_key_block_length(ctx->keyType)) { memcpy(dstdata, srcdata, srcdatalen); *dstdatalen = srcdatalen; + free(data); return; } @@ -587,6 +615,7 @@ static void DesfireSecureChannelDecodeEV1(DesfireContext_t *ctx, uint8_t *srcdat memcpy(dstdata, srcdata, srcdatalen); *dstdatalen = srcdatalen; } + free(data); } static void DesfireSecureChannelDecodeEV2(DesfireContext_t *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t respcode, uint8_t *dstdata, size_t *dstdatalen) { @@ -707,7 +736,9 @@ static void DesfireSecureChannelDecodeLRP(DesfireContext_t *ctx, uint8_t *srcdat static void DesfireISODecode(DesfireContext_t *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) { memcpy(dstdata, srcdata, srcdatalen); *dstdatalen = srcdatalen; - uint8_t data[1050] = {0}; + uint8_t *data = calloc(DESFIRE_BUFFER_SIZE, 1); + if (data == NULL) + return; if (srcdatalen < DesfireGetMACLength(ctx)) return; @@ -729,6 +760,7 @@ static void DesfireISODecode(DesfireContext_t *ctx, uint8_t *srcdata, size_t src PrintAndLogEx(INFO, "Received MAC OK"); } } + free(data); } void DesfireSecureChannelDecode(DesfireContext_t *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t respcode, uint8_t *dstdata, size_t *dstdatalen) { From 0d45642383cab6634744bdaffc30caca478cc673 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 24 Dec 2021 12:30:59 +0200 Subject: [PATCH 4/5] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 446aec9bc..db9860d1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fixed `hf mfdes` - works with dynamic apdu and encode/decode buffers (@merlokk) - Added luascript `hf_ntag_bruteforce.lua` - ntag password bruteforce with the option to do NFC Tools MD5 versions of passwords (@keldnorman) - Added option `--crc-ht` to `lf cmdread` to compute and add CRC-8/HITAG (@doegox) - Added option `-k` to `lf cmdread` to keep field on (@doegox) From b3f2a18ec4d6e745e836ffd218f314ad4b53b847 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 24 Dec 2021 19:14:48 +0200 Subject: [PATCH 5/5] top level read command dynamic memory allocation --- client/src/cmdhfmfdes.c | 13 ++++++++++++- client/src/mifare/desfirecore.c | 19 +++++++++++++++---- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 9ba244a3e..c8b165dda 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -4615,7 +4615,12 @@ static int DesfileReadFileAndPrint(DesfireContext_t *dctx, uint8_t fnum, int fil PrintAndLogEx(INFO, "------------------------------- " _CYAN_("File %02x data") " -------------------------------", fnum); - uint8_t resp[2048] = {0}; + uint8_t *resp = calloc(DESFIRE_BUFFER_SIZE, 1); + if (resp == NULL) { + PrintAndLogEx(ERR, "Desfire calloc " _RED_("error")); + DropField(); + return PM3_EMALLOC; + } size_t resplen = 0; if (filetype == RFTData) { @@ -4623,6 +4628,7 @@ static int DesfileReadFileAndPrint(DesfireContext_t *dctx, uint8_t fnum, int fil if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "Desfire ReadFile command " _RED_("error") ". Result: %d", res); DropField(); + free(resp); return PM3_ESOFT; } @@ -4640,6 +4646,7 @@ static int DesfileReadFileAndPrint(DesfireContext_t *dctx, uint8_t fnum, int fil if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "Desfire GetValue operation " _RED_("error") ". Result: %d", res); DropField(); + free(resp); return PM3_ESOFT; } PrintAndLogEx(SUCCESS, "Read file 0x%02x value: %d (0x%08x)", fnum, value, value); @@ -4652,6 +4659,7 @@ static int DesfileReadFileAndPrint(DesfireContext_t *dctx, uint8_t fnum, int fil if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "Desfire ReadRecords (len=1) command " _RED_("error") ". Result: %d", res); DropField(); + free(resp); return PM3_ESOFT; } reclen = resplen; @@ -4666,6 +4674,7 @@ static int DesfileReadFileAndPrint(DesfireContext_t *dctx, uint8_t fnum, int fil if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "Desfire ReadRecords command " _RED_("error") ". Result: %d", res); DropField(); + free(resp); return PM3_ESOFT; } } @@ -4690,6 +4699,7 @@ static int DesfileReadFileAndPrint(DesfireContext_t *dctx, uint8_t fnum, int fil if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "Desfire ReadFile command " _RED_("error") ". Result: %d", res); DropField(); + free(resp); return PM3_ESOFT; } @@ -4717,6 +4727,7 @@ static int DesfileReadFileAndPrint(DesfireContext_t *dctx, uint8_t fnum, int fil } } + free(resp); return PM3_SUCCESS; } diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 844b92223..8c67242fe 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -1861,20 +1861,31 @@ static int DesfireCommandEx(DesfireContext_t *dctx, uint8_t cmd, uint8_t *data, *resplen = 0; uint8_t respcode = 0xff; - uint8_t xresp[2050] = {0}; + uint8_t *xresp = calloc(DESFIRE_BUFFER_SIZE, 1); + if (xresp == NULL) + return PM3_EMALLOC; + size_t xresplen = 0; int res = DesfireExchangeEx(false, dctx, cmd, data, datalen, &respcode, xresp, &xresplen, true, splitbysize); - if (res != PM3_SUCCESS) + if (res != PM3_SUCCESS) { + free(xresp); return res; - if (respcode != MFDES_S_OPERATION_OK) + } + if (respcode != MFDES_S_OPERATION_OK) { + free(xresp); return PM3_EAPDU_FAIL; - if (checklength >= 0 && xresplen != checklength) + } + if (checklength >= 0 && xresplen != checklength) { + free(xresp); return PM3_EAPDU_FAIL; + } if (resplen) *resplen = xresplen; if (resp) memcpy(resp, xresp, (splitbysize == 0) ? xresplen : xresplen * splitbysize); + + free(xresp); return PM3_SUCCESS; }