diff --git a/CHANGELOG.md b/CHANGELOG.md index 86df97e12..78c36987e 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 DESFire D40 secure channel crypto (@nvx) - Fixed `hf mfp info` fix signature check on 4b UID cards (@doegox) - Automatically set maximum read/write block when using predefined types in `hf_mf_ultimatecard` script (@piotrva) - Changed SPI flash detection to calculate the size instead of table lookup, updated spi_flash_decode.py script with more ICs (@ANTodorov) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 7bf692184..ac44508f2 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -1222,14 +1222,17 @@ static int DesfireAuthenticateEV1(DesfireContext_t *dctx, DesfireSecureChannel s // - Encrypt our response if (secureChannel == DACd40) { + // Original DESFire (MF3ICD40) silicon can only do encryption operations, so all PCD + // side operations must be decrypt, even when encrypting when doing D40 compatible + // secure channel operations memset(IV, 0, DESFIRE_MAX_CRYPTO_BLOCK_SIZE); - DesfireCryptoEncDecEx(dctx, DCOMainKey, RndA, rndlen, encRndA, true, true, IV); + DesfireCryptoEncDecEx(dctx, DCOMainKey, RndA, rndlen, encRndA, true, false, IV); memcpy(both, encRndA, rndlen); bin_xor(rotRndB, encRndA, rndlen); memset(IV, 0, DESFIRE_MAX_CRYPTO_BLOCK_SIZE); - DesfireCryptoEncDecEx(dctx, DCOMainKey, rotRndB, rndlen, encRndB, true, true, IV); + DesfireCryptoEncDecEx(dctx, DCOMainKey, rotRndB, rndlen, encRndB, true, false, IV); memcpy(both + rndlen, encRndB, rndlen); } else if (secureChannel == DACEV1) { diff --git a/client/src/mifare/desfiresecurechan.c b/client/src/mifare/desfiresecurechan.c index d35833b4d..85e2d7d94 100644 --- a/client/src/mifare/desfiresecurechan.c +++ b/client/src/mifare/desfiresecurechan.c @@ -313,6 +313,10 @@ static void DesfireSecureChannelEncodeD40(DesfireContext_t *ctx, uint8_t cmd, ui size_t srcmaclen = padded_data_length(srcdatalen - hdrlen, desfire_get_key_block_length(ctx->keyType)); uint8_t mac[32] = {0}; + PrintAndLogEx(DEBUG, "MACing"); + // Even though original DESFire (MF3ICD40) silicon can only encrypt which means normally + // every PCD operation must be decrypt, verifying a MAC involves the same operation on both + // sides so this is still encrypt here DesfireCryptoEncDecEx(ctx, DCOSessionKeyMac, data, srcmaclen, NULL, true, true, mac); if (DesfireEV1D40TransmitMAC(ctx, cmd)) { @@ -889,4 +893,3 @@ bool PrintChannelModeWarning(uint8_t cmd, DesfireSecureChannel secureChannel, De return found; } -