// SPDX-License-Identifier: GPL-2.0+
/*
 * Defines APIs that allow an OS to interact with UEFI firmware to query
 * information about the device.
 * https://trustedcomputinggroup.org/resource/tcg-efi-protocol-specification/
 *
 * Copyright (c) 2020, Linaro Limited
 */

#define LOG_CATEGORY LOGC_EFI
#include <common.h>
#include <dm.h>
#include <efi_loader.h>
#include <efi_tcg2.h>
#include <log.h>
#include <malloc.h>
#include <version.h>
#include <tpm-v2.h>
#include <u-boot/hash-checksum.h>
#include <u-boot/sha1.h>
#include <u-boot/sha256.h>
#include <u-boot/sha512.h>
#include <linux/unaligned/access_ok.h>
#include <linux/unaligned/generic.h>
#include <hexdump.h>

struct event_log_buffer {
	void *buffer;
	void *final_buffer;
	size_t pos; /* eventlog position */
	size_t final_pos; /* final events config table position */
	size_t last_event_size;
	bool get_event_called;
	bool truncated;
};

static struct event_log_buffer event_log;
static bool tcg2_efi_app_invoked;
/*
 * When requesting TPM2_CAP_TPM_PROPERTIES the value is on a standard offset.
 * Since the current tpm2_get_capability() response buffers starts at
 * 'union tpmu_capabilities data' of 'struct tpms_capability_data', calculate
 * the response size and offset once for all consumers
 */
#define TPM2_RESPONSE_BUFFER_SIZE (sizeof(struct tpms_capability_data) - \
				   offsetof(struct tpms_capability_data, data))
#define properties_offset (offsetof(struct tpml_tagged_tpm_property, tpm_property) + \
			   offsetof(struct tpms_tagged_property, value))

static const efi_guid_t efi_guid_tcg2_protocol = EFI_TCG2_PROTOCOL_GUID;
static const efi_guid_t efi_guid_final_events = EFI_TCG2_FINAL_EVENTS_TABLE_GUID;

struct digest_info {
	u16 hash_alg;
	u32 hash_mask;
	u16 hash_len;
};

static const struct digest_info hash_algo_list[] = {
	{
		TPM2_ALG_SHA1,
		EFI_TCG2_BOOT_HASH_ALG_SHA1,
		TPM2_SHA1_DIGEST_SIZE,
	},
	{
		TPM2_ALG_SHA256,
		EFI_TCG2_BOOT_HASH_ALG_SHA256,
		TPM2_SHA256_DIGEST_SIZE,
	},
	{
		TPM2_ALG_SHA384,
		EFI_TCG2_BOOT_HASH_ALG_SHA384,
		TPM2_SHA384_DIGEST_SIZE,
	},
	{
		TPM2_ALG_SHA512,
		EFI_TCG2_BOOT_HASH_ALG_SHA512,
		TPM2_SHA512_DIGEST_SIZE,
	},
};

struct variable_info {
	u16		*name;
	const efi_guid_t	*guid;
};

static struct variable_info secure_variables[] = {
	{L"SecureBoot", &efi_global_variable_guid},
	{L"PK", &efi_global_variable_guid},
	{L"KEK", &efi_global_variable_guid},
	{L"db", &efi_guid_image_security_database},
	{L"dbx", &efi_guid_image_security_database},
};

#define MAX_HASH_COUNT ARRAY_SIZE(hash_algo_list)

/**
 * alg_to_mask - Get a TCG hash mask for algorithms
 *
 * @hash_alg: TCG defined algorithm
 *
 * @Return: TCG hashing algorithm bitmaps, 0 if the algorithm is not supported
 */
static u32 alg_to_mask(u16 hash_alg)
{
	size_t i;

	for (i = 0; i < MAX_HASH_COUNT; i++) {
		if (hash_algo_list[i].hash_alg == hash_alg)
			return hash_algo_list[i].hash_mask;
	}

	return 0;
}

/**
 * alg_to_len - Get a TCG hash len for algorithms
 *
 * @hash_alg: TCG defined algorithm
 *
 * @Return: len of chosen algorithm, 0 if the algorithm is not supported
 */
static u16 alg_to_len(u16 hash_alg)
{
	size_t i;

	for (i = 0; i < MAX_HASH_COUNT; i++) {
		if (hash_algo_list[i].hash_alg == hash_alg)
			return hash_algo_list[i].hash_len;
	}

	return 0;
}

static u32 tcg_event_final_size(struct tpml_digest_values *digest_list)
{
	u32 len;
	size_t i;

	len = offsetof(struct tcg_pcr_event2, digests);
	len += offsetof(struct tpml_digest_values, digests);
	for (i = 0; i < digest_list->count; i++) {
		u16 hash_alg = digest_list->digests[i].hash_alg;

		len += offsetof(struct tpmt_ha, digest);
		len += alg_to_len(hash_alg);
	}
	len += sizeof(u32); /* tcg_pcr_event2 event_size*/

	return len;
}

/* tcg2_pcr_extend - Extend PCRs for a TPM2 device for a given tpml_digest_values
 *
 * @dev:		device
 * @digest_list:	list of digest algorithms to extend
 *
 * @Return: status code
 */
static efi_status_t tcg2_pcr_extend(struct udevice *dev, u32 pcr_index,
				    struct tpml_digest_values *digest_list)
{
	u32 rc;
	size_t i;

	for (i = 0; i < digest_list->count; i++) {
		u32 alg = digest_list->digests[i].hash_alg;

		rc = tpm2_pcr_extend(dev, pcr_index, alg,
				     (u8 *)&digest_list->digests[i].digest,
				     alg_to_len(alg));
		if (rc) {
			EFI_PRINT("Failed to extend PCR\n");
			return EFI_DEVICE_ERROR;
		}
	}

	return EFI_SUCCESS;
}

/* tcg2_agile_log_append - Append an agile event to out eventlog
 *
 * @pcr_index:		PCR index
 * @event_type:		type of event added
 * @digest_list:	list of digest algorithms to add
 * @size:		size of event
 * @event:		event to add
 *
 * @Return: status code
 */
static efi_status_t tcg2_agile_log_append(u32 pcr_index, u32 event_type,
					  struct tpml_digest_values *digest_list,
					  u32 size, u8 event[])
{
	void *log = (void *)((uintptr_t)event_log.buffer + event_log.pos);
	size_t pos;
	size_t i;
	u32 event_size;

	if (event_log.get_event_called)
		log = (void *)((uintptr_t)event_log.final_buffer +
			       event_log.final_pos);

	/*
	 * size refers to the length of event[] only, we need to check against
	 * the final tcg_pcr_event2 size
	 */
	event_size = size + tcg_event_final_size(digest_list);
	if (event_log.pos + event_size > TPM2_EVENT_LOG_SIZE ||
	    event_log.final_pos + event_size > TPM2_EVENT_LOG_SIZE) {
		event_log.truncated = true;
		return EFI_VOLUME_FULL;
	}

	put_unaligned_le32(pcr_index, log);
	pos = offsetof(struct tcg_pcr_event2, event_type);
	put_unaligned_le32(event_type, (void *)((uintptr_t)log + pos));
	pos = offsetof(struct tcg_pcr_event2, digests); /* count */
	put_unaligned_le32(digest_list->count, (void *)((uintptr_t)log + pos));

	pos += offsetof(struct tpml_digest_values, digests);
	for (i = 0; i < digest_list->count; i++) {
		u16 hash_alg = digest_list->digests[i].hash_alg;
		u8 *digest = (u8 *)&digest_list->digests[i].digest;

		put_unaligned_le16(hash_alg, (void *)((uintptr_t)log + pos));
		pos += offsetof(struct tpmt_ha, digest);
		memcpy((void *)((uintptr_t)log + pos), digest, alg_to_len(hash_alg));
		pos += alg_to_len(hash_alg);
	}

	put_unaligned_le32(size, (void *)((uintptr_t)log + pos));
	pos += sizeof(u32); /* tcg_pcr_event2 event_size*/
	memcpy((void *)((uintptr_t)log + pos), event, size);
	pos += size;

	/* make sure the calculated buffer is what we checked against */
	if (pos != event_size)
		return EFI_INVALID_PARAMETER;

	/* if GetEventLog hasn't been called update the normal log */
	if (!event_log.get_event_called) {
		event_log.pos += pos;
		event_log.last_event_size = pos;
	} else {
	/* if GetEventLog has been called update config table log */
		struct efi_tcg2_final_events_table *final_event;

		final_event =
			(struct efi_tcg2_final_events_table *)(event_log.final_buffer);
		final_event->number_of_events++;
		event_log.final_pos += pos;
	}

	return EFI_SUCCESS;
}

/**
 * platform_get_tpm_device() - retrieve TPM device
 *
 * This function retrieves the udevice implementing a TPM
 *
 * This function may be overridden if special initialization is needed.
 *
 * @dev:	udevice
 * Return:	status code
 */
__weak efi_status_t platform_get_tpm2_device(struct udevice **dev)
{
	for_each_tpm_device(*dev) {
		/* Only support TPMv2 devices */
		if (tpm_get_version(*dev) == TPM_V2)
			return EFI_SUCCESS;
	}

	return EFI_NOT_FOUND;
}

/**
 * tpm2_get_max_command_size() - get the supported max command size
 *
 * @dev:		TPM device
 * @max_command_size:	output buffer for the size
 *
 * Return: 0 on success, -1 on error
 */
static int tpm2_get_max_command_size(struct udevice *dev, u16 *max_command_size)
{
	u8 response[TPM2_RESPONSE_BUFFER_SIZE];
	u32 ret;

	memset(response, 0, sizeof(response));
	ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES,
				  TPM2_PT_MAX_COMMAND_SIZE, response, 1);
	if (ret)
		return -1;

	*max_command_size = (uint16_t)get_unaligned_be32(response +
							 properties_offset);

	return 0;
}

/**
 * tpm2_get_max_response_size() - get the supported max response size
 *
 * @dev:		TPM device
 * @max_response_size:	output buffer for the size
 *
 * Return: 0 on success, -1 on error
 */
static int tpm2_get_max_response_size(struct udevice *dev,
				      u16 *max_response_size)
{
	u8 response[TPM2_RESPONSE_BUFFER_SIZE];
	u32 ret;

	memset(response, 0, sizeof(response));
	ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES,
				  TPM2_PT_MAX_RESPONSE_SIZE, response, 1);
	if (ret)
		return -1;

	*max_response_size = (uint16_t)get_unaligned_be32(response +
							  properties_offset);

	return 0;
}

/**
 * tpm2_get_manufacturer_id() - get the manufacturer ID
 *
 * @dev:		TPM device
 * @manufacturer_id:	output buffer for the id
 *
 * Return: 0 on success, -1 on error
 */
static int tpm2_get_manufacturer_id(struct udevice *dev, u32 *manufacturer_id)
{
	u8 response[TPM2_RESPONSE_BUFFER_SIZE];
	u32 ret;

	memset(response, 0, sizeof(response));
	ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES,
				  TPM2_PT_MANUFACTURER, response, 1);
	if (ret)
		return -1;

	*manufacturer_id = get_unaligned_be32(response + properties_offset);

	return 0;
}

/**
 * tpm2_get_num_pcr() - get the number of PCRs
 *
 * @dev:		TPM device
 * @manufacturer_id:	output buffer for the number
 *
 * Return: 0 on success, -1 on error
 */
static int tpm2_get_num_pcr(struct udevice *dev, u32 *num_pcr)
{
	u8 response[TPM2_RESPONSE_BUFFER_SIZE];
	u32 ret;

	memset(response, 0, sizeof(response));
	ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES,
				  TPM2_PT_PCR_COUNT, response, 1);
	if (ret)
		return -1;

	*num_pcr = get_unaligned_be32(response + properties_offset);
	if (*num_pcr > TPM2_MAX_PCRS)
		return -1;

	return 0;
}

/**
 * is_active_pcr() - Check if a supported algorithm is active
 *
 * @dev:		TPM device
 * @selection:		struct of PCR information
 *
 * Return: true if PCR is active
 */
static bool is_active_pcr(struct tpms_pcr_selection *selection)
{
	int i;
	/*
	 * check the pcr_select. If at least one of the PCRs supports the
	 * algorithm add it on the active ones
	 */
	for (i = 0; i < selection->size_of_select; i++) {
		if (selection->pcr_select[i])
			return true;
	}

	return false;
}

/**
 * tpm2_get_pcr_info() - get the supported, active PCRs and number of banks
 *
 * @dev:		TPM device
 * @supported_pcr:	bitmask with the algorithms supported
 * @active_pcr:		bitmask with the active algorithms
 * @pcr_banks:		number of PCR banks
 *
 * Return: 0 on success, -1 on error
 */
