move aiddesfire to mifare folder and refactoring

This commit is contained in:
merlokk 2021-08-02 16:41:49 +03:00
parent 5b03b9870b
commit fd138bdd04
8 changed files with 353 additions and 353 deletions

View file

@ -222,6 +222,7 @@ set (TARGET_SOURCES
${PM3_ROOT}/client/src/loclass/hash1_brute.c
${PM3_ROOT}/client/src/loclass/ikeys.c
${PM3_ROOT}/client/src/mifare/mad.c
${PM3_ROOT}/client/src/mifare/aiddesfire.c
${PM3_ROOT}/client/src/mifare/mfkey.c
${PM3_ROOT}/client/src/mifare/mifare4.c
${PM3_ROOT}/client/src/mifare/mifaredefault.c
@ -236,7 +237,6 @@ set (TARGET_SOURCES
${PM3_ROOT}/client/src/uart/uart_win32.c
${PM3_ROOT}/client/src/ui/overlays.ui
${PM3_ROOT}/client/src/ui/image.ui
${PM3_ROOT}/client/src/aiddesfire.c
${PM3_ROOT}/client/src/aidsearch.c
${PM3_ROOT}/client/src/cmdanalyse.c
${PM3_ROOT}/client/src/cmdcrc.c

View file

@ -474,7 +474,7 @@ POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d && $(TOUCH) $@
# enumerations #
################
SRCS = aiddesfire.c \
SRCS = mifare/aiddesfire.c \
aidsearch.c \
cmdanalyse.c \
cmdcrc.c \

View file

@ -1,133 +0,0 @@
//-----------------------------------------------------------------------------
// 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
// the license.
//-----------------------------------------------------------------------------
// AID DESFire functions
//-----------------------------------------------------------------------------
#include "aiddesfire.h"
#include "pm3_cmd.h"
#include "fileutils.h"
#include "jansson.h"
static json_t *df_known_aids = NULL;
static int open_aiddf_file(json_t **root, bool verbose) {
char *path;
int res = searchFile(&path, RESOURCES_SUBDIR, "aid_desfire", ".json", true);
if (res != PM3_SUCCESS) {
return PM3_EFILE;
}
int retval = PM3_SUCCESS;
json_error_t error;
*root = json_load_file(path, 0, &error);
if (!*root) {
PrintAndLogEx(ERR, "json (%s) error on line %d: %s", path, error.line, error.text);
retval = PM3_ESOFT;
goto out;
}
if (!json_is_array(*root)) {
PrintAndLogEx(ERR, "Invalid json (%s) format. root must be an array.", path);
retval = PM3_ESOFT;
goto out;
}
if (verbose)
PrintAndLogEx(SUCCESS, "Loaded file " _YELLOW_("`%s`") " (%s) %zu records.", path, _GREEN_("ok"), json_array_size(*root));
out:
free(path);
return retval;
}
static int close_aiddf_file(json_t *root) {
json_decref(root);
return PM3_SUCCESS;
}
static const char *aiddf_json_get_str(json_t *data, const char *name) {
json_t *jstr = json_object_get(data, name);
if (jstr == NULL)
return NULL;
if (!json_is_string(jstr)) {
PrintAndLogEx(WARNING, _YELLOW_("`%s`") " is not a string", name);
return NULL;
}
const char *cstr = json_string_value(jstr);
if (strlen(cstr) == 0)
return NULL;
return cstr;
}
static int print_aiddf_description(json_t *root, uint8_t aid[3], char *fmt, bool verbose) {
char laid[7] = {0};
sprintf(laid, "%02x%02x%02x", aid[2], aid[1], aid[0]); // must be lowercase
json_t *elm = NULL;
for (uint32_t idx = 0; idx < json_array_size(root); idx++) {
json_t *data = json_array_get(root, idx);
if (!json_is_object(data)) {
PrintAndLogEx(ERR, "data [%d] is not an object\n", idx);
continue;
}
const char *faid = aiddf_json_get_str(data, "AID");
char lfaid[strlen(faid) + 1];
strcpy(lfaid, faid);
str_lower(lfaid);
if (strcmp(laid, lfaid) == 0) {
elm = data;
break;
}
}
if (elm == NULL) {
PrintAndLogEx(INFO, fmt, " (unknown)");
return PM3_ENODATA;
}
const char *vaid = aiddf_json_get_str(elm, "AID");
const char *vendor = aiddf_json_get_str(elm, "Vendor");
const char *country = aiddf_json_get_str(elm, "Country");
const char *name = aiddf_json_get_str(elm, "Name");
const char *description = aiddf_json_get_str(elm, "Description");
const char *type = aiddf_json_get_str(elm, "Type");
if (name && vendor) {
char result[5 + strlen(name) + strlen(vendor)];
sprintf(result, " %s [%s]", name, vendor);
PrintAndLogEx(INFO, fmt, result);
}
if (verbose) {
PrintAndLogEx(SUCCESS, " AID: %s", vaid);
if (name)
PrintAndLogEx(SUCCESS, " Name: %s", name);
if (description)
PrintAndLogEx(SUCCESS, " Description: %s", description);
if (type)
PrintAndLogEx(SUCCESS, " Type: %s", type);
if (vendor)
PrintAndLogEx(SUCCESS, " Vendor: %s", vendor);
if (country)
PrintAndLogEx(SUCCESS, " Country: %s", country);
}
return PM3_SUCCESS;
}
int AIDDFDecodeAndPrint(uint8_t aid[3]) {
open_aiddf_file(&df_known_aids, false);
char fmt[80];
sprintf(fmt, " DF AID Function %02X%02X%02X :" _YELLOW_("%s"), aid[2], aid[1], aid[0], "%s");
print_aiddf_description(df_known_aids, aid, fmt, false);
close_aiddf_file(df_known_aids);
return PM3_SUCCESS;
}

View file

@ -38,7 +38,7 @@
#include "nfc/ndef.h" // NDEF
#include "mifare/mad.h"
#include "generator.h"
#include "aiddesfire.h"
#include "mifare/aiddesfire.h"
#include "util.h"
#define MAX_KEY_LEN 24
@ -146,202 +146,6 @@ typedef enum {
MFDES_VALUE_FILE
} MFDES_FILE_TYPE_T;
// NXP Appnote AN10787 - Application Directory (MAD)
typedef enum {
CL_ADMIN = 0,
CL_MISC1,
CL_MISC2,
CL_MISC3,
CL_MISC4,
CL_MISC5,
CL_MISC6,
CL_MISC7,
CL_AIRLINES = 8,
CL_FERRY,
CL_RAIL,
CL_MISC,
CL_TRANSPORT,
CL_SECURITY = 0x14,
CL_CITYTRAFFIC = 0x18,
CL_CZECH_RAIL,
CL_BUS,
CL_MMT,
CL_TAXI = 0x28,
CL_TOLL = 0x30,
CL_GENERIC_TRANS,
CL_COMPANY_SERVICES = 0x38,
CL_CITYCARD = 0x40,
CL_ACCESS_CONTROL_1 = 0x47,
CL_ACCESS_CONTROL_2,
CL_VIGIK = 0x49,
CL_NED_DEFENCE = 0x4A,
CL_BOSCH_TELECOM = 0x4B,
CL_EU = 0x4C,
CL_SKI_TICKET = 0x50,
CL_SOAA = 0x55,
CL_ACCESS2 = 0x56,
CL_FOOD = 0x60,
CL_NONFOOD = 0x68,
CL_HOTEL = 0x70,
CL_LOYALTY = 0x71,
CL_AIRPORT = 0x75,
CL_CAR_RENTAL = 0x78,
CL_NED_GOV = 0x79,
CL_ADMIN2 = 0x80,
CL_PURSE = 0x88,
CL_TV = 0x90,
CL_CRUISESHIP = 0x91,
CL_IOPTA = 0x95,
CL_METERING = 0x97,
CL_TELEPHONE = 0x98,
CL_HEALTH = 0xA0,
CL_WAREHOUSE = 0xA8,
CL_BANKING = 0xB8,
CL_ENTERTAIN = 0xC0,
CL_PARKING = 0xC8,
CL_FLEET = 0xC9,
CL_FUEL = 0xD0,
CL_INFO = 0xD8,
CL_PRESS = 0xE0,
CL_NFC = 0xE1,
CL_COMPUTER = 0xE8,
CL_MAIL = 0xF0,
CL_AMISC = 0xF8,
CL_AMISC1 = 0xF9,
CL_AMISC2 = 0xFA,
CL_AMISC3 = 0xFB,
CL_AMISC4 = 0xFC,
CL_AMISC5 = 0xFD,
CL_AMISC6 = 0xFE,
CL_AMISC7 = 0xFF,
} aidcluster_h;
static const char *cluster_to_text(uint8_t cluster) {
switch (cluster) {
case CL_ADMIN:
return "card administration";
case CL_MISC1:
case CL_MISC2:
case CL_MISC3:
case CL_MISC4:
case CL_MISC5:
case CL_MISC6:
case CL_MISC7:
return "miscellaneous applications";
case CL_AIRLINES:
return "airlines";
case CL_FERRY:
return "ferry traffic";
case CL_RAIL:
return "railway services";
case CL_MISC:
return "miscellaneous applications";
case CL_TRANSPORT:
return "transport";
case CL_SECURITY:
return "security solutions";
case CL_CITYTRAFFIC:
return "city traffic";
case CL_CZECH_RAIL:
return "Czech Railways";
case CL_BUS:
return "bus services";
case CL_MMT:
return "multi modal transit";
case CL_TAXI:
return "taxi";
case CL_TOLL:
return "road toll";
case CL_GENERIC_TRANS:
return "generic transport";
case CL_COMPANY_SERVICES:
return "company services";
case CL_CITYCARD:
return "city card services";
case CL_ACCESS_CONTROL_1:
case CL_ACCESS_CONTROL_2:
return "access control & security";
case CL_VIGIK:
return "VIGIK";
case CL_NED_DEFENCE:
return "Ministry of Defence, Netherlands";
case CL_BOSCH_TELECOM:
return "Bosch Telecom, Germany";
case CL_EU:
return "European Union Institutions";
case CL_SKI_TICKET:
return "ski ticketing";
case CL_SOAA:
return "SOAA standard for offline access standard";
case CL_ACCESS2:
return "access control & security";
case CL_FOOD:
return "food";
case CL_NONFOOD:
return "non-food trade";
case CL_HOTEL:
return "hotel";
case CL_LOYALTY:
return "loyalty";
case CL_AIRPORT:
return "airport services";
case CL_CAR_RENTAL:
return "car rental";
case CL_NED_GOV:
return "Dutch government";
case CL_ADMIN2:
return "administration services";
case CL_PURSE:
return "electronic purse";
case CL_TV:
return "television";
case CL_CRUISESHIP:
return "cruise ship";
case CL_IOPTA:
return "IOPTA";
case CL_METERING:
return "metering";
case CL_TELEPHONE:
return "telephone";
case CL_HEALTH:
return "health services";
case CL_WAREHOUSE:
return "warehouse";
case CL_BANKING:
return "banking";
case CL_ENTERTAIN:
return "entertainment & sports";
case CL_PARKING:
return "car parking";
case CL_FLEET:
return "fleet management";
case CL_FUEL:
return "fuel, gasoline";
case CL_INFO:
return "info services";
case CL_PRESS:
return "press";
case CL_NFC:
return "NFC Forum";
case CL_COMPUTER:
return "computer";
case CL_MAIL:
return "mail";
case CL_AMISC:
case CL_AMISC1:
case CL_AMISC2:
case CL_AMISC3:
case CL_AMISC4:
case CL_AMISC5:
case CL_AMISC6:
case CL_AMISC7:
return "miscellaneous applications";
default:
break;
}
return "reserved";
}
typedef enum {
DESFIRE_UNKNOWN = 0,
DESFIRE_MF3ICD40,
@ -2125,7 +1929,7 @@ static int CmdHF14ADesEnumApplications(const char *Cmd) {
if ((aid[2] >> 4) == 0xF) {
uint16_t short_aid = ((aid[2] & 0xF) << 12) | (aid[1] << 4) | (aid[0] >> 4);
PrintAndLogEx(SUCCESS, " AID mapped to MIFARE Classic AID (MAD): " _YELLOW_("%02X"), short_aid);
PrintAndLogEx(SUCCESS, " MAD AID Cluster 0x%02X : " _YELLOW_("%s"), short_aid >> 8, cluster_to_text(short_aid >> 8));
PrintAndLogEx(SUCCESS, " MAD AID Cluster 0x%02X : " _YELLOW_("%s"), short_aid >> 8, nxp_cluster_to_text(short_aid >> 8));
MADDFDecodeAndPrint(short_aid);
} else {
AIDDFDecodeAndPrint(aid);
@ -6308,16 +6112,7 @@ static int CmdHF14ADesLsApp(const char *Cmd) {
for (int i = 0; i < 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);
uint8_t aid[3] = {0};
DesfireAIDUintToByte(AppList[i].appNum, aid);
if ((aid[2] >> 4) == 0xF) {
uint16_t short_aid = ((aid[2] & 0xF) << 12) | (aid[1] << 4) | (aid[0] >> 4);
PrintAndLogEx(SUCCESS, " AID mapped to MIFARE Classic AID (MAD): " _YELLOW_("%02X"), short_aid);
PrintAndLogEx(SUCCESS, " MAD AID Cluster 0x%02X : " _YELLOW_("%s"), short_aid >> 8, cluster_to_text(short_aid >> 8));
MADDFDecodeAndPrint(short_aid);
} else {
AIDDFDecodeAndPrint(aid);
}
DesfirePrintAIDFunctions(AppList[i].appNum);
PrintAndLogEx(SUCCESS, "Auth commands: " NOLF);
DesfireCheckAuthCommandsPrint(&AppList[i].authCmdCheck);
@ -6390,16 +6185,7 @@ static int CmdHF14ADesDump(const char *Cmd) {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(SUCCESS, "Application " _CYAN_("%06x") " have " _GREEN_("%zu") " files", appid, filescount);
uint8_t aid[3] = {0};
DesfireAIDUintToByte(appid, aid);
if ((aid[2] >> 4) == 0xF) {
uint16_t short_aid = ((aid[2] & 0xF) << 12) | (aid[1] << 4) | (aid[0] >> 4);
PrintAndLogEx(SUCCESS, " AID mapped to MIFARE Classic AID (MAD): " _YELLOW_("%02X"), short_aid);
PrintAndLogEx(SUCCESS, " MAD AID Cluster 0x%02X : " _YELLOW_("%s"), short_aid >> 8, cluster_to_text(short_aid >> 8));
MADDFDecodeAndPrint(short_aid);
} else {
AIDDFDecodeAndPrint(aid);
}
DesfirePrintAIDFunctions(appid);
if (filescount == 0) {
PrintAndLogEx(INFO, "There is no files in the application %06x", appid);

View file

@ -0,0 +1,329 @@
//-----------------------------------------------------------------------------
// 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
// the license.
//-----------------------------------------------------------------------------
// AID DESFire functions
//-----------------------------------------------------------------------------
#include "aiddesfire.h"
#include "pm3_cmd.h"
#include "fileutils.h"
#include "jansson.h"
// NXP Appnote AN10787 - Application Directory (MAD)
typedef enum {
CL_ADMIN = 0,
CL_MISC1,
CL_MISC2,
CL_MISC3,
CL_MISC4,
CL_MISC5,
CL_MISC6,
CL_MISC7,
CL_AIRLINES = 8,
CL_FERRY,
CL_RAIL,
CL_MISC,
CL_TRANSPORT,
CL_SECURITY = 0x14,
CL_CITYTRAFFIC = 0x18,
CL_CZECH_RAIL,
CL_BUS,
CL_MMT,
CL_TAXI = 0x28,
CL_TOLL = 0x30,
CL_GENERIC_TRANS,
CL_COMPANY_SERVICES = 0x38,
CL_CITYCARD = 0x40,
CL_ACCESS_CONTROL_1 = 0x47,
CL_ACCESS_CONTROL_2,
CL_VIGIK = 0x49,
CL_NED_DEFENCE = 0x4A,
CL_BOSCH_TELECOM = 0x4B,
CL_EU = 0x4C,
CL_SKI_TICKET = 0x50,
CL_SOAA = 0x55,
CL_ACCESS2 = 0x56,
CL_FOOD = 0x60,
CL_NONFOOD = 0x68,
CL_HOTEL = 0x70,
CL_LOYALTY = 0x71,
CL_AIRPORT = 0x75,
CL_CAR_RENTAL = 0x78,
CL_NED_GOV = 0x79,
CL_ADMIN2 = 0x80,
CL_PURSE = 0x88,
CL_TV = 0x90,
CL_CRUISESHIP = 0x91,
CL_IOPTA = 0x95,
CL_METERING = 0x97,
CL_TELEPHONE = 0x98,
CL_HEALTH = 0xA0,
CL_WAREHOUSE = 0xA8,
CL_BANKING = 0xB8,
CL_ENTERTAIN = 0xC0,
CL_PARKING = 0xC8,
CL_FLEET = 0xC9,
CL_FUEL = 0xD0,
CL_INFO = 0xD8,
CL_PRESS = 0xE0,
CL_NFC = 0xE1,
CL_COMPUTER = 0xE8,
CL_MAIL = 0xF0,
CL_AMISC = 0xF8,
CL_AMISC1 = 0xF9,
CL_AMISC2 = 0xFA,
CL_AMISC3 = 0xFB,
CL_AMISC4 = 0xFC,
CL_AMISC5 = 0xFD,
CL_AMISC6 = 0xFE,
CL_AMISC7 = 0xFF,
} aidcluster_h;
const char *nxp_cluster_to_text(uint8_t cluster) {
switch (cluster) {
case CL_ADMIN:
return "card administration";
case CL_MISC1:
case CL_MISC2:
case CL_MISC3:
case CL_MISC4:
case CL_MISC5:
case CL_MISC6:
case CL_MISC7:
return "miscellaneous applications";
case CL_AIRLINES:
return "airlines";
case CL_FERRY:
return "ferry traffic";
case CL_RAIL:
return "railway services";
case CL_MISC:
return "miscellaneous applications";
case CL_TRANSPORT:
return "transport";
case CL_SECURITY:
return "security solutions";
case CL_CITYTRAFFIC:
return "city traffic";
case CL_CZECH_RAIL:
return "Czech Railways";
case CL_BUS:
return "bus services";
case CL_MMT:
return "multi modal transit";
case CL_TAXI:
return "taxi";
case CL_TOLL:
return "road toll";
case CL_GENERIC_TRANS:
return "generic transport";
case CL_COMPANY_SERVICES:
return "company services";
case CL_CITYCARD:
return "city card services";
case CL_ACCESS_CONTROL_1:
case CL_ACCESS_CONTROL_2:
return "access control & security";
case CL_VIGIK:
return "VIGIK";
case CL_NED_DEFENCE:
return "Ministry of Defence, Netherlands";
case CL_BOSCH_TELECOM:
return "Bosch Telecom, Germany";
case CL_EU:
return "European Union Institutions";
case CL_SKI_TICKET:
return "ski ticketing";
case CL_SOAA:
return "SOAA standard for offline access standard";
case CL_ACCESS2:
return "access control & security";
case CL_FOOD:
return "food";
case CL_NONFOOD:
return "non-food trade";
case CL_HOTEL:
return "hotel";
case CL_LOYALTY:
return "loyalty";
case CL_AIRPORT:
return "airport services";
case CL_CAR_RENTAL:
return "car rental";
case CL_NED_GOV:
return "Dutch government";
case CL_ADMIN2:
return "administration services";
case CL_PURSE:
return "electronic purse";
case CL_TV:
return "television";
case CL_CRUISESHIP:
return "cruise ship";
case CL_IOPTA:
return "IOPTA";
case CL_METERING:
return "metering";
case CL_TELEPHONE:
return "telephone";
case CL_HEALTH:
return "health services";
case CL_WAREHOUSE:
return "warehouse";
case CL_BANKING:
return "banking";
case CL_ENTERTAIN:
return "entertainment & sports";
case CL_PARKING:
return "car parking";
case CL_FLEET:
return "fleet management";
case CL_FUEL:
return "fuel, gasoline";
case CL_INFO:
return "info services";
case CL_PRESS:
return "press";
case CL_NFC:
return "NFC Forum";
case CL_COMPUTER:
return "computer";
case CL_MAIL:
return "mail";
case CL_AMISC:
case CL_AMISC1:
case CL_AMISC2:
case CL_AMISC3:
case CL_AMISC4:
case CL_AMISC5:
case CL_AMISC6:
case CL_AMISC7:
return "miscellaneous applications";
default:
break;
}
return "reserved";
}
static json_t *df_known_aids = NULL;
static int open_aiddf_file(json_t **root, bool verbose) {
char *path;
int res = searchFile(&path, RESOURCES_SUBDIR, "aid_desfire", ".json", true);
if (res != PM3_SUCCESS) {
return PM3_EFILE;
}
int retval = PM3_SUCCESS;
json_error_t error;
*root = json_load_file(path, 0, &error);
if (!*root) {
PrintAndLogEx(ERR, "json (%s) error on line %d: %s", path, error.line, error.text);
retval = PM3_ESOFT;
goto out;
}
if (!json_is_array(*root)) {
PrintAndLogEx(ERR, "Invalid json (%s) format. root must be an array.", path);
retval = PM3_ESOFT;
goto out;
}
if (verbose)
PrintAndLogEx(SUCCESS, "Loaded file " _YELLOW_("`%s`") " (%s) %zu records.", path, _GREEN_("ok"), json_array_size(*root));
out:
free(path);
return retval;
}
static int close_aiddf_file(json_t *root) {
json_decref(root);
return PM3_SUCCESS;
}
static const char *aiddf_json_get_str(json_t *data, const char *name) {
json_t *jstr = json_object_get(data, name);
if (jstr == NULL)
return NULL;
if (!json_is_string(jstr)) {
PrintAndLogEx(WARNING, _YELLOW_("`%s`") " is not a string", name);
return NULL;
}
const char *cstr = json_string_value(jstr);
if (strlen(cstr) == 0)
return NULL;
return cstr;
}
static int print_aiddf_description(json_t *root, uint8_t aid[3], char *fmt, bool verbose) {
char laid[7] = {0};
sprintf(laid, "%02x%02x%02x", aid[2], aid[1], aid[0]); // must be lowercase
json_t *elm = NULL;
for (uint32_t idx = 0; idx < json_array_size(root); idx++) {
json_t *data = json_array_get(root, idx);
if (!json_is_object(data)) {
PrintAndLogEx(ERR, "data [%d] is not an object\n", idx);
continue;
}
const char *faid = aiddf_json_get_str(data, "AID");
char lfaid[strlen(faid) + 1];
strcpy(lfaid, faid);
str_lower(lfaid);
if (strcmp(laid, lfaid) == 0) {
elm = data;
break;
}
}
if (elm == NULL) {
PrintAndLogEx(INFO, fmt, " (unknown)");
return PM3_ENODATA;
}
const char *vaid = aiddf_json_get_str(elm, "AID");
const char *vendor = aiddf_json_get_str(elm, "Vendor");
const char *country = aiddf_json_get_str(elm, "Country");
const char *name = aiddf_json_get_str(elm, "Name");
const char *description = aiddf_json_get_str(elm, "Description");
const char *type = aiddf_json_get_str(elm, "Type");
if (name && vendor) {
char result[5 + strlen(name) + strlen(vendor)];
sprintf(result, " %s [%s]", name, vendor);
PrintAndLogEx(INFO, fmt, result);
}
if (verbose) {
PrintAndLogEx(SUCCESS, " AID: %s", vaid);
if (name)
PrintAndLogEx(SUCCESS, " Name: %s", name);
if (description)
PrintAndLogEx(SUCCESS, " Description: %s", description);
if (type)
PrintAndLogEx(SUCCESS, " Type: %s", type);
if (vendor)
PrintAndLogEx(SUCCESS, " Vendor: %s", vendor);
if (country)
PrintAndLogEx(SUCCESS, " Country: %s", country);
}
return PM3_SUCCESS;
}
int AIDDFDecodeAndPrint(uint8_t aid[3]) {
open_aiddf_file(&df_known_aids, false);
char fmt[80];
sprintf(fmt, " DF AID Function %02X%02X%02X :" _YELLOW_("%s"), aid[2], aid[1], aid[0], "%s");
print_aiddf_description(df_known_aids, aid, fmt, false);
close_aiddf_file(df_known_aids);
return PM3_SUCCESS;
}

View file

@ -11,6 +11,7 @@
#include "common.h"
const char *nxp_cluster_to_text(uint8_t cluster);
int AIDDFDecodeAndPrint(uint8_t aid[3]);
#endif // _AIDDESFIRE_H_

View file

@ -32,6 +32,8 @@
#include "util_posix.h" // msleep
#include "mifare/desfire_crypto.h"
#include "desfiresecurechan.h"
#include "mifare/mad.h"
#include "mifare/aiddesfire.h"
const CLIParserOption DesfireAlgoOpts[] = {
{T_DES, "des"},
@ -825,6 +827,20 @@ int DesfireSelectAIDHexNoFieldOn(DesfireContext *ctx, uint32_t aid) {
return res;
}
void DesfirePrintAIDFunctions(uint32_t appid) {
uint8_t aid[3] = {0};
DesfireAIDUintToByte(appid, aid);
if ((aid[2] >> 4) == 0xF) {
uint16_t short_aid = ((aid[2] & 0xF) << 12) | (aid[1] << 4) | (aid[0] >> 4);
PrintAndLogEx(SUCCESS, " AID mapped to MIFARE Classic AID (MAD): " _YELLOW_("%02X"), short_aid);
PrintAndLogEx(SUCCESS, " MAD AID Cluster 0x%02X : " _YELLOW_("%s"), short_aid >> 8, nxp_cluster_to_text(short_aid >> 8));
MADDFDecodeAndPrint(short_aid);
} else {
AIDDFDecodeAndPrint(aid);
}
}
int DesfireSelectAndAuthenticateEx(DesfireContext *dctx, DesfireSecureChannel secureChannel, uint32_t aid, bool noauth, bool verbose) {
if (verbose)
DesfirePrintContext(dctx);

View file

@ -136,6 +136,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 DesfireSelectAIDHexNoFieldOn(DesfireContext *ctx, uint32_t aid);
void DesfirePrintAIDFunctions(uint32_t appid);
const char *DesfireAuthErrorToStr(int error);
int DesfireSelectAndAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel, uint32_t aid, bool verbose);