diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 384e67049..c29f74cc6 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -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 for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"), arg_str0("f", "kdf", "", "Key Derivation Function (KDF): None, AN10922, Gallagher"), arg_str0("i", "kdfi", "", "KDF input (HEX 1-31 bytes)"), - arg_str0("m", "cmode", "", "Commpunicaton mode: plain/mac/encrypt"), - arg_str0("c", "commc", "", "Commpunicaton channel: native/niso/iso"), - arg_str0("u", "authc", "", "Authentication channel: d40/ev1/ev2"), + arg_str0("m", "cmode", "", "Communicaton mode: plain/mac/encrypt"), + arg_str0("c", "ccset", "", "Communicaton command set: native/niso/iso"), + arg_str0("s", "schann", "", "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 for authenticate (HEX 8(DES), 16(2TDEA or AES) or 24(3TDEA) bytes)"), arg_str0("f", "kdf", "", "Key Derivation Function (KDF): None, AN10922, Gallagher"), arg_str0("i", "kdfi", "", "KDF input (HEX 1-31 bytes)"), - arg_str0("m", "cmode", "", "Commpunicaton mode: plain/mac/encrypt"), - arg_str0("c", "commc", "", "Commpunicaton channel: native/niso/iso"), - arg_str0("u", "authc", "", "Authentication channel: d40/ev1/ev2"), + arg_str0("m", "cmode", "", "Communicaton mode: plain/mac/encrypt"), + arg_str0("c", "ccset", "", "Communicaton command set: native/niso/iso"), + arg_str0("s", "schann", "", "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(); diff --git a/client/src/cmdhfmfdes.h b/client/src/cmdhfmfdes.h index eb4dd77e0..60ef9c35f 100644 --- a/client/src/cmdhfmfdes.h +++ b/client/src/cmdhfmfdes.h @@ -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 diff --git a/client/src/mifare/desfire_crypto.c b/client/src/mifare/desfire_crypto.c index 6ec606227..43c0ae3bf 100644 --- a/client/src/mifare/desfire_crypto.c +++ b/client/src/mifare/desfire_crypto.c @@ -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 diff --git a/client/src/mifare/desfire_crypto.h b/client/src/mifare/desfire_crypto.h index 71d17aea7..281b33978 100644 --- a/client/src/mifare/desfire_crypto.h +++ b/client/src/mifare/desfire_crypto.h @@ -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 + * + * $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 diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 18aa09265..f4bf93d0a 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -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)); diff --git a/client/src/mifare/desfirecore.h b/client/src/mifare/desfirecore.h index a0b31babb..079c0efe6 100644 --- a/client/src/mifare/desfirecore.h +++ b/client/src/mifare/desfirecore.h @@ -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);