diff --git a/Makefile b/Makefile index 638f48ea26..330e6f5763 100644 --- a/Makefile +++ b/Makefile @@ -787,6 +787,61 @@ src/x86/fsp_s.o: $(FSP_S_BIN) pico-sdk-info: FORCE @echo "To complete the build, check IDE/pico-sdk/rp2350" +## SBOM generation +# Usage: make sbom TARGET= SIGN= [HASH=SHA256] [EXT_FLASH=0] +# +# TARGET and SIGN select the build configuration; they default to stm32f4 and +# ED25519 (via tools/config.mk) if not supplied. Pass them explicitly to get +# an SBOM that reflects your actual build configuration. +# +# Extracts the configuration-specific C source list from OBJS (which is fully +# assembled by this point — core wolfBoot + wolfcrypt + HAL sources are all +# included), preprocesses wolfBoot's include dirs via cc -dM -E on the host, +# and calls gen-sbom to emit CycloneDX and SPDX output files. +# +# wolfcrypt sources are compiled directly into the wolfBoot image and are +# therefore listed as wolfBoot's own sources, not as a separate component. +# +# Optional make variables: +# CRA_PYTHON Python interpreter (default: python3) + +WOLFBOOT_VERSION:=$(shell sed -n \ + 's/.*LIBWOLFBOOT_VERSION_STRING[[:space:]]*"\([^"]*\)".*/\1/p' \ + include/wolfboot/version.h) +GEN_SBOM:=$(WOLFBOOT_LIB_WOLFSSL)/scripts/gen-sbom +SBOM_CDX_OUT:=wolfboot-$(WOLFBOOT_VERSION).cdx.json +SBOM_SPDX_OUT:=wolfboot-$(WOLFBOOT_VERSION).spdx.json +SBOM_PYTHON?=$(or $(CRA_PYTHON),python3) + +sbom: + @echo "wolfBoot SBOM: version=$(WOLFBOOT_VERSION) target=$(TARGET) sign=$(SIGN)" + @echo " Outputs: $(SBOM_CDX_OUT) $(SBOM_SPDX_OUT)" + $(eval _SBOM_SRCS := $(wildcard $(patsubst %.o,%.c,$(OBJS)))) + @if [ -z "$(_SBOM_SRCS)" ]; then \ + echo "ERROR: no .c sources found in OBJS — check that TARGET and SIGN are correct." >&2; \ + exit 1; \ + fi + @set -e; \ + _dh=$$(mktemp /tmp/wolfboot-sbom-defines.XXXXXX); \ + trap 'rm -f "$$_dh"' EXIT; \ + cc -dM -E \ + -I"$(WOLFBOOT_ROOT)/include" \ + -I"$(WOLFBOOT_LIB_WOLFSSL)" \ + -I"$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src" \ + -DWOLFSSL_USER_SETTINGS \ + -x c /dev/null >"$$_dh" 2>/dev/null || \ + { echo "ERROR: cc -dM -E failed; install a host C compiler." >&2; exit 1; }; \ + $(SBOM_PYTHON) "$(GEN_SBOM)" \ + --name wolfboot \ + --version "$(WOLFBOOT_VERSION)" \ + --supplier "wolfSSL Inc." \ + --license-file "$(WOLFBOOT_ROOT)/LICENSE" \ + --options-h "$$_dh" \ + --srcs $(_SBOM_SRCS) \ + --cdx-out "$(SBOM_CDX_OUT)" \ + --spdx-out "$(SBOM_SPDX_OUT)" + @echo "SBOM written: $(SBOM_CDX_OUT) $(SBOM_SPDX_OUT)" + FORCE: -.PHONY: FORCE clean keytool_check squashelf_check +.PHONY: FORCE clean keytool_check squashelf_check sbom diff --git a/README.md b/README.md index c98ea5a9b1..56a9696043 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,30 @@ make See [docs/CMake](./docs/CMake.md) and [cmake includes](./cmake/README.md). +## SBOM / EU CRA Compliance + +wolfBoot 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). + +```sh +git submodule update --init lib/wolfssl +make sbom TARGET= SIGN= HASH= +``` + +`TARGET`, `SIGN`, and `HASH` must match your wolfBoot build configuration (same +as a normal `make` invocation). `gen-sbom` lives in the `lib/wolfssl` submodule +and is used automatically. The artifact hash covers the compiled source files +for the given configuration. + +Output files in the build directory: + +| File | Format | +|------|--------| +| `wolfboot-2.8.0.cdx.json` | CycloneDX 1.6 | +| `wolfboot-2.8.0.spdx.json` | SPDX 2.3 JSON | + +For further CRA guidance see [wolfssl/doc/CRA.md](https://github.com/wolfSSL/wolfssl/blob/master/doc/CRA.md). + ## Troubleshooting 1. Python errors when signing a key: