Skip to content

Commit 79aadb5

Browse files
philljjdanielinux
authored andcommitted
XMSS wolfBoot support.
1 parent 9b12acf commit 79aadb5

File tree

14 files changed

+3399
-22
lines changed

14 files changed

+3399
-22
lines changed

config/examples/sim-xmss.config

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# XMSS/XMSS^MT/HSS signature example, based on sim.config example.
2+
#
3+
#
4+
5+
ARCH=sim
6+
TARGET=sim
7+
SIGN?=XMSS
8+
HASH?=SHA256
9+
XMSS_PARAMS='XMSS-SHA2_10_256'
10+
WOLFBOOT_SMALL_STACK=0
11+
SPI_FLASH=0
12+
DEBUG=0
13+
DELTA_UPDATES=0
14+
IMAGE_SIGNATURE_SIZE=2500
15+
IMAGE_HEADER_SIZE?=5000
16+
17+
# sizes should be multiple of system page size
18+
WOLFBOOT_PARTITION_SIZE=0x40000
19+
WOLFBOOT_SECTOR_SIZE=0x1000
20+
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x20000
21+
# if on external flash, it should be multiple of system page size
22+
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x60000
23+
WOLFBOOT_PARTITION_SWAP_ADDRESS=0xA0000
24+
25+
# required for keytools
26+
WOLFBOOT_FIXED_PARTITIONS=1

docs/PQ.md

Lines changed: 77 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
11
# Post-Quantum Signatures
22

