Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
32 changes: 31 additions & 1 deletion .github/workflows/test-configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,37 @@ jobs:
uses: ./.github/workflows/test-build.yml
with:
arch: host
config-file: ./config/examples/sim-wolfHSM-client.config
config-file: ./config/examples/sim-wolfHSM-client-ecc.config

sim_wolfhsm_client_mldsa_test:
uses: ./.github/workflows/test-build.yml
with:
arch: host
config-file: ./config/examples/sim-wolfHSM-client-mldsa.config

sim_wolfhsm_client_certchain_ecc_test:
uses: ./.github/workflows/test-build.yml
with:
arch: host
config-file: ./config/examples/sim-wolfHSM-client-certchain-ecc.config

sim_wolfhsm_client_certchain_rsa4096_test:
uses: ./.github/workflows/test-build.yml
with:
arch: host
config-file: ./config/examples/sim-wolfHSM-client-certchain-rsa4096.config

sim_wolfhsm_server_certchain_ecc_test:
uses: ./.github/workflows/test-build.yml
with:
arch: host
config-file: ./config/examples/sim-wolfHSM-server-certchain-ecc.config

sim_wolfhsm_server_certchain_rsa4096_test:
uses: ./.github/workflows/test-build.yml
with:
arch: host
config-file: ./config/examples/sim-wolfHSM-server-certchain-rsa4096.config

rp2350_test:
uses: ./.github/workflows/test-build-pico-sdk.yml
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-external-library-paths.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
build-tpm-tools: true

- name: "external wolfHSM"
config: "config/examples/sim-wolfHSM-client.config"
config: "config/examples/sim-wolfHSM-client-ecc.config"

- name: "Unit tests"
config: ""
Expand Down
46 changes: 34 additions & 12 deletions .github/workflows/test-wolfhsm-simulator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,36 @@ jobs:
strategy:
matrix:
config:
- name: "Standard wolfHSM"
file: "config/examples/sim-wolfHSM-client.config"
- name: "wolfHSM ML-DSA"
- name: "wolfHSM client ECC"
file: "config/examples/sim-wolfHSM-client-ecc.config"
needs_posix_server: true
posix_server_nvminit: false
needs_nvm_image: false
- name: "wolfHSM client ML-DSA"
file: "config/examples/sim-wolfHSM-client-mldsa.config"
- name: "wolfHSM cert chain verify"
file: "config/examples/sim-wolfHSM-client-certchain.config"
- name: "wolfHSM server cert chain verify"
file: "config/examples/sim-wolfHSM-server-certchain.config"
needs_posix_server: true
posix_server_nvminit: false
needs_nvm_image: false
- name: "wolfHSM client cert chain verify ECC"
file: "config/examples/sim-wolfHSM-client-certchain-ecc.config"
needs_posix_server: true
posix_server_nvminit: true
needs_nvm_image: false
- name: "wolfHSM client cert chain verify RSA4096"
file: "config/examples/sim-wolfHSM-client-certchain-rsa4096.config"
needs_posix_server: true
posix_server_nvminit: true
needs_nvm_image: false
- name: "wolfHSM server cert chain verify ECC"
file: "config/examples/sim-wolfHSM-server-certchain-ecc.config"
needs_posix_server: false
posix_server_nvminit: false
needs_nvm_image: true
- name: "wolfHSM server cert chain verify RSA4096"
file: "config/examples/sim-wolfHSM-server-certchain-rsa4096.config"
needs_posix_server: false
posix_server_nvminit: false
needs_nvm_image: true

fail-fast: false

Expand Down Expand Up @@ -98,15 +120,15 @@ jobs:
make clean && make test-sim-internal-flash-with-update

- name: Build example POSIX TCP server
if: matrix.config.name != 'wolfHSM server cert chain verify'
if: matrix.config.needs_posix_server
run: cd lib/wolfHSM/examples/posix/wh_posix_server && make WOLFSSL_DIR=../../../../wolfssl

