/* Firmware Interface Table support */
/* SPDX-License-Identifier: GPL-2.0-only */

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "fit.h"

/* FIXME: This code assumes it is being executed on a little endian machine. */

#define FIT_POINTER_LOCATION 0xffffffc0
#define FIT_TABLE_LOWEST_ADDRESS ((uint32_t)(-(16 << 20)))
#define FIT_ENTRY_CHECKSUM_VALID 0x80
#define FIT_HEADER_VERSION 0x0100
#define FIT_HEADER_ADDRESS "_FIT_   "
#define FIT_MICROCODE_VERSION 0x0100
#define FIT_TXT_VERSION 0x0100

#define FIT_SIZE_ALIGNMENT 16

struct fit_entry {
	/**
	 * Address is the base address of the firmware component
	 * must be aligned on 16 byte boundary
	 */
	uint64_t address;
	/**
	 * Size is the span of the component in multiple of 16 bytes
	 * Bits [24:31] are reserved and  must be set to 0
	 */
	uint32_t size_reserved;
	/**
	 * Component's version number in binary coded decimal (BCD) format.
	 * For the FIT header entry, the value in this field will indicate the
	 * revision number of the FIT data structure. The upper byte of the
	 * revision field indicates the major revision and the lower byte
	 * indicates the minor revision.
	 */
	uint16_t version;
	/**
	 * FIT types 0x00 to 0x7F
	 * Bit 7 (C_V) indicates whether component has valid checksum.
	 */
	uint8_t  type_checksum_valid;
	/**
	 * Component's checksum. The modulo sum of all the bytes in the
	 * component and the value in this field (Chksum) must add up to zero.
	 * This field is only valid if the C_V flag is non-zero.
	 */
	uint8_t  checksum;
} __packed;

struct fit_table {
	struct fit_entry header;
	struct fit_entry entries[];
} __packed;

struct microcode_header {
	uint32_t version;
	uint32_t revision;
	uint32_t date;
	uint32_t processor_signature;
	uint32_t checksum;
	uint32_t loader_revision;
	uint32_t processor_flags;
	uint32_t data_size;
	uint32_t total_size;
	uint8_t  reserved[12];
} __packed;

struct microcode_entry {
	int offset;
	int size;
};

static inline void *rom_buffer_pointer(struct buffer *buffer, int offset)
{
	return &buffer->data[offset];
}

static inline size_t fit_entry_size_bytes(const struct fit_entry *entry)
{
	return (entry->size_reserved & 0xffffff) << 4;
}

static inline void fit_entry_update_size(struct fit_entry *entry,
					 const int size_bytes)
{
	/* Size is multiples of 16 bytes. */
	entry->size_reserved = (size_bytes >> 4) & 0xffffff;
}

static inline void fit_entry_add_size(struct fit_entry *entry,
				      const int size_bytes)
{
	int size = fit_entry_size_bytes(entry);
	size += size_bytes;
	fit_entry_update_size(entry, size);
}

static inline int fit_entry_type(struct fit_entry *entry)
{
	return entry->type_checksum_valid & ~FIT_ENTRY_CHECKSUM_VALID;
}

/*
 * Get an offset from a host pointer. This function assumes the ROM is located
 * in the host address space at [4G - romsize -> 4G). It also assume all
 * pointers have values within this address range.
 */
static inline int ptr_to_offset(fit_offset_converter_t helper,
				const struct buffer *region, uint32_t host_ptr)
{
	return helper(region, -host_ptr);
}

/*
 * Get a pointer from an offset. This function assumes the ROM is located
 * in the host address space at [4G - romsize -> 4G). It also assume all
 * pointers have values within this address range.
 */
static inline uint32_t offset_to_ptr(fit_offset_converter_t helper,
				     const struct buffer *region, int offset)
{
	return -helper(region, offset);
}

/*
 * Return the number of FIT entries.
 */