static int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr,
			     u32 *active_pcr, u32 *pcr_banks)
{
	u8 response[TPM2_RESPONSE_BUFFER_SIZE];
	struct tpml_pcr_selection pcrs;
	u32 ret, num_pcr;
	size_t i;
	int tpm_ret;

	*supported_pcr = 0;
	*active_pcr = 0;
	*pcr_banks = 0;
	memset(response, 0, sizeof(response));
	ret = tpm2_get_capability(dev, TPM2_CAP_PCRS, 0, response, 1);
	if (ret)
		goto out;

	pcrs.count = get_unaligned_be32(response);
	/*
	 * We only support 5 algorithms for now so check against that
	 * instead of TPM2_NUM_PCR_BANKS
	 */
	if (pcrs.count > MAX_HASH_COUNT || pcrs.count < 1)
		goto out;

	tpm_ret = tpm2_get_num_pcr(dev, &num_pcr);
	if (tpm_ret)
		goto out;

	for (i = 0; i < pcrs.count; i++) {
		/*
		 * Definition of TPMS_PCR_SELECTION Structure
		 * hash: u16
		 * size_of_select: u8
		 * pcr_select: u8 array
		 *
		 * The offsets depend on the number of the device PCRs
		 * so we have to calculate them based on that
		 */
		u32 hash_offset = offsetof(struct tpml_pcr_selection, selection) +
			i * offsetof(struct tpms_pcr_selection, pcr_select) +
			i * ((num_pcr + 7) / 8);
		u32 size_select_offset =
			hash_offset + offsetof(struct tpms_pcr_selection,
					       size_of_select);
		u32 pcr_select_offset =
			hash_offset + offsetof(struct tpms_pcr_selection,
					       pcr_select);

		pcrs.selection[i].hash =
			get_unaligned_be16(response + hash_offset);
		pcrs.selection[i].size_of_select =
			__get_unaligned_be(response + size_select_offset);
		if (pcrs.selection[i].size_of_select > TPM2_PCR_SELECT_MAX)
			goto out;
		/* copy the array of pcr_select */
		memcpy(pcrs.selection[i].pcr_select, response + pcr_select_offset,
		       pcrs.selection[i].size_of_select);
	}

	for (i = 0; i < pcrs.count; i++) {
		u32 hash_mask = alg_to_mask(pcrs.selection[i].hash);

		if (hash_mask) {
			*supported_pcr |= hash_mask;
			if (is_active_pcr(&pcrs.selection[i]))
				*active_pcr |= hash_mask;
		} else {
			EFI_PRINT("Unknown algorithm %x\n", pcrs.selection[i].hash);
		}
	}

	*pcr_banks = pcrs.count;

	return 0;
out:
	return -1;
}

/**
 * __get_active_pcr_banks() - returns the currently active PCR banks
 *
 * @active_pcr_banks:		pointer for receiving the bitmap of currently
 *				active PCR banks
 *
 * Return:	status code
 */
static efi_status_t __get_active_pcr_banks(u32 *active_pcr_banks)
{
	struct udevice *dev;
	u32 active = 0, supported = 0, pcr_banks = 0;
	efi_status_t ret;
	int err;

	ret = platform_get_tpm2_device(&dev);
	if (ret != EFI_SUCCESS)
		goto out;

	err = tpm2_get_pcr_info(dev, &supported, &active, &pcr_banks);
	if (err) {
		ret = EFI_DEVICE_ERROR;
		goto out;
	}

	*active_pcr_banks = active;

out:
	return ret;
}

/* tcg2_create_digest - create a list of digests of the supported PCR banks
 *			for a given memory range
 *
 * @input:		input memory
 * @length:		length of buffer to calculate the digest
 * @digest_list:	list of digests to fill in
 *
 * Return:		status code
 */
static efi_status_t tcg2_create_digest(const u8 *input, u32 length,
				       struct tpml_digest_values *digest_list)
{
	sha1_context ctx;
	sha256_context ctx_256;
	sha512_context ctx_512;
	u8 final[TPM2_SHA512_DIGEST_SIZE];
	efi_status_t ret;
	u32 active;
	size_t i;

	ret = __get_active_pcr_banks(&active);
	if (ret != EFI_SUCCESS)
		return ret;

	digest_list->count = 0;
	for (i = 0; i < MAX_HASH_COUNT; i++) {
		u16 hash_alg = hash_algo_list[i].hash_alg;

		if (!(active & alg_to_mask(hash_alg)))
			continue;
		switch (hash_alg) {
		case TPM2_ALG_SHA1:
			sha1_starts(&ctx);
			sha1_update(&ctx, input, length);
			sha1_finish(&ctx, final);
			break;
		case TPM2_ALG_SHA256:
			sha256_starts(&ctx_256);
			sha256_update(&ctx_256, input, length);
			sha256_finish(&ctx_256, final);
			break;
		case TPM2_ALG_SHA384:
			sha384_starts(&ctx_512);
			sha384_update(&ctx_512, input, length);
			sha384_finish(&ctx_512, final);
			break;
		case TPM2_ALG_SHA512:
			sha512_starts(&ctx_512);
			sha512_update(&ctx_512, input, length);
			sha512_finish(&ctx_512, final);
			break;
		default:
			EFI_PRINT("Unsupported algorithm %x\n", hash_alg);
			return EFI_INVALID_PARAMETER;
		}
		digest_list->digests[digest_list->count].hash_alg = hash_alg;
		memcpy(&digest_list->digests[digest_list->count].digest, final,
		       (u32)alg_to_len(hash_alg));
		digest_list->count++;
	}

	return EFI_SUCCESS;
}

/**
 * efi_tcg2_get_capability() - protocol capability information and state information
 *
 * @this:		TCG2 protocol instance
 * @capability:		caller allocated memory with size field to the size of
 *			the structure allocated

 * Return:	status code
 */
static efi_status_t EFIAPI
efi_tcg2_get_capability(struct efi_tcg2_protocol *this,
			struct efi_tcg2_boot_service_capability *capability)
{
	struct udevice *dev;
	efi_status_t efi_ret;
	int ret;

	EFI_ENTRY("%p, %p", this, capability);

	if (!this || !capability) {
		efi_ret = EFI_INVALID_PARAMETER;
		goto out;
	}

	if (capability->size < BOOT_SERVICE_CAPABILITY_MIN) {
		capability->size = BOOT_SERVICE_CAPABILITY_MIN;
		efi_ret = EFI_BUFFER_TOO_SMALL;
		goto out;
	}

	if (capability->size < sizeof(*capability)) {
		capability->size = sizeof(*capability);
		efi_ret = EFI_BUFFER_TOO_SMALL;
		goto out;
	}

	capability->structure_version.major = 1;
	capability->structure_version.minor = 1;
	capability->protocol_version.major = 1;
	capability->protocol_version.minor = 1;

	efi_ret = platform_get_tpm2_device(&dev);
	if (efi_ret != EFI_SUCCESS) {
		capability->supported_event_logs = 0;
		capability->hash_algorithm_bitmap = 0;
		capability->tpm_present_flag = false;
		capability->max_command_size = 0;
		capability->max_response_size = 0;
		capability->manufacturer_id = 0;
		capability->number_of_pcr_banks = 0;
		capability->active_pcr_banks = 0;

		efi_ret = EFI_SUCCESS;
		goto out;
	}

	/* We only allow a TPMv2 device to register the EFI protocol */
	capability->supported_event_logs = TCG2_EVENT_LOG_FORMAT_TCG_2;

	capability->tpm_present_flag = true;

