Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add wolfcrypt xmss and lms support. #429

Merged
merged 12 commits into from
May 7, 2024
4 changes: 2 additions & 2 deletions .github/workflows/test-renode-nrf52.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ jobs:

# LMS TEST
- name: Renode Tests LMS-8-5-5
run: ./tools/renode/docker-test.sh "SIGN=LMS LMS_LEVELS=2 LMS_HEIGHT=5 LMS_WINTERNITZ=8 WOLFBOOT_SMALL_STACK=0 IMAGE_SIGNATURE_SIZE=2644 IMAGE_HEADER_SIZE=5288"
run: ./tools/renode/docker-test.sh "SIGN=ext_LMS LMS_LEVELS=2 LMS_HEIGHT=5 LMS_WINTERNITZ=8 WOLFBOOT_SMALL_STACK=0 IMAGE_SIGNATURE_SIZE=2644 IMAGE_HEADER_SIZE=5288"

# XMSS TEST
- name: Renode Tests XMSS-SHA2_10_256
run: ./tools/renode/docker-test.sh "SIGN=XMSS XMSS_PARAMS='XMSS-SHA2_10_256' WOLFBOOT_SMALL_STACK=0 IMAGE_SIGNATURE_SIZE=2500 IMAGE_HEADER_SIZE=5000"
run: ./tools/renode/docker-test.sh "SIGN=ext_XMSS XMSS_PARAMS='XMSS-SHA2_10_256' WOLFBOOT_SMALL_STACK=0 IMAGE_SIGNATURE_SIZE=2500 IMAGE_HEADER_SIZE=5000"

- name: Upload Output Dir
uses: actions/upload-artifact@v2
Expand Down
5 changes: 5 additions & 0 deletions config/examples/sim-xmss.config
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# XMSS/XMSS^MT/HSS signature example, based on sim.config example.
#
# XMSS/XMSS^MT is a post-quantum, stateful, hash-based signature scheme.
#
# Use the helper script
# tools/xmss/xmss_siglen.sh
# to calculate your signature length given an xmss parameter string.
#

ARCH=sim
Expand Down
2 changes: 1 addition & 1 deletion config/examples/stm32c0-lms-8-10-1.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ARCH?=ARM
TARGET?=stm32c0
SIGN?=LMS
SIGN?=ext_LMS
LMS_LEVELS=1
LMS_HEIGHT=10
LMS_WINTERNITZ=8
Expand Down
123 changes: 66 additions & 57 deletions docs/PQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,42 +19,18 @@ See these links for more info on stateful HBS support and wolfSSL/wolfCrypt:
- https://www.wolfssl.com/documentation/manuals/wolfssl/appendix07.html#post-quantum-stateful-hash-based-signatures
- https://github.com/wolfSSL/wolfssl-examples/tree/master/pq/stateful_hash_sig

## Supported PQ Signature Methods

## LMS/HSS
These four PQ signature options are supported:
- LMS: uses wolfcrypt implementation from `wc_lms.c`, and `wc_lms_impl.c`.
- XMSS: uses wolfcrypt implementation from `wc_xmss.c`, and `wc_xmss_impl.c`.
- ext_LMS: uses external integration from `ext_lms.c`.
- ext_XMSS: uses external integration from `ext_xmss.c`.

The wolfcrypt implementations are more performant and are recommended.
The external integrations are experimental and for testing interoperability.

### Building with LMS Support

