// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2013 The Chromium OS Authors.
 * Coypright (c) 2013 Guntermann & Drunck GmbH
 */

#define LOG_CATEGORY UCLASS_TPM

#include <dm.h>
#include <log.h>
#include <asm/unaligned.h>
#include <u-boot/sha1.h>
#include <tpm-common.h>
#include <tpm-v1.h>
#include "tpm-utils.h"

#ifdef CONFIG_TPM_AUTH_SESSIONS

#ifndef CONFIG_SHA1
#error "TPM_AUTH_SESSIONS require SHA1 to be configured, too"
#endif /* !CONFIG_SHA1 */

struct session_data {
	int		valid;
	u32	handle;
	u8		nonce_even[DIGEST_LENGTH];
	u8		nonce_odd[DIGEST_LENGTH];
};

static struct session_data oiap_session = {0, };

#endif /* CONFIG_TPM_AUTH_SESSIONS */

u32 tpm1_startup(struct udevice *dev, enum tpm_startup_type mode)
{
	const u8 command[12] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0,
	};
	const size_t mode_offset = 10;
	u8 buf[COMMAND_BUFFER_SIZE];

	if (pack_byte_string(buf, sizeof(buf), "sw",
			     0, command, sizeof(command),
			     mode_offset, mode))
		return TPM_LIB_ERROR;

	return tpm_sendrecv_command(dev, buf, NULL, NULL);
}

u32 tpm1_resume(struct udevice *dev)
{
	return tpm1_startup(dev, TPM_ST_STATE);
}

u32 tpm1_self_test_full(struct udevice *dev)
{
	const u8 command[10] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50,
	};
	return tpm_sendrecv_command(dev, command, NULL, NULL);
}

u32 tpm1_continue_self_test(struct udevice *dev)
{
	const u8 command[10] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53,
	};
	return tpm_sendrecv_command(dev, command, NULL, NULL);
}

u32 tpm1_auto_start(struct udevice *dev)
{
	u32 rc;

	rc = tpm1_startup(dev, TPM_ST_CLEAR);
	/* continue on if the TPM is already inited */
	if (rc && rc != TPM_INVALID_POSTINIT)
		return rc;

	rc = tpm1_self_test_full(dev);

	return rc;
}

u32 tpm1_clear_and_reenable(struct udevice *dev)
{
	u32 ret;

	log_info("TPM: Clear and re-enable\n");
	ret = tpm1_force_clear(dev);
	if (ret != TPM_SUCCESS) {
		log_err("Can't initiate a force clear\n");
		return ret;
	}

	ret = tpm1_physical_enable(dev);
	if (ret != TPM_SUCCESS) {
		log_err("TPM: Can't set enabled state\n");
		return ret;
	}

	ret = tpm1_physical_set_deactivated(dev, 0);
	if (ret != TPM_SUCCESS) {
		log_err("TPM: Can't set deactivated state\n");
		return ret;
	}

	return TPM_SUCCESS;
}

u32 tpm1_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size)
{
	const u8 command[101] = {
		0x0, 0xc1,		/* TPM_TAG */
		0x0, 0x0, 0x0, 0x65,	/* parameter size */
		0x0, 0x0, 0x0, 0xcc,	/* TPM_COMMAND_CODE */
		/* TPM_NV_DATA_PUBLIC->... */
		0x0, 0x18,		/* ...->TPM_STRUCTURE_TAG */
		0, 0, 0, 0,		/* ...->TPM_NV_INDEX */
		/* TPM_NV_DATA_PUBLIC->TPM_PCR_INFO_SHORT */
		0x0, 0x3,
		0, 0, 0,
		0x1f,
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		/* TPM_NV_DATA_PUBLIC->TPM_PCR_INFO_SHORT */
		0x0, 0x3,
		0, 0, 0,
		0x1f,
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		/* TPM_NV_ATTRIBUTES->... */
		0x0, 0x17,		/* ...->TPM_STRUCTURE_TAG */
		0, 0, 0, 0,		/* ...->attributes */
		/* End of TPM_NV_ATTRIBUTES */
		0,			/* bReadSTClear */
		0,			/* bWriteSTClear */
		0,			/* bWriteDefine */
		0, 0, 0, 0,		/* size */
	};
	const size_t index_offset = 12;
	const size_t perm_offset = 70;
	const size_t size_offset = 77;
	u8 buf[COMMAND_BUFFER_SIZE];

	if (pack_byte_string(buf, sizeof(buf), "sddd",
			     0, command, sizeof(command),
			     index_offset, index,
			     perm_offset, perm,
			     size_offset, size))
		return TPM_LIB_ERROR;

	return tpm_sendrecv_command(dev, buf, NULL, NULL);
}

u32 tpm1_nv_set_locked(struct udevice *dev)
{
	return tpm1_nv_define_space(dev, TPM_NV_INDEX_LOCK, 0, 0);
}

u32 tpm1_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count)
{
	const u8 command[22] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0xcf,
	};
	const size_t index_offset = 10;
	const size_t length_offset = 18;
	const size_t data_size_offset = 10;
	const size_t data_offset = 14;
	u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
	size_t response_length = sizeof(response);
	u32 data_size;
	u32 err;

	if (pack_byte_string(buf, sizeof(buf), "sdd",
			     0, command, sizeof(command),
			     index_offset, index,
			     length_offset, count))
		return TPM_LIB_ERROR;
	err = tpm_sendrecv_command(dev, buf, response, &response_length);
	if (err)
		return err;
	if (unpack_byte_string(response, response_length, "d",
			       data_size_offset, &data_size))
		return TPM_LIB_ERROR;
	if (data_size > count)
		return TPM_LIB_ERROR;
	if (unpack_byte_string(response, response_length, "s",
			       data_offset, data, data_size))
		return TPM_LIB_ERROR;

	return 0;
}

u32 tpm1_nv_write_value(struct udevice *dev, u32 index, const void *data,
			u32 length)
{
	const u8 command[256] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd,
	};
	const size_t command_size_offset = 2;
	const size_t index_offset = 10;
	const size_t length_offset = 18;
	const size_t data_offset = 22;
	const size_t write_info_size = 12;
	const u32 total_length =
		TPM_REQUEST_HEADER_LENGTH + write_info_size + length;
	u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
	size_t response_length = sizeof(response);
	u32 err;

	if (pack_byte_string(buf, sizeof(buf), "sddds",
			     0, command, sizeof(command),
			     command_size_offset, total_length,
			     index_offset, index,
			     length_offset, length,
			     data_offset, data, length))
		return TPM_LIB_ERROR;
	err = tpm_sendrecv_command(dev, buf, response, &response_length);
	if (err)
		return err;

	return 0;
}

u32 tpm1_extend(struct udevice *dev, u32 index, const void *in_digest,
		void *out_digest)
{
	const u8 command[34] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14,
	};
	const size_t index_offset = 10;
	const size_t in_digest_offset = 14;
	const size_t out_digest_offset = 10;
	u8 buf[COMMAND_BUFFER_SIZE];
	u8 response[TPM_RESPONSE_HEADER_LENGTH + PCR_DIGEST_LENGTH];
	size_t response_length = sizeof(response);
	u32 err;

	if (pack_byte_string(buf, sizeof(buf), "sds",
			     0, command, sizeof(command),
			     index_offset, index,
			     in_digest_offset, in_digest,
			     PCR_DIGEST_LENGTH))
		return TPM_LIB_ERROR;
	err = tpm_sendrecv_command(dev, buf, response, &response_length);
	if (err)
		return err;

	if (unpack_byte_string(response, response_length, "s",
			       out_digest_offset, out_digest,
			       PCR_DIGEST_LENGTH))
		return TPM_LIB_ERROR;

	return 0;
}

u32 tpm1_pcr_read(struct udevice *dev, u32 index, void *data, size_t count)
{
	const u8 command[14] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15,
	};
	const size_t index_offset = 10;
	const size_t out_digest_offset = 10;
	u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
	size_t response_length = sizeof(response);
	u32 err;

	if (count < PCR_DIGEST_LENGTH)
		return TPM_LIB_ERROR;

	if (pack_byte_string(buf, sizeof(buf), "sd",
			     0, command, sizeof(command),
			     index_offset, index))
		return TPM_LIB_ERROR;
	err = tpm_sendrecv_command(dev, buf, response, &response_length);
	if (err)
		return err;
	if (unpack_byte_string(response, response_length, "s",
			       out_digest_offset, data, PCR_DIGEST_LENGTH))
		return TPM_LIB_ERROR;

	return 0;
}

u32 tpm1_tsc_physical_presence(struct udevice *dev, u16 presence)
{
	const u8 command[12] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x0,
	};
	const size_t presence_offset = 10;
	u8 buf[COMMAND_BUFFER_SIZE];

	if (pack_byte_string(buf, sizeof(buf), "sw",
			     0, command, sizeof(command),
			     presence_offset, presence))
		return TPM_LIB_ERROR;

	return tpm_sendrecv_command(dev, buf, NULL, NULL);
}

u32 tpm1_finalise_physical_presence(struct udevice *dev)
{
	const u8 command[12] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x2, 0xa0,
	};

	return tpm_sendrecv_command(dev, command, NULL, NULL);
}

u32 tpm1_read_pubek(struct udevice *dev, void *data, size_t count)
{
	const u8 command[30] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x7c,
	};
	const size_t response_size_offset = 2;
	const size_t data_offset = 10;
	const size_t header_and_checksum_size = TPM_RESPONSE_HEADER_LENGTH + 20;
	u8 response[COMMAND_BUFFER_SIZE + TPM_PUBEK_SIZE];
	size_t response_length = sizeof(response);
	u32 data_size;
	u32 err;

	err = tpm_sendrecv_command(dev, command, response, &response_length);
	if (err)
		return err;
	if (unpack_byte_string(response, response_length, "d",
			       response_size_offset, &data_size))
		return TPM_LIB_ERROR;
	if (data_size < header_and_checksum_size)
		return TPM_LIB_ERROR;
	data_size -= header_and_checksum_size;
	if (data_size > count)
		return TPM_LIB_ERROR;
	if (unpack_byte_string(response, response_length, "s",
			       data_offset, data, data_size))
		return TPM_LIB_ERROR;

	return 0;
}

u32 tpm1_force_clear(struct udevice *dev)
{
	const u8 command[10] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d,
	};

	return tpm_sendrecv_command(dev, command, NULL, NULL);
}

u32 tpm1_physical_enable(struct udevice *dev)
{
	const u8 command[10] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f,
	};

	return tpm_sendrecv_command(dev, command, NULL, NULL);
}

u32 tpm1_physical_disable(struct udevice *dev)
{
	const u8 command[10] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70,
	};

	return tpm_sendrecv_command(dev, command, NULL, NULL);
}

u32 tpm1_physical_set_deactivated(struct udevice *dev, u8 state)
{
	const u8 command[11] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72,
	};
	const size_t state_offset = 10;
	u8 buf[COMMAND_BUFFER_SIZE];

	if (pack_byte_string(buf, sizeof(buf), "sb",
			     0, command, sizeof(command),
			     state_offset, state))
		return TPM_LIB_ERROR;

	return tpm_sendrecv_command(dev, buf, NULL, NULL);
}

u32 tpm1_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap,
			void *cap, size_t count)
{
	const u8 command[22] = {
		0x0, 0xc1,		/* TPM_TAG */
		0x0, 0x0, 0x0, 0x16,	/* parameter size */
		0x0, 0x0, 0x0, 0x65,	/* TPM_COMMAND_CODE */
		0x0, 0x0, 0x0, 0x0,	/* TPM_CAPABILITY_AREA */
		0x0, 0x0, 0x0, 0x4,	/* subcap size */
		0x0, 0x0, 0x0, 0x0,	/* subcap value */
	};
	const size_t cap_area_offset = 10;
	const size_t sub_cap_offset = 18;
	const size_t cap_offset = 14;
	const size_t cap_size_offset = 10;
	u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
	size_t response_length = sizeof(response);
	u32 cap_size;
	u32 err;

	if (pack_byte_string(buf, sizeof(buf), "sdd",
			     0, command, sizeof(command),
			     cap_area_offset, cap_area,
			     sub_cap_offset, sub_cap))
		return TPM_LIB_ERROR;
	err = tpm_sendrecv_command(dev, buf, response, &response_length);
	if (err)
		return err;
	if (unpack_byte_string(response, response_length, "d",
			       cap_size_offset, &cap_size))
		return TPM_LIB_ERROR;
	if (cap_size > response_length || cap_size > count)
		return TPM_LIB_ERROR;
	if (unpack_byte_string(response, response_length, "s",
			       cap_offset, cap, cap_size))
		return TPM_LIB_ERROR;

	return 0;
}

u32 tpm1_get_permanent_flags(struct udevice *dev,
			     struct tpm_permanent_flags *pflags)
{
	const u8 command[22] = {
		0x0, 0xc1,		/* TPM_TAG */
		0x0, 0x0, 0x0, 0x16,	/* parameter size */
		0x0, 0x0, 0x0, 0x65,	/* TPM_COMMAND_CODE */
		0x0, 0x0, 0x0, 0x4,	/* TPM_CAP_FLAG_PERM */
		0x0, 0x0, 0x0, 0x4,	/* subcap size */
		0x0, 0x0, 0x1, 0x8,	/* subcap value */
	};
	const size_t data_size_offset = TPM_HEADER_SIZE;
	const size_t data_offset = TPM_HEADER_SIZE + sizeof(u32);
	u8 response[COMMAND_BUFFER_SIZE];
	size_t response_length = sizeof(response);
	u32 err;
	u32 data_size;

	err = tpm_sendrecv_command(dev, command, response, &response_length);
	if (err)
		return err;
	if (unpack_byte_string(response, response_length, "d",
			       data_size_offset, &data_size)) {
		log_err("Cannot unpack data size\n");
		return TPM_LIB_ERROR;
	}
	if (data_size < sizeof(*pflags)) {
		log_err("Data size too small\n");
		return TPM_LIB_ERROR;
	}
	if (unpack_byte_string(response, response_length, "s",
			       data_offset, pflags, sizeof(*pflags))) {
		log_err("Cannot unpack pflags\n");
		return TPM_LIB_ERROR;
	}

	return 0;
}

u32 tpm1_get_permissions(struct udevice *dev, u32 index, u32 *perm)
{
	const u8 command[22] = {
		0x0, 0xc1,		/* TPM_TAG */
		0x0, 0x0, 0x0, 0x16,	/* parameter size */
		0x0, 0x0, 0x0, 0x65,	/* TPM_COMMAND_CODE */
		0x0, 0x0, 0x0, 0x11,
		0x0, 0x0, 0x0, 0x4,
	};
	const size_t index_offset = 18;
	const size_t perm_offset = 74;
	u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
	size_t response_length = sizeof(response);
	u32 err;

	if (pack_byte_string(buf, sizeof(buf), "sd",
			     0, command, sizeof(command),
			     index_offset, index))
		return TPM_LIB_ERROR;
	err = tpm_sendrecv_command(dev, buf, response, &response_length);
	if (err)
		return err;
	if (unpack_byte_string(response, response_length, "d",
			       perm_offset, perm))
		return TPM_LIB_ERROR;

	return 0;
}

#ifdef CONFIG_TPM_FLUSH_RESOURCES
u32 tpm1_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type)
{
	const u8 command[18] = {
		0x00, 0xc1,             /* TPM_TAG */
		0x00, 0x00, 0x00, 0x12, /* parameter size */
		0x00, 0x00, 0x00, 0xba, /* TPM_COMMAND_CODE */
		0x00, 0x00, 0x00, 0x00, /* key handle */
		0x00, 0x00, 0x00, 0x00, /* resource type */
	};
	const size_t key_handle_offset = 10;
	const size_t resource_type_offset = 14;
	u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
	size_t response_length = sizeof(response);
	u32 err;

	if (pack_byte_string(buf, sizeof(buf), "sdd",
			     0, command, sizeof(command),
			     key_handle_offset, key_handle,
			     resource_type_offset, resource_type))
		return TPM_LIB_ERROR;

	err = tpm_sendrecv_command(dev, buf, response, &response_length);
	if (err)
		return err;
	return 0;
}
#endif /* CONFIG_TPM_FLUSH_RESOURCES */