	/* Supported and active PCRs */
	capability->hash_algorithm_bitmap = 0;
	capability->active_pcr_banks = 0;
	ret = tpm2_get_pcr_info(dev, &capability->hash_algorithm_bitmap,
				&capability->active_pcr_banks,
				&capability->number_of_pcr_banks);
	if (ret) {
		efi_ret = EFI_DEVICE_ERROR;
		goto out;
	}

	/* Max command size */
	ret = tpm2_get_max_command_size(dev, &capability->max_command_size);
	if (ret) {
		efi_ret = EFI_DEVICE_ERROR;
		goto out;
	}

	/* Max response size */
	ret = tpm2_get_max_response_size(dev, &capability->max_response_size);
	if (ret) {
		efi_ret = EFI_DEVICE_ERROR;
		goto out;
	}

	/* Manufacturer ID */
	ret = tpm2_get_manufacturer_id(dev, &capability->manufacturer_id);
	if (ret) {
		efi_ret = EFI_DEVICE_ERROR;
		goto out;
	}

	return EFI_EXIT(EFI_SUCCESS);
out:
	return EFI_EXIT(efi_ret);
}

/**
 * efi_tcg2_get_eventlog() -	retrieve the the address of an event log and its
 *				last entry
 *
 * @this:			TCG2 protocol instance
 * @log_format:			type of event log format
 * @event_log_location:		pointer to the memory address of the event log
 * @event_log_last_entry:	pointer to the address of the start of the last
 *				entry in the event log in memory, if log contains
 *				more than 1 entry
 * @event_log_truncated:	set to true, if the Event Log is missing at i
 *				least one entry
 *
 * Return:	status code
 */
static efi_status_t EFIAPI
efi_tcg2_get_eventlog(struct efi_tcg2_protocol *this,
		      efi_tcg_event_log_format log_format,
		      u64 *event_log_location, u64 *event_log_last_entry,
		      bool *event_log_truncated)
{
	efi_status_t ret = EFI_SUCCESS;
	struct udevice *dev;

	EFI_ENTRY("%p, %u, %p, %p,  %p", this, log_format, event_log_location,
		  event_log_last_entry, event_log_truncated);

	if (!this || !event_log_location || !event_log_last_entry ||
	    !event_log_truncated) {
		ret = EFI_INVALID_PARAMETER;
		goto out;
	}

	/* Only support TPMV2 */
	if (log_format != TCG2_EVENT_LOG_FORMAT_TCG_2) {
		ret = EFI_INVALID_PARAMETER;
		goto out;
	}

	ret = platform_get_tpm2_device(&dev);
	if (ret != EFI_SUCCESS) {
		event_log_location = NULL;
		event_log_last_entry = NULL;
		*event_log_truncated = false;
		ret = EFI_SUCCESS;
		goto out;
	}
	*event_log_location = (uintptr_t)event_log.buffer;
	*event_log_last_entry = (uintptr_t)(event_log.buffer + event_log.pos -
					    event_log.last_event_size);
	*event_log_truncated = event_log.truncated;
	event_log.get_event_called = true;

out:
	return EFI_EXIT(ret);
}

/**
 * tcg2_hash_pe_image() - calculate PE/COFF image hash
 *
 * @efi:		pointer to the EFI binary
 * @efi_size:		size of @efi binary
 * @digest_list:	list of digest algorithms to extend
 *
 * Return:	status code
 */
static efi_status_t tcg2_hash_pe_image(void *efi, u64 efi_size,
				       struct tpml_digest_values *digest_list)
{
	WIN_CERTIFICATE *wincerts = NULL;
	size_t wincerts_len;
	struct efi_image_regions *regs = NULL;
	void *new_efi = NULL;
	u8 hash[TPM2_SHA512_DIGEST_SIZE];
	efi_status_t ret;
	u32 active;
	int i;

	new_efi = efi_prepare_aligned_image(efi, &efi_size);
	if (!new_efi)
		return EFI_OUT_OF_RESOURCES;

	if (!efi_image_parse(new_efi, efi_size, &regs, &wincerts,
			     &wincerts_len)) {
		log_err("Parsing PE executable image failed\n");
		ret = EFI_UNSUPPORTED;
		goto out;
	}

	ret = __get_active_pcr_banks(&active);
	if (ret != EFI_SUCCESS) {
		goto out;
	}

	digest_list->count = 0;
	for (i = 0; i < MAX_HASH_COUNT; i++) {
		u16 hash_alg = hash_algo_list[i].hash_alg;

		if (!(active & alg_to_mask(hash_alg)))
			continue;
		switch (hash_alg) {
		case TPM2_ALG_SHA1:
			hash_calculate("sha1", regs->reg, regs->num, hash);
			break;
		case TPM2_ALG_SHA256:
			hash_calculate("sha256", regs->reg, regs->num, hash);
			break;
		case TPM2_ALG_SHA384:
			hash_calculate("sha384", regs->reg, regs->num, hash);
			break;
		case TPM2_ALG_SHA512:
			hash_calculate("sha512", regs->reg, regs->num, hash);
			break;
		default:
			EFI_PRINT("Unsupported algorithm %x\n", hash_alg);
			return EFI_INVALID_PARAMETER;
		}
		digest_list->digests[digest_list->count].hash_alg = hash_alg;
		memcpy(&digest_list->digests[digest_list->count].digest, hash,
		       (u32)alg_to_len(hash_alg));
		digest_list->count++;
	}

out:
	if (new_efi != efi)
		free(new_efi);
	free(regs);

	return ret;
}

/**
 * tcg2_measure_pe_image() - measure PE/COFF image
 *
 * @efi:		pointer to the EFI binary
 * @efi_size:		size of @efi binary
 * @handle:		loaded image handle
 * @loaded_image:	loaded image protocol
 *
 * Return:	status code
 */
efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size,
				   struct efi_loaded_image_obj *handle,
				   struct efi_loaded_image *loaded_image)
{
	struct tpml_digest_values digest_list;
	efi_status_t ret;
	struct udevice *dev;
	u32 pcr_index, event_type, event_size;
	struct uefi_image_load_event *image_load_event;
	struct efi_device_path *device_path;
	u32 device_path_length;
	IMAGE_DOS_HEADER *dos;
	IMAGE_NT_HEADERS32 *nt;
	struct efi_handler *handler;

	ret = platform_get_tpm2_device(&dev);
	if (ret != EFI_SUCCESS)
		return ret;

	switch (handle->image_type) {
	case IMAGE_SUBSYSTEM_EFI_APPLICATION:
		pcr_index = 4;
		event_type = EV_EFI_BOOT_SERVICES_APPLICATION;
		break;
	case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
		pcr_index = 2;
		event_type = EV_EFI_BOOT_SERVICES_DRIVER;
		break;
	case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
		pcr_index = 2;
		event_type = EV_EFI_RUNTIME_SERVICES_DRIVER;
		break;
	default:
		return EFI_UNSUPPORTED;
	}

	ret = tcg2_hash_pe_image(efi, efi_size, &digest_list);
	if (ret != EFI_SUCCESS)
		return ret;

