// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright (c) 2018-2019, Linaro Limited
 */

#include <assert.h>
#include <crypto/crypto.h>
#include <kernel/handle.h>
#include <kernel/huk_subkey.h>
#include <kernel/misc.h>
#include <kernel/msg_param.h>
#include <kernel/pseudo_ta.h>
#include <kernel/user_ta.h>
#include <kernel/user_ta_store.h>
#include <ldelf.h>
#include <mm/file.h>
#include <mm/fobj.h>
#include <mm/tee_mmu.h>
#include <pta_system.h>
#include <string.h>
#include <tee_api_defines_extensions.h>
#include <tee_api_defines.h>
#include <util.h>

#define MAX_ENTROPY_IN			32u

struct bin_handle {
	const struct user_ta_store_ops *op;
	struct user_ta_store_handle *h;
	struct file *f;
	size_t offs_bytes;
	size_t size_bytes;
};

struct system_ctx {
	struct handle_db db;
	const struct user_ta_store_ops *store_op;
};

static unsigned int system_pnum;

static TEE_Result system_rng_reseed(struct tee_ta_session *s __unused,
				uint32_t param_types,
				TEE_Param params[TEE_NUM_PARAMS])
{
	size_t entropy_sz;
	uint8_t *entropy_input;
	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
					  TEE_PARAM_TYPE_NONE,
					  TEE_PARAM_TYPE_NONE,
					  TEE_PARAM_TYPE_NONE);

	if (exp_pt != param_types)
		return TEE_ERROR_BAD_PARAMETERS;
	entropy_input = params[0].memref.buffer;
	entropy_sz = params[0].memref.size;

	/* Fortuna PRNG requires seed <= 32 bytes */
	if (!entropy_sz)
		return TEE_ERROR_BAD_PARAMETERS;

	entropy_sz = MIN(entropy_sz, MAX_ENTROPY_IN);

	crypto_rng_add_event(CRYPTO_RNG_SRC_NONSECURE, &system_pnum,
			     entropy_input, entropy_sz);
	return TEE_SUCCESS;
}

static TEE_Result system_derive_ta_unique_key(struct tee_ta_session *s,
					      uint32_t param_types,
					      TEE_Param params[TEE_NUM_PARAMS])
{
	size_t data_len = sizeof(TEE_UUID);
	TEE_Result res = TEE_ERROR_GENERIC;
	uint8_t *data = NULL;
	uint32_t access_flags = 0;
	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
					  TEE_PARAM_TYPE_MEMREF_OUTPUT,
					  TEE_PARAM_TYPE_NONE,
					  TEE_PARAM_TYPE_NONE);
	struct user_ta_ctx *utc = NULL;

	if (exp_pt != param_types)
		return TEE_ERROR_BAD_PARAMETERS;

	if (params[0].memref.size > TA_DERIVED_EXTRA_DATA_MAX_SIZE ||
	    params[1].memref.size < TA_DERIVED_KEY_MIN_SIZE ||
	    params[1].memref.size > TA_DERIVED_KEY_MAX_SIZE)
		return TEE_ERROR_BAD_PARAMETERS;

	utc = to_user_ta_ctx(s->ctx);

	/*
	 * The derived key shall not end up in non-secure memory by
	 * mistake.
	 *
	 * Note that we're allowing shared memory as long as it's
	 * secure. This is needed because a TA always uses shared memory
	 * when communicating with another TA.
	 */
	access_flags = TEE_MEMORY_ACCESS_WRITE | TEE_MEMORY_ACCESS_ANY_OWNER |
		       TEE_MEMORY_ACCESS_SECURE;
	res = tee_mmu_check_access_rights(utc, access_flags,
					  (uaddr_t)params[1].memref.buffer,
					  params[1].memref.size);
	if (res != TEE_SUCCESS)
		return TEE_ERROR_SECURITY;

	/* Take extra data into account. */
	if (ADD_OVERFLOW(data_len, params[0].memref.size, &data_len))
		return TEE_ERROR_SECURITY;

	data = calloc(data_len, 1);
	if (!data)
		return TEE_ERROR_OUT_OF_MEMORY;

	memcpy(data, &s->ctx->uuid, sizeof(TEE_UUID));

	/* Append the user provided data */
	memcpy(data + sizeof(TEE_UUID), params[0].memref.buffer,
	       params[0].memref.size);

	res = huk_subkey_derive(HUK_SUBKEY_UNIQUE_TA, data, data_len,
				params[1].memref.buffer,
				params[1].memref.size);
	free(data);

	return res;
}

