From 50e0521bf7f2e37e98286520da51db9b6d4c1556 Mon Sep 17 00:00:00 2001 From: Tolly Hill Date: Fri, 9 Feb 2024 08:36:06 +0000 Subject: [PATCH] NFC: Custom UID entry when adding manually (#3363) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * NFC: Custom UID entry when adding manually * Fix incorrect types * Add Change UID option post-generation * Update UID derived data when using set_uid method * Fix PVS warnings Co-authored-by: gornekich Co-authored-by: あく --- .../protocol_support/mf_classic/mf_classic.c | 3 ++ .../mf_ultralight/mf_ultralight.c | 11 +++-- .../protocol_support/nfc_protocol_support.c | 9 ++++ .../main/nfc/plugins/supported_cards/hi.c | 2 +- .../main/nfc/plugins/supported_cards/mizip.c | 2 +- .../main/nfc/scenes/nfc_scene_set_uid.c | 4 ++ lib/nfc/helpers/nfc_data_generator.c | 43 +++++-------------- lib/nfc/protocols/mf_classic/mf_classic.c | 20 ++++++++- .../protocols/mf_ultralight/mf_ultralight.c | 14 +++++- 9 files changed, 69 insertions(+), 39 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 148601191..6abaa48cd 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 @@ -199,6 +199,9 @@ static bool nfc_scene_read_menu_on_event_mf_classic(NfcApp* instance, SceneManag } else if(event.event == SubmenuIndexDictAttack) { scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicDictAttack); consumed = true; + } else if(event.event == SubmenuIndexCommonEdit) { + scene_manager_next_scene(instance->scene_manager, NfcSceneSetUid); + consumed = true; } } diff --git a/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c b/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c index f0a46dd87..eb6911df7 100644 --- a/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c +++ b/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c @@ -266,16 +266,21 @@ static void nfc_scene_emulate_on_enter_mf_ultralight(NfcApp* instance) { static bool nfc_scene_read_and_saved_menu_on_event_mf_ultralight( NfcApp* instance, SceneManagerEvent event) { + bool consumed = false; + if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubmenuIndexUnlock) { scene_manager_next_scene(instance->scene_manager, NfcSceneMfUltralightUnlockMenu); - return true; + consumed = true; } else if(event.event == SubmenuIndexWrite) { scene_manager_next_scene(instance->scene_manager, NfcSceneMfUltralightWrite); - return true; + consumed = true; + } else if(event.event == SubmenuIndexCommonEdit) { + scene_manager_next_scene(instance->scene_manager, NfcSceneSetUid); + consumed = true; } } - return false; + return consumed; } const NfcProtocolSupportBase nfc_protocol_support_mf_ultralight = { diff --git a/applications/main/nfc/helpers/protocol_support/nfc_protocol_support.c b/applications/main/nfc/helpers/protocol_support/nfc_protocol_support.c index 2d46810a2..80fbb63de 100644 --- a/applications/main/nfc/helpers/protocol_support/nfc_protocol_support.c +++ b/applications/main/nfc/helpers/protocol_support/nfc_protocol_support.c @@ -233,6 +233,15 @@ static void nfc_protocol_support_scene_read_menu_on_enter(NfcApp* instance) { nfc_protocol_support_common_submenu_callback, instance); + if(scene_manager_has_previous_scene(instance->scene_manager, NfcSceneGenerateInfo)) { + submenu_add_item( + submenu, + "Change UID", + SubmenuIndexCommonEdit, + nfc_protocol_support_common_submenu_callback, + instance); + } + if(nfc_protocol_support_has_feature(protocol, NfcProtocolFeatureEmulateUid)) { submenu_add_item( submenu, diff --git a/applications/main/nfc/plugins/supported_cards/hi.c b/applications/main/nfc/plugins/supported_cards/hi.c index 21e602877..6807ab00c 100644 --- a/applications/main/nfc/plugins/supported_cards/hi.c +++ b/applications/main/nfc/plugins/supported_cards/hi.c @@ -88,7 +88,7 @@ static bool hi_verify_type(Nfc* nfc, MfClassicType type) { if(!hi_get_card_config(&cfg, type)) break; const uint8_t block_num = mf_classic_get_first_block_num_of_sector(cfg.verify_sector); - FURI_LOG_D(TAG, "Verifying sector %li", cfg.verify_sector); + FURI_LOG_D(TAG, "Verifying sector %lu", cfg.verify_sector); MfClassicKey key = {0}; nfc_util_num2bytes(cfg.keys[cfg.verify_sector].b, COUNT_OF(key.data), key.data); diff --git a/applications/main/nfc/plugins/supported_cards/mizip.c b/applications/main/nfc/plugins/supported_cards/mizip.c index bbcf9fdbc..b76c381e9 100644 --- a/applications/main/nfc/plugins/supported_cards/mizip.c +++ b/applications/main/nfc/plugins/supported_cards/mizip.c @@ -99,7 +99,7 @@ static bool mizip_verify_type(Nfc* nfc, MfClassicType type) { if(!mizip_get_card_config(&cfg, type)) break; const uint8_t block_num = mf_classic_get_first_block_num_of_sector(cfg.verify_sector); - FURI_LOG_D(TAG, "Verifying sector %li", cfg.verify_sector); + FURI_LOG_D(TAG, "Verifying sector %lu", cfg.verify_sector); MfClassicKey key = {0}; nfc_util_num2bytes(cfg.keys[cfg.verify_sector].b, COUNT_OF(key.data), key.data); diff --git a/applications/main/nfc/scenes/nfc_scene_set_uid.c b/applications/main/nfc/scenes/nfc_scene_set_uid.c index df8a4dc72..f09d0a430 100644 --- a/applications/main/nfc/scenes/nfc_scene_set_uid.c +++ b/applications/main/nfc/scenes/nfc_scene_set_uid.c @@ -44,6 +44,10 @@ bool nfc_scene_set_uid_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(instance->scene_manager, NfcSceneSaveSuccess); consumed = true; } + } else if(scene_manager_has_previous_scene(instance->scene_manager, NfcSceneReadMenu)) { + scene_manager_search_and_switch_to_previous_scene( + instance->scene_manager, NfcSceneReadMenu); + consumed = true; } else { scene_manager_next_scene(instance->scene_manager, NfcSceneSaveName); consumed = true; diff --git a/lib/nfc/helpers/nfc_data_generator.c b/lib/nfc/helpers/nfc_data_generator.c index 21f062605..0ecccc3ac 100644 --- a/lib/nfc/helpers/nfc_data_generator.c +++ b/lib/nfc/helpers/nfc_data_generator.c @@ -35,26 +35,16 @@ static void nfc_generate_mf_ul_uid(uint8_t* uid) { } static void nfc_generate_mf_ul_common(MfUltralightData* mfu_data) { + uint8_t uid[7]; mfu_data->iso14443_3a_data->uid_len = 7; - nfc_generate_mf_ul_uid(mfu_data->iso14443_3a_data->uid); + nfc_generate_mf_ul_uid(uid); + mf_ultralight_set_uid(mfu_data, uid, 7); + mfu_data->iso14443_3a_data->atqa[0] = 0x44; mfu_data->iso14443_3a_data->atqa[1] = 0x00; mfu_data->iso14443_3a_data->sak = 0x00; } -static void nfc_generate_calc_bcc(uint8_t* uid, uint8_t* bcc0, uint8_t* bcc1) { - *bcc0 = 0x88 ^ uid[0] ^ uid[1] ^ uid[2]; - *bcc1 = uid[3] ^ uid[4] ^ uid[5] ^ uid[6]; -} - -static void nfc_generate_mf_ul_copy_uid_with_bcc(MfUltralightData* mfu_data) { - memcpy(mfu_data->page[0].data, mfu_data->iso14443_3a_data->uid, 3); - memcpy(mfu_data->page[1].data, &mfu_data->iso14443_3a_data->uid[3], 4); - - nfc_generate_calc_bcc( - mfu_data->iso14443_3a_data->uid, &mfu_data->page[0].data[3], &mfu_data->page[2].data[0]); -} - static void nfc_generate_mf_ul_orig(NfcDevice* nfc_device) { MfUltralightData* mfu_data = mf_ultralight_alloc(); nfc_generate_mf_ul_common(mfu_data); @@ -62,7 +52,6 @@ static void nfc_generate_mf_ul_orig(NfcDevice* nfc_device) { mfu_data->type = MfUltralightTypeUnknown; mfu_data->pages_total = 16; mfu_data->pages_read = 16; - nfc_generate_mf_ul_copy_uid_with_bcc(mfu_data); memset(&mfu_data->page[4], 0xff, sizeof(MfUltralightPage)); nfc_device_set_data(nfc_device, NfcProtocolMfUltralight, mfu_data); @@ -74,7 +63,7 @@ static void nfc_generate_mf_ul_with_config_common(MfUltralightData* mfu_data, ui mfu_data->pages_total = num_pages; mfu_data->pages_read = num_pages; - nfc_generate_mf_ul_copy_uid_with_bcc(mfu_data); + uint16_t config_index = (num_pages - 4); mfu_data->page[config_index].data[0] = 0x04; // STRG_MOD_EN mfu_data->page[config_index].data[3] = 0xff; // AUTH0 @@ -150,7 +139,6 @@ static void nfc_generate_ntag203(NfcDevice* nfc_device) { mfu_data->type = MfUltralightTypeNTAG203; mfu_data->pages_total = 42; mfu_data->pages_read = 42; - nfc_generate_mf_ul_copy_uid_with_bcc(mfu_data); mfu_data->page[2].data[1] = 0x48; // Internal byte memcpy(&mfu_data->page[3], default_data_ntag203, sizeof(MfUltralightPage)); //-V1086 @@ -379,14 +367,7 @@ static void nfc_generate_mf_classic_block_0( furi_assert(uid_len == 4 || uid_len == 7); furi_assert(block); - if(uid_len == 4) { - // Calculate BCC - block[uid_len] = 0; - - for(int i = 0; i < uid_len; i++) { - block[uid_len] ^= block[i]; - } - } else { + if(uid_len == 7) { uid_len -= 1; } @@ -402,14 +383,12 @@ static void nfc_generate_mf_classic_block_0( static void nfc_generate_mf_classic(NfcDevice* nfc_device, uint8_t uid_len, MfClassicType type) { MfClassicData* mfc_data = mf_classic_alloc(); - nfc_generate_mf_classic_uid(mfc_data->block[0].data, uid_len); - nfc_generate_mf_classic_common(mfc_data, uid_len, type); + uint8_t uid[ISO14443_3A_MAX_UID_SIZE]; - // Set the UID - mfc_data->iso14443_3a_data->uid[0] = NXP_MANUFACTURER_ID; - for(int i = 1; i < uid_len; i++) { - mfc_data->iso14443_3a_data->uid[i] = mfc_data->block[0].data[i]; - } + nfc_generate_mf_classic_uid(uid, uid_len); + mf_classic_set_uid(mfc_data, uid, uid_len); + + nfc_generate_mf_classic_common(mfc_data, uid_len, type); mf_classic_set_block_read(mfc_data, 0, &mfc_data->block[0]); diff --git a/lib/nfc/protocols/mf_classic/mf_classic.c b/lib/nfc/protocols/mf_classic/mf_classic.c index e68e8c718..27236df4b 100644 --- a/lib/nfc/protocols/mf_classic/mf_classic.c +++ b/lib/nfc/protocols/mf_classic/mf_classic.c @@ -346,7 +346,25 @@ const uint8_t* mf_classic_get_uid(const MfClassicData* data, size_t* uid_len) { bool mf_classic_set_uid(MfClassicData* data, const uint8_t* uid, size_t uid_len) { furi_assert(data); - return iso14443_3a_set_uid(data->iso14443_3a_data, uid, uid_len); + bool uid_valid = iso14443_3a_set_uid(data->iso14443_3a_data, uid, uid_len); + + if(uid_valid) { + uint8_t* block = data->block[0].data; + + // Copy UID to block 0 + memcpy(block, data->iso14443_3a_data->uid, uid_len); + + if(uid_len == 4) { + // Calculate BCC byte + block[uid_len] = 0; + + for(size_t i = 0; i < uid_len; i++) { + block[uid_len] ^= block[i]; + } + } + } + + return uid_valid; } Iso14443_3aData* mf_classic_get_base_data(const MfClassicData* data) { diff --git a/lib/nfc/protocols/mf_ultralight/mf_ultralight.c b/lib/nfc/protocols/mf_ultralight/mf_ultralight.c index fd845f3c0..3cffa56ff 100644 --- a/lib/nfc/protocols/mf_ultralight/mf_ultralight.c +++ b/lib/nfc/protocols/mf_ultralight/mf_ultralight.c @@ -482,7 +482,19 @@ const uint8_t* mf_ultralight_get_uid(const MfUltralightData* data, size_t* uid_l bool mf_ultralight_set_uid(MfUltralightData* data, const uint8_t* uid, size_t uid_len) { furi_assert(data); - return iso14443_3a_set_uid(data->iso14443_3a_data, uid, uid_len); + bool uid_valid = iso14443_3a_set_uid(data->iso14443_3a_data, uid, uid_len); + + if(uid_valid) { + // Copy UID across first 2 pages + memcpy(data->page[0].data, data->iso14443_3a_data->uid, 3); + memcpy(data->page[1].data, &data->iso14443_3a_data->uid[3], 4); + + // Calculate BCC bytes + data->page[0].data[3] = 0x88 ^ uid[0] ^ uid[1] ^ uid[2]; + data->page[2].data[0] = uid[3] ^ uid[4] ^ uid[5] ^ uid[6]; + } + + return uid_valid; } Iso14443_3aData* mf_ultralight_get_base_data(const MfUltralightData* data) {