2 Commits 11b1951b2a ... 66fdb15378

Author SHA1 Message Date
  Daniele Lacamera 66fdb15378 Experiments with second disk 10 months ago
  Daniele Lacamera f49e1a5eb7 Added read-only USB drive with host utils for linux 10 months ago
11 changed files with 371 additions and 176 deletions
  1. 1 0
      CMakeLists.txt
  2. 1 0
      README.md
  3. 21 2
      msc_content/Makefile
  4. 12 1
      pico-sdk/src/rp2_common/pico_standard_link/memmap_default.ld
  5. 33 0
      src/cryptoengine.c
  6. 7 0
      src/cryptoengine.h
  7. 2 0
      src/flash.h
  8. 8 1
      src/fsm.c
  9. 283 165
      src/msc_disk.c
  10. 1 4
      src/password_safe.c
  11. 2 3
      src/ui.c

+ 1 - 0
CMakeLists.txt

@@ -25,6 +25,7 @@ target_sources(${PROJECT} PUBLIC
         ${CMAKE_CURRENT_SOURCE_DIR}/src/fsm.c
         ${CMAKE_CURRENT_SOURCE_DIR}/src/flash.c
         ${CMAKE_CURRENT_SOURCE_DIR}/src/hid.c
+        ${CMAKE_CURRENT_SOURCE_DIR}/src/disk0.c
         ${CMAKE_CURRENT_SOURCE_DIR}/lib/wolfssl/wolfcrypt/src/wc_port.c
         ${CMAKE_CURRENT_SOURCE_DIR}/lib/wolfssl/wolfcrypt/src/wolfmath.c
         ${CMAKE_CURRENT_SOURCE_DIR}/lib/wolfssl/wolfcrypt/src/hash.c

+ 1 - 0
README.md

@@ -164,6 +164,7 @@ To compile the firmware run the following from the source directory:
 ```
 mkdir build
 cd build
+make -C ../msc_content
 cmake .. -DFAMILY=rp2040 -DPICO_SDK_PATH=/path/to/motenpoche/pico-sdk
 ```
 

+ 21 - 2
msc_content/Makefile

@@ -1,7 +1,26 @@
-all: mep 
+all: ../src/disk0.c
 	
 mep: mep.c
 	gcc -g -ggdb -o mep mep.c -lwolfssl
 
+../src/disk0.c: mep FORCE
+	dd if=/dev/zero of=disk0.img bs=1K count=128
+	sudo mkfs.vfat disk0.img
+	sudo mkdir -p tmpfs
+	sudo mount -o loop disk0.img tmpfs
+	sudo mkdir -p tmpfs/mep
+	sudo cp mep.c mep tmpfs/mep
+	sudo cp Makefile.flash tmpfs/mep/Makefile
+	sudo cp ../README.md tmpfs
+	sudo umount tmpfs
+	xxd -i disk0.img | sed -e "s/unsigned/const unsigned/g" \
+	   | sed -e "s/char/char __attribute__((section(\".disk0\")))/g" > ../src/disk0.c 
+	
+
 clean:
-	rm -f mep
+	rm -f mep fatfs ../fatfs.ld
+	sudo umount tmpfs || true
+	sudo rm -rf tmpfs
+
+FORCE: 
+

+ 12 - 1
pico-sdk/src/rp2_common/pico_standard_link/memmap_default.ld

@@ -21,6 +21,7 @@
     __stack (== StackTop)
 */
 
+
 MEMORY
 {
     FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 2048k
@@ -93,6 +94,13 @@ SECTIONS
         *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*)))
         . = ALIGN(4);
     } > FLASH
+    
+    .fatfs_rodata : {
+        . = ALIGN(512);
+        __fatfs_start = .;
+        KEEP(*(.disk0*));
+        __fatfs_end = .;
+    } > FLASH
 
     .ARM.extab :
     {
@@ -115,7 +123,8 @@ SECTIONS
         *(.binary_info.*)
     } > FLASH
     __binary_info_end = .;
