mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-09-20 15:26:13 +08:00
make style
This commit is contained in:
parent
44d7c54be7
commit
ee8b9ca74b
|
@ -136,7 +136,7 @@ static bool saMifareDiscover(void) {
|
||||||
// Customized MifareChkKeys that operates on the already detected card in
|
// Customized MifareChkKeys that operates on the already detected card in
|
||||||
// mattyrun_card and tests authentication with our dictionary
|
// mattyrun_card and tests authentication with our dictionary
|
||||||
static int saMifareChkKeys(uint8_t const blockNo, uint8_t const keyType, bool const clearTrace,
|
static int saMifareChkKeys(uint8_t const blockNo, uint8_t const keyType, bool const clearTrace,
|
||||||
uint16_t const keyCount, uint64_t const * const mfKeys, uint64_t * const key) {
|
uint16_t const keyCount, uint64_t const *const mfKeys, uint64_t *const key) {
|
||||||
|
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
||||||
|
@ -179,10 +179,17 @@ static int saMifareChkKeys(uint8_t const blockNo, uint8_t const keyType, bool co
|
||||||
} else {
|
} else {
|
||||||
if (cascade_levels == 0) {
|
if (cascade_levels == 0) {
|
||||||
switch (mattyrun_card.uidlen) {
|
switch (mattyrun_card.uidlen) {
|
||||||
case 4: cascade_levels = 1; break;
|
case 4:
|
||||||
case 7: cascade_levels = 2; break;
|
cascade_levels = 1;
|
||||||
case 10: cascade_levels = 3; break;
|
break;
|
||||||
default: break;
|
case 7:
|
||||||
|
cascade_levels = 2;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
cascade_levels = 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// No need for anticollision. Since we sucessfully selected the card before,
|
// No need for anticollision. Since we sucessfully selected the card before,
|
||||||
|
@ -239,10 +246,10 @@ void RunMod(void) {
|
||||||
// usb_disable();
|
// usb_disable();
|
||||||
|
|
||||||
// Allocate dictionary buffer
|
// Allocate dictionary buffer
|
||||||
uint64_t * const mfcKeys = (uint64_t *)BigBuf_malloc(
|
uint64_t *const mfcKeys = (uint64_t *)BigBuf_malloc(
|
||||||
sizeof(uint64_t) * (ARRAYLEN(MATTYRUN_MFC_ESSENTIAL_KEYS) +
|
sizeof(uint64_t) * (ARRAYLEN(MATTYRUN_MFC_ESSENTIAL_KEYS) +
|
||||||
ARRAYLEN(MATTYRUN_MFC_DEFAULT_KEYS) +
|
ARRAYLEN(MATTYRUN_MFC_DEFAULT_KEYS) +
|
||||||
MIFARE_4K_MAXSECTOR * 2));
|
MIFARE_4K_MAXSECTOR * 2));
|
||||||
uint16_t mfcKeyCount = 0;
|
uint16_t mfcKeyCount = 0;
|
||||||
|
|
||||||
// Load essential keys to dictionary buffer
|
// Load essential keys to dictionary buffer
|
||||||
|
@ -550,10 +557,17 @@ void RunMod(void) {
|
||||||
|
|
||||||
uint16_t simflags = 0;
|
uint16_t simflags = 0;
|
||||||
switch (mattyrun_card.uidlen) {
|
switch (mattyrun_card.uidlen) {
|
||||||
case 4: simflags |= FLAG_4B_UID_IN_DATA; break;
|
case 4:
|
||||||
case 7: simflags |= FLAG_7B_UID_IN_DATA; break;
|
simflags |= FLAG_4B_UID_IN_DATA;
|
||||||
case 10: simflags |= FLAG_10B_UID_IN_DATA; break;
|
break;
|
||||||
default: break;
|
case 7:
|
||||||
|
simflags |= FLAG_7B_UID_IN_DATA;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
simflags |= FLAG_10B_UID_IN_DATA;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
uint16_t atqa = (uint16_t)bytes_to_num(mattyrun_card.atqa, 2);
|
uint16_t atqa = (uint16_t)bytes_to_num(mattyrun_card.atqa, 2);
|
||||||
|
|
||||||
|
|
|
@ -59,11 +59,11 @@ static uint64_t const MATTYRUN_MFC_DEFAULT_KEYS[] = {
|
||||||
0x0123456789AB,
|
0x0123456789AB,
|
||||||
0x123456789ABC,
|
0x123456789ABC,
|
||||||
|
|
||||||
// You could add more keys from, e.g, mfc_default_keys.dic here.
|
// You could add more keys from, e.g, mfc_default_keys.dic here.
|
||||||
// However, be aware that more keys means longer brute-force times
|
// However, be aware that more keys means longer brute-force times
|
||||||
// and too many keys will resuolt in running out of memory.
|
// and too many keys will resuolt in running out of memory.
|
||||||
// See https://github.com/RfidResearchGroup/proxmark3/pull/2377#issuecomment-2112658439
|
// See https://github.com/RfidResearchGroup/proxmark3/pull/2377#issuecomment-2112658439
|
||||||
// for a rough benchmark.
|
// for a rough benchmark.
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* HF_MATTYRUN_H__ */
|
#endif /* HF_MATTYRUN_H__ */
|
||||||
|
|
|
@ -184,32 +184,32 @@ int mifare_classic_authex_cmd(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
|
||||||
if (g_dbglevel >= DBG_EXTENDED) {
|
if (g_dbglevel >= DBG_EXTENDED) {
|
||||||
if (!isNested) {
|
if (!isNested) {
|
||||||
Dbprintf("auth cmd: %02x %02x | uid: %08x | nr: %08x %s| nt: %08x %s %5i| par: %i%i%i%i %s",
|
Dbprintf("auth cmd: %02x %02x | uid: %08x | nr: %08x %s| nt: %08x %s %5i| par: %i%i%i%i %s",
|
||||||
cmd, blockNo, uid,
|
cmd, blockNo, uid,
|
||||||
nr32, validate_prng_nonce(nr32) ? "@" : " ",
|
nr32, validate_prng_nonce(nr32) ? "@" : " ",
|
||||||
nt, validate_prng_nonce(nt) ? "@idx" : " idx",
|
nt, validate_prng_nonce(nt) ? "@idx" : " idx",
|
||||||
validate_prng_nonce(nt) ? nonce16_index(nt >> 16) : -1,
|
validate_prng_nonce(nt) ? nonce16_index(nt >> 16) : -1,
|
||||||
(receivedAnswerPar[0] >> 7) & 1,
|
(receivedAnswerPar[0] >> 7) & 1,
|
||||||
(receivedAnswerPar[0] >> 6) & 1,
|
(receivedAnswerPar[0] >> 6) & 1,
|
||||||
(receivedAnswerPar[0] >> 5) & 1,
|
(receivedAnswerPar[0] >> 5) & 1,
|
||||||
(receivedAnswerPar[0] >> 4) & 1,
|
(receivedAnswerPar[0] >> 4) & 1,
|
||||||
validate_parity_nonce(nt, receivedAnswerPar[0], nt) ? "ok " : "bad");
|
validate_parity_nonce(nt, receivedAnswerPar[0], nt) ? "ok " : "bad");
|
||||||
} else {
|
} else {
|
||||||
Dbprintf("auth nested cmd: %02x %02x | uid: %08x | nr: %08x %s| nt: %08x %s %5i| par: %i%i%i%i %s| ntenc: %08x %s| parerr: %i%i%i%i",
|
Dbprintf("auth nested cmd: %02x %02x | uid: %08x | nr: %08x %s| nt: %08x %s %5i| par: %i%i%i%i %s| ntenc: %08x %s| parerr: %i%i%i%i",
|
||||||
cmd, blockNo, uid,
|
cmd, blockNo, uid,
|
||||||
nr32, validate_prng_nonce(nr32) ? "@" : " ",
|
nr32, validate_prng_nonce(nr32) ? "@" : " ",
|
||||||
nt, validate_prng_nonce(nt) ? "@idx" : " idx",
|
nt, validate_prng_nonce(nt) ? "@idx" : " idx",
|
||||||
validate_prng_nonce(nt) ? nonce16_index(nt >> 16) : -1,
|
validate_prng_nonce(nt) ? nonce16_index(nt >> 16) : -1,
|
||||||
(receivedAnswerPar[0] >> 7) & 1,
|
(receivedAnswerPar[0] >> 7) & 1,
|
||||||
(receivedAnswerPar[0] >> 6) & 1,
|
(receivedAnswerPar[0] >> 6) & 1,
|
||||||
(receivedAnswerPar[0] >> 5) & 1,
|
(receivedAnswerPar[0] >> 5) & 1,
|
||||||
(receivedAnswerPar[0] >> 4) & 1,
|
(receivedAnswerPar[0] >> 4) & 1,
|
||||||
validate_parity_nonce(*ntencptr, receivedAnswerPar[0], nt) ? "ok " : "bad",
|
validate_parity_nonce(*ntencptr, receivedAnswerPar[0], nt) ? "ok " : "bad",
|
||||||
*ntencptr, validate_prng_nonce(*ntencptr) ? "@" : " ",
|
*ntencptr, validate_prng_nonce(*ntencptr) ? "@" : " ",
|
||||||
((receivedAnswerPar[0] >> 7) & 1) ^ oddparity8((*ntencptr >> 24) & 0xFF),
|
((receivedAnswerPar[0] >> 7) & 1) ^ oddparity8((*ntencptr >> 24) & 0xFF),
|
||||||
((receivedAnswerPar[0] >> 6) & 1) ^ oddparity8((*ntencptr >> 16) & 0xFF),
|
((receivedAnswerPar[0] >> 6) & 1) ^ oddparity8((*ntencptr >> 16) & 0xFF),
|
||||||
((receivedAnswerPar[0] >> 5) & 1) ^ oddparity8((*ntencptr >> 8) & 0xFF),
|
((receivedAnswerPar[0] >> 5) & 1) ^ oddparity8((*ntencptr >> 8) & 0xFF),
|
||||||
((receivedAnswerPar[0] >> 4) & 1) ^ oddparity8((*ntencptr >> 0) & 0xFF)
|
((receivedAnswerPar[0] >> 4) & 1) ^ oddparity8((*ntencptr >> 0) & 0xFF)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// save Nt
|
// save Nt
|
||||||
|
@ -932,7 +932,7 @@ int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData) {
|
||||||
bool validate_prng_nonce(uint32_t nonce) {
|
bool validate_prng_nonce(uint32_t nonce) {
|
||||||
uint16_t x = nonce >> 16;
|
uint16_t x = nonce >> 16;
|
||||||
x = (x & 0xff) << 8 | x >> 8;
|
x = (x & 0xff) << 8 | x >> 8;
|
||||||
for (uint8_t i = 0; i<16; i++) {
|
for (uint8_t i = 0; i < 16; i++) {
|
||||||
x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
|
x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
|
||||||
}
|
}
|
||||||
x = (x & 0xff) << 8 | x >> 8;
|
x = (x & 0xff) << 8 | x >> 8;
|
||||||
|
@ -942,11 +942,11 @@ bool validate_prng_nonce(uint32_t nonce) {
|
||||||
bool validate_parity_nonce(uint32_t ntenc, uint8_t ntparenc, uint32_t nt) {
|
bool validate_parity_nonce(uint32_t ntenc, uint8_t ntparenc, uint32_t nt) {
|
||||||
uint32_t ks = nt ^ ntenc;
|
uint32_t ks = nt ^ ntenc;
|
||||||
ntparenc >>= 4;
|
ntparenc >>= 4;
|
||||||
uint8_t ksp = (((ks >> 16)&1) << 3) | (((ks >> 8)&1) << 2) | (((ks >> 0)&1) << 1);
|
uint8_t ksp = (((ks >> 16) & 1) << 3) | (((ks >> 8) & 1) << 2) | (((ks >> 0) & 1) << 1);
|
||||||
uint8_t ntpar = ntparenc ^ ksp;
|
uint8_t ntpar = ntparenc ^ ksp;
|
||||||
return (((ntpar >> 3) & 1) == oddparity8((nt>>24) & 0xFF)) &&
|
return (((ntpar >> 3) & 1) == oddparity8((nt >> 24) & 0xFF)) &&
|
||||||
(((ntpar >> 2) & 1) == oddparity8((nt>>16) & 0xFF)) &&
|
(((ntpar >> 2) & 1) == oddparity8((nt >> 16) & 0xFF)) &&
|
||||||
(((ntpar >> 1) & 1) == oddparity8((nt>>8) & 0xFF));
|
(((ntpar >> 1) & 1) == oddparity8((nt >> 8) & 0xFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
int nonce16_distance(uint16_t x, uint16_t y) {
|
int nonce16_distance(uint16_t x, uint16_t y) {
|
||||||
|
@ -955,9 +955,9 @@ int nonce16_distance(uint16_t x, uint16_t y) {
|
||||||
x = (x & 0xff) << 8 | x >> 8;
|
x = (x & 0xff) << 8 | x >> 8;
|
||||||
y = (y & 0xff) << 8 | y >> 8;
|
y = (y & 0xff) << 8 | y >> 8;
|
||||||
uint16_t i = 1;
|
uint16_t i = 1;
|
||||||
for(;i;i++) {
|
for (; i; i++) {
|
||||||
x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
|
x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
|
||||||
if (x==y)
|
if (x == y)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
// never reached
|
// never reached
|
||||||
|
|
|
@ -1619,18 +1619,18 @@ static int CmdHFiClassDecrypt(const char *Cmd) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// use the first block (CSN) for filename
|
// use the first block (CSN) for filename
|
||||||
char *fptr = calloc(50, sizeof(uint8_t));
|
char *fptr = calloc(50, sizeof(uint8_t));
|
||||||
if (fptr == false) {
|
if (fptr == false) {
|
||||||
PrintAndLogEx(WARNING, "Failed to allocate memory");
|
PrintAndLogEx(WARNING, "Failed to allocate memory");
|
||||||
free(decrypted);
|
free(decrypted);
|
||||||
return PM3_EMALLOC;
|
return PM3_EMALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcat(fptr, "hf-iclass-");
|
strcat(fptr, "hf-iclass-");
|
||||||
FillFileNameByUID(fptr, hdr->csn, "-dump-decrypted", sizeof(hdr->csn));
|
FillFileNameByUID(fptr, hdr->csn, "-dump-decrypted", sizeof(hdr->csn));
|
||||||
|
|
||||||
pm3_save_dump(fptr, decrypted, decryptedlen, jsfIclass);
|
pm3_save_dump(fptr, decrypted, decryptedlen, jsfIclass);
|
||||||
free(fptr);
|
free(fptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1645,8 +1645,8 @@ static int CmdHFiClassDecrypt(const char *Cmd) {
|
||||||
// decode block 6
|
// decode block 6
|
||||||
bool has_values = (memcmp(decrypted + (8 * 6), empty, 8) != 0) && (memcmp(decrypted + (8 * 6), zeros, 8) != 0);
|
bool has_values = (memcmp(decrypted + (8 * 6), empty, 8) != 0) && (memcmp(decrypted + (8 * 6), zeros, 8) != 0);
|
||||||
if (has_values && use_sc) {
|
if (has_values && use_sc) {
|
||||||
DecodeBlock6(decrypted + (8 * 6));
|
DecodeBlock6(decrypted + (8 * 6));
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode block 7-8-9
|
// decode block 7-8-9
|
||||||
iclass_decode_credentials(decrypted);
|
iclass_decode_credentials(decrypted);
|
||||||
|
|
|
@ -3375,7 +3375,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) {
|
||||||
|
|
||||||
uint16_t singleSectorParams = 0;
|
uint16_t singleSectorParams = 0;
|
||||||
if (blockn != -1) {
|
if (blockn != -1) {
|
||||||
singleSectorParams = (blockn & 0xFF)| keytype << 8 | 1 << 15;
|
singleSectorParams = (blockn & 0xFF) | keytype << 8 | 1 << 15;
|
||||||
}
|
}
|
||||||
if (use_flashmemory) {
|
if (use_flashmemory) {
|
||||||
PrintAndLogEx(SUCCESS, "Using dictionary in flash memory");
|
PrintAndLogEx(SUCCESS, "Using dictionary in flash memory");
|
||||||
|
|
|
@ -264,7 +264,7 @@ int mfCheckKeys_fast_ex(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChun
|
||||||
if (curr_keys) {
|
if (curr_keys) {
|
||||||
uint64_t foo = bytes_to_num(resp.data.asBytes, 6);
|
uint64_t foo = bytes_to_num(resp.data.asBytes, 6);
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(SUCCESS, _GREEN_("Key %s for block %2i found: %012" PRIx64), (singleSectorParams >> 8) & 1 ? "B":"A", singleSectorParams & 0xFF, foo);
|
PrintAndLogEx(SUCCESS, _GREEN_("Key %s for block %2i found: %012" PRIx64), (singleSectorParams >> 8) & 1 ? "B" : "A", singleSectorParams & 0xFF, foo);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -605,16 +605,16 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo,
|
||||||
|
|
||||||
if (package->keytype < 2) {
|
if (package->keytype < 2) {
|
||||||
PrintAndLogEx(SUCCESS, "\nTarget block %4u key type %c -- found valid key [ " _GREEN_("%s") " ]",
|
PrintAndLogEx(SUCCESS, "\nTarget block %4u key type %c -- found valid key [ " _GREEN_("%s") " ]",
|
||||||
package->block,
|
package->block,
|
||||||
package->keytype ? 'B' : 'A',
|
package->keytype ? 'B' : 'A',
|
||||||
sprint_hex_inrow(resultKey, 6)
|
sprint_hex_inrow(resultKey, 6)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(SUCCESS, "\nTarget block %4u key type %02x -- found valid key [ " _GREEN_("%s") " ]",
|
PrintAndLogEx(SUCCESS, "\nTarget block %4u key type %02x -- found valid key [ " _GREEN_("%s") " ]",
|
||||||
package->block,
|
package->block,
|
||||||
MIFARE_AUTH_KEYA + package->keytype,
|
MIFARE_AUTH_KEYA + package->keytype,
|
||||||
sprint_hex_inrow(resultKey, 6)
|
sprint_hex_inrow(resultKey, 6)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -628,14 +628,14 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo,
|
||||||
out:
|
out:
|
||||||
if (package->keytype < 2) {
|
if (package->keytype < 2) {
|
||||||
PrintAndLogEx(SUCCESS, "\nTarget block %4u key type %c",
|
PrintAndLogEx(SUCCESS, "\nTarget block %4u key type %c",
|
||||||
package->block,
|
package->block,
|
||||||
package->keytype ? 'B' : 'A'
|
package->keytype ? 'B' : 'A'
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(SUCCESS, "\nTarget block %4u key type %02x",
|
PrintAndLogEx(SUCCESS, "\nTarget block %4u key type %02x",
|
||||||
package->block,
|
package->block,
|
||||||
MIFARE_AUTH_KEYA + package->keytype
|
MIFARE_AUTH_KEYA + package->keytype
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
free(statelists[0].head.slhead);
|
free(statelists[0].head.slhead);
|
||||||
free(statelists[1].head.slhead);
|
free(statelists[1].head.slhead);
|
||||||
|
@ -1430,17 +1430,17 @@ int detect_classic_static_encrypted_nonce_ex(uint8_t block_no, uint8_t key_type,
|
||||||
}
|
}
|
||||||
if (verbose && (resp.data.asBytes[0] == NONCE_STATIC_ENC)) {
|
if (verbose && (resp.data.asBytes[0] == NONCE_STATIC_ENC)) {
|
||||||
uint32_t uid = resp.data.asBytes[1] << 24 |
|
uint32_t uid = resp.data.asBytes[1] << 24 |
|
||||||
resp.data.asBytes[2] << 16 |
|
resp.data.asBytes[2] << 16 |
|
||||||
resp.data.asBytes[3] << 8 |
|
resp.data.asBytes[3] << 8 |
|
||||||
resp.data.asBytes[4];
|
resp.data.asBytes[4];
|
||||||
uint32_t nt = resp.data.asBytes[5] << 24 |
|
uint32_t nt = resp.data.asBytes[5] << 24 |
|
||||||
resp.data.asBytes[6] << 16 |
|
resp.data.asBytes[6] << 16 |
|
||||||
resp.data.asBytes[7] << 8 |
|
resp.data.asBytes[7] << 8 |
|
||||||
resp.data.asBytes[8];
|
resp.data.asBytes[8];
|
||||||
uint32_t ntenc = resp.data.asBytes[9] << 24 |
|
uint32_t ntenc = resp.data.asBytes[9] << 24 |
|
||||||
resp.data.asBytes[10] << 16 |
|
resp.data.asBytes[10] << 16 |
|
||||||
resp.data.asBytes[11] << 8 |
|
resp.data.asBytes[11] << 8 |
|
||||||
resp.data.asBytes[12];
|
resp.data.asBytes[12];
|
||||||
uint8_t ntencparenc = resp.data.asBytes[13];
|
uint8_t ntencparenc = resp.data.asBytes[13];
|
||||||
|
|
||||||
// recompute nt on client, just because
|
// recompute nt on client, just because
|
||||||
|
@ -1457,24 +1457,24 @@ int detect_classic_static_encrypted_nonce_ex(uint8_t block_no, uint8_t key_type,
|
||||||
ntencparenc >>= 4;
|
ntencparenc >>= 4;
|
||||||
// [...] Additionally, the bit of keystream used to encrypt the parity bits is reused to encrypt the next bit of plaintext.
|
// [...] Additionally, the bit of keystream used to encrypt the parity bits is reused to encrypt the next bit of plaintext.
|
||||||
// we can decrypt first 3 parity bits, not last one as it's using future keystream
|
// we can decrypt first 3 parity bits, not last one as it's using future keystream
|
||||||
uint8_t ksp = (((ks >> 16)&1) << 3) | (((ks >> 8)&1) << 2) | (((ks >> 0)&1) << 1);
|
uint8_t ksp = (((ks >> 16) & 1) << 3) | (((ks >> 8) & 1) << 2) | (((ks >> 0) & 1) << 1);
|
||||||
uint8_t ntencpar = ntencparenc ^ ksp;
|
uint8_t ntencpar = ntencparenc ^ ksp;
|
||||||
if (validate_prng_nonce(nt)) {
|
if (validate_prng_nonce(nt)) {
|
||||||
PrintAndLogEx(INFO, "nTenc " _GREEN_("%08x") " par {" _YELLOW_("%i%i%i%i") "}=" _YELLOW_("%i%i%ix") " | ks " _GREEN_("%08x") " | nT " _GREEN_("%08x") " par " _YELLOW_("%i%i%i%i")" | lfsr16 index " _GREEN_("%i"),
|
PrintAndLogEx(INFO, "nTenc " _GREEN_("%08x") " par {" _YELLOW_("%i%i%i%i") "}=" _YELLOW_("%i%i%ix") " | ks " _GREEN_("%08x") " | nT " _GREEN_("%08x") " par " _YELLOW_("%i%i%i%i")" | lfsr16 index " _GREEN_("%i"),
|
||||||
ntenc,
|
ntenc,
|
||||||
(ntencparenc >> 3) & 1, (ntencparenc >> 2) & 1, (ntencparenc >> 1) & 1, ntencparenc & 1,
|
(ntencparenc >> 3) & 1, (ntencparenc >> 2) & 1, (ntencparenc >> 1) & 1, ntencparenc & 1,
|
||||||
(ntencpar >> 3) & 1, (ntencpar >> 2) & 1, (ntencpar >> 1) & 1,
|
(ntencpar >> 3) & 1, (ntencpar >> 2) & 1, (ntencpar >> 1) & 1,
|
||||||
ks, nt,
|
ks, nt,
|
||||||
oddparity8((nt>>24) & 0xFF), oddparity8((nt>>16) & 0xFF), oddparity8((nt>>8) & 0xFF), oddparity8(nt & 0xFF),
|
oddparity8((nt >> 24) & 0xFF), oddparity8((nt >> 16) & 0xFF), oddparity8((nt >> 8) & 0xFF), oddparity8(nt & 0xFF),
|
||||||
nonce_distance(0, nt));
|
nonce_distance(0, nt));
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(INFO, "nTenc " _GREEN_("%08x") " par {" _YELLOW_("%i%i%i%i") "}=" _YELLOW_("%i%i%ix") " | ks " _YELLOW_("%08x") " | nT " _YELLOW_("%08x") " par " _YELLOW_("%i%i%i%i") " | " _RED_("not lfsr16") " (wrong key)",
|
PrintAndLogEx(INFO, "nTenc " _GREEN_("%08x") " par {" _YELLOW_("%i%i%i%i") "}=" _YELLOW_("%i%i%ix") " | ks " _YELLOW_("%08x") " | nT " _YELLOW_("%08x") " par " _YELLOW_("%i%i%i%i") " | " _RED_("not lfsr16") " (wrong key)",
|
||||||
ntenc,
|
ntenc,
|
||||||
(ntencparenc >> 3) & 1, (ntencparenc >> 2) & 1, (ntencparenc >> 1) & 1, ntencparenc & 1,
|
(ntencparenc >> 3) & 1, (ntencparenc >> 2) & 1, (ntencparenc >> 1) & 1, ntencparenc & 1,
|
||||||
(ntencpar >> 3) & 1, (ntencpar >> 2) & 1, (ntencpar >> 1) & 1,
|
(ntencpar >> 3) & 1, (ntencpar >> 2) & 1, (ntencpar >> 1) & 1,
|
||||||
ks, nt,
|
ks, nt,
|
||||||
oddparity8((nt>>24) & 0xFF), oddparity8((nt>>16) & 0xFF), oddparity8((nt>>8) & 0xFF), oddparity8(nt & 0xFF)
|
oddparity8((nt >> 24) & 0xFF), oddparity8((nt >> 16) & 0xFF), oddparity8((nt >> 8) & 0xFF), oddparity8(nt & 0xFF)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return resp.data.asBytes[0];
|
return resp.data.asBytes[0];
|
||||||
|
|
|
@ -337,6 +337,7 @@ const static vocabulary_t vocabulary[] = {
|
||||||
{ 1, "hf mf help" },
|
{ 1, "hf mf help" },
|
||||||
{ 1, "hf mf list" },
|
{ 1, "hf mf list" },
|
||||||
{ 0, "hf mf info" },
|
{ 0, "hf mf info" },
|
||||||
|
{ 0, "hf mf isen" },
|
||||||
{ 0, "hf mf darkside" },
|
{ 0, "hf mf darkside" },
|
||||||
{ 0, "hf mf nested" },
|
{ 0, "hf mf nested" },
|
||||||
{ 1, "hf mf hardnested" },
|
{ 1, "hf mf hardnested" },
|
||||||
|
|
|
@ -432,7 +432,7 @@ int nonce_distance(uint32_t from, uint32_t to) {
|
||||||
bool validate_prng_nonce(uint32_t nonce) {
|
bool validate_prng_nonce(uint32_t nonce) {
|
||||||
uint16_t x = nonce >> 16;
|
uint16_t x = nonce >> 16;
|
||||||
x = (x & 0xff) << 8 | x >> 8;
|
x = (x & 0xff) << 8 | x >> 8;
|
||||||
for (uint8_t i = 0; i<16; i++) {
|
for (uint8_t i = 0; i < 16; i++) {
|
||||||
x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
|
x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
|
||||||
}
|
}
|
||||||
x = (x & 0xff) << 8 | x >> 8;
|
x = (x & 0xff) << 8 | x >> 8;
|
||||||
|
|
|
@ -3234,9 +3234,10 @@
|
||||||
"-k, --key <hex> 3DES transport key",
|
"-k, --key <hex> 3DES transport key",
|
||||||
"-v, --verbose verbose output",
|
"-v, --verbose verbose output",
|
||||||
"--d6 decode as block 6",
|
"--d6 decode as block 6",
|
||||||
"-z, --dense dense dump output style"
|
"-z, --dense dense dump output style",
|
||||||
|
"--ns no save to file"
|
||||||
],
|
],
|
||||||
"usage": "hf iclass decrypt [-hvz] [-f <fn>] [-d <hex>] [-k <hex>] [--d6]"
|
"usage": "hf iclass decrypt [-hvz] [-f <fn>] [-d <hex>] [-k <hex>] [--d6] [--ns]"
|
||||||
},
|
},
|
||||||
"hf iclass dump": {
|
"hf iclass dump": {
|
||||||
"command": "hf iclass dump",
|
"command": "hf iclass dump",
|
||||||
|
@ -4699,9 +4700,12 @@
|
||||||
"--emu Fill simulator keys from found keys",
|
"--emu Fill simulator keys from found keys",
|
||||||
"--dump Dump found keys to binary file",
|
"--dump Dump found keys to binary file",
|
||||||
"--mem Use dictionary from flashmemory",
|
"--mem Use dictionary from flashmemory",
|
||||||
"-f, --file <fn> filename of dictionary"
|
"-f, --file <fn> filename of dictionary",
|
||||||
|
"--blk <dec> block number (single block recovery mode)",
|
||||||
|
"-a single block recovery key A",
|
||||||
|
"-b single block recovery key B"
|
||||||
],
|
],
|
||||||
"usage": "hf mf fchk [-h] [-k <hex>]... [--mini] [--1k] [--2k] [--4k] [--emu] [--dump] [--mem] [-f <fn>]"
|
"usage": "hf mf fchk [-hab] [-k <hex>]... [--mini] [--1k] [--2k] [--4k] [--emu] [--dump] [--mem] [-f <fn>] [--blk <dec>]"
|
||||||
},
|
},
|
||||||
"hf mf gchpwd": {
|
"hf mf gchpwd": {
|
||||||
"command": "hf mf gchpwd",
|
"command": "hf mf gchpwd",
|
||||||
|
@ -5015,6 +5019,39 @@
|
||||||
],
|
],
|
||||||
"usage": "hf mf info [-habnv] [--blk <dec>] [-k <hex>]"
|
"usage": "hf mf info [-habnv] [--blk <dec>] [-k <hex>]"
|
||||||
},
|
},
|
||||||
|
"hf mf isen": {
|
||||||
|
"command": "hf mf isen",
|
||||||
|
"description": "Information about Static Encrypted Nonce properties in a MIFARE Classic card",
|
||||||
|
"notes": [
|
||||||
|
"hf mf isen",
|
||||||
|
"Default behavior:",
|
||||||
|
"auth(blk)-auth(blk2)-auth(blk2)-...",
|
||||||
|
"Default behavior when wrong key2:",
|
||||||
|
"auth(blk)-auth(blk2) auth(blk)-auth(blk2) ..."
|
||||||
|
],
|
||||||
|
"offline": false,
|
||||||
|
"options": [
|
||||||
|
"-h, --help This help",
|
||||||
|
"--blk <dec> block number",
|
||||||
|
"-a input key type is key A (def)",
|
||||||
|
"-b input key type is key B",
|
||||||
|
"-c <dec> input key type is key A + offset",
|
||||||
|
"-k, --key <hex> key, 6 hex bytes",
|
||||||
|
"--blk2 <dec> nested block number (default=same)",
|
||||||
|
"--a2 nested input key type is key A (default=same)",
|
||||||
|
"--b2 nested input key type is key B (default=same)",
|
||||||
|
"--c2 <dec> nested input key type is key A + offset",
|
||||||
|
"--key2 <hex> nested key, 6 hex bytes (default=same)",
|
||||||
|
"-n <dec> number of nonces (default=2)",
|
||||||
|
"--reset reset between attempts, even if auth was successful",
|
||||||
|
"--addread auth(blk)-read(blk)-auth(blk2)",
|
||||||
|
"--addauth auth(blk)-auth(blk)-auth(blk2)",
|
||||||
|
"--incblk2 auth(blk)-auth(blk2)-auth(blk2+4)-...",
|
||||||
|
"--corruptnrar corrupt {nR}{aR}, but with correct parity",
|
||||||
|
"--corruptnrarparity correct {nR}{aR}, but with corrupted parity"
|
||||||
|
],
|
||||||
|
"usage": "hf mf isen [-hab] [--blk <dec>] [-c <dec>] [-k <hex>] [--blk2 <dec>] [--a2] [--b2] [--c2 <dec>] [--key2 <hex>] [-n <dec>] [--reset] [--addread] [--addauth] [--incblk2] [--corruptnrar] [--corruptnrarparity]"
|
||||||
|
},
|
||||||
"hf mf mad": {
|
"hf mf mad": {
|
||||||
"command": "hf mf mad",
|
"command": "hf mf mad",
|
||||||
"description": "Checks and prints MIFARE Application Directory (MAD)",
|
"description": "Checks and prints MIFARE Application Directory (MAD)",
|
||||||
|
@ -5131,14 +5168,17 @@
|
||||||
"--blk <dec> Input block number",
|
"--blk <dec> Input block number",
|
||||||
"-a Input key specified is A key (default)",
|
"-a Input key specified is A key (default)",
|
||||||
"-b Input key specified is B key",
|
"-b Input key specified is B key",
|
||||||
|
"-c <dec> input key type is key A + offset",
|
||||||
"--tblk <dec> Target block number",
|
"--tblk <dec> Target block number",
|
||||||
"--ta Target A key (default)",
|
"--ta Target A key (default)",
|
||||||
"--tb Target B key",
|
"--tb Target B key",
|
||||||
|
"--tc <dec> Nested input key type is key A + offset (you must specify a single block as well!)",
|
||||||
"--emu Fill simulator keys from found keys",
|
"--emu Fill simulator keys from found keys",
|
||||||
"--dump Dump found keys to file",
|
"--dump Dump found keys to file",
|
||||||
"--mem Use dictionary from flashmemory"
|
"--mem Use dictionary from flashmemory",
|
||||||
|
"-i Ignore static encrypted nonces"
|
||||||
],
|
],
|
||||||
"usage": "hf mf nested [-hab] [-k <hex>] [--mini] [--1k] [--2k] [--4k] [--blk <dec>] [--tblk <dec>] [--ta] [--tb] [--emu] [--dump] [--mem]"
|
"usage": "hf mf nested [-habi] [-k <hex>] [--mini] [--1k] [--2k] [--4k] [--blk <dec>] [-c <dec>] [--tblk <dec>] [--ta] [--tb] [--tc <dec>] [--emu] [--dump] [--mem]"
|
||||||
},
|
},
|
||||||
"hf mf personalize": {
|
"hf mf personalize": {
|
||||||
"command": "hf mf personalize",
|
"command": "hf mf personalize",
|
||||||
|
@ -5177,10 +5217,11 @@
|
||||||
"--blk <dec> block number",
|
"--blk <dec> block number",
|
||||||
"-a input key type is key A (def)",
|
"-a input key type is key A (def)",
|
||||||
"-b input key type is key B",
|
"-b input key type is key B",
|
||||||
|
"-c <dec> input key type is key A + offset",
|
||||||
"-k, --key <hex> key, 6 hex bytes",
|
"-k, --key <hex> key, 6 hex bytes",
|
||||||
"-v, --verbose verbose output"
|
"-v, --verbose verbose output"
|
||||||
],
|
],
|
||||||
"usage": "hf mf rdbl [-habv] --blk <dec> [-k <hex>]"
|
"usage": "hf mf rdbl [-habv] --blk <dec> [-c <dec>] [-k <hex>]"
|
||||||
},
|
},
|
||||||
"hf mf rdsc": {
|
"hf mf rdsc": {
|
||||||
"command": "hf mf rdsc",
|
"command": "hf mf rdsc",
|
||||||
|
@ -5194,11 +5235,12 @@
|
||||||
"-h, --help This help",
|
"-h, --help This help",
|
||||||
"-a input key specified is A key (def)",
|
"-a input key specified is A key (def)",
|
||||||
"-b input key specified is B key",
|
"-b input key specified is B key",
|
||||||
|
"-c <dec> input key type is key A + offset",
|
||||||
"-k, --key <hex> key specified as 6 hex bytes",
|
"-k, --key <hex> key specified as 6 hex bytes",
|
||||||
"-s, --sec <dec> sector number",
|
"-s, --sec <dec> sector number",
|
||||||
"-v, --verbose verbose output"
|
"-v, --verbose verbose output"
|
||||||
],
|
],
|
||||||
"usage": "hf mf rdsc [-habv] [-k <hex>] -s <dec>"
|
"usage": "hf mf rdsc [-habv] [-c <dec>] [-k <hex>] -s <dec>"
|
||||||
},
|
},
|
||||||
"hf mf restore": {
|
"hf mf restore": {
|
||||||
"command": "hf mf restore",
|
"command": "hf mf restore",
|
||||||
|
@ -5387,11 +5429,12 @@
|
||||||
"--blk <dec> block number",
|
"--blk <dec> block number",
|
||||||
"-a input key type is key A (def)",
|
"-a input key type is key A (def)",
|
||||||
"-b input key type is key B",
|
"-b input key type is key B",
|
||||||
|
"-c <dec> input key type is key A + offset",
|
||||||
"--force override warnings",
|
"--force override warnings",
|
||||||
"-k, --key <hex> key, 6 hex bytes",
|
"-k, --key <hex> key, 6 hex bytes",
|
||||||
"-d, --data <hex> bytes to write, 16 hex bytes"
|
"-d, --data <hex> bytes to write, 16 hex bytes"
|
||||||
],
|
],
|
||||||
"usage": "hf mf wrbl [-hab] --blk <dec> [--force] [-k <hex>] [-d <hex>]"
|
"usage": "hf mf wrbl [-hab] --blk <dec> [-c <dec>] [--force] [-k <hex>] [-d <hex>]"
|
||||||
},
|
},
|
||||||
"hf mfdes auth": {
|
"hf mfdes auth": {
|
||||||
"command": "hf mfdes auth",
|
"command": "hf mfdes auth",
|
||||||
|
@ -12765,8 +12808,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"commands_extracted": 739,
|
"commands_extracted": 740,
|
||||||
"extracted_by": "PM3Help2JSON v1.00",
|
"extracted_by": "PM3Help2JSON v1.00",
|
||||||
"extracted_on": "2024-07-21T14:16:40"
|
"extracted_on": "2024-08-03T19:17:38"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -508,6 +508,7 @@ Check column "offline" for their availability.
|
||||||
|`hf mf help `|Y |`This help`
|
|`hf mf help `|Y |`This help`
|
||||||
|`hf mf list `|Y |`List MIFARE history`
|
|`hf mf list `|Y |`List MIFARE history`
|
||||||
|`hf mf info `|N |`mfc card Info`
|
|`hf mf info `|N |`mfc card Info`
|
||||||
|
|`hf mf isen `|N |`mfc card Info Static Encrypted Nonces`
|
||||||
|`hf mf darkside `|N |`Darkside attack`
|
|`hf mf darkside `|N |`Darkside attack`
|
||||||
|`hf mf nested `|N |`Nested attack`
|
|`hf mf nested `|N |`Nested attack`
|
||||||
|`hf mf hardnested `|Y |`Nested attack for hardened MIFARE Classic cards`
|
|`hf mf hardnested `|Y |`Nested attack for hardened MIFARE Classic cards`
|
||||||
|
|
|
@ -272,7 +272,7 @@ static uint64_t **unpredictable_nested(NtpKs1List *pNKL, uint32_t keyCounts[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_unlock(&status_mutex);
|
pthread_mutex_unlock(&status_mutex);
|
||||||
printf("\33[2K\rProgress: %02.1f%%", (double)(startPos+1)*100 /pNKL->NtDataList[0].sizeNK);
|
printf("\33[2K\rProgress: %02.1f%%", (double)(startPos + 1) * 100 / pNKL->NtDataList[0].sizeNK);
|
||||||
printf(" keys[%d]:%9i", 0, keyCounts[0]);
|
printf(" keys[%d]:%9i", 0, keyCounts[0]);
|
||||||
for (uint32_t nonce_index = 1; nonce_index < pNKL->nr_nonces; nonce_index++) {
|
for (uint32_t nonce_index = 1; nonce_index < pNKL->nr_nonces; nonce_index++) {
|
||||||
printf(" keys[%d]:%5i", nonce_index, keyCounts[nonce_index]);
|
printf(" keys[%d]:%5i", nonce_index, keyCounts[nonce_index]);
|
||||||
|
@ -309,14 +309,14 @@ static uint64_t **unpredictable_nested(NtpKs1List *pNKL, uint32_t keyCounts[]) {
|
||||||
// Function to compare keys and keep track of their occurrences
|
// Function to compare keys and keep track of their occurrences
|
||||||
static void analyze_keys(uint64_t **keys, uint32_t keyCounts[MAX_NR_NONCES], uint32_t nr_nonces) {
|
static void analyze_keys(uint64_t **keys, uint32_t keyCounts[MAX_NR_NONCES], uint32_t nr_nonces) {
|
||||||
// Assuming the maximum possible keys
|
// Assuming the maximum possible keys
|
||||||
#define MAX_KEYS (MAX_NR_NONCES * KEY_SPACE_SIZE_STEP2)
|
#define MAX_KEYS (MAX_NR_NONCES * KEY_SPACE_SIZE_STEP2)
|
||||||
uint64_t combined_keys[MAX_KEYS] = {0};
|
uint64_t combined_keys[MAX_KEYS] = {0};
|
||||||
uint32_t combined_counts[MAX_KEYS] = {0};
|
uint32_t combined_counts[MAX_KEYS] = {0};
|
||||||
uint32_t combined_length = 0;
|
uint32_t combined_length = 0;
|
||||||
|
|
||||||
printf("Analyzing keys...\n");
|
printf("Analyzing keys...\n");
|
||||||
for (uint32_t i = 0; i < nr_nonces; i++) {
|
for (uint32_t i = 0; i < nr_nonces; i++) {
|
||||||
if (i==0) {
|
if (i == 0) {
|
||||||
printf("nT(%i): %i key candidates\n", i, keyCounts[i]);
|
printf("nT(%i): %i key candidates\n", i, keyCounts[i]);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
|
@ -344,7 +344,7 @@ static void analyze_keys(uint64_t **keys, uint32_t keyCounts[MAX_NR_NONCES], uin
|
||||||
|
|
||||||
for (uint32_t i = 0; i < combined_length; i++) {
|
for (uint32_t i = 0; i < combined_length; i++) {
|
||||||
if (combined_counts[i] > 1) {
|
if (combined_counts[i] > 1) {
|
||||||
printf("Key %012" PRIx64 " found in %d arrays: 0", combined_keys[i], combined_counts[i]+1);
|
printf("Key %012" PRIx64 " found in %d arrays: 0", combined_keys[i], combined_counts[i] + 1);
|
||||||
for (uint32_t ii = 1; ii < nr_nonces; ii++) {
|
for (uint32_t ii = 1; ii < nr_nonces; ii++) {
|
||||||
for (uint32_t j = 0; j < keyCounts[ii]; j++) {
|
for (uint32_t j = 0; j < keyCounts[ii]; j++) {
|
||||||
if (combined_keys[i] == keys[ii][j]) {
|
if (combined_keys[i] == keys[ii][j]) {
|
||||||
|
@ -418,9 +418,9 @@ int main(int argc, char *const argv[]) {
|
||||||
nttest = prng_successor(nttest, 1);
|
nttest = prng_successor(nttest, 1);
|
||||||
}
|
}
|
||||||
printf("uid=%08x nt_enc=%08x nt_par_err=%i%i%i%i nt_par_enc=%i%i%i%i %i/%i: %d\n", authuid, nt_enc,
|
printf("uid=%08x nt_enc=%08x nt_par_err=%i%i%i%i nt_par_enc=%i%i%i%i %i/%i: %d\n", authuid, nt_enc,
|
||||||
nt_par_err_arr[0], nt_par_err_arr[1], nt_par_err_arr[2], nt_par_err_arr[3],
|
nt_par_err_arr[0], nt_par_err_arr[1], nt_par_err_arr[2], nt_par_err_arr[3],
|
||||||
(nt_par_enc >> 3)&1, (nt_par_enc >> 2)&1, (nt_par_enc >> 1)&1, nt_par_enc&1,
|
(nt_par_enc >> 3) & 1, (nt_par_enc >> 2) & 1, (nt_par_enc >> 1) & 1, nt_par_enc & 1,
|
||||||
NKL.nr_nonces + 1, (argc - 1) / 3, j);
|
NKL.nr_nonces + 1, (argc - 1) / 3, j);
|
||||||
|
|
||||||
pNtData->authuid = authuid;
|
pNtData->authuid = authuid;
|
||||||
pNtData->sizeNK = j;
|
pNtData->sizeNK = j;
|
||||||
|
@ -437,7 +437,7 @@ int main(int argc, char *const argv[]) {
|
||||||
free(NKL.NtDataList[k].pNK);
|
free(NKL.NtDataList[k].pNK);
|
||||||
|
|
||||||
analyze_keys(keys, keyCounts, NKL.nr_nonces);
|
analyze_keys(keys, keyCounts, NKL.nr_nonces);
|
||||||
FILE* fptr;
|
FILE *fptr;
|
||||||
// opening the file in read mode
|
// opening the file in read mode
|
||||||
fptr = fopen("keys.dic", "w");
|
fptr = fopen("keys.dic", "w");
|
||||||
if (fptr != NULL) {
|
if (fptr != NULL) {
|
||||||
|
|
|
@ -129,20 +129,20 @@ int main(int argc, char *const argv[]) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
uint8_t nt_par_enc = ((nt_par_err_arr[0] ^ oddparity8((nt_enc >> 24) & 0xFF)) << 3) |
|
uint8_t nt_par_enc = ((nt_par_err_arr[0] ^ oddparity8((nt_enc >> 24) & 0xFF)) << 3) |
|
||||||
((nt_par_err_arr[1] ^ oddparity8((nt_enc >> 16) & 0xFF)) << 2) |
|
((nt_par_err_arr[1] ^ oddparity8((nt_enc >> 16) & 0xFF)) << 2) |
|
||||||
((nt_par_err_arr[2] ^ oddparity8((nt_enc >> 8) & 0xFF)) << 1) |
|
((nt_par_err_arr[2] ^ oddparity8((nt_enc >> 8) & 0xFF)) << 1) |
|
||||||
((nt_par_err_arr[3] ^ oddparity8((nt_enc >> 0) & 0xFF)) << 0);
|
((nt_par_err_arr[3] ^ oddparity8((nt_enc >> 0) & 0xFF)) << 0);
|
||||||
printf("uid=%08x nt=%08x nt_enc=%08x nt_par_err=%i%i%i%i nt_par_enc=%i%i%i%i ks1=%08x\n", authuid, nt, nt_enc,
|
printf("uid=%08x nt=%08x nt_enc=%08x nt_par_err=%i%i%i%i nt_par_enc=%i%i%i%i ks1=%08x\n", authuid, nt, nt_enc,
|
||||||
nt_par_err_arr[0], nt_par_err_arr[1], nt_par_err_arr[2], nt_par_err_arr[3],
|
nt_par_err_arr[0], nt_par_err_arr[1], nt_par_err_arr[2], nt_par_err_arr[3],
|
||||||
(nt_par_enc >> 3)&1, (nt_par_enc >> 2)&1, (nt_par_enc >> 1)&1, nt_par_enc&1,
|
(nt_par_enc >> 3) & 1, (nt_par_enc >> 2) & 1, (nt_par_enc >> 1) & 1, nt_par_enc & 1,
|
||||||
nt ^ nt_enc);
|
nt ^ nt_enc);
|
||||||
|
|
||||||
|
|
||||||
printf("Finding key candidates...\n");
|
printf("Finding key candidates...\n");
|
||||||
keys = generate_keys(authuid, nt, nt_enc, nt_par_enc, &keyCount);
|
keys = generate_keys(authuid, nt, nt_enc, nt_par_enc, &keyCount);
|
||||||
printf("Finding phase complete, found %i keys\n", keyCount);
|
printf("Finding phase complete, found %i keys\n", keyCount);
|
||||||
|
|
||||||
FILE* fptr;
|
FILE *fptr;
|
||||||
char filename[30];
|
char filename[30];
|
||||||
snprintf(filename, sizeof(filename), "keys_%08x_%02i_%08x.dic", authuid, sector, nt);
|
snprintf(filename, sizeof(filename), "keys_%08x_%02i_%08x.dic", authuid, sector, nt);
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ uint16_t s_lfsr16[1 << 16] = {0};
|
||||||
|
|
||||||
static void init_lfsr16_table(void) {
|
static void init_lfsr16_table(void) {
|
||||||
uint16_t x = 1;
|
uint16_t x = 1;
|
||||||
for (uint16_t i=1; i; ++i) {
|
for (uint16_t i = 1; i; ++i) {
|
||||||
i_lfsr16[(x & 0xff) << 8 | x >> 8] = i;
|
i_lfsr16[(x & 0xff) << 8 | x >> 8] = i;
|
||||||
s_lfsr16[i] = (x & 0xff) << 8 | x >> 8;
|
s_lfsr16[i] = (x & 0xff) << 8 | x >> 8;
|
||||||
x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
|
x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
|
||||||
|
@ -35,7 +35,7 @@ static void init_lfsr16_table(void) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
static uint16_t prev_lfsr16(uint16_t nonce) {
|
static uint16_t prev_lfsr16(uint16_t nonce) {
|
||||||
return s_lfsr16[(i_lfsr16[nonce]-1) % 65535];
|
return s_lfsr16[(i_lfsr16[nonce] - 1) % 65535];
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t compute_seednt16_nt32(uint32_t nt32, uint64_t key) {
|
static uint16_t compute_seednt16_nt32(uint32_t nt32, uint64_t key) {
|
||||||
|
@ -43,13 +43,13 @@ static uint16_t compute_seednt16_nt32(uint32_t nt32, uint64_t key) {
|
||||||
uint8_t b[] = {0, 13, 1, 14, 4, 10, 15, 7, 5, 3, 8, 6, 9, 2, 12, 11};
|
uint8_t b[] = {0, 13, 1, 14, 4, 10, 15, 7, 5, 3, 8, 6, 9, 2, 12, 11};
|
||||||
uint16_t nt = nt32 >> 16;
|
uint16_t nt = nt32 >> 16;
|
||||||
uint8_t prev = 14;
|
uint8_t prev = 14;
|
||||||
for (uint8_t i=0; i<prev; i++) {
|
for (uint8_t i = 0; i < prev; i++) {
|
||||||
nt = prev_lfsr16(nt);
|
nt = prev_lfsr16(nt);
|
||||||
}
|
}
|
||||||
uint8_t prevoff = 8;
|
uint8_t prevoff = 8;
|
||||||
bool odd = 1;
|
bool odd = 1;
|
||||||
|
|
||||||
for (uint8_t i=0; i<6*8; i+=8) {
|
for (uint8_t i = 0; i < 6 * 8; i += 8) {
|
||||||
if (odd) {
|
if (odd) {
|
||||||
nt ^= (a[(key >> i) & 0xF]);
|
nt ^= (a[(key >> i) & 0xF]);
|
||||||
nt ^= (b[(key >> i >> 4) & 0xF]) << 4;
|
nt ^= (b[(key >> i >> 4) & 0xF]) << 4;
|
||||||
|
@ -59,7 +59,7 @@ static uint16_t compute_seednt16_nt32(uint32_t nt32, uint64_t key) {
|
||||||
}
|
}
|
||||||
odd ^= 1;
|
odd ^= 1;
|
||||||
prev += prevoff;
|
prev += prevoff;
|
||||||
for (uint8_t j=0; j<prevoff; j++) {
|
for (uint8_t j = 0; j < prevoff; j++) {
|
||||||
nt = prev_lfsr16(nt);
|
nt = prev_lfsr16(nt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ int main(int argc, char *const argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t uid1, sector1, nt1, uid2, sector2, nt2;
|
uint32_t uid1, sector1, nt1, uid2, sector2, nt2;
|
||||||
char *filename1 = argv[1], *filename2= argv[2];
|
char *filename1 = argv[1], *filename2 = argv[2];
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
result = sscanf(filename1, "keys_%8x_%2d_%8x.dic", &uid1, §or1, &nt1);
|
result = sscanf(filename1, "keys_%8x_%2d_%8x.dic", &uid1, §or1, &nt1);
|
||||||
|
@ -105,13 +105,13 @@ int main(int argc, char *const argv[]) {
|
||||||
init_lfsr16_table();
|
init_lfsr16_table();
|
||||||
|
|
||||||
uint32_t keycount1 = 0;
|
uint32_t keycount1 = 0;
|
||||||
uint64_t* keys1 = NULL;
|
uint64_t *keys1 = NULL;
|
||||||
uint8_t* filter_keys1 = NULL;
|
uint8_t *filter_keys1 = NULL;
|
||||||
uint16_t* seednt1 = NULL;
|
uint16_t *seednt1 = NULL;
|
||||||
uint32_t keycount2 = 0;
|
uint32_t keycount2 = 0;
|
||||||
uint64_t* keys2 = NULL;
|
uint64_t *keys2 = NULL;
|
||||||
uint8_t* filter_keys2 = NULL;
|
uint8_t *filter_keys2 = NULL;
|
||||||
FILE* fptr;
|
FILE *fptr;
|
||||||
|
|
||||||
fptr = fopen(filename1, "r");
|
fptr = fopen(filename1, "r");
|
||||||
if (fptr != NULL) {
|
if (fptr != NULL) {
|
||||||
|
@ -120,9 +120,9 @@ int main(int argc, char *const argv[]) {
|
||||||
keycount1++;
|
keycount1++;
|
||||||
}
|
}
|
||||||
|
|
||||||
keys1 = (uint64_t*)malloc(keycount1 * sizeof(uint64_t));
|
keys1 = (uint64_t *)malloc(keycount1 * sizeof(uint64_t));
|
||||||
filter_keys1 = (uint8_t*)calloc(keycount1, sizeof(uint8_t));
|
filter_keys1 = (uint8_t *)calloc(keycount1, sizeof(uint8_t));
|
||||||
if ((keys1 == NULL)||(filter_keys1 == NULL)) {
|
if ((keys1 == NULL) || (filter_keys1 == NULL)) {
|
||||||
perror("Failed to allocate memory");
|
perror("Failed to allocate memory");
|
||||||
fclose(fptr);
|
fclose(fptr);
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -149,9 +149,9 @@ int main(int argc, char *const argv[]) {
|
||||||
keycount2++;
|
keycount2++;
|
||||||
}
|
}
|
||||||
|
|
||||||
keys2 = (uint64_t*)malloc(keycount2 * sizeof(uint64_t));
|
keys2 = (uint64_t *)malloc(keycount2 * sizeof(uint64_t));
|
||||||
filter_keys2 = (uint8_t*)calloc(keycount2, sizeof(uint8_t));
|
filter_keys2 = (uint8_t *)calloc(keycount2, sizeof(uint8_t));
|
||||||
if ((keys2 == NULL)||(filter_keys2 == NULL)) {
|
if ((keys2 == NULL) || (filter_keys2 == NULL)) {
|
||||||
perror("Failed to allocate memory");
|
perror("Failed to allocate memory");
|
||||||
fclose(fptr);
|
fclose(fptr);
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -174,7 +174,7 @@ int main(int argc, char *const argv[]) {
|
||||||
printf("%s: %i keys loaded\n", filename1, keycount1);
|
printf("%s: %i keys loaded\n", filename1, keycount1);
|
||||||
printf("%s: %i keys loaded\n", filename2, keycount2);
|
printf("%s: %i keys loaded\n", filename2, keycount2);
|
||||||
|
|
||||||
seednt1 = (uint16_t*)malloc(keycount1 * sizeof(uint16_t));
|
seednt1 = (uint16_t *)malloc(keycount1 * sizeof(uint16_t));
|
||||||
if (seednt1 == NULL) {
|
if (seednt1 == NULL) {
|
||||||
perror("Failed to allocate memory");
|
perror("Failed to allocate memory");
|
||||||
goto end;
|
goto end;
|
||||||
|
|
|
@ -25,7 +25,7 @@ uint16_t s_lfsr16[1 << 16] = {0};
|
||||||
|
|
||||||
static void init_lfsr16_table(void) {
|
static void init_lfsr16_table(void) {
|
||||||
uint16_t x = 1;
|
uint16_t x = 1;
|
||||||
for (uint16_t i=1; i; ++i) {
|
for (uint16_t i = 1; i; ++i) {
|
||||||
i_lfsr16[(x & 0xff) << 8 | x >> 8] = i;
|
i_lfsr16[(x & 0xff) << 8 | x >> 8] = i;
|
||||||
s_lfsr16[i] = (x & 0xff) << 8 | x >> 8;
|
s_lfsr16[i] = (x & 0xff) << 8 | x >> 8;
|
||||||
x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
|
x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
|
||||||
|
@ -37,7 +37,7 @@ static void init_lfsr16_table(void) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
static uint16_t prev_lfsr16(uint16_t nonce) {
|
static uint16_t prev_lfsr16(uint16_t nonce) {
|
||||||
return s_lfsr16[(i_lfsr16[nonce]-1) % 65535];
|
return s_lfsr16[(i_lfsr16[nonce] - 1) % 65535];
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t compute_seednt16_nt32(uint32_t nt32, uint64_t key) {
|
static uint16_t compute_seednt16_nt32(uint32_t nt32, uint64_t key) {
|
||||||
|
@ -45,13 +45,13 @@ static uint16_t compute_seednt16_nt32(uint32_t nt32, uint64_t key) {
|
||||||
uint8_t b[] = {0, 13, 1, 14, 4, 10, 15, 7, 5, 3, 8, 6, 9, 2, 12, 11};
|
uint8_t b[] = {0, 13, 1, 14, 4, 10, 15, 7, 5, 3, 8, 6, 9, 2, 12, 11};
|
||||||
uint16_t nt = nt32 >> 16;
|
uint16_t nt = nt32 >> 16;
|
||||||
uint8_t prev = 14;
|
uint8_t prev = 14;
|
||||||
for (uint8_t i=0; i<prev; i++) {
|
for (uint8_t i = 0; i < prev; i++) {
|
||||||
nt = prev_lfsr16(nt);
|
nt = prev_lfsr16(nt);
|
||||||
}
|
}
|
||||||
uint8_t prevoff = 8;
|
uint8_t prevoff = 8;
|
||||||
bool odd = 1;
|
bool odd = 1;
|
||||||
|
|
||||||
for (uint8_t i=0; i<6*8; i+=8) {
|
for (uint8_t i = 0; i < 6 * 8; i += 8) {
|
||||||
if (odd) {
|
if (odd) {
|
||||||
nt ^= (a[(key >> i) & 0xF]);
|
nt ^= (a[(key >> i) & 0xF]);
|
||||||
nt ^= (b[(key >> i >> 4) & 0xF]) << 4;
|
nt ^= (b[(key >> i >> 4) & 0xF]) << 4;
|
||||||
|
@ -61,7 +61,7 @@ static uint16_t compute_seednt16_nt32(uint32_t nt32, uint64_t key) {
|
||||||
}
|
}
|
||||||
odd ^= 1;
|
odd ^= 1;
|
||||||
prev += prevoff;
|
prev += prevoff;
|
||||||
for (uint8_t j=0; j<prevoff; j++) {
|
for (uint8_t j = 0; j < prevoff; j++) {
|
||||||
nt = prev_lfsr16(nt);
|
nt = prev_lfsr16(nt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ int main(int argc, char *const argv[]) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *filename= argv[3];
|
char *filename = argv[3];
|
||||||
uint32_t uid, sector, nt2;
|
uint32_t uid, sector, nt2;
|
||||||
|
|
||||||
int result;
|
int result;
|
||||||
|
@ -99,16 +99,16 @@ int main(int argc, char *const argv[]) {
|
||||||
init_lfsr16_table();
|
init_lfsr16_table();
|
||||||
|
|
||||||
uint32_t keycount2 = 0;
|
uint32_t keycount2 = 0;
|
||||||
uint64_t* keys2 = NULL;
|
uint64_t *keys2 = NULL;
|
||||||
|
|
||||||
FILE* fptr = fopen(filename, "r");
|
FILE *fptr = fopen(filename, "r");
|
||||||
if (fptr != NULL) {
|
if (fptr != NULL) {
|
||||||
uint64_t buffer;
|
uint64_t buffer;
|
||||||
while (fscanf(fptr, "%012" PRIx64, &buffer) == 1) {
|
while (fscanf(fptr, "%012" PRIx64, &buffer) == 1) {
|
||||||
keycount2++;
|
keycount2++;
|
||||||
}
|
}
|
||||||
|
|
||||||
keys2 = (uint64_t*)malloc(keycount2 * sizeof(uint64_t));
|
keys2 = (uint64_t *)malloc(keycount2 * sizeof(uint64_t));
|
||||||
if (keys2 == NULL) {
|
if (keys2 == NULL) {
|
||||||
perror("Failed to allocate memory");
|
perror("Failed to allocate memory");
|
||||||
fclose(fptr);
|
fclose(fptr);
|
||||||
|
|
Loading…
Reference in a new issue