From d2491d342d05bb4fcf8f18329dd64a06f0b10d83 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 5 Jul 2021 19:31:42 +0300 Subject: [PATCH] move secure channel functions to separate file --- client/CMakeLists.txt | 1 + client/Makefile | 1 + client/src/mifare/desfirecore.c | 157 +--------------------- client/src/mifare/desfiresecurechan.c | 180 ++++++++++++++++++++++++++ client/src/mifare/desfiresecurechan.h | 27 ++++ 5 files changed, 210 insertions(+), 156 deletions(-) create mode 100644 client/src/mifare/desfiresecurechan.c create mode 100644 client/src/mifare/desfiresecurechan.h diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 0aa5f2dc3..4879e953b 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -226,6 +226,7 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/mifare/mifarehost.c ${PM3_ROOT}/client/src/nfc/ndef.c ${PM3_ROOT}/client/src/mifare/desfire_crypto.c + ${PM3_ROOT}/client/src/mifare/desfiresecurechan.c ${PM3_ROOT}/client/src/mifare/desfirecore.c ${PM3_ROOT}/client/src/uart/uart_posix.c ${PM3_ROOT}/client/src/uart/uart_win32.c diff --git a/client/Makefile b/client/Makefile index 9a2ef3c5c..45ddffe31 100644 --- a/client/Makefile +++ b/client/Makefile @@ -590,6 +590,7 @@ SRCS = aiddesfire.c \ loclass/ikeys.c \ mifare/desfire_crypto.c \ mifare/desfirecore.c \ + mifare/desfiresecurechan.c \ mifare/mad.c \ mifare/mfkey.c \ mifare/mifare4.c \ diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 9b80ede51..ef8830302 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -31,6 +31,7 @@ #include "iso7816/iso7816core.h" // APDU logging #include "util_posix.h" // msleep #include "mifare/desfire_crypto.h" +#include "desfiresecurechan.h" const CLIParserOption DesfireAlgoOpts[] = { {T_DES, "des"}, @@ -543,162 +544,6 @@ static int DesfireExchangeISO(bool activate_field, DesfireContext *ctx, uint8_t return PM3_SUCCESS; } -static void DesfireCryptoEncDec(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode) { - uint8_t data[1024] = {0}; - - switch(ctx->keyType) { - case T_DES: - if (ctx->secureChannel == DACd40) { - if (encode) - des_encrypt_ecb(data, srcdata, srcdatalen, ctx->key); - else - des_decrypt_ecb(data, srcdata, srcdatalen, ctx->key); - } if (ctx->secureChannel == DACEV1) { - if (encode) - des_encrypt_cbc(data, srcdata, srcdatalen, ctx->key, ctx->IV); - else - des_decrypt_cbc(data, srcdata, srcdatalen, ctx->key, ctx->IV); - } - - if (dstdata) - memcpy(dstdata, data, srcdatalen); - break; - case T_3DES: - break; - case T_3K3DES: - break; - case T_AES: - if (encode) - aes_encode(ctx->IV, ctx->key, srcdata, data, srcdatalen); - else - aes_decode(ctx->IV, ctx->key, srcdata, data, srcdatalen); - if (dstdata) - memcpy(dstdata, data, srcdatalen); - break; - } -} - -static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) { - memcpy(dstdata, srcdata, srcdatalen); - *dstdatalen = srcdatalen; - - uint8_t data[1024] = {0}; - size_t rlen = 0; - - switch(ctx->commMode) { - case DCMPlain: - memcpy(dstdata, srcdata, srcdatalen); - *dstdatalen = srcdatalen; - break; - case DCMMACed: - if (srcdatalen == 0) - break; - - rlen = padded_data_length(srcdatalen, desfire_get_key_block_length(ctx->keyType)); - memcpy(data, srcdata, srcdatalen); - DesfireCryptoEncDec(ctx, data, rlen, NULL, true); - memcpy(dstdata, srcdata, srcdatalen); - memcpy(&dstdata[srcdatalen], ctx->IV, desfire_get_key_block_length(ctx->keyType)); - *dstdatalen = rlen; - break; - case DCMEncrypted: - rlen = padded_data_length(srcdatalen + 2, desfire_get_key_block_length(ctx->keyType)); // 2 - crc16 - memcpy(data, srcdata, srcdatalen); - compute_crc(CRC_14443_A, data, srcdatalen, &data[srcdatalen], &data[srcdatalen + 1]); - DesfireCryptoEncDec(ctx, data, rlen, dstdata, true); - *dstdatalen = rlen; - break; - case DCMNone:; - } -} - -static void DesfireSecureChannelEncodeEV1(DesfireContext *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) { - memcpy(dstdata, srcdata, srcdatalen); - *dstdatalen = srcdatalen; - - switch(ctx->commMode) { - case DCMPlain: - case DCMMACed: - - break; - case DCMEncrypted: - break; - case DCMNone:; - } -} - -static void DesfireSecureChannelEncode(DesfireContext *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) { - switch(ctx->secureChannel) { - case DACd40: - DesfireSecureChannelEncodeD40(ctx, cmd, srcdata, srcdatalen, dstdata, dstdatalen); - break; - case DACEV1: - DesfireSecureChannelEncodeEV1(ctx, cmd, srcdata, srcdatalen, dstdata, dstdatalen); - break; - case DACEV2: - break; - case DACNone: - memcpy(dstdata, srcdata, srcdatalen); - *dstdatalen = srcdatalen; - break; - } -} - -static void DesfireSecureChannelDecodeD40(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t respcode, uint8_t *dstdata, size_t *dstdatalen) { - memcpy(dstdata, srcdata, srcdatalen); - *dstdatalen = srcdatalen; - - switch(ctx->commMode) { - case DCMMACed: - - break; - case DCMEncrypted: - break; - case DCMPlain: - case DACNone: - memcpy(dstdata, srcdata, srcdatalen); - *dstdatalen = srcdatalen; - break; - } -} - -static void DesfireSecureChannelDecodeEV1(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t respcode, uint8_t *dstdata, size_t *dstdatalen) { - memcpy(dstdata, srcdata, srcdatalen); - *dstdatalen = srcdatalen; - - switch(ctx->commMode) { - case DCMPlain: - case DCMMACed: - memcpy(dstdata, srcdata, srcdatalen - 8); - *dstdatalen = srcdatalen - 8; - - break; - case DCMEncrypted: - break; - case DACNone: - memcpy(dstdata, srcdata, srcdatalen); - *dstdatalen = srcdatalen; - break; - } -} - -static void DesfireSecureChannelDecode(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t respcode, uint8_t *dstdata, size_t *dstdatalen) { - switch(ctx->secureChannel) { - case DACd40: - DesfireSecureChannelDecodeD40(ctx, srcdata, srcdatalen, respcode, dstdata, dstdatalen); - break; - case DACEV1: - DesfireSecureChannelDecodeEV1(ctx, srcdata, srcdatalen, respcode, dstdata, dstdatalen); - break; - case DACEV2: - break; - case DACNone: - memcpy(dstdata, srcdata, srcdatalen); - *dstdatalen = srcdatalen; - break; - } -} - // move data from blockdata [format: ...] to single data block static void DesfireJoinBlockToBytes(uint8_t *blockdata, size_t blockdatacount, size_t blockdatasize, uint8_t *dstdata, size_t *dstdatalen) { *dstdatalen = 0; diff --git a/client/src/mifare/desfiresecurechan.c b/client/src/mifare/desfiresecurechan.c new file mode 100644 index 000000000..1838a000a --- /dev/null +++ b/client/src/mifare/desfiresecurechan.c @@ -0,0 +1,180 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2010 Romain Tartiere. +// Copyright (C) 2014 Iceman +// Copyright (C) 2021 Merlok +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// High frequency Desfire secure channel functions +//----------------------------------------------------------------------------- + +#include "desfiresecurechan.h" + +#include +#include +#include +#include "ui.h" +#include "crc.h" +#include "crc16.h" // crc16 ccitt +#include "crc32.h" +#include "commonutil.h" +#include "mifare/desfire_crypto.h" + + +void DesfireCryptoEncDec(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode) { + uint8_t data[1024] = {0}; + + switch(ctx->keyType) { + case T_DES: + if (ctx->secureChannel == DACd40) { + if (encode) + des_encrypt_ecb(data, srcdata, srcdatalen, ctx->key); + else + des_decrypt_ecb(data, srcdata, srcdatalen, ctx->key); + } if (ctx->secureChannel == DACEV1) { + if (encode) + des_encrypt_cbc(data, srcdata, srcdatalen, ctx->key, ctx->IV); + else + des_decrypt_cbc(data, srcdata, srcdatalen, ctx->key, ctx->IV); + } + + if (dstdata) + memcpy(dstdata, data, srcdatalen); + break; + case T_3DES: + break; + case T_3K3DES: + break; + case T_AES: + if (encode) + aes_encode(ctx->IV, ctx->key, srcdata, data, srcdatalen); + else + aes_decode(ctx->IV, ctx->key, srcdata, data, srcdatalen); + if (dstdata) + memcpy(dstdata, data, srcdatalen); + break; + } +} + +static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) { + memcpy(dstdata, srcdata, srcdatalen); + *dstdatalen = srcdatalen; + + uint8_t data[1024] = {0}; + size_t rlen = 0; + + switch(ctx->commMode) { + case DCMPlain: + memcpy(dstdata, srcdata, srcdatalen); + *dstdatalen = srcdatalen; + break; + case DCMMACed: + if (srcdatalen == 0) + break; + + rlen = padded_data_length(srcdatalen, desfire_get_key_block_length(ctx->keyType)); + memcpy(data, srcdata, srcdatalen); + DesfireCryptoEncDec(ctx, data, rlen, NULL, true); + memcpy(dstdata, srcdata, srcdatalen); + memcpy(&dstdata[srcdatalen], ctx->IV, 4); + *dstdatalen = rlen; + break; + case DCMEncrypted: + rlen = padded_data_length(srcdatalen + 2, desfire_get_key_block_length(ctx->keyType)); // 2 - crc16 + memcpy(data, srcdata, srcdatalen); + compute_crc(CRC_14443_A, data, srcdatalen, &data[srcdatalen], &data[srcdatalen + 1]); + DesfireCryptoEncDec(ctx, data, rlen, dstdata, true); + *dstdatalen = rlen; + break; + case DCMNone:; + } +} + +static void DesfireSecureChannelEncodeEV1(DesfireContext *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) { + memcpy(dstdata, srcdata, srcdatalen); + *dstdatalen = srcdatalen; + + switch(ctx->commMode) { + case DCMPlain: + case DCMMACed: + + break; + case DCMEncrypted: + break; + case DCMNone:; + } +} + +void DesfireSecureChannelEncode(DesfireContext *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) { + switch(ctx->secureChannel) { + case DACd40: + DesfireSecureChannelEncodeD40(ctx, cmd, srcdata, srcdatalen, dstdata, dstdatalen); + break; + case DACEV1: + DesfireSecureChannelEncodeEV1(ctx, cmd, srcdata, srcdatalen, dstdata, dstdatalen); + break; + case DACEV2: + break; + case DACNone: + memcpy(dstdata, srcdata, srcdatalen); + *dstdatalen = srcdatalen; + break; + } +} + +static void DesfireSecureChannelDecodeD40(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t respcode, uint8_t *dstdata, size_t *dstdatalen) { + memcpy(dstdata, srcdata, srcdatalen); + *dstdatalen = srcdatalen; + + switch(ctx->commMode) { + case DCMMACed: + + break; + case DCMEncrypted: + break; + case DCMPlain: + case DACNone: + memcpy(dstdata, srcdata, srcdatalen); + *dstdatalen = srcdatalen; + break; + } +} + +static void DesfireSecureChannelDecodeEV1(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t respcode, uint8_t *dstdata, size_t *dstdatalen) { + memcpy(dstdata, srcdata, srcdatalen); + *dstdatalen = srcdatalen; + + switch(ctx->commMode) { + case DCMPlain: + case DCMMACed: + memcpy(dstdata, srcdata, srcdatalen - 8); + *dstdatalen = srcdatalen - 8; + + break; + case DCMEncrypted: + break; + case DACNone: + memcpy(dstdata, srcdata, srcdatalen); + *dstdatalen = srcdatalen; + break; + } +} + +void DesfireSecureChannelDecode(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t respcode, uint8_t *dstdata, size_t *dstdatalen) { + switch(ctx->secureChannel) { + case DACd40: + DesfireSecureChannelDecodeD40(ctx, srcdata, srcdatalen, respcode, dstdata, dstdatalen); + break; + case DACEV1: + DesfireSecureChannelDecodeEV1(ctx, srcdata, srcdatalen, respcode, dstdata, dstdatalen); + break; + case DACEV2: + break; + case DACNone: + memcpy(dstdata, srcdata, srcdatalen); + *dstdatalen = srcdatalen; + break; + } +} diff --git a/client/src/mifare/desfiresecurechan.h b/client/src/mifare/desfiresecurechan.h new file mode 100644 index 000000000..df997eb54 --- /dev/null +++ b/client/src/mifare/desfiresecurechan.h @@ -0,0 +1,27 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2010 Romain Tartiere. +// Copyright (C) 2014 Iceman +// Copyright (C) 2021 Merlok +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// High frequency Desfire secure channel functions +//----------------------------------------------------------------------------- + +#ifndef __DESFIRESECURECHAN_H +#define __DESFIRESECURECHAN_H + +#include "common.h" +#include "mifare/desfirecore.h" +#include "mifare/desfire_crypto.h" +#include "mifare/mifare4.h" + +void DesfireCryptoEncDec(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode); + +void DesfireSecureChannelEncode(DesfireContext *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, 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); + + +#endif // __DESFIRESECURECHAN_H