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

Andreas Dannenberg dannenberg at ti.com
Tue Jun 21 07:02:15 CEST 2016


Hi Lokesh--- comment inlined...

On Tue, Jun 21, 2016 at 10:01:54AM +0530, Lokesh Vutla wrote:
> 
> 
> 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)) { ?

Good suggestion! Will simplify.

> > +		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)) { ?

ditto.

> > +		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.

Oh yes, the UART boot. We actually explicitly added this printf for
successful authentication as the regular U-Boot verified boot also uses
some form of "positive feedback" (in form of a '+' sign or so) and we
felt its important feedback to _always_ provide some assurance that the
chain of trust is actually established (and not interrupted by a build
or setup error or something else).

So let's say we do want to keep this output, are there any other
options? Like suppressing it only in case of SPL UART boot, but not in
any of the other modes (sounds ugly but maybe there is another way)?

Thanks,
Andreas


> 
> 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