mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-18 09:13:06 +00:00
b661c1bc92
If the device is a GP and we detect a signing certificate then remove it. It would fail to authenticate otherwise as the device is GP and has no secure authentication services in SYSFW. This shouldn't happen often as trying to boot signed images on GP devices doesn't make much sense, but if we run into a signed image we should at least try to ignore the certificate and boot the image anyway. This could help with users of GP devices who only have HS images available. If this does happen, print a nice big warning. Signed-off-by: Andrew Davis <afd@ti.com> Reviewed-by: Tom Rini <trini@konsulko.com>
121 lines
3.4 KiB
C
121 lines
3.4 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* K3: Security functions
|
|
*
|
|
* Copyright (C) 2018-2022 Texas Instruments Incorporated - http://www.ti.com/
|
|
* Andrew F. Davis <afd@ti.com>
|
|
*/
|
|
|
|
#include <asm/io.h>
|
|
#include <common.h>
|
|
#include <cpu_func.h>
|
|
#include <dm.h>
|
|
#include <hang.h>
|
|
#include <image.h>
|
|
#include <log.h>
|
|
#include <asm/cache.h>
|
|
#include <linux/soc/ti/ti_sci_protocol.h>
|
|
#include <mach/spl.h>
|
|
#include <spl.h>
|
|
#include <asm/arch/sys_proto.h>
|
|
|
|
#include "common.h"
|
|
|
|
static bool ti_secure_cert_detected(void *p_image)
|
|
{
|
|
/* Primitive certificate detection, check for DER starting with
|
|
* two 4-Octet SEQUENCE tags
|
|
*/
|
|
return (((u8 *)p_image)[0] == 0x30 && ((u8 *)p_image)[1] == 0x82 &&
|
|
((u8 *)p_image)[4] == 0x30 && ((u8 *)p_image)[5] == 0x82);
|
|
}
|
|
|
|
/* Primitive certificate length, assumes one 2-Octet sized SEQUENCE */
|
|
static size_t ti_secure_cert_length(void *p_image)
|
|
{
|
|
size_t seq_length = be16_to_cpu(readw_relaxed(p_image + 2));
|
|
/* Add 4 for the SEQUENCE tag length */
|
|
return seq_length + 4;
|
|
}
|
|
|
|
void ti_secure_image_post_process(void **p_image, size_t *p_size)
|
|
{
|
|
struct ti_sci_handle *ti_sci = get_ti_sci_handle();
|
|
struct ti_sci_proc_ops *proc_ops = &ti_sci->ops.proc_ops;
|
|
size_t cert_length;
|
|
u64 image_addr;
|
|
u32 image_size;
|
|
int ret;
|
|
|
|
image_addr = (uintptr_t)*p_image;
|
|
image_size = *p_size;
|
|
|
|
if (!image_size)
|
|
return;
|
|
|
|
if (get_device_type() == K3_DEVICE_TYPE_GP) {
|
|
if (ti_secure_cert_detected(*p_image)) {
|
|
printf("Warning: Detected image signing certificate on GP device. "
|
|
"Skipping certificate to prevent boot failure. "
|
|
"This will fail if the image was also encrypted\n");
|
|
|
|
cert_length = ti_secure_cert_length(*p_image);
|
|
if (cert_length > *p_size) {
|
|
printf("Invalid signing certificate size\n");
|
|
return;
|
|
}
|
|
|
|
*p_image += cert_length;
|
|
*p_size -= cert_length;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (get_device_type() != K3_DEVICE_TYPE_HS_SE &&
|
|
!ti_secure_cert_detected(*p_image)) {
|
|
printf("Warning: Did not detect image signing certificate. "
|
|
"Skipping authentication to prevent boot failure. "
|
|
"This will fail on Security Enforcing(HS-SE) devices\n");
|
|
return;
|
|
}
|
|
|
|
debug("Authenticating image at address 0x%016llx\n", image_addr);
|
|
debug("Authenticating image of size %d bytes\n", image_size);
|
|
|
|
flush_dcache_range((unsigned long)image_addr,
|
|
ALIGN((unsigned long)image_addr + image_size,
|
|
ARCH_DMA_MINALIGN));
|
|
|
|
/* Authenticate image */
|
|
ret = proc_ops->proc_auth_boot_image(ti_sci, &image_addr, &image_size);
|
|
if (ret) {
|
|
printf("Authentication failed!\n");
|
|
hang();
|
|
}
|
|
|
|
if (image_size)
|
|
invalidate_dcache_range((unsigned long)image_addr,
|
|
ALIGN((unsigned long)image_addr +
|
|
image_size, ARCH_DMA_MINALIGN));
|
|
|
|
/*
|
|
* The image_size returned may be 0 when the authentication process has
|
|
* moved the image. When this happens no further processing on the
|
|
* image is needed or often even possible as it may have also been
|
|
* placed behind a firewall when moved.
|
|
*/
|
|
*p_size = image_size;
|
|
|
|
/*
|
|
* Output notification of successful authentication 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\n");
|
|
}
|