From c6cdaccc877682f1c13312aaaa02603999ae42c9 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Tue, 16 Dec 2025 17:40:28 +0300 Subject: [PATCH] Revert "upd pr 4316" This reverts commit 9d325c6d5c7c8f834691ca0b6aab27265b5cdb63. --- .../protocol_support/mf_classic/mf_classic.c | 9 +- .../protocol_support/mf_plus/mf_plus.c | 145 +----------------- lib/nfc/protocols/mf_classic/mf_classic.c | 3 +- .../mf_classic/mf_classic_listener.c | 9 -- 4 files changed, 9 insertions(+), 157 deletions(-) diff --git a/applications/main/nfc/helpers/protocol_support/mf_classic/mf_classic.c b/applications/main/nfc/helpers/protocol_support/mf_classic/mf_classic.c index 359599ae4..53218bb9f 100644 --- a/applications/main/nfc/helpers/protocol_support/mf_classic/mf_classic.c +++ b/applications/main/nfc/helpers/protocol_support/mf_classic/mf_classic.c @@ -204,14 +204,7 @@ static void nfc_scene_saved_menu_on_enter_mf_classic(NfcApp* instance) { } static void nfc_scene_emulate_on_enter_mf_classic(NfcApp* instance) { - // Use stored data; normalize ATQA/SAK in-place for 4-byte UID to avoid cascade-bit issues - MfClassicData* data = - (MfClassicData*)nfc_device_get_data(instance->nfc_device, NfcProtocolMfClassic); - if(data->iso14443_3a_data && data->iso14443_3a_data->uid_len == 4) { - data->iso14443_3a_data->atqa[0] = 0x04; - data->iso14443_3a_data->atqa[1] = 0x00; - data->iso14443_3a_data->sak = 0x08; // no cascade bit - } + const MfClassicData* data = nfc_device_get_data(instance->nfc_device, NfcProtocolMfClassic); instance->listener = nfc_listener_alloc(instance->nfc, NfcProtocolMfClassic, data); nfc_listener_start(instance->listener, NULL, NULL); } diff --git a/applications/main/nfc/helpers/protocol_support/mf_plus/mf_plus.c b/applications/main/nfc/helpers/protocol_support/mf_plus/mf_plus.c index b4d9fee13..2960886f7 100644 --- a/applications/main/nfc/helpers/protocol_support/mf_plus/mf_plus.c +++ b/applications/main/nfc/helpers/protocol_support/mf_plus/mf_plus.c @@ -2,13 +2,8 @@ #include "mf_plus_render.h" #include -#include - -#include -#include #include "nfc/nfc_app_i.h" -#include "../../mf_classic_key_cache.h" #include "../nfc_protocol_support_common.h" #include "../nfc_protocol_support_gui_common.h" @@ -87,143 +82,17 @@ static void nfc_scene_read_success_on_enter_mf_plus(NfcApp* instance) { } static void nfc_scene_emulate_on_enter_mf_plus(NfcApp* instance) { - const MfPlusData* mf_plus_data = nfc_device_get_data(instance->nfc_device, NfcProtocolMfPlus); + const Iso14443_4aData* iso14443_4a_data = + nfc_device_get_data(instance->nfc_device, NfcProtocolIso14443_4a); - // For SL1 2K cards, use Classic emulation (compatible with Classic readers) - // MIFARE Plus 2K SL1 emulates as Classic with 32 sectors (128 blocks total) - // This allows UID-only readers (like printers) to work, and exposes all 32 sectors - if(mf_plus_data->security_level == MfPlusSecurityLevel1 && - mf_plus_data->size == MfPlusSize2K) { - MfClassicData* classic_data = NULL; - - // Try to get Classic data if the card was read as Classic - // This ensures we emulate the actual data that was scanned (all sectors, keys, blocks) - const MfClassicData* existing_classic_data = NULL; - // Check if device protocol is Classic (card was read as Classic, not just Plus) - if(nfc_device_get_protocol(instance->nfc_device) == NfcProtocolMfClassic) { - existing_classic_data = - nfc_device_get_data(instance->nfc_device, NfcProtocolMfClassic); - } - - if(existing_classic_data && existing_classic_data->type == MfClassicTypePlus2k) { - // Use the actual Classic data that was read from the card - // This contains all the real sector data, keys, and blocks from the scan - classic_data = mf_classic_alloc(); - mf_classic_copy(classic_data, existing_classic_data); - - // Ensure sectors 18-31 are treated as uninitialized to match real card behavior - // On real MIFARE Plus 2K SL1 cards, sectors 18-31 are typically empty/uninitialized - // Clear key masks for sectors 18-31 if keys are zero (uninitialized) - for(uint8_t sector = 18; sector < 32; sector++) { - uint8_t sector_trailer_block = sector * 4 + 3; - MfClassicSectorTrailer* sec_tr = - (MfClassicSectorTrailer*)&classic_data->block[sector_trailer_block]; - - // Check if both keys are zero (uninitialized) - bool key_a_zero = true; - bool key_b_zero = true; - for(int i = 0; i < 6; i++) { - if(sec_tr->key_a.data[i] != 0) key_a_zero = false; - if(sec_tr->key_b.data[i] != 0) key_b_zero = false; - } - - // Check if keys were found in original read - bool key_a_found_orig = - mf_classic_is_key_found(existing_classic_data, sector, MfClassicKeyTypeA); - bool key_b_found_orig = - mf_classic_is_key_found(existing_classic_data, sector, MfClassicKeyTypeB); - - // Clear key masks if keys are zero (uninitialized) OR if they weren't found in original - // This ensures empty sectors appear as uninitialized, matching real card - // The listener will reject authentication attempts to sectors without keys found - if(key_a_zero || !key_a_found_orig) { - mf_classic_set_key_not_found(classic_data, sector, MfClassicKeyTypeA); - } - if(key_b_zero || !key_b_found_orig) { - mf_classic_set_key_not_found(classic_data, sector, MfClassicKeyTypeB); - } - } - } else { - // No Classic data available - create minimal Classic data from MF Plus - // This is a fallback when card was only read as Plus (without sector data) - classic_data = mf_classic_alloc(); - classic_data->type = MfClassicTypePlus2k; - - // Initialize key masks to zero (no keys found) - sectors are uninitialized - classic_data->key_a_mask = 0ULL; - classic_data->key_b_mask = 0ULL; - - // Copy ISO14443-3A data from MF Plus (UID, ATQA, SAK) - const Iso14443_3aData* iso3_data = - iso14443_4a_get_base_data(mf_plus_data->iso14443_4a_data); - if(iso3_data) { - iso14443_3a_copy(classic_data->iso14443_3a_data, iso3_data); - // Force SL1 Classic view: ATQA 0x0004, SAK 0x08 (no cascade bit) - classic_data->iso14443_3a_data->atqa[0] = 0x04; - classic_data->iso14443_3a_data->atqa[1] = 0x00; - classic_data->iso14443_3a_data->sak = 0x08; - // Ensure 4-byte UID form (the real card uses 4B UID) - if(classic_data->iso14443_3a_data->uid_len > 4) { - classic_data->iso14443_3a_data->uid_len = 4; - } - - // Try to load keys from key cache to speed up emulation - // This allows emulation to work faster if keys were previously cached - if(instance->mfc_key_cache) { - size_t uid_len = 0; - const uint8_t* uid = iso14443_3a_get_uid(iso3_data, &uid_len); - if(mf_classic_key_cache_load(instance->mfc_key_cache, uid, uid_len)) { - // Keys loaded from cache - copy them to classic_data - MfClassicDeviceKeys* cached_keys = &instance->mfc_key_cache->keys; - classic_data->key_a_mask = cached_keys->key_a_mask; - classic_data->key_b_mask = cached_keys->key_b_mask; - - // Copy cached keys to sector trailers - for(uint8_t sector = 0; sector < 32; sector++) { - if(FURI_BIT(cached_keys->key_a_mask, sector)) { - MfClassicSectorTrailer* sec_tr = - mf_classic_get_sector_trailer_by_sector(classic_data, sector); - sec_tr->key_a = cached_keys->key_a[sector]; - mf_classic_set_key_found( - classic_data, - sector, - MfClassicKeyTypeA, - bit_lib_bytes_to_num_be(cached_keys->key_a[sector].data, 6)); - } - if(FURI_BIT(cached_keys->key_b_mask, sector)) { - MfClassicSectorTrailer* sec_tr = - mf_classic_get_sector_trailer_by_sector(classic_data, sector); - sec_tr->key_b = cached_keys->key_b[sector]; - mf_classic_set_key_found( - classic_data, - sector, - MfClassicKeyTypeB, - bit_lib_bytes_to_num_be(cached_keys->key_b[sector].data, 6)); - } - } - } - } - } - // Note: Without Classic data, sectors without cached keys are uninitialized (no keys found) - // This matches real card behavior for empty sectors - } - - instance->listener = nfc_listener_alloc(instance->nfc, NfcProtocolMfClassic, classic_data); - nfc_listener_start(instance->listener, NULL, NULL); - } else { - // For SL2/SL3, use ISO14443-4A emulation - const Iso14443_4aData* iso14443_4a_data = - nfc_device_get_data(instance->nfc_device, NfcProtocolIso14443_4a); - - instance->listener = - nfc_listener_alloc(instance->nfc, NfcProtocolIso14443_4a, iso14443_4a_data); - nfc_listener_start( - instance->listener, nfc_scene_emulate_listener_callback_iso14443_4a, instance); - } + instance->listener = + nfc_listener_alloc(instance->nfc, NfcProtocolIso14443_4a, iso14443_4a_data); + nfc_listener_start( + instance->listener, nfc_scene_emulate_listener_callback_iso14443_4a, instance); } const NfcProtocolSupportBase nfc_protocol_support_mf_plus = { - .features = NfcProtocolFeatureEmulateFull | NfcProtocolFeatureMoreInfo, + .features = NfcProtocolFeatureEmulateUid | NfcProtocolFeatureMoreInfo, .scene_info = { diff --git a/lib/nfc/protocols/mf_classic/mf_classic.c b/lib/nfc/protocols/mf_classic/mf_classic.c index 453396411..e90444a2a 100644 --- a/lib/nfc/protocols/mf_classic/mf_classic.c +++ b/lib/nfc/protocols/mf_classic/mf_classic.c @@ -16,8 +16,7 @@ typedef struct { static const uint32_t mf_classic_data_format_version = 2; -// MIFARE Plus 2K SL1 has 32 sectors (128 blocks total) per official specification -#define MF_CLASSIC_PLUS2K_SCAN_SECTORS 32 +#define MF_CLASSIC_PLUS2K_SCAN_SECTORS 18 static const MfClassicFeatures mf_classic_features[MfClassicTypeNum] = { [MfClassicTypeMini] = diff --git a/lib/nfc/protocols/mf_classic/mf_classic_listener.c b/lib/nfc/protocols/mf_classic/mf_classic_listener.c index 72cf7ecbc..1f5eea271 100644 --- a/lib/nfc/protocols/mf_classic/mf_classic_listener.c +++ b/lib/nfc/protocols/mf_classic/mf_classic_listener.c @@ -65,15 +65,6 @@ static MfClassicListenerCommand mf_classic_listener_auth_first_part_handler( uint8_t sector_num = mf_classic_get_sector_by_block(block_num); - // Reject authentication immediately if keys are not found (uninitialized sector) - // This matches real card behavior where empty sectors reject authentication - // Fast path: check mask directly instead of function call - if(key_type == MfClassicKeyTypeA) { - if(FURI_BIT(instance->data->key_a_mask, sector_num) == 0) break; - } else { - if(FURI_BIT(instance->data->key_b_mask, sector_num) == 0) break; - } - MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(instance->data, sector_num); MfClassicKey* key = (key_type == MfClassicKeyTypeA) ? &sec_tr->key_a : &sec_tr->key_b;