Skip to content

Commit fae6a97

Browse files
committed
Adds RSA support to wolfBoot using "SIGN=RSA2048". Includes RSA signing script tool in Python and instructions.
1 parent dc4ea19 commit fae6a97

19 files changed

Lines changed: 363 additions & 69 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
# automatically generated source files
5353
src/ed25519_pub_key.c
5454
src/ecc256_pub_key.c
55+
src/rsa2048_pub_key.c
5556

5657
# keygen binaries
5758
tools/ed25519/ed25519_sign

Makefile

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,21 @@
88
include tools/config.mk
99

1010
## Initializers
11-
CFLAGS:=-D__WOLFBOOT -DWOLFBOOT_VERSION=$(WOLFBOOT_VERSION)UL -ffunction-sections -fdata-sections
11+
CFLAGS:=-D__WOLFBOOT -DWOLFBOOT_VERSION=$(WOLFBOOT_VERSION)UL -ffunction-sections -fdata-sections
1212
LSCRIPT:=config/target.ld
1313
LDFLAGS:=-T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=wolfboot.map -ffreestanding -nostartfiles
1414
OBJS:= \
1515
./hal/$(TARGET).o \
1616
./src/loader.o \
1717
./src/string.o \
1818
./src/image.o \
19-
./src/libwolfboot.o \
20-
./lib/wolfssl/wolfcrypt/src/sha256.o \
21-
./lib/wolfssl/wolfcrypt/src/hash.o \
22-
./lib/wolfssl/wolfcrypt/src/wolfmath.o \
23-
./lib/wolfssl/wolfcrypt/src/fe_low_mem.o
19+
./src/libwolfboot.o
2420

2521

2622
## Architecture/CPU configuration
2723
include arch.mk
2824

29-
3025
## DSA Settings
31-
3226
ifeq ($(SIGN),ECC256)
3327
KEYGEN_OPTIONS=--ecc256
3428
SIGN_OPTIONS=--ecc256
@@ -37,26 +31,53 @@ ifeq ($(SIGN),ECC256)
3731
$(ECC_EXTRA_OBJS) \
3832
$(MATH_OBJS) \
3933
./lib/wolfssl/wolfcrypt/src/ecc.o \
40-
./lib/wolfssl/wolfcrypt/src/ge_low_mem.o \
4134
./lib/wolfssl/wolfcrypt/src/memory.o \
4235
./lib/wolfssl/wolfcrypt/src/wc_port.o \
36+
./lib/wolfssl/wolfcrypt/src/sha256.o \
37+
./lib/wolfssl/wolfcrypt/src/hash.o \
4338
./src/ecc256_pub_key.o \
44-
./src/xmalloc.o
45-
CFLAGS+=-DWOLFBOOT_SIGN_ECC256 -DXMALLOC_USER $(ECC_EXTRA_CFLAGS)
46-
else
39+
./src/xmalloc_ecc.o
40+
CFLAGS+=-DWOLFBOOT_SIGN_ECC256 -DXMALLOC_USER $(ECC_EXTRA_CFLAGS) \
41+
-Wstack-usage=1024
42+
endif
43+
44+
ifeq ($(SIGN),ED25519)
4745
KEYGEN_OPTIONS=--ed25519
4846
SIGN_OPTIONS=--ed25519
4947
PRIVATE_KEY=ed25519.der
5048
OBJS+= ./lib/wolfssl/wolfcrypt/src/sha512.o \
5149
./lib/wolfssl/wolfcrypt/src/ed25519.o \
5250
./lib/wolfssl/wolfcrypt/src/ge_low_mem.o \
51+
./lib/wolfssl/wolfcrypt/src/sha256.o \
52+
./lib/wolfssl/wolfcrypt/src/hash.o \
53+
./lib/wolfssl/wolfcrypt/src/wolfmath.o \
54+
./lib/wolfssl/wolfcrypt/src/fe_low_mem.o \
5355
./src/ed25519_pub_key.o
54-
CFLAGS+=-DWOLFBOOT_SIGN_ED25519 -nostdlib -DWOLFSSL_STATIC_MEMORY
56+
CFLAGS+=-DWOLFBOOT_SIGN_ED25519 -nostdlib -DWOLFSSL_STATIC_MEMORY \
57+
-Wstack-usage=1024
5558
LDFLAGS+=-nostdlib
5659
endif
5760

61+
ifeq ($(SIGN),RSA2048)
62+
KEYGEN_OPTIONS=--rsa2048
63+
SIGN_OPTIONS=--rsa2048
64+
PRIVATE_KEY=rsa2048.der
65+
IMAGE_HEADER_SIZE=512
66+
OBJS+= \
67+
$(RSA_EXTRA_OBJS) \
68+
$(MATH_OBJS) \
69+
./lib/wolfssl/wolfcrypt/src/rsa.o \
70+
./lib/wolfssl/wolfcrypt/src/sha256.o \
71+
./lib/wolfssl/wolfcrypt/src/asn.o \
72+
./lib/wolfssl/wolfcrypt/src/hash.o \
73+
./src/rsa2048_pub_key.o \
74+
./src/xmalloc_rsa.o
75+
CFLAGS+=-DWOLFBOOT_SIGN_RSA2048 -DXMALLOC_USER $(RSA_EXTRA_CFLAGS) \
76+
-Wstack-usage=4096 -DIMAGE_HEADER_SIZE=512
77+
endif
78+
5879

59-
CFLAGS+=-Wall -Wextra -Wno-main -Wstack-usage=1024 -ffreestanding -Wno-unused \
80+
CFLAGS+=-Wall -Wextra -Wno-main -ffreestanding -Wno-unused \
6081
-I. -Iinclude/ -Ilib/wolfssl -nostartfiles \
6182
-DWOLFSSL_USER_SETTINGS \
6283
-DPLATFORM_$(TARGET)
@@ -108,15 +129,15 @@ ASFLAGS:=$(CFLAGS)
108129
all: factory.bin
109130

110131
wolfboot.bin: wolfboot.elf
111-
@echo "\t[BIN] $@"
132+
@echo "\t[BIN] $@"
112133
$(Q)$(OBJCOPY) -O binary $^ $@
113134

114135
wolfboot.hex: wolfboot.elf
115-
@echo "\t[HEX] $@"
136+
@echo "\t[HEX] $@"
116137
$(Q)$(OBJCOPY) -O ihex $^ $@
117138

