Added USB-MSC

This commit is contained in:
Daniele Lacamera 2019-11-04 15:38:49 +01:00
parent eb1a572eff
commit c958c4becb
15 changed files with 1273 additions and 34 deletions

View file

@ -1,15 +1,15 @@
CROSS_COMPILE:=arm-none-eabi-
CC:=$(CROSS_COMPILE)gcc
LD:=$(CROSS_COMPILE)gcc
USECFS:=$(HOME)/src/usecfs
WOLFSSL:=$(HOME)/src/wolfssl
OBJS:=startup.o main.o system.o usecfs_dev_spi.o $(USECFS)/src/usecfs.o mem.o led.o \
OBJS:=startup.o main.o system.o usecfs_dev_spi.o usecfs.o mem.o led.o \
i2c.o display.o font_twisted.o spi.o spi_flash.o button.o systick.o newlib.o uart.o ui.o \
sdcard.o random.o
sdcard.o random.o usb.o mutex.o
OBJS+= \
$(WOLFSSL)/wolfcrypt/src/sha256.o \
$(WOLFSSL)/wolfcrypt/src/chacha.o \
$(WOLFSSL)/wolfcrypt/src/aes.o \
$(WOLFSSL)/wolfcrypt/src/pwdbased.o \
$(WOLFSSL)/wolfcrypt/src/hash.o \
$(WOLFSSL)/wolfcrypt/src/hmac.o \
@ -30,13 +30,14 @@ LSCRIPT:=target.ld
OBJCOPY:=$(CROSS_COMPILE)objcopy
CFLAGS:=-mcpu=cortex-m3 -mthumb -Wall -Wno-main -Wstack-usage=200 -ffreestanding -Wno-unused -DBLOCK_SIZE=4096 -I$(USECFS)/src -I. -I$(WOLFSSL) -Ilib/unicore-mx/include
CFLAGS:=-mcpu=cortex-m3 -mthumb -Wall -Wno-main -Wstack-usage=200 -ffreestanding -Wno-unused -DBLOCK_SIZE=4096 -I. -I$(WOLFSSL) -Ilib/unicore-mx/include
CFLAGS+=-specs=nano.specs -lc -lg
CFLAGS+=$(UMXFLAGS)
#CFLAGS+=-O2
CFLAGS+=-g -ggdb3
CFLAGS+=-O2
#CFLAGS+=-g -ggdb3
CFLAGS+=-DWOLFSSL_USER_SETTINGS -DCRYPTO
ASFLAGS:=$(CFLAGS)
LDFLAGS:=-T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=image.map -mcpu=cortex-m3 -mthumb -nostartfiles
@ -52,4 +53,5 @@ $(UMX):
make -C lib/unicore-mx FP_FLAGS="-O3 -mfloat-abi=soft" TARGETS=stm32/f4
clean:
rm -f image.bin image.elf *.o image.map $(WOLFSSL)/wolfcrypt/src/*.o $(USECFS)/src/*.o
@rm -f image.bin image.elf *.o image.map $(WOLFSSL)/wolfcrypt/src/*.o $(USECFS)/src/*.o
make -C lib/unicore-mx clean

10
main.c
View file

@ -17,6 +17,7 @@
#include "ui.h"
#include "sdcard.h"
#include "button.h"
#include "usb.h"
extern uint32_t cpu_freq;
#define BLINK_INTERVAL 500
@ -74,6 +75,10 @@ static void bootlevel_1(void)
led_on(YELLOW_LED);
sdcard_detected = 1;
}
printf("Activating USB mass storage device\r\n");
printf("Activating I2C bus\r\n");
i2c_display_init();
printf("Display initialized.\r\n");
@ -89,10 +94,6 @@ static void bootlevel_1(void)
void process_button(uint16_t press, int hold)
{
char c = bu2c(press);
if (!hold)
printf("Pressed '%c'.\r\n", c);
else
printf("Held '%c'.\r\n", c);
ui_button_press(press);
}
@ -127,6 +128,7 @@ int main(void) {
do {
WFI();
usb_poll();
ret = button_poll(process_button);
if (jiffies - poll_time > hb_pulse) {
if (hb) {

47
mutex.S Normal file
View file

@ -0,0 +1,47 @@
.syntax unified
/* Lock function.
* On success, return 0.
* On failure, return -1 (Locked, try again later).
*/
.global _mutex_lock
_mutex_lock:
LDREX r1, [r0]
CMP r1, #0 // Test if mutex holds the value 0
BEQ _mutex_lock_fail // If it does, return -1
SUBS r1, #1 // If not, decrement temporary copy
STREX r2, r1, [r0] // Attempt Store-Exclusive
CMP r2, #0 // Check if Store-Exclusive succeeded
BNE _mutex_lock // If Store-Exclusive failed, retry from start
DMB // Required before accessing protected resource
MOVS r0, #0 // Successfully locked.
BX lr
_mutex_lock_fail:
DMB
MOV r0, #-1 // Already locked!
BX lr
/* Unlock mutex.
* On success, return 0.
* On failure, return -1 (Already unlocked!).
*/
.global _mutex_unlock
_mutex_unlock:
LDREX r1, [r0]
CMP r1, #0 // Test if mutex holds the value 0
BNE _mutex_unlock_fail // If it does not, it's already unlocked!
ADDS r1, #1 // Increment temporary copy
STREX r2, r1, [r0] // Attempt Store-Exclusive
CMP r2, #0 // Check if Store-Exclusive succeeded
BNE _mutex_unlock // Store failed - retry immediately
DMB // Required before releasing protected resource
MOVS r0, #0 // Successfully unlocked.
BX lr
_mutex_unlock_fail:
DMB
MOV r0, #-1 // Already unlocked!
BX lr

View file

@ -450,6 +450,13 @@ int sdcard_read(void *dev, void *_buf, uint32_t lba)
return err;
}
uint32_t sdcard_getsize(void *dev)
{
if (SD.card)
return SD.card->size;
return 0;
}
/*
* Write a Block from our Card
*/

View file

@ -58,6 +58,7 @@ int sdcard_read(void *dev, void *_buf, uint32_t lba);
int sdcard_write(void *dev, void *_buf, uint32_t lba);
int sdcard_sense(void);
int sdcard_detect(void);
uint32_t sdcard_getsize(void *dev);
void sdcard_hw_init(void);

View file

