/* SPDX-License-Identifier: GPL-2.0-only */

#include <boot_device.h>
#include <bootmem.h>
#include <bootmode.h>
#include <cbfs.h>
#include <vboot_check.h>
#include <vboot_common.h>
#include <vb2_internals_please_do_not_use.h>

#define RSA_PUBLICKEY_FILE_NAME "vboot_public_key.bin"

#if CONFIG(VENDORCODE_ELTAN_VBOOT_USE_SHA512)
#define DIGEST_SIZE VB2_SHA512_DIGEST_SIZE
#define HASH_ALG VB2_HASH_SHA512
#else
#define DIGEST_SIZE VB2_SHA256_DIGEST_SIZE
#define HASH_ALG VB2_HASH_SHA256
#endif

int verified_boot_check_manifest(void)
{
	uint8_t *buffer;
	struct vb2_context *ctx;
	struct vb2_kernel_preamble *pre;
	static struct vb2_shared_data *sd;
	size_t size;
	uint8_t wb_buffer[3000];

	if (vb2api_init(&wb_buffer, sizeof(wb_buffer), &ctx)) {
		goto fail;
	}

	sd = vb2_get_sd(ctx);

	buffer = cbfs_map(RSA_PUBLICKEY_FILE_NAME, &size);
	if (!buffer || !size) {
		printk(BIOS_ERR, "ERROR: Public key not found!\n");
		goto fail;
	}

	if ((size != CONFIG_VENDORCODE_ELTAN_VBOOT_KEY_SIZE) ||
	    (buffer != (void *)CONFIG_VENDORCODE_ELTAN_VBOOT_KEY_LOCATION)) {
		printk(BIOS_ERR, "ERROR: Illegal public key!\n");
		goto fail;
	}

	/*
	 * Check if all items will fit into workbuffer:
	 * vb2_shared data, Public Key, Preamble data
	 */
	if ((sd->workbuf_used + size + sizeof(struct vb2_kernel_preamble) +
	    ((CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE) + (2048/8))) >
	    sizeof(wb_buffer)) {
		printk(BIOS_ERR, "ERROR: Work buffer too small\n");
		goto fail;
	}

	/* Add public key */
	sd->data_key_offset = sd->workbuf_used;
	sd->data_key_size = size;
	sd->workbuf_used += sd->data_key_size;
	memcpy((void *)((void *)sd + (long)sd->data_key_offset), (uint8_t *)buffer, size);

	/* Fill preamble area */
	sd->preamble_size = sizeof(struct vb2_kernel_preamble);
	sd->preamble_offset = sd->data_key_offset + sd->data_key_size;
	sd->workbuf_used += sd->preamble_size;
	pre = (struct vb2_kernel_preamble *)((void *)sd + (long)sd->preamble_offset);

	pre->flags = VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO;

	/* Fill body_signature (vb2_structure). RSA2048 key is used */
	cbfs_map("oemmanifest.bin", &size);
	if (size != ((CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS * DIGEST_SIZE) + (2048/8))) {
		printk(BIOS_ERR, "ERROR: Incorrect manifest size!\n");
		goto fail;
	}
	pre->body_signature.data_size = CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_ITEMS *
					DIGEST_SIZE;
	pre->body_signature.sig_offset = sizeof(struct vb2_signature) +
					 pre->body_signature.data_size;
	pre->body_signature.sig_size = size - pre->body_signature.data_size;
	sd->workbuf_used += size;
	memcpy((void *)((void *)&pre->body_signature + (long)sizeof(struct vb2_signature)),
	       (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC, size);


	if (vb2api_verify_kernel_data(ctx, (void *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC,
				      pre->body_signature.data_size))
		goto fail;

	printk(BIOS_INFO, "%s: Successfully verified hash_table signature.\n", __func__);
	return 0;

fail:
	die("ERROR: HASH table verification failed!\n");
	return -1;
}

/*
 *
 * measure_item
 *
 * extends the defined pcr using the hash calculated by the verified boot
 * routines.
 *
 * @param[in] pcr		PCR to extend
 * @param[in] *hashData		Pointer to the hash data
 * @param[in] hashDataLen	Length of the hash data
 * @param[in] *event_msg	Message to log or display
 * @param[in] eventType		Event type to use when logging

 * @retval TPM_SUCCESS		Operation completed successfully.
 * @retval TPM_E_IOERROR	Unexpected device behavior.
 */
static int measure_item(uint32_t pcr, uint8_t *hashData, uint32_t hashDataLen,
		int8_t *event_msg, TCG_EVENTTYPE eventType)
{
	int status = TPM_SUCCESS;
	TCG_PCR_EVENT2_HDR tcgEventHdr;

	memset(&tcgEventHdr, 0, sizeof(tcgEventHdr));
	tcgEventHdr.pcrIndex = pcr;
	tcgEventHdr.eventType = eventType;
	if (event_msg) {
		status = mboot_hash_extend_log(MBOOT_HASH_PROVIDED, hashData,
					       hashDataLen, &tcgEventHdr,
					       (uint8_t *)event_msg);
		if (status == TPM_SUCCESS)
			printk(BIOS_INFO, "%s: Success! %s measured to pcr %d.\n", __func__,
			       event_msg, pcr);
	}
	return status;
}

static void verified_boot_check_buffer(const char *name, void *start, size_t size,
				       uint32_t hash_index, int32_t pcr)
{
	uint8_t  digest[DIGEST_SIZE];
	vb2_error_t status;

	printk(BIOS_DEBUG, "%s: %s HASH verification buffer %p size %d\n", __func__, name,
	       start, (int)size);

	if (start && size) {

		status = vb2_digest_buffer((const uint8_t *)start, size, HASH_ALG, digest,
					   DIGEST_SIZE);
		if ((CONFIG(VENDORCODE_ELTAN_VBOOT) && memcmp((void *)(
		    (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC +
		    sizeof(digest) * hash_index), digest, sizeof(digest))) || status) {
			printk(BIOS_DEBUG, "%s: buffer hash\n", __func__);
			hexdump(digest, sizeof(digest));
			printk(BIOS_DEBUG, "%s: manifest hash\n", __func__);
			hexdump((void *)( (uint8_t *)CONFIG_VENDORCODE_ELTAN_OEM_MANIFEST_LOC +
				 sizeof(digest) * hash_index), sizeof(digest));
			printk(BIOS_EMERG, "%s ", name);
			die("HASH verification failed!\n");
		} else {
			if (!ENV_BOOTBLOCK && CONFIG(VENDORCODE_ELTAN_MBOOT)) {
				if (pcr != -1) {
					printk(BIOS_DEBUG, "%s: measuring %s\n", __func__,
					       name);
					if (measure_item(pcr, digest, sizeof(digest),
							 (int8_t *)name, 0))
						printk(BIOS_DEBUG, "%s: measuring failed!\n",
						       __func__);
				}
			}
			if (CONFIG(VENDORCODE_ELTAN_VBOOT))
				printk(BIOS_DEBUG, "%s HASH verification success\n", name);
		}
	} else {
		printk(BIOS_EMERG, "Invalid buffer\n");
		die("HASH verification failed!\n");
	}
}

void verified_boot_check_cbfsfile(const char *name, uint32_t type, uint32_t hash_index,
				  void **buffer, uint32_t *filesize, int32_t pcr)
{
	void *start;
	size_t size;

	start = cbfs_map(name, &size);
	if (start && size) {
		/* Speed up processing by copying the file content to memory first */
		if (!ENV_ROMSTAGE_OR_BEFORE && (type & VERIFIED_BOOT_COPY_BLOCK)) {

			if ((buffer) && (*buffer) && (*filesize >= size) &&
			    ((uint32_t) start > (uint32_t)(~(CONFIG_CBFS_SIZE-1)))) {

				/* Use the buffer passed in if possible */
				printk(BIOS_DEBUG, "%s: move buffer to memory\n", __func__);
				/* Move the file to memory buffer passed in */
				memcpy(*buffer, start, size);
				start = *buffer;
				printk(BIOS_DEBUG, "%s: done\n", __func__);

			} else if (ENV_RAMSTAGE) {
				/* Try to allocate a buffer from boot_mem */
				void *local_buffer = bootmem_allocate_buffer(size);

				if (local_buffer) {

					/* Use the allocated buffer */
					printk(BIOS_DEBUG, "%s: move file to memory\n",
					       __func__);
					memcpy(local_buffer, start, size);
					start = local_buffer;
					printk(BIOS_DEBUG, "%s: done\n", __func__);
				}
			}
		}
		verified_boot_check_buffer(name, start, size, hash_index, pcr);
	} else {
		printk(BIOS_EMERG, "CBFS Failed to get file content for %s\n", name);
		die("HASH verification failed!\n");
	}
	if (buffer)
		*buffer = start;
	if (filesize)
		*filesize = size;
}

void process_verify_list(const verify_item_t list[])
{
	int i = 0;

	while (list[i].type != VERIFY_TERMINATOR) {
		switch (list[i].type) {
		case VERIFY_FILE:
 			verified_boot_check_cbfsfile(list[i].name, list[i].data.file.cbfs_type,
					list[i].hash_index, NULL, NULL, list[i].pcr);
			if (list[i].data.file.related_items) {
				printk(BIOS_SPEW, "process related items\n");
				process_verify_list(
				        (verify_item_t *)list[i].data.file.related_items);
			}
			break;
		case VERIFY_BLOCK:
			verified_boot_check_buffer(list[i].name,
						   (void *)list[i].data.block.start,
						   list[i].data.block.size,
						   list[i].hash_index, list[i].pcr);
			break;
		default:
			printk(BIOS_EMERG, "INVALID TYPE IN VERIFY LIST 0x%x\n", list[i].type);
			die("HASH verification failed!\n");
		}
		i++;
	}
}

/*
 * BOOTBLOCK
 */

void verified_boot_bootblock_check(void)
{
	printk(BIOS_SPEW, "%s: processing bootblock items\n", __func__);

	if (CONFIG(VENDORCODE_ELTAN_VBOOT_SIGNED_MANIFEST)) {
		printk(BIOS_SPEW, "%s: check the manifest\n", __func__);
		if (verified_boot_check_manifest() != 0)
			die("invalid manifest");
	}
	printk(BIOS_SPEW, "%s: process bootblock verify list\n", __func__);
	process_verify_list(bootblock_verify_list);
}

/*
 * ROMSTAGE
 */

void verified_boot_early_check(void)
{
	printk(BIOS_SPEW, "%s: processing early items\n", __func__);

	if (CONFIG(VENDORCODE_ELTAN_MBOOT)) {
		printk(BIOS_DEBUG, "mb_measure returned 0x%x\n",
		mb_measure(platform_is_resuming()));
	}

	printk(BIOS_SPEW, "%s: process early verify list\n", __func__);
	process_verify_list(romstage_verify_list);
}

/*
 * RAM STAGE
 */

static int process_oprom_list(const verify_item_t list[],
		struct rom_header *rom_header)
{
	int i = 0;
	struct pci_data *rom_data;
	uint32_t viddevid = 0;

	if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) {
		printk(BIOS_ERR, "Incorrect expansion ROM header signature %04x DONT START\n",
		       le32_to_cpu(rom_header->signature));
		return 0;
	}

	rom_data = (((void *)rom_header) + le32_to_cpu(rom_header->data));

	viddevid |= (rom_data->vendor << 16);
	viddevid |= rom_data->device;

	while (list[i].type != VERIFY_TERMINATOR) {
		switch (list[i].type) {
		case VERIFY_OPROM:
			if (viddevid == list[i].data.oprom.viddev) {
				verified_boot_check_buffer(list[i].name,
							   (void *)rom_header,
							   rom_header->size * 512,
							   list[i].hash_index, list[i].pcr);
				if (list[i].data.oprom.related_items) {
					printk(BIOS_SPEW, "%s: process related items\n",
					       __func__);
					process_verify_list(
					    (verify_item_t *)list[i].data.oprom.related_items);
				}
				printk(BIOS_SPEW, "%s: option rom can be started\n", __func__);
				return 1;
			}
			break;
		default:
			printk(BIOS_EMERG, "%s: INVALID TYPE IN OPTION ROM LIST 0x%x\n",
			       __func__, list[i].type);
			die("HASH verification failed!\n");
		}
		i++;
	}
	printk(BIOS_ERR, "%s: option rom not in list DONT START\n", __func__);
	return 0;
}

int verified_boot_should_run_oprom(struct rom_header *rom_header)
{
	return process_oprom_list(oprom_verify_list, rom_header);
}

int prog_locate_hook(struct prog *prog)
{
	if (ENV_BOOTBLOCK)
		verified_boot_bootblock_check();

	if (ENV_ROMSTAGE) {
		if (prog->type == PROG_REFCODE)
			verified_boot_early_check();

		if (CONFIG(POSTCAR_STAGE) && prog->type == PROG_POSTCAR)
			process_verify_list(postcar_verify_list);

		if (!CONFIG(POSTCAR_STAGE) && prog->type == PROG_RAMSTAGE)
			process_verify_list(ramstage_verify_list);
	}

	if (ENV_POSTCAR && prog->type == PROG_RAMSTAGE)
		process_verify_list(ramstage_verify_list);

	if (ENV_RAMSTAGE && prog->type == PROG_PAYLOAD)
		process_verify_list(payload_verify_list);

	return 0;
}
