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

#include <mboot.h>
#include <assert.h>
#include <build.h>
#include <vb2_api.h>
#include <board_mboot.h>

/*
 * Get the list of currently active PCR banks in TPM.
 *
 * @retval A map of active PCR banks.
 */
EFI_TCG2_EVENT_ALGORITHM_BITMAP tpm2_get_active_pcrs(void)
{
	int status;
	TPML_PCR_SELECTION Pcrs;
	EFI_TCG2_EVENT_ALGORITHM_BITMAP tpmHashAlgorithmBitmap = 0;
	uint32_t activePcrBanks = 0;
	uint32_t index;

	status = tpm2_get_capability_pcrs(&Pcrs);
	if (status != TPM_SUCCESS) {
		tpmHashAlgorithmBitmap = EFI_TCG2_BOOT_HASH_ALG_SHA1;
		activePcrBanks = EFI_TCG2_BOOT_HASH_ALG_SHA1;
	} else {
		for (index = 0; index < Pcrs.count; index++) {
			switch (Pcrs.pcrSelections[index].hash) {
			case TPM_ALG_SHA1:
				tpmHashAlgorithmBitmap |=
					EFI_TCG2_BOOT_HASH_ALG_SHA1;
				if (!is_zero_buffer(Pcrs.pcrSelections[index].pcrSelect,
				  Pcrs.pcrSelections[index].sizeofSelect))
					activePcrBanks |=
						 EFI_TCG2_BOOT_HASH_ALG_SHA1;
				break;
			case TPM_ALG_SHA256:
				tpmHashAlgorithmBitmap |=
					EFI_TCG2_BOOT_HASH_ALG_SHA256;
				if (!is_zero_buffer(Pcrs.pcrSelections[index].pcrSelect,
				  Pcrs.pcrSelections[index].sizeofSelect))
					activePcrBanks |=
						EFI_TCG2_BOOT_HASH_ALG_SHA256;
				break;
			case TPM_ALG_SHA384:
			case TPM_ALG_SHA512:
			case TPM_ALG_SM3_256:
			default:
				printk(BIOS_DEBUG, "%s: unsupported algorithm "
					"reported - 0x%x\n", __func__,
					Pcrs.pcrSelections[index].hash);
				break;
			}
		}
	}
	printk(BIOS_DEBUG, "Tcg2 Capability values from TPM\n");
	printk(BIOS_DEBUG, "tpmHashAlgorithmBitmap - 0x%08x\n",
		tpmHashAlgorithmBitmap);
	printk(BIOS_DEBUG, "activePcrBanks         - 0x%08x\n",
		activePcrBanks);

	return activePcrBanks;
}

/*
 * tpm2_get_capability_pcrs
 *
 * Return the TPM PCR information.
 *
 * This function parses the data got from tlcl_get_capability and returns the
 * PcrSelection.
 *
 * @param[out] Pcrs		The Pcr Selection
 *
 * @retval TPM_SUCCESS		Operation completed successfully.
 * @retval TPM_E_IOERROR	The command was unsuccessful.
 */
int tpm2_get_capability_pcrs(TPML_PCR_SELECTION *Pcrs)
{
	TPMS_CAPABILITY_DATA TpmCap;
	int status;
	int index;

	status = tlcl_get_capability(TPM_CAP_PCRS, 0, 1, &TpmCap);
	if (status == TPM_SUCCESS) {
		Pcrs->count = TpmCap.data.assignedPCR.count;
		printk(BIOS_DEBUG, "Pcrs->count = %d\n", Pcrs->count);
		for (index = 0; index < Pcrs->count; index++) {
			Pcrs->pcrSelections[index].hash =
				swab16(TpmCap.data.assignedPCR.pcrSelections[index].hash);
			printk(BIOS_DEBUG, "Pcrs->pcrSelections[%d].hash = 0x%x\n", index,
			       Pcrs->pcrSelections[index].hash);
			Pcrs->pcrSelections[index].sizeofSelect =
				TpmCap.data.assignedPCR.pcrSelections[index].sizeofSelect;
			memcpy(Pcrs->pcrSelections[index].pcrSelect,
				TpmCap.data.assignedPCR.pcrSelections[index].pcrSelect,
				Pcrs->pcrSelections[index].sizeofSelect);
		}
	}
	return status;
}

