fixes to when thing gets wrongly identified

This commit is contained in:
iceman1001 2024-04-20 11:32:51 +02:00
commit 543f8df8c0
3 changed files with 102 additions and 64 deletions

View file

@ -158,7 +158,9 @@ void MifareDesfireGetInformation(void) {
// card select - information // card select - information
if (!iso14443a_select_card(NULL, &card, NULL, true, 0, false)) { if (!iso14443a_select_card(NULL, &card, NULL, true, 0, false)) {
if (g_dbglevel >= DBG_ERROR) DbpString("Can't select card"); if (g_dbglevel >= DBG_ERROR) {
DbpString("Can't select card");
}
payload.isOK = 1; // 2 == can not select payload.isOK = 1; // 2 == can not select
reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload)); reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload));
switch_off(); switch_off();
@ -183,18 +185,22 @@ void MifareDesfireGetInformation(void) {
} }
if (len < sizeof(payload.versionHW) + 1) { if (len < sizeof(payload.versionHW) + 1) {
Dbprintf("Tag answer to MFDES_GET_VERSION was too short: data in Hardware Information is probably invalid."); payload.isOK = 3; // 3 == DOESN'T ANSWER TO GET_VERSION
print_result("Answer", resp, len); reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload));
memset(resp + len, 0xFF, sizeof(payload.versionHW) + 1 - len); // clear remaining bytes switch_off();
if (g_dbglevel >= DBG_ERROR) {
Dbprintf("Tag answer to MFDES_GET_VERSION was too short: data in Hardware Information is probably invalid.");
print_result("Answer", resp, len);
}
return;
} }
memcpy(payload.versionHW, resp + 1, sizeof(payload.versionHW)); memcpy(payload.versionHW, resp + 1, sizeof(payload.versionHW));
// ADDITION_FRAME 1 // ADDITION_FRAME 1
cmd[1] = MFDES_ADDITIONAL_FRAME; cmd[1] = MFDES_ADDITIONAL_FRAME;
len = DesfireAPDU(cmd, cmd_len, resp); len = DesfireAPDU(cmd, cmd_len, resp);
if (!len) { if (!len) {
print_result("ERROR <--: ", resp, len);
payload.isOK = 3; // 3 == DOESN'T ANSWER TO GET_VERSION payload.isOK = 3; // 3 == DOESN'T ANSWER TO GET_VERSION
reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload)); reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload));
switch_off(); switch_off();
@ -202,9 +208,14 @@ void MifareDesfireGetInformation(void) {
} }
if (len < sizeof(payload.versionSW) + 1) { if (len < sizeof(payload.versionSW) + 1) {
Dbprintf("Tag answer to MFDES_ADDITIONAL_FRAME 1 was too short: data in Software Information is probably invalid."); payload.isOK = 3; // 3 == DOESN'T ANSWER TO GET_VERSION
print_result("Answer", resp, len); reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload));
memset(resp + len, 0xFF, sizeof(payload.versionSW) + 1 - len); // clear remaining bytes switch_off();
if (g_dbglevel >= DBG_ERROR) {
Dbprintf("Tag answer to MFDES_ADDITIONAL_FRAME 1 was too short: data in Software Information is probably invalid.");
print_result("Answer", resp, len);
}
return;
} }
memcpy(payload.versionSW, resp + 1, sizeof(payload.versionSW)); memcpy(payload.versionSW, resp + 1, sizeof(payload.versionSW));
@ -212,7 +223,6 @@ void MifareDesfireGetInformation(void) {
// ADDITION_FRAME 2 // ADDITION_FRAME 2
len = DesfireAPDU(cmd, cmd_len, resp); len = DesfireAPDU(cmd, cmd_len, resp);
if (!len) { if (!len) {
print_result("ERROR <--: ", resp, len);
payload.isOK = 3; // 3 == DOESN'T ANSWER TO GET_VERSION payload.isOK = 3; // 3 == DOESN'T ANSWER TO GET_VERSION
reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload)); reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload));
switch_off(); switch_off();
@ -220,16 +230,19 @@ void MifareDesfireGetInformation(void) {
} }
if (len < sizeof(payload.details) + 1) { if (len < sizeof(payload.details) + 1) {
Dbprintf("Tag answer to MFDES_ADDITIONAL_FRAME 2 was too short: data in Batch number and Production date is probably invalid"); payload.isOK = 3; // 3 == DOESN'T ANSWER TO GET_VERSION
print_result("Answer", resp, len); reply_ng(CMD_HF_DESFIRE_INFO, PM3_ESOFT, (uint8_t *)&payload, sizeof(payload));
memset(resp + len, 0xFF, sizeof(payload.details) + 1 - len); // clear remaining bytes switch_off();
if (g_dbglevel >= DBG_ERROR) {
Dbprintf("Tag answer to MFDES_ADDITIONAL_FRAME 2 was too short: data in Batch number and Production date is probably invalid");
print_result("Answer", resp, len);
}
return;
} }
memcpy(payload.details, resp + 1, sizeof(payload.details)); memcpy(payload.details, resp + 1, sizeof(payload.details));
LED_B_ON();
reply_ng(CMD_HF_DESFIRE_INFO, PM3_SUCCESS, (uint8_t *)&payload, sizeof(payload)); reply_ng(CMD_HF_DESFIRE_INFO, PM3_SUCCESS, (uint8_t *)&payload, sizeof(payload));
LED_B_OFF();
// reset the pcb_blocknum, // reset the pcb_blocknum,
pcb_blocknum = 0; pcb_blocknum = 0;