118139
align: wolfboot-align.bin
119-
140+
120141
.bootloader-partition-size: FORCE
121142
@printf "%d" $(WOLFBOOT_PARTITION_BOOT_ADDRESS) > .wolfboot-offset
122143
@printf "%d" $(ARCH_FLASH_OFFSET) > .wolfboot-arch-offset
@@ -136,6 +157,15 @@ test-app/image.bin: wolfboot-align.bin
136157
@rm -f src/*.o hal/*.o
137158
@$(SIZE) test-app/image.elf
138159

160+
standalone:
161+
@make -C test-app TARGET=$(TARGET) EXT_FLASH=$(EXT_FLASH) SPI_FLASH=$(SPI_FLASH) ARCH=$(ARCH) \
162+
V=$(V) RAM_CODE=$(RAM_CODE) WOLFBOOT_VERSION=$(WOLFBOOT_VERSION)\
163+
KINETIS=$(KINETIS) KINETIS_CPU=$(KINETIS_CPU) KINETIS_DRIVERS=$(KINETIS_DRIVERS) \
164+
KINETIS_CMSIS=$(KINETIS_CMSIS) NVM_FLASH_WRITEONCE=$(NVM_FLASH_WRITEONCE) \
165+
FREEDOM_E_SDK=$(FREEDOM_E_SDK) standalone
166+
$(Q)$(OBJCOPY) -O binary test-app/image.elf standalone.bin
167+
@$(SIZE) test-app/image.elf
168+
139169
include tools/test.mk
140170

141171
ed25519.der:
@@ -144,6 +174,9 @@ ed25519.der:
144174
ecc256.der:
145175
@python3 tools/keytools/keygen.py $(KEYGEN_OPTIONS) src/ecc256_pub_key.c
146176

177+
rsa2048.der:
178+
@python3 tools/keytools/keygen.py $(KEYGEN_OPTIONS) src/rsa2048_pub_key.c
179+
147180
factory.bin: $(BOOT_IMG) wolfboot-align.bin $(PRIVATE_KEY)
148181
@echo "\t[SIGN] $(BOOT_IMG)"
149182
$(Q)python3 tools/keytools/sign.py $(SIGN_OPTIONS) $(BOOT_IMG) $(PRIVATE_KEY) 1
@@ -163,15 +196,17 @@ src/ed25519_pub_key.c: ed25519.der
163196

164197
src/ecc256_pub_key.c: ecc256.der
165198

199+
src/rsa2048_pub_key.c: rsa2048.der
200+
166201
keys: $(PRIVATE_KEY)
167-
202+
168203
clean:
169204
@find . -type f -name "*.o" | xargs rm -f
170205
@rm -f *.bin *.elf wolfboot.map *.bin *.hex config/target.ld
171206
@make -C test-app clean
172207

173208
distclean: clean
174-
@rm -f *.pem *.der tags ./src/ed25519_pub_key.c ./src/ecc256_pub_key.c include/target.h
209+
@rm -f *.pem *.der tags ./src/ed25519_pub_key.c ./src/ecc256_pub_key.c ./src/rsa2048_pub_key.c include/target.h
175210

176211
include/target.h: include/target.h.in FORCE
177212
@cat include/target.h.in | \
@@ -193,6 +228,6 @@ config: FORCE
193228
@echo "\t[AS-$(ARCH)] $@"
194229
$(Q)$(CC) $(CFLAGS) -c -o $@ $^
195230

196-
FORCE:
231+
FORCE:
197232

198233
.PHONY: FORCE clean

README.md

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# wolfBoot
22
wolfSSL Secure Bootloader ([Home page](https://www.wolfssl.com/products/wolfboot/))
33

4-
wolfBoot is a portable, OS-agnostic, secure bootloader solution for 32-bit microcontrollers,
4+
wolfBoot is a portable, OS-agnostic, secure bootloader solution for 32-bit microcontrollers,
55
relying on wolfCrypt for firmware authentication, providing firmware update mechanisms.
66

77
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.
2121

2222
This repository contains the following components:
2323
- the wolfBoot bootloader
24-
- key generator and image signing tools (requires python 3.x)
25-
- Baremetal test applications
24+
- key generator and image signing tools (requires python 3.x and wolfcrypt-py https://github.com/wolfSSL/wolfcrypt-py)
25+
- Baremetal test applications
2626

2727
### wolfBoot bootloader
2828

@@ -32,7 +32,7 @@ with no dynamic memory allocation mechanism or linkage to any standard C library
3232
The bootloader consists of the following components:
3333
- wolfCrypt, which is used to verify the signature of the images
3434
- 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
35-
- The core bootloader
35+
- The core bootloader
3636
- A small application library used by the application to interact with the bootloader [src/libwolfboot.c](src/libwolfboot.c)
3737

3838
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,
8383

8484
For more detailed information about firmware update implementation, see [Firmware Update](docs/firmware_update.md)
8585

86+
## Troubleshooting
87+
88+
1. Python errors when signing a key:
89+
90+
```
91+
Traceback (most recent call last):
92+
File "tools/keytools/keygen.py", line 135, in <module>
93+
rsa = ciphers.RsaPrivate.make_key(2048)
94+
AttributeError: type object 'RsaPrivate' has no attribute 'make_key'
95+
```
96+
97+
```
98+
Traceback (most recent call last):
99+
File "tools/keytools/sign.py", line 189, in <module>
100+
r, s = ecc.sign_raw(digest)
101+
AttributeError: 'EccPrivate' object has no attribute 'sign_raw'
102+
```
103+
104+
You need to install the latest wolfcrypt-pi here: https://github.com/wolfSSL/wolfcrypt-py
105+
106+
Use `pip3 install wolfcrypt`.
107+
Make sure the wolfSSL library has been built with:
108+
```sh
109+
110+
```
111+
112+
To install based on a local wolfSSL installation use:
113+
114+
```sh
115+
cd youwolfssldir
116+
./configure --enable-keygen --enable-rsa --enable-ecc --enable-ed25519 CFLAGS="-DWOLFSSL_PUBLIC_MP"
117+
make
118+
sudo make install
119+
120+
cd yourwolfcryptpydir
121+
USE_LOCAL_WOLFSSL=/usr/local pip3 install .
122+
```
123+
86124
## Release Notes
87125

88126
### v1.0 (2018-12-04)
89-
* Initial release with fail-safe update, HAL support for STM32 and nRF52
127+
* Initial release with fail-safe update, HAL support for STM32 and nRF52
90128

91129
### V1.1 (2019-03-27)
92130
* Added support for ECC-256 DSA

hal/stm32f4.ld

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ SECTIONS
1515
. = ALIGN(4);
1616
_end_text = .;
1717
} > FLASH
18+
.edidx :
19+
{
20+
. = ALIGN(4);
21+
*(.ARM.exidx*)
22+
} > FLASH
1823

1924
.edidx :
2025
{

hal/stm32l5.ld

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
MEMORY
2+
{
3+
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x001FFE0
4+
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00010000
5+
}
6+
7+
SECTIONS
8+
{
9+
.text :
10+
{
11+
_start_text = .;
12+
KEEP(*(.isr_vector))
13+
*(.text*)
14+
*(.rodata*)
15+
. = ALIGN(4);
16+
_end_text = .;
17+
} > FLASH
18+
19+
_stored_data = .;
20+
.data : AT (_stored_data)
21+
{
22+
_start_data = .;
23+
KEEP(*(.data*))
24+
. = ALIGN(4);
25+
KEEP(*(.ramcode))
26+
. = ALIGN(4);
27+
_end_data = .;
28+
} > RAM
29+
30+
.bss (NOLOAD) :
31+
{
32+
_start_bss = .;
33+
__bss_start__ = .;
34+
*(.bss*)
35+
*(COMMON)
36+
. = ALIGN(4);
37+
_end_bss = .;
38+
__bss_end__ = .;
39+
_end = .;
40+
} > RAM
41+
. = ALIGN(4);
42+
}
43+
44+
END_STACK = ORIGIN(RAM) + LENGTH(RAM);

hal/stm32wb.ld

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ SECTIONS
1515
. = ALIGN(4);
1616
_end_text = .;
1717
} > FLASH
18-
1918
.edidx :
2019
{
2120
. = ALIGN(4);

include/image.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ int wolfBoot_get_partition_state(uint8_t part, uint8_t *st);
7070
int wolfBoot_get_sector_flag(uint8_t part, uint8_t sector, uint8_t *flag);
7171

7272
/* Defined in libwolfboot */
73-
uint8_t wolfBoot_find_header(uint8_t *haystack, uint8_t type, uint8_t **ptr);
73+
uint16_t wolfBoot_find_header(uint8_t *haystack, uint16_t type, uint8_t **ptr);
7474