static TEE_Result system_map_zi(struct tee_ta_session *s, uint32_t param_types,
				TEE_Param params[TEE_NUM_PARAMS])
{
	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
					  TEE_PARAM_TYPE_VALUE_INOUT,
					  TEE_PARAM_TYPE_VALUE_INPUT,
					  TEE_PARAM_TYPE_NONE);
	struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx);
	uint32_t prot = TEE_MATTR_URW | TEE_MATTR_PRW;
	TEE_Result res = TEE_ERROR_GENERIC;
	struct mobj *mobj = NULL;
	uint32_t pad_begin = 0;
	uint32_t vm_flags = 0;
	struct fobj *f = NULL;
	uint32_t pad_end = 0;
	size_t num_bytes = 0;
	vaddr_t va = 0;

	if (exp_pt != param_types)
		return TEE_ERROR_BAD_PARAMETERS;
	if (params[0].value.b & ~PTA_SYSTEM_MAP_FLAG_SHAREABLE)
		return TEE_ERROR_BAD_PARAMETERS;

	if (params[0].value.b & PTA_SYSTEM_MAP_FLAG_SHAREABLE)
		vm_flags |= VM_FLAG_SHAREABLE;

	num_bytes = params[0].value.a;
	va = reg_pair_to_64(params[1].value.a, params[1].value.b);
	pad_begin = params[2].value.a;
	pad_end = params[2].value.b;

	f = fobj_ta_mem_alloc(ROUNDUP(num_bytes, SMALL_PAGE_SIZE) /
			      SMALL_PAGE_SIZE);
	if (!f)
		return TEE_ERROR_OUT_OF_MEMORY;
	mobj = mobj_with_fobj_alloc(f, NULL);
	fobj_put(f);
	if (!mobj)
		return TEE_ERROR_OUT_OF_MEMORY;
	res = vm_map_pad(utc, &va, num_bytes, prot, vm_flags,
			 mobj, 0, pad_begin, pad_end);
	mobj_put(mobj);
	if (!res)
		reg_pair_from_64(va, &params[1].value.a, &params[1].value.b);

	return res;
}

static TEE_Result system_unmap(struct tee_ta_session *s, uint32_t param_types,
			       TEE_Param params[TEE_NUM_PARAMS])
{
	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
					  TEE_PARAM_TYPE_VALUE_INPUT,
					  TEE_PARAM_TYPE_NONE,
					  TEE_PARAM_TYPE_NONE);

	if (exp_pt != param_types)
		return TEE_ERROR_BAD_PARAMETERS;

	if (params[0].value.b)
		return TEE_ERROR_BAD_PARAMETERS;

	return vm_unmap(to_user_ta_ctx(s->ctx),
			reg_pair_to_64(params[1].value.a, params[1].value.b),
			ROUNDUP(params[0].value.a, SMALL_PAGE_SIZE));
}

static void ta_bin_close(void *ptr)
{
	struct bin_handle *binh = ptr;

	if (binh) {
		if (binh->op && binh->h)
			binh->op->close(binh->h);
		file_put(binh->f);
	}
	free(binh);
}

static TEE_Result system_open_ta_binary(struct system_ctx *ctx,
					uint32_t param_types,
					TEE_Param params[TEE_NUM_PARAMS])
{
	TEE_Result res = TEE_SUCCESS;
	struct bin_handle *binh = NULL;
	int h = 0;
	TEE_UUID *uuid = NULL;
	uint8_t tag[FILE_TAG_SIZE] = { 0 };
	unsigned int tag_len = sizeof(tag);
	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
					  TEE_PARAM_TYPE_VALUE_OUTPUT,
					  TEE_PARAM_TYPE_NONE,
					  TEE_PARAM_TYPE_NONE);

	if (exp_pt != param_types)
		return TEE_ERROR_BAD_PARAMETERS;
	if (params[0].memref.size != sizeof(*uuid))
		return TEE_ERROR_BAD_PARAMETERS;

	uuid = params[0].memref.buffer;

	binh = calloc(1, sizeof(*binh));
	if (!binh)
		return TEE_ERROR_OUT_OF_MEMORY;

	SCATTERED_ARRAY_FOREACH(binh->op, ta_stores, struct user_ta_store_ops) {
		DMSG("Lookup user TA ELF %pUl (%s)",
		     (void *)uuid, binh->op->description);

		res = binh->op->open(uuid, &binh->h);
		DMSG("res=0x%x", res);
		if (res != TEE_ERROR_ITEM_NOT_FOUND &&
		    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
			break;
	}
	if (res)
		goto err;

	res = binh->op->get_size(binh->h, &binh->size_bytes);
	if (res)
		goto err;
	res = binh->op->get_tag(binh->h, tag, &tag_len);
	if (res)
		goto err;
	binh->f = file_get_by_tag(tag, tag_len);
	if (!binh->f)
		goto err_oom;

	h = handle_get(&ctx->db, binh);
	if (h < 0)
		goto err_oom;

	return TEE_SUCCESS;
err_oom:
	res = TEE_ERROR_OUT_OF_MEMORY;
err:
	ta_bin_close(binh);
	return res;
}

static TEE_Result system_close_ta_binary(struct system_ctx *ctx,
					 uint32_t param_types,
					 TEE_Param params[TEE_NUM_PARAMS])
{
	TEE_Result res = TEE_SUCCESS;
	struct bin_handle *binh = NULL;
	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
					  TEE_PARAM_TYPE_NONE,
					  TEE_PARAM_TYPE_NONE,
					  TEE_PARAM_TYPE_NONE);

	if (exp_pt != param_types)
		return TEE_ERROR_BAD_PARAMETERS;

	if (params[0].value.b)
		return TEE_ERROR_BAD_PARAMETERS;

	binh = handle_put(&ctx->db, params[0].value.a);
	if (!binh)
		return TEE_ERROR_BAD_PARAMETERS;

	if (binh->offs_bytes < binh->size_bytes)
		res = binh->op->read(binh->h, NULL,
				     binh->size_bytes - binh->offs_bytes);

	ta_bin_close(binh);
	return res;
}

static TEE_Result binh_copy_to(struct bin_handle *binh, vaddr_t va,
			       size_t offs_bytes, size_t num_bytes)
{
	TEE_Result res = TEE_SUCCESS;
	size_t l =  num_bytes;

	if (offs_bytes < binh->offs_bytes)
		return TEE_ERROR_BAD_STATE;
	if (offs_bytes > binh->offs_bytes) {
		res = binh->op->read(binh->h, NULL,
				     offs_bytes - binh->offs_bytes);
		if (res)
			return res;
		binh->offs_bytes = offs_bytes;
	}

	if (binh->offs_bytes + l > binh->size_bytes) {
		size_t rb = binh->size_bytes - binh->offs_bytes;

		res = binh->op->read(binh->h, (void *)va, rb);
		if (res)
			return res;
		memset((uint8_t *)va + rb, 0, l - rb);
		binh->offs_bytes = binh->size_bytes;
	} else {
		res = binh->op->read(binh->h, (void *)va, l);
		if (res)
			return res;
		binh->offs_bytes += l;
	}

	return TEE_SUCCESS;
}

static TEE_Result system_map_ta_binary(struct system_ctx *ctx,
				       struct tee_ta_session *s,
				       uint32_t param_types,
				       TEE_Param params[TEE_NUM_PARAMS])
{
	const uint32_t accept_flags = PTA_SYSTEM_MAP_FLAG_SHAREABLE |
				      PTA_SYSTEM_MAP_FLAG_WRITEABLE |
				      PTA_SYSTEM_MAP_FLAG_EXECUTABLE;
	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
					  TEE_PARAM_TYPE_VALUE_INPUT,
					  TEE_PARAM_TYPE_VALUE_INOUT,
					  TEE_PARAM_TYPE_VALUE_INPUT);
	struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx);
	struct bin_handle *binh = NULL;
	TEE_Result res = TEE_SUCCESS;
	struct file_slice *fs = NULL;
	bool file_is_locked = false;
	struct mobj *mobj = NULL;
	uint32_t offs_bytes = 0;
	uint32_t offs_pages = 0;
	uint32_t num_bytes = 0;
	uint32_t pad_begin = 0;
	uint32_t pad_end = 0;
	size_t num_pages = 0;
	uint32_t flags = 0;
	uint32_t prot = 0;
	vaddr_t va = 0;

	if (exp_pt != param_types)
		return TEE_ERROR_BAD_PARAMETERS;

	binh = handle_lookup(&ctx->db, params[0].value.a);
	if (!binh)
		return TEE_ERROR_BAD_PARAMETERS;
	flags = params[0].value.b;
	offs_bytes = params[1].value.a;
	num_bytes = params[1].value.b;
	va = reg_pair_to_64(params[2].value.a, params[2].value.b);
	pad_begin = params[3].value.a;
	pad_end = params[3].value.b;

	if ((flags & accept_flags) != flags)
		return TEE_ERROR_BAD_PARAMETERS;

	if ((flags & PTA_SYSTEM_MAP_FLAG_SHAREABLE) &&
	    (flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE))
		return TEE_ERROR_BAD_PARAMETERS;

	if ((flags & PTA_SYSTEM_MAP_FLAG_EXECUTABLE) &&
	    (flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE))
		return TEE_ERROR_BAD_PARAMETERS;

	if (offs_bytes & SMALL_PAGE_MASK)
		return TEE_ERROR_BAD_PARAMETERS;

	prot = TEE_MATTR_UR | TEE_MATTR_PR;
	if (flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE)
		prot |= TEE_MATTR_UW | TEE_MATTR_PW;
	if (flags & PTA_SYSTEM_MAP_FLAG_EXECUTABLE)
		prot |= TEE_MATTR_UX;

	offs_pages = offs_bytes >> SMALL_PAGE_SHIFT;
	num_pages = ROUNDUP(num_bytes, SMALL_PAGE_SIZE) / SMALL_PAGE_SIZE;

	if (!file_trylock(binh->f)) {
		/*
		 * Before we can block on the file lock we must make all
		 * our page tables available for reclaiming in order to
		 * avoid a dead-lock with the other thread (which already
		 * is holding the file lock) mapping lots of memory below.
		 */
		tee_mmu_set_ctx(NULL);
		file_lock(binh->f);
		tee_mmu_set_ctx(s->ctx);
	}
	file_is_locked = true;
	fs = file_find_slice(binh->f, offs_pages);
	if (fs) {
		/* If there's registered slice it has to match */
		if (fs->page_offset != offs_pages ||
		    num_pages > fs->fobj->num_pages) {
			res = TEE_ERROR_BAD_PARAMETERS;
			goto err;
		}

		/* If there's a slice we must be mapping shareable */
		if (!(flags & PTA_SYSTEM_MAP_FLAG_SHAREABLE)) {
			res = TEE_ERROR_BAD_PARAMETERS;
			goto err;
		}

		mobj = mobj_with_fobj_alloc(fs->fobj, binh->f);
		if (!mobj) {
			res = TEE_ERROR_OUT_OF_MEMORY;
			goto err;
		}
		res = vm_map_pad(utc, &va, num_pages * SMALL_PAGE_SIZE,
				 prot, VM_FLAG_READONLY,
				 mobj, 0, pad_begin, pad_end);
		mobj_put(mobj);
		if (res)
			goto err;
	} else {
		struct fobj *f = fobj_ta_mem_alloc(num_pages);
		struct file *file = NULL;
		uint32_t vm_flags = 0;

		if (!f) {
			res = TEE_ERROR_OUT_OF_MEMORY;
			goto err;
		}
		if (!(flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE)) {
			file = binh->f;
			vm_flags |= VM_FLAG_READONLY;
		}

		mobj = mobj_with_fobj_alloc(f, file);
		fobj_put(f);
		if (!mobj) {
			res = TEE_ERROR_OUT_OF_MEMORY;
			goto err;
		}
		res = vm_map_pad(utc, &va, num_pages * SMALL_PAGE_SIZE,
				 TEE_MATTR_PRW, vm_flags, mobj, 0,
				 pad_begin, pad_end);
		mobj_put(mobj);
		if (res)
			goto err;
		res = binh_copy_to(binh, va, offs_bytes, num_bytes);
		if (res)
			goto err_unmap_va;
		res = vm_set_prot(utc, va, num_pages * SMALL_PAGE_SIZE, prot);
		if (res)
			goto err_unmap_va;

		/*
		 * The context currently is active set it again to update
		 * the mapping.
		 */
		tee_mmu_set_ctx(s->ctx);

		if (!(flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE)) {
			res = file_add_slice(binh->f, f, offs_pages);
			if (res)
				goto err_unmap_va;
		}
	}

	file_unlock(binh->f);

	reg_pair_from_64(va, &params[2].value.a, &params[2].value.b);
	return TEE_SUCCESS;

err_unmap_va:
	if (vm_unmap(utc, va, num_pages * SMALL_PAGE_SIZE))
		panic();

	/*
	 * The context currently is active set it again to update
	 * the mapping.
	 */
	tee_mmu_set_ctx(s->ctx);

err:
	if (file_is_locked)
		file_unlock(binh->f);

	return res;
}

static TEE_Result system_copy_from_ta_binary(struct system_ctx *ctx,
					     uint32_t param_types,
					     TEE_Param params[TEE_NUM_PARAMS])
{
	struct bin_handle *binh = NULL;
	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
					  TEE_PARAM_TYPE_MEMREF_OUTPUT,
					  TEE_PARAM_TYPE_NONE,
					  TEE_PARAM_TYPE_NONE);

	if (exp_pt != param_types)
		return TEE_ERROR_BAD_PARAMETERS;

	binh = handle_lookup(&ctx->db, params[0].value.a);
	if (!binh)
		return TEE_ERROR_BAD_PARAMETERS;

	return binh_copy_to(binh, (vaddr_t)params[1].memref.buffer,
			    params[0].value.b, params[1].memref.size);
}

static TEE_Result system_set_prot(struct tee_ta_session *s,
				  uint32_t param_types,
				  TEE_Param params[TEE_NUM_PARAMS])
{
	const uint32_t accept_flags = PTA_SYSTEM_MAP_FLAG_WRITEABLE |
				      PTA_SYSTEM_MAP_FLAG_EXECUTABLE;
	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
					  TEE_PARAM_TYPE_VALUE_INPUT,
					  TEE_PARAM_TYPE_NONE,
					  TEE_PARAM_TYPE_NONE);
	struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx);
	uint32_t prot = TEE_MATTR_UR | TEE_MATTR_PR;
	TEE_Result res = TEE_SUCCESS;
	uint32_t vm_flags = 0;
	uint32_t flags = 0;
	vaddr_t va = 0;
	size_t sz = 0;

	if (exp_pt != param_types)
		return TEE_ERROR_BAD_PARAMETERS;

	flags = params[0].value.b;

	if ((flags & accept_flags) != flags)
		return TEE_ERROR_BAD_PARAMETERS;
	if (flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE)
		prot |= TEE_MATTR_UW | TEE_MATTR_PW;
	if (flags & PTA_SYSTEM_MAP_FLAG_EXECUTABLE)
		prot |= TEE_MATTR_UX;

	va = reg_pair_to_64(params[1].value.a, params[1].value.b),
	sz = ROUNDUP(params[0].value.a, SMALL_PAGE_SIZE);

	res = vm_get_flags(utc, va, sz, &vm_flags);
	if (res)
		return res;

	/*
	 * If the segment is a mapping of a part of a file (vm_flags &
	 * VM_FLAG_READONLY) it cannot be made writeable as all mapped
	 * files are mapped read-only.
	 */
	if ((vm_flags & VM_FLAG_READONLY) &&
	    (prot & (TEE_MATTR_UW | TEE_MATTR_PW)))
		return TEE_ERROR_ACCESS_DENIED;

	return vm_set_prot(utc, va, sz, prot);
}

static TEE_Result system_remap(struct tee_ta_session *s, uint32_t param_types,
			       TEE_Param params[TEE_NUM_PARAMS])
{
	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
					  TEE_PARAM_TYPE_VALUE_INPUT,
					  TEE_PARAM_TYPE_VALUE_INOUT,
					  TEE_PARAM_TYPE_VALUE_INPUT);
	struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx);
	TEE_Result res = TEE_SUCCESS;
	uint32_t num_bytes = 0;
	uint32_t pad_begin = 0;
	uint32_t pad_end = 0;
	vaddr_t old_va = 0;
	vaddr_t new_va = 0;

	if (exp_pt != param_types)
		return TEE_ERROR_BAD_PARAMETERS;

	num_bytes = params[0].value.a;
	old_va = reg_pair_to_64(params[1].value.a, params[1].value.b);
	new_va = reg_pair_to_64(params[2].value.a, params[2].value.b);
	pad_begin = params[3].value.a;
	pad_end = params[3].value.b;

	res = vm_remap(utc, &new_va, old_va, num_bytes, pad_begin, pad_end);
	if (!res)
		reg_pair_from_64(new_va, &params[2].value.a,
				 &params[2].value.b);

	return res;
}

/* ldelf has the same architecture/register width as the kernel */
#ifdef ARM32
static const bool is_arm32 = true;
#else
static const bool is_arm32;
#endif

static TEE_Result call_ldelf_dlopen(struct user_ta_ctx *utc, TEE_UUID *uuid,
				    uint32_t flags)
{
	uaddr_t usr_stack = utc->ldelf_stack_ptr;
	TEE_Result res = TEE_ERROR_GENERIC;
	struct dl_entry_arg *arg = NULL;
	uint32_t panic_code = 0;
	uint32_t panicked = 0;

	assert(uuid);

	usr_stack -= ROUNDUP(sizeof(*arg), STACK_ALIGNMENT);
	arg = (struct dl_entry_arg *)usr_stack;

	res = tee_mmu_check_access_rights(utc, TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_WRITE |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)arg, sizeof(*arg));
	if (res) {
		EMSG("ldelf stack is inaccessible!");
		return res;
	}

	memset(arg, 0, sizeof(*arg));
	arg->cmd = LDELF_DL_ENTRY_DLOPEN;
	arg->dlopen.uuid = *uuid;
	arg->dlopen.flags = flags;

	res = thread_enter_user_mode((vaddr_t)arg, 0, 0, 0,
				     usr_stack, utc->dl_entry_func,
				     is_arm32, &panicked, &panic_code);
	if (panicked) {
		EMSG("ldelf dl_entry function panicked");
		abort_print_current_ta();
		res = TEE_ERROR_TARGET_DEAD;
	}
	if (!res)
		res = arg->ret;

	return res;
}