@ -22,6 +22,8 @@ static unsigned int sp;
extern void main(void);
extern void isr_exti(void);
extern void isr_systick(void);
extern void otg_fs_isr(void);
extern void usb_fs_wkup_isr(void);
void isr_reset(void) {
register unsigned int *src, *dst;
@ -149,11 +151,54 @@ void (* const IV[])(void) =
isr_empty, // USART3_IRQ 39
isr_exti, // EXTI15_10_IRQ 40
isr_empty, // RTC_ALARM_IRQ 41
isr_empty, // USB_FS_WKUP_IRQ 42
usb_fs_wkup_isr, // USB_FS_WKUP_IRQ 42
isr_empty, // TIM8_BRK_TIM12_IRQ 43
isr_empty, // TIM8_UP_TIM13_IRQ 44
isr_empty, // TIM8_TRG_COM_TIM14_IRQ 45
isr_empty, // TIM8_CC_IRQ 46
isr_empty, // DMA1_STREAM7_IRQ 47
isr_empty, // FSMC_IRQ
isr_empty, // SDIO_IRQ
isr_empty, // TIM5_IRQ
isr_empty, // SPI3_IRQ
isr_empty, // UART4_IRQ
isr_empty, // UART5_IRQ
isr_empty, // TIM6_DAC_IRQ
isr_empty, // TIM7_IRQ
isr_empty, // DMA2_STREAM0_IRQ
isr_empty, // DMA2_STREAM1_IRQ
isr_empty, // DMA2_STREAM2_IRQ
isr_empty, // DMA2_STREAM3_IRQ
isr_empty, // DMA2_STREAM4_IRQ
isr_empty, // ETH_IRQ
isr_empty, // ETH_WKUP_IRQ
isr_empty, // CAN2_TX_IRQ
isr_empty, // CAN2_RX0_IRQ
isr_empty, // CAN2_RX1_IRQ
isr_empty, // CAN2_SCE_IRQ
otg_fs_isr, // OTG_FS_IRQ
isr_empty, // DMA2_STREAM5_IRQ
isr_empty, // DMA2_STREAM6_IRQ
isr_empty, // DMA2_STREAM7_IRQ
isr_empty, // USART6_IRQ
isr_empty, // I2C3_EV_IRQ
isr_empty, // I2C3_ER_IRQ
isr_empty, // OTG_HS_EP1_OUT_IRQ
isr_empty, // OTG_HS_EP1_IN_IRQ
isr_empty, // OTG_HS_WKUP_IRQ
isr_empty, // OTG_HS_IRQ
isr_empty, // DCMI_IRQ
isr_empty, // CRYP_IRQ
isr_empty, // HASH_RNG_IRQ
isr_empty, // FPU_IRQ
isr_empty, // UART7_IRQ
isr_empty, // UART8_IRQ
isr_empty, // SPI4_IRQ
isr_empty, // SPI5_IRQ
isr_empty, // SPI6_IRQ
isr_empty, // SAI1_IRQ
isr_empty, // LCD_TFT_IRQ
isr_empty, // LCD_TFT_ERR_IRQ
isr_empty, // DMA2D_IRQ
};

View file

@ -5,7 +5,10 @@
#define PLL_FULL_MASK (0x7F037FFF)
extern uint32_t cpu_freq;
void panic(void);
void printbin(const uint8_t *buf, int len); /* Defined in uart.c */
extern int _mutex_lock(void *); /* defined in mutex.S */
extern int _mutex_unlock(void *);
/* PIN CONFIG TARGET */
#define BLUE_LED 4
@ -427,4 +430,18 @@ static inline void nvic_irq_clear(uint8_t n)
#define SDIO_MASK_CCRCFAILIE (1 << 0)
/* Reboot */
#define AIRCR *(volatile uint32_t *)(0xE000ED0C)
#define AIRCR_VKEY (0x05FA << 16)
# define AIRCR_SYSRESETREQ (1 << 2)
static inline void reboot(void)
{
AIRCR = AIRCR_SYSRESETREQ | AIRCR_VKEY;
}
#endif

14
uart.c
View file

@ -6,6 +6,7 @@
* See LICENSE for details
*/
#include <stdint.h>
#include <stdio.h>
#include "uart.h"
#include "system.h"
@ -116,3 +117,16 @@ int _write(void *r, uint8_t *text, int len)
return len;
}
/* commodity to print binary buffers */
void printbin(const uint8_t *buf, int len)
{
int i;
for (i = 0; i < len; i++) {
if ((i % 16) == 0)
printf("\r\n%08x: ", i);
printf("%02x ", buf[i]);
}
printf("\r\n");
}

92
ui.c
View file

@ -13,6 +13,7 @@
#include <stdlib.h>
#include <string.h>
#include "usecfs.h"
#include "usb.h"
/* Uncomment for device initialization */
@ -42,6 +43,7 @@ static uint32_t offset = 0;
#define MAX_PASSWORD 32
static int fsm_state = ST_LOCKED;
static int sleeping = 0;
static char password[MAX_PASSWORD] = {};
static int pin_idx = 0;
@ -49,12 +51,36 @@ static int pin_idx = 0;
#define SLEEP_TIME (5000)
void ui_msg(const char *txt)
static void ui_sleep(void)
{
display_scroll(NULL, 0);
display_clear(NULL);
display_text(6, txt);
sleeping = 1;
}
static int ui_wakeup(void)
{
last_action = jiffies;
if (sleeping) {
sleeping = 0;
return 1;
}
return 0;
}
static int ui_vault_on(void)
{
ui_msg("Activating Vault");
bridge_init();
}
void ui_msg(const char *txt)
{
ui_wakeup();
display_scroll(NULL, 0);
display_clear(NULL);
display_text(6, txt);
}
void lock(void)
@ -64,7 +90,7 @@ void lock(void)
fsm_state = ST_LOCKED;
}
static void pwrst(void)
static void pwdrst(void)
{
memset(password, 0, MAX_PASSWORD);
pin_idx = 0;
@ -74,8 +100,11 @@ int unlock(void)
{
uint8_t stored_uuid[UUID_LEN];
if (pin_idx < 6) {
display_text(6, "Failed.");
pwrst();
display_scroll(NULL, 0);
display_clear(NULL);
display_text(5, "Failed.");
display_text(6, "Insert pin:");
pwdrst();
return -1;
}
display_scroll(NULL, 0);
@ -84,7 +113,7 @@ int unlock(void)
display_text(5, "Unlocking secret");
if ((usecfs_init(password, 0, stored_uuid) == 0) &&
(memcmp(stored_uuid, uuid, UUID_LEN) == 0)) {
pwrst();
pwdrst();
fsm_state = ST_UNLOCKED;
ui_msg("Device UNLOCKED");
return 0;
@ -96,8 +125,11 @@ int unlock(void)
return 0;
}
#endif
display_text(6, "Failed.");
pwrst();
display_scroll(NULL, 0);
display_clear(NULL);
display_text(5, "Failed.");
display_text(6, "Insert pin:");
pwdrst();
fsm_state = ST_LOCKED;
return -1;
}
@ -106,13 +138,21 @@ int unlock(void)
void ui_button_hold(uint16_t button)
{
last_action = jiffies;
ui_wakeup();
}
void ui_status(void)
{
display_scroll(NULL, 0);
display_clear(NULL);
display_text(5, "Status Report ");
display_text(6, "Status OK ");
}
void ui_sdcard_insert(void)
{
ui_wakeup();
ui_msg("SD Card detected");
last_action = jiffies;
}
void ui_menu(char in)
@ -125,27 +165,43 @@ void ui_menu(char in)
display_text(7, "1. Status ");
display_text(6, "0. Lockdown ");
display_text(5, "Main Menu ");
display_text(2, "4. Reboot ");
display_text(2, "4. UART menu ");
display_text(1, "3. SD format ");
display_text(0, "2. USB vault ON ");
switch (in) {
case ' ':
menu_scroll += 4;
menu_scroll %= 0x40;
display_scroll(NULL, menu_scroll);
break;
case '\r':
menu_scroll -= 4;
menu_scroll %= 0x40;
display_scroll(NULL, menu_scroll);
break;
case '1':
ui_status();
break;
case '2':
ui_vault_on();
break;
case '0':
reboot();
panic();
break;
}
menu_scroll %= 0x40;
display_scroll(NULL, menu_scroll);
}
void ui_button_press(uint16_t button)
{
int i;
char c;
if (ui_wakeup())
c = 0;
else
c = bu2c(button);
if (fsm_state == ST_LOCKED) {
pwrst();
pwdrst();
ui_msg("Insert pin:");
fsm_state = ST_PIN_ENTRY;
return;
@ -155,7 +211,6 @@ void ui_button_press(uint16_t button)
for (i = 0; i < pin_idx; i++) {
line[i] = '*';
}
c = bu2c(button);
if ((c >= '0') && (c <='9')) {
if (pin_idx < 16) {
line[pin_idx] = 'X';
@ -165,17 +220,13 @@ void ui_button_press(uint16_t button)
if (c == '\r') {
unlock();
} else {
display_scroll(NULL, 0);
display_clear(NULL);
display_text(7, line);
display_text(6, "Insert pin:");
}
}
if (fsm_state == ST_UNLOCKED)
{
ui_menu(bu2c(button));
}
last_action = jiffies;
}
void ui_init(void)
@ -208,8 +259,7 @@ void ui_init(void)
void ui_keepalive(uint32_t timeslice)
{
if ((jiffies - last_action) > SLEEP_TIME) {
display_scroll(NULL, 0);
display_clear(NULL);
ui_sleep();
if (fsm_state == ST_PIN_ENTRY)
lock();
}

368
usb.c Normal file
View file

@ -0,0 +1,368 @@
#include <unicore-mx/stm32/gpio.h>
#include <unicore-mx/stm32/rcc.h>
#include <unicore-mx/stm32/f4/rcc.h>
#include <unicore-mx/stm32/usart.h>
#include <unicore-mx/cm3/nvic.h>
#include <unicore-mx/usbd/usbd.h>
#include <unicore-mx/usbd/class/msc.h>
#include <unicore-mx/stm32/otg_fs.h>
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/sha256.h>
#include <wolfssl/wolfcrypt/aes.h>
#include <wolfssl/wolfcrypt/chacha.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "system.h"
#include "systick.h"
#include "sdcard.h"
//#define USB_DEBUG
#ifdef USB_DEBUG
#define USB_DBG printf
#define USB_DBG_BIN printbin
#else
#define USB_DBG(...) do{}while (0)
#define USB_DBG_BIN(...) do{}while (0)
#endif
#define CRYPTO_BLOCK_SIZE 64
#define KEYSZ 32
#define IVSZ 16
#define SECTOR_SIZE 512
static const char VID[] = "0001";
static const char PID[] = "0002";
static const char PR[] = "0003";
static const char iv_bytes[16] = {0x00, 0x00, 0x00, 0x00, 0xa8, 0xbb, 0x2a, 0x3e, 0x3c, 0xb7, 0x19, 0x27, 0x77, 0xbf, 0x3e, 0x60 };
static struct usbd_device *usbd_dev = NULL;
static uint8_t tmp_blk_rd[SECTOR_SIZE];
static uint8_t tmp_blk_wr[SECTOR_SIZE];
static uint32_t bridge_mutex = 1;
static int bridge_read_block(const usbd_msc_backend *backend, uint32_t lba, void *copy_to)
{
ChaCha cha;
uint8_t crypto_tmp[CRYPTO_BLOCK_SIZE];
uint32_t i;
uint32_t sd_size = sdcard_getsize(NULL);
volatile uint8_t *dst;
uint8_t crypto_iv[16];
if (lba > sd_size)
return -1;
if (lba < 2) {
USB_DBG("SD: requested block %08x\r\n", lba);
}
/*
if (lba == 0) {
dst = copy_to;
memcpy(copy_to, BootSector, SECTOR_SIZE);
dst[SECTOR_SIZE - 2] = 0x55;
dst[SECTOR_SIZE - 1] = 0xAA;
return 0;
}
*/
memset(copy_to, 0, SECTOR_SIZE);
dst = (uint8_t *)tmp_blk_rd;
sdcard_read(NULL, dst, lba);
wc_Chacha_SetKey(&cha, usecfs_getkey(), 32);
memcpy(crypto_iv, iv_bytes, 16);
*((uint32_t *)crypto_iv) = lba;
wc_Chacha_SetIV(&cha, crypto_iv, 16);
for (i = 0; i < SECTOR_SIZE / CRYPTO_BLOCK_SIZE; i++) {
memcpy(crypto_tmp, dst + i * CRYPTO_BLOCK_SIZE, CRYPTO_BLOCK_SIZE);
wc_Chacha_Process(&cha, dst + i * CRYPTO_BLOCK_SIZE, crypto_tmp, CRYPTO_BLOCK_SIZE);
}
if (lba < 2) {
USB_DBG("Decrypted:\r\n");
USB_DBG_BIN(dst, SECTOR_SIZE);
}
memcpy(copy_to, dst, SECTOR_SIZE);
return 0;
}
static int bridge_write_block(const usbd_msc_backend *backend, uint32_t lba, const void *copy_from)
{
ChaCha cha;
uint8_t crypto_tmp[CRYPTO_BLOCK_SIZE];
uint32_t i;
const uint8_t *src;
uint8_t crypto_iv[16];
uint32_t sd_size;
bridge_lock();
sd_size = sdcard_getsize(NULL);
if (lba > sd_size) {
printf("SD error: attempting to write to block %u out of range\r\n", lba);
return -1;
}
/*
if (lba == 0) {
return 0;
}
*/
if (lba < 2) {
USB_DBG("SD: provided block %u\r\n", lba);
USB_DBG_BIN(copy_from, SECTOR_SIZE);
}
memcpy(tmp_blk_wr, copy_from, SECTOR_SIZE);
src = (uint8_t *)tmp_blk_wr;
wc_Chacha_SetKey(&cha, usecfs_getkey(), 32);
memcpy(crypto_iv, iv_bytes, 16);
*((uint32_t *)crypto_iv) = lba;
wc_Chacha_SetIV(&cha, crypto_iv, 16);
for (i = 0; i < SECTOR_SIZE / CRYPTO_BLOCK_SIZE; i++) {
memcpy(crypto_tmp, src + i * CRYPTO_BLOCK_SIZE, CRYPTO_BLOCK_SIZE);
wc_Chacha_Process(&cha, tmp_blk_wr + i * CRYPTO_BLOCK_SIZE, crypto_tmp, CRYPTO_BLOCK_SIZE);
}
sdcard_write(NULL, tmp_blk_wr, lba);
bridge_unlock();
return 0;
}
int bridge_lock(void)
{
while(_mutex_lock(&bridge_mutex) == 0)
;
asm volatile ("cpsid i");
return 0;
}
int bridge_unlock(void)
{
asm volatile ("cpsie i");
return _mutex_unlock(&bridge_mutex);
}
struct usbd_msc_backend flash_backend = {
.vendor_id = VID,
.product_id = PID,
.product_rev = PR,
.block_count = 0,
//.lock = bridge_lock,
//.unlock = bridge_unlock,
.read_block = bridge_read_block,
.write_block = bridge_write_block,
};
const usbd_backend *msc_target_usb_driver(void)
{
return USBD_STM32_OTG_FS;
}
static const struct usb_string_descriptor string_lang_list = {
.bLength = USB_DT_STRING_SIZE(1),
.bDescriptorType = USB_DT_STRING,
.wData = {
USB_LANGID_ENGLISH_UNITED_STATES
}
};
const struct usb_string_descriptor usb_string_manuf = {
.bLength = USB_DT_STRING_SIZE(10),
.bDescriptorType = USB_DT_STRING,
/* danielinux */
.wData = {
0x0064, 0x0061, 0x006e, 0x0069, 0x0065, 0x006c, 0x0069, 0x006e, 0x0075, 0x0078
}
};
static const struct usb_string_descriptor usb_string_name = {
.bLength = USB_DT_STRING_SIZE(42),
.bDescriptorType = USB_DT_STRING,
/* "Encrypted SD Card in Secure Storage device" */
.wData = {
0x0045, 0x006e, 0x0063, 0x0072, 0x0079, 0x0070, 0x0074, 0x0065, 0x0064, 0x0020, 0x0053, 0x0044,
0x0020, 0x0043, 0x0061, 0x0072, 0x0064, 0x0020, 0x0069, 0x006e, 0x0020, 0x0053, 0x0065, 0x0063,
0x0075, 0x0072, 0x0065, 0x0020, 0x0053, 0x0074, 0x006f, 0x0072, 0x0061, 0x0067, 0x0065, 0x0020,
0x0064, 0x0065, 0x0076, 0x0069, 0x0063, 0x0065
}
};
static const struct usb_string_descriptor usb_serialn = {
.bLength = USB_DT_STRING_SIZE(3),
.bDescriptorType = USB_DT_STRING,
/* 000 */
.wData = {
0x0030, 0x0030, 0x0030
}
};
static const struct usb_string_descriptor **string_data[1] = {
(const struct usb_string_descriptor *[]) {
&usb_string_manuf,
&usb_string_name,
&usb_serialn
}
};
static const struct usb_device_descriptor msc_dev_desc= {
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = 0x0110,
.bDeviceClass = 0,
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
.bMaxPacketSize0 = 64,
.idVendor = 0x1d50,
.idProduct = 0xDAD0,
.bcdDevice = 0x0200,
.iManufacturer = 1,
.iProduct = 2,
.iSerialNumber = 3,
.bNumConfigurations = 1
};
static const struct __attribute__((packed)) {
struct usb_config_descriptor config;
struct usb_interface_descriptor msc_iface;
struct usb_endpoint_descriptor msc_endp[2];
} msc_config = {
.config = {
.bLength = USB_DT_CONFIGURATION_SIZE,
.bDescriptorType = USB_DT_CONFIGURATION,
.wTotalLength = sizeof(msc_config),
.bNumInterfaces = 1,
.bConfigurationValue = 1,
.iConfiguration = 0,
.bmAttributes = 0x80,
.bMaxPower = 0x32
},
.msc_iface = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 0,
.bAlternateSetting = 0,
.bNumEndpoints = 2,
.bInterfaceClass = USB_CLASS_MSC,
.bInterfaceSubClass = USB_MSC_SUBCLASS_SCSI,
.bInterfaceProtocol = USB_MSC_PROTOCOL_BBB,
.iInterface = 0
},
.msc_endp = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 0x01,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = 64,
.bInterval = 0,
}, {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 0x82,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = 64,
.bInterval = 0,
}}
};
static usbd_msc *ms;
static void msc_ep_set_config(usbd_device *usbd_dev,
const struct usb_config_descriptor *cfg)
{
(void)cfg;
usbd_ep_prepare(usbd_dev, 0x01, USBD_EP_BULK, 64, USBD_INTERVAL_NA, USBD_EP_DOUBLE_BUFFER);
usbd_ep_prepare(usbd_dev, 0x82, USBD_EP_BULK, 64, USBD_INTERVAL_NA, USBD_EP_DOUBLE_BUFFER);
usbd_msc_start(ms);
}
static const struct usbd_info_string msc_string = {
.lang_list = &string_lang_list,
.count = 3,
.data = string_data
};
static const struct usbd_info msc_info = {
.device = {
.desc = &msc_dev_desc,
.string = &msc_string
},
.config = {{
.desc = (const struct usb_config_descriptor *) &msc_config,
.string = &msc_string
}}
};
static void setup_callback(usbd_device *usbd_dev, uint8_t ep_addr,
const struct usb_setup_data *setup_data)
{
(void) ep_addr; /* assuming ep_addr == 0 */
if (!usbd_msc_setup_ep0(ms, setup_data)) {
usbd_ep0_setup(usbd_dev, setup_data);
}
}
static int usb_enabled = 0;
void usb_init(void)
{
if (usb_enabled == 0) {
rcc_periph_clock_enable(RCC_GPIOA);
rcc_periph_clock_enable(RCC_OTGFS);
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE,
GPIO9 | GPIO11 | GPIO12);
gpio_set_af(GPIOA, GPIO_AF10, GPIO9 | GPIO11 | GPIO12);
nvic_enable_irq(NVIC_OTG_FS_IRQ);
flash_backend.block_count = sdcard_getsize(NULL);
usbd_dev = usbd_init(msc_target_usb_driver(), NULL, &msc_info);
ms = usbd_msc_init(usbd_dev, 0x82, 64, 0x01, 64, &flash_backend);
usbd_register_set_config_callback(usbd_dev, msc_ep_set_config);
usbd_register_setup_callback(usbd_dev, setup_callback);
usb_enabled = 1;
}
}
void usb_deinit(void)
{
if (usb_enabled) {
rcc_periph_clock_disable(RCC_OTGFS);
nvic_disable_irq(NVIC_OTG_FS_IRQ);
gpio_mode_setup(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE,
GPIO9 | GPIO11 | GPIO12);
usb_enabled = 0;
}
}
static uint32_t last_call = 0;
void usb_poll(void)
{
bridge_lock();
if (usb_enabled && usbd_dev) {
if ((jiffies - last_call > 4)) {
usbd_poll(usbd_dev, 0);
last_call = jiffies;
}
}
bridge_unlock();
}
int bridge_init(void)
{
int ret = 0;
void *sdcard = sdcard_open();
if (!sdcard)
return -1;
usb_init();
return 0;
}
void otg_fs_isr(void)
{
last_call = jiffies;
usbd_poll(usbd_dev, 0);
}

