Skip to content

Commit

Permalink
Fixes for building wolfBoot with XMSS/LMS.
Browse files Browse the repository at this point in the history
  • Loading branch information
dgarske authored and danielinux committed Aug 14, 2024
1 parent be16914 commit 9e17315
Show file tree
Hide file tree
Showing 16 changed files with 208 additions and 37 deletions.
8 changes: 8 additions & 0 deletions IDE/XilinxSDK/.cproject
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
<listOptionValue builtIn="false" value="TARGET_zynq"/>
<listOptionValue builtIn="false" value="ARCH_AARCH64"/>
<listOptionValue builtIn="false" value="MMU"/>
<listOptionValue builtIn="false" value="NO_XIP"/>
<listOptionValue builtIn="false" value="PART_UPDATE_EXT=1"/>
<listOptionValue builtIn="false" value="PART_SWAP_EXT=1"/>
<listOptionValue builtIn="false" value="PART_BOOT_EXT=1"/>
Expand All @@ -51,6 +52,7 @@
<listOptionValue builtIn="false" value="WOLFTPM_USER_SETTINGS"/>
<listOptionValue builtIn="false" value="WOLFPKCS11_USER_SETTINGS"/>
<listOptionValue builtIn="false" value="WOLFBOOT_DUALBOOT"/>
<listOptionValue builtIn="false" value="WOLFBOOT_ELF"/>
</option>
<option id="xilinx.gnu.compiler.dircategory.includes.398847842" name="Include Paths" superClass="xilinx.gnu.compiler.dircategory.includes" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>
Expand All @@ -76,6 +78,7 @@
<listOptionValue builtIn="false" value="TARGET_zynq"/>
<listOptionValue builtIn="false" value="ARCH_AARCH64"/>
<listOptionValue builtIn="false" value="MMU"/>
<listOptionValue builtIn="false" value="NO_XIP"/>
<listOptionValue builtIn="false" value="PART_UPDATE_EXT=1"/>
<listOptionValue builtIn="false" value="PART_SWAP_EXT=1"/>
<listOptionValue builtIn="false" value="PART_BOOT_EXT=1"/>
Expand All @@ -90,6 +93,7 @@
<listOptionValue builtIn="false" value="WOLFTPM_USER_SETTINGS"/>
<listOptionValue builtIn="false" value="WOLFPKCS11_USER_SETTINGS"/>
<listOptionValue builtIn="false" value="WOLFBOOT_DUALBOOT"/>
<listOptionValue builtIn="false" value="WOLFBOOT_ELF"/>
</option>
<option id="xilinx.gnu.compiler.dircategory.includes.1725565215" name="Include Paths" superClass="xilinx.gnu.compiler.dircategory.includes" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>
Expand Down Expand Up @@ -169,6 +173,7 @@
<listOptionValue builtIn="false" value="TARGET_zynq"/>
<listOptionValue builtIn="false" value="ARCH_AARCH64"/>
<listOptionValue builtIn="false" value="MMU"/>
<listOptionValue builtIn="false" value="NO_XIP"/>
<listOptionValue builtIn="false" value="PART_UPDATE_EXT=1"/>
<listOptionValue builtIn="false" value="PART_SWAP_EXT=1"/>
<listOptionValue builtIn="false" value="PART_BOOT_EXT=1"/>
Expand All @@ -183,6 +188,7 @@
<listOptionValue builtIn="false" value="WOLFTPM_USER_SETTINGS"/>
<listOptionValue builtIn="false" value="WOLFPKCS11_USER_SETTINGS"/>
<listOptionValue builtIn="false" value="WOLFBOOT_DUALBOOT"/>
<listOptionValue builtIn="false" value="WOLFBOOT_ELF"/>
</option>
<option id="xilinx.gnu.compiler.dircategory.includes.1446899274" name="Include Paths" superClass="xilinx.gnu.compiler.dircategory.includes" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>
Expand All @@ -208,6 +214,7 @@
<listOptionValue builtIn="false" value="TARGET_zynq"/>
<listOptionValue builtIn="false" value="ARCH_AARCH64"/>
<listOptionValue builtIn="false" value="MMU"/>
<listOptionValue builtIn="false" value="NO_XIP"/>
<listOptionValue builtIn="false" value="PART_UPDATE_EXT=1"/>
<listOptionValue builtIn="false" value="PART_SWAP_EXT=1"/>
<listOptionValue builtIn="false" value="PART_BOOT_EXT=1"/>
Expand All @@ -222,6 +229,7 @@
<listOptionValue builtIn="false" value="WOLFTPM_USER_SETTINGS"/>
<listOptionValue builtIn="false" value="WOLFPKCS11_USER_SETTINGS"/>
<listOptionValue builtIn="false" value="WOLFBOOT_DUALBOOT"/>
<listOptionValue builtIn="false" value="WOLFBOOT_ELF"/>
</option>
<option id="xilinx.gnu.compiler.dircategory.includes.438324592" name="Include Paths" superClass="xilinx.gnu.compiler.dircategory.includes" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>
Expand Down
147 changes: 140 additions & 7 deletions IDE/XilinxSDK/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,14 @@ You may need to adjust/add the following project settings under Properties -> C/

