diff --git a/client/src/mifare/desfiretest.c b/client/src/mifare/desfiretest.c index cc8de88aa..2cd8ba1be 100644 --- a/client/src/mifare/desfiretest.c +++ b/client/src/mifare/desfiretest.c @@ -586,6 +586,37 @@ static bool TestLRPEval(void) { return res; } +static bool TestLRPIncCounter(void) { + bool res = true; + + uint8_t ctr1[] = {0x00, 0x01}; + LRPIncCounter(ctr1, 4); + uint8_t ctrr1[] = {0x00, 0x02}; + res = res && (memcmp(ctr1, ctrr1, sizeof(ctrr1)) == 0); + + uint8_t ctr2[] = {0x00, 0xf0}; + LRPIncCounter(ctr2, 3); + uint8_t ctrr2[] = {0x01, 0x00}; + res = res && (memcmp(ctr2, ctrr2, sizeof(ctrr2)) == 0); + + uint8_t ctr3[] = {0xff, 0xf0}; + LRPIncCounter(ctr3, 3); + uint8_t ctrr3[] = {0x00, 0x00}; + res = res && (memcmp(ctr3, ctrr3, sizeof(ctrr3)) == 0); + + uint8_t ctr4[] = {0xf0}; + LRPIncCounter(ctr4, 1); + uint8_t ctrr4[] = {0x00}; + res = res && (memcmp(ctr4, ctrr4, sizeof(ctrr4)) == 0); + + if (res) + PrintAndLogEx(INFO, "LRP inc counter... " _GREEN_("passed")); + else + PrintAndLogEx(ERR, "LRP inc counter... " _RED_("fail")); + + return res; +} + bool DesfireTest(bool verbose) { bool res = true; @@ -607,6 +638,7 @@ bool DesfireTest(bool verbose) { res = res && TestLRPPlaintexts(); res = res && TestLRPUpdatedKeys(); res = res && TestLRPEval(); + res = res && TestLRPIncCounter(); PrintAndLogEx(INFO, "---------------------------"); if (res) diff --git a/client/src/mifare/lrpcrypto.c b/client/src/mifare/lrpcrypto.c index 54d374f22..217747dc8 100644 --- a/client/src/mifare/lrpcrypto.c +++ b/client/src/mifare/lrpcrypto.c @@ -100,3 +100,23 @@ void LRPEvalLRP(LRPContext *ctx, uint8_t *iv, size_t ivlen, bool final, uint8_t if (final) aes_encode(NULL, y, const00, y, CRYPTO_AES128_KEY_SIZE); } + +void LRPIncCounter(uint8_t *ctr, size_t ctrlen) { + bool carry = true; + for (int i = ctrlen - 1; i >= 0; i--) { + uint8_t nk = (i % 2) ? ctr[i / 2] & 0x0f : (ctr[i / 2] >> 4) & 0x0f; + + if (carry) + nk++; + + carry = (nk > 0xf); + if (i % 2) + ctr[i / 2] = (ctr[i / 2] & 0xf0) | (nk & 0x0f); + else + ctr[i / 2] = (ctr[i / 2] & 0x0f) | ((nk << 4) & 0xf0); + + if(!carry) + break; + } +} + diff --git a/client/src/mifare/lrpcrypto.h b/client/src/mifare/lrpcrypto.h index 122e06911..a8dbefdb6 100644 --- a/client/src/mifare/lrpcrypto.h +++ b/client/src/mifare/lrpcrypto.h @@ -42,5 +42,7 @@ void LRPSetKey(LRPContext *ctx, uint8_t *key, size_t updatedKeyNum, bool useBitP void LRPGeneratePlaintexts(LRPContext *ctx, size_t plaintextsCount); void LRPGenerateUpdatedKeys(LRPContext *ctx, size_t updatedKeysCount); void LRPEvalLRP(LRPContext *ctx, uint8_t *iv, size_t ivlen, bool final, uint8_t *y); +void LRPIncCounter(uint8_t *ctr, size_t ctrlen); +void LRPEncode(LRPContext *ctx, uint8_t *ctr, size_t ctrlen, uint8_t *resp, size_t *resplen); #endif // __LRPCRYPTO_H