
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@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@ti.com + * Andreas Dannenberg dannenberg@ti.com * Harinarayan Bhatta harinarayan@ti.com + * Andrew F. Davis afd@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;