mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-09-23 08:46:13 +08:00
Merge branch 'master' into allin
update
This commit is contained in:
commit
e794c47303
|
@ -43,3 +43,4 @@ eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
|||
404142434445464748494a4b4c4d4e4f
|
||||
303132333435363738393a3b3c3d3e3f
|
||||
9CABF398358405AE2F0E2B3D31C99A8A # Default key
|
||||
605F5E5D5C5B5A59605F5E5D5C5B5A59 # access control
|
|
@ -27,4 +27,4 @@ eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
|||
100f0e0d0c0b0a090807060504030201
|
||||
404142434445464748494a4b4c4d4e4f
|
||||
303132333435363738393a3b3c3d3e3f
|
||||
|
||||
605F5E5D5C5B5A59605F5E5D5C5B5A59
|
||||
|
|
|
@ -380,7 +380,7 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) {
|
|||
{"NXP Public key", "04A748B6A632FBEE2C0897702B33BEA1C074998E17B84ACA04FF267E5D2C91F6DC"},
|
||||
{"NXP Ultralight Ev1", "0490933BDCD6E99B4E255E3DA55389A827564E11718E017292FAF23226A96614B8"},
|
||||
{"NXP NTAG21x (2013)", "04494E1A386D3D3CFE3DC10E5DE68A499B1C202DB5B132393E89ED19FE5BE8BC61"},
|
||||
{"MICRON Public key", "04f971eda742a4a80d32dcf6a814a707cc3dc396d35902f72929fdcd698b3468f2"},
|
||||
{"MIKRON Public key", "04f971eda742a4a80d32dcf6a814a707cc3dc396d35902f72929fdcd698b3468f2"},
|
||||
{"Spark1 Public key", "04d64bb732c0d214e7ec580736acf847284b502c25c0f7f2fa86aace1dada4387a"},
|
||||
};
|
||||
/*
|
||||
|
@ -423,6 +423,16 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) {
|
|||
};
|
||||
*/
|
||||
uint8_t i;
|
||||
uint8_t revuid[8];
|
||||
for (i = 0; i < sizeof(revuid); i++) {
|
||||
revuid[i] = uid[7 - i];
|
||||
}
|
||||
uint8_t revsign[32];
|
||||
for (i = 0; i < sizeof(revsign); i++) {
|
||||
revsign[i] = signature[31 - i];
|
||||
}
|
||||
|
||||
int reason = 0;
|
||||
bool is_valid = false;
|
||||
for (i = 0; i < ARRAYLEN(nxp_15693_public_keys); i++) {
|
||||
|
||||
|
@ -432,22 +442,65 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) {
|
|||
|
||||
int res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, uid, 8, signature, 32, false);
|
||||
is_valid = (res == 0);
|
||||
if (is_valid)
|
||||
if (is_valid) {
|
||||
reason = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// try with sha256
|
||||
res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, uid, 8, signature, 32, true);
|
||||
is_valid = (res == 0);
|
||||
if (is_valid) {
|
||||
reason = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
// try with reversed uid / signature
|
||||
res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, revuid, sizeof(revuid), revsign, sizeof(revsign), false);
|
||||
is_valid = (res == 0);
|
||||
if (is_valid) {
|
||||
reason = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// try with sha256
|
||||
res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, revuid, sizeof(revuid), revsign, sizeof(revsign), true);
|
||||
is_valid = (res == 0);
|
||||
if (is_valid) {
|
||||
reason = 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature"));
|
||||
if (is_valid == false || i == ARRAYLEN(nxp_15693_public_keys)) {
|
||||
PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed"));
|
||||
PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp128r1");
|
||||
PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 32));
|
||||
PrintAndLogEx(SUCCESS, " Signature verification: " _RED_("failed"));
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
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"));
|
||||
PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 32));
|
||||
PrintAndLogEx(SUCCESS, " Signature verification: " _GREEN_("successful"));
|
||||
switch(reason) {
|
||||
case 1:
|
||||
PrintAndLogEx(INFO, " Params used: UID and signature, plain");
|
||||
break;
|
||||
case 2:
|
||||
PrintAndLogEx(INFO, " Params used: UID and signature, SHA256");
|
||||
break;
|
||||
case 3:
|
||||
PrintAndLogEx(INFO, " Params used: reversed UID and signature, plain");
|
||||
break;
|
||||
case 4:
|
||||
PrintAndLogEx(INFO, " Params used: reversed UID and signature, SHA256");
|
||||
break;
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -1176,6 +1176,7 @@ static int desfire_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signat
|
|||
{"Mifare Plus EV1", "044409ADC42F91A8394066BA83D872FB1D16803734E911170412DDF8BAD1A4DADFD0416291AFE1C748253925DA39A5F39A1C557FFACD34C62E"}
|
||||
};
|
||||
|
||||
|
||||
uint32_t i;
|
||||
bool is_valid = false;
|
||||
|
||||
|
@ -1190,24 +1191,29 @@ static int desfire_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signat
|
|||
if (is_valid)
|
||||
break;
|
||||
}
|
||||
// PrintAndLogEx(NORMAL, "");
|
||||
// PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature"));
|
||||
if (is_valid == false || i == ARRAYLEN(nxp_desfire_public_keys)) {
|
||||
PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed"));
|
||||
PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp224r1");
|
||||
PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 16));
|
||||
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 16, 16));
|
||||
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 32, 16));
|
||||
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 48, signature_len - 48));
|
||||
PrintAndLogEx(SUCCESS, " Signature verification: " _RED_("failed"));
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
// PrintAndLogEx(NORMAL, "");
|
||||
// PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature"));
|
||||
PrintAndLogEx(INFO, " IC signature public key name: " _GREEN_("%s"), nxp_desfire_public_keys[i].desc);
|
||||
PrintAndLogEx(INFO, "IC signature public key value: %.32s", nxp_desfire_public_keys[i].value);
|
||||
PrintAndLogEx(INFO, " : %.32s", nxp_desfire_public_keys[i].value + 16);
|
||||
PrintAndLogEx(INFO, " : %.32s", nxp_desfire_public_keys[i].value + 32);
|
||||
PrintAndLogEx(INFO, " : %.32s", nxp_desfire_public_keys[i].value + 48);
|
||||
PrintAndLogEx(INFO, " : %.32s", nxp_desfire_public_keys[i].value + 64);
|
||||
PrintAndLogEx(INFO, " : %.32s", nxp_desfire_public_keys[i].value + 96);
|
||||
PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp224r1");
|
||||
PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 16));
|
||||
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 16, 16));
|
||||
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 32, 16));
|
||||
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 48, signature_len - 48));
|
||||
PrintAndLogEx(SUCCESS, " Signature verified: " _GREEN_("successful"));
|
||||
PrintAndLogEx(SUCCESS, " Signature verification: " _GREEN_("successful"));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,9 +58,9 @@ static char *getCardSizeStr(uint8_t fsize) {
|
|||
|
||||
// is LSB set?
|
||||
if (fsize & 1)
|
||||
snprintf(retStr, sizeof(buf), "0x%02X (" _YELLOW_("%d - %d bytes") ")", fsize, usize, lsize);
|
||||
snprintf(retStr, sizeof(buf), "0x%02X (" _GREEN_("%d - %d bytes") ")", fsize, usize, lsize);
|
||||
else
|
||||
snprintf(retStr, sizeof(buf), "0x%02X (" _YELLOW_("%d bytes") ")", fsize, lsize);
|
||||
snprintf(retStr, sizeof(buf), "0x%02X (" _GREEN_("%d bytes") ")", fsize, lsize);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -88,18 +88,17 @@ static char *getVersionStr(uint8_t major, uint8_t minor) {
|
|||
char *retStr = buf;
|
||||
|
||||
if (major == 0x00)
|
||||
snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("DESFire MF3ICD40") ")", major, minor);
|
||||
snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire MF3ICD40") ")", major, minor);
|
||||
else if (major == 0x01 && minor == 0x00)
|
||||
snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("DESFire EV1") ")", major, minor);
|
||||
snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire EV1") ")", major, minor);
|
||||
else if (major == 0x12 && minor == 0x00)
|
||||
snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("DESFire EV2") ")", major, minor);
|
||||
snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire EV2") ")", major, minor);
|
||||
else if (major == 0x33 && minor == 0x00)
|
||||
snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("DESFire EV3") ")", major, minor);
|
||||
snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire EV3") ")", major, minor);
|
||||
else if (major == 0x30 && minor == 0x00)
|
||||
snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("DESFire Light") ")", major, minor);
|
||||
|
||||
snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire Light") ")", major, minor);
|
||||
else if (major == 0x11 && minor == 0x00)
|
||||
snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("Plus EV1") ")", major, minor);
|
||||
snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("Plus EV1") ")", major, minor);
|
||||
else
|
||||
snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("Unknown") ")", major, minor);
|
||||
return buf;
|
||||
|
@ -186,21 +185,26 @@ static int plus_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signature
|
|||
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature"));
|
||||
|
||||
if (is_valid == false || i == ARRAYLEN(nxp_plus_public_keys)) {
|
||||
PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed"));
|
||||
PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp224r1");
|
||||
PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 16));
|
||||
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 16, 16));
|
||||
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 32, 16));
|
||||
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 48, signature_len - 48));
|
||||
PrintAndLogEx(SUCCESS, " Signature verification: " _RED_("failed"));
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, " IC signature public key name: " _GREEN_("%s"), nxp_plus_public_keys[i].desc);
|
||||
PrintAndLogEx(INFO, "IC signature public key value: %.32s", nxp_plus_public_keys[i].value);
|
||||
PrintAndLogEx(INFO, " : %.32s", nxp_plus_public_keys[i].value + 16);
|
||||
PrintAndLogEx(INFO, " : %.32s", nxp_plus_public_keys[i].value + 32);
|
||||
PrintAndLogEx(INFO, " : %.32s", nxp_plus_public_keys[i].value + 48);
|
||||
PrintAndLogEx(INFO, " : %.32s", nxp_plus_public_keys[i].value + 64);
|
||||
PrintAndLogEx(INFO, " : %.32s", nxp_plus_public_keys[i].value + 96);
|
||||
PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp224r1");
|
||||
PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 16));
|
||||
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 16, 16));
|
||||
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 32, 16));
|
||||
PrintAndLogEx(INFO, " : %s", sprint_hex_inrow(signature + 48, signature_len - 48));
|
||||
PrintAndLogEx(SUCCESS, " Signature verified: " _GREEN_("successful"));
|
||||
PrintAndLogEx(SUCCESS, " Signature verification: " _GREEN_("successful"));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -356,10 +360,8 @@ static int CmdHFMFPInfo(const char *Cmd) {
|
|||
}
|
||||
|
||||
if (card.sak == 0x20) {
|
||||
PrintAndLogEx(INFO, " SAK: " _GREEN_("MIFARE Plus SL0/SL3") " or " _GREEN_("MIFARE DESFire"));
|
||||
|
||||
if (card.ats_len > 0) {
|
||||
|
||||
PrintAndLogEx(INFO, " SAK: " _GREEN_("MIFARE Plus SL0/SL3") " or " _GREEN_("MIFARE DESFire"));
|
||||
SLmode = 3;
|
||||
// check SL0
|
||||
uint8_t data[250] = {0};
|
||||
|
@ -368,15 +370,22 @@ static int CmdHFMFPInfo(const char *Cmd) {
|
|||
uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00};
|
||||
int res = ExchangeRAW14a(cmd, sizeof(cmd), true, false, data, sizeof(data), &datalen, false);
|
||||
|
||||
// DESFire answers 0x1C
|
||||
// DESFire answers 0x1C or 67 00
|
||||
// Plus answers 0x0B, 0x09
|
||||
PrintAndLogEx(INFO, "ICEE: %s", sprint_hex(data, datalen));
|
||||
|
||||
if (memcmp(data, "\x67\x00", 2) == 0) {
|
||||
PrintAndLogEx(INFO, "\tMost likely a MIFARE DESFire tag");
|
||||
if ( data[0] != 0x0b && data[0] != 0x09 && data[0] != 0x1C && data[0] != 0x67) {
|
||||
PrintAndLogEx(INFO, _RED_("Send copy to iceman of this command output!"));
|
||||
PrintAndLogEx(INFO, "data: %s", sprint_hex(data, datalen));
|
||||
}
|
||||
|
||||
if ((memcmp(data, "\x67\x00", 2) == 0) ||
|
||||
(memcmp(data, "\x1C\x83\x0C", 3) == 0)
|
||||
) {
|
||||
PrintAndLogEx(INFO, " result: " _RED_("MIFARE DESFire"));
|
||||
PrintAndLogEx(HINT, "Hint: Try " _YELLOW_("`hf mfdes info`"));
|
||||
DropField();
|
||||
return PM3_SUCCESS;
|
||||
} else {
|
||||
PrintAndLogEx(INFO, " result: " _GREEN_("MIFARE Plus SL0/SL3"));
|
||||
}
|
||||
|
||||
if (!res && datalen > 1 && data[0] == 0x09) {
|
||||
|
|
|
@ -272,14 +272,14 @@ uint32_t UL_TYPES_ARRAY[] = {
|
|||
UNKNOWN, UL, UL_C, UL_EV1_48, UL_EV1_128, NTAG,
|
||||
NTAG_203, NTAG_210, NTAG_212, NTAG_213, NTAG_215, NTAG_216,
|
||||
MY_D, MY_D_NFC, MY_D_MOVE, MY_D_MOVE_NFC, MY_D_MOVE_LEAN, FUDAN_UL,
|
||||
UL_EV1, NTAG_213_F, NTAG_216_F, UL_NANO_40, NTAG_I2C_1K
|
||||
UL_EV1, NTAG_213_F, NTAG_216_F, UL_NANO_40, NTAG_I2C_1K, NTAG_213_TT
|
||||
};
|
||||
|
||||
uint8_t UL_MEMORY_ARRAY[ARRAYLEN(UL_TYPES_ARRAY)] = {
|
||||
MAX_UL_BLOCKS, MAX_UL_BLOCKS, MAX_ULC_BLOCKS, MAX_ULEV1a_BLOCKS, MAX_ULEV1b_BLOCKS, MAX_NTAG_203,
|
||||
MAX_NTAG_203, MAX_NTAG_210, MAX_NTAG_212, MAX_NTAG_213, MAX_NTAG_215, MAX_NTAG_216,
|
||||
MAX_UL_BLOCKS, MAX_MY_D_NFC, MAX_MY_D_MOVE, MAX_MY_D_MOVE, MAX_MY_D_MOVE_LEAN, MAX_UL_BLOCKS,
|
||||
MAX_ULEV1a_BLOCKS, MAX_NTAG_213, MAX_NTAG_216, MAX_UL_NANO_40, MAX_NTAG_I2C_1K
|
||||
MAX_ULEV1a_BLOCKS, MAX_NTAG_213, MAX_NTAG_216, MAX_UL_NANO_40, MAX_NTAG_I2C_1K, MAX_NTAG_213
|
||||
};
|
||||
|
||||
//------------------------------------
|
||||
|
@ -493,7 +493,7 @@ static int ul_fudan_check(void) {
|
|||
return (!resp.data.asBytes[0]) ? FUDAN_UL : UL; //if response == 0x00 then Fudan, else Genuine NXP
|
||||
}
|
||||
|
||||
static int ul_print_default(uint8_t *data) {
|
||||
static int ul_print_default(uint8_t *data, uint8_t *real_uid) {
|
||||
|
||||
uint8_t uid[7];
|
||||
uid[0] = data[0];
|
||||
|
@ -503,10 +503,14 @@ static int ul_print_default(uint8_t *data) {
|
|||
uid[4] = data[5];
|
||||
uid[5] = data[6];
|
||||
uid[6] = data[7];
|
||||
bool mful_uid_layout = true;
|
||||
|
||||
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(uid, 7));
|
||||
PrintAndLogEx(SUCCESS, " UID[0]: %02X, %s", uid[0], getTagInfo(uid[0]));
|
||||
if (uid[0] == 0x05 && ((uid[1] & 0xf0) >> 4) == 2) { // is infineon and 66RxxP
|
||||
if (memcmp(uid, real_uid, 7) != 0) {
|
||||
mful_uid_layout = false;
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(real_uid, 7));
|
||||
PrintAndLogEx(SUCCESS, " UID[0]: %02X, %s", real_uid[0], getTagInfo(real_uid[0]));
|
||||
if (real_uid[0] == 0x05 && ((real_uid[1] & 0xf0) >> 4) == 2) { // is infineon and 66RxxP
|
||||
uint8_t chip = (data[8] & 0xC7); // 11000111 mask, bit 3,4,5 RFU
|
||||
switch (chip) {
|
||||
case 0xC2:
|
||||
|
@ -520,20 +524,23 @@ static int ul_print_default(uint8_t *data) {
|
|||
break; //512 pages /2 sectors
|
||||
}
|
||||
}
|
||||
// CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2
|
||||
int crc0 = 0x88 ^ uid[0] ^ uid[1] ^ uid[2];
|
||||
if (data[3] == crc0)
|
||||
PrintAndLogEx(SUCCESS, " BCC0: %02X (" _GREEN_("ok") ")", data[3]);
|
||||
else
|
||||
PrintAndLogEx(NORMAL, " BCC0: %02X, crc should be %02X", data[3], crc0);
|
||||
if (mful_uid_layout) {
|
||||
// CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2
|
||||
int crc0 = 0x88 ^ uid[0] ^ uid[1] ^ uid[2];
|
||||
if (data[3] == crc0)
|
||||
PrintAndLogEx(SUCCESS, " BCC0: %02X (" _GREEN_("ok") ")", data[3]);
|
||||
else
|
||||
PrintAndLogEx(NORMAL, " BCC0: %02X, crc should be %02X", data[3], crc0);
|
||||
|
||||
int crc1 = uid[3] ^ uid[4] ^ uid[5] ^ uid[6];
|
||||
if (data[8] == crc1)
|
||||
PrintAndLogEx(SUCCESS, " BCC1: %02X (" _GREEN_("ok") ")", data[8]);
|
||||
else
|
||||
PrintAndLogEx(NORMAL, " BCC1: %02X, crc should be %02X", data[8], crc1);
|
||||
|
||||
PrintAndLogEx(SUCCESS, " Internal: %02X (%s)", data[9], (data[9] == 0x48) ? _GREEN_("default") : _RED_("not default"));
|
||||
int crc1 = uid[3] ^ uid[4] ^ uid[5] ^ uid[6];
|
||||
if (data[8] == crc1)
|
||||
PrintAndLogEx(SUCCESS, " BCC1: %02X (" _GREEN_("ok") ")", data[8]);
|
||||
else
|
||||
PrintAndLogEx(NORMAL, " BCC1: %02X, crc should be %02X", data[8], crc1);
|
||||
PrintAndLogEx(SUCCESS, " Internal: %02X (%s)", data[9], (data[9] == 0x48) ? _GREEN_("default") : _RED_("not default"));
|
||||
} else {
|
||||
PrintAndLogEx(SUCCESS, "Blocks 0-2: %s", sprint_hex(data + 0, 12));
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, " Lock: %s - %s",
|
||||
sprint_hex(data + 10, 2),
|
||||
|
@ -678,6 +685,8 @@ int ul_print_type(uint32_t tagtype, uint8_t spaces) {
|
|||
PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 213 144bytes (NT2H1311G0DU)"), spaces, "");
|
||||
else if (tagtype & NTAG_213_F)
|
||||
PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 213F 144bytes (NT2H1311F0DTL)"), spaces, "");
|
||||
else if (tagtype & NTAG_213_TT)
|
||||
PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 213TT 144bytes (NT2H1311TTDU)"), spaces, "");
|
||||
else if (tagtype & NTAG_215)
|
||||
PrintAndLogEx(SUCCESS, "%*sTYPE: " _YELLOW_("NTAG 215 504bytes (NT2H1511G0DU)"), spaces, "");
|
||||
else if (tagtype & NTAG_216)
|
||||
|
@ -758,7 +767,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st
|
|||
|
||||
PrintAndLogEx(INFO, " cfg0 [%u/0x%02X]: %s", startPage, startPage, sprint_hex(data, 4));
|
||||
|
||||
if ((tagtype & (NTAG_213_F | NTAG_216_F))) {
|
||||
if ((tagtype & (NTAG_213_F | NTAG_213_TT | NTAG_216_F))) {
|
||||
uint8_t mirror_conf = (data[0] & 0xC0);
|
||||
uint8_t mirror_byte = (data[0] & 0x30);
|
||||
bool sleep_en = (data[0] & 0x08);
|
||||
|
@ -801,7 +810,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st
|
|||
break;
|
||||
}
|
||||
// valid mirror start page and byte position within start page.
|
||||
if (tagtype & NTAG_213_F) {
|
||||
if ((tagtype & NTAG_213_F)||(tagtype & NTAG_213_TT)) {
|
||||
switch (mirror_conf) {
|
||||
case 1:
|
||||
{ PrintAndLogEx(INFO, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0x24) ? "OK" : "Invalid value"); break;}
|
||||
|
@ -880,7 +889,7 @@ static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *sig
|
|||
{"NXP Public key", "04A748B6A632FBEE2C0897702B33BEA1C074998E17B84ACA04FF267E5D2C91F6DC"},
|
||||
{"NXP Ultralight Ev1", "0490933BDCD6E99B4E255E3DA55389A827564E11718E017292FAF23226A96614B8"},
|
||||
{"NXP NTAG21x (2013)", "04494E1A386D3D3CFE3DC10E5DE68A499B1C202DB5B132393E89ED19FE5BE8BC61"},
|
||||
{"MICRON Public key", "04f971eda742a4a80d32dcf6a814a707cc3dc396d35902f72929fdcd698b3468f2"},
|
||||
{"MIKRON Public key", "04f971eda742a4a80d32dcf6a814a707cc3dc396d35902f72929fdcd698b3468f2"},
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -945,17 +954,19 @@ static int ulev1_print_signature(TagTypeUL_t tagtype, uint8_t *uid, uint8_t *sig
|
|||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature"));
|
||||
if (is_valid == false || i == ARRAYLEN(nxp_mfu_public_keys)) {
|
||||
PrintAndLogEx(SUCCESS, "Signature verification " _RED_("failed"));
|
||||
PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp128r1");
|
||||
PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, signature_len));
|
||||
PrintAndLogEx(SUCCESS, " Signature verification: " _RED_("failed"));
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
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"));
|
||||
PrintAndLogEx(SUCCESS, " Signature verification: " _GREEN_("successful"));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1088,6 +1099,7 @@ uint32_t GetHF14AMfU_Type(void) {
|
|||
MF0UNH1001DUx 0004030203000B03
|
||||
NT2L1001G0DUx 0004040102000B03
|
||||
NT2H1001G0DUx 0004040202000B03
|
||||
NT2H1311TTDUx 0004040203000F03
|
||||
Micron UL 0034210101000E03
|
||||
*/
|
||||
|
||||
|
@ -1104,6 +1116,7 @@ uint32_t GetHF14AMfU_Type(void) {
|
|||
else if (memcmp(version, "\x00\x04\x04\x02\x01\x00\x13", 7) == 0) { tagtype = NTAG_216; break; }
|
||||
else if (memcmp(version, "\x00\x04\x04\x04\x01\x00\x0F", 7) == 0) { tagtype = NTAG_213_F; break; }
|
||||
else if (memcmp(version, "\x00\x04\x04\x04\x01\x00\x13", 7) == 0) { tagtype = NTAG_216_F; break; }
|
||||
else if (memcmp(version, "\x00\x04\x04\x02\x03\x00\x0F", 7) == 0) { tagtype = NTAG_213_TT; break; }
|
||||
else if (memcmp(version, "\x00\x04\x04\x05\x02\x01\x13", 7) == 0) { tagtype = NTAG_I2C_1K; break; }
|
||||
else if (memcmp(version, "\x00\x04\x04\x05\x02\x01\x15", 7) == 0) { tagtype = NTAG_I2C_2K; break; }
|
||||
else if (memcmp(version, "\x00\x04\x04\x05\x02\x02\x13", 7) == 0) { tagtype = NTAG_I2C_1K_PLUS; break; }
|
||||
|
@ -1208,7 +1221,6 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
|
|||
uint8_t *key = pwd;
|
||||
uint8_t pack[4] = {0, 0, 0, 0};
|
||||
int len;
|
||||
uint8_t uid[7];
|
||||
|
||||
char tempStr[50];
|
||||
|
||||
|
@ -1261,9 +1273,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
|
|||
PrintAndLogEx(ERR, "Error: tag didn't answer to READ");
|
||||
return PM3_ESOFT;
|
||||
} else if (status == 16) {
|
||||
memcpy(uid, data, 3);
|
||||
memcpy(uid + 3, data + 4, 4);
|
||||
ul_print_default(data);
|
||||
ul_print_default(data, card.uid);
|
||||
ndef_print_CC(data + 12);
|
||||
} else {
|
||||
locked = true;
|
||||
|
@ -1328,7 +1338,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
|
|||
}
|
||||
|
||||
// NTAG counters?
|
||||
if ((tagtype & (NTAG_213 | NTAG_213_F | NTAG_215 | NTAG_216))) {
|
||||
if ((tagtype & (NTAG_213 | NTAG_213_F | NTAG_213_TT | NTAG_215 | NTAG_216))) {
|
||||
if (ntag_print_counter()) {
|
||||
// failed - re-select
|
||||
if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT;
|
||||
|
@ -1336,7 +1346,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
|
|||
}
|
||||
|
||||
// Read signature
|
||||
if ((tagtype & (UL_EV1_48 | UL_EV1_128 | UL_EV1 | UL_NANO_40 | NTAG_213 | NTAG_213_F | NTAG_215 | NTAG_216 | NTAG_216_F | NTAG_I2C_1K | NTAG_I2C_2K | NTAG_I2C_1K_PLUS | NTAG_I2C_2K_PLUS))) {
|
||||
if ((tagtype & (UL_EV1_48 | UL_EV1_128 | UL_EV1 | UL_NANO_40 | NTAG_213 | NTAG_213_F | NTAG_213_TT | NTAG_215 | NTAG_216 | NTAG_216_F | NTAG_I2C_1K | NTAG_I2C_2K | NTAG_I2C_1K_PLUS | NTAG_I2C_2K_PLUS))) {
|
||||
uint8_t ulev1_signature[32] = {0x00};
|
||||
status = ulev1_readSignature(ulev1_signature, sizeof(ulev1_signature));
|
||||
if (status == -1) {
|
||||
|
@ -1345,7 +1355,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
|
|||
return PM3_ESOFT;
|
||||
}
|
||||
if (status == 32) {
|
||||
ulev1_print_signature(tagtype, uid, ulev1_signature, sizeof(ulev1_signature));
|
||||
ulev1_print_signature(tagtype, card.uid, ulev1_signature, sizeof(ulev1_signature));
|
||||
} else {
|
||||
// re-select
|
||||
if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT;
|
||||
|
@ -2022,7 +2032,7 @@ static int CmdHF14AMfUDump(const char *Cmd) {
|
|||
uint8_t n = 0;
|
||||
|
||||
// NTAG has 1 counter, at 0x02
|
||||
if ((tagtype & (NTAG_213 | NTAG_213_F | NTAG_215 | NTAG_216))) {
|
||||
if ((tagtype & (NTAG_213 | NTAG_213_F | NTAG_213_TT | NTAG_215 | NTAG_216))) {
|
||||
n = 2;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ typedef enum TAGTYPE_UL {
|
|||
NTAG_216_F = 0x800000,
|
||||
UL_EV1 = 0x1000000,
|
||||
UL_NANO_40 = 0x2000000,
|
||||
NTAG_213_TT = 0x4000000,
|
||||
UL_MAGIC = UL | MAGIC,
|
||||
UL_C_MAGIC = UL_C | MAGIC,
|
||||
UL_ERROR = 0xFFFFFF,
|
||||
|
|
|
@ -1522,7 +1522,7 @@ out:
|
|||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"-----------", CmdHelp, AlwaysAvailable, "-------------- " _CYAN_("Direct") " --------------"},
|
||||
{"awid", CmdLFAWID, AlwaysAvailable, "{ AWID RFIDs... }"},
|
||||
{"cotag", CmdLFCOTAG, AlwaysAvailable, "{ COTAG CHIPs... }"},
|
||||
{"em", CmdLFEM4X, AlwaysAvailable, "{ EM4X CHIPs & RFIDs... }"},
|
||||
|
@ -1549,16 +1549,17 @@ static command_t CommandTable[] = {
|
|||
{"t55xx", CmdLFT55XX, AlwaysAvailable, "{ T55xx CHIPs... }"},
|
||||
{"viking", CmdLFViking, AlwaysAvailable, "{ Viking RFIDs... }"},
|
||||
{"visa2000", CmdLFVisa2k, AlwaysAvailable, "{ Visa2000 RFIDs... }"},
|
||||
{"", CmdHelp, AlwaysAvailable, ""},
|
||||
{"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"config", CmdLFConfig, IfPm3Lf, "Get/Set config for LF sampling, bit/sample, decimation, frequency"},
|
||||
{"cmdread", CmdLFCommandRead, IfPm3Lf, "Modulate LF reader field to send command before read (all periods in microseconds)"},
|
||||
{"read", CmdLFRead, IfPm3Lf, "Read LF tag"},
|
||||
{"search", CmdLFfind, AlwaysAvailable, "Read and Search for valid known tag (in offline mode it you can load first then search)"},
|
||||
{"sim", CmdLFSim, IfPm3Lf, "Simulate LF tag from buffer with optional GAP (in microseconds)"},
|
||||
{"simask", CmdLFaskSim, IfPm3Lf, "Simulate LF ASK tag from demodbuffer or input"},
|
||||
{"simfsk", CmdLFfskSim, IfPm3Lf, "Simulate LF FSK tag from demodbuffer or input"},
|
||||
{"simpsk", CmdLFpskSim, IfPm3Lf, "Simulate LF PSK tag from demodbuffer or input"},
|
||||
// {"simpsk", CmdLFnrzSim, IfPm3Lf, "Simulate LF NRZ tag from demodbuffer or input"},
|
||||
{"simask", CmdLFaskSim, IfPm3Lf, "Simulate " _YELLOW_("LF ASK tag") " from demodbuffer or input"},
|
||||
{"simfsk", CmdLFfskSim, IfPm3Lf, "Simulate " _YELLOW_("LF FSK tag") " from demodbuffer or input"},
|
||||
{"simpsk", CmdLFpskSim, IfPm3Lf, "Simulate " _YELLOW_("LF PSK tag") " from demodbuffer or input"},
|
||||
// {"simpsk", CmdLFnrzSim, IfPm3Lf, "Simulate " _YELLOW_("LF NRZ tag") " from demodbuffer or input"},
|
||||
{"simbidir", CmdLFSimBidir, IfPm3Lf, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
|
||||
{"sniff", CmdLFSniff, IfPm3Lf, "Sniff LF traffic between reader and tag"},
|
||||
{"tune", CmdLFTune, IfPm3Lf, "Continuously measure LF antenna tuning"},
|
||||
|
|
|
@ -168,7 +168,11 @@ void CmdsHelp(const command_t Commands[]) {
|
|||
while (Commands[i].Name) {
|
||||
if (Commands[i].IsAvailable()) {
|
||||
g_printAndLog = PRINTANDLOG_PRINT;
|
||||
PrintAndLogEx(NORMAL, _GREEN_("%-16s")" %s", Commands[i].Name, Commands[i].Help);
|
||||
if (Commands[i].Name[0] == '-' || Commands[i].Name[0] == ' ') {
|
||||
PrintAndLogEx(NORMAL, "%-16s %s", Commands[i].Name, Commands[i].Help);
|
||||
} else {
|
||||
PrintAndLogEx(NORMAL, _GREEN_("%-16s")" %s", Commands[i].Name, Commands[i].Help);
|
||||
}
|
||||
g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG;
|
||||
}
|
||||
++i;
|
||||
|
|
84
tools/recover_pk.py
Executable file
84
tools/recover_pk.py
Executable file
|
@ -0,0 +1,84 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# @doegox -- 2020
|
||||
|
||||
import sslcrypto
|
||||
import binascii
|
||||
import sys
|
||||
|
||||
debug = False
|
||||
|
||||
def recover(data, signature, alghash=None):
|
||||
recovered = set()
|
||||
if len(signature) == 32:
|
||||
curve = sslcrypto.ecc.get_curve("secp128r1")
|
||||
recoverable = False
|
||||
elif len(signature) == 33:
|
||||
curve = sslcrypto.ecc.get_curve("secp128r1")
|
||||
recoverable = True
|
||||
elif len(signature) == 56:
|
||||
curve = sslcrypto.ecc.get_curve("secp224r1")
|
||||
recoverable = False
|
||||
elif len(signature) == 57:
|
||||
curve = sslcrypto.ecc.get_curve("secp224r1")
|
||||
recoverable = True
|
||||
else:
|
||||
print("Unsupported signature size %i" % len(signature))
|
||||
exit(1)
|
||||
|
||||
if (recoverable):
|
||||
try:
|
||||
pk = curve.recover(signature, data, hash=alghash)
|
||||
recovered.add(pk)
|
||||
if debug:
|
||||
print("Possible Pk: ", binascii.hexlify(pk))
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
for i in range(2):
|
||||
# Brute force RECID
|
||||
recid = bytes([27+i])
|
||||
try:
|
||||
pk = curve.recover(recid + signature, data, hash=alghash)
|
||||
recovered.add(pk)
|
||||
if debug:
|
||||
print("Possible Pk: ", binascii.hexlify(pk))
|
||||
except:
|
||||
pass
|
||||
return recovered
|
||||
|
||||
def recover_multiple(uids, sigs, alghash=None):
|
||||
recovered = set()
|
||||
assert len(uids) == len(sigs)
|
||||
for i in range(len(uids)):
|
||||
data = binascii.unhexlify(uids[i])
|
||||
if debug:
|
||||
print("UID (%2i): " % len(data), binascii.hexlify(data))
|
||||
signature = binascii.unhexlify(sigs[i])
|
||||
if debug:
|
||||
print("Signature (%2i): " % len(signature), binascii.hexlify(signature))
|
||||
recovered_tmp = recover(data, signature, alghash)
|
||||
if i == 0:
|
||||
if recovered_tmp == set():
|
||||
break
|
||||
else:
|
||||
recovered = recovered_tmp
|
||||
else:
|
||||
recovered &= recovered_tmp
|
||||
return recovered
|
||||
|
||||
if len(sys.argv) < 3 or len(sys.argv) % 2 == 0:
|
||||
print("Usage: \n%s UID SIGN [UID SIGN] [...]" % sys.argv[0])
|
||||
print("Example: \n%s 04ee45daa34084 ebb6102bff74b087d18a57a54bc375159a04ea9bc61080b7f4a85afe1587d73b" % sys.argv[0])
|
||||
exit(1)
|
||||
|
||||
print("Assuming no hash was used in the signature generation:")
|
||||
recovered = recover_multiple(sys.argv[1:][::2], sys.argv[1:][1::2])
|
||||
print("Possible uncompressed Pk(s):")
|
||||
for pk in list(recovered):
|
||||
print(binascii.hexlify(pk).decode('utf8'))
|
||||
print("Assuming SHA-256 was used in the signature generation:")
|
||||
recovered = recover_multiple(sys.argv[1:][::2], sys.argv[1:][1::2], alghash="sha256")
|
||||
print("Possible uncompressed Pk(s):")
|
||||
for pk in list(recovered):
|
||||
print(binascii.hexlify(pk).decode('utf8'))
|
Loading…
Reference in a new issue