ev2 iv calc

This commit is contained in:
merlokk 2021-07-30 14:45:26 +03:00
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), desfire_get_key_block_length(ctx->keyType),
sprint_hex(ctx->IV, desfire_get_key_block_length(ctx->keyType))); sprint_hex(ctx->IV, desfire_get_key_block_length(ctx->keyType)));
if (ctx->secureChannel == DACEV2) { 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), sprint_hex(ctx->TI, 4),
ctx->cntrTx, ctx->cmdCntr);
ctx->cntrRx);
} }
} }
@ -1096,7 +1095,7 @@ static int DesfireAuthenticateEV2(DesfireContext *dctx, DesfireSecureChannel sec
// Let's send our auth command // Let's send our auth command
uint8_t cdata[2] = {dctx->keyNum, 0x00}; 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) { if (res != PM3_SUCCESS) {
return 1; return 1;
} }
@ -1175,7 +1174,7 @@ PrintAndLogEx(INFO, "IV : %s", sprint_hex(IV, CRYPTO_AES_BLOCK_SIZE));
uint8_t data[32] = {0}; 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; return 10;
PrintAndLogEx(INFO, "data : %s", sprint_hex(data, CRYPTO_AES_BLOCK_SIZE * 2)); 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) { if (firstauth) {
dctx->cntrRx = 0; dctx->cmdCntr = 0;
dctx->cntrTx = 0;
memcpy(dctx->TI, data, 4); memcpy(dctx->TI, data, 4);
} }
memset(dctx->IV, 0, DESFIRE_MAX_KEY_SIZE); 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)); memset(ctx->lastIV, 0, sizeof(ctx->lastIV));
ctx->lastCommand = 0; ctx->lastCommand = 0;
ctx->lastRequestZeroLen = false; ctx->lastRequestZeroLen = false;
ctx->cntrTx = 0; ctx->cmdCntr = 0;
ctx->cntrRx = 0;
memset(ctx->TI, 0, sizeof(ctx->TI)); 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) { if (ctx->secureChannel == DACd40) {
memset(ctx->IV, 0, DESFIRE_MAX_CRYPTO_BLOCK_SIZE); 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); 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); 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) { void desfire_crc32(const uint8_t *data, const size_t len, uint8_t *crc) {
crc32_ex(data, len, crc); crc32_ex(data, len, crc);
} }

View file

@ -82,9 +82,7 @@ typedef struct DesfireContextS {
uint8_t lastIV[DESFIRE_MAX_KEY_SIZE]; uint8_t lastIV[DESFIRE_MAX_KEY_SIZE];
uint8_t lastCommand; uint8_t lastCommand;
bool lastRequestZeroLen; bool lastRequestZeroLen;
//mf4Session_t AESSession; uint16_t cmdCntr; // for AES
uint16_t cntrTx; // for AES
uint16_t cntrRx; // for AES
uint8_t TI[4]; // for AES uint8_t TI[4]; // for AES
} DesfireContext; } DesfireContext;
@ -110,6 +108,7 @@ DesfireCommunicationMode DesfireFileCommModeToCommMode(uint8_t file_comm_mode);
uint8_t DesfireCommModeToFileCommMode(DesfireCommunicationMode 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 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(const uint8_t *data, const size_t len, uint8_t *crc);
void desfire_crc32_append(uint8_t *data, const size_t len); void desfire_crc32_append(uint8_t *data, const size_t len);

View file

@ -24,6 +24,7 @@
#include "mifare/desfire_crypto.h" #include "mifare/desfire_crypto.h"
static const uint8_t CommandsCanUseAnyChannel[] = { static const uint8_t CommandsCanUseAnyChannel[] = {
MFDES_S_ADDITIONAL_FRAME,
MFDES_READ_DATA, MFDES_READ_DATA,
MFDES_WRITE_DATA, MFDES_WRITE_DATA,
MFDES_GET_VALUE, MFDES_GET_VALUE,
@ -116,6 +117,9 @@ static const AllowedChannelModesS AllowedChannelModes[] = {
{MFDES_CHANGE_KEY, DACEV1, DCCNative, DCMEncryptedPlain}, {MFDES_CHANGE_KEY, DACEV1, DCCNative, DCMEncryptedPlain},
{MFDES_CHANGE_KEY_EV2, 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 #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) { void DesfireSecureChannelEncode(DesfireContext *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) {
ctx->lastCommand = cmd; ctx->lastCommand = cmd;
ctx->lastRequestZeroLen = (srcdatalen <= DesfireGetCmdHeaderLen(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); DesfireSecureChannelEncodeEV1(ctx, cmd, srcdata, srcdatalen, dstdata, dstdatalen);
break; break;
case DACEV2: case DACEV2:
DesfireSecureChannelEncodeEV2(ctx, cmd, srcdata, srcdatalen, dstdata, dstdatalen);
break; break;
case DACNone: case DACNone:
memcpy(dstdata, srcdata, srcdatalen); 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) { void DesfireSecureChannelDecode(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t respcode, uint8_t *dstdata, size_t *dstdatalen) {
switch (ctx->secureChannel) { switch (ctx->secureChannel) {
case DACd40: case DACd40:
@ -370,6 +387,7 @@ void DesfireSecureChannelDecode(DesfireContext *ctx, uint8_t *srcdata, size_t sr
DesfireSecureChannelDecodeEV1(ctx, srcdata, srcdatalen, respcode, dstdata, dstdatalen); DesfireSecureChannelDecodeEV1(ctx, srcdata, srcdatalen, respcode, dstdata, dstdatalen);
break; break;
case DACEV2: case DACEV2:
DesfireSecureChannelDecodeEV2(ctx, srcdata, srcdatalen, respcode, dstdata, dstdatalen);
break; break;
case DACNone: case DACNone:
memcpy(dstdata, srcdata, srcdatalen); memcpy(dstdata, srcdata, srcdatalen);