From 36ebc4c102b4914d9415a9669a97eb59f691157f Mon Sep 17 00:00:00 2001 From: gornekich Date: Mon, 29 Jan 2024 16:40:31 +0000 Subject: [PATCH 01/15] slix: add unlock option --- applications/main/nfc/helpers/slix_unlock.c | 21 +++++++ applications/main/nfc/helpers/slix_unlock.h | 29 +++++++++ applications/main/nfc/nfc_app.c | 2 + applications/main/nfc/nfc_app_i.h | 2 + .../main/nfc/scenes/nfc_scene_config.h | 4 ++ .../main/nfc/scenes/nfc_scene_extra_actions.c | 10 ++++ .../nfc/scenes/nfc_scene_slix_key_input.c | 44 ++++++++++++++ .../main/nfc/scenes/nfc_scene_slix_unlock.c | 23 +++++++ .../nfc/scenes/nfc_scene_slix_unlock_menu.c | 60 +++++++++++++++++++ 9 files changed, 195 insertions(+) create mode 100644 applications/main/nfc/helpers/slix_unlock.c create mode 100644 applications/main/nfc/helpers/slix_unlock.h create mode 100644 applications/main/nfc/scenes/nfc_scene_slix_key_input.c create mode 100644 applications/main/nfc/scenes/nfc_scene_slix_unlock.c create mode 100644 applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c diff --git a/applications/main/nfc/helpers/slix_unlock.c b/applications/main/nfc/helpers/slix_unlock.c new file mode 100644 index 00000000000..4686149cdc7 --- /dev/null +++ b/applications/main/nfc/helpers/slix_unlock.c @@ -0,0 +1,21 @@ +#include "slix_unlock.h" + +#include + +SlixUnlock* slix_unlock_alloc() { + SlixUnlock* instance = malloc(sizeof(SlixUnlock)); + + return instance; +} + +void slix_unlock_free(SlixUnlock* instance) { + furi_assert(instance); + + free(instance); +} + +void slix_unlock_reset(SlixUnlock* instance) { + furi_assert(instance); + + memset(instance, 0, sizeof(SlixUnlock)); +} diff --git a/applications/main/nfc/helpers/slix_unlock.h b/applications/main/nfc/helpers/slix_unlock.h new file mode 100644 index 00000000000..da1c4e70988 --- /dev/null +++ b/applications/main/nfc/helpers/slix_unlock.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SLIX_PASSWORD_LEN (4) + +typedef enum { + SlixUnlockMethodManual, + SlixUnlockMethodTonieBox, +} SlixUnlockMethod; + +typedef struct { + SlixUnlockMethod method; + uint8_t password[SLIX_PASSWORD_LEN]; +} SlixUnlock; + +SlixUnlock* slix_unlock_alloc(); + +void slix_unlock_free(SlixUnlock* instance); + +void slix_unlock_reset(SlixUnlock* instance); + +#ifdef __cplusplus +} +#endif diff --git a/applications/main/nfc/nfc_app.c b/applications/main/nfc/nfc_app.c index 183f498951c..c6e0f17efc6 100644 --- a/applications/main/nfc/nfc_app.c +++ b/applications/main/nfc/nfc_app.c @@ -50,6 +50,7 @@ NfcApp* nfc_app_alloc() { instance->nfc = nfc_alloc(); instance->mf_ul_auth = mf_ultralight_auth_alloc(); + instance->slix_unlock = slix_unlock_alloc(); instance->mfc_key_cache = mf_classic_key_cache_alloc(); instance->nfc_supported_cards = nfc_supported_cards_alloc(); @@ -140,6 +141,7 @@ void nfc_app_free(NfcApp* instance) { nfc_free(instance->nfc); mf_ultralight_auth_free(instance->mf_ul_auth); + slix_unlock_free(instance->slix_unlock); mf_classic_key_cache_free(instance->mfc_key_cache); nfc_supported_cards_free(instance->nfc_supported_cards); diff --git a/applications/main/nfc/nfc_app_i.h b/applications/main/nfc/nfc_app_i.h index 943d722f824..40aa37461dc 100644 --- a/applications/main/nfc/nfc_app_i.h +++ b/applications/main/nfc/nfc_app_i.h @@ -32,6 +32,7 @@ #include "helpers/mfkey32_logger.h" #include "helpers/mf_classic_key_cache.h" #include "helpers/nfc_supported_cards.h" +#include "helpers/slix_unlock.h" #include #include @@ -129,6 +130,7 @@ struct NfcApp { NfcListener* listener; MfUltralightAuth* mf_ul_auth; + SlixUnlock* slix_unlock; NfcMfClassicDictAttackContext nfc_dict_context; Mfkey32Logger* mfkey32_logger; MfUserDict* mf_user_dict; diff --git a/applications/main/nfc/scenes/nfc_scene_config.h b/applications/main/nfc/scenes/nfc_scene_config.h index 70e7c3d468e..4585a7e350f 100644 --- a/applications/main/nfc/scenes/nfc_scene_config.h +++ b/applications/main/nfc/scenes/nfc_scene_config.h @@ -59,4 +59,8 @@ ADD_SCENE(nfc, set_sak, SetSak) ADD_SCENE(nfc, set_atqa, SetAtqa) ADD_SCENE(nfc, set_uid, SetUid) +ADD_SCENE(nfc, slix_unlock_menu, SlixUnlockMenu) +ADD_SCENE(nfc, slix_key_input, SlixKeyInput) +ADD_SCENE(nfc, slix_unlock, SlixUnlock) + ADD_SCENE(nfc, generate_info, GenerateInfo) diff --git a/applications/main/nfc/scenes/nfc_scene_extra_actions.c b/applications/main/nfc/scenes/nfc_scene_extra_actions.c index d14f80b6247..2943c0c55ca 100644 --- a/applications/main/nfc/scenes/nfc_scene_extra_actions.c +++ b/applications/main/nfc/scenes/nfc_scene_extra_actions.c @@ -4,6 +4,7 @@ enum SubmenuIndex { SubmenuIndexReadCardType, SubmenuIndexMfClassicKeys, SubmenuIndexMfUltralightUnlock, + SubmenuIndexSlixUnlock, }; void nfc_scene_extra_actions_submenu_callback(void* context, uint32_t index) { @@ -34,6 +35,12 @@ void nfc_scene_extra_actions_on_enter(void* context) { SubmenuIndexMfUltralightUnlock, nfc_scene_extra_actions_submenu_callback, instance); + submenu_add_item( + submenu, + "Unlock SLIX-L", + SubmenuIndexSlixUnlock, + nfc_scene_extra_actions_submenu_callback, + instance); submenu_set_selected_item( submenu, scene_manager_get_scene_state(instance->scene_manager, NfcSceneExtraActions)); view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewMenu); @@ -54,6 +61,9 @@ bool nfc_scene_extra_actions_on_event(void* context, SceneManagerEvent event) { } else if(event.event == SubmenuIndexReadCardType) { scene_manager_next_scene(instance->scene_manager, NfcSceneSelectProtocol); consumed = true; + } else if(event.event == SubmenuIndexSlixUnlock) { + scene_manager_next_scene(instance->scene_manager, NfcSceneSlixUnlockMenu); + consumed = true; } scene_manager_set_scene_state(instance->scene_manager, NfcSceneExtraActions, event.event); } diff --git a/applications/main/nfc/scenes/nfc_scene_slix_key_input.c b/applications/main/nfc/scenes/nfc_scene_slix_key_input.c new file mode 100644 index 00000000000..fc79955da62 --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_slix_key_input.c @@ -0,0 +1,44 @@ +#include "../nfc_app_i.h" + +void nfc_scene_slix_key_input_byte_input_callback(void* context) { + NfcApp* instance = context; + + view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventByteInputDone); +} + +void nfc_scene_slix_key_input_on_enter(void* context) { + NfcApp* instance = context; + + // Setup view + ByteInput* byte_input = instance->byte_input; + byte_input_set_header_text(byte_input, "Enter the password in hex"); + byte_input_set_result_callback( + byte_input, + nfc_scene_slix_key_input_byte_input_callback, + NULL, + instance, + instance->slix_unlock->password, + sizeof(instance->slix_unlock->password)); + view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewByteInput); +} + +bool nfc_scene_slix_key_input_on_event(void* context, SceneManagerEvent event) { + NfcApp* instance = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == NfcCustomEventByteInputDone) { + scene_manager_next_scene(instance->scene_manager, NfcSceneSlixUnlock); + consumed = true; + } + } + return consumed; +} + +void nfc_scene_slix_key_input_on_exit(void* context) { + NfcApp* instance = context; + + // Clear view + byte_input_set_result_callback(instance->byte_input, NULL, NULL, NULL, NULL, 0); + byte_input_set_header_text(instance->byte_input, ""); +} diff --git a/applications/main/nfc/scenes/nfc_scene_slix_unlock.c b/applications/main/nfc/scenes/nfc_scene_slix_unlock.c new file mode 100644 index 00000000000..99f7a0048d6 --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_slix_unlock.c @@ -0,0 +1,23 @@ +#include "../nfc_app_i.h" + +void nfc_scene_slix_unlock_on_enter(void* context) { + NfcApp* instance = context; + + popup_set_header(instance->popup, "Hello motor", 64, 32, AlignCenter, AlignCenter); + view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup); +} + +bool nfc_scene_slix_unlock_on_event(void* context, SceneManagerEvent event) { + NfcApp* instance = context; + bool consumed = false; + UNUSED(instance); + UNUSED(event); + + return consumed; +} + +void nfc_scene_slix_unlock_on_exit(void* context) { + NfcApp* instance = context; + + popup_reset(instance->popup); +} diff --git a/applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c b/applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c new file mode 100644 index 00000000000..307f42da627 --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c @@ -0,0 +1,60 @@ +#include "../nfc_app_i.h" + +enum SubmenuIndex { + SubmenuIndexSlixUnlockMenuManual, + SubmenuIndexSlixUnlockMenuTonieBox, +}; + +void nfc_scene_slix_unlock_menu_submenu_callback(void* context, uint32_t index) { + NfcApp* instance = context; + + view_dispatcher_send_custom_event(instance->view_dispatcher, index); +} + +void nfc_scene_slix_unlock_menu_on_enter(void* context) { + NfcApp* instance = context; + Submenu* submenu = instance->submenu; + + uint32_t state = + scene_manager_get_scene_state(instance->scene_manager, NfcSceneSlixUnlockMenu); + submenu_add_item( + submenu, + "Enter Password Manually", + SubmenuIndexSlixUnlockMenuManual, + nfc_scene_slix_unlock_menu_submenu_callback, + instance); + submenu_add_item( + submenu, + "Auth As TonieBox", + SubmenuIndexSlixUnlockMenuTonieBox, + nfc_scene_slix_unlock_menu_submenu_callback, + instance); + submenu_set_selected_item(submenu, state); + view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewMenu); +} + +bool nfc_scene_slix_unlock_menu_on_event(void* context, SceneManagerEvent event) { + NfcApp* instance = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SubmenuIndexSlixUnlockMenuManual) { + instance->slix_unlock->method = SlixUnlockMethodManual; + scene_manager_next_scene(instance->scene_manager, NfcSceneSlixKeyInput); + consumed = true; + } else if(event.event == SubmenuIndexSlixUnlockMenuTonieBox) { + instance->slix_unlock->method = SlixUnlockMethodTonieBox; + scene_manager_next_scene(instance->scene_manager, NfcSceneSlixUnlock); + consumed = true; + } + scene_manager_set_scene_state( + instance->scene_manager, NfcSceneSlixUnlockMenu, event.event); + } + return consumed; +} + +void nfc_scene_slix_unlock_menu_on_exit(void* context) { + NfcApp* instance = context; + + submenu_reset(instance->submenu); +} From 46151f881c2cdd6178f7ad294ff9252dd5c0dbbf Mon Sep 17 00:00:00 2001 From: gornekich Date: Tue, 30 Jan 2024 11:25:53 +0000 Subject: [PATCH 02/15] iso15693 poller: add more modes --- .../protocols/iso15693_3/iso15693_3_poller.c | 20 +++++++++++++++++-- .../protocols/iso15693_3/iso15693_3_poller.h | 7 +++++++ .../iso15693_3/iso15693_3_poller_i.h | 1 + 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/lib/nfc/protocols/iso15693_3/iso15693_3_poller.c b/lib/nfc/protocols/iso15693_3/iso15693_3_poller.c index cf27b1f3fd5..20192c22ef7 100644 --- a/lib/nfc/protocols/iso15693_3/iso15693_3_poller.c +++ b/lib/nfc/protocols/iso15693_3/iso15693_3_poller.c @@ -69,7 +69,20 @@ static NfcCommand iso15693_3_poller_run(NfcGenericEvent event, void* context) { NfcCommand command = NfcCommandContinue; if(nfc_event->type == NfcEventTypePollerReady) { - if(instance->state != Iso15693_3PollerStateActivated) { + if(instance->state == Iso15693_3PollerStateIdle) { + instance->iso15693_3_event.type = Iso15693_3PollerEventTypeRequestMode; + command = instance->callback(instance->general_event, instance->context); + if(instance->iso15693_3_event_data.mode == Iso15693_3PollerModeRead) { + instance->state = Iso15693_3PollerStateColResInProgress; + } else { + instance->state = Iso15693_3PollerStateBypass; + } + } + if(instance->state == Iso15693_3PollerStateBypass) { + instance->iso15693_3_event.type = Iso15693_3PollerEventTypeReady; + command = instance->callback(instance->general_event, instance->context); + } + if(instance->state == Iso15693_3PollerStateColResInProgress) { Iso15693_3Error error = iso15693_3_poller_activate(instance, instance->data); if(error == Iso15693_3ErrorNone) { instance->iso15693_3_event.type = Iso15693_3PollerEventTypeReady; @@ -81,8 +94,11 @@ static NfcCommand iso15693_3_poller_run(NfcGenericEvent event, void* context) { command = instance->callback(instance->general_event, instance->context); // Add delay to switch context furi_delay_ms(100); + instance->state = Iso15693_3PollerStateColResFailed; } - } else { + } + + if(instance->state == Iso15693_3PollerStateActivated) { instance->iso15693_3_event.type = Iso15693_3PollerEventTypeReady; instance->iso15693_3_event_data.error = Iso15693_3ErrorNone; command = instance->callback(instance->general_event, instance->context); diff --git a/lib/nfc/protocols/iso15693_3/iso15693_3_poller.h b/lib/nfc/protocols/iso15693_3/iso15693_3_poller.h index efe8337afac..16d918dcca7 100644 --- a/lib/nfc/protocols/iso15693_3/iso15693_3_poller.h +++ b/lib/nfc/protocols/iso15693_3/iso15693_3_poller.h @@ -19,13 +19,20 @@ typedef struct Iso15693_3Poller Iso15693_3Poller; typedef enum { Iso15693_3PollerEventTypeError, /**< An error occured during activation procedure. */ Iso15693_3PollerEventTypeReady, /**< The card was activated by the poller. */ + Iso15693_3PollerEventTypeRequestMode, } Iso15693_3PollerEventType; +typedef enum { + Iso15693_3PollerModeRead, + Iso15693_3PollerModeBypass, +} Iso15693_3PollerMode; + /** * @brief Iso15693_3 poller event data. */ typedef union { Iso15693_3Error error; /**< Error code indicating card activation fail reason. */ + Iso15693_3PollerMode mode; } Iso15693_3PollerEventData; /** diff --git a/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.h b/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.h index 346d0d724c5..77d797ac12c 100644 --- a/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.h +++ b/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.h @@ -14,6 +14,7 @@ extern "C" { typedef enum { Iso15693_3PollerStateIdle, + Iso15693_3PollerStateBypass, Iso15693_3PollerStateColResInProgress, Iso15693_3PollerStateColResFailed, Iso15693_3PollerStateActivated, From 868c3a05d1ef41913bf8ca3d6bedf5401cc0cd41 Mon Sep 17 00:00:00 2001 From: gornekich Date: Wed, 31 Jan 2024 15:49:19 +0000 Subject: [PATCH 03/15] Revert "iso15693 poller: add more modes" This reverts commit 46151f881c2cdd6178f7ad294ff9252dd5c0dbbf. --- .../protocols/iso15693_3/iso15693_3_poller.c | 20 ++----------------- .../protocols/iso15693_3/iso15693_3_poller.h | 7 ------- .../iso15693_3/iso15693_3_poller_i.h | 1 - 3 files changed, 2 insertions(+), 26 deletions(-) diff --git a/lib/nfc/protocols/iso15693_3/iso15693_3_poller.c b/lib/nfc/protocols/iso15693_3/iso15693_3_poller.c index 20192c22ef7..cf27b1f3fd5 100644 --- a/lib/nfc/protocols/iso15693_3/iso15693_3_poller.c +++ b/lib/nfc/protocols/iso15693_3/iso15693_3_poller.c @@ -69,20 +69,7 @@ static NfcCommand iso15693_3_poller_run(NfcGenericEvent event, void* context) { NfcCommand command = NfcCommandContinue; if(nfc_event->type == NfcEventTypePollerReady) { - if(instance->state == Iso15693_3PollerStateIdle) { - instance->iso15693_3_event.type = Iso15693_3PollerEventTypeRequestMode; - command = instance->callback(instance->general_event, instance->context); - if(instance->iso15693_3_event_data.mode == Iso15693_3PollerModeRead) { - instance->state = Iso15693_3PollerStateColResInProgress; - } else { - instance->state = Iso15693_3PollerStateBypass; - } - } - if(instance->state == Iso15693_3PollerStateBypass) { - instance->iso15693_3_event.type = Iso15693_3PollerEventTypeReady; - command = instance->callback(instance->general_event, instance->context); - } - if(instance->state == Iso15693_3PollerStateColResInProgress) { + if(instance->state != Iso15693_3PollerStateActivated) { Iso15693_3Error error = iso15693_3_poller_activate(instance, instance->data); if(error == Iso15693_3ErrorNone) { instance->iso15693_3_event.type = Iso15693_3PollerEventTypeReady; @@ -94,11 +81,8 @@ static NfcCommand iso15693_3_poller_run(NfcGenericEvent event, void* context) { command = instance->callback(instance->general_event, instance->context); // Add delay to switch context furi_delay_ms(100); - instance->state = Iso15693_3PollerStateColResFailed; } - } - - if(instance->state == Iso15693_3PollerStateActivated) { + } else { instance->iso15693_3_event.type = Iso15693_3PollerEventTypeReady; instance->iso15693_3_event_data.error = Iso15693_3ErrorNone; command = instance->callback(instance->general_event, instance->context); diff --git a/lib/nfc/protocols/iso15693_3/iso15693_3_poller.h b/lib/nfc/protocols/iso15693_3/iso15693_3_poller.h index 16d918dcca7..efe8337afac 100644 --- a/lib/nfc/protocols/iso15693_3/iso15693_3_poller.h +++ b/lib/nfc/protocols/iso15693_3/iso15693_3_poller.h @@ -19,20 +19,13 @@ typedef struct Iso15693_3Poller Iso15693_3Poller; typedef enum { Iso15693_3PollerEventTypeError, /**< An error occured during activation procedure. */ Iso15693_3PollerEventTypeReady, /**< The card was activated by the poller. */ - Iso15693_3PollerEventTypeRequestMode, } Iso15693_3PollerEventType; -typedef enum { - Iso15693_3PollerModeRead, - Iso15693_3PollerModeBypass, -} Iso15693_3PollerMode; - /** * @brief Iso15693_3 poller event data. */ typedef union { Iso15693_3Error error; /**< Error code indicating card activation fail reason. */ - Iso15693_3PollerMode mode; } Iso15693_3PollerEventData; /** diff --git a/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.h b/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.h index 77d797ac12c..346d0d724c5 100644 --- a/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.h +++ b/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.h @@ -14,7 +14,6 @@ extern "C" { typedef enum { Iso15693_3PollerStateIdle, - Iso15693_3PollerStateBypass, Iso15693_3PollerStateColResInProgress, Iso15693_3PollerStateColResFailed, Iso15693_3PollerStateActivated, From a5b19e606dc149f6f902244315dcd3d9566ad916 Mon Sep 17 00:00:00 2001 From: gornekich Date: Wed, 31 Jan 2024 18:48:09 +0000 Subject: [PATCH 04/15] slix: add features for nxp get info and signature commands --- lib/nfc/protocols/slix/slix.c | 2 +- lib/nfc/protocols/slix/slix.h | 3 ++ lib/nfc/protocols/slix/slix_i.h | 4 ++- lib/nfc/protocols/slix/slix_poller.c | 39 ++++++++++++++++---------- lib/nfc/protocols/slix/slix_poller_i.h | 1 + 5 files changed, 32 insertions(+), 17 deletions(-) diff --git a/lib/nfc/protocols/slix/slix.c b/lib/nfc/protocols/slix/slix.c index 12dc6750dd1..b575baa728f 100644 --- a/lib/nfc/protocols/slix/slix.c +++ b/lib/nfc/protocols/slix/slix.c @@ -338,7 +338,7 @@ const Iso15693_3Data* slix_get_base_data(const SlixData* data) { } SlixType slix_get_type(const SlixData* data) { - SlixType type = SlixTypeCount; + SlixType type = SlixTypeUnknown; do { if(iso15693_3_get_manufacturer_id(data->iso15693_3_data) != SLIX_NXP_MANUFACTURER_CODE) diff --git a/lib/nfc/protocols/slix/slix.h b/lib/nfc/protocols/slix/slix.h index f6c1453c5dd..e6a545f8b3c 100644 --- a/lib/nfc/protocols/slix/slix.h +++ b/lib/nfc/protocols/slix/slix.h @@ -37,6 +37,7 @@ extern "C" { #define SLIX_TYPE_FEATURE_EAS (1U << 4) #define SLIX_TYPE_FEATURE_SIGNATURE (1U << 5) #define SLIX_TYPE_FEATURE_PROTECTION (1U << 6) +#define SLIX_TYPE_FEATURE_NFC_SYSTEM_INFO (1U << 7) typedef uint32_t SlixTypeFeatures; @@ -56,7 +57,9 @@ typedef enum { SlixTypeSlixS, SlixTypeSlixL, SlixTypeSlix2, + SlixTypeCount, + SlixTypeUnknown, } SlixType; typedef enum { diff --git a/lib/nfc/protocols/slix/slix_i.h b/lib/nfc/protocols/slix/slix_i.h index b5e445f31d0..e596d38e0d9 100644 --- a/lib/nfc/protocols/slix/slix_i.h +++ b/lib/nfc/protocols/slix/slix_i.h @@ -39,7 +39,9 @@ extern "C" { #define SLIX_CMD_CUSTOM_END (0xBEU) #define SLIX_CMD_CUSTOM_COUNT (SLIX_CMD_CUSTOM_END - SLIX_CMD_CUSTOM_START) +// TODO SLIX_TYPE_FEATURE_NFC_SYSTEM_INFO? #define SLIX_TYPE_FEATURES_SLIX (SLIX_TYPE_FEATURE_EAS) +// TODO SLIX_TYPE_FEATURE_NFC_SYSTEM_INFO? #define SLIX_TYPE_FEATURES_SLIX_S \ (SLIX_TYPE_FEATURE_READ | SLIX_TYPE_FEATURE_WRITE | SLIX_TYPE_FEATURE_PRIVACY | \ SLIX_TYPE_FEATURE_DESTROY | SLIX_TYPE_FEATURE_EAS) @@ -48,7 +50,7 @@ extern "C" { #define SLIX_TYPE_FEATURES_SLIX2 \ (SLIX_TYPE_FEATURE_READ | SLIX_TYPE_FEATURE_WRITE | SLIX_TYPE_FEATURE_PRIVACY | \ SLIX_TYPE_FEATURE_DESTROY | SLIX_TYPE_FEATURE_EAS | SLIX_TYPE_FEATURE_SIGNATURE | \ - SLIX_TYPE_FEATURE_PROTECTION) + SLIX_TYPE_FEATURE_PROTECTION | SLIX_TYPE_FEATURE_NFC_SYSTEM_INFO) #define SLIX2_FEATURE_FLAGS \ (SLIX_FEATURE_FLAG_UM_PP | SLIX_FEATURE_FLAG_COUNTER | SLIX_FEATURE_FLAG_EAS_ID | \ diff --git a/lib/nfc/protocols/slix/slix_poller.c b/lib/nfc/protocols/slix/slix_poller.c index 46a17119436..5f05c9eb54e 100644 --- a/lib/nfc/protocols/slix/slix_poller.c +++ b/lib/nfc/protocols/slix/slix_poller.c @@ -44,28 +44,41 @@ static void slix_poller_free(SlixPoller* instance) { static NfcCommand slix_poller_handler_idle(SlixPoller* instance) { iso15693_3_copy( instance->data->iso15693_3_data, iso15693_3_poller_get_data(instance->iso15693_3_poller)); - - instance->poller_state = SlixPollerStateGetNxpSysInfo; + instance->type = slix_get_type(instance->data); + if(instance->type >= SlixTypeCount) { + instance->error = SlixErrorNotSupported; + instance->poller_state = SlixPollerStateError; + } else { + instance->poller_state = SlixPollerStateGetNxpSysInfo; + } return NfcCommandContinue; } static NfcCommand slix_poller_handler_get_nfc_system_info(SlixPoller* instance) { - instance->error = slix_poller_get_nxp_system_info(instance, &instance->data->system_info); - if(instance->error == SlixErrorNone) { - instance->poller_state = SlixPollerStateReadSignature; + if(slix_type_has_features(instance->type, SLIX_TYPE_FEATURE_NFC_SYSTEM_INFO)) { + instance->error = slix_poller_get_nxp_system_info(instance, &instance->data->system_info); + if(instance->error == SlixErrorNone) { + instance->poller_state = SlixPollerStateReadSignature; + } else { + instance->poller_state = SlixPollerStateError; + } } else { - instance->poller_state = SlixPollerStateError; + instance->poller_state = SlixPollerStateReadSignature; } return NfcCommandContinue; } static NfcCommand slix_poller_handler_read_signature(SlixPoller* instance) { - instance->error = slix_poller_read_signature(instance, &instance->data->signature); - if(instance->error == SlixErrorNone) { - instance->poller_state = SlixPollerStateReady; + if(slix_type_has_features(instance->type, SLIX_TYPE_FEATURE_SIGNATURE)) { + instance->error = slix_poller_read_signature(instance, &instance->data->signature); + if(instance->error == SlixErrorNone) { + instance->poller_state = SlixPollerStateReady; + } else { + instance->poller_state = SlixPollerStateError; + } } else { - instance->poller_state = SlixPollerStateError; + instance->poller_state = SlixPollerStateReady; } return NfcCommandContinue; @@ -138,11 +151,7 @@ static bool slix_poller_detect(NfcGenericEvent event, void* context) { bool protocol_detected = false; if(iso15693_3_event->type == Iso15693_3PollerEventTypeReady) { - if(slix_get_type(instance->data) < SlixTypeCount) { - SlixSystemInfo system_info = {}; - SlixError error = slix_poller_get_nxp_system_info(instance, &system_info); - protocol_detected = (error == SlixErrorNone); - } + protocol_detected = (slix_get_type(instance->data) < SlixTypeCount); } return protocol_detected; diff --git a/lib/nfc/protocols/slix/slix_poller_i.h b/lib/nfc/protocols/slix/slix_poller_i.h index 1fda1a7d246..90acfed637c 100644 --- a/lib/nfc/protocols/slix/slix_poller_i.h +++ b/lib/nfc/protocols/slix/slix_poller_i.h @@ -19,6 +19,7 @@ typedef enum { struct SlixPoller { Iso15693_3Poller* iso15693_3_poller; + SlixType type; SlixData* data; SlixPollerState poller_state; SlixError error; From 42b1503937700b517ff0ddcd31170f597626369c Mon Sep 17 00:00:00 2001 From: gornekich Date: Thu, 1 Feb 2024 22:12:12 +0000 Subject: [PATCH 05/15] slix: working unlock --- .../main/nfc/scenes/nfc_scene_config.h | 1 + .../main/nfc/scenes/nfc_scene_slix_unlock.c | 48 ++++++++++++- .../scenes/nfc_scene_slix_unlock_success.c | 56 +++++++++++++++ .../iso15693_3/iso15693_3_poller_i.c | 18 ++--- lib/nfc/protocols/slix/slix.h | 1 + lib/nfc/protocols/slix/slix_i.c | 27 +++++++ lib/nfc/protocols/slix/slix_i.h | 2 + lib/nfc/protocols/slix/slix_poller.c | 42 ++++++++++- lib/nfc/protocols/slix/slix_poller.h | 12 ++++ lib/nfc/protocols/slix/slix_poller_i.c | 71 ++++++++++++++++--- lib/nfc/protocols/slix/slix_poller_i.h | 4 ++ 11 files changed, 260 insertions(+), 22 deletions(-) create mode 100644 applications/main/nfc/scenes/nfc_scene_slix_unlock_success.c diff --git a/applications/main/nfc/scenes/nfc_scene_config.h b/applications/main/nfc/scenes/nfc_scene_config.h index 4585a7e350f..035c4949cf2 100644 --- a/applications/main/nfc/scenes/nfc_scene_config.h +++ b/applications/main/nfc/scenes/nfc_scene_config.h @@ -62,5 +62,6 @@ ADD_SCENE(nfc, set_uid, SetUid) ADD_SCENE(nfc, slix_unlock_menu, SlixUnlockMenu) ADD_SCENE(nfc, slix_key_input, SlixKeyInput) ADD_SCENE(nfc, slix_unlock, SlixUnlock) +ADD_SCENE(nfc, slix_unlock_success, SlixUnlockSuccess) ADD_SCENE(nfc, generate_info, GenerateInfo) diff --git a/applications/main/nfc/scenes/nfc_scene_slix_unlock.c b/applications/main/nfc/scenes/nfc_scene_slix_unlock.c index 99f7a0048d6..43cb3fcb81e 100644 --- a/applications/main/nfc/scenes/nfc_scene_slix_unlock.c +++ b/applications/main/nfc/scenes/nfc_scene_slix_unlock.c @@ -1,17 +1,56 @@ #include "../nfc_app_i.h" +#include + +NfcCommand nfc_scene_slix_unlock_worker_callback(NfcGenericEvent event, void* context) { + furi_assert(event.protocol == NfcProtocolSlix); + + NfcCommand command = NfcCommandContinue; + + NfcApp* instance = context; + SlixPollerEvent* slix_event = event.event_data; + if(slix_event->type == SlixPollerEventTypePrivacyUnlockRequest) { + slix_event->data->privacy_password.password = 0x5B6EFD7F; + slix_event->data->privacy_password.password_set = true; + } else if(slix_event->type == SlixPollerEventTypeError) { + view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerFailure); + } else if(slix_event->type == SlixPollerEventTypeReady) { + nfc_device_set_data( + instance->nfc_device, NfcProtocolSlix, nfc_poller_get_data(instance->poller)); + view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerSuccess); + command = NfcCommandStop; + } + + return command; +} + void nfc_scene_slix_unlock_on_enter(void* context) { NfcApp* instance = context; - popup_set_header(instance->popup, "Hello motor", 64, 32, AlignCenter, AlignCenter); + popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50); + popup_set_header(instance->popup, "Unlocking", 97, 15, AlignCenter, AlignTop); + popup_set_text( + instance->popup, "Apply card to\nFlipper's back", 97, 27, AlignCenter, AlignTop); view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup); + + instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolSlix); + nfc_poller_start(instance->poller, nfc_scene_slix_unlock_worker_callback, instance); } bool nfc_scene_slix_unlock_on_event(void* context, SceneManagerEvent event) { NfcApp* instance = context; - bool consumed = false; UNUSED(instance); - UNUSED(event); + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == NfcCustomEventPollerFailure) { + consumed = true; + } else if(event.event == NfcCustomEventPollerSuccess) { + notification_message(instance->notifications, &sequence_success); + scene_manager_next_scene(instance->scene_manager, NfcSceneSlixUnlockSuccess); + consumed = true; + } + } return consumed; } @@ -19,5 +58,8 @@ bool nfc_scene_slix_unlock_on_event(void* context, SceneManagerEvent event) { void nfc_scene_slix_unlock_on_exit(void* context) { NfcApp* instance = context; + nfc_poller_stop(instance->poller); + nfc_poller_free(instance->poller); + popup_reset(instance->popup); } diff --git a/applications/main/nfc/scenes/nfc_scene_slix_unlock_success.c b/applications/main/nfc/scenes/nfc_scene_slix_unlock_success.c new file mode 100644 index 00000000000..c39db7dd034 --- /dev/null +++ b/applications/main/nfc/scenes/nfc_scene_slix_unlock_success.c @@ -0,0 +1,56 @@ +#include "../nfc_app_i.h" + +static void nfc_scene_slix_unlock_success_widget_callback( + GuiButtonType result, + InputType type, + void* context) { + NfcApp* instance = context; + + if(type == InputTypeShort) { + view_dispatcher_send_custom_event(instance->view_dispatcher, result); + } +} + +void nfc_scene_slix_unlock_success_on_enter(void* context) { + NfcApp* instance = context; + + Widget* widget = instance->widget; + widget_add_string_element( + widget, 64, 32, AlignCenter, AlignCenter, FontSecondary, "Unlock success"); + widget_add_button_element( + widget, + GuiButtonTypeLeft, + "Retry", + nfc_scene_slix_unlock_success_widget_callback, + instance); + widget_add_button_element( + widget, + GuiButtonTypeRight, + "More", + nfc_scene_slix_unlock_success_widget_callback, + instance); + + view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewWidget); +} + +bool nfc_scene_slix_unlock_success_on_event(void* context, SceneManagerEvent event) { + NfcApp* instance = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == GuiButtonTypeLeft) { + consumed = scene_manager_previous_scene(instance->scene_manager); + } else if(event.event == GuiButtonTypeRight) { + scene_manager_next_scene(instance->scene_manager, NfcSceneSavedMenu); + consumed = true; + } + } + + return consumed; +} + +void nfc_scene_slix_unlock_success_on_exit(void* context) { + NfcApp* instance = context; + + widget_reset(instance->widget); +} diff --git a/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.c b/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.c index ca6f5435e3e..08f4e928336 100644 --- a/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.c +++ b/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.c @@ -32,15 +32,15 @@ static Iso15693_3Error iso15693_3_poller_filter_error(Iso15693_3Error error) { } } -static Iso15693_3Error iso15693_3_poller_prepare_trx(Iso15693_3Poller* instance) { - furi_assert(instance); +// static Iso15693_3Error iso15693_3_poller_prepare_trx(Iso15693_3Poller* instance) { +// furi_assert(instance); - if(instance->state == Iso15693_3PollerStateIdle) { - return iso15693_3_poller_activate(instance, NULL); - } +// if(instance->state == Iso15693_3PollerStateIdle) { +// return iso15693_3_poller_activate(instance, NULL); +// } - return Iso15693_3ErrorNone; -} +// return Iso15693_3ErrorNone; +// } static Iso15693_3Error iso15693_3_poller_frame_exchange( Iso15693_3Poller* instance, @@ -293,8 +293,8 @@ Iso15693_3Error iso15693_3_poller_send_frame( Iso15693_3Error ret; do { - ret = iso15693_3_poller_prepare_trx(instance); - if(ret != Iso15693_3ErrorNone) break; + // ret = iso15693_3_poller_prepare_trx(instance); + // if(ret != Iso15693_3ErrorNone) break; ret = iso15693_3_poller_frame_exchange(instance, tx_buffer, rx_buffer, fwt); } while(false); diff --git a/lib/nfc/protocols/slix/slix.h b/lib/nfc/protocols/slix/slix.h index e6a545f8b3c..26341072b2a 100644 --- a/lib/nfc/protocols/slix/slix.h +++ b/lib/nfc/protocols/slix/slix.h @@ -74,6 +74,7 @@ typedef enum { typedef uint32_t SlixPassword; typedef uint8_t SlixSignature[SLIX_SIGNATURE_SIZE]; typedef bool SlixPrivacy; +typedef uint16_t SlixRandomNumber; typedef struct { uint8_t pointer; diff --git a/lib/nfc/protocols/slix/slix_i.c b/lib/nfc/protocols/slix/slix_i.c index 97d66484c01..26ac80be9da 100644 --- a/lib/nfc/protocols/slix/slix_i.c +++ b/lib/nfc/protocols/slix/slix_i.c @@ -99,6 +99,33 @@ SlixError slix_read_signature_response_parse(SlixSignature data, const BitBuffer return error; } +SlixError slix_get_random_number_response_parse(SlixRandomNumber* data, const BitBuffer* buf) { + SlixError error = SlixErrorNone; + + do { + if(slix_error_response_parse(&error, buf)) break; + + typedef struct { + uint8_t flags; + uint8_t random_number[2]; + } SlixGetRandomNumberResponseLayout; + + const size_t size_received = bit_buffer_get_size_bytes(buf); + const size_t size_required = sizeof(SlixGetRandomNumberResponseLayout); + + if(size_received != size_required) { + error = SlixErrorFormat; + break; + } + + const SlixGetRandomNumberResponseLayout* response = + (const SlixGetRandomNumberResponseLayout*)bit_buffer_get_data(buf); + *data = (response->random_number[1] << 8) | response->random_number[0]; + } while(false); + + return error; +} + void slix_set_password(SlixData* data, SlixPasswordType password_type, SlixPassword password) { furi_assert(data); furi_assert(password_type < SlixPasswordTypeCount); diff --git a/lib/nfc/protocols/slix/slix_i.h b/lib/nfc/protocols/slix/slix_i.h index e596d38e0d9..ce9344a46e7 100644 --- a/lib/nfc/protocols/slix/slix_i.h +++ b/lib/nfc/protocols/slix/slix_i.h @@ -76,6 +76,8 @@ SlixError slix_get_nxp_system_info_response_parse(SlixData* data, const BitBuffe SlixError slix_read_signature_response_parse(SlixSignature data, const BitBuffer* buf); +SlixError slix_get_random_number_response_parse(SlixRandomNumber* data, const BitBuffer* buf); + // Setters void slix_set_password(SlixData* data, SlixPasswordType password_type, SlixPassword password); diff --git a/lib/nfc/protocols/slix/slix_poller.c b/lib/nfc/protocols/slix/slix_poller.c index 5f05c9eb54e..e0761827132 100644 --- a/lib/nfc/protocols/slix/slix_poller.c +++ b/lib/nfc/protocols/slix/slix_poller.c @@ -84,6 +84,43 @@ static NfcCommand slix_poller_handler_read_signature(SlixPoller* instance) { return NfcCommandContinue; } +static NfcCommand slix_poller_handler_privacy_unlock(SlixPoller* instance) { + NfcCommand command = NfcCommandContinue; + instance->poller_state = SlixPollerStateError; + + FURI_LOG_I(TAG, "Requesting password from app"); + instance->slix_event.type = SlixPollerEventTypePrivacyUnlockRequest; + command = instance->callback(instance->general_event, instance->context); + if(instance->slix_event_data.privacy_password.password_set) { + SlixPassword pwd = instance->slix_event_data.privacy_password.password; + FURI_LOG_I(TAG, "Received password %08lX from app", pwd); + instance->error = slix_poller_get_random_number(instance, &instance->random_number); + if(instance->error != SlixErrorNone) { + FURI_LOG_E(TAG, "Error in get random number: %d", instance->error); + } else { + FURI_LOG_I(TAG, "Received random number: %04X", instance->random_number); + instance->error = slix_poller_set_password(instance, SlixPasswordTypePrivacy, pwd); + if(instance->error != SlixErrorNone) { + FURI_LOG_E(TAG, "Error setting password: %d", instance->error); + command = NfcCommandReset; + instance->poller_state = SlixPollerStateError; + } else { + instance->data->passwords[SlixPasswordTypePrivacy] = pwd; + FURI_LOG_I(TAG, "Privacy mode disabled"); + instance->poller_state = SlixPollerStateIdle; + command = NfcCommandReset; + } + } + } else { + instance->error = SlixErrorTimeout; + instance->poller_state = SlixPollerStateError; + } + + furi_delay_ms(1000); + + return command; +} + static NfcCommand slix_poller_handler_error(SlixPoller* instance) { instance->slix_event_data.error = instance->error; instance->slix_event.type = SlixPollerEventTypeError; @@ -103,6 +140,7 @@ static const SlixPollerStateHandler slix_poller_state_handler[SlixPollerStateNum [SlixPollerStateError] = slix_poller_handler_error, [SlixPollerStateGetNxpSysInfo] = slix_poller_handler_get_nfc_system_info, [SlixPollerStateReadSignature] = slix_poller_handler_read_signature, + [SlixPollerStatePrivacyUnlock] = slix_poller_handler_privacy_unlock, [SlixPollerStateReady] = slix_poller_handler_ready, }; @@ -130,8 +168,8 @@ static NfcCommand slix_poller_run(NfcGenericEvent event, void* context) { if(iso15693_3_event->type == Iso15693_3PollerEventTypeReady) { command = slix_poller_state_handler[instance->poller_state](instance); } else if(iso15693_3_event->type == Iso15693_3PollerEventTypeError) { - instance->slix_event.type = SlixPollerEventTypeError; - command = instance->callback(instance->general_event, instance->context); + instance->poller_state = SlixPollerStatePrivacyUnlock; + command = slix_poller_state_handler[instance->poller_state](instance); } return command; diff --git a/lib/nfc/protocols/slix/slix_poller.h b/lib/nfc/protocols/slix/slix_poller.h index 62d60be5fe2..660bade07e4 100644 --- a/lib/nfc/protocols/slix/slix_poller.h +++ b/lib/nfc/protocols/slix/slix_poller.h @@ -18,14 +18,21 @@ typedef struct SlixPoller SlixPoller; */ typedef enum { SlixPollerEventTypeError, /**< An error occured while reading card. */ + SlixPollerEventTypePrivacyUnlockRequest, SlixPollerEventTypeReady, /**< The card was successfully read by the poller. */ } SlixPollerEventType; +typedef struct { + SlixPassword password; + bool password_set; +} SlixPollerEventDataPrivacyUnlockContext; + /** * @brief Slixs poller event data. */ typedef union { SlixError error; /**< Error code indicating card reaing fail reason. */ + SlixPollerEventDataPrivacyUnlockContext privacy_password; } SlixPollerEventData; /** @@ -80,6 +87,11 @@ SlixError slix_poller_get_nxp_system_info(SlixPoller* instance, SlixSystemInfo* */ SlixError slix_poller_read_signature(SlixPoller* instance, SlixSignature* data); +SlixError slix_poller_get_random_number(SlixPoller* instance, SlixRandomNumber* data); + +SlixError + slix_poller_set_password(SlixPoller* instance, SlixPasswordType type, SlixPassword password); + #ifdef __cplusplus } #endif diff --git a/lib/nfc/protocols/slix/slix_poller_i.c b/lib/nfc/protocols/slix/slix_poller_i.c index 6d7bdf37795..a891a36abb3 100644 --- a/lib/nfc/protocols/slix/slix_poller_i.c +++ b/lib/nfc/protocols/slix/slix_poller_i.c @@ -1,4 +1,5 @@ #include "slix_poller_i.h" +#include #include @@ -6,18 +7,22 @@ #define TAG "SlixPoller" -static void slix_poller_prepare_request(SlixPoller* instance, uint8_t command) { +static void slix_poller_prepare_request(SlixPoller* instance, uint8_t command, bool skip_uid) { bit_buffer_reset(instance->tx_buffer); bit_buffer_reset(instance->rx_buffer); - bit_buffer_append_byte( - instance->tx_buffer, - ISO15693_3_REQ_FLAG_SUBCARRIER_1 | ISO15693_3_REQ_FLAG_DATA_RATE_HI | - ISO15693_3_REQ_FLAG_T4_ADDRESSED); + uint8_t flags = ISO15693_3_REQ_FLAG_SUBCARRIER_1 | ISO15693_3_REQ_FLAG_DATA_RATE_HI; + if(!skip_uid) { + flags |= ISO15693_3_REQ_FLAG_T4_ADDRESSED; + } + + bit_buffer_append_byte(instance->tx_buffer, flags); bit_buffer_append_byte(instance->tx_buffer, command); bit_buffer_append_byte(instance->tx_buffer, SLIX_NXP_MANUFACTURER_CODE); - iso15693_3_append_uid(instance->data->iso15693_3_data, instance->tx_buffer); + if(!skip_uid) { + iso15693_3_append_uid(instance->data->iso15693_3_data, instance->tx_buffer); + } } SlixError slix_poller_send_frame( @@ -36,7 +41,7 @@ SlixError slix_poller_get_nxp_system_info(SlixPoller* instance, SlixSystemInfo* furi_assert(instance); furi_assert(data); - slix_poller_prepare_request(instance, SLIX_CMD_GET_NXP_SYSTEM_INFORMATION); + slix_poller_prepare_request(instance, SLIX_CMD_GET_NXP_SYSTEM_INFORMATION, false); SlixError error = SlixErrorNone; @@ -54,7 +59,7 @@ SlixError slix_poller_read_signature(SlixPoller* instance, SlixSignature* data) furi_assert(instance); furi_assert(data); - slix_poller_prepare_request(instance, SLIX_CMD_READ_SIGNATURE); + slix_poller_prepare_request(instance, SLIX_CMD_READ_SIGNATURE, false); SlixError error = SlixErrorNone; @@ -67,3 +72,53 @@ SlixError slix_poller_read_signature(SlixPoller* instance, SlixSignature* data) return error; } + +SlixError slix_poller_get_random_number(SlixPoller* instance, SlixRandomNumber* data) { + furi_assert(instance); + furi_assert(data); + + slix_poller_prepare_request(instance, SLIX_CMD_GET_RANDOM_NUMBER, true); + + SlixError error = SlixErrorNone; + + do { + error = slix_poller_send_frame( + instance, instance->tx_buffer, instance->rx_buffer, ISO15693_3_FDT_POLL_FC); + if(error != SlixErrorNone) break; + + error = slix_get_random_number_response_parse(data, instance->rx_buffer); + } while(false); + + return error; +} + +SlixError + slix_poller_set_password(SlixPoller* instance, SlixPasswordType type, SlixPassword password) { + furi_assert(instance); + + bool skip_uid = (type == SlixPasswordTypePrivacy); + slix_poller_prepare_request(instance, SLIX_CMD_SET_PASSWORD, skip_uid); + uint8_t password_type = (0x01 << type); + bit_buffer_append_byte(instance->tx_buffer, password_type); + uint8_t rn_l = instance->random_number >> 8; + uint8_t rn_h = instance->random_number; + uint32_t double_rand_num = (rn_h << 24) | (rn_l << 16) | (rn_h << 8) | rn_l; + uint32_t xored_password = double_rand_num ^ password; + uint8_t xored_password_arr[4] = {}; + nfc_util_num2bytes(xored_password, 4, xored_password_arr); + bit_buffer_append_bytes(instance->tx_buffer, xored_password_arr, 4); + + SlixError error = SlixErrorNone; + + do { + error = slix_poller_send_frame(instance, instance->tx_buffer, instance->rx_buffer, 0); + if(error != SlixErrorNone) break; + + size_t rx_len = bit_buffer_get_size_bytes(instance->rx_buffer); + if(rx_len != 1) { + error = SlixErrorWrongPassword; + } + } while(false); + + return error; +} diff --git a/lib/nfc/protocols/slix/slix_poller_i.h b/lib/nfc/protocols/slix/slix_poller_i.h index 90acfed637c..3e91f23579c 100644 --- a/lib/nfc/protocols/slix/slix_poller_i.h +++ b/lib/nfc/protocols/slix/slix_poller_i.h @@ -4,6 +4,8 @@ #include "slix_poller.h" +#define SLIX_POLLER_SET_PASSWORD_FWT (20000) + #ifdef __cplusplus extern "C" { #endif @@ -12,6 +14,7 @@ typedef enum { SlixPollerStateIdle, SlixPollerStateGetNxpSysInfo, SlixPollerStateReadSignature, + SlixPollerStatePrivacyUnlock, SlixPollerStateReady, SlixPollerStateError, SlixPollerStateNum, @@ -23,6 +26,7 @@ struct SlixPoller { SlixData* data; SlixPollerState poller_state; SlixError error; + SlixRandomNumber random_number; BitBuffer* tx_buffer; BitBuffer* rx_buffer; From 16725165bd3699ddc23bdf189492d6181fa09f42 Mon Sep 17 00:00:00 2001 From: gornekich Date: Sun, 4 Feb 2024 18:35:11 +0000 Subject: [PATCH 06/15] nfc app: rewrite slix unlock --- applications/main/nfc/helpers/slix_unlock.c | 43 +++++++++++++++++++ applications/main/nfc/helpers/slix_unlock.h | 15 ++++--- .../nfc/scenes/nfc_scene_slix_key_input.c | 6 ++- .../main/nfc/scenes/nfc_scene_slix_unlock.c | 6 ++- .../nfc/scenes/nfc_scene_slix_unlock_menu.c | 4 +- 5 files changed, 61 insertions(+), 13 deletions(-) diff --git a/applications/main/nfc/helpers/slix_unlock.c b/applications/main/nfc/helpers/slix_unlock.c index 4686149cdc7..931ec179059 100644 --- a/applications/main/nfc/helpers/slix_unlock.c +++ b/applications/main/nfc/helpers/slix_unlock.c @@ -2,6 +2,17 @@ #include +#define SLIX_UNLOCK_PASSWORD_NUM_MAX (2) + +struct SlixUnlock { + SlixUnlockMethod method; + SlixPassword password_arr[SLIX_UNLOCK_PASSWORD_NUM_MAX]; + size_t password_arr_len; + size_t password_idx; +}; + +static const SlixPassword tonie_box_pass_arr[] = {0x5B6EFD7F, 0x0F0F0F0F}; + SlixUnlock* slix_unlock_alloc() { SlixUnlock* instance = malloc(sizeof(SlixUnlock)); @@ -19,3 +30,35 @@ void slix_unlock_reset(SlixUnlock* instance) { memset(instance, 0, sizeof(SlixUnlock)); } + +void slix_unlock_set_method(SlixUnlock* instance, SlixUnlockMethod method) { + furi_assert(instance); + + instance->method = method; + if(method == SlixUnlockMethodTonieBox) { + instance->password_arr_len = COUNT_OF(tonie_box_pass_arr); + memcpy(instance->password_arr, tonie_box_pass_arr, sizeof(tonie_box_pass_arr)); + } +} + +void slix_unlock_set_password(SlixUnlock* instance, SlixPassword password) { + furi_assert(instance); + furi_assert(instance->method == SlixUnlockMethodManual); + + instance->password_arr[0] = password; + instance->password_arr_len = 1; +} + +bool slix_unlock_get_next_password(SlixUnlock* instance, SlixPassword* password) { + furi_assert(instance); + furi_assert(password); + + bool password_set = false; + if(instance->password_arr_len) { + *password = instance->password_arr[instance->password_idx++]; + instance->password_idx %= instance->password_arr_len; + password_set = true; + } + + return password_set; +} diff --git a/applications/main/nfc/helpers/slix_unlock.h b/applications/main/nfc/helpers/slix_unlock.h index da1c4e70988..c378891e4d9 100644 --- a/applications/main/nfc/helpers/slix_unlock.h +++ b/applications/main/nfc/helpers/slix_unlock.h @@ -1,22 +1,17 @@ #pragma once -#include +#include #ifdef __cplusplus extern "C" { #endif -#define SLIX_PASSWORD_LEN (4) - typedef enum { SlixUnlockMethodManual, SlixUnlockMethodTonieBox, } SlixUnlockMethod; -typedef struct { - SlixUnlockMethod method; - uint8_t password[SLIX_PASSWORD_LEN]; -} SlixUnlock; +typedef struct SlixUnlock SlixUnlock; SlixUnlock* slix_unlock_alloc(); @@ -24,6 +19,12 @@ void slix_unlock_free(SlixUnlock* instance); void slix_unlock_reset(SlixUnlock* instance); +void slix_unlock_set_method(SlixUnlock* instance, SlixUnlockMethod method); + +void slix_unlock_set_password(SlixUnlock* instance, SlixPassword password); + +bool slix_unlock_get_next_password(SlixUnlock* instance, SlixPassword* password); + #ifdef __cplusplus } #endif diff --git a/applications/main/nfc/scenes/nfc_scene_slix_key_input.c b/applications/main/nfc/scenes/nfc_scene_slix_key_input.c index fc79955da62..f11b4b6affa 100644 --- a/applications/main/nfc/scenes/nfc_scene_slix_key_input.c +++ b/applications/main/nfc/scenes/nfc_scene_slix_key_input.c @@ -3,6 +3,8 @@ void nfc_scene_slix_key_input_byte_input_callback(void* context) { NfcApp* instance = context; + SlixPassword password = *(uint32_t*)instance->byte_input_store; + slix_unlock_set_password(instance->slix_unlock, password); view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventByteInputDone); } @@ -17,8 +19,8 @@ void nfc_scene_slix_key_input_on_enter(void* context) { nfc_scene_slix_key_input_byte_input_callback, NULL, instance, - instance->slix_unlock->password, - sizeof(instance->slix_unlock->password)); + instance->byte_input_store, + sizeof(SlixPassword)); view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewByteInput); } diff --git a/applications/main/nfc/scenes/nfc_scene_slix_unlock.c b/applications/main/nfc/scenes/nfc_scene_slix_unlock.c index 43cb3fcb81e..612b3750642 100644 --- a/applications/main/nfc/scenes/nfc_scene_slix_unlock.c +++ b/applications/main/nfc/scenes/nfc_scene_slix_unlock.c @@ -10,8 +10,10 @@ NfcCommand nfc_scene_slix_unlock_worker_callback(NfcGenericEvent event, void* co NfcApp* instance = context; SlixPollerEvent* slix_event = event.event_data; if(slix_event->type == SlixPollerEventTypePrivacyUnlockRequest) { - slix_event->data->privacy_password.password = 0x5B6EFD7F; - slix_event->data->privacy_password.password_set = true; + SlixPassword pwd = 0; + bool get_password_success = slix_unlock_get_next_password(instance->slix_unlock, &pwd); + slix_event->data->privacy_password.password = pwd; + slix_event->data->privacy_password.password_set = get_password_success; } else if(slix_event->type == SlixPollerEventTypeError) { view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventPollerFailure); } else if(slix_event->type == SlixPollerEventTypeReady) { diff --git a/applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c b/applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c index 307f42da627..8d1fbf4d56a 100644 --- a/applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c +++ b/applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c @@ -39,11 +39,11 @@ bool nfc_scene_slix_unlock_menu_on_event(void* context, SceneManagerEvent event) if(event.type == SceneManagerEventTypeCustom) { if(event.event == SubmenuIndexSlixUnlockMenuManual) { - instance->slix_unlock->method = SlixUnlockMethodManual; + slix_unlock_set_method(instance->slix_unlock, SlixUnlockMethodManual); scene_manager_next_scene(instance->scene_manager, NfcSceneSlixKeyInput); consumed = true; } else if(event.event == SubmenuIndexSlixUnlockMenuTonieBox) { - instance->slix_unlock->method = SlixUnlockMethodTonieBox; + slix_unlock_set_method(instance->slix_unlock, SlixUnlockMethodTonieBox); scene_manager_next_scene(instance->scene_manager, NfcSceneSlixUnlock); consumed = true; } From ab624df40461e77e2d773e65cadf36198545f2ce Mon Sep 17 00:00:00 2001 From: gornekich Date: Sun, 4 Feb 2024 18:44:36 +0000 Subject: [PATCH 07/15] slix poller: simplify unlock state handler --- lib/nfc/protocols/slix/slix_poller.c | 40 ++++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/nfc/protocols/slix/slix_poller.c b/lib/nfc/protocols/slix/slix_poller.c index e0761827132..d9d38d10207 100644 --- a/lib/nfc/protocols/slix/slix_poller.c +++ b/lib/nfc/protocols/slix/slix_poller.c @@ -88,36 +88,36 @@ static NfcCommand slix_poller_handler_privacy_unlock(SlixPoller* instance) { NfcCommand command = NfcCommandContinue; instance->poller_state = SlixPollerStateError; - FURI_LOG_I(TAG, "Requesting password from app"); instance->slix_event.type = SlixPollerEventTypePrivacyUnlockRequest; command = instance->callback(instance->general_event, instance->context); - if(instance->slix_event_data.privacy_password.password_set) { + + bool slix_unlocked = false; + do { + if(!instance->slix_event_data.privacy_password.password_set) break; SlixPassword pwd = instance->slix_event_data.privacy_password.password; - FURI_LOG_I(TAG, "Received password %08lX from app", pwd); + FURI_LOG_I(TAG, "Trying to disable privacy mode with password: %08lX", pwd); + instance->error = slix_poller_get_random_number(instance, &instance->random_number); + if(instance->error != SlixErrorNone) break; + + instance->error = slix_poller_set_password(instance, SlixPasswordTypePrivacy, pwd); if(instance->error != SlixErrorNone) { - FURI_LOG_E(TAG, "Error in get random number: %d", instance->error); - } else { - FURI_LOG_I(TAG, "Received random number: %04X", instance->random_number); - instance->error = slix_poller_set_password(instance, SlixPasswordTypePrivacy, pwd); - if(instance->error != SlixErrorNone) { - FURI_LOG_E(TAG, "Error setting password: %d", instance->error); - command = NfcCommandReset; - instance->poller_state = SlixPollerStateError; - } else { - instance->data->passwords[SlixPasswordTypePrivacy] = pwd; - FURI_LOG_I(TAG, "Privacy mode disabled"); - instance->poller_state = SlixPollerStateIdle; - command = NfcCommandReset; - } + command = NfcCommandReset; + break; } - } else { + + FURI_LOG_I(TAG, "Privacy mode disabled"); + instance->data->passwords[SlixPasswordTypePrivacy] = pwd; + instance->poller_state = SlixPollerStateIdle; + slix_unlocked = true; + } while(false); + + if(!slix_unlocked) { instance->error = SlixErrorTimeout; instance->poller_state = SlixPollerStateError; + furi_delay_ms(100); } - furi_delay_ms(1000); - return command; } From 0441e580eb76bfe607ff7133ed3be266529cecf6 Mon Sep 17 00:00:00 2001 From: gornekich Date: Sun, 4 Feb 2024 18:51:33 +0000 Subject: [PATCH 08/15] nfc app: fix slix key setting --- applications/main/nfc/scenes/nfc_scene_slix_key_input.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/applications/main/nfc/scenes/nfc_scene_slix_key_input.c b/applications/main/nfc/scenes/nfc_scene_slix_key_input.c index f11b4b6affa..1724eea8df8 100644 --- a/applications/main/nfc/scenes/nfc_scene_slix_key_input.c +++ b/applications/main/nfc/scenes/nfc_scene_slix_key_input.c @@ -1,9 +1,11 @@ #include "../nfc_app_i.h" +#include + void nfc_scene_slix_key_input_byte_input_callback(void* context) { NfcApp* instance = context; - SlixPassword password = *(uint32_t*)instance->byte_input_store; + SlixPassword password = nfc_util_bytes2num(instance->byte_input_store, sizeof(SlixPassword)); slix_unlock_set_password(instance->slix_unlock, password); view_dispatcher_send_custom_event(instance->view_dispatcher, NfcCustomEventByteInputDone); } From 22f5151e8e5ed1d06ebc43f8e5d66a9db372ab74 Mon Sep 17 00:00:00 2001 From: gornekich Date: Sun, 4 Feb 2024 19:05:03 +0000 Subject: [PATCH 09/15] nfc app: fix navigation --- applications/main/nfc/scenes/nfc_scene_retry_confirm.c | 7 +++++-- applications/main/nfc/scenes/nfc_scene_slix_unlock.c | 3 +++ applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c | 2 +- .../main/nfc/scenes/nfc_scene_slix_unlock_success.c | 6 +++++- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/applications/main/nfc/scenes/nfc_scene_retry_confirm.c b/applications/main/nfc/scenes/nfc_scene_retry_confirm.c index 99acbb0b803..656d47e9f5d 100644 --- a/applications/main/nfc/scenes/nfc_scene_retry_confirm.c +++ b/applications/main/nfc/scenes/nfc_scene_retry_confirm.c @@ -28,8 +28,11 @@ bool nfc_scene_retry_confirm_on_event(void* context, SceneManagerEvent event) { if(event.event == DialogExResultRight) { consumed = scene_manager_previous_scene(nfc->scene_manager); } else if(event.event == DialogExResultLeft) { - if(scene_manager_has_previous_scene( - nfc->scene_manager, NfcSceneMfUltralightUnlockWarn)) { + if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneSlixUnlock)) { + consumed = scene_manager_search_and_switch_to_previous_scene( + nfc->scene_manager, NfcSceneSlixUnlock); + } else if(scene_manager_has_previous_scene( + nfc->scene_manager, NfcSceneMfUltralightUnlockWarn)) { consumed = scene_manager_search_and_switch_to_previous_scene( nfc->scene_manager, NfcSceneMfUltralightUnlockMenu); } else if(scene_manager_has_previous_scene(nfc->scene_manager, NfcSceneDetect)) { diff --git a/applications/main/nfc/scenes/nfc_scene_slix_unlock.c b/applications/main/nfc/scenes/nfc_scene_slix_unlock.c index 612b3750642..b01876e068a 100644 --- a/applications/main/nfc/scenes/nfc_scene_slix_unlock.c +++ b/applications/main/nfc/scenes/nfc_scene_slix_unlock.c @@ -52,6 +52,9 @@ bool nfc_scene_slix_unlock_on_event(void* context, SceneManagerEvent event) { scene_manager_next_scene(instance->scene_manager, NfcSceneSlixUnlockSuccess); consumed = true; } + } else if(event.type == SceneManagerEventTypeBack) { + consumed = scene_manager_search_and_switch_to_previous_scene( + instance->scene_manager, NfcSceneSlixUnlockMenu); } return consumed; diff --git a/applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c b/applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c index 8d1fbf4d56a..b069c4d7fcf 100644 --- a/applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c +++ b/applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c @@ -25,7 +25,7 @@ void nfc_scene_slix_unlock_menu_on_enter(void* context) { instance); submenu_add_item( submenu, - "Auth As TonieBox", + "Auth As ShmonieCox", SubmenuIndexSlixUnlockMenuTonieBox, nfc_scene_slix_unlock_menu_submenu_callback, instance); diff --git a/applications/main/nfc/scenes/nfc_scene_slix_unlock_success.c b/applications/main/nfc/scenes/nfc_scene_slix_unlock_success.c index c39db7dd034..c17ef1ca6a6 100644 --- a/applications/main/nfc/scenes/nfc_scene_slix_unlock_success.c +++ b/applications/main/nfc/scenes/nfc_scene_slix_unlock_success.c @@ -39,11 +39,15 @@ bool nfc_scene_slix_unlock_success_on_event(void* context, SceneManagerEvent eve if(event.type == SceneManagerEventTypeCustom) { if(event.event == GuiButtonTypeLeft) { - consumed = scene_manager_previous_scene(instance->scene_manager); + scene_manager_next_scene(instance->scene_manager, NfcSceneRetryConfirm); + consumed = true; } else if(event.event == GuiButtonTypeRight) { scene_manager_next_scene(instance->scene_manager, NfcSceneSavedMenu); consumed = true; } + } else if(event.type == SceneManagerEventTypeBack) { + scene_manager_next_scene(instance->scene_manager, NfcSceneExitConfirm); + consumed = true; } return consumed; From a37a81c023d312580b20c966f43e9f1d00573410 Mon Sep 17 00:00:00 2001 From: gornekich Date: Sun, 4 Feb 2024 19:23:24 +0000 Subject: [PATCH 10/15] slix poller: code clean up --- lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.c | 10 ---------- lib/nfc/protocols/slix/slix_poller_i.c | 5 ++++- lib/nfc/protocols/slix/slix_poller_i.h | 2 +- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.c b/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.c index 08f4e928336..430d3e7f09e 100644 --- a/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.c +++ b/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.c @@ -32,16 +32,6 @@ static Iso15693_3Error iso15693_3_poller_filter_error(Iso15693_3Error error) { } } -// static Iso15693_3Error iso15693_3_poller_prepare_trx(Iso15693_3Poller* instance) { -// furi_assert(instance); - -// if(instance->state == Iso15693_3PollerStateIdle) { -// return iso15693_3_poller_activate(instance, NULL); -// } - -// return Iso15693_3ErrorNone; -// } - static Iso15693_3Error iso15693_3_poller_frame_exchange( Iso15693_3Poller* instance, const BitBuffer* tx_buffer, diff --git a/lib/nfc/protocols/slix/slix_poller_i.c b/lib/nfc/protocols/slix/slix_poller_i.c index a891a36abb3..5000efceb04 100644 --- a/lib/nfc/protocols/slix/slix_poller_i.c +++ b/lib/nfc/protocols/slix/slix_poller_i.c @@ -98,8 +98,10 @@ SlixError bool skip_uid = (type == SlixPasswordTypePrivacy); slix_poller_prepare_request(instance, SLIX_CMD_SET_PASSWORD, skip_uid); + uint8_t password_type = (0x01 << type); bit_buffer_append_byte(instance->tx_buffer, password_type); + uint8_t rn_l = instance->random_number >> 8; uint8_t rn_h = instance->random_number; uint32_t double_rand_num = (rn_h << 24) | (rn_l << 16) | (rn_h << 8) | rn_l; @@ -111,7 +113,8 @@ SlixError SlixError error = SlixErrorNone; do { - error = slix_poller_send_frame(instance, instance->tx_buffer, instance->rx_buffer, 0); + error = slix_poller_send_frame( + instance, instance->tx_buffer, instance->rx_buffer, SLIX_POLLER_SET_PASSWORD_FWT); if(error != SlixErrorNone) break; size_t rx_len = bit_buffer_get_size_bytes(instance->rx_buffer); diff --git a/lib/nfc/protocols/slix/slix_poller_i.h b/lib/nfc/protocols/slix/slix_poller_i.h index 3e91f23579c..7a3b543b7b4 100644 --- a/lib/nfc/protocols/slix/slix_poller_i.h +++ b/lib/nfc/protocols/slix/slix_poller_i.h @@ -4,7 +4,7 @@ #include "slix_poller.h" -#define SLIX_POLLER_SET_PASSWORD_FWT (20000) +#define SLIX_POLLER_SET_PASSWORD_FWT (100000) #ifdef __cplusplus extern "C" { From 22728def060ed48071644cc90a945ef2d525dd0f Mon Sep 17 00:00:00 2001 From: gornekich Date: Sun, 4 Feb 2024 20:26:10 +0000 Subject: [PATCH 11/15] slix: resolve TODO, clean code --- .../iso15693_3/iso15693_3_poller_i.c | 23 +++---------------- lib/nfc/protocols/slix/slix_i.h | 2 -- 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.c b/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.c index 430d3e7f09e..94939030547 100644 --- a/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.c +++ b/lib/nfc/protocols/iso15693_3/iso15693_3_poller_i.c @@ -32,7 +32,7 @@ static Iso15693_3Error iso15693_3_poller_filter_error(Iso15693_3Error error) { } } -static Iso15693_3Error iso15693_3_poller_frame_exchange( +Iso15693_3Error iso15693_3_poller_send_frame( Iso15693_3Poller* instance, const BitBuffer* tx_buffer, BitBuffer* rx_buffer, @@ -146,7 +146,7 @@ Iso15693_3Error iso15693_3_poller_inventory(Iso15693_3Poller* instance, uint8_t* Iso15693_3Error ret; do { - ret = iso15693_3_poller_frame_exchange( + ret = iso15693_3_poller_send_frame( instance, instance->tx_buffer, instance->rx_buffer, ISO15693_3_FDT_POLL_FC); if(ret != Iso15693_3ErrorNone) break; @@ -173,7 +173,7 @@ Iso15693_3Error Iso15693_3Error ret; do { - ret = iso15693_3_poller_frame_exchange( + ret = iso15693_3_poller_send_frame( instance, instance->tx_buffer, instance->rx_buffer, ISO15693_3_FDT_POLL_FC); if(ret != Iso15693_3ErrorNone) break; @@ -274,20 +274,3 @@ Iso15693_3Error iso15693_3_poller_get_blocks_security( return ret; } - -Iso15693_3Error iso15693_3_poller_send_frame( - Iso15693_3Poller* instance, - const BitBuffer* tx_buffer, - BitBuffer* rx_buffer, - uint32_t fwt) { - Iso15693_3Error ret; - - do { - // ret = iso15693_3_poller_prepare_trx(instance); - // if(ret != Iso15693_3ErrorNone) break; - - ret = iso15693_3_poller_frame_exchange(instance, tx_buffer, rx_buffer, fwt); - } while(false); - - return ret; -} diff --git a/lib/nfc/protocols/slix/slix_i.h b/lib/nfc/protocols/slix/slix_i.h index ce9344a46e7..4a15b50ff4e 100644 --- a/lib/nfc/protocols/slix/slix_i.h +++ b/lib/nfc/protocols/slix/slix_i.h @@ -39,9 +39,7 @@ extern "C" { #define SLIX_CMD_CUSTOM_END (0xBEU) #define SLIX_CMD_CUSTOM_COUNT (SLIX_CMD_CUSTOM_END - SLIX_CMD_CUSTOM_START) -// TODO SLIX_TYPE_FEATURE_NFC_SYSTEM_INFO? #define SLIX_TYPE_FEATURES_SLIX (SLIX_TYPE_FEATURE_EAS) -// TODO SLIX_TYPE_FEATURE_NFC_SYSTEM_INFO? #define SLIX_TYPE_FEATURES_SLIX_S \ (SLIX_TYPE_FEATURE_READ | SLIX_TYPE_FEATURE_WRITE | SLIX_TYPE_FEATURE_PRIVACY | \ SLIX_TYPE_FEATURE_DESTROY | SLIX_TYPE_FEATURE_EAS) From f7c953fba7f72a2daa963bbddbba2690b58e4ee9 Mon Sep 17 00:00:00 2001 From: gornekich Date: Mon, 5 Feb 2024 10:30:19 +0000 Subject: [PATCH 12/15] nfc app: fix naming --- applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c b/applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c index b069c4d7fcf..78eb9884edb 100644 --- a/applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c +++ b/applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c @@ -25,7 +25,7 @@ void nfc_scene_slix_unlock_menu_on_enter(void* context) { instance); submenu_add_item( submenu, - "Auth As ShmonieCox", + "Auth As TommyBox", SubmenuIndexSlixUnlockMenuTonieBox, nfc_scene_slix_unlock_menu_submenu_callback, instance); From 80f3fea468e59b9d5421f1c23af9ef8134e545f0 Mon Sep 17 00:00:00 2001 From: gornekich Date: Mon, 5 Feb 2024 16:54:33 +0000 Subject: [PATCH 13/15] nfc app: rework slix unlock success scene --- .../nfc/scenes/nfc_scene_slix_unlock_success.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/applications/main/nfc/scenes/nfc_scene_slix_unlock_success.c b/applications/main/nfc/scenes/nfc_scene_slix_unlock_success.c index c17ef1ca6a6..f25eabab2ca 100644 --- a/applications/main/nfc/scenes/nfc_scene_slix_unlock_success.c +++ b/applications/main/nfc/scenes/nfc_scene_slix_unlock_success.c @@ -15,8 +15,19 @@ void nfc_scene_slix_unlock_success_on_enter(void* context) { NfcApp* instance = context; Widget* widget = instance->widget; - widget_add_string_element( - widget, 64, 32, AlignCenter, AlignCenter, FontSecondary, "Unlock success"); + widget_add_string_element(widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "SLIX Unlocked!"); + + FuriString* temp_str = furi_string_alloc_set_str("UID:"); + size_t uid_len = 0; + const uint8_t* uid = nfc_device_get_uid(instance->nfc_device, &uid_len); + for(size_t i = 0; i < uid_len; i++) { + furi_string_cat_printf(temp_str, " %02X", uid[i]); + } + furi_string_cat_printf(temp_str, "\nPrivacy Mode: Disabled"); + widget_add_string_multiline_element( + widget, 0, 12, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(temp_str)); + furi_string_free(temp_str); + widget_add_button_element( widget, GuiButtonTypeLeft, @@ -42,7 +53,7 @@ bool nfc_scene_slix_unlock_success_on_event(void* context, SceneManagerEvent eve scene_manager_next_scene(instance->scene_manager, NfcSceneRetryConfirm); consumed = true; } else if(event.event == GuiButtonTypeRight) { - scene_manager_next_scene(instance->scene_manager, NfcSceneSavedMenu); + scene_manager_next_scene(instance->scene_manager, NfcSceneReadMenu); consumed = true; } } else if(event.type == SceneManagerEventTypeBack) { From 881e2f5b394a76e336d6b06deb7862840b20ee46 Mon Sep 17 00:00:00 2001 From: gornekich Date: Mon, 5 Feb 2024 17:14:27 +0000 Subject: [PATCH 14/15] slix poller: add documentation --- lib/nfc/protocols/slix/slix_poller.h | 30 ++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/lib/nfc/protocols/slix/slix_poller.h b/lib/nfc/protocols/slix/slix_poller.h index 660bade07e4..4ea7f880d78 100644 --- a/lib/nfc/protocols/slix/slix_poller.h +++ b/lib/nfc/protocols/slix/slix_poller.h @@ -18,13 +18,16 @@ typedef struct SlixPoller SlixPoller; */ typedef enum { SlixPollerEventTypeError, /**< An error occured while reading card. */ - SlixPollerEventTypePrivacyUnlockRequest, + SlixPollerEventTypePrivacyUnlockRequest, /**< Poller requests password to disable privacy mode. */ SlixPollerEventTypeReady, /**< The card was successfully read by the poller. */ } SlixPollerEventType; +/** + * @brief Slix poller privacy unlock context data. + */ typedef struct { - SlixPassword password; - bool password_set; + SlixPassword password; /**< Privacy password. */ + bool password_set; /**< Filed to indicate that password was set or not. */ } SlixPollerEventDataPrivacyUnlockContext; /** @@ -32,7 +35,7 @@ typedef struct { */ typedef union { SlixError error; /**< Error code indicating card reaing fail reason. */ - SlixPollerEventDataPrivacyUnlockContext privacy_password; + SlixPollerEventDataPrivacyUnlockContext privacy_password; /**< Privacy unlock event context. */ } SlixPollerEventData; /** @@ -87,8 +90,27 @@ SlixError slix_poller_get_nxp_system_info(SlixPoller* instance, SlixSystemInfo* */ SlixError slix_poller_read_signature(SlixPoller* instance, SlixSignature* data); +/** + * @brief Get random number from card. + * + * Must ONLY be used inside the callback function. + * + * @param[in, out] instance pointer to the instance to be used in the transaction. + * @param[out] data pointer to the SlixRandomNumber structure to be filled. + * @return SlixErrorNone on success, an error code on failure. + */ SlixError slix_poller_get_random_number(SlixPoller* instance, SlixRandomNumber* data); +/** + * @brief Set password to card. + * + * Must ONLY be used inside the callback function. + * + * @param[in, out] instance pointer to the instance to be used in the transaction. + * @param[out] type SlixPasswordType instance. + * @param[out] password SlixPassword instance. + * @return SlixErrorNone on success, an error code on failure. + */ SlixError slix_poller_set_password(SlixPoller* instance, SlixPasswordType type, SlixPassword password); From 2b8a7df2014f76f78ee88505ee1dbc1134ac0ccf Mon Sep 17 00:00:00 2001 From: gornekich Date: Tue, 6 Feb 2024 14:11:15 +0000 Subject: [PATCH 15/15] slix listener: fix password comparison --- lib/nfc/protocols/slix/slix_listener.c | 2 +- lib/nfc/protocols/slix/slix_listener_i.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/nfc/protocols/slix/slix_listener.c b/lib/nfc/protocols/slix/slix_listener.c index 204be5ab91a..6ff39038085 100644 --- a/lib/nfc/protocols/slix/slix_listener.c +++ b/lib/nfc/protocols/slix/slix_listener.c @@ -63,7 +63,7 @@ static NfcCommand slix_listener_run(NfcGenericEvent event, void* context) { if(iso15693_3_event->type == Iso15693_3ListenerEventTypeCustomCommand) { const SlixError error = slix_listener_process_request(instance, rx_buffer); if(error == SlixErrorWrongPassword) { - command = NfcCommandStop; + command = NfcCommandSleep; } } diff --git a/lib/nfc/protocols/slix/slix_listener_i.c b/lib/nfc/protocols/slix/slix_listener_i.c index dfcb6c88017..15ab2cd3c83 100644 --- a/lib/nfc/protocols/slix/slix_listener_i.c +++ b/lib/nfc/protocols/slix/slix_listener_i.c @@ -31,7 +31,7 @@ static SlixPasswordType slix_listener_get_password_type_by_id(uint8_t id) { static SlixPassword slix_listener_unxor_password(const SlixPassword password_xored, uint16_t random) { - return password_xored ^ ((SlixPassword)random << 16 | random); + return REVERSE_BYTES_U32(password_xored ^ ((SlixPassword)random << 16 | random)); } static SlixError slix_listener_set_password(