From 2227ef5837b91acf4197078b7bf1642ca69f8d47 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 2 Jul 2023 18:28:27 +0800 Subject: LFU-573-1 imx8m: hab: Verify hash of FIT FDT strucure By default, we insert the hash of FIT FDT into SPL image (append it after DDR FW) by imx-mkimage. When secure boot, this hash is authenticated with SPL image by ROM. So the hash is trusted. Before SPL starts parsing FIT image, SPL should verify the FIT FDT structure with the hash to ensure the FIT FDT structure is trusted. This patch could resolve the problem that SPL FIT authentication is later than loading the FIT image. Signed-off-by: Ye Li Reviewed-by: Peng Fan Upstream-Status: Inappropriate [downstream specific] Upstream U-Boot fixed this differently in combination with binman to create the final bootcontainer. Commit 6039e0edc854 ("imx: hab: Simplify the mechanism") Backport from NXP downstream [0746cfd931de8f7591d263ff60dd806ffe23c093] Conflicts: arch/arm/mach-imx/spl.c (additional includes in theirs, boot/lz4.h, image.h, image.h now needed) Signed-off-by: Max Krummenacher --- arch/arm/mach-imx/spl.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c index 16574ab303..26b3d00387 100644 --- a/arch/arm/mach-imx/spl.c +++ b/arch/arm/mach-imx/spl.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -316,6 +318,9 @@ ulong board_spl_fit_size_align(ulong size) size = ALIGN(size, 0x1000); size += CONFIG_CSF_SIZE; + if (size > CONFIG_SYS_BOOTM_LEN) + panic("spl: ERROR: image too big\n"); + return size; } @@ -347,6 +352,41 @@ int dram_init_banksize(void) } #endif +#if IS_ENABLED(CONFIG_SPL_LOAD_FIT) +static int spl_verify_fit_hash(const void *fit) +{ + unsigned long size; + u8 value[SHA256_SUM_LEN]; + int value_len; + ulong fit_hash; + +#if CONFIG_IS_ENABLED(OF_CONTROL) + if (gd->fdt_blob && !fdt_check_header(gd->fdt_blob)) { + fit_hash = roundup((unsigned long)&_end + + fdt_totalsize(gd->fdt_blob), 4) + 0x18000; + } +#else + fit_hash = (unsigned long)&_end + 0x18000; +#endif + + size = fdt_totalsize(fit); + + if (calculate_hash(fit, size, "sha256", value, &value_len)) { + printf("Unsupported hash algorithm\n"); + return -1; + } + + if (value_len != SHA256_SUM_LEN) { + printf("Bad hash value len\n"); + return -1; + } else if (memcmp(value, (const void *)fit_hash, value_len) != 0) { + printf("Bad hash value\n"); + return -1; + } + + return 0; +} + /* * read the address where the IVT header must sit * from IVT image header, loaded from SPL into @@ -361,6 +401,15 @@ void *spl_load_simple_fit_fix_load(const void *fit) unsigned long size; u8 *tmp = (u8 *)fit; + if (IS_ENABLED(CONFIG_IMX_HAB)) { + int ret = spl_verify_fit_hash(fit); + + if (ret && imx_hab_is_enabled()) + panic("spl: ERROR: FIT hash verify unsuccessful\n"); + + debug("spl_verify_fit_hash %d\n", ret); + } + offset = ALIGN(fdt_totalsize(fit), 0x1000); size = ALIGN(fdt_totalsize(fit), 4); size = board_spl_fit_size_align(size); @@ -379,6 +428,7 @@ void *spl_load_simple_fit_fix_load(const void *fit) return (void *)new; } +#endif #if defined(CONFIG_IMX8MP) || defined(CONFIG_IMX8MN) int board_handle_rdc_config(void *fdt_addr, const char *config_name, void *dst_addr) -- cgit v1.2.3