[RESEND PATCH v1 0/5] Add support for embedding public key in platform's dtb

Resending the same set of patches. For some reason, the first paragraph of the cover letter got deleted in the original set. Hopefully this will go through fine.
These patches add support for embedding the public key efi signature list(esl) file into the platform's device tree. The current solution for the Qemu arm64 platform has the public key as part of an overlay, and stored on the Efi System Partition(ESP). Having the provision to embed the public key into the platform's dtb which is then concatenated with the u-boot binary is a better approach, recommended by Heinrich[1].
Patch 1 fixes an issue of selection of IMAGE_SIGN_INFO config option when capsule authentication is enabled.
Patch 2 add two config symbols, EFI_PKEY_DTB_EMBED and EFI_PKEY_FILE which are used for enabling embedding of the public key in the dtb, and specifying the esl file name.
Patch 3 moves efi_capsule_auth_enabled as a weak function, which can be used as a default mechanism for checking if capsule authentication has been enabled.
Patch 4 adds a default weak function for retrieving the public key from the platform's dtb.
Patch 5 adds the functionality to embed the esl file into the platform's dtb during the platform build.
I have tested this functionality on the STM32MP157C DK2 board, and it works as expected.
[1] - https://lists.denx.de/pipermail/u-boot/2021-March/442867.html
Sughosh Ganu (5): efi_loader: Kconfig: Select IMAGE_SIGN_INFO when capsule authentication is enabled efi_loader: Kconfig: Add symbols for embedding the public key into the platform's dtb efi_capsule: Add a weak function to check whether capsule authentication is enabled efi_capsule: Add a weak function to get the public key needed for capsule authentication Makefile: Add provision for embedding public key in platform's dtb
Makefile | 10 ++++++ board/emulation/common/qemu_capsule.c | 6 ---- lib/efi_loader/Kconfig | 16 ++++++++++ lib/efi_loader/efi_capsule.c | 44 ++++++++++++++++++++++++--- 4 files changed, 66 insertions(+), 10 deletions(-)

Enable building of the crypto helper functions used during capsule authentication by selecting IMAGE_SIGN_INFO.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org ---
This was not detected when support for capsule auth was added to the qemu arm64 platform. This is because the platform includes CONFIG_FIT_SIGNATURE which selects IMAGE_SIGN_INFO.
lib/efi_loader/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index e44f004f3f..0b99d7c774 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -173,6 +173,7 @@ config EFI_CAPSULE_AUTHENTICATE select X509_CERTIFICATE_PARSER select PKCS7_MESSAGE_PARSER select PKCS7_VERIFY + select IMAGE_SIGN_INFO default n help Select this option if you want to enable capsule

On Thu, 8 Apr 2021 at 02:42, Sughosh Ganu sughosh.ganu@linaro.org wrote:
Enable building of the crypto helper functions used during capsule authentication by selecting IMAGE_SIGN_INFO.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org
This was not detected when support for capsule auth was added to the qemu arm64 platform. This is because the platform includes CONFIG_FIT_SIGNATURE which selects IMAGE_SIGN_INFO.
lib/efi_loader/Kconfig | 1 + 1 file changed, 1 insertion(+)
Reviewed-by: Simon Glass sjg@chromium.org

Add config options EFI_PKEY_DTB_EMBED and EFI_PKEY_FILE which are to be used for embedding the public key to be used for capsule authentication into the platform's device tree.
The embedding of the public key would take place during the platform build process.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- lib/efi_loader/Kconfig | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 0b99d7c774..de3083a979 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -179,6 +179,21 @@ config EFI_CAPSULE_AUTHENTICATE Select this option if you want to enable capsule authentication
+config EFI_PKEY_DTB_EMBED + bool "Embed the public key in the Device Tree" + default n + depends on EFI_CAPSULE_AUTHENTICATE + help + Select this option if the public key used for capsule + authentication is to be embedded into the platform's + device tree. + +config EFI_PKEY_FILE + string "Public Key esl file to be embedded into the Device Tree" + help + Specify the absolute path of the public key esl file that is + to be embedded in the platform's device tree. + config EFI_CAPSULE_FIRMWARE_FIT bool "FMP driver for FIT image" depends on EFI_CAPSULE_FIRMWARE_MANAGEMENT

