mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-24 23:25: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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue