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; FileSettingsS fsettings;
DesfireCommunicationMode commMode = dctx.commMode; DesfireCommunicationMode commMode = dctx.commMode;
DesfireSetCommMode(&dctx, DCMMACed); DesfireSetCommMode(&dctx, DCMPlain);
res = DesfireGetFileSettingsStruct(&dctx, fnum, &fsettings); res = DesfireGetFileSettingsStruct(&dctx, fnum, &fsettings);
DesfireSetCommMode(&dctx, commMode); DesfireSetCommMode(&dctx, commMode);
@ -6365,6 +6365,9 @@ static int CmdHF14ADesReadData(const char *Cmd) {
} }
DesfireSetCommMode(&dctx, fsettings.commMode); 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) if (verbose)
PrintAndLogEx(INFO, "Got file type: %s. Option: %s. comm mode: %s", PrintAndLogEx(INFO, "Got file type: %s. Option: %s. comm mode: %s",

View file

@ -212,14 +212,12 @@ static void DesfireCryptoEncDecSingleBlock(uint8_t *key, DesfireCryptoAlgorythm
memcpy(dstdata, edata, block_size); 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 data[1024] = {0};
uint8_t xiv[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; uint8_t xiv[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
bool xencode = encode;
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);
xencode = false;
} }
size_t block_size = desfire_get_key_block_length(ctx->keyType); 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; size_t offset = 0;
while (offset < srcdatalen) { while (offset < srcdatalen) {
if (use_session_key) 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 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; 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) { 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) { 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]; uint8_t ivect[kbs];
memset(ivect, 0, 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; 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); 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 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 DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *cmac);
void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorythm keytype, uint8_t version); 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_DEBIT, DACd40, DCCNative, DCMPlain},
{MFDES_COMMIT_TRANSACTION, DACd40, DCCNative, DCMPlain}, {MFDES_COMMIT_TRANSACTION, DACd40, DCCNative, DCMPlain},
{MFDES_CLEAR_RECORD_FILE, DACd40, DCCNative, DCMPlain}, {MFDES_CLEAR_RECORD_FILE, DACd40, DCCNative, DCMPlain},
{MFDES_GET_FILE_SETTINGS, DACd40, DCCNative, DCMPlain},
{MFDES_GET_VALUE, DACd40, DCCNative, DCMMACed}, {MFDES_GET_VALUE, DACd40, DCCNative, DCMMACed},
{MFDES_CREDIT, 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) { 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); memcpy(dstdata, srcdata, srcdatalen);
*dstdatalen = srcdatalen; *dstdatalen = srcdatalen;
switch (ctx->commMode) { switch (ctx->commMode) {
case DCMMACed: case DCMMACed: {
//if (srcdatalen > 4) size_t maclen = DesfireGetMACLength(ctx);
// *dstdatalen = srcdatalen - 4; if (srcdatalen > maclen) {
// TODO check MAC!!! 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; break;
}
case DCMEncrypted: case DCMEncrypted:
if (srcdatalen < desfire_get_key_block_length(ctx->keyType)) { if (srcdatalen < desfire_get_key_block_length(ctx->keyType)) {
memcpy(dstdata, srcdata, srcdatalen); memcpy(dstdata, srcdata, srcdatalen);