## wolfBoot Configuration

A build settings template for Zynq UltraScale+ can be found here `./config/examples/zynqmp.config`. This file can be copied to wolfBoot root as `.config` for building from the command line. These template settings are also in this `.cproject` as preprocessor macros. These settings are loaded into the `target.h.in` template by the wolfBoot `make`. If not using the built-in make then the following defines will need to be manually created in `target.h`:
A build settings template for Zynq UltraScale+ can be found here `./config/examples/zynqmp.config`. This file can be copied to wolfBoot root as `.config` for building from the command line.

```sh
$ cp ./config/examples/zynqmp.config .config
$ make keytools
```

These template settings are also in this `.cproject` as preprocessor macros. These settings are loaded into the `target.h.in` template by the wolfBoot `make`. If not using the built-in make then the following defines will need to be manually created in `target.h`:

```
#define WOLFBOOT_SECTOR_SIZE 0x20000
Expand All @@ -40,10 +47,25 @@ A build settings template for Zynq UltraScale+ can be found here `./config/examp

Note: If not using Position Independent Code (PIC) the linker script `ldscript.ld` must have the start address offset to match the `WOLFBOOT_LOAD_ADDRESS`.

## Generate signing key

The keygen tool creates an RSA 4096-bit private key (`wolfboot_signing_private_key.der`) and exports the public key to `src/keystore.c` for wolfBoot to use at compile-time as the default root-of-trust.

```sh
$ ./tools/keytools/keygen --rsa4096 -g wolfboot_signing_private_key.der
Keytype: RSA4096
Generating key (type: RSA4096)
RSA public key len: 550 bytes
Associated key file: wolfboot_signing_private_key.der
Partition ids mask: ffffffff
Key type : RSA4096
Public key slot: 0
Done.
```

## Signing Example

```sh
$ make keytools
$ ./tools/keytools/sign --rsa4096 --sha3 ../hello_world/Debug/hello_world.elf ./wolfboot_signing_private_key.der 1
wolfBoot KeyTools (Compiled C version)
wolfBoot version 2020000
Expand Down Expand Up @@ -115,11 +137,24 @@ Read FlashID Upper: Ret 0, 20 BB 20
Versions: Boot 1, Update 0
Trying Boot partition at 800000
Boot partition: 800000 (size 226024, version 0x1)
info: LMS wolfBoot_verify_signature
info: using LMS parameters: L2-H5-W8
info: wc_LmsKey_Verify returned OK
Successfully selected image in part: 0
Firmware Valid
Loading 226024 bytes to RAM at 10000000
Loading flash image from 8014A8 to RAM at 10000000 (226024 bytes)
Loading elf at 10000000
Found valid elf64 (little endian)
Program Headers 2 (size 56)
Load 57536 bytes (offset 10000) to 0 (p 0)
Clear 20600 bytes at 0 (p 0)
Entry point 0
DTB boot partition: 7B0000
Failed parsing DTB to load
Booting at 10000000
Booting at 0
Hello World
Successfully ran Hello World application
```


