[PATCH 1/3] efi_capsule: Move signature from DTB to .rodata

Sughosh Ganu sughosh.ganu at linaro.org
Fri Jul 16 08:44:16 CEST 2021


On Thu, 15 Jul 2021 at 22:30, Ilias Apalodimas <ilias.apalodimas at linaro.org>
wrote:

> The capsule signature is now part of our DTB.  This is problematic when a
> user is allowed to change/fixup that DTB from U-Boots command line since he
> can overwrite the signature as well.
> So Instead of adding the key on the DTB, embed it in the u-boot binary it
> self as part of it's .rodata.  This assumes that the U-Boot binary we load
> is authenticated by a previous boot stage loader.
>
> Signed-off-by: Ilias Apalodimas <ilias.apalodimas at linaro.org>
> ---
>  board/emulation/common/Makefile       |  1 -
>  board/emulation/common/qemu_capsule.c | 43 ---------------------------
>  include/asm-generic/sections.h        |  2 ++
>  lib/efi_loader/Kconfig                |  6 ++++
>  lib/efi_loader/Makefile               |  8 +++++
>  lib/efi_loader/efi_capsule.c          | 18 +++++++++--
>  lib/efi_loader/efi_capsule_key.S      |  8 +++++
>  7 files changed, 39 insertions(+), 47 deletions(-)
>  delete mode 100644 board/emulation/common/qemu_capsule.c
>  create mode 100644 lib/efi_loader/efi_capsule_key.S
>

Tested the changes on Qemu arm64 virt platform.

Tested-by: Sughosh Ganu <sughosh.ganu at linaro.org>

-sughosh


>
> diff --git a/board/emulation/common/Makefile
> b/board/emulation/common/Makefile
> index 7ed447a69dce..c5b452e7e341 100644
> --- a/board/emulation/common/Makefile
> +++ b/board/emulation/common/Makefile
> @@ -2,4 +2,3 @@
>
>  obj-$(CONFIG_SYS_MTDPARTS_RUNTIME) += qemu_mtdparts.o
>  obj-$(CONFIG_SET_DFU_ALT_INFO) += qemu_dfu.o
> -obj-$(CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT) += qemu_capsule.o
> diff --git a/board/emulation/common/qemu_capsule.c
> b/board/emulation/common/qemu_capsule.c
> deleted file mode 100644
> index 6b8a87022a4c..000000000000
> --- a/board/emulation/common/qemu_capsule.c
> +++ /dev/null
> @@ -1,43 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0+
> -/*
> - * Copyright (c) 2020 Linaro Limited
> - */
> -
> -#include <common.h>
> -#include <efi_api.h>
> -#include <efi_loader.h>
> -#include <env.h>
> -#include <fdtdec.h>
> -#include <asm/global_data.h>
> -
> -DECLARE_GLOBAL_DATA_PTR;
> -
> -int efi_get_public_key_data(void **pkey, efi_uintn_t *pkey_len)
> -{
> -       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) {
> -               EFI_PRINT("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) {
> -               EFI_PRINT("Unable to get capsule-key value\n");
> -               *pkey = NULL;
> -               *pkey_len = 0;
> -               return -FDT_ERR_NOTFOUND;
> -       }
> -
> -       *pkey = (void *)blob;
> -       *pkey_len = len;
> -
> -       return 0;
> -}
> diff --git a/include/asm-generic/sections.h
> b/include/asm-generic/sections.h
> index 267f1db73f23..ec992b0c2e3f 100644
> --- a/include/asm-generic/sections.h
> +++ b/include/asm-generic/sections.h
> @@ -27,6 +27,8 @@ 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/Kconfig b/lib/efi_loader/Kconfig
> index 156b39152112..42f1292fa04b 100644
> --- a/lib/efi_loader/Kconfig
> +++ b/lib/efi_loader/Kconfig
> @@ -213,6 +213,12 @@ config EFI_CAPSULE_AUTHENTICATE
>           Select this option if you want to enable capsule
>           authentication
>
> +config EFI_CAPSULE_KEY_PATH
> +       string "Path to .esl file for capsule authentication"
> +       depends on EFI_CAPSULE_AUTHENTICATE
> +       help
> +         Provide the .esl file used for capsule authentication
> +
>  config EFI_DEVICE_PATH_TO_TEXT
>         bool "Device path to text protocol"
>         default y
> diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
> index fd344cea29b0..9b369430e258 100644
> --- a/lib/efi_loader/Makefile
> +++ b/lib/efi_loader/Makefile
> @@ -20,11 +20,19 @@ always += helloworld.efi
>  targets += helloworld.o
>  endif
>
> +ifeq ($(CONFIG_EFI_CAPSULE_AUTHENTICATE),y)
> +EFI_CAPSULE_KEY_PATH := $(subst $\",,$(CONFIG_EFI_CAPSULE_KEY_PATH))
> +ifeq ("$(wildcard $(EFI_CAPSULE_KEY_PATH))","")
> +$(error .esl cerificate not found. Configure your
> CONFIG_EFI_CAPSULE_KEY_PATH)
> +endif
> +endif
> +
>  obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o
>  obj-$(CONFIG_CMD_BOOTEFI_BOOTMGR) += efi_bootmgr.o
>  obj-y += efi_boottime.o
>  obj-y += efi_helper.o
>  obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o
> +obj-$(CONFIG_EFI_CAPSULE_AUTHENTICATE) += efi_capsule_key.o
>  obj-$(CONFIG_EFI_CAPSULE_FIRMWARE) += efi_firmware.o
>  obj-y += efi_console.o
>  obj-y += efi_device_path.o
> diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
> index b878e71438b8..50e93cad4ee5 100644
> --- a/lib/efi_loader/efi_capsule.c
> +++ b/lib/efi_loader/efi_capsule.c
> @@ -16,6 +16,7 @@
>  #include <mapmem.h>
>  #include <sort.h>
>
> +#include <asm/sections.h>
>  #include <crypto/pkcs7.h>
>  #include <crypto/pkcs7_parser.h>
>  #include <linux/err.h>
> @@ -222,12 +223,23 @@ skip:
>  const efi_guid_t efi_guid_capsule_root_cert_guid =
>         EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
>
> +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;
> +
> +       *pkey = (void *)blob;
> +       *pkey_len = len;
> +
> +       return 0;
> +}
> +
>  efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t
> capsule_size,
>                                       void **image, efi_uintn_t
> *image_size)
>  {
>         u8 *buf;
>         int ret;
> -       void *fdt_pkey, *pkey;
> +       void *stored_pkey, *pkey;
>         efi_uintn_t pkey_len;
>         uint64_t monotonic_count;
>         struct efi_signature_store *truststore;
> @@ -286,7 +298,7 @@ efi_status_t efi_capsule_authenticate(const void
> *capsule, efi_uintn_t capsule_s
>                 goto out;
>         }
>
> -       ret = efi_get_public_key_data(&fdt_pkey, &pkey_len);
> +       ret = efi_get_public_key_data(&stored_pkey, &pkey_len);
>         if (ret < 0)
>                 goto out;
>
> @@ -294,7 +306,7 @@ efi_status_t efi_capsule_authenticate(const void
> *capsule, efi_uintn_t capsule_s
>         if (!pkey)
>                 goto out;
>
> -       memcpy(pkey, fdt_pkey, pkey_len);
> +       memcpy(pkey, stored_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
> new file mode 100644
> index 000000000000..f7047a42e39d
> --- /dev/null
> +++ b/lib/efi_loader/efi_capsule_key.S
> @@ -0,0 +1,8 @@
> +.section .rodata.capsule_key.init,"a"
> +.balign 16
> +.global __efi_capsule_sig_begin
> +__efi_capsule_sig_begin:
> +.incbin CONFIG_EFI_CAPSULE_KEY_PATH
> +__efi_capsule_sig_end:
> +.global __efi_capsule_sig_end
> +.balign 16
> --
> 2.32.0.rc0
>
>


More information about the U-Boot mailing list