#ifdef CONFIG_TPM_AUTH_SESSIONS

/**
 * Fill an authentication block in a request.
 * This func can create the first as well as the second auth block (for
 * double authorized commands).
 *
 * @param request	pointer to the request (w/ uninitialised auth data)
 * @param request_len0	length of the request without auth data
 * @param handles_len	length of the handles area in request
 * @param auth_session	pointer to the (valid) auth session to be used
 * @param request_auth	pointer to the auth block of the request to be filled
 * @param auth		authentication data (HMAC key)
 */
static u32 create_request_auth(const void *request, size_t request_len0,
			       size_t handles_len,
			       struct session_data *auth_session,
			       void *request_auth, const void *auth)
{
	u8 hmac_data[DIGEST_LENGTH * 3 + 1];
	sha1_context hash_ctx;
	const size_t command_code_offset = 6;
	const size_t auth_nonce_odd_offset = 4;
	const size_t auth_continue_offset = 24;
	const size_t auth_auth_offset = 25;

	if (!auth_session || !auth_session->valid)
		return TPM_LIB_ERROR;

	sha1_starts(&hash_ctx);
	sha1_update(&hash_ctx, request + command_code_offset, 4);
	if (request_len0 > TPM_REQUEST_HEADER_LENGTH + handles_len)
		sha1_update(&hash_ctx,
			    request + TPM_REQUEST_HEADER_LENGTH + handles_len,
			    request_len0 - TPM_REQUEST_HEADER_LENGTH
			    - handles_len);
	sha1_finish(&hash_ctx, hmac_data);

	sha1_starts(&hash_ctx);
	sha1_update(&hash_ctx, auth_session->nonce_odd, DIGEST_LENGTH);
	sha1_update(&hash_ctx, hmac_data, sizeof(hmac_data));
	sha1_finish(&hash_ctx, auth_session->nonce_odd);

	if (pack_byte_string(request_auth, TPM_REQUEST_AUTH_LENGTH, "dsb",
			     0, auth_session->handle,
			     auth_nonce_odd_offset, auth_session->nonce_odd,
			     DIGEST_LENGTH,
			     auth_continue_offset, 1))
		return TPM_LIB_ERROR;
	if (pack_byte_string(hmac_data, sizeof(hmac_data), "ss",
			     DIGEST_LENGTH,
			     auth_session->nonce_even,
			     DIGEST_LENGTH,
			     2 * DIGEST_LENGTH,
			     request_auth + auth_nonce_odd_offset,
			     DIGEST_LENGTH + 1))
		return TPM_LIB_ERROR;
	sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
		  request_auth + auth_auth_offset);

	return TPM_SUCCESS;
}

/**
 * Verify an authentication block in a response.
 * Since this func updates the nonce_even in the session data it has to be
 * called when receiving a succesfull AUTH response.
 * This func can verify the first as well as the second auth block (for
 * double authorized commands).
 *
 * @param command_code	command code of the request
 * @param response	pointer to the request (w/ uninitialised auth data)
 * @param handles_len	length of the handles area in response
 * @param auth_session	pointer to the (valid) auth session to be used
 * @param response_auth	pointer to the auth block of the response to be verified
 * @param auth		authentication data (HMAC key)
 */
static u32 verify_response_auth(u32 command_code, const void *response,
				size_t response_len0, size_t handles_len,
				struct session_data *auth_session,
				const void *response_auth, const void *auth)
{
	u8 hmac_data[DIGEST_LENGTH * 3 + 1];
	u8 computed_auth[DIGEST_LENGTH];
	sha1_context hash_ctx;
	const size_t return_code_offset = 6;
	const size_t auth_continue_offset = 20;
	const size_t auth_auth_offset = 21;
	u8 auth_continue;

	if (!auth_session || !auth_session->valid)
		return TPM_AUTHFAIL;
	if (pack_byte_string(hmac_data, sizeof(hmac_data), "d",
			     0, command_code))
		return TPM_LIB_ERROR;
	if (response_len0 < TPM_RESPONSE_HEADER_LENGTH)
		return TPM_LIB_ERROR;

	sha1_starts(&hash_ctx);
	sha1_update(&hash_ctx, response + return_code_offset, 4);
	sha1_update(&hash_ctx, hmac_data, 4);
	if (response_len0 > TPM_RESPONSE_HEADER_LENGTH + handles_len)
		sha1_update(&hash_ctx,
			    response + TPM_RESPONSE_HEADER_LENGTH + handles_len,
			    response_len0 - TPM_RESPONSE_HEADER_LENGTH
			    - handles_len);
	sha1_finish(&hash_ctx, hmac_data);

	memcpy(auth_session->nonce_even, response_auth, DIGEST_LENGTH);
	auth_continue = ((u8 *)response_auth)[auth_continue_offset];
	if (pack_byte_string(hmac_data, sizeof(hmac_data), "ssb",
			     DIGEST_LENGTH,
			     response_auth,
			     DIGEST_LENGTH,
			     2 * DIGEST_LENGTH,
			     auth_session->nonce_odd,
			     DIGEST_LENGTH,
			     3 * DIGEST_LENGTH,
			     auth_continue))
		return TPM_LIB_ERROR;

	sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
		  computed_auth);

	if (memcmp(computed_auth, response_auth + auth_auth_offset,
		   DIGEST_LENGTH))
		return TPM_AUTHFAIL;

	return TPM_SUCCESS;
}

u32 tpm1_terminate_auth_session(struct udevice *dev, u32 auth_handle)
{
	const u8 command[18] = {
		0x00, 0xc1,		/* TPM_TAG */
		0x00, 0x00, 0x00, 0x00,	/* parameter size */
		0x00, 0x00, 0x00, 0xba,	/* TPM_COMMAND_CODE */
		0x00, 0x00, 0x00, 0x00,	/* TPM_HANDLE */
		0x00, 0x00, 0x00, 0x02,	/* TPM_RESOURCE_TYPE */
	};
	const size_t req_handle_offset = TPM_REQUEST_HEADER_LENGTH;
	u8 request[COMMAND_BUFFER_SIZE];

	if (pack_byte_string(request, sizeof(request), "sd",
			     0, command, sizeof(command),
			     req_handle_offset, auth_handle))
		return TPM_LIB_ERROR;
	if (oiap_session.valid && oiap_session.handle == auth_handle)
		oiap_session.valid = 0;

	return tpm_sendrecv_command(dev, request, NULL, NULL);
}

u32 tpm1_end_oiap(struct udevice *dev)
{
	u32 err = TPM_SUCCESS;

	if (oiap_session.valid)
		err = tpm1_terminate_auth_session(dev, oiap_session.handle);
	return err;
}

u32 tpm1_oiap(struct udevice *dev, u32 *auth_handle)
{
	const u8 command[10] = {
		0x00, 0xc1,		/* TPM_TAG */
		0x00, 0x00, 0x00, 0x0a,	/* parameter size */
		0x00, 0x00, 0x00, 0x0a,	/* TPM_COMMAND_CODE */
	};
	const size_t res_auth_handle_offset = TPM_RESPONSE_HEADER_LENGTH;
	const size_t res_nonce_even_offset = TPM_RESPONSE_HEADER_LENGTH + 4;
	u8 response[COMMAND_BUFFER_SIZE];
	size_t response_length = sizeof(response);
	u32 err;

	if (oiap_session.valid)
		tpm1_terminate_auth_session(dev, oiap_session.handle);

	err = tpm_sendrecv_command(dev, command, response, &response_length);
	if (err)
		return err;
	if (unpack_byte_string(response, response_length, "ds",
			       res_auth_handle_offset, &oiap_session.handle,
			       res_nonce_even_offset, &oiap_session.nonce_even,
			       (u32)DIGEST_LENGTH))
		return TPM_LIB_ERROR;
	oiap_session.valid = 1;
	if (auth_handle)
		*auth_handle = oiap_session.handle;
	return 0;
}

u32 tpm1_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key,
			size_t key_length, const void *parent_key_usage_auth,
			u32 *key_handle)
{
	const u8 command[14] = {
		0x00, 0xc2,		/* TPM_TAG */
		0x00, 0x00, 0x00, 0x00,	/* parameter size */
		0x00, 0x00, 0x00, 0x41,	/* TPM_COMMAND_CODE */
		0x00, 0x00, 0x00, 0x00,	/* parent handle */
	};
	const size_t req_size_offset = 2;
	const size_t req_parent_handle_offset = TPM_REQUEST_HEADER_LENGTH;
	const size_t req_key_offset = TPM_REQUEST_HEADER_LENGTH + 4;
	const size_t res_handle_offset = TPM_RESPONSE_HEADER_LENGTH;
	u8 request[sizeof(command) + TPM_KEY12_MAX_LENGTH +
		   TPM_REQUEST_AUTH_LENGTH];
	u8 response[COMMAND_BUFFER_SIZE];
	size_t response_length = sizeof(response);
	u32 err;

	if (!oiap_session.valid) {
		err = tpm1_oiap(dev, NULL);
		if (err)
			return err;
	}
	if (pack_byte_string(request, sizeof(request), "sdds",
			     0, command, sizeof(command),
			     req_size_offset,
			     sizeof(command) + key_length
			     + TPM_REQUEST_AUTH_LENGTH,
			     req_parent_handle_offset, parent_handle,
			     req_key_offset, key, key_length
		))
		return TPM_LIB_ERROR;

	err = create_request_auth(request, sizeof(command) + key_length, 4,
				  &oiap_session,
				  request + sizeof(command) + key_length,
				  parent_key_usage_auth);
	if (err)
		return err;
	err = tpm_sendrecv_command(dev, request, response, &response_length);
	if (err) {
		if (err == TPM_AUTHFAIL)
			oiap_session.valid = 0;
		return err;
	}

	err = verify_response_auth(0x00000041, response,
				   response_length - TPM_RESPONSE_AUTH_LENGTH,
				   4, &oiap_session,
				   response + response_length -
				   TPM_RESPONSE_AUTH_LENGTH,
				   parent_key_usage_auth);
	if (err)
		return err;

	if (key_handle) {
		if (unpack_byte_string(response, response_length, "d",
				       res_handle_offset, key_handle))
			return TPM_LIB_ERROR;
	}

	return 0;
}

u32 tpm1_get_pub_key_oiap(struct udevice *dev, u32 key_handle,
			  const void *usage_auth, void *pubkey,
			  size_t *pubkey_len)
{
	const u8 command[14] = {
		0x00, 0xc2,		/* TPM_TAG */
		0x00, 0x00, 0x00, 0x00,	/* parameter size */
		0x00, 0x00, 0x00, 0x21,	/* TPM_COMMAND_CODE */
		0x00, 0x00, 0x00, 0x00,	/* key handle */
	};
	const size_t req_size_offset = 2;
	const size_t req_key_handle_offset = TPM_REQUEST_HEADER_LENGTH;
	const size_t res_pubkey_offset = TPM_RESPONSE_HEADER_LENGTH;
	u8 request[sizeof(command) + TPM_REQUEST_AUTH_LENGTH];
	u8 response[TPM_RESPONSE_HEADER_LENGTH + TPM_PUBKEY_MAX_LENGTH +
		    TPM_RESPONSE_AUTH_LENGTH];
	size_t response_length = sizeof(response);
	u32 err;

	if (!oiap_session.valid) {
		err = tpm1_oiap(dev, NULL);
		if (err)
			return err;
	}
	if (pack_byte_string(request, sizeof(request), "sdd",
			     0, command, sizeof(command),
			     req_size_offset,
			     (u32)(sizeof(command)
			     + TPM_REQUEST_AUTH_LENGTH),
			     req_key_handle_offset, key_handle
		))
		return TPM_LIB_ERROR;
	err = create_request_auth(request, sizeof(command), 4, &oiap_session,
				  request + sizeof(command), usage_auth);
	if (err)
		return err;
	err = tpm_sendrecv_command(dev, request, response, &response_length);
	if (err) {
		if (err == TPM_AUTHFAIL)
			oiap_session.valid = 0;
		return err;
	}
	err = verify_response_auth(0x00000021, response,
				   response_length - TPM_RESPONSE_AUTH_LENGTH,
				   0, &oiap_session,
				   response + response_length -
				   TPM_RESPONSE_AUTH_LENGTH,
				   usage_auth);
	if (err)
		return err;

	if (pubkey) {
		if ((response_length - TPM_RESPONSE_HEADER_LENGTH
		     - TPM_RESPONSE_AUTH_LENGTH) > *pubkey_len)
			return TPM_LIB_ERROR;
		*pubkey_len = response_length - TPM_RESPONSE_HEADER_LENGTH
			- TPM_RESPONSE_AUTH_LENGTH;
		memcpy(pubkey, response + res_pubkey_offset,
		       response_length - TPM_RESPONSE_HEADER_LENGTH
		       - TPM_RESPONSE_AUTH_LENGTH);
	}

	return 0;
}

#ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
u32 tpm1_find_key_sha1(struct udevice *dev, const u8 auth[20],
		       const u8 pubkey_digest[20], u32 *handle)
{
	u16 key_count;
	u32 key_handles[10];
	u8 buf[288];
	u8 *ptr;
	u32 err;
	u8 digest[20];
	size_t buf_len;
	unsigned int i;

	/* fetch list of already loaded keys in the TPM */
	err = tpm1_get_capability(dev, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
				 sizeof(buf));
	if (err)
		return -1;
	key_count = get_unaligned_be16(buf);
	ptr = buf + 2;
	for (i = 0; i < key_count; ++i, ptr += 4)
		key_handles[i] = get_unaligned_be32(ptr);

	/* now search a(/ the) key which we can access with the given auth */
	for (i = 0; i < key_count; ++i) {
		buf_len = sizeof(buf);
		err = tpm1_get_pub_key_oiap(dev, key_handles[i], auth, buf, &buf_len);
		if (err && err != TPM_AUTHFAIL)
			return -1;
		if (err)
			continue;
		sha1_csum(buf, buf_len, digest);
		if (!memcmp(digest, pubkey_digest, 20)) {
			*handle = key_handles[i];
			return 0;
		}
	}
	return 1;
}
#endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */

#endif /* CONFIG_TPM_AUTH_SESSIONS */

u32 tpm1_get_random(struct udevice *dev, void *data, u32 count)
{
	const u8 command[14] = {
		0x0, 0xc1,		/* TPM_TAG */
		0x0, 0x0, 0x0, 0xe,	/* parameter size */
		0x0, 0x0, 0x0, 0x46,	/* TPM_COMMAND_CODE */
	};
	const size_t length_offset = 10;
	const size_t data_size_offset = 10;
	const size_t data_offset = 14;
	u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
	size_t response_length = sizeof(response);
	u32 data_size;
	u8 *out = data;

	while (count > 0) {
		u32 this_bytes = min((size_t)count,
				     sizeof(response) - data_offset);
		u32 err;

		if (pack_byte_string(buf, sizeof(buf), "sd",
				     0, command, sizeof(command),
				     length_offset, this_bytes))
			return TPM_LIB_ERROR;
		err = tpm_sendrecv_command(dev, buf, response,
					   &response_length);
		if (err)
			return err;
		if (unpack_byte_string(response, response_length, "d",
				       data_size_offset, &data_size))
			return TPM_LIB_ERROR;
		if (data_size > count)
			return TPM_LIB_ERROR;
		if (unpack_byte_string(response, response_length, "s",
				       data_offset, out, data_size))
			return TPM_LIB_ERROR;

		count -= data_size;
		out += data_size;
	}

	return 0;
}
