All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v4] imx: Support i.MX6 High Assurance Boot authentication
@ 2014-09-16 18:33 Nitin Garg
  2014-09-22 14:07 ` Stefano Babic
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Nitin Garg @ 2014-09-16 18:33 UTC (permalink / raw)
  To: u-boot

When CONFIG_SECURE_BOOT is enabled, the signed images
like kernel and dtb can be authenticated using iMX6 CAAM.
The added command hab_auth_img can be used for HAB
authentication of images. The command takes the image
DDR location, IVT (Image Vector Table) offset inside
image as parameters. Detailed info about signing images
can be found in Freescale AppNote AN4581.

Signed-off-by: Nitin Garg <nitin.garg@freescale.com>

---

Changes in v4:
- Use single hab_caam_clock_enable api for en/disable
- Remove unused DEBUG_AUTHENTICATE_IMAGE
- Use DEBUG instead of DEBUG_AUTHENTICATE_IMAGE
- Add defined for pu_irom_mmu_enabled var location
- Add MMU check before setting ROM variable
- Replace printf with puts where applicable

Changes in v3:
- Remove typecast of get_cpu_rev since its not required

Changes in v2:
- Cleaned up clock code as per review comments
- Removed dead code as per review comments
- Re-written commit log as per review comments

 arch/arm/cpu/armv7/mx6/clock.c        |   27 ++++++
 arch/arm/cpu/armv7/mx6/hab.c          |  169 ++++++++++++++++++++++++++++++++-
 arch/arm/cpu/armv7/mx6/soc.c          |   15 +++
 arch/arm/include/asm/arch-mx6/clock.h |    1 +
 4 files changed, 211 insertions(+), 1 deletion(-)

diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c
index 8a33330..48f0bdd 100644
--- a/arch/arm/cpu/armv7/mx6/clock.c
+++ b/arch/arm/cpu/armv7/mx6/clock.c
@@ -568,6 +568,33 @@ void enable_pll3(void)
 	}
 }
 
+#ifdef CONFIG_SECURE_BOOT
+void hab_caam_clock_enable(unsigned char enable)
+{
+	u32 reg;
+
+	/* CG4 ~ CG6, CAAM clocks */
+	reg = __raw_readl(&imx_ccm->CCGR0);
+	if (enable)
+		reg |= (MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK |
+			MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
+			MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK);
+	else
+		reg &= ~(MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK |
+			MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
+			MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK);
+	__raw_writel(reg, &imx_ccm->CCGR0);
+
+	/* EMI slow clk */
+	reg = __raw_readl(&imx_ccm->CCGR6);
+	if (enable)
+		reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK;
+	else
+		reg &= ~MXC_CCM_CCGR6_EMI_SLOW_MASK;
+	__raw_writel(reg, &imx_ccm->CCGR6);
+}
+#endif
+
 unsigned int mxc_get_clock(enum mxc_clock clk)
 {
 	switch (clk) {
diff --git a/arch/arm/cpu/armv7/mx6/hab.c b/arch/arm/cpu/armv7/mx6/hab.c
index f6810a6..8dee595 100644
--- a/arch/arm/cpu/armv7/mx6/hab.c
+++ b/arch/arm/cpu/armv7/mx6/hab.c
@@ -1,12 +1,14 @@
 /*
- * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010-2014 Freescale Semiconductor, Inc.
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
 #include <asm/io.h>
+#include <asm/system.h>
 #include <asm/arch/hab.h>
+#include <asm/arch/clock.h>
 #include <asm/arch/sys_proto.h>
 
 /* -------- start of HAB API updates ------------*/
@@ -71,6 +73,44 @@
 	((hab_rvt_exit_t *)HAB_RVT_EXIT)			\
 )
 
+#define IVT_SIZE		0x20
+#define ALIGN_SIZE		0x1000
+#define CSF_PAD_SIZE		0x2000
+#define MX6DQ_PU_IROM_MMU_EN_VAR	0x009024a8
+#define MX6DLS_PU_IROM_MMU_EN_VAR	0x00901dd0
+#define MX6SL_PU_IROM_MMU_EN_VAR	0x00900a18
+
+/*
+ * +------------+  0x0 (DDR_UIMAGE_START) -
+ * |   Header   |                          |
+ * +------------+  0x40                    |
+ * |            |                          |
+ * |            |                          |
+ * |            |                          |
+ * |            |                          |
+ * | Image Data |                          |
+ * .            |                          |
+ * .            |                           > Stuff to be authenticated ----+
+ * .            |                          |                                |
+ * |            |                          |                                |
+ * |            |                          |                                |
+ * +------------+                          |                                |
+ * |            |                          |                                |
+ * | Fill Data  |                          |                                |
+ * |            |                          |                                |
+ * +------------+ Align to ALIGN_SIZE      |                                |
+ * |    IVT     |                          |                                |
+ * +------------+ + IVT_SIZE              -                                 |
+ * |            |                                                           |
+ * |  CSF DATA  | <---------------------------------------------------------+
+ * |            |
+ * +------------+
+ * |            |
+ * | Fill Data  |
+ * |            |
+ * +------------+ + CSF_PAD_SIZE
+ */
+
 bool is_hab_enabled(void)
 {
 	struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
@@ -144,6 +184,108 @@ int get_hab_status(void)
 	return 0;
 }
 
+uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size)
+{
+	uint32_t load_addr = 0;
+	size_t bytes;
+	ptrdiff_t ivt_offset = 0;
+	int result = 0;
+	ulong start;
+	hab_rvt_authenticate_image_t *hab_rvt_authenticate_image;
+	hab_rvt_entry_t *hab_rvt_entry;
+	hab_rvt_exit_t *hab_rvt_exit;
+
+	hab_rvt_authenticate_image = hab_rvt_authenticate_image_p;
+	hab_rvt_entry = hab_rvt_entry_p;
+	hab_rvt_exit = hab_rvt_exit_p;
+
+	if (is_hab_enabled()) {
+		printf("\nAuthenticate image from DDR location 0x%x...\n",
+		       ddr_start);
+
+		hab_caam_clock_enable(1);
+
+		if (hab_rvt_entry() == HAB_SUCCESS) {
+			/* If not already aligned, Align to ALIGN_SIZE */
+			ivt_offset = (image_size + ALIGN_SIZE - 1) &
+					~(ALIGN_SIZE - 1);
+
+			start = ddr_start;
+			bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE;
+#ifdef DEBUG
+			printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n",
+			       ivt_offset, ddr_start + ivt_offset);
+			puts("Dumping IVT\n");
+			print_buffer(ddr_start + ivt_offset,
+				     (void *)(ddr_start + ivt_offset),
+				     4, 0x8, 0);
+
+			puts("Dumping CSF Header\n");
+			print_buffer(ddr_start + ivt_offset+IVT_SIZE,
+				     (void *)(ddr_start + ivt_offset+IVT_SIZE),
+				     4, 0x10, 0);
+
+			get_hab_status();
+
+			puts("\nCalling authenticate_image in ROM\n");
+			printf("\tivt_offset = 0x%x\n", ivt_offset);
+			printf("\tstart = 0x%08lx\n", start);
+			printf("\tbytes = 0x%x\n", bytes);
+#endif
+			/*
+			 * If the MMU is enabled, we have to notify the ROM
+			 * code, or it won't flush the caches when needed.
+			 * This is done, by setting the "pu_irom_mmu_enabled"
+			 * word to 1. You can find its address by looking in
+			 * the ROM map. This is critical for
+			 * authenticate_image(). If MMU is enabled, without
+			 * setting this bit, authentication will fail and may
+			 * crash.
+			 */
+			/* Check MMU enabled */
+			if (get_cr() & CR_M) {
+				if (is_cpu_type(MXC_CPU_MX6Q) ||
+				    is_cpu_type(MXC_CPU_MX6D)) {
+					/*
+					 * This won't work on Rev 1.0.0 of
+					 * i.MX6Q/D, since their ROM doesn't
+					 * do cache flushes. don't think any
+					 * exist, so we ignore them.
+					 */
+					writel(1, MX6DQ_PU_IROM_MMU_EN_VAR);
+				} else if (is_cpu_type(MXC_CPU_MX6DL) ||
+					   is_cpu_type(MXC_CPU_MX6SOLO)) {
+					writel(1, MX6DLS_PU_IROM_MMU_EN_VAR);
+				} else if (is_cpu_type(MXC_CPU_MX6SL)) {
+					writel(1, MX6SL_PU_IROM_MMU_EN_VAR);
+				}
+			}
+
+			load_addr = (uint32_t)hab_rvt_authenticate_image(
+					HAB_CID_UBOOT,
+					ivt_offset, (void **)&start,
+					(size_t *)&bytes, NULL);
+			if (hab_rvt_exit() != HAB_SUCCESS) {
+				puts("hab exit function fail\n");
+				load_addr = 0;
+			}
+		} else {
+			puts("hab entry function fail\n");
+		}
+
+		hab_caam_clock_enable(0);
+
+		get_hab_status();
+	} else {
+		puts("hab fuse not enabled\n");
+	}
+
+	if ((!is_hab_enabled()) || (load_addr != 0))
+		result = 1;
+
+	return result;
+}
+
 int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	if ((argc != 1)) {
@@ -156,8 +298,33 @@ int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	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"
+	  );
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
index ac84a1f..0d5fbf1 100644
--- a/arch/arm/cpu/armv7/mx6/soc.c
+++ b/arch/arm/cpu/armv7/mx6/soc.c
@@ -273,10 +273,25 @@ int board_postclk_init(void)
 #ifndef CONFIG_SYS_DCACHE_OFF
 void enable_caches(void)
 {
+#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
+	enum dcache_option option = DCACHE_WRITETHROUGH;
+#else
+	enum dcache_option option = DCACHE_WRITEBACK;
+#endif
+
 	/* Avoid random hang when download by usb */
 	invalidate_dcache_all();
+
 	/* Enable D-cache. I-cache is already enabled in start.S */
 	dcache_enable();
+
+	/* Enable caching on OCRAM and ROM */
+	mmu_set_region_dcache_behaviour(ROMCP_ARB_BASE_ADDR,
+					ROMCP_ARB_END_ADDR,
+					option);
+	mmu_set_region_dcache_behaviour(IRAM_BASE_ADDR,
+					IRAM_SIZE,
+					option);
 }
 #endif
 
diff --git a/arch/arm/include/asm/arch-mx6/clock.h b/arch/arm/include/asm/arch-mx6/clock.h
index fd4b860..2953b36 100644
--- a/arch/arm/include/asm/arch-mx6/clock.h
+++ b/arch/arm/include/asm/arch-mx6/clock.h
@@ -61,4 +61,5 @@ int enable_spi_clk(unsigned char enable, unsigned spi_num);
 void enable_ipu_clock(void);
 int enable_fec_anatop_clock(enum enet_freq freq);
 void enable_pll3(void);
+void hab_caam_clock_enable(unsigned char enable);
 #endif /* __ASM_ARCH_CLOCK_H */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH v4] imx: Support i.MX6 High Assurance Boot authentication
  2014-09-16 18:33 [U-Boot] [PATCH v4] imx: Support i.MX6 High Assurance Boot authentication Nitin Garg
@ 2014-09-22 14:07 ` Stefano Babic
  2014-09-22 14:12   ` Nitin Garg
  2014-09-22 14:21 ` Stefano Babic
  2014-09-30 13:44 ` Fabio Estevam
  2 siblings, 1 reply; 6+ messages in thread
From: Stefano Babic @ 2014-09-22 14:07 UTC (permalink / raw)
  To: u-boot

Hi Nitin,

On 16/09/2014 20:33, Nitin Garg wrote:
> When CONFIG_SECURE_BOOT is enabled, the signed images
> like kernel and dtb can be authenticated using iMX6 CAAM.
> The added command hab_auth_img can be used for HAB
> authentication of images. The command takes the image
> DDR location, IVT (Image Vector Table) offset inside
> image as parameters. Detailed info about signing images
> can be found in Freescale AppNote AN4581.
> 
> Signed-off-by: Nitin Garg <nitin.garg@freescale.com>
> 
> ---
> 

I wanted to apply it on current tree, but it seems it depends on
"mx6: clock: Add api to enable pll3". Or better, it seems in your tree
on top the the patch for pll3. It is not an issue and I solve it myself,
but can you confim that or do you prefer that I apply this one only
after the thermal series will be merged ?

Best regards,
Stefano Babic


-- 
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH v4] imx: Support i.MX6 High Assurance Boot authentication
  2014-09-22 14:07 ` Stefano Babic
@ 2014-09-22 14:12   ` Nitin Garg
  0 siblings, 0 replies; 6+ messages in thread
From: Nitin Garg @ 2014-09-22 14:12 UTC (permalink / raw)
  To: u-boot

Hi Stefano,

On 09/22/2014 09:07 AM, Stefano Babic wrote:
> Hi Nitin,
> 
> On 16/09/2014 20:33, Nitin Garg wrote:
>> When CONFIG_SECURE_BOOT is enabled, the signed images
>> like kernel and dtb can be authenticated using iMX6 CAAM.
>> The added command hab_auth_img can be used for HAB
>> authentication of images. The command takes the image
>> DDR location, IVT (Image Vector Table) offset inside
>> image as parameters. Detailed info about signing images
>> can be found in Freescale AppNote AN4581.
>>
>> Signed-off-by: Nitin Garg <nitin.garg@freescale.com>
>>
>> ---
>>
> 
> I wanted to apply it on current tree, but it seems it depends on
> "mx6: clock: Add api to enable pll3". Or better, it seems in your tree
> on top the the patch for pll3. It is not an issue and I solve it myself,
> but can you confim that or do you prefer that I apply this one only
> after the thermal series will be merged ?
> 
> Best regards,
> Stefano Babic
> 
> 

Yes you are correct, in my tree I did HAB patch on top of
temperature sensor patch. Pls resolve it or I can help if needed.
I do not have any preference with ordering of HAB and temperature patch.

Thanks,
Nitin Garg

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH v4] imx: Support i.MX6 High Assurance Boot authentication
  2014-09-16 18:33 [U-Boot] [PATCH v4] imx: Support i.MX6 High Assurance Boot authentication Nitin Garg
  2014-09-22 14:07 ` Stefano Babic
