SBOM and Compliance¶
wolfTPM can generate a Software Bill of Materials (SBOM) to support compliance with the EU Cyber Resilience Act (CRA). This page covers how to generate it and how the generator is organized.
SBOM and EU CRA compliance¶
wolfTPM generates an SBOM in CycloneDX 1.6 and SPDX 2.3 formats. The generator is the wolfGlass snapshot vendored in tools/sbom/ and pinned by tools/sbom/.wolfglass-rev. The SBOM records the configured build options (from wolftpm/options.h), hashes the built libwolftpm library artifact (shared or static; ELF, Mach-O, or PE), and lists wolfSSL as a dependency so vulnerability scanners can associate wolfSSL advisories with a wolfTPM deployment.
Output is reproducible. Set SOURCE_DATE_EPOCH (or build from a git checkout, which uses the last commit time) and repeated runs are byte-identical.
With autotools:
make sbom
This requires python3 and pyspdxtools (pip install spdx-tools). The generator ships in the tree, so make sbom does not need a separate wolfSSL checkout. Pass WOLFSSL_DIR=/path/to/wolfssl when pkg-config cannot see the wolfSSL that this build linked, so the dependency version is read from wolfssl/version.h. SBOM_WOLFSSL_VERSION overrides that detection.
The CMake build exposes the same target. WOLFSSL_DIR is optional and has the same meaning:
cmake -B build .
cmake --build build --target sbom
The output files are:
wolftpm-<version>.cdx.jsonwolftpm-<version>.spdx.jsonwolftpm-<version>.spdx
Optional overrides:
| Variable | Purpose |
|---|---|
SBOM_LICENSE_OVERRIDE |
SPDX expression to use instead of the licence parsed from COPYING (for example LicenseRef-wolfSSL-Commercial for commercial licensees). Defaults to GPL-3.0-or-later, the per-file header licence. |
SBOM_LICENSE_TEXT |
Path to the licence text for any LicenseRef-* used in SBOM_LICENSE_OVERRIDE (required by SPDX 2.3). |
SBOM_WOLFSSL_VERSION |
Version recorded for the wolfSSL dependency. Auto-detected from WOLFSSL_DIR/wolfssl/version.h (or the wolfSSL pkg-config entry) when unset. |
To install the generated files:
make install-sbom # installs to $(datadir)/doc/wolftpm/
make uninstall-sbom
For further CRA guidance see wolfssl/doc/CRA.md.
Generator internals¶
The share/ set of wolfGlass is the only vendorable part. The tools/wolfglass-sync script copies these files into a product at tools/sbom/, together with the pin files (VERSION and .wolfglass-rev). Copy the files, not the share/ folder name.
Contents¶
| File | Role |
|---|---|
sbom-driver.py |
The product-neutral SBOM engine (Python). |
sbom-driver |
Thin shell wrapper that runs sbom-driver.py. |
validate_sbom.py |
Structural validator for CI (--name-prefix). |
frontends/compdb_sbom.py |
Extractor for any compile_commands.json. |
frontends/iar_sbom.py |
Extractor for an IAR Embedded Workbench .ewp. |
frontends/zephyr_sbom.py |
Extractor for a Zephyr module CMakeLists.txt. |
build/sbom.mk |
Shared plain-Make fragment and wolfglass_sbom_rule macro. |
build/sbom.cmake |
Shared CMake helper: wolfglass_add_sbom(). |
gen-sbom |
The vendored SBOM generator. |
sbom.am |
Shared autotools fragment. |
The driver contract¶
Every front end produces a composition input and a config input and hands them to the driver.
Composition (at least one):
--srcs-file PATH: the source files compiled into the artifact (tier E).--lib PATH: the built library to hash (tier R/L/S).--no-artifact-hash: record the artifact as-built and do not re-hash. Use it with--libfor a FIPS canister or a kernel module. Never substitute a source list for a certified artifact.
Config (choose one):
--cflags="...": raw CFLAGS. The driver expands the-Dtokens through the host compiler. Use the=form so a leading-dash value is not read as a flag.--options-h PATH: a pre-expanded flat#defineheader, used verbatim.--user-settings PATH: auser_settings.h, which the generator captures.--source-only: no build-config macros (for example a Kconfig-driven build).
Dependency (for linkers and bindings): --dep-wolfssl, --dep-openssl, and --dep-version are passed through only when the generator supports them.
The driver captures macros with the host compiler, so the SBOM is reproducible across toolchains. It scrubs absolute host paths from the captured macros unless you pass --no-scrub.
The shared driver is product-neutral and calls the vendored share/gen-sbom by default. Pass --gen-sbom only when you want to override that copy.
The manifest contract¶
A product does not copy logic. It describes itself:
- Make: set
SBOM_NAME,SBOM_SRCS,SBOM_CFLAGS, and a version (SBOM_VERSION, orSBOM_VERSION_FILEandSBOM_VERSION_MACRO), theninclude tools/sbom/build/sbom.mk. For a second target, instantiate$(eval $(call wolfglass_sbom_rule,<target>,<prefix>)). If the product configuration lives in auser_settings.h, also setSBOM_SETTINGS_H(andSBOM_INCLUDE_DIRSif that header needs paths the CFLAGS do not already carry).SBOM_CFLAGSalone records the literal-Dset and nothing it derives, which for a gated header means the SBOM describes a configuration nobody built. - CMake:
include(tools/sbom/build/sbom.cmake)and callwolfglass_add_sbom()withNAME,VERSION_FILE,VERSION_MACRO,TARGETS,DEFS,LICENSE.SBOM_GENis the canonical generator override.GEN_SBOMremains a legacy alias for compatibility. - Autotools: set the
SBOM_*variables andinclude tools/sbom/sbom.am.
Keep only true product knowledge in the product: the route-through script, the module extractor, and the HAL source selector.