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

static uint32_t *get_fit_ptr(struct buffer *bootblock, fit_offset_converter_t offset_fn,
		      uint32_t topswap_size)
{
	return rom_buffer_pointer(bootblock,
				  ptr_to_offset(offset_fn, bootblock,
						FIT_POINTER_LOCATION - topswap_size));
}

/* Set the FIT pointer to a FIT table. */
int set_fit_pointer(struct buffer *bootblock,
		    const uint32_t fit_address,
		    fit_offset_converter_t offset_fn,
		    uint32_t topswap_size)
{
	struct fit_table *fit;
	uint32_t *fit_pointer = get_fit_ptr(bootblock, offset_fn, topswap_size);

	fit = rom_buffer_pointer(bootblock, ptr_to_offset(offset_fn, bootblock, fit_address));

	if (fit_address < FIT_TABLE_LOWEST_ADDRESS) {
		ERROR("FIT must be reside in the top 16MiB.\n");
		return 1;
	}

	if (!fit_table_verified(fit)) {
		ERROR("FIT not found at address.\n");
		return 1;
	}

	fit_pointer[0] = fit_address;
	fit_pointer[1] = 0;
	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 = get_fit_ptr(bootblock, offset_fn, topswap_size);

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

	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;
}
