[PATCH 14/37] mx7ulp: hab: Add hab_status command for HABv4 M4 boot

Peng Fan (OSS) peng.fan at oss.nxp.com
Thu Mar 25 10:30:13 CET 2021


From: Breno Lima <breno.lima at nxp.com>

When booting in low power or dual boot modes the M4 binary is
authenticated by the M4 ROM code.

Add an option in hab_status command so users can retrieve M4 HAB
failure and warning events.

=> hab_status m4

   Secure boot disabled

   HAB Configuration: 0xf0, HAB State: 0x66
   No HAB Events Found!

Add command documentation in mx6_mx7_secure_boot.txt guide.

As HAB M4 API cannot be called from A7 core the code is parsing
the M4 HAB persistent memory region. The HAB persistent memory
stores HAB events, public keys and others HAB related information.

The HAB persistent memory region addresses and sizes can be found
in AN12263 "HABv4 RVT Guidelines and Recommendations".

Reviewed-by: Utkarsh Gupta <utkarsh.gupta at nxp.com>
Reviewed-by: Ye Li <ye.li at nxp.com>
Signed-off-by: Breno Lima <breno.lima at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm/include/asm/mach-imx/hab.h          | 15 +++
 arch/arm/mach-imx/hab.c                      | 99 ++++++++++++++++++++
 doc/imx/habv4/guides/mx6_mx7_secure_boot.txt | 25 +++++
 3 files changed, 139 insertions(+)

diff --git a/arch/arm/include/asm/mach-imx/hab.h b/arch/arm/include/asm/mach-imx/hab.h
index 62218818f9..1085c37828 100644
--- a/arch/arm/include/asm/mach-imx/hab.h
+++ b/arch/arm/include/asm/mach-imx/hab.h
@@ -42,6 +42,15 @@ struct __packed hab_hdr {
 	u8 par;              /* Parameters field */
 };
 
+/* Default event structure */
+struct __packed evt_def {
+	struct hab_hdr hdr;		/* Header */
+	uint32_t sts;			/* Status */
+	uint32_t ctx;			/* Default context */
+	uint8_t *data;			/* Default data location */
+	size_t bytes;			/* Size of default data */
+};
+
 /* -------- start of HAB API updates ------------*/
 /* The following are taken from HAB4 SIS */
 
@@ -211,6 +220,12 @@ typedef void hapi_clock_init_t(void);
 #define IVT_SIZE			0x20
 #define CSF_PAD_SIZE			0x2000
 
+#define HAB_TAG_EVT		0xDB
+#define HAB_TAG_EVT_DEF		0x0C
+
+#define HAB_MAJ_VER		0x40
+#define HAB_MAJ_MASK		0xF0
+
 /* ----------- end of HAB API updates ------------*/
 
 int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c
index 5f46df0f8b..469ef0fd1c 100644
--- a/arch/arm/mach-imx/hab.c
+++ b/arch/arm/mach-imx/hab.c
@@ -27,6 +27,12 @@ DECLARE_GLOBAL_DATA_PTR;
 	(is_soc_type(MXC_SOC_MX7ULP) ? 0x80000000 :	\
 	 ((is_soc_type(MXC_SOC_MX7) || is_soc_type(MXC_SOC_IMX8M)) ? 0x2000000 : 0x2))
 
