diff mbox series

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

Message ID 20210715170030.97758-1-ilias.apalodimas@linaro.org
State Superseded
Headers show
Series [1/3] efi_capsule: Move signature from DTB to .rodata | expand

Commit Message

Ilias Apalodimas July 15, 2021, 5 p.m. UTC
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@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

-- 
2.32.0.rc0

Comments

Masami Hiramatsu July 16, 2021, 5:57 a.m. UTC | #1
2021年7月16日(金) 2:00 Ilias Apalodimas <ilias.apalodimas@linaro.org>:
>

> 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.

>


I have tested this patch on DeveloperBox.
Without signing the capsule,

----
** Unrecognized filesystem type **
Capsule authentication check failed. Aborting update
Firmware update failed: <NULL>
Applying capsule UBOOT1024.Cap failed
PlatformLang:
----

With signing the capsule (by Takahiro's patch*)
(*) https://lists.denx.de/pipermail/u-boot/2021-May/449878.html
----
** Unrecognized filesystem type **
####################################################################################################
###########################################################################PlatformLang:
----

Reviewed-by: Masami Hiramatsu <masami.hiramatsu@linaro.org>

Tested-by: Masami Hiramatsu <masami.hiramatsu@linaro.org>


IMHO, we should have a command to show that the current U-Boot
has what certification from the console for debugging.
(also, need to import Takahiro's patch)

Thank you,

> Signed-off-by: Ilias Apalodimas <ilias.apalodimas@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

>

> 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

>



--
Masami Hiramatsu
Sughosh Ganu July 16, 2021, 6:44 a.m. UTC | #2
On Thu, 15 Jul 2021 at 22:30, Ilias Apalodimas <ilias.apalodimas@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@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@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

>

>
AKASHI Takahiro July 16, 2021, 1:39 p.m. UTC | #3
Just a few minor comments:

On Fri, Jul 16, 2021 at 02:57:00PM +0900, Masami Hiramatsu wrote:
> 2021年7月16日(金) 2:00 Ilias Apalodimas <ilias.apalodimas@linaro.org>:

> >

> > 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.

> >

> 

> I have tested this patch on DeveloperBox.

> Without signing the capsule,

> 

> ----

> ** Unrecognized filesystem type **

> Capsule authentication check failed. Aborting update

> Firmware update failed: <NULL>

> Applying capsule UBOOT1024.Cap failed

> PlatformLang:

> ----

> 

> With signing the capsule (by Takahiro's patch*)

> (*) https://lists.denx.de/pipermail/u-boot/2021-May/449878.html

> ----

> ** Unrecognized filesystem type **

> ####################################################################################################

> ###########################################################################PlatformLang:

> ----

> 

> Reviewed-by: Masami Hiramatsu <masami.hiramatsu@linaro.org>

> Tested-by: Masami Hiramatsu <masami.hiramatsu@linaro.org>

> 

> IMHO, we should have a command to show that the current U-Boot

> has what certification from the console for debugging.

> (also, need to import Takahiro's patch)

> 

> Thank you,

> 

> > Signed-off-by: Ilias Apalodimas <ilias.apalodimas@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

> >

> > 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


We might be friendly if we add what "esl" means here.
More importantly, we are able to contain more than one signatures
if we want.

> > +

> >  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


We should give users another choice here to allow them to add their
own solution for key storage.
Or only enable this line if "CONFIG_EFI_CAPSULE_KEY_PATH" != null?

> >  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)


static?

> > +{

> > +       const void *blob = __efi_capsule_sig_begin;

> > +       const int len = __efi_capsule_sig_end - __efi_capsule_sig_begin;


It seems that the length can be calculated at compile time.

> > +       *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 @@


Should we have "#include <config.h>" here?
Otherwise it looks good.

-Takahiro Akashi

> > +.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

> >

> 

> 

> --

> Masami Hiramatsu
Simon Glass July 16, 2021, 1:49 p.m. UTC | #4
Hi Ilias,

On Thu, 15 Jul 2021 at 11:00, Ilias Apalodimas
<ilias.apalodimas@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.


Do you mean with the 'fdt' command?

If you mean the FDT fixups, they happen to a different DT, the one
being passed to Linux.

> 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@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


Regards,
Simon
Ilias Apalodimas July 17, 2021, 11:35 a.m. UTC | #5
> > >


[...]

> > > +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

> 

> We might be friendly if we add what "esl" means here.

> More importantly, we are able to contain more than one signatures

> if we want.


Sure, I'll replace it on the help message

> 

> > > +

> > >  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

> 

> We should give users another choice here to allow them to add their

> own solution for key storage.

> Or only enable this line if "CONFIG_EFI_CAPSULE_KEY_PATH" != null?

> 

> > >  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)

> 

> static?


yea

> 

> > > +{

> > > +       const void *blob = __efi_capsule_sig_begin;

> > > +       const int len = __efi_capsule_sig_end - __efi_capsule_sig_begin;

> 

> It seems that the length can be calculated at compile time.

> 


Yea but you still need the __efi_capsule_sig_begin.  What's the proposal
here? Replace __efi_capsule_sig_end with the size on the .S file?

> > > +       *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 @@

> 

> Should we have "#include <config.h>" here?


Hmm maybe. Compiling didn't cause any problems, but it seems we can add
that include


> Otherwise it looks good.

> 

> -Takahiro Akashi


Thanks
/Ilias
> 

> > > +.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

> > >

> > 

> > 

> > --

> > Masami Hiramatsu
Ilias Apalodimas July 17, 2021, 11:36 a.m. UTC | #6
On Fri, Jul 16, 2021 at 07:49:09AM -0600, Simon Glass wrote:
> Hi Ilias,

> 

> On Thu, 15 Jul 2021 at 11:00, Ilias Apalodimas

> <ilias.apalodimas@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.

> 

> Do you mean with the 'fdt' command?

> 

> If you mean the FDT fixups, they happen to a different DT, the one

> being passed to Linux.

> 


This was only usable in QEMU pre-patch.  I think Sughosh replaced the
entire DTB (including the signature) on his tests.

Sughosh?

Cheers
/Ilias

> > 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@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

> 

> Regards,

> Simon
Ilias Apalodimas July 17, 2021, 2:14 p.m. UTC | #7
On Sat, 17 Jul 2021 at 14:35, Ilias Apalodimas
<ilias.apalodimas@linaro.org> wrote:
>

> > > >


[...]

> > > >  obj-$(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) += efi_capsule.o

> > > > +obj-$(CONFIG_EFI_CAPSULE_AUTHENTICATE) += efi_capsule_key.o

> >

> > We should give users another choice here to allow them to add their

> > own solution for key storage.

> > Or only enable this line if "CONFIG_EFI_CAPSULE_KEY_PATH" != null?


Actually once you enable the capsule authentication compilation fails
now if a file is not provided, with a message asking for the use to
provide a valid filepath.  I'd prefer leaving it as is and once we get
a hardware that can override the embedded key, we can add an extra
Kconfig option.

> >

> > > >  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)

> >

> > static?

>

> yea


Once we do get support for hardware stored signatures, this can be
changed to a __weak function.

>

> >

> > > > +{

> > > > +       const void *blob = __efi_capsule_sig_begin;

> > > > +       const int len = __efi_capsule_sig_end - __efi_capsule_sig_begin;

> >

> > It seems that the length can be calculated at compile time.

> >

>

> Yea but you still need the __efi_capsule_sig_begin.  What's the proposal

> here? Replace __efi_capsule_sig_end with the size on the .S file?

>

> > > > +       *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 @@

> >

> > Should we have "#include <config.h>" here?

>

> Hmm maybe. Compiling didn't cause any problems, but it seems we can add

> that include

>

>

> > Otherwise it looks good.

> >

> > -Takahiro Akashi

>

> Thanks

> /Ilias

> >

> > > > +.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

> > > >

> > >

> > >

> > > --

> > > Masami Hiramatsu
diff mbox series

Patch

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