-    . = ALIGN(4);
+
+
 
     /* End of .text-like segments */
     __etext = .;
@@ -178,6 +187,7 @@ SECTIONS
         . = ALIGN(4);
         *(.uninitialized_data*)
     } > RAM
+    
 
     /* Start and end symbols must be word-aligned */
     .scratch_x : {
@@ -234,6 +244,7 @@ SECTIONS
     .flash_end : {
         __flash_binary_end = .;
     } > FLASH
+    
 
     /* stack limit is poorly named, but historically is maximum heap ptr */
     __StackLimit = ORIGIN(RAM) + LENGTH(RAM);

+ 33 - 0
src/cryptoengine.c

@@ -41,6 +41,39 @@ static ecc_key ecc;
 static struct vault_service svc_cache;
 static int svc_cache_id = -1;
 
+int flash_decrypt_read_sector(uint32_t sector, uint8_t *buf)
+{
+    if (cryptoengine_check_vault() < 0)
+        return -1;
+    if (fsm_get() < VAULT_MAIN_MENU)
+        return -1;
+    if ((sector * SPI_FLASH_SECTOR_SIZE) >= DRIVE_FLASH_SIZE)
+        return -1;
+    flash_read(DRIVE_FLASH_OFFSET + sector * SPI_FLASH_SECTOR_SIZE, buf,
+            SPI_FLASH_SECTOR_SIZE);
+    wc_Chacha_SetIV(&cha, hdr_cache.host_seed, sector);
+    wc_Chacha_Process(&cha, buf, buf, SPI_FLASH_SECTOR_SIZE);
+    return 0;
+}
+
+int flash_encrypt_write_sector(uint32_t sector, uint8_t *buf)
+{
+    if (cryptoengine_check_vault() < 0)
+        return -1;
+    if (fsm_get() < VAULT_MAIN_MENU)
+        return -1;
+    if ((sector * SPI_FLASH_SECTOR_SIZE) >= DRIVE_FLASH_SIZE)
+        return -1;
+    wc_Chacha_SetIV(&cha, hdr_cache.host_seed, sector);
+    wc_Chacha_Process(&cha, buf, buf, SPI_FLASH_SECTOR_SIZE);
+
+    flash_sector_erase(DRIVE_FLASH_OFFSET + sector * SPI_FLASH_SECTOR_SIZE);
+
+    flash_write(DRIVE_FLASH_OFFSET + sector * SPI_FLASH_SECTOR_SIZE, buf,
+            SPI_FLASH_SECTOR_SIZE);
+    return 0;
+}
+
 int flash_decrypt_read_svc(struct vault_service *out, uint32_t addr)
 {
     if (cryptoengine_check_vault() < 0)

+ 7 - 0
src/cryptoengine.h

@@ -32,6 +32,9 @@
 #define VAULT_FLASH_OFFSET 0x00000000
 #define VAULT_FLASH_SIZE   (512 * 1024)
 
+#define DRIVE_FLASH_OFFSET (0x00080000)
+#define DRIVE_FLASH_SIZE   (512 * 1024)
+
 #define VAULT_DIGEST_SIZE WC_SHA512_DIGEST_SIZE
 #define SHA_PAYLOAD_SIZE (sizeof(struct vault_header) - (PK_SIGNATURE_SIZE + VAULT_DIGEST_SIZE))
 
@@ -116,4 +119,8 @@ int cryptoengine_service_count(uint16_t *n_srv, uint16_t *first_avail);
 int cryptoengine_fill_vault_status(struct vault_status *vst);
 int flash_decrypt_read_svc(struct vault_service *out, uint32_t addr);
 
+/* In msc_disk.c */
+void disk_crypto_activate(int status);
+void disk1_format(void);
+
 #endif

+ 2 - 0
src/flash.h

@@ -28,5 +28,7 @@ int flash_sector_erase(uint32_t address);
 int flash_read(uint32_t address, void *data, int len);
 int flash_write(uint32_t address, const void *data, int len);
 int flash_write_svc(struct vault_service *svc, int idx);
+int flash_decrypt_read_sector(uint32_t sector, uint8_t *buf);
+int flash_encrypt_write_sector(uint32_t sector, uint8_t *buf);
 uint8_t flash_read_status(void);
 #endif

+ 8 - 1
src/fsm.c

@@ -24,6 +24,7 @@
 #include "bsp/board.h"
 #include "fsm.h"
 #include "ui.h"
+#include "cryptoengine.h"
 
 static enum vault_state vault_state = VAULT_OFF;
 static volatile int ui_event_pending = 0;
@@ -45,9 +46,15 @@ void fsm_set(enum vault_state st)
 
     if (st == vault_state)
         return;
+
     /* Change state */
     vault_state = st;
-    ui_event_cb(old_st, fsm_get());
+    ui_event_cb(old_st, vault_state);
+    if ((vault_state == VAULT_SETTINGS_MENU) && 
+            (old_st == VAULT_VERIFY_PASSPHRASE)){
+        /* Just logged in! */
+        disk_crypto_activate(1);
+    }
 }
 
 enum vault_state fsm_get(void)

+ 283 - 165
src/msc_disk.c

@@ -25,136 +25,177 @@
 
 #include "bsp/board.h"
 #include "tusb.h"
+#include "flash.h"
+#include "fsm.h"
 
 #if CFG_TUD_MSC
 
+#define MSC_RO_ORIGIN (0x10180000)
+#define DISK_BLOCK_NUM 1024
+#define DISK_BLOCK_SIZE 512
+
+#define BLOCKS_PER_SECTOR (SPI_FLASH_SECTOR_SIZE / DISK_BLOCK_SIZE)
+
+extern const unsigned char disk0_img[];
+
+struct disk_lba {
+    uint8_t data[DISK_BLOCK_SIZE];
+};
+
+
+static const uint8_t last_cluster_init_info[4] = { 0xF8, 0xFF, 0xFF, 0xFF };
+
+static const uint8_t disk1_mbr[DISK_BLOCK_SIZE] = {
+    0xeb, 0x3c, 0x90, 0x6d, 0x6b, 0x66, 0x73, 0x2e, 0x66, 0x61, 0x74, 0x00,
+    0x02, 0x04, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0xf8, 0x01, 0x00,
+    0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x80, 0x00, 0x29, 0x9d, 0x0b, 0x6e, 0xd0, 0x4e, 0x4f, 0x20, 0x4e, 0x41,
+    0x4d, 0x45, 0x20, 0x20, 0x20, 0x20, 0x46, 0x41, 0x54, 0x31, 0x32, 0x20,
+    0x20, 0x20, 0x0e, 0x1f, 0xbe, 0x5b, 0x7c, 0xac, 0x22, 0xc0, 0x74, 0x0b,
+    0x56, 0xb4, 0x0e, 0xbb, 0x07, 0x00, 0xcd, 0x10, 0x5e, 0xeb, 0xf0, 0x32,
+    0xe4, 0xcd, 0x16, 0xcd, 0x19, 0xeb, 0xfe, 0x54, 0x68, 0x69, 0x73, 0x20,
+    0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x20, 0x62, 0x6f, 0x6f,
+    0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x2e, 0x20,
+    0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x65,
+    0x72, 0x74, 0x20, 0x61, 0x20, 0x62, 0x6f, 0x6f, 0x74, 0x61, 0x62, 0x6c,
+    0x65, 0x20, 0x66, 0x6c, 0x6f, 0x70, 0x70, 0x79, 0x20, 0x61, 0x6e, 0x64,
+    0x0d, 0x0a, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x79, 0x20,
+    0x6b, 0x65, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x61,
+    0x67, 0x61, 0x69, 0x6e, 0x20, 0x2e, 0x2e, 0x2e, 0x20, 0x0d, 0x0a, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
+};
+
+
 // whether host does safe-eject
 static bool ejected = false;
 
-// Some MCU doesn't have enough 8KB SRAM to store the whole disk
-// We will use Flash as read-only disk with board that has
-// CFG_EXAMPLE_MSC_READONLY defined
+static struct disk_lba sector_cache[BLOCKS_PER_SECTOR];
+static int sector_cached = -1;
 
-#define README_CONTENTS \
-"This is the password vault utilities directory.\r\n\r\nWork in progress\r\n"
+static int sector_cache_load(uint32_t sector)
+{
+    int ret;
+    if (sector * SPI_FLASH_SECTOR_SIZE > DRIVE_FLASH_SIZE) {
+        sector_cached = -1;
+        return -1;
+    }
+    //ret = flash_decrypt_read_sector(sector, sector_cache[0].data);
+    ret = flash_read(sector * SPI_FLASH_SECTOR_SIZE + DRIVE_FLASH_OFFSET,
+            sector_cache[0].data, SPI_FLASH_SECTOR_SIZE);
+    if (ret < 0) {
+        sector_cached = -1;
+        return ret;
+    }
+    sector_cached = sector;
+}
 
-enum
+static void sector_cache_commit(void)
 {
-  DISK_BLOCK_NUM  = 16, // 8KB is the smallest size that windows allow to mount
-  DISK_BLOCK_SIZE = 512
+    int ret;
+    uint32_t sector = sector_cached;
+    if (sector * SPI_FLASH_SECTOR_SIZE > DRIVE_FLASH_SIZE)
+        return;
+    //flash_encrypt_write_sector(sector, sector_cache[0].data);
+    flash_write(sector * SPI_FLASH_SECTOR_SIZE + DRIVE_FLASH_OFFSET, 
+            sector_cache[0].data, SPI_FLASH_SECTOR_SIZE);
+}
+
+struct drive {
+    const uint8_t lun;
+    const char vid[8];
+    const char pid[16];
+    const char rev[4];
+    const uint32_t n_lba;
 };
 
-#ifdef CFG_EXAMPLE_MSC_READONLY
-const
-#endif
-uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] =
-{
-  //------------- Block0: Boot Sector -------------//
-  // byte_per_sector    = DISK_BLOCK_SIZE; fat12_sector_num_16  = DISK_BLOCK_NUM;
-  // sector_per_cluster = 1; reserved_sectors = 1;
-  // fat_num            = 1; fat12_root_entry_num = 16;
-  // sector_per_fat     = 1; sector_per_track = 1; head_num = 1; hidden_sectors = 0;
-  // drive_number       = 0x80; media_type = 0xf8; extended_boot_signature = 0x29;
-  // filesystem_type    = "FAT12   "; volume_serial_number = 0x1234; volume_label = "TinyUSB MSC";
-  // FAT magic code at offset 510-511
-  {
-      0xEB, 0x3C, 0x90, 0x4D, 0x53, 0x44, 0x4F, 0x53, 0x35, 0x2E, 0x30, 0x00, 0x02, 0x01, 0x01, 0x00,
-      0x01, 0x10, 0x00, 0x10, 0x00, 0xF8, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x29, 0x34, 0x12, 0x00, 0x00, 'V' , 'a' , 'u' , 'l' , 't' ,
-      ' ' , 'T' , 'o' , 'o' , 'l' , 's' , 0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00,
-
-      // Zero up to 2 last bytes of FAT magic code
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xAA
-  },
-
-  //------------- Block1: FAT12 Table -------------//
-  {
-      0xF8, 0xFF, 0xFF, 0xFF, 0x0F // // first 2 entries must be F8FF, third entry is cluster end of readme file
-  },
-
-  //------------- Block2: Root Directory -------------//
-  {
-      // first entry is volume label
-      'V' , 'a' , 'u' , 'l' , 't' , ' ' , 'T' , 'o' , 'o' , 'l' , 's' , 0x08, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x6D, 0x65, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      // second entry is readme file
-      'R' , 'E' , 'A' , 'D' , 'M' , 'E' , ' ' , ' ' , 'T' , 'X' , 'T' , 0x20, 0x00, 0xC6, 0x52, 0x6D,
-      0x65, 0x43, 0x65, 0x43, 0x00, 0x00, 0x88, 0x6D, 0x65, 0x43, 0x02, 0x00,
-      sizeof(README_CONTENTS)-1, 0x00, 0x00, 0x00 // readme's files size (4 Bytes)
-  },
-
-  //------------- Block3: Readme Content -------------//
-  README_CONTENTS
+#define N_DRIVES 2
+
+static uint8_t drv_active[N_DRIVES] = {1, 1};
+
+
+const char global_vid[8] = "DLX";
+const char host_pid[16] = "MEP Tools";
+const char vault_pid[16] = "MEP Vault";
+const char global_rev[4] = "0.1";
+
+static const struct drive Drives[N_DRIVES] = { 
+    { 0, "DLX", "MEP Tools", "0.1", 256},
+    { 1, "DLX", "MEP Vault", "0.1", 1024}
 };
 
+
+uint8_t tud_msc_get_maxlun_cb(void)
+{
+  return 2;
+}
+
 // Invoked when received SCSI_CMD_INQUIRY
 // Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
 void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4])
 {
-  (void) lun;
-
-  const char vid[] = "DLX";
-  const char pid[] = "Vault tools";
-  const char rev[] = "0.1a";
-
-  memcpy(vendor_id  , vid, strlen(vid));
-  memcpy(product_id , pid, strlen(pid));
-  memcpy(product_rev, rev, strlen(rev));
+    const struct drive *drv;
+    if (lun >= N_DRIVES) {
+        return;
+    }
+    drv = &Drives[lun];
+    memcpy(vendor_id  , drv->vid, strlen(drv->vid));
+    memcpy(product_id , drv->pid, strlen(drv->pid));
+    memcpy(product_rev, drv->rev, strlen(drv->rev));
 }
 
 // Invoked when received Test Unit Ready command.
 // return true allowing host to read/write this LUN e.g SD card inserted
 bool tud_msc_test_unit_ready_cb(uint8_t lun)
 {
-  (void) lun;
-
-  // RAM disk is ready until ejected
-  if (ejected) {
-    tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00);
-    return false;
-  }
-
-  return true;
+    if (lun >= N_DRIVES) {
+        tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00);
+        return false;
+    }
+    if (drv_active[lun]) {
+        return true;
+    } else {
+        tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00);
+        return false;
+    }
 }
 
 // Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
 // Application update block count and block size
 void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size)
 {
-  (void) lun;
-
-  *block_count = DISK_BLOCK_NUM;
-  *block_size  = DISK_BLOCK_SIZE;
+    if (lun >= N_DRIVES) {
+        *block_count = 0;
+        *block_size  = DISK_BLOCK_SIZE;
+    } else {
+        *block_count = Drives[lun].n_lba;
+        *block_size  = DISK_BLOCK_SIZE;
+    }
 }
 
 // Invoked when received Start Stop Unit command
