arm: imx: add HAB authentication of image to SPL boot
authorSven Ebenfeld <sven.ebenfeld@gmail.com>
Sun, 6 Nov 2016 15:37:55 +0000 (16:37 +0100)
committerStefano Babic <sbabic@denx.de>
Mon, 2 Jan 2017 16:04:38 +0000 (17:04 +0100)
When using HAB as secure boot mechanism on Wandboard, the chain of
trust breaks immediately after the SPL. As this is not checking
the authenticity of the loaded image before jumping to it.

The HAB status output will not be implemented in SPL as it adds
a lot of strings that are only required in debug cases. With those
it exceeds the maximum size of the available OCRAM (69 KiB).

The SPL MISC driver support must be enabled, so that the driver can use OTP fuse
to check if HAB is enabled.

Cc: sbabic@denx.de
v2-Changes: None

Signed-off-by: Sven Ebenfeld <sven.ebenfeld@gmail.com>
Reviewed-by: George McCollister <george.mccollister@gmail.com>
Tested-by: George McCollister <george.mccollister@gmail.com>
arch/arm/imx-common/hab.c
arch/arm/imx-common/spl.c
arch/arm/imx-common/spl_sd.cfg
arch/arm/include/asm/imx-common/hab.h
include/configs/mx6_common.h

index 67318250607dd23604d2d799c4a4dff23764289b..7449487f0d5777236de822cc33c8419ee8a0635c 100644 (file)
  * +------------+ + CSF_PAD_SIZE
  */
 
+static bool is_hab_enabled(void);
+
+#if !defined(CONFIG_SPL_BUILD)
+
 #define MAX_RECORD_BYTES     (8*1024) /* 4 kbytes */
 
 struct record {
@@ -257,22 +261,6 @@ uint8_t hab_engines[16] = {
        -1
 };
 
-bool is_hab_enabled(void)
-{
-       struct imx_sec_config_fuse_t *fuse =
-               (struct imx_sec_config_fuse_t *)&imx_sec_config_fuse;
-       uint32_t reg;
-       int ret;
-
-       ret = fuse_read(fuse->bank, fuse->word, &reg);
-       if (ret) {
-               puts("\nSecure boot fuse read error\n");
-               return ret;
-       }
-
-       return (reg & IS_HAB_ENABLED_BIT) == IS_HAB_ENABLED_BIT;
-}
-
 static inline uint8_t get_idx(uint8_t *list, uint8_t tgt)
 {
        uint8_t idx = 0;
@@ -359,6 +347,68 @@ int get_hab_status(void)
        return 0;
 }
 
+int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       if ((argc != 1)) {
+               cmd_usage(cmdtp);
+               return 1;
+       }
+
+       get_hab_status();
+
+       return 0;
+}
+
+static int do_authenticate_image(cmd_tbl_t *cmdtp, int flag, int argc,
+                               char * const argv[])
+{
+       ulong   addr, ivt_offset;
+       int     rcode = 0;
+
+       if (argc < 3)
+               return CMD_RET_USAGE;
+
+       addr = simple_strtoul(argv[1], NULL, 16);
+       ivt_offset = simple_strtoul(argv[2], NULL, 16);
+
+       rcode = authenticate_image(addr, ivt_offset);
+
+       return rcode;
+}
+
+U_BOOT_CMD(
+               hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status,
+               "display HAB status",
+               ""
+         );
+
+U_BOOT_CMD(
+               hab_auth_img, 3, 0, do_authenticate_image,
+               "authenticate image via HAB",
+               "addr ivt_offset\n"
+               "addr - image hex address\n"
+               "ivt_offset - hex offset of IVT in the image"
+         );
+
+
+#endif /* !defined(CONFIG_SPL_BUILD) */
+
+static bool is_hab_enabled(void)
+{
+       struct imx_sec_config_fuse_t *fuse =
+               (struct imx_sec_config_fuse_t *)&imx_sec_config_fuse;
+       uint32_t reg;
+       int ret;
+
+       ret = fuse_read(fuse->bank, fuse->word, &reg);
+       if (ret) {
+               puts("\nSecure boot fuse read error\n");
+               return ret;
+       }
+
+       return (reg & IS_HAB_ENABLED_BIT) == IS_HAB_ENABLED_BIT;
+}
+
 uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size)
 {
        uint32_t load_addr = 0;
@@ -400,7 +450,9 @@ uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size)
                                     (void *)(ddr_start + ivt_offset+IVT_SIZE),
                                     4, 0x10, 0);
 
+#if  !defined(CONFIG_SPL_BUILD)
                        get_hab_status();
+#endif
 
                        puts("\nCalling authenticate_image in ROM\n");
                        printf("\tivt_offset = 0x%x\n", ivt_offset);
@@ -449,7 +501,9 @@ uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size)
 
                hab_caam_clock_enable(0);
 
+#if !defined(CONFIG_SPL_BUILD)
                get_hab_status();
+#endif
        } else {
                puts("hab fuse not enabled\n");
        }
@@ -459,46 +513,3 @@ uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size)
 
        return result;
 }
-
-int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-       if ((argc != 1)) {
-               cmd_usage(cmdtp);
-               return 1;
-       }
-
-       get_hab_status();
-
-       return 0;
-}
-
-static int do_authenticate_image(cmd_tbl_t *cmdtp, int flag, int argc,
-                               char * const argv[])
-{
-       ulong   addr, ivt_offset;
-       int     rcode = 0;
-
-       if (argc < 3)
-               return CMD_RET_USAGE;
-
-       addr = simple_strtoul(argv[1], NULL, 16);
-       ivt_offset = simple_strtoul(argv[2], NULL, 16);
-
-       rcode = authenticate_image(addr, ivt_offset);
-
-       return rcode;
-}
-
-U_BOOT_CMD(
-               hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status,
-               "display HAB status",
-               ""
-         );
-
-U_BOOT_CMD(
-               hab_auth_img, 3, 0, do_authenticate_image,
-               "authenticate image via HAB",
-               "addr ivt_offset\n"
-               "addr - image hex address\n"
-               "ivt_offset - hex offset of IVT in the image"
-         );
index bdcda7de937f0673392f5007f4377b597747fc0a..c86b6f83b85c81a59bba1fcd68e58237e8269293 100644 (file)
@@ -12,6 +12,7 @@
 #include <asm/arch/imx-regs.h>
 #include <asm/spl.h>
 #include <spl.h>
+#include <asm/imx-common/hab.h>
 
 #if defined(CONFIG_MX6)
 /* determine boot device from SRC_SBMR1 (BOOT_CFG[4:1]) or SRC_GPR9 register */
@@ -90,3 +91,27 @@ u32 spl_boot_mode(const u32 boot_device)
        }
 }
 #endif
+
+#if defined(CONFIG_SECURE_BOOT)
+
+__weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+{
+       typedef void __noreturn (*image_entry_noargs_t)(void);
+
+       image_entry_noargs_t image_entry =
+               (image_entry_noargs_t)(unsigned long)spl_image->entry_point;
+
+       debug("image entry point: 0x%X\n", spl_image->entry_point);
+
+       /* HAB looks for the CSF at the end of the authenticated data therefore,
+        * we need to subtract the size of the CSF from the actual filesize */
+       if (authenticate_image(spl_image->load_addr,
+                              spl_image->size - CONFIG_CSF_SIZE)) {
+               image_entry();
+       } else {
+               puts("spl: ERROR:  image authentication unsuccessful\n");
+               hang();
+       }
+}
+
+#endif
index 5fc3e8af3821b84ca6651f638db3e01718649ae5..14c135c549e487aebbca78087b03d508b509d926 100644 (file)
@@ -4,5 +4,15 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
+#define __ASSEMBLY__
+#include <config.h>
+
 IMAGE_VERSION  2
 BOOT_FROM      sd
+
+/*
+ * Secure boot support
+ */
+#ifdef CONFIG_SECURE_BOOT
+CSF CONFIG_CSF_SIZE
+#endif
\ No newline at end of file
index dab6789b1012bc832f87a314279a1f3dd98ddbc3..e0ff459d53fa2268aaf5fbc1ef9145ade600d99f 100644 (file)
@@ -145,4 +145,6 @@ typedef void hapi_clock_init_t(void);
 
 /* ----------- end of HAB API updates ------------*/
 
+uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size);
+
 #endif
index 3bb939ecf0f89b72f79ab5715bb5c1ddb72d6093..6e9b871103b6dff7d57607e6ff2b033c149d60af 100644 (file)
@@ -98,6 +98,9 @@
 #define CONFIG_FSL_CAAM
 #define CONFIG_CMD_DEKBLOB
 #define CONFIG_SYS_FSL_SEC_LE
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_SPL_DRIVERS_MISC_SUPPORT
+#endif
 #endif
 
 #endif