mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
create new desfirecrypto
This commit is contained in:
parent
f74e5db6f0
commit
c22050b638
8 changed files with 220 additions and 153 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/desfirecrypto.c
|
||||
${PM3_ROOT}/client/src/mifare/desfiresecurechan.c
|
||||
${PM3_ROOT}/client/src/mifare/desfirecore.c
|
||||
${PM3_ROOT}/client/src/uart/uart_posix.c
|
||||
|
|
|
@ -589,6 +589,7 @@ SRCS = aiddesfire.c \
|
|||
loclass/elite_crack.c \
|
||||
loclass/ikeys.c \
|
||||
mifare/desfire_crypto.c \
|
||||
mifare/desfirecrypto.c \
|
||||
mifare/desfirecore.c \
|
||||
mifare/desfiresecurechan.c \
|
||||
mifare/mad.c \
|
||||
|
|
|
@ -203,34 +203,6 @@ void DesfireAIDUintToByte(uint32_t aid, uint8_t *data) {
|
|||
data[2] = (aid >> 16) & 0xff;
|
||||
}
|
||||
|
||||
void DesfireClearContext(DesfireContext *ctx) {
|
||||
ctx->keyNum = 0;
|
||||
ctx->keyType = T_DES;
|
||||
memset(ctx->key, 0, sizeof(ctx->key));
|
||||
|
||||
ctx->secureChannel = DACNone;
|
||||
ctx->cmdSet = DCCNative;
|
||||
ctx->commMode = DCMNone;
|
||||
|
||||
ctx->kdfAlgo = 0;
|
||||
ctx->kdfInputLen = 0;
|
||||
memset(ctx->kdfInput, 0, sizeof(ctx->kdfInput));
|
||||
|
||||
DesfireClearSession(ctx);
|
||||
}
|
||||
|
||||
void DesfireClearSession(DesfireContext *ctx) {
|
||||
ctx->secureChannel = DACNone; // here none - not authenticared
|
||||
|
||||
memset(ctx->IV, 0, sizeof(ctx->IV));
|
||||
memset(ctx->sessionKeyMAC, 0, sizeof(ctx->sessionKeyMAC));
|
||||
memset(ctx->sessionKeyEnc, 0, sizeof(ctx->sessionKeyEnc));
|
||||
memset(ctx->lastIV, 0, sizeof(ctx->lastIV));
|
||||
ctx->cntrTx = 0;
|
||||
ctx->cntrRx = 0;
|
||||
memset(ctx->TI, 0, sizeof(ctx->TI));
|
||||
}
|
||||
|
||||
void DesfirePrintContext(DesfireContext *ctx) {
|
||||
PrintAndLogEx(INFO, "Key num: %d Key algo: %s Key[%d]: %s",
|
||||
ctx->keyNum,
|
||||
|
@ -258,29 +230,6 @@ void DesfirePrintContext(DesfireContext *ctx) {
|
|||
}
|
||||
}
|
||||
|
||||
void DesfireSetKey(DesfireContext *ctx, uint8_t keyNum, enum DESFIRE_CRYPTOALGO keyType, uint8_t *key) {
|
||||
DesfireClearContext(ctx);
|
||||
|
||||
ctx->keyNum = keyNum;
|
||||
ctx->keyType = keyType;
|
||||
memcpy(ctx->key, key, desfire_get_key_length(keyType));
|
||||
}
|
||||
|
||||
void DesfireSetCommandSet(DesfireContext *ctx, DesfireCommandSet cmdSet) {
|
||||
ctx->cmdSet = cmdSet;
|
||||
}
|
||||
|
||||
void DesfireSetCommMode(DesfireContext *ctx, DesfireCommunicationMode commMode) {
|
||||
ctx->commMode = commMode;
|
||||
}
|
||||
|
||||
void DesfireSetKdf(DesfireContext *ctx, uint8_t kdfAlgo, uint8_t *kdfInput, uint8_t kdfInputLen) {
|
||||
ctx->kdfAlgo = kdfAlgo;
|
||||
ctx->kdfInputLen = kdfInputLen;
|
||||
if (kdfInputLen)
|
||||
memcpy(ctx->kdfInput, kdfInput, kdfInputLen);
|
||||
}
|
||||
|
||||
static int DESFIRESendApdu(bool activate_field, sAPDU apdu, uint8_t *result, uint32_t max_result_len, uint32_t *result_len, uint16_t *sw) {
|
||||
if (result_len) *result_len = 0;
|
||||
if (sw) *sw = 0;
|
||||
|
@ -648,10 +597,6 @@ int DesfireSelectAIDHex(DesfireContext *ctx, uint32_t aid1, bool select_two, uin
|
|||
return DesfireSelectAID(ctx, data, (select_two) ? &data[3] : NULL);
|
||||
}
|
||||
|
||||
bool DesfireIsAuthenticated(DesfireContext *dctx) {
|
||||
return dctx->secureChannel != DACNone;
|
||||
}
|
||||
|
||||
int DesfireAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel) {
|
||||
// 3 different way to authenticate AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32)
|
||||
// 4 different crypto arg1 DES, 3DES, 3K3DES, AES
|
||||
|
|
|
@ -15,78 +15,22 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "cliparser.h"
|
||||
#include "mifare/desfirecrypto.h"
|
||||
#include "mifare/desfire_crypto.h"
|
||||
#include "mifare/mifare4.h"
|
||||
|
||||
#define DESF_MAX_KEY_LEN 24
|
||||
|
||||
#define DESFIRE_GET_ISO_STATUS(x) ( ((uint16_t)(0x91<<8)) + (uint16_t)x )
|
||||
|
||||
typedef enum DESFIRE_CRYPTOALGO DesfireCryptoAlgorythm;
|
||||
|
||||
typedef enum {
|
||||
DACNone,
|
||||
DACd40,
|
||||
DACEV1,
|
||||
DACEV2
|
||||
} DesfireSecureChannel;
|
||||
|
||||
typedef enum {
|
||||
DCCNative,
|
||||
DCCNativeISO,
|
||||
DCCISO
|
||||
} DesfireCommandSet;
|
||||
|
||||
typedef enum {
|
||||
DCMNone,
|
||||
DCMPlain,
|
||||
DCMMACed,
|
||||
DCMEncrypted
|
||||
} DesfireCommunicationMode;
|
||||
|
||||
|
||||
typedef struct DesfireContextS {
|
||||
uint8_t keyNum;
|
||||
enum DESFIRE_CRYPTOALGO keyType; // des/2tdea/3tdea/aes
|
||||
uint8_t key[DESF_MAX_KEY_LEN];
|
||||
|
||||
// KDF finction
|
||||
uint8_t kdfAlgo;
|
||||
uint8_t kdfInputLen;
|
||||
uint8_t kdfInput[31];
|
||||
|
||||
DesfireSecureChannel secureChannel; // none/d40/ev1/ev2
|
||||
DesfireCommandSet cmdSet; // native/nativeiso/iso
|
||||
DesfireCommunicationMode commMode; // plain/mac/enc
|
||||
|
||||
uint8_t IV[DESF_MAX_KEY_LEN];
|
||||
uint8_t sessionKeyMAC[DESF_MAX_KEY_LEN];
|
||||
uint8_t sessionKeyEnc[DESF_MAX_KEY_LEN]; // look at mifare4.h - mf4Session_t
|
||||
uint8_t lastIV[DESF_MAX_KEY_LEN];
|
||||
//mf4Session_t AESSession;
|
||||
uint16_t cntrTx; // for AES
|
||||
uint16_t cntrRx; // for AES
|
||||
uint8_t TI[4]; // for AES
|
||||
} DesfireContext;
|
||||
|
||||
extern const CLIParserOption DesfireAlgoOpts[];
|
||||
extern const CLIParserOption DesfireKDFAlgoOpts[];
|
||||
extern const CLIParserOption DesfireCommunicationModeOpts[];
|
||||
extern const CLIParserOption DesfireCommandSetOpts[];
|
||||
extern const CLIParserOption DesfireSecureChannelOpts[];
|
||||
|
||||
void DesfireClearContext(DesfireContext *ctx);
|
||||
void DesfirePrintContext(DesfireContext *ctx);
|
||||
void DesfireClearSession(DesfireContext *ctx);
|
||||
void DesfireSetKey(DesfireContext *ctx, uint8_t keyNum, enum DESFIRE_CRYPTOALGO keyType, uint8_t *key);
|
||||
void DesfireSetCommandSet(DesfireContext *ctx, DesfireCommandSet cmdSet);
|
||||
void DesfireSetCommMode(DesfireContext *ctx, DesfireCommunicationMode commMode);
|
||||
void DesfireSetKdf(DesfireContext *ctx, uint8_t kdfAlgo, uint8_t *kdfInput, uint8_t kdfInputLen);
|
||||
|
||||
const char *DesfireGetErrorString(int res, uint16_t *sw);
|
||||
uint32_t DesfireAIDByteToUint(uint8_t *data);
|
||||
void DesfireAIDUintToByte(uint32_t aid, uint8_t *data);
|
||||
|
||||
void DesfirePrintContext(DesfireContext *ctx);
|
||||
|
||||
int DesfireExchange(DesfireContext *ctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *respcode, uint8_t *resp, size_t *resplen);
|
||||
int DesfireExchangeEx(bool activate_field, DesfireContext *ctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *respcode, uint8_t *resp, size_t *resplen, bool enable_chaining, size_t splitbysize);
|
||||
|
||||
|
@ -94,7 +38,6 @@ int DesfireSelectAID(DesfireContext *ctx, uint8_t *aid1, uint8_t *aid2);
|
|||
int DesfireSelectAIDHex(DesfireContext *ctx, uint32_t aid1, bool select_two, uint32_t aid2);
|
||||
|
||||
int DesfireAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel);
|
||||
bool DesfireIsAuthenticated(DesfireContext *dctx);
|
||||
|
||||
int DesfireGetAIDList(DesfireContext *dctx, uint8_t *resp, size_t *resplen);
|
||||
int DesfireGetDFList(DesfireContext *dctx, uint8_t *resp, size_t *resplen);
|
||||
|
|
123
client/src/mifare/desfirecrypto.c
Normal file
123
client/src/mifare/desfirecrypto.c
Normal file
|
@ -0,0 +1,123 @@
|
|||
/*-
|
||||
* Copyright (C) 2010, Romain Tartiere.
|
||||
* Copyright (C) 2021 Merlok
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "desfirecrypto.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 DesfireClearContext(DesfireContext *ctx) {
|
||||
ctx->keyNum = 0;
|
||||
ctx->keyType = T_DES;
|
||||
memset(ctx->key, 0, sizeof(ctx->key));
|
||||
|
||||
ctx->secureChannel = DACNone;
|
||||
ctx->cmdSet = DCCNative;
|
||||
ctx->commMode = DCMNone;
|
||||
|
||||
ctx->kdfAlgo = 0;
|
||||
ctx->kdfInputLen = 0;
|
||||
memset(ctx->kdfInput, 0, sizeof(ctx->kdfInput));
|
||||
|
||||
DesfireClearSession(ctx);
|
||||
}
|
||||
|
||||
void DesfireClearSession(DesfireContext *ctx) {
|
||||
ctx->secureChannel = DACNone; // here none - not authenticared
|
||||
|
||||
memset(ctx->IV, 0, sizeof(ctx->IV));
|
||||
memset(ctx->sessionKeyMAC, 0, sizeof(ctx->sessionKeyMAC));
|
||||
memset(ctx->sessionKeyEnc, 0, sizeof(ctx->sessionKeyEnc));
|
||||
memset(ctx->lastIV, 0, sizeof(ctx->lastIV));
|
||||
ctx->cntrTx = 0;
|
||||
ctx->cntrRx = 0;
|
||||
memset(ctx->TI, 0, sizeof(ctx->TI));
|
||||
}
|
||||
|
||||
void DesfireSetKey(DesfireContext *ctx, uint8_t keyNum, enum DESFIRE_CRYPTOALGO keyType, uint8_t *key) {
|
||||
DesfireClearContext(ctx);
|
||||
|
||||
ctx->keyNum = keyNum;
|
||||
ctx->keyType = keyType;
|
||||
memcpy(ctx->key, key, desfire_get_key_length(keyType));
|
||||
}
|
||||
|
||||
void DesfireSetCommandSet(DesfireContext *ctx, DesfireCommandSet cmdSet) {
|
||||
ctx->cmdSet = cmdSet;
|
||||
}
|
||||
|
||||
void DesfireSetCommMode(DesfireContext *ctx, DesfireCommunicationMode commMode) {
|
||||
ctx->commMode = commMode;
|
||||
}
|
||||
|
||||
void DesfireSetKdf(DesfireContext *ctx, uint8_t kdfAlgo, uint8_t *kdfInput, uint8_t kdfInputLen) {
|
||||
ctx->kdfAlgo = kdfAlgo;
|
||||
ctx->kdfInputLen = kdfInputLen;
|
||||
if (kdfInputLen)
|
||||
memcpy(ctx->kdfInput, kdfInput, kdfInputLen);
|
||||
}
|
||||
|
||||
bool DesfireIsAuthenticated(DesfireContext *dctx) {
|
||||
return dctx->secureChannel != DACNone;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
91
client/src/mifare/desfirecrypto.h
Normal file
91
client/src/mifare/desfirecrypto.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*-
|
||||
* Copyright (C) 2010, Romain Tartiere.
|
||||
* Copyright (C) 2021 Merlok
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __DESFIRECRYPTO_H
|
||||
#define __DESFIRECRYPTO_H
|
||||
|
||||
#include "common.h"
|
||||
#include "mifare/desfire_crypto.h"
|
||||
#include "mifare/mifare4.h"
|
||||
|
||||
#define DESF_MAX_KEY_LEN 24
|
||||
|
||||
#define DESFIRE_GET_ISO_STATUS(x) ( ((uint16_t)(0x91<<8)) + (uint16_t)x )
|
||||
|
||||
typedef enum DESFIRE_CRYPTOALGO DesfireCryptoAlgorythm;
|
||||
|
||||
typedef enum {
|
||||
DACNone,
|
||||
DACd40,
|
||||
DACEV1,
|
||||
DACEV2
|
||||
} DesfireSecureChannel;
|
||||
|
||||
typedef enum {
|
||||
DCCNative,
|
||||
DCCNativeISO,
|
||||
DCCISO
|
||||
} DesfireCommandSet;
|
||||
|
||||
typedef enum {
|
||||
DCMNone,
|
||||
DCMPlain,
|
||||
DCMMACed,
|
||||
DCMEncrypted
|
||||
} DesfireCommunicationMode;
|
||||
|
||||
|
||||
typedef struct DesfireContextS {
|
||||
uint8_t keyNum;
|
||||
enum DESFIRE_CRYPTOALGO keyType; // des/2tdea/3tdea/aes
|
||||
uint8_t key[DESF_MAX_KEY_LEN];
|
||||
|
||||
// KDF finction
|
||||
uint8_t kdfAlgo;
|
||||
uint8_t kdfInputLen;
|
||||
uint8_t kdfInput[31];
|
||||
|
||||
DesfireSecureChannel secureChannel; // none/d40/ev1/ev2
|
||||
DesfireCommandSet cmdSet; // native/nativeiso/iso
|
||||
DesfireCommunicationMode commMode; // plain/mac/enc
|
||||
|
||||
uint8_t IV[DESF_MAX_KEY_LEN];
|
||||
uint8_t sessionKeyMAC[DESF_MAX_KEY_LEN];
|
||||
uint8_t sessionKeyEnc[DESF_MAX_KEY_LEN]; // look at mifare4.h - mf4Session_t
|
||||
uint8_t lastIV[DESF_MAX_KEY_LEN];
|
||||
//mf4Session_t AESSession;
|
||||
uint16_t cntrTx; // for AES
|
||||
uint16_t cntrRx; // for AES
|
||||
uint8_t TI[4]; // for AES
|
||||
} DesfireContext;
|
||||
|
||||
void DesfireClearContext(DesfireContext *ctx);
|
||||
void DesfireClearSession(DesfireContext *ctx);
|
||||
void DesfireSetKey(DesfireContext *ctx, uint8_t keyNum, enum DESFIRE_CRYPTOALGO keyType, uint8_t *key);
|
||||
void DesfireSetCommandSet(DesfireContext *ctx, DesfireCommandSet cmdSet);
|
||||
void DesfireSetCommMode(DesfireContext *ctx, DesfireCommunicationMode commMode);
|
||||
void DesfireSetKdf(DesfireContext *ctx, uint8_t kdfAlgo, uint8_t *kdfInput, uint8_t kdfInputLen);
|
||||
bool DesfireIsAuthenticated(DesfireContext *dctx);
|
||||
|
||||
|
||||
void DesfireCryptoEncDec(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode);
|
||||
|
||||
|
||||
#endif // __DESFIRECRYPTO_H
|
|
@ -22,42 +22,6 @@
|
|||
#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;
|
||||
|
|
|
@ -15,11 +15,10 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "mifare/desfirecore.h"
|
||||
#include "mifare/desfirecrypto.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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue