imx8: Add AHAB secure boot support
Add function and new command "auth_cntr" for secure boot support.
When booting with life cycle set to OEM closed, we need to use
this function to authenticate the OS container and load kernel & FDT
from OS container to their destination.
Also add image authentication call when loading container images.
Users can set CONFIG_AHAB_BOOT=y to enable the feature. It is not
set at default.
Signed-off-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
diff --git a/arch/arm/mach-imx/imx8/parse-container.c b/arch/arm/mach-imx/imx8/parse-container.c
index 32f78bd..b57e68e 100644
--- a/arch/arm/mach-imx/imx8/parse-container.c
+++ b/arch/arm/mach-imx/imx8/parse-container.c
@@ -7,6 +7,67 @@
#include <errno.h>
#include <spl.h>
#include <asm/arch/image.h>
+#include <asm/arch/sci/sci.h>
+
+#define SEC_SECURE_RAM_BASE 0x31800000UL
+#define SEC_SECURE_RAM_END_BASE (SEC_SECURE_RAM_BASE + 0xFFFFUL)
+#define SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE 0x60000000UL
+
+#define SECO_PT 2U
+
+#ifdef CONFIG_AHAB_BOOT
+static int authenticate_image(struct boot_img_t *img, int image_index)
+{
+ sc_faddr_t start, end;
+ sc_rm_mr_t mr;
+ int err;
+ int ret = 0;
+
+ debug("img %d, dst 0x%llx, src 0x%x, size 0x%x\n",
+ image_index, img->dst, img->offset, img->size);
+
+ /* Find the memreg and set permission for seco pt */
+ err = sc_rm_find_memreg(-1, &mr,
+ img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1),
+ ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE));
+
+ if (err) {
+ printf("can't find memreg for image: %d, err %d\n",
+ image_index, err);
+ return -ENOMEM;
+ }
+
+ err = sc_rm_get_memreg_info(-1, mr, &start, &end);
+ if (!err)
+ debug("memreg %u 0x%llx -- 0x%llx\n", mr, start, end);
+
+ err = sc_rm_set_memreg_permissions(-1, mr,
+ SECO_PT, SC_RM_PERM_FULL);
+ if (err) {
+ printf("set permission failed for img %d, error %d\n",
+ image_index, err);
+ return -EPERM;
+ }
+
+ err = sc_seco_authenticate(-1, SC_MISC_VERIFY_IMAGE,
+ 1 << image_index);
+ if (err) {
+ printf("authenticate img %d failed, return %d\n",
+ image_index, err);
+ ret = -EIO;
+ }
+
+ err = sc_rm_set_memreg_permissions(-1, mr,
+ SECO_PT, SC_RM_PERM_NONE);
+ if (err) {
+ printf("remove permission failed for img %d, error %d\n",
+ image_index, err);
+ ret = -EPERM;
+ }
+
+ return ret;
+}
+#endif
static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image,
struct spl_load_info *info,
@@ -44,6 +105,13 @@
printf("%s wrong\n", __func__);
return NULL;
}
+
+#ifdef CONFIG_AHAB_BOOT
+ if (authenticate_image(&images[image_index], image_index)) {
+ printf("Failed to authenticate image %d\n", image_index);
+ return NULL;
+ }
+#endif
return &images[image_index];
}
@@ -54,7 +122,7 @@
struct container_hdr *container = NULL;
u16 length;
u32 sectors;
- int i, size;
+ int i, size, ret = 0;
size = roundup(CONTAINER_HDR_ALIGNMENT, info->bl_len);
sectors = size / info->bl_len;
@@ -95,14 +163,28 @@
sectors)
return -EIO;
}
+
+#ifdef CONFIG_AHAB_BOOT
+ memcpy((void *)SEC_SECURE_RAM_BASE, (const void *)container,
+ ALIGN(length, CONFIG_SYS_CACHELINE_SIZE));
+
+ ret = sc_seco_authenticate(-1, SC_MISC_AUTH_CONTAINER,
+ SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE);
+ if (ret) {
+ printf("authenticate container hdr failed, return %d\n", ret);
+ return ret;
+ }
+#endif
for (i = 0; i < container->num_images; i++) {
struct boot_img_t *image = read_auth_image(spl_image, info,
container, i,
sector);
- if (!image)
- return -EINVAL;
+ if (!image) {
+ ret = -EINVAL;
+ goto end_auth;
+ }
if (i == 0) {
spl_image->load_addr = image->dst;
@@ -110,7 +192,12 @@
}
}
- return 0;
+end_auth:
+#ifdef CONFIG_AHAB_BOOT
+ if (sc_seco_authenticate(-1, SC_MISC_REL_CONTAINER, 0))
+ printf("Error: release container failed!\n");
+#endif
+ return ret;
}
int spl_load_imx_container(struct spl_image_info *spl_image,