NFC: Custom UID entry when adding manually (#3363)

* 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 <n.gorbadey@gmail.com>
Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Tolly Hill 2024-02-09 08:36:06 +00:00 committed by GitHub
parent ebd09a1981
commit 50e0521bf7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 69 additions and 39 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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