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

#include <common.h>
#include <command.h>
#include <dm.h>
#include <env.h>
#include <malloc.h>
#include <asm/unaligned.h>
#include <linux/string.h>
#include <tpm-common.h>
#include <tpm_api.h>
#include "tpm-user-utils.h"

static struct udevice *tpm_dev;

/**
 * Print a byte string in hexdecimal format, 16-bytes per line.
 *
 * @param data		byte string to be printed
 * @param count		number of bytes to be printed
 */
void print_byte_string(u8 *data, size_t count)
{
	int i, print_newline = 0;

	for (i = 0; i < count; i++) {
		printf(" %02x", data[i]);
		print_newline = (i % 16 == 15);
		if (print_newline)
			putc('\n');
	}
	/* Avoid duplicated newline at the end */
	if (!print_newline)
		putc('\n');
}

/**
 * Convert a text string of hexdecimal values into a byte string.
 *
 * @param bytes		text string of hexdecimal values with no space
 *			between them
 * @param data		output buffer for byte string.  The caller has to make
 *			sure it is large enough for storing the output.  If
 *			NULL is passed, a large enough buffer will be allocated,
 *			and the caller must free it.
 * @param count_ptr	output variable for the length of byte string
 * Return: pointer to output buffer
 */
void *parse_byte_string(char *bytes, u8 *data, size_t *count_ptr)
{
	char byte[3];
	size_t count, length;
	int i;

	if (!bytes)
		return NULL;
	length = strlen(bytes);
	count = length / 2;

	if (!data)
		data = malloc(count);
	if (!data)
		return NULL;

	byte[2] = '\0';
	for (i = 0; i < length; i += 2) {
		byte[0] = bytes[i];
		byte[1] = bytes[i + 1];
		data[i / 2] = (u8)hextoul(byte, NULL);
	}

	if (count_ptr)
		*count_ptr = count;

	return data;
}

/**
 * report_return_code() - Report any error and return failure or success
 *
 * @param return_code	TPM command return code
 * Return: value of enum command_ret_t
 */
int report_return_code(int return_code)
{
	if (return_code) {
		printf("Error: %d\n", return_code);
		return CMD_RET_FAILURE;
	} else {
		return CMD_RET_SUCCESS;
	}
}

/**
 * Return number of values defined by a type string.
 *
 * @param type_str	type string
 * Return: number of values of type string
 */
int type_string_get_num_values(const char *type_str)
{
	return strlen(type_str);
}

/**
 * Return total size of values defined by a type string.
 *
 * @param type_str	type string
 * Return: total size of values of type string, or 0 if type string
 *  contains illegal type character.
 */
size_t type_string_get_space_size(const char *type_str)
{
	size_t size;

	for (size = 0; *type_str; type_str++) {
		switch (*type_str) {
		case 'b':
			size += 1;
			break;
		case 'w':
			size += 2;
			break;
		case 'd':
			size += 4;
			break;
		default:
			return 0;
		}
	}

	return size;
}

/**
 * Allocate a buffer large enough to hold values defined by a type
 * string.  The caller has to free the buffer.
 *
 * @param type_str	type string
 * @param count		pointer for storing size of buffer
 * Return: pointer to buffer or NULL on error
 */
void *type_string_alloc(const char *type_str, u32 *count)
{
	void *data;
	size_t size;

	size = type_string_get_space_size(type_str);
	if (!size)
		return NULL;
	data = malloc(size);
	if (data)
		*count = size;

	return data;
}

/**
 * Pack values defined by a type string into a buffer.  The buffer must have
 * large enough space.
 *
 * @param type_str	type string
 * @param values	text strings of values to be packed
 * @param data		output buffer of values
 * Return: 0 on success, non-0 on error
 */
int type_string_pack(const char *type_str, char * const values[],
		     u8 *data)
{
	size_t offset;
	u32 value;

	for (offset = 0; *type_str; type_str++, values++) {
		value = simple_strtoul(values[0], NULL, 0);
		switch (*type_str) {
		case 'b':
			data[offset] = value;
			offset += 1;
			break;
		case 'w':
			put_unaligned_be16(value, data + offset);
			offset += 2;
			break;
		case 'd':
			put_unaligned_be32(value, data + offset);
			offset += 4;
			break;
		default:
			return -1;
		}
	}

	return 0;
}

/**
 * Read values defined by a type string from a buffer, and write these values
 * to environment variables.
 *
 * @param type_str	type string
 * @param data		input buffer of values
 * @param vars		names of environment variables
 * Return: 0 on success, non-0 on error
 */