static TEE_Result call_ldelf_dlsym(struct user_ta_ctx *utc, TEE_UUID *uuid,
				   const char *sym, size_t maxlen, vaddr_t *val)
{
	uaddr_t usr_stack = utc->ldelf_stack_ptr;
	TEE_Result res = TEE_ERROR_GENERIC;
	struct dl_entry_arg *arg = NULL;
	uint32_t panic_code = 0;
	uint32_t panicked = 0;
	size_t len = strnlen(sym, maxlen);

	if (len == maxlen)
		return TEE_ERROR_BAD_PARAMETERS;

	usr_stack -= ROUNDUP(sizeof(*arg) + len + 1, STACK_ALIGNMENT);
	arg = (struct dl_entry_arg *)usr_stack;

	res = tee_mmu_check_access_rights(utc, TEE_MEMORY_ACCESS_READ |
					  TEE_MEMORY_ACCESS_WRITE |
					  TEE_MEMORY_ACCESS_ANY_OWNER,
					  (uaddr_t)arg,
					  sizeof(*arg) + len + 1);
	if (res) {
		EMSG("ldelf stack is inaccessible!");
		return res;
	}

	memset(arg, 0, sizeof(*arg));
	arg->cmd = LDELF_DL_ENTRY_DLSYM;
	arg->dlsym.uuid = *uuid;
	memcpy(arg->dlsym.symbol, sym, len);
	arg->dlsym.symbol[len] = '\0';

	res = thread_enter_user_mode((vaddr_t)arg, 0, 0, 0,
				     usr_stack, utc->dl_entry_func,
				     is_arm32, &panicked, &panic_code);
	if (panicked) {
		EMSG("ldelf dl_entry function panicked");
		abort_print_current_ta();
		res = TEE_ERROR_TARGET_DEAD;
	}
	if (!res) {
		res = arg->ret;
		if (!res)
			*val = arg->dlsym.val;
	}

	return res;
}

static TEE_Result system_dlopen(struct tee_ta_session *cs, uint32_t param_types,
				TEE_Param params[TEE_NUM_PARAMS])
{
	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
					  TEE_PARAM_TYPE_VALUE_INPUT,
					  TEE_PARAM_TYPE_NONE,
					  TEE_PARAM_TYPE_NONE);
	TEE_Result res = TEE_ERROR_GENERIC;
	struct tee_ta_session *s = NULL;
	struct user_ta_ctx *utc = NULL;
	TEE_UUID *uuid = NULL;
	uint32_t flags = 0;

	if (exp_pt != param_types)
		return TEE_ERROR_BAD_PARAMETERS;

	uuid = params[0].memref.buffer;
	if (!uuid || params[0].memref.size != sizeof(*uuid))
		return TEE_ERROR_BAD_PARAMETERS;

	flags = params[1].value.a;

	utc = to_user_ta_ctx(cs->ctx);

	s = tee_ta_pop_current_session();
	res = call_ldelf_dlopen(utc, uuid, flags);
	tee_ta_push_current_session(s);

	return res;
}

