ev2 iv calc

This commit is contained in:
merlokk 2021-07-30 14:45:26 +03:00
parent a5ba41f5cf
commit f074386413
4 changed files with 51 additions and 12 deletions

View file

@ -303,10 +303,9 @@ void DesfirePrintContext(DesfireContext *ctx) {
desfire_get_key_block_length(ctx->keyType),
sprint_hex(ctx->IV, desfire_get_key_block_length(ctx->keyType)));
if (ctx->secureChannel == DACEV2) {
PrintAndLogEx(INFO, " TI: %s cnTX: 0x%08x cnRx: 0x%08x",
PrintAndLogEx(INFO, " TI: %s cmdCntr: 0x%08x",
sprint_hex(ctx->TI, 4),
ctx->cntrTx,
ctx->cntrRx);
ctx->cmdCntr);
}
}
@ -1096,7 +1095,7 @@ static int DesfireAuthenticateEV2(DesfireContext *dctx, DesfireSecureChannel sec
// Let's send our auth command
uint8_t cdata[2] = {dctx->keyNum, 0x00};
int res = DesfireExchangeEx(false, dctx, subcommand, cdata, sizeof(cdata), &respcode, recv_data, &recv_len, false, 0);
int res = DesfireExchangeEx(false, dctx, subcommand, cdata, (firstauth) ? sizeof(cdata) : 1, &respcode, recv_data, &recv_len, false, 0);
if (res != PM3_SUCCESS) {
return 1;
}
@ -1175,7 +1174,7 @@ PrintAndLogEx(INFO, "IV : %s", sprint_hex(IV, CRYPTO_AES_BLOCK_SIZE));
uint8_t data[32] = {0};
if (aes_decode(IV, key, recv_data, data, CRYPTO_AES_BLOCK_SIZE * 2))
if (aes_decode(IV, key, recv_data, data, recv_len))
return 10;
PrintAndLogEx(INFO, "data : %s", sprint_hex(data, CRYPTO_AES_BLOCK_SIZE * 2));
@ -1200,8 +1199,7 @@ PrintAndLogEx(INFO, "Generated_RndA : %s", sprint_hex(&data[4], CRYPTO_AES_BLOCK
}
if (firstauth) {
dctx->cntrRx = 0;
dctx->cntrTx = 0;
dctx->cmdCntr = 0;
memcpy(dctx->TI, data, 4);
}
memset(dctx->IV, 0, DESFIRE_MAX_KEY_SIZE);

View file

@ -58,8 +58,7 @@ void DesfireClearSession(DesfireContext *ctx) {
memset(ctx->lastIV, 0, sizeof(ctx->lastIV));
ctx->lastCommand = 0;
ctx->lastRequestZeroLen = false;
ctx->cntrTx = 0;
ctx->cntrRx = 0;
ctx->cmdCntr = 0;
memset(ctx->TI, 0, sizeof(ctx->TI));
}
@ -219,6 +218,10 @@ void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *s
if (ctx->secureChannel == DACd40) {
memset(ctx->IV, 0, DESFIRE_MAX_CRYPTO_BLOCK_SIZE);
}
if (ctx->secureChannel == DACEV2) {
DesfireEV2FillIV(ctx, dir_to_send, NULL);
}
size_t block_size = desfire_get_key_block_length(ctx->keyType);
@ -417,6 +420,27 @@ void DesfireGenSessionKeyEV2(uint8_t *key, uint8_t *rndA, uint8_t *rndB, bool en
memcpy(sessionkey, cmac, CRYPTO_AES_BLOCK_SIZE);
}
void DesfireEV2FillIV(DesfireContext *ctx, bool send, uint8_t *iv) {
uint8_t xiv[CRYPTO_AES_BLOCK_SIZE] = {0};
if (send) {
xiv[0] = 0xa5;
xiv[1] = 0x5a;
} else {
xiv[0] = 0x5a;
xiv[1] = 0xa5;
}
memcpy(xiv + 2, ctx->TI, 4);
Uint2byteToMemLe(xiv + 2 + 4, ctx->cmdCntr);
if (iv == NULL)
memcpy(ctx->IV, xiv, CRYPTO_AES_BLOCK_SIZE);
else
memcpy(iv, xiv, CRYPTO_AES_BLOCK_SIZE);
}
void desfire_crc32(const uint8_t *data, const size_t len, uint8_t *crc) {
crc32_ex(data, len, crc);
}

View file

@ -82,9 +82,7 @@ typedef struct DesfireContextS {
uint8_t lastIV[DESFIRE_MAX_KEY_SIZE];
uint8_t lastCommand;
bool lastRequestZeroLen;
//mf4Session_t AESSession;
uint16_t cntrTx; // for AES
uint16_t cntrRx; // for AES
uint16_t cmdCntr; // for AES
uint8_t TI[4]; // for AES
} DesfireContext;
@ -110,6 +108,7 @@ DesfireCommunicationMode DesfireFileCommModeToCommMode(uint8_t file_comm_mode);
uint8_t DesfireCommModeToFileCommMode(DesfireCommunicationMode comm_mode);
void DesfireGenSessionKeyEV2(uint8_t *key, uint8_t *rndA, uint8_t *rndB, bool enckey, uint8_t *sessionkey);
void DesfireEV2FillIV(DesfireContext *ctx, bool send, uint8_t *iv);
void desfire_crc32(const uint8_t *data, const size_t len, uint8_t *crc);
void desfire_crc32_append(uint8_t *data, const size_t len);

View file

@ -24,6 +24,7 @@
#include "mifare/desfire_crypto.h"
static const uint8_t CommandsCanUseAnyChannel[] = {
MFDES_S_ADDITIONAL_FRAME,
MFDES_READ_DATA,
MFDES_WRITE_DATA,
MFDES_GET_VALUE,
@ -116,6 +117,9 @@ static const AllowedChannelModesS AllowedChannelModes[] = {
{MFDES_CHANGE_KEY, DACEV1, DCCNative, DCMEncryptedPlain},
{MFDES_CHANGE_KEY_EV2, DACEV1, DCCNative, DCMEncryptedPlain},
{MFDES_AUTHENTICATE_EV2F, DACEV2, DCCNative, DCMPlain},
{MFDES_AUTHENTICATE_EV2NF, DACEV2, DCCNative, DCMPlain},
};
#define CMD_HEADER_LEN_ALL 0xffff
@ -239,6 +243,13 @@ static void DesfireSecureChannelEncodeEV1(DesfireContext *ctx, uint8_t cmd, uint
}
}
static void DesfireSecureChannelEncodeEV2(DesfireContext *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) {
memcpy(dstdata, srcdata, srcdatalen);
*dstdatalen = srcdatalen;
ctx->cmdCntr++;
}
void DesfireSecureChannelEncode(DesfireContext *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) {
ctx->lastCommand = cmd;
ctx->lastRequestZeroLen = (srcdatalen <= DesfireGetCmdHeaderLen(cmd));
@ -251,6 +262,7 @@ void DesfireSecureChannelEncode(DesfireContext *ctx, uint8_t cmd, uint8_t *srcda
DesfireSecureChannelEncodeEV1(ctx, cmd, srcdata, srcdatalen, dstdata, dstdatalen);
break;
case DACEV2:
DesfireSecureChannelEncodeEV2(ctx, cmd, srcdata, srcdatalen, dstdata, dstdatalen);
break;
case DACNone:
memcpy(dstdata, srcdata, srcdatalen);
@ -361,6 +373,11 @@ static void DesfireSecureChannelDecodeEV1(DesfireContext *ctx, uint8_t *srcdata,
}
}
static void DesfireSecureChannelDecodeEV2(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t respcode, uint8_t *dstdata, size_t *dstdatalen) {
memcpy(dstdata, srcdata, srcdatalen);
*dstdatalen = srcdatalen;
}
void DesfireSecureChannelDecode(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t respcode, uint8_t *dstdata, size_t *dstdatalen) {
switch (ctx->secureChannel) {
case DACd40:
@ -370,6 +387,7 @@ void DesfireSecureChannelDecode(DesfireContext *ctx, uint8_t *srcdata, size_t sr
DesfireSecureChannelDecodeEV1(ctx, srcdata, srcdatalen, respcode, dstdata, dstdatalen);
break;
case DACEV2:
DesfireSecureChannelDecodeEV2(ctx, srcdata, srcdatalen, respcode, dstdata, dstdatalen);
break;
case DACNone:
memcpy(dstdata, srcdata, srcdatalen);