Expand Down Expand Up @@ -156,11 +191,109 @@ Note: To generate a report of a boot.bin use the `bootgen_utility`:
## Post Quantum
XMSS
### PQ XMSS
1) Add these build symbols to the Xilinx project:
Note: Make sure and remove the existing `WOLFBOOT_SIGN_*`, `WOLFBOOT_HASH_*` and `IMAGE_HEADER_SIZE`
```
WOLFBOOT_SIGN_XMSS
WOLFBOOT_HASH_SHA256
WOLFSSL_HAVE_XMSS
WOLFSSL_WC_XMSS
WOLFSSL_WC_XMSS_SMALL
WOLFBOOT_XMSS_PARAMS="'XMSS-SHA2_10_256'"
WOLFSSL_XMSS_VERIFY_ONLY
WOLFSSL_XMSS_MAX_HEIGHT=32
WOLFBOOT_SHA_BLOCK_SIZE=4096
IMAGE_SIGNATURE_SIZE=2500
IMAGE_HEADER_SIZE=4096
```
2) Create and sign image:
```sh
./tools/keytools/keygen --xmss -g wolfboot_signing_private_key.der
./tools/keytools/sign --xmss test-app/image.bin wolfboot_signing_private_key.der 1
$ ./tools/keytools/keygen --xmss -g wolfboot_signing_private_key.der
Keytype: XMSS
Generating key (type: XMSS)
info: using XMSS parameters: XMSS-SHA2_10_256
Associated key file: wolfboot_signing_private_key.der
Partition ids mask: ffffffff
Key type : XMSS
Public key slot: 0
Done.
$ ./tools/keytools/sign --xmss ../hello_world/Debug/hello_world.elf wolfboot_signing_private_key.der 1
wolfBoot KeyTools (Compiled C version)
wolfBoot version 2020000
Update type: Firmware
Input image: ../hello_world/Debug/hello_world.elf
Selected cipher: XMSS
Selected hash : SHA256
Public key: wolfboot_signing_private_key.der
Output image: ../hello_world/Debug/hello_world_v1_signed.bin
Target partition id : 1
info: using XMSS parameters: XMSS-SHA2_10_256
info: XMSS signature size: 2500
info: xmss sk len: 1343
info: xmss pk len: 68
Found XMSS key
image header size calculated at runtime (5000 bytes)
Calculating SHA256 digest...
Signing the digest...
Output image(s) successfully created.
```

### PQ LMS

1) Add these build symbols to the Xilinx project:
Note: Make sure and remove the existing `WOLFBOOT_SIGN_*`, `WOLFBOOT_HASH_*` and `IMAGE_HEADER_SIZE`

```
WOLFBOOT_SIGN_LMS
WOLFBOOT_HASH_SHA256
WOLFSSL_HAVE_LMS
WOLFSSL_WC_LMS
WOLFSSL_WC_LMS_SMALL
WOLFSSL_LMS_VERIFY_ONLY
WOLFSSL_LMS_MAX_LEVELS=2
WOLFSSL_LMS_MAX_HEIGHT=5
LMS_LEVELS=2
LMS_HEIGHT=5
LMS_WINTERNITZ=8
IMAGE_SIGNATURE_SIZE=2644
IMAGE_HEADER_SIZE=5288
```
2) Create and sign image:

```sh
$ ./tools/keytools/keygen --lms -g wolfboot_signing_private_key.der
Keytype: LMS
Generating key (type: LMS)
info: using LMS parameters: L2-H5-W8
Associated key file: wolfboot_signing_private_key.der
Partition ids mask: ffffffff
Key type : LMS
Public key slot: 0
Done.

$ ./tools/keytools/sign --lms ../hello_world/Debug/hello_world.elf wolfboot_signing_private_key.der 1
wolfBoot KeyTools (Compiled C version)
wolfBoot version 2020000
Update type: Firmware
Input image: ../hello_world/Debug/hello_world.elf
Selected cipher: LMS
Selected hash : SHA256
Public key: wolfboot_signing_private_key.der
Output image: ../hello_world/Debug/hello_world_v1_signed.bin
Target partition id : 1
info: using LMS parameters: L2-H5-W8
info: LMS signature size: 2644
Found LMS key
image header size calculated at runtime (5288 bytes)
Calculating SHA256 digest...
Signing the digest...
Output image(s) successfully created.
```


Expand Down
2 changes: 1 addition & 1 deletion arch.mk
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,7 @@ ifeq ($(TARGET),x86_64_efi)
CFLAGS += -I/usr/include/efi -I/usr/include/efi/x86_64 \
-DTARGET_X86_64_EFI -DWOLFBOOT_DUALBOOT
# avoid using of fixed LOAD_ADDRESS, uefi target uses dynamic location
CFLAGS += -DNO_WOLFBOOT_LOAD_ADDRESS
CFLAGS += -DWOLFBOOT_NO_LOAD_ADDRESS
LDFLAGS = -shared -Bsymbolic -L/usr/lib -T$(GNU_EFI_LSCRIPT)
LD_START_GROUP = $(GNU_EFI_CRT0)
LD_END_GROUP = -lgnuefi -lefi
Expand Down
13 changes: 12 additions & 1 deletion config/examples/zynqmp.config
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,17 @@ IMAGE_HEADER_SIZE?=1024
#IMAGE_SIGNATURE_SIZE=2500
#IMAGE_HEADER_SIZE?=5000

