diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 238e7719c..0dd003987 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -2316,6 +2316,7 @@ static int CmdHF14ADesSelectApp(const char *Cmd) { bool idsoidpresent = (res == 1); if (res == 2) { PrintAndLogEx(ERR, "ISO ID for EF or DF must have 2 bytes length"); + CLIParserFree(ctx); return PM3_EINVARG; } @@ -2843,7 +2844,7 @@ static int CmdHF14ADesCreateApp(const char *Cmd) { DesfireContext dctx; int securechann = defaultSecureChannel; uint32_t appid = 0x000000; - int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 12, &securechann, DCMPlain, &appid); + int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 12, &securechann, DCMMACed, &appid); if (res) { CLIParserFree(ctx); return res; @@ -3007,7 +3008,7 @@ static int CmdHF14ADesDeleteApp(const char *Cmd) { DesfireContext dctx; int securechann = defaultSecureChannel; uint32_t appid = 0x000000; - int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMPlain, &appid); + int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid); if (res) { CLIParserFree(ctx); return res; @@ -3342,7 +3343,7 @@ static int CmdHF14ADesGetKeyVersions(const char *Cmd) { DesfireContext dctx; int securechann = defaultSecureChannel; uint32_t appid = 0x000000; - int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMPlain, &appid); // DCMMACed + int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid); if (res) { CLIParserFree(ctx); return res; @@ -3804,7 +3805,7 @@ static int CmdHF14ADesGetFileSettings(const char *Cmd) { DesfireContext dctx; int securechann = defaultSecureChannel; uint32_t appid = 0x000000; - int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMPlain, &appid); + int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid); if (res) { CLIParserFree(ctx); return res; @@ -4137,7 +4138,7 @@ static int CmdHF14ADesCreateFile(const char *Cmd) { DesfireContext dctx; int securechann = defaultSecureChannel; uint32_t appid = 0x000000; - int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMPlain, &appid); + int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid); if (res) { CLIParserFree(ctx); return res; @@ -4278,7 +4279,7 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) { DesfireContext dctx; int securechann = defaultSecureChannel; uint32_t appid = 0x000000; - int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMPlain, &appid); + int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid); if (res) { CLIParserFree(ctx); return res; @@ -4411,7 +4412,7 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) { DesfireContext dctx; int securechann = defaultSecureChannel; uint32_t appid = 0x000000; - int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMPlain, &appid); + int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid); if (res) { CLIParserFree(ctx); return res; @@ -4632,7 +4633,7 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) { DesfireContext dctx; int securechann = defaultSecureChannel; uint32_t appid = 0x000000; - int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMPlain, &appid); + int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid); if (res) { CLIParserFree(ctx); return res; @@ -4709,7 +4710,7 @@ static int CmdHF14ADesValueOperations(const char *Cmd) { DesfireContext dctx; int securechann = defaultSecureChannel; uint32_t appid = 0x000000; - int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMPlain, &appid); + int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid); if (res) { CLIParserFree(ctx); return res; @@ -4869,7 +4870,7 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) { DesfireContext dctx; int securechann = defaultSecureChannel; uint32_t appid = 0x000000; - int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMPlain, &appid); + int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid); if (res) { CLIParserFree(ctx); return res; @@ -4921,7 +4922,7 @@ static int DesfileReadFileAndPrint(DesfireContext *dctx, uint8_t fnum, int filet FileSettingsS fsettings; DesfireCommunicationMode commMode = dctx->commMode; - DesfireSetCommMode(dctx, DCMPlain); + DesfireSetCommMode(dctx, DCMMACed); res = DesfireGetFileSettingsStruct(dctx, fnum, &fsettings); DesfireSetCommMode(dctx, commMode); @@ -5105,7 +5106,7 @@ static int CmdHF14ADesReadData(const char *Cmd) { DesfireContext dctx; int securechann = defaultSecureChannel; uint32_t appid = 0x000000; - int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMPlain, &appid); + int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid); if (res) { CLIParserFree(ctx); return res; @@ -5268,7 +5269,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) { FileSettingsS fsettings; DesfireCommunicationMode commMode = dctx.commMode; - DesfireSetCommMode(&dctx, DCMPlain); + DesfireSetCommMode(&dctx, DCMMACed); res = DesfireGetFileSettingsStruct(&dctx, fnum, &fsettings); DesfireSetCommMode(&dctx, commMode); @@ -5431,7 +5432,7 @@ static int CmdHF14ADesLsFiles(const char *Cmd) { DesfireContext dctx; int securechann = defaultSecureChannel; uint32_t appid = 0x000000; - int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMPlain, &appid); + int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMMACed, &appid); if (res) { CLIParserFree(ctx); return res; @@ -5503,7 +5504,7 @@ static int CmdHF14ADesLsApp(const char *Cmd) { DesfireContext dctx; int securechann = defaultSecureChannel; - int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, &securechann, DCMPlain, NULL); + int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, &securechann, (noauth) ? DCMPlain : DCMMACed, NULL); if (res) { CLIParserFree(ctx); return res; @@ -5566,7 +5567,7 @@ static int CmdHF14ADesDump(const char *Cmd) { DesfireContext dctx; int securechann = defaultSecureChannel; uint32_t appid = 0x000000; - int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, DCMPlain, &appid); + int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, (noauth) ? DCMPlain : DCMMACed, &appid); if (res) { CLIParserFree(ctx); return res; diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index b75ec45bd..fda847a6d 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -1822,8 +1822,7 @@ int DesfireFillFileList(DesfireContext *dctx, FileListS FileList, size_t *filesc isoindx++; } } - if (isoindx > 0) - isoindx--; + if (isoindx * 2 != buflen) PrintAndLogEx(WARNING, "Wrong ISO ID list length. must be %zu but %zu", buflen, isoindx * 2); } else { diff --git a/client/src/mifare/desfiresecurechan.c b/client/src/mifare/desfiresecurechan.c index 475772ad8..b33287a00 100644 --- a/client/src/mifare/desfiresecurechan.c +++ b/client/src/mifare/desfiresecurechan.c @@ -42,26 +42,22 @@ static bool CommandCanUseAnyChannel(uint8_t cmd) { static const AllowedChannelModesS AllowedChannelModes[] = { {MFDES_SELECT_APPLICATION, DACd40, DCCNative, DCMPlain}, - {MFDES_CREATE_APPLICATION, DACd40, DCCNative, DCMPlain}, - {MFDES_DELETE_APPLICATION, DACd40, DCCNative, DCMPlain}, - {MFDES_GET_APPLICATION_IDS, DACd40, DCCNative, DCMPlain}, - {MFDES_GET_DF_NAMES, DACd40, DCCNative, DCMPlain}, - {MFDES_GET_KEY_SETTINGS, DACd40, DCCNative, DCMPlain}, - {MFDES_GET_KEY_VERSION, DACd40, DCCNative, DCMPlain}, - {MFDES_GET_FREE_MEMORY, DACd40, DCCNative, DCMPlain}, - {MFDES_CREATE_STD_DATA_FILE, DACd40, DCCNative, DCMPlain}, - {MFDES_CREATE_BACKUP_DATA_FILE, DACd40, DCCNative, DCMPlain}, - {MFDES_CREATE_VALUE_FILE, DACd40, DCCNative, DCMPlain}, - {MFDES_CREATE_LINEAR_RECORD_FILE, DACd40, DCCNative, DCMPlain}, - {MFDES_CREATE_CYCLIC_RECORD_FILE, DACd40, DCCNative, DCMPlain}, - {MFDES_GET_VALUE, DACd40, DCCNative, DCMPlain}, - {MFDES_CREDIT, DACd40, DCCNative, DCMPlain}, - {MFDES_LIMITED_CREDIT, DACd40, DCCNative, DCMPlain}, - {MFDES_DEBIT, DACd40, DCCNative, DCMPlain}, - {MFDES_COMMIT_TRANSACTION, DACd40, DCCNative, DCMPlain}, - {MFDES_CLEAR_RECORD_FILE, DACd40, DCCNative, DCMPlain}, - {MFDES_GET_FILE_SETTINGS, DACd40, DCCNative, DCMPlain}, - + + {MFDES_CREATE_APPLICATION, DACd40, DCCNative, DCMMACed}, + {MFDES_DELETE_APPLICATION, DACd40, DCCNative, DCMMACed}, + {MFDES_GET_APPLICATION_IDS, DACd40, DCCNative, DCMMACed}, + {MFDES_GET_DF_NAMES, DACd40, DCCNative, DCMMACed}, + {MFDES_GET_KEY_SETTINGS, DACd40, DCCNative, DCMMACed}, + {MFDES_GET_KEY_VERSION, DACd40, DCCNative, DCMMACed}, + {MFDES_GET_FREE_MEMORY, DACd40, DCCNative, DCMMACed}, + {MFDES_CREATE_STD_DATA_FILE, DACd40, DCCNative, DCMMACed}, + {MFDES_CREATE_BACKUP_DATA_FILE, DACd40, DCCNative, DCMMACed}, + {MFDES_CREATE_VALUE_FILE, DACd40, DCCNative, DCMMACed}, + {MFDES_CREATE_LINEAR_RECORD_FILE, DACd40, DCCNative, DCMMACed}, + {MFDES_CREATE_CYCLIC_RECORD_FILE, DACd40, DCCNative, DCMMACed}, + {MFDES_COMMIT_TRANSACTION, DACd40, DCCNative, DCMMACed}, + {MFDES_CLEAR_RECORD_FILE, DACd40, DCCNative, DCMMACed}, + {MFDES_GET_FILE_SETTINGS, DACd40, DCCNative, DCMMACed}, {MFDES_GET_VALUE, DACd40, DCCNative, DCMMACed}, {MFDES_CREDIT, DACd40, DCCNative, DCMMACed}, {MFDES_DEBIT, DACd40, DCCNative, DCMMACed}, @@ -85,10 +81,10 @@ static const AllowedChannelModesS AllowedChannelModes[] = { {MFDES_CHANGE_KEY, DACd40, DCCNative, DCMEncryptedPlain}, {MFDES_CHANGE_KEY_EV2, DACd40, DCCNative, DCMEncryptedPlain}, - {MFDES_GET_KEY_VERSION, DACEV1, DCCNative, DCMPlain}, - {MFDES_GET_FREE_MEMORY, DACEV1, DCCNative, DCMPlain}, {MFDES_SELECT_APPLICATION, DACEV1, DCCNative, DCMPlain}, + {MFDES_GET_KEY_VERSION, DACEV1, DCCNative, DCMMACed}, + {MFDES_GET_FREE_MEMORY, DACEV1, DCCNative, DCMMACed}, {MFDES_CREATE_APPLICATION, DACEV1, DCCNative, DCMMACed}, {MFDES_DELETE_APPLICATION, DACEV1, DCCNative, DCMMACed}, {MFDES_GET_APPLICATION_IDS, DACEV1, DCCNative, DCMMACed}, @@ -147,6 +143,49 @@ static uint8_t DesfireGetCmdHeaderLen(uint8_t cmd) { return 0; } +static const uint8_t EV1D40TransmitMAC[] = { + MFDES_WRITE_DATA, + MFDES_CREDIT, + MFDES_LIMITED_CREDIT, + MFDES_DEBIT, + MFDES_WRITE_RECORD, + MFDES_UPDATE_RECORD, + MFDES_COMMIT_READER_ID, + MFDES_INIT_KEY_SETTINGS, + MFDES_ROLL_KEY_SETTINGS, + MFDES_FINALIZE_KEY_SETTINGS, +}; + +static bool DesfireEV1D40TransmitMAC(DesfireContext *ctx, uint8_t cmd) { + if (ctx->secureChannel != DACd40 && ctx->secureChannel != DACEV1) + return true; + + for (int i = 0; i < ARRAY_LENGTH(EV1D40TransmitMAC); i++) + if (EV1D40TransmitMAC[i] == cmd) + return true; + + return false; +} + +static const uint8_t D40ReceiveMAC[] = { + MFDES_READ_DATA, + MFDES_READ_DATA2, + MFDES_READ_RECORDS, + MFDES_READ_RECORDS2, + MFDES_GET_VALUE, +}; + +static bool DesfireEV1D40ReceiveMAC(DesfireContext *ctx, uint8_t cmd) { + if (ctx->secureChannel != DACd40) + return true; + + for (int i = 0; i < ARRAY_LENGTH(D40ReceiveMAC); i++) + if (D40ReceiveMAC[i] == cmd) + return true; + + return false; +} + static void DesfireSecureChannelEncodeD40(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; @@ -168,9 +207,10 @@ static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint uint8_t mac[32] = {0}; DesfireCryptoEncDecEx(ctx, DCOSessionKeyMac, data, srcmaclen, NULL, true, true, mac); - memcpy(dstdata, srcdata, srcdatalen); - memcpy(&dstdata[srcdatalen], mac, DesfireGetMACLength(ctx)); - *dstdatalen = rlen; + if (DesfireEV1D40TransmitMAC(ctx, cmd)) { + memcpy(&dstdata[srcdatalen], mac, DesfireGetMACLength(ctx)); + *dstdatalen = rlen; + } } else if (ctx->commMode == DCMEncrypted) { if (srcdatalen <= hdrlen) return; @@ -216,7 +256,7 @@ static void DesfireSecureChannelEncodeEV1(DesfireContext *ctx, uint8_t cmd, uint memcpy(dstdata, srcdata, srcdatalen); *dstdatalen = srcdatalen; - if (srcdatalen > hdrlen && ctx->commMode == DCMMACed) { + if (ctx->commMode == DCMMACed && DesfireEV1D40TransmitMAC(ctx, cmd)) { memcpy(&dstdata[srcdatalen], cmac, DesfireGetMACLength(ctx)); *dstdatalen = srcdatalen + DesfireGetMACLength(ctx); } @@ -252,30 +292,28 @@ static void DesfireSecureChannelEncodeEV2(DesfireContext *ctx, uint8_t cmd, uint uint8_t hdrlen = DesfireGetCmdHeaderLen(cmd); - if (ctx->commMode == DCMPlain || ctx->commMode == DCMMACed || (ctx->commMode == DCMEncrypted && srcdatalen <= hdrlen)) { + if (ctx->commMode == DCMMACed) { + uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; + DesfireEV2CalcCMAC(ctx, cmd, srcdata, srcdatalen, cmac); - if (ctx->commMode == DCMMACed || ctx->commMode == DCMEncrypted) { - uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; - DesfireEV2CalcCMAC(ctx, cmd, srcdata, srcdatalen, cmac); - - memcpy(&dstdata[srcdatalen], cmac, DesfireGetMACLength(ctx)); - *dstdatalen = srcdatalen + DesfireGetMACLength(ctx); - } + memcpy(&dstdata[srcdatalen], cmac, DesfireGetMACLength(ctx)); + *dstdatalen = srcdatalen + DesfireGetMACLength(ctx); } else if (ctx->commMode == DCMEncrypted) { - DesfireEV2FillIV(ctx, true, NULL); // fill IV to ctx + memcpy(dstdata, srcdata, hdrlen); - rlen = padded_data_length(srcdatalen + 1 - hdrlen, desfire_get_key_block_length(ctx->keyType)); - memcpy(data, &srcdata[hdrlen], srcdatalen - hdrlen); - data[hdrlen] = 0x80; // padding + if (srcdatalen > hdrlen) { + rlen = padded_data_length(srcdatalen + 1 - hdrlen, desfire_get_key_block_length(ctx->keyType)); + memcpy(data, &srcdata[hdrlen], srcdatalen - hdrlen); + data[srcdatalen - hdrlen] = 0x80; // padding - dstdata[0] = cmd; - memcpy(&dstdata[1], srcdata, hdrlen); - DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, data, rlen, &dstdata[1 + hdrlen], true); + DesfireEV2FillIV(ctx, true, NULL); // fill IV to ctx + DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, data, rlen, &dstdata[hdrlen], true); + } uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; - DesfireEV2CalcCMAC(ctx, cmd, &dstdata[1], hdrlen + rlen, cmac); + DesfireEV2CalcCMAC(ctx, cmd, dstdata, hdrlen + rlen, cmac); - memcpy(&dstdata[ + hdrlen + rlen], cmac, DesfireGetMACLength(ctx)); + memcpy(&dstdata[hdrlen + rlen], cmac, DesfireGetMACLength(ctx)); *dstdatalen = hdrlen + rlen + DesfireGetMACLength(ctx); } else if (ctx->commMode == DCMEncryptedPlain) { @@ -317,7 +355,7 @@ static void DesfireSecureChannelDecodeD40(DesfireContext *ctx, uint8_t *srcdata, switch (ctx->commMode) { case DCMMACed: { size_t maclen = DesfireGetMACLength(ctx); - if (srcdatalen > maclen) { + if (srcdatalen > maclen && DesfireEV1D40ReceiveMAC(ctx, ctx->lastCommand)) { uint8_t mac[16] = {0}; rlen = padded_data_length(srcdatalen - maclen, desfire_get_key_block_length(ctx->keyType)); memcpy(data, srcdata, srcdatalen - maclen); @@ -325,10 +363,12 @@ static void DesfireSecureChannelDecodeD40(DesfireContext *ctx, uint8_t *srcdata, if (memcmp(mac, &srcdata[srcdatalen - maclen], maclen) == 0) { *dstdatalen = srcdatalen - maclen; + if (GetAPDULogging()) + PrintAndLogEx(INFO, "Received MAC OK"); } else { PrintAndLogEx(WARNING, "Received MAC is not match with calculated"); - //PrintAndLogEx(INFO, " received MAC: %s", sprint_hex(&srcdata[srcdatalen - maclen], maclen)); - //PrintAndLogEx(INFO, " calculated MAC: %s", sprint_hex(mac, maclen)); + PrintAndLogEx(INFO, " received MAC: %s", sprint_hex(&srcdata[srcdatalen - maclen], maclen)); + PrintAndLogEx(INFO, " calculated MAC: %s", sprint_hex(mac, maclen)); } } break; @@ -384,6 +424,9 @@ static void DesfireSecureChannelDecodeEV1(DesfireContext *ctx, uint8_t *srcdata, PrintAndLogEx(WARNING, "Received MAC is not match with calculated"); PrintAndLogEx(INFO, " received MAC: %s", sprint_hex(&srcdata[*dstdatalen], desfire_get_key_block_length(ctx->keyType))); PrintAndLogEx(INFO, " calculated MAC: %s", sprint_hex(cmac, desfire_get_key_block_length(ctx->keyType))); + } else { + if (GetAPDULogging()) + PrintAndLogEx(INFO, "Received MAC OK"); } } else if (ctx->commMode == DCMEncrypted) { if (srcdatalen < desfire_get_key_block_length(ctx->keyType)) { @@ -418,7 +461,7 @@ static void DesfireSecureChannelDecodeEV2(DesfireContext *ctx, uint8_t *srcdata, // if comm mode = plain --> response with MAC // if request is not zero length --> response MAC - if (ctx->commMode == DCMPlain || ctx->commMode == DCMMACed || (ctx->commMode == DCMEncrypted && !ctx->lastRequestZeroLen)) { + if (ctx->commMode == DCMMACed) { if (srcdatalen < DesfireGetMACLength(ctx)) { memcpy(dstdata, srcdata, srcdatalen); *dstdatalen = srcdatalen; @@ -433,9 +476,12 @@ static void DesfireSecureChannelDecodeEV2(DesfireContext *ctx, uint8_t *srcdata, PrintAndLogEx(WARNING, "Received MAC is not match with calculated"); PrintAndLogEx(INFO, " received MAC: %s", sprint_hex(&srcdata[*dstdatalen], desfire_get_key_block_length(ctx->keyType))); PrintAndLogEx(INFO, " calculated MAC: %s", sprint_hex(cmac, desfire_get_key_block_length(ctx->keyType))); + } else { + if (GetAPDULogging()) + PrintAndLogEx(INFO, "Received MAC OK"); } } else if (ctx->commMode == DCMEncrypted) { - if (srcdatalen < desfire_get_key_block_length(ctx->keyType) + DesfireGetMACLength(ctx)) { + if (srcdatalen < DesfireGetMACLength(ctx)) { memcpy(dstdata, srcdata, srcdatalen); *dstdatalen = srcdatalen; return; @@ -448,18 +494,20 @@ static void DesfireSecureChannelDecodeEV2(DesfireContext *ctx, uint8_t *srcdata, PrintAndLogEx(INFO, " received MAC: %s", sprint_hex(&srcdata[*dstdatalen], desfire_get_key_block_length(ctx->keyType))); PrintAndLogEx(INFO, " calculated MAC: %s", sprint_hex(cmac, desfire_get_key_block_length(ctx->keyType))); } else { - //PrintAndLogEx(INFO, "Received MAC OK"); + if (GetAPDULogging()) + PrintAndLogEx(INFO, "Received MAC OK"); } - DesfireEV2FillIV(ctx, false, NULL); // fill response IV to ctx + if (*dstdatalen >= desfire_get_key_block_length(ctx->keyType)) { + DesfireEV2FillIV(ctx, false, NULL); // fill response IV to ctx + DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, srcdata, *dstdatalen, dstdata, false); - DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, srcdata, *dstdatalen, dstdata, false); - - size_t puredatalen = FindISO9797M2PaddingDataLen(dstdata, *dstdatalen); - if (puredatalen != 0) { - *dstdatalen = puredatalen; - } else { - PrintAndLogEx(WARNING, "Padding search error."); + size_t puredatalen = FindISO9797M2PaddingDataLen(dstdata, *dstdatalen); + if (puredatalen != 0) { + *dstdatalen = puredatalen; + } else { + PrintAndLogEx(WARNING, "Padding search error."); + } } } }