7575
#ifdef EXT_FLASH
7676
# ifdef PART_UPDATE_EXT

include/loader.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@
3737
# define KEY_BUFFER ecc256_pub_key
3838
# define KEY_LEN ecc256_pub_key_len
3939
# define IMAGE_SIGNATURE_SIZE (64)
40+
#elif defined(WOLFBOOT_SIGN_RSA2048)
41+
extern const unsigned char rsa2048_pub_key[];
42+
extern unsigned int rsa2048_pub_key_len;
43+
# define KEY_BUFFER rsa2048_pub_key
44+
# define KEY_LEN rsa2048_pub_key_len
45+
# define IMAGE_SIGNATURE_SIZE (256)
4046
#else
4147
# error "No public key available for given signing algorithm."
4248
#endif /* Algorithm selection */

include/user_settings.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
# define NO_ED25519_EXPORT
4242
# define WOLFSSL_SHA512
4343
# define USE_SLOW_SHA512
44+
# define NO_RSA
45+
# define NO_ASN
4446
#endif
4547

4648
/* ECC and SHA256 */
@@ -78,15 +80,29 @@
7880
# define NO_ECC224
7981
# define HAVE_ECC256
8082
# define NO_ECC384
83+
# define NO_RSA
84+
# define NO_ASN
85+
#endif
86+
87+
#ifdef WOLFBOOT_SIGN_RSA2048
88+
# define HAVE_RSA
89+
# define RSA_LOW_MEM
90+
# define WOLFSSL_STATIC_RSA
91+
# define WOLFSSL_RSA_VERIFY_INLINE
92+
//# define WOLFSSL_RSA_PUBLIC_ONLY
93+
//# define WOLFSSL_RSA_VERIFY_ONLY
94+
# define WOLFSSL_HAVE_SP_RSA
95+
# define WOLFSSL_SP
96+
# define WOLFSSL_SP_SMALL
97+
# define WOLFSSL_SP_MATH
98+
# define SP_WORD_SIZE 32
8199
#endif
82100

83101
/* Disables - For minimum wolfCrypt build */
84102
#define NO_AES
85103
#define NO_CMAC
86104
#define NO_CODING
87-
#define NO_RSA
88105
#define NO_BIG_INT
89-
#define NO_ASN
90106
#define NO_RC4
91107
#define NO_SHA
92108
#define NO_DH

0 commit comments

Comments
 (0)