Просмотр исходного кода

Picopass save written key (#126)

Co-authored-by: あく <alleteam@gmail.com>
Eric Betts 1 год назад
Родитель
Сommit
4987eed622

+ 1 - 1
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");

+ 6 - 2
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;
                 }

+ 10 - 3
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);

+ 3 - 1
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);
 }

+ 3 - 1
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);
 

+ 2 - 2
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(

+ 2 - 1
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]);
         }
     }
 

+ 2 - 2
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");

+ 12 - 0
scenes/picopass_scene_write_key.c

@@ -17,6 +17,7 @@ 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);
+
         event.data->req_write_key.is_elite_key = picopass->write_key_context.is_elite;
     } else if(event.type == PicopassPollerEventTypeSuccess) {
         view_dispatcher_send_custom_event(
@@ -44,6 +45,17 @@ 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)) {
+        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);
+    }
+
     picopass->poller = picopass_poller_alloc(picopass->nfc);
     picopass_poller_start(picopass->poller, picopass_scene_write_key_poller_callback, picopass);
 }