@@ -162,58 +203,100 @@ void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_siz
 // - Start = 1 : active mode, if load_eject = 1 : load disk storage
 bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject)
 {
-  (void) lun;
-  (void) power_condition;
-
-  if ( load_eject )
-  {
-    if (start)
-    {
-      // load disk storage
-    }else
-    {
-      // unload disk storage
-      ejected = true;
+    const struct drive *drv;
+    (void) power_condition;
+
+    if (lun < N_DRIVES) {
+        drv = &Drives[lun];
+        if ( load_eject )
+        {
+            if (start)
+            {
+                drv_active[lun] = 1;
+            }else
+            {
+                drv_active[lun] = 0;
+            }
+        }
     }
-  }
-
-  return true;
+    return true;
 }
 
 // Callback invoked when received READ10 command.
 // Copy disk's data to buffer (up to bufsize) and return number of copied bytes.
 int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize)
 {
-  (void) lun;
-
-  // out of ramdisk
-  if ( lba >= DISK_BLOCK_NUM ) return -1;
-
-  uint8_t const* addr = msc_disk[lba] + offset;
-  memcpy(buffer, addr, bufsize);
 
-  return bufsize;
+    const struct drive *drv;
+    uint32_t sector, sec_off;
+    if (lun >= N_DRIVES)
+        return -1;
+    drv = &Drives[lun];
+
+    if ( lba >= drv->n_lba )
+        return -1;
+    
+    if (lun == 0) {
+        struct disk_lba *msc_ro = (struct disk_lba *)disk0_img;
+        memcpy(buffer, msc_ro[lba].data + offset, bufsize);
+        asm volatile("DMB");
+        return bufsize;
+    } else {
+        if (fsm_get() < VAULT_MAIN_MENU) {
+            memset(buffer, 0, bufsize);
+            return bufsize;
+        }
+        if (lba == 0) {
+            memcpy(buffer, disk1_mbr + offset, bufsize);
+            return bufsize;
+        }
+        sector = lba / BLOCKS_PER_SECTOR;
+        sec_off = lba - (sector * BLOCKS_PER_SECTOR);
+         
+        if ( sector != sector_cached) {
+            sector_cache_load(sector);
+            return 0;
+        }
+        memcpy(buffer, sector_cache[sec_off].data + offset, bufsize);
+        asm volatile("DMB");
+        return bufsize;
+    }
 }
 
 bool tud_msc_is_writable_cb (uint8_t lun)
 {
-  (void) lun;
-
-  /* Read only. */
-  return false;
+    if (lun != 1) {
+        /* Read only. */
+        return false;
+    } else {
+        return true;
+    }
 }
 
 // Callback invoked when received WRITE10 command.
 // Process data in buffer to disk's storage and return number of written bytes
 int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize)
 {
-  (void) lun;
-  // out of ramdisk
-  if ( lba >= DISK_BLOCK_NUM )
-      return -1;
-  /* Read only. Silently fail. */
-  (void) lba; (void) offset; (void) buffer;
-  return bufsize;
+    uint32_t sector, sec_off;
+    if (lun == 0)
+        return bufsize;
+    /* 
+    if (lba == 0)
+        return bufsize;
+    */
+    if ( lba >= Drives[lun].n_lba)
+        return -1;
+    if (fsm_get() < VAULT_MAIN_MENU)
+        return -1;
+    sector = lba / BLOCKS_PER_SECTOR;
+    sec_off = lba - (sector * BLOCKS_PER_SECTOR);
+    if ( sector != sector_cached) {
+        sector_cache_load(sector);
+    }
+    memcpy(sector_cache[sec_off].data + offset, buffer, bufsize);
+    sector_cache_commit();
+    asm volatile("DMB");
+    return bufsize;
 }
 
 // Callback invoked when received an SCSI command not in built-in list below
