From e021870ed8e1944aa858ad0240258de2d7e79435 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 19 Aug 2021 16:43:28 +0300 Subject: [PATCH] lrp maced channel fully works --- client/src/cmdhfmfdes.c | 3 +- client/src/mifare/desfiresecurechan.c | 60 +++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 59cf3c4de..dd6e39baf 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -3164,7 +3164,8 @@ static int CmdHF14ADesGetFileISOIDs(const char *Cmd) { "Get File IDs list from card. Master key needs to be provided or flag --no-auth set.", "hf mfdes getfileisoids --aid 123456 -> execute with defaults from `default` command\n" "hf mfdes getfileisoids -n 0 -t des -k 0000000000000000 -f none --aid 123456 -> execute with default factory setup\n" - "hf mfdes getfileisoids --appisoid df01 -> get file iso ids from Desfire Light with factory card settings"); + "hf mfdes getfileisoids --appisoid df01 -> get iso file ids from Desfire Light with factory card settings\n" + "hf mfdes getfileisoids --appisoid df01 -s lrp -t aes -> get iso file ids from Desfire Light via lrp channel with default key authentication"); void *argtable[] = { arg_param_begin, diff --git a/client/src/mifare/desfiresecurechan.c b/client/src/mifare/desfiresecurechan.c index 640273a59..ba5937a64 100644 --- a/client/src/mifare/desfiresecurechan.c +++ b/client/src/mifare/desfiresecurechan.c @@ -608,6 +608,64 @@ static void DesfireSecureChannelDecodeEV2(DesfireContext *ctx, uint8_t *srcdata, } } +static void DesfireSecureChannelDecodeLRP(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t respcode, uint8_t *dstdata, size_t *dstdatalen) { + ctx->cmdCntr++; + + memcpy(dstdata, srcdata, srcdatalen); + *dstdatalen = srcdatalen; + uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; + + if (ctx->commMode == DCMMACed) { + if (srcdatalen < DesfireGetMACLength(ctx)) { + memcpy(dstdata, srcdata, srcdatalen); + *dstdatalen = srcdatalen; + return; + } + + memcpy(dstdata, srcdata, srcdatalen - DesfireGetMACLength(ctx)); + *dstdatalen = srcdatalen - DesfireGetMACLength(ctx); + + DesfireLRPCalcCMAC(ctx, 0x00, srcdata, *dstdatalen, cmac); + if (memcmp(&srcdata[*dstdatalen], cmac, DesfireGetMACLength(ctx)) != 0) { + PrintAndLogEx(WARNING, "Received MAC is not match with calculated"); + PrintAndLogEx(INFO, " received MAC: %s", sprint_hex(&srcdata[*dstdatalen], DesfireGetMACLength(ctx))); + PrintAndLogEx(INFO, " calculated MAC: %s", sprint_hex(cmac, DesfireGetMACLength(ctx))); + } else { + if (GetAPDULogging()) + PrintAndLogEx(INFO, "Received MAC OK"); + } + } else if (ctx->commMode == DCMEncrypted || ctx->commMode == DCMEncryptedWithPadding) { + if (srcdatalen < DesfireGetMACLength(ctx)) { + memcpy(dstdata, srcdata, srcdatalen); + *dstdatalen = srcdatalen; + return; + } + + *dstdatalen = srcdatalen - DesfireGetMACLength(ctx); + DesfireLRPCalcCMAC(ctx, 0x00, srcdata, *dstdatalen, cmac); + if (memcmp(&srcdata[*dstdatalen], cmac, DesfireGetMACLength(ctx)) != 0) { + PrintAndLogEx(WARNING, "Received MAC is not match with calculated"); + PrintAndLogEx(INFO, " received MAC: %s", sprint_hex(&srcdata[*dstdatalen], DesfireGetMACLength(ctx))); + PrintAndLogEx(INFO, " calculated MAC: %s", sprint_hex(cmac, DesfireGetMACLength(ctx))); + } else { + if (GetAPDULogging()) + PrintAndLogEx(INFO, "Received MAC OK"); + } + + 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); + + size_t puredatalen = FindISO9797M2PaddingDataLen(dstdata, *dstdatalen); + if (puredatalen != 0) { + *dstdatalen = puredatalen; + } else { + PrintAndLogEx(WARNING, "Padding search error."); + } + } + } +} + static void DesfireISODecode(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) { memcpy(dstdata, srcdata, srcdatalen); *dstdatalen = srcdatalen; @@ -652,6 +710,8 @@ void DesfireSecureChannelDecode(DesfireContext *ctx, uint8_t *srcdata, size_t sr DesfireSecureChannelDecodeEV2(ctx, srcdata, srcdatalen, respcode, dstdata, dstdatalen); break; case DACLRP: + DesfireSecureChannelDecodeLRP(ctx, srcdata, srcdatalen, respcode, dstdata, dstdatalen); + break; case DACNone: memcpy(dstdata, srcdata, srcdatalen); *dstdatalen = srcdatalen;