int type_string_write_vars(const char *type_str, u8 *data,
			   char * const vars[])
{
	size_t offset;
	u32 value;

	for (offset = 0; *type_str; type_str++, vars++) {
		switch (*type_str) {
		case 'b':
			value = data[offset];
			offset += 1;
			break;
		case 'w':
			value = get_unaligned_be16(data + offset);
			offset += 2;
			break;
		case 'd':
			value = get_unaligned_be32(data + offset);
			offset += 4;
			break;
		default:
			return -1;
		}
		if (env_set_ulong(*vars, value))
			return -1;
	}

	return 0;
}

static int tpm_show_device(void)
{
	struct udevice *dev;
	char buf[80];
	int n = 0, rc;

	for_each_tpm_device(dev) {
		rc = tpm_get_desc(dev, buf, sizeof(buf));
		if (rc < 0)
			printf("device %d: can't get info\n", n);
		else
			printf("device %d: %s\n", n, buf);

		n++;
	};

	return 0;
}

static int tpm_set_device(unsigned long num)
{
	struct udevice *dev;
	unsigned long n = 0;
	int rc = CMD_RET_FAILURE;

	for_each_tpm_device(dev) {
		if (n == num) {
			rc = 0;
			break;
		}

		n++;
	}

	if (!rc)
		tpm_dev = dev;

	return rc;
}

int get_tpm(struct udevice **devp)
{
	int rc;

	/*
	 * To keep a backward compatibility with previous code,
	 * if a tpm device is not explicitly set, we set the first one.
	 */
	if (!tpm_dev) {
		rc = tpm_set_device(0);
		if (rc) {
			printf("Couldn't set TPM 0 (rc = %d)\n", rc);
			return CMD_RET_FAILURE;
		}
	}

	if (devp)
		*devp = tpm_dev;

	return 0;
}

int do_tpm_device(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	unsigned long num;
	int rc;

	if (argc == 2) {
		num = dectoul(argv[1], NULL);

		rc = tpm_set_device(num);
		if (rc)
			printf("Couldn't set TPM %lu (rc = %d)\n", num, rc);
	} else {
		rc = tpm_show_device();
	}

	return rc;
}

int do_tpm_info(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	struct udevice *dev;
	char buf[80];
	int rc;

	rc = get_tpm(&dev);
	if (rc)
		return rc;
	rc = tpm_get_desc(dev, buf, sizeof(buf));
	if (rc < 0) {
		printf("Couldn't get TPM info (%d)\n", rc);
		return CMD_RET_FAILURE;
	}
	printf("%s\n", buf);

	return 0;
}

int do_tpm_report_state(struct cmd_tbl *cmdtp, int flag, int argc,
			char *const argv[])
{
	struct udevice *dev;
	char buf[80];
	int rc;

	rc = get_tpm(&dev);
	if (rc)
		return rc;
	rc = tpm_report_state(dev, buf, sizeof(buf));
	if (rc < 0) {
		printf("Couldn't get TPM state (%d)\n", rc);
		return CMD_RET_FAILURE;
	}
	printf("%s\n", buf);

	return 0;
}

int do_tpm_init(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	struct udevice *dev;
	int rc;

	if (argc != 1)
		return CMD_RET_USAGE;
	rc = get_tpm(&dev);
	if (rc)
		return rc;

	return report_return_code(tpm_init(dev));
}

int do_tpm_autostart(struct cmd_tbl *cmdtp, int flag, int argc,
		     char *const argv[])
{
	struct udevice *dev;
	int rc;

	if (argc != 1)
		return CMD_RET_USAGE;
	rc = get_tpm(&dev);
	if (rc)
		return rc;

	return report_return_code(tpm_auto_start(dev));
}

int do_tpm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	struct cmd_tbl *tpm_commands, *cmd;
	struct tpm_chip_priv *priv;
	struct udevice *dev;
	unsigned int size;
	int ret;

	if (argc < 2)
		return CMD_RET_USAGE;

	ret = get_tpm(&dev);
	if (ret)
		return ret;

	priv = dev_get_uclass_priv(dev);

	/* Below getters return NULL if the desired stack is not built */
	switch (priv->version) {
	case TPM_V1:
		tpm_commands = get_tpm1_commands(&size);
		break;
	case TPM_V2:
		tpm_commands = get_tpm2_commands(&size);
		break;
	default:
		tpm_commands = NULL;
	}

	if (!tpm_commands)
		return CMD_RET_USAGE;

	cmd = find_cmd_tbl(argv[1], tpm_commands, size);
	if (!cmd)
		return CMD_RET_USAGE;

	return cmd->cmd(cmdtp, flag, argc - 1, argv + 1);
}
