Compare commits
No commits in common. "46329a7aa2144d744e9ad4222620ad2ecf07b538" and "eb1a572eff56445bfee94b3aa945887ba9da6a6f" have entirely different histories.
46329a7aa2
...
eb1a572eff
16 changed files with 34 additions and 1273 deletions
16
Makefile
16
Makefile
|
@ -1,15 +1,15 @@
|
||||||
CROSS_COMPILE:=arm-none-eabi-
|
CROSS_COMPILE:=arm-none-eabi-
|
||||||
CC:=$(CROSS_COMPILE)gcc
|
CC:=$(CROSS_COMPILE)gcc
|
||||||
LD:=$(CROSS_COMPILE)gcc
|
LD:=$(CROSS_COMPILE)gcc
|
||||||
|
USECFS:=$(HOME)/src/usecfs
|
||||||
WOLFSSL:=$(HOME)/src/wolfssl
|
WOLFSSL:=$(HOME)/src/wolfssl
|
||||||
|
|
||||||
OBJS:=startup.o main.o system.o usecfs_dev_spi.o usecfs.o mem.o led.o \
|
OBJS:=startup.o main.o system.o usecfs_dev_spi.o $(USECFS)/src/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 \
|
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 usb.o mutex.o
|
sdcard.o random.o
|
||||||
OBJS+= \
|
OBJS+= \
|
||||||
$(WOLFSSL)/wolfcrypt/src/sha256.o \
|
$(WOLFSSL)/wolfcrypt/src/sha256.o \
|
||||||
$(WOLFSSL)/wolfcrypt/src/chacha.o \
|
$(WOLFSSL)/wolfcrypt/src/chacha.o \
|
||||||
$(WOLFSSL)/wolfcrypt/src/aes.o \
|
|
||||||
$(WOLFSSL)/wolfcrypt/src/pwdbased.o \
|
$(WOLFSSL)/wolfcrypt/src/pwdbased.o \
|
||||||
$(WOLFSSL)/wolfcrypt/src/hash.o \
|
$(WOLFSSL)/wolfcrypt/src/hash.o \
|
||||||
$(WOLFSSL)/wolfcrypt/src/hmac.o \
|
$(WOLFSSL)/wolfcrypt/src/hmac.o \
|
||||||
|
@ -30,14 +30,13 @@ LSCRIPT:=target.ld
|
||||||
|
|
||||||
OBJCOPY:=$(CROSS_COMPILE)objcopy
|
OBJCOPY:=$(CROSS_COMPILE)objcopy
|
||||||
|
|
||||||
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:=-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+=-specs=nano.specs -lc -lg
|
CFLAGS+=-specs=nano.specs -lc -lg
|
||||||
CFLAGS+=$(UMXFLAGS)
|
CFLAGS+=$(UMXFLAGS)
|
||||||
CFLAGS+=-O2
|
#CFLAGS+=-O2
|
||||||
#CFLAGS+=-g -ggdb3
|
CFLAGS+=-g -ggdb3
|
||||||
|
|
||||||
CFLAGS+=-DWOLFSSL_USER_SETTINGS -DCRYPTO
|
CFLAGS+=-DWOLFSSL_USER_SETTINGS -DCRYPTO
|
||||||
ASFLAGS:=$(CFLAGS)
|
|
||||||
|
|
||||||
LDFLAGS:=-T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=image.map -mcpu=cortex-m3 -mthumb -nostartfiles
|
LDFLAGS:=-T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=image.map -mcpu=cortex-m3 -mthumb -nostartfiles
|
||||||
|
|
||||||
|
@ -53,5 +52,4 @@ $(UMX):
|
||||||
make -C lib/unicore-mx FP_FLAGS="-O3 -mfloat-abi=soft" TARGETS=stm32/f4
|
make -C lib/unicore-mx FP_FLAGS="-O3 -mfloat-abi=soft" TARGETS=stm32/f4
|
||||||
|
|
||||||
clean:
|
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
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 242585ee67510f65fd2e2fb5c809621410459ac6
|
Subproject commit 3ddec02525f0b507c8a54f5dbad0df9340772a36
|
10
main.c
10
main.c
|
@ -17,7 +17,6 @@
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "sdcard.h"
|
#include "sdcard.h"
|
||||||
#include "button.h"
|
#include "button.h"
|
||||||
#include "usb.h"
|
|
||||||
extern uint32_t cpu_freq;
|
extern uint32_t cpu_freq;
|
||||||
|
|
||||||
#define BLINK_INTERVAL 500
|
#define BLINK_INTERVAL 500
|
||||||
|
@ -75,10 +74,6 @@ static void bootlevel_1(void)
|
||||||
led_on(YELLOW_LED);
|
led_on(YELLOW_LED);
|
||||||
sdcard_detected = 1;
|
sdcard_detected = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Activating USB mass storage device\r\n");
|
|
||||||
|
|
||||||
printf("Activating I2C bus\r\n");
|
|
||||||
|
|
||||||
i2c_display_init();
|
i2c_display_init();
|
||||||
printf("Display initialized.\r\n");
|
printf("Display initialized.\r\n");
|
||||||
|
@ -94,6 +89,10 @@ static void bootlevel_1(void)
|
||||||
void process_button(uint16_t press, int hold)
|
void process_button(uint16_t press, int hold)
|
||||||
{
|
{
|
||||||
char c = bu2c(press);
|
char c = bu2c(press);
|
||||||
|
if (!hold)
|
||||||
|
printf("Pressed '%c'.\r\n", c);
|
||||||
|
else
|
||||||
|
printf("Held '%c'.\r\n", c);
|
||||||
ui_button_press(press);
|
ui_button_press(press);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +127,6 @@ int main(void) {
|
||||||
|
|
||||||
do {
|
do {
|
||||||
WFI();
|
WFI();
|
||||||
usb_poll();
|
|
||||||
ret = button_poll(process_button);
|
ret = button_poll(process_button);
|
||||||
if (jiffies - poll_time > hb_pulse) {
|
if (jiffies - poll_time > hb_pulse) {
|
||||||
if (hb) {
|
if (hb) {
|
||||||
|
|
47
mutex.S
47
mutex.S
|
@ -1,47 +0,0 @@
|
||||||
|
|
||||||
.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
|
|
||||||
|
|
7
sdcard.c
7
sdcard.c
|
@ -450,13 +450,6 @@ int sdcard_read(void *dev, void *_buf, uint32_t lba)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t sdcard_getsize(void *dev)
|
|
||||||
{
|
|
||||||
if (SD.card)
|
|
||||||
return SD.card->size;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write a Block from our Card
|
* Write a Block from our Card
|
||||||
*/
|
*/
|
||||||
|
|
1
sdcard.h
1
sdcard.h
|
@ -58,7 +58,6 @@ int sdcard_read(void *dev, void *_buf, uint32_t lba);
|
||||||
int sdcard_write(void *dev, void *_buf, uint32_t lba);
|
int sdcard_write(void *dev, void *_buf, uint32_t lba);
|
||||||
int sdcard_sense(void);
|
int sdcard_sense(void);
|
||||||
int sdcard_detect(void);
|
int sdcard_detect(void);
|
||||||
uint32_t sdcard_getsize(void *dev);
|
|
||||||
void sdcard_hw_init(void);
|
void sdcard_hw_init(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
47
startup.c
47
startup.c
|
@ -22,8 +22,6 @@ static unsigned int sp;
|
||||||
extern void main(void);
|
extern void main(void);
|
||||||
extern void isr_exti(void);
|
extern void isr_exti(void);
|
||||||
extern void isr_systick(void);
|
extern void isr_systick(void);
|
||||||
extern void otg_fs_isr(void);
|
|
||||||
extern void usb_fs_wkup_isr(void);
|
|
||||||
|
|
||||||
void isr_reset(void) {
|
void isr_reset(void) {
|
||||||
register unsigned int *src, *dst;
|
register unsigned int *src, *dst;
|
||||||
|
@ -151,54 +149,11 @@ void (* const IV[])(void) =
|
||||||
isr_empty, // USART3_IRQ 39
|
isr_empty, // USART3_IRQ 39
|
||||||
isr_exti, // EXTI15_10_IRQ 40
|
isr_exti, // EXTI15_10_IRQ 40
|
||||||
isr_empty, // RTC_ALARM_IRQ 41
|
isr_empty, // RTC_ALARM_IRQ 41
|
||||||
usb_fs_wkup_isr, // USB_FS_WKUP_IRQ 42
|
isr_empty, // USB_FS_WKUP_IRQ 42
|
||||||
isr_empty, // TIM8_BRK_TIM12_IRQ 43
|
isr_empty, // TIM8_BRK_TIM12_IRQ 43
|
||||||
isr_empty, // TIM8_UP_TIM13_IRQ 44
|
isr_empty, // TIM8_UP_TIM13_IRQ 44
|
||||||
isr_empty, // TIM8_TRG_COM_TIM14_IRQ 45
|
isr_empty, // TIM8_TRG_COM_TIM14_IRQ 45
|
||||||
isr_empty, // TIM8_CC_IRQ 46
|
isr_empty, // TIM8_CC_IRQ 46
|
||||||
isr_empty, // DMA1_STREAM7_IRQ 47
|
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
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
17
system.h
17
system.h
|
@ -5,10 +5,7 @@
|
||||||
#define PLL_FULL_MASK (0x7F037FFF)
|
#define PLL_FULL_MASK (0x7F037FFF)
|
||||||
extern uint32_t cpu_freq;
|
extern uint32_t cpu_freq;
|
||||||
void panic(void);
|
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 */
|
/* PIN CONFIG TARGET */
|
||||||
#define BLUE_LED 4
|
#define BLUE_LED 4
|
||||||
|
@ -430,18 +427,4 @@ static inline void nvic_irq_clear(uint8_t n)
|
||||||
#define SDIO_MASK_CCRCFAILIE (1 << 0)
|
#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
|
#endif
|
||||||
|
|
14
uart.c
14
uart.c
|
@ -6,7 +6,6 @@
|
||||||
* See LICENSE for details
|
* See LICENSE for details
|
||||||
*/
|
*/
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
|
@ -117,16 +116,3 @@ int _write(void *r, uint8_t *text, int len)
|
||||||
return 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");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
90
ui.c
90
ui.c
|
@ -13,7 +13,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "usecfs.h"
|
#include "usecfs.h"
|
||||||
#include "usb.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Uncomment for device initialization */
|
/* Uncomment for device initialization */
|
||||||
|
@ -43,7 +42,6 @@ static uint32_t offset = 0;
|
||||||
#define MAX_PASSWORD 32
|
#define MAX_PASSWORD 32
|
||||||
|
|
||||||
static int fsm_state = ST_LOCKED;
|
static int fsm_state = ST_LOCKED;
|
||||||
static int sleeping = 0;
|
|
||||||
|
|
||||||
static char password[MAX_PASSWORD] = {};
|
static char password[MAX_PASSWORD] = {};
|
||||||
static int pin_idx = 0;
|
static int pin_idx = 0;
|
||||||
|
@ -51,36 +49,12 @@ static int pin_idx = 0;
|
||||||
|
|
||||||
#define SLEEP_TIME (5000)
|
#define SLEEP_TIME (5000)
|
||||||
|
|
||||||
static void ui_sleep(void)
|
|
||||||
{
|
|
||||||
display_scroll(NULL, 0);
|
|
||||||
display_clear(NULL);
|
|
||||||
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)
|
void ui_msg(const char *txt)
|
||||||
{
|
{
|
||||||
ui_wakeup();
|
|
||||||
display_scroll(NULL, 0);
|
display_scroll(NULL, 0);
|
||||||
display_clear(NULL);
|
display_clear(NULL);
|
||||||
display_text(6, txt);
|
display_text(6, txt);
|
||||||
|
last_action = jiffies;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lock(void)
|
void lock(void)
|
||||||
|
@ -90,7 +64,7 @@ void lock(void)
|
||||||
fsm_state = ST_LOCKED;
|
fsm_state = ST_LOCKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pwdrst(void)
|
static void pwrst(void)
|
||||||
{
|
{
|
||||||
memset(password, 0, MAX_PASSWORD);
|
memset(password, 0, MAX_PASSWORD);
|
||||||
pin_idx = 0;
|
pin_idx = 0;
|
||||||
|
@ -100,11 +74,8 @@ int unlock(void)
|
||||||
{
|
{
|
||||||
uint8_t stored_uuid[UUID_LEN];
|
uint8_t stored_uuid[UUID_LEN];
|
||||||
if (pin_idx < 6) {
|
if (pin_idx < 6) {
|
||||||
display_scroll(NULL, 0);
|
display_text(6, "Failed.");
|
||||||
display_clear(NULL);
|
pwrst();
|
||||||
display_text(5, "Failed.");
|
|
||||||
display_text(6, "Insert pin:");
|
|
||||||
pwdrst();
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
display_scroll(NULL, 0);
|
display_scroll(NULL, 0);
|
||||||
|
@ -113,7 +84,7 @@ int unlock(void)
|
||||||
display_text(5, "Unlocking secret");
|
display_text(5, "Unlocking secret");
|
||||||
if ((usecfs_init(password, 0, stored_uuid) == 0) &&
|
if ((usecfs_init(password, 0, stored_uuid) == 0) &&
|
||||||
(memcmp(stored_uuid, uuid, UUID_LEN) == 0)) {
|
(memcmp(stored_uuid, uuid, UUID_LEN) == 0)) {
|
||||||
pwdrst();
|
pwrst();
|
||||||
fsm_state = ST_UNLOCKED;
|
fsm_state = ST_UNLOCKED;
|
||||||
ui_msg("Device UNLOCKED");
|
ui_msg("Device UNLOCKED");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -125,11 +96,8 @@ int unlock(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
display_scroll(NULL, 0);
|
display_text(6, "Failed.");
|
||||||
display_clear(NULL);
|
pwrst();
|
||||||
display_text(5, "Failed.");
|
|
||||||
display_text(6, "Insert pin:");
|
|
||||||
pwdrst();
|
|
||||||
fsm_state = ST_LOCKED;
|
fsm_state = ST_LOCKED;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -138,21 +106,13 @@ int unlock(void)
|
||||||
|
|
||||||
void ui_button_hold(uint16_t button)
|
void ui_button_hold(uint16_t button)
|
||||||
{
|
{
|
||||||
ui_wakeup();
|
last_action = jiffies;
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
void ui_sdcard_insert(void)
|
||||||
{
|
{
|
||||||
ui_wakeup();
|
|
||||||
ui_msg("SD Card detected");
|
ui_msg("SD Card detected");
|
||||||
|
last_action = jiffies;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_menu(char in)
|
void ui_menu(char in)
|
||||||
|
@ -165,43 +125,27 @@ void ui_menu(char in)
|
||||||
display_text(7, "1. Status ");
|
display_text(7, "1. Status ");
|
||||||
display_text(6, "0. Lockdown ");
|
display_text(6, "0. Lockdown ");
|
||||||
display_text(5, "Main Menu ");
|
display_text(5, "Main Menu ");
|
||||||
display_text(2, "4. UART menu ");
|
display_text(2, "4. Reboot ");
|
||||||
display_text(1, "3. SD format ");
|
display_text(1, "3. SD format ");
|
||||||
display_text(0, "2. USB vault ON ");
|
display_text(0, "2. USB vault ON ");
|
||||||
switch (in) {
|
switch (in) {
|
||||||
case ' ':
|
case ' ':
|
||||||
menu_scroll += 4;
|
menu_scroll += 4;
|
||||||
menu_scroll %= 0x40;
|
|
||||||
display_scroll(NULL, menu_scroll);
|
|
||||||
break;
|
break;
|
||||||
case '\r':
|
case '\r':
|
||||||
menu_scroll -= 4;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
menu_scroll %= 0x40;
|
||||||
|
display_scroll(NULL, menu_scroll);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_button_press(uint16_t button)
|
void ui_button_press(uint16_t button)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char c;
|
char c;
|
||||||
if (ui_wakeup())
|
|
||||||
c = 0;
|
|
||||||
else
|
|
||||||
c = bu2c(button);
|
|
||||||
if (fsm_state == ST_LOCKED) {
|
if (fsm_state == ST_LOCKED) {
|
||||||
pwdrst();
|
pwrst();
|
||||||
ui_msg("Insert pin:");
|
ui_msg("Insert pin:");
|
||||||
fsm_state = ST_PIN_ENTRY;
|
fsm_state = ST_PIN_ENTRY;
|
||||||
return;
|
return;
|
||||||
|
@ -211,6 +155,7 @@ void ui_button_press(uint16_t button)
|
||||||
for (i = 0; i < pin_idx; i++) {
|
for (i = 0; i < pin_idx; i++) {
|
||||||
line[i] = '*';
|
line[i] = '*';
|
||||||
}
|
}
|
||||||
|
c = bu2c(button);
|
||||||
if ((c >= '0') && (c <='9')) {
|
if ((c >= '0') && (c <='9')) {
|
||||||
if (pin_idx < 16) {
|
if (pin_idx < 16) {
|
||||||
line[pin_idx] = 'X';
|
line[pin_idx] = 'X';
|
||||||
|
@ -220,13 +165,17 @@ void ui_button_press(uint16_t button)
|
||||||
if (c == '\r') {
|
if (c == '\r') {
|
||||||
unlock();
|
unlock();
|
||||||
} else {
|
} else {
|
||||||
|
display_scroll(NULL, 0);
|
||||||
|
display_clear(NULL);
|
||||||
display_text(7, line);
|
display_text(7, line);
|
||||||
|
display_text(6, "Insert pin:");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fsm_state == ST_UNLOCKED)
|
if (fsm_state == ST_UNLOCKED)
|
||||||
{
|
{
|
||||||
ui_menu(bu2c(button));
|
ui_menu(bu2c(button));
|
||||||
}
|
}
|
||||||
|
last_action = jiffies;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_init(void)
|
void ui_init(void)
|
||||||
|
@ -259,7 +208,8 @@ void ui_init(void)
|
||||||
void ui_keepalive(uint32_t timeslice)
|
void ui_keepalive(uint32_t timeslice)
|
||||||
{
|
{
|
||||||
if ((jiffies - last_action) > SLEEP_TIME) {
|
if ((jiffies - last_action) > SLEEP_TIME) {
|
||||||
ui_sleep();
|
display_scroll(NULL, 0);
|
||||||
|
display_clear(NULL);
|
||||||
if (fsm_state == ST_PIN_ENTRY)
|
if (fsm_state == ST_PIN_ENTRY)
|
||||||
lock();
|
lock();
|
||||||
}
|
}
|
||||||
|
|
368
usb.c
368
usb.c
|
@ -1,368 +0,0 @@
|
||||||
#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
5
usb.h
|
@ -1,5 +0,0 @@
|
||||||
#ifndef USB_INCLUDED
|
|
||||||
#define USB_INCLUDED
|
|
||||||
void usb_init(void);
|
|
||||||
void usb_poll(void);
|
|
||||||
#endif
|
|
646
usecfs.c
646
usecfs.c
|
@ -1,646 +0,0 @@
|
||||||
#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
20
usecfs.h
|
@ -1,20 +0,0 @@
|
||||||
#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
13
usecfs_dev.h
|
@ -1,13 +0,0 @@
|
||||||
#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
|
|
|
@ -13,9 +13,6 @@
|
||||||
#define HAVE_CHACHA
|
#define HAVE_CHACHA
|
||||||
#define HAVE_SHA256
|
#define HAVE_SHA256
|
||||||
#define HAVE_PBKDF2
|
#define HAVE_PBKDF2
|
||||||
#define HAVE_AES
|
|
||||||
#define HAVE_AES_CBC
|
|
||||||
#define HAVE_AES_DECRYPT
|
|
||||||
|
|
||||||
#define CUSTOM_RAND_GENERATE random_uint32
|
#define CUSTOM_RAND_GENERATE random_uint32
|
||||||
#define CUSTOM_RAND_TYPE uint32_t
|
#define CUSTOM_RAND_TYPE uint32_t
|
||||||
|
@ -28,6 +25,7 @@
|
||||||
#define SINGLE_THREADED
|
#define SINGLE_THREADED
|
||||||
|
|
||||||
/* Disables - For minimum wolfCrypt build */
|
/* Disables - For minimum wolfCrypt build */
|
||||||
|
#define NO_AES
|
||||||
#define NO_CMAC
|
#define NO_CMAC
|
||||||
#define NO_CODING
|
#define NO_CODING
|
||||||
#define NO_RSA
|
#define NO_RSA
|
||||||
|
|
Loading…
Reference in a new issue