+#ifdef CONFIG_MX7ULP
+#define HAB_M4_PERSISTENT_START	((soc_rev() >= CHIP_REV_2_0) ? 0x20008040 : \
+				  0x20008180)
+#define HAB_M4_PERSISTENT_BYTES		0xB80
+#endif
+
 static int ivt_header_error(const char *err_str, struct ivt_header *ivt_hdr)
 {
 	printf("%s magic=0x%x length=0x%02x version=0x%x\n", err_str,
@@ -477,15 +483,99 @@ static int get_hab_status(void)
 	return 0;
 }
 
+#ifdef CONFIG_MX7ULP
+
+static int get_record_len(struct record *rec)
+{
+	return (size_t)((rec->len[0] << 8) + (rec->len[1]));
+}
+
+static int get_hab_status_m4(void)
+{
+	unsigned int index = 0;
+	uint8_t event_data[128];
+	size_t record_len, offset = 0;
+	enum hab_config config = 0;
+	enum hab_state state = 0;
+
+	if (imx_hab_is_enabled())
+		puts("\nSecure boot enabled\n");
+	else
+		puts("\nSecure boot disabled\n");
+
+	/*
+	 * HAB in both A7 and M4 gather the security state
+	 * and configuration of the chip from
+	 * shared SNVS module
+	 */
+	hab_rvt_report_status(&config, &state);
+	printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
+	       config, state);
+
+	struct record *rec = (struct record *)(HAB_M4_PERSISTENT_START);
+
+	record_len = get_record_len(rec);
+
+	/* Check if HAB persistent memory is valid */
+	if (rec->tag != HAB_TAG_EVT_DEF ||
+	    record_len != sizeof(struct evt_def) ||
+	    (rec->par & HAB_MAJ_MASK) != HAB_MAJ_VER) {
+		puts("\nERROR: Invalid HAB persistent memory\n");
+		return 1;
+	}
+
+	/* Parse events in HAB M4 persistent memory region */
+	while (offset < HAB_M4_PERSISTENT_BYTES) {
+		rec = (struct record *)(HAB_M4_PERSISTENT_START + offset);
+
+		record_len = get_record_len(rec);
+
+		if (rec->tag == HAB_TAG_EVT) {
+			memcpy(&event_data, rec, record_len);
+			puts("\n");
+			printf("--------- HAB Event %d -----------------\n",
+			       index + 1);
+			puts("event data:\n");
+			display_event(event_data, record_len);
+			puts("\n");
+			index++;
+		}
+
+		offset += record_len;
+
+		/* Ensure all records start on a word boundary */
+		if ((offset % 4) != 0)
+			offset =  offset + (4 - (offset % 4));
+	}
+
+	if (!index)
+		puts("No HAB Events Found!\n\n");
+
+	return 0;
+}
+#endif
+
 static int do_hab_status(struct cmd_tbl *cmdtp, int flag, int argc,
 			 char *const argv[])
 {
+#ifdef CONFIG_MX7ULP
+	if ((argc > 2)) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	if (strcmp("m4", argv[1]) == 0)
+		get_hab_status_m4();
+	else
+		get_hab_status();
+#else
 	if ((argc != 1)) {
 		cmd_usage(cmdtp);
 		return 1;
 	}
 
 	get_hab_status();
+#endif
 
 	return 0;
 }
@@ -588,11 +678,20 @@ error:
 	return ret;
 }
 
+#ifdef CONFIG_MX7ULP
+U_BOOT_CMD(
+		hab_status, CONFIG_SYS_MAXARGS, 2, do_hab_status,
+		"display HAB status and events",
+		"hab_status - A7 HAB event and status\n"
+		"hab_status m4 - M4 HAB event and status"
+	  );
+#else
 U_BOOT_CMD(
 		hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status,
 		"display HAB status",
 		""
 	  );
+#endif
 
 U_BOOT_CMD(
 		hab_auth_img, 4, 0, do_authenticate_image,
diff --git a/doc/imx/habv4/guides/mx6_mx7_secure_boot.txt b/doc/imx/habv4/guides/mx6_mx7_secure_boot.txt
index 20fff937b6..53f71fbc3e 100644
--- a/doc/imx/habv4/guides/mx6_mx7_secure_boot.txt
+++ b/doc/imx/habv4/guides/mx6_mx7_secure_boot.txt
@@ -213,6 +213,30 @@ the example below:
   HAB Configuration: 0xf0, HAB State: 0x66
   No HAB Events Found!
 
+1.6.1 Verifying HAB events in i.MX7ULP
+---------------------------------------
+
+When booting i.MX7ULP in low power or dual boot modes the M4 binary is
+authenticated by an independent HAB in M4 ROM code using a
+different SRK key set.
+
+The U-Boot provides a M4 option in hab_status command so users can retrieve
+M4 HAB failure and warning events.
+
+- Verify HAB M4 events:
+
+  => hab_status m4
+
+  Secure boot disabled
+
+  HAB Configuration: 0xf0, HAB State: 0x66
+  No HAB Events Found!
+
+As HAB M4 API cannot be called from A7 core the command is parsing the M4 HAB
+persistent memory region, M4 software should not modify this reserved region.
+
+Details about HAB persistent memory region can be found in AN12263[2].
+
 1.7 Closing the device
 -----------------------
 
@@ -400,3 +424,4 @@ If no HAB events were found the zImage is successfully signed.
 References:
 [1] AN4581: "Secure Boot on i.MX 50, i.MX 53, i.MX 6 and i.MX 7 Series using
  HABv4" - Rev 2.
+[2] AN12263: "HABv4 RVT Guidelines and Recommendations" - Rev 0.
-- 
2.25.1



More information about the U-Boot mailing list