From 03d6da87e2ef2ea644f3540c5d433a51f1227d96 Mon Sep 17 00:00:00 2001 From: Tomas Nilsson Date: Sun, 8 Mar 2026 18:35:11 +0100 Subject: [PATCH] Simplify hf mfp dump: remove key probing, load-and-read only Restructure hf mfp dump to match hf mf dump pattern: load keys from files, read sectors, save. Remove all key probing/checking logic (use hf mfp chk and hf mf chk separately for key discovery). Use MF_KEY_A/MF_KEY_B defines instead of magic numbers. Replace custom JSON parser with existing loadFileJSON infrastructure. --- client/src/cmdhfmfp.c | 390 +++++++----------------------------------- 1 file changed, 59 insertions(+), 331 deletions(-) diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index b393af092..a6b182fd1 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -38,8 +38,6 @@ #include "mifare/mifarehost.h" // mf_read_sector (SL1 CRYPTO1) #include "cmdtrace.h" #include "crypto/originality.h" -#include "jansson.h" -#include "preferences.h" // getDeviceDebugLevel, setDeviceDebugLevel static const uint8_t mfp_default_key[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; static uint16_t mfp_card_adresses[] = {0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 0x9006, 0x9007, 0xA000, 0xA001, 0xA080, 0xA081, 0xC000, 0xC001}; @@ -1905,41 +1903,37 @@ static int CmdHFMFPChk(const char *Cmd) { static int mfp_load_keys_from_json(const char *filename, uint8_t foundKeys[2][64][AES_KEY_LEN + 1]) { - json_t *root = NULL; - int res = loadFileJSONroot(filename, (void **)&root, true); + // loadFileJSON handles "mfpkeys" file type via loadFileJSONex. + // Buffer layout: UID(7) + pad(3) + SAK(1) + ATQA(2) + ATSlen(1) + ATS(atslen) + // then flat keys: KeyA0(16) KeyB0(16) KeyA1(16) KeyB1(16) ... + uint8_t data[14 + 256 + (2 * 64 * AES_KEY_LEN)]; + memset(data, 0, sizeof(data)); + size_t datalen = 0; + + int res = loadFileJSON(filename, data, sizeof(data), &datalen, NULL); if (res != PM3_SUCCESS) { return res; } - // check file type - json_t *jtype = json_object_get(root, "FileType"); - if (!jtype || !json_is_string(jtype) || strcmp(json_string_value(jtype), "mfpkeys") != 0) { - PrintAndLogEx(ERR, "Key file is not a MIFARE Plus key file"); - json_decref(root); - return PM3_EFILE; - } - - char path[64]; - uint8_t tmpkey[AES_KEY_LEN]; - size_t tmplen = 0; + uint8_t atslen = data[13]; + size_t key_offset = 14 + atslen; for (int i = 0; i < 64; i++) { - snprintf(path, sizeof(path), "$.SectorKeys.%d.KeyA", i); - tmplen = 0; - if (JsonLoadBufAsHex(root, path, tmpkey, AES_KEY_LEN, &tmplen) == 0 && tmplen == AES_KEY_LEN) { - foundKeys[0][i][0] = 1; - memcpy(&foundKeys[0][i][1], tmpkey, AES_KEY_LEN); - } + size_t off = key_offset + (i * 2 * AES_KEY_LEN); + uint8_t *ka = data + off; + uint8_t *kb = data + off + AES_KEY_LEN; - snprintf(path, sizeof(path), "$.SectorKeys.%d.KeyB", i); - tmplen = 0; - if (JsonLoadBufAsHex(root, path, tmpkey, AES_KEY_LEN, &tmplen) == 0 && tmplen == AES_KEY_LEN) { - foundKeys[1][i][0] = 1; - memcpy(&foundKeys[1][i][1], tmpkey, AES_KEY_LEN); + // check if key is non-zero (present in JSON) + if (memcmp(ka, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", AES_KEY_LEN) != 0) { + foundKeys[MF_KEY_A][i][0] = 1; + memcpy(&foundKeys[MF_KEY_A][i][1], ka, AES_KEY_LEN); + } + if (memcmp(kb, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", AES_KEY_LEN) != 0) { + foundKeys[MF_KEY_B][i][0] = 1; + memcpy(&foundKeys[MF_KEY_B][i][1], kb, AES_KEY_LEN); } } - json_decref(root); return PM3_SUCCESS; } @@ -1961,13 +1955,13 @@ static int mfp_load_mfc_keys_from_bin(const char *filename, uint8_t mfcFoundKeys } for (uint8_t s = 0; s < numSectors && s * MIFARE_KEY_SIZE < alen; s++) { - mfcFoundKeys[0][s][0] = 1; - memcpy(&mfcFoundKeys[0][s][1], keyA + s * MIFARE_KEY_SIZE, MIFARE_KEY_SIZE); + mfcFoundKeys[MF_KEY_A][s][0] = 1; + memcpy(&mfcFoundKeys[MF_KEY_A][s][1], keyA + s * MIFARE_KEY_SIZE, MIFARE_KEY_SIZE); } for (uint8_t s = 0; s < numSectors && s * MIFARE_KEY_SIZE < blen; s++) { - mfcFoundKeys[1][s][0] = 1; - memcpy(&mfcFoundKeys[1][s][1], keyB + s * MIFARE_KEY_SIZE, MIFARE_KEY_SIZE); + mfcFoundKeys[MF_KEY_B][s][0] = 1; + memcpy(&mfcFoundKeys[MF_KEY_B][s][1], keyB + s * MIFARE_KEY_SIZE, MIFARE_KEY_SIZE); } free(keyA); @@ -1984,92 +1978,25 @@ static int mfp_read_sector_sl1(uint8_t sectorNo, uint8_t keyType, const uint8_t return res; } -// Build a list of default MFC 6-byte keys for SL1 probing -static int mfp_load_mfc_default_keys(uint8_t **pkeyBlock, uint32_t *pkeycnt) { - size_t numDefaults = ARRAYLEN(g_mifare_default_keys); - *pkeyBlock = calloc(numDefaults, MIFARE_KEY_SIZE); - if (*pkeyBlock == NULL) { - return PM3_EMALLOC; - } - - for (size_t i = 0; i < numDefaults; i++) { - num_to_bytes(g_mifare_default_keys[i], MIFARE_KEY_SIZE, *pkeyBlock + i * MIFARE_KEY_SIZE); - } - *pkeycnt = numDefaults; - return PM3_SUCCESS; -} - -// Try to find an MFC (CRYPTO1) key for a sector by attempting to read it. -// Uses mf_read_sector which has a proper timeout, unlike mf_check_keys -// which can hang in firmware if the card doesn't respond to ISO 14443-3. -// Returns true if a working key was found. -// Try MFC (CRYPTO1) keys on a sector using mf_read_sector. -// Returns true if a working key was found (stored in mfcFoundKeys). -// Bails out early if the card doesn't respond to ISO 14443-3 select -// (PM3_ETIMEOUT), which means the sector is SL3-only. -static bool mfp_sl1_try_keys(uint8_t sectorNo, uint8_t *keys, uint32_t keycnt, - uint8_t mfcFoundKeys[2][64][MIFARE_KEY_SIZE + 1], bool verbose) { - - uint8_t dummy[16 * 16] = {0}; - - for (uint8_t kt = 0; kt < 2; kt++) { - if (mfcFoundKeys[kt][sectorNo][0]) { - continue; - } - - for (uint32_t i = 0; i < keycnt; i++) { - uint8_t *trykey = keys + i * MIFARE_KEY_SIZE; - int res = mf_read_sector(sectorNo, kt, trykey, dummy); - if (res == PM3_SUCCESS) { - mfcFoundKeys[kt][sectorNo][0] = 1; - memcpy(&mfcFoundKeys[kt][sectorNo][1], trykey, MIFARE_KEY_SIZE); - if (verbose) { - PrintAndLogEx(INFO, "SL1 key found: sector %u key%s [ " _GREEN_("%s") " ]", - sectorNo, (kt == 0) ? "A" : "B", - sprint_hex_inrow(trykey, MIFARE_KEY_SIZE)); - } else { - PrintAndLogEx(NORMAL, "+" NOLF); - } - return true; - } - // Timeout means card doesn't respond to ISO 14443-3 select at all. - // This sector is SL3-only; no point trying more CRYPTO1 keys. - if (res == PM3_ETIMEOUT) { - if (verbose) { - PrintAndLogEx(DEBUG, "Sector %u not responding to ISO 14443-3, skipping MFC probe", sectorNo); - } - return false; - } - } - } - return false; -} - static int CmdHFMFPDump(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfp dump", "Dump MIFARE Plus tag to file (bin/json)\n" - "Supports both SL3 (AES) and SL1 (CRYPTO1) sectors.\n" - "Automatically detects sector security level.\n" + "Reads sectors using keys from `hf mfp chk --dump` (AES/SL3)\n" + "and/or `hf mf chk` key file (CRYPTO1/SL1) for mixed-mode cards.\n" "If no given, UID will be used as filename", - "hf mfp dump\n" "hf mfp dump --keys hf-mfp-01020304-key.json\n" - "hf mfp dump -k ffffffffffffffffffffffffffffffff\n" - "hf mfp dump --dict mfp_default_keys\n" "hf mfp dump --keys hf-mfp-01020304-key.json --mfc-keys hf-mf-01020304-key.bin\n" - "hf mfp dump --keys hf-mfp-01020304-key.json --mfc-dict mfc_default_keys\n"); + "hf mfp dump -k ffffffffffffffffffffffffffffffff\n"); void *argtable[] = { arg_param_begin, arg_str0("f", "file", "", "Specify a filename for dump file"), arg_str0(NULL, "keys", "", "AES key file from `hf mfp chk --dump` (JSON)"), arg_str0("k", "key", "", "AES key for all sectors (16 hex bytes)"), - arg_str0(NULL, "dict", "", "AES dictionary file"), arg_str0(NULL, "mfc-keys", "", "MFC key file for SL1 sectors (.bin from `hf mf chk`)"), - arg_str0(NULL, "mfc-dict", "", "MFC dictionary file for SL1 sectors"), arg_lit0(NULL, "ns", "No save to file"), arg_lit0("v", "verbose", "Verbose output"), - arg_lit0(NULL, "no-default", "Skip default key probing for unknown sectors"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -2086,21 +2013,12 @@ static int CmdHFMFPDump(const char *Cmd) { uint8_t userkey[AES_KEY_LEN] = {0}; CLIGetHexWithReturn(ctx, 3, userkey, &userkeylen); - int dictfnlen = 0; - char dict_fn[FILE_PATH_SIZE] = {0}; - CLIParamStrToBuf(arg_get_str(ctx, 4), (uint8_t *)dict_fn, FILE_PATH_SIZE, &dictfnlen); - int mfckeyfnlen = 0; char mfc_key_fn[FILE_PATH_SIZE] = {0}; - CLIParamStrToBuf(arg_get_str(ctx, 5), (uint8_t *)mfc_key_fn, FILE_PATH_SIZE, &mfckeyfnlen); + CLIParamStrToBuf(arg_get_str(ctx, 4), (uint8_t *)mfc_key_fn, FILE_PATH_SIZE, &mfckeyfnlen); - int mfcdictfnlen = 0; - char mfc_dict_fn[FILE_PATH_SIZE] = {0}; - CLIParamStrToBuf(arg_get_str(ctx, 6), (uint8_t *)mfc_dict_fn, FILE_PATH_SIZE, &mfcdictfnlen); - - bool nosave = arg_get_lit(ctx, 7); - bool verbose = arg_get_lit(ctx, 8); - bool no_default = arg_get_lit(ctx, 9); + bool nosave = arg_get_lit(ctx, 5); + bool verbose = arg_get_lit(ctx, 6); CLIParserFree(ctx); @@ -2137,7 +2055,7 @@ static int CmdHFMFPDump(const char *Cmd) { PrintAndLogEx(NORMAL, ""); // ======================================== - // Phase 0: Key file loading (no card interaction yet) + // Load keys // ======================================== // AES keys: aesFoundKeys[keytype][sector][0]=found, [1..16]=key @@ -2148,7 +2066,7 @@ static int CmdHFMFPDump(const char *Cmd) { uint8_t mfcFoundKeys[2][64][MIFARE_KEY_SIZE + 1]; memset(mfcFoundKeys, 0, sizeof(mfcFoundKeys)); - // 0a. Load AES keys from JSON key file (from hf mfp chk --dump) + // Load AES keys from JSON key file (from hf mfp chk --dump) if (keyfnlen > 0) { res = mfp_load_keys_from_json(key_fn, aesFoundKeys); if (res != PM3_SUCCESS) { @@ -2156,18 +2074,18 @@ static int CmdHFMFPDump(const char *Cmd) { } else { int cnt = 0; for (uint8_t s = 0; s < numSectors; s++) { - if (aesFoundKeys[0][s][0]) cnt++; - if (aesFoundKeys[1][s][0]) cnt++; + if (aesFoundKeys[MF_KEY_A][s][0]) cnt++; + if (aesFoundKeys[MF_KEY_B][s][0]) cnt++; } PrintAndLogEx(SUCCESS, "Loaded " _GREEN_("%d") " AES keys from key file", cnt); } } - // 0b. Apply user-supplied AES key to all slots that don't have one yet + // Apply user-supplied AES key to all slots that don't have one yet if (userkeylen == AES_KEY_LEN) { int applied = 0; for (uint8_t s = 0; s < numSectors; s++) { - for (uint8_t kt = 0; kt < 2; kt++) { + for (uint8_t kt = MF_KEY_A; kt <= MF_KEY_B; kt++) { if (aesFoundKeys[kt][s][0] == 0) { aesFoundKeys[kt][s][0] = 1; memcpy(&aesFoundKeys[kt][s][1], userkey, AES_KEY_LEN); @@ -2178,7 +2096,7 @@ static int CmdHFMFPDump(const char *Cmd) { PrintAndLogEx(SUCCESS, "Applied user AES key to " _GREEN_("%d") " key slots", applied); } - // 0c. Load MFC keys from binary key file (from hf mf chk/autopwn) + // Load MFC keys from binary key file (from hf mf chk) if (mfckeyfnlen > 0) { res = mfp_load_mfc_keys_from_bin(mfc_key_fn, mfcFoundKeys, numSectors); if (res != PM3_SUCCESS) { @@ -2186,218 +2104,29 @@ static int CmdHFMFPDump(const char *Cmd) { } else { int cnt = 0; for (uint8_t s = 0; s < numSectors; s++) { - if (mfcFoundKeys[0][s][0]) cnt++; - if (mfcFoundKeys[1][s][0]) cnt++; + if (mfcFoundKeys[MF_KEY_A][s][0]) cnt++; + if (mfcFoundKeys[MF_KEY_B][s][0]) cnt++; } PrintAndLogEx(SUCCESS, "Loaded " _GREEN_("%d") " MFC (CRYPTO1) keys from key file", cnt); } } - // 0d. Build combined MFC probe key list (dictionary + defaults) - uint8_t *mfcProbeKeys = NULL; - uint32_t mfcProbeKeyCnt = 0; - - if (!no_default) { - uint8_t *dict_keys = NULL; - uint32_t dict_cnt = 0; - if (mfcdictfnlen > 0) { - loadFileDICTIONARY_safe(mfc_dict_fn, (void **)&dict_keys, MIFARE_KEY_SIZE, &dict_cnt); - } - - uint8_t *def_keys = NULL; - uint32_t def_cnt = 0; - mfp_load_mfc_default_keys(&def_keys, &def_cnt); - - uint32_t total = dict_cnt + def_cnt; - if (total > 0) { - mfcProbeKeys = calloc(total, MIFARE_KEY_SIZE); - if (mfcProbeKeys) { - if (dict_cnt > 0) { - memcpy(mfcProbeKeys, dict_keys, dict_cnt * MIFARE_KEY_SIZE); - } - if (def_cnt > 0) { - memcpy(mfcProbeKeys + dict_cnt * MIFARE_KEY_SIZE, def_keys, def_cnt * MIFARE_KEY_SIZE); - } - mfcProbeKeyCnt = total; - } - } - free(dict_keys); - free(def_keys); - } - // ======================================== - // Phase 1: Classify sectors as SL3 or SL1 + // Read sectors with loaded keys // ======================================== - // Try one MFC key (FFFFFFFFFFFF) on each sector to determine SL. - // mf_read_sector returns: - // PM3_SUCCESS -> SL1 confirmed, key found - // PM3_EUNDEF -> SL1 confirmed (card responded to ISO 14443-3 auth), wrong key - // PM3_ETIMEOUT -> SL3 (card doesn't respond to ISO 14443-3) - - // Suppress firmware debug messages during classification and key probing. - // The many auth attempts produce a flood of "Auth error" / "Can't select card" - // messages from the firmware that interfere with other tools reading stdout. - uint8_t dbg_curr = DBG_NONE; - if (getDeviceDebugLevel(&dbg_curr) != PM3_SUCCESS) { - free(mfcProbeKeys); - return PM3_EFAILED; - } - setDeviceDebugLevel(DBG_NONE, false); + // Determine SL for each sector based on which keys are available uint8_t sectorSL[64]; memset(sectorSL, MFP_SL_UNKNOWN, sizeof(sectorSL)); - - // Sectors with pre-loaded keys already have a known SL for (uint8_t s = 0; s < numSectors; s++) { - if (aesFoundKeys[0][s][0] || aesFoundKeys[1][s][0]) { + if (aesFoundKeys[MF_KEY_A][s][0] || aesFoundKeys[MF_KEY_B][s][0]) { sectorSL[s] = MFP_SL_3; } - if (mfcFoundKeys[0][s][0] || mfcFoundKeys[1][s][0]) { + if (mfcFoundKeys[MF_KEY_A][s][0] || mfcFoundKeys[MF_KEY_B][s][0]) { sectorSL[s] = MFP_SL_1; } } - // Probe unclassified sectors with FFFFFFFFFFFF (CRYPTO1) - { - uint8_t probe_key[MIFARE_KEY_SIZE]; - memset(probe_key, 0xFF, MIFARE_KEY_SIZE); - uint8_t dummy[16 * 16] = {0}; - PrintAndLogEx(INFO, "Classifying sector security levels..."); - - for (uint8_t s = 0; s < numSectors; s++) { - if (sectorSL[s] != MFP_SL_UNKNOWN) { - continue; - } - - DropField(); - res = mf_read_sector(s, 0, probe_key, dummy); - if (res == PM3_SUCCESS) { - // FFFFFFFFFFFF worked -> SL1 with default key - sectorSL[s] = MFP_SL_1; - mfcFoundKeys[0][s][0] = 1; - memcpy(&mfcFoundKeys[0][s][1], probe_key, MIFARE_KEY_SIZE); - } else if (res == PM3_EUNDEF) { - // Card responded to ISO 14443-3 but wrong key -> SL1 - sectorSL[s] = MFP_SL_1; - } else { - // Timeout or other error -> SL3 - sectorSL[s] = MFP_SL_3; - } - } - DropField(); - - int pre_sl3 = 0, pre_sl1 = 0; - for (uint8_t s = 0; s < numSectors; s++) { - if (sectorSL[s] == MFP_SL_3) pre_sl3++; - else if (sectorSL[s] == MFP_SL_1) pre_sl1++; - } - PrintAndLogEx(SUCCESS, "Sector classification: " _GREEN_("%d") " SL3, " _YELLOW_("%d") " SL1", - pre_sl3, pre_sl1); - } - - // ======================================== - // Phase 2: AES key probing (SL3 sectors only) - // ======================================== - // plus_key_check skips sectors where foundKeys[][sector][0] is set, - // so we mark SL1 sectors with a dummy key to exclude them. - { - // Save and temporarily mark SL1 sectors so plus_key_check skips them - uint8_t sl1_backup[2][64]; - memset(sl1_backup, 0, sizeof(sl1_backup)); - - for (uint8_t s = 0; s < numSectors; s++) { - if (sectorSL[s] == MFP_SL_1) { - for (uint8_t kt = 0; kt < 2; kt++) { - sl1_backup[kt][s] = aesFoundKeys[kt][s][0]; - if (aesFoundKeys[kt][s][0] == 0) { - // Mark as "found" with dummy so plus_key_check skips it - aesFoundKeys[kt][s][0] = 0xFF; - } - } - } - } - - bool need_aes_probe = false; - for (uint8_t s = 0; s < numSectors; s++) { - if (sectorSL[s] == MFP_SL_3 && - (aesFoundKeys[0][s][0] == 0 || aesFoundKeys[1][s][0] == 0)) { - need_aes_probe = true; - break; - } - } - - if (need_aes_probe && !no_default) { - uint8_t *key_block = NULL; - uint32_t keycnt = 0; - res = mfp_load_keys(&key_block, &keycnt, NULL, 0, dict_fn, dictfnlen, card.uid, true); - if (res == PM3_SUCCESS && keycnt > 0) { - int sl3_unknown = 0; - for (uint8_t s = 0; s < numSectors; s++) { - if (sectorSL[s] == MFP_SL_3 && - (aesFoundKeys[0][s][0] == 0 || aesFoundKeys[1][s][0] == 0)) { - sl3_unknown++; - } - } - PrintAndLogEx(INFO, "Probing " _YELLOW_("%u") " AES keys against %d SL3 sectors...", keycnt, sl3_unknown); - uint8_t end_sector = numSectors - 1; - res = plus_key_check(0, end_sector, 0, 1, key_block, keycnt, aesFoundKeys, verbose, true); - if (res == PM3_EOPABORTED) { - PrintAndLogEx(WARNING, "\nAborted"); - } - PrintAndLogEx(NORMAL, ""); - } - free(key_block); - } - - // Restore SL1 sector dummy markers - for (uint8_t s = 0; s < numSectors; s++) { - if (sectorSL[s] == MFP_SL_1) { - for (uint8_t kt = 0; kt < 2; kt++) { - if (aesFoundKeys[kt][s][0] == 0xFF) { - aesFoundKeys[kt][s][0] = sl1_backup[kt][s]; - } - } - } - } - } - - // ======================================== - // Phase 3: MFC key probing (SL1 sectors only) - // ======================================== - if (mfcProbeKeyCnt > 0 && mfcProbeKeys != NULL) { - int sl1_need_keys = 0; - for (uint8_t s = 0; s < numSectors; s++) { - if (sectorSL[s] == MFP_SL_1 && - (mfcFoundKeys[0][s][0] == 0 || mfcFoundKeys[1][s][0] == 0)) { - sl1_need_keys++; - } - } - - if (sl1_need_keys > 0) { - PrintAndLogEx(INFO, "Probing " _YELLOW_("%u") " MFC keys against %d SL1 sectors...", mfcProbeKeyCnt, sl1_need_keys); - for (uint8_t s = 0; s < numSectors; s++) { - if (kbd_enter_pressed()) { - PrintAndLogEx(WARNING, "\naborted via keyboard"); - break; - } - if (sectorSL[s] != MFP_SL_1) { - continue; - } - if (mfcFoundKeys[0][s][0] && mfcFoundKeys[1][s][0]) { - continue; - } - mfp_sl1_try_keys(s, mfcProbeKeys, mfcProbeKeyCnt, mfcFoundKeys, verbose); - } - PrintAndLogEx(NORMAL, ""); - } - } - - // Restore firmware debug level before reading - setDeviceDebugLevel(dbg_curr, false); - - // ======================================== - // Phase 4: Read sectors with found keys - // ======================================== uint16_t totalBlocks = 0; for (uint8_t s = 0; s < numSectors; s++) { totalBlocks += mfNumBlocksPerSector(s); @@ -2406,7 +2135,7 @@ static int CmdHFMFPDump(const char *Cmd) { uint8_t *carddata = calloc(totalBlocks * MFBLOCK_SIZE, sizeof(uint8_t)); if (carddata == NULL) { PrintAndLogEx(ERR, "Failed to allocate memory"); - free(mfcProbeKeys); + return PM3_EMALLOC; } @@ -2432,7 +2161,7 @@ static int CmdHFMFPDump(const char *Cmd) { if (sectorSL[s] == MFP_SL_3) { // --- Try SL3 (AES) --- - for (uint8_t kt = 0; kt < 2 && !readOK; kt++) { + for (uint8_t kt = MF_KEY_A; kt <= MF_KEY_B && !readOK; kt++) { if (aesFoundKeys[kt][s][0] == 0) { continue; } @@ -2446,13 +2175,13 @@ static int CmdHFMFPDump(const char *Cmd) { sectorsRead++; sl3Count++; } else if (verbose) { - PrintAndLogEx(DEBUG, "Sector %u SL3 key%s failed: %d", s, (kt == 0) ? "A" : "B", res); + PrintAndLogEx(DEBUG, "Sector %u SL3 key%s failed: %d", s, (kt == MF_KEY_A) ? "A" : "B", res); } } } else if (sectorSL[s] == MFP_SL_1) { // --- Try SL1 (CRYPTO1) --- DropField(); - for (uint8_t kt = 0; kt < 2 && !readOK; kt++) { + for (uint8_t kt = MF_KEY_A; kt <= MF_KEY_B && !readOK; kt++) { if (mfcFoundKeys[kt][s][0] == 0) { continue; } @@ -2466,7 +2195,7 @@ static int CmdHFMFPDump(const char *Cmd) { sectorsRead++; sl1Count++; } else if (verbose) { - PrintAndLogEx(DEBUG, "Sector %u SL1 key%s failed: %d", s, (kt == 0) ? "A" : "B", res); + PrintAndLogEx(DEBUG, "Sector %u SL1 key%s failed: %d", s, (kt == MF_KEY_A) ? "A" : "B", res); } } } @@ -2500,26 +2229,26 @@ static int CmdHFMFPDump(const char *Cmd) { switch (sectorSL[s]) { case MFP_SL_3: slStr = _GREEN_("3 "); - if (aesFoundKeys[0][s][0]) { - snprintf(strA, sizeof(strA), _GREEN_("%s"), sprint_hex_inrow(&aesFoundKeys[0][s][1], AES_KEY_LEN)); + if (aesFoundKeys[MF_KEY_A][s][0]) { + snprintf(strA, sizeof(strA), _GREEN_("%s"), sprint_hex_inrow(&aesFoundKeys[MF_KEY_A][s][1], AES_KEY_LEN)); } else { snprintf(strA, sizeof(strA), _RED_("%s"), "--------------------------------"); } - if (aesFoundKeys[1][s][0]) { - snprintf(strB, sizeof(strB), _GREEN_("%s"), sprint_hex_inrow(&aesFoundKeys[1][s][1], AES_KEY_LEN)); + if (aesFoundKeys[MF_KEY_B][s][0]) { + snprintf(strB, sizeof(strB), _GREEN_("%s"), sprint_hex_inrow(&aesFoundKeys[MF_KEY_B][s][1], AES_KEY_LEN)); } else { snprintf(strB, sizeof(strB), _RED_("%s"), "--------------------------------"); } break; case MFP_SL_1: slStr = _YELLOW_("1 "); - if (mfcFoundKeys[0][s][0]) { - snprintf(strA, sizeof(strA), _GREEN_("%s") " ", sprint_hex_inrow(&mfcFoundKeys[0][s][1], MIFARE_KEY_SIZE)); + if (mfcFoundKeys[MF_KEY_A][s][0]) { + snprintf(strA, sizeof(strA), _GREEN_("%s") " ", sprint_hex_inrow(&mfcFoundKeys[MF_KEY_A][s][1], MIFARE_KEY_SIZE)); } else { snprintf(strA, sizeof(strA), _RED_("%s"), "--------------------------------"); } - if (mfcFoundKeys[1][s][0]) { - snprintf(strB, sizeof(strB), _GREEN_("%s") " ", sprint_hex_inrow(&mfcFoundKeys[1][s][1], MIFARE_KEY_SIZE)); + if (mfcFoundKeys[MF_KEY_B][s][0]) { + snprintf(strB, sizeof(strB), _GREEN_("%s") " ", sprint_hex_inrow(&mfcFoundKeys[MF_KEY_B][s][1], MIFARE_KEY_SIZE)); } else { snprintf(strB, sizeof(strB), _RED_("%s"), "--------------------------------"); } @@ -2555,7 +2284,7 @@ static int CmdHFMFPDump(const char *Cmd) { if (nosave) { PrintAndLogEx(INFO, "Called with no-save option"); free(carddata); - free(mfcProbeKeys); + return PM3_SUCCESS; } @@ -2570,7 +2299,7 @@ static int CmdHFMFPDump(const char *Cmd) { if (fptr == NULL) { PrintAndLogEx(ERR, "Failed to allocate memory"); free(carddata); - free(mfcProbeKeys); + return PM3_EMALLOC; } strcpy(fptr, "hf-mfp-"); @@ -2587,7 +2316,6 @@ static int CmdHFMFPDump(const char *Cmd) { } free(carddata); - free(mfcProbeKeys); return PM3_SUCCESS; }