/*
 * mboot_hash_extend_log
 *
 * Calculates the hash over the data and extends it in active PCR banks and
 * then logs them in the event log.
 *
 * @param[in] flags		flags associated with hash data.
 * @param[in] hashData		data to be hashed.
 * @param[in] hashDataLen	length of the data to be hashed.
 * @param[in] newEventHdr	event header in TCG_PCR_EVENT2 format.
 * @param[in] eventLog		description of the event.
 *
 * @retval TPM_SUCCESS		Operation completed successfully.
 * @retval TPM_E_IOERROR	Unexpected device behavior.
 */
int mboot_hash_extend_log(uint64_t flags, uint8_t *hashData, uint32_t hashDataLen,
	TCG_PCR_EVENT2_HDR *newEventHdr, uint8_t *eventLog)
{
	TPMT_HA *digest = NULL;

	printk(BIOS_DEBUG, "%s: Hash Data Length: %zu bytes\n", __func__, (size_t)hashDataLen);

	/* Generate SHA256 */
	digest = &(newEventHdr->digest.digests[0]);
	if (flags & MBOOT_HASH_PROVIDED) {
		/* The hash is provided as data */
		memcpy(digest->digest.sha256, (void *)hashData, hashDataLen);
	} else {
		struct vb2_hash tmp;
		if (vb2_hash_calculate(false, hashData, hashDataLen, VB2_HASH_SHA256, &tmp))
			return TPM_E_IOERROR;
		memcpy(digest->digest.sha256, tmp.sha256, sizeof(tmp.sha256));
	}

	printk(BIOS_DEBUG, "%s: SHA256 Hash Digest:\n", __func__);
	mboot_print_buffer(digest->digest.sha256, VB2_SHA256_DIGEST_SIZE);

	return (tlcl_extend(newEventHdr->pcrIndex, (uint8_t *)&(newEventHdr->digest), NULL));
}

/*
 * invalidate_pcrs
 *
 * Invalidate PCRs 0-7 with extending 1 after tpm failure.
 */
void invalidate_pcrs(void)
{
	int pcr;
	int status;

	TCG_PCR_EVENT2_HDR tcgEventHdr;
	uint8_t invalidate = 1;

	for (pcr = 0; pcr < 8; pcr++) {
		printk(BIOS_DEBUG, "%s: Invalidating PCR %d\n", __func__, pcr);
		memset(&tcgEventHdr, 0, sizeof(tcgEventHdr));
		tcgEventHdr.pcrIndex  = pcr;
		tcgEventHdr.eventType = EV_NO_ACTION;
		tcgEventHdr.eventSize = (uint32_t) sizeof(invalidate);

		status = mboot_hash_extend_log(0, (uint8_t *)&invalidate,
					       tcgEventHdr.eventSize, &tcgEventHdr,
					       (uint8_t *)"Invalidate PCR");
		if (status != TPM_SUCCESS)
			printk(BIOS_DEBUG, "%s: invalidating pcr %d returned"
				" 0x%x\n", __func__, pcr, status);
	}
}

/*
 * is_zero_buffer
 *
 * Check if buffer is all zero.
 *
 * @param[in] buffer   Buffer to be checked.
 * @param[in] size     Size of buffer to be checked.
 *
 * @retval TRUE  buffer is all zero.
 * @retval FALSE buffer is not all zero.
 */
int is_zero_buffer(void *buffer, unsigned int size)
{
	uint8_t *ptr;

	ptr = buffer;
	while (size--) {
		if (*(ptr++) != 0)
			return false;
	}
	return true;
}

/*
 * Prints command or response buffer for debugging purposes.
 *
 * @param[in] Buffer     Buffer to print.
 * @param[in] BufferSize Buffer data length.
 *
 * @retval  None
 */
void mboot_print_buffer(uint8_t *buffer, uint32_t bufferSize)
{
	uint32_t index;

	printk(BIOS_DEBUG, "Buffer Address: 0x%08x, Size: 0x%08x, Value:\n",
		(unsigned int)*buffer, bufferSize);
	for (index = 0; index < bufferSize; index++) {
		printk(BIOS_DEBUG, "%02x ", *(buffer + index));
		if ((index+1) % 16 == 0)
			printk(BIOS_DEBUG, "\n");
	}
	printk(BIOS_DEBUG, "\n");
}

/*
 * measures and logs the specified cbfs file.
 *
 * @param[in] name		name of the cbfs file to measure
 * @param[in] type		data type of the cbfs file.
 * @param[in] pcr		pcr to extend.
 * @param[in] evenType		tcg event type.
 * @param[in] event_msg		description of the event.
 *
 * @retval TPM_SUCCESS		Operation completed successfully.
 * @retval TPM_E_IOERROR	Unexpected device behavior.
 */
