mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 02:27:26 -07:00
layout, text, colors - mfu info, 15 info
This commit is contained in:
parent
7b54cbacb9
commit
34adf411c3
7 changed files with 252 additions and 214 deletions
|
@ -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();
|
||||
|
|
148
client/cmdhf15.c
148
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue