LRPSessionKeys and TestLRPSessionKeys

This commit is contained in:
merlokk 2021-08-18 19:05:28 +03:00
commit 67d198d946
4 changed files with 53 additions and 6 deletions

View file

@ -31,13 +31,14 @@
#include "crc16.h" // crc16 ccitt
#include "crc32.h"
#include "commonutil.h"
#include "crypto/libpcrypto.h"
void DesfireClearContext(DesfireContext *ctx) {
ctx->keyNum = 0;
ctx->keyType = T_DES;
memset(ctx->key, 0, sizeof(ctx->key));
LRPClearContext(&ctx->lrpCtx);
ctx->secureChannel = DACNone;
ctx->cmdSet = DCCNative;
ctx->commMode = DCMNone;
@ -260,12 +261,17 @@ void DesfireCryptoEncDecEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type,
if (key == NULL)
return;
if (ctx->secureChannel == DACLRP) {
size_t dstlen = 0;
LRPEncDec(key, iv, encode, srcdata, srcdatalen, data, &dstlen);
} else {
size_t offset = 0;
while (offset < srcdatalen) {
DesfireCryptoEncDecSingleBlock(key, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode);
offset += block_size;
}
}
if (iv == NULL)
memcpy(ctx->IV, xiv, block_size);
@ -585,6 +591,31 @@ void DesfireGenSessionKeyEV2(uint8_t *key, uint8_t *rndA, uint8_t *rndB, bool en
memcpy(sessionkey, cmac, CRYPTO_AES_BLOCK_SIZE);
}
// https://www.nxp.com/docs/en/data-sheet/MF2DLHX0.pdf
// page 35
void DesfireGenSessionKeyLRP(uint8_t *key, uint8_t *rndA, uint8_t *rndB, bool enckey, uint8_t *sessionkey) {
uint8_t data[64] = {0};
memset(sessionkey, 0, CRYPTO_AES_BLOCK_SIZE);
data[1] = 0x01;
data[3] = 0x80;
memcpy(data + 4, rndA, 8);
bin_xor(data + 6, rndB, 6); // xor rndb 6b
memcpy(data + 12, rndB + 6, 10);
memcpy(data + 22, rndA + 8, 8);
data[30] = 0x96;
data[31] = 0x69;
PrintAndLogEx(INFO, "rndA: %s", sprint_hex(rndA, CRYPTO_AES_BLOCK_SIZE));
PrintAndLogEx(INFO, "rndB: %s", sprint_hex(rndB, CRYPTO_AES_BLOCK_SIZE));
PrintAndLogEx(INFO, "data: %s", sprint_hex(data, 32));
LRPContext ctx = {0};
LRPSetKey(&ctx, key, 0, true);
LRPCMAC(&ctx, data, 32, sessionkey);
PrintAndLogEx(INFO, "mk: %s", sprint_hex(sessionkey, CRYPTO_AES_BLOCK_SIZE));
}
void DesfireEV2FillIV(DesfireContext *ctx, bool ivforcommand, uint8_t *iv) {
uint8_t xiv[CRYPTO_AES_BLOCK_SIZE] = {0};

View file

@ -23,6 +23,7 @@
#include "common.h"
#include "crypto/libpcrypto.h"
#include "mifare/lrpcrypto.h"
#define MAX_CRYPTO_BLOCK_SIZE 16
#define DESFIRE_MAX_CRYPTO_BLOCK_SIZE 16
@ -36,7 +37,7 @@ enum DESFIRE_CRYPTOALGO {
T_DES = 0x00,
T_3DES = 0x01, //aka 2K3DES
T_3K3DES = 0x02,
T_AES = 0x03
T_AES = 0x03,
};
typedef enum DESFIRE_CRYPTOALGO DesfireCryptoAlgorythm;
@ -77,6 +78,8 @@ typedef struct DesfireContextS {
uint8_t key[DESFIRE_MAX_KEY_SIZE];
uint8_t masterKey[DESFIRE_MAX_KEY_SIZE]; // source for kdf
LRPContext lrpCtx;
// KDF finction
uint8_t kdfAlgo;
uint8_t kdfInputLen;
@ -123,6 +126,8 @@ void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen,
void DesfireCryptoCMACEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *data, size_t len, size_t minlen, uint8_t *cmac);
void MifareKdfAn10922(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, const uint8_t *data, size_t len);
void DesfireGenSessionKeyLRP(uint8_t *key, uint8_t *rndA, uint8_t *rndB, bool enckey, uint8_t *sessionkey);
void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorythm keytype, uint8_t version);
uint8_t DesfireDESKeyGetVersion(uint8_t *key);

View file

@ -192,6 +192,16 @@ void LRPDecode(LRPContext *ctx, uint8_t *data, size_t datalen, uint8_t *resp, si
}
}
void LRPEncDec(uint8_t *key, uint8_t *iv, bool encode, uint8_t *data, size_t datalen, uint8_t *resp, size_t *resplen) {
LRPContext ctx = {0};
LRPSetKeyEx(&ctx, key, iv, 4 * 2, 0, false);
if (encode)
LRPEncode(&ctx, data, datalen, resp, resplen);
else
LRPDecode(&ctx, data, datalen, resp, resplen);
}
static bool shiftLeftBe(uint8_t *data, size_t length) {
if (length == 0)
return false;

View file

@ -54,6 +54,7 @@ void LRPEvalLRP(LRPContext *ctx, uint8_t *iv, size_t ivlen, bool final, uint8_t
void LRPIncCounter(uint8_t *ctr, size_t ctrlen);
void LRPEncode(LRPContext *ctx, uint8_t *data, size_t datalen, uint8_t *resp, size_t *resplen);
void LRPDecode(LRPContext *ctx, uint8_t *data, size_t datalen, uint8_t *resp, size_t *resplen);
void LRPEncDec(uint8_t *key, uint8_t *iv, bool encode, uint8_t *data, size_t datalen, uint8_t *resp, size_t *resplen);
void LRPGenSubkeys(uint8_t *key, uint8_t *sk1, uint8_t *sk2);
void LRPCMAC(LRPContext *ctx, uint8_t *data, size_t datalen, uint8_t *cmac);
void LRPCMAC8(LRPContext *ctx, uint8_t *data, size_t datalen, uint8_t *cmac);