int mb_measure_log_worker(const char *name, uint32_t type, uint32_t pcr,
			  TCG_EVENTTYPE eventType, const char *event_msg)
{
	int status;
	TCG_PCR_EVENT2_HDR tcgEventHdr;
	uint8_t *base;
	size_t size;

	printk(BIOS_DEBUG, "%s: Measure %s\n", __func__, name);
	base = cbfs_map(name, &size);

	if (base == NULL) {
		printk(BIOS_DEBUG, "%s: CBFS locate fail: %s\n", __func__, name);
		return VB2_ERROR_READ_FILE_OPEN;
	}

	printk(BIOS_DEBUG, "%s: CBFS locate success: %s\n", __func__, name);
	memset(&tcgEventHdr, 0, sizeof(tcgEventHdr));
	tcgEventHdr.pcrIndex  = pcr;
	tcgEventHdr.eventType = eventType;
	if (event_msg)
		tcgEventHdr.eventSize = (uint32_t) strlen(event_msg);

	status = mboot_hash_extend_log(0, base, size, &tcgEventHdr, (uint8_t *)event_msg);
	return status;
}

/*
 * Called from early romstage
 *
 *mb_entry
 *
 * initializes measured boot mechanism, initializes the tpm library and starts the tpm called
 * by mb_measure
 *
 * The function can be overridden at the mainboard level my simply creating a function with the
 * same name there.
 *
 * @param[in] wake_from_s3	1 if we are waking from S3, 0 standard boot
 *
 * @retval TPM_SUCCESS		Operation completed successfully.
 * @retval TPM_E_IOERROR	Unexpected device behavior.
**/

int __attribute__((weak)) mb_entry(int wake_from_s3)
{
	int status;

	/* Initialize TPM driver. */
	printk(BIOS_DEBUG, "%s: tlcl_lib_init\n", __func__);
	if (tlcl_lib_init() != VB2_SUCCESS) {
		printk(BIOS_ERR, "%s: TPM driver initialization failed.\n", __func__);
		return TPM_E_IOERROR;
	}

	if (wake_from_s3) {
		printk(BIOS_DEBUG, "%s: tlcl_resume\n", __func__);
		status = tlcl_resume();
	} else {
		printk(BIOS_DEBUG, "%s: tlcl_startup\n", __func__);
		status = tlcl_startup();
	}

	if (status)
		printk(BIOS_ERR, "%s: StartUp failed 0x%x!\n", __func__, status);

	return status;
}

/*
 *
 * mb_measure
 *
 * initial call to the measured boot mechanism, initializes the
 * tpm library, starts the tpm and performs the measurements defined by
 * the coreboot platform.
 *
 * The pcrs will be invalidated if the measurement fails
 *
 * The function can be overridden at the mainboard level my simply creating a
 * function with the same name there.
 *
 * @param[in] wake_from_s3	1 if we are waking from S3, 0 standard boot
 *
 * @retval TPM_SUCCESS		Operation completed successfully.
 * @retval TPM_E_IOERROR	Unexpected device behavior.
 */

int __attribute__((weak))mb_measure(int wake_from_s3)
{
	uint32_t status;

	status = mb_entry(wake_from_s3);
	if (status == TPM_SUCCESS) {
		printk(BIOS_DEBUG, "%s: StartUp, successful!\n", __func__);
		status = mb_measure_log_start();
		if (status == TPM_SUCCESS) {
			printk(BIOS_DEBUG, "%s: Measuring, successful!\n", __func__);
		} else {
			invalidate_pcrs();
			printk(BIOS_ERR, "%s: Measuring returned 0x%x unsuccessful! PCRs invalidated.\n",
			       __func__, status);
		}
	} else {
		invalidate_pcrs();
		printk(BIOS_ERR, "%s: StartUp returned 0x%x, unsuccessful! PCRs invalidated.\n", __func__,
		       status);
	}
	return status;
}

/*
 *
 * mb_measure_log_start
 *
 * performs the measurements defined by the the board routines.
 *
 * The logging is defined by the mb_log_list structure
 *
 * These items need to be defined in the mainboard part of the mboot
 * implementation
 *
 * The function can be overridden at the mainboard level my simply creating a
 * function with the same name there.
 *
 * @param[in]  none
 *
 * @retval TPM_SUCCESS		Operation completed successfully.
 * @retval TPM_E_IOERROR	Unexpected device behavior.
 */
