Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions .github/workflows/test-wolfhsm-simulator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ jobs:
file: "config/examples/sim-wolfHSM.config"
- name: "wolfHSM ML-DSA"
file: "config/examples/sim-wolfHSM-mldsa.config"
- name: "wolfHSM cert chain verify"
file: "config/examples/sim-wolfHSM-certchain.config"
fail-fast: false

runs-on: ubuntu-latest
Expand Down Expand Up @@ -54,8 +56,7 @@ jobs:
with:
repository: wolfssl/wolfHSM-examples
# Make sure to update this when the wolfHSM submodule is updated!
#ref: wolfHSM-v1.1.0
ref: 3e03bd4d4a8439ed4a8a9577823c89e4c37eb9be
ref: wolfHSM-examples-v1.2.0
path: wolfHSM-examples

- name: Build example POSIX TCP server
Expand All @@ -65,7 +66,13 @@ jobs:
- name: Run POSIX TCP server
run: |
cd wolfHSM-examples/posix/tcp/wh_server_tcp
./Build/wh_server_tcp.elf --client 12 --id 255 --key ../../../../wolfboot_signing_private_key_pub.der &
if [ "${{ matrix.config.name }}" = "wolfHSM cert chain verify" ]; then
tmpfile=$(mktemp)
echo "obj 1 0xFFFF 0x0000 \"cert CA\" ../../../../test-dummy-ca/root-cert.der" >> $tmpfile
./Build/wh_server_tcp.elf --nvminit $tmpfile &
else
./Build/wh_server_tcp.elf --client 12 --id 255 --key ../../../../wolfboot_signing_private_key_pub.der --cert ../../../../wolfboot_signing_cert_chain.der &
fi
TCP_SERVER_PID=$!
echo "TCP_SERVER_PID=$TCP_SERVER_PID" >> $GITHUB_ENV

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ include/target.h
.wolfboot-partition-size
.bootloader-partition-size
MPLabX/wolfBoot-SAME51.X/.generated_files/
test-dummy-ca/**

# Test tools
tools/check_config/check_config
Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ $(PRIVATE_KEY):
$(Q)(test $(SIGN) = NONE) || ($(SIGN_ENV) "$(KEYGEN_TOOL)" $(KEYGEN_OPTIONS) -g $(PRIVATE_KEY)) || true
$(Q)(test $(SIGN) = NONE) && (echo "// SIGN=NONE" > src/keystore.c) || true
$(Q)(test "$(FLASH_OTP_KEYSTORE)" = "1") && (make -C tools/keytools/otp) || true
$(Q)(test $(SIGN) = NONE) || (test "$(CERT_CHAIN_VERIFY)" = "") || (test "$(CERT_CHAIN_GEN)" = "") || (tools/scripts/sim-gen-dummy-chain.sh --algo $(CERT_CHAIN_GEN_ALGO) --leaf $(PRIVATE_KEY))

$(SECONDARY_PRIVATE_KEY): $(PRIVATE_KEY) keystore.der
$(Q)$(MAKE) keytools_check
Expand Down Expand Up @@ -390,6 +391,7 @@ utilsclean: clean

keysclean: clean
$(Q)rm -f *.pem *.der tags ./src/*_pub_key.c ./src/keystore.c include/target.h
$(Q)(test "$(CERT_CHAIN_GEN)" = "") || rm -rf test-dummy-ca || true

distclean: clean keysclean utilsclean
$(Q)rm -f *.bin *.elf
Expand Down
39 changes: 39 additions & 0 deletions config/examples/sim-wolfHSM-certchain.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
ARCH=sim
TARGET=sim
SIGN?=ECC256
HASH?=SHA256
WOLFBOOT_SMALL_STACK?=0
SPI_FLASH=0
DEBUG=1

# Cert chain options
CERT_CHAIN_VERIFY=1
CERT_CHAIN_GEN=1

# Ensure header is large enough to hold the cert chain (check sign tool output)
# for actual length
IMAGE_HEADER_SIZE=2048

# If SIGN=RSA4096, use the below options
#WOLFBOOT_HUGE_STACK=1
#IMAGE_HEADER_SIZE=4096

# wolfHSM options
WOLFHSM_CLIENT=1

# sizes should be multiple of system page size
#WOLFBOOT_PARTITION_SIZE=0x40000
WOLFBOOT_PARTITION_SIZE=0x100000
WOLFBOOT_SECTOR_SIZE=0x1000
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x80000
# if on external flash, it should be multiple of system page size
#WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x100000
#WOLFBOOT_PARTITION_SWAP_ADDRESS=0x180000
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x180000
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x280000

# required for keytools
WOLFBOOT_FIXED_PARTITIONS=1

# For debugging XMALLOC/XFREE
#CFLAGS_EXTRA+=-DWOLFBOOT_DEBUG_MALLOC
10 changes: 9 additions & 1 deletion docs/Signing.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ If none of the following is used, '--sha256' is assumed by default.

* `--sha3` Use sha3-384 for digest calculation on binary images and public keys.

#### Certificate Chain Options

wolfBoot also supports verifying firmware images using certificate chains instead of raw public keys. In this mode of operation, a certificate chain is included in the image manifest header, and the image is signed with the private key corresponding to the leaf certificate identity (signer cert). On boot, wolfBoot verifies the trust of the certificate chain (and therefore the signer cert) against a trusted root CA stored in the wolfHSM server, and if the chain is trusted, verifies the authenticity of the firmware image using the public key from the image signer certificate.

To generate an image for use with this mode, pass the `--cert-chain CERT_CHAIN.der` option to the sign tool, where `CERT_CHAIN.der` is a der encoded certificate chain containing one or more certificates in SSL order (leaf/signer cert last). Note that the sign tool still expects a signing private key to be provided as described above, and assumes that the public key of the signer cert in the chain corresponds to the signing private key.

Certificate chain verification of images is currently limited to use in conjunction with wolfHSM. See [wolfHSM.md](wolfHSM.md) for more details.

#### Target partition id (Multiple partition images, "self-update" feature)

If none of the following is used, "--id=1" is assumed by default. On systems
Expand Down Expand Up @@ -257,7 +265,7 @@ For a real-life example, see the section below.
./tools/keytools/sign --rsa2048 --sha256 test-app/image.bin wolfboot_signing_private_key.der 1
```

Note: The last argument is the version number.
Note: The last argument is the "version" number.

### Signing Firmware with External Private Key (HSM)

Expand Down
23 changes: 23 additions & 0 deletions docs/firmware_update.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,26 @@ Note: When using scattered ELF images, ensure that:

- The ELF file adheres to the ELF file specification and was generated by a toolchain supporting the target architecture
- All section addresses are within valid executable memory regions and **do not overlap with the wolfBoot image, nor the BOOT, UPDATE and SWAP partitions**.

## Certificate Verification

wolfBoot supports authenticating images using certificate chains instead of raw public keys. in this mode of operation, a certificate chain is included in the image manifest header, and the image is signed with the private key corresponding to the leaf certificate identity (signer cert). On boot, wolfBoot verifies the trust of the certificate chain (and therefore the signer cert) against a trusted root CA stored in the wolfHSM server, and if the chain is trusted, verifies the authenticity of the firmware image using the public key from the image signer certificate.

To use this feature:

1. Enable the feature in your wolfBoot configuration by defining `WOLFBOOT_CERT_CHAIN_VERIFY`
2. When signing firmware, include the certificate chain using the `--cert-chain` option:

```sh
./tools/keytools/sign --rsa2048 --sha256 --cert-chain cert_chain.der test-app/image.bin private_key.der 1
```

When verifying firmware, wolfBoot will:

1. Extract the certificate chain from the firmware header
2. Verify the chain using the pre-provisioned root certificate
3. Use the public key from the leaf certificate to verify the firmware signature

This feature is particularly useful in scenarios where you want to rotate signing keys without updating the bootloader, as you can simply resign the image with a new key, create a new certificate chain, then update the certificate chain in the firmware header.

Note: Currently, support for certificate verification is limited to use in conjuction with wolfHSM. Fore more information see [wolfHSM.md](wolfHSM.md).
28 changes: 28 additions & 0 deletions docs/wolfHSM.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,34 @@ wolfBoot supports using wolfHSM for the following algorithms:

Encrypted images with wolfHSM is not yet supported in wolfBoot. Note that every HAL target may not support all of these algorithms. Consult the platform-specific wolfBoot documentation for details.

## Additional Features

wolfBoot with wolfHSM also supports the following features:

### Certificate Verification

wolfBoot with wolfHSM supports certificate chain verification for firmware images. In this mode, instead of using raw public keys for signature verification, wolfBoot verifies firmware images using wolfHSM with a public key embedded in a certificate chain that is included in the image manifest header.

The certificate verification process with wolfHSM works as follows:

1. A root CA is created serving as the root of trust for the entire PKI system
2. A signing keypair and corresponding identity certificate is created for signing firmware images
3. The firmware image is signed with the signing private key
4. A certificate chain is created consisting of the signing identity certificate and an optional number of intermediate certificates, where trust is chained back to the root CA.
5. During the signing process, the image is signed with the signer private key and the certificate chain is embedded in the firmware image header.
6. During boot, wolfBoot extracts the certificate chain from the firmware header
7. wolfBoot uses the wolfHSM server to verify the certificate chain against a pre-provisioned root CA certificate stored on the HSM and caches the public key of the leaf certificate if the chain verifies as trusted
8. If the chain is trusted, wolfBoot uses the cached public key from the leaf certificate to verify the firmware signature on the wolfHSM server

To use certificate verification with wolfHSM:

1. Enable `WOLFBOOT_CERT_CHAIN_VERIFY` in your wolfBoot configuration
2. Ensure the wolfHSM server is configured with certificate manager support (`WOLFHSM_CFG_CERTIFICATE_MANAGER`)
3. Pre-provision the root CA certificate on the wolfHSM server at the NVM ID specified by the HAL `hsmClientNvmIdCertRootCA`
4. Sign firmware images with the `--cert-chain` option, providing a DER-encoded certificate chain

To build the simulator using wolfHSM for certificate verification, use [config/examples/sim-wolfHSM-certchain.config](config/examples/sim-wolfHSM-certchain.config).

## Configuration Options

This section describes the configuration options available for wolfHSM client integration. Note that these options should be configured automatically by the build system for each supported platform when wolfHSM support is enabled. Consult the platform-specific documentation for details on enabling wolfHSM support.
Expand Down
3 changes: 3 additions & 0 deletions hal/sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ const int hsmClientKeyIdPubKey = 0xFF;
const int hsmClientDevIdCrypt = WH_DEV_ID;
const int hsmClientKeyIdCrypt = 0xFF;
#endif
#ifdef WOLFBOOT_CERT_CHAIN_VERIFY
const whNvmId hsmClientNvmIdCertRootCA = 1;
#endif

int hal_hsm_init_connect(void);
int hal_hsm_disconnect(void);
Expand Down
4 changes: 4 additions & 0 deletions include/hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ extern const int hsmClientKeyIdPubKey; /* KeyId for public key operations */
#ifdef EXT_ENCRYPTED
extern const int hsmClientKeyIdCrypt; /* KeyId for image (enc/dec)ryption */
#endif
#ifdef WOLFBOOT_CERT_CHAIN_VERIFY
/* NvmId for trusted root CA certificate */
extern const whNvmId hsmClientNvmIdCertRootCA;
Comment thread
bigbrett marked this conversation as resolved.
#endif

