LRPEncode ok

This commit is contained in:
merlokk 2021-08-14 12:41:09 +03:00
commit e56243501e
3 changed files with 71 additions and 1 deletions

View file

@ -617,6 +617,32 @@ static bool TestLRPIncCounter(void) {
return res;
}
static bool TestLRPEncode(void) {
bool res = true;
uint8_t resp[100] = {0};
size_t resplen = 0;
LRPContext ctx = {0};
uint8_t key1[] = {0xE0, 0xC4, 0x93, 0x5F, 0xF0, 0xC2, 0x54, 0xCD, 0x2C, 0xEF, 0x8F, 0xDD, 0xC3, 0x24, 0x60, 0xCF};
uint8_t iv1[] = {0xC3, 0x31, 0x5D, 0xBF};
LRPSetKeyEx(&ctx, key1, iv1, sizeof(iv1) * 2, 0, true);
uint8_t data1[] = {0x01, 0x2D, 0x7F, 0x16, 0x53, 0xCA, 0xF6, 0x50, 0x3C, 0x6A, 0xB0, 0xC1, 0x01, 0x0E, 0x8C, 0xB0};
LRPEncode(&ctx, data1, sizeof (data1), resp, &resplen);
uint8_t res1[] = {0xFC, 0xBB, 0xAC, 0xAA, 0x4F, 0x29, 0x18, 0x24, 0x64, 0xF9, 0x9D, 0xE4, 0x10, 0x85, 0x26, 0x6F,
0x48, 0x0E, 0x86, 0x3E, 0x48, 0x7B, 0xAA, 0xF6, 0x87, 0xB4, 0x3E, 0xD1, 0xEC, 0xE0, 0xD6, 0x23};
res = res && (resplen == sizeof(res1));
res = res && (memcmp(resp, res1, sizeof(res1)) == 0);
if (res)
PrintAndLogEx(INFO, "LRP encode........ " _GREEN_("passed"));
else
PrintAndLogEx(ERR, "LRP encode........ " _RED_("fail"));
return res;
}
bool DesfireTest(bool verbose) {
bool res = true;
@ -639,6 +665,7 @@ bool DesfireTest(bool verbose) {
res = res && TestLRPUpdatedKeys();
res = res && TestLRPEval();
res = res && TestLRPIncCounter();
res = res && TestLRPEncode();
PrintAndLogEx(INFO, "---------------------------");
if (res)

View file

@ -53,6 +53,17 @@ void LRPSetKey(LRPContext *ctx, uint8_t *key, size_t updatedKeyNum, bool useBitP
ctx->useBitPadding = useBitPadding;
}
void LRPSetCounter(LRPContext *ctx, uint8_t *counter, size_t counterLenNibbles) {
memcpy(ctx->counter, counter, counterLenNibbles / 2);
ctx->counterLenNibbles = counterLenNibbles;
}
void LRPSetKeyEx(LRPContext *ctx, uint8_t *key, uint8_t *counter, size_t counterLenNibbles, size_t updatedKeyNum, bool useBitPadding){
LRPSetKey(ctx, key, updatedKeyNum, useBitPadding);
LRPSetCounter(ctx, counter, counterLenNibbles);
}
// https://www.nxp.com/docs/en/application-note/AN12304.pdf
// Algorithm 1
void LRPGeneratePlaintexts(LRPContext *ctx, size_t plaintextsCount) {
@ -120,3 +131,29 @@ void LRPIncCounter(uint8_t *ctr, size_t ctrlen) {
}
}
// https://www.nxp.com/docs/en/application-note/AN12304.pdf
// Algorithm 4
void LRPEncode(LRPContext *ctx, uint8_t *data, size_t datalen, uint8_t *resp, size_t *resplen) {
*resplen = 0;
uint8_t xdata[1024] = {0};
memcpy(xdata, data, datalen);
if (ctx->useBitPadding) {
xdata[datalen] = 0x80;
datalen++;
}
if (datalen % CRYPTO_AES128_KEY_SIZE)
datalen = datalen + CRYPTO_AES128_KEY_SIZE - (datalen % CRYPTO_AES128_KEY_SIZE);
if (datalen == 0)
return;
uint8_t y[CRYPTO_AES128_KEY_SIZE] = {0};
for (int i = 0; i < datalen / CRYPTO_AES128_KEY_SIZE; i++) {
LRPEvalLRP(ctx, ctx->counter, ctx->counterLenNibbles, true, y);
aes_encode(NULL, y, &xdata[i * CRYPTO_AES128_KEY_SIZE], &resp[i * CRYPTO_AES128_KEY_SIZE], CRYPTO_AES128_KEY_SIZE);
*resplen += CRYPTO_AES128_KEY_SIZE;
LRPIncCounter(ctx->counter, ctx->counterLenNibbles);
}
}

View file

@ -25,6 +25,7 @@
#define LRP_MAX_PLAINTEXTS_SIZE 16
#define LRP_MAX_UPDATED_KEYS_SIZE 4
#define LRP_MAX_COUNTER_SIZE (CRYPTO_AES128_KEY_SIZE * 4)
typedef struct {
uint8_t key[CRYPTO_AES128_KEY_SIZE];
@ -35,14 +36,19 @@ typedef struct {
size_t updatedKeysCount;
uint8_t updatedKeys[LRP_MAX_UPDATED_KEYS_SIZE][CRYPTO_AES128_KEY_SIZE];
size_t useUpdatedKeyNum;
uint8_t counter[LRP_MAX_COUNTER_SIZE];
size_t counterLenNibbles; // len in bytes * 2 (or * 2 - 1)
} LRPContext;
void LRPClearContext(LRPContext *ctx);
void LRPSetKey(LRPContext *ctx, uint8_t *key, size_t updatedKeyNum, bool useBitPadding);
void LRPSetKeyEx(LRPContext *ctx, uint8_t *key, uint8_t *counter, size_t counterLenNibbles, size_t updatedKeyNum, bool useBitPadding);
void LRPSetCounter(LRPContext *ctx, uint8_t *counter, size_t counterLenNibbles);
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);
void LRPEncode(LRPContext *ctx, uint8_t *data, size_t datalen, uint8_t *resp, size_t *resplen);
#endif // __LRPCRYPTO_H