int __attribute__((weak))mb_measure_log_start(void)
{
	int status;
	uint32_t i;

	if ((tpm2_get_active_pcrs() & EFI_TCG2_BOOT_HASH_ALG_SHA256) == 0x0) {
		printk(BIOS_DEBUG, "%s: SHA256 PCR Bank not active in TPM.\n",
			__func__);
		return TPM_E_IOERROR;
	}

	status = mb_crtm();
	if (status != TPM_SUCCESS) {
		printk(BIOS_DEBUG, "%s: Fail! CRTM Version can't be measured."
			" ABORTING!!!\n", __func__);
		return status;
	}
	printk(BIOS_DEBUG, "%s: Success! CRTM Version measured.\n", __func__);

	/* Log the items defined by the mainboard */
	for (i = 0; i < ARRAY_SIZE(mb_log_list); i++) {
		status = mb_measure_log_worker(
				mb_log_list[i].cbfs_name,
				mb_log_list[i].cbfs_type, mb_log_list[i].pcr,
				mb_log_list[i].eventType,
				mb_log_list[i].event_msg);
		if (status != TPM_SUCCESS) {
			printk(BIOS_DEBUG, "%s: Fail! %s can't be measured."
				"ABORTING!!!\n", __func__,
				mb_log_list[i].cbfs_name);
			return status;
		}
		printk(BIOS_DEBUG, "%s: Success! %s measured to pcr"
			"%d.\n", __func__, mb_log_list[i].cbfs_name,
			mb_log_list[i].pcr);
	}
	return status;
}

static const uint8_t crtm_version[] =
	CONFIG_VENDORCODE_ELTAN_CRTM_VERSION_STRING\
	COREBOOT_VERSION COREBOOT_EXTRA_VERSION " " COREBOOT_BUILD;

/*
 *
 * mb_crtm
 *
 * measures the crtm version. this consists of a string than can be
 * defined using make menuconfig and automatically generated version
 * information.
 *
 * The function can be overridden at the mainboard level my simply creating a
 * function with the same name there.
 *
 * @retval TPM_SUCCESS		Operation completed successfully.
 * @retval TPM_E_IOERROR	Unexpected device behavior.
**/
int __attribute__((weak))mb_crtm(void)
{
	int status;
	TCG_PCR_EVENT2_HDR tcgEventHdr;
	uint8_t hash[VB2_SHA256_DIGEST_SIZE];
	uint8_t *msgPtr;

	/* Use FirmwareVersion string to represent CRTM version. */
	printk(BIOS_DEBUG, "%s: Measure CRTM Version\n", __func__);
	memset(&tcgEventHdr, 0, sizeof(tcgEventHdr));
	tcgEventHdr.pcrIndex = MBOOT_PCR_INDEX_0;
	tcgEventHdr.eventType = EV_S_CRTM_VERSION;
	tcgEventHdr.eventSize = sizeof(crtm_version);
	printk(BIOS_DEBUG, "%s: EventSize - %u\n", __func__,
		tcgEventHdr.eventSize);

	status = mboot_hash_extend_log(0, (uint8_t *)crtm_version, tcgEventHdr.eventSize,
				       &tcgEventHdr, (uint8_t *)crtm_version);
	if (status) {
		printk(BIOS_DEBUG, "Measure CRTM Version returned 0x%x\n", status);
		return status;
	}

	status = get_intel_me_hash(hash);
	if (status) {
		printk(BIOS_DEBUG, "get_intel_me_hash returned 0x%x\n", status);
		status = TPM_E_IOERROR;
		return status;
	}

	/* Add the me hash */
	printk(BIOS_DEBUG, "%s: Add the hash returned by the ME\n",
		__func__);
	memset(&tcgEventHdr, 0, sizeof(tcgEventHdr));
	tcgEventHdr.pcrIndex  = MBOOT_PCR_INDEX_0;
	tcgEventHdr.eventType = EV_S_CRTM_CONTENTS;

	msgPtr = NULL;
	tcgEventHdr.eventSize = 0;
	status = mboot_hash_extend_log(MBOOT_HASH_PROVIDED, hash, sizeof(hash), &tcgEventHdr,
				       msgPtr);
	if (status)
		printk(BIOS_DEBUG, "Add ME hash returned 0x%x\n", status);

	return status;
}
