arm: omap-common: secure ROM signature verify API
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@ti.com> Signed-off-by: Andreas Dannenberg <dannenberg@ti.com> Reviewed-by: Tom Rini <trini@konsulko.com>
This commit is contained in:
parent
d86f7afda4
commit
1bb0a21b46
@ -17,6 +17,11 @@
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/omap_common.h>
|
||||
#include <asm/omap_sec_common.h>
|
||||
#include <asm/spl.h>
|
||||
#include <spl.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);
|
||||
|
||||
@ -49,3 +54,86 @@ 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 (!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);
|
||||
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;
|
||||
}
|
||||
|
@ -18,4 +18,13 @@
|
||||
*/
|
||||
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);
|
||||
|
||||
#endif /* _OMAP_SEC_COMMON_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user