	ret = tcg2_pcr_extend(dev, pcr_index, &digest_list);
	if (ret != EFI_SUCCESS)
		return ret;

	ret = efi_search_protocol(&handle->header,
				  &efi_guid_loaded_image_device_path, &handler);
	if (ret != EFI_SUCCESS)
		return ret;

	device_path = handler->protocol_interface;
	device_path_length = efi_dp_size(device_path);
	if (device_path_length > 0) {
		/* add end node size */
		device_path_length += sizeof(struct efi_device_path);
	}
	event_size = sizeof(struct uefi_image_load_event) + device_path_length;
	image_load_event = calloc(1, event_size);
	if (!image_load_event)
		return EFI_OUT_OF_RESOURCES;

	image_load_event->image_location_in_memory = (uintptr_t)efi;
	image_load_event->image_length_in_memory = efi_size;
	image_load_event->length_of_device_path = device_path_length;

	dos = (IMAGE_DOS_HEADER *)efi;
	nt = (IMAGE_NT_HEADERS32 *)(efi + dos->e_lfanew);
	if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
		IMAGE_NT_HEADERS64 *nt64 = (IMAGE_NT_HEADERS64 *)nt;

		image_load_event->image_link_time_address =
				nt64->OptionalHeader.ImageBase;
	} else if (nt->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
		image_load_event->image_link_time_address =
				nt->OptionalHeader.ImageBase;
	} else {
		ret = EFI_INVALID_PARAMETER;
		goto out;
	}

	/* device_path_length might be zero */
	memcpy(image_load_event->device_path, device_path, device_path_length);

	ret = tcg2_agile_log_append(pcr_index, event_type, &digest_list,
				    event_size, (u8 *)image_load_event);

out:
	free(image_load_event);

	return ret;
}

/**
 * efi_tcg2_hash_log_extend_event() - extend and optionally log events
 *
 * @this:			TCG2 protocol instance
 * @flags:			bitmap providing additional information on the
 *				operation
 * @data_to_hash:		physical address of the start of the data buffer
 *				to be hashed
 * @data_to_hash_len:		the length in bytes of the buffer referenced by
 *				data_to_hash
 * @efi_tcg_event:		pointer to data buffer containing information
 *				about the event
 *
 * Return:	status code
 */
static efi_status_t EFIAPI
efi_tcg2_hash_log_extend_event(struct efi_tcg2_protocol *this, u64 flags,
			       u64 data_to_hash, u64 data_to_hash_len,
			       struct efi_tcg2_event *efi_tcg_event)
{
	struct udevice *dev;
	efi_status_t ret;
	u32 event_type, pcr_index, event_size;
	struct tpml_digest_values digest_list;

	EFI_ENTRY("%p, %llu, %llu, %llu, %p", this, flags, data_to_hash,
		  data_to_hash_len, efi_tcg_event);

	if (!this || !data_to_hash || !efi_tcg_event) {
		ret = EFI_INVALID_PARAMETER;
		goto out;
	}

	ret = platform_get_tpm2_device(&dev);
	if (ret != EFI_SUCCESS)
		goto out;

	if (efi_tcg_event->size < efi_tcg_event->header.header_size +
	    sizeof(u32)) {
		ret = EFI_INVALID_PARAMETER;
		goto out;
	}

	if (efi_tcg_event->header.pcr_index > EFI_TCG2_MAX_PCR_INDEX) {
		ret = EFI_INVALID_PARAMETER;
		goto out;
	}

	/*
	 * if PE_COFF_IMAGE is set we need to make sure the image is not
	 * corrupted, verify it and hash the PE/COFF image in accordance with
	 * the procedure specified in "Calculating the PE Image Hash"
	 * section of the "Windows Authenticode Portable Executable Signature
	 * Format"
	 */
	if (flags & PE_COFF_IMAGE) {
		IMAGE_NT_HEADERS32 *nt;

		ret = efi_check_pe((void *)(uintptr_t)data_to_hash,
				   data_to_hash_len, (void **)&nt);
		if (ret != EFI_SUCCESS) {
			log_err("Not a valid PE-COFF file\n");
			ret = EFI_UNSUPPORTED;
			goto out;
		}
		ret = tcg2_hash_pe_image((void *)(uintptr_t)data_to_hash,
					 data_to_hash_len, &digest_list);
	} else {
		ret = tcg2_create_digest((u8 *)(uintptr_t)data_to_hash,
					 data_to_hash_len, &digest_list);
	}

	if (ret != EFI_SUCCESS)
		goto out;

	pcr_index = efi_tcg_event->header.pcr_index;
	event_type = efi_tcg_event->header.event_type;

	ret = tcg2_pcr_extend(dev, pcr_index, &digest_list);
	if (ret != EFI_SUCCESS)
		goto out;

	if (flags & EFI_TCG2_EXTEND_ONLY) {
		if (event_log.truncated)
			ret = EFI_VOLUME_FULL;
		goto out;
	}

	/*
	 * The efi_tcg_event size includes the size component and the
	 * headersize
	 */
	event_size = efi_tcg_event->size - sizeof(efi_tcg_event->size) -
		efi_tcg_event->header.header_size;
	ret = tcg2_agile_log_append(pcr_index, event_type, &digest_list,
				    event_size, efi_tcg_event->event);
out:
	return EFI_EXIT(ret);
}

/**
 * efi_tcg2_submit_command() - Send command to the TPM
 *
 * @this:			TCG2 protocol instance
 * @input_param_block_size:	size of the TPM input parameter block
 * @input_param_block:		pointer to the TPM input parameter block
 * @output_param_block_size:	size of the TPM output parameter block
 * @output_param_block:		pointer to the TPM output parameter block
 *
 * Return:	status code
 */
static efi_status_t EFIAPI
efi_tcg2_submit_command(__maybe_unused struct efi_tcg2_protocol *this,
			u32 __maybe_unused input_param_block_size,
			u8 __maybe_unused *input_param_block,
			u32 __maybe_unused output_param_block_size,
			u8 __maybe_unused *output_param_block)
{
	return EFI_UNSUPPORTED;
}

/**
 * efi_tcg2_get_active_pcr_banks() - returns the currently active PCR banks
 *
 * @this:			TCG2 protocol instance
 * @active_pcr_banks:		pointer for receiving the bitmap of currently
 *				active PCR banks
 *
 * Return:	status code
 */
static efi_status_t EFIAPI
efi_tcg2_get_active_pcr_banks(struct efi_tcg2_protocol *this,
			      u32 *active_pcr_banks)
{
	efi_status_t ret;

	if (!this || !active_pcr_banks) {
		ret = EFI_INVALID_PARAMETER;
		goto out;
	}

	EFI_ENTRY("%p, %p", this, active_pcr_banks);
	ret = __get_active_pcr_banks(active_pcr_banks);

out:
	return EFI_EXIT(ret);
}

