mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-02-23 07:37:23 +08:00
TestLRPPlaintexts
This commit is contained in:
parent
99bc47c1ac
commit
442bbd38b5
3 changed files with 117 additions and 1 deletions
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "crypto/libpcrypto.h"
|
||||
#include "mifare/desfirecrypto.h"
|
||||
#include "mifare/lrpcrypto.h"
|
||||
|
||||
static uint8_t CMACData[] = {0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
|
||||
0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
|
||||
|
@ -474,6 +475,47 @@ static bool TestTransSessionKeys(void) {
|
|||
return res;
|
||||
}
|
||||
|
||||
// https://www.nxp.com/docs/en/application-note/AN12304.pdf
|
||||
// page 10
|
||||
static bool TestLRPPlaintexts(void) {
|
||||
bool res = true;
|
||||
|
||||
uint8_t key[] = {0x56, 0x78, 0x26, 0xB8, 0xDA, 0x8E, 0x76, 0x84, 0x32, 0xA9, 0x54, 0x8D, 0xBE, 0x4A, 0xA3, 0xA0};
|
||||
LRPContext ctx = {0};
|
||||
LRPSetKey(&ctx, key, 0, false);
|
||||
|
||||
uint8_t key0[] = {0xAC, 0x20, 0xD3, 0x9F, 0x53, 0x41, 0xFE, 0x98, 0xDF, 0xCA, 0x21, 0xDA, 0x86, 0xBA, 0x79, 0x14};
|
||||
res = res && (memcmp(ctx.plaintexts[0], key0, sizeof(key0)) == 0);
|
||||
|
||||
uint8_t key1[] = {0x90, 0x7D, 0xA0, 0x3D, 0x67, 0x24, 0x49, 0x16, 0x69, 0x15, 0xE4, 0x56, 0x3E, 0x08, 0x9D, 0x6D};
|
||||
res = res && (memcmp(ctx.plaintexts[1], key1, sizeof(key1)) == 0);
|
||||
|
||||
uint8_t key14[] = {0x37, 0xD7, 0x34, 0xA5, 0x1C, 0x07, 0x6E, 0xB8, 0x03, 0xBD, 0x53, 0x0E, 0x17, 0xEB, 0x87, 0xDC};
|
||||
res = res && (memcmp(ctx.plaintexts[14], key14, sizeof(key14)) == 0);
|
||||
|
||||
uint8_t key15[] = {0x71, 0xB4, 0x44, 0xAF, 0x25, 0x7A, 0x93, 0x21, 0x53, 0x11, 0xD7, 0x58, 0xDD, 0x33, 0x32, 0x47};
|
||||
res = res && (memcmp(ctx.plaintexts[15], key15, sizeof(key15)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "LRP plaintexts.... " _GREEN_("passed"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "LRP plaintexts.... " _RED_("fail"));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool TestLRPUpdatedKeys(void) {
|
||||
bool res = true;
|
||||
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "LRP updated keys.. " _GREEN_("passed"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "LRP updated keys.. " _RED_("fail"));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool DesfireTest(bool verbose) {
|
||||
bool res = true;
|
||||
|
||||
|
@ -492,6 +534,8 @@ bool DesfireTest(bool verbose) {
|
|||
res = res && TestEV2IVEncode();
|
||||
res = res && TestEV2MAC();
|
||||
res = res && TestTransSessionKeys();
|
||||
res = res && TestLRPPlaintexts();
|
||||
res = res && TestLRPUpdatedKeys();
|
||||
|
||||
PrintAndLogEx(INFO, "---------------------------");
|
||||
if (res)
|
||||
|
|
|
@ -26,3 +26,62 @@
|
|||
#include "aes.h"
|
||||
#include "commonutil.h"
|
||||
|
||||
static uint8_t constAA[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
|
||||
static uint8_t const55[] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
|
||||
|
||||
void LRPClearContext(LRPContext *ctx) {
|
||||
memset(ctx->key, 0, CRYPTO_AES128_KEY_SIZE);
|
||||
|
||||
ctx->useBitPadding = false;
|
||||
ctx->plaintextsCount = 0;
|
||||
memset(ctx->plaintexts, 0, LRP_MAX_PLAINTEXTS_SIZE * CRYPTO_AES128_KEY_SIZE);
|
||||
ctx->updatedKeysCount = 0;
|
||||
memset(ctx->updatedKeys, 0, LRP_MAX_UPDATED_KEYS_SIZE * CRYPTO_AES128_KEY_SIZE);
|
||||
ctx->useUpdatedKeyNum = 0;
|
||||
}
|
||||
|
||||
void LRPSetKey(LRPContext *ctx, uint8_t *key, size_t updatedKeyNum, bool useBitPadding) {
|
||||
LRPClearContext(ctx);
|
||||
|
||||
memcpy(ctx->key, key, CRYPTO_AES128_KEY_SIZE);
|
||||
|
||||
LRPGeneratePlaintexts(ctx, 16);
|
||||
LRPGenerateUpdatedKeys(ctx, 4);
|
||||
|
||||
ctx->useUpdatedKeyNum = updatedKeyNum;
|
||||
ctx->useBitPadding = useBitPadding;
|
||||
}
|
||||
|
||||
// https://www.nxp.com/docs/en/application-note/AN12304.pdf
|
||||
// Algorithm 1
|
||||
void LRPGeneratePlaintexts(LRPContext *ctx, size_t plaintextsCount) {
|
||||
if (plaintextsCount > LRP_MAX_PLAINTEXTS_SIZE)
|
||||
return;
|
||||
|
||||
uint8_t h[CRYPTO_AES128_KEY_SIZE] = {0};
|
||||
memcpy(h, ctx->key, CRYPTO_AES128_KEY_SIZE);
|
||||
|
||||
for (int i = 0; i < plaintextsCount; i++) {
|
||||
aes_encode(NULL, h, const55, h, CRYPTO_AES128_KEY_SIZE);
|
||||
aes_encode(NULL, h, constAA, ctx->plaintexts[i], CRYPTO_AES128_KEY_SIZE);
|
||||
}
|
||||
|
||||
ctx->plaintextsCount = plaintextsCount;
|
||||
}
|
||||
|
||||
// https://www.nxp.com/docs/en/application-note/AN12304.pdf
|
||||
// Algorithm 2
|
||||
void LRPGenerateUpdatedKeys(LRPContext *ctx, size_t updatedKeysCount) {
|
||||
if (updatedKeysCount > LRP_MAX_UPDATED_KEYS_SIZE)
|
||||
return;
|
||||
|
||||
uint8_t h[CRYPTO_AES128_KEY_SIZE] = {0};
|
||||
aes_encode(NULL, ctx->key, const55, h, CRYPTO_AES128_KEY_SIZE);
|
||||
|
||||
for (int i = 0; i < updatedKeysCount; i++) {
|
||||
aes_encode(NULL, h, constAA, ctx->plaintexts[i], CRYPTO_AES128_KEY_SIZE);
|
||||
aes_encode(NULL, h, const55, h, CRYPTO_AES128_KEY_SIZE);
|
||||
}
|
||||
|
||||
ctx->updatedKeysCount = updatedKeysCount;
|
||||
}
|
||||
|
|
|
@ -23,11 +23,24 @@
|
|||
#include "common.h"
|
||||
#include "crypto/libpcrypto.h"
|
||||
|
||||
#define LRP_MAX_PLAINTEXTS_SIZE 16
|
||||
#define LRP_MAX_UPDATED_KEYS_SIZE 4
|
||||
|
||||
typedef struct {
|
||||
uint8_t key[CRYPTO_AES128_KEY_SIZE];
|
||||
|
||||
bool useBitPadding;
|
||||
size_t plaintextsCount;
|
||||
uint8_t plaintexts[LRP_MAX_PLAINTEXTS_SIZE][CRYPTO_AES128_KEY_SIZE];
|
||||
size_t updatedKeysCount;
|
||||
uint8_t updatedKeys[LRP_MAX_UPDATED_KEYS_SIZE][CRYPTO_AES128_KEY_SIZE];
|
||||
size_t useUpdatedKeyNum;
|
||||
} LRPContext;
|
||||
|
||||
void LRPSetKey(LRPContext *ctx);
|
||||
void LRPClearContext(LRPContext *ctx);
|
||||
void LRPSetKey(LRPContext *ctx, uint8_t *key, size_t updatedKeyNum, bool useBitPadding);
|
||||
void LRPGeneratePlaintexts(LRPContext *ctx, size_t plaintextsCount);
|
||||
void LRPGenerateUpdatedKeys(LRPContext *ctx, size_t updatedKeysCount);
|
||||
|
||||
|
||||
#endif // __LRPCRYPTO_H
|
||||
|
|
Loading…
Reference in a new issue