// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2015 Google, Inc
 */

#include <common.h>
#include <command.h>
#include <cpu_func.h>
#include <log.h>
#include <tpm-v1.h>
#include "tpm-user-utils.h"
#include <tpm_api.h>

/* Prints error and returns on failure */
#define TPM_CHECK(tpm_command) do { \
	uint32_t result; \
	\
	result = (tpm_command); \
	if (result != TPM_SUCCESS) { \
		printf("TEST FAILED: line %d: " #tpm_command ": 0x%x\n", \
			__LINE__, result); \
		return result; \
	} \
} while (0)

#define INDEX0			0xda70
#define INDEX1			0xda71
#define INDEX2			0xda72
#define INDEX3			0xda73
#define INDEX_INITIALISED	0xda80
#define PHYS_PRESENCE		4
#define PRESENCE		8

static uint32_t TlclStartupIfNeeded(struct udevice *dev)
{
	uint32_t result = tpm_startup(dev, TPM_ST_CLEAR);

	return result == TPM_INVALID_POSTINIT ? TPM_SUCCESS : result;
}

static int test_timer(struct udevice *dev)
{
	printf("get_timer(0) = %lu\n", get_timer(0));
	return 0;
}

static uint32_t tpm_get_flags(struct udevice *dev, uint8_t *disable,
			      uint8_t *deactivated, uint8_t *nvlocked)
{
	struct tpm_permanent_flags pflags;
	uint32_t result;

	result = tpm1_get_permanent_flags(dev, &pflags);
	if (result)
		return result;
	if (disable)
		*disable = pflags.disable;
	if (deactivated)
		*deactivated = pflags.deactivated;
	if (nvlocked)
		*nvlocked = pflags.nv_locked;
	debug("TPM: Got flags disable=%d, deactivated=%d, nvlocked=%d\n",
	      pflags.disable, pflags.deactivated, pflags.nv_locked);

	return 0;
}

static uint32_t tpm_nv_write_value_lock(struct udevice *dev, uint32_t index)
{
	debug("TPM: Write lock 0x%x\n", index);

	return tpm_nv_write_value(dev, index, NULL, 0);
}

static int tpm_is_owned(struct udevice *dev)
{
	uint8_t response[TPM_PUBEK_SIZE];
	uint32_t result;

	result = tpm_read_pubek(dev, response, sizeof(response));

	return result != TPM_SUCCESS;
}

static int test_early_extend(struct udevice *dev)
{
	uint8_t value_in[20];
	uint8_t value_out[20];

	printf("Testing earlyextend ...");
	tpm_init(dev);
	TPM_CHECK(tpm_startup(dev, TPM_ST_CLEAR));
	TPM_CHECK(tpm_continue_self_test(dev));
	TPM_CHECK(tpm_pcr_extend(dev, 1, value_in, sizeof(value_in), value_out,
				 "test"));
	printf("done\n");
	return 0;
}

static int test_early_nvram(struct udevice *dev)
{
	uint32_t x;

	printf("Testing earlynvram ...");
	tpm_init(dev);
	TPM_CHECK(tpm_startup(dev, TPM_ST_CLEAR));
	TPM_CHECK(tpm_continue_self_test(dev));
	TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
	TPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)));
	printf("done\n");
	return 0;
}

static int test_early_nvram2(struct udevice *dev)
{
	uint32_t x;

	printf("Testing earlynvram2 ...");
	tpm_init(dev);
	TPM_CHECK(tpm_startup(dev, TPM_ST_CLEAR));
	TPM_CHECK(tpm_continue_self_test(dev));
	TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
	TPM_CHECK(tpm_nv_write_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)));
	printf("done\n");
	return 0;
}

static int test_enable(struct udevice *dev)
{
	uint8_t disable = 0, deactivated = 0;

	printf("Testing enable ...\n");
	tpm_init(dev);
	TPM_CHECK(TlclStartupIfNeeded(dev));
	TPM_CHECK(tpm_self_test_full(dev));
	TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
	TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL));
	printf("\tdisable is %d, deactivated is %d\n", disable, deactivated);
	TPM_CHECK(tpm_physical_enable(dev));
	TPM_CHECK(tpm_physical_set_deactivated(dev, 0));
	TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL));
	printf("\tdisable is %d, deactivated is %d\n", disable, deactivated);
	if (disable == 1 || deactivated == 1)
		printf("\tfailed to enable or activate\n");
	printf("\tdone\n");
	return 0;
}

#define reboot() do { \
	printf("\trebooting...\n"); \
	reset_cpu(); \
} while (0)

static int test_fast_enable(struct udevice *dev)
{
	uint8_t disable = 0, deactivated = 0;
	int i;

	printf("Testing fastenable ...\n");
	tpm_init(dev);
	TPM_CHECK(TlclStartupIfNeeded(dev));
	TPM_CHECK(tpm_self_test_full(dev));
	TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
	TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL));
	printf("\tdisable is %d, deactivated is %d\n", disable, deactivated);
	for (i = 0; i < 2; i++) {
		TPM_CHECK(tpm_force_clear(dev));
		TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL));
		printf("\tdisable is %d, deactivated is %d\n", disable,
		       deactivated);
		assert(disable == 1 && deactivated == 1);
		TPM_CHECK(tpm_physical_enable(dev));
		TPM_CHECK(tpm_physical_set_deactivated(dev, 0));
		TPM_CHECK(tpm_get_flags(dev, &disable, &deactivated, NULL));
		printf("\tdisable is %d, deactivated is %d\n", disable,
		       deactivated);
		assert(disable == 0 && deactivated == 0);
	}
	printf("\tdone\n");
	return 0;
}

static int test_global_lock(struct udevice *dev)
{
	uint32_t zero = 0;
	uint32_t result;
	uint32_t x;

	printf("Testing globallock ...\n");
	tpm_init(dev);
	TPM_CHECK(TlclStartupIfNeeded(dev));
	TPM_CHECK(tpm_self_test_full(dev));
	TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
	TPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)));
	TPM_CHECK(tpm_nv_write_value(dev, INDEX0, (uint8_t *)&zero,
				     sizeof(uint32_t)));
	TPM_CHECK(tpm_nv_read_value(dev, INDEX1, (uint8_t *)&x, sizeof(x)));
	TPM_CHECK(tpm_nv_write_value(dev, INDEX1, (uint8_t *)&zero,
				     sizeof(uint32_t)));
	TPM_CHECK(tpm_set_global_lock(dev));
	/* Verifies that write to index0 fails */
	x = 1;
	result = tpm_nv_write_value(dev, INDEX0, (uint8_t *)&x, sizeof(x));
	assert(result == TPM_AREA_LOCKED);
	TPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)));
	assert(x == 0);
	/* Verifies that write to index1 is still possible */
	x = 2;
	TPM_CHECK(tpm_nv_write_value(dev, INDEX1, (uint8_t *)&x, sizeof(x)));
	TPM_CHECK(tpm_nv_read_value(dev, INDEX1, (uint8_t *)&x, sizeof(x)));
	assert(x == 2);
	/* Turns off PP */
	tpm_tsc_physical_presence(dev, PHYS_PRESENCE);
	/* Verifies that write to index1 fails */
	x = 3;
	result = tpm_nv_write_value(dev, INDEX1, (uint8_t *)&x, sizeof(x));
	assert(result == TPM_BAD_PRESENCE);
	TPM_CHECK(tpm_nv_read_value(dev, INDEX1, (uint8_t *)&x, sizeof(x)));
	assert(x == 2);
	printf("\tdone\n");
	return 0;
}

static int test_lock(struct udevice *dev)
{
	printf("Testing lock ...\n");
	tpm_init(dev);
	tpm_startup(dev, TPM_ST_CLEAR);
	tpm_self_test_full(dev);
	tpm_tsc_physical_presence(dev, PRESENCE);
	tpm_nv_write_value_lock(dev, INDEX0);
	printf("\tLocked 0x%x\n", INDEX0);
	printf("\tdone\n");
	return 0;
}

static void initialise_spaces(struct udevice *dev)
{
	uint32_t zero = 0;
	uint32_t perm = TPM_NV_PER_WRITE_STCLEAR | TPM_NV_PER_PPWRITE;

	printf("\tInitialising spaces\n");
	tpm1_nv_set_locked(dev);  /* useful only the first time */
	tpm1_nv_define_space(dev, INDEX0, perm, 4);
	tpm_nv_write_value(dev, INDEX0, (uint8_t *)&zero, 4);
	tpm1_nv_define_space(dev, INDEX1, perm, 4);
	tpm_nv_write_value(dev, INDEX1, (uint8_t *)&zero, 4);
	tpm1_nv_define_space(dev, INDEX2, perm, 4);
	tpm_nv_write_value(dev, INDEX2, (uint8_t *)&zero, 4);
	tpm1_nv_define_space(dev, INDEX3, perm, 4);
	tpm_nv_write_value(dev, INDEX3, (uint8_t *)&zero, 4);
	perm = TPM_NV_PER_READ_STCLEAR | TPM_NV_PER_WRITE_STCLEAR |
		TPM_NV_PER_PPWRITE;
	tpm1_nv_define_space(dev, INDEX_INITIALISED, perm, 1);
}

static int test_readonly(struct udevice *dev)
{
	uint8_t c;
	uint32_t index_0, index_1, index_2, index_3;
	int read0, read1, read2, read3;

	printf("Testing readonly ...\n");
	tpm_init(dev);
	tpm_startup(dev, TPM_ST_CLEAR);
	tpm_self_test_full(dev);
	tpm_tsc_physical_presence(dev, PRESENCE);
	/*
	 * Checks if initialisation has completed by trying to read-lock a
	 * space that's created at the end of initialisation
	 */
	if (tpm_nv_read_value(dev, INDEX_INITIALISED, &c, 0) == TPM_BADINDEX) {
		/* The initialisation did not complete */
		initialise_spaces(dev);
	}

	/* Checks if spaces are OK or messed up */
	read0 = tpm_nv_read_value(dev, INDEX0, (uint8_t *)&index_0,
				  sizeof(index_0));
	read1 = tpm_nv_read_value(dev, INDEX1, (uint8_t *)&index_1,
				  sizeof(index_1));
	read2 = tpm_nv_read_value(dev, INDEX2, (uint8_t *)&index_2,
				  sizeof(index_2));
	read3 = tpm_nv_read_value(dev, INDEX3, (uint8_t *)&index_3,
				  sizeof(index_3));
	if (read0 || read1 || read2 || read3) {
		printf("Invalid contents\n");
		return 0;
	}

	/*
	 * Writes space, and locks it.  Then attempts to write again.
	 * I really wish I could use the imperative.
	 */
	index_0 += 1;
	if (tpm_nv_write_value(dev, INDEX0, (uint8_t *)&index_0,
			       sizeof(index_0) !=
		TPM_SUCCESS)) {
		pr_err("\tcould not write index 0\n");
	}
	tpm_nv_write_value_lock(dev, INDEX0);
	if (tpm_nv_write_value(dev, INDEX0, (uint8_t *)&index_0,
			       sizeof(index_0)) ==
			TPM_SUCCESS)
		pr_err("\tindex 0 is not locked\n");

	printf("\tdone\n");
	return 0;
}

static int test_redefine_unowned(struct udevice *dev)
{
	uint32_t perm;
	uint32_t result;
	uint32_t x;

	printf("Testing redefine_unowned ...");
	tpm_init(dev);
	TPM_CHECK(TlclStartupIfNeeded(dev));
	TPM_CHECK(tpm_self_test_full(dev));
	TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
	assert(!tpm_is_owned(dev));

	/* Ensures spaces exist. */
	TPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)));
	TPM_CHECK(tpm_nv_read_value(dev, INDEX1, (uint8_t *)&x, sizeof(x)));

	/* Redefines spaces a couple of times. */
	perm = TPM_NV_PER_PPWRITE | TPM_NV_PER_GLOBALLOCK;
	TPM_CHECK(tpm1_nv_define_space(dev, INDEX0, perm,
				       2 * sizeof(uint32_t)));
	TPM_CHECK(tpm1_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t)));
	perm = TPM_NV_PER_PPWRITE;
	TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm,
				       2 * sizeof(uint32_t)));
	TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t)));

	/* Sets the global lock */
	tpm_set_global_lock(dev);

	/* Verifies that index0 cannot be redefined */
	result = tpm1_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t));
	assert(result == TPM_AREA_LOCKED);

	/* Checks that index1 can */
	TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm,
				       2 * sizeof(uint32_t)));
	TPM_CHECK(tpm1_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t)));

	/* Turns off PP */
	tpm_tsc_physical_presence(dev, PHYS_PRESENCE);

	/* Verifies that neither index0 nor index1 can be redefined */
	result = tpm1_nv_define_space(dev, INDEX0, perm, sizeof(uint32_t));
	assert(result == TPM_BAD_PRESENCE);
	result = tpm1_nv_define_space(dev, INDEX1, perm, sizeof(uint32_t));
	assert(result == TPM_BAD_PRESENCE);

	printf("done\n");
	return 0;
}

