// 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 <linux/dma-mapping.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_check_binary(void **p_image, size_t *p_size)
{
	u32 image_size;
	size_t cert_length;
	image_size = *p_size;

	if (!image_size) {
		debug("%s: Image size is %d\n", __func__, 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;
	}
}

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;
	u64 image_addr;
	u32 image_size;
	int ret;

	image_size = *p_size;
	if (!image_size) {
		debug("%s: Image size is %d\n", __func__, image_size);
		return;
	}

	if (get_device_type() != K3_DEVICE_TYPE_HS_SE &&
	    get_device_type() != K3_DEVICE_TYPE_HS_FS)
		return;

	/* Clean out image so it can be seen by system firmware */
	image_addr = dma_map_single(*p_image, *p_size, DMA_BIDIRECTIONAL);

	debug("Authenticating image at address 0x%016llx\n", image_addr);
	debug("Authenticating image of size %d bytes\n", image_size);

	/* Authenticate image */
	ret = proc_ops->proc_auth_boot_image(ti_sci, &image_addr, &image_size);
	if (ret) {
		printf("Authentication failed!\n");
		hang();
	}

	/* Invalidate any stale lines over data written by system firmware */
	if (image_size)
		dma_unmap_single(image_addr, image_size, DMA_BIDIRECTIONAL);

	/*
	 * 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");
}
