Browse Source

Experiments with second disk

Daniele Lacamera 10 months ago
parent
commit
66fdb15378
7 changed files with 214 additions and 40 deletions
  1. 33 0
      src/cryptoengine.c
  2. 7 0
      src/cryptoengine.h
  3. 2 0
      src/flash.h
  4. 8 1
      src/fsm.c
  5. 161 32
      src/msc_disk.c
  6. 1 4
      src/password_safe.c
  7. 2 3
      src/ui.c

+ 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)

+ 161 - 32
src/msc_disk.c

@@ -25,6 +25,8 @@
 
 #include "bsp/board.h"
 #include "tusb.h"
+#include "flash.h"
+#include "fsm.h"
 
 #if CFG_TUD_MSC
 
@@ -32,6 +34,8 @@
 #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 {
@@ -39,11 +43,88 @@ struct disk_lba {
 };
 
 
+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;
 
-static struct disk_lba lba_cache;
-static int lba_cached = -1;
+static struct disk_lba sector_cache[BLOCKS_PER_SECTOR];
+static int sector_cached = -1;
+
+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;
+}
+
+static void sector_cache_commit(void)
+{
+    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;
@@ -55,7 +136,7 @@ struct drive {
 
 #define N_DRIVES 2
 
-static uint8_t drv_active[N_DRIVES] = {1, 0};
+static uint8_t drv_active[N_DRIVES] = {1, 1};
 
 
 const char global_vid[8] = "DLX";
@@ -64,14 +145,14 @@ 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", 1024},
+    { 0, "DLX", "MEP Tools", "0.1", 256},
     { 1, "DLX", "MEP Vault", "0.1", 1024}
 };
 
 
 uint8_t tud_msc_get_maxlun_cb(void)
 {
-  return 1;
+  return 2;
 }
 
 // Invoked when received SCSI_CMD_INQUIRY
@@ -109,7 +190,7 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun)
 void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size)
 {
     if (lun >= N_DRIVES) {
-        *block_count = DISK_BLOCK_NUM;
+        *block_count = 0;
         *block_size  = DISK_BLOCK_SIZE;
     } else {
         *block_count = Drives[lun].n_lba;
@@ -147,37 +228,37 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff
 {
 
     const struct drive *drv;
-    uint8_t const *addr;
+    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 0
-        if ( lba != lba_cached) {
-            if (lba == 0) {
-                memcpy(lba_cache.data, mbr.data, sizeof(struct disk_lba)); 
-                lba_cached = lba;
-                return 0;
-            }
-            memcpy(lba_cache.data, msc_ro[lba].data, sizeof(struct disk_lba)); 
-            lba_cached = lba;
+        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, lba_cache.data + offset, bufsize);
-#endif
-        memset(buffer, 0xA5, bufsize);
+        memcpy(buffer, sector_cache[sec_off].data + offset, bufsize);
+        asm volatile("DMB");
         return bufsize;
     }
 }
@@ -185,8 +266,8 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff
 bool tud_msc_is_writable_cb (uint8_t lun)
 {
     if (lun != 1) {
-      /* Read only. */
-      return false;
+        /* Read only. */
+        return false;
     } else {
         return true;
     }
@@ -196,13 +277,26 @@ bool tud_msc_is_writable_cb (uint8_t lun)
 // 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
@@ -251,4 +345,39 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer,
     return resplen;
 }
 
+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();
+    }
+
+    /* 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,"                 ");