static TEE_Result system_dlsym(struct tee_ta_session *cs, uint32_t param_types,
			       TEE_Param params[TEE_NUM_PARAMS])
{
	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
					  TEE_PARAM_TYPE_MEMREF_INPUT,
					  TEE_PARAM_TYPE_VALUE_OUTPUT,
					  TEE_PARAM_TYPE_NONE);
	TEE_Result res = TEE_ERROR_GENERIC;
	struct tee_ta_session *s = NULL;
	struct user_ta_ctx *utc = NULL;
	const char *sym = NULL;
	TEE_UUID *uuid = NULL;
	size_t maxlen = 0;
	vaddr_t va = 0;

	if (exp_pt != param_types)
		return TEE_ERROR_BAD_PARAMETERS;

	uuid = params[0].memref.buffer;
	if (uuid && params[0].memref.size != sizeof(*uuid))
		return TEE_ERROR_BAD_PARAMETERS;

	sym = params[1].memref.buffer;
	if (!sym)
		return TEE_ERROR_BAD_PARAMETERS;
	maxlen = params[1].memref.size;

	utc = to_user_ta_ctx(cs->ctx);

	s = tee_ta_pop_current_session();
	res = call_ldelf_dlsym(utc, uuid, sym, maxlen, &va);
	tee_ta_push_current_session(s);

	if (!res)
		reg_pair_from_64(va, &params[2].value.a, &params[2].value.b);

	return res;
}

static TEE_Result open_session(uint32_t param_types __unused,
			       TEE_Param params[TEE_NUM_PARAMS] __unused,
			       void **sess_ctx)
{
	struct tee_ta_session *s = NULL;
	struct system_ctx *ctx = NULL;

	/* Check that we're called from a user TA */
	s = tee_ta_get_calling_session();
	if (!s)
		return TEE_ERROR_ACCESS_DENIED;
	if (!is_user_ta_ctx(s->ctx))
		return TEE_ERROR_ACCESS_DENIED;

	ctx = calloc(1, sizeof(*ctx));
	if (!ctx)
		return TEE_ERROR_OUT_OF_MEMORY;

	*sess_ctx = ctx;

	return TEE_SUCCESS;
}

static void close_session(void *sess_ctx)
{
	struct system_ctx *ctx = sess_ctx;

	handle_db_destroy(&ctx->db, ta_bin_close);
	free(ctx);
}

static TEE_Result invoke_command(void *sess_ctx, uint32_t cmd_id,
				 uint32_t param_types,
				 TEE_Param params[TEE_NUM_PARAMS])
{
	struct tee_ta_session *s = tee_ta_get_calling_session();

	switch (cmd_id) {
	case PTA_SYSTEM_ADD_RNG_ENTROPY:
		return system_rng_reseed(s, param_types, params);
	case PTA_SYSTEM_DERIVE_TA_UNIQUE_KEY:
		return system_derive_ta_unique_key(s, param_types, params);
	case PTA_SYSTEM_MAP_ZI:
		return system_map_zi(s, param_types, params);
	case PTA_SYSTEM_UNMAP:
		return system_unmap(s, param_types, params);
	case PTA_SYSTEM_OPEN_TA_BINARY:
		return system_open_ta_binary(sess_ctx, param_types, params);
	case PTA_SYSTEM_CLOSE_TA_BINARY:
		return system_close_ta_binary(sess_ctx, param_types, params);
	case PTA_SYSTEM_MAP_TA_BINARY:
		return system_map_ta_binary(sess_ctx, s, param_types, params);
	case PTA_SYSTEM_COPY_FROM_TA_BINARY:
		return system_copy_from_ta_binary(sess_ctx, param_types,
						  params);
	case PTA_SYSTEM_SET_PROT:
		return system_set_prot(s, param_types, params);
	case PTA_SYSTEM_REMAP:
		return system_remap(s, param_types, params);
	case PTA_SYSTEM_DLOPEN:
		return system_dlopen(s, param_types, params);
	case PTA_SYSTEM_DLSYM:
		return system_dlsym(s, param_types, params);
	default:
		break;
	}

	return TEE_ERROR_NOT_IMPLEMENTED;
}

pseudo_ta_register(.uuid = PTA_SYSTEM_UUID, .name = "system.pta",
		   .flags = PTA_DEFAULT_FLAGS | TA_FLAG_CONCURRENT,
		   .open_session_entry_point = open_session,
		   .close_session_entry_point = close_session,
		   .invoke_command_entry_point = invoke_command);