@ 2014-09-22 14:21 ` Stefano Babic
  2014-09-30 13:44 ` Fabio Estevam
  2 siblings, 0 replies; 6+ messages in thread
From: Stefano Babic @ 2014-09-22 14:21 UTC (permalink / raw)
  To: u-boot

Hi Nitin,

On 16/09/2014 20:33, Nitin Garg wrote:
> When CONFIG_SECURE_BOOT is enabled, the signed images
> like kernel and dtb can be authenticated using iMX6 CAAM.
> The added command hab_auth_img can be used for HAB
> authentication of images. The command takes the image
> DDR location, IVT (Image Vector Table) offset inside
> image as parameters. Detailed info about signing images
> can be found in Freescale AppNote AN4581.
> 
> Signed-off-by: Nitin Garg <nitin.garg@freescale.com>
> 
> ---
> 

Applied to u-boot-imx, thanks !

Best regards,
Stefano Babic

-- 
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH v4] imx: Support i.MX6 High Assurance Boot authentication
  2014-09-16 18:33 [U-Boot] [PATCH v4] imx: Support i.MX6 High Assurance Boot authentication Nitin Garg
  2014-09-22 14:07 ` Stefano Babic
  2014-09-22 14:21 ` Stefano Babic
@ 2014-09-30 13:44 ` Fabio Estevam
  2014-09-30 14:46   ` Nitin Garg
  2 siblings, 1 reply; 6+ messages in thread