33
wolfBoot is adding support for post-quantum signatures. At present, support
4-
for LMS/HSS signatures has been added.
4+
for LMS/HSS (https://www.rfc-editor.org/rfc/rfc8554.html), and XMSS/XMSS^MT
5+
(https://www.rfc-editor.org/rfc/rfc8391.html) has been added.
56

6-
## LMS/HSS
7-
8-
LMS/HSS is a post-quantum stateful hash-based signature scheme (HBS). It
9-
is known for having small public and private keys, but larger signatures.
10-
The signature size is tunable via the different LMS parameters.
7+
LMS/HSS and XMSS/XMSS^MT are both post-quantum stateful hash-based signature
8+
(HBS) schemes. They are known for having small public keys, relatively fast
9+
signing and verifying operations, but larger signatures. Their signature sizes
10+
however are tunable via their different parameters, which affords a space-time
11+
tradeoff.
1112

1213
Stateful HBS schemes are based on the security of their underlying hash
1314
functions and Merkle trees, which are not expected to be broken by the advent
14-
of cryptographically relevant quantum computers.
15+
of cryptographically relevant quantum computers. For this reason they have
16+
been recommended by both NIST SP 800-208, and the NSA’s CNSA 2.0 suite.
17+
18+
See these links for more info on stateful HBS support and wolfSSL/wolfCrypt:
19+
- https://www.wolfssl.com/documentation/manuals/wolfssl/appendix07.html#post-quantum-stateful-hash-based-signatures
20+
- https://github.com/wolfSSL/wolfssl-examples/tree/master/pq/stateful_hash_sig
21+
22+
23+
## LMS/HSS
24+
1525

1626
### Building with LMS Support
1727

@@ -44,7 +54,7 @@ keygen, signing, and verifying functionality. However wolfBoot
4454
links directly with the subset of objects in the `hss_verify.a`
4555
build rule, as it only requires verify functionality.
4656

47-
### Config
57+
### LMS Config
4858

4959
A new LMS sim example has been added here:
5060
```
@@ -69,17 +79,66 @@ In LMS the signature size is a function of the parameters. Use the added helper
6979
script `tools/lms/lms_siglen.sh` to calculate your signature length given your
7080
LMS parameters:
7181
```
72-
$./tools/lms/lms_siglen.sh
73-
levels: 3
74-
height: 5
75-
winternitz: 8
76-
#
77-
total_len: 3992
82+
$ ./tools/lms/lms_siglen.sh 2 5 8
83+
levels: 2
84+
height: 5
85+
winternitz: 8
86+
signature length: 2644
7887
```
7988

80-
### More Info
89+
## XMSS/XMSS^MT
8190

82-
See these links for more info on LMS and wolfSSL/wolfCrypt:
83-
- https://www.wolfssl.com/documentation/manuals/wolfssl/appendix07.html#post-quantum-stateful-hash-based-signatures
84-
- https://github.com/wolfSSL/wolfssl-examples/tree/master/pq/stateful_hash_sig
91+
### Building with XMSS Support
92+
93+
XMSS/XMSS^MT support in wolfCrypt requires a patched version of the
94+
xmss-reference library ( https://github.com/XMSS/xmss-reference.git ).
95+
Use the following procedure to prepare xmss-reference for building with
96+
wolfBoot:
97+
98+
```
99+
$ cd lib
100+
$ git clone https://github.com/XMSS/xmss-reference.git xmss
101+
$ ls
102+
CMakeLists.txt wolfPKCS11 wolfTPM wolfssl xmss
103+
$ cd xmss
104+
$ git checkout 171ccbd26f098542a67eb5d2b128281c80bd71a6
105+
$ git apply ../../../tools/xmss/0001-Patch-to-support-wolfSSL-xmss-reference-integration.patch
106+
```
85107

108+
The patch creates an addendum readme, `patch_readme.md`, with further comments.
109+
110+
Nothing more is needed beyond the patch step, as wolfBoot will handle building
111+
the xmss build artifacts it requires.
112+
113+
### XMSS Config
114+
A new XMSS sim example has been added here:
115+
```
116+
config/examples/sim-xmss.config
117+
```
118+
119+
The `XMSS_PARAMS`, `IMAGE_SIGNATURE_SIZE`, and (optionally) `IMAGE_HEADER_SIZE`
120+
must be set:
121+
122+
```
123+
SIGN?=XMSS
124+
...
125+
XMSS_PARAMS='XMSS-SHA2_10_256'
126+
...
127+
IMAGE_SIGNATURE_SIZE=2500
128+
IMAGE_HEADER_SIZE?=5000
129+
```
130+
131+
The `XMSS_PARAMS` may be any SHA256 parameter set string from Tables 10 and 11
132+
from NIST SP 800-208. Use the helper script `tools/xmss/xmss_siglen.sh` to
133+
calculate your signature length given your XMSS/XMSS^MT parameter string, e.g.:
134+
```
135+
$ ./tools/xmss/xmss_siglen.sh XMSS-SHA2_10_256
136+
parameter set: XMSS-SHA2_10_256
137+
signature length: 2500
138+
```
139+
140+
```
141+
$ ./tools/xmss/xmss_siglen.sh XMSSMT-SHA2_20/2_256
142+
parameter set: XMSSMT-SHA2_20/2_256
143+
signature length: 4963
144+
```

include/loader.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ extern "C" {
6767
* options.mk from the .config file. */
6868
extern const unsigned char lms_pub_key[];
6969
extern unsigned int lms_pub_key_len;
70+
#elif defined(WOLFBOOT_SIGN_XMSS)
71+
extern const unsigned char xmss_pub_key[];
72+
extern unsigned int xmss_pub_key_len;
7073
#elif !defined(WOLFBOOT_NO_SIGN)
7174
# error "No public key available for given signing algorithm."
7275
#endif /* Algorithm selection */

include/wolfboot/wolfboot.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ extern "C" {
8585
#define AUTH_KEY_ECC521 0x07
8686
#define AUTH_KEY_RSA3072 0x08
8787
#define AUTH_KEY_LMS 0x09
88+
#define AUTH_KEY_XMSS 0x10
8889

8990

9091

@@ -105,6 +106,7 @@ extern "C" {
105106
#define HDR_IMG_TYPE_AUTH_ECC521 (AUTH_KEY_ECC521 << 8)
106107
#define HDR_IMG_TYPE_AUTH_RSA3072 (AUTH_KEY_RSA3072 << 8)
107108
#define HDR_IMG_TYPE_AUTH_LMS (AUTH_KEY_LMS << 8)
109+
#define HDR_IMG_TYPE_AUTH_XMSS (AUTH_KEY_XMSS << 8)
108110

109111
#define HDR_IMG_TYPE_DIFF 0x00D0
110112

@@ -122,6 +124,7 @@ extern "C" {
122124
#define KEYSTORE_PUBKEY_SIZE_RSA3072 448
123125
#define KEYSTORE_PUBKEY_SIZE_RSA4096 576
124126
#define KEYSTORE_PUBKEY_SIZE_LMS 60
127+
#define KEYSTORE_PUBKEY_SIZE_XMSS 68
125128

126129
/* Mask for key permissions */
127130
#define KEY_VERIFY_ALL (0xFFFFFFFFU)
@@ -222,6 +225,11 @@ extern "C" {
222225
# ifndef WOLFBOOT_UNIVERSAL_KEYSTORE
223226
# define KEYSTORE_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_LMS
224227
# endif
228+
#elif defined(WOLFBOOT_SIGN_XMSS)
229+
# define HDR_IMG_TYPE_AUTH HDR_IMG_TYPE_AUTH_XMSS
230+
# ifndef WOLFBOOT_UNIVERSAL_KEYSTORE
231+
# define KEYSTORE_PUBKEY_SIZE KEYSTORE_PUBKEY_SIZE_XMSS
232+
# endif
225233
#else
226234
# error "No valid authentication mechanism selected. " \
227235
"Please select a valid SIGN= option."

options.mk

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,46 @@ ifeq ($(SIGN),LMS)
381381
endif
382382
endif
383383

384+
ifeq ($(SIGN),XMSS)
385+
ifndef XMSS_PARAMS
386+
$(error XMSS_PARAMS not set)
387+
endif
388+
389+
ifndef IMAGE_SIGNATURE_SIZE
390+
$(error IMAGE_SIGNATURE_SIZE not set)
391+
endif
392+
393+
ifndef IMAGE_HEADER_SIZE
394+
$(error IMAGE_HEADER_SIZE not set)
395+
endif
396+
397+
XMSSDIR = lib/xmss
398+
KEYGEN_OPTIONS+=--xmss
399+
SIGN_OPTIONS+=--xmss
400+
WOLFCRYPT_OBJS+= \
401+
./$(XMSSDIR)/params.o \
402+
./$(XMSSDIR)/thash.o \
403+
./$(XMSSDIR)/hash_address.o \
404+
./$(XMSSDIR)/wots.o \
405+
./$(XMSSDIR)/xmss.o \
406+
./$(XMSSDIR)/xmss_core_fast.o \
407+
./$(XMSSDIR)/xmss_commons.o \
408+
./$(XMSSDIR)/utils.o \
409+
./lib/wolfssl/wolfcrypt/src/ext_xmss.o \
410+
./lib/wolfssl/wolfcrypt/src/memory.o \
411+
./lib/wolfssl/wolfcrypt/src/wc_port.o \
412+
./lib/wolfssl/wolfcrypt/src/hash.o
413+
CFLAGS+=-D"WOLFBOOT_SIGN_XMSS" -D"WOLFSSL_HAVE_XMSS" -D"HAVE_LIBXMSS" \
414+
-DXMSS_PARAMS=\"$(XMSS_PARAMS)\" -I$(XMSSDIR) \
415+
-D"IMAGE_SIGNATURE_SIZE"=$(IMAGE_SIGNATURE_SIZE) \
416+
-D"WOLFSSL_XMSS_VERIFY_ONLY" -D"XMSS_VERIFY_ONLY"
417+
ifeq ($(WOLFBOOT_SMALL_STACK),1)
418+
$(error WOLFBOOT_SMALL_STACK with XMSS not supported)
419+
else
420+
STACK_USAGE=18064
421+
endif
422+
endif
423+
384424
ifeq ($(RAM_CODE),1)
385425
CFLAGS+= -D"RAM_CODE"
386426
endif

src/image.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,71 @@ static void wolfBoot_verify_signature(uint8_t key_slot,
382382
}
383383
#endif /* WOLFBOOT_SIGN_LMS */
384384

385+
#ifdef WOLFBOOT_SIGN_XMSS
386+
#include <wolfssl/wolfcrypt/xmss.h>
387+
#ifdef HAVE_LIBXMSS
388+
#include <wolfssl/wolfcrypt/ext_xmss.h>
389+
#endif
390+
391+
static void wolfBoot_verify_signature(uint8_t key_slot,
392+
struct wolfBoot_image *img, uint8_t *sig)
393+
{
394+
int ret = 0;
395+
XmssKey xmss;
396+
word32 pub_len = 0;
397+
uint8_t * pubkey = NULL;
398+
399+
wolfBoot_printf("info: XMSS wolfBoot_verify_signature\n");
400+
401+
pubkey = keystore_get_buffer(key_slot);
402+
if (pubkey == NULL) {
403+
wolfBoot_printf("error: Xmss pubkey not found\n");
404+
return;
405+
}
406+
407+
ret = wc_XmssKey_Init(&xmss, NULL, INVALID_DEVID);
408+
if (ret != 0) {
409+
wolfBoot_printf("error: wc_XmssKey_Init returned %d\n", ret);
410+
return;
411+
}
412+
413+
wolfBoot_printf("info: using XMSS parameters: %s\n", XMSS_PARAMS);
414+
415+
/* Set the XMSS parameters. */
416+
ret = wc_XmssKey_SetParamStr(&xmss, XMSS_PARAMS);
417+
if (ret != 0) {
418+
/* Something is wrong with the pub key or XMSS parameters. */
419+
wolfBoot_printf("error: wc_XmssKey_SetParamStr(%s)" \
420+
" returned %d\n", XMSS_PARAMS, ret);
421+
return;
422+
}
423+
424+
wolfBoot_printf("info: using XMSS parameters: %s\n", XMSS_PARAMS);
425+
426+
/* Set the public key. */
427+
ret = wc_XmssKey_ImportPubRaw(&xmss, pubkey, KEYSTORE_PUBKEY_SIZE);
428+
if (ret != 0) {
429+
/* Something is wrong with the pub key or LMS parameters. */
430+
wolfBoot_printf("error: wc_XmssKey_ImportPubRaw" \
431+
" returned %d\n", ret);
432+
return;
433+
}
434+
435+
ret = wc_XmssKey_Verify(&xmss, sig, IMAGE_SIGNATURE_SIZE, img->sha_hash,
436+
WOLFBOOT_SHA_DIGEST_SIZE);
437+
438+
if (ret == 0) {
439+
wolfBoot_printf("info: wc_XmssKey_Verify returned OK\n");
440+
wolfBoot_image_confirm_signature_ok(img);
441+
}
442+
else {
443+
wolfBoot_printf("error: wc_XmssKey_Verify returned %d\n", ret);
444+
}
445+
446+
wc_XmssKey_Free(&xmss);
447+
}
448+
#endif /* WOLFBOOT_SIGN_XMSS */
449+
385450
#endif /* WOLFBOOT_TPM && WOLFBOOT_TPM_VERIFY */
386451

387452

tools/config.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ ifeq ($(ARCH),)
3434
LMS_LEVELS?=0
3535
LMS_HEIGHT?=0
3636
LMS_WINTERNITZ?=0
37+
XMSS_PARAMS?=XMSS-SHA2_10_256
3738
NO_MPU?=0
3839
ENCRYPT?=0
3940
ENCRYPT_WITH_CHACHA?=0
@@ -93,4 +94,5 @@ CONFIG_VARS:= ARCH TARGET SIGN HASH MCUXSDK MCUXPRESSO MCUXPRESSO_CPU MCUXPRESSO
9394
ENCRYPT_WITH_CHACHA ENCRYPT_WITH_AES128 ENCRYPT_WITH_AES256 ARMORED \
9495
LMS_LEVELS LMS_HEIGHT LMS_WINTERNITZ \
9596
WOLFBOOT_UNIVERSAL_KEYSTORE \
97+
XMSS_PARAMS \
9698
ELF

tools/keytools/Makefile

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ ifeq ($(SIGN),LMS)
2525
-D"LMS_WINTERNITZ=$(LMS_WINTERNITZ)"
2626
endif
2727

28+
ifeq ($(SIGN),XMSS)
29+
$(info xmss params: $(XMSS_PARAMS))
30+
XMSSDIR = $(WOLFBOOTDIR)/lib/xmss
31+
CFLAGS +=-DWOLFBOOT_SIGN_XMSS -DWOLFSSL_HAVE_XMSS -DHAVE_LIBXMSS -I$(XMSSDIR) \
32+
-D"IMAGE_SIGNATURE_SIZE"=$(IMAGE_SIGNATURE_SIZE) \
33+
-DXMSS_PARAMS=\"$(XMSS_PARAMS)\"
34+
endif
35+
36+
2837
# option variables
2938
DEBUG_FLAGS = -g -DDEBUG -DDEBUG_SIGNTOOL -DDEBUG_WOLFSSL -DDEBUG_WOLFSSL_VERBOSE
3039
SANITIZE_FLAGS = -fsanitize=address
@@ -75,16 +84,33 @@ OBJS_REAL=\
7584
$(WOLFDIR)/wolfcrypt/src/tfm.o \
7685
$(WOLFDIR)/wolfcrypt/src/wc_port.o \
7786
$(WOLFDIR)/wolfcrypt/src/wolfmath.o \
78-
$(WOLFDIR)/wolfcrypt/src/ext_lms.o
87+
$(WOLFDIR)/wolfcrypt/src/ext_lms.o \
88+
$(WOLFDIR)/wolfcrypt/src/ext_xmss.o
7989

8090
OBJS_REAL+=\
8191
$(WOLFBOOTDIR)/src/delta.o
8292

93+
ifeq ($(SIGN),XMSS)
94+
OBJS_REAL+=\
95+
$(XMSSDIR)/params.o \
96+
$(XMSSDIR)/thash.o \
97+
$(XMSSDIR)/hash_address.o \
98+
$(XMSSDIR)/wots.o \
99+
$(XMSSDIR)/xmss.o \
100+
$(XMSSDIR)/xmss_core_fast.o \
101+
$(XMSSDIR)/xmss_commons.o \
102+
$(XMSSDIR)/utils.o
103+
endif
104+
83105
OBJS_VIRT=$(addprefix $(OBJDIR), $(notdir $(OBJS_REAL)))
84106
vpath %.c $(WOLFDIR)/wolfcrypt/src/
85107
vpath %.c $(WOLFBOOTDIR)/src/
86108
vpath %.c ./
87109

110+
ifeq ($(SIGN),XMSS)
111+
vpath %.c $(XMSSDIR)/
112+
endif
113+
88114
.PHONY: clean all
89115

90116
all: $(WOLFBOOTDIR)/include/target.h sign keygen
@@ -114,6 +140,9 @@ $(OBJDIR)/%.o: $(WOLFBOOTDIR)/src/%.c
114140
$(OBJDIR)/%.o: $(WOLFDIR)/wolfcrypt/src/%.c
115141
$(Q)$(CC) $(CFLAGS) -c -o $@ $<
116142

143+
$(XMSSDIR)/src/%.o: $(XMSSDIR)/src/%.c
144+
$(Q)$(CC) $(CFLAGS) -c -o $@ $<
145+
117146
# build templates
118147
sign: $(OBJS_VIRT) $(LIBS) sign.o
119148
@echo "Building signing tool"

0 commit comments

Comments
 (0)