diff options
Diffstat (limited to 'arch/arm/mach-imx/spl.c')
-rw-r--r-- | arch/arm/mach-imx/spl.c | 72 |
1 files changed, 69 insertions, 3 deletions
diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c index ea709d15a5..fe33a7b611 100644 --- a/arch/arm/mach-imx/spl.c +++ b/arch/arm/mach-imx/spl.c @@ -21,6 +21,8 @@ #include <g_dnl.h> #include <linux/libfdt.h> #include <mmc.h> +#include <image.h> +#include <asm/sections.h> DECLARE_GLOBAL_DATA_PTR; @@ -148,7 +150,7 @@ u32 spl_boot_device(void) return BOOT_DEVICE_NONE; } -#elif defined(CONFIG_MX7) || defined(CONFIG_IMX8M) || defined(CONFIG_IMX8) +#elif defined(CONFIG_MX7) || defined(CONFIG_IMX8M) || defined(CONFIG_IMX8) || defined(CONFIG_IMX9) /* Translate iMX7/i.MX8M boot device to the SPL boot device enumeration */ u32 spl_boot_device(void) { @@ -184,7 +186,7 @@ u32 spl_boot_device(void) #ifdef CONFIG_SPL_USB_GADGET int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name) { - put_unaligned(0x0151, &dev->idProduct); + put_unaligned(CONFIG_USB_GADGET_PRODUCT_NUM + 0xfff, &dev->idProduct); return 0; } @@ -314,7 +316,10 @@ ulong board_spl_fit_size_align(ulong size) */ size = ALIGN(size, 0x1000); - size += CONFIG_CSF_SIZE; + size += 2 * CONFIG_CSF_SIZE; + + if (size > CONFIG_SYS_BOOTM_LEN) + panic("spl: ERROR: image too big\n"); return size; } @@ -347,6 +352,42 @@ int dram_init_banksize(void) } #endif +#if IS_ENABLED(CONFIG_SPL_LOAD_FIT) && IS_ENABLED(CONFIG_IMX_HAB) && \ + !IS_ENABLED(CONFIG_SPL_FIT_SIGNATURE) +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 +402,30 @@ void *spl_load_simple_fit_fix_load(const void *fit) unsigned long size; u8 *tmp = (u8 *)fit; + if (IS_ENABLED(CONFIG_IMX_HAB)) { + if (IS_ENABLED(CONFIG_IMX_SPL_FIT_FDT_SIGNATURE)) { + u32 offset = ALIGN(fdt_totalsize(fit), 0x1000); + + if (imx_hab_authenticate_image((uintptr_t)fit, + offset + 2 * CSF_PAD_SIZE, + offset + CSF_PAD_SIZE)) { +#ifdef CONFIG_ANDROID_SUPPORT + printf("spl: ERROR: FIT FDT authentication unsuccessful\n"); + return NULL; +#else + panic("spl: ERROR: FIT FDT authentication unsuccessful\n"); +#endif + } + } else { + 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 +444,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) |