Skip to content

Commit

Permalink
Add elite keygen attack to UI
Browse files Browse the repository at this point in the history
  • Loading branch information
bettse committed Jun 21, 2024
1 parent 9997036 commit aa572f1
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 0 deletions.
1 change: 1 addition & 0 deletions scenes/picopass_scene_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ ADD_SCENE(picopass, nr_mac_saved, NrMacSaved)
ADD_SCENE(picopass, more_info, MoreInfo)
ADD_SCENE(picopass, formats, Formats)
ADD_SCENE(picopass, acknowledgements, Acknowledgements)
ADD_SCENE(picopass, elite_keygen_attack, EliteKeygenAttack)
145 changes: 145 additions & 0 deletions scenes/picopass_scene_elite_keygen_attack.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#include "../picopass_i.h"
#include <dolphin/dolphin.h>
#include "../picopass_elite_keygen.h"

#define PICOPASS_SCENE_DICT_ATTACK_KEYS_BATCH_UPDATE (10)
#define PICOPASS_SCENE_ELITE_KEYGEN_ATTACK_LIMIT (2000)

NfcCommand picopass_elite_keygen_attack_worker_callback(PicopassPollerEvent event, void* context) {
furi_assert(context);
NfcCommand command = NfcCommandContinue;

Picopass* picopass = context;

if(event.type == PicopassPollerEventTypeRequestMode) {
event.data->req_mode.mode = PicopassPollerModeRead;
} else if(event.type == PicopassPollerEventTypeRequestKey) {
uint8_t key[PICOPASS_KEY_LEN] = {};
bool is_key_provided = false;
if(picopass->dict_attack_ctx.current_key < PICOPASS_SCENE_ELITE_KEYGEN_ATTACK_LIMIT) {
picopass_elite_nextKey(key);
is_key_provided = true;
}

memcpy(event.data->req_key.key, key, PICOPASS_KEY_LEN);
event.data->req_key.is_elite_key = true;
event.data->req_key.is_key_provided = is_key_provided;
if(is_key_provided) {
picopass->dict_attack_ctx.current_key++;
if(picopass->dict_attack_ctx.current_key %
PICOPASS_SCENE_DICT_ATTACK_KEYS_BATCH_UPDATE ==
0) {
view_dispatcher_send_custom_event(
picopass->view_dispatcher, PicopassCustomEventDictAttackUpdateView);
}
}
} else if(
event.type == PicopassPollerEventTypeSuccess ||
event.type == PicopassPollerEventTypeFail ||
event.type == PicopassPollerEventTypeAuthFail) {
const PicopassDeviceData* data = picopass_poller_get_data(picopass->poller);
memcpy(&picopass->dev->dev_data, data, sizeof(PicopassDeviceData));
view_dispatcher_send_custom_event(
picopass->view_dispatcher, PicopassCustomEventPollerSuccess);
} else if(event.type == PicopassPollerEventTypeCardLost) {
picopass->dict_attack_ctx.card_detected = false;
view_dispatcher_send_custom_event(
picopass->view_dispatcher, PicopassCustomEventDictAttackUpdateView);
} else if(event.type == PicopassPollerEventTypeCardDetected) {
picopass->dict_attack_ctx.card_detected = true;
view_dispatcher_send_custom_event(
picopass->view_dispatcher, PicopassCustomEventDictAttackUpdateView);
}

return command;
}

static void picopass_scene_elite_keygen_attack_update_view(Picopass* instance) {
if(instance->dict_attack_ctx.card_detected) {
dict_attack_set_card_detected(instance->dict_attack);
dict_attack_set_header(instance->dict_attack, instance->dict_attack_ctx.name);
dict_attack_set_total_dict_keys(
instance->dict_attack, PICOPASS_SCENE_ELITE_KEYGEN_ATTACK_LIMIT);
dict_attack_set_current_dict_key(
instance->dict_attack, instance->dict_attack_ctx.current_key);
} else {
dict_attack_set_card_removed(instance->dict_attack);
}
}

static void picopass_scene_elite_keygen_attack_callback(void* context) {
Picopass* instance = context;

view_dispatcher_send_custom_event(
instance->view_dispatcher, PicopassCustomEventDictAttackSkip);
}

