From cdf920b2894c6db8e91b44c6af5dcd75d1e209c5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 8 Apr 2020 14:18:21 +0200 Subject: [PATCH 1/6] coverity fix --- client/cmdhflegic.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 088800780..5c007f9f9 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -662,6 +662,8 @@ static int CmdLegicWrbl(const char *Cmd) { // OUT-OF-BOUNDS checks // UID 4+1 bytes can't be written to. if (offset < 5) { + if (data) + free(data); PrintAndLogEx(WARNING, "Out-of-bounds, bytes 0-1-2-3-4 can't be written to. Offset = %d", offset); return PM3_EOUTOFBOUND; } From 7643b24ca76b4efe150d83d986d36e6a12bd5295 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 8 Apr 2020 15:21:40 +0200 Subject: [PATCH 2/6] chg: 'hf mfp info' - colors and now checks originality for Plus EV1 --- client/cmdhfmfp.c | 75 +++++++++++++++++++++++++++++++++++++++++ client/mifare/mifare4.c | 5 +++ client/mifare/mifare4.h | 2 ++ 3 files changed, 82 insertions(+) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 31acb1a24..b872eba12 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -24,6 +24,9 @@ #include "mifare/mifaredefault.h" #include "util_posix.h" #include "fileutils.h" +#include "protocols.h" +#include "crypto/libpcrypto.h" + static const uint8_t DefaultKey[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; @@ -31,6 +34,70 @@ uint16_t CardAddresses[] = {0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 0xA000, 0xA0 static int CmdHelp(const char *Cmd); +// --- GET SIGNATURE +static int plus_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature_len) { + + // ref: MIFARE Plus EV1 Originality Signature Validation + #define PUBLIC_PLUS_ECDA_KEYLEN 57 + const ecdsa_publickey_t nxp_plus_public_keys[] = { + {"Mifare Plus EV1", "044409ADC42F91A8394066BA83D872FB1D16803734E911170412DDF8BAD1A4DADFD0416291AFE1C748253925DA39A5F39A1C557FFACD34C62E"} + }; + + uint8_t i; + int res; + bool is_valid = false; + + for (i = 0; i < ARRAYLEN(nxp_plus_public_keys); i++) { + + int dl = 0; + uint8_t key[PUBLIC_PLUS_ECDA_KEYLEN]; + param_gethex_to_eol(nxp_plus_public_keys[i].value, 0, key, PUBLIC_PLUS_ECDA_KEYLEN, &dl); + + res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP224R1, key, uid, uidlen, signature, signature_len, false); + is_valid = (res == 0); + if (is_valid) + break; + } + if (is_valid == false) { + PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed")); + return PM3_ESOFT; + } + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature")); + PrintAndLogEx(INFO, " IC signature public key name: " _GREEN_("%s"), nxp_plus_public_keys[i].desc); + PrintAndLogEx(INFO, "IC signature public key value: %.32s", nxp_plus_public_keys[i].value); + PrintAndLogEx(INFO, " : %.32s", nxp_plus_public_keys[i].value + 16); + PrintAndLogEx(INFO, " : %.32s", nxp_plus_public_keys[i].value + 32); + PrintAndLogEx(INFO, " : %.32s", nxp_plus_public_keys[i].value + 48); + PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp224r1"); + PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 16, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 32, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 48, signature_len - 48)); + PrintAndLogEx(SUCCESS, " Signature verified: " _GREEN_("successful")); + return PM3_SUCCESS; +} + +static int get_plus_signature(uint8_t *signature, int *signature_len) { + + mfpSetVerboseMode(false); + + uint8_t data[59] = {0}; + int resplen = 0, retval = PM3_SUCCESS; + MFPGetSignature(true, false, data, sizeof(data), &resplen); + + if (resplen == 59) { + memcpy(signature, data + 1, 56); + *signature_len = 56; + } else { + *signature_len = 0; + retval = PM3_ESOFT; + } + mfpSetVerboseMode(false); + return retval; +} + static int CmdHFMFPInfo(const char *Cmd) { if (Cmd && strlen(Cmd) > 0) @@ -53,6 +120,14 @@ static int CmdHFMFPInfo(const char *Cmd) { uint64_t select_status = resp.oldarg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision + // Signature originality check + uint8_t signature[56] = {0}; + int signature_len = sizeof(signature); + if (get_plus_signature(signature, &signature_len) == PM3_SUCCESS) { + plus_print_signature(card.uid, card.uidlen, signature, signature_len); + } + + if (select_status == 1 || select_status == 2) { PrintAndLogEx(INFO, "--- " _CYAN_("Fingerprint")); diff --git a/client/mifare/mifare4.c b/client/mifare/mifare4.c index 966a2027d..7b45d2d4a 100644 --- a/client/mifare/mifare4.c +++ b/client/mifare/mifare4.c @@ -429,6 +429,11 @@ int mfpReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data return 0; } +int MFPGetSignature(bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { + uint8_t c[] = {0x3c, 0x00}; + return intExchangeRAW14aPlus(c, sizeof(c), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); +} + // Mifare Memory Structure: up to 32 Sectors with 4 blocks each (1k and 2k cards), // plus evtl. 8 sectors with 16 blocks each (4k cards) uint8_t mfNumBlocksPerSector(uint8_t sectorNo) { diff --git a/client/mifare/mifare4.h b/client/mifare/mifare4.h index cb2c8d652..379218543 100644 --- a/client/mifare/mifare4.h +++ b/client/mifare/mifare4.h @@ -59,6 +59,8 @@ int MFPReadBlock(mf4Session_t *session, bool plain, uint8_t blockNum, uint8_t bl int MFPWriteBlock(mf4Session_t *session, uint8_t blockNum, uint8_t *data, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, uint8_t *mac); int mfpReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *dataout, bool verbose); +int MFPGetSignature(bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); + const char *mfGetAccessConditionsDesc(uint8_t blockn, uint8_t *data); uint8_t mfNumBlocksPerSector(uint8_t sectorNo); From 133e2a6bc49e015355b013cdaa5ee194cc296b5f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 8 Apr 2020 17:13:05 +0200 Subject: [PATCH 3/6] fix: 'hf mfp info' - now support GetVersion command (Plus EV1) --- client/cmdhfmfp.c | 99 ++++++++++++++++++++++++++++++++++++++++- client/mifare/mifare4.c | 16 +++++++ client/mifare/mifare4.h | 1 + 3 files changed, 115 insertions(+), 1 deletion(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index b872eba12..6a80b9122 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -34,6 +34,63 @@ uint16_t CardAddresses[] = {0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 0xA000, 0xA0 static int CmdHelp(const char *Cmd); +/* + The 7 MSBits (= n) code the storage size itself based on 2^n, + the LSBit is set to '0' if the size is exactly 2^n + and set to '1' if the storage size is between 2^n and 2^(n+1). + For this version of DESFire the 7 MSBits are set to 0x0C (2^12 = 4096) and the LSBit is '0'. +*/ +static char *getCardSizeStr(uint8_t fsize) { + + static char buf[40] = {0x00}; + char *retStr = buf; + + uint16_t usize = 1 << ((fsize >> 1) + 1); + uint16_t lsize = 1 << (fsize >> 1); + + // is LSB set? + if (fsize & 1) + sprintf(retStr, "0x%02X ( " _YELLOW_("%d - %d bytes") ")", fsize, usize, lsize); + else + sprintf(retStr, "0x%02X ( " _YELLOW_("%d bytes") ")", fsize, lsize); + return buf; +} + +static char *getProtocolStr(uint8_t id) { + + static char buf[40] = {0x00}; + char *retStr = buf; + + if (id == 0x05) + sprintf(retStr, "0x%02X ( " _YELLOW_("ISO 14443-3, 14443-4") ")", id); + else + sprintf(retStr, "0x%02X ( " _YELLOW_("Unknown") ")", id); + return buf; +} + +static char *getVersionStr(uint8_t major, uint8_t minor) { + + static char buf[40] = {0x00}; + char *retStr = buf; + + if (major == 0x00) + sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire MF3ICD40") ")", major, minor); + else if (major == 0x01 && minor == 0x00) + sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire EV1") ")", major, minor); + else if (major == 0x12 && minor == 0x00) + sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire EV2") ")", major, minor); +// else if (major == 0x13 && minor == 0x00) +// sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire EV3") ")", major, minor); + else if (major == 0x30 && minor == 0x00) + sprintf(retStr, "%x.%x ( " _YELLOW_("DESFire Light") ")", major, minor); + + else if (major == 0x11 && minor == 0x00) + sprintf(retStr, "%x.%x ( " _YELLOW_("Plus EV1") ")", major, minor); + else + sprintf(retStr, "%x.%x ( " _YELLOW_("Unknown") ")", major, minor); + return buf; +} + // --- GET SIGNATURE static int plus_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature_len) { @@ -97,6 +154,40 @@ static int get_plus_signature(uint8_t *signature, int *signature_len) { mfpSetVerboseMode(false); return retval; } +// GET VERSION +static int plus_print_version(uint8_t *version) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Hardware Information")); + PrintAndLogEx(INFO, " Vendor Id: " _YELLOW_("%s"), getTagInfo(version[0])); + PrintAndLogEx(INFO, " Type: " _YELLOW_("0x%02X"), version[1]); + PrintAndLogEx(INFO, " Subtype: " _YELLOW_("0x%02X"), version[2]); + PrintAndLogEx(INFO, " Version: %s", getVersionStr(version[3], version[4])); + PrintAndLogEx(INFO, " Storage size: %s", getCardSizeStr(version[5])); + PrintAndLogEx(INFO, " Protocol: %s", getProtocolStr(version[6])); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Software Information")); + PrintAndLogEx(INFO, " Vendor Id: " _YELLOW_("%s"), getTagInfo(version[0])); + PrintAndLogEx(INFO, " Type: " _YELLOW_("0x%02X"), version[1]); + PrintAndLogEx(INFO, " Subtype: " _YELLOW_("0x%02X"), version[2]); + PrintAndLogEx(INFO, " Version: " _YELLOW_("%d.%d"), version[3], version[4]); + PrintAndLogEx(INFO, " Storage size: %s", getCardSizeStr(version[5])); + PrintAndLogEx(INFO, " Protocol: %s", getProtocolStr(version[6])); + return PM3_SUCCESS; +} +static int get_plus_version(uint8_t *version, int *version_len) { + + int resplen = 0, retval = PM3_SUCCESS; + + mfpSetVerboseMode(false); + MFPGetVersion(true, false, version, *version_len, &resplen); + mfpSetVerboseMode(false); + + *version_len = resplen; + if (resplen != 14) { + retval = PM3_ESOFT; + } + return retval; +} static int CmdHFMFPInfo(const char *Cmd) { @@ -110,6 +201,13 @@ static int CmdHFMFPInfo(const char *Cmd) { // info about 14a part infoHF14A(false, false, false); + // version check + uint8_t version[15] = {0}; + int version_len = sizeof(version); + if (get_plus_version(version, &version_len) == PM3_SUCCESS) { + plus_print_version(version); + } + // Mifare Plus info SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); PacketResponseNG resp; @@ -127,7 +225,6 @@ static int CmdHFMFPInfo(const char *Cmd) { plus_print_signature(card.uid, card.uidlen, signature, signature_len); } - if (select_status == 1 || select_status == 2) { PrintAndLogEx(INFO, "--- " _CYAN_("Fingerprint")); diff --git a/client/mifare/mifare4.c b/client/mifare/mifare4.c index 7b45d2d4a..bb5742408 100644 --- a/client/mifare/mifare4.c +++ b/client/mifare/mifare4.c @@ -434,6 +434,22 @@ int MFPGetSignature(bool activateField, bool leaveSignalON, uint8_t *dataout, in return intExchangeRAW14aPlus(c, sizeof(c), activateField, leaveSignalON, dataout, maxdataoutlen, dataoutlen); } +int MFPGetVersion(bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { + uint8_t tmp[10] = {0}; + uint8_t c[] = {0x60}; + int res = intExchangeRAW14aPlus(c, sizeof(c), activateField, true, tmp, maxdataoutlen, dataoutlen); + if (tmp[0] == 0xAF) { //MFDES_ADDITIONAL_FRAME + memcpy(dataout, tmp + 1, 7); + c[0] = 0xAF; + res = intExchangeRAW14aPlus(c, sizeof(c), false, leaveSignalON, tmp, maxdataoutlen, dataoutlen); + if (res == 0) { + memcpy(dataout + 7, tmp + 1, 7); + *dataoutlen = 14; + } + } + return res; +} + // Mifare Memory Structure: up to 32 Sectors with 4 blocks each (1k and 2k cards), // plus evtl. 8 sectors with 16 blocks each (4k cards) uint8_t mfNumBlocksPerSector(uint8_t sectorNo) { diff --git a/client/mifare/mifare4.h b/client/mifare/mifare4.h index 379218543..0c3e08458 100644 --- a/client/mifare/mifare4.h +++ b/client/mifare/mifare4.h @@ -60,6 +60,7 @@ int MFPWriteBlock(mf4Session_t *session, uint8_t blockNum, uint8_t *data, bool a int mfpReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *dataout, bool verbose); int MFPGetSignature(bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); +int MFPGetVersion(bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); const char *mfGetAccessConditionsDesc(uint8_t blockn, uint8_t *data); From f216fc7f5ed925109a24842bfc59b9c69c54424a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 8 Apr 2020 19:07:11 +0200 Subject: [PATCH 4/6] chg: hf mfp info - need all data from getversion. Layout changes --- client/cmdhfmfp.c | 86 +++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 36 deletions(-) diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index 6a80b9122..fa4feb5a4 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -156,6 +156,9 @@ static int get_plus_signature(uint8_t *signature, int *signature_len) { } // GET VERSION static int plus_print_version(uint8_t *version) { + PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(version + 14, 7)); + PrintAndLogEx(SUCCESS, " Batch number: " _GREEN_("%s"), sprint_hex(version + 21, 5)); + PrintAndLogEx(SUCCESS, " Production date: week " _GREEN_("%02x") "/ " _GREEN_("20%02x"), version[7+7+7+5], version[7+7+7+5+1]); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("Hardware Information")); PrintAndLogEx(INFO, " Vendor Id: " _YELLOW_("%s"), getTagInfo(version[0])); @@ -177,13 +180,12 @@ static int plus_print_version(uint8_t *version) { static int get_plus_version(uint8_t *version, int *version_len) { int resplen = 0, retval = PM3_SUCCESS; - mfpSetVerboseMode(false); MFPGetVersion(true, false, version, *version_len, &resplen); mfpSetVerboseMode(false); *version_len = resplen; - if (resplen != 14) { + if (resplen != 28) { retval = PM3_ESOFT; } return retval; @@ -198,14 +200,18 @@ static int CmdHFMFPInfo(const char *Cmd) { PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") "---------------------------"); PrintAndLogEx(INFO, "-------------------------------------------------------------"); - // info about 14a part - infoHF14A(false, false, false); + bool supportVersion = false; + bool supportSignature = false; // version check - uint8_t version[15] = {0}; + uint8_t version[30] = {0}; int version_len = sizeof(version); if (get_plus_version(version, &version_len) == PM3_SUCCESS) { plus_print_version(version); + supportVersion = true; + } else { + // info about 14a part + infoHF14A(false, false, false); } // Mifare Plus info @@ -223,11 +229,18 @@ static int CmdHFMFPInfo(const char *Cmd) { int signature_len = sizeof(signature); if (get_plus_signature(signature, &signature_len) == PM3_SUCCESS) { plus_print_signature(card.uid, card.uidlen, signature, signature_len); + supportSignature = true; } if (select_status == 1 || select_status == 2) { PrintAndLogEx(INFO, "--- " _CYAN_("Fingerprint")); + + if (supportVersion && supportSignature) { + PrintAndLogEx(INFO, " Tech: " _GREEN_("MIFARE Plus EV1")); + } else { + PrintAndLogEx(INFO, " Tech: " _YELLOW_("MIFARE Plus SE/X")); + } // MIFARE Type Identification Procedure // https://www.nxp.com/docs/en/application-note/AN10833.pdf @@ -235,36 +248,36 @@ static int CmdHFMFPInfo(const char *Cmd) { bool isPlus = false; if (ATQA & 0x0004) { - PrintAndLogEx(INFO, " ATQA - " _GREEN_("MIFARE Plus 2K") "(%s UID)", (ATQA & 0x0040) ? "7" : "4"); + PrintAndLogEx(INFO, " ATQA: " _GREEN_("2K") "(%s UID)", (ATQA & 0x0040) ? "7" : "4"); isPlus = true; } if (ATQA & 0x0002) { - PrintAndLogEx(INFO, " ATQA - " _GREEN_("MIFARE Plus 4K") "(%s UID)", (ATQA & 0x0040) ? "7" : "4"); + PrintAndLogEx(INFO, " ATQA: " _GREEN_("4K") "(%s UID)", (ATQA & 0x0040) ? "7" : "4"); isPlus = true; } - uint8_t SLmode = 0xff; + uint8_t SLmode = 0xFF; if (isPlus) { if (card.sak == 0x08) { - PrintAndLogEx(INFO, " SAK - " _GREEN_("MIFARE Plus 2K 7b UID")); + PrintAndLogEx(INFO, " SAK: " _GREEN_("2K 7b UID")); if (select_status == 2) SLmode = 1; } if (card.sak == 0x18) { - PrintAndLogEx(INFO, " SAK - " _GREEN_("MIFARE Plus 4K 7b UID")); + PrintAndLogEx(INFO, " SAK: " _GREEN_("4K 7b UID")); if (select_status == 2) SLmode = 1; } if (card.sak == 0x10) { - PrintAndLogEx(INFO, " SAK - " _GREEN_("MIFARE Plus 2K")); + PrintAndLogEx(INFO, " SAK: " _GREEN_("2K")); if (select_status == 2) SLmode = 2; } if (card.sak == 0x11) { - PrintAndLogEx(INFO, " SAK - " _GREEN_("MIFARE Plus 4K")); + PrintAndLogEx(INFO, " SAK: " _GREEN_("4K")); if (select_status == 2) SLmode = 2; } } if (card.sak == 0x20) { - PrintAndLogEx(INFO, " SAK - " _GREEN_("MIFARE Plus SL0/SL3") "or " _GREEN_("MIFARE DESFire")); + PrintAndLogEx(INFO, " SAK: " _GREEN_("MIFARE Plus SL0/SL3") "or " _GREEN_("MIFARE DESFire")); if (card.ats_len > 0) { @@ -289,34 +302,35 @@ static int CmdHFMFPInfo(const char *Cmd) { } } - // How do we detect SL0 / SL1 / SL2 / SL3 modes?!? - PrintAndLogEx(INFO, "--- " _CYAN_("Security Level (SL)")); + if (isPlus) { + // How do we detect SL0 / SL1 / SL2 / SL3 modes?!? + PrintAndLogEx(INFO, "--- " _CYAN_("Security Level (SL)")); - if (SLmode != 0xFF) - PrintAndLogEx(SUCCESS, " MIFARE Plus SL mode: " _YELLOW_("SL%d"), SLmode); - else - PrintAndLogEx(WARNING, " MIFARE Plus SL mode: " _YELLOW_("unknown")); - - switch(SLmode) { - case 0: - PrintAndLogEx(INFO, " SL 0: initial delivery configuration, used for card personalization"); - break; - case 1: - PrintAndLogEx(INFO, " SL 1: backwards functional compatibility mode (with MIFARE Classic 1K / 4K) with an optional AES authentication"); - break; - case 2: - PrintAndLogEx(INFO, " SL 2: 3-Pass Authentication based on AES followed by MIFARE CRYPTO1 authentication, communication secured by MIFARE CRYPTO1"); - break; - 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."); - break; - default: - break; + if (SLmode != 0xFF ) + PrintAndLogEx(SUCCESS, " SL mode: " _YELLOW_("SL%d"), SLmode); + else + PrintAndLogEx(WARNING, " SL mode: " _YELLOW_("unknown")); + switch(SLmode) { + case 0: + PrintAndLogEx(INFO, " SL 0: initial delivery configuration, used for card personalization"); + break; + case 1: + PrintAndLogEx(INFO, " SL 1: backwards functional compatibility mode (with MIFARE Classic 1K / 4K) with an optional AES authentication"); + break; + case 2: + PrintAndLogEx(INFO, " SL 2: 3-Pass Authentication based on AES followed by MIFARE CRYPTO1 authentication, communication secured by MIFARE CRYPTO1"); + break; + 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."); + break; + default: + break; + } } } else { PrintAndLogEx(INFO, "\tMifare Plus info not available."); } - + PrintAndLogEx(NORMAL, ""); DropField(); return PM3_SUCCESS; } From df83c71470409452e2c0023f22359fe3098c02ad Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 8 Apr 2020 19:07:17 +0200 Subject: [PATCH 5/6] chg: hf mfp info - need all data from getversion. Layout changes --- client/mifare/mifare4.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/client/mifare/mifare4.c b/client/mifare/mifare4.c index bb5742408..848528611 100644 --- a/client/mifare/mifare4.c +++ b/client/mifare/mifare4.c @@ -435,18 +435,37 @@ int MFPGetSignature(bool activateField, bool leaveSignalON, uint8_t *dataout, in } int MFPGetVersion(bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { - uint8_t tmp[10] = {0}; + uint8_t tmp[20] = {0}; uint8_t c[] = {0x60}; int res = intExchangeRAW14aPlus(c, sizeof(c), activateField, true, tmp, maxdataoutlen, dataoutlen); - if (tmp[0] == 0xAF) { //MFDES_ADDITIONAL_FRAME - memcpy(dataout, tmp + 1, 7); + if (res != 0) { + DropField(); + *dataoutlen = 0; + return res; + } + + memcpy(dataout, tmp + 1, (*dataoutlen - 3)); + + *dataoutlen = 0; + // MFDES_ADDITIONAL_FRAME + if (tmp[0] == 0xAF) { c[0] = 0xAF; - res = intExchangeRAW14aPlus(c, sizeof(c), false, leaveSignalON, tmp, maxdataoutlen, dataoutlen); + res = intExchangeRAW14aPlus(c, sizeof(c), false, true, tmp, maxdataoutlen, dataoutlen); if (res == 0) { - memcpy(dataout + 7, tmp + 1, 7); - *dataoutlen = 14; + + memcpy(dataout + 7, tmp + 1, (*dataoutlen - 3)); + + // MFDES_ADDITIONAL_FRAME + res = intExchangeRAW14aPlus(c, sizeof(c), false, false, tmp, maxdataoutlen, dataoutlen); + if (res == 0) { + if (tmp[0] == 0x90) { + memcpy(dataout + 7 + 7, tmp + 1, (*dataoutlen - 3)); + *dataoutlen = 28; + } + } } } + DropField(); return res; } From 68a890d0e9e1a1a9e40dafff984ad08f2c2484b9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 8 Apr 2020 19:16:42 +0200 Subject: [PATCH 6/6] textual --- client/cmdhf14a.c | 6 ++---- client/cmdhfmfp.c | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 60f54adaf..2e5fcb69e 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -1317,10 +1317,8 @@ int detect_nxp_card(uint8_t sak, uint16_t atqa) { printTag("MIFARE NTAG424DNA (Random ID feature)"); type |= MTDESFIRE; } else { - printTag("MIFARE Plus 2K / Plus EV1 2K"); - printTag("MIFARE Plus 4K / Plus EV1 4K"); - printTag("MIFARE Plus CL2 2K / Plus CL2 EV1 4K"); - printTag("MIFARE Plus CL2 4K / Plus CL2 EV1 4K"); + printTag("MIFARE Plus 2K/4K / Plus EV1 2K/4K"); + printTag("MIFARE Plus CL2 2K/4K / Plus CL2 EV1 2K/4K"); type |= MTPLUS; } } diff --git a/client/cmdhfmfp.c b/client/cmdhfmfp.c index fa4feb5a4..71da93bcc 100644 --- a/client/cmdhfmfp.c +++ b/client/cmdhfmfp.c @@ -248,11 +248,11 @@ static int CmdHFMFPInfo(const char *Cmd) { bool isPlus = false; if (ATQA & 0x0004) { - PrintAndLogEx(INFO, " ATQA: " _GREEN_("2K") "(%s UID)", (ATQA & 0x0040) ? "7" : "4"); + PrintAndLogEx(INFO, " SIZE: " _GREEN_("2K") "(%s UID)", (ATQA & 0x0040) ? "7" : "4"); isPlus = true; } if (ATQA & 0x0002) { - PrintAndLogEx(INFO, " ATQA: " _GREEN_("4K") "(%s UID)", (ATQA & 0x0040) ? "7" : "4"); + PrintAndLogEx(INFO, " SIZE: " _GREEN_("4K") "(%s UID)", (ATQA & 0x0040) ? "7" : "4"); isPlus = true; }