Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FL-3676] Slix disable privacy #3425

Merged
merged 17 commits into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions applications/main/nfc/helpers/slix_unlock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "slix_unlock.h"

#include <furi/furi.h>

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

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

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;
}
30 changes: 30 additions & 0 deletions applications/main/nfc/helpers/slix_unlock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once

#include <nfc/protocols/slix/slix.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef enum {
SlixUnlockMethodManual,
SlixUnlockMethodTonieBox,
} SlixUnlockMethod;

typedef struct SlixUnlock SlixUnlock;

SlixUnlock* slix_unlock_alloc();

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
2 changes: 2 additions & 0 deletions applications/main/nfc/nfc_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,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();

Expand Down Expand Up @@ -141,6 +142,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);

Expand Down
2 changes: 2 additions & 0 deletions applications/main/nfc/nfc_app_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <dialogs/dialogs.h>
#include <storage/storage.h>
Expand Down Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions applications/main/nfc/scenes/nfc_scene_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,9 @@ 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, slix_unlock_success, SlixUnlockSuccess)

ADD_SCENE(nfc, generate_info, GenerateInfo)
10 changes: 10 additions & 0 deletions applications/main/nfc/scenes/nfc_scene_extra_actions.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ enum SubmenuIndex {
SubmenuIndexReadCardType,
SubmenuIndexMfClassicKeys,
SubmenuIndexMfUltralightUnlock,
SubmenuIndexSlixUnlock,
};

void nfc_scene_extra_actions_submenu_callback(void* context, uint32_t index) {
Expand Down Expand Up @@ -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);
Expand All @@ -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);
}
Expand Down
6 changes: 5 additions & 1 deletion applications/main/nfc/scenes/nfc_scene_retry_confirm.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +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, NfcSceneMfClassicDictAttack)) {
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, NfcSceneMfClassicDictAttack)) {
consumed = scene_manager_search_and_switch_to_previous_scene(
nfc->scene_manager, NfcSceneMfClassicDictAttack);
} else if(scene_manager_has_previous_scene(
Expand Down
48 changes: 48 additions & 0 deletions applications/main/nfc/scenes/nfc_scene_slix_key_input.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include "../nfc_app_i.h"

#include <nfc/helpers/nfc_util.h>

void nfc_scene_slix_key_input_byte_input_callback(void* context) {
NfcApp* instance = context;

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

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->byte_input_store,
sizeof(SlixPassword));
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, "");
}
70 changes: 70 additions & 0 deletions applications/main/nfc/scenes/nfc_scene_slix_unlock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include "../nfc_app_i.h"

#include <nfc/protocols/slix/slix_poller.h>

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) {
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) {
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_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;
UNUSED(instance);
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;
}
} else if(event.type == SceneManagerEventTypeBack) {
consumed = scene_manager_search_and_switch_to_previous_scene(
instance->scene_manager, NfcSceneSlixUnlockMenu);
}

return consumed;
}

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);
}
60 changes: 60 additions & 0 deletions applications/main/nfc/scenes/nfc_scene_slix_unlock_menu.c
Original file line number Diff line number Diff line change
@@ -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 TommyBox",
gornekich marked this conversation as resolved.
Show resolved Hide resolved
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) {
slix_unlock_set_method(instance->slix_unlock, SlixUnlockMethodManual);
scene_manager_next_scene(instance->scene_manager, NfcSceneSlixKeyInput);
consumed = true;
} else if(event.event == SubmenuIndexSlixUnlockMenuTonieBox) {
slix_unlock_set_method(instance->slix_unlock, 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);
}
Loading
Loading