mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-22 22:33:48 -07:00
LRPEncode ok
This commit is contained in:
parent
ae3ba512f0
commit
e56243501e
3 changed files with 71 additions and 1 deletions
|
@ -617,6 +617,32 @@ static bool TestLRPIncCounter(void) {
|
||||||
return res;
|
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 DesfireTest(bool verbose) {
|
||||||
bool res = true;
|
bool res = true;
|
||||||
|
|
||||||
|
@ -639,6 +665,7 @@ bool DesfireTest(bool verbose) {
|
||||||
res = res && TestLRPUpdatedKeys();
|
res = res && TestLRPUpdatedKeys();
|
||||||
res = res && TestLRPEval();
|
res = res && TestLRPEval();
|
||||||
res = res && TestLRPIncCounter();
|
res = res && TestLRPIncCounter();
|
||||||
|
res = res && TestLRPEncode();
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "---------------------------");
|
PrintAndLogEx(INFO, "---------------------------");
|
||||||
if (res)
|
if (res)
|
||||||
|
|
|
@ -53,6 +53,17 @@ void LRPSetKey(LRPContext *ctx, uint8_t *key, size_t updatedKeyNum, bool useBitP
|
||||||
ctx->useBitPadding = useBitPadding;
|
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
|
// https://www.nxp.com/docs/en/application-note/AN12304.pdf
|
||||||
// Algorithm 1
|
// Algorithm 1
|
||||||
void LRPGeneratePlaintexts(LRPContext *ctx, size_t plaintextsCount) {
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#define LRP_MAX_PLAINTEXTS_SIZE 16
|
#define LRP_MAX_PLAINTEXTS_SIZE 16
|
||||||
#define LRP_MAX_UPDATED_KEYS_SIZE 4
|
#define LRP_MAX_UPDATED_KEYS_SIZE 4
|
||||||
|
#define LRP_MAX_COUNTER_SIZE (CRYPTO_AES128_KEY_SIZE * 4)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t key[CRYPTO_AES128_KEY_SIZE];
|
uint8_t key[CRYPTO_AES128_KEY_SIZE];
|
||||||
|
@ -35,14 +36,19 @@ typedef struct {
|
||||||
size_t updatedKeysCount;
|
size_t updatedKeysCount;
|
||||||
uint8_t updatedKeys[LRP_MAX_UPDATED_KEYS_SIZE][CRYPTO_AES128_KEY_SIZE];
|
uint8_t updatedKeys[LRP_MAX_UPDATED_KEYS_SIZE][CRYPTO_AES128_KEY_SIZE];
|
||||||
size_t useUpdatedKeyNum;
|
size_t useUpdatedKeyNum;
|
||||||
|
|
||||||
|
uint8_t counter[LRP_MAX_COUNTER_SIZE];
|
||||||
|
size_t counterLenNibbles; // len in bytes * 2 (or * 2 - 1)
|
||||||
} LRPContext;
|
} LRPContext;
|
||||||
|
|
||||||
void LRPClearContext(LRPContext *ctx);
|
void LRPClearContext(LRPContext *ctx);
|
||||||
void LRPSetKey(LRPContext *ctx, uint8_t *key, size_t updatedKeyNum, bool useBitPadding);
|
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 LRPGeneratePlaintexts(LRPContext *ctx, size_t plaintextsCount);
|
||||||
void LRPGenerateUpdatedKeys(LRPContext *ctx, size_t updatedKeysCount);
|
void LRPGenerateUpdatedKeys(LRPContext *ctx, size_t updatedKeysCount);
|
||||||
void LRPEvalLRP(LRPContext *ctx, uint8_t *iv, size_t ivlen, bool final, uint8_t *y);
|
void LRPEvalLRP(LRPContext *ctx, uint8_t *iv, size_t ivlen, bool final, uint8_t *y);
|
||||||
void LRPIncCounter(uint8_t *ctr, size_t ctrlen);
|
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
|
#endif // __LRPCRYPTO_H
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue