layout, text, colors - mfu info, 15 info

This commit is contained in:
iceman1001 2020-04-04 12:17:55 +02:00
commit 34adf411c3
7 changed files with 252 additions and 214 deletions

View file

@ -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();

View file

@ -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;
}

View file

@ -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;
}

View file

@ -8,9 +8,7 @@
// High frequency MIFARE ULTRALIGHT (C) commands
//-----------------------------------------------------------------------------
#include "cmdhfmfu.h"
#include <ctype.h>
#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

View file

@ -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;
}

View file

@ -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

View file

@ -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