Knowledge · SBOM

We already have an SBOM: five checks before the CRA

Yes, if it names every built-in component per release, with its version and an identifier for matching.

Five checks with jq show in minutes where it has gaps. Take the SBOM that ST ships with its STM32CubeF4 package: 74 components, all with a version, but no CPE and none of the five bundled libraries.

As of 23 October 2026 · 4 min readYou make the conformity statement. This page and our reports provide technical findings as its basis.

The test subject
File
sbom_cdx.json from STM32CubeF4 v1.28.3
SHA-256
5418487d4a2bd5b3134101885c6b7d4a2e302733b9eb3a7a35d281901d0d96fa

STMicroelectronics/STM32CubeF4, tag v1.28.3

The test subject: STMicroelectronics/STM32CubeF4, tag v1.28.3

Why is an existing SBOM not automatically enough?

A bill of materials taken from the source tree or the package manager names what is in the repository. The CRA asks about the product you place on the market: the components the build took over, with version, for each shipped firmware.

The five checks below work with any CycloneDX file; for SPDX the same questions apply with different field names.

Check 1: Are format and scope right?

Since version 2.1.0, Technical Guideline TR-03183-2 of Germany's BSI requires CycloneDX 1.6 or later or SPDX 3.0.1 or later for newly created SBOMs.

Check metadata.component too. It says whose bill of materials this is. For ST it is the STM32CubeF4 1.28.3 package, as of 25 April 2025. An SBOM for the CRA names your product there, with the version of the release.

Format and version
jq -r '.bomFormat + " " + .specVersion' sbom_cdx.json

Output

CycloneDX 1.5
Number of components
jq '.components | length' sbom_cdx.json
Output
74
What the SBOM describes, and when it was made
jq -r '.metadata.component | .name + " " + .version' sbom_cdx.jsonjq -r '.metadata.timestamp' sbom_cdx.json

Output

STM32CubeF4 1.28.3
2025-04-25T08:52:14Z

Check 2: Are versions missing?

Complete here. A component without a version stays in the list, but cannot be matched reliably to any vulnerability: a matcher skips it or reports every vulnerability of the product.

Shell
jq '[.components[] | select(.version == null or .version == "")] | length' sbom_cdx.json
Output
0

Check 3: Does every component carry an identifier for matching?

NVD maps vulnerabilities via CPE, other databases via purl. Without one of the two identifiers a tool has to recognise the component by its name, and a name like “BSP Common” is not unambiguous.

Components with a Package URL
jq '[.components[] | select(.purl)] | length' sbom_cdx.json
Output
1
Components with a CPE
jq '[.components[] | select(.cpe)] | length' sbom_cdx.json
Output
0

Check 4: Are hashes in it?

TR-03183-2 requires a SHA-512 hash of the shipped file for each component. With it you can check whether the bill of materials matches what was actually delivered.

Shell
jq '[.components[] | select(.hashes)] | length' sbom_cdx.json
Output
0

Check 5: Are built-in libraries missing?

This is the most important check, and the only one that is not in the SBOM itself: you need a second source that shows what is in the product. For firmware, that is the build that goes onto the device. A library that leaves functions there belongs in the SBOM.

What the package ships under Third_Party
ls Middlewares/Third_Party

Output

FatFs
FreeRTOS
LibJPEG
LwIP
mbedTLS
How often the SBOM names these five
grep -ciE 'lwip|mbed|freertos|fatfs|libjpeg' sbom_cdx.json
Output
0

Are creator and dependencies stated?

TR-03183-2 requires for each component its creator, as an email or URL, and the direct dependencies, stating whether the list is complete. In ST's SBOM, 4 of the 74 components carry an author and one carries a supplier name. The dependencies are flat: the package depends directly on all 74 components, there are no further entries.

The opposite direction pays off too. The only component with a purl is jQuery 1.7.1. All 14 jquery.js files in the package sit in HTML documentation, 13 under Drivers/CMSIS/Documentation, one in the LwIP docs. They go into no device. For jQuery 1.7.1 NVD lists six CVEs, one of them in the KEV catalogue; the article on supplier SBOMs shows how to check this.

Components with an author, components with a supplier name
jq '[.components[] | select(.author)] | length' sbom_cdx.jsonjq '[.components[] | select((.supplier.name // "") != "")] | length' sbom_cdx.json

Output

4
1
Entries under dependencies, dependencies of the first
jq '.dependencies | length' sbom_cdx.jsonjq '.dependencies[0].dependsOn | length' sbom_cdx.json

Output

1
74

What do I do with the result?

  1. 1

    One SBOM per release

    from the build that is shipped.

  2. 2

    Add missing libraries

    everything the linker took over, with version.

  3. 3

    Add identifiers

    purl or CPE for each component, so that matching against vulnerabilities hits.

  4. 4

    Name product and creator

    your device with its release version in metadata.component, the creator for each component.

  5. 5

    Sort out what does not go into the device

    documentation, examples and tools do not belong in the firmware's bill of materials.

  6. 6

    Raise the format

    CycloneDX 1.6 or SPDX 3.0.1, if a customer asks for TR-03183-2.

Can this run automatically?

You upload your existing SBOM to the device, together with the firmware. LegacyMind matches the SBOM against vulnerabilities and reads from the firmware the inventory that is actually in the image. Both sit side by side on the same device.

Questions

We already generate the SBOM for the Radio Equipment Directive. Is that enough for the CRA?

If it is generated per release from the shipped build and names every built-in component with version and identifier, yes. The five checks show whether that is the case.

What goes into metadata.component?

What the SBOM describes: name, version and type of the main component. For the CRA that is your product in one release. If it names a package or a repository, the file does not describe your device.

How do I check that the file is valid CycloneDX?

With the CycloneDX project's JSON schema for the version in specVersion and a validator. ST's SBOM passes the check against schema 1.5 with ajv-cli; the article on supplier SBOMs shows the command.

Does the SBOM also have to contain transitive dependencies?

The CRA requires at the very least the top-level dependencies (Annex I, Part II, point 1). TR-03183-2 requires the dependencies to be resolved for everything that is part of the delivery.

Do vulnerabilities belong in the SBOM?

TR-03183-2 rules that out: an SBOM that lists vulnerabilities does not meet the TR (§ 8.1.14). Vulnerabilities belong in CSAF with a VEX profile, because the vulnerability situation changes daily and the bill of materials only with the release.

Sources

  1. [1]STMicroelectronics: STM32CubeF4, release v1.28.3
  2. [2]BSI TR-03183-2, version 2.1.0
  3. [3]jq
  4. [4]Regulation (EU) 2024/2847, Cyber Resilience Act, Official Journal

Check your own image

Upload one firmware image, an AXF or a supplier SBOM in your own LegacyMind account. Report and SBOM within three working days, NDA on request. The app and the reports are in German; questions in English are welcome.