static inline size_t fit_table_entries(const struct fit_table *fit)
{
	if (!fit)
		return 0;

	return (fit_entry_size_bytes(&fit->header) / FIT_SIZE_ALIGNMENT) - 1;
}

/*
 * Return the number of unused entries.
 */
static inline size_t fit_free_space(struct fit_table *fit,
				 const size_t max_entries)
{
	if (!fit)
		return 0;

	return max_entries - fit_table_entries(fit);
}

/*
 * Sort entries by type and fill gaps (entries with type unused).
 * To be called after adding or deleting entries.
 *
 * This one is critical, as mentioned in Chapter 1.2.1 "FIT Ordering Rules"
 * "Firmware Interface Table BIOS Specification".
 *
 * We need to use a stable sorting algorithm, as the order of
 * FIT_TYPE_BIOS_STARTUP matter for measurements.
 */
static void sort_fit_table(struct fit_table *fit)
{
	struct fit_entry tmp;
	size_t i, j;
	int swapped;

	/* Bubble sort entries */
	for (j = 0; j < fit_table_entries(fit) - 1; j++) {
		swapped = 0;
		for (i = 0; i < fit_table_entries(fit) - j - 1; i++) {
			if (fit->entries[i].type_checksum_valid <=
			    fit->entries[i + 1].type_checksum_valid)
				continue;
			/* SWAP entries */
			memcpy(&tmp, &fit->entries[i], sizeof(tmp));
			memcpy(&fit->entries[i], &fit->entries[i + 1],
			       sizeof(fit->entries[i]));
			memcpy(&fit->entries[i + 1], &tmp,
			       sizeof(fit->entries[i + 1]));
			swapped = 1;
		}
		if (!swapped)
			break;
	}
}

static int fit_table_verified(struct fit_table *table)
{
	if (!table)
		return 0;

	/* Check that the address field has the proper signature. */
	if (strncmp((const char *)&table->header.address, FIT_HEADER_ADDRESS,
			sizeof(table->header.address)))
		return 0;

	if (table->header.version != FIT_HEADER_VERSION)
		return 0;

	if (fit_entry_type(&table->header) != FIT_TYPE_HEADER)
		return 0;

	/* Assume that the FIT table contains at least the header */
	if (fit_entry_size_bytes(&table->header) < sizeof(struct fit_entry))
		return 0;

	return 1;
}

/*
 * Update the FIT checksum.
 * To be called after modifiying the table.
 */
static void update_fit_checksum(struct fit_table *fit)
{
	int size_bytes;
	uint8_t *buffer;
	uint8_t result;
	int i;

	if (!fit)
		return;

	fit->header.checksum = 0;
	size_bytes = fit_entry_size_bytes(&fit->header);
	result = 0;
	buffer = (void *)fit;
	for (i = 0; i < size_bytes; i++)
		result += buffer[i];
	fit->header.checksum = -result;
}

/*
 * Return a pointer to the next free entry.
 * Caller must take care if enough space is available.
 */
static struct fit_entry *get_next_free_entry(struct fit_table *fit)
{
	return &fit->entries[fit_table_entries(fit)];
}

static void fit_location_from_cbfs_header(uint32_t *current_offset,
					  uint32_t *file_length, void *ptr)
{
	struct buffer buf;
	struct cbfs_file header;
	memset(&buf, 0, sizeof(buf));

	buf.data = ptr;
	buf.size = sizeof(header);

	bgets(&buf, header.magic, sizeof(header.magic));
	header.len = xdr_be.get32(&buf);
	header.type = xdr_be.get32(&buf);
	header.attributes_offset = xdr_be.get32(&buf);
	header.offset = xdr_be.get32(&buf);

	*current_offset = header.offset;
	*file_length = header.len;
}

