From ed310ed432470b62093befd7c46158b3ec8d1926 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 2 Aug 2021 17:49:04 +0300 Subject: [PATCH] DesfireFillAppList refactoring --- client/src/cmdhfmfdes.c | 109 +++----------------------------- client/src/mifare/desfirecore.c | 107 +++++++++++++++++++++++++++++++ client/src/mifare/desfirecore.h | 14 ++++ 3 files changed, 131 insertions(+), 99 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 53c9ececd..3d1ddbc3c 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -5976,14 +5976,6 @@ static int CmdHF14ADesLsFiles(const char *Cmd) { return PM3_SUCCESS; } -static int AppListSearchAID(uint32_t appNum, AppListS AppList, size_t appcount) { - for (int i = 0; i < appcount; i++) - if (AppList[i].appNum == appNum) - return i; - - return -1; -} - static int CmdHF14ADesLsApp(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfdes lsapp", @@ -6013,7 +6005,7 @@ static int CmdHF14ADesLsApp(const char *Cmd) { DesfireContext dctx; int securechann = defaultSecureChannel; - int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, &securechann, DCMMACed, NULL); + int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 0, &securechann, DCMPlain, NULL); if (res) { CLIParserFree(ctx); return res; @@ -6028,106 +6020,25 @@ static int CmdHF14ADesLsApp(const char *Cmd) { return res; } - uint8_t buf[250] = {0}; - size_t buflen = 0; - - uint32_t freemem = 0; - DesfireGetFreeMem(&dctx, &freemem); - - - res = DesfireGetAIDList(&dctx, buf, &buflen); - if (res != PM3_SUCCESS) { - PrintAndLogEx(ERR, "Desfire GetAIDList command " _RED_("error") ". Result: %d", res); - DropField(); - return PM3_ESOFT; - } - + PICCInfoS PICCInfo = {0}; AppListS AppList = {0}; - - size_t appcount = buflen / 3; - for (int i = 0; i < buflen; i += 3) - AppList[i / 3].appNum = DesfireAIDByteToUint(&buf[i]); - - // result bytes: 3, 2, 1-16. total record size = 24 - res = DesfireGetDFList(&dctx, buf, &buflen); - if (res != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Desfire GetDFList command " _RED_("error") ". Result: %d", res); - } else if (buflen > 1) { - for (int i = 0; i < buflen; i++) { - int indx = AppListSearchAID(DesfireAIDByteToUint(&buf[i * 24 + 1]), AppList, appcount); - if (indx >= 0) { - AppList[indx].appISONum = MemBeToUint2byte(&buf[i * 24 + 1 + 3]); - memcpy(AppList[indx].appDFName, &buf[i * 24 + 1 + 5], strnlen((char *)&buf[i * 24 + 1 + 5], 16)); - } - } - } - - uint8_t keysettings0 = 0; - uint8_t numkeys0 = 0; - uint8_t keyVer0 = 0; - res = DesfireGetKeySettings(&dctx, buf, &buflen); - if (res == PM3_SUCCESS && buflen >= 2) { - keysettings0 = buf[0]; - numkeys0 = buf[1]; - if ((numkeys0 & 0x1f) > 0) { - uint8_t keyNum0 = numkeys0 & 0x1f; - res = DesfireGetKeyVersion(&dctx, &keyNum0, 1, buf, &buflen); - if (res == PM3_SUCCESS && buflen > 0) { - keyVer0 = buf[0]; - } - } - } - - if (appcount > 0) { - for (int i = 0; i < appcount; i++) { - res = DesfireSelectAIDHexNoFieldOn(&dctx, AppList[i].appNum); - if (res != PM3_SUCCESS) - continue; - - DesfireGetKeySettings(&dctx, buf, &buflen); - if (res == PM3_SUCCESS && buflen >= 2) { - AppList[i].keySettings = buf[0]; - AppList[i].numKeysRaw = buf[1]; - AppList[i].numberOfKeys = AppList[i].numKeysRaw & 0x1f; - AppList[i].isoFileIDEnabled = ((AppList[i].numKeysRaw & 0x20) != 0); - AppList[i].keyType = DesfireKeyTypeToAlgo(AppList[i].numKeysRaw >> 6); - - if (AppList[i].numberOfKeys > 0) - for (uint8_t keyn = 0; keyn < AppList[i].numberOfKeys; keyn++) { - res = DesfireGetKeyVersion(&dctx, &keyn, 1, buf, &buflen); - if (res == PM3_SUCCESS && buflen > 0) { - AppList[i].keyVersions[keyn] = buf[0]; - } - } - } - } - } - - // field on-off zone - AuthCommandsChk authCmdCheck0 = {0}; - DesfireCheckAuthCommands(0x000000, NULL, 0, &authCmdCheck0); - - if (appcount > 0) { - for (int i = 0; i < appcount; i++) { - DesfireCheckAuthCommands(AppList[i].appNum, AppList[i].appDFName, 0, &AppList[i].authCmdCheck); - } - } + DesfireFillAppList(&dctx, &PICCInfo, AppList, true); // print zone PrintAndLogEx(SUCCESS, "------------------- " _CYAN_("PICC level") " ------------------"); - PrintAndLogEx(SUCCESS, "Applications count: " _GREEN_("%zu") " free memory " _GREEN_("%d"), appcount, freemem); + PrintAndLogEx(SUCCESS, "Applications count: " _GREEN_("%zu") " free memory " _GREEN_("%d"), PICCInfo.appCount, PICCInfo.freemem); PrintAndLogEx(SUCCESS, "PICC level auth commands: " NOLF); - DesfireCheckAuthCommandsPrint(&authCmdCheck0); - if (numkeys0 > 0) { - PrintKeySettings(keysettings0, numkeys0, false, true); - PrintAndLogEx(SUCCESS, "PICC key 0 version: %d (0x%02x)", keyVer0, keyVer0); + DesfireCheckAuthCommandsPrint(&PICCInfo.authCmdCheck); + if (PICCInfo.numberOfKeys > 0) { + PrintKeySettings(PICCInfo.keySettings, PICCInfo.numKeysRaw, false, true); + PrintAndLogEx(SUCCESS, "PICC key 0 version: %d (0x%02x)", PICCInfo.keyVersion0, PICCInfo.keyVersion0); } - if (appcount > 0) { + if (PICCInfo.appCount > 0) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "-------------- " _CYAN_("Alications list") " --------------"); - for (int i = 0; i < appcount; i++) { + for (int i = 0; i < PICCInfo.appCount; i++) { PrintAndLogEx(SUCCESS, _CYAN_("Application number: 0x%02x") " iso id: " _GREEN_("0x%04x") " name: " _GREEN_("%s"), AppList[i].appNum, AppList[i].appISONum, AppList[i].appDFName); DesfirePrintAIDFunctions(AppList[i].appNum); diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 52984f9ff..a3a806293 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -1457,6 +1457,113 @@ void DesfireCheckAuthCommandsPrint(AuthCommandsChk *authCmdCheck) { ); } +int DesfireFillPICCInfo(DesfireContext *dctx, PICCInfoS *PICCInfo, bool deepmode) { + uint8_t buf[250] = {0}; + size_t buflen = 0; + + uint32_t freemem = 0; + int res = DesfireGetFreeMem(dctx, &freemem); + if (res == PM3_SUCCESS) + PICCInfo->freemem = freemem; + + PICCInfo->keySettings = 0; + PICCInfo->numKeysRaw = 0; + PICCInfo->keyVersion0 = 0; + res = DesfireGetKeySettings(dctx, buf, &buflen); + if (res == PM3_SUCCESS && buflen >= 2) { + PICCInfo->keySettings = buf[0]; + PICCInfo->numKeysRaw = buf[1]; + PICCInfo->numberOfKeys = PICCInfo->numKeysRaw & 0x1f; + if (PICCInfo->numKeysRaw > 0) { + uint8_t keyNum0 = 0; + res = DesfireGetKeyVersion(dctx, &keyNum0, 1, buf, &buflen); + if (res == PM3_SUCCESS && buflen > 0) { + PICCInfo->keyVersion0 = buf[0]; + } + } + } + + // field on-off zone + if (deepmode) + DesfireCheckAuthCommands(0x000000, NULL, 0, &PICCInfo->authCmdCheck); + + return PM3_SUCCESS; +} + +static int AppListSearchAID(uint32_t appNum, AppListS AppList, size_t appcount) { + for (int i = 0; i < appcount; i++) + if (AppList[i].appNum == appNum) + return i; + + return -1; +} + +int DesfireFillAppList(DesfireContext *dctx, PICCInfoS *PICCInfo, AppListS appList, bool deepmode) { + uint8_t buf[250] = {0}; + size_t buflen = 0; + + DesfireFillPICCInfo(dctx, PICCInfo, deepmode); + + int res = DesfireGetAIDList(dctx, buf, &buflen); + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Desfire GetAIDList command " _RED_("error") ". Result: %d", res); + DropField(); + return PM3_ESOFT; + } + + PICCInfo->appCount = buflen / 3; + for (int i = 0; i < buflen; i += 3) + appList[i / 3].appNum = DesfireAIDByteToUint(&buf[i]); + + // result bytes: 3, 2, 1-16. total record size = 24 + res = DesfireGetDFList(dctx, buf, &buflen); + if (res != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "Desfire GetDFList command " _RED_("error") ". Result: %d", res); + } else if (buflen > 1) { + for (int i = 0; i < buflen; i++) { + int indx = AppListSearchAID(DesfireAIDByteToUint(&buf[i * 24 + 1]), appList, PICCInfo->appCount); + if (indx >= 0) { + appList[indx].appISONum = MemBeToUint2byte(&buf[i * 24 + 1 + 3]); + memcpy(appList[indx].appDFName, &buf[i * 24 + 1 + 5], strnlen((char *)&buf[i * 24 + 1 + 5], 16)); + } + } + } + + if (PICCInfo->appCount > 0) { + for (int i = 0; i < PICCInfo->appCount; i++) { + res = DesfireSelectAIDHexNoFieldOn(dctx, appList[i].appNum); + if (res != PM3_SUCCESS) + continue; + + DesfireGetKeySettings(dctx, buf, &buflen); + if (res == PM3_SUCCESS && buflen >= 2) { + appList[i].keySettings = buf[0]; + appList[i].numKeysRaw = buf[1]; + appList[i].numberOfKeys = appList[i].numKeysRaw & 0x1f; + appList[i].isoFileIDEnabled = ((appList[i].numKeysRaw & 0x20) != 0); + appList[i].keyType = DesfireKeyTypeToAlgo(appList[i].numKeysRaw >> 6); + + if (appList[i].numberOfKeys > 0) + for (uint8_t keyn = 0; keyn < appList[i].numberOfKeys; keyn++) { + res = DesfireGetKeyVersion(dctx, &keyn, 1, buf, &buflen); + if (res == PM3_SUCCESS && buflen > 0) { + appList[i].keyVersions[keyn] = buf[0]; + } + } + } + } + } + + // field on-off zone + if (PICCInfo->appCount > 0 && deepmode) { + for (int i = 0; i < PICCInfo->appCount; i++) { + DesfireCheckAuthCommands(appList[i].appNum, appList[i].appDFName, 0, &appList[i].authCmdCheck); + } + } + + return PM3_SUCCESS; +} + static int DesfireCommandEx(DesfireContext *dctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *resp, size_t *resplen, int checklength, size_t splitbysize) { if (resplen) *resplen = 0; diff --git a/client/src/mifare/desfirecore.h b/client/src/mifare/desfirecore.h index 0f8da7392..d63d6582a 100644 --- a/client/src/mifare/desfirecore.h +++ b/client/src/mifare/desfirecore.h @@ -109,6 +109,18 @@ typedef struct { } AppListElmS; typedef AppListElmS AppListS[64]; +typedef struct { + size_t appCount; + uint32_t freemem; + AuthCommandsChk authCmdCheck; + + uint8_t keySettings; + uint8_t numKeysRaw; + uint8_t numberOfKeys; // from numKeysRaw + + uint8_t keyVersion0; +} PICCInfoS; + typedef enum { RFTAuto, RFTData, @@ -152,6 +164,8 @@ int DesfireGetFreeMem(DesfireContext *dctx, uint32_t *freemem); int DesfireGetUID(DesfireContext *dctx, uint8_t *resp, size_t *resplen); int DesfireGetAIDList(DesfireContext *dctx, uint8_t *resp, size_t *resplen); int DesfireGetDFList(DesfireContext *dctx, uint8_t *resp, size_t *resplen); +int DesfireFillPICCInfo(DesfireContext *dctx, PICCInfoS *PICCInfo, bool deepmode); +int DesfireFillAppList(DesfireContext *dctx, PICCInfoS *PICCInfo, AppListS appList, bool deepmode); int DesfireCreateApplication(DesfireContext *dctx, uint8_t *appdata, size_t appdatalen); int DesfireDeleteApplication(DesfireContext *dctx, uint32_t aid);