/* Implementation of functions provided by HAL */
int hal_hsm_init_connect(void);
Expand Down
1 change: 1 addition & 0 deletions include/wolfboot/wolfboot.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ extern "C" {
#define HDR_SIGNATURE 0x20
#define HDR_POLICY_SIGNATURE 0x21
#define HDR_SECONDARY_SIGNATURE 0x22
#define HDR_CERT_CHAIN 0x23
#define HDR_PADDING 0xFF

/* Auth Key types */
Expand Down
2 changes: 1 addition & 1 deletion lib/wolfHSM
Submodule wolfHSM updated 41 files
+34 −0 .github/workflows/build-and-bench.yml
+1 −1 .github/workflows/build-and-test.yml
+240 −0 benchmark/Makefile
+196 −0 benchmark/README.md
+359 −0 benchmark/bench_modules/wh_bench_mod_aes.c
+280 −0 benchmark/bench_modules/wh_bench_mod_all.h
+175 −0 benchmark/bench_modules/wh_bench_mod_cmac.c
+250 −0 benchmark/bench_modules/wh_bench_mod_curve25519.c
+555 −0 benchmark/bench_modules/wh_bench_mod_ecc.c
+92 −0 benchmark/bench_modules/wh_bench_mod_echo.c
+163 −0 benchmark/bench_modules/wh_bench_mod_hmac.c
+1,116 −0 benchmark/bench_modules/wh_bench_mod_mldsa.c
+92 −0 benchmark/bench_modules/wh_bench_mod_rng.c
+985 −0 benchmark/bench_modules/wh_bench_mod_rsa.c
+137 −0 benchmark/bench_modules/wh_bench_mod_sha2.c
+40 −0 benchmark/bench_modules/wh_bench_mod_sha3.c
+189 −0 benchmark/settings/user_settings.h
+44 −0 benchmark/settings/wolfhsm_cfg.h
+682 −0 benchmark/wh_bench.c
+51 −0 benchmark/wh_bench.h
+34 −0 benchmark/wh_bench_data.c
+60 −0 benchmark/wh_bench_data.h
+46 −0 benchmark/wh_bench_main.c
+62 −0 benchmark/wh_bench_mod.h
+421 −0 benchmark/wh_bench_ops.c
+103 −0 benchmark/wh_bench_ops.h
+33 −0 benchmark/wh_bench_utils.h
+144 −26 src/wh_client_cert.c
+9 −9 src/wh_client_cryptocb.c
+26 −0 src/wh_message_cert.c
+64 −12 src/wh_server_cert.c
+17 −11 src/wh_server_crypto.c
+133 −81 test/wh_test_cert.c
+1,003 −973 test/wh_test_cert_data.h
+23 −0 test/wh_test_check_struct_padding.c
+12 −1 tools/testcertgen/gen_test_cert_chain.sh
+129 −0 wolfhsm/wh_client.h
+8 −2 wolfhsm/wh_common.h
+30 −28 wolfhsm/wh_error.h
+25 −3 wolfhsm/wh_message_cert.h
+2 −1 wolfhsm/wh_server_cert.h
2 changes: 1 addition & 1 deletion lib/wolfssl
Submodule wolfssl updated 92 files
+3 −3 .github/workflows/async.yml
+2 −2 .github/workflows/codespell.yml
+17 −4 .github/workflows/libssh2.yml
+4 −9 .github/workflows/msys2.yml
+2 −1 .github/workflows/multi-arch.yml
+1 −1 .github/workflows/multi-compiler.yml
+1 −1 .github/workflows/no-malloc.yml
+2 −2 .github/workflows/opensslcoexist.yml
+4 −1 .github/workflows/os-check.yml
+20 −1 .wolfssl_known_macro_extras
+25 −1 IDE/ARDUINO/wolfssl-arduino.cpp
+8 −0 IDE/ARDUINO/wolfssl-arduino.sh
+10 −0 IDE/Espressif/ESP-IDF/examples/template/components/wolfssl/include/user_settings.h
+10 −0 IDE/Espressif/ESP-IDF/examples/wolfssl_benchmark/components/wolfssl/include/user_settings.h
+10 −0 IDE/Espressif/ESP-IDF/examples/wolfssl_client/components/wolfssl/include/user_settings.h
+10 −0 IDE/Espressif/ESP-IDF/examples/wolfssl_server/components/wolfssl/include/user_settings.h
+1 −0 IDE/Espressif/ESP-IDF/examples/wolfssl_test/components/wolfssl/include/user_settings.h
+73 −63 configure.ac
+45 −3 examples/asn1/asn1.c
+11,603 −0 examples/asn1/dumpasn1.cfg
+137 −0 examples/asn1/gen_oid_names.rb
+4 −0 examples/asn1/include.am
+5,572 −0 examples/asn1/oid_names.h
+4 −0 examples/configs/user_settings_arduino.h
+0 −10 fips-check.sh
+1 −0 linuxkm/include.am
+9 −2 linuxkm/linuxkm_wc_port.h
+85 −19 linuxkm/lkcapi_aes_glue.c
+2,967 −0 linuxkm/lkcapi_dh_glue.c
+104 −5 linuxkm/lkcapi_ecdh_glue.c
+65 −3 linuxkm/lkcapi_ecdsa_glue.c
+430 −220 linuxkm/lkcapi_glue.c
+423 −58 linuxkm/lkcapi_rsa_glue.c
+421 −23 linuxkm/lkcapi_sha_glue.c
+112 −1 linuxkm/module_hooks.c
+60 −19 linuxkm/x86_vector_register_glue.c
+1,249 −0 scripts/asn1_oid_sum.pl
+2 −1 scripts/include.am
+1 −0 src/crl.c
+7 −3 src/internal.c
+4 −0 src/quic.c
+18 −5 src/sniffer.c
+79 −66 src/ssl.c
+1 −1 src/ssl_certman.c
+11 −2 src/ssl_crypto.c
+0 −11 src/ssl_misc.c
+32 −19 src/tls.c
+8 −5 src/tls13.c
+2 −2 src/wolfio.c
+264 −75 tests/api.c
+3 −2 tests/api/test_aes.c
+2 −2 tests/api/test_aes.h
+2 −0 tests/api/test_dtls.c
+8 −0 tests/api/test_hash.c
+54 −5 tests/api/test_sha3.c
+71 −9 tests/quic.c
+1 −1 tests/suites.c
+7 −1 testsuite/testsuite.c
+201 −11 wolfcrypt/src/asn.c
+7 −4 wolfcrypt/src/curve25519.c
+34 −2 wolfcrypt/src/dh.c
+7 −3 wolfcrypt/src/ecc.c
+1 −1 wolfcrypt/src/evp.c
+0 −21 wolfcrypt/src/hash.c
+1 −1 wolfcrypt/src/hmac.c
+14 −1 wolfcrypt/src/hpke.c
+0 −10 wolfcrypt/src/pkcs12.c
+0 −4 wolfcrypt/src/pkcs7.c
+21 −21 wolfcrypt/src/port/Renesas/renesas_tsip_util.c
+12 −3 wolfcrypt/src/port/riscv/riscv-64-sha256.c
+25 −1 wolfcrypt/src/port/riscv/riscv-64-sha512.c
+33 −11 wolfcrypt/src/port/st/stm32.c
+46 −5 wolfcrypt/src/random.c
+1 −0 wolfcrypt/src/sha.c
+1 −0 wolfcrypt/src/sha256.c
+18 −7 wolfcrypt/src/wc_port.c
+65 −12 wolfcrypt/test/test.c
+1 −0 wolfssl.vcxproj
+5 −4 wolfssl/internal.h
+1 −0 wolfssl/test.h
+23 −410 wolfssl/wolfcrypt/asn.h
+9 −88 wolfssl/wolfcrypt/asn_public.h
+11 −1 wolfssl/wolfcrypt/dh.h
+2 −1 wolfssl/wolfcrypt/include.am
+1,899 −0 wolfssl/wolfcrypt/oid_sum.h
+0 −16 wolfssl/wolfcrypt/pkcs7.h
+40 −45 wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h
+6 −0 wolfssl/wolfcrypt/random.h
+17 −1 wolfssl/wolfcrypt/settings.h
+12 −0 wolfssl/wolfcrypt/types.h
+4 −4 wrapper/Ada/alire.toml
+3 −0 wrapper/CSharp/user_settings.h
38 changes: 38 additions & 0 deletions options.mk
Original file line number Diff line number Diff line change
Expand Up @@ -907,5 +907,43 @@ ifeq ($(WOLFHSM_CLIENT),1)
ifneq ($(WOLFHSM_CLIENT_LOCAL_KEYS),1)
KEYGEN_OPTIONS += --nolocalkeys
CFLAGS += -DWOLFBOOT_USE_WOLFHSM_PUBKEY_ID
# big enough for cert chain
Comment thread
bigbrett marked this conversation as resolved.
Outdated
CFLAGS += -DWOLFHSM_CFG_COMM_DATA_LEN=5000
endif

# Ensure wolfHSM is configured to use certificate manager if we are
# doing cert chain verification
ifneq ($(CERT_CHAIN_VERIFY),)
WOLFHSM_CLIENT_OBJS += \
$(LIBDIR)/wolfHSM/src/wh_client_cert.o \
$(LIBDIR)/wolfHSM/src/wh_message_cert.o
CFLAGS += -DWOLFHSM_CFG_CERTIFICATE_MANAGER
endif
endif

# Cert chain verification options
ifneq ($(CERT_CHAIN_VERIFY),)
CFLAGS += -DWOLFBOOT_CERT_CHAIN_VERIFY
# export the private key in DER format so it can be used with certificates
KEYGEN_OPTIONS += --der
ifneq ($(CERT_CHAIN_GEN),)
# Use dummy cert chain file if not provided (needs to be generated when keys are generated)
CERT_CHAIN_FILE = test-dummy-ca/raw_chain.der

# Set appropriate cert gen options based on sigalg
ifeq ($(SIGN),ECC256)
CERT_CHAIN_GEN_ALGO+=ecc256
endif
ifeq ($(SIGN),RSA2048)
CERT_CHAIN_GEN_ALGO+=rsa2048
endif
ifeq ($(SIGN),RSA4096)
CERT_CHAIN_GEN_ALGO+=rsa4096
endif
else
ifeq ($(CERT_CHAIN_FILE),)
$(error CERT_CHAIN_FILE must be specified when CERT_CHAIN_VERIFY is enabled and not using CERT_CHAIN_GEN)
endif
endif
SIGN_OPTIONS += --cert-chain $(CERT_CHAIN_FILE)
endif
Loading