/*
 * Copyright (c) 2019-2020 The Fuchsia Authors
 *
 * SPDX-License-Identifier:	BSD-3-Clause
 */

#include <common.h>
#include <tee.h>
#include <tee/ta_helper.h>
#include <tee/ta_vx.h>
#include <tee/ta_vx_helper.h>
#include <zircon/boot_args.h>

#ifdef CONFIG_TA_VX
#define VX_PERM_ATTR_HASH_SIZE 32

static struct tee_optee_ta_uuid vx_uuid = TA_VX_UUID;

static int ta_vx_read_lock_state(enum vx_lock_state *lock_state)
{
	int rc;

	struct tee_param param = { 0 };
	param.attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT;

	rc = ta_call(&vx_uuid, TA_VX_CMD_READ_LOCK_STATE, 1, &param);
	if (!rc) {
		*lock_state = param.u.value.a;
	}

	return rc;
}

static int ta_vx_write_lock_state(enum vx_lock_state lock_state)
{
	struct tee_param param = { 0 };
	param.attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
	param.u.value.a = lock_state;

	return ta_call(&vx_uuid, TA_VX_CMD_WRITE_LOCK_STATE, 1, &param);
}

int ta_vx_lock(void)
{
	int rc = zircon_clear_stored_cmdline();
	if (rc) {
		printf("Failed to clear stored boot args\n");
		return rc;
	}

	return ta_vx_write_lock_state(VX_LOCKED);
}

int ta_vx_lock_if_ephemerally_unlocked(void)
{
	int rc;
	uint32_t vars;

	rc = ta_vx_getvar_all(&vars);
	if (rc) {
		return rc;
	}

	if (!(vars & VX_VAR_EPHEMERALLY_UNLOCKED)) {
		return 0;
	}

	printf("Locking up an ephemerally unlocked device\n");
	rc = ta_vx_lock();
	if (!rc) {
		printf("ta_vx_lock() failed\n");
		return rc;
	}

	rc = ta_vx_getvar_all(&vars);
	if (rc) {
		return rc;
	}

	if (vars & VX_VAR_EPHEMERALLY_UNLOCKED) {
		printf("SHOCKED: device is still ephemerally unlocked after "
		       "successful locking\n");
		return -EINVAL;
	}

	return 0;
}

int ta_vx_unlock(void)
{
	return ta_vx_write_lock_state(VX_UNLOCKED);
}

int ta_vx_is_unlocked(bool *unlocked)
{
	enum vx_lock_state lock_state;
	if (ta_vx_read_lock_state(&lock_state)) {
		return -EIO;
	}
	*unlocked = (lock_state == VX_UNLOCKED);
	return 0;
}

int ta_vx_read_rollback_index(uint32_t slot, uint64_t *rollback_index)
{
	int rc;
	struct tee_param params[2] = { 0 };

	params[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
	params[0].u.value.a = slot;

	params[1].attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT;

	rc = ta_call(&vx_uuid, TA_VX_CMD_READ_ROLLBACK_INDEX,
		     ARRAY_SIZE(params), params);
	if (!rc) {
		*rollback_index = ((uint64_t)params[1].u.value.a) << 32 |
				  params[1].u.value.b;
	}

	return rc;
}

int ta_vx_write_rollback_index(uint32_t slot, uint64_t rollback_index)
{
	struct tee_param params[2] = { 0 };

	params[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
	params[0].u.value.a = slot;

	params[1].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
	params[1].u.value.a = rollback_index >> 32;
	params[1].u.value.b = rollback_index;

	return ta_call(&vx_uuid, TA_VX_CMD_WRITE_ROLLBACK_INDEX,
		       ARRAY_SIZE(params), params);
}

int ta_vx_read_persistent_value(const char *name, void *buf, size_t buf_len,
				size_t *bytes_read)
{
	int rc;
	struct ta_context context = { 0 };
	struct tee_param params[2] = { 0 };

	struct tee_shm *shm_key = NULL;
	struct tee_shm *shm_buf = NULL;

	size_t key_len = strlen(name) + 1;

	/* Connect to TA. */
	rc = ta_open(&vx_uuid, &context);
	if (rc)
		return rc;

	/* Pass in @key via shared memory. */
	rc = tee_shm_alloc(context.tee, key_len, TEE_SHM_ALLOC, &shm_key);
	if (rc)
		goto out;

	memcpy(shm_key->addr, name, key_len);
	params[0].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT;
	params[0].u.memref.shm = shm_key;
	params[0].u.memref.size = key_len;

	/* Pass in buf via shared memory. */
	rc = tee_shm_alloc(context.tee, buf_len, TEE_SHM_ALLOC, &shm_buf);
	if (rc)
		goto out;

	params[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INOUT;
	params[1].u.memref.shm = shm_buf;
	params[1].u.memref.size = buf_len;

	/* Invoke the TA. */
	rc = ta_invoke(&context, TA_VX_CMD_READ_PERSIST_VALUE,
		       ARRAY_SIZE(params), params);
	if (!rc) {
		memcpy(buf, (void *)(params[1].u.memref.shm->addr),
		       params[1].u.memref.size);
		if (bytes_read) {
			*bytes_read = params[1].u.memref.size;
		}
	}

out:
	tee_shm_free(shm_key);
	tee_shm_free(shm_buf);

	ta_close(&context);
	return rc;
}

int ta_vx_write_persistent_value(const char *name, const void *buf,
				 size_t buf_len)
{
	int rc;
	struct ta_context context = { 0 };
	struct tee_param params[2] = { 0 };

	struct tee_shm *shm_key = NULL;
	struct tee_shm *shm_buf = NULL;

	size_t key_len = strlen(name) + 1;

	/* Connect to TA. */
	rc = ta_open(&vx_uuid, &context);
	if (rc)
		return rc;

	/* Pass in @key via shared memory. */
	rc = tee_shm_alloc(context.tee, key_len, TEE_SHM_ALLOC, &shm_key);
	if (rc)
		goto out;

	memcpy(shm_key->addr, name, key_len);
	params[0].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT;
	params[0].u.memref.shm = shm_key;
	params[0].u.memref.size = key_len;

	/* Pass in buf via shared memory. */
	rc = tee_shm_alloc(context.tee, buf_len, TEE_SHM_ALLOC, &shm_buf);
	if (rc)
		goto out;

	memcpy(shm_buf->addr, buf, buf_len);
	params[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT;
	params[1].u.memref.shm = shm_buf;
	params[1].u.memref.size = buf_len;

	/* Invoke the TA. */
	rc = ta_invoke(&context, TA_VX_CMD_WRITE_PERSIST_VALUE,
		       ARRAY_SIZE(params), params);

out:
	tee_shm_free(shm_key);
	tee_shm_free(shm_buf);

	ta_close(&context);
	return rc;
}

int ta_vx_delete_persistent_value(const char *name)
{
	int rc;
	struct ta_context context = { 0 };
	struct tee_param params[1] = { 0 };

	struct tee_shm *shm_key = NULL;
	size_t key_len = strlen(name) + 1;

	/* Connect to TA. */
	rc = ta_open(&vx_uuid, &context);
	if (rc)
		return rc;

	/* Pass in @key via shared memory. */
	rc = tee_shm_alloc(context.tee, key_len, TEE_SHM_ALLOC, &shm_key);
	if (rc)
		goto out;
	memcpy(shm_key->addr, name, key_len);
	params[0].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT;
	params[0].u.memref.shm = shm_key;
	params[0].u.memref.size = key_len;

	/* Invoke the TA. */
	rc = ta_invoke(&context, TA_VX_CMD_DELETE_PERSIST_VALUE,
		       ARRAY_SIZE(params), params);

out:
	tee_shm_free(shm_key);
	ta_close(&context);
	return rc;
}

int ta_vx_cprng_draw(void *buf, size_t buf_len)
{
	int rc;
	struct ta_context context = { 0 };
	struct tee_param params[1] = { 0 };
	struct tee_shm *shm_buf = NULL;

	if (!(buf && buf_len))
		return -EINVAL;

	rc = ta_open(&vx_uuid, &context);
	if (rc)
		return rc;

	rc = tee_shm_alloc(context.tee, buf_len, TEE_SHM_ALLOC, &shm_buf);
	if (rc)
		goto out;

	params[0].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INOUT;
	params[0].u.memref.shm = shm_buf;
	params[0].u.memref.size = buf_len;

	rc = ta_invoke(&context, TA_VX_CMD_CPRNG_DRAW, ARRAY_SIZE(params),
		       params);
	if (!rc) {
		memcpy(buf, (void *)(params[0].u.memref.shm->addr),
		       params[0].u.memref.size);
	}

out:
	tee_shm_free(shm_buf);

	ta_close(&context);
	return rc;
}

void ta_vx_exit_bootloader_or_panic(void)
{
	uint32_t vars;

	if (ta_call(&vx_uuid, TA_VX_CMD_EXIT_BOOTLOADER, 0, NULL)) {
		panic("VX finalization failed!");
	}

	/* Make sure we are indeed beyond the bootloader security domain. */
	if (ta_vx_getvar_all(&vars) || !(vars & VX_VAR_OUT_OF_BOOTLOADER)) {
		panic("VX finalization verification failed.");
	}

	return;
}

int ta_vx_read_perm_attr(void *buf, size_t buf_len, size_t *bytes_read)
{
	int rc;
	struct ta_context context = { 0 };
	struct tee_param params[1] = { 0 };

	struct tee_shm *shm_buf = NULL;

	if (!(buf && buf_len)) {
		return -EINVAL;
	}

	/* Connect to TA. */
	rc = ta_open(&vx_uuid, &context);
	if (rc) {
		return rc;
	}

	/* Pass in buf via shared memory. */
	rc = tee_shm_alloc(context.tee, buf_len, TEE_SHM_ALLOC, &shm_buf);
	if (rc) {
		ta_close(&context);
		return rc;
	}

	params[0].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INOUT;
	params[0].u.memref.shm = shm_buf;
	params[0].u.memref.size = buf_len;

	/* Invoke the TA. */
	rc = ta_invoke(&context, TA_VX_CMD_READ_PERM_ATTR,
		       ARRAY_SIZE(params), params);
	if (!rc) {
		memcpy(buf, (void *)(params[0].u.memref.shm->addr),
		       params[0].u.memref.size);
		if (bytes_read) {
			*bytes_read = params[0].u.memref.size;
		}
	}

	tee_shm_free(shm_buf);

	ta_close(&context);
	return rc;
}

int ta_vx_write_perm_attr(const void *buf, size_t buf_len)
{
	int rc;
	struct ta_context context = { 0 };
	struct tee_param params[1] = { 0 };

	struct tee_shm *shm_buf = NULL;

	if (!(buf && buf_len))
		return -EINVAL;

	/* Connect to TA. */
	rc = ta_open(&vx_uuid, &context);
	if (rc) {
		return rc;
	}

	/* Pass in buf via shared memory. */
	rc = tee_shm_alloc(context.tee, buf_len, TEE_SHM_ALLOC, &shm_buf);
	if (rc) {
		ta_close(&context);
		return rc;
	}

	memcpy(shm_buf->addr, buf, buf_len);
	params[0].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT;
	params[0].u.memref.shm = shm_buf;
	params[0].u.memref.size = buf_len;

	/* Invoke the TA. */
	rc = ta_invoke(&context, TA_VX_CMD_WRITE_PERM_ATTR,
		       ARRAY_SIZE(params), params);

	tee_shm_free(shm_buf);

	ta_close(&context);
	return rc;
}

int ta_vx_get_rpmb_status(uint32_t *out_status, uint32_t *out_write_count)
{
	int rc;
	struct tee_param params[1] = { 0 };

	params[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT;
	rc = ta_call(&vx_uuid, TA_VX_CMD_GET_RPMB_STATUS,
			ARRAY_SIZE(params), params);
	if (rc) {
		return rc;
	}

	if (out_status) {
		*out_status = params[0].u.value.a;
	}
	if (out_write_count) {
		*out_write_count = params[0].u.value.b;
	}

	return 0;
}

int ta_vx_provision_rpmb(void)
{
	return ta_call(&vx_uuid, TA_VX_CMD_PROVISION_RPMB, 0, NULL);
}

int ta_vx_reroute_rpmb_till_reboot(void)
{
	return ta_call(&vx_uuid, TA_VX_CMD_REROUTE_RPMB_TILL_REBOOT, 0, NULL);
}

int ta_vx_reroute_rpmb_to_software(void)
{
	return ta_call(&vx_uuid, TA_VX_CMD_REROUTE_RPMB_TO_SOFTWARE, 0, NULL);
}

int ta_vx_reroute_rpmb_to_hardware(void)
{
	return ta_call(&vx_uuid, TA_VX_CMD_REROUTE_RPMB_TO_HARDWARE, 0, NULL);
}

int ta_vx_delete_perm_attr(void)
{
	return ta_call(&vx_uuid, TA_VX_CMD_DELETE_PERM_ATTR, 0, NULL);
}

int ta_vx_read_perm_attr_hash(void *buf, size_t buf_len)
{
	int rc;
	struct ta_context context = { 0 };
	struct tee_param params[1] = { 0 };

	struct tee_shm *shm_buf = NULL;

	if (!buf || (buf_len < VX_PERM_ATTR_HASH_SIZE))
		return -EINVAL;

	/* Connect to TA. */
	rc = ta_open(&vx_uuid, &context);
	if (rc) {
		return rc;
	}

	/* Pass in buf via shared memory. */
	rc = tee_shm_alloc(context.tee, VX_PERM_ATTR_HASH_SIZE, TEE_SHM_ALLOC,
			&shm_buf);
	if (rc) {
		ta_close(&context);
		return rc;
	}

	params[0].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INOUT;
	params[0].u.memref.shm = shm_buf;
	params[0].u.memref.size = VX_PERM_ATTR_HASH_SIZE;

	/* Invoke the TA. */
	rc = ta_invoke(&context, TA_VX_CMD_READ_PERM_ATTR_HASH,
		       ARRAY_SIZE(params), params);
	if (!rc) {
		memcpy(buf, (void *)(params[0].u.memref.shm->addr),
		       params[0].u.memref.size);
	}

	tee_shm_free(shm_buf);

	ta_close(&context);
	return rc;
}

int ta_vx_get_perm_attr_status(uint32_t *status)
{
	int rc;

	struct tee_param param = { 0 };
	param.attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT;

	rc = ta_call(&vx_uuid, TA_VX_CMD_GET_PERM_ATTR_STATUS, 1, &param);
	if (!rc) {
		if (status) {
			*status = param.u.value.a;
		}
	}

	return rc;
}

int ta_vx_lock_perm_attr(void)
{
	return ta_call(&vx_uuid, TA_VX_CMD_LOCK_PERM_ATTR, 0, NULL);
}

int ta_vx_getvar_all(uint32_t *out_vars)
{
	int rc;
	struct tee_param params[1] = { 0 };

	if (!out_vars) {
		return -EINVAL;
	}

	params[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT;
	rc = ta_call(&vx_uuid, TA_VX_CMD_GETVAR_ALL, ARRAY_SIZE(params),
		     params);
	if (rc) {
		return rc;
	}

	*out_vars = params[0].u.value.a;
	return 0;
}

#ifdef CONFIG_TA_VX_TESTS
int ta_vx_run_tests(const char *name)
{
	int rc;
	struct ta_context context = { 0 };
	struct tee_param params[1] = { 0 };
	size_t name_len = strlen(name) + 1;
	struct tee_shm *shm_buf = NULL;

	rc = ta_open(&vx_uuid, &context);
	if (rc)
		return rc;

	rc = tee_shm_alloc(context.tee, name_len, TEE_SHM_ALLOC, &shm_buf);
	if (rc)
		goto out;

	memcpy(shm_buf->addr, name, name_len);
	params[0].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INPUT;
	params[0].u.memref.shm = shm_buf;
	params[0].u.memref.size = name_len;

	rc = ta_invoke(&context, TA_VX_CMD_RUN_TESTS, ARRAY_SIZE(params),
		       params);

out:
	tee_shm_free(shm_buf);

	ta_close(&context);
	return rc;
}
#endif // CONFIG_TA_VX_TESTS

#else // CONFIG_TA_VX

static int ta_vx_fail(const char *func)
{
	printf("%s: failure due to disabled VX TA\n", func);
	return -1;
}

int ta_vx_lock()
{
	return ta_vx_fail(__func__);
}

int ta_vx_lock_if_ephemerally_unlocked()
{
	return ta_vx_fail(__func__);
}

int ta_vx_unlock()
{
	return ta_vx_fail(__func__);
}

int ta_vx_is_unlocked(bool *unlocked)
{
	return ta_vx_fail(__func__);
}

int ta_vx_read_rollback_index(uint32_t slot, uint64_t *rollback_index)
{
	return ta_vx_fail(__func__);
}

int ta_vx_write_rollback_index(uint32_t slot, uint64_t rollback_index)
{
	return ta_vx_fail(__func__);
}

int ta_vx_read_persistent_value(const char *name, void *buf, size_t buf_len,
				size_t *bytes_read)
{
	return ta_vx_fail(__func__);
}

int ta_vx_write_persistent_value(const char *name, const void *val_buf,
				 size_t val_buf_len)
{
	return ta_vx_fail(__func__);
}

int ta_vx_delete_persistent_value(const char *name)
{
	return ta_vx_fail(__func__);
}

int ta_vx_cprng_draw(void *buf, size_t buf_len)
{
	return ta_vx_fail(__func__);
}

void ta_vx_exit_bootloader_or_panic()
{
	return ta_vx_fail(__func__);
}

int ta_vx_read_perm_attr(void *buf, size_t buf_len, size_t *bytes_read)
{
	return ta_vx_fail(__func__);
}

int ta_vx_write_perm_attr(const void *val_buf, size_t val_buf_len)
{
	return ta_vx_fail(__func__);
}

int ta_vx_read_perm_attr_hash(void *buf, size_t buf_len)
{
	return ta_vx_fail(__func__);
}

int ta_vx_delete_perm_attr(void)
{
	return ta_vx_fail(__func__);
}

int ta_vx_get_perm_attr_status(uint32_t *status)
{
	return ta_vx_fail(__func__);
}

int ta_vx_lock_perm_attr(void)
{
	return ta_vx_fail(__func__);
}

int ta_vx_get_rpmb_status(uint32_t *out_status, uint32_t *out_write_count)
{
	return ta_vx_fail(__func__);
}

int ta_vx_provision_rpmb(void)
{
	return ta_vx_fail(__func__);
}

int ta_vx_reroute_rpmb_till_reboot(void)
{
	return ta_vx_fail(__func__);
}

int ta_vx_reroute_rpmb_to_software(void)
{
	return ta_vx_fail(__func__);
}

int ta_vx_reroute_rpmb_to_hardware(void)
{
	return ta_vx_fail(__func__);
}

int ta_vx_getvar_all(uint32_t *out_vars)
{
	return ta_vx_fail(__func__);
}

#endif // CONFIG_TA_VX
