Skip to content
Open
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
19 changes: 18 additions & 1 deletion .github/workflows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,17 @@ An accepted upload queues analysis; results appear after Coverity processes it.
| **Fast (per-PR)** | every PR; push to main | host unit suites, ISO C99, house style, bare-scope scan, Arm PSA-FF conformance, cross-compile, compiler matrix, sanitizers, valgrind, integrations, core/port split guard |
| **M33MU smoke** | every PR | per port, on both crypto engines: STM32H563 `positive gtzcneg crossdomain bothpsa confboot devcrypto`; MIMXRT700 `positive ahbscneg crossdomain bothpsa confboot devcrypto` |
| **M33MU full** | PR labels `ci:all`, `ci:stm32h563`, `ci:imxrt700`; push to main; `cron: 0 8 * * *`; `workflow_dispatch` (port input) | every scenario of that port on both engines (see below) |
| **AArch64 smoke** | every PR | a representative subset: `virt-gicv3-a72` `smoke boot positive crossdomain ffa-direct confboot devcrypto` on both crypto engines, and `versal-virt` the same on the native engine |
| **AArch64 smoke** | every PR | a representative subset: `virt-gicv3-a72` `smoke boot positive crossdomain ffa-direct confboot devcrypto` on both crypto engines, `versal-virt` the same on the native engine, plus dedicated QEMU fwTPM and PKCS#11 interface and isolation jobs |
| **AArch64 full** | PR labels `ci:all`, `ci:aarch64`, `ci:qemu-virt`, `ci:qemu-versal`; push to main; nightly; `workflow_dispatch` (cell input) | every AArch64 scenario and the Arm FF-A ACS groups on three QEMU cells under both crypto engines (see below) |

All dedicated API and interface-isolation rows require a real terminal pass
marker; a successful skip cannot satisfy the job. Each job identifies its
engine and operation profile. M33MU runs 24 positives across
`[default, full] x [native, hsm] x [psa, pkcs11, tpm] x [zephyr, freertos]`, plus
eight interface-isolation jobs. QEMU `virt` runs 20 positives/isolation jobs
across both profiles and engines. Versal cross-builds both engines, but its QEMU
model cannot provide the XMPU/RISAF isolation those runtime scenarios require.

