-
Notifications
You must be signed in to change notification settings - Fork 38
feat: add sbom Makefile target #414
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
2324dc1
6b7ee11
e4b910d
4c0af52
4cef60f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,162 @@ | ||
| # Nightly integration: build wolfBoot's STM32H5 TrustZone demo against | ||
| # the latest wolfHSM main and run it under the m33mu emulator. This | ||
| # catches drift between wolfHSM and wolfBoot main (in either direction) | ||
| # that the pinned-submodule per-PR builds do not. The full client suite | ||
| # runs software RSA and ECC, which is slow under the emulator, so this | ||
| # is a nightly job rather than a per-PR gate. | ||
| # | ||
| # On failure it opens (or updates) a tracking issue assigned to | ||
| # wolfSSL-Bot. | ||
|
|
||
| name: wolfBoot TrustZone integration nightly (m33mu) | ||
|
|
||
| on: | ||
| schedule: | ||
| # 07:00 UTC daily | ||
| - cron: '0 7 * * *' | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
| issues: write | ||
|
|
||
| jobs: | ||
| wolfboot-stm32h5-tz-wolfhsm: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 60 | ||
| container: | ||
| image: ghcr.io/wolfssl/wolfboot-ci-m33mu:latest | ||
|
|
||
| steps: | ||
| - name: Checkout wolfHSM (this repo, main) | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| path: wolfHSM | ||
|
|
||
| - name: Checkout wolfBoot master | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: wolfSSL/wolfBoot | ||
| path: wolfBoot | ||
| # Skip lib/wolfHSM submodule init - we replace it with this | ||
| # checkout. Other submodules still need to come down. | ||
| submodules: false | ||
|
|
||
| - name: Initialise wolfBoot submodules (except lib/wolfHSM) | ||
| working-directory: wolfBoot | ||
| run: | | ||
| git config -f .gitmodules submodule.lib/wolfHSM.update none | ||
| git submodule update --init --recursive | ||
|
|
||
| - name: Point lib/wolfHSM at this checkout | ||
| working-directory: wolfBoot | ||
| run: | | ||
| rm -rf lib/wolfHSM | ||
| ln -s "$GITHUB_WORKSPACE/wolfHSM" lib/wolfHSM | ||
| ls -l lib/wolfHSM | ||
|
|
||
| - name: Build wolfBoot STM32H5 TZ demo | ||
| working-directory: wolfBoot/port/stmicro/stm32h5-tz-wolfhsm | ||
| run: make | ||
|
|
||
| - name: Run wolfHSM whTest_ClientConfig under m33mu | ||
| working-directory: wolfBoot/port/stmicro/stm32h5-tz-wolfhsm | ||
| run: | | ||
| set -o pipefail | ||
| mkdir -p /tmp/m33mu-wolfhsm-persist | ||
| cp out/wolfboot.bin out/image_v1_signed.bin /tmp/m33mu-wolfhsm-persist/ | ||
| cd /tmp/m33mu-wolfhsm-persist | ||
| # m33mu timeout below the 60 min job timeout so a hung run | ||
| # still produces a log. Software RSA keygen dominates. | ||
| m33mu wolfboot.bin image_v1_signed.bin:0x60000 \ | ||
| --persist --uart-stdout --timeout 3000 \ | ||
| --expect-bkpt 0x7d --quit-on-faults \ | ||
| 2>&1 | tee /tmp/m33mu-wolfhsm.log | ||
|
|
||
| - name: Verify wolfHSM whTest_ClientConfig | ||
| run: | | ||
| grep -q "wolfHSM whTest_ClientConfig PASSED" /tmp/m33mu-wolfhsm.log | ||
| grep -q "RNG DEVID=0x5748534D SUCCESS" /tmp/m33mu-wolfhsm.log | ||
| grep -q "AES GCM DEVID=0x5748534D SUCCESS" /tmp/m33mu-wolfhsm.log | ||
| grep -q "RSA SUCCESS" /tmp/m33mu-wolfhsm.log | ||
| grep -q "ECC ephemeral ECDH SUCCESS" /tmp/m33mu-wolfhsm.log | ||
| grep -q "SHA256 DEVID=0x5748534D SUCCESS" /tmp/m33mu-wolfhsm.log | ||
| grep -q "HKDF SUCCESS" /tmp/m33mu-wolfhsm.log | ||
| grep -q "\\[BKPT\\] imm=0x7d" /tmp/m33mu-wolfhsm.log | ||
| grep -q "\\[EXPECT BKPT\\] Success" /tmp/m33mu-wolfhsm.log | ||
|
|
||
| - name: Archive emulator log on failure | ||
| if: failure() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: m33mu-wolfhsm.log | ||
| path: /tmp/m33mu-wolfhsm.log | ||
|
|
||
| - name: Open or update tracking issue on failure | ||
| if: failure() | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; | ||
| const marker = 'nightly-tz-integration'; | ||
| const title = 'Nightly wolfBoot TrustZone (m33mu) integration failed'; | ||
| const body = [ | ||
| 'The nightly wolfBoot STM32H5 TrustZone integration run failed.', | ||
| '', | ||
| `Run: ${runUrl}`, | ||
| '', | ||
| 'This builds wolfBoot main against wolfHSM main and runs the', | ||
| 'STM32H5 demo under m33mu. A failure usually means a regression', | ||
| 'in the NSC transport, the wolfBoot port, or a wolfHSM/wolfBoot', | ||
| 'API drift. The emulator log is attached to the run as an artifact.', | ||
| ].join('\n'); | ||
|
|
||
| // Reuse one open tracking issue instead of opening a new one | ||
| // every night. | ||
| const existing = await github.rest.issues.listForRepo({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| state: 'open', | ||
| labels: marker, | ||
| }); | ||
|
|
||
| if (existing.data.length > 0) { | ||
| await github.rest.issues.createComment({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: existing.data[0].number, | ||
| body: `Still failing as of ${runUrl}`, | ||
| }); | ||
| return; | ||
| } | ||
|
|
||
| // Best-effort label create (ignore if it already exists). | ||
| try { | ||
| await github.rest.issues.createLabel({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| name: marker, | ||
| color: 'b60205', | ||
| }); | ||
| } catch (e) { /* label exists */ } | ||
|
|
||
| try { | ||
| await github.rest.issues.create({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| title, | ||
| body, | ||
| labels: [marker], | ||
| assignees: ['wolfSSL-Bot'], | ||
| }); | ||
| } catch (e) { | ||
| // Assignee may not be assignable; retry without it so the | ||
| // issue still gets filed. | ||
| await github.rest.issues.create({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| title, | ||
| body, | ||
| labels: [marker], | ||
| }); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,3 +25,58 @@ please refer to the following resources. | |
| - [wolfHSM Manual](https://www.wolfssl.com/documentation/manuals/wolfhsm/index.html) | ||
| - [wolfHSM API Reference](https://www.wolfssl.com/documentation/manuals/wolfhsm/appendix01.html) | ||
| - [wolfHSM Examples](https://github.com/wolfSSL/wolfHSM/tree/main/examples) | ||
|
|
||
| ## SBOM / EU CRA Compliance | ||
|
|
||
| wolfHSM generates a Software Bill of Materials (SBOM) in CycloneDX 1.6 and | ||
| SPDX 2.3 formats to support compliance with the EU Cyber Resilience Act (CRA). | ||
|
|
||
| Generate both SBOMs with the `sbom` Makefile target: | ||
|
|
||
| ```sh | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔵 [Low] README manual invocation diverges from the Makefile sbom target · Logic The README documents a manual Fix: Lead the README section with
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed — README manual invocation now matches the Makefile target (same flags and version derivation), with the raw command kept as a documented fallback. |
||
| make sbom WOLFSSL_DIR=../wolfssl | ||
| ``` | ||
|
|
||
| This parses the version from `ChangeLog.md`, collects `src/*.c`, and writes | ||
| `wolfhsm-<version>.cdx.json` and `wolfhsm-<version>.spdx.json`. | ||
|
|
||
| The SBOM records the build configuration by preprocessing | ||
| `wolfhsm/wh_settings.h` against a config directory. `WOLFHSM_CFG_DIR` | ||
| (default: `test/config`) selects the directory holding the `wolfhsm_cfg.h` | ||
| and `user_settings.h` your build uses — point it at your port's config so the | ||
| recorded `WOLFHSM_CFG_*` and wolfSSL options match the library you ship: | ||
|
|
||
| ```sh | ||
| make sbom WOLFSSL_DIR=../wolfssl WOLFHSM_CFG_DIR=path/to/your/config | ||
| ``` | ||
|
|
||
| Note: alongside the real config macros, the dump currently includes libc | ||
| constants pulled in by `wh_settings.h`'s system includes; see the comment on | ||
| the `sbom` target in `Makefile` for why they are not filtered here and what | ||
| the planned gen-sbom fix is. | ||
|
|
||
| `WOLFSSL_DIR` must point to a wolfssl source tree containing `scripts/gen-sbom`, | ||
| which ships in wolfSSL PR #10343 (pending a future wolfSSL release). If the | ||
| script is absent the target fails with a message telling you what is missing. | ||
|
|
||
| Requires `python3` and `pyspdxtools` (`pip install spdx-tools`). | ||
|
|
||
| To invoke `gen-sbom` directly instead of through the target, run the same | ||
| command it runs: | ||
|
|
||
| ```sh | ||
| cc -dM -E -DWOLFHSM_CFG -DWOLFSSL_USER_SETTINGS \ | ||
| -I. -Itest/config -I$WOLFSSL_DIR \ | ||
| -include wolfhsm/wh_settings.h -x c /dev/null > wolfhsm-defines.h | ||
| python3 $WOLFSSL_DIR/scripts/gen-sbom \ | ||
| --name wolfhsm \ | ||
| --version $(sed -n 's/^# wolfHSM Release v\([0-9][0-9.]*\).*/\1/p' ChangeLog.md | head -1) \ | ||
| --supplier "wolfSSL Inc." \ | ||
| --license-file LICENSING \ | ||
| --options-h wolfhsm-defines.h \ | ||
| --srcs src/*.c \ | ||
| --cdx-out wolfhsm.cdx.json \ | ||
| --spdx-out wolfhsm.spdx.json | ||
| ``` | ||
|
|
||
| For further CRA guidance see [wolfssl/doc/CRA.md](https://github.com/wolfSSL/wolfssl/blob/master/doc/CRA.md). | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| # ARMv8-M TrustZone NSC bridge transport | ||
|
|
||
| A synchronous wolfHSM transport for ARMv8-M TrustZone targets that | ||
| bridges a non-secure client to a secure-world server through a single | ||
| Non-Secure Callable (NSC) veneer. See `wh_transport_nsc.h` for the C | ||
| API. | ||
|
|
||
| ## How it works | ||
|
|
||
| Client and server share a single secure-callable function. The | ||
| non-secure side packs a wolfHSM request into a buffer, calls the | ||
| veneer, and waits for the veneer to return with the response written | ||
| into a second buffer. The secure side runs the wolfHSM server in the | ||
| same process; there is no separate task, no IRQ, and no shared-memory | ||
| ring — just a function call across the security boundary. | ||
|
|
||
| ## Host-side veneer contract | ||
|
|
||
| The integrator provides one function with this exact shape: | ||
|
|
||
| ```c | ||
| int wcs_wolfhsm_transmit(const uint8_t *cmd, uint32_t cmdSz, | ||
| uint8_t *rsp, uint32_t *rspSz); | ||
| ``` | ||
|
|
||
| declared `cmse_nonsecure_entry` from the secure side. On entry, | ||
| `cmd[0..cmdSz)` holds the request and `*rspSz` is the maximum response | ||
| size the client can accept; on return the function writes the | ||
| response into `rsp[0..*rspSz)` and updates `*rspSz` to the actual | ||
| size. Return value follows wolfHSM's `WH_ERROR_*` convention. | ||
|
|
||
| The veneer must not block on anything outside the secure server; the | ||
| non-secure side treats it as a synchronous call. | ||
|
|
||
| ## Known integrations | ||
|
|
||
| - **wolfBoot STM32H5 demo app** at | ||
| [`port/stmicro/stm32h5-tz-wolfhsm/`](https://github.com/wolfSSL/wolfBoot/tree/main/port/stmicro/stm32h5-tz-wolfhsm) | ||
| in wolfBoot. Reference integration on a NUCLEO-H563ZI; | ||
| verified end-to-end on real silicon and on the m33mu emulator. | ||
|
|
||
| To add a new integration, copy the veneer skeleton from wolfBoot's | ||
| demo, wire `wh_transport_nsc.h` into the non-secure client init, and | ||
| write a `whServerCb` table for the secure server. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed —
SRCS := $(sort $(wildcard src/*.c))for reproducible ordering.