d40/mac mode works in mac and plain modes

This commit is contained in:
merlokk 2021-07-28 15:27:22 +03:00
commit b508ca3e5d
4 changed files with 36 additions and 14 deletions

View file

@ -6334,7 +6334,7 @@ static int CmdHF14ADesReadData(const char *Cmd) {
FileSettingsS fsettings;
DesfireCommunicationMode commMode = dctx.commMode;
DesfireSetCommMode(&dctx, DCMMACed);
DesfireSetCommMode(&dctx, DCMPlain);
res = DesfireGetFileSettingsStruct(&dctx, fnum, &fsettings);
DesfireSetCommMode(&dctx, commMode);
@ -6366,6 +6366,9 @@ static int CmdHF14ADesReadData(const char *Cmd) {
DesfireSetCommMode(&dctx, fsettings.commMode);
if (fsettings.fileCommMode != 0 && noauth)
PrintAndLogEx(WARNING, "File needs communication mode `%s` but there is no authentication", CLIGetOptionListStr(DesfireCommunicationModeOpts, fsettings.commMode));
if (verbose)
PrintAndLogEx(INFO, "Got file type: %s. Option: %s. comm mode: %s",
GetDesfireFileType(fsettings.fileType),

View file

@ -212,14 +212,12 @@ static void DesfireCryptoEncDecSingleBlock(uint8_t *key, DesfireCryptoAlgorythm
memcpy(dstdata, edata, block_size);
}
void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode, uint8_t *iv) {
void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool dir_to_send, bool encode, uint8_t *iv) {
uint8_t data[1024] = {0};
uint8_t xiv[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
bool xencode = encode;
if (ctx->secureChannel == DACd40) {
memset(ctx->IV, 0, DESFIRE_MAX_CRYPTO_BLOCK_SIZE);
xencode = false;
}
size_t block_size = desfire_get_key_block_length(ctx->keyType);
@ -232,9 +230,9 @@ void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *s
size_t offset = 0;
while (offset < srcdatalen) {
if (use_session_key)
DesfireCryptoEncDecSingleBlock(ctx->sessionKeyMAC, ctx->keyType, srcdata + offset, data + offset, xiv, encode, xencode);
DesfireCryptoEncDecSingleBlock(ctx->sessionKeyMAC, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode);
else
DesfireCryptoEncDecSingleBlock(ctx->key, ctx->keyType, srcdata + offset, data + offset, xiv, encode, xencode);
DesfireCryptoEncDecSingleBlock(ctx->key, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode);
offset += block_size;
}
@ -248,7 +246,12 @@ void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *s
}
void DesfireCryptoEncDec(DesfireContext *ctx, bool use_session_key, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode) {
DesfireCryptoEncDecEx(ctx, use_session_key, srcdata, srcdatalen, dstdata, encode, NULL);
bool dir_to_send = encode;
bool xencode = encode;
if (ctx->secureChannel == DACd40)
xencode = false;
DesfireCryptoEncDecEx(ctx, use_session_key, srcdata, srcdatalen, dstdata, dir_to_send, xencode, NULL);
}
static void DesfireCMACGenerateSubkeys(DesfireContext *ctx, uint8_t *sk1, uint8_t *sk2) {
@ -261,7 +264,7 @@ static void DesfireCMACGenerateSubkeys(DesfireContext *ctx, uint8_t *sk1, uint8_
uint8_t ivect[kbs];
memset(ivect, 0, kbs);
DesfireCryptoEncDecEx(ctx, true, l, kbs, l, true, ivect);
DesfireCryptoEncDecEx(ctx, true, l, kbs, l, true, true, ivect);
bool txor = false;

View file

@ -99,7 +99,7 @@ size_t DesfireGetMACLength(DesfireContext *ctx);
size_t DesfireSearchCRCPos(uint8_t *data, size_t datalen, uint8_t respcode, uint8_t crclen);
void DesfireCryptoEncDec(DesfireContext *ctx, bool use_session_key, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode);
void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode, uint8_t *iv);
void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool dir_to_send, bool encode, uint8_t *iv);
void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *cmac);
void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorythm keytype, uint8_t version);

View file

@ -58,6 +58,7 @@ static const AllowedChannelModesS AllowedChannelModes[] = {
{MFDES_DEBIT, DACd40, DCCNative, DCMPlain},
{MFDES_COMMIT_TRANSACTION, DACd40, DCCNative, DCMPlain},
{MFDES_CLEAR_RECORD_FILE, DACd40, DCCNative, DCMPlain},
{MFDES_GET_FILE_SETTINGS, DACd40, DCCNative, DCMPlain},
{MFDES_GET_VALUE, DACd40, DCCNative, DCMMACed},
{MFDES_CREDIT, DACd40, DCCNative, DCMMACed},
@ -249,16 +250,31 @@ void DesfireSecureChannelEncode(DesfireContext *ctx, uint8_t cmd, uint8_t *srcda
}
static void DesfireSecureChannelDecodeD40(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t respcode, uint8_t *dstdata, size_t *dstdatalen) {
uint8_t data[1024] = {0};
size_t rlen = 0;
memcpy(dstdata, srcdata, srcdatalen);
*dstdatalen = srcdatalen;
switch (ctx->commMode) {
case DCMMACed:
//if (srcdatalen > 4)
// *dstdatalen = srcdatalen - 4;
// TODO check MAC!!!
case DCMMACed: {
size_t maclen = DesfireGetMACLength(ctx);
if (srcdatalen > maclen) {
uint8_t mac[16] = {0};
rlen = padded_data_length(srcdatalen - maclen, desfire_get_key_block_length(ctx->keyType));
memcpy(data, srcdata, srcdatalen - maclen);
DesfireCryptoEncDecEx(ctx, true, data, rlen, NULL, true, true, mac);
if (memcmp(mac, &srcdata[srcdatalen - maclen], maclen) == 0) {
*dstdatalen = srcdatalen - maclen;
} else {
PrintAndLogEx(WARNING, "Received MAC is not match with calculated");
//PrintAndLogEx(INFO, " received MAC: %s", sprint_hex(&srcdata[srcdatalen - maclen], maclen));
//PrintAndLogEx(INFO, " calculated MAC: %s", sprint_hex(mac, maclen));
}
}
break;
}
case DCMEncrypted:
if (srcdatalen < desfire_get_key_block_length(ctx->keyType)) {
memcpy(dstdata, srcdata, srcdatalen);