Prechádzať zdrojové kódy

Merge picopass from https://gitlab.com/bettse/picopass

Willy-JL 11 mesiacov pred
rodič
commit
4de5aef122

+ 3 - 0
picopass/.catalog/changelog.md

@@ -1,3 +1,6 @@
+## 1.18
+ - Added Save SR as legacy from saved menu
+ - Fix write key 'retry' when presented with new card
 ## 1.17
  - CVE-2024-41566: When keys are unknown emulate with a dummy MAC and ignore reader MACs
 ## 1.16

+ 1 - 1
picopass/application.fam

@@ -14,7 +14,7 @@ App(
     ],
     stack_size=4 * 1024,
     fap_description="App to communicate with NFC tags using the PicoPass(iClass) format",
-    fap_version="1.17",
+    fap_version="1.18",
     fap_icon="125_10px.png",
     fap_category="NFC",
     fap_libs=["mbedtls"],

+ 16 - 13
picopass/picopass_device.c

@@ -60,21 +60,26 @@ static bool picopass_device_save_file_seader(
         if(!flipper_format_write_hex(file, "Credential", pacs->credential, PICOPASS_BLOCK_LEN))
             break;
 
-        // Seader only captures 64 byte SIO so I'm going to leave it at that
-        uint8_t sio[64];
+        uint8_t start_block = 0;
 
         // TODO: save SR vs SE more properly
         if(pacs->sio) { // SR
-            for(uint8_t i = 0; i < 8; i++) {
-                memcpy(sio + (i * 8), card_data[10 + i].data, PICOPASS_BLOCK_LEN);
-            }
-            if(!flipper_format_write_hex(file, "SIO", sio, sizeof(sio))) break;
+            start_block = 10;
         } else if(pacs->se_enabled) { //SE
-            for(uint8_t i = 0; i < 8; i++) {
-                memcpy(sio + (i * 8), card_data[6 + i].data, PICOPASS_BLOCK_LEN);
-            }
-            if(!flipper_format_write_hex(file, "SIO", sio, sizeof(sio))) break;
+            start_block = 6;
         }
+
+        uint8_t sio[128];
+        size_t sio_length = card_data[start_block].data[1];
+        size_t block_count = (sio_length + PICOPASS_BLOCK_LEN - 1) / PICOPASS_BLOCK_LEN;
+        for(uint8_t i = 0; i < block_count; i++) {
+            memcpy(
+                sio + (i * PICOPASS_BLOCK_LEN),
+                card_data[start_block + i].data,
+                PICOPASS_BLOCK_LEN);
+        }
+        if(!flipper_format_write_hex(file, "SIO", sio, block_count * PICOPASS_BLOCK_LEN)) break;
+
         if(!flipper_format_write_hex(
                file, "Diversifier", card_data[PICOPASS_CSN_BLOCK_INDEX].data, PICOPASS_BLOCK_LEN))
             break;
@@ -503,11 +508,9 @@ void picopass_device_set_loading_callback(
 }
 
 void picopass_device_decrypt(uint8_t* enc_data, uint8_t* dec_data) {
-    uint8_t key[32] = {0};
-    memcpy(key, picopass_iclass_decryptionkey, sizeof(picopass_iclass_decryptionkey));
     mbedtls_des3_context ctx;
     mbedtls_des3_init(&ctx);
-    mbedtls_des3_set2key_dec(&ctx, key);
+    mbedtls_des3_set2key_dec(&ctx, picopass_iclass_decryptionkey);
     mbedtls_des3_crypt_ecb(&ctx, enc_data, dec_data);
     mbedtls_des3_free(&ctx);
 }

+ 19 - 0
picopass/scenes/picopass_scene_saved_menu.c

@@ -8,6 +8,7 @@ enum SubmenuIndex {
     SubmenuIndexDelete,
     SubmenuIndexSaveAsLF,
     SubmenuIndexSaveLegacy,
+    SubmenuIndexSaveAsSeader,
 };
 
 void picopass_scene_saved_menu_submenu_callback(void* context, uint32_t index) {
@@ -26,8 +27,11 @@ void picopass_scene_saved_menu_on_enter(void* context) {
     bool secured = (card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[7] & PICOPASS_FUSE_CRYPT10) !=
                    PICOPASS_FUSE_CRYPT0;
     bool no_credential = picopass_is_memset(pacs->credential, 0x00, sizeof(pacs->credential));
+    bool SE = card_data[PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX].valid &&
+              0x30 == card_data[PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX].data[0];
     bool SR = card_data[PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX].data[0] == 0xA3 &&
               card_data[10].valid && 0x30 == card_data[10].data[0];
+    bool has_sio = SE || SR;
 
     submenu_add_item(
         submenu, "Info", SubmenuIndexInfo, picopass_scene_saved_menu_submenu_callback, picopass);
@@ -40,6 +44,15 @@ void picopass_scene_saved_menu_on_enter(void* context) {
         picopass_scene_saved_menu_submenu_callback,
         picopass);
 
+    if(secured && has_sio) {
+        submenu_add_item(
+            submenu,
+            "Save in Seader fmt",
+            SubmenuIndexSaveAsSeader,
+            picopass_scene_saved_menu_submenu_callback,
+            picopass);
+    }
+
     if(secured && !no_credential) {
         submenu_add_item(
             submenu,
@@ -113,6 +126,12 @@ bool picopass_scene_saved_menu_on_event(void* context, SceneManagerEvent event)
             picopass->dev->format = PicopassDeviceSaveFormatLegacy;
             scene_manager_next_scene(picopass->scene_manager, PicopassSceneSaveName);
             consumed = true;
+        } else if(event.event == SubmenuIndexSaveAsSeader) {
+            scene_manager_set_scene_state(
+                picopass->scene_manager, PicopassSceneSavedMenu, event.event);
+            scene_manager_next_scene(picopass->scene_manager, PicopassSceneSaveName);
+            picopass->dev->format = PicopassDeviceSaveFormatSeader;
+            consumed = true;
         }
     }