diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h index ddbbfac491f..28cac120bf9 100644 --- a/include/asm-generic/sections.h +++ b/include/asm-generic/sections.h @@ -27,8 +27,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 fa727397e99..a8e7f83336f 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 @@ -75,23 +74,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 #include -#include #include #include #include @@ -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; - *pkey = blob; + 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 = (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 - */ - -#include - -.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 4977bb737d9..3c9d37c911e 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)