View file

@ -146,6 +146,7 @@ typedef enum {
PLUS_EV1, PLUS_EV1,
PLUS_EV2, PLUS_EV2,
NTAG413DNA, NTAG413DNA,
NTAG424,
} nxp_cardtype_t; } nxp_cardtype_t;
typedef enum { typedef enum {
@ -250,7 +251,7 @@ static char *getVersionStr(uint8_t type, uint8_t major, uint8_t minor) {
static char buf[40] = {0x00}; static char buf[40] = {0x00};
char *retStr = buf; char *retStr = buf;
if (major == 0x00) if (type == 0x01 && major == 0x00)
snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire MF3ICD40") " )", major, minor); snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire MF3ICD40") " )", major, minor);
else if (major == 0x10 && minor == 0x00) else if (major == 0x10 && minor == 0x00)
snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("NTAG413DNA") " )", major, minor); snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("NTAG413DNA") " )", major, minor);
@ -283,18 +284,21 @@ static char *getTypeStr(uint8_t type) {
char *retStr = buf; char *retStr = buf;
switch (type) { switch (type) {
case 1: case 0x01:
snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("DESFire") " )", type); snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("DESFire") " )", type);
break; break;
case 2: case 0x02:
snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("Plus") " )", type); snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("Plus") " )", type);
break; break;
case 3: case 0x03:
snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("Ultralight") " )", type); snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("Ultralight") " )", type);
break; break;
case 4: case 0x04:
snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("NTAG") " )", type); snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("NTAG") " )", type);
break; break;
case 0x81:
snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("Smartcard") " )", type);
break;
default: default:
break; break;
} }
@ -315,7 +319,7 @@ static const char *getAidCommentStr(uint8_t *aid) {
static nxp_cardtype_t getCardType(uint8_t type, uint8_t major, uint8_t minor) { static nxp_cardtype_t getCardType(uint8_t type, uint8_t major, uint8_t minor) {
// DESFire MF3ICD40 // DESFire MF3ICD40
if (major == 0x00 && minor == 0x00) if (type == 0x01 && major == 0x00 && minor == 0x02)
return DESFIRE_MF3ICD40; return DESFIRE_MF3ICD40;
// DESFire EV1 // DESFire EV1
@ -329,17 +333,18 @@ static nxp_cardtype_t getCardType(uint8_t type, uint8_t major, uint8_t minor) {
if (type == 0x01 && major == 0x22 && minor == 0x00) if (type == 0x01 && major == 0x22 && minor == 0x00)
return DESFIRE_EV2_XL; return DESFIRE_EV2_XL;
if (type == 0x01 && major == 0x42 && minor == 0x00)
return DESFIRE_EV2;
// DESFire EV3 // DESFire EV3
if (type == 0x01 && major == 0x33 && minor == 0x00) if (type == 0x01 && major == 0x33 && minor == 0x00)
return DESFIRE_EV3; return DESFIRE_EV3;
// DESFire Light // DESFire Light
if (type == 0x01 && major == 0x30 && minor == 0x00) if (type == 0x08 && major == 0x30 && minor == 0x00)
return DESFIRE_LIGHT; return DESFIRE_LIGHT;
// combo card DESFire / EMV
if (type == 0x81 && major == 0x42 && minor == 0x00)
return DESFIRE_EV2;
// Plus EV1 // Plus EV1
if (type == 0x02 && major == 0x11 && minor == 0x00) if (type == 0x02 && major == 0x11 && minor == 0x00)
return PLUS_EV1; return PLUS_EV1;
@ -352,6 +357,10 @@ static nxp_cardtype_t getCardType(uint8_t type, uint8_t major, uint8_t minor) {
if (major == 0x10 && minor == 0x00) if (major == 0x10 && minor == 0x00)
return NTAG413DNA; return NTAG413DNA;
// NTAG 424
if (type == 0x04 && major == 0x30 && minor == 0x00)
return NTAG424;
return DESFIRE_UNKNOWN; return DESFIRE_UNKNOWN;
} }
@ -391,9 +400,9 @@ static const char *getProductTypeStr(const uint8_t *versionhw) {
} }
static int mfdes_get_info(mfdes_info_res_t *info) { static int mfdes_get_info(mfdes_info_res_t *info) {
SendCommandNG(CMD_HF_DESFIRE_INFO, NULL, 0);
PacketResponseNG resp;
PacketResponseNG resp;
SendCommandNG(CMD_HF_DESFIRE_INFO, NULL, 0);
if (WaitForResponseTimeout(CMD_HF_DESFIRE_INFO, &resp, 1500) == false) { if (WaitForResponseTimeout(CMD_HF_DESFIRE_INFO, &resp, 1500) == false) {
PrintAndLogEx(WARNING, "Command execute timeout"); PrintAndLogEx(WARNING, "Command execute timeout");
DropField(); DropField();
@ -403,6 +412,7 @@ static int mfdes_get_info(mfdes_info_res_t *info) {
memcpy(info, resp.data.asBytes, sizeof(mfdes_info_res_t)); memcpy(info, resp.data.asBytes, sizeof(mfdes_info_res_t));
if (resp.status != PM3_SUCCESS) { if (resp.status != PM3_SUCCESS) {
switch (info->isOK) { switch (info->isOK) {
case 1: case 1:
PrintAndLogEx(WARNING, "Can't select card"); PrintAndLogEx(WARNING, "Can't select card");
@ -713,11 +723,19 @@ static int CmdHF14ADesInfo(const char *Cmd) {
DropField(); DropField();
return PM3_SUCCESS; return PM3_SUCCESS;
} }
if (cardtype == PLUS_EV2) { if (cardtype == PLUS_EV2) {
PrintAndLogEx(INFO, "Card seems to be MIFARE Plus EV2. Try " _YELLOW_("`hf mfp info`")); PrintAndLogEx(INFO, "Card seems to be MIFARE Plus EV2. Try " _YELLOW_("`hf mfp info`"));
DropField(); DropField();
return PM3_SUCCESS; return PM3_SUCCESS;
} }
if (cardtype == NTAG424) {
PrintAndLogEx(INFO, "Card seems to be NTAG 424. Try " _YELLOW_("`hf ntag424 info`"));
DropField();
return PM3_SUCCESS;
}
if (cardtype == DESFIRE_UNKNOWN) { if (cardtype == DESFIRE_UNKNOWN) {
PrintAndLogEx(INFO, "HW Version.. %s", sprint_hex_inrow(info.versionHW, sizeof(info.versionHW))); PrintAndLogEx(INFO, "HW Version.. %s", sprint_hex_inrow(info.versionHW, sizeof(info.versionHW)));
PrintAndLogEx(INFO, "SW Version.. %s", sprint_hex_inrow(info.versionSW, sizeof(info.versionSW))); PrintAndLogEx(INFO, "SW Version.. %s", sprint_hex_inrow(info.versionSW, sizeof(info.versionSW)));

View file

@ -88,7 +88,7 @@ static char *getVersionStr(uint8_t type, uint8_t major, uint8_t minor) {
static char buf[40] = {0x00}; static char buf[40] = {0x00};
char *retStr = buf; char *retStr = buf;
if (major == 0x00) if (type == 0x01 && major == 0x00)
snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire MF3ICD40") " )", major, minor); snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire MF3ICD40") " )", major, minor);
else if (major == 0x10 && minor == 0x00) else if (major == 0x10 && minor == 0x00)
snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("NTAG413DNA") " )", major, minor); snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("NTAG413DNA") " )", major, minor);
@ -119,18 +119,21 @@ static char *getTypeStr(uint8_t type) {
char *retStr = buf; char *retStr = buf;
switch (type) { switch (type) {
case 1: case 0x01:
snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("DESFire") " )", type); snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("DESFire") " )", type);
break; break;
case 2: case 0x02:
snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("Plus") " )", type); snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("Plus") " )", type);
break; break;
case 3: case 0x03:
snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("Ultralight") " )", type); snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("Ultralight") " )", type);
break; break;
case 4: case 0x04:
snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("NTAG") " )", type); snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("NTAG") " )", type);
break; break;
case 0x81:
snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("Smartcard") " )", type);
break;
default: default:
break; break;
} }
@ -140,7 +143,7 @@ static char *getTypeStr(uint8_t type) {
static nxp_cardtype_t getCardType(uint8_t type, uint8_t major, uint8_t minor) { static nxp_cardtype_t getCardType(uint8_t type, uint8_t major, uint8_t minor) {
// DESFire MF3ICD40 // DESFire MF3ICD40
if (major == 0x00 && minor == 0x00) if (type == 0x01 && major == 0x00 && minor == 0x02)
return DESFIRE_MF3ICD40; return DESFIRE_MF3ICD40;
// DESFire EV1 // DESFire EV1
@ -154,17 +157,18 @@ static nxp_cardtype_t getCardType(uint8_t type, uint8_t major, uint8_t minor) {
if (type == 0x01 && major == 0x22 && minor == 0x00) if (type == 0x01 && major == 0x22 && minor == 0x00)
return DESFIRE_EV2_XL; return DESFIRE_EV2_XL;
if (type == 0x01 && major == 0x42 && minor == 0x00)
return DESFIRE_EV2;
// DESFire EV3 // DESFire EV3
if (type == 0x01 && major == 0x33 && minor == 0x00) if (type == 0x01 && major == 0x33 && minor == 0x00)
return DESFIRE_EV3; return DESFIRE_EV3;
// DESFire Light // DESFire Light
if (type == 0x01 && major == 0x30 && minor == 0x00) if (type == 0x08 && major == 0x30 && minor == 0x00)
return DESFIRE_LIGHT; return DESFIRE_LIGHT;
// combo card DESFire / EMV
if (type == 0x81 && major == 0x42 && minor == 0x00)
return DESFIRE_EV2;
// Plus EV1 // Plus EV1
if (type == 0x02 && major == 0x11 && minor == 0x00) if (type == 0x02 && major == 0x11 && minor == 0x00)
return PLUS_EV1; return PLUS_EV1;
@ -174,9 +178,13 @@ static nxp_cardtype_t getCardType(uint8_t type, uint8_t major, uint8_t minor) {
return PLUS_EV2; return PLUS_EV2;
// NTAG 413 DNA // NTAG 413 DNA
if (major == 0x10 && minor == 0x00) if (type == 0x04 && major == 0x10 && minor == 0x00)
return NTAG413DNA; return NTAG413DNA;
// NTAG 424
if (type == 0x04 && major == 0x30 && minor == 0x00)
return NTAG424;
return MFP_UNKNOWN; return MFP_UNKNOWN;
} }
@ -350,18 +358,18 @@ static int CmdHFMFPInfo(const char *Cmd) {
switch(cardtype) { switch(cardtype) {
case PLUS_EV1: { case PLUS_EV1: {
if (supportSignature) { if (supportSignature) {
PrintAndLogEx(INFO, " Tech...... " _GREEN_("MIFARE Plus EV1")); PrintAndLogEx(INFO, "Tech..... " _GREEN_("MIFARE Plus EV1"));
} else { } else {
PrintAndLogEx(INFO, " Tech...... " _YELLOW_("MIFARE Plus SE/X")); PrintAndLogEx(INFO, "Tech..... " _YELLOW_("MIFARE Plus SE/X"));
} }
isPlus = true; isPlus = true;
break; break;
} }
case PLUS_EV2: { case PLUS_EV2: {
if (supportSignature) { if (supportSignature) {
PrintAndLogEx(INFO, " Tech...... " _GREEN_("MIFARE Plus EV2")); PrintAndLogEx(INFO, "Tech..... " _GREEN_("MIFARE Plus EV2"));
} else { } else {
PrintAndLogEx(INFO, " Tech...... " _YELLOW_("MIFARE Plus EV2 ???")); PrintAndLogEx(INFO, "Tech..... " _YELLOW_("MIFARE Plus EV2 ???"));
} }
isPlus = true; isPlus = true;
break; break;
@ -378,7 +386,7 @@ static int CmdHFMFPInfo(const char *Cmd) {
return PM3_SUCCESS; return PM3_SUCCESS;
} }
default: { default: {
PrintAndLogEx(INFO, " Tech...... Unknown ( " _YELLOW_("%u") " )", cardtype); PrintAndLogEx(INFO, "Tech..... Unknown ( " _YELLOW_("%u") " )", cardtype);
break; break;
} }
} }
@ -389,37 +397,37 @@ static int CmdHFMFPInfo(const char *Cmd) {
uint16_t ATQA = card.atqa[0] + (card.atqa[1] << 8); uint16_t ATQA = card.atqa[0] + (card.atqa[1] << 8);
if (ATQA & 0x0004) { if (ATQA & 0x0004) {
PrintAndLogEx(INFO, " Size....... " _GREEN_("2K") " (%s UID)", (ATQA & 0x0040) ? "7" : "4"); PrintAndLogEx(INFO, "Size..... " _GREEN_("2K") " (%s UID)", (ATQA & 0x0040) ? "7" : "4");
isPlus = true; isPlus = true;
} }
if (ATQA & 0x0002) { if (ATQA & 0x0002) {
PrintAndLogEx(INFO, " Size....... " _GREEN_("4K") " (%s UID)", (ATQA & 0x0040) ? "7" : "4"); PrintAndLogEx(INFO, "Size..... " _GREEN_("4K") " (%s UID)", (ATQA & 0x0040) ? "7" : "4");
isPlus = true; isPlus = true;
} }
uint8_t SLmode = 0xFF; uint8_t SLmode = 0xFF;
if (isPlus) { if (isPlus) {
if (card.sak == 0x08) { if (card.sak == 0x08) {
PrintAndLogEx(INFO, " SAK....... " _GREEN_("2K 7b UID")); PrintAndLogEx(INFO, "SAK...... " _GREEN_("2K 7b UID"));
if (select_status == 2) SLmode = 1; if (select_status == 2) SLmode = 1;
} }
if (card.sak == 0x18) { if (card.sak == 0x18) {
PrintAndLogEx(INFO, " SAK....... " _GREEN_("4K 7b UID")); PrintAndLogEx(INFO, "SAK...... " _GREEN_("4K 7b UID"));
if (select_status == 2) SLmode = 1; if (select_status == 2) SLmode = 1;
} }
if (card.sak == 0x10) { if (card.sak == 0x10) {
PrintAndLogEx(INFO, " SAK....... " _GREEN_("2K")); PrintAndLogEx(INFO, "SAK...... " _GREEN_("2K"));
if (select_status == 2) SLmode = 2; if (select_status == 2) SLmode = 2;
} }
if (card.sak == 0x11) { if (card.sak == 0x11) {
PrintAndLogEx(INFO, " SAK....... " _GREEN_("4K")); PrintAndLogEx(INFO, "SAK...... " _GREEN_("4K"));
if (select_status == 2) SLmode = 2; if (select_status == 2) SLmode = 2;
} }
} }
if (card.sak == 0x20) { if (card.sak == 0x20) {
if (card.ats_len > 0) { if (card.ats_len > 0) {
PrintAndLogEx(INFO, " SAK....... " _GREEN_("MIFARE Plus SL0/SL3") " or " _GREEN_("MIFARE DESFire")); PrintAndLogEx(INFO, "SAK...... " _GREEN_("MIFARE Plus SL0/SL3") " or " _GREEN_("MIFARE DESFire"));
SLmode = 3; SLmode = 3;
// check SL0 // check SL0
uint8_t data[128] = {0}; uint8_t data[128] = {0};
@ -428,7 +436,7 @@ static int CmdHFMFPInfo(const char *Cmd) {
uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00}; uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00};
int res = ExchangeRAW14a(cmd, sizeof(cmd), true, false, data, sizeof(data), &datalen, false); int res = ExchangeRAW14a(cmd, sizeof(cmd), true, false, data, sizeof(data), &datalen, false);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
PrintAndLogEx(INFO, "identification failed"); PrintAndLogEx(INFO, "Identification failed");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
DropField(); DropField();
return PM3_SUCCESS; return PM3_SUCCESS;
@ -445,14 +453,14 @@ static int CmdHFMFPInfo(const char *Cmd) {
data[0] != 0x6E) { data[0] != 0x6E) {
PrintAndLogEx(INFO, _RED_("Send copy to iceman of this command output!")); PrintAndLogEx(INFO, _RED_("Send copy to iceman of this command output!"));
PrintAndLogEx(INFO, "data: %s", sprint_hex(data, datalen)); PrintAndLogEx(INFO, "Data... %s", sprint_hex(data, datalen));
} }
if ((memcmp(data, "\x67\x00", 2) == 0) || // wrong length if ((memcmp(data, "\x67\x00", 2) == 0) || // wrong length
(memcmp(data, "\x1C\x83\x0C", 3) == 0) // desfire answers (memcmp(data, "\x1C\x83\x0C", 3) == 0) // desfire answers
) { ) {
PrintAndLogEx(INFO, " result.... " _RED_("MIFARE DESFire")); PrintAndLogEx(INFO, "Result... " _RED_("MIFARE DESFire"));
PrintAndLogEx(HINT, "Hint: Try " _YELLOW_("`hf mfdes info`")); PrintAndLogEx(NORMAL, "");
DropField(); DropField();
return PM3_SUCCESS; return PM3_SUCCESS;
@ -461,11 +469,10 @@ static int CmdHFMFPInfo(const char *Cmd) {
// } else if (memcmp(data, "\x6E\x00", 2) == 0) { // Class not supported // } else if (memcmp(data, "\x6E\x00", 2) == 0) { // Class not supported
isPlus = false; isPlus = false;
} else { } else {
PrintAndLogEx(INFO, " result.... " _GREEN_("MIFARE Plus SL0/SL3")); PrintAndLogEx(INFO, "Result... " _GREEN_("MIFARE Plus SL0/SL3"));
} }
if ((datalen > 1) && if ((datalen > 1) && (data[0] == 0x09)) {
(data[0] == 0x09)) {
SLmode = 0; SLmode = 0;
} }
} }
@ -477,29 +484,29 @@ static int CmdHFMFPInfo(const char *Cmd) {
PrintAndLogEx(INFO, "--- " _CYAN_("Security Level (SL)")); PrintAndLogEx(INFO, "--- " _CYAN_("Security Level (SL)"));
if (SLmode != 0xFF) if (SLmode != 0xFF)
PrintAndLogEx(SUCCESS, " SL mode... " _YELLOW_("SL%d"), SLmode); PrintAndLogEx(SUCCESS, "SL mode... " _YELLOW_("SL%d"), SLmode);
else else
PrintAndLogEx(WARNING, " SL mode... " _YELLOW_("unknown")); PrintAndLogEx(WARNING, "SL mode... " _YELLOW_("unknown"));
switch (SLmode) { switch (SLmode) {
case 0: case 0:
PrintAndLogEx(INFO, " SL 0: initial delivery configuration, used for card personalization"); PrintAndLogEx(INFO, "SL 0: initial delivery configuration, used for card personalization");
break; break;
case 1: case 1:
PrintAndLogEx(INFO, " SL 1: backwards functional compatibility mode (with MIFARE Classic 1K / 4K) with an optional AES authentication"); PrintAndLogEx(INFO, "SL 1: backwards functional compatibility mode (with MIFARE Classic 1K / 4K) with an optional AES authentication");
break; break;
case 2: case 2:
PrintAndLogEx(INFO, " SL 2: 3-Pass Authentication based on AES followed by MIFARE CRYPTO1 authentication, communication secured by MIFARE CRYPTO1"); PrintAndLogEx(INFO, "SL 2: 3-Pass Authentication based on AES followed by MIFARE CRYPTO1 authentication, communication secured by MIFARE CRYPTO1");
break; break;
case 3: case 3:
PrintAndLogEx(INFO, " SL 3: 3-Pass authentication based on AES, data manipulation commands secured by AES encryption and an AES based MACing method."); PrintAndLogEx(INFO, "SL 3: 3-Pass authentication based on AES, data manipulation commands secured by AES encryption and an AES based MACing method.");
break; break;
default: default:
break; break;
} }
} }
} else { } else {
PrintAndLogEx(INFO, " Mifare Plus info not available"); PrintAndLogEx(INFO, "MIFARE Plus info not available");
} }
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
DropField(); DropField();