# Start the server in the background
- name: Run POSIX TCP server
if: matrix.config.name != 'wolfHSM server cert chain verify'
if: matrix.config.needs_posix_server
run: |
cd lib/wolfHSM/examples/posix/wh_posix_server
if [ "${{ matrix.config.name }}" = "wolfHSM cert chain verify" ]; then
if [ "${{ matrix.config.posix_server_nvminit }}" = "true" ]; then
tmpfile=$(mktemp)
echo "obj 1 0xFFFF 0x0000 \"cert CA\" ../../../../../test-dummy-ca/root-cert.der" >> $tmpfile
./Build/wh_posix_server.elf --type tcp --nvminit $tmpfile &
Expand All @@ -120,7 +142,7 @@ jobs:
# For testing the wolfHSM server cert chain verify feature, we need to create an NVM image containing our root CA that
# the internal wolfHSM server can load.
- name: Create NVM image for wolfHSM server cert chain verify
if: matrix.config.name == 'wolfHSM server cert chain verify'
if: matrix.config.needs_nvm_image
run: |
make -C lib/wolfHSM/tools/whnvmtool
tmpfile=$(mktemp)
Expand All @@ -134,6 +156,6 @@ jobs:

# Kill the server if it is still running
- name: Kill POSIX TCP server
if: always() && matrix.config.name != 'wolfHSM server cert chain verify'
if: always() && matrix.config.needs_posix_server
run: |
kill $TCP_SERVER_PID || true
123 changes: 107 additions & 16 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,84 @@ ifneq ($(TARGET),library)
OBJS+=./hal/$(TARGET).o
endif

# User-provided key configuration
# - USER_PRIVATE_KEY: Path to user's private key (DER format)
# - USER_PUBLIC_KEY: Path to user's public key (DER format)
# - USER_CERT_CHAIN: Path to user's certificate chain (DER format)
# All must be provided together, or none at all

# Validate USER_PRIVATE_KEY and USER_PUBLIC_KEY are used together
ifneq ($(USER_PRIVATE_KEY),)
ifeq ($(USER_PUBLIC_KEY),)
$(error USER_PRIVATE_KEY requires USER_PUBLIC_KEY to also be set)
endif
ifeq ($(wildcard $(USER_PRIVATE_KEY)),)
$(error USER_PRIVATE_KEY file not found: $(USER_PRIVATE_KEY))
endif
endif

ifneq ($(USER_PUBLIC_KEY),)
ifeq ($(USER_PRIVATE_KEY),)
$(error USER_PUBLIC_KEY requires USER_PRIVATE_KEY to also be set)
endif
ifeq ($(wildcard $(USER_PUBLIC_KEY)),)
$(error USER_PUBLIC_KEY file not found: $(USER_PUBLIC_KEY))
endif
endif

# Validate USER_CERT_CHAIN requires USER_PRIVATE_KEY and USER_PUBLIC_KEY
ifneq ($(USER_CERT_CHAIN),)
ifeq ($(USER_PRIVATE_KEY),)
$(error USER_CERT_CHAIN requires USER_PRIVATE_KEY to also be set)
endif
ifeq ($(USER_PUBLIC_KEY),)
$(error USER_CERT_CHAIN requires USER_PUBLIC_KEY to also be set)
endif
ifeq ($(wildcard $(USER_CERT_CHAIN)),)
$(error USER_CERT_CHAIN file not found: $(USER_CERT_CHAIN))
endif
endif

# Validate USER_NVM_INIT if provided
# - USER_NVM_INIT: Path to user's NVM init file for wolfHSM NVM image generation
ifneq ($(USER_NVM_INIT),)
ifeq ($(wildcard $(USER_NVM_INIT)),)
$(error USER_NVM_INIT file not found: $(USER_NVM_INIT))
endif
endif

# Helper variable to detect if user-provided keys are being used
# This is used to skip auto-generated NVM images when users provide their own keys
ifneq ($(USER_PRIVATE_KEY),)
_USER_PROVIDED_KEYS:=1
else ifneq ($(USER_PUBLIC_KEY),)
_USER_PROVIDED_KEYS:=1
else ifneq ($(USER_CERT_CHAIN),)
_USER_PROVIDED_KEYS:=1
endif

# USER_NVM_INIT overrides default NVM_CONFIG when provided
ifneq ($(USER_NVM_INIT),)
NVM_CONFIG:=$(USER_NVM_INIT)
endif

