[U-Boot] [PATCH 1/6] arm: mach-omap2: Move omap5/sec-fxns.c into sec-common.c

Andrew F. Davis afd at ti.com
Fri Jun 16 19:26:56 UTC 2017


TEE loading and firewall setup are common to all omap2 devices, move
these function out of omap5 and into mach-omap2. This allows us
to use these functions from other omap class devices.

Signed-off-by: Andrew F. Davis <afd at ti.com>
---
 arch/arm/mach-omap2/Kconfig                        |  26 ++++
 arch/arm/mach-omap2/omap5/Kconfig                  |  26 ----
 arch/arm/mach-omap2/omap5/Makefile                 |   1 -
 .../mach-omap2/{omap5/sec-fxns.c => sec-common.c}  | 155 ++++++++++++++++++++-
 4 files changed, 174 insertions(+), 34 deletions(-)
 rename arch/arm/mach-omap2/{omap5/sec-fxns.c => sec-common.c} (64%)

diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 683cdb9296..013586edd9 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -119,6 +119,32 @@ config TI_SECURE_DEVICE
 	  authenticated) and the code. See the doc/README.ti-secure
 	  file for further details.
 
+config TI_SECURE_EMIF_REGION_START
+	hex "Reserved EMIF region start address"
+	depends on TI_SECURE_DEVICE
+	default 0x0
+	help
+	  Reserved EMIF region start address. Set to "0" to auto-select
+	  to be at the end of the external memory region.
+
+config TI_SECURE_EMIF_TOTAL_REGION_SIZE
+	hex "Reserved EMIF region size"
+	depends on TI_SECURE_DEVICE
+	default 0x0
+	help
+	  Total reserved EMIF region size. Default is 0, which means no reserved EMIF
+	  region on secure devices.
+
+config TI_SECURE_EMIF_PROTECTED_REGION_SIZE
+	hex "Size of protected region within reserved EMIF region"
+	depends on TI_SECURE_DEVICE
+	default 0x0
+	help
+	  This config option is used to specify the size of the portion of the total
+	  reserved EMIF region set aside for secure OS needs that will  be protected
+	  using hardware memory firewalls. This value must be smaller than the
+	  TI_SECURE_EMIF_TOTAL_REGION_SIZE value.
+
 source "arch/arm/mach-omap2/omap3/Kconfig"
 
 source "arch/arm/mach-omap2/omap4/Kconfig"
diff --git a/arch/arm/mach-omap2/omap5/Kconfig b/arch/arm/mach-omap2/omap5/Kconfig
index 1a66abdeb2..7e8e532d4c 100644
--- a/arch/arm/mach-omap2/omap5/Kconfig
+++ b/arch/arm/mach-omap2/omap5/Kconfig
@@ -37,32 +37,6 @@ endchoice
 config SYS_SOC
 	default "omap5"
 
-config TI_SECURE_EMIF_REGION_START
-	hex "Reserved EMIF region start address"
-	depends on TI_SECURE_DEVICE
-	default 0x0
-	help
-	  Reserved EMIF region start address. Set to "0" to auto-select
-	  to be at the end of the external memory region.
-
-config TI_SECURE_EMIF_TOTAL_REGION_SIZE
-	hex "Reserved EMIF region size"
-	depends on TI_SECURE_DEVICE
-	default 0x0
-	help
-	  Total reserved EMIF region size. Default is 0, which means no reserved EMIF
-	  region on secure devices.
-
-config TI_SECURE_EMIF_PROTECTED_REGION_SIZE
-	hex "Size of protected region within reserved EMIF region"
-	depends on TI_SECURE_DEVICE
-	default 0x0
-	help
-	  This config option is used to specify the size of the portion of the total
-	  reserved EMIF region set aside for secure OS needs that will  be protected
-	  using hardware memory firewalls. This value must be smaller than the
-	  TI_SECURE_EMIF_TOTAL_REGION_SIZE value.
-
 config OMAP_PLATFORM_RESET_TIME_MAX_USEC
 	int "Something"
 	range 0  31219
diff --git a/arch/arm/mach-omap2/omap5/Makefile b/arch/arm/mach-omap2/omap5/Makefile
index af17a3deab..a6a5d17ff6 100644
--- a/arch/arm/mach-omap2/omap5/Makefile
+++ b/arch/arm/mach-omap2/omap5/Makefile
@@ -14,5 +14,4 @@ obj-y	+= hw_data.o
 obj-y	+= abb.o
 obj-y	+= fdt.o
 obj-$(CONFIG_IODELAY_RECALIBRATION) += dra7xx_iodelay.o
-obj-$(CONFIG_TI_SECURE_DEVICE) += sec-fxns.o
 obj-$(CONFIG_DRA7XX) += sec_entry_cpu1.o
diff --git a/arch/arm/mach-omap2/omap5/sec-fxns.c b/arch/arm/mach-omap2/sec-common.c
similarity index 64%
rename from arch/arm/mach-omap2/omap5/sec-fxns.c
rename to arch/arm/mach-omap2/sec-common.c
index 7fab57592e..f230c9ea4e 100644
--- a/arch/arm/mach-omap2/omap5/sec-fxns.c
+++ b/arch/arm/mach-omap2/sec-common.c
@@ -1,12 +1,14 @@
 /*
  *
- * Security related functions for OMAP5 class devices
+ * Common security related functions for OMAP devices
  *
- * (C) Copyright 2016
+ * (C) Copyright 2016-2017
  * Texas Instruments, <www.ti.com>
  *
  * Daniel Allred <d-allred at ti.com>
+ * Andreas Dannenberg <dannenberg at ti.com>
  * Harinarayan Bhatta <harinarayan at ti.com>
+ * Andrew F. Davis <afd at ti.com>
  *
  * SPDX-License-Identifier: GPL-2.0+
  */
@@ -15,14 +17,22 @@
 #include <stdarg.h>
 
 #include <asm/arch/sys_proto.h>
+#include <asm/cache.h>
 #include <asm/omap_common.h>
 #include <asm/omap_sec_common.h>
 #include <asm/spl.h>
-#include <spl.h>
-#include <asm/cache.h>
+#include <asm/ti-common/sys_proto.h>
 #include <mapmem.h>
+#include <spl.h>
 #include <tee/optee.h>
 
+/* Index for signature verify ROM API */
+#ifdef CONFIG_AM33XX
+#define API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX	(0x0000000C)
+#else
+#define API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX	(0x0000000E)
+#endif
+
 /* Index for signature PPA-based TI HAL APIs */
 #define PPA_HAL_SERVICES_START_INDEX        (0x200)
 #define PPA_SERV_HAL_TEE_LOAD_MASTER        (PPA_HAL_SERVICES_START_INDEX + 23)
@@ -43,6 +53,129 @@ struct ppa_tee_load_info {
 	u32 tee_arg0;          /* argument to TEE jump function, in r0 */
 };
 
+static uint32_t secure_rom_call_args[5] __aligned(ARCH_DMA_MINALIGN);
+
+u32 secure_rom_call(u32 service, u32 proc_id, u32 flag, ...)
+{
+	int i;
+	u32 num_args;
+	va_list ap;
+
+	va_start(ap, flag);
+
+	num_args = va_arg(ap, u32);
+
+	if (num_args > 4) {
+		va_end(ap);
+		return 1;
+	}
+
+	/* Copy args to aligned args structure */
+	for (i = 0; i < num_args; i++)
+		secure_rom_call_args[i + 1] = va_arg(ap, u32);
+
+	secure_rom_call_args[0] = num_args;
+
+	va_end(ap);
+
+	/* if data cache is enabled, flush the aligned args structure */
+	flush_dcache_range(
+		(unsigned int)&secure_rom_call_args[0],
+		(unsigned int)&secure_rom_call_args[0] +
+		roundup(sizeof(secure_rom_call_args), ARCH_DMA_MINALIGN));
+
+	return omap_smc_sec(service, proc_id, flag, secure_rom_call_args);
+}
+
+static u32 find_sig_start(char *image, size_t size)
+{
+	char *image_end = image + size;
+	char *sig_start_magic = "CERT_";
+	int magic_str_len = strlen(sig_start_magic);
+	char *ch;
+
+	while (--image_end > image) {
+		if (*image_end == '_') {
+			ch = image_end - magic_str_len + 1;
+			if (!strncmp(ch, sig_start_magic, magic_str_len))
+				return (u32)ch;
+		}
+	}
+	return 0;
+}
+
+int secure_boot_verify_image(void **image, size_t *size)
+{
+	int result = 1;
+	u32 cert_addr, sig_addr;
+	size_t cert_size;
+
+	/* Perform cache writeback on input buffer */
+	flush_dcache_range(
+		(u32)*image,
+		(u32)*image + roundup(*size, ARCH_DMA_MINALIGN));
+
+	cert_addr = (uint32_t)*image;
+	sig_addr = find_sig_start((char *)*image, *size);
+
+	if (sig_addr == 0) {
+		printf("No signature found in image!\n");
+		result = 1;
+		goto auth_exit;
+	}
+
+	*size = sig_addr - cert_addr;	/* Subtract out the signature size */
+	cert_size = *size;
+
+	/* Check if image load address is 32-bit aligned */
+	if (!IS_ALIGNED(cert_addr, 4)) {
+		printf("Image is not 4-byte aligned!\n");
+		result = 1;
+		goto auth_exit;
+	}
+
+	/* Image size also should be multiple of 4 */
+	if (!IS_ALIGNED(cert_size, 4)) {
+		printf("Image size is not 4-byte aligned!\n");
+		result = 1;
+		goto auth_exit;
+	}
+
+	/* Call ROM HAL API to verify certificate signature */
+	debug("%s: load_addr = %x, size = %x, sig_addr = %x\n", __func__,
+	      cert_addr, cert_size, sig_addr);
+
+	result = secure_rom_call(
+		API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX, 0, 0,
+		4, cert_addr, cert_size, sig_addr, 0xFFFFFFFF);
+
+	/* Perform cache writeback on output buffer */
+	flush_dcache_range(
+		(u32)*image,
+		(u32)*image + roundup(*size, ARCH_DMA_MINALIGN));
+
+auth_exit:
+	if (result != 0) {
+		printf("Authentication failed!\n");
+		printf("Return Value = %08X\n", result);
+		hang();
+	}
+
+	/*
+	 * Output notification of successful authentication as well the name of
+	 * the signing certificate used to re-assure the user that the secure
+	 * code is being processed as expected. However suppress any such log
+	 * output in case of building for SPL and booting via YMODEM. This is
+	 * done to avoid disturbing the YMODEM serial protocol transactions.
+	 */
+	if (!(IS_ENABLED(CONFIG_SPL_BUILD) &&
+	      IS_ENABLED(CONFIG_SPL_YMODEM_SUPPORT) &&
+	      spl_boot_device() == BOOT_DEVICE_UART))
+		printf("Authentication passed: %s\n", (char *)sig_addr);
+
+	return result;
+}
+
 static u32 get_sec_mem_start(void)
 {
 	u32 sec_mem_start = CONFIG_TI_SECURE_EMIF_REGION_START;
@@ -55,8 +188,14 @@ static u32 get_sec_mem_start(void)
 	 */
 	if (sec_mem_start == 0)
 		sec_mem_start =
-			(CONFIG_SYS_SDRAM_BASE +
-			(omap_sdram_size() - sec_mem_size));
+			(CONFIG_SYS_SDRAM_BASE + (
+#if defined(CONFIG_OMAP54XX)
+			omap_sdram_size()
+#else
+			get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
+				     CONFIG_MAX_RAM_BANK_SIZE)
+#endif
+			- sec_mem_size));
 	return sec_mem_start;
 }
 
@@ -151,7 +290,6 @@ int secure_tee_install(u32 addr)
 	u32 tee_file_size;
 	u32 sec_mem_start = get_sec_mem_start();
 	const u32 size = CONFIG_TI_SECURE_EMIF_PROTECTED_REGION_SIZE;
-	u32 *smc_cpu1_params;
 	u32 ret;
 
 	/* If there is no protected region, there is no place to put the TEE */
@@ -211,7 +349,9 @@ int secure_tee_install(u32 addr)
 	}
 	printf("TEE_LOAD_MASTER Done\n");
 
+#if defined(CONFIG_OMAP54XX)
 	if (!is_dra72x()) {
+		u32 *smc_cpu1_params;
 		/* Reuse the tee_info buffer for SMC params */
 		smc_cpu1_params = (u32 *)&tee_info;
 		smc_cpu1_params[0] = 0;
@@ -227,6 +367,7 @@ int secure_tee_install(u32 addr)
 		}
 		printf("TEE_LOAD_SLAVE Done\n");
 	}
+#endif
 
 	tee_loaded = 1;
 
-- 
2.13.0



More information about the U-Boot mailing list