How to Build an SBOM for Legacy Firmware Under the CRA

How to Build an SBOM for Legacy Firmware Under the CRA

The Cyber Resilience Act sets 11 December 2027 as the day every product with digital elements sold in the EU must be documented in a Software Bill of Materials. Firmware written before package managers existed makes that a documentation cliff. This guide shows how to build an SBOM for legacy firmware, model the patched and vendored libraries already in your source tree, and keep the file valid through the product’s support period. It is aimed at embedded engineers and product compliance leads who inherited a codebase they now have to declare.

Why does the CRA make the SBOM non-negotiable for embedded products?

Annex I, Part II, point (1) of Regulation (EU) 2024/2847 obliges manufacturers to identify and document the vulnerabilities and components in their products, including by drawing up an SBOM in a commonly used, machine-readable format.

Article 13(2) ties this to your risk assessment, one of the core hardware obligations decoded here. If you cannot enumerate what is inside the firmware, you cannot assess its vulnerabilities, and your technical file is incomplete.

Market surveillance authorities can request the SBOM for ten years after the product is placed on the market, or for the support period, whichever is longer. Absence, or a stale copy, is treated as non-conformity.

The same document feeds your Article 14 vulnerability reporting workflow, which becomes enforceable on 11 September 2026. Without a maintained SBOM you cannot meet the 24-hour early-warning obligation when a vulnerability is actively exploited.

What makes legacy embedded firmware harder to inventory?

Modern SBOM tooling assumes a lockfile: package.json, requirements.txt, Cargo.lock, go.mod. Legacy embedded projects rarely have one. Their dependencies were dropped into the source tree years ago and often modified in place.

The obstacles show up on almost every retrofit:

  • Vendored HAL and RTOS sources with local edits, such as STM32Cube, ESP-IDF, MCUXpresso, or FreeRTOS
  • Third-party libraries pasted as .c and .h files with no version marker
  • Silent forks, removed files, and in-tree patches with no changelog
  • No manifest, no supplier record, no hash reference to any upstream release

The result is a codebase that cannot be inventoried by scanning alone. Every retrofit needs build-time evidence plus manual reconstruction of provenance for the vendored code.

How do you model patched vendored libraries in an SBOM?

CycloneDX has a dedicated pedigree object for exactly this case. Use it.

The correct model is a single component that represents the patched version you actually ship, with pedigree fields pointing back to the unpatched upstream:

  • ancestors: the upstream component with its original version, supplier, and PURL
  • patches: each in-tree modification, ideally with a diff reference or ticket ID
  • commits or notes: the internal identifier that links the patch to your VCS
  • The main component’s version should encode your fork state, not the upstream tag

This model gives vulnerability scanners the information they need. When a CVE targets the upstream version and PURL, the scanner still matches your component. Patch notes then let a triager decide whether the affected code path was actually shipped.

Do not model the patched library and the upstream as two separate components. That inflates the SBOM, breaks pedigree, and hides the fact that the code you ship is not the code the scanner is comparing against.

What tooling actually works on embedded C and C++ codebases?

No single tool covers a legacy embedded tree fully. A realistic workflow combines two or three, and cross-checks their output against the final image.

The current set worth trialling:

  • cdxgen (CycloneDX project) with -t c, tuned for C and C++ build trees
  • syft (Anchore) for combined source and binary scanning, with wide format support
  • cve-bin-tool (Intel) for binary-only scanning of the compiled firmware image
  • Dependency-Track as the post-generation aggregator and CVE-feed watcher

Run at least one binary scanner against the final .elf or .bin. Binary scanning catches statically linked libraries that source scanning missed, and gives you a fallback inventory when the source-side view is incomplete.

How do you keep the SBOM maintainable after the first pass?

An SBOM generated once and stored as a PDF is worthless. Every firmware release changes the inventory, and the CRA obligation runs for the entire declared support period.

Bake generation into the build:

  • Run the SBOM generator as a post-build target in CMake or Make
  • Store the CycloneDX JSON alongside the .bin in your artifact registry
  • Version-align the SBOM filename with the firmware version and Git SHA
  • Sign the SBOM when your Notified Body’s conformity assessment depends on it

Feed the output into a vulnerability aggregator such as Dependency-Track or OSV-Scanner. This converts a static inventory into the vulnerability handling required by Annex I, Part II.

The output of that pipeline is what a Notified Body will ask to see, and what your Article 14 reporting workflow will draw from when an exploited vulnerability lands in one of your dependencies.

Frequently Asked Questions

Does the CRA accept a partial SBOM?

The Regulation requires coverage of top-level dependencies at a minimum. Partial in the sense of “only some products” or “only some builds” is not compliant. Partial in the sense of “top-level only, not transitive” is the current floor, though deeper coverage is best practice and what most Notified Bodies expect.

What SBOM format does the CRA require?

The text specifies a commonly used, machine-readable format. In practice this means CycloneDX or SPDX, in JSON or XML. PDFs and spreadsheets do not qualify. For embedded work, CycloneDX is usually the better fit because of its hardware-and-firmware component model.

Do I have to publish my SBOM publicly?

No. The CRA requires you to hold the SBOM and provide it to market surveillance authorities on request. Publishing is optional and rarely done, though some enterprise customers now request it during procurement.

How does the SBOM relate to CRA vulnerability reporting?

The SBOM is the input to vulnerability handling. When a CVE hits a component you ship, the SBOM tells you which products are affected. If that vulnerability is actively exploited, the 24-hour early-warning clock under Article 14 starts the moment you become aware of the exploitation.

Is a build-time SBOM better than a source-scan SBOM?

For legacy embedded work, yes. Source scans over-report by including files that never made it into the binary. Build-time capture, filtered by the compilation database and cross-checked against the final image, reflects what you actually shipped.

Conclusion

Legacy firmware retrofits are a documentation problem before they are a tooling problem, and the compiler is the source of truth. CycloneDX pedigree, not two parallel components, is the correct way to model patched vendored libraries. Continuous generation from the build pipeline is the only way to keep the file valid through the product’s support period.

The manufacturers who solve this before 11 December 2027 will hold a working vulnerability-handling process, not just a document.

Get in Touch

LEAVE A REPLY

Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.

spot_img

Related Articles