@@ -221,45 +304,80 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t*
 // - READ10 and WRITE10 has their own callbacks
 int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize)
 {
-  // read10 & write10 has their own callback and MUST not be handled here
+    // read10 & write10 has their own callback and MUST not be handled here
 
-  void const* response = NULL;
-  int32_t resplen = 0;
+    void const* response = NULL;
+    int32_t resplen = 0;
 
-  // most scsi handled is input
-  bool in_xfer = true;
+    // most scsi handled is input
+    bool in_xfer = true;
 
-  switch (scsi_cmd[0])
-  {
-    case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
-      // Host is about to read/write etc ... better not to disconnect disk
-      resplen = 0;
-    break;
+    switch (scsi_cmd[0])
+    {
+        case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
+            // Host is about to read/write etc ... better not to disconnect disk
+            resplen = 0;
+            break;
+
+        default:
+            // Set Sense = Invalid Command Operation
+            tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
+
+            // negative means error -> tinyusb could stall and/or response with failed status
+            resplen = -1;
+            break;
+    }
 
-    default:
-      // Set Sense = Invalid Command Operation
-      tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
+    // return resplen must not larger than bufsize
+    if ( resplen > bufsize ) resplen = bufsize;
 
-      // negative means error -> tinyusb could stall and/or response with failed status
-      resplen = -1;
-    break;
-  }
+    if ( response && (resplen > 0) )
+    {
+        if(in_xfer)
+        {
+            memcpy(buffer, response, resplen);
+        }else
+        {
+            // SCSI output
+        }
+    }
 
-  // return resplen must not larger than bufsize
-  if ( resplen > bufsize ) resplen = bufsize;
+    return resplen;
+}
 