static int
parse_microcode_blob(struct cbfs_image *image,
		     const char *blob_name,
		     size_t *mcus_found,
		     struct microcode_entry *mcus,
		     const size_t max_fit_entries)
{
	size_t num_mcus;
	uint32_t current_offset;
	uint32_t file_length;
	struct cbfs_file *mcode_file;

	mcode_file = cbfs_get_entry(image, blob_name);
	if (!mcode_file)
		return 1;

	fit_location_from_cbfs_header(&current_offset, &file_length,
				      mcode_file);
	current_offset += cbfs_get_entry_addr(image, mcode_file);

	num_mcus = 0;
	while (file_length > sizeof(struct microcode_header)) {
		const struct microcode_header *mcu_header;

		mcu_header = rom_buffer_pointer(&image->buffer, current_offset);
		if (!mcu_header) {
			ERROR("Couldn't parse microcode header.\n");
			return 1;
		}

		/* Newer microcode updates include a size field, whereas older
		 * containers set it at 0 and are exactly 2048 bytes long */
		uint32_t total_size = mcu_header->total_size ?: 2048;

		/* Quickly sanity check a prospective microcode update. */
		if (total_size < sizeof(*mcu_header))
			break;

		/* FIXME: Should the checksum be validated? */
		mcus[num_mcus].offset = current_offset;
		mcus[num_mcus].size = total_size;

		/* Proceed to next payload. */
		current_offset += mcus[num_mcus].size;
		file_length -= mcus[num_mcus].size;
		num_mcus++;
		/* Reached limit of FIT entries. */
		if (num_mcus == max_fit_entries)
			break;
		if (file_length < sizeof(struct microcode_header))
			break;
	}

	/* Update how many microcode updates we found. */
	*mcus_found = num_mcus;

	return 0;
}

/* There can be zero or more FIT_TYPE_MICROCODE entries */
static void update_fit_ucode_entry(struct fit_table *fit,
				   struct fit_entry *entry,
				   const uint64_t mcu_addr)
{
	entry->address = mcu_addr;
	/*
	 * While loading MCU, its size is not referred from FIT and
	 * rather from the MCU header, hence we can assign zero here.
	 */
	entry->size_reserved = 0;
	entry->type_checksum_valid = FIT_TYPE_MICROCODE;
	entry->version = FIT_MICROCODE_VERSION;
	entry->checksum = 0;
	fit_entry_add_size(&fit->header, sizeof(struct fit_entry));
}

/*
 * There can be zero or one FIT_TYPE_BIOS_ACM entry per table.
 * In case there's a FIT_TYPE_BIOS_ACM entry, at least one
 * FIT_TYPE_BIOS_STARTUP entry must exist.
 *
 * The caller has to provide valid arguments as those aren't verfied.
 */
static void update_fit_bios_acm_entry(struct fit_table *fit,
				      struct fit_entry *entry,
				      const uint64_t acm_addr)
{
	entry->address = acm_addr;
	/*
	 * The Address field points to a BIOS ACM. The Address field points to
	 * the first byte of the AC module header. When BIOS ACM is loaded in
	 * Authenticated Code RAM, one MTRR base/limit pair is used to map it.
	 */
	entry->size_reserved = 0;
	entry->type_checksum_valid = FIT_TYPE_BIOS_ACM;
	entry->version = FIT_TXT_VERSION;
	entry->checksum = 0;
	fit_entry_add_size(&fit->header, sizeof(struct fit_entry));
}

/*
 * In case there's a FIT_TYPE_BIOS_ACM entry, at least one
 * FIT_TYPE_BIOS_STARTUP entry must exist.
 *
 * The caller has to provide valid arguments as those aren't verfied.
 */
static void update_fit_bios_startup_entry(struct fit_table *fit,
					  struct fit_entry *entry,
					  const uint64_t sm_addr,
					  const uint32_t sm_size)
{
	entry->address = sm_addr;
	assert(sm_size % 16 == 0);
	/*
	 * BIOS Startup code is defined as the code that gets control at the
	 * reset vector and continues the chain of trust in TCG-compliant
	 * fashion. In addition, this code may also configure memory and SMRAM.
	 */
	fit_entry_update_size(entry, sm_size);
	entry->type_checksum_valid = FIT_TYPE_BIOS_STARTUP;
	entry->version = FIT_TXT_VERSION;
	entry->checksum = 0;
	fit_entry_add_size(&fit->header, sizeof(struct fit_entry));
}

