Adds RSA support to wolfBoot using "SIGN=RSA2048". Includes RSA signing script tool in Python and instructions.

pull/26/head
David Garske 2019-12-06 06:33:47 -08:00
parent dc4ea1975d
commit fae6a974c8
19 changed files with 363 additions and 69 deletions

1
.gitignore vendored
View File

@ -52,6 +52,7 @@
# automatically generated source files
src/ed25519_pub_key.c
src/ecc256_pub_key.c
src/rsa2048_pub_key.c
# keygen binaries
tools/ed25519/ed25519_sign

View File

@ -8,7 +8,7 @@
include tools/config.mk
## 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
LDFLAGS:=-T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=wolfboot.map -ffreestanding -nostartfiles
OBJS:= \
@ -16,19 +16,13 @@ OBJS:= \
./src/loader.o \
./src/string.o \
./src/image.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
./src/libwolfboot.o
## Architecture/CPU configuration
include arch.mk
## DSA Settings
ifeq ($(SIGN),ECC256)
KEYGEN_OPTIONS=--ecc256
SIGN_OPTIONS=--ecc256
@ -37,26 +31,53 @@ ifeq ($(SIGN),ECC256)
$(ECC_EXTRA_OBJS) \
$(MATH_OBJS) \
./lib/wolfssl/wolfcrypt/src/ecc.o \
./lib/wolfssl/wolfcrypt/src/ge_low_mem.o \
./lib/wolfssl/wolfcrypt/src/memory.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/xmalloc.o
CFLAGS+=-DWOLFBOOT_SIGN_ECC256 -DXMALLOC_USER $(ECC_EXTRA_CFLAGS)
else
./src/xmalloc_ecc.o
CFLAGS+=-DWOLFBOOT_SIGN_ECC256 -DXMALLOC_USER $(ECC_EXTRA_CFLAGS) \
-Wstack-usage=1024
endif
ifeq ($(SIGN),ED25519)
KEYGEN_OPTIONS=--ed25519
SIGN_OPTIONS=--ed25519
PRIVATE_KEY=ed25519.der
OBJS+= ./lib/wolfssl/wolfcrypt/src/sha512.o \
./lib/wolfssl/wolfcrypt/src/ed25519.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
CFLAGS+=-DWOLFBOOT_SIGN_ED25519 -nostdlib -DWOLFSSL_STATIC_MEMORY
CFLAGS+=-DWOLFBOOT_SIGN_ED25519 -nostdlib -DWOLFSSL_STATIC_MEMORY \
-Wstack-usage=1024
LDFLAGS+=-nostdlib
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 \
-DWOLFSSL_USER_SETTINGS \
-DPLATFORM_$(TARGET)
@ -108,15 +129,15 @@ ASFLAGS:=$(CFLAGS)
all: factory.bin
wolfboot.bin: wolfboot.elf
@echo "\t[BIN] $@"
@echo "\t[BIN] $@"
$(Q)$(OBJCOPY) -O binary $^ $@
wolfboot.hex: wolfboot.elf
@echo "\t[HEX] $@"
@echo "\t[HEX] $@"
$(Q)$(OBJCOPY) -O ihex $^ $@
align: wolfboot-align.bin
.bootloader-partition-size: FORCE
@printf "%d" $(WOLFBOOT_PARTITION_BOOT_ADDRESS) > .wolfboot-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
@$(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
ed25519.der:
@ -144,6 +174,9 @@ ed25519.der:
ecc256.der:
@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)
@echo "\t[SIGN] $(BOOT_IMG)"
$(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/rsa2048_pub_key.c: rsa2048.der
keys: $(PRIVATE_KEY)
clean:
@find . -type f -name "*.o" | xargs rm -f
@rm -f *.bin *.elf wolfboot.map *.bin *.hex config/target.ld
@make -C test-app 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
@cat include/target.h.in | \
@ -193,6 +228,6 @@ config: FORCE
@echo "\t[AS-$(ARCH)] $@"
$(Q)$(CC) $(CFLAGS) -c -o $@ $^
FORCE:
FORCE:
.PHONY: FORCE clean

View File

@ -1,7 +1,7 @@
# 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.
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:
- the wolfBoot bootloader
- key generator and image signing tools (requires python 3.x)
- Baremetal test applications
- key generator and image signing tools (requires python 3.x and wolfcrypt-py https://github.com/wolfSSL/wolfcrypt-py)
- Baremetal test applications
### 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:
- 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
- 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)
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)
## 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
### 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)
* Added support for ECC-256 DSA

View File

@ -15,6 +15,11 @@ SECTIONS
. = ALIGN(4);
_end_text = .;
} > FLASH
.edidx :
{
. = ALIGN(4);
*(.ARM.exidx*)
} > FLASH
.edidx :
{

44
hal/stm32l5.ld 100644
View File

@ -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);

View File

@ -15,7 +15,6 @@ SECTIONS
. = ALIGN(4);
_end_text = .;
} > FLASH
.edidx :
{
. = ALIGN(4);

View File

@ -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);
/* 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 PART_UPDATE_EXT

View File

@ -37,6 +37,12 @@
# define KEY_BUFFER ecc256_pub_key
# define KEY_LEN ecc256_pub_key_len
# 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
# error "No public key available for given signing algorithm."
#endif /* Algorithm selection */

View File

@ -41,6 +41,8 @@
# define NO_ED25519_EXPORT
# define WOLFSSL_SHA512
# define USE_SLOW_SHA512
# define NO_RSA
# define NO_ASN
#endif
/* ECC and SHA256 */
@ -78,15 +80,29 @@
# define NO_ECC224
# define HAVE_ECC256
# 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
/* Disables - For minimum wolfCrypt build */
#define NO_AES
#define NO_CMAC
#define NO_CODING
#define NO_RSA
#define NO_BIG_INT
#define NO_ASN
#define NO_RC4
#define NO_SHA
#define NO_DH

View File

@ -28,7 +28,10 @@
#include <stdint.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 WOLFBOOT_MAGIC 0x464C4F57 /* WOLF */
@ -45,6 +48,7 @@
#define HDR_IMG_TYPE_AUTH_ED25519 0x0100
#define HDR_IMG_TYPE_AUTH_ECC256 0x0200
#define HDR_IMG_TYPE_AUTH_RSA2048 0x0300
#define HDR_IMG_TYPE_WOLFBOOT 0x0000
#define HDR_IMG_TYPE_APP 0x0001
@ -54,8 +58,10 @@
# 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
#elif defined(WOLFBOOT_SIGN_RSA2048)
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_RSA2048
#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 */

@ -1 +1 @@
Subproject commit 0fe5d40507e42945d5bc9aefb653ebb0b9f32cf3
Subproject commit 9fd56281482bac15de56269e68162b26f2fab6e7

View File

@ -86,9 +86,43 @@ static int wolfBoot_verify_signature(uint8_t *hash, uint8_t *sig)
}
#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(img->part == PART_UPDATE)
@ -128,7 +162,7 @@ static uint8_t *fetch_hdr_cpy(struct wolfBoot_image *img)
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);
}
@ -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)
{
uint8_t *stored_sha, *end_sha;
uint8_t stored_sha_len;
uint16_t stored_sha_len;
uint8_t *p;
int blksz;
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)
return -1;
wc_InitSha256(&sha256_ctx);
end_sha = stored_sha - 2;
end_sha = stored_sha - 4;
while (p < end_sha) {
blksz = SHA256_BLOCK_SIZE;
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)
{
uint8_t *stored_sha;
uint8_t stored_sha_len;
uint16_t stored_sha_len;
stored_sha_len = get_header(img, HDR_SHA256, &stored_sha);
if (stored_sha_len != SHA256_DIGEST_SIZE)
return -1;
@ -263,12 +297,12 @@ int wolfBoot_verify_integrity(struct wolfBoot_image *img)
int wolfBoot_verify_authenticity(struct wolfBoot_image *img)
{
uint8_t *stored_signature;
uint8_t stored_signature_size;
uint16_t stored_signature_size;
uint8_t *pubkey_hint;
uint8_t pubkey_hint_size;
uint16_t pubkey_hint_size;
uint8_t *image_type_buf;
uint16_t image_type;
uint8_t image_type_size;
uint16_t image_type_size;
stored_signature_size = get_header(img, HDR_SIGNATURE, &stored_signature);
if (stored_signature_size != IMAGE_SIGNATURE_SIZE)

View File

@ -251,21 +251,21 @@ void RAMFUNCTION wolfBoot_success(void)
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;
while (*p != 0) {
uint16_t len;
while (((p[0] != 0) || (p[1] != 0)) && ((p - haystack) < IMAGE_HEADER_SIZE)) {
if (*p == HDR_PADDING) {
p++;
continue;
}
if (*p == type) {
p++;
*ptr = (p + 1);
return *p;
len = p[2] | (p[3] << 8);
if ((p[0] | (p[1] << 8)) == type) {
*ptr = (p + 4);
return len;
}
p++;
p += (*p + 1);
p += 4 + len;
}
*ptr = NULL;
return 0;

View File

@ -1,4 +1,4 @@
/* xmalloc.h
/* xmalloc_ecc.c
*
* Implementations of minimal malloc/free
*

54
src/xmalloc_rsa.c 100644
View File

@ -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;
}

View File

@ -61,7 +61,7 @@ void led_pwm_setup(void)
void boot_led_on(void)
{
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;
reg = GPIOD_MODE & ~(0x03 << (pin * 2));
GPIOD_MODE = reg | (1 << (pin * 2));

View File

@ -39,4 +39,3 @@ CONFIG_VARS:= ARCH TARGET SIGN KINETIS KINETIS_CPU KINETIS_DRIVERS \
WOLFBOOT_PARTITION_SIZE WOLFBOOT_SECTOR_SIZE \
WOLFBOOT_PARTITION_BOOT_ADDRESS WOLFBOOT_PARTITION_UPDATE_ADDRESS \
WOLFBOOT_PARTITION_SWAP_ADDRESS

View File

@ -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"
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"
@ -40,12 +41,12 @@ argc = len(sys.argv)
argv = sys.argv
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)
if argc == 3:
if argv[1] != '--ed25519' and argv[1] != '--ecc256':
print("Usage: %s [--ed25519 | --ecc256 ] pub_key_file.c\n" % sys.argv[0])
if argv[1] != '--ed25519' and argv[1] != '--ecc256' and argv[1] != '--rsa2048':
print("Usage: %s [--ed25519 | --ecc256 | --rsa2048] pub_key_file.c\n" % sys.argv[0])
sys.exit(1)
sign=argv[1][2:]
pubkey_cfile = argv[2]
@ -130,3 +131,30 @@ if (sign == "ecc256"):
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()

View File

@ -45,10 +45,13 @@ HDR_SIGNATURE_LEN = 64
HDR_IMG_TYPE_AUTH_ED25519 = 0x0100
HDR_IMG_TYPE_AUTH_ECC256 = 0x0200
HDR_IMG_TYPE_AUTH_RSA2048 = 0x0300
HDR_IMG_TYPE_WOLFBOOT = 0x0000
HDR_IMG_TYPE_APP = 0x0001
WOLFBOOT_HEADER_SIZE = 256
sign="auto"
self_update=False
@ -56,13 +59,15 @@ argc = len(sys.argv)
argv = sys.argv
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)
for i in range(1, len(argv)):
if (argv[i] == '--ed25519'):
sign='ed25519'
elif (argv[i] == '--ecc256'):
sign='ecc256'
elif (argv[i] == '--rsa2048'):
sign='rsa2048'
elif (argv[i] == '--wolfboot-update'):
self_update = True
else:
@ -93,7 +98,7 @@ print ("Output image: " + output_image_file)
''' import (decode) private key for signing '''
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)
if wolfboot_private_key_len == 64:
if (sign == 'ecc256'):
@ -109,6 +114,11 @@ elif wolfboot_private_key_len == 96:
if sign == 'auto':
sign = 'ecc256'
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:
print ("Error: key size does not match any cipher")
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:])
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)
# Magic header (spells 'WOLF')
@ -130,28 +146,28 @@ header = struct.pack('<L', WOLFBOOT_MAGIC)
# Image size
header += struct.pack('<L', img_size)
# Two pad bytes so version is aligned
header += struct.pack('BB', 0xFF, 0xFF)
# No pad bytes, version is aligned
# 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)
# Six pad bytes so timestamp is aligned
header += struct.pack('BB', 0xFF, 0xFF)
# Four pad bytes, so timestamp is aligned
header += struct.pack('BB', 0xFF, 0xFF)
header += struct.pack('BB', 0xFF, 0xFF)
# 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)))
# 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'):
img_type = HDR_IMG_TYPE_AUTH_ED25519
if (sign == 'ecc256'):
img_type = HDR_IMG_TYPE_AUTH_ECC256
if (sign == 'rsa2048'):
img_type = HDR_IMG_TYPE_AUTH_RSA2048
if (not self_update):
img_type |= HDR_IMG_TYPE_APP
@ -171,32 +187,45 @@ while True:
digest = sha.digest()
# 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
#print("sha:")
#print([hex(j) for j in digest])
# pubkey SHA calculation
#print([hex(j) for j in pubkey])
#print(len(pubkey))
keysha = hashes.Sha256.new()
keysha.update(pubkey)
header += struct.pack('BB', HDR_PUBKEY, HDR_PUBKEY_LEN)
key_digest = keysha.digest()
header += struct.pack('<HH', HDR_PUBKEY, HDR_PUBKEY_LEN)
header += key_digest
#print([hex(j) for j in key_digest])
# Sign the digest
print("Signing the firmware...")
if (sign == 'ed25519'):
signature = ed.sign(digest)
else:
elif (sign == 'ecc256'):
r, s = ecc.sign_raw(digest)
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
#print ("len sig: %d\n" % len(signature))
#print([hex(j) for j in signature])
print ("Done.")
# Create output image. Add padded header in front
outfile = open(output_image_file, 'wb')
outfile.write(header)
sz = len(header)
while sz < 256:
while sz < WOLFBOOT_HEADER_SIZE:
outfile.write(struct.pack('B',0xFF))
sz += 1
infile = open(image_file, 'rb')