Define a weak function which checks if the environment variable capsule_authentication_enabled has been set, for enabling capsule authentication. Other platforms might have a different mechanism to determine this, and would then define their own platform specific function.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- board/emulation/common/qemu_capsule.c | 6 ------ lib/efi_loader/efi_capsule.c | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/board/emulation/common/qemu_capsule.c b/board/emulation/common/qemu_capsule.c index 5cb461d52b..6b8a87022a 100644 --- a/board/emulation/common/qemu_capsule.c +++ b/board/emulation/common/qemu_capsule.c @@ -41,9 +41,3 @@ int efi_get_public_key_data(void **pkey, efi_uintn_t *pkey_len)
return 0; } - -bool efi_capsule_auth_enabled(void) -{ - return env_get("capsule_authentication_enabled") != NULL ? - true : false; -} diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index 0cfff0daf7..1423b675c8 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -218,6 +218,12 @@ __weak int efi_get_public_key_data(void **pkey, efi_uintn_t *pkey_len) return 0; }
+__weak bool efi_capsule_auth_enabled(void) +{ + return env_get("capsule_authentication_enabled") ? + true : false; +} + efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_size, void **image, efi_uintn_t *image_size) {

Define a weak function which would be used in the scenario where the public key is stored on the platform's dtb. This dtb is concatenated with the u-boot binary during the build process. Platforms which have a different mechanism for getting the public key would define their own platform specific function.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- lib/efi_loader/efi_capsule.c | 38 ++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-)
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c index 1423b675c8..fc5e1c0856 100644 --- a/lib/efi_loader/efi_capsule.c +++ b/lib/efi_loader/efi_capsule.c @@ -14,10 +14,13 @@ #include <mapmem.h> #include <sort.h>
+#include <asm/global_data.h> #include <crypto/pkcs7.h> #include <crypto/pkcs7_parser.h> #include <linux/err.h>
+DECLARE_GLOBAL_DATA_PTR; + const efi_guid_t efi_guid_capsule_report = EFI_CAPSULE_REPORT_GUID; static const efi_guid_t efi_guid_firmware_management_capsule_id = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; @@ -210,11 +213,38 @@ const efi_guid_t efi_guid_capsule_root_cert_guid =
__weak int efi_get_public_key_data(void **pkey, efi_uintn_t *pkey_len) { - /* The platform is supposed to provide - * a method for getting the public key - * stored in the form of efi signature - * list + /* + * This is a function for retrieving the public key from the + * platform's device tree. The platform's device tree has been + * concatenated with the u-boot binary. + * If a platform has a different mechanism to get the public + * key, it can define it's own function. */ + 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; }

Add provision for embedding the public key used for capsule authentication in the platform's dtb. This is done by invoking the mkeficapsule utility which puts the public key in the efi signature list(esl) format into the dtb.
Signed-off-by: Sughosh Ganu sughosh.ganu@linaro.org --- Makefile | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/Makefile b/Makefile index 193aa4d1c9..0d50c6a805 100644 --- a/Makefile +++ b/Makefile @@ -1010,6 +1010,10 @@ cmd_pad_cat = $(cmd_objcopy) && $(append) || { rm -f $@; false; } quiet_cmd_lzma = LZMA $@ cmd_lzma = lzma -c -z -k -9 $< > $@
+quiet_cmd_mkeficapsule = MKEFICAPSULE $@ +cmd_mkeficapsule = $(objtree)/tools/mkeficapsule -K $(CONFIG_EFI_PKEY_FILE) \ + -D $@ + cfg: u-boot.cfg
quiet_cmd_cfgcheck = CFGCHK $2 @@ -1104,8 +1108,14 @@ endif PHONY += dtbs dtbs: dts/dt.dtb @: +ifeq ($(CONFIG_EFI_CAPSULE_AUTHENTICATE)$(CONFIG_EFI_PKEY_DTB_EMBED),yy) +dts/dt.dtb: u-boot tools + $(Q)$(MAKE) $(build)=dts dtbs + $(call cmd,mkeficapsule) +else dts/dt.dtb: u-boot $(Q)$(MAKE) $(build)=dts dtbs +endif
quiet_cmd_copy = COPY $@ cmd_copy = cp $< $@
participants (2)
-
Simon Glass
-
Sughosh Ganu