/*
 * There can be zero or one FIT_TYPE_BIOS_POLICY Record in the FIT.
 * If the platform uses the hash comparison method and employs a
 * failsafe bootblock, one FIT_TYPE_BIOS_POLICY entry is needed to
 * contain the failsafe hash.
 * If the platform uses the Signature verification method, one
 * FIT_TYPE_BIOS_POLICY entry is needed. In this case, the entry
 * contains the OEM key, hash of the BIOS and signature over the hash
 * using the OEM key.
 * In all other cases, the FIT_TYPE_BIOS_POLICY record is not required.
 *
 * The caller has to provide valid arguments as those aren't verfied.
 */
static void update_fit_bios_policy_entry(struct fit_table *fit,
					 struct fit_entry *entry,
					 const uint64_t lcp_policy_addr,
					 const uint32_t lcp_policy_size)
{
	entry->address = lcp_policy_addr;
	fit_entry_update_size(entry, lcp_policy_size);
	entry->type_checksum_valid = FIT_TYPE_BIOS_POLICY;
	entry->version = FIT_TXT_VERSION;
	entry->checksum = 0;
	fit_entry_add_size(&fit->header, sizeof(struct fit_entry));
}

/*
 * There can be zero or one FIT_TYPE_TXT_POLICY entries
 *
 * The caller has to provide valid arguments as those aren't verfied.
 */
static void update_fit_txt_policy_entry(struct fit_table *fit,
					struct fit_entry *entry,
					uint64_t txt_policy_addr)
{
	entry->address = txt_policy_addr;
	/*
	 * Points to the flag indicating if TXT is enabled on this platform.
	 * If not present, TXT is not disabled by FIT.
	 */
	entry->size_reserved = 0;
	entry->type_checksum_valid = FIT_TYPE_TXT_POLICY;
	entry->version = 0x1;
	entry->checksum = 0;
	fit_entry_add_size(&fit->header, sizeof(struct fit_entry));
}

/*
 * There can be zero or one FIT_TYPE_BOOT_POLICY entries
 *
 * The caller has to provide valid arguments as those aren't verified.
 */
static void update_fit_boot_policy_entry(struct fit_table *fit,
					struct fit_entry *entry,
					uint64_t boot_policy_addr,
					uint32_t boot_policy_size)
{
	entry->address = boot_policy_addr;
	entry->type_checksum_valid = FIT_TYPE_BOOT_POLICY;
	entry->size_reserved = boot_policy_size;
	entry->version = FIT_TXT_VERSION;
	entry->checksum = 0;
	fit_entry_add_size(&fit->header, sizeof(struct fit_entry));
}

/*
 * There can be zero or one FIT_TYPE_KEY_MANIFEST entries
 *
 * The caller has to provide valid arguments as those aren't verified.
 */
static void update_fit_key_manifest_entry(struct fit_table *fit,
					struct fit_entry *entry,
					uint64_t key_manifest_addr,
					uint32_t key_manifest_size)
{
	entry->address = key_manifest_addr;

	entry->type_checksum_valid = FIT_TYPE_KEY_MANIFEST;
	entry->size_reserved = key_manifest_size;
	entry->version = FIT_TXT_VERSION;
	entry->checksum = 0;
	fit_entry_add_size(&fit->header, sizeof(struct fit_entry));
}

/* Special case for ucode CBFS file, as it might contain more than one ucode */
int fit_add_microcode_file(struct fit_table *fit,
			   struct cbfs_image *image,
			   const char *blob_name,
			   fit_offset_converter_t offset_helper,
			   const size_t max_fit_entries)
{
	struct microcode_entry *mcus;

	size_t i;
	size_t mcus_found;

	mcus = malloc(sizeof(*mcus) * max_fit_entries);
	if (!mcus) {
		ERROR("Couldn't allocate memory for microcode entries.\n");
		return 1;
	}

	if (parse_microcode_blob(image, blob_name, &mcus_found, mcus,
				 max_fit_entries)) {
		ERROR("Couldn't parse microcode blob.\n");
		free(mcus);
		return 1;
	}

	if (mcus_found > fit_free_space(fit, max_fit_entries)) {
		ERROR("Maximum of FIT entries reached.\n");
		free(mcus);
		return 1;
	}

	for (i = 0; i < mcus_found; i++) {
		if (fit_add_entry(fit,
				  offset_to_ptr(offset_helper, &image->buffer,
						mcus[i].offset),
				  0,
				  FIT_TYPE_MICROCODE,
				  max_fit_entries)) {

			free(mcus);
			return 1;
		}
	}

	free(mcus);
	return 0;
}

/*
 * Return a pointer to the active FIT.
 */
struct fit_table *fit_get_table(struct buffer *bootblock,
				fit_offset_converter_t offset_fn,
				uint32_t topswap_size)
{
	struct fit_table *fit;
	uint32_t *fit_pointer;

	fit_pointer = rom_buffer_pointer(bootblock,
			ptr_to_offset(offset_fn, bootblock,
			FIT_POINTER_LOCATION));

	/* Ensure pointer is below 4GiB and within 16MiB of 4GiB */
	if (fit_pointer[1] != 0 || fit_pointer[0] < FIT_TABLE_LOWEST_ADDRESS) {
		ERROR("FIT not found.\n");
		return NULL;
	}

	fit = rom_buffer_pointer(bootblock,
			   ptr_to_offset(offset_fn, bootblock, *fit_pointer));
	if (!fit_table_verified(fit)) {
		ERROR("FIT not found.\n");
		return NULL;
	}

	if (topswap_size) {
		struct fit_table *fit2 = (struct fit_table *)((uintptr_t)fit -
							      topswap_size);
		if (!fit_table_verified(fit2)) {
			ERROR("second FIT is invalid\n");
			return NULL;
		}
		fit = fit2;
	}

	DEBUG("Operating on table (0x%x)\n", *fit_pointer - topswap_size);

	return fit;
}

/*
 * Dump the current FIT in human readable format to stdout.
 */
int fit_dump(struct fit_table *fit)
{
	size_t i;

	if (!fit)
		return 1;

	printf("\n");
	printf("    FIT table:\n");

	if (fit_table_entries(fit) < 1) {
		printf("    empty\n\n");
		return 0;
	}

	printf("    %-6s %-20s %-16s %-8s\n", "Index", "Type", "Addr", "Size");

	for (i = 0; i < fit_table_entries(fit); i++) {
		const char *name;

		switch (fit->entries[i].type_checksum_valid) {
		case FIT_TYPE_MICROCODE:
			name = "Microcode";
			break;
		case FIT_TYPE_BIOS_ACM:
			name = "BIOS ACM";
			break;
		case FIT_TYPE_BIOS_STARTUP:
			name = "BIOS Startup Module";
			break;
		case FIT_TYPE_TPM_POLICY:
			name = "TPM Policy";
			break;
		case FIT_TYPE_BIOS_POLICY:
			name = "BIOS Policy";
			break;
		case FIT_TYPE_TXT_POLICY:
			name = "TXT Policy";
			break;
		case FIT_TYPE_KEY_MANIFEST:
			name = "Key Manifest";
			break;
		case FIT_TYPE_BOOT_POLICY:
			name = "Boot Policy";
			break;
		case FIT_TYPE_CSE_SECURE_BOOT:
			name = "CSE SecureBoot";
			break;
		case FIT_TYPE_TXTSX_POLICY:
			name = "TXTSX policy";
			break;
		case FIT_TYPE_JMP_DEBUG_POLICY:
			name = "JMP debug policy";
			break;
		case FIT_TYPE_UNUSED:
			name = "unused";
			break;
		default:
			name = "unknown";
		}

		printf("    %6zd %-20s 0x%08"PRIx64"      0x%08zx\n", i, name,
			fit->entries[i].address,
			fit_entry_size_bytes(&fit->entries[i]));
	}
	printf("\n");
	return 0;
}

