mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
move secure channel functions to separate file
This commit is contained in:
parent
b63a991bc3
commit
d2491d342d
5 changed files with 210 additions and 156 deletions
|
@ -226,6 +226,7 @@ set (TARGET_SOURCES
|
||||||
${PM3_ROOT}/client/src/mifare/mifarehost.c
|
${PM3_ROOT}/client/src/mifare/mifarehost.c
|
||||||
${PM3_ROOT}/client/src/nfc/ndef.c
|
${PM3_ROOT}/client/src/nfc/ndef.c
|
||||||
${PM3_ROOT}/client/src/mifare/desfire_crypto.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/mifare/desfirecore.c
|
||||||
${PM3_ROOT}/client/src/uart/uart_posix.c
|
${PM3_ROOT}/client/src/uart/uart_posix.c
|
||||||
${PM3_ROOT}/client/src/uart/uart_win32.c
|
${PM3_ROOT}/client/src/uart/uart_win32.c
|
||||||
|
|
|
@ -590,6 +590,7 @@ SRCS = aiddesfire.c \
|
||||||
loclass/ikeys.c \
|
loclass/ikeys.c \
|
||||||
mifare/desfire_crypto.c \
|
mifare/desfire_crypto.c \
|
||||||
mifare/desfirecore.c \
|
mifare/desfirecore.c \
|
||||||
|
mifare/desfiresecurechan.c \
|
||||||
mifare/mad.c \
|
mifare/mad.c \
|
||||||
mifare/mfkey.c \
|
mifare/mfkey.c \
|
||||||
mifare/mifare4.c \
|
mifare/mifare4.c \
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "iso7816/iso7816core.h" // APDU logging
|
#include "iso7816/iso7816core.h" // APDU logging
|
||||||
#include "util_posix.h" // msleep
|
#include "util_posix.h" // msleep
|
||||||
#include "mifare/desfire_crypto.h"
|
#include "mifare/desfire_crypto.h"
|
||||||
|
#include "desfiresecurechan.h"
|
||||||
|
|
||||||
const CLIParserOption DesfireAlgoOpts[] = {
|
const CLIParserOption DesfireAlgoOpts[] = {
|
||||||
{T_DES, "des"},
|
{T_DES, "des"},
|
||||||
|
@ -543,162 +544,6 @@ static int DesfireExchangeISO(bool activate_field, DesfireContext *ctx, uint8_t
|
||||||
return PM3_SUCCESS;
|
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: <length, data><length, data>...] to single data block
|
// move data from blockdata [format: <length, data><length, data>...] to single data block
|
||||||
static void DesfireJoinBlockToBytes(uint8_t *blockdata, size_t blockdatacount, size_t blockdatasize, uint8_t *dstdata, size_t *dstdatalen) {
|
static void DesfireJoinBlockToBytes(uint8_t *blockdata, size_t blockdatacount, size_t blockdatasize, uint8_t *dstdata, size_t *dstdatalen) {
|
||||||
*dstdatalen = 0;
|
*dstdatalen = 0;
|
||||||
|
|
180
client/src/mifare/desfiresecurechan.c
Normal file
180
client/src/mifare/desfiresecurechan.c
Normal file
|
@ -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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <util.h>
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
27
client/src/mifare/desfiresecurechan.h
Normal file
27
client/src/mifare/desfiresecurechan.h
Normal file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue