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

#include <common.h>
#include <stdarg.h>
#include <u-boot/sha1.h>
#include <tpm.h>
#include <asm/unaligned.h>

/* Internal error of TPM command library */
#define TPM_LIB_ERROR	((uint32_t)~0u)

/* Useful constants */
enum {
	COMMAND_BUFFER_SIZE		= 256,
	TPM_PUBEK_SIZE			= 256,
	TPM_REQUEST_HEADER_LENGTH	= 10,
	TPM_RESPONSE_HEADER_LENGTH	= 10,
	PCR_DIGEST_LENGTH		= 20,
	DIGEST_LENGTH			= 20,
	TPM_REQUEST_AUTH_LENGTH		= 45,
	TPM_RESPONSE_AUTH_LENGTH	= 41,
	/* some max lengths, valid for RSA keys <= 2048 bits */
	TPM_KEY12_MAX_LENGTH		= 618,
	TPM_PUBKEY_MAX_LENGTH		= 288,
};

#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;
	uint32_t	handle;
	uint8_t		nonce_even[DIGEST_LENGTH];
	uint8_t		nonce_odd[DIGEST_LENGTH];
};

static struct session_data oiap_session = {0, };

#endif /* CONFIG_TPM_AUTH_SESSIONS */

/**
 * Pack data into a byte string.  The data types are specified in
 * the format string: 'b' means unsigned byte, 'w' unsigned word,
 * 'd' unsigned double word, and 's' byte string.  The data are a
 * series of offsets and values (for type byte string there are also
 * lengths).  The data values are packed into the byte string
 * sequentially, and so a latter value could over-write a former
 * value.
 *
 * @param str		output string
 * @param size		size of output string
 * @param format	format string
 * @param ...		data points
 * @return 0 on success, non-0 on error
 */
int pack_byte_string(uint8_t *str, size_t size, const char *format, ...)
{
	va_list args;
	size_t offset = 0, length = 0;
	uint8_t *data = NULL;
	uint32_t value = 0;

	va_start(args, format);
	for (; *format; format++) {
		switch (*format) {
		case 'b':
			offset = va_arg(args, size_t);
			value = va_arg(args, int);
			length = 1;
			break;
		case 'w':
			offset = va_arg(args, size_t);
			value = va_arg(args, int);
			length = 2;
			break;
		case 'd':
			offset = va_arg(args, size_t);
			value = va_arg(args, uint32_t);
			length = 4;
			break;
		case 's':
			offset = va_arg(args, size_t);
			data = va_arg(args, uint8_t *);
			length = va_arg(args, uint32_t);
			break;
		default:
			debug("Couldn't recognize format string\n");
			return -1;
		}

		if (offset + length > size)
			return -1;

		switch (*format) {
		case 'b':
			str[offset] = value;
			break;
		case 'w':
			put_unaligned_be16(value, str + offset);
			break;
		case 'd':
			put_unaligned_be32(value, str + offset);
			break;
		case 's':
			memcpy(str + offset, data, length);
			break;
		}
	}
	va_end(args);

	return 0;
}

/**
 * Unpack data from a byte string.  The data types are specified in
 * the format string: 'b' means unsigned byte, 'w' unsigned word,
 * 'd' unsigned double word, and 's' byte string.  The data are a
 * series of offsets and pointers (for type byte string there are also
 * lengths).
 *
 * @param str		output string
 * @param size		size of output string
 * @param format	format string
 * @param ...		data points
 * @return 0 on success, non-0 on error
 */
int unpack_byte_string(const uint8_t *str, size_t size, const char *format, ...)
{
	va_list args;
	size_t offset = 0, length = 0;
	uint8_t *ptr8 = NULL;
	uint16_t *ptr16 = NULL;
	uint32_t *ptr32 = NULL;

	va_start(args, format);
	for (; *format; format++) {
		switch (*format) {
		case 'b':
			offset = va_arg(args, size_t);
			ptr8 = va_arg(args, uint8_t *);
			length = 1;
			break;
		case 'w':
			offset = va_arg(args, size_t);
			ptr16 = va_arg(args, uint16_t *);
			length = 2;
			break;
		case 'd':
			offset = va_arg(args, size_t);
			ptr32 = va_arg(args, uint32_t *);
			length = 4;
			break;
		case 's':
			offset = va_arg(args, size_t);
			ptr8 = va_arg(args, uint8_t *);
			length = va_arg(args, uint32_t);
			break;
		default:
			debug("Couldn't recognize format string\n");
			return -1;
		}

		if (offset + length > size)
			return -1;

		switch (*format) {
		case 'b':
			*ptr8 = str[offset];
			break;
		case 'w':
			*ptr16 = get_unaligned_be16(str + offset);
			break;
		case 'd':
			*ptr32 = get_unaligned_be32(str + offset);
			break;
		case 's':
			memcpy(ptr8, str + offset, length);
			break;
		}
	}
	va_end(args);

	return 0;
}

/**
 * Get TPM command size.
 *
 * @param command	byte string of TPM command
 * @return command size of the TPM command
 */
static uint32_t tpm_command_size(const void *command)
{
	const size_t command_size_offset = 2;
	return get_unaligned_be32(command + command_size_offset);
}

/**
 * Get TPM response return code, which is one of TPM_RESULT values.
 *
 * @param response	byte string of TPM response
 * @return return code of the TPM response
 */
static uint32_t tpm_return_code(const void *response)
{
	const size_t return_code_offset = 6;
	return get_unaligned_be32(response + return_code_offset);
}

/**
 * Send a TPM command and return response's return code, and optionally
 * return response to caller.
 *
 * @param command	byte string of TPM command
 * @param response	output buffer for TPM response, or NULL if the
 *			caller does not care about it
 * @param size_ptr	output buffer size (input parameter) and TPM
 *			response length (output parameter); this parameter
 *			is a bidirectional
 * @return return code of the TPM response
 */
static uint32_t tpm_sendrecv_command(const void *command,
		void *response, size_t *size_ptr)
{
	uint8_t response_buffer[COMMAND_BUFFER_SIZE];
	size_t response_length;
	uint32_t err;

	if (response) {
		response_length = *size_ptr;
	} else {
		response = response_buffer;
		response_length = sizeof(response_buffer);
	}
	err = tis_sendrecv(command, tpm_command_size(command),
			response, &response_length);
	if (err)
		return TPM_LIB_ERROR;
	if (size_ptr)
		*size_ptr = response_length;

	return tpm_return_code(response);
}

uint32_t tpm_init(void)
{
	uint32_t err;

	err = tis_init();
	if (err)
		return err;

	return tis_open();
}

uint32_t tpm_startup(enum tpm_startup_type mode)
{
	const uint8_t command[12] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0,
	};
	const size_t mode_offset = 10;
	uint8_t 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(buf, NULL, NULL);
}

uint32_t tpm_self_test_full(void)
{
	const uint8_t command[10] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50,
	};
	return tpm_sendrecv_command(command, NULL, NULL);
}

uint32_t tpm_continue_self_test(void)
{
	const uint8_t command[10] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53,
	};
	return tpm_sendrecv_command(command, NULL, NULL);
}

uint32_t tpm_nv_define_space(uint32_t index, uint32_t perm, uint32_t size)
{
	const uint8_t 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;
	uint8_t 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(buf, NULL, NULL);
}

uint32_t tpm_nv_read_value(uint32_t index, void *data, uint32_t count)
{
	const uint8_t 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;
	uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
	size_t response_length = sizeof(response);
	uint32_t data_size;
	uint32_t 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(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;
}

uint32_t tpm_nv_write_value(uint32_t index, const void *data, uint32_t length)
{
	const uint8_t 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 uint32_t total_length =
		TPM_REQUEST_HEADER_LENGTH + write_info_size + length;
	uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
	size_t response_length = sizeof(response);
	uint32_t 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(buf, response, &response_length);
	if (err)
		return err;

	return 0;
}

uint32_t tpm_extend(uint32_t index, const void *in_digest, void *out_digest)
{
	const uint8_t 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;
	uint8_t buf[COMMAND_BUFFER_SIZE];
	uint8_t response[TPM_RESPONSE_HEADER_LENGTH + PCR_DIGEST_LENGTH];
	size_t response_length = sizeof(response);
	uint32_t 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(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;
}

uint32_t tpm_pcr_read(uint32_t index, void *data, size_t count)
{
	const uint8_t 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;
	uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
	size_t response_length = sizeof(response);
	uint32_t 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(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;
}

uint32_t tpm_tsc_physical_presence(uint16_t presence)
{
	const uint8_t command[12] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x0,
	};
	const size_t presence_offset = 10;
	uint8_t 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(buf, NULL, NULL);
}

uint32_t tpm_read_pubek(void *data, size_t count)
{
	const uint8_t 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;
	uint8_t response[COMMAND_BUFFER_SIZE + TPM_PUBEK_SIZE];
	size_t response_length = sizeof(response);
	uint32_t data_size;
	uint32_t err;

	err = tpm_sendrecv_command(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;
}

uint32_t tpm_force_clear(void)
{
	const uint8_t command[10] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d,
	};

	return tpm_sendrecv_command(command, NULL, NULL);
}

uint32_t tpm_physical_enable(void)
{
	const uint8_t command[10] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f,
	};

	return tpm_sendrecv_command(command, NULL, NULL);
}

uint32_t tpm_physical_disable(void)
{
	const uint8_t command[10] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70,
	};

	return tpm_sendrecv_command(command, NULL, NULL);
}

uint32_t tpm_physical_set_deactivated(uint8_t state)
{
	const uint8_t command[11] = {
		0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72,
	};
	const size_t state_offset = 10;
	uint8_t 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(buf, NULL, NULL);
}

uint32_t tpm_get_capability(uint32_t cap_area, uint32_t sub_cap,
		void *cap, size_t count)
{
	const uint8_t 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;
	uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
	size_t response_length = sizeof(response);
	uint32_t cap_size;
	uint32_t 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(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;
}

#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 uint32_t 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)
{
	uint8_t 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 uint32_t verify_response_auth(uint32_t 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)
{
	uint8_t hmac_data[DIGEST_LENGTH * 3 + 1];
	uint8_t 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;
	uint8_t 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 = ((uint8_t *)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;
}


uint32_t tpm_terminate_auth_session(uint32_t auth_handle)
{
	const uint8_t 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_RESSOURCE_TYPE */
	};
	const size_t req_handle_offset = TPM_REQUEST_HEADER_LENGTH;
	uint8_t 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(request, NULL, NULL);
}

uint32_t tpm_end_oiap(void)
{
	uint32_t err = TPM_SUCCESS;
	if (oiap_session.valid)
		err = tpm_terminate_auth_session(oiap_session.handle);
	return err;
}

uint32_t tpm_oiap(uint32_t *auth_handle)
{
	const uint8_t 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;
	uint8_t response[COMMAND_BUFFER_SIZE];
	size_t response_length = sizeof(response);
	uint32_t err;

	if (oiap_session.valid)
		tpm_terminate_auth_session(oiap_session.handle);

	err = tpm_sendrecv_command(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,
			       (uint32_t)DIGEST_LENGTH))
		return TPM_LIB_ERROR;
	oiap_session.valid = 1;
	if (auth_handle)
		*auth_handle = oiap_session.handle;
	return 0;
}

uint32_t tpm_load_key2_oiap(uint32_t parent_handle,
		const void *key, size_t key_length,
		const void *parent_key_usage_auth,
		uint32_t *key_handle)
{
	const uint8_t 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;
	uint8_t request[sizeof(command) + TPM_KEY12_MAX_LENGTH
			+ TPM_REQUEST_AUTH_LENGTH];
	uint8_t response[COMMAND_BUFFER_SIZE];
	size_t response_length = sizeof(response);
	uint32_t err;

	if (!oiap_session.valid) {
		err = tpm_oiap(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(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;
}

uint32_t tpm_get_pub_key_oiap(uint32_t key_handle, const void *usage_auth,
			void *pubkey, size_t *pubkey_len)
{
	const uint8_t 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;
	uint8_t request[sizeof(command) + TPM_REQUEST_AUTH_LENGTH];
	uint8_t response[TPM_RESPONSE_HEADER_LENGTH + TPM_PUBKEY_MAX_LENGTH
			+ TPM_RESPONSE_AUTH_LENGTH];
	size_t response_length = sizeof(response);
	uint32_t err;

	if (!oiap_session.valid) {
		err = tpm_oiap(NULL);
		if (err)
			return err;
	}
	if (pack_byte_string(request, sizeof(request), "sdd",
			     0, command, sizeof(command),
			     req_size_offset,
			     (uint32_t)(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(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;
}

#endif /* CONFIG_TPM_AUTH_SESSIONS */
