Skip to content

Building

github-actions[bot] edited this page Sep 23, 2026 · 3 revisions

Building

The supported Secure build tuple is Armv8-M on STM32H563. The root Makefile includes mk/target-stm32h563.mk, mk/arch-armv8m.mk, and mk/common.mk (target facts, architecture facts, and the shared build in that order) and cross-compiles a freestanding Cortex-M33 image.

Prerequisites

  • GNU Make
  • Python 3
  • Git and initialized submodules
  • GNU Arm Embedded tools with the arm-none-eabi- prefix
  • a native C compiler for host tests

Some submodule URLs use GitHub SSH. Configure GitHub SSH access or an equivalent Git URL rewrite before initializing them.

git submodule update --init --recursive

The Zephyr guest build additionally uses a Python virtual environment, CMake, Ninja, and network access to create its v4.2.0 workspace. The FreeRTOS guest build uses the Arm cross-toolchain and network access; its default source reference is the mutable main branch, not a pinned workspace.

Secure image

make

The default uses the native crypto engine. Keep separate output directories when comparing or retaining both engine builds:

make secure-image WT_ENGINE=native BUILD_DIR=build-native
make secure-image WT_ENGINE=hsm BUILD_DIR=build-hsm

WT_ENGINE_HSM=0 and WT_ENGINE_HSM=1 remain as legacy aliases for native and hsm, respectively. WT_ENGINE is the public selector for new builds. See Crypto Engines for the behavior, key model, and measured footprint of each choice.

The default target builds:

Output Purpose
build/wolftrust.elf Secure image with symbols
build/wolftrust.bin Flat Secure binary
build/secure_cmse_implib.o CMSE import library for Non-secure linking
build/manifest/wolftrust_manifest_generated.c Generated manifest source
build/manifest/wolftrust_manifest_generated.h Generated partition and service constants
build/nsc-syms.txt Symbol list used to enforce the five-veneer gateway

Use another output directory or tool prefix as Make variables:

make BUILD_DIR=build-h5 TOOLPREFIX=/opt/gcc-arm/bin/arm-none-eabi-

The build records the variables enumerated by the secure_build_mode.stamp recipe and regenerates when one of those values changes. The current stamp omits TOOLPREFIX, WT_GUEST_FLASH_WRP, the VNET tuning variables (WT_VNET_POOL_SLOTS, WT_VNET_FRAME_MAX, WT_VNET_RX_QUEUE_DEPTH, WT_VNET_RX_IRQ, WT_VNET_TIMEOUT_TICKS, and WT_VNET_UNKNOWN_UCAST_FLOOD), and the test-only WT_VAULT_FOREIGN_PROBE, WT_VAULT_PROBE_SECURED, and WT_CONF_DIAG_TRAP variables. Use a fresh BUILD_DIR or clean the active output directory before changing an option that the recipe does not record.

Manifest generation

The default input is port/stm32h563/manifest.json. CONFIG_VNET=y selects manifest-vnet.json, and WT_CONFORMANCE=1 selects manifest-conformance.json.

make CONFIG_VNET=y
make WT_CONFORMANCE=1

The generator is constrained to FF-M framework version 0x0100, feature mask 0x1 (connection-based IPC), and 32-bit addresses. Unsupported capabilities or an invalid resource layout stop the build.

Build controls

Examples:

make WT_TIMESLICE_MS=5
make WT_MAX_GUESTS=1
make BUILD_DIR=build-wrp WT_GUEST_FLASH_WRP=1
make CONFIG_VNET=y

Changing guest count, addresses, or sizes also requires matching manifest, guest linker, emulator-load, flash, and measurement-record settings. See Macros for the supported values and constraints.

Reference guests

Set up the pinned Zephyr workspace, then build the Zephyr PSA guest and the FreeRTOS PSA guest together:

make -C tests/firmware/zephyr-stm32h5 clone
make -C tests/firmware/zephyr-stm32h5 \
    build-guest0-psa build-freertos-guest1

WT_ENGINE must match the Secure image and every guest image. The guest build scripts default to native and pass the same selector through the Secure and guest builds:

WT_ENGINE=native make -C tests/firmware/zephyr-stm32h5 \
    build-guest0-psa build-freertos-guest1
WT_ENGINE=hsm make -C tests/firmware/zephyr-stm32h5 \
    build-guest0-psa build-freertos-guest1

For a direct Zephyr configuration rather than the wrapper script:

  • native uses CONFIG_WOLFTRUST_NATIVE_CLIENT=y and CONFIG_WOLFTRUST_WOLFHSM_CLIENT=n; and
  • hsm uses CONFIG_WOLFTRUST_WOLFHSM_CLIENT=y and leaves CONFIG_WOLFTRUST_NATIVE_CLIENT disabled.

The native Zephyr module links guest wolfCrypt plus src/client/crypto_native_client.c. The wolfHSM module instead links the wolfHSM client, crypto-callback glue, and src/client/hsm_psa_transport.c. The FreeRTOS build_freertos_guest.sh script makes the same source and preprocessor choice from its WT_ENGINE environment variable.

This produces:

  • tests/firmware/zephyr-stm32h5/build/guest0_psa/zephyr/zephyr.bin
  • tests/firmware/zephyr-stm32h5/build/freertos_guest1/freertos_guest1.bin

The same Makefile also provides:

Target Result
build-guest0 Diagnostic Zephyr guest without the full PSA demo
build-guest0-psa Zephyr PSA guest
build-guest1 Bare-metal heartbeat guest
build-freertos-guest1 FreeRTOS PSA guest
run Zephyr PSA plus bare-metal guest under M33MU
run-uarts Same pair with separated UART output
run-tui Same pair with the M33MU TUI
zephyr-freertos-uarts Zephyr and FreeRTOS PSA guests under M33MU

Engine coverage in CI

The cross-compile workflow links a Secure image with each engine. The M33MU lifecycle job crosses guest: [zephyr, freertos] with engine: [native, hsm]. The scenario job also adds the engine as a matrix dimension, and the label-selected pull-request workflow runs each requested scenario under both engines.

The hsmattackneg scenario is intentionally hsm-only. It injects raw wolfHSM protocol packets and attacks a wolfHSM namespace and NVM relay surface that is not linked into the native engine. All other scenario rows run under both engines. See Testing for the commands and validation scope.

Authenticated image assembly

make alone produces an unsigned flat Secure binary. The target runners perform the complete assembly:

  1. build wolfBoot and the guest images;
  2. copy the unpatched wolfTrust binary;
  3. run tools/measure/patch_guest_digests.py with each guest ID, version, and binary;
  4. sign the patched wolfTrust image with the wolfBoot key; and
  5. load wolfBoot, signed wolfTrust, and guests at matching addresses.

Do not sign wolfTrust before patching the guest records. An unpatched record count causes required guest launch to fail.

Virtual network build

The optional wolfTrust virtual Ethernet switch for wolfIP guests is off by default:

make CONFIG_VNET=y
make test-vnet
make test-vnet-target

The end-to-end VNET guests use tests/firmware/stm32h563-vnet/, not the Zephyr and FreeRTOS demo images.

Clean builds

make clean
make -C tests/host clean
make -C tests/firmware/zephyr-stm32h5 clean

The root target removes the Secure build, bare-metal and VNET reference firmware, and the host suites it names. The second command clears every native host-suite build; the third clears Zephyr and FreeRTOS guest outputs. Downloaded guest workspaces under ignored directories may remain.

See Getting Started for the shortest path and Testing for validation commands.

Clone this wiki locally