-  if ( response && (resplen > 0) )
-  {
-    if(in_xfer)
-    {
-      memcpy(buffer, response, resplen);
-    }else
-    {
-      // SCSI output
+void disk1_format(void)
+{
+    uint8_t block[DISK_BLOCK_SIZE];
+    int i, j;
+    if (cryptoengine_check_vault() < 0)
+        return;
+
+    memset(block, 0, DISK_BLOCK_SIZE);
+    for (i = 1; i < 5; i++) {
+        if (sector_cached != i) {
+            sector_cache_load(i);
+        }
+        for (j = 0; j < BLOCKS_PER_SECTOR; j++)
+            memcpy(sector_cache[j].data, block, DISK_BLOCK_SIZE);
+        sector_cache_commit();
     }
-  }
 
-  return resplen;
+    /* Fill "last cluster" info */
+    sector_cache_load(0);
+    for (j = 0; j < BLOCKS_PER_SECTOR; j++)
+            memcpy(sector_cache[j].data, block, DISK_BLOCK_SIZE);
+    memcpy(sector_cache[0].data, disk1_mbr, DISK_BLOCK_SIZE);
+    memcpy(sector_cache[1].data, last_cluster_init_info, 4); 
+    memcpy(sector_cache[2].data, last_cluster_init_info, 4); 
+    sector_cache_commit();
+}
+
+void disk_crypto_activate(int status)
+{
+    drv_active[1] = status;
+    if (status) {
+
+    }
 }
 
 #endif

+ 1 - 4
src/password_safe.c

@@ -84,8 +84,6 @@ static uint Led[] = {
 #define SPI_MISO_PIN     4
 #define SPI_FLASH_CS_PIN 5
 
-
-
 uint16_t flash_info = 0xFFFF;
 
 #define AIRCR *(volatile uint32_t *)(0xE000ED0C)
@@ -166,6 +164,7 @@ void system_boot(void)
     spi_init(SPI, SPI_BAUDRATE);
     flash_info = flash_init(SPI);
     
+    
     printf("Initializing I2C Display\r\n");
     gpio_init(I2C_SDA_PIN);
     gpio_init(I2C_SCL_PIN);
@@ -311,8 +310,6 @@ int main(void) {
     int i;
     system_boot();
     printf("Loop started.\n");
-
-
     while (main_plug) {
         uint32_t ms_tick = board_millis();
         if ((ms_tick % 10) == 0) {

+ 2 - 3
src/ui.c

@@ -81,16 +81,15 @@ void ui_event_cb(enum vault_state old_st, enum vault_state st)
                 fsm_set(VAULT_VERIFY_FAILED);
                 return;
             }
-            gpio_put(GREEN_LED, 0);
             fsm_set(VAULT_MAIN_MENU);
-            return;
-            break;
+            return; /* State changed, avoid non-tail recursion */
         case VAULT_MAIN_MENU:
             display_text(0,"                 ");
             display_text(1,"                 ");
             display_text(2,"                 ");
             display_text(3,"                 ");
             display_text_inverse(0, 2, "[Main Menu]");
+            gpio_put(GREEN_LED, 0);
             break;
         case VAULT_SETTINGS_MENU:
             display_text(0,"                 ");