From 8fca466ffdd4a2bf8d9eb4b4a188f9241cf1e5c9 Mon Sep 17 00:00:00 2001 From: Eric Betts Date: Fri, 2 Feb 2024 14:45:20 -0800 Subject: [PATCH 1/4] Picopass: Save written key to user dict if there is none --- picopass/helpers/iclass_elite_dict.c | 2 +- picopass/scenes/picopass_scene_write_key.c | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/picopass/helpers/iclass_elite_dict.c b/picopass/helpers/iclass_elite_dict.c index 5f0f41f8..f74f515f 100644 --- a/picopass/helpers/iclass_elite_dict.c +++ b/picopass/helpers/iclass_elite_dict.c @@ -147,7 +147,7 @@ bool iclass_elite_dict_add_key(IclassEliteDict* dict, uint8_t* key) { furi_assert(dict->stream); FuriString* key_str = furi_string_alloc(); - for(size_t i = 0; i < 6; i++) { + for(size_t i = 0; i < ICLASS_ELITE_KEY_LEN; i++) { furi_string_cat_printf(key_str, "%02X", key[i]); } furi_string_cat_printf(key_str, "\n"); diff --git a/picopass/scenes/picopass_scene_write_key.c b/picopass/scenes/picopass_scene_write_key.c index 67c39958..2d52b166 100644 --- a/picopass/scenes/picopass_scene_write_key.c +++ b/picopass/scenes/picopass_scene_write_key.c @@ -17,6 +17,15 @@ NfcCommand picopass_scene_write_key_poller_callback(PicopassPollerEvent event, v event.data->req_write_key.key, picopass->write_key_context.key_to_write, PICOPASS_KEY_LEN); + + // If there is no user dictionary, create it with the key they entered + // Prevent people who set all 0's from bricking their card + // TODO: Consider checking the elite user dict, when it exists, for the key + if(!iclass_elite_dict_check_presence(IclassEliteDictTypeUser)) { + IclassEliteDict* dict = iclass_elite_dict_alloc(IclassEliteDictTypeUser); + iclass_elite_dict_add_key(dict, picopass->write_key_context.key_to_write); + iclass_elite_dict_free(dict); + } event.data->req_write_key.is_elite_key = picopass->write_key_context.is_elite; } else if(event.type == PicopassPollerEventTypeSuccess) { view_dispatcher_send_custom_event( From f1467dfa814e2673ce5db516242eeaa19d100bb8 Mon Sep 17 00:00:00 2001 From: Eric Betts Date: Fri, 2 Feb 2024 14:45:35 -0800 Subject: [PATCH 2/4] ufbt format --- picopass/picopass_device.c | 8 ++++++-- picopass/protocol/picopass_listener.c | 13 ++++++++++--- picopass/protocol/picopass_listener_i.c | 4 +++- picopass/protocol/picopass_poller.c | 4 +++- picopass/scenes/picopass_scene_card_menu.c | 4 ++-- picopass/scenes/picopass_scene_more_info.c | 3 ++- picopass/scenes/picopass_scene_read_card_success.c | 4 ++-- 7 files changed, 28 insertions(+), 12 deletions(-) diff --git a/picopass/picopass_device.c b/picopass/picopass_device.c index 697beb09..3fb49bdf 100644 --- a/picopass/picopass_device.c +++ b/picopass/picopass_device.c @@ -197,13 +197,17 @@ static bool picopass_device_save_file( if(!flipper_format_write_comment_cstr(file, "Picopass blocks")) break; bool block_saved = true; - size_t app_limit = card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[0] < PICOPASS_MAX_APP_LIMIT ? + size_t app_limit = card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[0] < + PICOPASS_MAX_APP_LIMIT ? card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[0] : PICOPASS_MAX_APP_LIMIT; for(size_t i = 0; i < app_limit; i++) { furi_string_printf(temp_str, "Block %d", i); if(!flipper_format_write_hex( - file, furi_string_get_cstr(temp_str), card_data[i].data, PICOPASS_BLOCK_LEN)) { + file, + furi_string_get_cstr(temp_str), + card_data[i].data, + PICOPASS_BLOCK_LEN)) { block_saved = false; break; } diff --git a/picopass/protocol/picopass_listener.c b/picopass/protocol/picopass_listener.c index 60f3ab3b..eafb64dd 100644 --- a/picopass/protocol/picopass_listener.c +++ b/picopass/protocol/picopass_listener.c @@ -47,7 +47,10 @@ static void picopass_listener_loclass_update_csn(PicopassListener* instance) { uint8_t key[PICOPASS_BLOCK_LEN] = {}; loclass_iclass_calc_div_key(csn, picopass_iclass_key, key, false); - memcpy(instance->data->card_data[PICOPASS_SECURE_KD_BLOCK_INDEX].data, key, sizeof(PicopassBlock)); + memcpy( + instance->data->card_data[PICOPASS_SECURE_KD_BLOCK_INDEX].data, + key, + sizeof(PicopassBlock)); picopass_listener_init_cipher_state_key(instance, key); } @@ -176,7 +179,9 @@ PicopassListenerCommand } } else { bit_buffer_copy_bytes( - instance->tx_buffer, instance->data->card_data[block_num].data, sizeof(PicopassBlock)); + instance->tx_buffer, + instance->data->card_data[block_num].data, + sizeof(PicopassBlock)); } PicopassError error = picopass_listener_send_frame(instance, instance->tx_buffer); if(error != PicopassErrorNone) { @@ -530,7 +535,9 @@ PicopassListenerCommand } } else { bit_buffer_copy_bytes( - instance->tx_buffer, instance->data->card_data[block_num].data, sizeof(PicopassBlock)); + instance->tx_buffer, + instance->data->card_data[block_num].data, + sizeof(PicopassBlock)); } PicopassError error = picopass_listener_send_frame(instance, instance->tx_buffer); diff --git a/picopass/protocol/picopass_listener_i.c b/picopass/protocol/picopass_listener_i.c index 06dae64c..89b86993 100644 --- a/picopass/protocol/picopass_listener_i.c +++ b/picopass/protocol/picopass_listener_i.c @@ -21,7 +21,9 @@ static PicopassError picopass_listener_process_error(NfcError error) { void picopass_listener_init_cipher_state_key(PicopassListener* instance, const uint8_t* key) { uint8_t cc[PICOPASS_BLOCK_LEN] = {}; memcpy( - cc, instance->data->card_data[PICOPASS_SECURE_EPURSE_BLOCK_INDEX].data, sizeof(PicopassBlock)); + cc, + instance->data->card_data[PICOPASS_SECURE_EPURSE_BLOCK_INDEX].data, + sizeof(PicopassBlock)); instance->cipher_state = loclass_opt_doTagMAC_1(cc, key); } diff --git a/picopass/protocol/picopass_poller.c b/picopass/protocol/picopass_poller.c index d2adb74e..210ca094 100644 --- a/picopass/protocol/picopass_poller.c +++ b/picopass/protocol/picopass_poller.c @@ -455,7 +455,9 @@ NfcCommand picopass_poller_read_block_handler(PicopassPoller* instance) { block.data[6], block.data[7]); memcpy( - instance->data->card_data[instance->current_block].data, block.data, sizeof(PicopassBlock)); + instance->data->card_data[instance->current_block].data, + block.data, + sizeof(PicopassBlock)); instance->current_block++; } while(false); diff --git a/picopass/scenes/picopass_scene_card_menu.c b/picopass/scenes/picopass_scene_card_menu.c index 0a760f16..68081c4f 100644 --- a/picopass/scenes/picopass_scene_card_menu.c +++ b/picopass/scenes/picopass_scene_card_menu.c @@ -28,8 +28,8 @@ void picopass_scene_card_menu_on_enter(void* context) { bool zero_config = picopass_is_memset( card_data[PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX].data, 0x00, PICOPASS_BLOCK_LEN); bool no_credential = picopass_is_memset(pacs->credential, 0x00, sizeof(pacs->credential)); - bool no_key = - picopass_is_memset(card_data[PICOPASS_SECURE_KD_BLOCK_INDEX].data, 0xFF, PICOPASS_BLOCK_LEN); + bool no_key = picopass_is_memset( + card_data[PICOPASS_SECURE_KD_BLOCK_INDEX].data, 0xFF, PICOPASS_BLOCK_LEN); if(secured && zero_config) { submenu_add_item( diff --git a/picopass/scenes/picopass_scene_more_info.c b/picopass/scenes/picopass_scene_more_info.c index 5ced6403..4c075825 100644 --- a/picopass/scenes/picopass_scene_more_info.c +++ b/picopass/scenes/picopass_scene_more_info.c @@ -19,7 +19,8 @@ void picopass_scene_more_info_on_enter(void* context) { for(size_t i = 0; i < app_limit; i++) { for(size_t j = 0; j < PICOPASS_BLOCK_LEN; j += 2) { - furi_string_cat_printf(str, "%02X%02X ", card_data[i].data[j], card_data[i].data[j + 1]); + furi_string_cat_printf( + str, "%02X%02X ", card_data[i].data[j], card_data[i].data[j + 1]); } } diff --git a/picopass/scenes/picopass_scene_read_card_success.c b/picopass/scenes/picopass_scene_read_card_success.c index 6f788331..9ccaaf6b 100644 --- a/picopass/scenes/picopass_scene_read_card_success.c +++ b/picopass/scenes/picopass_scene_read_card_success.c @@ -133,8 +133,8 @@ void picopass_scene_read_card_success_on_enter(void* context) { furi_string_cat_printf(credential_str, " +SIO"); } - bool no_key = - picopass_is_memset(card_data[PICOPASS_SECURE_KD_BLOCK_INDEX].data, 0xFF, PICOPASS_BLOCK_LEN); + bool no_key = picopass_is_memset( + card_data[PICOPASS_SECURE_KD_BLOCK_INDEX].data, 0xFF, PICOPASS_BLOCK_LEN); if(no_key) { furi_string_cat_printf(key_str, "No Key: used NR-MAC"); From 5f4859345eff4321d1886a0e0b77b7c63c5b0d11 Mon Sep 17 00:00:00 2001 From: Eric Betts Date: Tue, 6 Feb 2024 17:02:15 -0800 Subject: [PATCH 3/4] Save key before poller runs --- picopass/scenes/picopass_scene_write_key.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/picopass/scenes/picopass_scene_write_key.c b/picopass/scenes/picopass_scene_write_key.c index 2d52b166..7ba5e419 100644 --- a/picopass/scenes/picopass_scene_write_key.c +++ b/picopass/scenes/picopass_scene_write_key.c @@ -18,14 +18,6 @@ NfcCommand picopass_scene_write_key_poller_callback(PicopassPollerEvent event, v picopass->write_key_context.key_to_write, PICOPASS_KEY_LEN); - // If there is no user dictionary, create it with the key they entered - // Prevent people who set all 0's from bricking their card - // TODO: Consider checking the elite user dict, when it exists, for the key - if(!iclass_elite_dict_check_presence(IclassEliteDictTypeUser)) { - IclassEliteDict* dict = iclass_elite_dict_alloc(IclassEliteDictTypeUser); - iclass_elite_dict_add_key(dict, picopass->write_key_context.key_to_write); - iclass_elite_dict_free(dict); - } event.data->req_write_key.is_elite_key = picopass->write_key_context.is_elite; } else if(event.type == PicopassPollerEventTypeSuccess) { view_dispatcher_send_custom_event( @@ -53,6 +45,15 @@ void picopass_scene_write_key_on_enter(void* context) { view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewPopup); picopass_blink_start(picopass); + // If there is no user dictionary, create it with the key they entered + // Prevent people who set all 0's from bricking their card + // TODO: Consider checking the elite user dict, when it exists, for the key + if(!iclass_elite_dict_check_presence(IclassEliteDictTypeUser)) { + IclassEliteDict* dict = iclass_elite_dict_alloc(IclassEliteDictTypeUser); + iclass_elite_dict_add_key(dict, picopass->write_key_context.key_to_write); + iclass_elite_dict_free(dict); + } + picopass->poller = picopass_poller_alloc(picopass->nfc); picopass_poller_start(picopass->poller, picopass_scene_write_key_poller_callback, picopass); } From 97d2063f4760e69713bdf46110203095e9d2ce9a Mon Sep 17 00:00:00 2001 From: Eric Betts Date: Thu, 8 Feb 2024 17:06:38 -0800 Subject: [PATCH 4/4] Create folders if they don't exist --- picopass/scenes/picopass_scene_write_key.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/picopass/scenes/picopass_scene_write_key.c b/picopass/scenes/picopass_scene_write_key.c index 7ba5e419..b4f716f6 100644 --- a/picopass/scenes/picopass_scene_write_key.c +++ b/picopass/scenes/picopass_scene_write_key.c @@ -49,6 +49,8 @@ void picopass_scene_write_key_on_enter(void* context) { // Prevent people who set all 0's from bricking their card // TODO: Consider checking the elite user dict, when it exists, for the key if(!iclass_elite_dict_check_presence(IclassEliteDictTypeUser)) { + storage_simply_mkdir(picopass->dev->storage, STORAGE_APP_DATA_PATH_PREFIX); + storage_simply_mkdir(picopass->dev->storage, APP_DATA_PATH("assets")); IclassEliteDict* dict = iclass_elite_dict_alloc(IclassEliteDictTypeUser); iclass_elite_dict_add_key(dict, picopass->write_key_context.key_to_write); iclass_elite_dict_free(dict);