update signature data

This commit is contained in:
iceman1001 2024-04-23 02:16:01 +02:00
parent 399b85919a
commit 3ef3e3a63d
5 changed files with 54 additions and 38 deletions

View file

@ -267,14 +267,15 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) {
#define PUBLIC_ECDA_KEYLEN 33 #define PUBLIC_ECDA_KEYLEN 33
const ecdsa_publickey_t nxp_15693_public_keys[] = { const ecdsa_publickey_t nxp_15693_public_keys[] = {
{"NXP MIFARE Classic MFC1C14_x", "044F6D3F294DEA5737F0F46FFEE88A356EED95695DD7E0C27A591E6F6F65962BAF"}, {"NXP MIFARE Classic MFC1C14_x", "044F6D3F294DEA5737F0F46FFEE88A356EED95695DD7E0C27A591E6F6F65962BAF"},
{"Manufacturer MIFARE Classic / QL88", "046F70AC557F5461CE5052C8E4A7838C11C7A236797E8A0730A101837C004039C2"}, {"MIFARE Classic / QL88", "046F70AC557F5461CE5052C8E4A7838C11C7A236797E8A0730A101837C004039C2"},
{"NXP ICODE DNA, ICODE SLIX2", "048878A2A2D3EEC336B4F261A082BD71F9BE11C4E2E896648B32EFA59CEA6E59F0"}, {"NXP ICODE DNA, ICODE SLIX2", "048878A2A2D3EEC336B4F261A082BD71F9BE11C4E2E896648B32EFA59CEA6E59F0"},
{"NXP Public key", "04A748B6A632FBEE2C0897702B33BEA1C074998E17B84ACA04FF267E5D2C91F6DC"}, {"NXP Public key", "04A748B6A632FBEE2C0897702B33BEA1C074998E17B84ACA04FF267E5D2C91F6DC"},
{"NXP Ultralight Ev1", "0490933BDCD6E99B4E255E3DA55389A827564E11718E017292FAF23226A96614B8"}, {"NXP Ultralight Ev1", "0490933BDCD6E99B4E255E3DA55389A827564E11718E017292FAF23226A96614B8"},
{"NXP NTAG21x (2013)", "04494E1A386D3D3CFE3DC10E5DE68A499B1C202DB5B132393E89ED19FE5BE8BC61"}, {"NXP NTAG21x (2013)", "04494E1A386D3D3CFE3DC10E5DE68A499B1C202DB5B132393E89ED19FE5BE8BC61"},
{"MIKRON Public key", "04f971eda742a4a80d32dcf6a814a707cc3dc396d35902f72929fdcd698b3468f2"}, {"MIKRON Public key", "04F971EDA742A4A80D32DCF6A814A707CC3DC396D35902F72929FDCD698B3468F2"},
{"VivoKey Spark1 Public key", "04d64bb732c0d214e7ec580736acf847284b502c25c0f7f2fa86aace1dada4387a"}, {"VivoKey Spark1 Public key", "04D64BB732C0D214E7EC580736ACF847284B502C25C0F7F2FA86AACE1DADA4387A"},
{"TruST25 (ST)", "04101E188A8B4CDDBC62D5BC3E0E6850F0C2730E744B79765A0E079907FBDB01BC"},
}; };
/* /*
uint8_t nxp_15693_public_keys[][PUBLIC_ECDA_KEYLEN] = { uint8_t nxp_15693_public_keys[][PUBLIC_ECDA_KEYLEN] = {

View file

@ -70,8 +70,15 @@ int mfc_ev1_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signature, in
// ref: MIFARE Classic EV1 Originality Signature Validation // ref: MIFARE Classic EV1 Originality Signature Validation
#define PUBLIC_MFCEV1_ECDA_KEYLEN 33 #define PUBLIC_MFCEV1_ECDA_KEYLEN 33
const ecdsa_publickey_t nxp_mfc_public_keys[] = { const ecdsa_publickey_t nxp_mfc_public_keys[] = {
{"NXP MIFARE Classic MFC1C14_x", "044F6D3F294DEA5737F0F46FFEE88A356EED95695DD7E0C27A591E6F6F65962BAF"}, {"NXP MIFARE Classic MFC1C14_x", "044F6D3F294DEA5737F0F46FFEE88A356EED95695DD7E0C27A591E6F6F65962BAF"},
{"Manufacturer MIFARE Classic / QL88", "046F70AC557F5461CE5052C8E4A7838C11C7A236797E8A0730A101837C004039C2"}, {"MIFARE Classic / QL88", "046F70AC557F5461CE5052C8E4A7838C11C7A236797E8A0730A101837C004039C2"},
{"NXP ICODE DNA, ICODE SLIX2", "048878A2A2D3EEC336B4F261A082BD71F9BE11C4E2E896648B32EFA59CEA6E59F0"},
{"NXP Public key", "04A748B6A632FBEE2C0897702B33BEA1C074998E17B84ACA04FF267E5D2C91F6DC"},
{"NXP Ultralight Ev1", "0490933BDCD6E99B4E255E3DA55389A827564E11718E017292FAF23226A96614B8"},
{"NXP NTAG21x (2013)", "04494E1A386D3D3CFE3DC10E5DE68A499B1C202DB5B132393E89ED19FE5BE8BC61"},
{"MIKRON Public key", "04F971EDA742A4A80D32DCF6A814A707CC3DC396D35902F72929FDCD698B3468F2"},
{"VivoKey Spark1 Public key", "04D64BB732C0D214E7EC580736ACF847284B502C25C0F7F2FA86AACE1DADA4387A"},
{"TruST25 (ST)", "04101E188A8B4CDDBC62D5BC3E0E6850F0C2730E744B79765A0E079907FBDB01BC"},
}; };
uint8_t i; uint8_t i;

View file

@ -215,11 +215,12 @@ int ul_read_uid(uint8_t *uid) {
PrintAndLogEx(DEBUG, "iso14443a card select failed"); PrintAndLogEx(DEBUG, "iso14443a card select failed");
return PM3_ESOFT; return PM3_ESOFT;
} }
memcpy(uid, card.uid, 7);
if (card.uidlen != 7) { if (card.uidlen != 7) {
PrintAndLogEx(WARNING, "Wrong sized UID, expected 7 bytes, got " _RED_("%d"), card.uidlen); PrintAndLogEx(WARNING, "Wrong sized UID, expected 7 bytes, got " _RED_("%d"), card.uidlen);
return PM3_ESOFT; return PM3_ELENGTH;
} }
memcpy(uid, card.uid, 7);
return PM3_SUCCESS; return PM3_SUCCESS;
} }
@ -1245,13 +1246,15 @@ static int ulev1_print_signature(uint64_t tagtype, uint8_t *uid, uint8_t *signat
// ref: AN11350 NTAG 21x Originality Signature Validation // ref: AN11350 NTAG 21x Originality Signature Validation
// ref: AN11341 MIFARE Ultralight EV1 Originality Signature Validation // ref: AN11341 MIFARE Ultralight EV1 Originality Signature Validation
const ecdsa_publickey_t nxp_mfu_public_keys[] = { const ecdsa_publickey_t nxp_mfu_public_keys[] = {
{"NXP MIFARE Classic MFC1C14_x", "044F6D3F294DEA5737F0F46FFEE88A356EED95695DD7E0C27A591E6F6F65962BAF"}, {"NXP MIFARE Classic MFC1C14_x", "044F6D3F294DEA5737F0F46FFEE88A356EED95695DD7E0C27A591E6F6F65962BAF"},
{"Manufacturer MIFARE Classic / QL88", "046F70AC557F5461CE5052C8E4A7838C11C7A236797E8A0730A101837C004039C2"}, {"MIFARE Classic / QL88", "046F70AC557F5461CE5052C8E4A7838C11C7A236797E8A0730A101837C004039C2"},
{"NXP ICODE DNA, ICODE SLIX2", "048878A2A2D3EEC336B4F261A082BD71F9BE11C4E2E896648B32EFA59CEA6E59F0"}, {"NXP ICODE DNA, ICODE SLIX2", "048878A2A2D3EEC336B4F261A082BD71F9BE11C4E2E896648B32EFA59CEA6E59F0"},
{"NXP Public key", "04A748B6A632FBEE2C0897702B33BEA1C074998E17B84ACA04FF267E5D2C91F6DC"}, {"NXP Public key", "04A748B6A632FBEE2C0897702B33BEA1C074998E17B84ACA04FF267E5D2C91F6DC"},
{"NXP Ultralight Ev1", "0490933BDCD6E99B4E255E3DA55389A827564E11718E017292FAF23226A96614B8"}, {"NXP Ultralight Ev1", "0490933BDCD6E99B4E255E3DA55389A827564E11718E017292FAF23226A96614B8"},
{"NXP NTAG21x (2013)", "04494E1A386D3D3CFE3DC10E5DE68A499B1C202DB5B132393E89ED19FE5BE8BC61"}, {"NXP NTAG21x (2013)", "04494E1A386D3D3CFE3DC10E5DE68A499B1C202DB5B132393E89ED19FE5BE8BC61"},
{"MIKRON Public key", "04F971EDA742A4A80D32DCF6A814A707CC3DC396D35902F72929FDCD698B3468F2"}, {"MIKRON Public key", "04F971EDA742A4A80D32DCF6A814A707CC3DC396D35902F72929FDCD698B3468F2"},
{"VivoKey Spark1 Public key", "04D64BB732C0D214E7EC580736ACF847284B502C25C0F7F2FA86AACE1DADA4387A"},
{"TruST25 (ST)", "04101E188A8B4CDDBC62D5BC3E0E6850F0C2730E744B79765A0E079907FBDB01BC"},
}; };
// https://www.nxp.com/docs/en/application-note/AN13452.pdf // https://www.nxp.com/docs/en/application-note/AN13452.pdf

View file

@ -262,7 +262,7 @@ while true; do
if ! CheckExecute "findbits test" "tools/findbits.py 73 0110010101110011" "Match at bit 9: 011001010"; then break; fi if ! CheckExecute "findbits test" "tools/findbits.py 73 0110010101110011" "Match at bit 9: 011001010"; then break; fi
if ! CheckExecute "findbits_test test" "tools/findbits_test.py 2>&1" "OK"; then break; fi if ! CheckExecute "findbits_test test" "tools/findbits_test.py 2>&1" "OK"; then break; fi
if ! CheckExecute "pm3_eml_mfd test" "tools/pm3_eml_mfd_test.py 2>&1" "OK"; then break; fi if ! CheckExecute "pm3_eml_mfd test" "tools/pm3_eml_mfd_test.py 2>&1" "OK"; then break; fi
if ! CheckExecute "recover_pk test" "tools/recover_pk.py selftests 2>&1" "Tests:.*\[OK\]"; then break; fi if ! CheckExecute "recover_pk test" "tools/recover_pk.py selftests 2>&1" "Tests:.*\(.*ok.*"; then break; fi
if ! CheckExecute "mkversion create test" "tools/mkversion.sh --short" 'Iceman/'; then break; fi if ! CheckExecute "mkversion create test" "tools/mkversion.sh --short" 'Iceman/'; then break; fi
fi fi
if $TESTALL || $TESTBOOTROM; then if $TESTALL || $TESTBOOTROM; then

View file

@ -12,7 +12,6 @@ from colors import color
debug = False debug = False
def guess_curvename(signature): def guess_curvename(signature):
siglen = (len(signature) // 2) & 0xfe siglen = (len(signature) // 2) & 0xfe
if siglen == 32: if siglen == 32:
@ -28,10 +27,10 @@ def guess_curvename(signature):
elif siglen == 132: elif siglen == 132:
curves = ["secp521r1"] curves = ["secp521r1"]
else: else:
raise ValueError("Unsupported signature size %i" % len(signature)) lenstr = color('%i', fg='red') % len(signature)
raise ValueError("Unsupported signature size %s" % lenstr)
return curves return curves
def recover(data, signature, curvename, alghash=None): def recover(data, signature, curvename, alghash=None):
recovered = set() recovered = set()
try: try:
@ -61,7 +60,6 @@ def recover(data, signature, curvename, alghash=None):
pass pass
return recovered return recovered
def recover_multiple(uids, sigs, curvename, alghash=None): def recover_multiple(uids, sigs, curvename, alghash=None):
recovered = set() recovered = set()
assert len(uids) == len(sigs) assert len(uids) == len(sigs)
@ -147,7 +145,7 @@ def selftests():
# (and it uses a SHA256) # (and it uses a SHA256)
'samples': ["E0040118009C870C", "4B4E03E1211952EF6A5F9D84AB218CD4D7549D0CDF8CA8779F9AD16C9A9CBF3B", 'samples': ["E0040118009C870C", "4B4E03E1211952EF6A5F9D84AB218CD4D7549D0CDF8CA8779F9AD16C9A9CBF3B",
"E0040118009B4D62", "25CF13747C3389EC7889DE916E3747584978511CC78B51CFB1883B494CBED7AB"], "E0040118009B4D62", "25CF13747C3389EC7889DE916E3747584978511CC78B51CFB1883B494CBED7AB"],
'pk': "04d64bb732c0d214e7ec580736acf847284b502c25c0f7f2fa86aace1dada4387a"}, 'pk': "04D64BB732C0D214E7EC580736ACF847284B502C25C0F7F2FA86AACE1DADA4387A"},
{'name': "ICODE DNA, ICODE SLIX2", {'name': "ICODE DNA, ICODE SLIX2",
# ! tag UID is considered inverted: E0040118009B5FEE => EE5F9B00180104E0 # ! tag UID is considered inverted: E0040118009B5FEE => EE5F9B00180104E0
@ -166,30 +164,33 @@ def selftests():
'pk': "040F732E0EA7DF2B38F791BF89425BF7DCDF3EE4D976669E3831F324FF15751BD52AFF1782F72FF2731EEAD5F63ABE7D126E03C856FFB942AF"}, 'pk': "040F732E0EA7DF2B38F791BF89425BF7DCDF3EE4D976669E3831F324FF15751BD52AFF1782F72FF2731EEAD5F63ABE7D126E03C856FFB942AF"},
# {'name': "MIFARE Ultralight AES", # {'name': "MIFARE Ultralight AES",
# uses , # uses NID_secp192r1, OpenSSL doesn't support it. This is commented out until that day.
# 'samples': ["04E163C2451390", "240284F3F2703C6911D2E7B4211A421378C3DE911F6E9DA120224508C72D4CDE58F3DBEE065C824BA595AB0352888516", # 'samples': ["045E4CC2451390", "C9BBDA1B99EB6634CDFD8E3251AC5C4742EA5FA507B8A8A8B39B19AB7340D173331589C54C56C49F0CCA6DDBAC1E492A",
# "042F6892457080", "1824472A4CC927C7CA423F2B75E8E15CD26F682D3D633B3E032879B11D2E7C0E5BDC720D7D4F3AB04DEC7229EC213C89"], # "043F88C2451390", "5C2055A7373F119C3FDD9843020B06AA0E6DE18C16496C425C4AD971A50F05FA1A67B9E39CA60C355EEEEBF8214A84A5"],
# 'pk': "0453BF8C49B7BD9FE3207A91513B9C1D238ECAB07186B772104AB535F7D3AE63CF7C7F3DD0D169DA3E99E43C6399621A86"}, # 'pk': "0453BF8C49B7BD9FE3207A91513B9C1D238ECAB07186B772104AB535F7D3AE63CF7C7F3DD0D169DA3E99E43C6399621A86"},
{'name': "Manufacturer MIFARE Classic / QL88", {'name': "MIFARE Classic / QL88",
'samples': ["30933C61", "AEA4DD0B800FAC63D4DE08EE91F4650ED825FD6B4D7DEEE98DBC9BAE10BE003E", 'samples': ["30933C61", "AEA4DD0B800FAC63D4DE08EE91F4650ED825FD6B4D7DEEE98DBC9BAE10BE003E",
"20593261", "F762CDD59EEDC075F4DDBA7ECD529FEEE5135C65A84D12EF0A250A321B2012F5"], "20593261", "F762CDD59EEDC075F4DDBA7ECD529FEEE5135C65A84D12EF0A250A321B2012F5"],
'pk': "046F70AC557F5461CE5052C8E4A7838C11C7A236797E8A0730A101837C004039C2"}, 'pk': "046F70AC557F5461CE5052C8E4A7838C11C7A236797E8A0730A101837C004039C2"},
# TruST25 (ST) - KeyID 0x04? # TruST25 (ST) - KeyID 0x04?
# curve=secp128r1, hash=sha256 - from block 63 in ST25TV, starting with KeyID ? # curve=secp128r1, hash=sha256 - from block 63 in ST25TV, starting with KeyID ?
{'name': "ST25TV02KC - TruST25 (ST) - KeyID 0x04?", {'name': "ST25TV02KC TruST25 (ST) / KeyID 0x04?",
'samples': ["E00208000A227AAA", "FE458A550ACD30B45B9C4D10676FC63E30AC69027217547FBDF04A8F7942AD3B", 'samples': ["E00208000A227AAA", "FE458A550ACD30B45B9C4D10676FC63E30AC69027217547FBDF04A8F7942AD3B",
"E00208000A17DB6E", "B3ED5025F16455AAC6012CA1C1FC5F94F8C805AF1EF6A86B646081C9916CDD2E", "E00208000A17DB6E", "B3ED5025F16455AAC6012CA1C1FC5F94F8C805AF1EF6A86B646081C9916CDD2E",
"E00208000A174F60", "AB42F1FA68D7470F91D4ED77C4D951B1B4AAB006812BE194BFEB7AAE48E4FA45"], "E00208000A174F60", "AB42F1FA68D7470F91D4ED77C4D951B1B4AAB006812BE194BFEB7AAE48E4FA45"],
'pk': "04101e188a8b4cddbc62d5bc3e0e6850f0c2730e744b79765a0e079907fbdb01bc"}, 'pk': "04101E188A8B4CDDBC62D5BC3E0E6850F0C2730E744B79765A0E079907FBDB01BC"},
] ]
succeeded = True succeeded = True
for t in tests: for t in tests:
print("Testing %-25s" % (t['name']+":"), end="")
print("Testing %-38s" % (t['name']+":"), end="")
curvenames = guess_curvename(t['samples'][1]) curvenames = guess_curvename(t['samples'][1])
recovered = set() recovered = set()
for c in curvenames: for c in curvenames:
for h in [None, "md5", "sha1", "sha256", "sha512"]: for h in [None, "md5", "sha1", "sha256", "sha512"]:
recovered |= recover_multiple(t['samples'][::2], t['samples'][1::2], c, alghash=h) recovered |= recover_multiple(t['samples'][::2], t['samples'][1::2], c, alghash=h)
@ -198,22 +199,26 @@ def selftests():
pk = recovered.pop() pk = recovered.pop()
pk = binascii.hexlify(pk).decode('utf8') pk = binascii.hexlify(pk).decode('utf8')
if pk.lower() == t['pk'].lower(): if pk.lower() == t['pk'].lower():
print("[OK]") print("( %s )" % color('ok', fg='green'))
else: else:
succeeded = False succeeded = False
print("[FAIL], got %s" % pk.lower()) print("( FAIL ) got %s" % pk.lower())
elif len(t['samples'])//2 == 1: elif len(t['samples'])//2 == 1:
pks = [binascii.hexlify(pk).decode('utf8').lower() for pk in list(recovered)] pks = [binascii.hexlify(pk).decode('utf8').lower() for pk in list(recovered)]
if t['pk'].lower() in pks: if t['pk'].lower() in pks:
print("[OK] (partial)") print("( %s ) partial" % color('ok', fg='green'))
else: else:
succeeded = False succeeded = False
print("[FAIL], got %s" % pks) print("( %s ), got %s" % color('fail', fg='red'), pks)
else: else:
print("( %s )" % color('fail', fg='red'))
succeeded = False succeeded = False
print("[FAIL]")
print("Tests: [%s]" % ["FAIL", "OK"][succeeded])
print("=====================================================")
fail = color('fail', fg='red')
ok = color('ok', fg='green')
print("Tests: ( %s )" % [fail, ok][succeeded])
print("")
if __name__ == "__main__": if __name__ == "__main__":
if len(sys.argv) == 2 and sys.argv[1] == "selftests": if len(sys.argv) == 2 and sys.argv[1] == "selftests":