/**
 * efi_tcg2_set_active_pcr_banks() - sets the currently active PCR banks
 *
 * @this:			TCG2 protocol instance
 * @active_pcr_banks:		bitmap of the requested active PCR banks
 *
 * Return:	status code
 */
static efi_status_t EFIAPI
efi_tcg2_set_active_pcr_banks(__maybe_unused struct efi_tcg2_protocol *this,
			      u32 __maybe_unused active_pcr_banks)
{
	return EFI_UNSUPPORTED;
}

/**
 * efi_tcg2_get_result_of_set_active_pcr_banks() - retrieve result for previous
 *						   set_active_pcr_banks()
 *
 * @this:			TCG2 protocol instance
 * @operation_present:		non-zero value to indicate a
 *				set_active_pcr_banks operation was
 *				invoked during last boot
 * @response:			result value could be returned
 *
 * Return:	status code
 */
static efi_status_t EFIAPI
efi_tcg2_get_result_of_set_active_pcr_banks(__maybe_unused struct efi_tcg2_protocol *this,
					    u32 __maybe_unused *operation_present,
					    u32 __maybe_unused *response)
{
	return EFI_UNSUPPORTED;
}

static const struct efi_tcg2_protocol efi_tcg2_protocol = {
	.get_capability = efi_tcg2_get_capability,
	.get_eventlog = efi_tcg2_get_eventlog,
	.hash_log_extend_event = efi_tcg2_hash_log_extend_event,
	.submit_command = efi_tcg2_submit_command,
	.get_active_pcr_banks = efi_tcg2_get_active_pcr_banks,
	.set_active_pcr_banks = efi_tcg2_set_active_pcr_banks,
	.get_result_of_set_active_pcr_banks = efi_tcg2_get_result_of_set_active_pcr_banks,
};

/**
 * create_specid_event() - Create the first event in the eventlog
 *
 * @dev:			tpm device
 * @event_header:		Pointer to the final event header
 * @event_size:			final spec event size
 *
 * Return:	status code
 */
static efi_status_t create_specid_event(struct udevice *dev, void *buffer,
					size_t *event_size)
{
	struct tcg_efi_spec_id_event *spec_event;
	size_t spec_event_size;
	efi_status_t ret = EFI_DEVICE_ERROR;
	u32 active = 0, supported = 0, pcr_count = 0, alg_count = 0;
	int err;
	size_t i;

	/*
	 * Create Spec event. This needs to be the first event in the log
	 * according to the TCG EFI protocol spec
	 */

	/* Setup specID event data */
	spec_event = (struct tcg_efi_spec_id_event *)buffer;
	memcpy(spec_event->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03,
	       sizeof(spec_event->signature));
	put_unaligned_le32(0, &spec_event->platform_class); /* type client */
	spec_event->spec_version_minor =
		TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2;
	spec_event->spec_version_major =
		TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2;
	spec_event->spec_errata =
		TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_ERRATA_TPM2;
	spec_event->uintn_size = sizeof(efi_uintn_t) / sizeof(u32);

	err = tpm2_get_pcr_info(dev, &supported, &active, &pcr_count);

	if (err)
		goto out;

	for (i = 0; i < pcr_count; i++) {
		u16 hash_alg = hash_algo_list[i].hash_alg;
		u16 hash_len = hash_algo_list[i].hash_len;

		if (active & alg_to_mask(hash_alg)) {
			put_unaligned_le16(hash_alg,
					   &spec_event->digest_sizes[alg_count].algorithm_id);
			put_unaligned_le16(hash_len,
					   &spec_event->digest_sizes[alg_count].digest_size);
			alg_count++;
		}
	}

	spec_event->number_of_algorithms = alg_count;
	if (spec_event->number_of_algorithms > MAX_HASH_COUNT ||
	    spec_event->number_of_algorithms < 1)
		goto out;

	/*
	 * the size of the spec event and placement of vendor_info_size
	 * depends on supported algoriths
	 */
	spec_event_size =
		offsetof(struct tcg_efi_spec_id_event, digest_sizes) +
		spec_event->number_of_algorithms * sizeof(spec_event->digest_sizes[0]);
	/* no vendor info for us */
	memset(buffer + spec_event_size, 0, 1);
	/* add a byte for vendor_info_size in the spec event */
	spec_event_size += 1;
	*event_size = spec_event_size;

	return EFI_SUCCESS;

out:
	return ret;
}

/**
 * tcg2_uninit - remove the final event table and free efi memory on failures
 */
void tcg2_uninit(void)
{
	efi_status_t ret;

	ret = efi_install_configuration_table(&efi_guid_final_events, NULL);
	if (ret != EFI_SUCCESS)
		log_err("Failed to delete final events config table\n");

	efi_free_pool(event_log.buffer);
	event_log.buffer = NULL;
	efi_free_pool(event_log.final_buffer);
	event_log.final_buffer = NULL;
}

/**
 * create_final_event() - Create the final event and install the config
 *			defined by the TCG EFI spec
 */
static efi_status_t create_final_event(void)
{
	struct efi_tcg2_final_events_table *final_event;
	efi_status_t ret;

	/*
	 * All events generated after the invocation of
	 * EFI_TCG2_GET_EVENT_LOGS need to be stored in an instance of an
	 * EFI_CONFIGURATION_TABLE
	 */
	ret = efi_allocate_pool(EFI_ACPI_MEMORY_NVS, TPM2_EVENT_LOG_SIZE,
				&event_log.final_buffer);
	if (ret != EFI_SUCCESS)
		goto out;

	memset(event_log.final_buffer, 0xff, TPM2_EVENT_LOG_SIZE);
	final_event = event_log.final_buffer;
	final_event->number_of_events = 0;
	final_event->version = EFI_TCG2_FINAL_EVENTS_TABLE_VERSION;
	event_log.final_pos = sizeof(*final_event);
	ret = efi_install_configuration_table(&efi_guid_final_events,
					      final_event);
	if (ret != EFI_SUCCESS) {
		efi_free_pool(event_log.final_buffer);
		event_log.final_buffer = NULL;
	}

out:
	return ret;
}

/**
 * efi_init_event_log() - initialize an eventlog
 */