DEBUG?=1
# LMS/HSS is a post-quantum, stateful, hash-based signature scheme.
# Use the helper script `tools/lms/lms_siglen`
#SIGN?=LMS
#HASH?=SHA256
#LMS_LEVELS=2
#LMS_HEIGHT=5
#LMS_WINTERNITZ=8
#IMAGE_SIGNATURE_SIZE=2644
#IMAGE_HEADER_SIZE?=5288

DEBUG?=0
DEBUG_UART=1
#DEBUG_ZYNQ=1

Expand All @@ -37,6 +47,7 @@ EXT_FLASH?=1
SPI_FLASH?=0
NO_XIP=1
USE_GCC=1
ELF?=1

# Flash Sector Size
WOLFBOOT_SECTOR_SIZE=0x20000
Expand Down
2 changes: 1 addition & 1 deletion hal/zynq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1301,7 +1301,7 @@ int RAMFUNCTION ext_flash_read(uintptr_t address, uint8_t *data, int len)
wolfBoot_printf("Flash Read: Ret %d\r\n", ret);
#endif

return ret;
return (ret == 0) ? len : ret;
}

/* Issues a sector erase based on flash address */
Expand Down
2 changes: 1 addition & 1 deletion include/target.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@

#endif /* WOLFBOOT_FIXED_PARTITIONS */

#if !defined(NO_WOLFBOOT_LOAD_ADDRESS)
#if !defined(WOLFBOOT_NO_LOAD_ADDRESS)
/* Load address in RAM for staged OS (update_ram only) */
#define WOLFBOOT_LOAD_ADDRESS @WOLFBOOT_LOAD_ADDRESS@
#endif
Expand Down
3 changes: 2 additions & 1 deletion include/user_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,8 @@ extern int tolower(int c);
# define WC_NO_HASHDRBG
# define NO_DEV_RANDOM
# define NO_ECC_KEY_EXPORT
# ifdef NO_RSA
# if defined(NO_RSA) && !defined(WOLFSSL_HAVE_XMSS) && \
!defined(WOLFSSL_HAVE_LMS)
# define NO_ASN
# endif
#endif
Expand Down
4 changes: 2 additions & 2 deletions options.mk
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ ifeq ($(SIGN),LMS)
ifeq ($(WOLFBOOT_SMALL_STACK),1)
$(error WOLFBOOT_SMALL_STACK with LMS not supported)
else
STACK_USAGE=1024
STACK_USAGE=1296
endif
endif

Expand Down Expand Up @@ -447,7 +447,7 @@ ifeq ($(SIGN),XMSS)
ifeq ($(WOLFBOOT_SMALL_STACK),1)
$(error WOLFBOOT_SMALL_STACK with XMSS not supported)
else
STACK_USAGE=2688
STACK_USAGE=2720
endif
endif

Expand Down
2 changes: 0 additions & 2 deletions src/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,6 @@ static void wolfBoot_verify_signature(uint8_t key_slot,
{
int ret = 0;
LmsKey lms;
word32 pub_len = 0;
uint8_t * pubkey = NULL;

wolfBoot_printf("info: LMS wolfBoot_verify_signature\n");
Expand Down Expand Up @@ -419,7 +418,6 @@ static void wolfBoot_verify_signature(uint8_t key_slot,
{
int ret = 0;
XmssKey xmss;
word32 pub_len = 0;
uint8_t * pubkey = NULL;

wolfBoot_printf("info: XMSS wolfBoot_verify_signature\n");
Expand Down
3 changes: 2 additions & 1 deletion src/qspi_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,8 @@ int spi_flash_read(uint32_t address, void *data, int len)
ret, address, len, FLASH_READ_CMD);
#endif

return ret;
/* external flash read expects length returned */
return (ret == 0) ? len : ret;
}

int spi_flash_write(uint32_t address, const void *data, int len)
Expand Down
Loading

0 comments on commit 9e17315

Please sign in to comment.