diff --git a/src/cryptoengine.c b/src/cryptoengine.c index 6fad831..5d2415c 100644 --- a/src/cryptoengine.c +++ b/src/cryptoengine.c @@ -41,6 +41,20 @@ static ecc_key ecc; static struct vault_service svc_cache; static int svc_cache_id = -1; +extern const uint8_t disk1_mbr[]; + +#define CHACHA_BLOCK_SIZE 64 +#define CHACHA_BUFFER_SIZE (CHACHA_BLOCK_SIZE * 16) +#define LBA_SIZE 512 + +#define CHACHA_INLINE + + +#ifndef CHACHA_INLINE +static uint8_t chacha_tmp[CHACHA_BUFFER_SIZE]; +static uint32_t chacha_processed; +#endif + int flash_decrypt_read_sector(uint32_t sector, uint8_t *buf) { if (cryptoengine_check_vault() < 0) @@ -51,8 +65,21 @@ int flash_decrypt_read_sector(uint32_t sector, uint8_t *buf) 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_SetIV(&cha, hdr_cache.host_seed, sector * (SPI_FLASH_SECTOR_SIZE / CHACHA_BLOCK_SIZE)); +#ifndef CHACHA_INLINE + chacha_processed = 0; + while (chacha_processed < SPI_FLASH_SECTOR_SIZE) { + wc_Chacha_Process(&cha, chacha_tmp, buf + chacha_processed, + CHACHA_BUFFER_SIZE); + memcpy(buf + chacha_processed, chacha_tmp, CHACHA_BUFFER_SIZE); + chacha_processed += CHACHA_BUFFER_SIZE; + } +#else wc_Chacha_Process(&cha, buf, buf, SPI_FLASH_SECTOR_SIZE); +#endif + if (sector == 0) { + memcpy(buf, disk1_mbr, LBA_SIZE); + } return 0; } @@ -64,8 +91,21 @@ int flash_encrypt_write_sector(uint32_t sector, uint8_t *buf) return -1; if ((sector * SPI_FLASH_SECTOR_SIZE) >= DRIVE_FLASH_SIZE) return -1; - wc_Chacha_SetIV(&cha, hdr_cache.host_seed, sector); + if (sector == 0) { + memcpy(buf, disk1_mbr, LBA_SIZE); + } + wc_Chacha_SetIV(&cha, hdr_cache.host_seed, sector * (SPI_FLASH_SECTOR_SIZE / CHACHA_BLOCK_SIZE)); +#ifndef CHACHA_INLINE + chacha_processed = 0; + while (chacha_processed < SPI_FLASH_SECTOR_SIZE) { + wc_Chacha_Process(&cha, chacha_tmp, buf + chacha_processed, + CHACHA_BUFFER_SIZE); + memcpy(buf + chacha_processed, chacha_tmp, CHACHA_BUFFER_SIZE); + chacha_processed += CHACHA_BUFFER_SIZE; + } +#else wc_Chacha_Process(&cha, buf, buf, SPI_FLASH_SECTOR_SIZE); +#endif flash_write(DRIVE_FLASH_OFFSET + sector * SPI_FLASH_SECTOR_SIZE, buf, SPI_FLASH_SECTOR_SIZE); return 0; diff --git a/src/hid.c b/src/hid.c index aa10fc1..53c0971 100644 --- a/src/hid.c +++ b/src/hid.c @@ -195,6 +195,8 @@ static void send_hid_report(uint8_t report_id, uint32_t unused) } } +extern void ForceZero(const void* mem, word32 len); + void hid_keys_string_send(const char *str) { int len = strlen(str); diff --git a/src/msc_disk.c b/src/msc_disk.c index 76a9879..444b199 100644 --- a/src/msc_disk.c +++ b/src/msc_disk.c @@ -45,12 +45,12 @@ 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] = { +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, + 0x80, 0x00, 0x29, 0x9d, 0x0b, 0x6e, 0xd0, 'M', 'E', 'P', ' ', 'V', + 'a', 'u', 'l', 't', 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, @@ -107,14 +107,13 @@ static int sector_cache_load(uint32_t sector) 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); + ret = flash_decrypt_read_sector(sector, sector_cache[0].data); if (ret < 0) { sector_cached = -1; return ret; } sector_cached = sector; + return sector; } static inline void sector_cache_sched_commit(void) @@ -130,10 +129,8 @@ static void sector_cache_commit(void) cache_busy = 0; return; } - //flash_encrypt_write_sector(sector, sector_cache[0].data); flash_sector_erase(sector * SPI_FLASH_SECTOR_SIZE + DRIVE_FLASH_OFFSET); - flash_write(sector * SPI_FLASH_SECTOR_SIZE + DRIVE_FLASH_OFFSET, - sector_cache[0].data, SPI_FLASH_SECTOR_SIZE); + flash_encrypt_write_sector(sector, sector_cache[0].data); cache_busy = 0; } @@ -163,7 +160,11 @@ static const struct drive Drives[N_DRIVES] = { uint8_t tud_msc_get_maxlun_cb(void) { +#ifdef HAVE_VAULT return 2; +#else + return 1; +#endif } // Invoked when received SCSI_CMD_INQUIRY @@ -240,6 +241,7 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff const struct drive *drv; uint32_t sector, sec_off; + uint32_t remaining_bufsize = 0, total_bufsize = bufsize; if (lun >= N_DRIVES) return -1; drv = &Drives[lun]; @@ -257,21 +259,37 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff 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) { - if (!cache_busy) - sector_cache_load(sector); - return 0; - } - memcpy(buffer, sector_cache[sec_off].data + offset, bufsize); - asm volatile("DMB"); - return bufsize; + do { + if ( sector != sector_cached) { + if (!cache_busy) { + if (sector_cache_load(sector) != sector) + return -1; + } else { + if (total_bufsize == bufsize) + return -1; + return total_bufsize - bufsize; + } + } + if (sec_off * DISK_BLOCK_SIZE + offset + bufsize > SPI_FLASH_SECTOR_SIZE) { + remaining_bufsize = bufsize; + bufsize = SPI_FLASH_SECTOR_SIZE - (sec_off * DISK_BLOCK_SIZE + offset); + remaining_bufsize -= bufsize; + } + memcpy(buffer, sector_cache[sec_off].data + offset, bufsize); + asm volatile("DMB"); + if (remaining_bufsize > 0) { + sector++; + sec_off = 0; + bufsize = remaining_bufsize; + remaining_bufsize = 0; + } else { + break; + } + } while (bufsize > 0); + return total_bufsize; } } @@ -290,27 +308,49 @@ bool tud_msc_is_writable_cb (uint8_t lun) int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) { uint32_t sector, sec_off; + uint32_t remaining_bufsize = 0; + uint32_t total_bufsize = bufsize; 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) { - while(cache_busy) - sleep_ms(1); - sector_cache_load(sector); - } - memcpy(sector_cache[sec_off].data + offset, buffer, bufsize); - sector_cache_sched_commit(); + do { + if ( sector != sector_cached) { + while(cache_busy) + sleep_ms(1); + if (sector_cache_load(sector) < 0) + return total_bufsize; + } + if (bufsize + sec_off * DISK_BLOCK_SIZE + offset > SPI_FLASH_SECTOR_SIZE) { + remaining_bufsize = bufsize; + bufsize = SPI_FLASH_SECTOR_SIZE - (sec_off * DISK_BLOCK_SIZE + offset); + remaining_bufsize -= bufsize; + } else { + remaining_bufsize = 0; + } + if (bufsize == 0) + return total_bufsize; + memcpy(sector_cache[sec_off].data + offset, buffer, bufsize); + sector_cache_sched_commit(); + if (remaining_bufsize > 0) { + return total_bufsize; + /* + sector++; + sec_off = 0; + bufsize = remaining_bufsize; + remaining_bufsize = 0; + */ + } else { + bufsize = 0; + break; + } + } while (bufsize > 0); asm volatile("DMB"); - return bufsize; + return total_bufsize; } // Callback invoked when received an SCSI command not in built-in list below @@ -369,7 +409,8 @@ void disk1_format(void) memset(block, 0, DISK_BLOCK_SIZE); for (i = 1; i < 5; i++) { if (sector_cached != i) { - sector_cache_load(i); + if (sector_cache_load(i) < 0) + break; } for (j = 0; j < BLOCKS_PER_SECTOR; j++) memcpy(sector_cache[j].data, block, DISK_BLOCK_SIZE);