mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 21:33:47 -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/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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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: <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) {
|
||||
*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