diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey.inc b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey.inc index 82e760feb..0fd2d0f55 100644 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey.inc +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey.inc @@ -251,15 +251,17 @@ do_deploy:append:ccmp1() { install -m 0777 ${B}/${config}/u-boot-nodtb.bin ${DEPLOYDIR}/${BOOT_TOOLS}/u-boot-nodtb.bin # Append signature to u-boot DT - if [ "x${UBOOT_SIGN_ENABLE}" = "x1" ] ; then - # get name of u-boot devicetree without signature - ubootdevicetree=`ls -1 ${DEPLOYDIR}/${BOOT_TOOLS}/*.dtb | head -n 1` - namewithoutsignature=`echo $ubootdevicetree | sed "s/\.dtb/-without-signature.dtb/g"` - namewithsignature=`echo $ubootdevicetree | sed "s/\.dtb/-with-signature.dtb/g"` - mv $ubootdevicetree $namewithoutsignature - # get name of U-Boot device tree from DEPLOY_DIR - nameonkernel="${DEPLOY_DIR_IMAGE}/u-boot-${MACHINE}*.dtb" - cp $nameonkernel $namewithsignature - cp $nameonkernel $ubootdevicetree + if [ "x${UBOOT_SIGN_ENABLE}" = "x1" ] && [ -n "${UBOOT_DEVICETREE}" ] ; then + for devicetree in ${UBOOT_DEVICETREE}; do + # get name of u-boot devicetree without signature + ubootdevicetree="${DEPLOYDIR}/${BOOT_TOOLS}/${FIP_UBOOT_DTB}-${devicetree}.dtb" + namewithoutsignature=`echo $ubootdevicetree | sed "s/\.dtb/-without-signature.dtb/g"` + namewithsignature=`echo $ubootdevicetree | sed "s/\.dtb/-with-signature.dtb/g"` + mv $ubootdevicetree $namewithoutsignature + # get name of U-Boot device tree from DEPLOY_DIR + nameonkernel="${DEPLOY_DIR_IMAGE}/${FIP_UBOOT_DTB}-${devicetree}-with-signature.dtb" + cp $nameonkernel $namewithsignature + cp $nameonkernel $ubootdevicetree + done fi } diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2021.10.bb b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2021.10.bb index 8f0dca3e6..1d0e04099 100644 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2021.10.bb +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-dey_2021.10.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2022,2023 Digi International +# Copyright (C) 2022-2024 Digi International require u-boot-dey.inc LIC_FILES_CHKSUM = "file://Licenses/README;md5=5a7450c57ffe5ae63fd732446b988025" @@ -17,22 +17,32 @@ UBOOT_FIT_CFG_FRAGMENTS = " \ SRC_URI += " \ ${@oe.utils.conditional('TRUSTFENCE_SIGN', '1', '${UBOOT_FIT_CFG_FRAGMENTS}', '', d)} \ " -# Install UBOOT_ENV_BINARY to datadir, so that kernel can use it -# to include it into the FIT image. -install_helper_bootscr() { + +install_helper_files() { + # Install UBOOT_ENV_BINARY to datadir, so that kernel can use it + # to include it into the FIT image. if [ -f "${D}/boot/${UBOOT_ENV_BINARY}" ]; then - # Install UBOOT_ENV_BINARY into datadir to share it with the kernel install -Dm 0644 ${D}/boot/${UBOOT_ENV_BINARY} ${D}${datadir}/${UBOOT_ENV_IMAGE} ln -sf ${UBOOT_ENV_IMAGE} ${D}${datadir}/${UBOOT_ENV_BINARY} else bbwarn "${D}/boot/${UBOOT_ENV_BINARY} not found" fi + + # Install dtbs from UBOOT_DEVICETREE to datadir, so that kernel + # can use it for signing, and kernel will deploy after signs it. + if [ -n "${UBOOT_DEVICETREE}" ]; then + for devicetree in ${UBOOT_DEVICETREE}; do + install -Dm 0644 ${B}/${config}/arch/arm/dts/${devicetree}.dtb ${D}${datadir}/${devicetree}.dtb + done + else + bbwarn "${UBOOT_DEVICETREE} not found" + fi } do_install:append() { - # Copy boot script, so kernel can include it when creating the FIT image - if [ "${TRUSTFENCE_FIT_IMG}" = "1" ] && [ -n "${UBOOT_ENV_BINARY}" ]; then - install_helper_bootscr + # Copy additional files, so kernel can use it when creating the FIT image + if [ "${TRUSTFENCE_FIT_IMG}" = "1" ]; then + install_helper_files fi } diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-tools/0001-tools-add-fdt_add_pubkey.patch b/meta-digi-arm/recipes-bsp/u-boot/u-boot-tools/0001-tools-add-fdt_add_pubkey.patch new file mode 100644 index 000000000..911bf3dc1 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-tools/0001-tools-add-fdt_add_pubkey.patch @@ -0,0 +1,233 @@ +From: Roman Kopytin +Date: Wed, 8 Mar 2023 01:13:41 +0000 +Subject: [PATCH] tools: add fdt_add_pubkey + +Having to use the -K option to mkimage to populate U-Boot's .dtb with the +public key while signing the kernel FIT image is often a little +awkward. In particular, when using a meta-build system such as +bitbake/Yocto, having the tasks of the kernel and U-Boot recipes +intertwined, modifying deployed artifacts and rebuilding U-Boot with +an updated .dtb is quite cumbersome. Also, in some scenarios one may +wish to build U-Boot complete with the public key(s) embedded in the +.dtb without the corresponding private keys being present on the same +build host. + +So this adds a simple tool that allows one to disentangle the kernel +and U-Boot builds, by simply copy-pasting just enough of the mkimage +code to allow one to add a public key to a .dtb. When using mkimage, +some of the information is taken from the .its used to build the +kernel (algorithm and key name), so that of course needs to be +supplied on the command line. + +Signed-off-by: Roman Kopytin +Signed-off-by: Ivan Mikhaylov +Signed-off-by: Jan Kiszka +Cc: Rasmus Villemoes + +--- + tools/.gitignore | 1 + + tools/Makefile | 3 + + tools/fdt_add_pubkey.c | 138 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 142 insertions(+) + create mode 100644 tools/fdt_add_pubkey.c + +diff --git a/tools/.gitignore b/tools/.gitignore +index a88453f64d..f312b760e4 100644 +--- a/tools/.gitignore ++++ b/tools/.gitignore +@@ -4,10 +4,11 @@ + /bmp_logo + /common/ + /dumpimage + /easylogo/easylogo + /envcrc ++/fdt_add_pubkey + /fdtgrep + /file2include + /fit_check_sign + /fit_info + /gdb/gdbcont +diff --git a/tools/Makefile b/tools/Makefile +index 1763f44cac..ce7a49ff61 100644 +--- a/tools/Makefile ++++ b/tools/Makefile +@@ -71,10 +71,11 @@ HOSTCFLAGS_xway-swap-bytes.o := -pedantic + hostprogs-y += mkenvimage + mkenvimage-objs := mkenvimage.o os_support.o lib/crc32.o + + hostprogs-y += dumpimage mkimage + hostprogs-$(CONFIG_TOOLS_LIBCRYPTO) += fit_info fit_check_sign ++hostprogs-$(CONFIG_TOOLS_LIBCRYPTO) += fdt_add_pubkey + + hostprogs-$(CONFIG_CMD_BOOTEFI_SELFTEST) += file2include + + FIT_OBJS-y := fit_common.o fit_image.o image-host.o boot/image-fit.o + FIT_SIG_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := image-sig-host.o boot/image-fit-sig.o +@@ -152,10 +153,11 @@ dumpimage-mkimage-objs := aisimage.o \ + + dumpimage-objs := $(dumpimage-mkimage-objs) dumpimage.o + mkimage-objs := $(dumpimage-mkimage-objs) mkimage.o + fit_info-objs := $(dumpimage-mkimage-objs) fit_info.o + fit_check_sign-objs := $(dumpimage-mkimage-objs) fit_check_sign.o ++fdt_add_pubkey-objs := $(dumpimage-mkimage-objs) fdt_add_pubkey.o + file2include-objs := file2include.o + + ifneq ($(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_TOOLS_LIBCRYPTO),) + # Add CONFIG_MXS into host CFLAGS, so we can check whether or not register + # the mxsimage support within tools/mxsimage.c . +@@ -189,10 +191,11 @@ endif + HOSTCFLAGS_fit_image.o += -DMKIMAGE_DTC=\"$(CONFIG_MKIMAGE_DTC_PATH)\" + + HOSTLDLIBS_dumpimage := $(HOSTLDLIBS_mkimage) + HOSTLDLIBS_fit_info := $(HOSTLDLIBS_mkimage) + HOSTLDLIBS_fit_check_sign := $(HOSTLDLIBS_mkimage) ++HOSTLDLIBS_fdt_add_pubkey := $(HOSTLDLIBS_mkimage) + + hostprogs-$(CONFIG_EXYNOS5250) += mkexynosspl + hostprogs-$(CONFIG_EXYNOS5420) += mkexynosspl + HOSTCFLAGS_mkexynosspl.o := -pedantic + +diff --git a/tools/fdt_add_pubkey.c b/tools/fdt_add_pubkey.c +new file mode 100644 +index 0000000000..999f5a7e83 +--- /dev/null ++++ b/tools/fdt_add_pubkey.c +@@ -0,0 +1,138 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++#include ++#include "fit_common.h" ++ ++static const char *cmdname; ++ ++static const char *algo_name = "sha1,rsa2048"; /* -a */ ++static const char *keydir = "."; /* -k */ ++static const char *keyname = "key"; /* -n */ ++static const char *require_keys; /* -r */ ++static const char *keydest; /* argv[n] */ ++ ++static void print_usage(const char *msg) ++{ ++ fprintf(stderr, "Error: %s\n", msg); ++ fprintf(stderr, "Usage: %s [-a ] [-k ] [-n ] [-r ]" ++ " \n", cmdname); ++ fprintf(stderr, "Help information: %s [-h]\n", cmdname); ++ exit(EXIT_FAILURE); ++} ++ ++static void print_help(void) ++{ ++ fprintf(stderr, "Options:\n" ++ "\t-a Cryptographic algorithm. Optional parameter, default value: sha1,rsa2048\n" ++ "\t-k Directory with public key. Optional parameter, default value: .\n" ++ "\t-n Public key name. Optional parameter, default value: key\n" ++ "\t-r Required: If present this indicates that the key must be verified for the image / configuration to be considered valid.\n" ++ "\t FDT blob file for adding of the public key. Required parameter.\n"); ++ exit(EXIT_FAILURE); ++} ++ ++static void process_args(int argc, char *argv[]) ++{ ++ int opt; ++ ++ while ((opt = getopt(argc, argv, "a:k:n:r:h")) != -1) { ++ switch (opt) { ++ case 'k': ++ keydir = optarg; ++ break; ++ case 'a': ++ algo_name = optarg; ++ break; ++ case 'n': ++ keyname = optarg; ++ break; ++ case 'r': ++ require_keys = optarg; ++ break; ++ case 'h': ++ print_help(); ++ default: ++ print_usage("Invalid option"); ++ } ++ } ++ /* The last parameter is expected to be the .dtb to add the public key to */ ++ if (optind < argc) ++ keydest = argv[optind]; ++ ++ if (!keydest) ++ print_usage("Missing dtb file to update"); ++} ++ ++static void reset_info(struct image_sign_info *info) ++{ ++ if (!info) ++ fprintf(stderr, "Error: info is NULL in %s\n", __func__); ++ ++ memset(info, 0, sizeof(struct image_sign_info)); ++ ++ info->keydir = keydir; ++ info->keyname = keyname; ++ info->name = algo_name; ++ info->require_keys = require_keys; ++ info->crypto = image_get_crypto_algo(algo_name); ++ ++ if (!info->crypto) { ++ fprintf(stderr, "Unsupported signature algorithm '%s'\n", ++ algo_name); ++ exit(EXIT_FAILURE); ++ } ++} ++ ++static int add_pubkey(struct image_sign_info *info) ++{ ++ int destfd = -1, ret; ++ void *dest_blob = NULL; ++ struct stat dest_sbuf; ++ size_t size_inc = 0; ++ ++ if (!info) ++ fprintf(stderr, "Error: info is NULL in %s\n", __func__); ++ ++ do { ++ if (destfd >= 0) { ++ munmap(dest_blob, dest_sbuf.st_size); ++ close(destfd); ++ ++ fprintf(stderr, ".dtb too small, increasing size by 1024 bytes\n"); ++ size_inc = 1024; ++ } ++ ++ destfd = mmap_fdt(cmdname, keydest, size_inc, &dest_blob, ++ &dest_sbuf, false, false); ++ if (destfd < 0) ++ exit(EXIT_FAILURE); ++ ++ ret = info->crypto->add_verify_data(info, dest_blob); ++ if (ret == -ENOSPC) ++ continue; ++ else if (ret < 0) ++ break; ++ } while (ret == -ENOSPC); ++ ++ return ret; ++} ++ ++int main(int argc, char *argv[]) ++{ ++ struct image_sign_info info; ++ int ret; ++ ++ cmdname = argv[0]; ++ ++ process_args(argc, argv); ++ reset_info(&info); ++ ret = add_pubkey(&info); ++ ++ if (ret < 0) { ++ fprintf(stderr, "%s: Cannot add public key to FIT blob: %s\n", ++ cmdname, strerror(ret)); ++ exit(EXIT_FAILURE); ++ } ++ ++ exit(EXIT_SUCCESS); ++} ++ diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-tools/0002-tools-avoid-implicit-fallthrough-in-fdt_add_pubkey.patch b/meta-digi-arm/recipes-bsp/u-boot/u-boot-tools/0002-tools-avoid-implicit-fallthrough-in-fdt_add_pubkey.patch new file mode 100644 index 000000000..55e5be235 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-tools/0002-tools-avoid-implicit-fallthrough-in-fdt_add_pubkey.patch @@ -0,0 +1,48 @@ +From: Heinrich Schuchardt +Date: Sat, 1 Apr 2023 08:09:34 +0200 +Subject: [PATCH] tools: avoid implicit fallthrough in fdt_add_pubkey + +When building with -Wimplicit-fallthrough we get a warning + + tools/fdt_add_pubkey.c:52:25: warning: + this statement may fall through [-Wimplicit-fallthrough=] + 52 | print_help(); + | + +Explicitly declare which functions don't return. + +Fixes: 30238e99619c ("tools: add fdt_add_pubkey") +Signed-off-by: Heinrich Schuchardt +Reviewed-by: Simon Glass + +--- + tools/fdt_add_pubkey.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/fdt_add_pubkey.c b/tools/fdt_add_pubkey.c +index 999f5a7e83..5582d7a8ef 100644 +--- a/tools/fdt_add_pubkey.c ++++ b/tools/fdt_add_pubkey.c +@@ -8,20 +8,20 @@ static const char *algo_name = "sha1,rsa2048"; /* -a */ + static const char *keydir = "."; /* -k */ + static const char *keyname = "key"; /* -n */ + static const char *require_keys; /* -r */ + static const char *keydest; /* argv[n] */ + +-static void print_usage(const char *msg) ++static void __attribute__((__noreturn__)) print_usage(const char *msg) + { + fprintf(stderr, "Error: %s\n", msg); + fprintf(stderr, "Usage: %s [-a ] [-k ] [-n ] [-r ]" + " \n", cmdname); + fprintf(stderr, "Help information: %s [-h]\n", cmdname); + exit(EXIT_FAILURE); + } + +-static void print_help(void) ++static void __attribute__((__noreturn__)) print_help(void) + { + fprintf(stderr, "Options:\n" + "\t-a Cryptographic algorithm. Optional parameter, default value: sha1,rsa2048\n" + "\t-k Directory with public key. Optional parameter, default value: .\n" + "\t-n Public key name. Optional parameter, default value: key\n" diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-tools_%.bbappend b/meta-digi-arm/recipes-bsp/u-boot/u-boot-tools_%.bbappend new file mode 100644 index 000000000..18505972c --- /dev/null +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-tools_%.bbappend @@ -0,0 +1,21 @@ +# Copyright (C) 2024 Digi International + +FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:" + +# Backport from v2023.07 +SRC_URI:append = " \ + file://0001-tools-add-fdt_add_pubkey.patch \ + file://0002-tools-avoid-implicit-fallthrough-in-fdt_add_pubkey.patch \ +" + +do_install:append () { + install -d ${D}${bindir} + + # fdt_add_pubkey + if [ -f tools/fdt_add_pubkey ]; then + install -m 0755 tools/fdt_add_pubkey ${D}${bindir}/uboot-fdt_add_pubkey + ln -sf uboot-fdt_add_pubkey ${D}${bindir}/fdt_add_pubkey + fi +} + +FILES:${PN}-mkimage += "${bindir}/uboot-fdt_add_pubkey" diff --git a/meta-digi-arm/recipes-kernel/linux/linux-dey_5.15.bb b/meta-digi-arm/recipes-kernel/linux/linux-dey_5.15.bb index 1f6141a39..e219c7709 100644 --- a/meta-digi-arm/recipes-kernel/linux/linux-dey_5.15.bb +++ b/meta-digi-arm/recipes-kernel/linux/linux-dey_5.15.bb @@ -1,4 +1,4 @@ -# Copyright (C) 2022,2023 Digi International +# Copyright (C) 2022-2024 Digi International require recipes-kernel/linux/linux-dey.inc @@ -13,4 +13,45 @@ do_assemble_fitimage:prepend:ccmp1() { install -m 0644 ${RECIPE_SYSROOT}/${datadir}/${UBOOT_ENV_BINARY} ${STAGING_DIR_HOST}/boot/ } +do_assemble_fitimage:append:ccmp1() { + # + # Step 9: Add public keys to the different U-Boot dtb files + # + if [ "${UBOOT_SIGN_ENABLE}" = "1" ] && [ -n "${UBOOT_DEVICETREE}" ]; then + for devicetree in ${UBOOT_DEVICETREE}; do + if [ -f "${STAGING_DATADIR}/${devicetree}.dtb" ]; then + cp -P "${STAGING_DATADIR}/${devicetree}.dtb" ${B} + + # Add image public key in U-Boot dtb file + fdt_add_pubkey -a "${FIT_HASH_ALG},${FIT_SIGN_ALG}" \ + -k "${UBOOT_SIGN_KEYDIR}" \ + -n "${UBOOT_SIGN_IMG_KEYNAME}" \ + -r "image" \ + "${B}/${devicetree}.dtb" + + # Add configuration public key in U-Boot dtb file + fdt_add_pubkey -a "${FIT_HASH_ALG},${FIT_SIGN_ALG}" \ + -k "${UBOOT_SIGN_KEYDIR}" \ + -n "${UBOOT_SIGN_KEYNAME}" \ + -r "conf" \ + "${B}/${devicetree}.dtb" + fi + done + fi +} + +kernel_do_deploy:append:ccmp1() { + if [ "${UBOOT_SIGN_ENABLE}" = "1" -o "${UBOOT_FITIMAGE_ENABLE}" = "1" ] && \ + [ -n "${UBOOT_DTB_BINARY}" ] ; then + # Install device tree files with signature + if [ -n "${UBOOT_DEVICETREE}" ]; then + for devicetree in ${UBOOT_DEVICETREE}; do + if [ -f "${B}/${devicetree}.dtb" ]; then + install -m 0644 ${B}/${devicetree}.dtb "${DEPLOYDIR}/${FIP_UBOOT_DTB}-${devicetree}-with-signature.dtb" + fi + done + fi + fi +} + COMPATIBLE_MACHINE = "(ccimx6|ccimx6ul|ccimx8m|ccimx8x|ccmp1)"