diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 7ea08e59c..a35ac4c57 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -93,8 +93,6 @@ #define CheckCrc15(data, len) check_crc(CRC_15693, (data), (len)) #define AddCrc15(data, len) compute_crc(CRC_15693, (data), (len), (data)+(len), (data)+(len)+1) -#define sprintUID(target,uid) Iso15693sprintUID((target), (uid)) - static void BuildIdentifyRequest(uint8_t *cmdout); //static void BuildReadBlockRequest(uint8_t *cmdout, uint8_t *uid, uint8_t blockNumber ); static void BuildInventoryResponse(uint8_t *cmdout, uint8_t *uid); @@ -946,7 +944,7 @@ void BruteforceIso15693Afi(uint32_t speed) { WDT_HIT(); if (recvlen >= 12) { - Dbprintf("NoAFI UID = %s", sprintUID(NULL, buf + 2)); + Dbprintf("NoAFI UID = %s", iso15693_sprintUID(NULL, buf + 2)); } // now with AFI @@ -964,7 +962,7 @@ void BruteforceIso15693Afi(uint32_t speed) { recvlen = SendDataTag(data, datalen, false, speed, buf); WDT_HIT(); if (recvlen >= 12) { - Dbprintf("AFI = %i UID = %s", i, sprintUID(NULL, buf + 2)); + Dbprintf("AFI = %i UID = %s", i, iso15693_sprintUID(NULL, buf + 2)); } aborted = BUTTON_PRESS(); diff --git a/client/cmdhf15.c b/client/cmdhf15.c index a5c9e5877..b6a601391 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -50,10 +50,6 @@ #define AddCrc15(data, len) compute_crc(CRC_15693, (data), (len), (data)+(len), (data)+(len)+1) #endif -#ifndef sprintUID -# define sprintUID(target, uid) Iso15693sprintUID((target), (uid)) -#endif - typedef struct { uint8_t lock; uint8_t block[4]; @@ -212,54 +208,70 @@ const productName uidmapping[] = { { 0, 0, "no tag-info available" } // must be the last entry }; -#define PUBLIC_ECDA_KEYLEN 33 -uint8_t nxp_15693_public_keys[][PUBLIC_ECDA_KEYLEN] = { - // ICODE SLIX2 / DNA - { - 0x04, 0x88, 0x78, 0xA2, 0xA2, 0xD3, 0xEE, 0xC3, - 0x36, 0xB4, 0xF2, 0x61, 0xA0, 0x82, 0xBD, 0x71, - 0xF9, 0xBE, 0x11, 0xC4, 0xE2, 0xE8, 0x96, 0x64, - 0x8B, 0x32, 0xEF, 0xA5, 0x9C, 0xEA, 0x6E, 0x59, 0xF0 - }, - // unknown. Needs identification - { - 0x04, 0x4F, 0x6D, 0x3F, 0x29, 0x4D, 0xEA, 0x57, - 0x37, 0xF0, 0xF4, 0x6F, 0xFE, 0xE8, 0x8A, 0x35, - 0x6E, 0xED, 0x95, 0x69, 0x5D, 0xD7, 0xE0, 0xC2, - 0x7A, 0x59, 0x1E, 0x6F, 0x6F, 0x65, 0x96, 0x2B, 0xAF - }, - // unknown. Needs identification - { - 0x04, 0xA7, 0x48, 0xB6, 0xA6, 0x32, 0xFB, 0xEE, - 0x2C, 0x08, 0x97, 0x70, 0x2B, 0x33, 0xBE, 0xA1, - 0xC0, 0x74, 0x99, 0x8E, 0x17, 0xB8, 0x4A, 0xCA, - 0x04, 0xFF, 0x26, 0x7E, 0x5D, 0x2C, 0x91, 0xF6, 0xDC - }, - // manufacturer public key - { - 0x04, 0x6F, 0x70, 0xAC, 0x55, 0x7F, 0x54, 0x61, - 0xCE, 0x50, 0x52, 0xC8, 0xE4, 0xA7, 0x83, 0x8C, - 0x11, 0xC7, 0xA2, 0x36, 0x79, 0x7E, 0x8A, 0x07, - 0x30, 0xA1, 0x01, 0x83, 0x7C, 0x00, 0x40, 0x39, 0xC2 - }, - // MIKRON public key. - { - 0x04, 0xf9, 0x71, 0xed, 0xa7, 0x42, 0xa4, 0xa8, - 0x0d, 0x32, 0xdc, 0xf6, 0xa8, 0x14, 0xa7, 0x07, - 0xcc, 0x3d, 0xc3, 0x96, 0xd3, 0x59, 0x02, 0xf7, - 0x29, 0x29, 0xfd, 0xcd, 0x69, 0x8b, 0x34, 0x68, 0xf2 - } -}; - static int CmdHF15Help(const char *Cmd); static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) { + #define PUBLIC_ECDA_KEYLEN 33 + const ecdsa_publickey_t nxp_15693_public_keys[] = { + {"NXP Mifare Classic MFC1C14_x", "044F6D3F294DEA5737F0F46FFEE88A356EED95695DD7E0C27A591E6F6F65962BAF"}, + {"Manufacturer Mifare Classic MFC1C14_x", "046F70AC557F5461CE5052C8E4A7838C11C7A236797E8A0730A101837C004039C2"}, + {"NXP ICODE DNA, ICODE SLIX2", "048878A2A2D3EEC336B4F261A082BD71F9BE11C4E2E896648B32EFA59CEA6E59F0"}, + {"NXP Public key", "04A748B6A632FBEE2C0897702B33BEA1C074998E17B84ACA04FF267E5D2C91F6DC"}, + {"NXP Ultralight Ev1", "0490933BDCD6E99B4E255E3DA55389A827564E11718E017292FAF23226A96614B8"}, + {"NXP NTAG21x (2013)", "04494E1A386D3D3CFE3DC10E5DE68A499B1C202DB5B132393E89ED19FE5BE8BC61"}, + {"MICRON Public key", "04f971eda742a4a80d32dcf6a814a707cc3dc396d35902f72929fdcd698b3468f2"}, + }; +/* + uint8_t nxp_15693_public_keys[][PUBLIC_ECDA_KEYLEN] = { + // ICODE SLIX2 / DNA + { + 0x04, 0x88, 0x78, 0xA2, 0xA2, 0xD3, 0xEE, 0xC3, + 0x36, 0xB4, 0xF2, 0x61, 0xA0, 0x82, 0xBD, 0x71, + 0xF9, 0xBE, 0x11, 0xC4, 0xE2, 0xE8, 0x96, 0x64, + 0x8B, 0x32, 0xEF, 0xA5, 0x9C, 0xEA, 0x6E, 0x59, 0xF0 + }, + // unknown. Needs identification + { + 0x04, 0x4F, 0x6D, 0x3F, 0x29, 0x4D, 0xEA, 0x57, + 0x37, 0xF0, 0xF4, 0x6F, 0xFE, 0xE8, 0x8A, 0x35, + 0x6E, 0xED, 0x95, 0x69, 0x5D, 0xD7, 0xE0, 0xC2, + 0x7A, 0x59, 0x1E, 0x6F, 0x6F, 0x65, 0x96, 0x2B, 0xAF + }, + // unknown. Needs identification + { + 0x04, 0xA7, 0x48, 0xB6, 0xA6, 0x32, 0xFB, 0xEE, + 0x2C, 0x08, 0x97, 0x70, 0x2B, 0x33, 0xBE, 0xA1, + 0xC0, 0x74, 0x99, 0x8E, 0x17, 0xB8, 0x4A, 0xCA, + 0x04, 0xFF, 0x26, 0x7E, 0x5D, 0x2C, 0x91, 0xF6, 0xDC + }, + // manufacturer public key + { + 0x04, 0x6F, 0x70, 0xAC, 0x55, 0x7F, 0x54, 0x61, + 0xCE, 0x50, 0x52, 0xC8, 0xE4, 0xA7, 0x83, 0x8C, + 0x11, 0xC7, 0xA2, 0x36, 0x79, 0x7E, 0x8A, 0x07, + 0x30, 0xA1, 0x01, 0x83, 0x7C, 0x00, 0x40, 0x39, 0xC2 + }, + // MIKRON public key. + { + 0x04, 0xf9, 0x71, 0xed, 0xa7, 0x42, 0xa4, 0xa8, + 0x0d, 0x32, 0xdc, 0xf6, 0xa8, 0x14, 0xa7, 0x07, + 0xcc, 0x3d, 0xc3, 0x96, 0xd3, 0x59, 0x02, 0xf7, + 0x29, 0x29, 0xfd, 0xcd, 0x69, 0x8b, 0x34, 0x68, 0xf2 + } + }; +*/ + uint8_t i; int res; bool is_valid = false; for (i = 0; i< ARRAYLEN(nxp_15693_public_keys); i++) { - res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, nxp_15693_public_keys[i], uid, 8, signature, 32, false); + + int dl = 0; + uint8_t key[PUBLIC_ECDA_KEYLEN]; + param_gethex_to_eol(nxp_15693_public_keys[i].value, 0, key, PUBLIC_ECDA_KEYLEN, &dl); + + res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, uid, 8, signature, 32, false); is_valid = (res == 0); if (is_valid) break; @@ -271,12 +283,12 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) { return PM3_ESOFT; } - PrintAndLogEx(INFO, "\n--- Tag Signature"); - PrintAndLogEx(INFO, " IC signature public key name : %s", (i == 0)? "NXP ICODE SLIX2 / DNA" : "unknown, post on forum"); - PrintAndLogEx(INFO, " IC signature public key value : %s", sprint_hex(nxp_15693_public_keys[i], 33)); - PrintAndLogEx(INFO, " Elliptic curve parameters : NID_secp128r1"); - PrintAndLogEx(INFO, " TAG IC Signature : %s", sprint_hex(signature, 32)); - PrintAndLogEx(INFO, " Signature verification " _GREEN_("successful")); + PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature")); + PrintAndLogEx(INFO, " IC signature public key name: %s", nxp_15693_public_keys[i].desc); + PrintAndLogEx(INFO, "IC signature public key value: %s", nxp_15693_public_keys[i].value); + PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp128r1"); + PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex(signature, 32)); + PrintAndLogEx(SUCCESS, " Signature verified: " _GREEN_("successful")); return PM3_SUCCESS; } @@ -577,7 +589,7 @@ static bool prepareHF15Cmd(char **cmd, uint16_t *reqlen, uint8_t *arg1, uint8_t return false; } memcpy(&req[tmpreqlen], uid, sizeof(uid)); - PrintAndLogEx(SUCCESS, "Detected UID %s", sprintUID(NULL, uid)); + PrintAndLogEx(SUCCESS, "Detected UID " _GREEN_("%s"), iso15693_sprintUID(NULL,uid)); tmpreqlen += sizeof(uid); break; default: @@ -590,7 +602,7 @@ static bool prepareHF15Cmd(char **cmd, uint16_t *reqlen, uint8_t *arg1, uint8_t uid[7 - i] = temp & 0xff; } - PrintAndLogEx(SUCCESS, "Using UID %s", sprintUID(NULL, uid)); + PrintAndLogEx(SUCCESS, "Using UID " _GREEN_("%s"), iso15693_sprintUID(NULL,uid)); memcpy(&req[tmpreqlen], uid, sizeof(uid)); tmpreqlen += sizeof(uid); break; @@ -870,8 +882,8 @@ static int NxpSysInfo(uint8_t *uid) { */ static int CmdHF15Info(const char *Cmd) { - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_15_info(); + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) < 1 || cmdp == 'h') return usage_15_info(); PacketResponseNG resp; uint8_t *recv; @@ -890,11 +902,8 @@ static int CmdHF15Info(const char *Cmd) { AddCrc15(req, reqlen); reqlen += 2; - // PrintAndLogEx(NORMAL, "cmd %s", sprint_hex(req, reqlen) ); - clearCommandBuffer(); SendCommandOLD(CMD_HF_ISO15693_COMMAND, reqlen, arg1, 1, req, reqlen); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { PrintAndLogEx(WARNING, "iso15693 card select failed"); DropField(); @@ -918,11 +927,12 @@ static int CmdHF15Info(const char *Cmd) { } memcpy(uid, recv + 2, sizeof(uid)); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, " UID : %s", sprintUID(NULL, uid)); - PrintAndLogEx(SUCCESS, " TYPE : %s", getTagInfo_15(recv + 2)); - PrintAndLogEx(SUCCESS, " SYSINFO : %s", sprint_hex(recv, status - 2)); + PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") "---------"); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); + PrintAndLogEx(SUCCESS, " TYPE: " _YELLOW_("%s"), getTagInfo_15(recv + 2)); + PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), iso15693_sprintUID(NULL,uid)); + PrintAndLogEx(SUCCESS, " SYSINFO: %s", sprint_hex(recv, status - 2)); // DSFID if (recv[1] & 0x01) @@ -953,7 +963,7 @@ static int CmdHF15Info(const char *Cmd) { } // Check if SLIX2 and attempt to get NXP System Information - PrintAndLogEx(INFO, "4 & 08 :: %02x 7 == 1 :: %u 8 == 4 :: %u", recv[4], recv[7], recv[8]); + PrintAndLogEx(DEBUG, "4 & 08 :: %02x 7 == 1 :: %u 8 == 4 :: %u", recv[4], recv[7], recv[8]); if (recv[8] == 0x04 && recv[7] == 0x01 && recv[4] & 0x80) { return NxpSysInfo(uid); } @@ -993,7 +1003,7 @@ static int CmdHF15Sim(const char *Cmd) { return PM3_EINVARG; } - PrintAndLogEx(SUCCESS, "Starting simulating UID %s", sprint_hex(uid, sizeof(uid))); + PrintAndLogEx(SUCCESS, "Starting simulating UID " _YELLOW_("%s"), iso15693_sprintUID(NULL,uid)); clearCommandBuffer(); SendCommandOLD(CMD_HF_ISO15693_SIMULATE, 0, 0, 0, uid, 8); @@ -1191,7 +1201,7 @@ static int CmdHF15Dump(const char *Cmd) { } // detect blocksize from card :) - PrintAndLogEx(SUCCESS, "Reading memory from tag UID " _YELLOW_("%s"), sprintUID(NULL, uid)); + PrintAndLogEx(SUCCESS, "Reading memory from tag UID " _YELLOW_("%s"), iso15693_sprintUID(NULL,uid)); int blocknum = 0; uint8_t *recv = NULL; @@ -1752,7 +1762,7 @@ static int CmdHF15CSetUID(const char *Cmd) { return PM3_EINVARG; } - PrintAndLogEx(SUCCESS, "Input new UID | %s", sprint_hex(uid, sizeof(uid))); + PrintAndLogEx(SUCCESS, "Input new UID | " _YELLOW_("%s"), iso15693_sprintUID(NULL,uid)); if (!getUID(oldUid)) { PrintAndLogEx(FAILED, "Can't get old/current UID."); @@ -1823,8 +1833,8 @@ static int CmdHF15CSetUID(const char *Cmd) { PrintAndLogEx(FAILED, "Setting UID on tag failed."); return PM3_ESOFT; } else { - PrintAndLogEx(SUCCESS, "old UID : %02X %02X %02X %02X %02X %02X %02X %02X", oldUid[7], oldUid[6], oldUid[5], oldUid[4], oldUid[3], oldUid[2], oldUid[1], oldUid[0]); - PrintAndLogEx(SUCCESS, "new UID : %02X %02X %02X %02X %02X %02X %02X %02X", newUid[7], newUid[6], newUid[5], newUid[4], newUid[3], newUid[2], newUid[1], newUid[0]); + PrintAndLogEx(SUCCESS, "Old: %s", iso15693_sprintUID(NULL, oldUid)); + PrintAndLogEx(SUCCESS, "New: " _GREEN_("%s"), iso15693_sprintUID(NULL, newUid)); return PM3_SUCCESS; } } @@ -1873,7 +1883,7 @@ bool readHF15Uid(bool verbose) { return false; } PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, " UID : %s", sprintUID(NULL, uid)); - PrintAndLogEx(SUCCESS, " TYPE : %s", getTagInfo_15(uid)); + PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), iso15693_sprintUID(NULL, uid)); + PrintAndLogEx(SUCCESS, "TYPE: " _YELLOW_("%s"), getTagInfo_15(uid)); return true; } diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index bfc842071..62f952824 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -27,7 +27,6 @@ uint8_t key_ones_data[16] = { 0x01 }; uint8_t key_defa_data[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; uint8_t key_picc_data[16] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f }; - typedef enum { UNKNOWN = 0, MF3ICD40, @@ -122,10 +121,20 @@ static int get_desfire_freemem(uint32_t *free_mem) { // --- GET SIGNATURE static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t signature_len, desfire_cardtype_t card_type) { - #define PUBLIC_DESFIRE_ECDA_KEYLEN 57 - // DESFire Ev3 - wanted // ref: MIFARE Desfire Originality Signature Validation + + #define PUBLIC_DESFIRE_ECDA_KEYLEN 57 + const ecdsa_publickey_t nxp_desfire_public_keys[] = { + {"NTAG42x 1-3 NTAG 424 DNA TagTamper, NTAG426 TT, NTAG424DNA, DESFire EV2", "048A9B380AF2EE1B98DC417FECC263F8449C7625CECE82D9B916C992DA209D68422B81EC20B65A66B5102A61596AF3379200599316A00A1410"}, + {"NTAG42x 4, NTAG426, DESFire Ev2", "04B304DC4C615F5326FE9383DDEC9AA892DF3A57FA7FFB3276192BC0EAA252ED45A865E3B093A3D0DCE5BE29E92F1392CE7DE321E3E5C52B3A"}, + {"NTAG42x 3, NTAG 424 DNA, DESFire Light EV1", "040E98E117AAA36457F43173DC920A8757267F44CE4EC5ADD3C54075571AEBBF7B942A9774A1D94AD02572427E5AE0A2DD36591B1FB34FCF3D"}, + {"NTAG413DNA, DESFire EV1", "04BB5D514F7050025C7D0F397310360EEC91EAF792E96FC7E0F496CB4E669D414F877B7B27901FE67C2E3B33CD39D1C797715189AC951C2ADD"}, + {"Mifare Plus", "044409ADC42F91A8394066BA83D872FB1D16803734E911170412DDF8BAD1A4DADFD0416291AFE1C748253925DA39A5F39A1C557FFACD34C62E"}, + {"NTAG424DNA, NTAG424DNATT (Tag Tamper), DESFire Light EV2", "04B304DC4C615F5326FE9383DDEC9AA892DF3A57FA7FFB3276192BC0EAA252ED45A865E3B093A3D0DCE5BE29E92F1392CE7DE321E3E5C52B3B"}, + }; + +/* uint8_t nxp_desfire_keys[][PUBLIC_DESFIRE_ECDA_KEYLEN] = { // NTAG42x 3 - NTAG 424 DNA, DESFire Light { @@ -137,7 +146,7 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign 0xD0, 0x25, 0x72, 0x42, 0x7E, 0x5A, 0xE0, 0xA2, 0xDD, 0x36, 0x59, 0x1B, 0x1F, 0xB3, 0x4F, 0xCF, 0x3D }, - + // NTAG42x 1-3 NTAG 424 DNA TagTamper, NTAG426 TT { 0x04, 0x8A, 0x9B, 0x38, 0x0A, 0xF2, 0xEE, 0x1B, @@ -148,7 +157,7 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign 0xB5, 0x10, 0x2A, 0x61, 0x59, 0x6A, 0xF3, 0x37, 0x92, 0x00, 0x59, 0x93, 0x16, 0xA0, 0x0A, 0x14, 0x10 }, - + // Unknown - needs identification { 0x04, 0x44, 0x09, 0xAD, 0xC4, 0x2F, 0x91, 0xA8, @@ -159,7 +168,7 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign 0x48, 0x25, 0x39, 0x25, 0xDA, 0x39, 0xA5, 0xF3, 0x9A, 0x1C, 0x55, 0x7F, 0xFA, 0xCD, 0x34, 0xC6, 0x2E }, - + // NTAG42x 4 - NTAG426, DESFire Ev2 { 0x04, 0xB3, 0x04, 0xDC, 0x4C, 0x61, 0x5F, 0x53, @@ -170,17 +179,30 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign 0xDC, 0xE5, 0xBE, 0x29, 0xE9, 0x2F, 0x13, 0x92, 0xCE, 0x7D, 0xE3, 0x21, 0xE3, 0xE5, 0xC5, 0x2B, 0x3A }, - + // Unknown - needs identification + { + 0x04, 0xBB, 0x5D, 0x51, 0x4F, 0x70, 0x50, 0x02, + 0x5C, 0x7D, 0x0F, 0x39, 0x73, 0x10, 0x36, 0x0E, + 0xEC, 0x91, 0xEA, 0xF7, 0x92, 0xE9, 0x6F, 0xC7, + 0xE0, 0xF4, 0x96, 0xCB, 0x4E, 0x66, 0x9D, 0x41, + 0x4F, 0x87, 0x7B, 0x7B, 0x27, 0x90, 0x1F, 0xE6, + 0x7C, 0x2E, 0x3B, 0x33, 0xCD, 0x39, 0xD1, 0xC7, + 0x97, 0x71, 0x51, 0x89, 0xAC, 0x95, 0x1C, 0x2A, 0xDD + } }; - +*/ + uint8_t i; int res; bool is_valid = false; - for (i = 0; i< ARRAYLEN(nxp_desfire_keys); i++) { - - res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP224R1, nxp_desfire_keys[i], uid, 7, signature, signature_len, false); - + for (i = 0; i< ARRAYLEN(nxp_desfire_public_keys); i++) { + + int dl = 0; + uint8_t key[PUBLIC_DESFIRE_ECDA_KEYLEN]; + param_gethex_to_eol(nxp_desfire_public_keys[i].value, 0, key, PUBLIC_DESFIRE_ECDA_KEYLEN, &dl); + + res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP224R1, key, uid, 7, signature, signature_len, false); is_valid = (res == 0); if (is_valid) break; @@ -190,6 +212,7 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign return PM3_ESOFT; } +/* char *publickeyname; switch(i) { case 0: @@ -205,19 +228,20 @@ static int desfire_print_signature(uint8_t *uid, uint8_t *signature, size_t sign publickeyname = "Unknown DESFire, post on forum"; break; } + */ - PrintAndLogEx(INFO, " Tag Signature"); - PrintAndLogEx(INFO, " IC signature public key name : %s", publickeyname); - PrintAndLogEx(INFO, " IC signature public key value : %s", sprint_hex(nxp_desfire_keys[i], 16)); - PrintAndLogEx(INFO, " : %s", sprint_hex(nxp_desfire_keys[i] + 16, 16)); - PrintAndLogEx(INFO, " : %s", sprint_hex(nxp_desfire_keys[i] + 32, 16)); - PrintAndLogEx(INFO, " : %s", sprint_hex(nxp_desfire_keys[i] + 48, PUBLIC_DESFIRE_ECDA_KEYLEN - 48)); - PrintAndLogEx(INFO, " Elliptic curve parameters : NID_secp224r1"); - PrintAndLogEx(INFO, " TAG IC Signature : %s", sprint_hex(signature, 16)); - PrintAndLogEx(INFO, " : %s", sprint_hex(signature + 16, 16)); - PrintAndLogEx(INFO, " : %s", sprint_hex(signature + 32, 16)); - PrintAndLogEx(INFO, " : %s", sprint_hex(signature + 48, signature_len - 48)); - PrintAndLogEx( (is_valid) ? SUCCESS : WARNING, " Signature verified " _GREEN_("successful")); + PrintAndLogEx(INFO, "--- Tag Signature"); + PrintAndLogEx(INFO, "IC signature public key name : %s", nxp_desfire_public_keys[i].desc); + PrintAndLogEx(INFO, "IC signature public key value : %.16s", nxp_desfire_public_keys[i].value); + PrintAndLogEx(INFO, " : %.16s", nxp_desfire_public_keys[i].value + 16); + PrintAndLogEx(INFO, " : %.16s", nxp_desfire_public_keys[i].value + 32); + PrintAndLogEx(INFO, " : %.16s", nxp_desfire_public_keys[i].value + 48); + PrintAndLogEx(INFO, " Elliptic curve parameters : NID_secp224r1"); + PrintAndLogEx(INFO, " TAG IC Signature : %s", sprint_hex(signature, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex(signature + 16, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex(signature + 32, 16)); + PrintAndLogEx(INFO, " : %s", sprint_hex(signature + 48, signature_len - 48)); + PrintAndLogEx( (is_valid) ? SUCCESS : WARNING, "Signature verified " _GREEN_("successful")); PrintAndLogEx(INFO, "-------------------------------------------------------------"); return PM3_SUCCESS; } diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index af501d8f2..7b9750cb0 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -8,9 +8,7 @@ // High frequency MIFARE ULTRALIGHT (C) commands //----------------------------------------------------------------------------- #include "cmdhfmfu.h" - #include - #include "cmdparser.h" #include "commonutil.h" #include "crypto/libpcrypto.h" @@ -535,7 +533,7 @@ static int ul_print_default(uint8_t *data) { sprint_bin(data + 10, 2) ); - PrintAndLogEx(SUCCESS, "OneTimePad : %s - %s\n", + PrintAndLogEx(SUCCESS, "OneTimePad: %s - %s\n", sprint_hex(data + 12, 4), sprint_bin(data + 12, 4) ); @@ -609,23 +607,24 @@ static int ndef_print_CC(uint8_t *data) { } - PrintAndLogEx(NORMAL, "--- NDEF Message"); - PrintAndLogEx(NORMAL, "Capability Container: %s", sprint_hex(data, 4)); - PrintAndLogEx(NORMAL, " %02X : NDEF Magic Number", data[0]); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("NDEF Message")); + PrintAndLogEx(SUCCESS, "Capability Container: %s", sprint_hex(data, 4)); + PrintAndLogEx(SUCCESS, " %02X: NDEF Magic Number", data[0]); -// PrintAndLogEx(NORMAL, " %02X : version %d.%d supported by tag", data[1], (data[1] & 0xF0) >> 4, data[1] & 0x0F); - PrintAndLogEx(NORMAL, " %02X : version %d.%d supported by tag", data[1], cc_major, cc_minor); - PrintAndLogEx(NORMAL, " : %s / %s", rStr, wStr); +// PrintAndLogEx(SUCCESS, " %02X : version %d.%d supported by tag", data[1], (data[1] & 0xF0) >> 4, data[1] & 0x0F); + PrintAndLogEx(SUCCESS, " %02X: version %d.%d supported by tag", data[1], cc_major, cc_minor); + PrintAndLogEx(SUCCESS, " : %s / %s", rStr, wStr); - PrintAndLogEx(NORMAL, " %02X : Physical Memory Size: %d bytes", data[2], data[2] * 8); + PrintAndLogEx(SUCCESS, " %02X: Physical Memory Size: %d bytes", data[2], data[2] * 8); if (data[2] == 0x06) - PrintAndLogEx(NORMAL, " %02X : NDEF Memory Size: %d bytes", data[2], 48); + PrintAndLogEx(SUCCESS, " %02X: NDEF Memory Size: %d bytes", data[2], 48); else if (data[2] == 0x12) - PrintAndLogEx(NORMAL, " %02X : NDEF Memory Size: %d bytes", data[2], 144); + PrintAndLogEx(SUCCESS, " %02X: NDEF Memory Size: %d bytes", data[2], 144); else if (data[2] == 0x3E) - PrintAndLogEx(NORMAL, " %02X : NDEF Memory Size: %d bytes", data[2], 496); + PrintAndLogEx(SUCCESS, " %02X: NDEF Memory Size: %d bytes", data[2], 496); else if (data[2] == 0x6D) - PrintAndLogEx(NORMAL, " %02X : NDEF Memory Size: %d bytes", data[2], 872); + PrintAndLogEx(SUCCESS, " %02X: NDEF Memory Size: %d bytes", data[2], 872); uint8_t msb3 = (data[3] & 0xE0) >> 5; uint8_t sf = (data[3] & 0x10) >> 4; @@ -633,14 +632,14 @@ static int ndef_print_CC(uint8_t *data) { uint8_t mlrule = (data[3] & 0x06) >> 1; uint8_t mbread = (data[3] & 0x01); - PrintAndLogEx(NORMAL, " Additional feature information"); - PrintAndLogEx(NORMAL, " %02X", data[3]); - PrintAndLogEx(NORMAL, " 00000000"); - PrintAndLogEx(NORMAL, " xxx - %02X : RFU ( %s)", msb3, (msb3 == 0) ? _GREEN_("ok") : _RED_("fail")); - PrintAndLogEx(NORMAL, " x - %02X : %s special frame", sf, (sf) ? "support" : "don\'t support"); - PrintAndLogEx(NORMAL, " x - %02X : %s lock block", lb, (lb) ? "support" : "don\'t support"); - PrintAndLogEx(NORMAL, " xx - %02X : RFU ( %s)", mlrule, (mlrule == 0) ? _GREEN_("ok") : _RED_("fail")); - PrintAndLogEx(NORMAL, " x - %02X : IC %s multiple block reads", mbread, (mbread) ? "support" : "don\'t support"); + PrintAndLogEx(SUCCESS, " Additional feature information"); + PrintAndLogEx(SUCCESS, " %02X", data[3]); + PrintAndLogEx(SUCCESS, " 00000000"); + PrintAndLogEx(SUCCESS, " xxx - %02X: RFU ( %s)", msb3, (msb3 == 0) ? _GREEN_("ok") : _RED_("fail")); + PrintAndLogEx(SUCCESS, " x - %02X: %s special frame", sf, (sf) ? "support" : "don\'t support"); + PrintAndLogEx(SUCCESS, " x - %02X: %s lock block", lb, (lb) ? "support" : "don\'t support"); + PrintAndLogEx(SUCCESS, " xx - %02X: RFU ( %s)", mlrule, (mlrule == 0) ? _GREEN_("ok") : _RED_("fail")); + PrintAndLogEx(SUCCESS, " x - %02X: IC %s multiple block reads", mbread, (mbread) ? "support" : "don\'t support"); return PM3_SUCCESS; } @@ -710,31 +709,31 @@ int ul_print_type(uint32_t tagtype, uint8_t spaces) { } static int ulc_print_3deskey(uint8_t *data) { - PrintAndLogEx(NORMAL, " deskey1 [44/0x2C] : %s [%s]", sprint_hex(data, 4), sprint_ascii(data, 4)); - PrintAndLogEx(NORMAL, " deskey1 [45/0x2D] : %s [%s]", sprint_hex(data + 4, 4), sprint_ascii(data + 4, 4)); - PrintAndLogEx(NORMAL, " deskey2 [46/0x2E] : %s [%s]", sprint_hex(data + 8, 4), sprint_ascii(data + 8, 4)); - PrintAndLogEx(NORMAL, " deskey2 [47/0x2F] : %s [%s]", sprint_hex(data + 12, 4), sprint_ascii(data + 12, 4)); - PrintAndLogEx(NORMAL, "\n 3des key : %s", sprint_hex(SwapEndian64(data, 16, 8), 16)); + PrintAndLogEx(NORMAL, " deskey1 [44/0x2C]: %s [%s]", sprint_hex(data, 4), sprint_ascii(data, 4)); + PrintAndLogEx(NORMAL, " deskey1 [45/0x2D]: %s [%s]", sprint_hex(data + 4, 4), sprint_ascii(data + 4, 4)); + PrintAndLogEx(NORMAL, " deskey2 [46/0x2E]: %s [%s]", sprint_hex(data + 8, 4), sprint_ascii(data + 8, 4)); + PrintAndLogEx(NORMAL, " deskey2 [47/0x2F]: %s [%s]", sprint_hex(data + 12, 4), sprint_ascii(data + 12, 4)); + PrintAndLogEx(NORMAL, "\n 3des key: %s", sprint_hex(SwapEndian64(data, 16, 8), 16)); return PM3_SUCCESS; } static int ulc_print_configuration(uint8_t *data) { - PrintAndLogEx(NORMAL, "--- UL-C Configuration"); - PrintAndLogEx(NORMAL, " Higher Lockbits [40/0x28] : %s - %s", sprint_hex(data, 4), sprint_bin(data, 2)); - PrintAndLogEx(NORMAL, " Counter [41/0x29] : %s - %s", sprint_hex(data + 4, 4), sprint_bin(data + 4, 2)); + PrintAndLogEx(NORMAL, "\n--- " _CYAN_("UL-C Configuration")); + PrintAndLogEx(NORMAL, " Higher Lockbits [40/0x28]: %s - %s", sprint_hex(data, 4), sprint_bin(data, 2)); + PrintAndLogEx(NORMAL, " Counter [41/0x29]: %s - %s", sprint_hex(data + 4, 4), sprint_bin(data + 4, 2)); bool validAuth = (data[8] >= 0x03 && data[8] <= 0x30); if (validAuth) - PrintAndLogEx(NORMAL, " Auth0 [42/0x2A] : %s page %d/0x%02X and above need authentication", sprint_hex(data + 8, 4), data[8], data[8]); + PrintAndLogEx(NORMAL, " Auth0 [42/0x2A]: %s page %d/0x%02X and above need authentication", sprint_hex(data + 8, 4), data[8], data[8]); else { if (data[8] == 0) { - PrintAndLogEx(NORMAL, " Auth0 [42/0x2A] : %s default", sprint_hex(data + 8, 4)); + PrintAndLogEx(NORMAL, " Auth0 [42/0x2A]: %s default", sprint_hex(data + 8, 4)); } else { - PrintAndLogEx(NORMAL, " Auth0 [42/0x2A] : %s auth byte is out-of-range", sprint_hex(data + 8, 4)); + PrintAndLogEx(NORMAL, " Auth0 [42/0x2A]: %s auth byte is out-of-range", sprint_hex(data + 8, 4)); } } - PrintAndLogEx(NORMAL, " Auth1 [43/0x2B] : %s %s", + PrintAndLogEx(NORMAL, " Auth1 [43/0x2B]: %s %s", sprint_hex(data + 12, 4), (data[12] & 1) ? "write access restricted" : "read and write access restricted" ); @@ -743,7 +742,8 @@ static int ulc_print_configuration(uint8_t *data) { static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t startPage) { - PrintAndLogEx(NORMAL, "\n--- Tag Configuration"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Tag Configuration")); bool strg_mod_en = (data[0] & 2); uint8_t authlim = (data[4] & 0x07); @@ -753,7 +753,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st bool prot = (data[4] & 0x80); uint8_t vctid = data[5]; - PrintAndLogEx(NORMAL, " cfg0 [%u/0x%02X] : %s", startPage, startPage, sprint_hex(data, 4)); + PrintAndLogEx(INFO, " cfg0 [%u/0x%02X]: %s", startPage, startPage, sprint_hex(data, 4)); if ((tagtype & (NTAG_213_F | NTAG_216_F))) { uint8_t mirror_conf = (data[0] & 0xC0); @@ -764,35 +764,35 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st switch (mirror_conf) { case 0: - PrintAndLogEx(NORMAL, " - no ASCII mirror"); + PrintAndLogEx(INFO, " - no ASCII mirror"); break; case 1: - PrintAndLogEx(NORMAL, " - UID ASCII mirror"); + PrintAndLogEx(INFO, " - UID ASCII mirror"); break; case 2: - PrintAndLogEx(NORMAL, " - NFC counter ASCII mirror"); + PrintAndLogEx(INFO, " - NFC counter ASCII mirror"); break; case 3: - PrintAndLogEx(NORMAL, " - UID and NFC counter ASCII mirror"); + PrintAndLogEx(INFO, " - UID and NFC counter ASCII mirror"); break; default: break; } - PrintAndLogEx(NORMAL, " - SLEEP mode %s", (sleep_en) ? "enabled" : "disabled"); + PrintAndLogEx(INFO, " - SLEEP mode %s", (sleep_en) ? "enabled" : "disabled"); switch (fdp_conf) { case 0: - PrintAndLogEx(NORMAL, " - no field detect"); + PrintAndLogEx(INFO, " - no field detect"); break; case 1: - PrintAndLogEx(NORMAL, " - enabled by first State-of-Frame (start of communication)"); + PrintAndLogEx(INFO, " - enabled by first State-of-Frame (start of communication)"); break; case 2: - PrintAndLogEx(NORMAL, " - enabled by selection of the tag"); + PrintAndLogEx(INFO, " - enabled by selection of the tag"); break; case 3: - PrintAndLogEx(NORMAL, " - enabled by field presence"); + PrintAndLogEx(INFO, " - enabled by field presence"); break; default: break; @@ -801,54 +801,54 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st if (tagtype & NTAG_213_F) { switch (mirror_conf) { case 1: - { PrintAndLogEx(NORMAL, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0x24) ? "OK" : "Invalid value"); break;} + { PrintAndLogEx(INFO, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0x24) ? "OK" : "Invalid value"); break;} case 2: - { PrintAndLogEx(NORMAL, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0x26) ? "OK" : "Invalid value"); break;} + { PrintAndLogEx(INFO, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0x26) ? "OK" : "Invalid value"); break;} case 3: - { PrintAndLogEx(NORMAL, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0x22) ? "OK" : "Invalid value"); break;} + { PrintAndLogEx(INFO, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0x22) ? "OK" : "Invalid value"); break;} default: break; } } else if (tagtype & NTAG_216_F) { switch (mirror_conf) { case 1: - { PrintAndLogEx(NORMAL, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0xDE) ? "OK" : "Invalid value"); break;} + { PrintAndLogEx(INFO, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0xDE) ? "OK" : "Invalid value"); break;} case 2: - { PrintAndLogEx(NORMAL, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0xE0) ? "OK" : "Invalid value"); break;} + { PrintAndLogEx(INFO, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0xE0) ? "OK" : "Invalid value"); break;} case 3: - { PrintAndLogEx(NORMAL, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0xDC) ? "OK" : "Invalid value"); break;} + { PrintAndLogEx(INFO, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0xDC) ? "OK" : "Invalid value"); break;} default: break; } } } - PrintAndLogEx(NORMAL, " - strong modulation mode %s", (strg_mod_en) ? "enabled" : "disabled"); + PrintAndLogEx(INFO, " - strong modulation mode %s", (strg_mod_en) ? "enabled" : "disabled"); if (data[3] < 0xff) - PrintAndLogEx(NORMAL, " - page %d and above need authentication", data[3]); + PrintAndLogEx(INFO, " - page %d and above need authentication", data[3]); else - PrintAndLogEx(NORMAL, " - pages don't need authentication"); + PrintAndLogEx(INFO, " - pages don't need authentication"); - PrintAndLogEx(NORMAL, " cfg1 [%u/0x%02X] : %s", startPage + 1, startPage + 1, sprint_hex(data + 4, 4)); + PrintAndLogEx(INFO, " cfg1 [%u/0x%02X]: %s", startPage + 1, startPage + 1, sprint_hex(data + 4, 4)); if (authlim == 0) - PrintAndLogEx(NORMAL, " - Unlimited password attempts"); + PrintAndLogEx(INFO, " - " _GREEN_("Unlimited password attempts")); else - PrintAndLogEx(NORMAL, " - Max number of password attempts is " _YELLOW_("%d"), authlim); + PrintAndLogEx(INFO, " - Max number of password attempts is " _YELLOW_("%d"), authlim); - PrintAndLogEx(NORMAL, " - NFC counter %s", (nfc_cnf_en) ? "enabled" : "disabled"); - PrintAndLogEx(NORMAL, " - NFC counter %s", (nfc_cnf_prot_pwd) ? "not protected" : "password protection enabled"); + PrintAndLogEx(INFO, " - NFC counter %s", (nfc_cnf_en) ? "enabled" : "disabled"); + PrintAndLogEx(INFO, " - NFC counter %s", (nfc_cnf_prot_pwd) ? "not protected" : "password protection enabled"); - PrintAndLogEx(NORMAL, " - user configuration %s", cfglck ? "permanently locked" : "writeable"); - PrintAndLogEx(NORMAL, " - %s access is protected with password", prot ? "read and write" : "write"); - PrintAndLogEx(NORMAL, " - %02X, Virtual Card Type Identifier is %s default", vctid, (vctid == 0x05) ? "" : "not"); - PrintAndLogEx(NORMAL, " PWD [%u/0x%02X] : %s- (cannot be read)", startPage + 2, startPage + 2, sprint_hex(data + 8, 4)); - PrintAndLogEx(NORMAL, " PACK [%u/0x%02X] : %s - (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data + 12, 2)); - PrintAndLogEx(NORMAL, " RFU [%u/0x%02X] : %s- (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data + 14, 2)); + PrintAndLogEx(INFO, " - user configuration %s", cfglck ? "permanently locked" : "writeable"); + PrintAndLogEx(INFO, " - %s access is protected with password", prot ? "read and write" : "write"); + PrintAndLogEx(INFO, " - %02X, Virtual Card Type Identifier is %sdefault", vctid, (vctid == 0x05) ? "" : "not "); + PrintAndLogEx(INFO, " PWD [%u/0x%02X]: %s- (cannot be read)", startPage + 2, startPage + 2, sprint_hex(data + 8, 4)); + PrintAndLogEx(INFO, " PACK [%u/0x%02X]: %s - (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data + 12, 2)); + PrintAndLogEx(INFO, " RFU [%u/0x%02X]: %s- (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data + 14, 2)); return PM3_SUCCESS; } static int ulev1_print_counters() { - PrintAndLogEx(NORMAL, "--- Tag Counters"); + PrintAndLogEx(INFO, "--- " _CYAN_("Tag Counters")); uint8_t tear[1] = {0}; uint8_t counter[3] = {0, 0, 0}; uint16_t len = 0; @@ -856,8 +856,8 @@ static int ulev1_print_counters() { ulev1_readTearing(i, tear, sizeof(tear)); len = ulev1_readCounter(i, counter, sizeof(counter)); if (len == 3) { - PrintAndLogEx(NORMAL, " [%0d] : %s", i, sprint_hex(counter, 3)); - PrintAndLogEx(NORMAL, " - %02X tearing %s", tear[0], (tear[0] == 0xBD) ? "Ok" : "failure"); + PrintAndLogEx(INFO, " [%0d]: %s", i, sprint_hex(counter, 3)); + PrintAndLogEx(SUCCESS, " - %02X tearing %s", tear[0], (tear[0] == 0xBD) ? "Ok" : "failure"); } } return len; @@ -866,10 +866,20 @@ static int ulev1_print_counters() { static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *signature, size_t signature_len) { #define PUBLIC_ECDA_KEYLEN 33 - // known public keys for the originality check (source: https://github.com/alexbatalov/node-nxp-originality-verifier) // ref: AN11350 NTAG 21x Originality Signature Validation // ref: AN11341 MIFARE Ultralight EV1 Originality Signature Validation + const ecdsa_publickey_t nxp_mfu_public_keys[] = { + {"NXP Mifare Classic MFC1C14_x", "044F6D3F294DEA5737F0F46FFEE88A356EED95695DD7E0C27A591E6F6F65962BAF"}, + {"Manufacturer Mifare Classic MFC1C14_x", "046F70AC557F5461CE5052C8E4A7838C11C7A236797E8A0730A101837C004039C2"}, + {"NXP ICODE DNA, ICODE SLIX2", "048878A2A2D3EEC336B4F261A082BD71F9BE11C4E2E896648B32EFA59CEA6E59F0"}, + {"NXP Public key", "04A748B6A632FBEE2C0897702B33BEA1C074998E17B84ACA04FF267E5D2C91F6DC"}, + {"NXP Ultralight Ev1", "0490933BDCD6E99B4E255E3DA55389A827564E11718E017292FAF23226A96614B8"}, + {"NXP NTAG21x (2013)", "04494E1A386D3D3CFE3DC10E5DE68A499B1C202DB5B132393E89ED19FE5BE8BC61"}, + {"MICRON Public key", "04f971eda742a4a80d32dcf6a814a707cc3dc396d35902f72929fdcd698b3468f2"}, + }; + +/* uint8_t nxp_mfu_public_keys[6][PUBLIC_ECDA_KEYLEN] = { // UL, NTAG21x and NDEF { @@ -914,61 +924,49 @@ static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *sig 0x29, 0x29, 0xfd, 0xcd, 0x69, 0x8b, 0x34, 0x68, 0xf2 } }; - +*/ uint8_t i; int res; bool is_valid = false; for (i = 0; i< ARRAYLEN(nxp_mfu_public_keys); i++) { - - res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, nxp_mfu_public_keys[i], uid, 7, signature, signature_len, false); + + int dl = 0; + uint8_t key[PUBLIC_ECDA_KEYLEN]; + param_gethex_to_eol(nxp_mfu_public_keys[i].value, 0, key, PUBLIC_ECDA_KEYLEN, &dl); + + res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, uid, 7, signature, signature_len, false); is_valid = (res == 0); if (is_valid) break; } + + PrintAndLogEx(NORMAL, ""); if (is_valid == false) { PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed")); return PM3_ESOFT; } - - char *publickeyname; - switch(i) { - case 0: - publickeyname = "NXP NTAG21x (2013)"; - break; - case 1: - publickeyname = "NXP Ev1"; - break; - case 4: - publickeyname = "Manufacturer, post on forum"; - break; - case 5: - publickeyname = "MIKRON"; - break; - default: - publickeyname = "Unknown, post on forum"; - break; - } - PrintAndLogEx(INFO, "\n--- Tag Signature"); - PrintAndLogEx(INFO, "IC signature public key name : %s", publickeyname); - PrintAndLogEx(INFO, "IC signature public key value : %s", sprint_hex(nxp_mfu_public_keys[i], PUBLIC_ECDA_KEYLEN)); - PrintAndLogEx(INFO, " Elliptic curve parameters : NID_secp128r1"); - PrintAndLogEx(INFO, " TAG IC Signature : %s", sprint_hex(signature, signature_len)); - PrintAndLogEx(SUCCESS, "Signature verified " _GREEN_("successful")); + PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature")); + PrintAndLogEx(INFO, " IC signature public key name: %s", nxp_mfu_public_keys[i].desc); + PrintAndLogEx(INFO, "IC signature public key value: %s", nxp_mfu_public_keys[i].value); + PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp128r1"); + PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, signature_len)); + PrintAndLogEx(SUCCESS, " Signature verified: " _GREEN_("successful")); return PM3_SUCCESS; } static int ulev1_print_version(uint8_t *data) { - PrintAndLogEx(NORMAL, "\n--- Tag Version"); - PrintAndLogEx(NORMAL, " Raw bytes: %s", sprint_hex(data, 8)); - PrintAndLogEx(NORMAL, " Vendor ID: %02X, %s", data[1], getTagInfo(data[1])); - PrintAndLogEx(NORMAL, " Product type: %s", getProductTypeStr(data[2])); - PrintAndLogEx(NORMAL, " Product subtype: %02X, %s", data[3], (data[3] == 1) ? "17 pF" : "50pF"); - PrintAndLogEx(NORMAL, " Major version: %02X", data[4]); - PrintAndLogEx(NORMAL, " Minor version: %02X", data[5]); - PrintAndLogEx(NORMAL, " Size: %s", getUlev1CardSizeStr(data[6])); - PrintAndLogEx(NORMAL, " Protocol type: %02X %s", data[7], (data[7] == 0x3) ? "(ISO14443-3 Compliant)" : ""); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Tag Version")); + PrintAndLogEx(INFO, " Raw bytes: %s", sprint_hex(data, 8)); + PrintAndLogEx(INFO, " Vendor ID: %02X, %s", data[1], getTagInfo(data[1])); + PrintAndLogEx(INFO, " Product type: %s", getProductTypeStr(data[2])); + PrintAndLogEx(INFO, " Product subtype: %02X, %s", data[3], (data[3] == 1) ? "17 pF" : "50pF"); + PrintAndLogEx(INFO, " Major version: %02X", data[4]); + PrintAndLogEx(INFO, " Minor version: %02X", data[5]); + PrintAndLogEx(INFO, " Size: %s", getUlev1CardSizeStr(data[6])); + PrintAndLogEx(INFO, " Protocol type: %02X%s", data[7], (data[7] == 0x3) ? ", ISO14443-3 Compliant" : ""); return PM3_SUCCESS; } @@ -1188,8 +1186,9 @@ static int CmdHF14AMfUInfo(const char *Cmd) { TagTypeUL_t tagtype = GetHF14AMfU_Type(); if (tagtype == UL_ERROR) return PM3_ESOFT; - PrintAndLogEx(NORMAL, "\n--- Tag Information ---------"); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") "---------"); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); ul_print_type(tagtype, 6); // Swap endianness @@ -1339,7 +1338,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) { // hasAuthKey, if we was called with key, skip test. if (!authlim && !hasAuthKey) { PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, _GREEN_("--- Known EV1/NTAG passwords ---")); + PrintAndLogEx(SUCCESS, "--- " _CYAN_("Known EV1/NTAG passwords")); // test pwd gen A num_to_bytes(ul_ev1_pwdgenA(card.uid), 4, key); len = ulev1_requestAuthentication(key, pack, sizeof(pack)); @@ -1790,7 +1789,7 @@ void printMFUdumpEx(mfu_dump_t *card, uint16_t pages, uint8_t startpage) { // Read and Dump Card Contents, using auto detection of tag size. static int CmdHF14AMfUDump(const char *Cmd) { - uint8_t fileNameLen = 0; + int fileNameLen = 0; char filename[FILE_PATH_SIZE] = {0x00}; char *fptr = filename; @@ -1834,6 +1833,8 @@ static int CmdHF14AMfUDump(const char *Cmd) { break; case 'f': fileNameLen = param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)); + if (fileNameLen > FILE_PATH_SIZE - 5) + fileNameLen = FILE_PATH_SIZE - 5; cmdp += 2; break; case 'p': //set start page diff --git a/common/iso15693tools.c b/common/iso15693tools.c index 66a0f81da..725baedb6 100644 --- a/common/iso15693tools.c +++ b/common/iso15693tools.c @@ -11,18 +11,18 @@ // returns a string representation of the UID // UID is transmitted and stored LSB first, displayed MSB first -// target char* buffer, where to put the UID, if NULL a static buffer is returned +// dest char* buffer, where to put the UID, if NULL a static buffer is returned // uid[] the UID in transmission order // return: ptr to string -char *Iso15693sprintUID(char *target, uint8_t *uid) { +char *iso15693_sprintUID(char *dest, uint8_t *uid) { static char tempbuf[3 * 8 + 1] = {0}; - if (target == NULL) - target = tempbuf; + if (dest == NULL) + dest = tempbuf; - sprintf(target, "%02X %02X %02X %02X %02X %02X %02X %02X", + sprintf(dest, "%02X %02X %02X %02X %02X %02X %02X %02X", uid[7], uid[6], uid[5], uid[4], uid[3], uid[2], uid[1], uid[0] ); - return target; + return dest; } diff --git a/common/iso15693tools.h b/common/iso15693tools.h index 62ad85499..1096b501a 100644 --- a/common/iso15693tools.h +++ b/common/iso15693tools.h @@ -142,6 +142,6 @@ static const int Iso15693FrameEOF[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; -char *Iso15693sprintUID(char *target, uint8_t *uid); +char *iso15693_sprintUID(char *dest, uint8_t *uid); #endif diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 8cffa892a..d97fae6ed 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -267,6 +267,11 @@ typedef struct { uint8_t AIA[8]; } PACKED iclass_reader_t; +typedef struct { + const char *desc; + const char *value; +} PACKED ecdsa_publickey_t; + // For the bootloader #define CMD_DEVICE_INFO 0x0000 //#define CMD_SETUP_WRITE 0x0001