ifeq ($(SIGN),NONE)
PRIVATE_KEY=
else
# Key selection logic:
# - Without CERT_CHAIN_GEN: Single key (wolfboot_signing_private_key.der) signs everything
# - With CERT_CHAIN_GEN: Generate cert chain, use leaf key (test-dummy-ca/leaf-prvkey.der) for signing
ifneq ($(CERT_CHAIN_GEN),)
PRIVATE_KEY=test-dummy-ca/leaf-prvkey.der
# Private Key selection logic:
# 1. User-provided private keys take precedence (USER_PRIVATE_KEY)
# 2. Otherwise, if CERT_CHAIN_VERIFY, use generated dummy cert chain leaf key
# 3. Otherwise use standard generated private key
ifneq ($(USER_PRIVATE_KEY),)
PRIVATE_KEY=$(USER_PRIVATE_KEY)
else
PRIVATE_KEY=wolfboot_signing_private_key.der
ifneq ($(CERT_CHAIN_VERIFY),)
# Auto-generate cert chain mode - use leaf key
PRIVATE_KEY?=test-dummy-ca/leaf-prvkey.der
else
# No cert chain verification - standard single key mode
PRIVATE_KEY?=wolfboot_signing_private_key.der
endif
endif
ifeq ($(FLASH_OTP_KEYSTORE),1)
OBJS+=./src/flash_otp_keystore.o
Expand Down Expand Up @@ -268,21 +336,31 @@ hal/$(TARGET).o:

keytools_check: keytools

# Generate the initial signing key
# - Always creates wolfboot_signing_private_key.der
# - If CERT_CHAIN_GEN is set, also generates cert chain with leaf key
# Generate the initial signing key (only if not using user-provided keys)
# - Creates wolfboot_signing_private_key.der when USER_PRIVATE_KEY is not set
# - If CERT_CHAIN_VERIFY is enabled and USER_CERT_CHAIN not provided, also generates cert chain with leaf key
wolfboot_signing_private_key.der:
ifeq ($(USER_PRIVATE_KEY),)
$(Q)$(MAKE) keytools_check
$(Q)(test $(SIGN) = NONE) || ($(SIGN_ENV) "$(KEYGEN_TOOL)" $(KEYGEN_OPTIONS) -g wolfboot_signing_private_key.der) || 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 wolfboot_signing_private_key.der)
$(Q)(test $(SIGN) = NONE) || (test "$(CERT_CHAIN_VERIFY)" = "") || (test "$(USER_CERT_CHAIN)" != "") || (tools/scripts/sim-gen-dummy-chain.sh --algo $(CERT_CHAIN_GEN_ALGO) --leaf wolfboot_signing_private_key.der)
else
@echo "Using user-provided private key: $(USER_PRIVATE_KEY)"
endif

# CERT_CHAIN_GEN only: Ensure leaf key exists after cert chain generation
ifneq ($(CERT_CHAIN_GEN),)
# Auto-generate cert chain mode: Ensure leaf key exists after cert chain generation
# Only applies when CERT_CHAIN_VERIFY is enabled and USER_CERT_CHAIN not provided
# Skip this when using user-provided keys
ifeq ($(USER_PRIVATE_KEY),)
ifneq ($(CERT_CHAIN_VERIFY),)
ifeq ($(USER_CERT_CHAIN),)
$(PRIVATE_KEY): wolfboot_signing_private_key.der
@test -f $(PRIVATE_KEY) || (echo "Error: $(PRIVATE_KEY) not found" && exit 1)
endif
endif
endif

$(SECONDARY_PRIVATE_KEY): $(PRIVATE_KEY) keystore.der
$(Q)$(MAKE) keytools_check
Expand Down Expand Up @@ -320,6 +398,13 @@ endif
ifeq ($(WOLFHSM_SERVER),1)
_DO_WH_NVMTOOL:=1
endif
# Disable NVM image generation if user-provided keys without explicit USER_NVM_INIT
# (providing USER_NVM_INIT allows users to supply keys and still generate a custom NVM image)
ifeq ($(_USER_PROVIDED_KEYS),1)
ifeq ($(USER_NVM_INIT),)
_DO_WH_NVMTOOL:=
endif
endif
ifeq ($(_DO_WH_NVMTOOL),1)
whnvmtool:
@echo "Building wolfHSM NVM tool"
Expand Down Expand Up @@ -363,9 +448,7 @@ internal_flash.dd: $(BINASSEMBLE) wolfboot.bin $(BOOT_IMG) $(PRIVATE_KEY) test-a
$(Q)dd if=/dev/zero bs=1 count=$$(($(WOLFBOOT_SECTOR_SIZE))) > /tmp/swap
make assemble_internal_flash.dd

