From a7f39a1b79f3800960de69db948ebb0b83ed4134 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 9 Jul 2021 13:09:59 +0300 Subject: [PATCH] move crc search function to desfirecrypto --- client/src/mifare/desfirecrypto.c | 44 +++++++++++++++++++++++++++ client/src/mifare/desfirecrypto.h | 1 + client/src/mifare/desfiresecurechan.c | 39 +++--------------------- 3 files changed, 50 insertions(+), 34 deletions(-) diff --git a/client/src/mifare/desfirecrypto.c b/client/src/mifare/desfirecrypto.c index b65512b23..246545e9e 100644 --- a/client/src/mifare/desfirecrypto.c +++ b/client/src/mifare/desfirecrypto.c @@ -109,6 +109,50 @@ size_t DesfireGetMACLength(DesfireContext *ctx) { return mac_length; } +size_t DesfireSearchCRCPos(uint8_t *data, size_t datalen, uint8_t respcode, uint8_t crclen) { + size_t crcpos = datalen - 1; + while (crcpos > 0) + if (data[crcpos] == 0) + crcpos--; + else + break; + crcpos++; // crc may be 0x00000000 or 0x0000 + PrintAndLogEx(INFO, "crcpos: %d", crcpos); + if (crcpos < crclen) { + PrintAndLogEx(WARNING, "No space for crc. pos: %d", crcpos); + return 0; + } + + uint8_t crcdata[1024] = {0}; + bool crcok = false; + for (int i = 0; i < crclen + 1; i++) { + PrintAndLogEx(INFO, "--crcpos: %d", crcpos - i); + if (crcpos - i == 0) + break; + if (crcpos - i + crclen > datalen) + continue; + PrintAndLogEx(INFO, "--crcposcheck: %d", crcpos - i); + + memcpy(crcdata, data, crcpos - i); + crcdata[crcpos - i] = respcode; + bool res; + if (crclen == 4) + res = desfire_crc32_check(crcdata, crcpos - i + 1, &data[crcpos - i]); + else + res = iso14443a_crc_check(crcdata, crcpos - i + 1, &data[crcpos - i]); + if (res) { + PrintAndLogEx(INFO, "--crc OK pos: %d", crcpos - i); + crcpos -= i; + crcok = true; + break; + } + } + if (!crcok) + crcpos = 0; + + return crcpos; +} + static void DesfireCryptoEncDecSingleBlock(uint8_t *key, DesfireCryptoAlgorythm keyType, uint8_t *data, uint8_t *dstdata, uint8_t *ivect, bool dir_to_send, bool encode) { size_t block_size = desfire_get_key_block_length(keyType); uint8_t sdata[MAX_CRYPTO_BLOCK_SIZE] = {0}; diff --git a/client/src/mifare/desfirecrypto.h b/client/src/mifare/desfirecrypto.h index ff12335e6..824225b39 100644 --- a/client/src/mifare/desfirecrypto.h +++ b/client/src/mifare/desfirecrypto.h @@ -95,6 +95,7 @@ void DesfireSetKdf(DesfireContext *ctx, uint8_t kdfAlgo, uint8_t *kdfInput, uint bool DesfireIsAuthenticated(DesfireContext *dctx); size_t DesfireGetMACLength(DesfireContext *ctx); +size_t DesfireSearchCRCPos(uint8_t *data, size_t datalen, uint8_t respcode, uint8_t crclen); void DesfireCryptoEncDec(DesfireContext *ctx, bool use_session_key, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode); void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode, uint8_t *iv); diff --git a/client/src/mifare/desfiresecurechan.c b/client/src/mifare/desfiresecurechan.c index 5f9fec5a9..b62a0a056 100644 --- a/client/src/mifare/desfiresecurechan.c +++ b/client/src/mifare/desfiresecurechan.c @@ -161,41 +161,12 @@ static void DesfireSecureChannelDecodeEV1(DesfireContext *ctx, uint8_t *srcdata, DesfireCryptoEncDec(ctx, true, srcdata, srcdatalen, dstdata, false); PrintAndLogEx(INFO, "decoded[%d]: %s", srcdatalen, sprint_hex(dstdata, srcdatalen)); - size_t crcpos = srcdatalen - 1; - while (crcpos > 0) - if (dstdata[crcpos] == 0) - crcpos--; - else - break; - crcpos++; // crc may be 0x00000000 - *dstdatalen = crcpos; - PrintAndLogEx(INFO, "crcpos: %d", crcpos); - if (crcpos < 4) { - PrintAndLogEx(WARNING, "No space for crc. pos: %d", crcpos); - return; - } - - uint8_t crcdata[1024] = {0}; - bool crcok = false; - for (int i = 0; i < 5; i++) { - if (crcpos == 0) - break; - if (crcpos - i + 4 > srcdatalen) - continue; - - memcpy(crcdata, dstdata, crcpos - i); - crcdata[crcpos - i] = respcode; - if (desfire_crc32_check(crcdata, crcpos - i + 1, &dstdata[crcpos - i])) { - crcpos -= i; - crcok = true; - break; - } - } - - if (crcok) { - *dstdatalen = crcpos; + size_t puredatalen = DesfireSearchCRCPos(dstdata, srcdatalen, respcode, 4); + if (puredatalen != 0) { + *dstdatalen = puredatalen; } else { - PrintAndLogEx(WARNING, "CRC32 error. pos: %d", crcpos); + PrintAndLogEx(WARNING, "CRC32 error."); + *dstdatalen = srcdatalen; } } else {