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. */