diff --git a/.github/workflows/cra-evidence.yml b/.github/workflows/cra-evidence.yml new file mode 100644 index 00000000..a03f5008 --- /dev/null +++ b/.github/workflows/cra-evidence.yml @@ -0,0 +1,22 @@ +name: CRA Evidence Kit + +on: + push: + paths: + - 'cra-evidence/**' + - '.github/workflows/cra-evidence.yml' + pull_request: + paths: + - 'cra-evidence/**' + - '.github/workflows/cra-evidence.yml' + +jobs: + validate-auditor-packet: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.x' + - name: Validate pinned auditor packet + run: ./cra-evidence/scripts/validate.sh diff --git a/README.md b/README.md index 3a6371b9..dd371be5 100644 --- a/README.md +++ b/README.md @@ -413,6 +413,25 @@ Please see the for further usage and details. +
+ +#### cra-evidence (CRA / SBOM evidence kit) + +This directory is **not** a TLS/crypto tutorial. It demonstrates how to +generate wolfSSL **component SBOMs** (SPDX + CycloneDX), nest them in a +**fictional product SBOM**, and understand optional **bomsh** build provenance +(Linux host only) for EU Cyber Resilience Act-style software transparency. + +Includes a one-page [Evidence Map](cra-evidence/EVIDENCE-MAP.md), full +[glossary](cra-evidence/CRA-Supply-Chain-Glossary.md), sample +[auditor packet](cra-evidence/auditor-packet/), and helper scripts (`validate.sh` +runs without building wolfSSL). Regenerating component SBOMs requires a wolfSSL +tree with SBOM support — see [cra-evidence/README.md](cra-evidence/README.md). + +Please see the [cra-evidence/README.md](cra-evidence/README.md) for further +usage and details. + +
#### uefi-library (wolfCrypt UEFI boot module and test app) diff --git a/cra-evidence/CRA-Supply-Chain-Glossary.md b/cra-evidence/CRA-Supply-Chain-Glossary.md new file mode 100644 index 00000000..d4562a63 --- /dev/null +++ b/cra-evidence/CRA-Supply-Chain-Glossary.md @@ -0,0 +1,111 @@ +# CRA & Supply Chain Terminology — Customer Cheat Sheet + +One-page reference for teams shipping products that include wolfSSL. +**Not legal advice.** Map obligations to your product class and role with counsel. + +This kit is **self-contained** in [wolfssl-examples `cra-evidence/`](https://github.com/wolfSSL/wolfssl-examples/tree/master/cra-evidence). +Upstream wolfSSL integration detail (requires a wolfSSL source tree with SBOM support): + +- [CRA.md](https://github.com/wolfSSL/wolfssl/blob/master/doc/CRA.md) +- [SBOM.md](https://github.com/wolfSSL/wolfssl/blob/master/doc/SBOM.md) + +Handout (shorter): [`EVIDENCE-MAP.md`](EVIDENCE-MAP.md) · Worked example: [`auditor-packet/`](auditor-packet/) + +--- + +## The big picture (30 seconds) + +```mermaid +flowchart LR + subgraph you["Your company (manufacturer)"] + PSBOM["Product SBOM\n(all components)"] + end + subgraph wolf["wolfSSL (component)"] + WSBOM["wolfSSL SBOM\n(SPDX + CycloneDX)"] + BOMSH["OmniBOR / bomsh\n(optional)"] + end + PSBOM -->|"references or contains"| WSBOM + WSBOM -.->|"optional deeper proof"| BOMSH +``` + +| Question | Short answer | +|----------|--------------| +| Do we need **our own** SBOM? | **Yes** — for the **whole product** you place on the EU market. | +| Is wolfSSL’s SBOM enough by itself? | **No** (unless you only redistribute wolfSSL). Use it **inside** your product SBOM. | +| Do we need **bomsh**? | **Usually no.** SBOM alone covers most CRA transparency needs; bomsh adds build traceability if you want it. | +| SPDX or CycloneDX? | **Both are fine.** wolfSSL ships both; use whichever your tools expect (many teams keep both). | + +--- + +## Glossary + +| Term | Stands for / means | Plain English | +|------|-------------------|---------------| +| **CRA** | EU **Cyber Resilience Act** | EU law for products with digital elements: inventory, security, vulnerability handling. | +| **SBOM** | **Software Bill of Materials** | Machine-readable “ingredients list” of software in a product (name, version, supplier, license, IDs, relationships). | +| **Product SBOM** | — | **Yours:** every OSS/third-party component in the **shipped product**. | +| **Component SBOM** | — | **wolfSSL’s:** inventory of **wolfSSL only** (`make sbom` or `gen-sbom`). | +| **SPDX** | **Software Package Data Exchange** | A standard **format** for SBOMs (Linux Foundation). Files: `*.spdx.json`, `*.spdx`. | +| **CycloneDX** | (project name) | Another standard **format** for SBOMs (OWASP ecosystem). File: `*.cdx.json`. | +| **NTIA minimum elements** | US NTIA guidance | Checklist of what a “good” SBOM must include (supplier, name, version, unique ID, deps, author, timestamp). CRA practice aligns with this. | +| **PURL** | **Package URL** | Standard ID like `pkg:generic/wolfssl@5.9.1` — helps tools match components. | +| **CPE** | **Common Platform Enumeration** | Standard ID like `cpe:2.3:a:wolfssl:wolfssl:…` — used by many vulnerability databases. | +| **VEX** | **Vulnerability Exploitability eXchange** | CycloneDX-side signal: “this CVE does/doesn’t apply to our build.” Often layered on top of SBOM in security tools. | +| **CBOM** | **Cryptographic Bill of Materials** | Inventory of **crypto algorithms/keys/modules** (beyond generic SBOM). Today: `wolfssl:build:*` in CycloneDX; formal CBOM: see [`ROADMAP.md`](ROADMAP.md). | +| **bomsh** | wolfSSL **make** target | Runs **OmniBOR** provenance: proves **how** the library binary was built from sources (**Linux host only**). | +| **OmniBOR** | Omni **Bill of Resources** | Merkle DAG of build inputs/outputs; stored under `omnibor/`. | +| **gitoid** | Git-object-style ID | Hash pointer (`gitoid:blob:sha1:…`) into the OmniBOR graph; appears in `omnibor.*.spdx.json`. | +| **Manufacturer** | CRA role | Entity that places the product on the EU market — **owns** product SBOM and vulnerability process. | +| **Integrator / OEM** | Industry term | You build a device/app containing wolfSSL → you typically act as **manufacturer** for your product. | +| **externalDocumentRefs** | SPDX feature | Your product SPDX **points to** wolfSSL’s SPDX file without copying every file entry. | +| **SOURCE_DATE_EPOCH** | Reproducible builds | Fixed timestamp so two `make sbom` runs produce **byte-identical** SBOMs (useful in CI/attestation). | + +--- + +## wolfSSL artefacts (what we ship) + +| Command | Outputs | Answers | +|---------|---------|---------| +| `make sbom` | `wolfssl-.spdx.json`, `.cdx.json`, `.spdx` | **What** is in wolfSSL (version, license, hashes, config flags). | +| `make bomsh` *(optional)* | `omnibor/`, `omnibor.wolfssl-.spdx.json` | **How** wolfSSL was built (source → binary traceability). | + +Embedded/custom builds: `scripts/gen-sbom` with **your** `user_settings.h` and source list — see kit +[`scripts/generate-embedded-sbom.sh`](scripts/generate-embedded-sbom.sh) and upstream [SBOM.md §1](https://github.com/wolfSSL/wolfssl/blob/master/doc/SBOM.md). + +--- + +## Your checklist + +1. **Product SBOM** in release CI (SPDX and/or CycloneDX). +2. **wolfSSL component** — reference our SBOM (`externalDocumentRefs` / CycloneDX `bom` ref) or copy the package entry; link with `STATIC_LINK` / `DYNAMIC_LINK` / `CONTAINS`. +3. **Match your build** — if `user_settings.h` or source set differs from stock, regenerate wolfSSL’s SBOM for **your** build. +4. **Commercial license** — override GPL in SBOM (`SBOM_LICENSE_OVERRIDE`) or in **your** product SBOM entry for wolfSSL; see upstream [CRA.md](https://github.com/wolfSSL/wolfssl/blob/master/doc/CRA.md). +5. **Vulnerabilities** — document your process; wolfSSL disclosure: [SECURITY-POLICY.md](https://github.com/wolfSSL/wolfssl/blob/master/SECURITY-POLICY.md). +6. **bomsh** — only if auditors or contracts ask for build-level proof beyond the SBOM (Linux CI). + +--- + +## SPDX vs CycloneDX (same job, different tools) + +| | **SPDX** | **CycloneDX** | +|---|----------|----------------| +| **Typical use** | License compliance, legal review, nested documents | Security scanners, VEX, commercial SBOM platforms | +| **wolfSSL file** | `wolfssl-.spdx.json` | `wolfssl-.cdx.json` | +| **Nesting wolfSSL** | `externalDocumentRefs` + relationship | Component + `externalReferences` type `bom` | + +You do **not** choose “CRA format” — you provide an SBOM that meets NTIA-style expectations; SPDX and CycloneDX are both widely accepted encodings. + +--- + +## Who provides what to an auditor + +| Evidence | Provided by | +|----------|-------------| +| Product SBOM (full inventory) | **Customer** | +| wolfSSL SBOM files | **wolfSSL** (customer integrates or references) | +| OmniBOR / bomsh bundle | **wolfSSL** *(optional)* | +| Vulnerability disclosure & advisories | **wolfSSL** ([security page](https://www.wolfssl.com/docs/security-vulnerabilities/)); **customer** owns product incident process | + +--- + +*wolfSSL · Part of the [CRA Evidence Kit](README.md). Questions: support@wolfssl.com* diff --git a/cra-evidence/EVIDENCE-MAP.md b/cra-evidence/EVIDENCE-MAP.md new file mode 100644 index 00000000..e00a9034 --- /dev/null +++ b/cra-evidence/EVIDENCE-MAP.md @@ -0,0 +1,70 @@ +# wolfSSL CRA Evidence Map (one page) + +**Not legal advice.** You are the **manufacturer** for your product on the EU +market; wolfSSL provides **component evidence** for the wolfSSL library only. + +--- + +## Three questions → three layers of evidence + +| Question | Layer | wolfSSL today | +|----------|-------|---------------| +| What software is in the product? | **SBOM** | `make sbom` / `gen-sbom` → SPDX + CycloneDX | +| What crypto is actually enabled? | **Crypto signals** (→ CBOM) | `wolfssl:build:*` in CycloneDX | +| How was the library binary built? | **Provenance** (optional) | `make bomsh` (Linux host only) | + +**Product SBOM** (all components) = **yours**. **wolfSSL SBOM** = nest or reference ours. + +--- + +## All the “BOMs” (today vs roadmap) + +| Name | What it lists | Owner | wolfSSL today | Roadmap | +|------|----------------|-------|---------------|---------| +| Product SBOM | Whole shipped product | **You** | — | — | +| Component SBOM | wolfSSL only | **wolfSSL** (you integrate) | **Yes** | CI / validation | +| VEX | CVE applies to your build? | **You** (+ tools) | Advisories + policy | Examples / automation | +| CBOM | Crypto algorithms / modules | **You**; we signal | **Partial** (build properties) | Formal `cryptographic-asset` | +| OmniBOR / bomsh | Source → binary graph | **wolfSSL** (optional) | **Yes** (Linux **host**) | Same | + +--- + +## Four decisions + +| Question | Answer | +|----------|--------| +| Need our own SBOM? | **Yes** — entire product | +| wolfSSL SBOM enough alone? | **No** — reference or embed in yours | +| Need bomsh for CRA? | **Usually no** | +| SPDX or CycloneDX? | **Both shipped** — use what your tools consume | + +--- + +## Your first week (Friday path) + +| When | Action | +|------|--------| +| **Today (~15 min)** | Generate wolfSSL SBOM (`make sbom` or `gen-sbom`) | +| **This week** | Add wolfSSL to **product** SBOM (see `auditor-packet/` example) | +| **Before release** | Product SBOM in CI; vulnerability owner + process | +| **If contract requires** | `make bomsh` on **Linux** CI (not macOS/Windows native) | + +--- + +## bomsh in one sentence + +**Optional.** Traces the build on a **Linux machine** (patched strace); your firmware +can run anywhere. macOS/Windows hosts → use Linux CI, WSL2, or a container. + +--- + +## Example + docs + +| Resource | Location | +|----------|----------| +| This kit | `wolfssl-examples/cra-evidence/` | +| Sample auditor folder | [`auditor-packet/`](auditor-packet/) | +| Full guide | [wolfssl/doc/CRA.md](https://github.com/wolfSSL/wolfssl/blob/master/doc/CRA.md) | +| Full glossary | [CRA-Supply-Chain-Glossary.md](CRA-Supply-Chain-Glossary.md) | + +**CTA:** 30-min CRA readiness — bring your `user_settings.h` → support@wolfssl.com diff --git a/cra-evidence/GLOSSARY.md b/cra-evidence/GLOSSARY.md new file mode 100644 index 00000000..c61eb4d1 --- /dev/null +++ b/cra-evidence/GLOSSARY.md @@ -0,0 +1,7 @@ +# Glossary + +The full terminology reference lives in this kit: + +**[CRA-Supply-Chain-Glossary.md](CRA-Supply-Chain-Glossary.md)** + +For a one-page handout, use **[EVIDENCE-MAP.md](EVIDENCE-MAP.md)**. diff --git a/cra-evidence/README.md b/cra-evidence/README.md new file mode 100644 index 00000000..9d96b2cf --- /dev/null +++ b/cra-evidence/README.md @@ -0,0 +1,226 @@ +# wolfSSL CRA Evidence Kit + +Example project and scripts for teams that ship products containing wolfSSL and +need **EU Cyber Resilience Act (CRA)**-style **software transparency** evidence. + +**This kit does not make your product “CRA compliant.”** It shows how to obtain +and nest **wolfSSL component evidence** inside **your** product SBOM and auditor +packet. + +**Not legal advice.** Map obligations to your product class and role with counsel. + +| Document | Use | +|----------|-----| +| [`EVIDENCE-MAP.md`](EVIDENCE-MAP.md) | One-page handout (presentations, PDF) | +| [`CRA-Supply-Chain-Glossary.md`](CRA-Supply-Chain-Glossary.md) | Full terminology (**self-contained in this kit**) | +| [`ROADMAP.md`](ROADMAP.md) | SBOM / CBOM / VEX / bomsh — today vs roadmap | +| [`auditor-packet/`](auditor-packet/) | Fictional **Acme Connect Gateway** + wolfSSL SBOM samples | + +**Self-contained:** all customer-facing docs live in this directory. You only need a +separate **wolfSSL source tree** (with SBOM support) to **regenerate** component SBOMs. + +--- + +## Prerequisites + +- **wolfSSL** source with SBOM support (see [wolfSSL PR / branch](#wolfssl-sbom-feature) below). + Typical layout: + + ``` + wolf/ + ├── wolfssl/ ← WOLFSSL_DIR (default: ../../wolfssl from here) + └── wolfssl-examples/ + └── cra-evidence/ ← you are here + ``` + +- **Python 3** for `scripts/gen-sbom` (embedded path) and `scripts/validate.sh`. +- **`pcpp`** (optional for embedded): install on the **same** interpreter as `python3`: + `python3 -m pip install pcpp`. If `pip install pcpp` used conda but your shell runs + `/usr/local/bin/python3`, use `CRA_PYTHON=python` or rely on the script’s automatic + **compiler `-dM -E` fallback** (no pcpp required). + +--- + +## All the “BOMs” (today vs roadmap) + +| Name | What it lists | Who owns it | wolfSSL today | Roadmap | +|------|----------------|-------------|---------------|---------| +| **Product SBOM** | Entire shipped product | **You** | — | — | +| **Component SBOM** | wolfSSL only | **wolfSSL** (you integrate) | **Yes** — SPDX 2.3 + CycloneDX 1.6 | Ongoing | +| **VEX** | Does CVE X apply to our build? | **You** | Advisories + [SECURITY-POLICY](https://github.com/wolfSSL/wolfssl/blob/master/SECURITY-POLICY.md) | Templates / automation | +| **CBOM** | Crypto algorithms / modules | **You**; we **signal** | **Partial** — `wolfssl:build:*` in CycloneDX | Formal `cryptographic-asset` | +| **OmniBOR / bomsh** | How the library binary was built | **wolfSSL** (optional) | **Yes** — Linux **host** only | Same | + +Details: [`ROADMAP.md`](ROADMAP.md). + +**Plain summary:** SBOM = what’s inside. Crypto build properties = what crypto you +compiled in (CBOM direction). bomsh = how the library was built (optional). Product +SBOM = your job. + +--- + +## Which path are you? + +| Profile | Build | Generate wolfSSL SBOM | +|---------|-------|------------------------| +| **A. Linux / server / Yocto / package** | `./configure && make` | `make sbom` in wolfSSL tree | +| **B. Embedded / RTOS / IDE** | `user_settings.h` + your Makefile / Keil / Zephyr / ESP-IDF | `./scripts/generate-embedded-sbom.sh` (kit demo) or upstream `gen-sbom` | +| **C. Commercial license** | Either | Same + `SBOM_LICENSE_OVERRIDE` or `--license-override` | + +**Every manufacturer still:** + +1. Maintains a **product SBOM** (all components). +2. **References or copies** wolfSSL’s `.spdx.json` / `.cdx.json` into it. +3. **Regenerates** wolfSSL SBOM when `user_settings.h` or your source list changes. +4. Owns **vulnerability handling** (process + owner). +5. Uses **bomsh** only if an auditor or contract requires build proof — on a **Linux** host. + +--- + +## Quick start + +### 1. Validate the bundled sample (no wolfSSL build required) + +```sh +cd wolfssl-examples/cra-evidence +./scripts/validate.sh +``` + +### 2. Regenerate component SBOMs (requires wolfSSL with `make sbom`) + +```sh +export WOLFSSL_DIR=../../wolfssl +./scripts/refresh-samples.sh # make sbom + auto-fix product SPDX checksum +``` + +Or without updating the product stub checksum: + +```sh +./scripts/generate-wolfssl-sbom.sh # default: autotools if Makefile exists +CRA_SBOM_MODE=embedded ./scripts/generate-wolfssl-sbom.sh # rarely used for packet/ +./scripts/generate-embedded-sbom.sh # writes wolfssl-component-embedded/ +``` + +**Pinned samples** in `auditor-packet/wolfssl-component/` are from **`make sbom`** +(autotools). Embedded regen produces a **different** SBOM — see +[`auditor-packet/wolfssl-component/SAMPLE-PROVENANCE.md`](auditor-packet/wolfssl-component/SAMPLE-PROVENANCE.md). + +### 3. Study the sample product packet + +Open [`auditor-packet/00-INDEX.md`](auditor-packet/00-INDEX.md) — fictional **Acme +Connect Gateway** shows CycloneDX `bom` external reference and SPDX +`externalDocumentRefs` pointing at wolfSSL’s files. + +### 4. Integrate into your real product SBOM + +Copy the pattern from `product-acme-connect-gateway.*` or follow +[wolfssl/doc/CRA.md § Integrating wolfSSL into Your Product SBOM](https://github.com/wolfSSL/wolfssl/blob/master/doc/CRA.md). + +--- + +## Your first week (Friday path) + +| When | Action | +|------|--------| +| **Today (~15 min)** | `./scripts/generate-wolfssl-sbom.sh` | +| **This week** | Add wolfSSL entry to your product SBOM (reference or copy) | +| **Before release** | Product SBOM in release CI; name vuln process owner | +| **If required** | `make bomsh` on **Linux** CI only | + +--- + +## `make bomsh` — Linux host only (simple explanation) + +`make bomsh` is **optional** for most CRA transparency needs. Use it when someone +asks: *“Prove this `libwolfssl.so` was built from these exact sources.”* + +**Why only Linux?** Bomsh runs **bomtrace3** — a patched **strace** that watches +every compiler call during a **full rebuild**. That program is built and tested on +**Linux build machines** (normal `ptrace`, no kernel patches). + +| Your situation | What to do | +|----------------|------------| +| Build on **Linux** | `make bomsh` after `make sbom` in wolfSSL | +| Build on **macOS / Windows** | Run bomsh in **Linux CI**, **WSL2**, or a **container** | +| Ship firmware to **MCU / RTOS** | **Target OS does not matter** — tracing runs on the **build host** | +| **Embedded**, no Linux in house | Use **`gen-sbom`** for SBOM on any OS; skip bomsh unless required | + +The sample packet does **not** ship `omnibor/` (large). See +[`auditor-packet/wolfssl-component/README-bomsh.md`](auditor-packet/wolfssl-component/README-bomsh.md). + +Full detail: [wolfssl/doc/SBOM.md §3](https://github.com/wolfSSL/wolfssl/blob/master/doc/SBOM.md). + +--- + +## wolfSSL SBOM feature (upstream) + +SBOM and optional bomsh provenance are developed in the main **wolfSSL** repository: + +| Item | Location | +|------|----------| +| Generator | `wolfssl/scripts/gen-sbom` | +| Autotools | `make sbom`, `make bomsh` | +| CI | `wolfssl/.github/workflows/sbom.yml` | +| Integration guide | [doc/CRA.md](https://github.com/wolfSSL/wolfssl/blob/master/doc/CRA.md) | +| Reference | [doc/SBOM.md](https://github.com/wolfSSL/wolfssl/blob/master/doc/SBOM.md) | +| Glossary (this kit) | [`CRA-Supply-Chain-Glossary.md`](CRA-Supply-Chain-Glossary.md) | + +Use a wolfSSL tree that includes the SBOM/bomsh work (e.g. branch `feat/sbom-bomsh` +/ PR integrating `make sbom` and `make bomsh`) before running the scripts here. + +Pinned sample version: see [`VERSION`](VERSION) (default **5.9.1**). + +--- + +## Embedded demo settings + +[`user_settings.h`](user_settings.h) in this directory is included when +`WOLFSSL_USER_SETTINGS` is defined for `./scripts/generate-embedded-sbom.sh`. +Production SBOMs must use **your** project's `user_settings.h` and **your** full +`--srcs` list (every wolfSSL `.c` you compile). + +--- + +## Presentation + +15-minute co-sponsor slide track: [`presentations/SLIDE-OUTLINE.md`](presentations/SLIDE-OUTLINE.md). + +Handout to attendees: print or export [`EVIDENCE-MAP.md`](EVIDENCE-MAP.md). + +--- + +## Agent skill + +For Cursor / agents: [`SKILL.md`](SKILL.md) — copy to `.cursor/skills/wolfssl-cra-evidence/` +in your workspace if desired. + +--- + +## FAQ + +**Do we need our own SBOM?** +Yes — for the whole product you place on the EU market. + +**Is wolfSSL’s SBOM enough alone?** +No — nest or reference it in your product SBOM (see `auditor-packet/`). + +**SPDX or CycloneDX?** +wolfSSL ships both; use what your tools expect. + +**Do we need bomsh for CRA?** +Usually no. SBOM alone covers most transparency asks. + +**What about CBOM?** +Many RFQs ask for crypto inventory. Today: `wolfssl:build:*` properties in +CycloneDX from your real config. Formal CycloneDX CBOM: **roadmap** — see +[`ROADMAP.md`](ROADMAP.md). + +**FIPS builds?** +The SBOM generator does not change validated module code; your FIPS boundary +documentation remains separate. + +--- + +## Support + +questions: **support@wolfssl.com** diff --git a/cra-evidence/ROADMAP.md b/cra-evidence/ROADMAP.md new file mode 100644 index 00000000..3137f62d --- /dev/null +++ b/cra-evidence/ROADMAP.md @@ -0,0 +1,17 @@ +# Supply-chain artefacts — today vs roadmap + +Honest status for customer conversations. This is **not** a commitment schedule. + +| Capability | Status | What you do today | +|--------------|--------|-------------------| +| **SBOM** (SPDX 2.3 + CycloneDX 1.6) | **Available** | `make sbom` or `scripts/gen-sbom` | +| **Config-accurate build properties** | **Available** | Read `wolfssl:build:*` in `.cdx.json` | +| **Embedded source-merkle checksum** | **Available** | `gen-sbom` with `--srcs` (no `libwolfssl.a` required) | +| **Commercial license in SBOM** | **Available** | `SBOM_LICENSE_OVERRIDE` / `--license-override` | +| **Reproducible SBOM timestamps** | **Available** | `SOURCE_DATE_EPOCH` | +| **OmniBOR / `make bomsh`** | **Available** | Linux **build host** only; optional for CRA | +| **Formal CBOM** (`cryptographic-asset`) | **Roadmap** | Use build properties + your product crypto documentation | +| **VEX templates / automation** | **Roadmap** | Your scanner + [SECURITY-POLICY](https://github.com/wolfSSL/wolfssl/blob/master/SECURITY-POLICY.md) | +| **Product SBOM tool** | **Out of scope** | Your BOM platform or manual merge | + +Upstream implementation detail: [wolfssl/doc/SBOM.md](https://github.com/wolfSSL/wolfssl/blob/master/doc/SBOM.md). diff --git a/cra-evidence/SKILL.md b/cra-evidence/SKILL.md new file mode 100644 index 00000000..b6d3831c --- /dev/null +++ b/cra-evidence/SKILL.md @@ -0,0 +1,43 @@ +--- +name: wolfssl-cra-evidence +description: >- + wolfSSL CRA Evidence Kit (wolfssl-examples/cra-evidence): self-contained docs, + auditor packet, generate/validate/refresh scripts, embedded user_settings.h demo. + Use for EU CRA transparency, make sbom, gen-sbom, SPDX, CycloneDX, bomsh Linux-only. +--- + +# wolfSSL CRA Evidence Kit (agent) + +## Scope + +- **Self-contained** in `wolfssl-examples/cra-evidence/` (glossary, Evidence Map, samples). +- wolfSSL **source tree** needed only to **regenerate** SBOMs (`WOLFSSL_DIR`). +- Never claim "CRA compliant"; **product SBOM** is always the customer's job. + +## Start here + +1. `wolfssl-examples/cra-evidence/README.md` +2. `EVIDENCE-MAP.md` (one-pager) +3. `CRA-Supply-Chain-Glossary.md` (terminology — in this kit, not wolfssl repo) +4. Upstream detail: GitHub `wolfssl/doc/CRA.md`, `doc/SBOM.md` + +## Scripts + +| Script | Purpose | +|--------|---------| +| `validate.sh` | JSON + SPDX checksum (no wolfSSL build) | +| `refresh-samples.sh` | `make sbom` + patch product SPDX checksum | +| `generate-wolfssl-sbom.sh` | `CRA_SBOM_MODE=autotools\|embedded` | +| `generate-embedded-sbom.sh` | → `auditor-packet/wolfssl-component-embedded/` | + +Embedded demo uses `cra-evidence/user_settings.h` + `WOLFSSL_USER_SETTINGS`. + +## Samples + +- Product: `auditor-packet/product-acme-connect-gateway.{spdx,cdx}.json` +- Component (autotools): `auditor-packet/wolfssl-component/` +- Embedded (optional gen): `auditor-packet/wolfssl-component-embedded/` + +## bomsh + +Optional; **Linux build host only**. Not in sample packet. diff --git a/cra-evidence/VERSION b/cra-evidence/VERSION new file mode 100644 index 00000000..b64a5e97 --- /dev/null +++ b/cra-evidence/VERSION @@ -0,0 +1,3 @@ +# Pinned wolfSSL SBOM samples under auditor-packet/wolfssl-component/ +# Regenerate with: ./scripts/generate-wolfssl-sbom.sh && ./scripts/refresh-samples.sh +WOLFSSL_VERSION=5.9.1 diff --git a/cra-evidence/auditor-packet/00-INDEX.md b/cra-evidence/auditor-packet/00-INDEX.md new file mode 100644 index 00000000..4a1e5707 --- /dev/null +++ b/cra-evidence/auditor-packet/00-INDEX.md @@ -0,0 +1,19 @@ +# Auditor packet index (fictional Acme Connect Gateway) + +Example of what a **manufacturer** might bundle alongside wolfSSL component +artefacts. **Not legal advice** — adapt to your product and counsel. + +| File | Role | +|------|------| +| `product-acme-connect-gateway.cdx.json` | **Your** product SBOM (CycloneDX) — references wolfSSL | +| `product-acme-connect-gateway.spdx.json` | **Your** product SBOM (SPDX) — `externalDocumentRefs` to wolfSSL | +| `wolfssl-component/wolfssl-5.9.1.cdx.json` | wolfSSL component SBOM — **autotools / make sbom** sample | +| `wolfssl-component/wolfssl-5.9.1.spdx.json` | wolfSSL component SBOM (SPDX) | +| `wolfssl-component/SAMPLE-PROVENANCE.md` | How the pinned autotools samples were produced | +| `wolfssl-component-embedded/` | Optional embedded `gen-sbom` output (generate locally) | +| `wolfssl-component/README-bomsh.md` | Optional OmniBOR — not included by default | + +Also provide: your vulnerability process, release notes, and +[wolfSSL SECURITY-POLICY](https://github.com/wolfSSL/wolfssl/blob/master/SECURITY-POLICY.md). + +**Regenerate autotools samples + product checksum:** `./scripts/refresh-samples.sh` diff --git a/cra-evidence/auditor-packet/README-auditor-packet.md b/cra-evidence/auditor-packet/README-auditor-packet.md new file mode 100644 index 00000000..fd3e8e26 --- /dev/null +++ b/cra-evidence/auditor-packet/README-auditor-packet.md @@ -0,0 +1,9 @@ +# Sample auditor packet + +This directory is a **teaching example** only. **Acme Industries** and +**acme-connect-gateway** are fictional. + +It shows how a **product SBOM** references wolfSSL’s **component SBOM** in +both CycloneDX and SPDX forms. + +See [`00-INDEX.md`](00-INDEX.md) for the file list. diff --git a/cra-evidence/auditor-packet/product-acme-connect-gateway.cdx.json b/cra-evidence/auditor-packet/product-acme-connect-gateway.cdx.json new file mode 100644 index 00000000..f4a09f80 --- /dev/null +++ b/cra-evidence/auditor-packet/product-acme-connect-gateway.cdx.json @@ -0,0 +1,40 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "serialNumber": "urn:uuid:acme-connect-gateway-1.0.0-cdx-example", + "version": 1, + "metadata": { + "timestamp": "2026-05-18T12:00:00Z", + "component": { + "type": "firmware", + "bom-ref": "acme-connect-gateway-1.0.0", + "name": "acme-connect-gateway", + "version": "1.0.0", + "supplier": { "name": "Acme Industries (fictional example)" } + } + }, + "components": [ + { + "type": "library", + "bom-ref": "wolfssl-5.9.1", + "name": "wolfssl", + "version": "5.9.1", + "purl": "pkg:generic/wolfssl@5.9.1", + "cpe": "cpe:2.3:a:wolfssl:wolfssl:5.9.1:*:*:*:*:*:*:*", + "externalReferences": [ + { + "type": "bom", + "url": "file:wolfssl-component/wolfssl-5.9.1.cdx.json", + "comment": "Component SBOM from wolfSSL; regenerate with scripts/generate-wolfssl-sbom.sh" + } + ] + } + ], + "dependencies": [ + { + "ref": "acme-connect-gateway-1.0.0", + "dependsOn": ["wolfssl-5.9.1"] + } + ] +} diff --git a/cra-evidence/auditor-packet/product-acme-connect-gateway.spdx.json b/cra-evidence/auditor-packet/product-acme-connect-gateway.spdx.json new file mode 100644 index 00000000..483b46ae --- /dev/null +++ b/cra-evidence/auditor-packet/product-acme-connect-gateway.spdx.json @@ -0,0 +1,46 @@ +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "acme-connect-gateway-1.0.0", + "documentNamespace": "urn:uuid:acme-connect-gateway-1.0.0-spdx-example", + "creationInfo": { + "creators": [ + "Organization: Acme Industries (fictional example)" + ], + "created": "2026-05-18T12:00:00Z" + }, + "externalDocumentRefs": [ + { + "externalDocumentId": "DocumentRef-wolfssl", + "spdxDocument": "file:wolfssl-component/wolfssl-5.9.1.spdx.json", + "checksum": { + "algorithm": "SHA256", + "checksumValue": "4ec1a3488f714aea0f15c9f455b9a05875c4894a7f65f6ee5a07a33612516b9e" + } + } + ], + "packages": [ + { + "SPDXID": "SPDXRef-Package-Product", + "name": "acme-connect-gateway", + "versionInfo": "1.0.0", + "supplier": "Organization: Acme Industries", + "downloadLocation": "NOASSERTION", + "filesAnalyzed": false + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package-Product", + "relationshipType": "DESCRIBES" + }, + { + "spdxElementId": "SPDXRef-Package-Product", + "relatedSpdxElement": "DocumentRef-wolfssl:SPDXRef-Package-wolfssl", + "relationshipType": "STATIC_LINK", + "comment": "Fictional embedded firmware links wolfSSL statically; use DYNAMIC_LINK for .so" + } + ] +} diff --git a/cra-evidence/auditor-packet/wolfssl-component-embedded/README.md b/cra-evidence/auditor-packet/wolfssl-component-embedded/README.md new file mode 100644 index 00000000..188f06ca --- /dev/null +++ b/cra-evidence/auditor-packet/wolfssl-component-embedded/README.md @@ -0,0 +1,19 @@ +# Embedded component SBOM (optional sample) + +This directory is **empty in git** until you generate an embedded-profile SBOM. + +```sh +export WOLFSSL_DIR=../../wolfssl # wolfSSL tree with scripts/gen-sbom +python3 -m pip install pcpp # same python3 as in your PATH (see README) +./scripts/generate-embedded-sbom.sh +``` + +If pcpp is not on your `python3`, the script falls back to `cc -dM -E` and `--options-h` +(no extra install). + +Uses [`../../user_settings.h`](../../user_settings.h) via `WOLFSSL_USER_SETTINGS` and a +**demo** `--srcs` list (see `scripts/generate-wolfssl-sbom.sh`). Production firmware +must pass **your** `user_settings.h` and **every** wolfSSL `.c` file you compile. + +Outputs differ from [`../wolfssl-component/`](../wolfssl-component/) (autotools / +`make sbom`). Compare `wolfssl:sbom:hash-kind` in the CycloneDX files. diff --git a/cra-evidence/auditor-packet/wolfssl-component-embedded/wolfssl-5.9.1.cdx.json b/cra-evidence/auditor-packet/wolfssl-component-embedded/wolfssl-5.9.1.cdx.json new file mode 100644 index 00000000..46c2ea12 --- /dev/null +++ b/cra-evidence/auditor-packet/wolfssl-component-embedded/wolfssl-5.9.1.cdx.json @@ -0,0 +1,328 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "serialNumber": "urn:uuid:bbd8fa2c-814a-5921-b121-e872fe1b42a2", + "version": 1, + "metadata": { + "timestamp": "2026-05-18T11:56:58Z", + "tools": { + "components": [ + { + "type": "application", + "author": "wolfSSL Inc.", + "name": "wolfssl-sbom-gen", + "version": "1.0" + } + ] + }, + "component": { + "bom-ref": "721ce791-b9c8-5edf-a9d2-ef3b0539043b", + "type": "library", + "supplier": { + "name": "wolfSSL Inc." + }, + "name": "wolfssl", + "version": "5.9.1", + "licenses": [ + { + "license": { + "id": "GPL-3.0-only" + } + } + ], + "copyright": "Copyright (C) 2006-2026 wolfSSL Inc.", + "cpe": "cpe:2.3:a:wolfssl:wolfssl:5.9.1:*:*:*:*:*:*:*", + "purl": "pkg:generic/wolfssl@5.9.1", + "hashes": [ + { + "alg": "SHA-256", + "content": "3538981aad331ad5cd160abd2b51ce0a5fa1a58b3c51f990e08ca91bb44627a0" + } + ], + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/wolfSSL/wolfssl" + } + ], + "properties": [ + { + "name": "wolfssl:build:AES_MAX_KEY_SIZE", + "value": "256" + }, + { + "name": "wolfssl:build:DH_MAX_SIZE", + "value": "WC_BITS_FULL_BYTES(SP_INT_BITS)" + }, + { + "name": "wolfssl:build:ECC_DECODE_EXTRA", + "value": "1" + }, + { + "name": "wolfssl:build:ECC_MIN_KEY_SZ", + "value": "224" + }, + { + "name": "wolfssl:build:FLASH_QUALIFIER", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_AESGCM", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_AES_CBC", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_AES_DECRYPT", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_ALL_CURVES", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_ECC", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_ECC_CHECK_KEY", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_ECC_DHE", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_ECC_KEY_EXPORT", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_ECC_KEY_IMPORT", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_ECC_SIGN", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_ECC_VERIFY", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_PBKDF1", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_PBKDF2", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_PKCS12", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_PKCS8", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_PUBLIC_FFDHE", + "value": "1" + }, + { + "name": "wolfssl:build:LIBWOLFSSL_CMAKE_OUTPUT", + "value": "\"\"" + }, + { + "name": "wolfssl:build:MIN_FFDHE_BITS", + "value": "0" + }, + { + "name": "wolfssl:build:MIN_FFDHE_FP_MAX_BITS", + "value": "(MIN_FFDHE_BITS * 2)" + }, + { + "name": "wolfssl:build:NO_OLD_TLS", + "value": "1" + }, + { + "name": "wolfssl:build:NO_PSK", + "value": "1" + }, + { + "name": "wolfssl:build:NO_RC4", + "value": "1" + }, + { + "name": "wolfssl:build:NO_XSTREAM_ALIGN", + "value": "1" + }, + { + "name": "wolfssl:build:RSA_DECODE_EXTRA", + "value": "1" + }, + { + "name": "wolfssl:build:USE_WOLFSSL_MEMORY", + "value": "1" + }, + { + "name": "wolfssl:build:WC_ASYNC_DEV_SIZE", + "value": "0" + }, + { + "name": "wolfssl:build:WC_TEST_NO_ECC_SIGN_VERIFY_ZERO_DIGEST", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_ABI", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_AES_128", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_AES_192", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_AES_256", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_ALERT_COUNT_MAX", + "value": "5" + }, + { + "name": "wolfssl:build:WOLFSSL_API", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_ASN_TEMPLATE", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_ASYNC_IO", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_BASE64_DECODE", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_FIPS_VERSION2_CODE", + "value": "WOLFSSL_FIPS_VERSION_CODE" + }, + { + "name": "wolfssl:build:WOLFSSL_FIPS_VERSION_CODE", + "value": "WOLFSSL_MAKE_FIPS_VERSION3(0,0,0)" + }, + { + "name": "wolfssl:build:WOLFSSL_GENERAL_ALIGNMENT", + "value": "0" + }, + { + "name": "wolfssl:build:WOLFSSL_HAVE_PRF", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_LOCAL", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_MAX_EMPTY_RECORDS", + "value": "32" + }, + { + "name": "wolfssl:build:WOLFSSL_MIN_AUTH_TAG_SZ", + "value": "12" + }, + { + "name": "wolfssl:build:WOLFSSL_PEM_TO_DER", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SMALL_STACK_STATIC", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SP_ADD_D", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SP_INVMOD", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SP_INVMOD_MONT_CT", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SP_MATH_ALL", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SP_MUL_D", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SP_NO_DYN_STACK", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SP_PRIME_GEN", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SP_READ_RADIX_10", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SP_READ_RADIX_16", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SP_SUB_D", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_TEST_VIS", + "value": "WOLFSSL_API WC_DEPRECATED(\"internal use only\")" + }, + { + "name": "wolfssl:build:WOLFSSL_TLS13", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_USER_SETTINGS", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_W64_WRAPPER", + "value": "1" + }, + { + "name": "wolfssl:build:XGEN_ALIGN", + "value": "1" + }, + { + "name": "wolfssl:sbom:hash-kind", + "value": "source-merkle-omnibor" + }, + { + "name": "wolfssl:sbom:source-set", + "value": "aes.c,ecc.c,keys.c,random.c,sha.c,sha256.c,tls.c,tls13.c,wc_port.c" + } + ] + } + }, + "components": [], + "dependencies": [ + { + "ref": "721ce791-b9c8-5edf-a9d2-ef3b0539043b", + "dependsOn": [] + } + ] +} diff --git a/cra-evidence/auditor-packet/wolfssl-component-embedded/wolfssl-5.9.1.spdx.json b/cra-evidence/auditor-packet/wolfssl-component-embedded/wolfssl-5.9.1.spdx.json new file mode 100644 index 00000000..a166573f --- /dev/null +++ b/cra-evidence/auditor-packet/wolfssl-component-embedded/wolfssl-5.9.1.spdx.json @@ -0,0 +1,53 @@ +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "wolfssl-5.9.1", + "documentNamespace": "urn:uuid:480ff203-f994-5b71-b858-0653e74e422a", + "creationInfo": { + "creators": [ + "Organization: wolfSSL Inc.", + "Tool: wolfssl-sbom-gen-1.0" + ], + "created": "2026-05-18T11:56:58Z" + }, + "packages": [ + { + "SPDXID": "SPDXRef-Package-wolfssl", + "name": "wolfssl", + "versionInfo": "5.9.1", + "supplier": "Organization: wolfSSL Inc.", + "downloadLocation": "https://github.com/wolfSSL/wolfssl", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA256", + "checksumValue": "3538981aad331ad5cd160abd2b51ce0a5fa1a58b3c51f990e08ca91bb44627a0" + } + ], + "licenseConcluded": "GPL-3.0-only", + "licenseDeclared": "GPL-3.0-only", + "copyrightText": "Copyright (C) 2006-2026 wolfSSL Inc.", + "comment": "Build configuration defines: AES_MAX_KEY_SIZE, DH_MAX_SIZE, ECC_DECODE_EXTRA, ECC_MIN_KEY_SZ, FLASH_QUALIFIER, HAVE_AESGCM, HAVE_AES_CBC, HAVE_AES_DECRYPT, HAVE_ALL_CURVES, HAVE_ECC, HAVE_ECC_CHECK_KEY, HAVE_ECC_DHE, HAVE_ECC_KEY_EXPORT, HAVE_ECC_KEY_IMPORT, HAVE_ECC_SIGN, HAVE_ECC_VERIFY, HAVE_PBKDF1, HAVE_PBKDF2, HAVE_PKCS12, HAVE_PKCS8, HAVE_PUBLIC_FFDHE, LIBWOLFSSL_CMAKE_OUTPUT, MIN_FFDHE_BITS, MIN_FFDHE_FP_MAX_BITS, NO_OLD_TLS, NO_PSK, NO_RC4, NO_XSTREAM_ALIGN, RSA_DECODE_EXTRA, USE_WOLFSSL_MEMORY, WC_ASYNC_DEV_SIZE, WC_TEST_NO_ECC_SIGN_VERIFY_ZERO_DIGEST, WOLFSSL_ABI, WOLFSSL_AES_128, WOLFSSL_AES_192, WOLFSSL_AES_256, WOLFSSL_ALERT_COUNT_MAX, WOLFSSL_API, WOLFSSL_ASN_TEMPLATE, WOLFSSL_ASYNC_IO, WOLFSSL_BASE64_DECODE, WOLFSSL_FIPS_VERSION2_CODE, WOLFSSL_FIPS_VERSION_CODE, WOLFSSL_GENERAL_ALIGNMENT, WOLFSSL_HAVE_PRF, WOLFSSL_LOCAL, WOLFSSL_MAX_EMPTY_RECORDS, WOLFSSL_MIN_AUTH_TAG_SZ, WOLFSSL_PEM_TO_DER, WOLFSSL_SMALL_STACK_STATIC, WOLFSSL_SP_ADD_D, WOLFSSL_SP_INVMOD, WOLFSSL_SP_INVMOD_MONT_CT, WOLFSSL_SP_MATH_ALL, WOLFSSL_SP_MUL_D, WOLFSSL_SP_NO_DYN_STACK, WOLFSSL_SP_PRIME_GEN, WOLFSSL_SP_READ_RADIX_10, WOLFSSL_SP_READ_RADIX_16, WOLFSSL_SP_SUB_D, WOLFSSL_TEST_VIS, WOLFSSL_TLS13, WOLFSSL_USER_SETTINGS, WOLFSSL_W64_WRAPPER, XGEN_ALIGN | hash-kind=source-merkle-omnibor | source-set=aes.c,ecc.c,keys.c,random.c,sha.c,sha256.c,tls.c,tls13.c,wc_port.c", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:wolfssl:wolfssl:5.9.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:generic/wolfssl@5.9.1" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package-wolfssl", + "relationshipType": "DESCRIBES" + } + ] +} diff --git a/cra-evidence/auditor-packet/wolfssl-component/README-bomsh.md b/cra-evidence/auditor-packet/wolfssl-component/README-bomsh.md new file mode 100644 index 00000000..4ff6d893 --- /dev/null +++ b/cra-evidence/auditor-packet/wolfssl-component/README-bomsh.md @@ -0,0 +1,21 @@ +# Optional: OmniBOR / bomsh bundle + +`make bomsh` is **not** included in this sample packet. Most CRA transparency +workflows need the SBOM files only. + +When an auditor or contract requires **build provenance**: + +1. On a **Linux** build host (or Linux CI / WSL2 / container), in your wolfSSL tree: + ```sh + ./configure && make sbom && make bomsh + ``` +2. Add to your release bundle: + - `omnibor/` directory + - `omnibor.wolfssl-.spdx.json` + +**Why Linux only?** `bomsh` uses `bomtrace3`, a patched `strace` that records +compiler invocations during a full rebuild. That tooling is built and supported +on Linux hosts. The **target** of your firmware (MCU, RTOS, etc.) does not need +to run Linux — only the machine **tracing the build** does. + +Details: [wolfssl/doc/SBOM.md §3](https://github.com/wolfSSL/wolfssl/blob/master/doc/SBOM.md) diff --git a/cra-evidence/auditor-packet/wolfssl-component/SAMPLE-PROVENANCE.md b/cra-evidence/auditor-packet/wolfssl-component/SAMPLE-PROVENANCE.md new file mode 100644 index 00000000..4e6419b4 --- /dev/null +++ b/cra-evidence/auditor-packet/wolfssl-component/SAMPLE-PROVENANCE.md @@ -0,0 +1,21 @@ +# Sample provenance + +Pinned files in this directory (`wolfssl-5.9.1.cdx.json`, `wolfssl-5.9.1.spdx.json`) +were produced with the **autotools** path: + +```sh +cd "$WOLFSSL_DIR" && ./configure && make sbom +``` + +They reflect a **configured library build** (SHA-256 of `libwolfssl` and full +`wolfssl:build:*` properties from `options.h`). + +They are **not** the same as the **embedded** demo under +[`../wolfssl-component-embedded/`](../wolfssl-component-embedded/), which uses +`user_settings.h` and a trimmed `--srcs` list (source-merkle checksum). + +Regenerate autotools samples and fix the product stub checksum: + +```sh +./scripts/refresh-samples.sh +``` diff --git a/cra-evidence/auditor-packet/wolfssl-component/wolfssl-5.9.1.cdx.json b/cra-evidence/auditor-packet/wolfssl-component/wolfssl-5.9.1.cdx.json new file mode 100644 index 00000000..48f4064a --- /dev/null +++ b/cra-evidence/auditor-packet/wolfssl-component/wolfssl-5.9.1.cdx.json @@ -0,0 +1,300 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "serialNumber": "urn:uuid:bbd8fa2c-814a-5921-b121-e872fe1b42a2", + "version": 1, + "metadata": { + "timestamp": "2026-05-12T16:59:40Z", + "tools": { + "components": [ + { + "type": "application", + "author": "wolfSSL Inc.", + "name": "wolfssl-sbom-gen", + "version": "1.0" + } + ] + }, + "component": { + "bom-ref": "721ce791-b9c8-5edf-a9d2-ef3b0539043b", + "type": "library", + "supplier": { + "name": "wolfSSL Inc." + }, + "name": "wolfssl", + "version": "5.9.1", + "licenses": [ + { + "license": { + "id": "GPL-3.0-only" + } + } + ], + "copyright": "Copyright (C) 2006-2026 wolfSSL Inc.", + "cpe": "cpe:2.3:a:wolfssl:wolfssl:5.9.1:*:*:*:*:*:*:*", + "purl": "pkg:generic/wolfssl@5.9.1", + "hashes": [ + { + "alg": "SHA-256", + "content": "391e86477f5eee025e677a24b13e2d9a4d3e4c18d88e6359853ebf1c9932279e" + } + ], + "externalReferences": [ + { + "type": "vcs", + "url": "https://github.com/wolfSSL/wolfssl" + } + ], + "properties": [ + { + "name": "wolfssl:build:ECC_MIN_KEY_SZ", + "value": "224" + }, + { + "name": "wolfssl:build:ECC_SHAMIR", + "value": "1" + }, + { + "name": "wolfssl:build:ECC_TIMING_RESISTANT", + "value": "1" + }, + { + "name": "wolfssl:build:ERROR_QUEUE_PER_THREAD", + "value": "1" + }, + { + "name": "wolfssl:build:GCM_TABLE_4BIT", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_AESGCM", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_CHACHA", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_C___ATOMIC", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_DH_DEFAULT_PARAMS", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_ECC", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_ENCRYPT_THEN_MAC", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_EXTENDED_MASTER", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_FFDHE_2048", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_GETPID", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_HASHDRBG", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_HKDF", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_POLY1305", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_SERVER_RENEGOTIATION_INFO", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_SNI", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_SUPPORTED_CURVES", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_THREAD_LS", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_TLS_EXTENSIONS", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE_WC_INTROSPECTION", + "value": "1" + }, + { + "name": "wolfssl:build:HAVE___UINT128_T", + "value": "1" + }, + { + "name": "wolfssl:build:NO_DES3", + "value": "1" + }, + { + "name": "wolfssl:build:NO_DES3_TLS_SUITES", + "value": "1" + }, + { + "name": "wolfssl:build:NO_DO178", + "value": "1" + }, + { + "name": "wolfssl:build:NO_DSA", + "value": "1" + }, + { + "name": "wolfssl:build:NO_MD4", + "value": "1" + }, + { + "name": "wolfssl:build:NO_MD5", + "value": "1" + }, + { + "name": "wolfssl:build:NO_OLD_TLS", + "value": "1" + }, + { + "name": "wolfssl:build:NO_PSK", + "value": "1" + }, + { + "name": "wolfssl:build:NO_RC4", + "value": "1" + }, + { + "name": "wolfssl:build:TFM_TIMING_RESISTANT", + "value": "1" + }, + { + "name": "wolfssl:build:WC_NO_ASYNC_THREADING", + "value": "1" + }, + { + "name": "wolfssl:build:WC_RSA_BLINDING", + "value": "1" + }, + { + "name": "wolfssl:build:WC_RSA_PSS", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_ARMASM_NO_HW_CRYPTO", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_ASN_PRINT", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_ASN_TEMPLATE", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_BASE64_ENCODE", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_DRBG_SHA512", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_HAVE_ASSERT_H", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_HAVE_ATOMIC_H", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_HAVE_MLKEM", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_PQC_HYBRIDS", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_PSS_LONG_SALT", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SHA224", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SHA3", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SHA384", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SHA512", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SHAKE128", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SHAKE256", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SP_MATH_ALL", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SP_X86_64", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_SYS_CA_CERTS", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_TLS13", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_TLS_NO_MLKEM_STANDALONE", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_USE_ALIGN", + "value": "1" + }, + { + "name": "wolfssl:build:WOLFSSL_X86_64_BUILD", + "value": "1" + } + ] + } + }, + "components": [], + "dependencies": [ + { + "ref": "721ce791-b9c8-5edf-a9d2-ef3b0539043b", + "dependsOn": [] + } + ] +} diff --git a/cra-evidence/auditor-packet/wolfssl-component/wolfssl-5.9.1.spdx b/cra-evidence/auditor-packet/wolfssl-component/wolfssl-5.9.1.spdx new file mode 100644 index 00000000..85242500 --- /dev/null +++ b/cra-evidence/auditor-packet/wolfssl-component/wolfssl-5.9.1.spdx @@ -0,0 +1,30 @@ +## Document Information +SPDXVersion: SPDX-2.3 +DataLicense: CC0-1.0 +SPDXID: SPDXRef-DOCUMENT +DocumentName: wolfssl-5.9.1 +DocumentNamespace: urn:uuid:480ff203-f994-5b71-b858-0653e74e422a + +## Creation Information +Creator: Organization: wolfSSL Inc. +Creator: Tool: wolfssl-sbom-gen-1.0 +Created: 2026-05-12T16:59:40Z + +## Package Information +PackageName: wolfssl +SPDXID: SPDXRef-Package-wolfssl +PackageVersion: 5.9.1 +PackageSupplier: Organization: wolfSSL Inc. +PackageDownloadLocation: https://github.com/wolfSSL/wolfssl +FilesAnalyzed: false +PackageChecksum: SHA256: 391e86477f5eee025e677a24b13e2d9a4d3e4c18d88e6359853ebf1c9932279e +PackageLicenseConcluded: GPL-3.0-only +PackageLicenseDeclared: GPL-3.0-only +PackageCopyrightText: Copyright (C) 2006-2026 wolfSSL Inc. +PackageComment: Build configuration defines: ECC_MIN_KEY_SZ, ECC_SHAMIR, ECC_TIMING_RESISTANT, ERROR_QUEUE_PER_THREAD, GCM_TABLE_4BIT, HAVE_AESGCM, HAVE_CHACHA, HAVE_C___ATOMIC, HAVE_DH_DEFAULT_PARAMS, HAVE_ECC, HAVE_ENCRYPT_THEN_MAC, HAVE_EXTENDED_MASTER, HAVE_FFDHE_2048, HAVE_GETPID, HAVE_HASHDRBG, HAVE_HKDF, HAVE_POLY1305, HAVE_SERVER_RENEGOTIATION_INFO, HAVE_SNI, HAVE_SUPPORTED_CURVES, HAVE_THREAD_LS, HAVE_TLS_EXTENSIONS, HAVE_WC_INTROSPECTION, HAVE___UINT128_T, NO_DES3, NO_DES3_TLS_SUITES, NO_DO178, NO_DSA, NO_MD4, NO_MD5, NO_OLD_TLS, NO_PSK, NO_RC4, TFM_TIMING_RESISTANT, WC_NO_ASYNC_THREADING, WC_RSA_BLINDING, WC_RSA_PSS, WOLFSSL_ARMASM_NO_HW_CRYPTO, WOLFSSL_ASN_PRINT, WOLFSSL_ASN_TEMPLATE, WOLFSSL_BASE64_ENCODE, WOLFSSL_DRBG_SHA512, WOLFSSL_HAVE_ASSERT_H, WOLFSSL_HAVE_ATOMIC_H, WOLFSSL_HAVE_MLKEM, WOLFSSL_PQC_HYBRIDS, WOLFSSL_PSS_LONG_SALT, WOLFSSL_SHA224, WOLFSSL_SHA3, WOLFSSL_SHA384, WOLFSSL_SHA512, WOLFSSL_SHAKE128, WOLFSSL_SHAKE256, WOLFSSL_SP_MATH_ALL, WOLFSSL_SP_X86_64, WOLFSSL_SYS_CA_CERTS, WOLFSSL_TLS13, WOLFSSL_TLS_NO_MLKEM_STANDALONE, WOLFSSL_USE_ALIGN, WOLFSSL_X86_64_BUILD +ExternalRef: SECURITY cpe23Type cpe:2.3:a:wolfssl:wolfssl:5.9.1:*:*:*:*:*:*:* +ExternalRef: PACKAGE-MANAGER purl pkg:generic/wolfssl@5.9.1 + +## Relationships +Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-Package-wolfssl + diff --git a/cra-evidence/auditor-packet/wolfssl-component/wolfssl-5.9.1.spdx.json b/cra-evidence/auditor-packet/wolfssl-component/wolfssl-5.9.1.spdx.json new file mode 100644 index 00000000..05e8e7c8 --- /dev/null +++ b/cra-evidence/auditor-packet/wolfssl-component/wolfssl-5.9.1.spdx.json @@ -0,0 +1,53 @@ +{ + "spdxVersion": "SPDX-2.3", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "wolfssl-5.9.1", + "documentNamespace": "urn:uuid:480ff203-f994-5b71-b858-0653e74e422a", + "creationInfo": { + "creators": [ + "Organization: wolfSSL Inc.", + "Tool: wolfssl-sbom-gen-1.0" + ], + "created": "2026-05-12T16:59:40Z" + }, + "packages": [ + { + "SPDXID": "SPDXRef-Package-wolfssl", + "name": "wolfssl", + "versionInfo": "5.9.1", + "supplier": "Organization: wolfSSL Inc.", + "downloadLocation": "https://github.com/wolfSSL/wolfssl", + "filesAnalyzed": false, + "checksums": [ + { + "algorithm": "SHA256", + "checksumValue": "391e86477f5eee025e677a24b13e2d9a4d3e4c18d88e6359853ebf1c9932279e" + } + ], + "licenseConcluded": "GPL-3.0-only", + "licenseDeclared": "GPL-3.0-only", + "copyrightText": "Copyright (C) 2006-2026 wolfSSL Inc.", + "comment": "Build configuration defines: ECC_MIN_KEY_SZ, ECC_SHAMIR, ECC_TIMING_RESISTANT, ERROR_QUEUE_PER_THREAD, GCM_TABLE_4BIT, HAVE_AESGCM, HAVE_CHACHA, HAVE_C___ATOMIC, HAVE_DH_DEFAULT_PARAMS, HAVE_ECC, HAVE_ENCRYPT_THEN_MAC, HAVE_EXTENDED_MASTER, HAVE_FFDHE_2048, HAVE_GETPID, HAVE_HASHDRBG, HAVE_HKDF, HAVE_POLY1305, HAVE_SERVER_RENEGOTIATION_INFO, HAVE_SNI, HAVE_SUPPORTED_CURVES, HAVE_THREAD_LS, HAVE_TLS_EXTENSIONS, HAVE_WC_INTROSPECTION, HAVE___UINT128_T, NO_DES3, NO_DES3_TLS_SUITES, NO_DO178, NO_DSA, NO_MD4, NO_MD5, NO_OLD_TLS, NO_PSK, NO_RC4, TFM_TIMING_RESISTANT, WC_NO_ASYNC_THREADING, WC_RSA_BLINDING, WC_RSA_PSS, WOLFSSL_ARMASM_NO_HW_CRYPTO, WOLFSSL_ASN_PRINT, WOLFSSL_ASN_TEMPLATE, WOLFSSL_BASE64_ENCODE, WOLFSSL_DRBG_SHA512, WOLFSSL_HAVE_ASSERT_H, WOLFSSL_HAVE_ATOMIC_H, WOLFSSL_HAVE_MLKEM, WOLFSSL_PQC_HYBRIDS, WOLFSSL_PSS_LONG_SALT, WOLFSSL_SHA224, WOLFSSL_SHA3, WOLFSSL_SHA384, WOLFSSL_SHA512, WOLFSSL_SHAKE128, WOLFSSL_SHAKE256, WOLFSSL_SP_MATH_ALL, WOLFSSL_SP_X86_64, WOLFSSL_SYS_CA_CERTS, WOLFSSL_TLS13, WOLFSSL_TLS_NO_MLKEM_STANDALONE, WOLFSSL_USE_ALIGN, WOLFSSL_X86_64_BUILD", + "externalRefs": [ + { + "referenceCategory": "SECURITY", + "referenceType": "cpe23Type", + "referenceLocator": "cpe:2.3:a:wolfssl:wolfssl:5.9.1:*:*:*:*:*:*:*" + }, + { + "referenceCategory": "PACKAGE-MANAGER", + "referenceType": "purl", + "referenceLocator": "pkg:generic/wolfssl@5.9.1" + } + ] + } + ], + "relationships": [ + { + "spdxElementId": "SPDXRef-DOCUMENT", + "relatedSpdxElement": "SPDXRef-Package-wolfssl", + "relationshipType": "DESCRIBES" + } + ] +} diff --git a/cra-evidence/scripts/generate-embedded-sbom.sh b/cra-evidence/scripts/generate-embedded-sbom.sh new file mode 100755 index 00000000..dafc32f5 --- /dev/null +++ b/cra-evidence/scripts/generate-embedded-sbom.sh @@ -0,0 +1,9 @@ +#!/bin/sh +# Force embedded gen-sbom (user_settings.h + --srcs) into wolfssl-component-embedded/. +set -eu + +SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +KIT_DIR=$(dirname "$SCRIPT_DIR") +export CRA_SBOM_MODE=embedded +export CRA_SBOM_OUT_DIR="$KIT_DIR/auditor-packet/wolfssl-component-embedded" +exec "$SCRIPT_DIR/generate-wolfssl-sbom.sh" diff --git a/cra-evidence/scripts/generate-wolfssl-sbom.sh b/cra-evidence/scripts/generate-wolfssl-sbom.sh new file mode 100755 index 00000000..561f57d5 --- /dev/null +++ b/cra-evidence/scripts/generate-wolfssl-sbom.sh @@ -0,0 +1,162 @@ +#!/bin/sh +# Generate wolfSSL component SBOMs (autotools make sbom or embedded gen-sbom). +# CRA_SBOM_MODE=autotools|embedded (default: autotools if configure+Makefile exist) +# WOLFSSL_DIR=path/to/wolfssl +# CRA_PYTHON=python3 (optional: interpreter with pcpp for embedded path) +set -eu + +SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +KIT_DIR=$(dirname "$SCRIPT_DIR") +WOLFSSL_DIR=${WOLFSSL_DIR:-$(cd "$KIT_DIR/../../wolfssl" 2>/dev/null && pwd || true)} +OUT_DIR=${CRA_SBOM_OUT_DIR:-"$KIT_DIR/auditor-packet/wolfssl-component"} +VERSION_FILE="$KIT_DIR/VERSION" + +if [ -z "${WOLFSSL_DIR:-}" ] || [ ! -d "$WOLFSSL_DIR" ]; then + echo "ERROR: wolfSSL source not found." >&2 + echo " Set WOLFSSL_DIR to your wolfssl checkout (sibling of wolfssl-examples)." >&2 + exit 1 +fi + +# shellcheck disable=SC1090 +. "$VERSION_FILE" 2>/dev/null || true +VERSION=${WOLFSSL_VERSION:-5.9.1} + +mkdir -p "$OUT_DIR" +CDX_OUT="$OUT_DIR/wolfssl-${VERSION}.cdx.json" +SPDX_OUT="$OUT_DIR/wolfssl-${VERSION}.spdx.json" + +echo "wolfSSL tree: $WOLFSSL_DIR" +echo "Outputs: $CDX_OUT" +echo " $SPDX_OUT" + +# Pick a Python that can `import pcpp` (pip may target a different python3 than /usr/local/bin). +_python_with_pcpp() { + for py in ${CRA_PYTHON:-} python3 python; do + [ -n "$py" ] || continue + if command -v "$py" >/dev/null 2>&1 && \ + "$py" -c "import pcpp" 2>/dev/null; then + echo "$py" + return 0 + fi + done + return 1 +} + +_embedded_srcs() { + # Demo list only — production SBOMs must mirror every wolfSSL .c on your link line. + for f in \ + "$WOLFSSL_DIR/wolfcrypt/src/aes.c" \ + "$WOLFSSL_DIR/wolfcrypt/src/sha.c" \ + "$WOLFSSL_DIR/wolfcrypt/src/sha256.c" \ + "$WOLFSSL_DIR/wolfcrypt/src/random.c" \ + "$WOLFSSL_DIR/wolfcrypt/src/ecc.c" \ + "$WOLFSSL_DIR/wolfcrypt/src/wc_port.c" \ + "$WOLFSSL_DIR/src/tls.c" \ + "$WOLFSSL_DIR/src/tls13.c" \ + "$WOLFSSL_DIR/src/keys.c" + do + if [ -f "$f" ]; then + echo "$f" + fi + done +} + +_run_embedded() { + echo "==> Embedded path: gen-sbom with cra-evidence user_settings.h" + if [ ! -f "$KIT_DIR/user_settings.h" ]; then + echo "ERROR: $KIT_DIR/user_settings.h missing (demo settings for WOLFSSL_USER_SETTINGS)." >&2 + exit 1 + fi + GEN="$WOLFSSL_DIR/scripts/gen-sbom" + if [ ! -f "$GEN" ]; then + echo "ERROR: $GEN not found (need wolfSSL with SBOM support)." >&2 + exit 1 + fi + + SETTINGS_H="$WOLFSSL_DIR/wolfssl/wolfcrypt/settings.h" + if [ ! -f "$SETTINGS_H" ]; then + echo "ERROR: $SETTINGS_H not found." >&2 + exit 1 + fi + + # shellcheck disable=SC2046 + set -- $( _embedded_srcs ) + + if _py=$(_python_with_pcpp); then + echo " Using $_py (pcpp) for --user-settings" + "$_py" "$GEN" \ + --name wolfssl --version "$VERSION" \ + --license-file "$WOLFSSL_DIR/LICENSING" \ + --user-settings "$SETTINGS_H" \ + --user-settings-include "$WOLFSSL_DIR" \ + --user-settings-include "$KIT_DIR" \ + --user-settings-define WOLFSSL_USER_SETTINGS \ + --srcs "$@" \ + --cdx-out "$CDX_OUT" \ + --spdx-out "$SPDX_OUT" + return 0 + fi + + echo "NOTE: pcpp not found for python3/python; using compiler -dM -E -> --options-h" + echo " Install pcpp on the same interpreter: python3 -m pip install pcpp" + echo " (conda users: pip install pcpp often targets conda python, not /usr/local/bin/python3)" + + DEFINES_H="$OUT_DIR/.wolfssl-defines-$$.h" + CC=${CC:-cc} + if ! "$CC" -dM -E \ + -I"$WOLFSSL_DIR" \ + -I"$KIT_DIR" \ + -DWOLFSSL_USER_SETTINGS \ + -include "$SETTINGS_H" \ + -x c /dev/null >"$DEFINES_H" 2>/dev/null; then + rm -f "$DEFINES_H" + echo "ERROR: $CC -dM -E failed; install pcpp or set CC to your cross-compiler." >&2 + exit 1 + fi + + PYTHON=python3 + command -v python3 >/dev/null 2>&1 || PYTHON=python + "$PYTHON" "$GEN" \ + --name wolfssl --version "$VERSION" \ + --license-file "$WOLFSSL_DIR/LICENSING" \ + --options-h "$DEFINES_H" \ + --srcs "$@" \ + --cdx-out "$CDX_OUT" \ + --spdx-out "$SPDX_OUT" + rm -f "$DEFINES_H" +} + +_run_autotools() { + echo "==> Autotools path: make sbom" + (cd "$WOLFSSL_DIR" && { + if [ ! -f Makefile ]; then + echo " Running ./configure first..." + ./configure + fi + make sbom + cp -f "wolfssl-${VERSION}.cdx.json" "$CDX_OUT" + cp -f "wolfssl-${VERSION}.spdx.json" "$SPDX_OUT" + if [ -f "wolfssl-${VERSION}.spdx" ]; then + cp -f "wolfssl-${VERSION}.spdx" "$OUT_DIR/" + fi + }) +} + +MODE=${CRA_SBOM_MODE:-} +case "$MODE" in + embedded) _run_embedded ;; + autotools) _run_autotools ;; + "") + if [ -f "$WOLFSSL_DIR/Makefile" ] && [ -f "$WOLFSSL_DIR/configure" ]; then + _run_autotools + else + _run_embedded + fi + ;; + *) + echo "ERROR: CRA_SBOM_MODE must be 'autotools' or 'embedded', not '$MODE'" >&2 + exit 1 + ;; +esac + +echo "Done." diff --git a/cra-evidence/scripts/refresh-samples.sh b/cra-evidence/scripts/refresh-samples.sh new file mode 100755 index 00000000..d8919fd6 --- /dev/null +++ b/cra-evidence/scripts/refresh-samples.sh @@ -0,0 +1,33 @@ +#!/bin/sh +# Regenerate pinned autotools samples and sync product SPDX externalDocumentRef checksum. +set -eu + +SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +KIT_DIR=$(dirname "$SCRIPT_DIR") + +export CRA_SBOM_MODE=autotools +export CRA_SBOM_OUT_DIR="$KIT_DIR/auditor-packet/wolfssl-component" +"$SCRIPT_DIR/generate-wolfssl-sbom.sh" + +# shellcheck disable=SC1090 +. "$KIT_DIR/VERSION" +SPDX_COMPONENT="$KIT_DIR/auditor-packet/wolfssl-component/wolfssl-${WOLFSSL_VERSION}.spdx.json" +PRODUCT_SPDX="$KIT_DIR/auditor-packet/product-acme-connect-gateway.spdx.json" + +python3 < {digest}") +PY + +"$SCRIPT_DIR/validate.sh" diff --git a/cra-evidence/scripts/validate.sh b/cra-evidence/scripts/validate.sh new file mode 100755 index 00000000..4481cd1f --- /dev/null +++ b/cra-evidence/scripts/validate.sh @@ -0,0 +1,75 @@ +#!/bin/sh +# Sanity checks on the example auditor packet (JSON + SPDX checksum sync). +set -eu + +SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +KIT_DIR=$(dirname "$SCRIPT_DIR") +AP="$KIT_DIR/auditor-packet" +PRODUCT_CDX="$AP/product-acme-connect-gateway.cdx.json" +PRODUCT_SPDX="$AP/product-acme-connect-gateway.spdx.json" +WOLF_CDX="$AP/wolfssl-component/wolfssl-5.9.1.cdx.json" +WOLF_SPDX="$AP/wolfssl-component/wolfssl-5.9.1.spdx.json" + +fail() { echo "FAIL: $*" >&2; exit 1; } +ok() { echo "OK: $*"; } + +command -v python3 >/dev/null 2>&1 || fail "python3 required" + +# shellcheck disable=SC1090 +. "$KIT_DIR/VERSION" 2>/dev/null || WOLFSSL_VERSION=5.9.1 +WOLF_CDX="$AP/wolfssl-component/wolfssl-${WOLFSSL_VERSION}.cdx.json" +WOLF_SPDX="$AP/wolfssl-component/wolfssl-${WOLFSSL_VERSION}.spdx.json" + +for f in "$PRODUCT_CDX" "$PRODUCT_SPDX" "$WOLF_CDX" "$WOLF_SPDX"; do + [ -f "$f" ] || fail "missing $f" + python3 -c "import json; json.load(open('$f'))" || fail "invalid JSON: $f" + ok "$(basename "$f") parses" +done + +PRODUCT_SPDX="$PRODUCT_SPDX" WOLF_SPDX="$WOLF_SPDX" python3 <<'PY' +import hashlib, json, os, sys + +product = json.load(open(os.environ["PRODUCT_SPDX"])) +wolf = open(os.environ["WOLF_SPDX"], "rb").read() +digest = hashlib.sha256(wolf).hexdigest() +refs = product.get("externalDocumentRefs") or [] +if not refs: + sys.exit("product SPDX has no externalDocumentRefs") +chk = refs[0].get("checksum", {}).get("checksumValue", "") +if chk.lower() != digest.lower(): + sys.exit( + f"SPDX checksum mismatch:\n embedded={chk}\n actual ={digest}\n" + "Run scripts/refresh-samples.sh after regenerating wolfSSL SBOM." + ) +print("OK: product SPDX checksum matches wolfssl-component SBOM") +PY + +PRODUCT_CDX="$PRODUCT_CDX" WOLF_CDX="$WOLF_CDX" python3 <<'PY' +import hashlib, json, os, sys + +prod = json.load(open(os.environ["PRODUCT_CDX"])) +wolf_bytes = open(os.environ["WOLF_CDX"], "rb").read() +digest = hashlib.sha256(wolf_bytes).hexdigest() +comps = prod.get("components") or [] +wolf = next((c for c in comps if c.get("name") == "wolfssl"), None) +if not wolf: + sys.exit("product CDX has no wolfssl component") +refs = wolf.get("externalReferences") or [] +bom = next((r for r in refs if r.get("type") == "bom"), None) +if not bom: + sys.exit("wolfssl component has no bom externalReference (optional check skipped)") +hashes = bom.get("hashes") or [] +if hashes: + got = hashes[0].get("content", "").lower() + if got and got != digest.lower(): + sys.exit( + f"CycloneDX bom hash mismatch:\n embedded={got}\n actual ={digest}\n" + "Add or update hashes[] after refresh-samples, or remove hashes to skip." + ) + if got: + print("OK: product CycloneDX bom hash matches wolfssl-component CDX") +else: + print("OK: product CycloneDX bom ref present (no hash pinned in stub)") +PY + +ok "auditor packet validation passed" diff --git a/cra-evidence/user_settings.h b/cra-evidence/user_settings.h new file mode 100644 index 00000000..29583716 --- /dev/null +++ b/cra-evidence/user_settings.h @@ -0,0 +1,12 @@ +/* Demo user_settings.h for cra-evidence embedded SBOM generation. + * Production: replace with your project's user_settings.h (or point gen-sbom at it). */ +#ifndef CRA_EVIDENCE_USER_SETTINGS_H +#define CRA_EVIDENCE_USER_SETTINGS_H + +#define WOLFSSL_TLS13 +#define HAVE_AESGCM +#define HAVE_ECC +#define NO_PSK +#define NO_OLD_TLS + +#endif /* CRA_EVIDENCE_USER_SETTINGS_H */ diff --git a/cra-evidence/user_settings_minimal.h b/cra-evidence/user_settings_minimal.h new file mode 100644 index 00000000..4ce09dc9 --- /dev/null +++ b/cra-evidence/user_settings_minimal.h @@ -0,0 +1 @@ +/* Deprecated name — use user_settings.h in this directory for embedded demos. */