5
usb.h Normal file
View file

@ -0,0 +1,5 @@
#ifndef USB_INCLUDED
#define USB_INCLUDED
void usb_init(void);
void usb_poll(void);
#endif

646
usecfs.c Normal file
View file

@ -0,0 +1,646 @@
#include <stdint.h>
#include <string.h>
#include "usecfs.h"
#include "usecfs_dev.h"
#ifndef NULL
# define NULL (void *)0
#endif
#define NO_BLOCK (0xFFFFFFFFUL)
#ifndef BLOCKDEV_OPEN_ARGS
# define BLOCKDEV_OPEN_ARGS (NULL)
#endif
#define MAX_BLOCKS_0 ((BLOCK_SIZE - MAX_FILENAME) / 4) - 3 /* accounts for 3 32bit fields + FILENAME */
#define MAX_BLOCKS_N ((BLOCK_SIZE - MAX_FILENAME) / 4) - 1 /* overhead is only 'extra' fields */
#define MAX_INLINE_SIZE ((MAX_BLOCKS_0 - 1) * 4) /* Max data size for self-contained block */
#define INLINE_PAYLOAD(x) ((uint8_t *)(&x->blk[1])) /* Macro to access INLINE paylaod */
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/sha256.h>
#ifdef CRYPTO
#define CRYPTO_BLOCK_SIZE 16
uint8_t crypto_tmp[CRYPTO_BLOCK_SIZE];
uint8_t crypto_iv[CRYPTO_BLOCK_SIZE];
#include <wolfssl/wolfcrypt/chacha.h>
#include <wolfssl/wolfcrypt/pwdbased.h>
static ChaCha chacha;
ChaCha *chacha_secret = &chacha;
#define CRYPTO_KEY_SIZE 32
#endif
#define HASH_LEN 32
#define MAGIC 0x5AFED15C
static uint8_t cache[BLOCK_SIZE];
static uint8_t inline_buffer_copy[MAX_INLINE_SIZE];
struct __attribute__((packed)) extra {
uint32_t extra;
uint32_t blk[(BLOCK_SIZE / 4) - 1];
};
struct __attribute__((packed)) inode {
uint32_t extra;
uint32_t blk[((BLOCK_SIZE - MAX_FILENAME) / 4) - 3];
uint32_t size;
uint32_t nextfile;
char filename[MAX_FILENAME];
};
struct __attribute__((packed)) root_block {
uint32_t magic;
uint32_t blk[((BLOCK_SIZE - MAX_FILENAME) / 4) - 3];
uint32_t fs_size; /* unused */
uint32_t nextfile;
uint8_t uuid[UUID_LEN];
uint8_t hash[HASH_LEN];
};
/* One-sector cache, single entry point for read/write
* on blocks
*/
static uint32_t cached_block = NO_BLOCK;
void *blockdev = NULL;
static int is_block_empty(void)
{
uint32_t *w = (uint32_t *)cache;
int i;
for(i = 0; i < (BLOCK_SIZE / sizeof(uint32_t)); i++) {
if (w[i] != NO_BLOCK)
return 0;
}
return 1;
}
static void cache_commit(void)
{
if (cached_block == NO_BLOCK)
return;
#ifdef CRYPTO
if (!is_block_empty()) {
uint32_t i;
memset(crypto_iv, 0, CRYPTO_BLOCK_SIZE);
for (i = 0; i < BLOCK_SIZE / CRYPTO_BLOCK_SIZE; i++) {
memcpy(&crypto_iv[0], &cached_block, sizeof(uint32_t));
memcpy(&crypto_iv[4], &i, sizeof(uint32_t));
memcpy(crypto_tmp, cache + (i * CRYPTO_BLOCK_SIZE), CRYPTO_BLOCK_SIZE);
wc_Chacha_SetIV(&chacha, crypto_iv, CRYPTO_BLOCK_SIZE);
wc_Chacha_Process(&chacha, cache + i * CRYPTO_BLOCK_SIZE, crypto_tmp, CRYPTO_BLOCK_SIZE);
}
}
#endif
block_write(blockdev, cache, cached_block);
cached_block = NO_BLOCK;
}
static void cache_load(uint32_t blk)
{
if (cached_block == blk)
return;
if (cached_block != NO_BLOCK)
cache_commit();
if (block_read(blockdev, cache, blk) == BLOCK_SIZE) {
cached_block = blk;
#ifdef CRYPTO
if (!is_block_empty()) {
uint32_t i;
memset(crypto_iv, 0, CRYPTO_BLOCK_SIZE);
for (i = 0; i < BLOCK_SIZE / CRYPTO_BLOCK_SIZE; i++) {
memcpy(&crypto_iv[0], &blk, sizeof(uint32_t));
memcpy(&crypto_iv[4], &i, sizeof(uint32_t));
memcpy(crypto_tmp, cache + (i * CRYPTO_BLOCK_SIZE), CRYPTO_BLOCK_SIZE);
wc_Chacha_SetIV(&chacha, crypto_iv, CRYPTO_BLOCK_SIZE);
wc_Chacha_Process(&chacha, cache + i * CRYPTO_BLOCK_SIZE, crypto_tmp, CRYPTO_BLOCK_SIZE);
}
}
#endif
}
}
static uint32_t get_file(const char *filename)
{
struct inode *ci = (struct inode *)cache;
uint32_t blk = 0;
cache_load(blk);
while (1) {
if (strncmp(filename, ci->filename, MAX_FILENAME - 1) == 0)
return blk;
if (ci->nextfile != NO_BLOCK) {
blk = ci->nextfile;
cache_load(blk);
} else
return NO_BLOCK;
}
return NO_BLOCK; /* Never reached */
}
static uint32_t get_free_block(uint32_t *fs_tail)
{
struct inode *ci = (struct inode *)cache;
struct extra *ce = (struct extra *)cache;
uint32_t first_free = 1;
uint32_t cur_inode_0 = 0;
int i;
cache_load(0);
if (ci->nextfile == NO_BLOCK) {
if (fs_tail)
*fs_tail = 0;
return 1;
}
cur_inode_0 = ci->nextfile;
cache_load(cur_inode_0);
while (1) {
for (i = 0; i < MAX_BLOCKS_0; i++)
{
if (ci->blk[i] == NO_BLOCK)
break;
if (first_free == ci->blk[i])
first_free++;
}
if (ci->extra != NO_BLOCK)
{
cache_load(ci->extra);
while (1) {
for (i = 0; i < MAX_BLOCKS_N; i++)
{
if (ce->blk[i] == NO_BLOCK)
break;
if (first_free == ce->blk[i])
first_free++;
}
if (ce->extra == NO_BLOCK)
break;
cache_load(ce->extra);
}
cache_load(cur_inode_0);
}
if (ci->nextfile != NO_BLOCK) {
cur_inode_0 = ci->nextfile;
cache_load(cur_inode_0);
} else {
if (fs_tail)
*fs_tail = cur_inode_0;
return first_free;
}
}
}
static uint32_t new_inode(void)
{
struct inode *ci = (struct inode *)cache;
uint32_t fs_tail = NO_BLOCK;
uint32_t new_block = get_free_block(&fs_tail);
if (new_block == NO_BLOCK || fs_tail == NO_BLOCK)
return NO_BLOCK;
cache_load(fs_tail);
ci->nextfile = new_block;
cache_load(new_block);
memset(cache, 0xFF, BLOCK_SIZE);
ci->nextfile = NO_BLOCK;
return new_block;
}
struct openfile {
uint32_t blk;
uint32_t off;
};
struct openfile OpenFiles[MAX_OPEN_FILES];
static int get_free_fd(void)
{
int i, free_fd = -1;
for (i = 0; i < MAX_OPEN_FILES; i++) {
if (OpenFiles[i].blk == NO_BLOCK) {
free_fd = i;
break;
}
}
return free_fd;
}
static uint32_t get_index_block(uint32_t inode0, uint32_t off)
{
struct inode *ci = (struct inode *)cache;
struct extra *ce = (struct extra *)cache;
uint32_t idx = 0;
cache_load(inode0);
idx = off / BLOCK_SIZE;
if (idx <= MAX_BLOCKS_0)
return inode0;
if (ci->extra == NO_BLOCK)
return NO_BLOCK;
inode0 = ci->extra;
cache_load(inode0);
idx -= MAX_BLOCKS_0;
while (idx >= MAX_BLOCKS_N) {
if (ce->extra == NO_BLOCK)
return NO_BLOCK;
inode0 = ce->extra;
cache_load(inode0);
idx -= MAX_BLOCKS_N;
}
return inode0;
}
static void set_block(uint32_t node0, uint32_t nodeN, uint32_t off)
{
struct inode *ci = (struct inode *)cache;
struct extra *ce = (struct extra *)cache;
uint32_t idx;
uint32_t idxblk;
idxblk = get_index_block(node0, off);
}
static void file_grow(uint32_t node0, uint32_t newsize)
{
struct inode *ci = (struct inode *)cache;
struct extra *ce = (struct extra *)cache;
uint32_t cur_idx, new_idx;
uint32_t cur_idx_block, new_idx_block;
uint32_t i;
cache_load(node0);
cur_idx = ci->size / BLOCK_SIZE;
new_idx = newsize / BLOCK_SIZE;
cur_idx_block = get_index_block(node0, ci->size);
new_idx_block = get_index_block(node0, newsize);
for (i = cur_idx; i < new_idx; i++) {
cur_idx_block = get_index_block(node0, i * BLOCK_SIZE);
if (cur_idx_block == NO_BLOCK)
return;
cache_load(cur_idx_block);
if (cur_idx_block == node0) {
uint32_t idx = i + 1;
if (idx == (MAX_BLOCKS_0)) {
uint32_t extra = get_free_block(NULL);
cache_load(extra);
memset(cache, 0xFF, BLOCK_SIZE);
cache_load(node0);
ci->extra = extra;
cache_load(extra);
idx = 0;
}
ci->blk[idx] = get_free_block(NULL);
} else {
uint32_t idx = ((i - MAX_BLOCKS_0) % MAX_BLOCKS_N) + 1;
if (idx == MAX_BLOCKS_N) {
uint32_t extra = get_free_block(NULL);
cache_load(extra);
memset(cache, 0xFF, BLOCK_SIZE);
cache_load(cur_idx_block);
ce->extra = extra;
cache_load(extra);
idx = 0;
}
ce->blk[idx] = get_free_block(NULL);
}
}
if (ci->size < newsize)
ci->size = newsize;
}
/* Public interface */
int usecfs_format(const uint8_t *uuid)
{
struct root_block *rb = (struct root_block *)cache;
wc_Sha256 sha;
cache_load(0);
memset(cache, 0xFF, BLOCK_SIZE);
rb->magic = MAGIC;
rb->blk[0] = 0;
memcpy(rb->uuid, uuid, UUID_LEN);
wc_InitSha256(&sha);
wc_Sha256Update(&sha, uuid, UUID_LEN);
wc_Sha256Final(&sha, rb->hash);
cache_commit();
return 0;
}
int usecfs_mount(uint8_t *uuid)
{
struct root_block *rb = (struct root_block *)cache;
wc_Sha256 sha;
uint8_t hash[HASH_LEN];
cache_load(0);
if (rb->magic != MAGIC)
return -1;
wc_InitSha256(&sha);
wc_Sha256Update(&sha, rb->uuid, UUID_LEN);
wc_Sha256Final(&sha, hash);
if (memcmp(hash, rb->hash, HASH_LEN) != 0)
return -1;
if (uuid)
memcpy(uuid, rb->uuid, UUID_LEN);
return 0;
}
int usecfs_read(int fd, void *data, uint32_t len)
{
int r = 0;
uint32_t node0 = OpenFiles[fd].blk;
uint32_t *off = &OpenFiles[fd].off;
struct inode *ci = (struct inode *)cache;
if (node0 == NO_BLOCK)
return -1;
cache_load(node0);
if ((ci->size - *off) < len)
len = ci->size - *off;
if (ci->blk[0] == node0) {
/* file is INLINE */
memcpy(data, INLINE_PAYLOAD(ci), len);
*off += len;
return len;
}
while (r < len) {
int idx = *off / BLOCK_SIZE;
uint32_t idx_block;
uint32_t off_within_block;
uint32_t len_within_block;
/* Find the index block for the offset */
idx_block = get_index_block(node0, *off);
if (idx_block == NO_BLOCK)
return -1;
cache_load(idx_block);
if (ci->blk[idx] == NO_BLOCK)
return -1;
cache_load(ci->blk[idx]);
/* Find the offset/len within this block */
off_within_block = *off % BLOCK_SIZE;
len_within_block = BLOCK_SIZE - off_within_block;
if (len_within_block > (len - r))
len_within_block = (len - r);
/* Copy data from cache, increase counters */
memcpy(data + r, cache + off_within_block, len_within_block);
r += len_within_block;
*off += len_within_block;
}
return len;
}
int usecfs_write(int fd, const void *data, uint32_t len)
{
int w = 0;
uint32_t node0 = OpenFiles[fd].blk;
uint32_t *off = &OpenFiles[fd].off;
struct inode *ci = (struct inode *)cache;
uint32_t blkn;
if (node0 == NO_BLOCK)
return -1;
cache_load(node0);
if (ci->size + *off <= MAX_INLINE_SIZE) {
if (ci->size + *off + len <= MAX_INLINE_SIZE) {
/* file can still be inline */
memcpy(INLINE_PAYLOAD(ci) + *off, data, len);
*off += len;
if (*off > ci->size)
ci->size = *off;
cache_commit();
return len;
} else {
/* Special case: migrating data to new block */
memcpy(inline_buffer_copy, INLINE_PAYLOAD(ci), MAX_INLINE_SIZE);
blkn = get_free_block(NULL);
memcpy(cache, inline_buffer_copy, MAX_INLINE_SIZE);
cache_load(node0);
ci->blk[0] = blkn;
}
}
if (ci->size < *off + len)
file_grow(node0, *off + len);
while (w < len) {
uint32_t off_within_block;
uint32_t len_within_block;
int idx = *off / BLOCK_SIZE;
uint32_t idx_block;
idx_block = get_index_block(node0, *off);
if (idx_block == NO_BLOCK)
return -1;
cache_load(idx_block);
off_within_block = *off % BLOCK_SIZE;
len_within_block = BLOCK_SIZE - off_within_block;
if (len_within_block > (len - w))
len_within_block = (len - w);
if (ci->blk[idx] == NO_BLOCK)
return -1;
cache_load(ci->blk[idx]);
memcpy(cache + off_within_block, data + w, len_within_block);
w += len_within_block;
*off += len_within_block;
}
return len;
}
int usecfs_seek(int fd, int offset, int whence)
{
struct inode *ci = (struct inode *)cache;
if (OpenFiles[fd].blk == NO_BLOCK)
return -1;
cache_load(OpenFiles[fd].blk);
switch(whence) {
case 0: /* SEEK_SET */
if (offset < 0)
return -1;
OpenFiles[fd].off = offset;
break;
case 1: /* SEEK_CUR */
if ((OpenFiles[fd].off - offset) < 0)
OpenFiles[fd].off = 0;
else
OpenFiles[fd].off += offset;
break;
case 2: /* SEEK_END */
OpenFiles[fd].off = ci->size + offset;
break;
default:
return -1;
} /* switch(whence) */
if (OpenFiles[fd].off > ci->size)
file_grow(OpenFiles[fd].blk, OpenFiles[fd].off);
return OpenFiles[fd].off;
}
int usecfs_open(const char *name)
{
int free_fd;
free_fd = get_free_fd();
if (free_fd < 0)
return -1;
OpenFiles[free_fd].blk = get_file(name);
if (OpenFiles[free_fd].blk == NO_BLOCK)
return -1;
OpenFiles[free_fd].off = 0;
return free_fd;
}
int usecfs_creat(const char *name)
{
int free_fd;
int i;
uint32_t newnode;
struct inode *ci = (struct inode *)cache;
free_fd = get_free_fd();
if (free_fd < 0)
return -1;
if (get_file(name) != NO_BLOCK)
return -1;
newnode = new_inode();
if (newnode == NO_BLOCK)
return -1;
OpenFiles[free_fd].blk = newnode;
/* Initialize inode (already in cache from new_inode()) */
ci->size = 0; /* newly created file is zero bytes long */
memset(ci->filename, 0, MAX_FILENAME);
for (i = 0; (i < strlen(name)) && (i < MAX_FILENAME - 1); i++)
ci->filename[i] = name[i];
ci->blk[0] = newnode; /* self-reference, start as INLINE */
for (i = 1; i < MAX_BLOCKS_0; i++)
ci->blk[i] = NO_BLOCK;
OpenFiles[free_fd].off = 0;
cache_commit();
return free_fd;
}
int usecfs_truncate(int fd, uint32_t newsize)
{
struct inode *ci = (struct inode *)cache;
struct extra *ce = (struct extra *)cache;
uint32_t idx, new_idx;
uint32_t last_block_idx;
uint32_t idx_block, new_idx_block;
uint32_t node0 = OpenFiles[fd].blk;
uint32_t idx_off;
uint32_t i;
if (node0 == NO_BLOCK)
return -1;
cache_load(OpenFiles[fd].blk);
if (ci->size <= newsize)
return -1;
idx = ci->size / BLOCK_SIZE;
new_idx = newsize / BLOCK_SIZE;
if (ci->size <= (BLOCK_SIZE * MAX_BLOCKS_0) || /* File is inlined, or */
(idx == new_idx) ) /* number of blocks is unchanged? */
{
ci->size = newsize;
return 0;
}
if ((ci->size > MAX_INLINE_SIZE) && (newsize <= MAX_INLINE_SIZE))
{
/* Special case: file was big, now it's inlined. */
cache_load(ci->blk[0]);
memcpy(inline_buffer_copy, cache, newsize);
cache_load(node0);
memcpy(INLINE_PAYLOAD(ci), inline_buffer_copy, newsize);
ci->blk[0] = node0; /* establish self-reference */
for (i = 1; i < MAX_BLOCKS_0; i++)
ci->blk[i] = NO_BLOCK;
ci->size = newsize;
return 0;
}
idx_block = get_index_block(node0, ci->size);
new_idx_block = get_index_block(node0, newsize);
cache_load(new_idx_block);
if (idx_block != new_idx_block)
ci->extra = NO_BLOCK;
if (idx_block <= MAX_BLOCKS_0) {
idx_off = new_idx_block;
for (i = idx_off; i < MAX_BLOCKS_N; i++)
ce->blk[i] = NO_BLOCK;
} else {
idx_off = (new_idx_block - MAX_BLOCKS_0) % MAX_BLOCKS_N;
while (idx_off > MAX_BLOCKS_N)
idx_off -= MAX_BLOCKS_N;
for (i = idx_off; i < MAX_BLOCKS_N; i++)
ce->blk[i] = NO_BLOCK;
}
ci->size = newsize;
return 0;
}
int usecfs_unlink(const char *filename)
{
struct inode *ci = (struct inode *)cache;
uint32_t blk = 1;
uint32_t blk_prev = 0;
uint32_t blk_next;
cache_load(blk);
while (1) {
if (strncmp(filename, ci->filename, MAX_FILENAME - 1) == 0)
{
blk_next = ci->nextfile;
cache_load(blk_prev);
ci->nextfile = blk_next;
return 0;
}
if (ci->nextfile != NO_BLOCK) {
blk_prev = blk;
blk = ci->nextfile;
cache_load(blk);
} else
return -1;
}
return -1; /* Never reached */
}
int usecfs_close(int fd)
{
if (OpenFiles[fd].blk != NO_BLOCK) {
cache_commit();
OpenFiles[fd].blk = NO_BLOCK;
}
return 0;
}
#define SALT_LEN 32
const uint8_t password_salt[SALT_LEN] = {
0xe7, 0xa1, 0x9c, 0xb0, 0x48, 0xa8, 0x30, 0xf9, 0x37, 0xda, 0x8e, 0xde,
0xff, 0xb2, 0x62, 0x03, 0x24, 0x55, 0xb8, 0x8b, 0x7b, 0x18, 0x68, 0x57,
0x7d, 0x35, 0xbe, 0xbd, 0xf6, 0x0e, 0xc1, 0x2c
};
static uint8_t chacha_key[CRYPTO_KEY_SIZE];
int usecfs_getkey(void)
{
return chacha_key;
}
int usecfs_init(const char *password, int format, uint8_t *uuid)
{
blockdev = block_open(BLOCKDEV_OPEN_ARGS);
if (!blockdev)
return -1;
memset(OpenFiles, 0xFF, MAX_OPEN_FILES * sizeof(struct openfile));
{
int ret = 0;
ret = wc_PBKDF2(chacha_key, password, strlen(password), password_salt, SALT_LEN, 2048, CRYPTO_KEY_SIZE, SHA256);
wc_Chacha_SetKey(&chacha, chacha_key, CRYPTO_KEY_SIZE);
}
if (format) {
if (!uuid)
return -1;
else
return usecfs_format(uuid);
} else
return usecfs_mount(uuid);
}

