Software Bill of Materials (SBOM)

SBOM is a collection of information of each software component you are supplying/building. Similar to a package manager on Linux based systems, it holds information of as many software parts as possible. This information can be a version, name of the software, URL, license information and more. A SBOM can be saved in various formats. In coreboot it’s saved as “uSWID” file. uSWID is not a standard or specification but it doesn’t need to be, since it’s basically just an array/list of CoSWID (Concise Software Identification) files which in turn are specified by a RFC specification. CoSWID files are saved in a CBOR format. CBOR is like JSON if JSON were a binary format. Similar to a package manager the CoSWID format can link multiple softwares together. For example on most modern Intel systems FSP is included as a dependency of coreboot. That kind of relationship between software components (among others) can be expressed in an uSWID file. That makes firmware/software much more transparent. One could for example create a software that takes a coreboot firmware image as input and automatically creates a graph with all software components the coreboot image contains and their relationship to each other.

SWID/CoSWID

SWID is a standard hidden behind an ISO paywall. It generally identifies/describes Software components. Since SWID files are written in XML, they can get too large for devices with network and storage constraints. CoSWID is basically SWID but in CBOR binary format, which makes it far smaller compared to its big brother. Also, CoSWID is a RFC specification (so publicly accessible). Therefore CoSWID is the standard used in coreboot SBOM. But one CoSWID file/tag can only describe one single software, but since software is usually composed of multiple parts (especially in firmware with many binary blobs) uSWID was born as a container format to hold multiple CoSWID files. It also has a magic value, that makes software capable of extracting uSWID/CoSWID data without the need to understand the underlying format of the binary (in coreboot it’s the CBFS and in EDK2 it’s the COFF). To get a simple overview of how a SWID/CoSWID file looks like, just take a look at the various “templates” in src/sbom/. There are of course other SBOM specifications out there, but most of them are rather blown up and don’t support a binary format at all.

coreboot implementation

Quick overview of how things are generated:

../_images/sbom_generation.svgGeneration of an SBOM File in coreboot

After all SBOM data has been fetched from all the software components, the ‘goswid’ tool links them all together into one sbom.uswid file. Therefore the goswid tool is basically a linker that takes multiple CoSWID/SWID files and converts them into one uSWID file. Although the image shows only Files in JSON format it is also possible to supply them in XML or CBOR format.

The final SBOM file is located inside the CBFS. For each software component in coreboot SBOM, there is an option in Kconfig (usually called CONFIG_INCLUDE_[software-name]_SBOM) to either include or not include SBOM metadata for the specified software. Furthermore there is a CONFIG_SBOM_[software-name]_PATH option which contains a path to a SWID/CoSWID file in a format of choice (being either JSON, XML or CBOR). CONFIG_SBOM_[software-name]_PATH option usually defaults to a very generic CoSWID file in JSON format (which are stored in src/sbom/). That at least gives minimal information like the name of the software and maybe a version. But it is always preferred, that the CONFIG_SBOM_[software-name]_PATH is set to a custom CoSWID/SWID file that contains much more information (like version/commit-hash, license, URL, dependencies, …). Therefore using the defaults is by any means to be avoided, since they hold very little information or even worse wrong information. Furthermore some of these Kconfig options have a suboption (usually called CONFIG_SBOM_[software-name]_GENERATE) to generate some basic SBOM data for the specified software component, in order to get at least some bit of information about it by analyzing the binary (for binary blobs) or querying information via git (for open source projects). This is for example currently done for all payloads. For each payload the commit hash used in the build is taken and put into the SBOM file. For open-source projects (like all payloads) crucial information like the current commit-hash of the payload can easily be put into the SBOM file. Extracting information out of binary blobs is a bit trickier for obvious reasons. For closed source binary blobs it is therefore recommended that vendors and software-engineers create a SBOM file as part of their build process and add a path to that SBOM file via Kconfig options in coreboot (CONFIG_SBOM_[software-name]_PATH). That way the final SBOM has much more useful and correct data.

Build coreboot with SBOM

Directly under the ‘General setup’ Kconfig menu is a ‘Software Bill of Materials (SBOM)’ submenu where all options are to enable/disable SBOM integration in to the corebeoot build. Therefore one can just enable/disable them via make menuconfig.

What to do as Developer of a binary blob (which is used in coreboot)

  1. Generate a SWID/CoSWID/uSWID File in either JSON, XML or CBOR Format as part of your software build process
  2. Supply that generated File along with your binary blob (preferably not inside the blob)
  3. To build coreboot: Add CONFIG_SBOM_[software-name]_PATH to your defconfig pointing to your [software-name] generated File.

What to do as Developer of an open source project (which is used in coreboot)

  1. Generate a SWID/CoSWID/uSWID file in either JSON, XML or CBOR format as part of your software’s build process. For example in form of a Makefile target.
  2. Change src/sbom/Makefile.mk (in order to know where to find the CoSWID/SWID/uSWID file) as well as the Makefile in coreboot which builds said software. For example for GRUB2 that could mean to add a Makefile target in payloads/external/GRUB2/Makefile.

Problems

What to do if the binary blob that is included in coreboot’s build already has a SBOM file embedded in the binary? One could supply the path of the software binary itself (e.g. me.bin) as SBOM file path for the software in question. Which would basically mean to set CONFIG_SBOM_[software-name]_PATH=/path/to/me.bin. This is possible since the ‘goswid’ tooling is able to extract uSWID information out of an unknown binary format because of uSWIDs magic value. But even if coreboot can extract the uSWID data there is still the question of what to do next. One can do one of the following:

  • Do not include the Software’s SBOM data in the final SBOM of coreboot. Data would not be duplicated, but therefore not included in coreboot SBOM file.
  • Extract the uSWID/CoSWID information from the binary and also include it in the coreboot SBOM. That would mean, that SBOM data is duplicated.

The first solution should in general be preferred, since its no problem if SBOM data is located at multiple locations/binaries if they don’t have a direct dependency on each other. It would be good if software that cannot run on its own only supplies the SBOM data along with it as kind of extra file instead of embedded in an unknown binary blob. coreboot can then just take it and include it in its own SBOM file. If on the other hand the binary can function on its own (e.g. EC or BMC binary), it is generally preferred that the software supplies its own SBOM data and coreboot just simply doesn’t include it in its own SBOM file. That would make a more or less clear distinction and avoids duplication in case the BMC or EC is updated (without updating coreboot). The distinction is not always easy and this problem is currently not considered in the implementation, since none of the software components currently create a SBOM file on their own.