static efi_status_t efi_init_event_log(void)
{
	/*
	 * vendor_info_size is currently set to 0, we need to change the length
	 * and allocate the flexible array member if this changes
	 */
	struct tcg_pcr_event *event_header = NULL;
	struct udevice *dev;
	size_t spec_event_size;
	efi_status_t ret;

	ret = platform_get_tpm2_device(&dev);
	if (ret != EFI_SUCCESS)
		goto out;

	ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, TPM2_EVENT_LOG_SIZE,
				(void **)&event_log.buffer);
	if (ret != EFI_SUCCESS)
		goto out;

	/*
	 * initialize log area as 0xff so the OS can easily figure out the
	 * last log entry
	 */
	memset(event_log.buffer, 0xff, TPM2_EVENT_LOG_SIZE);
	event_log.pos = 0;
	event_log.last_event_size = 0;
	event_log.get_event_called = false;
	event_log.truncated = false;

	/*
	 * The log header is defined to be in SHA1 event log entry format.
	 * Setup event header
	 */
	event_header =  (struct tcg_pcr_event *)event_log.buffer;
	put_unaligned_le32(0, &event_header->pcr_index);
	put_unaligned_le32(EV_NO_ACTION, &event_header->event_type);
	memset(&event_header->digest, 0, sizeof(event_header->digest));
	ret = create_specid_event(dev, (void *)((uintptr_t)event_log.buffer + sizeof(*event_header)),
				  &spec_event_size);
	if (ret != EFI_SUCCESS)
		goto free_pool;
	put_unaligned_le32(spec_event_size, &event_header->event_size);
	event_log.pos = spec_event_size + sizeof(*event_header);
	event_log.last_event_size = event_log.pos;

	ret = create_final_event();
	if (ret != EFI_SUCCESS)
		goto free_pool;

out:
	return ret;

free_pool:
	efi_free_pool(event_log.buffer);
	event_log.buffer = NULL;
	return ret;
}

/**
 * tcg2_measure_event() - common function to add event log and extend PCR
 *
 * @dev:		TPM device
 * @pcr_index:		PCR index
 * @event_type:		type of event added
 * @size:		event size
 * @event:		event data
 *
 * Return:	status code
 */
static efi_status_t
tcg2_measure_event(struct udevice *dev, u32 pcr_index, u32 event_type,
		   u32 size, u8 event[])
{
	struct tpml_digest_values digest_list;
	efi_status_t ret;

	ret = tcg2_create_digest(event, size, &digest_list);
	if (ret != EFI_SUCCESS)
		goto out;

	ret = tcg2_pcr_extend(dev, pcr_index, &digest_list);
	if (ret != EFI_SUCCESS)
		goto out;

	ret = tcg2_agile_log_append(pcr_index, event_type, &digest_list,
				    size, event);

out:
	return ret;
}

/**
 * efi_append_scrtm_version - Append an S-CRTM EV_S_CRTM_VERSION event on the
 *			      eventlog and extend the PCRs
 *
 * @dev:	TPM device
 *
 * @Return:	status code
 */
static efi_status_t efi_append_scrtm_version(struct udevice *dev)
{
	u8 ver[] = U_BOOT_VERSION_STRING;
	efi_status_t ret;

	ret = tcg2_measure_event(dev, 0, EV_S_CRTM_VERSION, sizeof(ver), ver);

	return ret;
}

/**
 * tcg2_measure_variable() - add variable event log and extend PCR
 *
 * @dev:		TPM device
 * @pcr_index:		PCR index
 * @event_type:		type of event added
 * @var_name:		variable name
 * @guid:		guid
 * @data_size:		variable data size
 * @data:		variable data
 *
 * Return:	status code
 */
static efi_status_t tcg2_measure_variable(struct udevice *dev, u32 pcr_index,
					  u32 event_type, u16 *var_name,
					  const efi_guid_t *guid,
					  efi_uintn_t data_size, u8 *data)
{
	u32 event_size;
	efi_status_t ret;
	struct efi_tcg2_uefi_variable_data *event;

	event_size = sizeof(event->variable_name) +
		     sizeof(event->unicode_name_length) +
		     sizeof(event->variable_data_length) +
		     (u16_strlen(var_name) * sizeof(u16)) + data_size;
	event = malloc(event_size);
	if (!event)
		return EFI_OUT_OF_RESOURCES;

	guidcpy(&event->variable_name, guid);
	event->unicode_name_length = u16_strlen(var_name);
	event->variable_data_length = data_size;
	memcpy(event->unicode_name, var_name,
	       (event->unicode_name_length * sizeof(u16)));
	if (data) {
		memcpy((u16 *)event->unicode_name + event->unicode_name_length,
		       data, data_size);
	}
	ret = tcg2_measure_event(dev, pcr_index, event_type, event_size,
				 (u8 *)event);
	free(event);
	return ret;
}

/**
 * tcg2_measure_boot_variable() - measure boot variables
 *
 * @dev:	TPM device
 *
 * Return:	status code
 */
static efi_status_t tcg2_measure_boot_variable(struct udevice *dev)
{
	u16 *boot_order;
	u16 *boot_index;
	u16 var_name[] = L"BootOrder";
	u16 boot_name[] = L"Boot####";
	u8 *bootvar;
	efi_uintn_t var_data_size;
	u32 count, i;
	efi_status_t ret;

	boot_order = efi_get_var(var_name, &efi_global_variable_guid,
				 &var_data_size);
	if (!boot_order) {
		ret = EFI_NOT_FOUND;
		goto error;
	}

	ret = tcg2_measure_variable(dev, 1, EV_EFI_VARIABLE_BOOT2, var_name,
				    &efi_global_variable_guid, var_data_size,
				    (u8 *)boot_order);
	if (ret != EFI_SUCCESS)
		goto error;

	count = var_data_size / sizeof(*boot_order);
	boot_index = boot_order;
	for (i = 0; i < count; i++) {
		efi_create_indexed_name(boot_name, sizeof(boot_name),
					"Boot", *boot_index++);

		bootvar = efi_get_var(boot_name, &efi_global_variable_guid,
				      &var_data_size);

		if (!bootvar) {
			log_info("%ls not found\n", boot_name);
			continue;
		}

		ret = tcg2_measure_variable(dev, 1, EV_EFI_VARIABLE_BOOT2,
					    boot_name,
					    &efi_global_variable_guid,
					    var_data_size, bootvar);
		free(bootvar);
		if (ret != EFI_SUCCESS)
			goto error;
	}

error:
	free(boot_order);
	return ret;
}

/**
 * efi_tcg2_measure_efi_app_invocation() - measure efi app invocation
 *
 * Return:	status code
 */
efi_status_t efi_tcg2_measure_efi_app_invocation(void)
{
	efi_status_t ret;
	u32 pcr_index;
	struct udevice *dev;
	u32 event = 0;

	if (tcg2_efi_app_invoked)
		return EFI_SUCCESS;

	ret = platform_get_tpm2_device(&dev);
	if (ret != EFI_SUCCESS)
		return ret;

	ret = tcg2_measure_boot_variable(dev);
	if (ret != EFI_SUCCESS)
		goto out;

	ret = tcg2_measure_event(dev, 4, EV_EFI_ACTION,
				 strlen(EFI_CALLING_EFI_APPLICATION),
				 (u8 *)EFI_CALLING_EFI_APPLICATION);
	if (ret != EFI_SUCCESS)
		goto out;

	for (pcr_index = 0; pcr_index <= 7; pcr_index++) {
		ret = tcg2_measure_event(dev, pcr_index, EV_SEPARATOR,
					 sizeof(event), (u8 *)&event);
		if (ret != EFI_SUCCESS)
			goto out;
	}

	tcg2_efi_app_invoked = true;
out:
	return ret;
}