/*
 * Remove all entries from table.
 */
int fit_clear_table(struct fit_table *fit)
{
	if (!fit)
		return 1;

	memset(fit->entries, 0,
	       sizeof(struct fit_entry) * fit_table_entries(fit));

	/* Reset entry counter in header */
	fit_entry_update_size(&fit->header, sizeof(fit->header));

	update_fit_checksum(fit);

	return 0;
}

/*
 * Returns true if the FIT type is know and can be added to the table.
 */
int fit_is_supported_type(const enum fit_type type)
{
	switch (type) {
	case FIT_TYPE_MICROCODE:
	case FIT_TYPE_BIOS_ACM:
	case FIT_TYPE_BIOS_STARTUP:
	case FIT_TYPE_BIOS_POLICY:
	case FIT_TYPE_TXT_POLICY:
	case FIT_TYPE_KEY_MANIFEST:
	case FIT_TYPE_BOOT_POLICY:
		return 1;
	case FIT_TYPE_TPM_POLICY:
	default:
		return 0;
	}
}

/*
 * Adds an known entry to the FIT.
 * len is optional for same types and might be zero.
 * offset is an absolute address in 32-bit protected mode address space.
 */
int fit_add_entry(struct fit_table *fit,
		  const uint32_t offset,
		  const uint32_t len,
		  const enum fit_type type,
		  const size_t max_fit_entries)
{
	struct fit_entry *entry;

	if (!fit) {
		ERROR("Internal error.");
		return 1;
	}

	if (fit_free_space(fit, max_fit_entries) < 1) {
		ERROR("No space left in FIT.");
		return 1;
	}

	if (!fit_is_supported_type(type)) {
		ERROR("Unsupported FIT type %u\n", type);
		return 1;
	}

	DEBUG("Adding new entry type %u at offset %zd\n", type,
	      fit_table_entries(fit));

	entry = get_next_free_entry(fit);

	switch (type) {
	case FIT_TYPE_MICROCODE:
		update_fit_ucode_entry(fit, entry, offset);
		break;
	case FIT_TYPE_BIOS_ACM:
		update_fit_bios_acm_entry(fit, entry, offset);
		break;
	case FIT_TYPE_BIOS_STARTUP:
		update_fit_bios_startup_entry(fit, entry, offset, len);
		break;
	case FIT_TYPE_BIOS_POLICY:
		update_fit_bios_policy_entry(fit, entry, offset, len);
		break;
	case FIT_TYPE_TXT_POLICY:
		update_fit_txt_policy_entry(fit, entry, offset);
		break;
	case FIT_TYPE_KEY_MANIFEST:
		update_fit_key_manifest_entry(fit, entry, offset, len);
		break;
	case FIT_TYPE_BOOT_POLICY:
		update_fit_boot_policy_entry(fit, entry, offset, len);
		break;
	default:
		return 1;
	}

	sort_fit_table(fit);

	update_fit_checksum(fit);

	return 0;
}

/*
 * Delete one entry from table.
 */
int fit_delete_entry(struct fit_table *fit,
		     const size_t idx)
{
	if (!fit) {
		ERROR("Internal error.");
		return 1;
	}

	if (idx >= fit_table_entries(fit)) {
		ERROR("Index out of range.");
		return 1;
	}

	memset(&fit->entries[idx], 0, sizeof(struct fit_entry));

	fit->entries[idx].type_checksum_valid = FIT_TYPE_UNUSED;

	sort_fit_table(fit);

	/* The unused entry is now the last one */
	fit_entry_add_size(&fit->header, -(int)sizeof(struct fit_entry));

	update_fit_checksum(fit);

	return 0;
}