void picopass_scene_elite_keygen_attack_on_enter(void* context) {
Picopass* picopass = context;
dolphin_deed(DolphinDeedNfcRead);

// Setup dict attack context
uint32_t state = PicopassSceneEliteKeygenAttack;

picopass->dict = keys_dict_alloc(
PICOPASS_ICLASS_STANDARD_DICT_FLIPPER_NAME, KeysDictModeOpenExisting, PICOPASS_KEY_LEN);

dict_attack_reset(picopass->dict_attack);
picopass->dict_attack_ctx.card_detected = false;
picopass->dict_attack_ctx.total_keys = PICOPASS_SCENE_ELITE_KEYGEN_ATTACK_LIMIT;
picopass->dict_attack_ctx.current_key = 0;
picopass->dict_attack_ctx.name = "Elite Keygen Attack";
scene_manager_set_scene_state(picopass->scene_manager, PicopassSceneEliteKeygenAttack, state);

// Setup view
picopass_scene_elite_keygen_attack_update_view(picopass);
dict_attack_set_callback(
picopass->dict_attack, picopass_scene_elite_keygen_attack_callback, picopass);

// Start worker
picopass->poller = picopass_poller_alloc(picopass->nfc);
picopass_poller_start(
picopass->poller, picopass_elite_keygen_attack_worker_callback, picopass);

view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewDictAttack);
picopass_blink_start(picopass);
}

bool picopass_scene_elite_keygen_attack_on_event(void* context, SceneManagerEvent event) {
Picopass* picopass = context;
bool consumed = false;

if(event.type == SceneManagerEventTypeCustom) {
if(event.event == PicopassCustomEventPollerSuccess) {
scene_manager_next_scene(picopass->scene_manager, PicopassSceneReadCardSuccess);
consumed = true;
} else if(event.event == PicopassCustomEventDictAttackUpdateView) {
picopass_scene_elite_keygen_attack_update_view(picopass);
consumed = true;
} else if(event.event == PicopassCustomEventDictAttackSkip) {
scene_manager_next_scene(picopass->scene_manager, PicopassSceneReadCardSuccess);
consumed = true;
}
}
return consumed;
}

void picopass_scene_elite_keygen_attack_on_exit(void* context) {
Picopass* picopass = context;

if(picopass->dict) {
keys_dict_free(picopass->dict);
picopass->dict = NULL;
}
picopass->dict_attack_ctx.current_key = 0;
picopass->dict_attack_ctx.total_keys = 0;
picopass_elite_reset();

picopass_poller_stop(picopass->poller);
picopass_poller_free(picopass->poller);

// Clear view
popup_reset(picopass->popup);

picopass_blink_stop(picopass);
}
12 changes: 12 additions & 0 deletions scenes/picopass_scene_start.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ enum SubmenuIndex {
SubmenuIndexSaved,
SubmenuIndexLoclass,
SubmenuIndexAcknowledgements,
SubmenuIndexKeygenAttack,
};

void picopass_scene_start_submenu_callback(void* context, uint32_t index) {
Expand All @@ -26,6 +27,12 @@ void picopass_scene_start_on_enter(void* context) {
SubmenuIndexAcknowledgements,
picopass_scene_start_submenu_callback,
picopass);
submenu_add_item(
submenu,
"Elite Keygen Attack",
SubmenuIndexKeygenAttack,
picopass_scene_start_submenu_callback,
picopass);

submenu_set_selected_item(
submenu, scene_manager_get_scene_state(picopass->scene_manager, PicopassSceneStart));
Expand Down Expand Up @@ -60,6 +67,11 @@ bool picopass_scene_start_on_event(void* context, SceneManagerEvent event) {
picopass->scene_manager, PicopassSceneStart, PicopassSceneAcknowledgements);
scene_manager_next_scene(picopass->scene_manager, PicopassSceneAcknowledgements);
consumed = true;
} else if(event.event == SubmenuIndexKeygenAttack) {
scene_manager_set_scene_state(
picopass->scene_manager, PicopassSceneStart, SubmenuIndexKeygenAttack);
scene_manager_next_scene(picopass->scene_manager, PicopassSceneEliteKeygenAttack);
consumed = true;
}
}

Expand Down

0 comments on commit aa572f1

Please sign in to comment.