diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 1a1890b11..454616643 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -1295,7 +1295,7 @@ static int DesfireAuthenticateISO(DesfireContext *dctx, DesfireSecureChannel sec // encode DesfireClearIV(dctx); - DesfireCryptoEncDec(dctx, false, both, rndlen * 2, both, true); // error 303 + DesfireCryptoEncDec(dctx, DCOMainKey, both, rndlen * 2, both, true); // error 303 // external authenticate res = DesfireISOExternalAuth(dctx, dctx->appSelected, dctx->keyNum, dctx->keyType, both); @@ -1314,7 +1314,7 @@ static int DesfireAuthenticateISO(DesfireContext *dctx, DesfireSecureChannel sec // decode rnddata uint8_t piccrnd2[64] = {0}; - DesfireCryptoEncDec(dctx, false, rnddata, rndlen * 2, piccrnd2, false); // error 307 + DesfireCryptoEncDec(dctx, DCOMainKey, rnddata, rndlen * 2, piccrnd2, false); // error 307 // check if (memcmp(hostrnd2, &piccrnd2[rndlen], rndlen) != 0) diff --git a/client/src/mifare/desfirecrypto.c b/client/src/mifare/desfirecrypto.c index 7501de141..95dc95b0e 100644 --- a/client/src/mifare/desfirecrypto.c +++ b/client/src/mifare/desfirecrypto.c @@ -217,7 +217,7 @@ 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 dir_to_send, bool encode, uint8_t *iv) { +void DesfireCryptoEncDecEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, 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}; @@ -234,10 +234,13 @@ void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *s size_t offset = 0; while (offset < srcdatalen) { - if (use_session_key) + if (key_type == DCOSessionKeyMac) { DesfireCryptoEncDecSingleBlock(ctx->sessionKeyMAC, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode); - else + } else if (key_type == DCOSessionKeyEnc) { + DesfireCryptoEncDecSingleBlock(ctx->sessionKeyEnc, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode); + } else { DesfireCryptoEncDecSingleBlock(ctx->key, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode); + } offset += block_size; } @@ -250,13 +253,13 @@ void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *s memcpy(dstdata, data, srcdatalen); } -void DesfireCryptoEncDec(DesfireContext *ctx, bool use_session_key, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode) { +void DesfireCryptoEncDec(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode) { 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); + DesfireCryptoEncDecEx(ctx, key_type, srcdata, srcdatalen, dstdata, dir_to_send, xencode, NULL); } static void DesfireCMACGenerateSubkeys(DesfireContext *ctx, uint8_t *sk1, uint8_t *sk2) { @@ -269,7 +272,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, true, ivect); + DesfireCryptoEncDecEx(ctx, DCOSessionKeyMac, l, kbs, l, true, true, ivect); bool txor = false; @@ -314,7 +317,7 @@ void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *data, size_t len, uint8_t * bin_xor(buffer + len - kbs, sk1, kbs); } - DesfireCryptoEncDec(ctx, true, buffer, len, NULL, true); + DesfireCryptoEncDec(ctx, DCOSessionKeyMac, buffer, len, NULL, true); if (cmac != NULL) memcpy(cmac, ctx->IV, kbs); @@ -484,7 +487,7 @@ int DesfireEV2CalcCMAC(DesfireContext *ctx, uint8_t cmd, uint8_t *data, size_t d if (data != NULL && datalen > 0) memcpy(&mdata[7], data, datalen); mdatalen = 1 + 2 + 4 + datalen; - + return aes_cmac8(NULL, ctx->sessionKeyMAC, mdata, mac, mdatalen); } diff --git a/client/src/mifare/desfirecrypto.h b/client/src/mifare/desfirecrypto.h index 2de188981..dfc9a0685 100644 --- a/client/src/mifare/desfirecrypto.h +++ b/client/src/mifare/desfirecrypto.h @@ -61,6 +61,11 @@ typedef enum { DCMEncryptedPlain } DesfireCommunicationMode; +typedef enum { + DCOMainKey, + DCOSessionKeyMac, + DCOSessionKeyEnc +} DesfireCryptoOpKeyType; typedef struct DesfireContextS { uint8_t keyNum; @@ -100,8 +105,8 @@ 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 dir_to_send, bool encode, uint8_t *iv); +void DesfireCryptoEncDec(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode); +void DesfireCryptoEncDecEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, 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); diff --git a/client/src/mifare/desfiresecurechan.c b/client/src/mifare/desfiresecurechan.c index 1fc5ed78a..0f6ad2bd4 100644 --- a/client/src/mifare/desfiresecurechan.c +++ b/client/src/mifare/desfiresecurechan.c @@ -166,7 +166,7 @@ static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint size_t srcmaclen = padded_data_length(srcdatalen - hdrlen, desfire_get_key_block_length(ctx->keyType)); uint8_t mac[32] = {0}; - DesfireCryptoEncDecEx(ctx, true, data, srcmaclen, NULL, true, true, mac); + DesfireCryptoEncDecEx(ctx, DCOSessionKeyMac, data, srcmaclen, NULL, true, true, mac); memcpy(dstdata, srcdata, srcdatalen); memcpy(&dstdata[srcdatalen], mac, DesfireGetMACLength(ctx)); @@ -181,7 +181,7 @@ static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint memcpy(dstdata, srcdata, hdrlen); //PrintAndLogEx(INFO, "src[%d]: %s", srcdatalen - hdrlen + 2, sprint_hex(data, srcdatalen - hdrlen + 2)); - DesfireCryptoEncDec(ctx, true, data, rlen - hdrlen, &dstdata[hdrlen], true); + DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, data, rlen - hdrlen, &dstdata[hdrlen], true); *dstdatalen = rlen; } else if (ctx->commMode == DCMEncryptedPlain) { @@ -191,7 +191,7 @@ static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint rlen = padded_data_length(srcdatalen - hdrlen, desfire_get_key_block_length(ctx->keyType)) + hdrlen; memcpy(data, srcdata, srcdatalen); memcpy(dstdata, srcdata, hdrlen); - DesfireCryptoEncDec(ctx, true, &data[hdrlen], rlen - hdrlen, &dstdata[hdrlen], true); + DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, &data[hdrlen], rlen - hdrlen, &dstdata[hdrlen], true); *dstdatalen = rlen; ctx->commMode = DCMEncrypted; } @@ -227,7 +227,7 @@ static void DesfireSecureChannelEncodeEV1(DesfireContext *ctx, uint8_t cmd, uint desfire_crc32_append(data, srcdatalen + 1); memcpy(dstdata, srcdata, hdrlen); - DesfireCryptoEncDec(ctx, true, &data[1 + hdrlen], rlen, &dstdata[hdrlen], true); + DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, &data[1 + hdrlen], rlen, &dstdata[hdrlen], true); *dstdatalen = hdrlen + rlen; } else if (ctx->commMode == DCMEncryptedPlain) { @@ -237,7 +237,7 @@ static void DesfireSecureChannelEncodeEV1(DesfireContext *ctx, uint8_t cmd, uint memcpy(dstdata, srcdata, hdrlen); memcpy(data, &srcdata[hdrlen], srcdatalen); rlen = padded_data_length(srcdatalen - hdrlen, desfire_get_key_block_length(ctx->keyType)); - DesfireCryptoEncDec(ctx, true, data, rlen, &dstdata[hdrlen], true); + DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, data, rlen, &dstdata[hdrlen], true); *dstdatalen = hdrlen + rlen; ctx->commMode = DCMEncrypted; } @@ -270,7 +270,7 @@ static void DesfireSecureChannelEncodeEV2(DesfireContext *ctx, uint8_t cmd, uint dstdata[0] = cmd; memcpy(&dstdata[1], srcdata, hdrlen); - DesfireCryptoEncDec(ctx, true, data, rlen, &dstdata[1 + hdrlen], true); + DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, data, rlen, &dstdata[1 + hdrlen], true); uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; DesfireEV2CalcCMAC(ctx, cmd, &dstdata[1], hdrlen + rlen, cmac); @@ -321,7 +321,7 @@ static void DesfireSecureChannelDecodeD40(DesfireContext *ctx, uint8_t *srcdata, 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); + DesfireCryptoEncDecEx(ctx, DCOSessionKeyMac, data, rlen, NULL, true, true, mac); if (memcmp(mac, &srcdata[srcdatalen - maclen], maclen) == 0) { *dstdatalen = srcdatalen - maclen; @@ -340,7 +340,7 @@ static void DesfireSecureChannelDecodeD40(DesfireContext *ctx, uint8_t *srcdata, return; } - DesfireCryptoEncDec(ctx, true, srcdata, srcdatalen, dstdata, false); + DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, srcdata, srcdatalen, dstdata, false); //PrintAndLogEx(INFO, "decoded[%d]: %s", srcdatalen, sprint_hex(dstdata, srcdatalen)); size_t puredatalen = DesfireSearchCRCPos(dstdata, srcdatalen, respcode, 2); @@ -392,7 +392,7 @@ static void DesfireSecureChannelDecodeEV1(DesfireContext *ctx, uint8_t *srcdata, return; } - DesfireCryptoEncDec(ctx, true, srcdata, srcdatalen, dstdata, false); + DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, srcdata, srcdatalen, dstdata, false); //PrintAndLogEx(INFO, "decoded[%d]: %s", srcdatalen, sprint_hex(dstdata, srcdatalen)); size_t puredatalen = DesfireSearchCRCPos(dstdata, srcdatalen, respcode, 4); @@ -447,12 +447,13 @@ static void DesfireSecureChannelDecodeEV2(DesfireContext *ctx, uint8_t *srcdata, PrintAndLogEx(WARNING, "Received MAC is not match with calculated"); PrintAndLogEx(INFO, " received MAC: %s", sprint_hex(&srcdata[*dstdatalen], desfire_get_key_block_length(ctx->keyType))); PrintAndLogEx(INFO, " calculated MAC: %s", sprint_hex(cmac, desfire_get_key_block_length(ctx->keyType))); + } else { + //PrintAndLogEx(INFO, "Received MAC OK"); } - DesfireEV2FillIV(ctx, true, NULL); // fill IV to ctx + DesfireEV2FillIV(ctx, false, NULL); // fill response IV to ctx - DesfireCryptoEncDec(ctx, true, srcdata, *dstdatalen, dstdata, false); - PrintAndLogEx(INFO, "decoded[%d]: %s", *dstdatalen, sprint_hex(dstdata, *dstdatalen)); + DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, srcdata, *dstdatalen, dstdata, false); size_t puredatalen = FindISO9797M2PaddingDataLen(dstdata, *dstdatalen); if (puredatalen != 0) {