#define PERMPPGL (TPM_NV_PER_PPWRITE | TPM_NV_PER_GLOBALLOCK)
#define PERMPP TPM_NV_PER_PPWRITE

static int test_space_perm(struct udevice *dev)
{
	uint32_t perm;

	printf("Testing spaceperm ...");
	tpm_init(dev);
	TPM_CHECK(TlclStartupIfNeeded(dev));
	TPM_CHECK(tpm_continue_self_test(dev));
	TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
	TPM_CHECK(tpm_get_permissions(dev, INDEX0, &perm));
	assert((perm & PERMPPGL) == PERMPPGL);
	TPM_CHECK(tpm_get_permissions(dev, INDEX1, &perm));
	assert((perm & PERMPP) == PERMPP);
	printf("done\n");
	return 0;
}

static int test_startup(struct udevice *dev)
{
	uint32_t result;

	printf("Testing startup ...\n");

	tpm_init(dev);
	result = tpm_startup(dev, TPM_ST_CLEAR);
	if (result != 0 && result != TPM_INVALID_POSTINIT)
		printf("\ttpm startup failed with 0x%x\n", result);
	result = tpm_get_flags(dev, NULL, NULL, NULL);
	if (result != 0)
		printf("\ttpm getflags failed with 0x%x\n", result);
	printf("\texecuting SelfTestFull\n");
	tpm_self_test_full(dev);
	result = tpm_get_flags(dev, NULL, NULL, NULL);
	if (result != 0)
		printf("\ttpm getflags failed with 0x%x\n", result);
	printf("\tdone\n");
	return 0;
}

/*
 * Runs [op] and ensures it returns success and doesn't run longer than
 * [time_limit] in milliseconds.
 */
#define TTPM_CHECK(op, time_limit) do { \
	ulong start, time; \
	uint32_t __result; \
	\
	start = get_timer(0); \
	__result = op; \
	if (__result != TPM_SUCCESS) { \
		printf("\t" #op ": error 0x%x\n", __result); \
		return -1; \
	} \
	time = get_timer(start); \
	printf("\t" #op ": %lu ms\n", time); \
	if (time > (ulong)time_limit) { \
		printf("\t" #op " exceeded " #time_limit " ms\n"); \
	} \
} while (0)


static int test_timing(struct udevice *dev)
{
	uint8_t in[20], out[20];
	uint32_t x;

	printf("Testing timing ...");
	tpm_init(dev);
	TTPM_CHECK(TlclStartupIfNeeded(dev), 50);
	TTPM_CHECK(tpm_continue_self_test(dev), 100);
	TTPM_CHECK(tpm_self_test_full(dev), 1000);
	TTPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE), 100);
	TTPM_CHECK(tpm_nv_write_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)),
		   100);
	TTPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)),
		   100);
	TTPM_CHECK(tpm_pcr_extend(dev, 0, in, sizeof(in), out, "test"), 200);
	TTPM_CHECK(tpm_set_global_lock(dev), 50);
	TTPM_CHECK(tpm_tsc_physical_presence(dev, PHYS_PRESENCE), 100);
	printf("done\n");
	return 0;
}

#define TPM_MAX_NV_WRITES_NOOWNER 64