LMS/HSS support in wolfCrypt requires the hash-sigs library ( https://github.com/cisco/hash-sigs ).
Use the following procedure to prepare hash-sigs for building with wolfBoot:

```
$ cd lib
$ mkdir hash-sigs
$ls
CMakeLists.txt hash-sigs wolfssl wolfTPM
$ cd hash-sigs
$ mkdir lib
$ git clone https://github.com/cisco/hash-sigs.git src
$ cd src
$ git checkout b0631b8891295bf2929e68761205337b7c031726
$ git apply ../../../tools/lms/0001-Patch-to-support-wolfBoot-LMS-build.patch
```

Nothing more is needed, as wolfBoot will automatically produce the required
hash-sigs build artifacts.

Note: the hash-sigs project only builds static libraries:
- hss_verify.a: a single-threaded verify-only static lib.
- hss_lib.a: a single-threaded static lib.
- hss_lib_thread.a: a multi-threaded static lib.

The keytools utility links against `hss_lib.a`, as it needs full
keygen, signing, and verifying functionality. However wolfBoot
links directly with the subset of objects in the `hss_verify.a`
build rule, as it only requires verify functionality.

### LMS Config
### LMS/HSS Config

A new LMS sim example has been added here:
```
Expand Down Expand Up @@ -86,31 +62,8 @@ winternitz: 8
signature length: 2644
```

## XMSS/XMSS^MT
### XMSS/XMSS^MT Config

### Building with XMSS Support

XMSS/XMSS^MT support in wolfCrypt requires a patched version of the
xmss-reference library ( https://github.com/XMSS/xmss-reference.git ).
Use the following procedure to prepare xmss-reference for building with
wolfBoot:

```
$ cd lib
$ git clone https://github.com/XMSS/xmss-reference.git xmss
$ ls
CMakeLists.txt wolfPKCS11 wolfTPM wolfssl xmss
$ cd xmss
$ git checkout 171ccbd26f098542a67eb5d2b128281c80bd71a6
$ git apply ../../tools/xmss/0001-Patch-to-support-wolfSSL-xmss-reference-integration.patch
```

The patch creates an addendum readme, `patch_readme.md`, with further comments.

Nothing more is needed beyond the patch step, as wolfBoot will handle building
the xmss build artifacts it requires.

### XMSS Config
A new XMSS sim example has been added here:
```
config/examples/sim-xmss.config
Expand Down Expand Up @@ -142,3 +95,59 @@ $ ./tools/xmss/xmss_siglen.sh XMSSMT-SHA2_20/2_256
parameter set: XMSSMT-SHA2_20/2_256
signature length: 4963
```

## Building the external PQ Integrations

### ext_LMS Support

The external LMS/HSS support in wolfCrypt requires the hash-sigs library ( https://github.com/cisco/hash-sigs ).
Use the following procedure to prepare hash-sigs for building with wolfBoot:

```
$ cd lib
$ mkdir hash-sigs
$ls
CMakeLists.txt hash-sigs wolfssl wolfTPM
$ cd hash-sigs
$ mkdir lib
$ git clone https://github.com/cisco/hash-sigs.git src
$ cd src
$ git checkout b0631b8891295bf2929e68761205337b7c031726
$ git apply ../../../tools/lms/0001-Patch-to-support-wolfBoot-LMS-build.patch
```

Nothing more is needed, as wolfBoot will automatically produce the required
hash-sigs build artifacts.

Note: the hash-sigs project only builds static libraries:
- hss_verify.a: a single-threaded verify-only static lib.
- hss_lib.a: a single-threaded static lib.
- hss_lib_thread.a: a multi-threaded static lib.

The keytools utility links against `hss_lib.a`, as it needs full
keygen, signing, and verifying functionality. However wolfBoot
links directly with the subset of objects in the `hss_verify.a`
build rule, as it only requires verify functionality.


### ext_XMSS Support

The external XMSS/XMSS^MT support in wolfCrypt requires a patched version of the
xmss-reference library ( https://github.com/XMSS/xmss-reference.git ).
Use the following procedure to prepare xmss-reference for building with
wolfBoot:

```
$ cd lib
$ git clone https://github.com/XMSS/xmss-reference.git xmss
$ ls
CMakeLists.txt wolfPKCS11 wolfTPM wolfssl xmss
$ cd xmss
$ git checkout 171ccbd26f098542a67eb5d2b128281c80bd71a6
$ git apply ../../tools/xmss/0001-Patch-to-support-wolfSSL-xmss-reference-integration.patch
```

The patch creates an addendum readme, `patch_readme.md`, with further comments.

Nothing more is needed beyond the patch step, as wolfBoot will handle building
the xmss build artifacts it requires.
2 changes: 1 addition & 1 deletion docs/STM32-TZ.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ OPTION BYTES BANK: 0
nRST_STOP : 0x1 (No reset generated when entering Stop mode)
nRST_STDBY : 0x1 (No reset generated when entering Standby mode)
nRST_SHDW : 0x1 (No reset generated when entering the Shutdown mode)
IWDG_SW : 0x1 (Software independant watchdog)
IWDG_SW : 0x1 (Software independent watchdog)
IWDG_STOP : 0x1 (IWDG counter active in stop mode)
IWDG_STDBY : 0x1 (IWDG counter active in standby mode)
WWDG_SW : 0x1 (Software window watchdog)
Expand Down
6 changes: 6 additions & 0 deletions docs/Signing.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ file is in this format.
* `--rsa4096` Use rsa4096 for signing the firmware. Assume that the given KEY.DER
file is in this format.

* `--lms` Use LMS/HSS for signing the firmware. Assume that the given KEY.DER
file is in this format.

* `--xmss` Use XMSS/XMSS^MT for signing the firmware. Assume that the given KEY.DER
file is in this format.

* `--no-sign` Disable secure boot signature verification. No signature
verification is performed in the bootloader, and the KEY.DER argument should
not be supplied.
Expand Down
6 changes: 3 additions & 3 deletions docs/Targets.md
Original file line number Diff line number Diff line change
Expand Up @@ -1766,7 +1766,7 @@ O.K.

Reset or power cycle board.

Once wolfBoot has performaed validation of the partition and booted the D15 Green LED on P3_13 will illuminate.
Once wolfBoot has performed validation of the partition and booted the D15 Green LED on P3_13 will illuminate.

### MCX A: Testing firmware update

Expand Down Expand Up @@ -1935,10 +1935,10 @@ Flash Allocation:
Detailed steps can be found at [Readme.md](../IDE/Renesas/e2studio/RA6M4/Readme.md).

## Renesas RZN2L
This example demonstrates simple secure firmware boot from extarnal flash by wolfBoot.
This example demonstrates simple secure firmware boot from external flash by wolfBoot.
A sample application v1 is securely loaded into internal RAM if there is not higher version in update region. A sample application v2 will be loaded when it is in update region.Both versions behave the same except blinking LED Red(v1) or Yellow(v2). They are compiled by e2Studio and running on the target board.

The exmaple uses SPI boot mode with external flash on the evaluation board. On this boot mode, the loader program, which is wolfBoot, is copied to the internal RAM(B-TCM). wolfBoot copies the application program from external flash memory to RAM(System RAM). As final step of wolfBoot the entry point of the copied applicatin program is called if its integrity and authenticity are OK.
The example uses SPI boot mode with external flash on the evaluation board. On this boot mode, the loader program, which is wolfBoot, is copied to the internal RAM(B-TCM). wolfBoot copies the application program from external flash memory to RAM(System RAM). As final step of wolfBoot the entry point of the copied application program is called if its integrity and authenticity are OK.

![Operation Overview](../IDE/Renesas/e2studio/RZN2L/doc/image1.png)

Expand Down
73 changes: 66 additions & 7 deletions options.mk
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ ifneq ($(findstring RSA4096,$(SIGN)),)
endif
endif

ifeq ($(SIGN),LMS)
ifneq (,$(filter $(SIGN), LMS ext_LMS))
# For LMS the signature size is a function of the LMS parameters.
# All five of these parms must be set in the LMS .config file:
# LMS_LEVELS, LMS_HEIGHT, LMS_WINTERNITZ, IMAGE_SIGNATURE_SIZE,
Expand All @@ -348,7 +348,33 @@ ifeq ($(SIGN),LMS)
ifndef IMAGE_HEADER_SIZE
$(error IMAGE_HEADER_SIZE not set)
endif
endif

ifeq ($(SIGN),LMS)
KEYGEN_OPTIONS+=--lms
SIGN_OPTIONS+=--lms
WOLFCRYPT_OBJS+= \
./lib/wolfssl/wolfcrypt/src/wc_lms.o \
./lib/wolfssl/wolfcrypt/src/wc_lms_impl.o \
./lib/wolfssl/wolfcrypt/src/memory.o \
./lib/wolfssl/wolfcrypt/src/wc_port.o \
./lib/wolfssl/wolfcrypt/src/hash.o
CFLAGS+=-D"WOLFBOOT_SIGN_LMS" -D"WOLFSSL_HAVE_LMS" \
-D"WOLFSSL_WC_LMS" -D"WOLFSSL_WC_LMS_SMALL" \
-D"WOLFSSL_LMS_MAX_LEVELS=$(LMS_LEVELS)" \
-D"WOLFSSL_LMS_MAX_HEIGHT=$(LMS_HEIGHT)" \
-D"LMS_LEVELS=$(LMS_LEVELS)" -D"LMS_HEIGHT=$(LMS_HEIGHT)" \
-D"LMS_WINTERNITZ=$(LMS_WINTERNITZ)" \
-D"IMAGE_SIGNATURE_SIZE"=$(IMAGE_SIGNATURE_SIZE) \
-D"WOLFSSL_LMS_VERIFY_ONLY"
ifeq ($(WOLFBOOT_SMALL_STACK),1)
$(error WOLFBOOT_SMALL_STACK with LMS not supported)
else
STACK_USAGE=1024
endif
endif

ifeq ($(SIGN),ext_LMS)
LMSDIR = lib/hash-sigs
KEYGEN_OPTIONS+=--lms
SIGN_OPTIONS+=--lms
Expand Down Expand Up @@ -377,11 +403,11 @@ ifeq ($(SIGN),LMS)
ifeq ($(WOLFBOOT_SMALL_STACK),1)
$(error WOLFBOOT_SMALL_STACK with LMS not supported)
else
STACK_USAGE=18064
STACK_USAGE=1024
endif
endif

ifeq ($(SIGN),XMSS)
ifneq (,$(filter $(SIGN), XMSS ext_XMSS))
ifndef XMSS_PARAMS
$(error XMSS_PARAMS not set)
endif
Expand All @@ -393,7 +419,32 @@ ifeq ($(SIGN),XMSS)
ifndef IMAGE_HEADER_SIZE
$(error IMAGE_HEADER_SIZE not set)
endif
endif

ifeq ($(SIGN),XMSS)
# Use wc_xmss implementation.
KEYGEN_OPTIONS+=--xmss
SIGN_OPTIONS+=--xmss
WOLFCRYPT_OBJS+= \
./lib/wolfssl/wolfcrypt/src/wc_xmss.o \
./lib/wolfssl/wolfcrypt/src/wc_xmss_impl.o \
./lib/wolfssl/wolfcrypt/src/memory.o \
./lib/wolfssl/wolfcrypt/src/wc_port.o \
./lib/wolfssl/wolfcrypt/src/hash.o
CFLAGS+=-D"WOLFBOOT_SIGN_XMSS" -D"WOLFSSL_HAVE_XMSS" \
-D"WOLFSSL_WC_XMSS" -D"WOLFSSL_WC_XMSS_SMALL" \
-DWOLFBOOT_XMSS_PARAMS=\"$(XMSS_PARAMS)\" \
-D"IMAGE_SIGNATURE_SIZE"=$(IMAGE_SIGNATURE_SIZE) \
-D"WOLFSSL_XMSS_VERIFY_ONLY" -D"WOLFSSL_XMSS_MAX_HEIGHT=32"
ifeq ($(WOLFBOOT_SMALL_STACK),1)
$(error WOLFBOOT_SMALL_STACK with XMSS not supported)
else
STACK_USAGE=2688
endif
endif

ifeq ($(SIGN),ext_XMSS)
# Use ext_xmss implementation.
XMSSDIR = lib/xmss
KEYGEN_OPTIONS+=--xmss
SIGN_OPTIONS+=--xmss
Expand All @@ -411,19 +462,19 @@ ifeq ($(SIGN),XMSS)
./lib/wolfssl/wolfcrypt/src/wc_port.o \
./lib/wolfssl/wolfcrypt/src/hash.o
CFLAGS+=-D"WOLFBOOT_SIGN_XMSS" -D"WOLFSSL_HAVE_XMSS" -D"HAVE_LIBXMSS" \
-DXMSS_PARAMS=\"$(XMSS_PARAMS)\" -I$(XMSSDIR) \
-DWOLFBOOT_XMSS_PARAMS=\"$(XMSS_PARAMS)\" -I$(XMSSDIR) \
-D"IMAGE_SIGNATURE_SIZE"=$(IMAGE_SIGNATURE_SIZE) \
-D"WOLFSSL_XMSS_VERIFY_ONLY" -D"XMSS_VERIFY_ONLY"
ifeq ($(WOLFBOOT_SMALL_STACK),1)
$(error WOLFBOOT_SMALL_STACK with XMSS not supported)
else
STACK_USAGE=18064
STACK_USAGE=2712
endif
endif

# Only needed if using 3rd party integration. This can be
# removed when wc_lms and wc_xmss become default in wolfboot.
ifneq (,$(filter $(SIGN), LMS XMSS))
# removed if ext_lms and ext_xmss are deprecated.
ifneq (,$(filter $(SIGN), ext_LMS ext_XMSS))
CFLAGS +=-DWOLFSSL_EXPERIMENTAL_SETTINGS
endif

Expand Down Expand Up @@ -748,3 +799,11 @@ endif
ifeq ($(SIGN_ALG),)
SIGN_ALG=$(SIGN)
endif

ifeq ($(SIGN_ALG),ext_XMSS)
SIGN_ALG=XMSS
endif

ifeq ($(SIGN_ALG),ext_LMS)
SIGN_ALG=LMS
endif
12 changes: 7 additions & 5 deletions src/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,8 @@ static void wolfBoot_verify_signature(uint8_t key_slot,
#include <wolfssl/wolfcrypt/lms.h>
#ifdef HAVE_LIBLMS
#include <wolfssl/wolfcrypt/ext_lms.h>
#else
#include <wolfssl/wolfcrypt/wc_lms.h>
#endif

static void wolfBoot_verify_signature(uint8_t key_slot,
Expand Down Expand Up @@ -386,6 +388,8 @@ static void wolfBoot_verify_signature(uint8_t key_slot,
#include <wolfssl/wolfcrypt/xmss.h>
#ifdef HAVE_LIBXMSS
#include <wolfssl/wolfcrypt/ext_xmss.h>
#else
#include <wolfssl/wolfcrypt/wc_xmss.h>
#endif

static void wolfBoot_verify_signature(uint8_t key_slot,
Expand All @@ -410,18 +414,16 @@ static void wolfBoot_verify_signature(uint8_t key_slot,
return;
}

wolfBoot_printf("info: using XMSS parameters: %s\n", XMSS_PARAMS);

/* Set the XMSS parameters. */
ret = wc_XmssKey_SetParamStr(&xmss, XMSS_PARAMS);
ret = wc_XmssKey_SetParamStr(&xmss, WOLFBOOT_XMSS_PARAMS);
if (ret != 0) {
/* Something is wrong with the pub key or XMSS parameters. */
wolfBoot_printf("error: wc_XmssKey_SetParamStr(%s)" \
" returned %d\n", XMSS_PARAMS, ret);
" returned %d\n", WOLFBOOT_XMSS_PARAMS, ret);
return;
}

wolfBoot_printf("info: using XMSS parameters: %s\n", XMSS_PARAMS);
wolfBoot_printf("info: using XMSS parameters: %s\n", WOLFBOOT_XMSS_PARAMS);

/* Set the public key. */
ret = wc_XmssKey_ImportPubRaw(&xmss, pubkey, KEYSTORE_PUBKEY_SIZE);
Expand Down