/**
 * efi_tcg2_measure_efi_app_exit() - measure efi app exit
 *
 * Return:	status code
 */
efi_status_t efi_tcg2_measure_efi_app_exit(void)
{
	efi_status_t ret;
	struct udevice *dev;

	ret = platform_get_tpm2_device(&dev);
	if (ret != EFI_SUCCESS)
		return ret;

	ret = tcg2_measure_event(dev, 4, EV_EFI_ACTION,
				 strlen(EFI_RETURNING_FROM_EFI_APPLICATION),
				 (u8 *)EFI_RETURNING_FROM_EFI_APPLICATION);
	return ret;
}

/**
 * efi_tcg2_notify_exit_boot_services() - ExitBootService callback
 *
 * @event:	callback event
 * @context:	callback context
 */
static void EFIAPI
efi_tcg2_notify_exit_boot_services(struct efi_event *event, void *context)
{
	efi_status_t ret;
	struct udevice *dev;

	EFI_ENTRY("%p, %p", event, context);

	ret = platform_get_tpm2_device(&dev);
	if (ret != EFI_SUCCESS)
		goto out;

	ret = tcg2_measure_event(dev, 5, EV_EFI_ACTION,
				 strlen(EFI_EXIT_BOOT_SERVICES_INVOCATION),
				 (u8 *)EFI_EXIT_BOOT_SERVICES_INVOCATION);
	if (ret != EFI_SUCCESS)
		goto out;

	ret = tcg2_measure_event(dev, 5, EV_EFI_ACTION,
				 strlen(EFI_EXIT_BOOT_SERVICES_SUCCEEDED),
				 (u8 *)EFI_EXIT_BOOT_SERVICES_SUCCEEDED);

out:
	EFI_EXIT(ret);
}

/**
 * efi_tcg2_notify_exit_boot_services_failed()
 *  - notify ExitBootServices() is failed
 *
 * Return:	status code
 */
efi_status_t efi_tcg2_notify_exit_boot_services_failed(void)
{
	struct udevice *dev;
	efi_status_t ret;

	ret = platform_get_tpm2_device(&dev);
	if (ret != EFI_SUCCESS)
		goto out;

	ret = tcg2_measure_event(dev, 5, EV_EFI_ACTION,
				 strlen(EFI_EXIT_BOOT_SERVICES_INVOCATION),
				 (u8 *)EFI_EXIT_BOOT_SERVICES_INVOCATION);
	if (ret != EFI_SUCCESS)
		goto out;

	ret = tcg2_measure_event(dev, 5, EV_EFI_ACTION,
				 strlen(EFI_EXIT_BOOT_SERVICES_FAILED),
				 (u8 *)EFI_EXIT_BOOT_SERVICES_FAILED);

out:
	return ret;
}

/**
 * tcg2_measure_secure_boot_variable() - measure secure boot variables
 *
 * @dev:	TPM device
 *
 * Return:	status code
 */
static efi_status_t tcg2_measure_secure_boot_variable(struct udevice *dev)
{
	u8 *data;
	efi_uintn_t data_size;
	u32 count, i;
	efi_status_t ret;

	count = ARRAY_SIZE(secure_variables);
	for (i = 0; i < count; i++) {
		/*
		 * According to the TCG2 PC Client PFP spec, "SecureBoot",
		 * "PK", "KEK", "db" and "dbx" variables must be measured
		 * even if they are empty.
		 */
		data = efi_get_var(secure_variables[i].name,
				   secure_variables[i].guid,
				   &data_size);

		ret = tcg2_measure_variable(dev, 7,
					    EV_EFI_VARIABLE_DRIVER_CONFIG,
					    secure_variables[i].name,
					    secure_variables[i].guid,
					    data_size, data);
		free(data);
		if (ret != EFI_SUCCESS)
			goto error;
	}

	/*
	 * TCG2 PC Client PFP spec says "dbt" and "dbr" are
	 * measured if present and not empty.
	 */
	data = efi_get_var(L"dbt",
			   &efi_guid_image_security_database,
			   &data_size);
	if (data) {
		ret = tcg2_measure_variable(dev, 7,
					    EV_EFI_VARIABLE_DRIVER_CONFIG,
					    L"dbt",
					    &efi_guid_image_security_database,
					    data_size, data);
		free(data);
	}

	data = efi_get_var(L"dbr",
			   &efi_guid_image_security_database,
			   &data_size);
	if (data) {
		ret = tcg2_measure_variable(dev, 7,
					    EV_EFI_VARIABLE_DRIVER_CONFIG,
					    L"dbr",
					    &efi_guid_image_security_database,
					    data_size, data);
		free(data);
	}

error:
	return ret;
}

/**
 * efi_tcg2_register() - register EFI_TCG2_PROTOCOL
 *
 * If a TPM2 device is available, the TPM TCG2 Protocol is registered
 *
 * Return:	An error status is only returned if adding the protocol fails.
 */
efi_status_t efi_tcg2_register(void)
{
	efi_status_t ret = EFI_SUCCESS;
	struct udevice *dev;
	struct efi_event *event;

	ret = platform_get_tpm2_device(&dev);
	if (ret != EFI_SUCCESS) {
		log_warning("Unable to find TPMv2 device\n");
		return EFI_SUCCESS;
	}

	ret = efi_init_event_log();
	if (ret != EFI_SUCCESS)
		goto fail;

	ret = efi_append_scrtm_version(dev);
	if (ret != EFI_SUCCESS) {
		tcg2_uninit();
		goto fail;
	}

	ret = efi_add_protocol(efi_root, &efi_guid_tcg2_protocol,
			       (void *)&efi_tcg2_protocol);
	if (ret != EFI_SUCCESS) {
		tcg2_uninit();
		goto fail;
	}

	ret = efi_create_event(EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,
			       efi_tcg2_notify_exit_boot_services, NULL,
			       NULL, &event);
	if (ret != EFI_SUCCESS) {
		tcg2_uninit();
		goto fail;
	}

	ret = tcg2_measure_secure_boot_variable(dev);
	if (ret != EFI_SUCCESS) {
		tcg2_uninit();
		goto fail;
	}

	return ret;

fail:
	log_err("Cannot install EFI_TCG2_PROTOCOL\n");
	/*
	 * Return EFI_SUCCESS and don't stop the EFI subsystem.
	 * That's done for 2 reasons
	 * - If the protocol is not installed the PCRs won't be extended.  So
	 *   someone later in the boot flow will notice that and take the
	 *   necessary actions.
	 * - The TPM sandbox is limited and we won't be able to run any efi
	 *   related tests with TCG2 enabled
	 */
	return EFI_SUCCESS;
}
