make style

This commit is contained in:
Philippe Teuwen 2024-08-03 21:21:11 +02:00
parent 44d7c54be7
commit ee8b9ca74b
14 changed files with 229 additions and 170 deletions

View file

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

View file

@ -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__ */

View file

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

View file

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

View file

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

View file

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

View file

@ -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" },

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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, &sector1, &nt1); result = sscanf(filename1, "keys_%8x_%2d_%8x.dic", &uid1, &sector1, &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;

View file

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