From ee8b9ca74b10536db246286179183e0f1d89770e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 3 Aug 2024 21:21:11 +0200 Subject: [PATCH] make style --- armsrc/Standalone/hf_mattyrun.c | 64 +++++++++------- armsrc/Standalone/hf_mattyrun.h | 10 +-- armsrc/mifareutil.c | 62 ++++++++-------- client/src/cmdhficlass.c | 26 +++---- client/src/cmdhfmf.c | 2 +- client/src/mifare/mifarehost.c | 74 +++++++++---------- client/src/pm3line_vocabulary.h | 1 + common/crapto1/crapto1.c | 2 +- doc/commands.json | 65 +++++++++++++--- doc/commands.md | 1 + tools/mfc/card_only/staticnested_0nt.c | 20 ++--- tools/mfc/card_only/staticnested_1nt.c | 16 ++-- .../mfc/card_only/staticnested_2x1nt_rf08s.c | 38 +++++----- .../card_only/staticnested_2x1nt_rf08s_1key.c | 18 ++--- 14 files changed, 229 insertions(+), 170 deletions(-) diff --git a/armsrc/Standalone/hf_mattyrun.c b/armsrc/Standalone/hf_mattyrun.c index dc2de06e2..70563d3c8 100644 --- a/armsrc/Standalone/hf_mattyrun.c +++ b/armsrc/Standalone/hf_mattyrun.c @@ -38,19 +38,19 @@ #include "ticks.h" #include "util.h" -/* +/* * `hf_mattyrun` tries to dump MIFARE Classic cards into emulator memory and emulates them. - * + * * This standalone mode uses a predefined dictionary to authenticate to MIFARE Classic * cards (cf. `hf mf chk`) and to dump the card into emulator memory (cf. `hf mf ecfill`). * Once a card has been dumped, the card is emulated (cf. `hf mf sim`). Emulation will * start even if only a partial dump could be retrieved from the card (e.g. due to missing * keys). - * + * * This standalone mode is specifically designed for devices without flash. However, * users can pass data to/from the standalone mode through emulator memory (assuming * continuous (battery) power supply): - * + * * - Keys can be added to the dictionary by loading them into the emulator before * starting the standalone mode. You can use `hf mf eload -f dump_file` to load * any existing card dump. All keys from the key slots in the sector trailers @@ -58,14 +58,14 @@ * trailers available for a 4K card to store your user dictionary. Sector and key * type are ignored during chk; all user keys will be tested for all sectors and * for both key types. - * + * * - Once a card has been cloned into emulator memory, you can extract the dump by * ending the standalone mode and retrieving the emulator memory (`hf mf eview` * or `hf mf esave [--mini|--1k|--2k|--4k] -f dump_file`). - * + * * This standalone mode will log status information via USB. In addition, the LEDs * display status information: - * + * * - Waiting for card: LED C is on, LED D blinks. * - Tying to authenticate: LED C and D are on; LED D will blink on errors. * - Nested attack (NOT IMPLEMENTED!): LED B is on. @@ -73,14 +73,14 @@ * - Starting emulation: LED A, B, and C are on. LED D is on if only a partial * dump is available. * - Emulation started: All LEDS are off. - * + * * You can use the user button to interact with the standalone mode. During * emulation, (short) pressing the button ends emulation and returns to card * discovery. Long pressing the button ends the standalone mode. - * + * * Developers can configure the behavior of the standalone mode through the below * constants: - * + * * - MATTYRUN_PRINT_KEYS: Activate display of actually used key dictionary on startup. * - MATTYRUN_NO_ECFILL: Do not load and emulate card (only discovered keys are stored). * - MATTYRUN_MFC_DEFAULT_KEYS: Compiled-in default dictionary defined in a separate @@ -88,7 +88,7 @@ * dictionaries here. * - MATTYRUN_MFC_ESSENTIAL_KEYS: Compiled-in dictionary of keys that should be tested * before any user dictionary. - * + * * This is a major rewrite of the original `hf_mattyrun` by Matías A. Ré Medina. * The original version is described [here](http://bit.ly/2c9nZXR) (in Spanish). */ @@ -136,7 +136,7 @@ static bool saMifareDiscover(void) { // Customized MifareChkKeys that operates on the already detected card in // mattyrun_card and tests authentication with our dictionary 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; @@ -179,10 +179,17 @@ static int saMifareChkKeys(uint8_t const blockNo, uint8_t const keyType, bool co } else { if (cascade_levels == 0) { switch (mattyrun_card.uidlen) { - case 4: cascade_levels = 1; break; - case 7: cascade_levels = 2; break; - case 10: cascade_levels = 3; break; - default: break; + case 4: + cascade_levels = 1; + 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, @@ -239,10 +246,10 @@ void RunMod(void) { // usb_disable(); // Allocate dictionary buffer - uint64_t * const mfcKeys = (uint64_t *)BigBuf_malloc( - sizeof(uint64_t) * (ARRAYLEN(MATTYRUN_MFC_ESSENTIAL_KEYS) + - ARRAYLEN(MATTYRUN_MFC_DEFAULT_KEYS) + - MIFARE_4K_MAXSECTOR * 2)); + uint64_t *const mfcKeys = (uint64_t *)BigBuf_malloc( + sizeof(uint64_t) * (ARRAYLEN(MATTYRUN_MFC_ESSENTIAL_KEYS) + + ARRAYLEN(MATTYRUN_MFC_DEFAULT_KEYS) + + MIFARE_4K_MAXSECTOR * 2)); uint16_t mfcKeyCount = 0; // Load essential keys to dictionary buffer @@ -542,7 +549,7 @@ void RunMod(void) { LED_D_OFF(); DbpString("[=] Started emulation. Press button to abort at anytime."); - + if (partialEmulation) { LED_D_ON(); DbpString("[=] Partial memory dump loaded. Trying best effort emulation approach."); @@ -550,10 +557,17 @@ void RunMod(void) { uint16_t simflags = 0; switch (mattyrun_card.uidlen) { - case 4: simflags |= FLAG_4B_UID_IN_DATA; break; - case 7: simflags |= FLAG_7B_UID_IN_DATA; break; - case 10: simflags |= FLAG_10B_UID_IN_DATA; break; - default: break; + case 4: + simflags |= FLAG_4B_UID_IN_DATA; + 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); diff --git a/armsrc/Standalone/hf_mattyrun.h b/armsrc/Standalone/hf_mattyrun.h index 528d410b8..605ea447b 100644 --- a/armsrc/Standalone/hf_mattyrun.h +++ b/armsrc/Standalone/hf_mattyrun.h @@ -59,11 +59,11 @@ static uint64_t const MATTYRUN_MFC_DEFAULT_KEYS[] = { 0x0123456789AB, 0x123456789ABC, - // You could add more keys from, e.g, mfc_default_keys.dic here. - // However, be aware that more keys means longer brute-force times - // and too many keys will resuolt in running out of memory. - // See https://github.com/RfidResearchGroup/proxmark3/pull/2377#issuecomment-2112658439 - // for a rough benchmark. + // You could add more keys from, e.g, mfc_default_keys.dic here. + // However, be aware that more keys means longer brute-force times + // and too many keys will resuolt in running out of memory. + // See https://github.com/RfidResearchGroup/proxmark3/pull/2377#issuecomment-2112658439 + // for a rough benchmark. }; #endif /* HF_MATTYRUN_H__ */ diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 601f4fc69..c95d9a316 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -184,32 +184,32 @@ int mifare_classic_authex_cmd(struct Crypto1State *pcs, uint32_t uid, uint8_t bl if (g_dbglevel >= DBG_EXTENDED) { if (!isNested) { Dbprintf("auth cmd: %02x %02x | uid: %08x | nr: %08x %s| nt: %08x %s %5i| par: %i%i%i%i %s", - cmd, blockNo, uid, - nr32, validate_prng_nonce(nr32) ? "@" : " ", - nt, validate_prng_nonce(nt) ? "@idx" : " idx", - validate_prng_nonce(nt) ? nonce16_index(nt >> 16) : -1, - (receivedAnswerPar[0] >> 7) & 1, - (receivedAnswerPar[0] >> 6) & 1, - (receivedAnswerPar[0] >> 5) & 1, - (receivedAnswerPar[0] >> 4) & 1, - validate_parity_nonce(nt, receivedAnswerPar[0], nt) ? "ok " : "bad"); + cmd, blockNo, uid, + nr32, validate_prng_nonce(nr32) ? "@" : " ", + nt, validate_prng_nonce(nt) ? "@idx" : " idx", + validate_prng_nonce(nt) ? nonce16_index(nt >> 16) : -1, + (receivedAnswerPar[0] >> 7) & 1, + (receivedAnswerPar[0] >> 6) & 1, + (receivedAnswerPar[0] >> 5) & 1, + (receivedAnswerPar[0] >> 4) & 1, + validate_parity_nonce(nt, receivedAnswerPar[0], nt) ? "ok " : "bad"); } 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", - cmd, blockNo, uid, - nr32, validate_prng_nonce(nr32) ? "@" : " ", - nt, validate_prng_nonce(nt) ? "@idx" : " idx", - validate_prng_nonce(nt) ? nonce16_index(nt >> 16) : -1, - (receivedAnswerPar[0] >> 7) & 1, - (receivedAnswerPar[0] >> 6) & 1, - (receivedAnswerPar[0] >> 5) & 1, - (receivedAnswerPar[0] >> 4) & 1, - validate_parity_nonce(*ntencptr, receivedAnswerPar[0], nt) ? "ok " : "bad", - *ntencptr, validate_prng_nonce(*ntencptr) ? "@" : " ", - ((receivedAnswerPar[0] >> 7) & 1) ^ oddparity8((*ntencptr >> 24) & 0xFF), - ((receivedAnswerPar[0] >> 6) & 1) ^ oddparity8((*ntencptr >> 16) & 0xFF), - ((receivedAnswerPar[0] >> 5) & 1) ^ oddparity8((*ntencptr >> 8) & 0xFF), - ((receivedAnswerPar[0] >> 4) & 1) ^ oddparity8((*ntencptr >> 0) & 0xFF) - ); + cmd, blockNo, uid, + nr32, validate_prng_nonce(nr32) ? "@" : " ", + nt, validate_prng_nonce(nt) ? "@idx" : " idx", + validate_prng_nonce(nt) ? nonce16_index(nt >> 16) : -1, + (receivedAnswerPar[0] >> 7) & 1, + (receivedAnswerPar[0] >> 6) & 1, + (receivedAnswerPar[0] >> 5) & 1, + (receivedAnswerPar[0] >> 4) & 1, + validate_parity_nonce(*ntencptr, receivedAnswerPar[0], nt) ? "ok " : "bad", + *ntencptr, validate_prng_nonce(*ntencptr) ? "@" : " ", + ((receivedAnswerPar[0] >> 7) & 1) ^ oddparity8((*ntencptr >> 24) & 0xFF), + ((receivedAnswerPar[0] >> 6) & 1) ^ oddparity8((*ntencptr >> 16) & 0xFF), + ((receivedAnswerPar[0] >> 5) & 1) ^ oddparity8((*ntencptr >> 8) & 0xFF), + ((receivedAnswerPar[0] >> 4) & 1) ^ oddparity8((*ntencptr >> 0) & 0xFF) + ); } } // 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) { uint16_t x = nonce >> 16; 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 & 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) { uint32_t ks = nt ^ ntenc; 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; - return (((ntpar >> 3) & 1) == oddparity8((nt>>24) & 0xFF)) && - (((ntpar >> 2) & 1) == oddparity8((nt>>16) & 0xFF)) && - (((ntpar >> 1) & 1) == oddparity8((nt>>8) & 0xFF)); + return (((ntpar >> 3) & 1) == oddparity8((nt >> 24) & 0xFF)) && + (((ntpar >> 2) & 1) == oddparity8((nt >> 16) & 0xFF)) && + (((ntpar >> 1) & 1) == oddparity8((nt >> 8) & 0xFF)); } 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; y = (y & 0xff) << 8 | y >> 8; uint16_t i = 1; - for(;i;i++) { + for (; i; i++) { x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15; - if (x==y) + if (x == y) return i; } // never reached diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index fb31da17a..11b3712b4 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -1449,7 +1449,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { arg_lit0("v", "verbose", "verbose output"), arg_lit0(NULL, "d6", "decode as block 6"), arg_lit0("z", "dense", "dense dump output style"), - arg_lit0(NULL, "ns", "no save to file"), + arg_lit0(NULL, "ns", "no save to file"), arg_param_end }; CLIExecWithReturn(clictx, Cmd, argtable, false); @@ -1619,18 +1619,18 @@ static int CmdHFiClassDecrypt(const char *Cmd) { PrintAndLogEx(NORMAL, ""); } else { - // use the first block (CSN) for filename - char *fptr = calloc(50, sizeof(uint8_t)); - if (fptr == false) { - PrintAndLogEx(WARNING, "Failed to allocate memory"); - free(decrypted); - return PM3_EMALLOC; - } + // use the first block (CSN) for filename + char *fptr = calloc(50, sizeof(uint8_t)); + if (fptr == false) { + PrintAndLogEx(WARNING, "Failed to allocate memory"); + free(decrypted); + return PM3_EMALLOC; + } - strcat(fptr, "hf-iclass-"); - FillFileNameByUID(fptr, hdr->csn, "-dump-decrypted", sizeof(hdr->csn)); + strcat(fptr, "hf-iclass-"); + 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); } @@ -1645,8 +1645,8 @@ static int CmdHFiClassDecrypt(const char *Cmd) { // decode block 6 bool has_values = (memcmp(decrypted + (8 * 6), empty, 8) != 0) && (memcmp(decrypted + (8 * 6), zeros, 8) != 0); if (has_values && use_sc) { - DecodeBlock6(decrypted + (8 * 6)); - } + DecodeBlock6(decrypted + (8 * 6)); + } // decode block 7-8-9 iclass_decode_credentials(decrypted); diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 9e6df4bcb..40f4d7708 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -3375,7 +3375,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) { uint16_t singleSectorParams = 0; if (blockn != -1) { - singleSectorParams = (blockn & 0xFF)| keytype << 8 | 1 << 15; + singleSectorParams = (blockn & 0xFF) | keytype << 8 | 1 << 15; } if (use_flashmemory) { PrintAndLogEx(SUCCESS, "Using dictionary in flash memory"); diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index c2e009278..6f02846d1 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -264,7 +264,7 @@ int mfCheckKeys_fast_ex(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChun if (curr_keys) { uint64_t foo = bytes_to_num(resp.data.asBytes, 6); 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; } } @@ -605,16 +605,16 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, if (package->keytype < 2) { PrintAndLogEx(SUCCESS, "\nTarget block %4u key type %c -- found valid key [ " _GREEN_("%s") " ]", - package->block, - package->keytype ? 'B' : 'A', - sprint_hex_inrow(resultKey, 6) - ); + package->block, + package->keytype ? 'B' : 'A', + sprint_hex_inrow(resultKey, 6) + ); } else { PrintAndLogEx(SUCCESS, "\nTarget block %4u key type %02x -- found valid key [ " _GREEN_("%s") " ]", - package->block, - MIFARE_AUTH_KEYA + package->keytype, - sprint_hex_inrow(resultKey, 6) - ); + package->block, + MIFARE_AUTH_KEYA + package->keytype, + sprint_hex_inrow(resultKey, 6) + ); } @@ -628,14 +628,14 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, out: if (package->keytype < 2) { PrintAndLogEx(SUCCESS, "\nTarget block %4u key type %c", - package->block, - package->keytype ? 'B' : 'A' - ); + package->block, + package->keytype ? 'B' : 'A' + ); } else { PrintAndLogEx(SUCCESS, "\nTarget block %4u key type %02x", - package->block, - MIFARE_AUTH_KEYA + package->keytype - ); + package->block, + MIFARE_AUTH_KEYA + package->keytype + ); } free(statelists[0].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)) { uint32_t uid = resp.data.asBytes[1] << 24 | - resp.data.asBytes[2] << 16 | - resp.data.asBytes[3] << 8 | - resp.data.asBytes[4]; + resp.data.asBytes[2] << 16 | + resp.data.asBytes[3] << 8 | + resp.data.asBytes[4]; uint32_t nt = resp.data.asBytes[5] << 24 | - resp.data.asBytes[6] << 16 | - resp.data.asBytes[7] << 8 | - resp.data.asBytes[8]; + resp.data.asBytes[6] << 16 | + resp.data.asBytes[7] << 8 | + resp.data.asBytes[8]; uint32_t ntenc = resp.data.asBytes[9] << 24 | - resp.data.asBytes[10] << 16 | - resp.data.asBytes[11] << 8 | - resp.data.asBytes[12]; + resp.data.asBytes[10] << 16 | + resp.data.asBytes[11] << 8 | + resp.data.asBytes[12]; uint8_t ntencparenc = resp.data.asBytes[13]; // 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; // [...] 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 - 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; 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"), - ntenc, - (ntencparenc >> 3) & 1, (ntencparenc >> 2) & 1, (ntencparenc >> 1) & 1, ntencparenc & 1, - (ntencpar >> 3) & 1, (ntencpar >> 2) & 1, (ntencpar >> 1) & 1, - ks, nt, - oddparity8((nt>>24) & 0xFF), oddparity8((nt>>16) & 0xFF), oddparity8((nt>>8) & 0xFF), oddparity8(nt & 0xFF), - nonce_distance(0, nt)); + ntenc, + (ntencparenc >> 3) & 1, (ntencparenc >> 2) & 1, (ntencparenc >> 1) & 1, ntencparenc & 1, + (ntencpar >> 3) & 1, (ntencpar >> 2) & 1, (ntencpar >> 1) & 1, + ks, nt, + oddparity8((nt >> 24) & 0xFF), oddparity8((nt >> 16) & 0xFF), oddparity8((nt >> 8) & 0xFF), oddparity8(nt & 0xFF), + nonce_distance(0, nt)); } 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)", - ntenc, - (ntencparenc >> 3) & 1, (ntencparenc >> 2) & 1, (ntencparenc >> 1) & 1, ntencparenc & 1, - (ntencpar >> 3) & 1, (ntencpar >> 2) & 1, (ntencpar >> 1) & 1, - ks, nt, - oddparity8((nt>>24) & 0xFF), oddparity8((nt>>16) & 0xFF), oddparity8((nt>>8) & 0xFF), oddparity8(nt & 0xFF) - ); + ntenc, + (ntencparenc >> 3) & 1, (ntencparenc >> 2) & 1, (ntencparenc >> 1) & 1, ntencparenc & 1, + (ntencpar >> 3) & 1, (ntencpar >> 2) & 1, (ntencpar >> 1) & 1, + ks, nt, + oddparity8((nt >> 24) & 0xFF), oddparity8((nt >> 16) & 0xFF), oddparity8((nt >> 8) & 0xFF), oddparity8(nt & 0xFF) + ); } } return resp.data.asBytes[0]; diff --git a/client/src/pm3line_vocabulary.h b/client/src/pm3line_vocabulary.h index 36cf4f8ff..10e72a4de 100644 --- a/client/src/pm3line_vocabulary.h +++ b/client/src/pm3line_vocabulary.h @@ -337,6 +337,7 @@ const static vocabulary_t vocabulary[] = { { 1, "hf mf help" }, { 1, "hf mf list" }, { 0, "hf mf info" }, + { 0, "hf mf isen" }, { 0, "hf mf darkside" }, { 0, "hf mf nested" }, { 1, "hf mf hardnested" }, diff --git a/common/crapto1/crapto1.c b/common/crapto1/crapto1.c index 4a2e9e791..0847f20c3 100644 --- a/common/crapto1/crapto1.c +++ b/common/crapto1/crapto1.c @@ -432,7 +432,7 @@ int nonce_distance(uint32_t from, uint32_t to) { bool validate_prng_nonce(uint32_t nonce) { uint16_t x = nonce >> 16; 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 & 0xff) << 8 | x >> 8; diff --git a/doc/commands.json b/doc/commands.json index fabb918ec..65501d183 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -3234,9 +3234,10 @@ "-k, --key 3DES transport key", "-v, --verbose verbose output", "--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 ] [-d ] [-k ] [--d6]" + "usage": "hf iclass decrypt [-hvz] [-f ] [-d ] [-k ] [--d6] [--ns]" }, "hf iclass dump": { "command": "hf iclass dump", @@ -4699,9 +4700,12 @@ "--emu Fill simulator keys from found keys", "--dump Dump found keys to binary file", "--mem Use dictionary from flashmemory", - "-f, --file filename of dictionary" + "-f, --file filename of dictionary", + "--blk block number (single block recovery mode)", + "-a single block recovery key A", + "-b single block recovery key B" ], - "usage": "hf mf fchk [-h] [-k ]... [--mini] [--1k] [--2k] [--4k] [--emu] [--dump] [--mem] [-f ]" + "usage": "hf mf fchk [-hab] [-k ]... [--mini] [--1k] [--2k] [--4k] [--emu] [--dump] [--mem] [-f ] [--blk ]" }, "hf mf gchpwd": { "command": "hf mf gchpwd", @@ -5015,6 +5019,39 @@ ], "usage": "hf mf info [-habnv] [--blk ] [-k ]" }, + "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 block number", + "-a input key type is key A (def)", + "-b input key type is key B", + "-c input key type is key A + offset", + "-k, --key key, 6 hex bytes", + "--blk2 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 nested input key type is key A + offset", + "--key2 nested key, 6 hex bytes (default=same)", + "-n 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 ] [-c ] [-k ] [--blk2 ] [--a2] [--b2] [--c2 ] [--key2 ] [-n ] [--reset] [--addread] [--addauth] [--incblk2] [--corruptnrar] [--corruptnrarparity]" + }, "hf mf mad": { "command": "hf mf mad", "description": "Checks and prints MIFARE Application Directory (MAD)", @@ -5131,14 +5168,17 @@ "--blk Input block number", "-a Input key specified is A key (default)", "-b Input key specified is B key", + "-c input key type is key A + offset", "--tblk Target block number", "--ta Target A key (default)", "--tb Target B key", + "--tc Nested input key type is key A + offset (you must specify a single block as well!)", "--emu Fill simulator keys from found keys", "--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 ] [--mini] [--1k] [--2k] [--4k] [--blk ] [--tblk ] [--ta] [--tb] [--emu] [--dump] [--mem]" + "usage": "hf mf nested [-habi] [-k ] [--mini] [--1k] [--2k] [--4k] [--blk ] [-c ] [--tblk ] [--ta] [--tb] [--tc ] [--emu] [--dump] [--mem]" }, "hf mf personalize": { "command": "hf mf personalize", @@ -5177,10 +5217,11 @@ "--blk block number", "-a input key type is key A (def)", "-b input key type is key B", + "-c input key type is key A + offset", "-k, --key key, 6 hex bytes", "-v, --verbose verbose output" ], - "usage": "hf mf rdbl [-habv] --blk [-k ]" + "usage": "hf mf rdbl [-habv] --blk [-c ] [-k ]" }, "hf mf rdsc": { "command": "hf mf rdsc", @@ -5194,11 +5235,12 @@ "-h, --help This help", "-a input key specified is A key (def)", "-b input key specified is B key", + "-c input key type is key A + offset", "-k, --key key specified as 6 hex bytes", "-s, --sec sector number", "-v, --verbose verbose output" ], - "usage": "hf mf rdsc [-habv] [-k ] -s " + "usage": "hf mf rdsc [-habv] [-c ] [-k ] -s " }, "hf mf restore": { "command": "hf mf restore", @@ -5387,11 +5429,12 @@ "--blk block number", "-a input key type is key A (def)", "-b input key type is key B", + "-c input key type is key A + offset", "--force override warnings", "-k, --key key, 6 hex bytes", "-d, --data bytes to write, 16 hex bytes" ], - "usage": "hf mf wrbl [-hab] --blk [--force] [-k ] [-d ]" + "usage": "hf mf wrbl [-hab] --blk [-c ] [--force] [-k ] [-d ]" }, "hf mfdes auth": { "command": "hf mfdes auth", @@ -12765,8 +12808,8 @@ } }, "metadata": { - "commands_extracted": 739, + "commands_extracted": 740, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2024-07-21T14:16:40" + "extracted_on": "2024-08-03T19:17:38" } } diff --git a/doc/commands.md b/doc/commands.md index ed0e84766..5c08fed0a 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -508,6 +508,7 @@ Check column "offline" for their availability. |`hf mf help `|Y |`This help` |`hf mf list `|Y |`List MIFARE history` |`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 nested `|N |`Nested attack` |`hf mf hardnested `|Y |`Nested attack for hardened MIFARE Classic cards` diff --git a/tools/mfc/card_only/staticnested_0nt.c b/tools/mfc/card_only/staticnested_0nt.c index e0f312693..abe5e59d0 100644 --- a/tools/mfc/card_only/staticnested_0nt.c +++ b/tools/mfc/card_only/staticnested_0nt.c @@ -270,9 +270,9 @@ static uint64_t **unpredictable_nested(NtpKs1List *pNKL, uint32_t keyCounts[]) { if (thread_status[i]) activeThreads++; } } - + 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]); for (uint32_t nonce_index = 1; nonce_index < pNKL->nr_nonces; 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 static void analyze_keys(uint64_t **keys, uint32_t keyCounts[MAX_NR_NONCES], uint32_t nr_nonces) { // 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}; uint32_t combined_counts[MAX_KEYS] = {0}; uint32_t combined_length = 0; printf("Analyzing keys...\n"); 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]); continue; } 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++) { 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 j = 0; j < keyCounts[ii]; j++) { if (combined_keys[i] == keys[ii][j]) { @@ -382,7 +382,7 @@ int main(int argc, char *const argv[]) { NtpKs1List NKL = {0}; uint64_t **keys = NULL; uint32_t keyCounts[MAX_NR_NONCES] = {0}; - + uint32_t authuid = hex_to_uint32(argv[1]); // process all args. printf("Generating nonce candidates...\n"); @@ -418,9 +418,9 @@ int main(int argc, char *const argv[]) { 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, - 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, - NKL.nr_nonces + 1, (argc - 1) / 3, j); + 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, + NKL.nr_nonces + 1, (argc - 1) / 3, j); pNtData->authuid = authuid; pNtData->sizeNK = j; @@ -437,7 +437,7 @@ int main(int argc, char *const argv[]) { free(NKL.NtDataList[k].pNK); analyze_keys(keys, keyCounts, NKL.nr_nonces); - FILE* fptr; + FILE *fptr; // opening the file in read mode fptr = fopen("keys.dic", "w"); if (fptr != NULL) { diff --git a/tools/mfc/card_only/staticnested_1nt.c b/tools/mfc/card_only/staticnested_1nt.c index fcd03434a..e4da1c113 100644 --- a/tools/mfc/card_only/staticnested_1nt.c +++ b/tools/mfc/card_only/staticnested_1nt.c @@ -119,7 +119,7 @@ int main(int argc, char *const argv[]) { } uint64_t *keys = NULL; uint32_t keyCount = 0; - + uint32_t authuid = hex_to_uint32(argv[1]); uint32_t sector = hex_to_uint32(argv[2]); uint32_t nt = hex_to_uint32(argv[3]); @@ -129,20 +129,20 @@ int main(int argc, char *const argv[]) { return 1; } 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[2] ^ oddparity8((nt_enc >> 8) & 0xFF)) << 1) | - ((nt_par_err_arr[3] ^ oddparity8((nt_enc >> 0) & 0xFF)) << 0); + ((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[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, - 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 ^ nt_enc); + 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 ^ nt_enc); printf("Finding key candidates...\n"); keys = generate_keys(authuid, nt, nt_enc, nt_par_enc, &keyCount); printf("Finding phase complete, found %i keys\n", keyCount); - FILE* fptr; + FILE *fptr; char filename[30]; snprintf(filename, sizeof(filename), "keys_%08x_%02i_%08x.dic", authuid, sector, nt); diff --git a/tools/mfc/card_only/staticnested_2x1nt_rf08s.c b/tools/mfc/card_only/staticnested_2x1nt_rf08s.c index a4351b75c..c6308a68b 100644 --- a/tools/mfc/card_only/staticnested_2x1nt_rf08s.c +++ b/tools/mfc/card_only/staticnested_2x1nt_rf08s.c @@ -23,7 +23,7 @@ uint16_t s_lfsr16[1 << 16] = {0}; static void init_lfsr16_table(void) { 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; s_lfsr16[i] = (x & 0xff) << 8 | x >> 8; 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) { - 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) { @@ -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}; uint16_t nt = nt32 >> 16; uint8_t prev = 14; - for (uint8_t i=0; i> i) & 0xF]); 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; prev += prevoff; - for (uint8_t j=0; j> 8] = i; s_lfsr16[i] = (x & 0xff) << 8 | x >> 8; 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) { - 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) { @@ -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}; uint16_t nt = nt32 >> 16; uint8_t prev = 14; - for (uint8_t i=0; i> i) & 0xF]); 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; prev += prevoff; - for (uint8_t j=0; j