mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-25 07:35:40 -07:00
DesfireFillAppList refactoring
This commit is contained in:
parent
d27c340ab0
commit
ed310ed432
3 changed files with 131 additions and 99 deletions
|
@ -5976,14 +5976,6 @@ static int CmdHF14ADesLsFiles(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
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) {
|
static int CmdHF14ADesLsApp(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "hf mfdes lsapp",
|
CLIParserInit(&ctx, "hf mfdes lsapp",
|
||||||
|
@ -6013,7 +6005,7 @@ static int CmdHF14ADesLsApp(const char *Cmd) {
|
||||||
|
|
||||||
DesfireContext dctx;
|
DesfireContext dctx;
|
||||||
int securechann = defaultSecureChannel;
|
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) {
|
if (res) {
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
return res;
|
return res;
|
||||||
|
@ -6028,106 +6020,25 @@ static int CmdHF14ADesLsApp(const char *Cmd) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t buf[250] = {0};
|
PICCInfoS PICCInfo = {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;
|
|
||||||
}
|
|
||||||
|
|
||||||
AppListS AppList = {0};
|
AppListS AppList = {0};
|
||||||
|
DesfireFillAppList(&dctx, &PICCInfo, AppList, true);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// print zone
|
// print zone
|
||||||
PrintAndLogEx(SUCCESS, "------------------- " _CYAN_("PICC level") " ------------------");
|
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);
|
PrintAndLogEx(SUCCESS, "PICC level auth commands: " NOLF);
|
||||||
DesfireCheckAuthCommandsPrint(&authCmdCheck0);
|
DesfireCheckAuthCommandsPrint(&PICCInfo.authCmdCheck);
|
||||||
if (numkeys0 > 0) {
|
if (PICCInfo.numberOfKeys > 0) {
|
||||||
PrintKeySettings(keysettings0, numkeys0, false, true);
|
PrintKeySettings(PICCInfo.keySettings, PICCInfo.numKeysRaw, false, true);
|
||||||
PrintAndLogEx(SUCCESS, "PICC key 0 version: %d (0x%02x)", keyVer0, keyVer0);
|
PrintAndLogEx(SUCCESS, "PICC key 0 version: %d (0x%02x)", PICCInfo.keyVersion0, PICCInfo.keyVersion0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appcount > 0) {
|
if (PICCInfo.appCount > 0) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(SUCCESS, "-------------- " _CYAN_("Alications list") " --------------");
|
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);
|
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);
|
DesfirePrintAIDFunctions(AppList[i].appNum);
|
||||||
|
|
|
@ -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) {
|
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)
|
if (resplen)
|
||||||
*resplen = 0;
|
*resplen = 0;
|
||||||
|
|
|
@ -109,6 +109,18 @@ typedef struct {
|
||||||
} AppListElmS;
|
} AppListElmS;
|
||||||
typedef AppListElmS AppListS[64];
|
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 {
|
typedef enum {
|
||||||
RFTAuto,
|
RFTAuto,
|
||||||
RFTData,
|
RFTData,
|
||||||
|
@ -152,6 +164,8 @@ int DesfireGetFreeMem(DesfireContext *dctx, uint32_t *freemem);
|
||||||
int DesfireGetUID(DesfireContext *dctx, uint8_t *resp, size_t *resplen);
|
int DesfireGetUID(DesfireContext *dctx, uint8_t *resp, size_t *resplen);
|
||||||
int DesfireGetAIDList(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 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 DesfireCreateApplication(DesfireContext *dctx, uint8_t *appdata, size_t appdatalen);
|
||||||
int DesfireDeleteApplication(DesfireContext *dctx, uint32_t aid);
|
int DesfireDeleteApplication(DesfireContext *dctx, uint32_t aid);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue