// 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_GP &&
	    (get_device_type() != K3_DEVICE_TYPE_HS_SE &&
	     !ti_secure_cert_detected(*p_image)))
		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");
}
