diff --git a/.gitmodules b/.gitmodules index 9793beb..53e048c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "lib/unicore-mx"] path = lib/unicore-mx url = https://gitlab.com/insane-adding-machines/unicore-mx +[submodule "wolfboot"] + path = wolfboot + url = https://github.com/wolfssl/wolfboot diff --git a/Makefile b/Makefile index 76e0b61..7f308da 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,12 @@ CROSS_COMPILE:=arm-none-eabi- CC:=$(CROSS_COMPILE)gcc LD:=$(CROSS_COMPILE)gcc -WOLFSSL:=$(HOME)/src/wolfssl +WOLFSSL:=$(HOME)/wolfssl +VERSION?=1 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 usb.o mutex.o + sdcard.o random.o usb.o mutex.o fw_update.o OBJS+= \ $(WOLFSSL)/wolfcrypt/src/sha256.o \ $(WOLFSSL)/wolfcrypt/src/chacha.o \ @@ -30,7 +31,9 @@ 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. -I$(WOLFSSL) -Ilib/unicore-mx/include +CFLAGS:=-mcpu=cortex-m3 -mthumb -Wall -Wno-main -Wstack-usage=320 \ + -ffreestanding -Wno-unused -DBLOCK_SIZE=4096 -I. -I$(WOLFSSL) -Ilib/unicore-mx/include \ + -Iwolfboot/src -Iwolfboot/hal -Iwolfboot/include/wolfboot CFLAGS+=-specs=nano.specs -lc -lg CFLAGS+=$(UMXFLAGS) CFLAGS+=-O2 @@ -49,9 +52,23 @@ image.bin: image.elf image.elf: $(LIBS) $(OBJS) $(LSCRIPT) $(LD) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ +wolfboot: wolfboot-align.bin + +wolfboot-align.bin: + @rm -f wolfboot/.config + @rm -f $(WOLFSSL)/wolfcrypt/src/*.o + cp wolfboot.config wolfboot/.config + make -C wolfboot $@ + $(UMX): make -C lib/unicore-mx FP_FLAGS="-O3 -mfloat-abi=soft" TARGETS=stm32/f4 + +sign: image.bin + python3 wolfboot/tools/keytools/sign.py image.bin wolfboot/ecc256.der $(VERSION) clean: @rm -f image.bin image.elf *.o image.map $(WOLFSSL)/wolfcrypt/src/*.o $(USECFS)/src/*.o make -C lib/unicore-mx clean + make -C wolfboot clean + +.PHONY: wolfboot diff --git a/fw_update.c b/fw_update.c new file mode 100644 index 0000000..9e3da62 --- /dev/null +++ b/fw_update.c @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include "system.h" +#include "spi_flash.h" +#include "wolfboot/include/target.h" + +extern void wolfBoot_success(void); +#define MSGSIZE (4 + 4 + 8) +#define PAGESIZE (256) + +uint8_t page[PAGESIZE]; + +static uint32_t next_seq; +static uint32_t tot_len = 0; +const char err[]="!!!!"; + + +static void ack(uint32_t _off) +{ + uint32_t off = _off; + uint8_t ack_start = '#'; + + write(STDOUT_FILENO, &ack_start, 1); + write(STDOUT_FILENO, &off, 4); +} + +static int check(uint8_t *pkt, int size) +{ + int i; + uint16_t c = 0; + uint16_t c_rx = *((uint16_t *)(pkt + 2)); + uint16_t *p = (uint16_t *)(pkt + 4); + for (i = 0; i < ((size - 4) >> 1); i++) + c += p[i]; + if (c == c_rx) + return 0; + return -1; +} + +static uint8_t msg[MSGSIZE]; + +static void update_loop(void) +{ + int r; + uint32_t tlen = 0; + volatile uint32_t recv_seq; + uint32_t r_total = 0; + memset(page, 0xFF, PAGESIZE); + while (1) { + r_total = 0; + do { + while(r_total < 2) { + r = read(STDIN_FILENO, msg + r_total, 2 - r_total); + if (r <= 0) + continue; + r_total += r; + if ((r_total == 2) && ((msg[0] != 0xA5) || msg[1] != 0x5A)) { + r_total = 0; + continue; + } + } + r = read(STDIN_FILENO, msg + r_total, MSGSIZE - r_total); + if (r <= 0) + continue; + r_total += r; + if ((tot_len == 0) && r_total == 2 + sizeof(uint32_t)) + break; + if ((r_total > 8) && (tot_len <= ((r_total - 8) + next_seq))) + break; + } while (r_total < MSGSIZE); + + if (tot_len == 0) { + tlen = msg[2] + (msg[3] << 8) + (msg[4] << 16) + (msg[5] << 24); + if (tlen > WOLFBOOT_PARTITION_SIZE - 8) { + write(STDOUT_FILENO, err, 4); + break; + } + tot_len = tlen; + ack(0); + continue; + } + + if (check(msg, r_total) < 0) { + ack(next_seq); + continue; + } + + recv_seq = msg[4] + (msg[5] << 8) + (msg[6] << 16) + (msg[7] << 24); + if (recv_seq == next_seq) + { + int psize = r_total - 8; + int page_idx = recv_seq % PAGESIZE; + memcpy(&page[recv_seq % PAGESIZE], msg + 8, psize); + page_idx += psize; + if ((page_idx == PAGESIZE) || (next_seq + psize >= tot_len)) { + uint32_t dst = (WOLFBOOT_PARTITION_UPDATE_ADDRESS + recv_seq) / PAGESIZE; + flashpage_write_and_verify(dst, page); + memset(page, 0xFF, PAGESIZE); + } + next_seq += psize; + } + ack(next_seq); + if (next_seq >= tot_len) { + /* Update complete */ + wolfBoot_update_trigger(); + reboot(); + while(1) + ; + } + } +} diff --git a/lib/unicore-mx b/lib/unicore-mx index 242585e..72be468 160000 --- a/lib/unicore-mx +++ b/lib/unicore-mx @@ -1 +1 @@ -Subproject commit 242585ee67510f65fd2e2fb5c809621410459ac6 +Subproject commit 72be4686cba2d190765695477e735ca10ca473cf diff --git a/target.ld b/target.ld index f93d82f..3f5868d 100644 --- a/target.ld +++ b/target.ld @@ -1,6 +1,6 @@ MEMORY { - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K - 0x100 RAM (rw) : ORIGIN = 0x20001000, LENGTH = 60K RAM_S (rw) : ORIGIN = 0x20000000, LENGTH = 4K } diff --git a/ui.c b/ui.c index d129d42..7c1d6a7 100644 --- a/ui.c +++ b/ui.c @@ -68,11 +68,6 @@ static int ui_wakeup(void) return 0; } -static int ui_vault_on(void) -{ - ui_msg("Activating Vault"); - bridge_init(); -} void ui_msg(const char *txt) @@ -83,6 +78,13 @@ void ui_msg(const char *txt) display_text(6, txt); } +static int ui_vault_on(void) +{ + ui_msg("Activating Vault"); + bridge_init(); + return 0; +} + void lock(void) { //led_on(RED_LED); @@ -146,7 +148,11 @@ void ui_status(void) display_scroll(NULL, 0); display_clear(NULL); display_text(5, "Status Report "); - display_text(6, "Status OK "); + display_text(6, " - UART2 ON "); + display_text(7, " - SPI OK "); + display_text(0, " - SDCARD OK "); + display_text(1, " - USB VAULT ON "); + } void ui_sdcard_insert(void) diff --git a/usb.c b/usb.c index ae81ee0..3b4c543 100644 --- a/usb.c +++ b/usb.c @@ -42,7 +42,39 @@ static uint8_t tmp_blk_rd[SECTOR_SIZE]; static uint8_t tmp_blk_wr[SECTOR_SIZE]; static uint32_t bridge_mutex = 1; +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); +} + static int bridge_read_block(const usbd_msc_backend *backend, uint32_t lba, void *copy_to) +{ + uint32_t sd_size = sdcard_getsize(NULL); + if (lba > sd_size) + return -1; + sdcard_read(NULL, copy_to, lba); + return 0; +} + +static int bridge_write_block(const usbd_msc_backend *backend, uint32_t lba, const void *copy_from) +{ + uint32_t sd_size = sdcard_getsize(NULL); + if (lba > sd_size) + return -1; + sdcard_write(NULL, copy_from, lba); + return 0; +} + +static int bridge_read_block_enc(const usbd_msc_backend *backend, uint32_t lba, void *copy_to) { ChaCha cha; uint8_t crypto_tmp[CRYPTO_BLOCK_SIZE]; @@ -85,7 +117,7 @@ static int bridge_read_block(const usbd_msc_backend *backend, uint32_t lba, void -static int bridge_write_block(const usbd_msc_backend *backend, uint32_t lba, const void *copy_from) +static int bridge_write_block_enc(const usbd_msc_backend *backend, uint32_t lba, const void *copy_from) { ChaCha cha; uint8_t crypto_tmp[CRYPTO_BLOCK_SIZE]; @@ -124,19 +156,8 @@ static int bridge_write_block(const usbd_msc_backend *backend, uint32_t lba, con 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); -} +static uint8_t usb_buffer[SECTOR_SIZE]; struct usbd_msc_backend flash_backend = { .vendor_id = VID, @@ -147,6 +168,8 @@ struct usbd_msc_backend flash_backend = { //.unlock = bridge_unlock, .read_block = bridge_read_block, .write_block = bridge_write_block, + .block_size = SECTOR_SIZE, + .scratch_buffer = usb_buffer }; const usbd_backend *msc_target_usb_driver(void) diff --git a/usb.h b/usb.h index 3a42e75..91cb081 100644 --- a/usb.h +++ b/usb.h @@ -2,4 +2,5 @@ #define USB_INCLUDED void usb_init(void); void usb_poll(void); +int bridge_init(void); #endif diff --git a/wolfboot b/wolfboot new file mode 160000 index 0000000..1c6ea8d --- /dev/null +++ b/wolfboot @@ -0,0 +1 @@ +Subproject commit 1c6ea8d7325beba386e3c1007720a8e143539e35