From: Fabio Estevam @ 2014-09-30 13:44 UTC (permalink / raw)
  To: u-boot

Hi Nitin,

On Tue, Sep 16, 2014 at 3:33 PM, Nitin Garg <nitin.garg@freescale.com> wrote:
> When CONFIG_SECURE_BOOT is enabled, the signed images
> like kernel and dtb can be authenticated using iMX6 CAAM.
> The added command hab_auth_img can be used for HAB
> authentication of images. The command takes the image
> DDR location, IVT (Image Vector Table) offset inside
> image as parameters. Detailed info about signing images
> can be found in Freescale AppNote AN4581.
>
> Signed-off-by: Nitin Garg <nitin.garg@freescale.com>

I have just tested the 'hab_status' command and it hangs my mx6sxsabresd board:

U-Boot 2014.10-rc2-16959-g6eb2f0d-dirty (Sep 30 2014 - 10:28:19)

CPU:   Freescale i.MX6SX rev1.0 at 792 MHz
Reset cause: POR
Board: MX6SX SABRE SDB
I2C:   ready
DRAM:  1 GiB
MMC:   FSL_SDHC: 0
In:    serial
Out:   serial
Err:   serial
PMIC:  PFUZE100 ID=0x10
Net:   FEC [PRIME]
Hit any key to stop autoboot:  0
=> hab_status

