regactoring desfire commands. textual fixes

This commit is contained in:
merlokk 2021-07-03 17:31:12 +03:00
parent 0d00f56777
commit 1b2442ec36
6 changed files with 223 additions and 181 deletions

View file

@ -1,5 +1,6 @@
//-----------------------------------------------------------------------------
// 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
@ -4997,6 +4998,133 @@ static int CmdHF14aDesMAD(const char *Cmd) {
return PM3_SUCCESS;
}
*/
static uint8_t defaultKeyNum = 0;
static enum DESFIRE_CRYPTOALGO defaultAlgoId = T_DES;
static uint8_t defaultKey[DESFIRE_MAX_KEY_SIZE] = {0};
static int defaultKdfAlgo = MFDES_KDF_ALGO_NONE;
static int defaultKdfInputLen = 0;
static uint8_t defaultKdfInput[50] = {0};
static DesfireSecureChannel defaultSecureChannel = DACEV1;
static DesfireCommandSet defaultCommSet = DCCNativeISO;
static DesfireCommunicationMode defaultCommMode = DCMPlain;
static int CmdDesGetSessionParameters(CLIParserContext *ctx, DesfireContext *dctx,
uint8_t keynoid, uint8_t algoid, uint8_t keyid,
uint8_t kdfid, uint8_t kdfiid,
uint8_t cmodeid, uint8_t ccsetid, uint8_t schannid,
int *securechannel) {
uint8_t keynum = defaultKeyNum;
int algores = defaultAlgoId;
uint8_t key[DESFIRE_MAX_KEY_SIZE] = {0};
memcpy(key, defaultKey, DESFIRE_MAX_KEY_SIZE);
int kdfAlgo = defaultKdfAlgo;
int kdfInputLen = defaultKdfInputLen;
uint8_t kdfInput[50] = {0};
memcpy(kdfInput, defaultKdfInput, defaultKdfInputLen);
int commmode = defaultCommMode;
int commset = defaultCommSet;
int secchann = defaultSecureChannel;
if (keynoid) {
keynum = arg_get_int_def(ctx, keynoid, keynum);
}
const CLIParserOption algo_opts[] = {
{T_DES, "des"},
{T_3DES, "2tdea"},
{T_3K3DES, "3tdea"},
{T_AES, "aes"},
};
if (algoid) {
if (CLIGetOptionList(arg_get_str(ctx, algoid), algo_opts, ARRAY_LENGTH(algo_opts), &algores))
return PM3_ESOFT;
PrintAndLogEx(INFO, "algo: %s", CLIGetOptionListStr(algo_opts, ARRAY_LENGTH(algo_opts), algores));
}
if (keyid) {
int keylen = 0;
uint8_t keydata[200] = {0};
if (CLIParamHexToBuf(arg_get_str(ctx, keyid), keydata, sizeof(keydata), &keylen))
return PM3_ESOFT;
if (keylen && keylen != key_size(algores)) {
PrintAndLogEx(ERR, "%s key must have %d bytes length instead of %d.", CLIGetOptionListStr(algo_opts, ARRAY_LENGTH(algo_opts), algores), key_size(algores), keylen);
return PM3_EINVARG;
}
if (keylen)
memcpy(key, keydata, keylen);
}
if (kdfid) {
const CLIParserOption kdf_opts[] = {
{MFDES_KDF_ALGO_NONE, "none"},
{MFDES_KDF_ALGO_AN10922, "an10922"},
{MFDES_KDF_ALGO_GALLAGHER, "gallagher"},
};
if (CLIGetOptionList(arg_get_str(ctx, kdfid), kdf_opts, ARRAY_LENGTH(kdf_opts), &kdfAlgo))
return PM3_ESOFT;
PrintAndLogEx(INFO, "kdf funct: %s", CLIGetOptionListStr(kdf_opts, ARRAY_LENGTH(kdf_opts), kdfAlgo));
}
if (kdfiid) {
int datalen = kdfInputLen;
uint8_t data[200] = {0};
if (CLIParamHexToBuf(arg_get_str(ctx, kdfiid), data, sizeof(data), &datalen))
return PM3_ESOFT;
if (datalen) {
kdfInputLen = datalen;
memcpy(kdfInput, data, datalen);
}
}
if (cmodeid) {
const CLIParserOption cmode_opts[] = {
{DCMPlain, "plain"},
{DCMMACed, "mac"},
{DCMEncrypted, "encrypt"},
};
if (CLIGetOptionList(arg_get_str(ctx, cmodeid), cmode_opts, ARRAY_LENGTH(cmode_opts), &commmode))
return PM3_ESOFT;
PrintAndLogEx(INFO, "comm mode: %s", CLIGetOptionListStr(cmode_opts, ARRAY_LENGTH(cmode_opts), commmode));
}
if (ccsetid) {
const CLIParserOption commc_opts[] = {
{DCCNative, "native"},
{DCCNativeISO, "niso"},
{DCCISO, "iso"},
};
if (CLIGetOptionList(arg_get_str(ctx, ccsetid), commc_opts, ARRAY_LENGTH(commc_opts), &commset))
return PM3_ESOFT;
PrintAndLogEx(INFO, "comm mode: %s", CLIGetOptionListStr(commc_opts, ARRAY_LENGTH(commc_opts), commset));
}
if (schannid) {
const CLIParserOption authc_opts[] = {
{DACd40, "d40"},
{DACEV1, "ev1"},
{DACEV2, "ev2"},
};
if (CLIGetOptionList(arg_get_str(ctx, schannid), authc_opts, ARRAY_LENGTH(authc_opts), &secchann))
return PM3_ESOFT;
PrintAndLogEx(INFO, "auth channel: %s", CLIGetOptionListStr(authc_opts, ARRAY_LENGTH(authc_opts), secchann));
}
DesfireSetKey(dctx, keynum, algores, key);
DesfireSetKdf(dctx, kdfAlgo, kdfInput, kdfInputLen);
DesfireSetCommandSet(dctx, commset);
DesfireSetCommMode(dctx, commmode);
if (securechannel)
*securechannel = secchann;
return PM3_SUCCESS;
}
static int CmdHF14ADesGetAIDs(const char *Cmd) {
CLIParserContext *ctx;
@ -5013,102 +5141,38 @@ static int CmdHF14ADesGetAIDs(const char *Cmd) {
arg_str0("k", "key", "<Key>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
arg_str0("f", "kdf", "<none/AN10922/gallagher>", "Key Derivation Function (KDF): None, AN10922, Gallagher"),
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Commpunicaton mode: plain/mac/encrypt"),
arg_str0("c", "commc", "<native/niso/iso>", "Commpunicaton channel: native/niso/iso"),
arg_str0("u", "authc", "<d40/ev1/ev2>", "Authentication channel: d40/ev1/ev2"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
bool APDULogging = arg_get_lit(ctx, 1);
bool verbose = arg_get_lit(ctx, 2);
uint8_t keyNum = arg_get_int_def(ctx, 3, 0); // defaultKeyId
const CLIParserOption algo_opts[] = {
{T_DES, "des"},
{T_3DES, "2tdea"},
{T_3K3DES, "3tdea"},
{T_AES, "aes"},
};
int ares = T_DES;
CLIGetOptionListWithReturn(ctx, 4, algo_opts, ARRAY_LENGTH(algo_opts), &ares);
PrintAndLogEx(INFO, "algo: %s", CLIGetOptionListStr(algo_opts, ARRAY_LENGTH(algo_opts), ares));
int keylen = 0;
uint8_t key[200] = {0};
CLIGetHexWithReturn(ctx, 5, key, &keylen);
if (keylen == 0) {
keylen = key_size(ares);
//memcpy(key, defaultkey, key_size(ares));
}
if (keylen != key_size(ares)) {
PrintAndLogEx(ERR, "%s key must have %d bytes length instead of %d.", CLIGetOptionListStr(algo_opts, ARRAY_LENGTH(algo_opts), ares), key_size(ares), keylen);
DesfireContext dctx;
int securechann = defaultSecureChannel;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, &securechann);
if (res) {
CLIParserFree(ctx);
return PM3_EINVARG;
return res;
}
const CLIParserOption kdf_opts[] = {
{MFDES_KDF_ALGO_NONE, "none"},
{MFDES_KDF_ALGO_AN10922, "an10922"},
{MFDES_KDF_ALGO_GALLAGHER, "gallagher"},
};
int kres = MFDES_KDF_ALGO_NONE;
CLIGetOptionListWithReturn(ctx, 6, kdf_opts, ARRAY_LENGTH(kdf_opts), &kres);
PrintAndLogEx(INFO, "kdf funct: %s", CLIGetOptionListStr(kdf_opts, ARRAY_LENGTH(kdf_opts), kres));
int kdfInputLen = 0;
uint8_t kdfInput[50] = {0};
CLIGetHexWithReturn(ctx, 7, kdfInput, &kdfInputLen);
const CLIParserOption cmode_opts[] = {
{DCMPlain, "plain"},
{DCMMACed, "mac"},
{DCMEncrypted, "encrypt"},
};
int commmode = DCMPlain;
CLIGetOptionListWithReturn(ctx, 8, cmode_opts, ARRAY_LENGTH(cmode_opts), &commmode);
PrintAndLogEx(INFO, "comm mode: %s", CLIGetOptionListStr(cmode_opts, ARRAY_LENGTH(cmode_opts), commmode));
const CLIParserOption commc_opts[] = {
{DCCNative, "native"},
{DCCNativeISO, "niso"},
{DCCISO, "iso"},
};
int commchann = DCCNativeISO;
CLIGetOptionListWithReturn(ctx, 9, commc_opts, ARRAY_LENGTH(commc_opts), &commchann);
PrintAndLogEx(INFO, "comm mode: %s", CLIGetOptionListStr(commc_opts, ARRAY_LENGTH(commc_opts), commchann));
const CLIParserOption authc_opts[] = {
{DACd40, "d40"},
{DACEV1, "ev1"},
{DACEV2, "ev2"},
};
int authchann = DACEV1;
CLIGetOptionListWithReturn(ctx, 10, authc_opts, ARRAY_LENGTH(authc_opts), &authchann);
PrintAndLogEx(INFO, "auth channel: %s", CLIGetOptionListStr(authc_opts, ARRAY_LENGTH(authc_opts), authchann));
SetAPDULogging(APDULogging);
CLIParserFree(ctx);
DesfireContext dctx;
DesfireSetKey(&dctx, keyNum, ares, key); // T_DES T_3DES T_3K3DES T_AES
DesfireSetCommandChannel(&dctx, commchann);
if (verbose)
DesfirePrintContext(&dctx);
int res = DesfireSelectAIDHex(&dctx, 0x000000, false, 0);
res = DesfireSelectAIDHex(&dctx, 0x000000, false, 0);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire select " _RED_("error") ".");
DropField();
return PM3_ESOFT;
}
res = DesfireAuthenticate(&dctx, authchann); //DACd40 DACEV1
res = DesfireAuthenticate(&dctx, securechann); //DACd40 DACEV1
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire authenticate " _RED_("error") ". Result: %d", res);
DropField();
@ -5157,102 +5221,38 @@ static int CmdHF14ADesGetAppNames(const char *Cmd) {
arg_str0("k", "key", "<Key>", "Key for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"),
arg_str0("f", "kdf", "<none/AN10922/gallagher>", "Key Derivation Function (KDF): None, AN10922, Gallagher"),
arg_str0("i", "kdfi", "<kdfi>", "KDF input (HEX 1-31 bytes)"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Commpunicaton mode: plain/mac/encrypt"),
arg_str0("c", "commc", "<native/niso/iso>", "Commpunicaton channel: native/niso/iso"),
arg_str0("u", "authc", "<d40/ev1/ev2>", "Authentication channel: d40/ev1/ev2"),
arg_str0("m", "cmode", "<plain/mac/encrypt>", "Communicaton mode: plain/mac/encrypt"),
arg_str0("c", "ccset", "<native/niso/iso>", "Communicaton command set: native/niso/iso"),
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
bool APDULogging = arg_get_lit(ctx, 1);
bool verbose = arg_get_lit(ctx, 2);
uint8_t keyNum = arg_get_int_def(ctx, 3, 0); // defaultKeyId
const CLIParserOption algo_opts[] = {
{T_DES, "des"},
{T_3DES, "2tdea"},
{T_3K3DES, "3tdea"},
{T_AES, "aes"},
};
int ares = T_DES;
CLIGetOptionListWithReturn(ctx, 4, algo_opts, ARRAY_LENGTH(algo_opts), &ares);
PrintAndLogEx(INFO, "algo: %s", CLIGetOptionListStr(algo_opts, ARRAY_LENGTH(algo_opts), ares));
int keylen = 0;
uint8_t key[200] = {0};
CLIGetHexWithReturn(ctx, 5, key, &keylen);
if (keylen == 0) {
keylen = key_size(ares);
//memcpy(key, defaultkey, key_size(ares));
}
if (keylen != key_size(ares)) {
PrintAndLogEx(ERR, "%s key must have %d bytes length instead of %d.", CLIGetOptionListStr(algo_opts, ARRAY_LENGTH(algo_opts), ares), key_size(ares), keylen);
CLIParserFree(ctx);
return PM3_EINVARG;
}
const CLIParserOption kdf_opts[] = {
{MFDES_KDF_ALGO_NONE, "none"},
{MFDES_KDF_ALGO_AN10922, "an10922"},
{MFDES_KDF_ALGO_GALLAGHER, "gallagher"},
};
int kres = MFDES_KDF_ALGO_NONE;
CLIGetOptionListWithReturn(ctx, 6, kdf_opts, ARRAY_LENGTH(kdf_opts), &kres);
PrintAndLogEx(INFO, "kdf funct: %s", CLIGetOptionListStr(kdf_opts, ARRAY_LENGTH(kdf_opts), kres));
int kdfInputLen = 0;
uint8_t kdfInput[50] = {0};
CLIGetHexWithReturn(ctx, 7, kdfInput, &kdfInputLen);
const CLIParserOption cmode_opts[] = {
{DCMPlain, "plain"},
{DCMMACed, "mac"},
{DCMEncrypted, "encrypt"},
};
int commmode = DCMPlain;
CLIGetOptionListWithReturn(ctx, 8, cmode_opts, ARRAY_LENGTH(cmode_opts), &commmode);
PrintAndLogEx(INFO, "comm mode: %s", CLIGetOptionListStr(cmode_opts, ARRAY_LENGTH(cmode_opts), commmode));
const CLIParserOption commc_opts[] = {
{DCCNative, "native"},
{DCCNativeISO, "niso"},
{DCCISO, "iso"},
};
int commchann = DCCNativeISO;
CLIGetOptionListWithReturn(ctx, 9, commc_opts, ARRAY_LENGTH(commc_opts), &commchann);
PrintAndLogEx(INFO, "comm mode: %s", CLIGetOptionListStr(commc_opts, ARRAY_LENGTH(commc_opts), commchann));
const CLIParserOption authc_opts[] = {
{DACd40, "d40"},
{DACEV1, "ev1"},
{DACEV2, "ev2"},
};
int authchann = DACEV1;
CLIGetOptionListWithReturn(ctx, 10, authc_opts, ARRAY_LENGTH(authc_opts), &authchann);
PrintAndLogEx(INFO, "auth channel: %s", CLIGetOptionListStr(authc_opts, ARRAY_LENGTH(authc_opts), authchann));
SetAPDULogging(APDULogging);
CLIParserFree(ctx);
DesfireContext dctx;
DesfireSetKey(&dctx, keyNum, ares, key);
DesfireSetCommandChannel(&dctx, commchann);
int securechann = defaultSecureChannel;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, &securechann);
if (res) {
CLIParserFree(ctx);
return res;
}
SetAPDULogging(APDULogging);
CLIParserFree(ctx);
int res = DesfireSelectAIDHex(&dctx, 0x000000, false, 0);
if (verbose)
DesfirePrintContext(&dctx);
res = DesfireSelectAIDHex(&dctx, 0x000000, false, 0);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire select " _RED_("error") ".");
DropField();
return PM3_ESOFT;
}
res = DesfireAuthenticate(&dctx, authchann);
res = DesfireAuthenticate(&dctx, securechann);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire authenticate " _RED_("error") ". Result: %d", res);
DropField();

View file

@ -1,5 +1,6 @@
//-----------------------------------------------------------------------------
// Iceman, 2014
// Copyright (C) Iceman, 2014
// 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

View file

@ -1,5 +1,6 @@
/*-
* 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

View file

@ -1,4 +1,24 @@
#ifndef __DESFIRE_CRYPTO_H
/*-
* 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 __DESFIRE_CRYPTO_H
#define __DESFIRE_CRYPTO_H
#include "common.h"
@ -7,6 +27,7 @@
#define MAX_CRYPTO_BLOCK_SIZE 16
#define DESFIRE_MAX_KEY_SIZE 24
/* Mifare DESFire EV1 Application crypto operations */
#define APPLICATION_CRYPTO_DES 0x00
#define APPLICATION_CRYPTO_3K3DES 0x40

View file

@ -9,7 +9,7 @@
//-----------------------------------------------------------------------------
// High frequency Desfire core functions
//-----------------------------------------------------------------------------
// Info from here and many other soursec from the internet
// Info from here and many other sources from the public internet sites
// https://github.com/revk/DESFireAES
// https://github.com/step21/desfire_rfid
// https://github.com/patsys/desfire-python/blob/master/Desfire/DESFire.py
@ -163,8 +163,8 @@ void DesfireClearContext(DesfireContext *ctx) {
ctx->keyType = T_DES;
memset(ctx->key, 0, sizeof(ctx->key));
ctx->authChannel = DACNone;
ctx->cmdChannel = DCCNative;
ctx->secureChannel = DACNone;
ctx->cmdSet = DCCNative;
ctx->commMode = DCMNone;
ctx->kdfAlgo = 0;
@ -175,7 +175,7 @@ void DesfireClearContext(DesfireContext *ctx) {
}
void DesfireClearSession(DesfireContext *ctx) {
ctx->authChannel = DACNone; // here none - not authenticared
ctx->secureChannel = DACNone; // here none - not authenticared
memset(ctx->sessionKeyMAC, 0, sizeof(ctx->sessionKeyMAC));
memset(ctx->sessionKeyEnc, 0, sizeof(ctx->sessionKeyEnc));
@ -185,6 +185,11 @@ void DesfireClearSession(DesfireContext *ctx) {
memset(ctx->TI, 0, sizeof(ctx->TI));
}
void DesfirePrintContext(DesfireContext *ctx) {
//PrintAndLogEx(INFO, "algo: %s", CLIGetOptionListStr(algo_opts, ARRAY_LENGTH(algo_opts), algores));
PrintAndLogEx(INFO, "Key num: %d Key type: %d Key[%d]: %s", ctx->keyNum, ctx->keyType, key_size(ctx->keyType), sprint_hex(ctx->key, key_size(ctx->keyType)));
}
void DesfireSetKey(DesfireContext *ctx, uint8_t keyNum, enum DESFIRE_CRYPTOALGO keyType, uint8_t *key) {
DesfireClearContext(ctx);
@ -193,8 +198,19 @@ void DesfireSetKey(DesfireContext *ctx, uint8_t keyNum, enum DESFIRE_CRYPTOALGO
memcpy(ctx->key, key, desfire_get_key_length(keyType));
}
void DesfireSetCommandChannel(DesfireContext *ctx, DesfireCommandChannel cmdChannel) {
ctx->cmdChannel = cmdChannel;
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) {
@ -342,7 +358,7 @@ static int DesfireExchangeISO(bool activate_field, DesfireContext *ctx, uint8_t
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) {
int res = PM3_SUCCESS;
switch(ctx->cmdChannel) {
switch(ctx->cmdSet) {
case DCCNative:
res = DesfireExchangeNative(activate_field, ctx, cmd, data, datalen, respcode, resp, resplen, enable_chaining, splitbysize);
break;
@ -397,17 +413,17 @@ int DesfireSelectAIDHex(DesfireContext *ctx, uint32_t aid1, bool select_two, uin
}
bool DesfireIsAuthenticated(DesfireContext *dctx) {
return dctx->authChannel != DACNone;
return dctx->secureChannel != DACNone;
}
int DesfireAuthenticate(DesfireContext *dctx, DesfireAuthChannel authChannel) {
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
// 3 different communication modes, PLAIN,MAC,CRYPTO
DesfireClearSession(dctx);
if (authChannel == DACNone)
if (secureChannel == DACNone)
return PM3_SUCCESS;
mbedtls_aes_context ctx;
@ -456,8 +472,8 @@ int DesfireAuthenticate(DesfireContext *dctx, DesfireAuthChannel authChannel) {
}
uint8_t subcommand = MFDES_AUTHENTICATE;
dctx->authChannel = authChannel;
if (dctx->authChannel == DACEV1) {
dctx->secureChannel = secureChannel;
if (dctx->secureChannel == DACEV1) {
if (dctx->keyType == T_AES)
subcommand = MFDES_AUTHENTICATE_AES;
else
@ -522,7 +538,7 @@ int DesfireAuthenticate(DesfireContext *dctx, DesfireAuthChannel authChannel) {
uint8_t encRndA[16] = {0x00};
// - Encrypt our response
if (dctx->authChannel == DACd40) {
if (dctx->secureChannel == DACd40) {
des_decrypt(encRndA, RndA, key->data);
memcpy(both, encRndA, rndlen);
@ -532,7 +548,7 @@ int DesfireAuthenticate(DesfireContext *dctx, DesfireAuthChannel authChannel) {
des_decrypt(encRndB, rotRndB, key->data);
memcpy(both + rndlen, encRndB, rndlen);
} else if (dctx->authChannel == DACEV1 && dctx->keyType != T_AES) {
} else if (dctx->secureChannel == DACEV1 && dctx->keyType != T_AES) {
if (dctx->keyType == T_3DES) {
uint8_t tmp[16] = {0x00};
memcpy(tmp, RndA, rndlen);
@ -558,7 +574,7 @@ int DesfireAuthenticate(DesfireContext *dctx, DesfireAuthChannel authChannel) {
PrintAndLogEx(DEBUG, "EncBoth: %s", sprint_hex(both, 32));
}
}
} else if (dctx->authChannel == DACEV1 && dctx->keyType == T_AES) {
} else if (dctx->secureChannel == DACEV1 && dctx->keyType == T_AES) {
uint8_t tmp[32] = {0x00};
memcpy(tmp, RndA, rndlen);
memcpy(tmp + rndlen, rotRndB, rndlen);
@ -637,7 +653,7 @@ PrintAndLogEx(INFO, "Generated_RndA : %s", sprint_hex(encRndA, rndlen));
memcpy(&dctx->sessionKeyEnc[8], dctx->sessionKeyEnc, 8);
}
if (dctx->authChannel == DACEV1) {
if (dctx->secureChannel == DACEV1) {
cmac_generate_subkeys(&sesskey, MCD_RECEIVE);
//key->cmac_sk1 and key->cmac_sk2
//memcpy(dctx->sessionKeyEnc, sesskey.data, desfire_get_key_length(dctx->keyType));

View file

@ -28,13 +28,13 @@ typedef enum {
DACd40,
DACEV1,
DACEV2
} DesfireAuthChannel;
} DesfireSecureChannel;
typedef enum {
DCCNative,
DCCNativeISO,
DCCISO
} DesfireCommandChannel;
} DesfireCommandSet;
typedef enum {
DCMNone,
@ -54,9 +54,9 @@ typedef struct DesfireContextS {
uint8_t kdfInputLen;
uint8_t kdfInput[31];
DesfireAuthChannel authChannel; // none/d40/ev1/ev2
DesfireCommandChannel cmdChannel; // native/nativeiso/iso
DesfireCommunicationMode commMode; // plain/mac/enc
DesfireSecureChannel secureChannel; // none/d40/ev1/ev2
DesfireCommandSet cmdSet; // native/nativeiso/iso
DesfireCommunicationMode commMode; // plain/mac/enc
uint8_t sessionKeyMAC[DESF_MAX_KEY_LEN];
uint8_t sessionKeyEnc[DESF_MAX_KEY_LEN]; // look at mifare4.h - mf4Session_t
@ -68,9 +68,12 @@ typedef struct DesfireContextS {
} DesfireContext;
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 DesfireSetCommandChannel(DesfireContext *ctx, DesfireCommandChannel cmdChannel);
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);
@ -82,7 +85,7 @@ int DesfireExchangeEx(bool activate_field, DesfireContext *ctx, uint8_t cmd, uin
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, DesfireAuthChannel authChannel);
int DesfireAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel);
bool DesfireIsAuthenticated(DesfireContext *dctx);
int DesfireGetAIDList(DesfireContext *dctx, uint8_t *resp, size_t *resplen);