Maximilian Brune | 1d7a9de | 2022-04-14 14:54:16 +0200 | [diff] [blame] | 1 | ## SPDX-License-Identifier: GPL-2.0-only |
| 2 | |
| 3 | obj ?= build |
| 4 | src ?= src |
| 5 | build-dir = $(obj)/sbom |
| 6 | src-dir = $(src)/sbom |
| 7 | |
Maximilian Brune | e6cd4d2 | 2023-01-21 20:31:05 +0100 | [diff] [blame] | 8 | # Strip quotes from binary paths and SBOM file paths. Each binary path should have a |
| 9 | # corresponding SBOM file path, but not every SBOM file path needs a binary path. That |
| 10 | # is because binary files are only needed if they are used to extract information from |
| 11 | # them which in turn can be included in the SBOM files (like version or config stuff). |
| 12 | # But for some Software there are only SBOM files, which basically tell the most generic |
| 13 | # information about that piece of Software. Ideally one would not need the binary files |
| 14 | # at all, because extacting information out of mostly unknown binary blobs is a pain. |
Maximilian Brune | 3b3f947 | 2022-12-26 06:25:16 +0100 | [diff] [blame] | 15 | CONFIG_ME_BIN_PATH := $(call strip_quotes, $(CONFIG_ME_BIN_PATH)) |
Maximilian Brune | e6cd4d2 | 2023-01-21 20:31:05 +0100 | [diff] [blame] | 16 | CONFIG_SBOM_ME_PATH := $(call strip_quotes, $(CONFIG_SBOM_ME_PATH)) |
Maximilian Brune | 3b3f947 | 2022-12-26 06:25:16 +0100 | [diff] [blame] | 17 | CONFIG_FSP_S_FILE := $(call strip_quotes, $(CONFIG_FSP_S_FILE)) |
| 18 | CONFIG_FSP_M_FILE := $(call strip_quotes, $(CONFIG_FSP_M_FILE)) |
| 19 | CONFIG_FSP_T_FILE := $(call strip_quotes, $(CONFIG_FSP_T_FILE)) |
Maximilian Brune | 3b3f947 | 2022-12-26 06:25:16 +0100 | [diff] [blame] | 20 | CONFIG_SBOM_FSP_PATH := $(call strip_quotes, $(CONFIG_SBOM_FSP_PATH)) |
Maximilian Brune | e6cd4d2 | 2023-01-21 20:31:05 +0100 | [diff] [blame] | 21 | CONFIG_PAYLOAD_FILE := $(call strip_quotes, $(CONFIG_PAYLOAD_FILE)) |
Maximilian Brune | 3b3f947 | 2022-12-26 06:25:16 +0100 | [diff] [blame] | 22 | CONFIG_SBOM_PAYLOAD_PATH := $(call strip_quotes, $(CONFIG_SBOM_PAYLOAD_PATH)) |
Maximilian Brune | e6cd4d2 | 2023-01-21 20:31:05 +0100 | [diff] [blame] | 23 | CONFIG_EC_PATH := $(call strip_quotes, $(CONFIG_EC_PATH)) |
| 24 | CONFIG_SBOM_EC_PATH := $(call strip_quotes, $(CONFIG_SBOM_EC_PATH)) |
| 25 | CONFIG_SBOM_BIOS_ACM_PATH := $(call strip_quotes, $(CONFIG_SBOM_BIOS_ACM_PATH)) |
| 26 | CONFIG_SBOM_SINIT_ACM_PATH := $(call strip_quotes, $(CONFIG_SBOM_SINIT_ACM_PATH)) |
| 27 | CONFIG_SBOM_COMPILER_PATH := $(call strip_quotes, $(CONFIG_SBOM_COMPILER_PATH)) |
Maximilian Brune | 1d7a9de | 2022-04-14 14:54:16 +0200 | [diff] [blame] | 28 | |
Maximilian Brune | e6cd4d2 | 2023-01-21 20:31:05 +0100 | [diff] [blame] | 29 | # Select the correct payload directory for the used payload. Ideally we could just make this |
| 30 | # a one-liner, but since the payload is generated externally (with an extra make command), we |
| 31 | # have to hard code the paths here. |
Maximilian Brune | 1d7a9de | 2022-04-14 14:54:16 +0200 | [diff] [blame] | 32 | ifeq ($(CONFIG_SBOM_PAYLOAD_GENERATE), y) |
| 33 | payload-git-dir-$(CONFIG_PAYLOAD_BOOTBOOT) = payloads/external/BOOTBOOT/bootboot |
| 34 | payload-git-dir-$(CONFIG_PAYLOAD_DEPTHCHARGE) = payloads/external/depthcharge/depthcharge |
| 35 | payload-git-dir-$(CONFIG_PAYLOAD_FILO) = payloads/external/FILO/filo |
| 36 | payload-git-dir-$(CONFIG_PAYLOAD_GRUB2) = payloads/external/GRUB2/grub2 |
| 37 | payload-git-dir-$(CONFIG_PAYLOAD_LINUXBOOT) = payloads/external/LinuxBoot/linuxboot |
| 38 | payload-git-dir-$(CONFIG_PAYLOAD_SEABIOS) = payloads/external/SeaBIOS/seabios |
| 39 | payload-git-dir-$(CONFIG_PAYLOAD_SKIBOOT) = payloads/external/skiboot/skiboot |
| 40 | #payload-git-dir-$(CONFIG_PAYLOAD_TIANOCORE) = payloads/external/tianocore/ |
| 41 | payload-git-dir-$(CONFIG_PAYLOAD_UBOOT) = payloads/external/U-Boot/u-boot |
| 42 | payload-git-dir-$(CONFIG_PAYLOAD_IPXE) = payloads/external/iPXE/ipxe |
| 43 | ifneq ($(payload-git-dir-y),) |
| 44 | # only proceed with payload sbom data, if one of the above payloads were selected (should be guarded by Kconfig as well) |
| 45 | # e.g. payload-git-dir-y=payloads/external/SeaBIOS/seabios -> payload-json-file=$(build-dir)/payload-SeaBIOS.json |
| 46 | payload-swid = $(build-dir)/payload-$(subst /,,$(dir $(patsubst payloads/external/%,%,$(payload-git-dir-y)))).json |
| 47 | payload-swid-template = $(patsubst $(build-dir)/%.json,$(src-dir)/%.json,$(payload-swid)) |
| 48 | endif |
| 49 | endif |
| 50 | |
Maximilian Brune | e6cd4d2 | 2023-01-21 20:31:05 +0100 | [diff] [blame] | 51 | # Add all SBOM files into the swid-files-y target. This target contains all |
| 52 | # .json, .ini, .uswid, .xml, .pc SBOM files that are later merged into one uSWID SBOM file. |
| 53 | # Some of these have an option that this Makefile generates/extracts some information from |
| 54 | # binary files in order to give more complete/detailed information inside the SBOM file. |
| 55 | # These files are either in src/sbom/ or build/sbom (if they are generated). |
Maximilian Brune | 1d7a9de | 2022-04-14 14:54:16 +0200 | [diff] [blame] | 56 | swid-files-$(CONFIG_SBOM_ME) += $(if $(CONFIG_SBOM_ME_GENERATE), $(build-dir)/intel-me.json, $(CONFIG_SBOM_ME_PATH)) |
| 57 | swid-files-$(CONFIG_SBOM_PAYLOAD) += $(if $(CONFIG_SBOM_PAYLOAD_GENERATE), $(payload-swid), $(CONFIG_SBOM_PAYLOAD_PATH)) |
| 58 | # 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? |
| 59 | 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))) |
| 60 | swid-files-$(CONFIG_SBOM_MICROCODE) += $(patsubst ${FIRMWARE_LOCATION}/UcodePatch_%.bin, $(build-dir)/amd-microcode-%.json, $(filter ${FIRMWARE_LOCATION}/UcodePatch_%.bin, $(cpu_microcode_bins))) |
| 61 | swid-files-$(CONFIG_SBOM_FSP) += $(CONFIG_SBOM_FSP_PATH) |
| 62 | swid-files-$(CONFIG_SBOM_EC) += $(CONFIG_SBOM_EC_PATH) |
| 63 | swid-files-$(CONFIG_SBOM_BIOS_ACM) += $(CONFIG_BIOS_ACM_PATH) |
| 64 | swid-files-$(CONFIG_SBOM_SINIT_ACM) += $(CONFIG_SINIT_ACM_PATH) |
| 65 | |
| 66 | 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 |
| 67 | swid-files-$(CONFIG_SBOM_VBOOT) += $(vboot-pkgconfig-files) |
| 68 | $(vboot-pkgconfig-files): $(VBOOT_LIB_bootblock) $(VBOOT_LIB_romstage) $(VBOOT_LIB_ramstage) $(VBOOT_LIB_postcar) # src/security/vboot/Makefile.inc |
| 69 | |
| 70 | ifeq ($(CONFIG_SBOM_COMPILER),y) |
Maximilian Brune | 1d7a9de | 2022-04-14 14:54:16 +0200 | [diff] [blame] | 71 | 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) |
Maximilian Brune | e6cd4d2 | 2023-01-21 20:31:05 +0100 | [diff] [blame] | 72 | swid-files-compiler = $(CONFIG_SBOM_COMPILER_PATH) |
Maximilian Brune | 1d7a9de | 2022-04-14 14:54:16 +0200 | [diff] [blame] | 73 | endif |
| 74 | |
Maximilian Brune | e6cd4d2 | 2023-01-21 20:31:05 +0100 | [diff] [blame] | 75 | # include all licenses used in coreboot. Ideally we would only include the licenses, |
| 76 | # which are used in this build |
Maximilian Brune | 1d7a9de | 2022-04-14 14:54:16 +0200 | [diff] [blame] | 77 | coreboot-licenses = $(foreach license, $(patsubst %.txt, %, $(filter-out retained-copyrights.txt, $(patsubst LICENSES/%, %, $(wildcard LICENSES/*)))), https://spdx.org/licenses/$(license).html) |
| 78 | |
| 79 | # only include CBFS SBOM section if there is any data for it |
| 80 | ifeq ($(CONFIG_SBOM),y) |
| 81 | cbfs-files-y += sbom |
| 82 | sbom-file = $(build-dir)/sbom.uswid |
| 83 | sbom-type = raw |
| 84 | endif |
| 85 | |
| 86 | ## Build final SBOM (Software Bill of Materials) file in uswid format |
| 87 | |
Maximilian Brune | e47d9fd | 2023-02-02 01:50:51 +0100 | [diff] [blame] | 88 | $(build-dir)/sbom.uswid: $(build-dir)/coreboot.json $$(swid-files-y) $(swid-files-compiler) | $(build-dir)/goswid $(build-dir) |
Maximilian Brune | 1d7a9de | 2022-04-14 14:54:16 +0200 | [diff] [blame] | 89 | echo " SBOM " $^ |
| 90 | $(build-dir)/goswid convert -o $@ \ |
| 91 | --parent $(build-dir)/coreboot.json \ |
| 92 | $(if $(swid-files-y), --requires $$(echo $(swid-files-y) | tr ' ' ','),) \ |
| 93 | $(if $(swid-files-compiler), --compiler $(swid-files-compiler),) |
| 94 | |
| 95 | # all build files depend on the $(build-dir) directory being created |
| 96 | $(build-dir): |
| 97 | mkdir -p $(build-dir) |
| 98 | |
| 99 | $(build-dir)/goswid: | $(build-dir) |
| 100 | echo " SBOM building goswid tool" |
| 101 | cd util/goswid; \ |
Maximilian Brune | b57f87f | 2023-09-12 16:20:17 +0200 | [diff] [blame] | 102 | GOPATH=$(abspath build/go) GO111MODULE=on go build -modcacherw -o $(abspath $@) ./cmd/goswid |
Maximilian Brune | 1d7a9de | 2022-04-14 14:54:16 +0200 | [diff] [blame] | 103 | |
| 104 | ## Generate all .json files |
| 105 | |
| 106 | $(build-dir)/compiler-%.json: $(src-dir)/compiler-%.json | $(build-dir)/goswid |
| 107 | cp $< $@ |
| 108 | for tool in $$(echo $(compiler-toolchain) | tr ' ' '\n' | sort | uniq); do \ |
| 109 | version=$$($$tool --version 2>&1 | head -n 1 | grep -Eo '([0-9]+\.[0-9]+\.*[0-9]*)'); \ |
| 110 | $(build-dir)/goswid add-payload-file -o $@ -i $@ --name $$(basename $$tool) --version $$version; \ |
| 111 | done |
| 112 | |
| 113 | $(build-dir)/coreboot.json: $(src-dir)/coreboot.json .git/HEAD | $(build-dir)/goswid |
| 114 | cp $< $@ |
| 115 | git_tree_hash=$$(git log -n 1 --format=%T);\ |
| 116 | git_comm_hash=$$(git log -n 1 --format=%H);\ |
| 117 | sed -i -e "s/<colloquial_version>/$$git_tree_hash/" -e "s/<software_version>/$$git_comm_hash/" $@;\ |
| 118 | $(build-dir)/goswid add-license -o $@ -i $@ $(coreboot-licenses) |
| 119 | |
| 120 | $(build-dir)/intel-me.json: $(src-dir)/intel-me.json $(CONFIG_ME_BIN_PATH) | $(build-dir) |
| 121 | cp $< $@ |
| 122 | #TODO put more Intel Management Engine metadata in sbom file |
| 123 | |
| 124 | |
| 125 | $(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 |
| 126 | cp $(src-dir)/generic-fsp.json $@ |
| 127 | ifneq ($(CONFIG_FSP_S_FILE),) |
| 128 | echo " SBOM Adding FSP-S" |
| 129 | $(build-dir)/goswid add-payload-file -o $@ -i $@ --name "FSP-S" |
| 130 | endif |
| 131 | ifneq ($(CONFIG_FSP_T_FILE),) |
| 132 | echo " SBOM Adding FSP-T" |
| 133 | $(build-dir)/goswid add-payload-file -o $@ -i $@ --name "FSP-T" |
| 134 | endif |
| 135 | ifneq ($(CONFIG_FSP_M_FILE),) |
| 136 | echo " SBOM Adding FSP-M" |
| 137 | $(build-dir)/goswid add-payload-file -o $@ -i $@ --name "FSP-M" |
| 138 | endif |
| 139 | |
| 140 | $(build-dir)/intel-microcode-%.json: $(src-dir)/intel-microcode.json 3rdparty/intel-microcode/intel-ucode/% | $(build-dir) $(build-dir)/goswid |
| 141 | cp $< $@ |
| 142 | year=$$(hexdump --skip 8 --length 2 --format '"%04x"' $(word 2,$^));\ |
| 143 | day=$$(hexdump --skip 10 --length 1 --format '"%02x"' $(word 2,$^));\ |
| 144 | month=$$(hexdump --skip 11 --length 1 --format '"%02x"' $(word 2,$^));\ |
| 145 | sed -i "s/<software_version>/$$year-$$month-$$day/" $@ |
| 146 | #TODO add cpuid (processor family, model, stepping) as extra attribute |
| 147 | |
| 148 | $(build-dir)/amd-microcode-%.json: $(src-dir)/amd-microcode.json ${FIRMWARE_LOCATION}/UcodePatch_%.bin | $(build-dir) $(build-dir)/goswid |
| 149 | cp $< $@ |
| 150 | year=$$(hexdump --skip 0 --length 2 --format '"%04x"' $(word 2,$^));\ |
| 151 | day=$$(hexdump --skip 2 --length 1 --format '"%02x"' $(word 2,$^));\ |
| 152 | month=$$(hexdump --skip 3 --length 1 --format '"%02x"' $(word 2,$^));\ |
| 153 | sed -i "s/<software_version>/$$year-$$month-$$day/" $@ |
| 154 | |
| 155 | $(payload-swid): $(payload-swid-template) $(CONFIG_PAYLOAD_FILE) | $(build-dir) |
| 156 | cp $< $@;\ |
| 157 | git_tree_hash=$$(git --git-dir $(payload-git-dir-y)/.git log -n 1 --format=%T);\ |
| 158 | git_comm_hash=$$(git --git-dir $(payload-git-dir-y)/.git log -n 1 --format=%H);\ |
| 159 | sed -i -e "s/<colloquial_version>/$$git_tree_hash/" -e "s/<software_version>/$$git_comm_hash/" $@; |