The dtb part of this patch was rejected a few years ago[1][2] It seems to have crept in under another name.
With signatures in U-Boot itself it is difficult to insert signatures after U-Boot itself is built. The devicetree approach is more flexible, since it can be updates by Binman or other build processes. This reverts commit 261b422aed7d265c21a8d205f8af9bd31259f5d3. [1] https://patchwork.ozlabs.org/project/uboot/patch/20210802014621.2280899-1-...@chromium.org/ [2] https://lore.kernel.org/u-boot/capnjgz1uijvhxe2qd3gryo2lbrxwazxsqp_hyuaboxjkrip...@mail.gmail.com/ Signed-off-by: Simon Glass <s...@chromium.org> --- include/asm-generic/sections.h | 2 -- lib/efi_loader/Makefile | 18 --------------- lib/efi_loader/capsule_esl.dtsi.in | 11 +++++++++ lib/efi_loader/efi_capsule.c | 37 ++++++++++++++++++++++-------- lib/efi_loader/efi_capsule_key.S | 17 -------------- scripts/Makefile.lib | 27 ++++++++++++++++++++++ 6 files changed, 66 insertions(+), 46 deletions(-) create mode 100644 lib/efi_loader/capsule_esl.dtsi.in delete mode 100644 lib/efi_loader/efi_capsule_key.S diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h index d59787948fd..024b1adde27 100644 --- a/include/asm-generic/sections.h +++ b/include/asm-generic/sections.h @@ -28,8 +28,6 @@ extern char __efi_helloworld_begin[]; extern char __efi_helloworld_end[]; extern char __efi_var_file_begin[]; extern char __efi_var_file_end[]; -extern char __efi_capsule_sig_begin[]; -extern char __efi_capsule_sig_end[]; /* Private data used by of-platdata devices/uclasses */ extern char __priv_data_start[], __priv_data_end[]; diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index d8864e87052..702d3e79fae 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -29,7 +29,6 @@ obj-y += efi_boottime.o obj-y += efi_helper.o obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o obj-$(CONFIG_EFI_CAPSULE_FIRMWARE) += efi_firmware.o -obj-$(CONFIG_EFI_CAPSULE_AUTHENTICATE) += efi_capsule_key.o obj-y += efi_console.o obj-y += efi_device_path.o obj-$(CONFIG_EFI_DEVICE_PATH_TO_TEXT) += efi_device_path_to_text.o @@ -74,23 +73,6 @@ obj-$(CONFIG_EFI_ECPT) += efi_conformance.o EFI_VAR_SEED_FILE := $(subst $\",,$(CONFIG_EFI_VAR_SEED_FILE)) $(obj)/efi_var_seed.o: $(srctree)/$(EFI_VAR_SEED_FILE) -ifeq ($(CONFIG_EFI_CAPSULE_AUTHENTICATE),y) -capsule_crt_path=($(subst $(quote),,$(CONFIG_EFI_CAPSULE_CRT_FILE))) -capsule_crt_full=$(srctree)/$(subst $(quote),,$(CONFIG_EFI_CAPSULE_CRT_FILE)) -quiet_cmd_capsule_esl_gen = CAPSULE_ESL_GEN $@ -cmd_capsule_esl_gen = cert-to-efi-sig-list $(capsule_crt_full) $@ -$(srctree)/capsule_esl_file: FORCE - @if [ ! -e "$(capsule_crt_full)" ]; then \ - echo "ERROR: path $(capsule_crt_full) is invalid." >&2; \ - echo "EFI CONFIG_EFI_CAPSULE_CRT_FILE must be specified when CONFIG_EFI_CAPSULE_AUTHENTICATE is enabled." >&2; \ - exit 1; \ - fi - $(call cmd,capsule_esl_gen) - -$(obj)/efi_capsule.o: $(srctree)/capsule_esl_file FORCE -asflags-y += -DCAPSULE_ESL_PATH=\"$(srctree)/capsule_esl_file\" -endif - # Set the C flags to add and remove for each app $(foreach f,$(apps-y),\ $(eval CFLAGS_$(f).o := $(CFLAGS_EFI) -Os -ffreestanding)\ diff --git a/lib/efi_loader/capsule_esl.dtsi.in b/lib/efi_loader/capsule_esl.dtsi.in new file mode 100644 index 00000000000..bc7db836faa --- /dev/null +++ b/lib/efi_loader/capsule_esl.dtsi.in @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Devicetree file with the public key EFI Signature List(ESL) + * node. This file is used to generate the dtsi file to be + * included into the DTB. + */ +/ { + signature { + capsule-key = /incbin/("ESL_BIN_FILE"); + }; +}; diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index 1aa52ac7bb6..f8a4a7c6ef4 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -22,7 +22,6 @@ #include <asm/global_data.h> #include <u-boot/uuid.h> -#include <asm/sections.h> #include <crypto/pkcs7.h> #include <crypto/pkcs7_parser.h> #include <linux/err.h> @@ -285,12 +284,33 @@ out: } #if defined(CONFIG_EFI_CAPSULE_AUTHENTICATE) -static int efi_get_public_key_data(const void **pkey, efi_uintn_t *pkey_len) +int efi_get_public_key_data(void **pkey, efi_uintn_t *pkey_len) { - const void *blob = __efi_capsule_sig_begin; - const int len = __efi_capsule_sig_end - __efi_capsule_sig_begin; + const void *fdt_blob = gd->fdt_blob; + const void *blob; + const char *cnode_name = "capsule-key"; + const char *snode_name = "signature"; + int sig_node; + int len; + + sig_node = fdt_subnode_offset(fdt_blob, 0, snode_name); + if (sig_node < 0) { + log_err("Unable to get signature node offset\n"); + + return -FDT_ERR_NOTFOUND; + } + + blob = fdt_getprop(fdt_blob, sig_node, cnode_name, &len); + + if (!blob || len < 0) { + log_err("Unable to get capsule-key value\n"); + *pkey = NULL; + *pkey_len = 0; + + return -FDT_ERR_NOTFOUND; + } - *pkey = blob; + *pkey = (void *)blob; *pkey_len = len; return 0; @@ -301,8 +321,7 @@ efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_s { u8 *buf; int ret; - void *pkey; - const void *stored_pkey; + void *fdt_pkey, *pkey; efi_uintn_t pkey_len; uint64_t monotonic_count; struct efi_signature_store *truststore; @@ -354,7 +373,7 @@ efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_s goto out; } - ret = efi_get_public_key_data(&stored_pkey, &pkey_len); + ret = efi_get_public_key_data(&fdt_pkey, &pkey_len); if (ret < 0) goto out; @@ -362,7 +381,7 @@ efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_s if (!pkey) goto out; - memcpy(pkey, stored_pkey, pkey_len); + memcpy(pkey, fdt_pkey, pkey_len); truststore = efi_build_signature_store(pkey, pkey_len); if (!truststore) goto out; diff --git a/lib/efi_loader/efi_capsule_key.S b/lib/efi_loader/efi_capsule_key.S deleted file mode 100644 index 80cefbe16ae..00000000000 --- a/lib/efi_loader/efi_capsule_key.S +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * .esl cert for capsule authentication - * - * Copyright (c) 2021, Ilias Apalodimas <ilias.apalodi...@linaro.org> - */ - -#include <config.h> - -.section .rodata.capsule_key.init,"a" -.balign 16 -.global __efi_capsule_sig_begin -__efi_capsule_sig_begin: -.incbin CAPSULE_ESL_PATH -__efi_capsule_sig_end: -.global __efi_capsule_sig_end -.balign 16 diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index e89a4a51b74..371f3922e99 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -377,8 +377,35 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ ; \ sed "s:$(pre-tmp):$(<):" $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) +capsule_esl_input_file=$(srctree)/lib/efi_loader/capsule_esl.dtsi.in +capsule_crt_file=$(subst $(quote),,$(CONFIG_EFI_CAPSULE_CRT_FILE)) +capsule_esl_dtsi=.capsule_esl.dtsi + +quiet_cmd_capsule_esl_gen = CAPSULE_ESL_GEN $@ +cmd_capsule_esl_gen = cert-to-efi-sig-list $< $@ + +$(obj)/capsule_esl_file: $(capsule_crt_file) FORCE +ifeq ($(CONFIG_EFI_CAPSULE_CRT_FILE),"") + $(error "CONFIG_EFI_CAPSULE_CRT_FILE is empty, EFI capsule authentication \ + public key must be specified when CONFIG_EFI_CAPSULE_AUTHENTICATE is enabled") +else + $(call cmd,capsule_esl_gen) +endif + +quiet_cmd_capsule_dtsi_gen = CAPSULE_DTSI_GEN $@ +cmd_capsule_dtsi_gen = \ + $(shell sed "s:ESL_BIN_FILE:$(abspath $<):" $(capsule_esl_input_file) > $@) + +$(obj)/$(capsule_esl_dtsi): $(obj)/capsule_esl_file FORCE + $(call cmd,capsule_dtsi_gen) + dtsi_include_list_deps := $(addprefix $(u_boot_dtsi_loc),$(subst $(quote),,$(dtsi_include_list))) +ifdef CONFIG_EFI_CAPSULE_AUTHENTICATE +dtsi_include_list += $(capsule_esl_dtsi) +dtsi_include_list_deps += $(obj)/$(capsule_esl_dtsi) +endif + ifneq ($(CHECK_DTBS),) DT_CHECKER ?= dt-validate DT_CHECKER_FLAGS ?= $(if $(DT_SCHEMA_FILES),-l $(DT_SCHEMA_FILES),-m) -- 2.34.1