mirror of https://github.com/wolfSSL/wolfBoot.git
wolfBoot can update itself when compiled with RAM_CODE=1
- Added wolfBoot version - Added extra 16bit header tag to identify the image type and authentication - Implemented optional in-ram self-update of the bootloader, with version control and authentication mechanism (not fail-safe)pull/7/head
parent
937e9d46fb
commit
fc547e4a25
6
Makefile
6
Makefile
|
@ -21,6 +21,7 @@ EXT_FLASH?=0
|
||||||
SPI_FLASH?=0
|
SPI_FLASH?=0
|
||||||
ALLOW_DOWNGRADE?=0
|
ALLOW_DOWNGRADE?=0
|
||||||
NVM_FLASH_WRITEONCE?=0
|
NVM_FLASH_WRITEONCE?=0
|
||||||
|
WOLFBOOT_VERSION?=0
|
||||||
V?=0
|
V?=0
|
||||||
SPMATH?=1
|
SPMATH?=1
|
||||||
RAM_CODE?=0
|
RAM_CODE?=0
|
||||||
|
@ -28,7 +29,7 @@ RAM_CODE?=0
|
||||||
|
|
||||||
|
|
||||||
## Initializers
|
## Initializers
|
||||||
CFLAGS:=-D__WOLFBOOT
|
CFLAGS:=-D__WOLFBOOT -DWOLFBOOT_VERSION=$(WOLFBOOT_VERSION)UL
|
||||||
LSCRIPT:=hal/$(TARGET).ld
|
LSCRIPT:=hal/$(TARGET).ld
|
||||||
LDFLAGS:=-T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=wolfboot.map -ffreestanding -nostartfiles
|
LDFLAGS:=-T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=wolfboot.map -ffreestanding -nostartfiles
|
||||||
OBJS:= \
|
OBJS:= \
|
||||||
|
@ -147,7 +148,8 @@ wolfboot-align.bin: wolfboot.bin
|
||||||
@echo
|
@echo
|
||||||
|
|
||||||
test-app/image.bin:
|
test-app/image.bin:
|
||||||
@make -C test-app TARGET=$(TARGET) EXT_FLASH=$(EXT_FLASH) SPI_FLASH=$(SPI_FLASH) ARCH=$(ARCH) V=$(V) \
|
@make -C test-app TARGET=$(TARGET) EXT_FLASH=$(EXT_FLASH) SPI_FLASH=$(SPI_FLASH) ARCH=$(ARCH) \
|
||||||
|
V=$(V) RAM_CODE=$(RAM_CODE) WOLFBOOT_VERSION=$(WOLFBOOT_VERSION)\
|
||||||
KINETIS=$(KINETIS) KINETIS_CPU=$(KINETIS_CPU) KINETIS_DRIVERS=$(KINETIS_DRIVERS) \
|
KINETIS=$(KINETIS) KINETIS_CPU=$(KINETIS_CPU) KINETIS_DRIVERS=$(KINETIS_DRIVERS) \
|
||||||
KINETIS_CMSIS=$(KINETIS_CMSIS) NVM_FLASH_WRITEONCE=$(NVM_FLASH_WRITEONCE) \
|
KINETIS_CMSIS=$(KINETIS_CMSIS) NVM_FLASH_WRITEONCE=$(NVM_FLASH_WRITEONCE) \
|
||||||
FREEDOM_E_SDK=$(FREEDOM_E_SDK)
|
FREEDOM_E_SDK=$(FREEDOM_E_SDK)
|
||||||
|
|
|
@ -19,6 +19,7 @@ SECTIONS
|
||||||
KEEP(*(.isr_vector))
|
KEEP(*(.isr_vector))
|
||||||
*(.text*)
|
*(.text*)
|
||||||
*(.rodata*)
|
*(.rodata*)
|
||||||
|
*(.srodata*)
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
_end_text = .;
|
_end_text = .;
|
||||||
} > FLASH
|
} > FLASH
|
||||||
|
|
|
@ -4,6 +4,13 @@
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
|
||||||
|
/* Architecture specific calls */
|
||||||
|
extern void do_boot(const uint32_t *app_offset);
|
||||||
|
extern void arch_reboot(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void hal_init(void);
|
void hal_init(void);
|
||||||
int hal_flash_write(uint32_t address, const uint8_t *data, int len);
|
int hal_flash_write(uint32_t address, const uint8_t *data, int len);
|
||||||
int hal_flash_erase(uint32_t address, int len);
|
int hal_flash_erase(uint32_t address, int len);
|
||||||
|
|
|
@ -41,6 +41,9 @@ int wolfBoot_set_sector_flag(uint8_t part, uint8_t sector, uint8_t newflag);
|
||||||
int wolfBoot_get_partition_state(uint8_t part, uint8_t *st);
|
int wolfBoot_get_partition_state(uint8_t part, uint8_t *st);
|
||||||
int wolfBoot_get_sector_flag(uint8_t part, uint8_t sector, uint8_t *flag);
|
int wolfBoot_get_sector_flag(uint8_t part, uint8_t sector, uint8_t *flag);
|
||||||
|
|
||||||
|
/* Defined in libwolfboot */
|
||||||
|
uint8_t wolfBoot_find_header(uint8_t *haystack, uint8_t type, uint8_t **ptr);
|
||||||
|
|
||||||
#ifdef EXT_FLASH
|
#ifdef EXT_FLASH
|
||||||
# ifdef PART_UPDATE_EXT
|
# ifdef PART_UPDATE_EXT
|
||||||
# define UPDATE_EXT 1
|
# define UPDATE_EXT 1
|
||||||
|
|
|
@ -13,10 +13,27 @@
|
||||||
#define HDR_VERSION 0x01
|
#define HDR_VERSION 0x01
|
||||||
#define HDR_TIMESTAMP 0x02
|
#define HDR_TIMESTAMP 0x02
|
||||||
#define HDR_SHA256 0x03
|
#define HDR_SHA256 0x03
|
||||||
|
#define HDR_IMG_TYPE 0x04
|
||||||
#define HDR_PUBKEY 0x10
|
#define HDR_PUBKEY 0x10
|
||||||
#define HDR_SIGNATURE 0x20
|
#define HDR_SIGNATURE 0x20
|
||||||
#define HDR_PADDING 0xFF
|
#define HDR_PADDING 0xFF
|
||||||
|
|
||||||
|
#define HDR_IMG_TYPE_AUTH_ED25519 0x0100
|
||||||
|
#define HDR_IMG_TYPE_AUTH_ECC256 0x0200
|
||||||
|
#define HDR_IMG_TYPE_WOLFBOOT 0x0000
|
||||||
|
#define HDR_IMG_TYPE_APP 0x0001
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __WOLFBOOT
|
||||||
|
#if defined(WOLFBOOT_SIGN_ED25519)
|
||||||
|
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_ED25519
|
||||||
|
#elif defined(WOLFBOOT_SIGN_ECC256)
|
||||||
|
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_ECC256
|
||||||
|
#else
|
||||||
|
# error "no valid authentication mechanism selected. Please define WOLFBOOT_SIGN_ED25519 or WOLFBOOT_SIGN_ECC256"
|
||||||
|
#endif /* defined WOLFBOOT_SIGN_ECC256 || WOLFBOOT_SIGN_ED25519 */
|
||||||
|
#endif /* defined WOLFBOOT */
|
||||||
|
|
||||||
#define PART_BOOT 0
|
#define PART_BOOT 0
|
||||||
#define PART_UPDATE 1
|
#define PART_UPDATE 1
|
||||||
#define PART_SWAP 2
|
#define PART_SWAP 2
|
||||||
|
@ -26,6 +43,8 @@
|
||||||
#define IMG_STATE_TESTING 0x10
|
#define IMG_STATE_TESTING 0x10
|
||||||
#define IMG_STATE_SUCCESS 0x00
|
#define IMG_STATE_SUCCESS 0x00
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void wolfBoot_erase_partition(uint8_t part);
|
void wolfBoot_erase_partition(uint8_t part);
|
||||||
void wolfBoot_update_trigger(void);
|
void wolfBoot_update_trigger(void);
|
||||||
void wolfBoot_success(void);
|
void wolfBoot_success(void);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* boot_arm.c
|
/* boot_arm.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2018 wolfSSL Inc.
|
* Copyright (C) 2018 wolfSSL Inc.
|
||||||
*
|
*
|
||||||
|
@ -18,9 +18,10 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||||
*/
|
*/
|
||||||
#include <loader.h>
|
#include "image.h"
|
||||||
|
#include "loader.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <wolfboot/wolfboot.h>
|
#include "wolfboot/wolfboot.h"
|
||||||
extern unsigned int _stored_data;
|
extern unsigned int _stored_data;
|
||||||
extern unsigned int _start_data;
|
extern unsigned int _start_data;
|
||||||
extern unsigned int _end_data;
|
extern unsigned int _end_data;
|
||||||
|
@ -33,7 +34,7 @@ extern void main(void);
|
||||||
|
|
||||||
void isr_reset(void) {
|
void isr_reset(void) {
|
||||||
register unsigned int *src, *dst;
|
register unsigned int *src, *dst;
|
||||||
#ifdef PLATFORM_kinetis
|
#ifdef PLATFORM_kinetis
|
||||||
/* Immediately disable Watchdog after boot */
|
/* Immediately disable Watchdog after boot */
|
||||||
/* Write Keys to unlock register */
|
/* Write Keys to unlock register */
|
||||||
*((volatile unsigned short *)0x4005200E) = 0xC520;
|
*((volatile unsigned short *)0x4005200E) = 0xC520;
|
||||||
|
@ -86,6 +87,7 @@ void isr_empty(void)
|
||||||
static void *app_entry;
|
static void *app_entry;
|
||||||
static uint32_t app_end_stack;
|
static uint32_t app_end_stack;
|
||||||
|
|
||||||
|
|
||||||
void do_boot(const uint32_t *app_offset)
|
void do_boot(const uint32_t *app_offset)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -171,3 +173,18 @@ void (* const IV[])(void) =
|
||||||
isr_empty,
|
isr_empty,
|
||||||
isr_empty,
|
isr_empty,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef RAM_CODE
|
||||||
|
|
||||||
|
#define AIRCR *(volatile uint32_t *)(0xE000ED0C)
|
||||||
|
#define AIRCR_VKEY (0x05FA << 16)
|
||||||
|
# define AIRCR_SYSRESETREQ (1 << 2)
|
||||||
|
|
||||||
|
void RAMFUNCTION arch_reboot(void)
|
||||||
|
{
|
||||||
|
AIRCR = AIRCR_SYSRESETREQ | AIRCR_VKEY;
|
||||||
|
while(1)
|
||||||
|
;
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "image.h"
|
||||||
|
|
||||||
extern void trap_entry(void);
|
extern void trap_entry(void);
|
||||||
extern void trap_exit(void);
|
extern void trap_exit(void);
|
||||||
|
@ -36,6 +37,12 @@ extern uint32_t _global_pointer;
|
||||||
extern void (* const IV[])(void);
|
extern void (* const IV[])(void);
|
||||||
|
|
||||||
extern void main(void);
|
extern void main(void);
|
||||||
|
void RAMFUNCTION reloc_iv(uint32_t *address)
|
||||||
|
{
|
||||||
|
asm volatile("csrw mtvec, %0":: "r"(address + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void __attribute__((naked,section(".init"))) _reset(void) {
|
void __attribute__((naked,section(".init"))) _reset(void) {
|
||||||
register uint32_t *src, *dst;
|
register uint32_t *src, *dst;
|
||||||
asm volatile("la gp, _global_pointer");
|
asm volatile("la gp, _global_pointer");
|
||||||
|
@ -83,4 +90,31 @@ void isr_empty(void)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef RAM_CODE
|
||||||
|
|
||||||
|
#define AON_WDOGCFG *(volatile uint32_t *)(0x10000000UL)
|
||||||
|
#define AON_WDOGKEY *(volatile uint32_t *)(0x1000001CUL)
|
||||||
|
#define AON_WDOGFEED *(volatile uint32_t *)(0x10000018UL)
|
||||||
|
#define AON_WDOGCMP *(volatile uint32_t *)(0x10000020UL)
|
||||||
|
|
||||||
|
#define AON_WDOGKEY_VALUE 0x0051F15E
|
||||||
|
#define AON_WDOGCFG_SCALE 0x0000000F
|
||||||
|
#define AON_WDOGCFG_RSTEN 0x00000100
|
||||||
|
#define AON_WDOGCFG_ZEROCMP 0x00000200
|
||||||
|
#define AON_WDOGCFG_ENALWAYS 0x00001000
|
||||||
|
|
||||||
|
|
||||||
|
void RAMFUNCTION arch_reboot(void)
|
||||||
|
{
|
||||||
|
AON_WDOGKEY = AON_WDOGKEY_VALUE;
|
||||||
|
AON_WDOGCMP = 0;
|
||||||
|
//wdogconfig: : wdogrsten | enablealways | reset to 0 | max scale
|
||||||
|
AON_WDOGKEY = AON_WDOGKEY_VALUE;
|
||||||
|
AON_WDOGCFG |= (AON_WDOGCFG_RSTEN | AON_WDOGCFG_ENALWAYS | AON_WDOGCFG_ZEROCMP | AON_WDOGCFG_SCALE) ;
|
||||||
|
AON_WDOGKEY = AON_WDOGKEY_VALUE;
|
||||||
|
AON_WDOGFEED = 1;
|
||||||
|
while(1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
20
src/image.c
20
src/image.c
|
@ -18,18 +18,16 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||||
*/
|
*/
|
||||||
#include <image.h>
|
#include "loader.h"
|
||||||
#include <hal.h>
|
#include "image.h"
|
||||||
|
#include "hal.h"
|
||||||
#include <wolfssl/wolfcrypt/sha256.h>
|
#include <wolfssl/wolfcrypt/sha256.h>
|
||||||
#include <wolfssl/ssl.h>
|
#include <wolfssl/ssl.h>
|
||||||
#include <loader.h>
|
|
||||||
|
|
||||||
#ifdef WOLFBOOT_SIGN_ED25519
|
#ifdef WOLFBOOT_SIGN_ED25519
|
||||||
#include <wolfssl/wolfcrypt/ed25519.h>
|
#include <wolfssl/wolfcrypt/ed25519.h>
|
||||||
|
|
||||||
|
|
||||||
extern uint8_t wolfBoot_find_header(uint8_t *haystack, uint8_t type, uint8_t **ptr);
|
|
||||||
|
|
||||||
static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
|
static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
|
||||||
{
|
{
|
||||||
int ret, res;
|
int ret, res;
|
||||||
|
@ -266,6 +264,9 @@ int wolfBoot_verify_authenticity(struct wolfBoot_image *img)
|
||||||
uint8_t stored_signature_size;
|
uint8_t stored_signature_size;
|
||||||
uint8_t *pubkey_hint;
|
uint8_t *pubkey_hint;
|
||||||
uint8_t pubkey_hint_size;
|
uint8_t pubkey_hint_size;
|
||||||
|
uint8_t *image_type_buf;
|
||||||
|
uint16_t image_type;
|
||||||
|
uint8_t image_type_size;
|
||||||
|
|
||||||
stored_signature_size = get_header(img, HDR_SIGNATURE, &stored_signature);
|
stored_signature_size = get_header(img, HDR_SIGNATURE, &stored_signature);
|
||||||
if (stored_signature_size != IMAGE_SIGNATURE_SIZE)
|
if (stored_signature_size != IMAGE_SIGNATURE_SIZE)
|
||||||
|
@ -276,6 +277,15 @@ int wolfBoot_verify_authenticity(struct wolfBoot_image *img)
|
||||||
if (memcmp(digest, pubkey_hint, SHA256_DIGEST_SIZE) != 0)
|
if (memcmp(digest, pubkey_hint, SHA256_DIGEST_SIZE) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
image_type_size = get_header(img, HDR_IMG_TYPE, &image_type_buf);
|
||||||
|
if (image_type_size != sizeof(uint16_t))
|
||||||
|
return -1;
|
||||||
|
image_type = (uint16_t)(image_type_buf[0] + (image_type_buf[1] << 8));
|
||||||
|
|
||||||
|
if ((image_type & 0xFF00) != HDR_IMG_TYPE_AUTH)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
|
||||||
if (image_hash(img, digest) != 0)
|
if (image_hash(img, digest) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (wolfBoot_verify_signature(digest, stored_signature) != 0)
|
if (wolfBoot_verify_signature(digest, stored_signature) != 0)
|
||||||
|
|
93
src/loader.c
93
src/loader.c
|
@ -22,8 +22,13 @@
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
#include "spi_flash.h"
|
#include "spi_flash.h"
|
||||||
|
#include "wolfboot/wolfboot.h"
|
||||||
|
|
||||||
extern void do_boot(const uint32_t *app_offset);
|
#ifdef RAM_CODE
|
||||||
|
extern unsigned int _start_text;
|
||||||
|
static volatile const uint32_t wolfboot_version = WOLFBOOT_VERSION;
|
||||||
|
extern void (** const IV_RAM)(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#define FLASHBUFFER_SIZE 256
|
#define FLASHBUFFER_SIZE 256
|
||||||
static int wolfBoot_copy_sector(struct wolfBoot_image *src, struct wolfBoot_image *dst, uint32_t sector)
|
static int wolfBoot_copy_sector(struct wolfBoot_image *src, struct wolfBoot_image *dst, uint32_t sector)
|
||||||
|
@ -87,10 +92,16 @@ static int wolfBoot_update(int fallback_allowed)
|
||||||
/* Check the first sector to detect interrupted update */
|
/* Check the first sector to detect interrupted update */
|
||||||
if ((wolfBoot_get_sector_flag(PART_UPDATE, 0, &flag) < 0) || (flag == SECT_FLAG_NEW))
|
if ((wolfBoot_get_sector_flag(PART_UPDATE, 0, &flag) < 0) || (flag == SECT_FLAG_NEW))
|
||||||
{
|
{
|
||||||
|
uint8_t *update_type;
|
||||||
/* In case this is a new update, do the required
|
/* In case this is a new update, do the required
|
||||||
* checks on the firmware update
|
* checks on the firmware update
|
||||||
* before starting the swap
|
* before starting the swap
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (wolfBoot_find_header(update.hdr + IMAGE_HEADER_OFFSET, HDR_IMG_TYPE, &update_type) == sizeof(uint16_t)) {
|
||||||
|
if ((update_type[0] != HDR_IMG_TYPE_APP) || update_type[1] != (HDR_IMG_TYPE_AUTH >> 8))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (!update.hdr_ok || (wolfBoot_verify_integrity(&update) < 0)
|
if (!update.hdr_ok || (wolfBoot_verify_integrity(&update) < 0)
|
||||||
|| (wolfBoot_verify_authenticity(&update) < 0)) {
|
|| (wolfBoot_verify_authenticity(&update) < 0)) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -153,11 +164,89 @@ static int wolfBoot_update(int fallback_allowed)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef RAM_CODE
|
||||||
|
|
||||||
|
static void RAMFUNCTION wolfBoot_erase_bootloader(void)
|
||||||
|
{
|
||||||
|
uint32_t *start = (uint32_t *)&_start_text;
|
||||||
|
uint32_t len = WOLFBOOT_PARTITION_BOOT_ADDRESS - (uint32_t)start;
|
||||||
|
hal_flash_erase((uint32_t)start, len);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RAMFUNCTION wolfBoot_self_update(struct wolfBoot_image *src)
|
||||||
|
{
|
||||||
|
uint32_t pos = 0;
|
||||||
|
uint32_t src_offset = IMAGE_HEADER_SIZE;
|
||||||
|
|
||||||
|
hal_flash_unlock();
|
||||||
|
wolfBoot_erase_bootloader();
|
||||||
|
#ifdef EXT_FLASH
|
||||||
|
while (pos < src->fw_size) {
|
||||||
|
if (PART_IS_EXT(src)) {
|
||||||
|
uint8_t buffer[FLASHBUFFER_SIZE];
|
||||||
|
if (src_offset + pos < (src->fw_size + IMAGE_HEADER_SIZE + FLASHBUFFER_SIZE)) {
|
||||||
|
ext_flash_read((uint32_t)(src->hdr) + src_offset + pos, (void *)buffer, FLASHBUFFER_SIZE);
|
||||||
|
hal_flash_write(pos + (uint32_t)&_start_text, buffer, FLASHBUFFER_SIZE);
|
||||||
|
}
|
||||||
|
pos += FLASHBUFFER_SIZE;
|
||||||
|
}
|
||||||
|
goto lock_and_reset;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
while (pos < src->fw_size) {
|
||||||
|
if (src_offset + pos < (src->fw_size + IMAGE_HEADER_SIZE + FLASHBUFFER_SIZE)) {
|
||||||
|
uint8_t *orig = (uint8_t*)(src->hdr + src_offset + pos);
|
||||||
|
hal_flash_write(pos + (uint32_t)&_start_text, orig, FLASHBUFFER_SIZE);
|
||||||
|
}
|
||||||
|
pos += FLASHBUFFER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock_and_reset:
|
||||||
|
hal_flash_lock();
|
||||||
|
arch_reboot();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wolfBoot_check_self_update(void)
|
||||||
|
{
|
||||||
|
uint8_t st;
|
||||||
|
struct wolfBoot_image update;
|
||||||
|
uint8_t *update_type;
|
||||||
|
uint32_t update_version;
|
||||||
|
|
||||||
|
/* Check for self update in the UPDATE partition */
|
||||||
|
if ((wolfBoot_get_partition_state(PART_UPDATE, &st) == 0) && (st == IMG_STATE_UPDATING) &&
|
||||||
|
(wolfBoot_open_image(&update, PART_UPDATE) == 0) &&
|
||||||
|
(wolfBoot_find_header(update.hdr + IMAGE_HEADER_OFFSET, HDR_IMG_TYPE, &update_type) == sizeof(uint16_t)) &&
|
||||||
|
update_type[0] == HDR_IMG_TYPE_WOLFBOOT &&
|
||||||
|
update_type[1] == (HDR_IMG_TYPE_AUTH >> 8)) {
|
||||||
|
uint32_t update_version = wolfBoot_update_firmware_version();
|
||||||
|
if (update_version <= wolfboot_version) {
|
||||||
|
hal_flash_unlock();
|
||||||
|
wolfBoot_erase_partition(PART_UPDATE);
|
||||||
|
hal_flash_lock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (wolfBoot_verify_integrity(&update) < 0)
|
||||||
|
return;
|
||||||
|
if (wolfBoot_verify_authenticity(&update) < 0)
|
||||||
|
return;
|
||||||
|
wolfBoot_self_update(&update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* RAM_CODE for self_update */
|
||||||
|
|
||||||
static void wolfBoot_start(void)
|
static void wolfBoot_start(void)
|
||||||
{
|
{
|
||||||
uint8_t st;
|
uint8_t st;
|
||||||
struct wolfBoot_image boot, update;
|
struct wolfBoot_image boot, update;
|
||||||
/* First, check if the BOOT partition is still in TESTING,
|
|
||||||
|
#ifdef RAM_CODE
|
||||||
|
wolfBoot_check_self_update();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Check if the BOOT partition is still in TESTING,
|
||||||
* to trigger fallback.
|
* to trigger fallback.
|
||||||
*/
|
*/
|
||||||
if ((wolfBoot_get_partition_state(PART_BOOT, &st) == 0) && (st == IMG_STATE_TESTING)) {
|
if ((wolfBoot_get_partition_state(PART_BOOT, &st) == 0) && (st == IMG_STATE_TESTING)) {
|
||||||
|
|
|
@ -30,37 +30,48 @@ HDR_END = 0x00
|
||||||
HDR_VERSION = 0x01
|
HDR_VERSION = 0x01
|
||||||
HDR_TIMESTAMP = 0x02
|
HDR_TIMESTAMP = 0x02
|
||||||
HDR_SHA256 = 0x03
|
HDR_SHA256 = 0x03
|
||||||
|
HDR_IMG_TYPE = 0x04
|
||||||
HDR_PUBKEY = 0x10
|
HDR_PUBKEY = 0x10
|
||||||
HDR_SIGNATURE = 0x20
|
HDR_SIGNATURE = 0x20
|
||||||
HDR_PADDING = 0xFF
|
HDR_PADDING = 0xFF
|
||||||
|
|
||||||
|
|
||||||
HDR_VERSION_LEN = 4
|
HDR_VERSION_LEN = 4
|
||||||
HDR_TIMESTAMP_LEN = 8
|
HDR_TIMESTAMP_LEN = 8
|
||||||
HDR_SHA256_LEN = 32
|
HDR_SHA256_LEN = 32
|
||||||
|
HDR_IMG_TYPE_LEN = 2
|
||||||
HDR_PUBKEY_LEN = 32
|
HDR_PUBKEY_LEN = 32
|
||||||
HDR_SIGNATURE_LEN = 64
|
HDR_SIGNATURE_LEN = 64
|
||||||
|
|
||||||
|
HDR_IMG_TYPE_AUTH_ED25519 = 0x0100
|
||||||
|
HDR_IMG_TYPE_AUTH_ECC256 = 0x0200
|
||||||
|
|
||||||
|
HDR_IMG_TYPE_WOLFBOOT = 0x0000
|
||||||
|
HDR_IMG_TYPE_APP = 0x0001
|
||||||
|
|
||||||
sign="auto"
|
sign="auto"
|
||||||
|
self_update=False
|
||||||
|
|
||||||
argc = len(sys.argv)
|
argc = len(sys.argv)
|
||||||
argv = sys.argv
|
argv = sys.argv
|
||||||
|
|
||||||
if (argc < 4) or (argc > 5):
|
if (argc < 4) or (argc > 6):
|
||||||
print("Usage: %s [--ed25519 | --ecc256 ] image key.der fw_version\n" % sys.argv[0])
|
print("Usage: %s [--ed25519 | --ecc256 ] [--wolfboot-update] image key.der fw_version\n" % sys.argv[0])
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
for i in range(1, len(argv)):
|
||||||
|
if (argv[i] == '--ed25519'):
|
||||||
|
sign='ed25519'
|
||||||
|
elif (argv[i] == '--ecc256'):
|
||||||
|
sign='ecc256'
|
||||||
|
elif (argv[i] == '--wolfboot-update'):
|
||||||
|
self_update = True
|
||||||
|
else:
|
||||||
|
i-=1
|
||||||
|
break
|
||||||
|
|
||||||
if argc == 5:
|
image_file = argv[i+1]
|
||||||
if argv[1] != '--ed25519' and argv[1] != '--ecc256':
|
key_file = argv[i+2]
|
||||||
print("Usage: %s [--ed25519 | --ecc256 ] image key.der fw_version\n" % sys.argv[0])
|
fw_version = int(argv[i+3])
|
||||||
sys.exit(1)
|
|
||||||
sign=argv[1][2:]
|
|
||||||
image_file = argv[2]
|
|
||||||
key_file = argv[3]
|
|
||||||
fw_version = int(argv[4])
|
|
||||||
else:
|
|
||||||
image_file = argv[1]
|
|
||||||
key_file = argv[2]
|
|
||||||
fw_version = int(argv[3])
|
|
||||||
|
|
||||||
if '.' in image_file:
|
if '.' in image_file:
|
||||||
tokens = image_file.split('.')
|
tokens = image_file.split('.')
|
||||||
|
@ -69,6 +80,11 @@ if '.' in image_file:
|
||||||
else:
|
else:
|
||||||
output_image_file = image_file + "_v" + str(fw_version) + "_signed.bin"
|
output_image_file = image_file + "_v" + str(fw_version) + "_signed.bin"
|
||||||
|
|
||||||
|
if (self_update):
|
||||||
|
print("Update type: wolfBoot")
|
||||||
|
else:
|
||||||
|
print("Update type: Firmware")
|
||||||
|
|
||||||
print ("Selected cipher: " + sign)
|
print ("Selected cipher: " + sign)
|
||||||
print ("Private key: " + key_file)
|
print ("Private key: " + key_file)
|
||||||
print ("Input image: " + image_file)
|
print ("Input image: " + image_file)
|
||||||
|
@ -130,6 +146,18 @@ header += struct.pack('BB', 0xFF, 0xFF)
|
||||||
header += struct.pack('BB', HDR_TIMESTAMP, HDR_TIMESTAMP_LEN)
|
header += struct.pack('BB', HDR_TIMESTAMP, HDR_TIMESTAMP_LEN)
|
||||||
header += struct.pack('<Q', int(os.path.getmtime(image_file)))
|
header += struct.pack('<Q', int(os.path.getmtime(image_file)))
|
||||||
|
|
||||||
|
# Image type field
|
||||||
|
header += struct.pack('BB', HDR_IMG_TYPE, HDR_IMG_TYPE_LEN)
|
||||||
|
if (sign == 'ed25519'):
|
||||||
|
img_type = HDR_IMG_TYPE_AUTH_ED25519
|
||||||
|
if (sign == 'ecc256'):
|
||||||
|
img_type = HDR_IMG_TYPE_AUTH_ECC256
|
||||||
|
|
||||||
|
if (not self_update):
|
||||||
|
img_type |= HDR_IMG_TYPE_APP
|
||||||
|
|
||||||
|
header += struct.pack('<H', img_type)
|
||||||
|
|
||||||
sha = hashes.Sha256.new()
|
sha = hashes.Sha256.new()
|
||||||
# Sha calculation
|
# Sha calculation
|
||||||
sha.update(header)
|
sha.update(header)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
TEST_UPDATE_VERSION?=2
|
TEST_UPDATE_VERSION?=2
|
||||||
|
WOLFBOOT_VERSION?=0
|
||||||
EXPVER=tools/test-expect-version/test-expect-version
|
EXPVER=tools/test-expect-version/test-expect-version
|
||||||
SPI_CHIP=SST25VF080B
|
SPI_CHIP=SST25VF080B
|
||||||
|
|
||||||
SIGN_TOOL=/bin/false
|
SIGN_TOOL=/bin/false
|
||||||
|
|
||||||
ifeq ($(SIGN),ED25519)
|
ifeq ($(SIGN),ED25519)
|
||||||
|
@ -40,7 +40,6 @@ test-spi-off: FORCE
|
||||||
@echo "in" >/sys/class/gpio/gpio10/direction
|
@echo "in" >/sys/class/gpio/gpio10/direction
|
||||||
@echo "in" >/sys/class/gpio/gpio11/direction
|
@echo "in" >/sys/class/gpio/gpio11/direction
|
||||||
|
|
||||||
|
|
||||||
test-update: test-app/image.bin FORCE
|
test-update: test-app/image.bin FORCE
|
||||||
@dd if=/dev/zero bs=131067 count=1 2>/dev/null | tr "\000" "\377" > test-update.bin
|
@dd if=/dev/zero bs=131067 count=1 2>/dev/null | tr "\000" "\377" > test-update.bin
|
||||||
@python3 $(SIGN_TOOL) test-app/image.bin $(PRIVATE_KEY) $(TEST_UPDATE_VERSION)
|
@python3 $(SIGN_TOOL) test-app/image.bin $(PRIVATE_KEY) $(TEST_UPDATE_VERSION)
|
||||||
|
@ -52,6 +51,17 @@ test-update: test-app/image.bin FORCE
|
||||||
(make test-reset && sleep 1 && st-flash --reset write test-update.bin 0x08040000) || \
|
(make test-reset && sleep 1 && st-flash --reset write test-update.bin 0x08040000) || \
|
||||||
(make test-reset && sleep 1 && st-flash --reset write test-update.bin 0x08040000)
|
(make test-reset && sleep 1 && st-flash --reset write test-update.bin 0x08040000)
|
||||||
|
|
||||||
|
test-self-update: wolfboot.bin test-app/image.bin FORCE
|
||||||
|
@dd if=/dev/zero bs=131067 count=1 2>/dev/null | tr "\000" "\377" > test-self-update.bin
|
||||||
|
@$(SIGN_TOOL) --wolfboot-update wolfboot.bin $(PRIVATE_KEY) $(WOLFBOOT_VERSION)
|
||||||
|
@dd if=wolfboot_v$(WOLFBOOT_VERSION)_signed.bin of=test-self-update.bin bs=1 conv=notrunc
|
||||||
|
@printf "pBOOT" >> test-self-update.bin
|
||||||
|
@make test-reset
|
||||||
|
@sleep 2
|
||||||
|
@st-flash --reset write test-self-update.bin 0x08040000 || \
|
||||||
|
(make test-reset && sleep 1 && st-flash --reset write test-self-update.bin 0x08040000) || \
|
||||||
|
(make test-reset && sleep 1 && st-flash --reset write test-self-update.bin 0x08040000)
|
||||||
|
|
||||||
test-update-ext: test-app/image.bin FORCE
|
test-update-ext: test-app/image.bin FORCE
|
||||||
@python3 $(SIGN_TOOL) test-app/image.bin $(PRIVATE_KEY) $(TEST_UPDATE_VERSION)
|
@python3 $(SIGN_TOOL) test-app/image.bin $(PRIVATE_KEY) $(TEST_UPDATE_VERSION)
|
||||||
@$$(dd if=/dev/zero bs=1M count=1 | tr '\000' '\377' > test-update.rom)
|
@$$(dd if=/dev/zero bs=1M count=1 | tr '\000' '\377' > test-update.rom)
|
||||||
|
|
Loading…
Reference in New Issue