mirror of https://github.com/wolfSSL/wolfBoot.git
Adds RSA support to wolfBoot using "SIGN=RSA2048". Includes RSA signing script tool in Python and instructions.
parent
dc4ea1975d
commit
fae6a974c8
|
@ -52,6 +52,7 @@
|
||||||
# automatically generated source files
|
# automatically generated source files
|
||||||
src/ed25519_pub_key.c
|
src/ed25519_pub_key.c
|
||||||
src/ecc256_pub_key.c
|
src/ecc256_pub_key.c
|
||||||
|
src/rsa2048_pub_key.c
|
||||||
|
|
||||||
# keygen binaries
|
# keygen binaries
|
||||||
tools/ed25519/ed25519_sign
|
tools/ed25519/ed25519_sign
|
||||||
|
|
75
Makefile
75
Makefile
|
@ -8,7 +8,7 @@
|
||||||
include tools/config.mk
|
include tools/config.mk
|
||||||
|
|
||||||
## Initializers
|
## Initializers
|
||||||
CFLAGS:=-D__WOLFBOOT -DWOLFBOOT_VERSION=$(WOLFBOOT_VERSION)UL -ffunction-sections -fdata-sections
|
CFLAGS:=-D__WOLFBOOT -DWOLFBOOT_VERSION=$(WOLFBOOT_VERSION)UL -ffunction-sections -fdata-sections
|
||||||
LSCRIPT:=config/target.ld
|
LSCRIPT:=config/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:= \
|
||||||
|
@ -16,19 +16,13 @@ OBJS:= \
|
||||||
./src/loader.o \
|
./src/loader.o \
|
||||||
./src/string.o \
|
./src/string.o \
|
||||||
./src/image.o \
|
./src/image.o \
|
||||||
./src/libwolfboot.o \
|
./src/libwolfboot.o
|
||||||
./lib/wolfssl/wolfcrypt/src/sha256.o \
|
|
||||||
./lib/wolfssl/wolfcrypt/src/hash.o \
|
|
||||||
./lib/wolfssl/wolfcrypt/src/wolfmath.o \
|
|
||||||
./lib/wolfssl/wolfcrypt/src/fe_low_mem.o
|
|
||||||
|
|
||||||
|
|
||||||
## Architecture/CPU configuration
|
## Architecture/CPU configuration
|
||||||
include arch.mk
|
include arch.mk
|
||||||
|
|
||||||
|
|
||||||
## DSA Settings
|
## DSA Settings
|
||||||
|
|
||||||
ifeq ($(SIGN),ECC256)
|
ifeq ($(SIGN),ECC256)
|
||||||
KEYGEN_OPTIONS=--ecc256
|
KEYGEN_OPTIONS=--ecc256
|
||||||
SIGN_OPTIONS=--ecc256
|
SIGN_OPTIONS=--ecc256
|
||||||
|
@ -37,26 +31,53 @@ ifeq ($(SIGN),ECC256)
|
||||||
$(ECC_EXTRA_OBJS) \
|
$(ECC_EXTRA_OBJS) \
|
||||||
$(MATH_OBJS) \
|
$(MATH_OBJS) \
|
||||||
./lib/wolfssl/wolfcrypt/src/ecc.o \
|
./lib/wolfssl/wolfcrypt/src/ecc.o \
|
||||||
./lib/wolfssl/wolfcrypt/src/ge_low_mem.o \
|
|
||||||
./lib/wolfssl/wolfcrypt/src/memory.o \
|
./lib/wolfssl/wolfcrypt/src/memory.o \
|
||||||
./lib/wolfssl/wolfcrypt/src/wc_port.o \
|
./lib/wolfssl/wolfcrypt/src/wc_port.o \
|
||||||
|
./lib/wolfssl/wolfcrypt/src/sha256.o \
|
||||||
|
./lib/wolfssl/wolfcrypt/src/hash.o \
|
||||||
./src/ecc256_pub_key.o \
|
./src/ecc256_pub_key.o \
|
||||||
./src/xmalloc.o
|
./src/xmalloc_ecc.o
|
||||||
CFLAGS+=-DWOLFBOOT_SIGN_ECC256 -DXMALLOC_USER $(ECC_EXTRA_CFLAGS)
|
CFLAGS+=-DWOLFBOOT_SIGN_ECC256 -DXMALLOC_USER $(ECC_EXTRA_CFLAGS) \
|
||||||
else
|
-Wstack-usage=1024
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(SIGN),ED25519)
|
||||||
KEYGEN_OPTIONS=--ed25519
|
KEYGEN_OPTIONS=--ed25519
|
||||||
SIGN_OPTIONS=--ed25519
|
SIGN_OPTIONS=--ed25519
|
||||||
PRIVATE_KEY=ed25519.der
|
PRIVATE_KEY=ed25519.der
|
||||||
OBJS+= ./lib/wolfssl/wolfcrypt/src/sha512.o \
|
OBJS+= ./lib/wolfssl/wolfcrypt/src/sha512.o \
|
||||||
./lib/wolfssl/wolfcrypt/src/ed25519.o \
|
./lib/wolfssl/wolfcrypt/src/ed25519.o \
|
||||||
./lib/wolfssl/wolfcrypt/src/ge_low_mem.o \
|
./lib/wolfssl/wolfcrypt/src/ge_low_mem.o \
|
||||||
|
./lib/wolfssl/wolfcrypt/src/sha256.o \
|
||||||
|
./lib/wolfssl/wolfcrypt/src/hash.o \
|
||||||
|
./lib/wolfssl/wolfcrypt/src/wolfmath.o \
|
||||||
|
./lib/wolfssl/wolfcrypt/src/fe_low_mem.o \
|
||||||
./src/ed25519_pub_key.o
|
./src/ed25519_pub_key.o
|
||||||
CFLAGS+=-DWOLFBOOT_SIGN_ED25519 -nostdlib -DWOLFSSL_STATIC_MEMORY
|
CFLAGS+=-DWOLFBOOT_SIGN_ED25519 -nostdlib -DWOLFSSL_STATIC_MEMORY \
|
||||||
|
-Wstack-usage=1024
|
||||||
LDFLAGS+=-nostdlib
|
LDFLAGS+=-nostdlib
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(SIGN),RSA2048)
|
||||||
|
KEYGEN_OPTIONS=--rsa2048
|
||||||
|
SIGN_OPTIONS=--rsa2048
|
||||||
|
PRIVATE_KEY=rsa2048.der
|
||||||
|
IMAGE_HEADER_SIZE=512
|
||||||
|
OBJS+= \
|
||||||
|
$(RSA_EXTRA_OBJS) \
|
||||||
|
$(MATH_OBJS) \
|
||||||
|
./lib/wolfssl/wolfcrypt/src/rsa.o \
|
||||||
|
./lib/wolfssl/wolfcrypt/src/sha256.o \
|
||||||
|
./lib/wolfssl/wolfcrypt/src/asn.o \
|
||||||
|
./lib/wolfssl/wolfcrypt/src/hash.o \
|
||||||
|
./src/rsa2048_pub_key.o \
|
||||||
|
./src/xmalloc_rsa.o
|
||||||
|
CFLAGS+=-DWOLFBOOT_SIGN_RSA2048 -DXMALLOC_USER $(RSA_EXTRA_CFLAGS) \
|
||||||
|
-Wstack-usage=4096 -DIMAGE_HEADER_SIZE=512
|
||||||
|
endif
|
||||||
|
|
||||||
CFLAGS+=-Wall -Wextra -Wno-main -Wstack-usage=1024 -ffreestanding -Wno-unused \
|
|
||||||
|
CFLAGS+=-Wall -Wextra -Wno-main -ffreestanding -Wno-unused \
|
||||||
-I. -Iinclude/ -Ilib/wolfssl -nostartfiles \
|
-I. -Iinclude/ -Ilib/wolfssl -nostartfiles \
|
||||||
-DWOLFSSL_USER_SETTINGS \
|
-DWOLFSSL_USER_SETTINGS \
|
||||||
-DPLATFORM_$(TARGET)
|
-DPLATFORM_$(TARGET)
|
||||||
|
@ -108,15 +129,15 @@ ASFLAGS:=$(CFLAGS)
|
||||||
all: factory.bin
|
all: factory.bin
|
||||||
|
|
||||||
wolfboot.bin: wolfboot.elf
|
wolfboot.bin: wolfboot.elf
|
||||||
@echo "\t[BIN] $@"
|
@echo "\t[BIN] $@"
|
||||||
$(Q)$(OBJCOPY) -O binary $^ $@
|
$(Q)$(OBJCOPY) -O binary $^ $@
|
||||||
|
|
||||||
wolfboot.hex: wolfboot.elf
|
wolfboot.hex: wolfboot.elf
|
||||||
@echo "\t[HEX] $@"
|
@echo "\t[HEX] $@"
|
||||||
$(Q)$(OBJCOPY) -O ihex $^ $@
|
$(Q)$(OBJCOPY) -O ihex $^ $@
|
||||||
|
|
||||||
align: wolfboot-align.bin
|
align: wolfboot-align.bin
|
||||||
|
|
||||||
.bootloader-partition-size: FORCE
|
.bootloader-partition-size: FORCE
|
||||||
@printf "%d" $(WOLFBOOT_PARTITION_BOOT_ADDRESS) > .wolfboot-offset
|
@printf "%d" $(WOLFBOOT_PARTITION_BOOT_ADDRESS) > .wolfboot-offset
|
||||||
@printf "%d" $(ARCH_FLASH_OFFSET) > .wolfboot-arch-offset
|
@printf "%d" $(ARCH_FLASH_OFFSET) > .wolfboot-arch-offset
|
||||||
|
@ -136,6 +157,15 @@ test-app/image.bin: wolfboot-align.bin
|
||||||
@rm -f src/*.o hal/*.o
|
@rm -f src/*.o hal/*.o
|
||||||
@$(SIZE) test-app/image.elf
|
@$(SIZE) test-app/image.elf
|
||||||
|
|
||||||
|
standalone:
|
||||||
|
@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_CMSIS=$(KINETIS_CMSIS) NVM_FLASH_WRITEONCE=$(NVM_FLASH_WRITEONCE) \
|
||||||
|
FREEDOM_E_SDK=$(FREEDOM_E_SDK) standalone
|
||||||
|
$(Q)$(OBJCOPY) -O binary test-app/image.elf standalone.bin
|
||||||
|
@$(SIZE) test-app/image.elf
|
||||||
|
|
||||||
include tools/test.mk
|
include tools/test.mk
|
||||||
|
|
||||||
ed25519.der:
|
ed25519.der:
|
||||||
|
@ -144,6 +174,9 @@ ed25519.der:
|
||||||
ecc256.der:
|
ecc256.der:
|
||||||
@python3 tools/keytools/keygen.py $(KEYGEN_OPTIONS) src/ecc256_pub_key.c
|
@python3 tools/keytools/keygen.py $(KEYGEN_OPTIONS) src/ecc256_pub_key.c
|
||||||
|
|
||||||
|
rsa2048.der:
|
||||||
|
@python3 tools/keytools/keygen.py $(KEYGEN_OPTIONS) src/rsa2048_pub_key.c
|
||||||
|
|
||||||
factory.bin: $(BOOT_IMG) wolfboot-align.bin $(PRIVATE_KEY)
|
factory.bin: $(BOOT_IMG) wolfboot-align.bin $(PRIVATE_KEY)
|
||||||
@echo "\t[SIGN] $(BOOT_IMG)"
|
@echo "\t[SIGN] $(BOOT_IMG)"
|
||||||
$(Q)python3 tools/keytools/sign.py $(SIGN_OPTIONS) $(BOOT_IMG) $(PRIVATE_KEY) 1
|
$(Q)python3 tools/keytools/sign.py $(SIGN_OPTIONS) $(BOOT_IMG) $(PRIVATE_KEY) 1
|
||||||
|
@ -163,15 +196,17 @@ src/ed25519_pub_key.c: ed25519.der
|
||||||
|
|
||||||
src/ecc256_pub_key.c: ecc256.der
|
src/ecc256_pub_key.c: ecc256.der
|
||||||
|
|
||||||
|
src/rsa2048_pub_key.c: rsa2048.der
|
||||||
|
|
||||||
keys: $(PRIVATE_KEY)
|
keys: $(PRIVATE_KEY)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@find . -type f -name "*.o" | xargs rm -f
|
@find . -type f -name "*.o" | xargs rm -f
|
||||||
@rm -f *.bin *.elf wolfboot.map *.bin *.hex config/target.ld
|
@rm -f *.bin *.elf wolfboot.map *.bin *.hex config/target.ld
|
||||||
@make -C test-app clean
|
@make -C test-app clean
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
@rm -f *.pem *.der tags ./src/ed25519_pub_key.c ./src/ecc256_pub_key.c include/target.h
|
@rm -f *.pem *.der tags ./src/ed25519_pub_key.c ./src/ecc256_pub_key.c ./src/rsa2048_pub_key.c include/target.h
|
||||||
|
|
||||||
include/target.h: include/target.h.in FORCE
|
include/target.h: include/target.h.in FORCE
|
||||||
@cat include/target.h.in | \
|
@cat include/target.h.in | \
|
||||||
|
@ -193,6 +228,6 @@ config: FORCE
|
||||||
@echo "\t[AS-$(ARCH)] $@"
|
@echo "\t[AS-$(ARCH)] $@"
|
||||||
$(Q)$(CC) $(CFLAGS) -c -o $@ $^
|
$(Q)$(CC) $(CFLAGS) -c -o $@ $^
|
||||||
|
|
||||||
FORCE:
|
FORCE:
|
||||||
|
|
||||||
.PHONY: FORCE clean
|
.PHONY: FORCE clean
|
||||||
|
|
48
README.md
48
README.md
|
@ -1,7 +1,7 @@
|
||||||
# wolfBoot
|
# wolfBoot
|
||||||
wolfSSL Secure Bootloader ([Home page](https://www.wolfssl.com/products/wolfboot/))
|
wolfSSL Secure Bootloader ([Home page](https://www.wolfssl.com/products/wolfboot/))
|
||||||
|
|
||||||
wolfBoot is a portable, OS-agnostic, secure bootloader solution for 32-bit microcontrollers,
|
wolfBoot is a portable, OS-agnostic, secure bootloader solution for 32-bit microcontrollers,
|
||||||
relying on wolfCrypt for firmware authentication, providing firmware update mechanisms.
|
relying on wolfCrypt for firmware authentication, providing firmware update mechanisms.
|
||||||
|
|
||||||
Due to the minimalist design of the bootloader and the tiny HAL API, wolfBoot is completely independent
|
Due to the minimalist design of the bootloader and the tiny HAL API, wolfBoot is completely independent
|
||||||
|
@ -21,8 +21,8 @@ projects to provide a secure firmware update mechanism.
|
||||||
|
|
||||||
This repository contains the following components:
|
This repository contains the following components:
|
||||||
- the wolfBoot bootloader
|
- the wolfBoot bootloader
|
||||||
- key generator and image signing tools (requires python 3.x)
|
- key generator and image signing tools (requires python 3.x and wolfcrypt-py https://github.com/wolfSSL/wolfcrypt-py)
|
||||||
- Baremetal test applications
|
- Baremetal test applications
|
||||||
|
|
||||||
### wolfBoot bootloader
|
### wolfBoot bootloader
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ with no dynamic memory allocation mechanism or linkage to any standard C library
|
||||||
The bootloader consists of the following components:
|
The bootloader consists of the following components:
|
||||||
- wolfCrypt, which is used to verify the signature of the images
|
- wolfCrypt, which is used to verify the signature of the images
|
||||||
- A minimalist Hardware Abstraction Layer, with an implementation provided for the supported target, which is in charge for IAP flash access and clock setting on the specific MCU
|
- A minimalist Hardware Abstraction Layer, with an implementation provided for the supported target, which is in charge for IAP flash access and clock setting on the specific MCU
|
||||||
- The core bootloader
|
- The core bootloader
|
||||||
- A small application library used by the application to interact with the bootloader [src/libwolfboot.c](src/libwolfboot.c)
|
- A small application library used by the application to interact with the bootloader [src/libwolfboot.c](src/libwolfboot.c)
|
||||||
|
|
||||||
Only ARM Cortex-M boot mechanism is supported at this stage. Support for more architectures and
|
Only ARM Cortex-M boot mechanism is supported at this stage. Support for more architectures and
|
||||||
|
@ -83,10 +83,48 @@ For detailed information about the configuration options for the target system,
|
||||||
|
|
||||||
For more detailed information about firmware update implementation, see [Firmware Update](docs/firmware_update.md)
|
For more detailed information about firmware update implementation, see [Firmware Update](docs/firmware_update.md)
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
1. Python errors when signing a key:
|
||||||
|
|
||||||
|
```
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "tools/keytools/keygen.py", line 135, in <module>
|
||||||
|
rsa = ciphers.RsaPrivate.make_key(2048)
|
||||||
|
AttributeError: type object 'RsaPrivate' has no attribute 'make_key'
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "tools/keytools/sign.py", line 189, in <module>
|
||||||
|
r, s = ecc.sign_raw(digest)
|
||||||
|
AttributeError: 'EccPrivate' object has no attribute 'sign_raw'
|
||||||
|
```
|
||||||
|
|
||||||
|
You need to install the latest wolfcrypt-pi here: https://github.com/wolfSSL/wolfcrypt-py
|
||||||
|
|
||||||
|
Use `pip3 install wolfcrypt`.
|
||||||
|
Make sure the wolfSSL library has been built with:
|
||||||
|
```sh
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
To install based on a local wolfSSL installation use:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd youwolfssldir
|
||||||
|
./configure --enable-keygen --enable-rsa --enable-ecc --enable-ed25519 CFLAGS="-DWOLFSSL_PUBLIC_MP"
|
||||||
|
make
|
||||||
|
sudo make install
|
||||||
|
|
||||||
|
cd yourwolfcryptpydir
|
||||||
|
USE_LOCAL_WOLFSSL=/usr/local pip3 install .
|
||||||
|
```
|
||||||
|
|
||||||
## Release Notes
|
## Release Notes
|
||||||
|
|
||||||
### v1.0 (2018-12-04)
|
### v1.0 (2018-12-04)
|
||||||
* Initial release with fail-safe update, HAL support for STM32 and nRF52
|
* Initial release with fail-safe update, HAL support for STM32 and nRF52
|
||||||
|
|
||||||
### V1.1 (2019-03-27)
|
### V1.1 (2019-03-27)
|
||||||
* Added support for ECC-256 DSA
|
* Added support for ECC-256 DSA
|
||||||
|
|
|
@ -15,6 +15,11 @@ SECTIONS
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
_end_text = .;
|
_end_text = .;
|
||||||
} > FLASH
|
} > FLASH
|
||||||
|
.edidx :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.ARM.exidx*)
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
.edidx :
|
.edidx :
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x001FFE0
|
||||||
|
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00010000
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
_start_text = .;
|
||||||
|
KEEP(*(.isr_vector))
|
||||||
|
*(.text*)
|
||||||
|
*(.rodata*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_end_text = .;
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
_stored_data = .;
|
||||||
|
.data : AT (_stored_data)
|
||||||
|
{
|
||||||
|
_start_data = .;
|
||||||
|
KEEP(*(.data*))
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.ramcode))
|
||||||
|
. = ALIGN(4);
|
||||||
|
_end_data = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.bss (NOLOAD) :
|
||||||
|
{
|
||||||
|
_start_bss = .;
|
||||||
|
__bss_start__ = .;
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_end_bss = .;
|
||||||
|
__bss_end__ = .;
|
||||||
|
_end = .;
|
||||||
|
} > RAM
|
||||||
|
. = ALIGN(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
END_STACK = ORIGIN(RAM) + LENGTH(RAM);
|
|
@ -15,7 +15,6 @@ SECTIONS
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
_end_text = .;
|
_end_text = .;
|
||||||
} > FLASH
|
} > FLASH
|
||||||
|
|
||||||
.edidx :
|
.edidx :
|
||||||
{
|
{
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
|
|
|
@ -70,7 +70,7 @@ 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 */
|
/* Defined in libwolfboot */
|
||||||
uint8_t wolfBoot_find_header(uint8_t *haystack, uint8_t type, uint8_t **ptr);
|
uint16_t wolfBoot_find_header(uint8_t *haystack, uint16_t type, uint8_t **ptr);
|
||||||
|
|
||||||
#ifdef EXT_FLASH
|
#ifdef EXT_FLASH
|
||||||
# ifdef PART_UPDATE_EXT
|
# ifdef PART_UPDATE_EXT
|
||||||
|
|
|
@ -37,6 +37,12 @@
|
||||||
# define KEY_BUFFER ecc256_pub_key
|
# define KEY_BUFFER ecc256_pub_key
|
||||||
# define KEY_LEN ecc256_pub_key_len
|
# define KEY_LEN ecc256_pub_key_len
|
||||||
# define IMAGE_SIGNATURE_SIZE (64)
|
# define IMAGE_SIGNATURE_SIZE (64)
|
||||||
|
#elif defined(WOLFBOOT_SIGN_RSA2048)
|
||||||
|
extern const unsigned char rsa2048_pub_key[];
|
||||||
|
extern unsigned int rsa2048_pub_key_len;
|
||||||
|
# define KEY_BUFFER rsa2048_pub_key
|
||||||
|
# define KEY_LEN rsa2048_pub_key_len
|
||||||
|
# define IMAGE_SIGNATURE_SIZE (256)
|
||||||
#else
|
#else
|
||||||
# error "No public key available for given signing algorithm."
|
# error "No public key available for given signing algorithm."
|
||||||
#endif /* Algorithm selection */
|
#endif /* Algorithm selection */
|
||||||
|
|
|
@ -41,6 +41,8 @@
|
||||||
# define NO_ED25519_EXPORT
|
# define NO_ED25519_EXPORT
|
||||||
# define WOLFSSL_SHA512
|
# define WOLFSSL_SHA512
|
||||||
# define USE_SLOW_SHA512
|
# define USE_SLOW_SHA512
|
||||||
|
# define NO_RSA
|
||||||
|
# define NO_ASN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ECC and SHA256 */
|
/* ECC and SHA256 */
|
||||||
|
@ -78,15 +80,29 @@
|
||||||
# define NO_ECC224
|
# define NO_ECC224
|
||||||
# define HAVE_ECC256
|
# define HAVE_ECC256
|
||||||
# define NO_ECC384
|
# define NO_ECC384
|
||||||
|
# define NO_RSA
|
||||||
|
# define NO_ASN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WOLFBOOT_SIGN_RSA2048
|
||||||
|
# define HAVE_RSA
|
||||||
|
# define RSA_LOW_MEM
|
||||||
|
# define WOLFSSL_STATIC_RSA
|
||||||
|
# define WOLFSSL_RSA_VERIFY_INLINE
|
||||||
|
//# define WOLFSSL_RSA_PUBLIC_ONLY
|
||||||
|
//# define WOLFSSL_RSA_VERIFY_ONLY
|
||||||
|
# define WOLFSSL_HAVE_SP_RSA
|
||||||
|
# define WOLFSSL_SP
|
||||||
|
# define WOLFSSL_SP_SMALL
|
||||||
|
# define WOLFSSL_SP_MATH
|
||||||
|
# define SP_WORD_SIZE 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Disables - For minimum wolfCrypt build */
|
/* Disables - For minimum wolfCrypt build */
|
||||||
#define NO_AES
|
#define NO_AES
|
||||||
#define NO_CMAC
|
#define NO_CMAC
|
||||||
#define NO_CODING
|
#define NO_CODING
|
||||||
#define NO_RSA
|
|
||||||
#define NO_BIG_INT
|
#define NO_BIG_INT
|
||||||
#define NO_ASN
|
|
||||||
#define NO_RC4
|
#define NO_RC4
|
||||||
#define NO_SHA
|
#define NO_SHA
|
||||||
#define NO_DH
|
#define NO_DH
|
||||||
|
|
|
@ -28,7 +28,10 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
|
||||||
#define IMAGE_HEADER_SIZE 256
|
|
||||||
|
#ifndef IMAGE_HEADER_SIZE
|
||||||
|
# define IMAGE_HEADER_SIZE 256
|
||||||
|
#endif
|
||||||
#define IMAGE_HEADER_OFFSET (2 * sizeof(uint32_t))
|
#define IMAGE_HEADER_OFFSET (2 * sizeof(uint32_t))
|
||||||
|
|
||||||
#define WOLFBOOT_MAGIC 0x464C4F57 /* WOLF */
|
#define WOLFBOOT_MAGIC 0x464C4F57 /* WOLF */
|
||||||
|
@ -45,6 +48,7 @@
|
||||||
|
|
||||||
#define HDR_IMG_TYPE_AUTH_ED25519 0x0100
|
#define HDR_IMG_TYPE_AUTH_ED25519 0x0100
|
||||||
#define HDR_IMG_TYPE_AUTH_ECC256 0x0200
|
#define HDR_IMG_TYPE_AUTH_ECC256 0x0200
|
||||||
|
#define HDR_IMG_TYPE_AUTH_RSA2048 0x0300
|
||||||
#define HDR_IMG_TYPE_WOLFBOOT 0x0000
|
#define HDR_IMG_TYPE_WOLFBOOT 0x0000
|
||||||
#define HDR_IMG_TYPE_APP 0x0001
|
#define HDR_IMG_TYPE_APP 0x0001
|
||||||
|
|
||||||
|
@ -54,8 +58,10 @@
|
||||||
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_ED25519
|
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_ED25519
|
||||||
#elif defined(WOLFBOOT_SIGN_ECC256)
|
#elif defined(WOLFBOOT_SIGN_ECC256)
|
||||||
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_ECC256
|
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_ECC256
|
||||||
|
#elif defined(WOLFBOOT_SIGN_RSA2048)
|
||||||
|
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_RSA2048
|
||||||
#else
|
#else
|
||||||
# error "no valid authentication mechanism selected. Please define WOLFBOOT_SIGN_ED25519 or WOLFBOOT_SIGN_ECC256"
|
# error "no valid authentication mechanism selected. Please define WOLFBOOT_SIGN_ED25519 or WOLFBOOT_SIGN_ECC256 or WOLFBOOT_SIGN_RSA2048"
|
||||||
#endif /* defined WOLFBOOT_SIGN_ECC256 || WOLFBOOT_SIGN_ED25519 */
|
#endif /* defined WOLFBOOT_SIGN_ECC256 || WOLFBOOT_SIGN_ED25519 */
|
||||||
#endif /* defined WOLFBOOT */
|
#endif /* defined WOLFBOOT */
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0fe5d40507e42945d5bc9aefb653ebb0b9f32cf3
|
Subproject commit 9fd56281482bac15de56269e68162b26f2fab6e7
|
52
src/image.c
52
src/image.c
|
@ -86,9 +86,43 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
|
||||||
}
|
}
|
||||||
#endif /* WOLFBOOT_SIGN_ECC256 */
|
#endif /* WOLFBOOT_SIGN_ECC256 */
|
||||||
|
|
||||||
static uint8_t get_header_ext(struct wolfBoot_image *img, uint8_t type, uint8_t **ptr);
|
#ifdef WOLFBOOT_SIGN_RSA2048
|
||||||
|
#include <wolfssl/wolfcrypt/rsa.h>
|
||||||
|
#include <wolfssl/wolfcrypt/asn_public.h>
|
||||||
|
#define RSA_MAX_KEY_SIZE 256
|
||||||
|
#define RSA_SIG_SIZE 256
|
||||||
|
|
||||||
static uint8_t get_header(struct wolfBoot_image *img, uint8_t type, uint8_t **ptr)
|
static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
|
||||||
|
{
|
||||||
|
int ret, res = 0;
|
||||||
|
struct RsaKey rsa;
|
||||||
|
uint8_t digest_out[IMAGE_SIGNATURE_SIZE];
|
||||||
|
word32 in_out = 0;
|
||||||
|
|
||||||
|
|
||||||
|
ret = wc_InitRsaKey(&rsa, NULL);
|
||||||
|
if (ret < 0) {
|
||||||
|
/* Failed to initialize key */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* Import public key */
|
||||||
|
ret = wc_RsaPublicKeyDecode((byte*)KEY_BUFFER, &in_out, &rsa, KEY_LEN);
|
||||||
|
if (ret < 0) {
|
||||||
|
/* Failed to import rsa key */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ret = wc_RsaSSL_Verify(sig, RSA_SIG_SIZE, digest_out, RSA_SIG_SIZE, &rsa);
|
||||||
|
if (ret == SHA256_DIGEST_SIZE) {
|
||||||
|
if (memcmp(digest_out, hash, ret) == 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif /* WOLFBOOT_SIGN_RSA2048 */
|
||||||
|
|
||||||
|
static uint8_t get_header_ext(struct wolfBoot_image *img, uint16_t type, uint8_t **ptr);
|
||||||
|
|
||||||
|
static uint16_t get_header(struct wolfBoot_image *img, uint16_t type, uint8_t **ptr)
|
||||||
{
|
{
|
||||||
#if defined(PART_UPDATE_EXT)
|
#if defined(PART_UPDATE_EXT)
|
||||||
if(img->part == PART_UPDATE)
|
if(img->part == PART_UPDATE)
|
||||||
|
@ -128,7 +162,7 @@ static uint8_t *fetch_hdr_cpy(struct wolfBoot_image *img)
|
||||||
return hdr_cpy;
|
return hdr_cpy;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t get_header_ext(struct wolfBoot_image *img, uint8_t type, uint8_t **ptr)
|
static uint16_t get_header_ext(struct wolfBoot_image *img, uint16_t type, uint8_t **ptr)
|
||||||
{
|
{
|
||||||
return wolfBoot_find_header(fetch_hdr_cpy(img) + IMAGE_HEADER_OFFSET, type, ptr);
|
return wolfBoot_find_header(fetch_hdr_cpy(img) + IMAGE_HEADER_OFFSET, type, ptr);
|
||||||
}
|
}
|
||||||
|
@ -148,7 +182,7 @@ static uint8_t *get_img_hdr(struct wolfBoot_image *img)
|
||||||
static int image_hash(struct wolfBoot_image *img, uint8_t *hash)
|
static int image_hash(struct wolfBoot_image *img, uint8_t *hash)
|
||||||
{
|
{
|
||||||
uint8_t *stored_sha, *end_sha;
|
uint8_t *stored_sha, *end_sha;
|
||||||
uint8_t stored_sha_len;
|
uint16_t stored_sha_len;
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
int blksz;
|
int blksz;
|
||||||
uint32_t position = 0;
|
uint32_t position = 0;
|
||||||
|
@ -160,7 +194,7 @@ static int image_hash(struct wolfBoot_image *img, uint8_t *hash)
|
||||||
if (stored_sha_len != SHA256_DIGEST_SIZE)
|
if (stored_sha_len != SHA256_DIGEST_SIZE)
|
||||||
return -1;
|
return -1;
|
||||||
wc_InitSha256(&sha256_ctx);
|
wc_InitSha256(&sha256_ctx);
|
||||||
end_sha = stored_sha - 2;
|
end_sha = stored_sha - 4;
|
||||||
while (p < end_sha) {
|
while (p < end_sha) {
|
||||||
blksz = SHA256_BLOCK_SIZE;
|
blksz = SHA256_BLOCK_SIZE;
|
||||||
if (end_sha - p < blksz)
|
if (end_sha - p < blksz)
|
||||||
|
@ -248,7 +282,7 @@ int wolfBoot_open_image(struct wolfBoot_image *img, uint8_t part)
|
||||||
int wolfBoot_verify_integrity(struct wolfBoot_image *img)
|
int wolfBoot_verify_integrity(struct wolfBoot_image *img)
|
||||||
{
|
{
|
||||||
uint8_t *stored_sha;
|
uint8_t *stored_sha;
|
||||||
uint8_t stored_sha_len;
|
uint16_t stored_sha_len;
|
||||||
stored_sha_len = get_header(img, HDR_SHA256, &stored_sha);
|
stored_sha_len = get_header(img, HDR_SHA256, &stored_sha);
|
||||||
if (stored_sha_len != SHA256_DIGEST_SIZE)
|
if (stored_sha_len != SHA256_DIGEST_SIZE)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -263,12 +297,12 @@ int wolfBoot_verify_integrity(struct wolfBoot_image *img)
|
||||||
int wolfBoot_verify_authenticity(struct wolfBoot_image *img)
|
int wolfBoot_verify_authenticity(struct wolfBoot_image *img)
|
||||||
{
|
{
|
||||||
uint8_t *stored_signature;
|
uint8_t *stored_signature;
|
||||||
uint8_t stored_signature_size;
|
uint16_t stored_signature_size;
|
||||||
uint8_t *pubkey_hint;
|
uint8_t *pubkey_hint;
|
||||||
uint8_t pubkey_hint_size;
|
uint16_t pubkey_hint_size;
|
||||||
uint8_t *image_type_buf;
|
uint8_t *image_type_buf;
|
||||||
uint16_t image_type;
|
uint16_t image_type;
|
||||||
uint8_t image_type_size;
|
uint16_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)
|
||||||
|
|
|
@ -251,21 +251,21 @@ void RAMFUNCTION wolfBoot_success(void)
|
||||||
hal_flash_lock();
|
hal_flash_lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t wolfBoot_find_header(uint8_t *haystack, uint8_t type, uint8_t **ptr)
|
uint16_t wolfBoot_find_header(uint8_t *haystack, uint16_t type, uint8_t **ptr)
|
||||||
{
|
{
|
||||||
uint8_t *p = haystack;
|
uint8_t *p = haystack;
|
||||||
while (*p != 0) {
|
uint16_t len;
|
||||||
|
while (((p[0] != 0) || (p[1] != 0)) && ((p - haystack) < IMAGE_HEADER_SIZE)) {
|
||||||
if (*p == HDR_PADDING) {
|
if (*p == HDR_PADDING) {
|
||||||
p++;
|
p++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (*p == type) {
|
len = p[2] | (p[3] << 8);
|
||||||
p++;
|
if ((p[0] | (p[1] << 8)) == type) {
|
||||||
*ptr = (p + 1);
|
*ptr = (p + 4);
|
||||||
return *p;
|
return len;
|
||||||
}
|
}
|
||||||
p++;
|
p += 4 + len;
|
||||||
p += (*p + 1);
|
|
||||||
}
|
}
|
||||||
*ptr = NULL;
|
*ptr = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* xmalloc.h
|
/* xmalloc_ecc.c
|
||||||
*
|
*
|
||||||
* Implementations of minimal malloc/free
|
* Implementations of minimal malloc/free
|
||||||
*
|
*
|
|
@ -0,0 +1,54 @@
|
||||||
|
/* xmalloc_rsa.c
|
||||||
|
*
|
||||||
|
* Implementations of minimal malloc/free
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 wolfSSL Inc.
|
||||||
|
*
|
||||||
|
* This file is part of wolfBoot.
|
||||||
|
*
|
||||||
|
* wolfBoot is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* wolfBoot is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* Allow one single sp_point to be allocated at one time */
|
||||||
|
#define SP_DIGIT_SIZE (1800)
|
||||||
|
static uint8_t sp_digit[SP_DIGIT_SIZE];
|
||||||
|
static int sp_digit_in_use = 0;
|
||||||
|
|
||||||
|
static void* xmalloc_sp_digit(void)
|
||||||
|
{
|
||||||
|
if (sp_digit_in_use)
|
||||||
|
return NULL;
|
||||||
|
sp_digit_in_use++;
|
||||||
|
return sp_digit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void* XMALLOC(size_t n, void* heap, int type)
|
||||||
|
{
|
||||||
|
if (n == SP_DIGIT_SIZE)
|
||||||
|
return xmalloc_sp_digit();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XFREE(void *ptr)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (ptr == sp_digit)
|
||||||
|
sp_digit_in_use = 0;
|
||||||
|
}
|
|
@ -61,7 +61,7 @@ void led_pwm_setup(void)
|
||||||
void boot_led_on(void)
|
void boot_led_on(void)
|
||||||
{
|
{
|
||||||
uint32_t reg;
|
uint32_t reg;
|
||||||
uint32_t pin = LED_BOOT_PIN - 2 * (wolfBoot_current_firmware_version() & 0x01);
|
uint32_t pin = LED_BOOT_PIN;// - 2 * (wolfBoot_current_firmware_version() & 0x01);
|
||||||
AHB1_CLOCK_ER |= GPIOD_AHB1_CLOCK_ER;
|
AHB1_CLOCK_ER |= GPIOD_AHB1_CLOCK_ER;
|
||||||
reg = GPIOD_MODE & ~(0x03 << (pin * 2));
|
reg = GPIOD_MODE & ~(0x03 << (pin * 2));
|
||||||
GPIOD_MODE = reg | (1 << (pin * 2));
|
GPIOD_MODE = reg | (1 << (pin * 2));
|
||||||
|
|
|
@ -39,4 +39,3 @@ CONFIG_VARS:= ARCH TARGET SIGN KINETIS KINETIS_CPU KINETIS_DRIVERS \
|
||||||
WOLFBOOT_PARTITION_SIZE WOLFBOOT_SECTOR_SIZE \
|
WOLFBOOT_PARTITION_SIZE WOLFBOOT_SECTOR_SIZE \
|
||||||
WOLFBOOT_PARTITION_BOOT_ADDRESS WOLFBOOT_PARTITION_UPDATE_ADDRESS \
|
WOLFBOOT_PARTITION_BOOT_ADDRESS WOLFBOOT_PARTITION_UPDATE_ADDRESS \
|
||||||
WOLFBOOT_PARTITION_SWAP_ADDRESS
|
WOLFBOOT_PARTITION_SWAP_ADDRESS
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ Cfile_Banner="/* Public-key file for wolfBoot, automatically generated. Do not e
|
||||||
|
|
||||||
Ed25519_pub_key_define = "const uint8_t ed25519_pub_key[32] = {\n\t"
|
Ed25519_pub_key_define = "const uint8_t ed25519_pub_key[32] = {\n\t"
|
||||||
Ecc256_pub_key_define = "const uint8_t ecc256_pub_key[64] = {\n\t"
|
Ecc256_pub_key_define = "const uint8_t ecc256_pub_key[64] = {\n\t"
|
||||||
|
Rsa_pub_key_define = "const uint8_t rsa2048_pub_key[%d] = {\n\t"
|
||||||
|
|
||||||
sign="ed25519"
|
sign="ed25519"
|
||||||
|
|
||||||
|
@ -40,12 +41,12 @@ argc = len(sys.argv)
|
||||||
argv = sys.argv
|
argv = sys.argv
|
||||||
|
|
||||||
if (argc < 2) or (argc > 3):
|
if (argc < 2) or (argc > 3):
|
||||||
print("Usage: %s [--ed25519 | --ecc256 ] pub_key_file.c\n" % sys.argv[0])
|
print("Usage: %s [--ed25519 | --ecc256 | --rsa2048 ] pub_key_file.c\n" % sys.argv[0])
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if argc == 3:
|
if argc == 3:
|
||||||
if argv[1] != '--ed25519' and argv[1] != '--ecc256':
|
if argv[1] != '--ed25519' and argv[1] != '--ecc256' and argv[1] != '--rsa2048':
|
||||||
print("Usage: %s [--ed25519 | --ecc256 ] pub_key_file.c\n" % sys.argv[0])
|
print("Usage: %s [--ed25519 | --ecc256 | --rsa2048] pub_key_file.c\n" % sys.argv[0])
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
sign=argv[1][2:]
|
sign=argv[1][2:]
|
||||||
pubkey_cfile = argv[2]
|
pubkey_cfile = argv[2]
|
||||||
|
@ -130,3 +131,30 @@ if (sign == "ecc256"):
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
if (sign == "rsa2048"):
|
||||||
|
rsa = ciphers.RsaPrivate.make_key(2048)
|
||||||
|
if os.path.exists(key_file):
|
||||||
|
choice = input("** Warning: key file already exist! Are you sure you want to "+
|
||||||
|
"generate a new key and overwrite the existing key? [Type 'Yes, I am sure!']: ")
|
||||||
|
if (choice != "Yes, I am sure!"):
|
||||||
|
print("Operation canceled.")
|
||||||
|
sys.exit(2)
|
||||||
|
priv,pub = rsa.encode_key()
|
||||||
|
print()
|
||||||
|
print("Creating file " + key_file)
|
||||||
|
with open(key_file, "wb") as f:
|
||||||
|
f.write(priv)
|
||||||
|
f.close()
|
||||||
|
print("Creating file " + pubkey_cfile)
|
||||||
|
with open(pubkey_cfile, "w") as f:
|
||||||
|
f.write(Cfile_Banner)
|
||||||
|
f.write(Rsa_pub_key_define % len(pub))
|
||||||
|
i = 0
|
||||||
|
for c in bytes(pub):
|
||||||
|
f.write("0x%02X, " % c)
|
||||||
|
i += 1
|
||||||
|
if (i % 8 == 0):
|
||||||
|
f.write('\n')
|
||||||
|
f.write("\n};\n")
|
||||||
|
f.write("const uint32_t rsa2048_pub_key_len = %d;\n" % len(pub))
|
||||||
|
f.close()
|
||||||
|
|
|
@ -45,10 +45,13 @@ HDR_SIGNATURE_LEN = 64
|
||||||
|
|
||||||
HDR_IMG_TYPE_AUTH_ED25519 = 0x0100
|
HDR_IMG_TYPE_AUTH_ED25519 = 0x0100
|
||||||
HDR_IMG_TYPE_AUTH_ECC256 = 0x0200
|
HDR_IMG_TYPE_AUTH_ECC256 = 0x0200
|
||||||
|
HDR_IMG_TYPE_AUTH_RSA2048 = 0x0300
|
||||||
|
|
||||||
HDR_IMG_TYPE_WOLFBOOT = 0x0000
|
HDR_IMG_TYPE_WOLFBOOT = 0x0000
|
||||||
HDR_IMG_TYPE_APP = 0x0001
|
HDR_IMG_TYPE_APP = 0x0001
|
||||||
|
|
||||||
|
WOLFBOOT_HEADER_SIZE = 256
|
||||||
|
|
||||||
sign="auto"
|
sign="auto"
|
||||||
self_update=False
|
self_update=False
|
||||||
|
|
||||||
|
@ -56,13 +59,15 @@ argc = len(sys.argv)
|
||||||
argv = sys.argv
|
argv = sys.argv
|
||||||
|
|
||||||
if (argc < 4) or (argc > 6):
|
if (argc < 4) or (argc > 6):
|
||||||
print("Usage: %s [--ed25519 | --ecc256 ] [--wolfboot-update] image key.der fw_version\n" % sys.argv[0])
|
print("Usage: %s [--ed25519 | --ecc256 | --rsa2048 ] [--wolfboot-update] image key.der fw_version\n" % sys.argv[0])
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
for i in range(1, len(argv)):
|
for i in range(1, len(argv)):
|
||||||
if (argv[i] == '--ed25519'):
|
if (argv[i] == '--ed25519'):
|
||||||
sign='ed25519'
|
sign='ed25519'
|
||||||
elif (argv[i] == '--ecc256'):
|
elif (argv[i] == '--ecc256'):
|
||||||
sign='ecc256'
|
sign='ecc256'
|
||||||
|
elif (argv[i] == '--rsa2048'):
|
||||||
|
sign='rsa2048'
|
||||||
elif (argv[i] == '--wolfboot-update'):
|
elif (argv[i] == '--wolfboot-update'):
|
||||||
self_update = True
|
self_update = True
|
||||||
else:
|
else:
|
||||||
|
@ -93,7 +98,7 @@ print ("Output image: " + output_image_file)
|
||||||
|
|
||||||
''' import (decode) private key for signing '''
|
''' import (decode) private key for signing '''
|
||||||
kf = open(key_file, "rb")
|
kf = open(key_file, "rb")
|
||||||
wolfboot_private_key = kf.read(96)
|
wolfboot_private_key = kf.read(4096)
|
||||||
wolfboot_private_key_len = len(wolfboot_private_key)
|
wolfboot_private_key_len = len(wolfboot_private_key)
|
||||||
if wolfboot_private_key_len == 64:
|
if wolfboot_private_key_len == 64:
|
||||||
if (sign == 'ecc256'):
|
if (sign == 'ecc256'):
|
||||||
|
@ -109,6 +114,11 @@ elif wolfboot_private_key_len == 96:
|
||||||
if sign == 'auto':
|
if sign == 'auto':
|
||||||
sign = 'ecc256'
|
sign = 'ecc256'
|
||||||
print("'ecc256' key autodetected.")
|
print("'ecc256' key autodetected.")
|
||||||
|
elif (wolfboot_private_key_len > 128):
|
||||||
|
if (sign == 'auto'):
|
||||||
|
print("'rsa2048' key autodetected.")
|
||||||
|
elif (sign != 'rsa2048'):
|
||||||
|
print ("Error: key size too large for the selected cipher")
|
||||||
else:
|
else:
|
||||||
print ("Error: key size does not match any cipher")
|
print ("Error: key size does not match any cipher")
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
@ -123,6 +133,12 @@ if sign == 'ecc256':
|
||||||
ecc.decode_key_raw(wolfboot_private_key[0:31], wolfboot_private_key[32:63], wolfboot_private_key[64:])
|
ecc.decode_key_raw(wolfboot_private_key[0:31], wolfboot_private_key[32:63], wolfboot_private_key[64:])
|
||||||
pubkey = wolfboot_private_key[0:64]
|
pubkey = wolfboot_private_key[0:64]
|
||||||
|
|
||||||
|
if sign == 'rsa2048':
|
||||||
|
WOLFBOOT_HEADER_SIZE = 512
|
||||||
|
HDR_SIGNATURE_LEN = 256
|
||||||
|
rsa = ciphers.RsaPrivate(wolfboot_private_key)
|
||||||
|
privkey,pubkey = rsa.encode_key()
|
||||||
|
|
||||||
|
|
||||||
img_size = os.path.getsize(image_file)
|
img_size = os.path.getsize(image_file)
|
||||||
# Magic header (spells 'WOLF')
|
# Magic header (spells 'WOLF')
|
||||||
|
@ -130,28 +146,28 @@ header = struct.pack('<L', WOLFBOOT_MAGIC)
|
||||||
# Image size
|
# Image size
|
||||||
header += struct.pack('<L', img_size)
|
header += struct.pack('<L', img_size)
|
||||||
|
|
||||||
# Two pad bytes so version is aligned
|
# No pad bytes, version is aligned
|
||||||
header += struct.pack('BB', 0xFF, 0xFF)
|
|
||||||
|
|
||||||
# Version field
|
# Version field
|
||||||
header += struct.pack('BB', HDR_VERSION, HDR_VERSION_LEN)
|
header += struct.pack('<HH', HDR_VERSION, HDR_VERSION_LEN)
|
||||||
header += struct.pack('<L', fw_version)
|
header += struct.pack('<L', fw_version)
|
||||||
|
|
||||||
# Six pad bytes so timestamp is aligned
|
# Four pad bytes, so timestamp is aligned
|
||||||
header += struct.pack('BB', 0xFF, 0xFF)
|
|
||||||
header += struct.pack('BB', 0xFF, 0xFF)
|
header += struct.pack('BB', 0xFF, 0xFF)
|
||||||
header += struct.pack('BB', 0xFF, 0xFF)
|
header += struct.pack('BB', 0xFF, 0xFF)
|
||||||
|
|
||||||
# Timestamp field
|
# Timestamp field
|
||||||
header += struct.pack('BB', HDR_TIMESTAMP, HDR_TIMESTAMP_LEN)
|
header += struct.pack('<HH', 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
|
# Image type field
|
||||||
header += struct.pack('BB', HDR_IMG_TYPE, HDR_IMG_TYPE_LEN)
|
header += struct.pack('<HH', HDR_IMG_TYPE, HDR_IMG_TYPE_LEN)
|
||||||
if (sign == 'ed25519'):
|
if (sign == 'ed25519'):
|
||||||
img_type = HDR_IMG_TYPE_AUTH_ED25519
|
img_type = HDR_IMG_TYPE_AUTH_ED25519
|
||||||
if (sign == 'ecc256'):
|
if (sign == 'ecc256'):
|
||||||
img_type = HDR_IMG_TYPE_AUTH_ECC256
|
img_type = HDR_IMG_TYPE_AUTH_ECC256
|
||||||
|
if (sign == 'rsa2048'):
|
||||||
|
img_type = HDR_IMG_TYPE_AUTH_RSA2048
|
||||||
|
|
||||||
if (not self_update):
|
if (not self_update):
|
||||||
img_type |= HDR_IMG_TYPE_APP
|
img_type |= HDR_IMG_TYPE_APP
|
||||||
|
@ -171,32 +187,45 @@ while True:
|
||||||
digest = sha.digest()
|
digest = sha.digest()
|
||||||
|
|
||||||
# Add SHA to the header
|
# Add SHA to the header
|
||||||
header += struct.pack('BB', HDR_SHA256, HDR_SHA256_LEN)
|
header += struct.pack('<HH', HDR_SHA256, HDR_SHA256_LEN)
|
||||||
header += digest
|
header += digest
|
||||||
|
#print("sha:")
|
||||||
|
#print([hex(j) for j in digest])
|
||||||
|
|
||||||
# pubkey SHA calculation
|
# pubkey SHA calculation
|
||||||
|
#print([hex(j) for j in pubkey])
|
||||||
|
#print(len(pubkey))
|
||||||
keysha = hashes.Sha256.new()
|
keysha = hashes.Sha256.new()
|
||||||
keysha.update(pubkey)
|
keysha.update(pubkey)
|
||||||
header += struct.pack('BB', HDR_PUBKEY, HDR_PUBKEY_LEN)
|
|
||||||
key_digest = keysha.digest()
|
key_digest = keysha.digest()
|
||||||
|
header += struct.pack('<HH', HDR_PUBKEY, HDR_PUBKEY_LEN)
|
||||||
header += key_digest
|
header += key_digest
|
||||||
|
#print([hex(j) for j in key_digest])
|
||||||
|
|
||||||
# Sign the digest
|
# Sign the digest
|
||||||
print("Signing the firmware...")
|
print("Signing the firmware...")
|
||||||
if (sign == 'ed25519'):
|
if (sign == 'ed25519'):
|
||||||
signature = ed.sign(digest)
|
signature = ed.sign(digest)
|
||||||
else:
|
elif (sign == 'ecc256'):
|
||||||
r, s = ecc.sign_raw(digest)
|
r, s = ecc.sign_raw(digest)
|
||||||
signature = r + s
|
signature = r + s
|
||||||
header += struct.pack('BB', HDR_SIGNATURE, HDR_SIGNATURE_LEN)
|
elif (sign == 'rsa2048'):
|
||||||
|
signature = rsa.sign(digest)
|
||||||
|
#plain = rsa.verify(signature)
|
||||||
|
#print("plain:%d " % len(plain))
|
||||||
|
#print([hex(j) for j in plain])
|
||||||
|
|
||||||
|
header += struct.pack('<HH', HDR_SIGNATURE, HDR_SIGNATURE_LEN)
|
||||||
header += signature
|
header += signature
|
||||||
|
#print ("len sig: %d\n" % len(signature))
|
||||||
|
#print([hex(j) for j in signature])
|
||||||
print ("Done.")
|
print ("Done.")
|
||||||
|
|
||||||
# Create output image. Add padded header in front
|
# Create output image. Add padded header in front
|
||||||
outfile = open(output_image_file, 'wb')
|
outfile = open(output_image_file, 'wb')
|
||||||
outfile.write(header)
|
outfile.write(header)
|
||||||
sz = len(header)
|
sz = len(header)
|
||||||
while sz < 256:
|
while sz < WOLFBOOT_HEADER_SIZE:
|
||||||
outfile.write(struct.pack('B',0xFF))
|
outfile.write(struct.pack('B',0xFF))
|
||||||
sz += 1
|
sz += 1
|
||||||
infile = open(image_file, 'rb')
|
infile = open(image_file, 'rb')
|
||||||
|
|
Loading…
Reference in New Issue