From 75ddc749d6f86bbb5d0f7ca8fc52eeb1fb531426 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Tue, 28 Jun 2016 01:16:51 -0400 Subject: Fix the bootloader to accept firmware (with PIN login). This involves entirely too much duplication of the CLI. --- Makefile | 2 +- projects/bootloader/Makefile | 7 +++ projects/bootloader/bootloader.c | 6 +- projects/bootloader/dfu.c | 118 +++++++++++++++++++++++++++++++++++---- projects/bootloader/stm-init.c | 1 - 5 files changed, 119 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index af50d13..c8e363c 100644 --- a/Makefile +++ b/Makefile @@ -140,7 +140,7 @@ libhal-test: $(BOARD_OBJS) $(LIBS) $(LIBHAL_BLD)/libhal.a hsm: $(BOARD_OBJS) $(LIBS) $(LIBHAL_BLD)/libhal.a $(RTOS_DIR)/librtos.a $(LIBCLI_BLD)/libcli.a $(MAKE) -C projects/hsm -bootloader: $(BOARD_OBJS) $(LIBS) +bootloader: $(BOARD_OBJS) $(LIBS) $(LIBHAL_BLD)/libhal.a $(MAKE) -C projects/bootloader # don't automatically delete objects, to avoid a lot of unnecessary rebuilding diff --git a/projects/bootloader/Makefile b/projects/bootloader/Makefile index a63d29c..7de93c0 100644 --- a/projects/bootloader/Makefile +++ b/projects/bootloader/Makefile @@ -4,7 +4,11 @@ OBJS = crc32.o dfu.o BOARD_OBJS = \ ./stm-init.o \ + $(TOPLEVEL)/stm-fmc.o \ $(TOPLEVEL)/stm-uart.o \ + $(TOPLEVEL)/spiflash_n25q128.o \ + $(TOPLEVEL)/stm-fpgacfg.o \ + $(TOPLEVEL)/stm-keystore.o \ $(TOPLEVEL)/stm-flash.o \ $(TOPLEVEL)/syscalls.o \ $(BOARD_DIR)/system_stm32f4xx.o \ @@ -12,6 +16,9 @@ BOARD_OBJS = \ ./startup_stm32f429xx.o \ $(BOARD_DIR)/stm32f4xx_it.o +CFLAGS += -I$(LIBHAL_SRC) +LIBS += $(LIBHAL_BLD)/libhal.a $(LIBTFM_BLD)/libtfm.a + all: $(PROG:=.elf) %.elf: %.o $(BOARD_OBJS) $(OBJS) $(LIBS) diff --git a/projects/bootloader/bootloader.c b/projects/bootloader/bootloader.c index 30cd120..3040bd1 100644 --- a/projects/bootloader/bootloader.c +++ b/projects/bootloader/bootloader.c @@ -35,6 +35,7 @@ #include "stm-init.h" #include "stm-led.h" #include "stm-uart.h" +#include "stm-fmc.h" #include "dfu.h" #undef HAL_Delay @@ -72,12 +73,12 @@ int should_dfu() int i; uint8_t rx = 0; - /* While blinking the blue LED for one second, see if we receive a CR on the MGMT UART. + /* While blinking the blue LED for 5 seconds, see if we receive a CR on the MGMT UART. * We've discussed also requiring one or both of the FPGA config jumpers installed * before allowing DFU of the STM32 - that check could be done here. */ led_on(LED_BLUE); - for (i = 0; i < 10; i++) { + for (i = 0; i < 50; i++) { HAL_Delay(100); led_toggle(LED_BLUE); if (uart_recv_char2(STM_UART_MGMT, &rx, 0) == HAL_OK) { @@ -93,6 +94,7 @@ main() int status; stm_init(); + fmc_init(); uart_send_string2(STM_UART_MGMT, (char *) "\r\n\r\nThis is the bootloader speaking..."); diff --git a/projects/bootloader/dfu.c b/projects/bootloader/dfu.c index 231e388..eeaa035 100644 --- a/projects/bootloader/dfu.c +++ b/projects/bootloader/dfu.c @@ -31,43 +31,130 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +/* Rename both CMSIS HAL_OK and libhal HAL_OK to disambiguate */ +#define HAL_OK CMSIS_HAL_OK #include "dfu.h" #include "stm-led.h" #include "stm-uart.h" #include "stm-flash.h" +#undef HAL_OK +#define HAL_OK LIBHAL_OK +#include "hal.h" +#undef HAL_OK + #include extern uint32_t update_crc(uint32_t crc, uint8_t *buf, int len); +static int getline(char *buf, int len) +{ + int i; + uint8_t c; + + for (i = 0; i < len; ++i) { + if (uart_recv_char2(STM_UART_MGMT, &c, HAL_MAX_DELAY) != CMSIS_HAL_OK) + return -1; + if (c == '\r') { + buf[i] = '\0'; + break; + } + buf[i] = c; + } + return i; +} + +static void uart_flush(void) +{ + uint8_t c; + while (uart_recv_char2(STM_UART_MGMT, &c, 0) == CMSIS_HAL_OK) { ; } +} + +static int do_login(void) +{ + char username[8]; + char pin[hal_rpc_max_pin_length]; + hal_client_handle_t client = { -1 }; + hal_user_t user; + int n; + + uart_flush(); + uart_send_string2(STM_UART_MGMT, "\r\nUsername: "); + if (getline(username, sizeof(username)) <= 0) + return -1; + if (strcmp(username, "wheel") == 0) + user = HAL_USER_WHEEL; + else if (strcmp(username, "so") == 0) + user = HAL_USER_SO; + else if (strcmp(username, "user") == 0) + user = HAL_USER_NORMAL; + else + user = HAL_USER_NONE; + + uart_flush(); + uart_send_string2(STM_UART_MGMT, "\r\nPassword: "); + if ((n = getline(pin, sizeof(pin))) <= 0) + return -1; + + uart_flush(); + + if (hal_rpc_login(client, user, pin, n) != LIBHAL_OK) { + uart_send_string2(STM_UART_MGMT, "\r\nAccess denied\r\n"); + return -1; + } + return 0; +} int dfu_receive_firmware(void) { uint32_t filesize = 0, crc = 0, my_crc = 0, counter = 0; uint32_t offset = DFU_FIRMWARE_ADDR, n = DFU_UPLOAD_CHUNK_SIZE; - uint32_t buf[DFU_UPLOAD_CHUNK_SIZE / 4]; + uint8_t buf[DFU_UPLOAD_CHUNK_SIZE]; + + if (do_login() != 0) + return -1; + + /* Fake the CLI */ + uart_send_string2(STM_UART_MGMT, "\r\ncryptech> "); + char cmd[64]; + if (getline(cmd, sizeof(cmd)) <= 0) + return -1; + if (strcmp(cmd, "firmware upload") != 0) { + uart_send_string2(STM_UART_MGMT, "\r\nInvalid command \""); + uart_send_string2(STM_UART_MGMT, cmd); + uart_send_string2(STM_UART_MGMT, "\"\r\n"); + return -1; + } - uart_send_string2(STM_UART_MGMT, (char *) "\r\nOK, bootloader waiting for new firmware\r\n"); + uart_send_string2(STM_UART_MGMT, "OK, write size (4 bytes), data in 4096 byte chunks, CRC-32 (4 bytes)\r\n"); /* Read file size (4 bytes) */ - uart_receive_bytes(STM_UART_MGMT, (void *) &filesize, 4, 1000); + uart_receive_bytes(STM_UART_MGMT, (void *) &filesize, 4, 10000); if (filesize < 512 || filesize > DFU_FIRMWARE_END_ADDR - DFU_FIRMWARE_ADDR) { + uart_send_string2(STM_UART_MGMT, "Invalid filesize "); + uart_send_number2(STM_UART_MGMT, filesize, 1, 10); + uart_send_string2(STM_UART_MGMT, "\r\n"); return -1; } HAL_FLASH_Unlock(); + uart_send_string2(STM_UART_MGMT, "Send "); + uart_send_number2(STM_UART_MGMT, filesize, 1, 10); + uart_send_string2(STM_UART_MGMT, " bytes of data\r\n"); + while (filesize) { /* By initializing buf to the same value that erased flash has (0xff), we don't * have to try and be smart when writing the last page of data to the memory. */ - memset(buf, 0xffffffff, sizeof(buf)); + memset(buf, 0xff, sizeof(buf)); if (filesize < n) { n = filesize; } - if (uart_receive_bytes(STM_UART_MGMT, (void *) &buf, n, 1000) != HAL_OK) { + if (uart_receive_bytes(STM_UART_MGMT, (void *) buf, n, 10000) != CMSIS_HAL_OK) { return -2; } filesize -= n; @@ -75,8 +162,8 @@ int dfu_receive_firmware(void) /* After reception of a chunk but before ACKing we have "all" the time in the world to * calculate CRC and write it to flash. */ - my_crc = update_crc(my_crc, (uint8_t *) buf, n); - stm_flash_write32(offset, buf, sizeof(buf) / 4); + my_crc = update_crc(my_crc, buf, n); + stm_flash_write32(offset, (uint32_t *)buf, sizeof(buf)/4); offset += DFU_UPLOAD_CHUNK_SIZE; /* ACK this chunk by sending the current chunk counter (4 bytes) */ @@ -87,11 +174,20 @@ int dfu_receive_firmware(void) HAL_FLASH_Lock(); - /* The sending side will now send it's calculated CRC-32 */ - uart_receive_bytes(STM_UART_MGMT, (void *) &crc, 4, 1000); + uart_send_string2(STM_UART_MGMT, "Send CRC-32\r\n"); + + /* The sending side will now send its calculated CRC-32 */ + uart_receive_bytes(STM_UART_MGMT, (void *) &crc, 4, 10000); + + uart_send_string2(STM_UART_MGMT, "CRC-32 0x"); + uart_send_number2(STM_UART_MGMT, crc, 1, 16); + uart_send_string2(STM_UART_MGMT, ", calculated CRC 0x"); + uart_send_number2(STM_UART_MGMT, my_crc, 1, 16); if (crc == my_crc) { - uart_send_string2(STM_UART_MGMT, (char *) "\r\nSuccess\r\n"); - return 0; + uart_send_string2(STM_UART_MGMT, "CRC checksum MATCHED\r\n"); + return 0; + } else { + uart_send_string2(STM_UART_MGMT, "CRC checksum did NOT match\r\n"); } led_on(LED_RED); diff --git a/projects/bootloader/stm-init.c b/projects/bootloader/stm-init.c index 209dc8c..b331b8a 100644 --- a/projects/bootloader/stm-init.c +++ b/projects/bootloader/stm-init.c @@ -3,6 +3,5 @@ #include "stm32f4xx_hal.h" #undef HAL_I2C_MODULE_ENABLED -#undef HAL_SPI_MODULE_ENABLED #include "../../stm-init.c" -- cgit v1.2.3