mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-22 06:13:51 -07:00
LRPSessionKeys and TestLRPSessionKeys
This commit is contained in:
parent
a6a80bf952
commit
67d198d946
4 changed files with 53 additions and 6 deletions
|
@ -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,11 +261,16 @@ void DesfireCryptoEncDecEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type,
|
|||
if (key == NULL)
|
||||
return;
|
||||
|
||||
size_t offset = 0;
|
||||
while (offset < srcdatalen) {
|
||||
DesfireCryptoEncDecSingleBlock(key, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode);
|
||||
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;
|
||||
offset += block_size;
|
||||
}
|
||||
}
|
||||
|
||||
if (iv == NULL)
|
||||
|
@ -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};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue