From 75f5e6604bf76d65a733bab6ee53b973e80d8924 Mon Sep 17 00:00:00 2001 From: g3gg0 Date: Thu, 17 Nov 2022 01:35:39 +0100 Subject: [PATCH] separate ISO15693 basic and SLIX extensions a bit more changed save format to reflect this executing emulation from browser now also works --- applications/main/nfc/nfc.c | 3 + applications/main/nfc/nfc_cli.c | 7 +- .../main/nfc/scenes/nfc_scene_nfc_data_info.c | 31 ++- .../nfc/scenes/nfc_scene_nfcv_key_input.c | 3 +- .../main/nfc/scenes/nfc_scene_nfcv_menu.c | 2 +- .../main/nfc/scenes/nfc_scene_nfcv_unlock.c | 48 +--- applications/main/nfc/scenes/nfc_scene_rpc.c | 7 + .../main/nfc/scenes/nfc_scene_saved_menu.c | 2 + lib/nfc/nfc_device.c | 236 ++++++++++++++++-- lib/nfc/nfc_device.h | 5 +- lib/nfc/nfc_worker.c | 35 ++- lib/nfc/nfc_worker_i.h | 2 +- lib/nfc/protocols/nfcv.c | 216 ++++++++++++---- lib/nfc/protocols/nfcv.h | 58 ++++- lib/nfc/protocols/{slix_l.c => slix.c} | 45 +++- lib/nfc/protocols/{slix_l.h => slix.h} | 6 +- 16 files changed, 555 insertions(+), 151 deletions(-) rename lib/nfc/protocols/{slix_l.c => slix.c} (52%) rename lib/nfc/protocols/{slix_l.h => slix.h} (63%) diff --git a/applications/main/nfc/nfc.c b/applications/main/nfc/nfc.c index 55c68a450..aeddc5904 100644 --- a/applications/main/nfc/nfc.c +++ b/applications/main/nfc/nfc.c @@ -280,6 +280,9 @@ int32_t nfc_app(void* p) { } else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicEmulate); DOLPHIN_DEED(DolphinDeedNfcEmulate); + } else if(nfc->dev->format == NfcDeviceSaveFormatNfcV) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateNfcV); + DOLPHIN_DEED(DolphinDeedNfcEmulate); } else if(nfc->dev->format == NfcDeviceSaveFormatBankCard) { scene_manager_next_scene(nfc->scene_manager, NfcSceneDeviceInfo); } else { diff --git a/applications/main/nfc/nfc_cli.c b/applications/main/nfc/nfc_cli.c index cc2770731..180c7ba8f 100644 --- a/applications/main/nfc/nfc_cli.c +++ b/applications/main/nfc/nfc_cli.c @@ -286,8 +286,11 @@ static void nfc_cli_st25r_trans(Cli* cli, FuriString* args) { .block_num = 8, .block_size = 4, .ic_ref = 3, - .key_privacy = { 0x0F, 0x0F, 0x0F, 0x0F }, - .privacy = false + .type = NfcVTypeSlixL, + .sub_data.slix_l = { + .key_privacy = { 0x0F, 0x0F, 0x0F, 0x0F }, + .privacy = false + } }; memset(nfcv_data.data, 0xAE, 4 * 8); diff --git a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c index 98d11f2dc..bee3cc36d 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c +++ b/applications/main/nfc/scenes/nfc_scene_nfc_data_info.c @@ -15,7 +15,7 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { NfcProtocol protocol = dev_data->protocol; uint8_t text_scroll_height = 0; if((protocol == NfcDeviceProtocolMifareDesfire) || (protocol == NfcDeviceProtocolMifareUl) - || (protocol == NfcDeviceProtocolSlixL) || (protocol == NfcDeviceProtocolNfcV)) { + || (protocol == NfcDeviceProtocolNfcV)) { widget_add_button_element( widget, GuiButtonTypeRight, "More", nfc_scene_nfc_data_info_widget_callback, nfc); text_scroll_height = 52; @@ -42,15 +42,33 @@ void nfc_scene_nfc_data_info_on_enter(void* context) { } else if(protocol == NfcDeviceProtocolMifareDesfire) { furi_string_cat_printf(temp_str, "\e#MIFARE DESfire\n"); } else if(protocol == NfcDeviceProtocolNfcV) { - furi_string_cat_printf(temp_str, "\e#ISO15693\n"); - } else if(protocol == NfcDeviceProtocolSlixL) { - furi_string_cat_printf(temp_str, "\e#ISO15693 SLIX-L\n"); + switch (dev_data->nfcv_data.type) + { + case NfcVTypePlain: + furi_string_cat_printf(temp_str, "\e#ISO15693\n"); + break; + case NfcVTypeSlix: + furi_string_cat_printf(temp_str, "\e#ISO15693 SLIX\n"); + break; + case NfcVTypeSlixS: + furi_string_cat_printf(temp_str, "\e#ISO15693 SLIX-S\n"); + break; + case NfcVTypeSlixL: + furi_string_cat_printf(temp_str, "\e#ISO15693 SLIX-L\n"); + break; + case NfcVTypeSlix2: + furi_string_cat_printf(temp_str, "\e#ISO15693 SLIX2\n"); + break; + default: + furi_string_cat_printf(temp_str, "\e#ISO15693 (unknown)\n"); + break; + } } else { furi_string_cat_printf(temp_str, "\e#Unknown ISO tag\n"); } // Set tag iso data - if((protocol == NfcDeviceProtocolSlixL) || (protocol == NfcDeviceProtocolNfcV)) { + if(protocol == NfcDeviceProtocolNfcV) { NfcVData* nfcv_data = &nfc->dev->dev_data.nfcv_data; furi_string_cat_printf(temp_str, "UID:\n"); @@ -151,9 +169,6 @@ bool nfc_scene_nfc_data_info_on_event(void* context, SceneManagerEvent event) { } else if(protocol == NfcDeviceProtocolMifareUl) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightData); consumed = true; - } else if(protocol == NfcDeviceProtocolSlixL) { - scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcVMenu); - consumed = true; } else if(protocol == NfcDeviceProtocolNfcV) { scene_manager_next_scene(nfc->scene_manager, NfcSceneNfcVMenu); consumed = true; diff --git a/applications/main/nfc/scenes/nfc_scene_nfcv_key_input.c b/applications/main/nfc/scenes/nfc_scene_nfcv_key_input.c index d73498e7a..d0e223c15 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfcv_key_input.c +++ b/applications/main/nfc/scenes/nfc_scene_nfcv_key_input.c @@ -3,8 +3,9 @@ void nfc_scene_nfcv_key_input_byte_input_callback(void* context) { Nfc* nfc = context; + NfcVSlixLData* data = &nfc->dev->dev_data.nfcv_data.sub_data.slix_l; - memcpy(nfc->dev->dev_data.nfcv_data.key_privacy, nfc->byte_input_store, 4); + memcpy(data->key_privacy, nfc->byte_input_store, 4); view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventByteInputDone); } diff --git a/applications/main/nfc/scenes/nfc_scene_nfcv_menu.c b/applications/main/nfc/scenes/nfc_scene_nfcv_menu.c index fdf7de9ff..ee26baf69 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfcv_menu.c +++ b/applications/main/nfc/scenes/nfc_scene_nfcv_menu.c @@ -33,7 +33,7 @@ bool nfc_scene_nfcv_menu_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubmenuIndexSave) { - nfc->dev->format = NfcDeviceSaveFormatSlixL; + nfc->dev->format = NfcDeviceSaveFormatNfcV; // Clear device name nfc_device_set_name(nfc->dev, ""); scene_manager_next_scene(nfc->scene_manager, NfcSceneSaveName); diff --git a/applications/main/nfc/scenes/nfc_scene_nfcv_unlock.c b/applications/main/nfc/scenes/nfc_scene_nfcv_unlock.c index b9050e0fc..4fabd2d99 100644 --- a/applications/main/nfc/scenes/nfc_scene_nfcv_unlock.c +++ b/applications/main/nfc/scenes/nfc_scene_nfcv_unlock.c @@ -11,53 +11,15 @@ typedef enum { static bool nfc_scene_nfcv_unlock_worker_callback(NfcWorkerEvent event, void* context) { Nfc* nfc = context; + NfcVSlixLData* data = &nfc->dev->dev_data.nfcv_data.sub_data.slix_l; if(event == NfcWorkerEventNfcVPassKey) { - memcpy(nfc->dev->dev_data.nfcv_data.key_privacy, nfc->byte_input_store, 4); + memcpy(data->key_privacy, nfc->byte_input_store, 4); } else { view_dispatcher_send_custom_event(nfc->view_dispatcher, event); } return true; } -/* -static void nfc_scene_nfcv_unlock_button_callback(GuiButtonType event, InputType type, void* context) { - furi_assert(context); - furi_assert(type); - Nfc* nfc = context; - - if(event == GuiButtonTypeCenter) { - if(nfc_worker_get_state(nfc->worker) == NfcWorkerStateNfcVUnlockAndSave) { - nfc_worker_stop(nfc->worker); - nfc_worker_start( - nfc->worker, - NfcWorkerStateNfcVUnlock, - &nfc->dev->dev_data, - nfc_scene_nfcv_unlock_worker_callback, - nfc); - widget_add_button_element( - nfc->widget, - GuiButtonTypeCenter, - "Autosave", - nfc_scene_nfcv_unlock_button_callback, - nfc); - } else { - nfc_worker_stop(nfc->worker); - nfc_worker_start( - nfc->worker, - NfcWorkerStateNfcVUnlockAndSave, - &nfc->dev->dev_data, - nfc_scene_nfcv_unlock_worker_callback, - nfc); - widget_add_button_element( - nfc->widget, - GuiButtonTypeCenter, - "Unlock", - nfc_scene_nfcv_unlock_button_callback, - nfc); - } - notification_message(nfc->notifications, &sequence_single_vibro); - } -}*/ void nfc_scene_nfcv_unlock_popup_callback(void* context) { Nfc* nfc = context; @@ -82,10 +44,10 @@ void nfc_scene_nfcv_unlock_set_state(Nfc* nfc, NfcSceneNfcVUnlockState state) { if(nfc_worker_get_state(nfc->worker) == NfcWorkerStateNfcVUnlockAndSave) { nfc_text_store_set(nfc, "SLIX-L_%02X%02X%02X%02X%02X%02X%02X%02X", - nfc_data->uid[7], nfc_data->uid[6], nfc_data->uid[5], nfc_data->uid[4], - nfc_data->uid[3], nfc_data->uid[2], nfc_data->uid[1], nfc_data->uid[0]); + nfc_data->uid[0], nfc_data->uid[1], nfc_data->uid[2], nfc_data->uid[3], + nfc_data->uid[4], nfc_data->uid[5], nfc_data->uid[6], nfc_data->uid[7]); - nfc->dev->format = NfcDeviceSaveFormatSlixL; + nfc->dev->format = NfcDeviceSaveFormatNfcV; if(nfc_device_save(nfc->dev, nfc->text_store)) { popup_set_header(popup, "Successfully\nsaved", 94, 3, AlignCenter, AlignTop); diff --git a/applications/main/nfc/scenes/nfc_scene_rpc.c b/applications/main/nfc/scenes/nfc_scene_rpc.c index e5128a52f..1c0e4fa85 100644 --- a/applications/main/nfc/scenes/nfc_scene_rpc.c +++ b/applications/main/nfc/scenes/nfc_scene_rpc.c @@ -55,6 +55,13 @@ bool nfc_scene_rpc_on_event(void* context, SceneManagerEvent event) { &nfc->dev->dev_data, nfc_scene_rpc_emulate_callback, nfc); + } else if(nfc->dev->format == NfcDeviceSaveFormatNfcV) { + nfc_worker_start( + nfc->worker, + NfcWorkerStateNfcVEmulate, + &nfc->dev->dev_data, + nfc_scene_rpc_emulate_callback, + nfc); } else { nfc_worker_start( nfc->worker, NfcWorkerStateUidEmulate, &nfc->dev->dev_data, NULL, nfc); diff --git a/applications/main/nfc/scenes/nfc_scene_saved_menu.c b/applications/main/nfc/scenes/nfc_scene_saved_menu.c index 231f12089..2a5c93fb8 100644 --- a/applications/main/nfc/scenes/nfc_scene_saved_menu.c +++ b/applications/main/nfc/scenes/nfc_scene_saved_menu.c @@ -99,6 +99,8 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightEmulate); } else if(nfc->dev->format == NfcDeviceSaveFormatMifareClassic) { scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicEmulate); + } else if(nfc->dev->format == NfcDeviceSaveFormatNfcV) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateNfcV); } else { scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateUid); } diff --git a/lib/nfc/nfc_device.c b/lib/nfc/nfc_device.c index c7aeb9a06..886944fb1 100644 --- a/lib/nfc/nfc_device.c +++ b/lib/nfc/nfc_device.c @@ -50,8 +50,8 @@ static void nfc_device_prepare_format_string(NfcDevice* dev, FuriString* format_ furi_string_set(format_string, "Mifare Classic"); } else if(dev->format == NfcDeviceSaveFormatMifareDesfire) { furi_string_set(format_string, "Mifare DESFire"); - } else if(dev->format == NfcDeviceSaveFormatSlixL) { - furi_string_set(format_string, "NXP SLIX-L"); + } else if(dev->format == NfcDeviceSaveFormatNfcV) { + furi_string_set(format_string, "ISO15693"); } else { furi_string_set(format_string, "Unknown"); } @@ -87,9 +87,9 @@ static bool nfc_device_parse_format_string(NfcDevice* dev, FuriString* format_st dev->dev_data.protocol = NfcDeviceProtocolMifareDesfire; return true; } - if(furi_string_start_with_str(format_string, "NXP SLIX-L")) { - dev->format = NfcDeviceSaveFormatSlixL; - dev->dev_data.protocol = NfcDeviceProtocolSlixL; + if(furi_string_start_with_str(format_string, "ISO15693")) { + dev->format = NfcDeviceSaveFormatNfcV; + dev->dev_data.protocol = NfcDeviceProtocolNfcV; return true; } return false; @@ -643,21 +643,92 @@ bool nfc_device_load_mifare_df_data(FlipperFormat* file, NfcDevice* dev) { return parsed; } +static bool nfc_device_save_slix_data(FlipperFormat* file, NfcDevice* dev) { + bool saved = false; + NfcVSlixData* data = &dev->dev_data.nfcv_data.sub_data.slix; + + do { + if(!flipper_format_write_comment_cstr(file, "SLIX specific data")) break; + if(!flipper_format_write_hex(file, "Password EAS", data->key_eas, sizeof(data->key_eas))) break; + saved = true; + } while(false); + + return saved; +} + +bool nfc_device_load_slix_data(FlipperFormat* file, NfcDevice* dev) { + bool parsed = false; + NfcVSlixData* data = &dev->dev_data.nfcv_data.sub_data.slix; + memset(data, 0, sizeof(NfcVData)); + + do { + if(!flipper_format_read_hex( + file, "Password EAS", data->key_eas, sizeof(data->key_eas))) + break; + + parsed = true; + } while(false); + + return parsed; +} + +static bool nfc_device_save_slix_s_data(FlipperFormat* file, NfcDevice* dev) { + bool saved = false; + NfcVSlixSData* data = &dev->dev_data.nfcv_data.sub_data.slix_s; + + do { + if(!flipper_format_write_comment_cstr(file, "SLIX-S specific data")) break; + if(!flipper_format_write_hex(file, "Password Read", data->key_read, sizeof(data->key_read))) break; + if(!flipper_format_write_hex(file, "Password Write", data->key_write, sizeof(data->key_write))) break; + if(!flipper_format_write_hex(file, "Password Privacy", data->key_privacy, sizeof(data->key_privacy))) break; + if(!flipper_format_write_hex(file, "Password Destroy", data->key_destroy, sizeof(data->key_destroy))) break; + if(!flipper_format_write_hex(file, "Password EAS", data->key_eas, sizeof(data->key_eas))) break; + if(!flipper_format_write_bool(file, "Privacy Mode", &data->privacy, 1)) break; + saved = true; + } while(false); + + return saved; +} + +bool nfc_device_load_slix_s_data(FlipperFormat* file, NfcDevice* dev) { + bool parsed = false; + NfcVSlixSData* data = &dev->dev_data.nfcv_data.sub_data.slix_s; + memset(data, 0, sizeof(NfcVData)); + + do { + if(!flipper_format_read_hex( + file, "Password Read", data->key_read, sizeof(data->key_read))) + break; + if(!flipper_format_read_hex( + file, "Password Write", data->key_write, sizeof(data->key_write))) + break; + if(!flipper_format_read_hex( + file, "Password Privacy", data->key_privacy, sizeof(data->key_privacy))) + break; + if(!flipper_format_read_hex( + file, "Password Destroy", data->key_destroy, sizeof(data->key_destroy))) + break; + if(!flipper_format_read_hex( + file, "Password EAS", data->key_eas, sizeof(data->key_eas))) + break; + if(!flipper_format_read_bool(file, "Privacy Mode", &data->privacy, 1)) break; + + parsed = true; + } while(false); + + return parsed; +} + static bool nfc_device_save_slix_l_data(FlipperFormat* file, NfcDevice* dev) { bool saved = false; - NfcVData* data = &dev->dev_data.nfcv_data; + NfcVSlixLData* data = &dev->dev_data.nfcv_data.sub_data.slix_l; do { if(!flipper_format_write_comment_cstr(file, "SLIX-L specific data")) break; if(!flipper_format_write_hex(file, "Password Privacy", data->key_privacy, sizeof(data->key_privacy))) break; if(!flipper_format_write_hex(file, "Password Destroy", data->key_destroy, sizeof(data->key_destroy))) break; if(!flipper_format_write_hex(file, "Password EAS", data->key_eas, sizeof(data->key_eas))) break; - if(!flipper_format_write_hex(file, "DSFID", &(data->dsfid), 1)) break; - if(!flipper_format_write_hex(file, "AFI", &(data->afi), 1)) break; - if(!flipper_format_write_hex(file, "IC Reference", &(data->ic_ref), 1)) break; - if(!flipper_format_write_hex(file, "Block Count", &(data->block_num), 1)) break; - if(!flipper_format_write_hex(file, "Block Size", &(data->block_size), 1)) break; - if(!flipper_format_write_hex(file, "Data Content", data->data, data->block_num * data->block_size)) break; + if(!flipper_format_write_bool(file, "Privacy Mode", &data->privacy, 1)) break; saved = true; } while(false); @@ -666,7 +737,7 @@ static bool nfc_device_save_slix_l_data(FlipperFormat* file, NfcDevice* dev) { bool nfc_device_load_slix_l_data(FlipperFormat* file, NfcDevice* dev) { bool parsed = false; - NfcVData* data = &dev->dev_data.nfcv_data; + NfcVSlixLData* data = &dev->dev_data.nfcv_data.sub_data.slix_l; memset(data, 0, sizeof(NfcVData)); do { @@ -679,7 +750,108 @@ bool nfc_device_load_slix_l_data(FlipperFormat* file, NfcDevice* dev) { if(!flipper_format_read_hex( file, "Password EAS", data->key_eas, sizeof(data->key_eas))) break; + if(!flipper_format_read_bool(file, "Privacy Mode", &data->privacy, 1)) break; + parsed = true; + } while(false); + + return parsed; +} + +static bool nfc_device_save_slix2_data(FlipperFormat* file, NfcDevice* dev) { + bool saved = false; + NfcVSlix2Data* data = &dev->dev_data.nfcv_data.sub_data.slix2; + + do { + if(!flipper_format_write_comment_cstr(file, "SLIX2 specific data")) break; + if(!flipper_format_write_hex(file, "Password Read", data->key_read, sizeof(data->key_read))) break; + if(!flipper_format_write_hex(file, "Password Write", data->key_write, sizeof(data->key_write))) break; + if(!flipper_format_write_hex(file, "Password Privacy", data->key_privacy, sizeof(data->key_privacy))) break; + if(!flipper_format_write_hex(file, "Password Destroy", data->key_destroy, sizeof(data->key_destroy))) break; + if(!flipper_format_write_hex(file, "Password EAS", data->key_eas, sizeof(data->key_eas))) break; + if(!flipper_format_write_bool(file, "Privacy Mode", &data->privacy, 1)) break; + saved = true; + } while(false); + + return saved; +} + +bool nfc_device_load_slix2_data(FlipperFormat* file, NfcDevice* dev) { + bool parsed = false; + NfcVSlix2Data* data = &dev->dev_data.nfcv_data.sub_data.slix2; + memset(data, 0, sizeof(NfcVData)); + + do { + if(!flipper_format_read_hex( + file, "Password Read", data->key_read, sizeof(data->key_read))) + break; + if(!flipper_format_read_hex( + file, "Password Write", data->key_write, sizeof(data->key_write))) + break; + if(!flipper_format_read_hex( + file, "Password Privacy", data->key_privacy, sizeof(data->key_privacy))) + break; + if(!flipper_format_read_hex( + file, "Password Destroy", data->key_destroy, sizeof(data->key_destroy))) + break; + if(!flipper_format_read_hex( + file, "Password EAS", data->key_eas, sizeof(data->key_eas))) + break; + if(!flipper_format_read_bool(file, "Privacy Mode", &data->privacy, 1)) break; + + parsed = true; + } while(false); + + return parsed; +} + +static bool nfc_device_save_nfcv_data(FlipperFormat* file, NfcDevice* dev) { + bool saved = false; + uint8_t temp_value = 0; + NfcVData* data = &dev->dev_data.nfcv_data; + + do { + if(!flipper_format_write_hex(file, "DSFID", &(data->dsfid), 1)) break; + if(!flipper_format_write_hex(file, "AFI", &(data->afi), 1)) break; + if(!flipper_format_write_hex(file, "IC Reference", &(data->ic_ref), 1)) break; + if(!flipper_format_write_hex(file, "Block Count", &(data->block_num), 1)) break; + if(!flipper_format_write_hex(file, "Block Size", &(data->block_size), 1)) break; + if(!flipper_format_write_hex(file, "Data Content", data->data, data->block_num * data->block_size)) break; + if(!flipper_format_write_comment_cstr(file, "Subtype of this card (0 = ISO15693, 1 = SLIX, 2 = SLIX-S, 3 = SLIX-L, 4 = SLIX2)")) break; + + temp_value = data->type; + if(!flipper_format_write_hex(file, "Subtype", &temp_value, 1)) break; + + switch(data->type) { + case NfcVTypePlain: + saved = true; + break; + case NfcVTypeSlix: + saved = nfc_device_save_slix_data(file, dev); + break; + case NfcVTypeSlixS: + saved = nfc_device_save_slix_s_data(file, dev); + break; + case NfcVTypeSlixL: + saved = nfc_device_save_slix_l_data(file, dev); + break; + case NfcVTypeSlix2: + saved = nfc_device_save_slix2_data(file, dev); + break; + } + } while(false); + + return saved; +} + +bool nfc_device_load_nfcv_data(FlipperFormat* file, NfcDevice* dev) { + bool parsed = false; + uint8_t temp_value = 0; + NfcVData* data = &dev->dev_data.nfcv_data; + + memset(data, 0, sizeof(NfcVData)); + + do { if(!flipper_format_read_hex(file, "DSFID", &(data->dsfid), 1)) break; if(!flipper_format_read_hex(file, "AFI", &(data->afi), 1)) break; if(!flipper_format_read_hex(file, "IC Reference", &(data->ic_ref), 1)) break; @@ -688,8 +860,26 @@ bool nfc_device_load_slix_l_data(FlipperFormat* file, NfcDevice* dev) { if(!flipper_format_read_hex( file, "Data Content", data->data, data->block_num * data->block_size)) break; + if(!flipper_format_read_hex(file, "Subtype", &temp_value, 1)) break; + data->type = temp_value; - parsed = true; + switch(data->type) { + case NfcVTypePlain: + parsed = true; + break; + case NfcVTypeSlix: + parsed = nfc_device_load_slix_data(file, dev); + break; + case NfcVTypeSlixS: + parsed = nfc_device_load_slix_s_data(file, dev); + break; + case NfcVTypeSlixL: + parsed = nfc_device_load_slix_l_data(file, dev); + break; + case NfcVTypeSlix2: + parsed = nfc_device_load_slix2_data(file, dev); + break; + } } while(false); return parsed; @@ -1127,17 +1317,19 @@ static bool nfc_device_save_file( if(!flipper_format_write_header_cstr(file, nfc_file_header, nfc_file_version)) break; // Write nfc device type if(!flipper_format_write_comment_cstr( - file, "Nfc device type can be UID, Mifare Ultralight, Mifare Classic")) + file, "Nfc device type can be UID, Mifare Ultralight, Mifare Classic or ISO15693")) break; nfc_device_prepare_format_string(dev, temp_str); if(!flipper_format_write_string(file, "Device type", temp_str)) break; // Write UID - if(!flipper_format_write_comment_cstr(file, "UID, ATQA and SAK are common for all formats except ISO15693")) + if(!flipper_format_write_comment_cstr(file, "UID is common for all formats")) break; if(!flipper_format_write_hex(file, "UID", data->uid, data->uid_len)) break; - if(dev->format != NfcDeviceSaveFormatSlixL) { + if(dev->format != NfcDeviceSaveFormatNfcV) { // Write ATQA, SAK + if(!flipper_format_write_comment_cstr(file, "ISO14443 specific fields")) + break; if(!flipper_format_write_hex(file, "ATQA", data->atqa, 2)) break; if(!flipper_format_write_hex(file, "SAK", &data->sak, 1)) break; } @@ -1146,8 +1338,8 @@ static bool nfc_device_save_file( if(!nfc_device_save_mifare_ul_data(file, dev)) break; } else if(dev->format == NfcDeviceSaveFormatMifareDesfire) { if(!nfc_device_save_mifare_df_data(file, dev)) break; - } else if(dev->format == NfcDeviceSaveFormatSlixL) { - if(!nfc_device_save_slix_l_data(file, dev)) break; + } else if(dev->format == NfcDeviceSaveFormatNfcV) { + if(!nfc_device_save_nfcv_data(file, dev)) break; } else if(dev->format == NfcDeviceSaveFormatBankCard) { if(!nfc_device_save_bank_card_data(file, dev)) break; } else if(dev->format == NfcDeviceSaveFormatMifareClassic) { @@ -1215,7 +1407,7 @@ static bool nfc_device_load_data(NfcDevice* dev, FuriString* path, bool show_dia if(!(data_cnt == 4 || data_cnt == 7 || data_cnt == 8)) break; data->uid_len = data_cnt; if(!flipper_format_read_hex(file, "UID", data->uid, data->uid_len)) break; - if(dev->format != NfcDeviceSaveFormatSlixL) { + if(dev->format != NfcDeviceSaveFormatNfcV) { if(!flipper_format_read_hex(file, "ATQA", data->atqa, 2)) break; if(!flipper_format_read_hex(file, "SAK", &data->sak, 1)) break; } @@ -1233,8 +1425,8 @@ static bool nfc_device_load_data(NfcDevice* dev, FuriString* path, bool show_dia if(!nfc_device_load_mifare_classic_data(file, dev)) break; } else if(dev->format == NfcDeviceSaveFormatMifareDesfire) { if(!nfc_device_load_mifare_df_data(file, dev)) break; - } else if(dev->format == NfcDeviceSaveFormatSlixL) { - if(!nfc_device_load_slix_l_data(file, dev)) break; + } else if(dev->format == NfcDeviceSaveFormatNfcV) { + if(!nfc_device_load_nfcv_data(file, dev)) break; } else if(dev->format == NfcDeviceSaveFormatBankCard) { if(!nfc_device_load_bank_card_data(file, dev)) break; } diff --git a/lib/nfc/nfc_device.h b/lib/nfc/nfc_device.h index d0299fea2..576280918 100644 --- a/lib/nfc/nfc_device.h +++ b/lib/nfc/nfc_device.h @@ -33,8 +33,7 @@ typedef enum { NfcDeviceProtocolMifareUl, NfcDeviceProtocolMifareClassic, NfcDeviceProtocolMifareDesfire, - NfcDeviceProtocolNfcV, - NfcDeviceProtocolSlixL, + NfcDeviceProtocolNfcV } NfcProtocol; typedef enum { @@ -43,7 +42,7 @@ typedef enum { NfcDeviceSaveFormatMifareUl, NfcDeviceSaveFormatMifareClassic, NfcDeviceSaveFormatMifareDesfire, - NfcDeviceSaveFormatSlixL, + NfcDeviceSaveFormatNfcV, } NfcDeviceSaveFormat; typedef struct { diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index 98f88a0ab..ea1c72514 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -176,11 +176,12 @@ void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) { if(nfcv_data->auth_method == NfcVAuthMethodManual) { uint32_t key = 0; + uint8_t *key_data = nfc_worker->dev_data->nfcv_data.sub_data.slix_l.key_privacy; - key |= nfc_worker->dev_data->nfcv_data.key_privacy[0] << 24; - key |= nfc_worker->dev_data->nfcv_data.key_privacy[1] << 16; - key |= nfc_worker->dev_data->nfcv_data.key_privacy[2] << 8; - key |= nfc_worker->dev_data->nfcv_data.key_privacy[3] << 0; + key |= key_data[0] << 24; + key |= key_data[1] << 16; + key |= key_data[2] << 8; + key |= key_data[3] << 0; ret = slix_l_unlock(4, rand, key); } else { ret = slix_l_unlock(4, rand, 0x7FFD6E5B); @@ -493,17 +494,31 @@ static bool nfc_worker_read_nfcv(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* t furi_assert(tx_rx); FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data; + NfcVData* nfcv_data = &nfc_worker->dev_data->nfcv_data; bool card_read = false; furi_hal_nfc_sleep(); - if(slix_l_check_card_type(nfc_data->uid[7], nfc_data->uid[6], nfc_data->uid[5])) { + + /* until here the UID field is reversed from the reader IC. + we will read it here again and it will get placed in the right order. */ + card_read = nfc_worker_read_nfcv_content(nfc_worker, tx_rx); + + nfc_worker->dev_data->protocol = NfcDeviceProtocolNfcV; + + if(slix_check_card_type(nfc_data)) { + FURI_LOG_I(TAG, "NXP SLIX detected"); + nfcv_data->type = NfcVTypeSlix; + } else if(slix2_check_card_type(nfc_data)) { + FURI_LOG_I(TAG, "NXP SLIX2 detected"); + nfcv_data->type = NfcVTypeSlix2; + } else if(slix_s_check_card_type(nfc_data)) { FURI_LOG_I(TAG, "NXP SLIX-L detected"); - nfc_worker->dev_data->protocol = NfcDeviceProtocolSlixL; - card_read = nfc_worker_read_nfcv_content(nfc_worker, tx_rx); + nfcv_data->type = NfcVTypeSlixS; + } else if(slix_l_check_card_type(nfc_data)) { + FURI_LOG_I(TAG, "NXP SLIX-L detected"); + nfcv_data->type = NfcVTypeSlixL; } else { - FURI_LOG_I(TAG, "unknown detected"); - nfc_worker->dev_data->protocol = NfcDeviceProtocolNfcV; - card_read = nfc_worker_read_nfcv_content(nfc_worker, tx_rx); + nfcv_data->type = NfcVTypePlain; } return card_read; diff --git a/lib/nfc/nfc_worker_i.h b/lib/nfc/nfc_worker_i.h index d50d2a274..67fdcdc3d 100644 --- a/lib/nfc/nfc_worker_i.h +++ b/lib/nfc/nfc_worker_i.h @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include struct NfcWorker { diff --git a/lib/nfc/protocols/nfcv.c b/lib/nfc/protocols/nfcv.c index 11604afef..1f94211fc 100644 --- a/lib/nfc/protocols/nfcv.c +++ b/lib/nfc/protocols/nfcv.c @@ -8,6 +8,10 @@ #include #include #include +#include +#include +#include +#include #include "nfcv.h" #include "nfc_util.h" @@ -75,7 +79,7 @@ ReturnCode nfcv_read_sysinfo(FuriHalNfcDevData* nfc_data, NfcVData* data) { if(ret == ERR_NONE) { nfc_data->type = FuriHalNfcTypeV; nfc_data->uid_len = 8; - /* UID is stored reversed in this structure */ + /* UID is stored reversed in this response */ for(int pos = 0; pos < nfc_data->uid_len; pos++) { nfc_data->uid[pos] = rxBuf[2 + (7 - pos)]; } @@ -316,41 +320,62 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui } uint8_t response_buffer[32]; + + switch(nfcv_data->type) { + case NfcVTypeSlixL: + if(nfcv_data->sub_data.slix_l.privacy && + command != ISO15693_CMD_NXP_GET_RANDOM_NUMBER && + command != ISO15693_CMD_NXP_SET_PASSWORD) { + snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "(command ignored, privacy)"); + } + break; + + default: + break; + } switch(command) { - case ISO15693_GET_SYSTEM_INFO: - { - if(nfcv_data->privacy) { - snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "SYSTEMINFO (ignored, privacy)"); - } else { - response_buffer[0] = ISO15693_NOERROR; - response_buffer[1] = 0x0F; - nfcv_uidcpy(&response_buffer[2], nfc_data->uid); - response_buffer[10] = nfcv_data->dsfid; /* DSFID */ - response_buffer[11] = nfcv_data->afi; /* AFI */ - response_buffer[12] = nfcv_data->block_num - 1; /* number of blocks */ - response_buffer[13] = nfcv_data->block_size - 1; /* block size */ - response_buffer[14] = nfcv_data->ic_ref; /* IC reference */ - - nfcv_emu_send(response_buffer, 15); - snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "SYSTEMINFO"); - } - - break; - } case ISO15693_INVENTORY: { - if(nfcv_data->privacy) { - snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "INVENTORY (ignored, privacy)"); - } else { - response_buffer[0] = ISO15693_NOERROR; - response_buffer[1] = nfcv_data->dsfid; /* DSFID */ - nfcv_uidcpy(&response_buffer[2], nfc_data->uid); + response_buffer[0] = ISO15693_NOERROR; + response_buffer[1] = nfcv_data->dsfid; /* DSFID */ + nfcv_uidcpy(&response_buffer[2], nfc_data->uid); - nfcv_emu_send(response_buffer, 10); - snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "INVENTORY"); - } + nfcv_emu_send(response_buffer, 10); + snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "INVENTORY"); + break; + } + + case ISO15693_STAYQUIET: + { + snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "STAYQUIET"); + break; + } + + case ISO15693_LOCKBLOCK: + { + snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "LOCKBLOCK"); + break; + } + + case ISO15693_READ_MULTI_BLOCK: + { + snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "READ_MULTI_BLOCK"); + break; + } + + case ISO15693_WRITE_MULTI_BLOCK: + { + snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "WRITE_MULTI_BLOCK"); + break; + } + + case ISO15693_SELECT: + { + response_buffer[0] = ISO15693_NOERROR; + nfcv_emu_send(response_buffer, 1); + snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "SELECT"); break; } @@ -386,11 +411,31 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui break; } + case ISO15693_GET_SYSTEM_INFO: + { + response_buffer[0] = ISO15693_NOERROR; + response_buffer[1] = 0x0F; + nfcv_uidcpy(&response_buffer[2], nfc_data->uid); + response_buffer[10] = nfcv_data->dsfid; /* DSFID */ + response_buffer[11] = nfcv_data->afi; /* AFI */ + response_buffer[12] = nfcv_data->block_num - 1; /* number of blocks */ + response_buffer[13] = nfcv_data->block_size - 1; /* block size */ + response_buffer[14] = nfcv_data->ic_ref; /* IC reference */ + + nfcv_emu_send(response_buffer, 15); + snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "SYSTEMINFO"); + + break; + } + case ISO15693_CMD_NXP_GET_RANDOM_NUMBER: { + nfcv_data->sub_data.slix_l.rand[0] = 0x00; + nfcv_data->sub_data.slix_l.rand[1] = 0x00; + response_buffer[0] = ISO15693_NOERROR; - response_buffer[1] = 0x00; /* set number to 0x0000 so we get the key in plaintext */ - response_buffer[2] = 0x00; + response_buffer[1] = nfcv_data->sub_data.slix_l.rand[0]; + response_buffer[2] = nfcv_data->sub_data.slix_l.rand[1]; nfcv_emu_send(response_buffer, 3); snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "GET_RANDOM_NUMBER"); @@ -399,17 +444,43 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui case ISO15693_CMD_NXP_SET_PASSWORD: { - uint32_t pass = (payload[payload_offset + 1] << 24) - | (payload[payload_offset + 2] << 16) - | (payload[payload_offset + 3] << 8) - | (payload[payload_offset + 4] << 0); + uint8_t password_id = payload[payload_offset]; + uint8_t *password_xored = &payload[payload_offset + 1]; + uint8_t *rand = nfcv_data->sub_data.slix_l.rand; + uint8_t status = ISO15693_ERROR_GENERIC; + uint8_t *password = NULL; + uint8_t password_rcv[4]; - response_buffer[0] = ISO15693_NOERROR; + switch(password_id) { + case 4: + password = nfcv_data->sub_data.slix_l.key_privacy; + break; + case 8: + password = nfcv_data->sub_data.slix_l.key_destroy; + break; + case 10: + password = nfcv_data->sub_data.slix_l.key_eas; + break; + default: + break; + } + + for(int pos = 0; pos < 4; pos++) { + password_rcv[pos] = password_xored[pos] ^ rand[pos % 2]; + } + + if(!memcmp(password, password_rcv, 4)) { + status = ISO15693_NOERROR; + nfcv_data->sub_data.slix_l.privacy = false; + } else { + printf("pass mismatch: %08lX %08lX %02X", *((uint32_t *)password), *((uint32_t *)password_xored), *rand); + } + + response_buffer[0] = status; nfcv_emu_send(response_buffer, 1); - snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "SET_PASSWORD #%02X: %08lX", payload[payload_offset + 0], pass); + snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "SET_PASSWORD #%02X", password_id); - nfcv_data->privacy = false; break; } @@ -420,7 +491,7 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui nfcv_emu_send(response_buffer, 1); snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "ISO15693_CMD_NXP_ENABLE_PRIVACY"); - nfcv_data->privacy = true; + nfcv_data->sub_data.slix_l.privacy = true; break; } @@ -430,6 +501,10 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui } } +#define COUNT(x) ((sizeof(x))/(sizeof(x[0]))) +uint32_t nfcv_timer_buffer_src[32]; +uint32_t nfcv_timer_buffer[1024]; + void nfcv_emu_init() { nfcv_emu_alloc(); rfal_platform_spi_acquire(); @@ -440,6 +515,53 @@ void nfcv_emu_init() { st25r3916ExecuteCommand(ST25R3916_CMD_TRANSPARENT_MODE); furi_hal_spi_bus_handle_deinit(&furi_hal_spi_bus_handle_nfc); + +#if 0 + memset(nfcv_timer_buffer_src, 0xEE, sizeof(nfcv_timer_buffer_src)); + memset(nfcv_timer_buffer, 0xFA, sizeof(nfcv_timer_buffer)); + + /* configure DMA to read from a timer peripheral */ + LL_DMA_InitTypeDef dma_config = {}; + dma_config.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY; + dma_config.PeriphOrM2MSrcAddress = (uint32_t) &(TIM2->CNT); + dma_config.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; + dma_config.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD; + dma_config.MemoryOrM2MDstAddress = (uint32_t) nfcv_timer_buffer; + dma_config.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; + dma_config.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD; + dma_config.Mode = LL_DMA_MODE_NORMAL; + dma_config.NbData = 32; /* executes LL_DMA_SetDataLength */ + dma_config.PeriphRequest = LL_DMAMUX_REQ_GENERATOR0; /* executes LL_DMA_SetPeriphRequest */ + dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH; + + /* now set up DMA with these settings */ + LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_4); + LL_DMA_Init(DMA1, LL_DMA_CHANNEL_4, &dma_config); + LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_4); + + /* make some noise on the counter */ + LL_TIM_DisableCounter(TIM2); + LL_TIM_SetCounterMode(TIM2, LL_TIM_COUNTERMODE_UP); + LL_TIM_SetClockDivision(TIM2, LL_TIM_CLOCKDIVISION_DIV1); + LL_TIM_SetPrescaler(TIM2, 0); + LL_TIM_SetAutoReload(TIM2, 0xFFF); + LL_TIM_SetCounter(TIM2, 0); + LL_TIM_EnableCounter(TIM2); + + /* make sure request generation is disabled before modifying registers */ + LL_DMAMUX_DisableRequestGen(NULL, LL_DMAMUX_REQ_GEN_0); + /* generator 0 gets fed by EXTI_LINE4 */ + LL_DMAMUX_SetRequestSignalID(NULL, LL_DMAMUX_REQ_GEN_0, LL_DMAMUX_REQ_GEN_EXTI_LINE4); + /* trigger on any edge - for now. should be only one? */ + LL_DMAMUX_SetRequestGenPolarity(NULL, LL_DMAMUX_REQ_GEN_0, LL_DMAMUX_REQ_GEN_POL_RISING); + /* now enable request generation again */ + LL_DMAMUX_EnableRequestGen(NULL, LL_DMAMUX_REQ_GEN_0); + + /* configure PB4 as source for EXTI_LINE4. shall it rain. */ + LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTB, LL_GPIO_PIN_4); + +#endif + } void nfcv_emu_deinit() { @@ -469,6 +591,7 @@ bool nfcv_emu_loop(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, uint32_t ti bool in_critical = false; FURI_CRITICAL_DEFINE(); + while(true) { bool state = furi_hal_gpio_read(&gpio_spi_r_miso); @@ -633,6 +756,7 @@ bool nfcv_emu_loop(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, uint32_t ti if(timeout && cur_time > timeout) { break; } + /* might exit early on overflows. guess thats okay. */ if(cur_time > next_sleep) { break; @@ -659,8 +783,16 @@ bool nfcv_emu_loop(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, uint32_t ti nfcv_emu_handle_packet(nfc_data, nfcv_data, frame_payload, frame_pos); ret = true; } - - furi_delay_ms(0); +/* + printf("nfcv_timer_buffer: %ld", LL_DMA_GetDataLength(DMA1, LL_DMA_CHANNEL_4)); + for(uint32_t pos = 0; pos < 64; pos++) { + if((pos % 4) == 0) { + printf("\r\n"); + } + printf(" 0x%08lX ", nfcv_timer_buffer[pos]); + } + furi_delay_ms(100); + */ return ret; } diff --git a/lib/nfc/protocols/nfcv.h b/lib/nfc/protocols/nfcv.h index c2efcd1a1..e8188cb3f 100644 --- a/lib/nfc/protocols/nfcv.h +++ b/lib/nfc/protocols/nfcv.h @@ -81,31 +81,71 @@ typedef enum { } NfcVAuthMethod; typedef enum { - NfcVTypeSlix, - NfcVTypeSlixS, - NfcVTypeSlixL, - NfcVTypeSlix2, + NfcVTypePlain = 0, + NfcVTypeSlix = 1, + NfcVTypeSlixS = 2, + NfcVTypeSlixL = 3, + NfcVTypeSlix2 = 4, } NfcVType; typedef struct { - NfcVType type; - NfcVAuthMethod auth_method; - bool auth_success; + uint8_t key_eas[4]; + uint8_t rand[2]; +} NfcVSlixData; +typedef struct { + uint8_t key_read[4]; + uint8_t key_write[4]; uint8_t key_privacy[4]; uint8_t key_destroy[4]; uint8_t key_eas[4]; + uint8_t rand[2]; + bool privacy; +} NfcVSlix2Data; +typedef struct { + uint8_t key_read[4]; + uint8_t key_write[4]; + uint8_t key_privacy[4]; + uint8_t key_destroy[4]; + uint8_t key_eas[4]; + uint8_t rand[2]; + bool privacy; +} NfcVSlixSData; + +typedef struct { + uint8_t key_privacy[4]; + uint8_t key_destroy[4]; + uint8_t key_eas[4]; + uint8_t rand[2]; + bool privacy; +} NfcVSlixLData; + +typedef union { + NfcVSlixData slix; + NfcVSlix2Data slix2; + NfcVSlixSData slix_s; + NfcVSlixLData slix_l; +} NfcVSubtypeData; + +typedef struct { + /* common ISO15693 fields */ uint8_t dsfid; uint8_t afi; uint8_t ic_ref; uint8_t block_num; uint8_t block_size; uint8_t data[NFCV_MAX_DUMP_SIZE]; - bool privacy; - char error[32]; + /* specfic variant infos */ + NfcVType type; + NfcVSubtypeData sub_data; + + /* runtime data */ char last_command[128]; + char error[32]; + NfcVAuthMethod auth_method; + bool auth_success; } NfcVData; typedef struct { diff --git a/lib/nfc/protocols/slix_l.c b/lib/nfc/protocols/slix.c similarity index 52% rename from lib/nfc/protocols/slix_l.c rename to lib/nfc/protocols/slix.c index d22a8470e..e7dfe44be 100644 --- a/lib/nfc/protocols/slix_l.c +++ b/lib/nfc/protocols/slix.c @@ -1,14 +1,45 @@ #include #include "nfcv.h" -#include "slix_l.h" +#include "slix.h" #include "nfc_util.h" #include #include "furi_hal_nfc.h" -bool slix_l_check_card_type(uint8_t UID0, uint8_t UID1, uint8_t UID2) { - if((UID0 == 0xE0) && (UID1 == 0x04) && (UID2 == 0x03)) { +bool slix_check_card_type(FuriHalNfcDevData* nfc_data) { + if((nfc_data->uid[0] == 0xE0) + && (nfc_data->uid[1] == 0x04) + && (nfc_data->uid[2] == 0x01) + && (((nfc_data->uid[3] >> 4) & 3) == 2)) { + return true; + } + return false; +} + +bool slix2_check_card_type(FuriHalNfcDevData* nfc_data) { + if((nfc_data->uid[0] == 0xE0) + && (nfc_data->uid[1] == 0x04) + && (nfc_data->uid[2] == 0x01) + && (((nfc_data->uid[3] >> 4) & 3) == 1)) { + return true; + } + return false; +} + +bool slix_s_check_card_type(FuriHalNfcDevData* nfc_data) { + if((nfc_data->uid[0] == 0xE0) + && (nfc_data->uid[1] == 0x04) + && (nfc_data->uid[2] == 0x02)) { + return true; + } + return false; +} + +bool slix_l_check_card_type(FuriHalNfcDevData* nfc_data) { + if((nfc_data->uid[0] == 0xE0) + && (nfc_data->uid[1] == 0x04) + && (nfc_data->uid[2] == 0x03)) { return true; } return false; @@ -49,10 +80,10 @@ ReturnCode slix_l_unlock(uint32_t id, uint8_t* rand, uint32_t password) { uint8_t rxBuf[32]; uint8_t cmd_set_pass[] = { id, - rand[0] ^ ((password>>0) & 0xFF), - rand[1] ^ ((password>>8) & 0xFF), - rand[0] ^ ((password>>16) & 0xFF), - rand[1] ^ ((password>>24) & 0xFF) + rand[0] ^ ((password >> 0) & 0xFF), + rand[1] ^ ((password >> 8) & 0xFF), + rand[0] ^ ((password >> 16) & 0xFF), + rand[1] ^ ((password >> 24) & 0xFF) }; ReturnCode ret = rfalNfcvPollerTransceiveReq( diff --git a/lib/nfc/protocols/slix_l.h b/lib/nfc/protocols/slix.h similarity index 63% rename from lib/nfc/protocols/slix_l.h rename to lib/nfc/protocols/slix.h index fb7a9c4c0..0bcfe702a 100644 --- a/lib/nfc/protocols/slix_l.h +++ b/lib/nfc/protocols/slix.h @@ -10,8 +10,10 @@ #define ISO15693_MANUFACTURER_NXP 0x04 -bool slix_l_check_card_type(uint8_t UID0, uint8_t UID1, uint8_t UID2); - +bool slix_check_card_type(FuriHalNfcDevData* nfc_data); +bool slix2_check_card_type(FuriHalNfcDevData* nfc_data); +bool slix_s_check_card_type(FuriHalNfcDevData* nfc_data); +bool slix_l_check_card_type(FuriHalNfcDevData* nfc_data); ReturnCode slix_l_get_random(uint8_t* rand); ReturnCode slix_l_unlock(uint32_t id, uint8_t* rand, uint32_t password);