static int test_write_limit(struct udevice *dev)
{
	uint32_t result;
	int i;

	printf("Testing writelimit ...\n");
	tpm_init(dev);
	TPM_CHECK(TlclStartupIfNeeded(dev));
	TPM_CHECK(tpm_self_test_full(dev));
	TPM_CHECK(tpm_tsc_physical_presence(dev, PRESENCE));
	TPM_CHECK(tpm_force_clear(dev));
	TPM_CHECK(tpm_physical_enable(dev));
	TPM_CHECK(tpm_physical_set_deactivated(dev, 0));

	for (i = 0; i < TPM_MAX_NV_WRITES_NOOWNER + 2; i++) {
		printf("\twriting %d\n", i);
		result = tpm_nv_write_value(dev, INDEX0, (uint8_t *)&i,
					    sizeof(i));
		switch (result) {
		case TPM_SUCCESS:
			break;
		case TPM_MAXNVWRITES:
			assert(i >= TPM_MAX_NV_WRITES_NOOWNER);
		default:
			pr_err("\tunexpected error code %d (0x%x)\n",
			      result, result);
		}
	}

	/* Reset write count */
	TPM_CHECK(tpm_force_clear(dev));
	TPM_CHECK(tpm_physical_enable(dev));
	TPM_CHECK(tpm_physical_set_deactivated(dev, 0));

	/* Try writing again. */
	TPM_CHECK(tpm_nv_write_value(dev, INDEX0, (uint8_t *)&i, sizeof(i)));
	printf("\tdone\n");
	return 0;
}

#define VOIDTEST(XFUNC) \
	int do_test_##XFUNC(struct cmd_tbl *cmd_tbl, int flag, int argc, \
	char *const argv[]) \
	{ \
		struct udevice *dev; \
		int ret; \
\
		ret = get_tpm(&dev); \
		if (ret) \
			return ret; \
		return test_##XFUNC(dev); \
	}

#define VOIDENT(XNAME) \
	U_BOOT_CMD_MKENT(XNAME, 0, 1, do_test_##XNAME, "", ""),

VOIDTEST(early_extend)
VOIDTEST(early_nvram)
VOIDTEST(early_nvram2)
VOIDTEST(enable)
VOIDTEST(fast_enable)
VOIDTEST(global_lock)
VOIDTEST(lock)
VOIDTEST(readonly)
VOIDTEST(redefine_unowned)
VOIDTEST(space_perm)
VOIDTEST(startup)
VOIDTEST(timing)
VOIDTEST(write_limit)
VOIDTEST(timer)

static struct cmd_tbl cmd_cros_tpm_sub[] = {
	VOIDENT(early_extend)
	VOIDENT(early_nvram)
	VOIDENT(early_nvram2)
	VOIDENT(enable)
	VOIDENT(fast_enable)
	VOIDENT(global_lock)
	VOIDENT(lock)
	VOIDENT(readonly)
	VOIDENT(redefine_unowned)
	VOIDENT(space_perm)
	VOIDENT(startup)
	VOIDENT(timing)
	VOIDENT(write_limit)
	VOIDENT(timer)
};

static int do_tpmtest(struct cmd_tbl *cmdtp, int flag, int argc,
		      char *const argv[])
{
	struct cmd_tbl *c;
	int i;

	printf("argc = %d, argv = ", argc);

	for (i = 0; i < argc; i++)
		printf(" %s", argv[i]);

	printf("\n------\n");

	argc--;
	argv++;
	c = find_cmd_tbl(argv[0], cmd_cros_tpm_sub,
			 ARRAY_SIZE(cmd_cros_tpm_sub));
	return c ? c->cmd(cmdtp, flag, argc, argv) : cmd_usage(cmdtp);
}

U_BOOT_CMD(tpmtest, 2, 1, do_tpmtest, "TPM tests",
	"\n\tearly_extend\n"
	"\tearly_nvram\n"
	"\tearly_nvram2\n"
	"\tenable\n"
	"\tfast_enable\n"
	"\tglobal_lock\n"
	"\tlock\n"
	"\treadonly\n"
	"\tredefine_unowned\n"
	"\tspace_perm\n"
	"\tstartup\n"
	"\ttiming\n"
	"\twrite_limit\n");
