From d716971430f02c723509172149228c090b9cc1a3 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 22 Aug 2021 23:12:16 +0300 Subject: [PATCH 1/6] detect lrp authentication --- client/src/cmdhfmfdes.c | 37 ++++++++++--------- client/src/mifare/desfirecore.c | 63 +++++++++++++++------------------ client/src/mifare/desfirecore.h | 3 +- 3 files changed, 50 insertions(+), 53 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 2685d7f0c..5b375cf15 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -1294,7 +1294,7 @@ static int CmdHF14ADesList(const char *Cmd) { return CmdTraceListAlias(Cmd, "hf mfdes", "des"); } -static int DesfireAuthCheck(DesfireContext_t *dctx, uint32_t appid, DesfireSecureChannel secureChannel, uint8_t *key) { +static int DesfireAuthCheck(DesfireContext_t *dctx, DesfireISOSelectWay way, uint32_t appID, DesfireSecureChannel secureChannel, uint8_t *key) { DesfireSetKeyNoClear(dctx, dctx->keyNum, dctx->keyType, key); int res = DesfireAuthenticate(dctx, secureChannel, false); @@ -1303,7 +1303,7 @@ static int DesfireAuthCheck(DesfireContext_t *dctx, uint32_t appid, DesfireSecur return PM3_SUCCESS; } else if (res < 7) { DropField(); - res = DesfireSelectAIDHex(dctx, appid, false, 0); + res = DesfireSelect(dctx, way, appID, NULL); if (res != PM3_SUCCESS) { return -10; } @@ -1335,6 +1335,7 @@ static int CmdHF14aDesDetect(const char *Cmd) { arg_str0("c", "ccset", "", "Communicaton command set: native/niso/iso"), arg_str0("s", "schann", "", "Secure channel: d40/ev1/ev2/lrp"), arg_str0(NULL, "aid", "", "Application ID (3 hex bytes, big endian)"), + arg_str0(NULL, "appisoid", "", "Application ISO ID (ISO DF ID) (2 hex bytes, big endian)."), arg_str0(NULL, "dict", "", "File with keys dictionary"), arg_lit0(NULL, "save", "save found key and parameters to defaults"), arg_param_end @@ -1346,8 +1347,9 @@ static int CmdHF14aDesDetect(const char *Cmd) { DesfireContext_t dctx; int securechann = defaultSecureChannel; - uint32_t appid = 0x000000; - int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, &securechann, DCMMACed, &appid, NULL); + uint32_t id = 0x000000; + DesfireISOSelectWay selectway = ISW6bAID; + int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, &securechann, DCMMACed, &id, &selectway); if (res) { CLIParserFree(ctx); return res; @@ -1355,22 +1357,22 @@ static int CmdHF14aDesDetect(const char *Cmd) { uint8_t dict_filename[FILE_PATH_SIZE + 2] = {0}; int dict_filenamelen = 0; - if (CLIParamStrToBuf(arg_get_str(ctx, 12), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) { + if (CLIParamStrToBuf(arg_get_str(ctx, 13), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) { PrintAndLogEx(FAILED, "File name too long or invalid."); CLIParserFree(ctx); return PM3_EINVARG; } - bool save = arg_get_lit(ctx, 13); + bool save = arg_get_lit(ctx, 14); SetAPDULogging(APDULogging); CLIParserFree(ctx); // no auth and fill KDF if needs - res = DesfireSelectAndAuthenticateEx(&dctx, securechann, appid, true, verbose); + res = DesfireSelectAndAuthenticateAppW(&dctx, securechann, selectway, id, true, verbose); if (res != PM3_SUCCESS) { DropField(); - PrintAndLogEx(FAILED, "Select AID 0x%06x " _RED_("failed") ". Result: %d", appid, res); + PrintAndLogEx(FAILED, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway, id), res, DesfireAuthErrorToStr(res)); return res; } @@ -1398,7 +1400,7 @@ static int CmdHF14aDesDetect(const char *Cmd) { } else { // if fail - check auth commands AuthCommandsChk_t authCmdCheck = {0}; - DesfireCheckAuthCommands(appid, NULL, 0, &authCmdCheck); + DesfireCheckAuthCommands(selectway, id, NULL, 0, &authCmdCheck); if (authCmdCheck.checked) { if (authCmdCheck.auth) { keytypes[T_DES] = true; @@ -1416,18 +1418,19 @@ static int CmdHF14aDesDetect(const char *Cmd) { keytypes[T_DES] = true; } - res = DesfireSelectAIDHex(&dctx, appid, false, 0); + res = DesfireSelectAndAuthenticateAppW(&dctx, securechann, selectway, id, true, verbose); if (res != PM3_SUCCESS) { - PrintAndLogEx(ERR, "Desfire select " _RED_("error") "."); + DropField(); + PrintAndLogEx(FAILED, "Select or authentication %s " _RED_("failed") ". Result [%d] %s", DesfireWayIDStr(selectway, id), res, DesfireAuthErrorToStr(res)); return res; } } if (verbose) { - if (appid == 0) + if (DesfireMFSelected(selectway, id)) PrintAndLogEx(INFO, "Check PICC key num: %d (0x%02x)", dctx.keyNum, dctx.keyNum); else - PrintAndLogEx(INFO, "Check app: %06x key num: %d (0x%02x)", appid, dctx.keyNum, dctx.keyNum); + PrintAndLogEx(INFO, "Check: %s key num: %d (0x%02x)", DesfireWayIDStr(selectway, id), dctx.keyNum, dctx.keyNum); PrintAndLogEx(INFO, "keys: DES: %s 2TDEA: %s 3TDEA: %s AES: %s", keytypes[T_DES] ? _GREEN_("YES") : _RED_("NO"), keytypes[T_3DES] ? _GREEN_("YES") : _RED_("NO"), @@ -1455,7 +1458,7 @@ static int CmdHF14aDesDetect(const char *Cmd) { if (ktype == T_3K3DES) memcpy(&key[16], key, 8); - res = DesfireAuthCheck(&dctx, appid, securechann, key); + res = DesfireAuthCheck(&dctx, selectway, id, securechann, key); if (res == PM3_SUCCESS) { found = true; break; // all the params already in the dctx @@ -1490,7 +1493,7 @@ static int CmdHF14aDesDetect(const char *Cmd) { break; for (int i = 0; i < keyListLen; i++) { - res = DesfireAuthCheck(&dctx, appid, securechann, &keyList[i * keylen]); + res = DesfireAuthCheck(&dctx, selectway, id, securechann, &keyList[i * keylen]); if (res == PM3_SUCCESS) { found = true; break; // all the params already in the dctx @@ -1523,10 +1526,10 @@ static int CmdHF14aDesDetect(const char *Cmd) { } if (found) { - if (appid == 0) + if (DesfireMFSelected(selectway, id)) PrintAndLogEx(INFO, _GREEN_("Found") " key num: %d (0x%02x)", dctx.keyNum, dctx.keyNum); else - PrintAndLogEx(INFO, "Found key for app: %06x key num: %d (0x%02x)", appid, dctx.keyNum, dctx.keyNum); + PrintAndLogEx(INFO, "Found key for: %s key num: %d (0x%02x)", DesfireWayIDStr(selectway, id), dctx.keyNum, dctx.keyNum); PrintAndLogEx(INFO, "key " _GREEN_("%s") " [%d]: " _GREEN_("%s"), CLIGetOptionListStr(DesfireAlgoOpts, dctx.keyType), diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 181d12cd5..f61254143 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -1571,7 +1571,7 @@ int DesfireAuthenticate(DesfireContext_t *dctx, DesfireSecureChannel secureChann return 100; } -static bool DesfireCheckAuthCmd(uint32_t appAID, uint8_t keyNum, uint8_t authcmd) { +static bool DesfireCheckAuthCmd(DesfireISOSelectWay way, uint32_t appID, uint8_t keyNum, uint8_t authcmd, bool checklrp) { size_t recv_len = 0; uint8_t respcode = 0; uint8_t recv_data[256] = {0}; @@ -1579,44 +1579,35 @@ static bool DesfireCheckAuthCmd(uint32_t appAID, uint8_t keyNum, uint8_t authcmd DesfireContext_t dctx = {0}; dctx.keyNum = keyNum; dctx.commMode = DCMPlain; - dctx.cmdSet = DCCNative; + dctx.cmdSet = (checklrp) ? DCCNativeISO : DCCNative; // if cant select - return false - int res = DesfireSelectAIDHex(&dctx, appAID, false, 0); + int res = DesfireSelect(&dctx, way, appID, NULL); if (res != PM3_SUCCESS) return false; - uint8_t data[] = {keyNum, 0x00}; - res = DesfireExchangeEx(false, &dctx, authcmd, data, (authcmd == MFDES_AUTHENTICATE_EV2F) ? 2 : 1, &respcode, recv_data, &recv_len, false, 0); + uint8_t data[] = {keyNum, (checklrp) ? 0x01 : 0x00, 0x02}; + uint8_t datalen = (authcmd == MFDES_AUTHENTICATE_EV2F) ? 2 : 1; + if (checklrp) + datalen = 3; + res = DesfireExchangeEx(false, &dctx, authcmd, data, datalen, &respcode, recv_data, &recv_len, false, 0); DropField(); - return (res == PM3_SUCCESS && respcode == 0xaf); + + if (checklrp) + return (res == PM3_SUCCESS && respcode == 0xaf && recv_len == 17 && recv_data[0] == 0x01); + else + return (res == PM3_SUCCESS && respcode == 0xaf); } -static bool DesfireCheckISOAuthCmd(uint32_t appAID, char *dfname, uint8_t keyNum, DesfireCryptoAlgorithm keytype) { +static bool DesfireCheckISOAuthCmd(DesfireISOSelectWay way, uint32_t appID, char *dfname, uint8_t keyNum, DesfireCryptoAlgorithm keytype) { DesfireContext_t dctx = {0}; dctx.keyNum = keyNum; dctx.commMode = DCMPlain; dctx.cmdSet = DCCISO; - bool app_level = (appAID != 0x000000); - int res = 0; - if (dfname == NULL || strnlen(dfname, 16) == 0) { - if (appAID == 0x000000) { - res = DesfireISOSelect(&dctx, ISSMFDFEF, NULL, 0, NULL, NULL); - if (res != PM3_SUCCESS) - return false; - } else { - res = DesfireSelectAIDHex(&dctx, appAID, false, 0); - if (res != PM3_SUCCESS) - return false; - } - } else { - res = DesfireISOSelectDF(&dctx, dfname, NULL, NULL); - if (res != PM3_SUCCESS) - return false; - app_level = true; - } + bool app_level = DesfireMFSelected(way, appID); + int res = DesfireSelect(&dctx, way, appID, dfname); uint8_t rndlen = DesfireGetRndLenForKey(keytype); @@ -1637,24 +1628,26 @@ static bool DesfireCheckISOAuthCmd(uint32_t appAID, char *dfname, uint8_t keyNum return (sw == 0x9000 || sw == 0x6982); } -void DesfireCheckAuthCommands(uint32_t appAID, char *dfname, uint8_t keyNum, AuthCommandsChk_t *authCmdCheck) { +void DesfireCheckAuthCommands(DesfireISOSelectWay way, uint32_t appID, char *dfname, uint8_t keyNum, AuthCommandsChk_t *authCmdCheck) { memset(authCmdCheck, 0, sizeof(AuthCommandsChk_t)); - authCmdCheck->auth = DesfireCheckAuthCmd(appAID, keyNum, MFDES_AUTHENTICATE); - authCmdCheck->authISO = DesfireCheckAuthCmd(appAID, keyNum, MFDES_AUTHENTICATE_ISO); - authCmdCheck->authAES = DesfireCheckAuthCmd(appAID, keyNum, MFDES_AUTHENTICATE_AES); - authCmdCheck->authEV2 = DesfireCheckAuthCmd(appAID, keyNum, MFDES_AUTHENTICATE_EV2F); - authCmdCheck->authISONative = DesfireCheckISOAuthCmd(appAID, dfname, keyNum, T_DES); + authCmdCheck->auth = DesfireCheckAuthCmd(way, appID, keyNum, MFDES_AUTHENTICATE, false); + authCmdCheck->authISO = DesfireCheckAuthCmd(way, appID, keyNum, MFDES_AUTHENTICATE_ISO, false); + authCmdCheck->authAES = DesfireCheckAuthCmd(way, appID, keyNum, MFDES_AUTHENTICATE_AES, false); + authCmdCheck->authEV2 = DesfireCheckAuthCmd(way, appID, keyNum, MFDES_AUTHENTICATE_EV2F, false); + authCmdCheck->authISONative = DesfireCheckISOAuthCmd(way, appID, dfname, keyNum, T_DES); + authCmdCheck->authLRP = DesfireCheckAuthCmd(way, appID, keyNum, MFDES_AUTHENTICATE_EV2F, true); authCmdCheck->checked = true; } void DesfireCheckAuthCommandsPrint(AuthCommandsChk_t *authCmdCheck) { - PrintAndLogEx(NORMAL, "auth: %s auth iso: %s auth aes: %s auth ev2: %s auth iso native: %s", + PrintAndLogEx(NORMAL, "auth: %s auth iso: %s auth aes: %s auth ev2: %s auth iso native: %s auth lrp: %s", authCmdCheck->auth ? _GREEN_("YES") : _RED_("NO"), authCmdCheck->authISO ? _GREEN_("YES") : _RED_("NO"), authCmdCheck->authAES ? _GREEN_("YES") : _RED_("NO"), authCmdCheck->authEV2 ? _GREEN_("YES") : _RED_("NO"), - authCmdCheck->authISONative ? _GREEN_("YES") : _RED_("NO") + authCmdCheck->authISONative ? _GREEN_("YES") : _RED_("NO"), + authCmdCheck->authLRP ? _GREEN_("YES") : _RED_("NO") ); } @@ -1688,7 +1681,7 @@ int DesfireFillPICCInfo(DesfireContext_t *dctx, PICCInfo_t *PICCInfo, bool deepm // field on-off zone if (deepmode) - DesfireCheckAuthCommands(0x000000, NULL, 0, &PICCInfo->authCmdCheck); + DesfireCheckAuthCommands(ISW6bAID, 0x000000, NULL, 0, &PICCInfo->authCmdCheck); return PM3_SUCCESS; } @@ -1770,7 +1763,7 @@ int DesfireFillAppList(DesfireContext_t *dctx, PICCInfo_t *PICCInfo, AppListS ap // field on-off zone if (fillAppSettings && PICCInfo->appCount > 0 && deepmode) { for (int i = 0; i < PICCInfo->appCount; i++) { - DesfireCheckAuthCommands(appList[i].appNum, appList[i].appDFName, 0, &appList[i].authCmdCheck); + DesfireCheckAuthCommands(ISW6bAID, appList[i].appNum, appList[i].appDFName, 0, &appList[i].authCmdCheck); } } diff --git a/client/src/mifare/desfirecore.h b/client/src/mifare/desfirecore.h index 1df4cfedb..8c834137c 100644 --- a/client/src/mifare/desfirecore.h +++ b/client/src/mifare/desfirecore.h @@ -98,6 +98,7 @@ typedef struct { bool authAES; bool authEV2; bool authISONative; + bool authLRP; } AuthCommandsChk_t; typedef struct { @@ -183,7 +184,7 @@ int DesfireSelectAndAuthenticateW(DesfireContext_t *dctx, DesfireSecureChannel s int DesfireSelectAndAuthenticateAppW(DesfireContext_t *dctx, DesfireSecureChannel secureChannel, DesfireISOSelectWay way, uint32_t id, bool noauth, bool verbose); int DesfireSelectAndAuthenticateISO(DesfireContext_t *dctx, DesfireSecureChannel secureChannel, bool useaid, uint32_t aid, uint16_t isoappid, bool selectfile, uint16_t isofileid, bool noauth, bool verbose); int DesfireAuthenticate(DesfireContext_t *dctx, DesfireSecureChannel secureChannel, bool verbose); -void DesfireCheckAuthCommands(uint32_t appAID, char *dfname, uint8_t keyNum, AuthCommandsChk_t *authCmdCheck); +void DesfireCheckAuthCommands(DesfireISOSelectWay way, uint32_t appID, char *dfname, uint8_t keyNum, AuthCommandsChk_t *authCmdCheck); void DesfireCheckAuthCommandsPrint(AuthCommandsChk_t *authCmdCheck); int DesfireFormatPICC(DesfireContext_t *dctx); From 46f2defcd32c790359aefcb77e83dba309b9757a Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 24 Aug 2021 12:47:29 +0300 Subject: [PATCH 2/6] add auto select channel to lrp --- client/src/cmdhfmfdes.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 5b375cf15..5868e1b56 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -1320,7 +1320,8 @@ static int CmdHF14aDesDetect(const char *Cmd) { "hf mfdes detect -> detect key 0 from PICC level\n" "hf mfdes detect -s d40 -> detect key 0 from PICC level via secure channel D40\n" "hf mfdes detect --dict mfdes_default_keys -> detect key 0 from PICC level with help of the standard dictionary\n" - "hf mfdes detect --aid 123456 -n 2 --save -> detect key 2 from app 123456 and if succeed - save params to defaults (`default` command)"); + "hf mfdes detect --aid 123456 -n 2 --save -> detect key 2 from app 123456 and if succeed - save params to defaults (`default` command)\n" + "hf mfdes detect --appisoid df01 --save -> detect key 0 and save to defaults with card in the LRP mode"); void *argtable[] = { arg_param_begin, @@ -1377,6 +1378,7 @@ static int CmdHF14aDesDetect(const char *Cmd) { } bool keytypes[4] = {0}; + bool uselrp = false; uint8_t data[250] = {0}; size_t datalen = 0; @@ -1413,6 +1415,11 @@ static int CmdHF14aDesDetect(const char *Cmd) { if (authCmdCheck.authAES || authCmdCheck.authEV2) { keytypes[T_AES] = true; } + if (authCmdCheck.authLRP) { + keytypes[T_AES] = true; + uselrp = true; + securechann = DACLRP; + } } else { // if nothing helps - we check DES only keytypes[T_DES] = true; @@ -1431,11 +1438,12 @@ static int CmdHF14aDesDetect(const char *Cmd) { PrintAndLogEx(INFO, "Check PICC key num: %d (0x%02x)", dctx.keyNum, dctx.keyNum); else PrintAndLogEx(INFO, "Check: %s key num: %d (0x%02x)", DesfireWayIDStr(selectway, id), dctx.keyNum, dctx.keyNum); - PrintAndLogEx(INFO, "keys: DES: %s 2TDEA: %s 3TDEA: %s AES: %s", + PrintAndLogEx(INFO, "keys: DES: %s 2TDEA: %s 3TDEA: %s AES: %s LRP: %s", keytypes[T_DES] ? _GREEN_("YES") : _RED_("NO"), keytypes[T_3DES] ? _GREEN_("YES") : _RED_("NO"), keytypes[T_3K3DES] ? _GREEN_("YES") : _RED_("NO"), - keytypes[T_AES] ? _GREEN_("YES") : _RED_("NO") + keytypes[T_AES] ? _GREEN_("YES") : _RED_("NO"), + uselrp ? _GREEN_("YES") : _RED_("NO") ); } @@ -1531,7 +1539,8 @@ static int CmdHF14aDesDetect(const char *Cmd) { else PrintAndLogEx(INFO, "Found key for: %s key num: %d (0x%02x)", DesfireWayIDStr(selectway, id), dctx.keyNum, dctx.keyNum); - PrintAndLogEx(INFO, "key " _GREEN_("%s") " [%d]: " _GREEN_("%s"), + PrintAndLogEx(INFO, "channel " _GREEN_("%s") " key " _GREEN_("%s") " [%d]: " _GREEN_("%s"), + CLIGetOptionListStr(DesfireSecureChannelOpts, securechann), CLIGetOptionListStr(DesfireAlgoOpts, dctx.keyType), desfire_get_key_length(dctx.keyType), sprint_hex(dctx.key, desfire_get_key_length(dctx.keyType))); From fddf7cf6b8a0b5e4d78a2a903f1d3bfe62cd833f Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 24 Aug 2021 13:11:52 +0300 Subject: [PATCH 3/6] desfire info updates --- client/src/cmdhfmfdes.c | 18 +++++++++++++++++- client/src/mifare/desfirecore.c | 2 +- client/src/mifare/desfirecore.h | 2 ++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 5868e1b56..e2b5d2dff 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -683,8 +683,24 @@ static int CmdHF14ADesInfo(const char *Cmd) { PrintAndLogEx(SUCCESS, " Card doesn't support 'free mem' cmd"); } } - PrintAndLogEx(NORMAL, ""); + + if (cardtype == DESFIRE_LIGHT) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Desfire Light info")); + if (DesfireSelect(&dctx, ISWIsoID, 0xdf01, NULL) == PM3_SUCCESS) + PrintAndLogEx(SUCCESS, " Card have " _GREEN_("default (0xdf01)") " iso id for application"); + else + PrintAndLogEx(SUCCESS, " Card have " _RED_("not a default") " iso id for application"); + + if (DesfireCheckAuthCmd(ISWIsoID, 0x3f00, 1, MFDES_AUTHENTICATE_EV2F, false)) { + PrintAndLogEx(SUCCESS, " Card in the " _GREEN_("AES") " mode"); + } else if (DesfireCheckAuthCmd(ISWIsoID, 0x3f00, 1, MFDES_AUTHENTICATE_EV2F, true)) { + PrintAndLogEx(SUCCESS, " Card in the " _GREEN_("LRP") " mode"); + } + } + + PrintAndLogEx(NORMAL, ""); iso14a_card_select_t card; res = SelectCard14443A_4(true, false, &card); diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index f61254143..cf6973e86 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -1571,7 +1571,7 @@ int DesfireAuthenticate(DesfireContext_t *dctx, DesfireSecureChannel secureChann return 100; } -static bool DesfireCheckAuthCmd(DesfireISOSelectWay way, uint32_t appID, uint8_t keyNum, uint8_t authcmd, bool checklrp) { +bool DesfireCheckAuthCmd(DesfireISOSelectWay way, uint32_t appID, uint8_t keyNum, uint8_t authcmd, bool checklrp) { size_t recv_len = 0; uint8_t respcode = 0; uint8_t recv_data[256] = {0}; diff --git a/client/src/mifare/desfirecore.h b/client/src/mifare/desfirecore.h index 8c834137c..5cdcb3c26 100644 --- a/client/src/mifare/desfirecore.h +++ b/client/src/mifare/desfirecore.h @@ -184,6 +184,8 @@ int DesfireSelectAndAuthenticateW(DesfireContext_t *dctx, DesfireSecureChannel s int DesfireSelectAndAuthenticateAppW(DesfireContext_t *dctx, DesfireSecureChannel secureChannel, DesfireISOSelectWay way, uint32_t id, bool noauth, bool verbose); int DesfireSelectAndAuthenticateISO(DesfireContext_t *dctx, DesfireSecureChannel secureChannel, bool useaid, uint32_t aid, uint16_t isoappid, bool selectfile, uint16_t isofileid, bool noauth, bool verbose); int DesfireAuthenticate(DesfireContext_t *dctx, DesfireSecureChannel secureChannel, bool verbose); + +bool DesfireCheckAuthCmd(DesfireISOSelectWay way, uint32_t appID, uint8_t keyNum, uint8_t authcmd, bool checklrp); void DesfireCheckAuthCommands(DesfireISOSelectWay way, uint32_t appID, char *dfname, uint8_t keyNum, AuthCommandsChk_t *authCmdCheck); void DesfireCheckAuthCommandsPrint(AuthCommandsChk_t *authCmdCheck); From 4bf3c43c7f15d814b2667240e551c56a0170a16a Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 25 Aug 2021 13:28:39 +0300 Subject: [PATCH 4/6] fix select command via iso channel (with wrapper) --- client/src/mifare/desfirecore.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index cf6973e86..28e81b161 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -1586,14 +1586,14 @@ bool DesfireCheckAuthCmd(DesfireISOSelectWay way, uint32_t appID, uint8_t keyNum if (res != PM3_SUCCESS) return false; - uint8_t data[] = {keyNum, (checklrp) ? 0x01 : 0x00, 0x02}; + uint8_t data[] = {keyNum, 0x01, (checklrp) ? 0x02 : 0x00}; uint8_t datalen = (authcmd == MFDES_AUTHENTICATE_EV2F) ? 2 : 1; - if (checklrp) + if (checklrp) datalen = 3; res = DesfireExchangeEx(false, &dctx, authcmd, data, datalen, &respcode, recv_data, &recv_len, false, 0); DropField(); - if (checklrp) + if (checklrp) return (res == PM3_SUCCESS && respcode == 0xaf && recv_len == 17 && recv_data[0] == 0x01); else return (res == PM3_SUCCESS && respcode == 0xaf); @@ -1606,9 +1606,11 @@ static bool DesfireCheckISOAuthCmd(DesfireISOSelectWay way, uint32_t appID, char dctx.commMode = DCMPlain; dctx.cmdSet = DCCISO; - bool app_level = DesfireMFSelected(way, appID); int res = DesfireSelect(&dctx, way, appID, dfname); + if (res != PM3_SUCCESS) + return false; + bool app_level = !DesfireMFSelected(way, appID); uint8_t rndlen = DesfireGetRndLenForKey(keytype); uint8_t piccrnd[64] = {0}; @@ -2948,18 +2950,31 @@ int DesfireSelectEx(DesfireContext_t *ctx, bool fieldon, DesfireISOSelectWay way size_t resplen = 0; if (way == ISWMF || (way == ISWDFName && dfname == NULL)) { - return DesfireISOSelect(ctx, ISSMFDFEF, NULL, 0, resp, &resplen); + return DesfireISOSelectEx(ctx, fieldon, ISSMFDFEF, NULL, 0, resp, &resplen); } else if (way == ISW6bAID) { + if (id == 0x000000 && fieldon) + return DesfireAnticollision(false); + + DesfireCommandSet cmdset = ctx->cmdSet; + int res; + + // if we try to select 6b AID via ISO channel - we can only switch the channel via the over channel because there is no equivalent command in the iso commands + if (ctx->cmdSet == DCCISO) + ctx->cmdSet = DCCNativeISO; + if (fieldon) - return DesfireSelectAIDHex(ctx, id, false, 0); + res = DesfireSelectAIDHex(ctx, id, false, 0); else - return DesfireSelectAIDHexNoFieldOn(ctx, id); + res = DesfireSelectAIDHexNoFieldOn(ctx, id); + + ctx->cmdSet = cmdset; + return res; } else if (way == ISWIsoID) { uint8_t data[2] = {0}; Uint2byteToMemBe(data, id); return DesfireISOSelectEx(ctx, fieldon, ISSMFDFEF, data, 2, resp, &resplen); } else if (way == ISWDFName) { - return DesfireISOSelect(ctx, ISSMFDFEF, NULL, 0, resp, &resplen); + return DesfireISOSelectEx(ctx, fieldon, ISSMFDFEF, NULL, 0, resp, &resplen); } return PM3_ESOFT; } From 81343f0ec174d6ba44710865754ca8856e301810 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 25 Aug 2021 13:57:35 +0300 Subject: [PATCH 5/6] fix info, add there desfire light tests --- client/src/cmdhfmfdes.c | 19 ++++++++++++------- client/src/mifare/desfirecore.c | 6 ++---- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index e2b5d2dff..52d1afad4 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -688,15 +688,20 @@ static int CmdHF14ADesInfo(const char *Cmd) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("Desfire Light info")); - if (DesfireSelect(&dctx, ISWIsoID, 0xdf01, NULL) == PM3_SUCCESS) + if (DesfireSelect(&dctx, ISWIsoID, 0xdf01, NULL) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, " Card have " _GREEN_("default (0xdf01)") " iso id for application"); - else - PrintAndLogEx(SUCCESS, " Card have " _RED_("not a default") " iso id for application"); - if (DesfireCheckAuthCmd(ISWIsoID, 0x3f00, 1, MFDES_AUTHENTICATE_EV2F, false)) { - PrintAndLogEx(SUCCESS, " Card in the " _GREEN_("AES") " mode"); - } else if (DesfireCheckAuthCmd(ISWIsoID, 0x3f00, 1, MFDES_AUTHENTICATE_EV2F, true)) { - PrintAndLogEx(SUCCESS, " Card in the " _GREEN_("LRP") " mode"); + if (DesfireCheckAuthCmd(ISWIsoID, 0xdf01, 0, MFDES_AUTHENTICATE_EV2F, false)) { + PrintAndLogEx(SUCCESS, " Card in the " _GREEN_("AES") " mode"); + } else if (DesfireCheckAuthCmd(ISWIsoID, 0xdf01, 0, MFDES_AUTHENTICATE_EV2F, true)) { + PrintAndLogEx(SUCCESS, " Card in the " _GREEN_("LRP") " mode"); + } + } else { + PrintAndLogEx(SUCCESS, " Card have " _RED_("not a default") " iso id for application"); + } + + if (DesfireCheckAuthCmd(ISWIsoID, 0x3f00, 1, MFDES_AUTHENTICATE_EV2F, true)) { + PrintAndLogEx(SUCCESS, " Card have " _GREEN_("LRP") " key in the MF/key1"); } } diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 28e81b161..e15f73437 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -1579,7 +1579,7 @@ bool DesfireCheckAuthCmd(DesfireISOSelectWay way, uint32_t appID, uint8_t keyNum DesfireContext_t dctx = {0}; dctx.keyNum = keyNum; dctx.commMode = DCMPlain; - dctx.cmdSet = (checklrp) ? DCCNativeISO : DCCNative; + dctx.cmdSet = (checklrp || way != ISW6bAID) ? DCCNativeISO : DCCNative; // if cant select - return false int res = DesfireSelect(&dctx, way, appID, NULL); @@ -1587,9 +1587,7 @@ bool DesfireCheckAuthCmd(DesfireISOSelectWay way, uint32_t appID, uint8_t keyNum return false; uint8_t data[] = {keyNum, 0x01, (checklrp) ? 0x02 : 0x00}; - uint8_t datalen = (authcmd == MFDES_AUTHENTICATE_EV2F) ? 2 : 1; - if (checklrp) - datalen = 3; + uint8_t datalen = (authcmd == MFDES_AUTHENTICATE_EV2F) ? 3 : 1; res = DesfireExchangeEx(false, &dctx, authcmd, data, datalen, &respcode, recv_data, &recv_len, false, 0); DropField(); From 13b0dc73d529b19f6b2fc462f16b9a1ffcafcb63 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 25 Aug 2021 14:15:48 +0300 Subject: [PATCH 6/6] fix --- client/src/mifare/desfirecore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index e15f73437..a001d3b8b 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -1579,7 +1579,7 @@ bool DesfireCheckAuthCmd(DesfireISOSelectWay way, uint32_t appID, uint8_t keyNum DesfireContext_t dctx = {0}; dctx.keyNum = keyNum; dctx.commMode = DCMPlain; - dctx.cmdSet = (checklrp || way != ISW6bAID) ? DCCNativeISO : DCCNative; + dctx.cmdSet = DCCNativeISO; // if cant select - return false int res = DesfireSelect(&dctx, way, appID, NULL);