The M33MU workflow (`m33mu.yml`) is label-selected the way wolfProvider's
`pr-osp-select.yml` is: a `select` job checks the routing table
(`scenario_matrix.py --selftest`), reads the PR's `ci:*` labels, the
Expand Down Expand Up @@ -63,6 +71,10 @@ test-target` also reads. The table below is a representative slice:
| `stm32h563_confboot_<engine>` | `confboot` | full Arm FF-M IPC suite |
| `stm32h563_devstorage_<engine>` | `devstorage` | PSA ITS/PS conformance |
| `stm32h563_devcrypto_<engine>` | `devcrypto` | PSA Crypto conformance |
| `stm32h563_pkcs11_<zephyr\|freertos>_<engine>_<profile>` | `pkcs11` | each RTOS application runs the nine-case default or 40-case full PKCS#11 suite through `SERVICE_PKCS11` and the isolated provider |
| `stm32h563_tpm_<zephyr\|freertos>_<engine>_<profile>` | `tpm` | each RTOS application sends real TPM 2.0 commands through `SERVICE_TPM` to the isolated fwTPM guest |
| `stm32h563_pkcs11neg_<engine>_<profile>` | `pkcs11neg` | PKCS#11 partition-band isolation and provider recovery |
| `stm32h563_tpmneg_<engine>_<profile>` | `tpmneg` | TPM relay and fwTPM partition-band isolation |
| `stm32h563_vaultrecover_<engine>` | `vaultrecover` | #95 foreign pool reformatted |
| `stm32h563_vaultrecoversec_<engine>` | `vaultrecoversec` | #95 SECURED never wipes |
| `mimxrt700_positive_<engine>` | `positive` | MIMXRT700 chain under the RT700 model, both guests finish |
Expand Down Expand Up @@ -114,6 +126,11 @@ full matrix. The cells and the smoke subset live in

| Check name | What it proves |
|------------|----------------|
| `qemuvirt_psa_<engine>` | the Normal-world PSA client uses the selected engine through FF-A |
| `qemuvirt_tpm_<engine>_<profile>` | the Normal-world application sends real TPM 2.0 GetRandom, CreatePrimary, Sign, and full-profile PCR Extend/Read commands through FF-A and `SERVICE_TPM` to the isolated fwTPM |
| `qemuvirt_tpmneg_<engine>_<profile>` | the fwTPM round trip plus TPM state-band, provider-RAM, and execute-never isolation negatives |
| `qemuvirt_pkcs11_<engine>_<profile>` | the Normal-world application runs nine default or 40 full PKCS#11 cases through FF-A and the isolated provider |
| `qemuvirt_pkcs11neg_<engine>_<profile>` | the PKCS#11 suite plus state-band, provider-RAM, execute-never, and engine-appropriate restart/recovery negatives |
| `el3_<cell>_<engine>` | the EL3 image links under the symbol guard, then the tier's QEMU AArch64 scenarios run through `tests/target/run_suite.sh qemu-a` |
| `ffa_acs_<cell>_<engine>` | the Arm FF-A ACS groups (discovery, direct and indirect messaging, memory, notifications, interrupts) at their asserted floors (full tier only) |

Expand Down
69 changes: 68 additions & 1 deletion .github/workflows/aarch64-cross-compile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,62 @@ jobs:
for e in json.load(sys.stdin):
print(e["job"], "(" + e["engine"] + ")")'

interfaces-qemu-a:
name: qemuvirt_${{ matrix.scenario }}_${{ matrix.engine }}_${{ matrix.profile }}
if: >-
github.event_name != 'workflow_dispatch' || inputs.cell == '' ||
inputs.cell == 'all' || inputs.cell == 'qemu-virt' ||
inputs.cell == 'virt-gicv3-a72'
runs-on: ubuntu-latest
timeout-minutes: 45
container:
image: ghcr.io/wolfssl/wolfboot-ci-aarch64:v1.15
strategy:
fail-fast: false
matrix:
scenario: [positive, tpm, tpmneg, pkcs11, pkcs11neg]
engine: [native, hsm]
profile: [default, full]
env:
WT_ENGINE: ${{ matrix.engine }}
WT_CRYPTO_PROFILE: ${{ matrix.profile }}
WT_REQUIRE_SCENARIO_PASS: 1
MACHINE: virt
GIC: 3
CPU: cortex-a72
SMP: 1
steps:
- uses: actions/checkout@v4

- name: Trust the checked-out workspace
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"

- name: Initialize wolfTrust dependencies
run: |
git config --global url."https://github.com/".insteadOf "git@github.com:"
git submodule update --init --single-branch lib/wolfSSL lib/wolfHSM lib/wolfCOSE lib/wolfPSA lib/wolfTPM lib/wolfPKCS11

- name: Toolchain and emulator versions
run: |
aarch64-none-elf-gcc --version | head -1
qemu-system-aarch64 --version | head -1

- name: Self-test the EL3 symbol guard and the expect library
run: |
tools/check-el3-symbols.sh --selftest
tests/target/lib/expect.sh --selftest

- name: Run the direct SPM interface scenario
run: tests/target/run_suite.sh qemu-a ${{ matrix.scenario }}

- name: Show the boot logs
if: always()
run: |
for f in logs/target-*.log; do
echo "== $f"
cat "$f" || true
done

qemu-a:
name: ${{ matrix.job }}
needs: select
Expand Down Expand Up @@ -78,7 +134,7 @@ jobs:
- name: Initialize wolfTrust dependencies
run: |
git config --global url."https://github.com/".insteadOf "git@github.com:"
git submodule update --init --single-branch lib/wolfSSL lib/wolfHSM lib/wolfCOSE lib/wolfPSA
git submodule update --init --single-branch lib/wolfSSL lib/wolfHSM lib/wolfCOSE lib/wolfPSA lib/wolfTPM lib/wolfPKCS11

- name: Toolchain and emulator versions
run: |
Expand All @@ -95,6 +151,17 @@ jobs:
if: matrix.kind == 'suite'
run: make ARCH=aarch64 TARGET=${{ matrix.target }} WT_GIC_VERSION="$GIC" WT_CPU="$CPU" BUILD_DIR=build-aarch64-guard el3-image

- name: Cross-build the Versal TPM and PKCS11 interfaces
if: matrix.kind == 'suite' && matrix.target == 'versal'
run: |
make ARCH=aarch64 TARGET=versal WT_GIC_VERSION="$GIC" \
WT_CPU="$CPU" WT_PORT_BOOT_CPUS=1 WT_ENGINE=${{ matrix.engine }} CONFIG_TPM=y \
WT_ATTEST_COSE=0 BUILD_DIR=build-versal-tpm secure-image
make ARCH=aarch64 TARGET=versal WT_GIC_VERSION="$GIC" \
WT_CPU="$CPU" WT_PORT_BOOT_CPUS=1 CONFIG_PKCS11=y \
WT_ENGINE=${{ matrix.engine }} WT_ATTEST_COSE=0 \
BUILD_DIR=build-versal-pkcs11 secure-image

- name: Fetch the pinned Arm FF-A ACS once for the six groups
if: matrix.kind == 'acs'
run: |
Expand Down
14 changes: 13 additions & 1 deletion .github/workflows/cross-compile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ jobs:
git config --global url."https://github.com/".insteadOf git@github.com:
git submodule update --init --depth 1 --jobs 4 \
lib/wolfCOSE lib/wolfHSM lib/wolfPSA lib/wolfSSL \
lib/wolfhal
lib/wolfTPM lib/wolfPKCS11 lib/wolfhal
test -f lib/wolfTPM/src/fwtpm/fwtpm.c
test -f lib/wolfPKCS11/src/wolfpkcs11.c
- name: Build STM32H563 secure firmware
run: make -C tests/firmware/stm32h563 all TOOLPREFIX=arm-none-eabi-
- name: Validate the LTO gate, rebuild, and size reduction
Expand Down Expand Up @@ -96,3 +98,13 @@ jobs:
WT_CONFORMANCE=1 secure-image TOOLPREFIX=arm-none-eabi- \
BUILD_DIR=build_rt700_conf_$engine
done
- name: Build both interfaces with both crypto engines on both ports
run: |
for engine in native hsm; do
for target in stm32h563 mimxrt700; do
make TARGET="$target" CONFIG_TPM=y WT_ENGINE="$engine" \
WT_ATTEST_COSE=0 BUILD_DIR="build-$target-tpm-$engine" secure-image
make TARGET="$target" CONFIG_PKCS11=y WT_ENGINE="$engine" \
WT_ATTEST_COSE=0 BUILD_DIR="build-$target-pkcs11-$engine" secure-image
done
done
67 changes: 61 additions & 6 deletions .github/workflows/m33mu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,22 +87,30 @@ jobs:
run: |
./test-app/emu-test-apps/test.sh

wolfboot-wolftrust-m33mu:
name: stm32h563_${{ matrix.guest }}_lifecycle_${{ matrix.engine }}
interfaces-m33mu:
name: stm32h563_${{ matrix.api }}_${{ matrix.os }}_${{ matrix.engine }}_${{ matrix.profile }}
if: >-
github.event_name != 'workflow_dispatch' ||
inputs.port == 'all' || inputs.port == 'stm32h563'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
guest: [zephyr, freertos]
api: [psa, pkcs11, tpm]
os: [zephyr, freertos]
engine: [native, hsm]
timeout-minutes: 45
profile: [default, full]
timeout-minutes: 60
container:
image: ghcr.io/wolfssl/wolfboot-ci-m33mu:v1.15
env:
# Keep the validated H5 secure-app handoff until that configuration is
# upstreamed; upstream master does not yet ship this wolfTrust config.
WOLFBOOT_REF: d85fa9dbdf6c36f47b7e96eba5c9df750ad3c963
WT_ENGINE: ${{ matrix.engine }}
WT_CRYPTO_PROFILE: ${{ matrix.profile }}
WT_INTERFACE_OS: ${{ matrix.os }}
WT_REQUIRE_SCENARIO_PASS: 1
CROSS_COMPILE: /usr/local/bin/arm-none-eabi-
ZEPHYR_TOOLCHAIN_VARIANT: cross-compile
# The wolfBoot configuration reserves the wolfTrust partition at the
Expand All @@ -120,7 +128,7 @@ jobs:
WT_ZEPHYR_DTC_OVERLAY_FILE: boards/wolfboot-stm32h563.overlay
WT_MAX_GUESTS: 2
ZEPHYR_BOARD: nucleo_h563zi/stm32h563xx/ns
WT_TEST_GUEST: ${{ matrix.guest }}
WT_TEST_GUEST: ${{ matrix.os }}
# Upstream master with danielinux/m33mu PR #21 (deterministic USART IRQ timing).
M33MU_REF: f3c03675260264cdec815adebe4b020bb6fe57b8
steps:
Expand All @@ -132,6 +140,7 @@ jobs:
git config --global url."https://github.com/".insteadOf git@github.com:

- name: Build pinned upstream M33MU
if: matrix.api == 'psa' && matrix.profile == 'full'
run: |
git clone --no-checkout https://github.com/danielinux/m33mu.git m33mu
git -C m33mu fetch --depth 1 origin "$M33MU_REF"
Expand All @@ -141,20 +150,24 @@ jobs:
echo "M33MU=$GITHUB_WORKSPACE/m33mu/build/m33mu" >> "$GITHUB_ENV"

- name: Initialize wolfTrust dependencies
if: matrix.api == 'psa' && matrix.profile == 'full'
run: git submodule update --init --single-branch

- name: Prepare Zephyr and FreeRTOS workspaces
if: matrix.api == 'psa' && matrix.profile == 'full'
working-directory: tests/firmware/zephyr-stm32h5
run: make clone

- name: Fetch secure-app wolfBoot
if: matrix.api == 'psa' && matrix.profile == 'full'
run: |
git clone --no-checkout https://github.com/aidangarske/wolfBoot.git wolfBoot
git -C wolfBoot fetch --depth 1 origin "$WOLFBOOT_REF"
git -C wolfBoot checkout --detach "$WOLFBOOT_REF"
git -C wolfBoot submodule update --init --single-branch

- name: Build wolfBoot secure first stage
if: matrix.api == 'psa' && matrix.profile == 'full'
working-directory: wolfBoot
run: |
cp config/examples/stm32h5-tz-wolftrust.config .config
Expand All @@ -167,10 +180,12 @@ jobs:
make -j1 wolfboot.bin wolfboot_signing_private_key.der

- name: Build relocated wolfTrust
if: matrix.api == 'psa' && matrix.profile == 'full'
run: |
make build/wolftrust.bin build/secure_cmse_implib.o

- name: Build Zephyr and FreeRTOS PSA guests
if: matrix.api == 'psa' && matrix.profile == 'full'
run: |
make -C tests/firmware/zephyr-stm32h5 \
WT_REUSE_SECURE_BUILD=1 \
Expand All @@ -180,12 +195,14 @@ jobs:
build-guest0-psa build-freertos-guest1

- name: Pin guest measurements into the secure image
if: matrix.api == 'psa' && matrix.profile == 'full'
run: |
python3 tools/measure/patch_guest_digests.py build/wolftrust.bin \
"0:1:tests/firmware/zephyr-stm32h5/build/guest0_psa/zephyr/zephyr.bin" \
"1:1:tests/firmware/zephyr-stm32h5/build/freertos_guest1/freertos_guest1.bin"

- name: Sign wolfTrust secure runtime
if: matrix.api == 'psa' && matrix.profile == 'full'
working-directory: wolfBoot
run: |
IMAGE_HEADER_SIZE=1024 \
Expand All @@ -197,12 +214,14 @@ jobs:
test -s "$GITHUB_WORKSPACE/build/wolftrust_v1_signed.bin"

- name: Read the wolfBoot authenticated measurement
if: matrix.api == 'psa' && matrix.profile == 'full'
run: |
measurement=$(python3 tests/scripts/read_wolfboot_measurement.py \
build/wolftrust_v1_signed.bin)
echo "WT_EXPECTED_MEASUREMENT_HEX=$measurement" >> "$GITHUB_ENV"

- name: Boot the authenticated wolfBoot → wolfTrust → guests chain
if: matrix.api == 'psa' && matrix.profile == 'full'
run: |
echo "Guest vector tables (SP, reset PC):"
od -An -tx4 -N8 tests/firmware/zephyr-stm32h5/build/guest0_psa/zephyr/zephyr.bin
Expand Down Expand Up @@ -277,8 +296,43 @@ jobs:
need_raw "freertos_guest1: psa_crypto_init st=0"
need_raw "freertos_guest1: psa rng ok"
need_raw "freertos_guest1: psa hash ok"
need_raw "freertos_guest1: psa ECC keygen/sign/verify ok"
fi

- name: Run the direct SPM interface scenario
if: matrix.api != 'psa' || matrix.profile != 'full'
run: tests/target/run_suite.sh m33mu ${{ matrix.api == 'psa' && 'positive' || matrix.api }}

interface-isolation-m33mu:
name: stm32h563_${{ matrix.scenario }}_${{ matrix.engine }}_${{ matrix.profile }}
if: >-
github.event_name != 'workflow_dispatch' ||
inputs.port == 'all' || inputs.port == 'stm32h563'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
scenario: [tpmneg, pkcs11neg]
engine: [native, hsm]
profile: [default, full]
timeout-minutes: 45
container:
image: ghcr.io/wolfssl/wolfboot-ci-m33mu:v1.15
env:
WT_ENGINE: ${{ matrix.engine }}
WT_CRYPTO_PROFILE: ${{ matrix.profile }}
WT_REQUIRE_SCENARIO_PASS: 1
steps:
- uses: actions/checkout@v4

- name: Trust the checked-out workspace
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
git config --global url."https://github.com/".insteadOf git@github.com:

- name: Run the direct interface scenario
run: tests/target/run_suite.sh m33mu ${{ matrix.scenario }}

# Label-selected, the wolfProvider way: one select job reads the ci:* labels
# (ci:stm32h563 or ci:imxrt700 for that port's full matrix when only that port
# changed, ci:all or ci:m33mu for everything after a core change, no label
Expand All @@ -292,7 +346,8 @@ jobs:
steps:
- uses: actions/checkout@v4

- id: p
- name: Generate and verify the M33MU scenario matrix
id: p
env:
PR_LABELS: ${{ join(github.event.pull_request.labels.*.name, ' ') }}
PORT_INPUT: ${{ inputs.port }}
Expand Down
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,9 @@
[submodule "lib/wolfCOSE"]
path = lib/wolfCOSE
url = https://github.com/wolfSSL/wolfCOSE.git
[submodule "lib/wolfPKCS11"]
path = lib/wolfPKCS11
url = git@github.com:wolfSSL/wolfPKCS11.git
[submodule "lib/wolfTPM"]
path = lib/wolfTPM
url = git@github.com:wolfSSL/wolfTPM.git
Loading
Loading