Secure boot disabled

(hangs the system)

Could you please take a look at this issue?

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH v4] imx: Support i.MX6 High Assurance Boot authentication
  2014-09-30 13:44 ` Fabio Estevam
@ 2014-09-30 14:46   ` Nitin Garg
  0 siblings, 0 replies; 6+ messages in thread
From: Nitin Garg @ 2014-09-30 14:46 UTC (permalink / raw)
  To: u-boot

Hi Fabio,

On 09/30/2014 08:44 AM, Fabio Estevam wrote:
> Hi Nitin,
> 
> On Tue, Sep 16, 2014 at 3:33 PM, Nitin Garg <nitin.garg@freescale.com> wrote:
>> When CONFIG_SECURE_BOOT is enabled, the signed images
>> like kernel and dtb can be authenticated using iMX6 CAAM.
>> The added command hab_auth_img can be used for HAB
>> authentication of images. The command takes the image
>> DDR location, IVT (Image Vector Table) offset inside
>> image as parameters. Detailed info about signing images
>> can be found in Freescale AppNote AN4581.
>>
>> Signed-off-by: Nitin Garg <nitin.garg@freescale.com>
> 
> I have just tested the 'hab_status' command and it hangs my mx6sxsabresd board:
> 
> U-Boot 2014.10-rc2-16959-g6eb2f0d-dirty (Sep 30 2014 - 10:28:19)
> 
> CPU:   Freescale i.MX6SX rev1.0 at 792 MHz
> Reset cause: POR
> Board: MX6SX SABRE SDB
> I2C:   ready
> DRAM:  1 GiB
> MMC:   FSL_SDHC: 0
> In:    serial
> Out:   serial
> Err:   serial
> PMIC:  PFUZE100 ID=0x10
> Net:   FEC [PRIME]
> Hit any key to stop autoboot:  0
> => hab_status
> 
> Secure boot disabled
> 
> (hangs the system)
> 
> Could you please take a look at this issue?
> 

I found the reason for the hang. The HAB api table was not
updated for i.MX6SX. Since i.MX6SX ROM implements unified
sections in ROM, the HAP function pointers needs to be
updated. I have sent a patch for the same.

-Nitin

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2014-09-30 14:46 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-16 18:33 [U-Boot] [PATCH v4] imx: Support i.MX6 High Assurance Boot authentication Nitin Garg
2014-09-22 14:07 ` Stefano Babic
2014-09-22 14:12   ` Nitin Garg
2014-09-22 14:21 ` Stefano Babic
2014-09-30 13:44 ` Fabio Estevam
2014-09-30 14:46   ` Nitin Garg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.