ifeq ($(WOLFHSM_CLIENT),1)
factory.bin: $(BINASSEMBLE) wolfboot.bin $(BOOT_IMG) $(PRIVATE_KEY) test-app/image_v1_signed.bin nvm-image
else ifeq ($(WOLFHSM_SERVER),1)
ifeq ($(_DO_WH_NVMTOOL),1)
factory.bin: $(BINASSEMBLE) wolfboot.bin $(BOOT_IMG) $(PRIVATE_KEY) test-app/image_v1_signed.bin nvm-image
else
factory.bin: $(BINASSEMBLE) wolfboot.bin $(BOOT_IMG) $(PRIVATE_KEY) test-app/image_v1_signed.bin
Expand Down Expand Up @@ -435,7 +518,15 @@ srec: wolfboot.srec
@echo "\t[ELF2SREC] $@"
@$(OBJCOPY) -O srec $^ $@

# Keystore generation: use user-provided public key if available
ifneq ($(USER_PUBLIC_KEY),)
src/keystore.c: $(USER_PUBLIC_KEY)
@echo "Generating keystore from user-provided public key: $(USER_PUBLIC_KEY)"
$(Q)$(MAKE) keytools_check
$(Q)$(SIGN_ENV) "$(KEYGEN_TOOL)" $(KEYGEN_OPTIONS) --force -i $(USER_PUBLIC_KEY)
else
src/keystore.c: $(PRIVATE_KEY)
endif

flash_keystore: src/flash_otp_keystore.o

Expand Down Expand Up @@ -479,7 +570,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
$(Q)(test "$(CERT_CHAIN_VERIFY)" = "" || test "$(USER_CERT_CHAIN)" != "") || rm -rf test-dummy-ca || true

distclean: clean keysclean utilsclean
$(Q)rm -f *.bin *.elf
Expand Down
13 changes: 11 additions & 2 deletions arch.mk
Original file line number Diff line number Diff line change
Expand Up @@ -1160,6 +1160,14 @@ ifeq ($(ARCH),sim)
$(WOLFBOOT_LIB_WOLFHSM)/src/wh_transport_mem.o

endif
# wolfHSM NVM image generation support for simulator
# User must provide NVM_CONFIG for their specific setup
ifneq ($(filter 1,$(WOLFHSM_CLIENT) $(WOLFHSM_SERVER)),)
WH_NVM_BIN ?= whNvmImage.bin
WH_NVM_HEX ?= whNvmImage.hex
WH_NVM_PART_SIZE ?= 16384 # must match partition size in hal/sim.c
WH_NVM_BASE_ADDRESS ?= 0x0
endif
endif

# Infineon AURIX Tricore
Expand Down Expand Up @@ -1201,10 +1209,11 @@ ifeq ($(ARCH), AURIX_TC3)
WH_NVM_BASE_ADDRESS ?= 0xAFC00000

# Select config file based on certificate chain verification
# Use ?= to allow user override via command line (e.g., for offline cert chain)
ifneq ($(CERT_CHAIN_VERIFY),)
NVM_CONFIG = tools/scripts/tc3xx/wolfBoot-wolfHSM-dummy-certchain.nvminit
NVM_CONFIG ?= tools/scripts/tc3xx/wolfBoot-wolfHSM-dummy-certchain.nvminit
else
NVM_CONFIG = tools/scripts/tc3xx/wolfBoot-wolfHSM-keys.nvminit
NVM_CONFIG ?= tools/scripts/tc3xx/wolfBoot-wolfHSM-keys.nvminit
endif
endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,11 @@ ELF_FLASH_SCATTER=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


ARCH_FLASH_OFFSET=0x800A0000
WOLFBOOT_SECTOR_SIZE=0x4000

Expand Down
Loading