20
usecfs.h Normal file
View file

@ -0,0 +1,20 @@
#ifndef INC_USECFS
#define INC_USECFS
#define MAX_FILENAME 256
#define MAX_OPEN_FILES 16
#define UUID_LEN 64
#include <stdint.h>
int usecfs_init(const char *password, int format, uint8_t *uuid);
int usecfs_format(const uint8_t *uuid);
int usecfs_mount(uint8_t *uuid);
int usecfs_open(const char *name);
int usecfs_creat(const char *name);
int usecfs_read(int fd, void *data, uint32_t len);
int usecfs_write(int fd, const void *data, uint32_t len);
int usecfs_seek(int fd, int offset, int whence);
int usecfs_truncate(int fd, uint32_t newsize);
int usecfs_unlink(const char *filename);
int usecfs_close(int fd);
#endif

13
usecfs_dev.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef INC_USECFS_BLOCK
#define INC_USECFS_BLOCK
#ifndef BLOCK_SIZE
# define BLOCK_SIZE 4096
#endif
void *block_open(void *args);
int block_read(void *dev, void *_buf, uint32_t lba);
int block_write(void *dev, const void *_buf, uint32_t lba);
void block_close(void *dev);
#endif

View file

@ -13,6 +13,9 @@
#define HAVE_CHACHA
#define HAVE_SHA256
#define HAVE_PBKDF2
#define HAVE_AES
#define HAVE_AES_CBC
#define HAVE_AES_DECRYPT
#define CUSTOM_RAND_GENERATE random_uint32
#define CUSTOM_RAND_TYPE uint32_t
@ -25,7 +28,6 @@
#define SINGLE_THREADED
/* Disables - For minimum wolfCrypt build */
#define NO_AES
#define NO_CMAC
#define NO_CODING
#define NO_RSA