coreboot-kgpe-d16/src/sbom/Makefile.inc

144 lines
7.7 KiB
PHP
Raw Normal View History

Add SBOM (Software Bill of Materials) Generation Firmware is typically delivered as one large binary image that gets flashed. Since this final image consists of binaries and data from a vast number of different people and companies, it's hard to determine what all the small parts included in it are. The goal of the software bill of materials (SBOM) is to take a firmware image and make it easy to find out what it consists of and where those pieces came from. Basically, this answers the question, who supplied the code that's running on my system right now? For example, buyers of a system can use an SBOM to perform an automated vulnerability check or license analysis, both of which can be used to evaluate risk in a product. Furthermore, one can quickly check to see if the firmware is subject to a new vulnerability included in one of the software parts (with the specified version) of the firmware. Further reference: https://web.archive.org/web/20220310104905/https://blogs.gnome.org/hughsie/2022/03/10/firmware-software-bill-of-materials/ - Add Makefile.inc to generate and build coswid tags - Add templates for most payloads, coreboot, intel-microcode, amd-microcode. intel FSP-S/M/T, EC, BIOS_ACM, SINIT_ACM, intel ME and compiler (gcc,clang,other) - Add Kconfig entries to optionally supply a path to CoSWID tags instead of using the default CoSWID tags - Add CBFS entry called SBOM to each build via Makefile.inc - Add goswid utility tool to generate SBOM data Signed-off-by: Maximilian Brune <maximilian.brune@9elements.com> Change-Id: Icb7481d4903f95d200eddbfed7728fbec51819d0 Reviewed-on: https://review.coreboot.org/c/coreboot/+/63639 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin Roth <martin.roth@amd.corp-partner.google.com>
2022-04-14 14:54:16 +02:00
## SPDX-License-Identifier: GPL-2.0-only
obj ?= build
src ?= src
build-dir = $(obj)/sbom
src-dir = $(src)/sbom
CONFIG_ME_BIN_PATH := $(call strip_quotes, $(CONFIG_ME_BIN_PATH))
CONFIG_FSP_S_FILE := $(call strip_quotes, $(CONFIG_FSP_S_FILE))
CONFIG_FSP_M_FILE := $(call strip_quotes, $(CONFIG_FSP_M_FILE))
CONFIG_FSP_T_FILE := $(call strip_quotes, $(CONFIG_FSP_T_FILE))
CONFIG_PAYLOAD_FILE := $(call strip_quotes, $(CONFIG_PAYLOAD_FILE))
CONFIG_EC_PATH := $(call strip_quotes, $(CONFIG_EC_PATH))
CONFIG_BIOS_ACM_PATH := $(call strip_quotes, $(CONFIG_BIOS_ACM_PATH))
CONFIG_SINIT_ACM_PATH := $(call strip_quotes, $(CONFIG_SINIT_ACM_PATH))
ifeq ($(CONFIG_SBOM_PAYLOAD_GENERATE), y)
payload-git-dir-$(CONFIG_PAYLOAD_BOOTBOOT) = payloads/external/BOOTBOOT/bootboot
payload-git-dir-$(CONFIG_PAYLOAD_DEPTHCHARGE) = payloads/external/depthcharge/depthcharge
payload-git-dir-$(CONFIG_PAYLOAD_FILO) = payloads/external/FILO/filo
payload-git-dir-$(CONFIG_PAYLOAD_GRUB2) = payloads/external/GRUB2/grub2
payload-git-dir-$(CONFIG_PAYLOAD_LINUXBOOT) = payloads/external/LinuxBoot/linuxboot
payload-git-dir-$(CONFIG_PAYLOAD_SEABIOS) = payloads/external/SeaBIOS/seabios
payload-git-dir-$(CONFIG_PAYLOAD_SKIBOOT) = payloads/external/skiboot/skiboot
#payload-git-dir-$(CONFIG_PAYLOAD_TIANOCORE) = payloads/external/tianocore/
payload-git-dir-$(CONFIG_PAYLOAD_UBOOT) = payloads/external/U-Boot/u-boot
payload-git-dir-$(CONFIG_PAYLOAD_IPXE) = payloads/external/iPXE/ipxe
ifneq ($(payload-git-dir-y),)
# only proceed with payload sbom data, if one of the above payloads were selected (should be guarded by Kconfig as well)
# e.g. payload-git-dir-y=payloads/external/SeaBIOS/seabios -> payload-json-file=$(build-dir)/payload-SeaBIOS.json
payload-swid = $(build-dir)/payload-$(subst /,,$(dir $(patsubst payloads/external/%,%,$(payload-git-dir-y)))).json
payload-swid-template = $(patsubst $(build-dir)/%.json,$(src-dir)/%.json,$(payload-swid))
endif
endif
swid-files-$(CONFIG_SBOM_ME) += $(if $(CONFIG_SBOM_ME_GENERATE), $(build-dir)/intel-me.json, $(CONFIG_SBOM_ME_PATH))
swid-files-$(CONFIG_SBOM_PAYLOAD) += $(if $(CONFIG_SBOM_PAYLOAD_GENERATE), $(payload-swid), $(CONFIG_SBOM_PAYLOAD_PATH))
# TODO think about just using one CoSWID tag for all intel-microcode instead of one for each. maybe put each microcode into files entity of CoSWID tag?
swid-files-$(CONFIG_SBOM_MICROCODE) += $(patsubst 3rdparty/intel-microcode/intel-ucode/%, $(build-dir)/intel-microcode-%.json, $(filter 3rdparty/intel-microcode/intel-ucode/%, $(cpu_microcode_bins)))
swid-files-$(CONFIG_SBOM_MICROCODE) += $(patsubst ${FIRMWARE_LOCATION}/UcodePatch_%.bin, $(build-dir)/amd-microcode-%.json, $(filter ${FIRMWARE_LOCATION}/UcodePatch_%.bin, $(cpu_microcode_bins)))
swid-files-$(CONFIG_SBOM_FSP) += $(CONFIG_SBOM_FSP_PATH)
swid-files-$(CONFIG_SBOM_EC) += $(CONFIG_SBOM_EC_PATH)
swid-files-$(CONFIG_SBOM_BIOS_ACM) += $(CONFIG_BIOS_ACM_PATH)
swid-files-$(CONFIG_SBOM_SINIT_ACM) += $(CONFIG_SINIT_ACM_PATH)
vboot-pkgconfig-files = $(obj)/external/vboot_reference-bootblock/vboot_host.pc $(obj)/external/vboot_reference-romstage/vboot_host.pc $(obj)/external/vboot_reference-ramstage/vboot_host.pc $(obj)/external/vboot_reference-postcar/vboot_host.pc
swid-files-$(CONFIG_SBOM_VBOOT) += $(vboot-pkgconfig-files)
$(vboot-pkgconfig-files): $(VBOOT_LIB_bootblock) $(VBOOT_LIB_romstage) $(VBOOT_LIB_ramstage) $(VBOOT_LIB_postcar) # src/security/vboot/Makefile.inc
ifeq ($(CONFIG_SBOM_COMPILER),y)
ifeq ($(CONFIG_ANY_TOOLCHAIN),y)
swid-files-compiler = $(build-dir)/compiler-generic.json
else ifeq ($(CONFIG_COMPILER_GCC),y)
swid-files-compiler = $(build-dir)/compiler-gcc.json
else ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
swid-files-compiler = $(build-dir)/compiler-clang.json
endif
compiler-toolchain = $(CC_bootblock) $(CC_romstage) $(CC_ramstage) $(CC_postcar) $(CC_verstage) $(LD_bootblock) $(LD_romstage) $(LD_ramstage) $(LD_postcar) $(LD_verstage) $(AS_bootblock) $(AS_romstage) $(AS_ramstage) $(AS_postcar) $(AS_verstage)
endif
coreboot-licenses = $(foreach license, $(patsubst %.txt, %, $(filter-out retained-copyrights.txt, $(patsubst LICENSES/%, %, $(wildcard LICENSES/*)))), https://spdx.org/licenses/$(license).html)
# only include CBFS SBOM section if there is any data for it
ifeq ($(CONFIG_SBOM),y)
cbfs-files-y += sbom
sbom-file = $(build-dir)/sbom.uswid
sbom-type = raw
endif
## Build final SBOM (Software Bill of Materials) file in uswid format
$(build-dir)/sbom.uswid: $(build-dir)/coreboot.json $(swid-files-y) $(swid-files-compiler) | $(build-dir)/goswid $(build-dir)
echo " SBOM " $^
$(build-dir)/goswid convert -o $@ \
--parent $(build-dir)/coreboot.json \
$(if $(swid-files-y), --requires $$(echo $(swid-files-y) | tr ' ' ','),) \
$(if $(swid-files-compiler), --compiler $(swid-files-compiler),)
# all build files depend on the $(build-dir) directory being created
$(build-dir):
mkdir -p $(build-dir)
$(build-dir)/goswid: | $(build-dir)
echo " SBOM building goswid tool"
cd util/goswid; \
GO111MODULE=on go build -o $(abspath $@) ./cmd/goswid
## Generate all .json files
$(build-dir)/compiler-%.json: $(src-dir)/compiler-%.json | $(build-dir)/goswid
cp $< $@
for tool in $$(echo $(compiler-toolchain) | tr ' ' '\n' | sort | uniq); do \
version=$$($$tool --version 2>&1 | head -n 1 | grep -Eo '([0-9]+\.[0-9]+\.*[0-9]*)'); \
$(build-dir)/goswid add-payload-file -o $@ -i $@ --name $$(basename $$tool) --version $$version; \
done
$(build-dir)/coreboot.json: $(src-dir)/coreboot.json .git/HEAD | $(build-dir)/goswid
cp $< $@
git_tree_hash=$$(git log -n 1 --format=%T);\
git_comm_hash=$$(git log -n 1 --format=%H);\
sed -i -e "s/<colloquial_version>/$$git_tree_hash/" -e "s/<software_version>/$$git_comm_hash/" $@;\
$(build-dir)/goswid add-license -o $@ -i $@ $(coreboot-licenses)
$(build-dir)/intel-me.json: $(src-dir)/intel-me.json $(CONFIG_ME_BIN_PATH) | $(build-dir)
cp $< $@
#TODO put more Intel Management Engine metadata in sbom file
$(build-dir)/generic-fsp.json: $(src-dir)/generic-fsp.json $(CONFIG_FSP_S_FILE) $(CONFIG_FSP_T_FILE) $(CONFIG_FSP_M_FILE) | $(build-dir)/goswid
cp $(src-dir)/generic-fsp.json $@
ifneq ($(CONFIG_FSP_S_FILE),)
echo " SBOM Adding FSP-S"
$(build-dir)/goswid add-payload-file -o $@ -i $@ --name "FSP-S"
endif
ifneq ($(CONFIG_FSP_T_FILE),)
echo " SBOM Adding FSP-T"
$(build-dir)/goswid add-payload-file -o $@ -i $@ --name "FSP-T"
endif
ifneq ($(CONFIG_FSP_M_FILE),)
echo " SBOM Adding FSP-M"
$(build-dir)/goswid add-payload-file -o $@ -i $@ --name "FSP-M"
endif
$(build-dir)/intel-microcode-%.json: $(src-dir)/intel-microcode.json 3rdparty/intel-microcode/intel-ucode/% | $(build-dir) $(build-dir)/goswid
cp $< $@
year=$$(hexdump --skip 8 --length 2 --format '"%04x"' $(word 2,$^));\
day=$$(hexdump --skip 10 --length 1 --format '"%02x"' $(word 2,$^));\
month=$$(hexdump --skip 11 --length 1 --format '"%02x"' $(word 2,$^));\
sed -i "s/<software_version>/$$year-$$month-$$day/" $@
#TODO add cpuid (processor family, model, stepping) as extra attribute
$(build-dir)/amd-microcode-%.json: $(src-dir)/amd-microcode.json ${FIRMWARE_LOCATION}/UcodePatch_%.bin | $(build-dir) $(build-dir)/goswid
cp $< $@
year=$$(hexdump --skip 0 --length 2 --format '"%04x"' $(word 2,$^));\
day=$$(hexdump --skip 2 --length 1 --format '"%02x"' $(word 2,$^));\
month=$$(hexdump --skip 3 --length 1 --format '"%02x"' $(word 2,$^));\
sed -i "s/<software_version>/$$year-$$month-$$day/" $@
$(payload-swid): $(payload-swid-template) $(CONFIG_PAYLOAD_FILE) | $(build-dir)
cp $< $@;\
git_tree_hash=$$(git --git-dir $(payload-git-dir-y)/.git log -n 1 --format=%T);\
git_comm_hash=$$(git --git-dir $(payload-git-dir-y)/.git log -n 1 --format=%H);\
sed -i -e "s/<colloquial_version>/$$git_tree_hash/" -e "s/<software_version>/$$git_comm_hash/" $@;