[U-Boot] [PATCH 5/9] arm: omap-common: secure ROM signature verify API

Lokesh Vutla lokeshvutla at ti.com
Tue Jun 21 06:31:54 CEST 2016



On Tuesday 21 June 2016 09:04 AM, Andreas Dannenberg wrote:
> Adds an API that verifies a signature attached to an image (binary
> blob). This API is basically a entry to a secure ROM service provided by
> the device and accessed via an SMC call, using a particular calling
> convention.
> 
> Signed-off-by: Daniel Allred <d-allred at ti.com>
> Signed-off-by: Andreas Dannenberg <dannenberg at ti.com>
> ---
>  arch/arm/cpu/armv7/omap-common/sec-common.c | 76 +++++++++++++++++++++++++++++
>  arch/arm/include/asm/omap_common.h          |  9 ++++
>  2 files changed, 85 insertions(+)
> 
> diff --git a/arch/arm/cpu/armv7/omap-common/sec-common.c b/arch/arm/cpu/armv7/omap-common/sec-common.c
> index b9c0a42..dbb9078 100644
> --- a/arch/arm/cpu/armv7/omap-common/sec-common.c
> +++ b/arch/arm/cpu/armv7/omap-common/sec-common.c
> @@ -16,6 +16,9 @@
>  #include <asm/arch/sys_proto.h>
>  #include <asm/omap_common.h>
>  
> +/* Index for signature verify ROM API */
> +#define API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX	(0x0000000E)
> +
>  static uint32_t secure_rom_call_args[5] __aligned(ARCH_DMA_MINALIGN);
>  
>  u32 secure_rom_call(u32 service, u32 proc_id, u32 flag, ...)
> @@ -47,3 +50,76 @@ u32 secure_rom_call(u32 service, u32 proc_id, u32 flag, ...)
>  
>  	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 (0 != (0x3 & cert_addr)) {

	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 (0 != (0x3 & cert_size)) {

	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);
> +auth_exit:
> +	if (result != 0) {
> +		printf("Authentication failed!\n");
> +		printf("Return Value = %08X\n", result);
> +		hang();
> +	}
> +
> +	printf("Authentication passed: %s\n", (char *)sig_addr);

Uart boot will break because of these prints during the FIT loading. Can
you make this as debug?

Prints in the failed case is fine as we need to know if it is failed.

Thanks and regards,
Lokesh

> +
> +	return result;
> +}
> diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h
> index 293fc72..8887335 100644
> --- a/arch/arm/include/asm/omap_common.h
> +++ b/arch/arm/include/asm/omap_common.h
> @@ -640,6 +640,15 @@ u32 omap_smc_sec(u32 service, u32 proc_id, u32 flag, u32 *params);
>   */
>  u32 secure_rom_call(u32 service, u32 proc_id, u32 flag, ...);
>  
> +/*
> + * Invoke a secure ROM API on high-secure (HS) device variants that can be used
> + * to verify a secure blob by authenticating and optionally decrypting it. The
> + * exact operation performed depends on how the certificate that was embedded
> + * into the blob during the signing/encryption step when the secure blob was
> + * first created.
> + */
> +int secure_boot_verify_image(void **p_image, size_t *p_size);
> +
>  void enable_edma3_clocks(void);
>  void disable_edma3_clocks(void);
>  
> 


More information about the U-Boot mailing list