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

/*
 * Security properties of REE-FS TAs
 * =================================
 *
 * Authentication only
 * -------------------
 *
 * Required security properties:
 * 1. Authentication and non-repudiation of a TA to Service Provider (SP).
 * 2. Integrity of a TA.
 *
 * To satisfy (1) and (2), SP needs to sign TA and OP-TEE core needs to verify
 * the signature using SP public key with computed hash of the TA.
 *
 * Authentication along with Confidentiality
 * -----------------------------------------
 *
 * Required security properties:
 * 1. Authentication and non-repudiation of a TA to Service Provider (SP).
 * 2. Confidentiality of a TA.
 * 3. Integrity of an encrypted TA blob.
 *
 * To satisfy (1), SP needs to sign plain TA and OP-TEE core needs to verify the
 * signature using SP public key with computed hash of the TA.
 *
 * To satisfy (2) and (3), SP needs to do authenticated encryption of TA and
 * OP-TEE core needs to do authenticated decryption of TA to retrieve its
 * contents. Here encryption provides the confidentiality of TA and MAC tag
 * provides the integrity of encrypted TA blob.
 */

#include <assert.h>
#include <crypto/crypto.h>
#include <initcall.h>
#include <kernel/thread.h>
#include <kernel/user_ta_store.h>
#include <mm/core_memprot.h>
#include <mm/tee_mm.h>
#include <mm/mobj.h>
#include <optee_rpc_cmd.h>
#include <signed_hdr.h>
#include <stdlib.h>
#include <string.h>
#include <tee_api_types.h>
#include <tee/tee_ta_enc_manager.h>
#include <tee/uuid.h>
#include <utee_defines.h>

struct ree_fs_ta_handle {
	struct shdr *nw_ta; /* Non-secure (shared memory) */
	size_t nw_ta_size;
	struct mobj *mobj;
	size_t offs;
	struct shdr *shdr; /* Verified secure copy of @nw_ta's signed header */
	void *hash_ctx;
	void *enc_ctx;
	struct shdr_encrypted_ta *ehdr;
};

/*
 * Load a TA via RPC with UUID defined by input param @uuid. The virtual
 * address of the raw TA binary is received in out parameter @ta.
 */
static TEE_Result rpc_load(const TEE_UUID *uuid, struct shdr **ta,
			   size_t *ta_size, struct mobj **mobj)
{
	TEE_Result res;
	struct thread_param params[2];

	if (!uuid || !ta || !mobj || !ta_size)
		return TEE_ERROR_BAD_PARAMETERS;

	memset(params, 0, sizeof(params));
	params[0].attr = THREAD_PARAM_ATTR_VALUE_IN;
	tee_uuid_to_octets((void *)&params[0].u.value, uuid);
	params[1].attr = THREAD_PARAM_ATTR_MEMREF_OUT;

	res = thread_rpc_cmd(OPTEE_RPC_CMD_LOAD_TA, 2, params);
	if (res != TEE_SUCCESS)
		return res;

	*mobj = thread_rpc_alloc_payload(params[1].u.memref.size);
	if (!*mobj)
		return TEE_ERROR_OUT_OF_MEMORY;

	if ((*mobj)->size < params[1].u.memref.size) {
		res = TEE_ERROR_SHORT_BUFFER;
		goto exit;
	}

	*ta = mobj_get_va(*mobj, 0);
	/* We don't expect NULL as thread_rpc_alloc_payload() was successful */
	assert(*ta);
	*ta_size = params[1].u.memref.size;

	params[0].attr = THREAD_PARAM_ATTR_VALUE_IN;
	tee_uuid_to_octets((void *)&params[0].u.value, uuid);
	params[1].attr = THREAD_PARAM_ATTR_MEMREF_OUT;
	params[1].u.memref.offs = 0;
	params[1].u.memref.mobj = *mobj;

	res = thread_rpc_cmd(OPTEE_RPC_CMD_LOAD_TA, 2, params);
exit:
	if (res != TEE_SUCCESS)
		thread_rpc_free_payload(*mobj);

	return res;
}

static TEE_Result ree_fs_ta_open(const TEE_UUID *uuid,
				 struct user_ta_store_handle **h)
{
	struct ree_fs_ta_handle *handle;
	struct shdr *shdr = NULL;
	struct mobj *mobj = NULL;
	void *hash_ctx = NULL;
	struct shdr *ta = NULL;
	size_t ta_size = 0;
	TEE_Result res;
	size_t offs;
	struct shdr_encrypted_ta *ehdr = NULL;

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

	/* Request TA from tee-supplicant */
	res = rpc_load(uuid, &ta, &ta_size, &mobj);
	if (res != TEE_SUCCESS)
		goto error;

	/* Make secure copy of signed header */
	shdr = shdr_alloc_and_copy(ta, ta_size);
	if (!shdr) {
		res = TEE_ERROR_SECURITY;
		goto error_free_payload;
	}

	/* Validate header signature */
	res = shdr_verify_signature(shdr);
	if (res != TEE_SUCCESS)
		goto error_free_payload;
	if (shdr->img_type != SHDR_TA && shdr->img_type != SHDR_BOOTSTRAP_TA &&
	    shdr->img_type != SHDR_ENCRYPTED_TA) {
		res = TEE_ERROR_SECURITY;
		goto error_free_payload;
	}

	/*
	 * Initialize a hash context and run the algorithm over the signed
	 * header (less the final file hash and its signature of course)
	 */
	res = crypto_hash_alloc_ctx(&hash_ctx,
				    TEE_DIGEST_HASH_TO_ALGO(shdr->algo));
	if (res != TEE_SUCCESS)
		goto error_free_payload;
	res = crypto_hash_init(hash_ctx);
	if (res != TEE_SUCCESS)
		goto error_free_hash;
	res = crypto_hash_update(hash_ctx, (uint8_t *)shdr, sizeof(*shdr));
	if (res != TEE_SUCCESS)
		goto error_free_hash;
	offs = SHDR_GET_SIZE(shdr);

	if (shdr->img_type == SHDR_BOOTSTRAP_TA ||
	    shdr->img_type == SHDR_ENCRYPTED_TA) {
		TEE_UUID bs_uuid;
		struct shdr_bootstrap_ta bs_hdr;

		if (ta_size < SHDR_GET_SIZE(shdr) + sizeof(bs_hdr)) {
			res = TEE_ERROR_SECURITY;
			goto error_free_hash;
		}

		memcpy(&bs_hdr, ((uint8_t *)ta + offs), sizeof(bs_hdr));

		/*
		 * There's a check later that the UUID embedded inside the
		 * ELF is matching, but since we now have easy access to
		 * the expected uuid of the TA we check it a bit earlier
		 * here.
		 */
		tee_uuid_from_octets(&bs_uuid, bs_hdr.uuid);
		if (memcmp(&bs_uuid, uuid, sizeof(TEE_UUID))) {
			res = TEE_ERROR_SECURITY;
			goto error_free_hash;
		}

		res = crypto_hash_update(hash_ctx, (uint8_t *)&bs_hdr,
					 sizeof(bs_hdr));
		if (res != TEE_SUCCESS)
			goto error_free_hash;
		offs += sizeof(bs_hdr);
	}

	if (shdr->img_type == SHDR_ENCRYPTED_TA) {
		struct shdr_encrypted_ta img_ehdr;

		if (ta_size < SHDR_GET_SIZE(shdr) +
		    sizeof(struct shdr_bootstrap_ta) + sizeof(img_ehdr)) {
			res = TEE_ERROR_SECURITY;
			goto error_free_hash;
		}

		memcpy(&img_ehdr, ((uint8_t *)ta + offs), sizeof(img_ehdr));

		ehdr = malloc(SHDR_ENC_GET_SIZE(&img_ehdr));
		if (!ehdr)
			return TEE_ERROR_OUT_OF_MEMORY;

		memcpy(ehdr, ((uint8_t *)ta + offs),
		       SHDR_ENC_GET_SIZE(&img_ehdr));

		res = crypto_hash_update(hash_ctx, (uint8_t *)ehdr,
					 SHDR_ENC_GET_SIZE(ehdr));
		if (res != TEE_SUCCESS)
			goto error_free_hash;

		res = tee_ta_decrypt_init(&handle->enc_ctx, ehdr,
					  shdr->img_size);
		if (res != TEE_SUCCESS)
			goto error_free_hash;

		offs += SHDR_ENC_GET_SIZE(ehdr);
		handle->ehdr = ehdr;
	}

	if (ta_size != offs + shdr->img_size) {
		res = TEE_ERROR_SECURITY;
		goto error_free_hash;
	}

	handle->nw_ta = ta;
	handle->nw_ta_size = ta_size;
	handle->offs = offs;
	handle->hash_ctx = hash_ctx;
	handle->shdr = shdr;
	handle->mobj = mobj;
	*h = (struct user_ta_store_handle *)handle;
	return TEE_SUCCESS;

error_free_hash:
	crypto_hash_free_ctx(hash_ctx);
error_free_payload:
	thread_rpc_free_payload(mobj);
error:
	free(ehdr);
	shdr_free(shdr);
	free(handle);
	return res;
}

static TEE_Result ree_fs_ta_get_size(const struct user_ta_store_handle *h,
				     size_t *size)
{
	struct ree_fs_ta_handle *handle = (struct ree_fs_ta_handle *)h;

	*size = handle->shdr->img_size;
	return TEE_SUCCESS;
}

static TEE_Result ree_fs_ta_get_tag(const struct user_ta_store_handle *h,
				    uint8_t *tag, unsigned int *tag_len)
{
	struct ree_fs_ta_handle *handle = (struct ree_fs_ta_handle *)h;

	if (!tag || *tag_len < handle->shdr->hash_size) {
		*tag_len = handle->shdr->hash_size;
		return TEE_ERROR_SHORT_BUFFER;
	}
	*tag_len = handle->shdr->hash_size;

	memcpy(tag, SHDR_GET_HASH(handle->shdr), handle->shdr->hash_size);

	return TEE_SUCCESS;
}

static TEE_Result check_digest(struct ree_fs_ta_handle *h)
{
	void *digest = NULL;
	TEE_Result res;

	digest = malloc(h->shdr->hash_size);
	if (!digest)
		return TEE_ERROR_OUT_OF_MEMORY;
	res = crypto_hash_final(h->hash_ctx, digest, h->shdr->hash_size);
	if (res != TEE_SUCCESS) {
		res = TEE_ERROR_SECURITY;
		goto out;
	}
	if (memcmp(digest, SHDR_GET_HASH(h->shdr), h->shdr->hash_size))
		res = TEE_ERROR_SECURITY;
out:
	free(digest);
	return res;
}

static TEE_Result ree_fs_ta_read(struct user_ta_store_handle *h, void *data,
				 size_t len)
{
	struct ree_fs_ta_handle *handle = (struct ree_fs_ta_handle *)h;

	uint8_t *src = (uint8_t *)handle->nw_ta + handle->offs;
	uint8_t *dst = src;
	TEE_Result res;

	if (handle->offs + len > handle->nw_ta_size)
		return TEE_ERROR_BAD_PARAMETERS;

	if (handle->shdr->img_type == SHDR_ENCRYPTED_TA) {
		if (data) {
			dst = data; /* Hash secure buffer */
			res = tee_ta_decrypt_update(handle->enc_ctx, dst, src,
						    len);
			if (res != TEE_SUCCESS)
				return TEE_ERROR_SECURITY;
		} else {
			size_t num_bytes = 0;
			size_t b_size = MIN(1024U, len);
			uint8_t *b = malloc(b_size);

			if (!b)
				return TEE_ERROR_OUT_OF_MEMORY;

			dst = NULL;
			while (num_bytes < len) {
				size_t n = MIN(b_size, len - num_bytes);

				res = tee_ta_decrypt_update(handle->enc_ctx, b,
							    src + num_bytes, n);
				if (res)
					break;
				num_bytes += n;

				res = crypto_hash_update(handle->hash_ctx, b,
							 n);
				if (res)
					break;
			}

			free(b);
			if (res != TEE_SUCCESS)
				return TEE_ERROR_SECURITY;
		}
	} else if (data) {
		dst = data; /* Hash secure buffer (shm might be modified) */
		memcpy(dst, src, len);
	}

	if (dst) {
		res = crypto_hash_update(handle->hash_ctx, dst, len);
		if (res != TEE_SUCCESS)
			return TEE_ERROR_SECURITY;
	}

	handle->offs += len;
	if (handle->offs == handle->nw_ta_size) {
		if (handle->shdr->img_type == SHDR_ENCRYPTED_TA) {
			/*
			 * Last read: time to finalize authenticated
			 * decryption.
			 */
			res = tee_ta_decrypt_final(handle->enc_ctx,
						   handle->ehdr, NULL, NULL, 0);
			if (res != TEE_SUCCESS)
				return TEE_ERROR_SECURITY;
		}
		/*
		 * Last read: time to check if our digest matches the expected
		 * one (from the signed header)
		 */
		res = check_digest(handle);
	}
	return res;
}

static void ree_fs_ta_close(struct user_ta_store_handle *h)
{
	struct ree_fs_ta_handle *handle = (struct ree_fs_ta_handle *)h;

	if (!handle)
		return;
	thread_rpc_free_payload(handle->mobj);
	crypto_hash_free_ctx(handle->hash_ctx);
	free(handle->shdr);
	free(handle->ehdr);
	free(handle);
}

#ifndef CFG_REE_FS_TA_BUFFERED
TEE_TA_REGISTER_TA_STORE(9) = {
	.description = "REE",
	.open = ree_fs_ta_open,
	.get_size = ree_fs_ta_get_size,
	.get_tag = ree_fs_ta_get_tag,
	.read = ree_fs_ta_read,
	.close = ree_fs_ta_close,
};
#endif

#ifdef CFG_REE_FS_TA_BUFFERED

/*
 * This is a wrapper around the "REE FS" TA store.
 * The whole TA/library is read into a temporary buffer during .open(). This
 * allows the binary to be authenticated before any data is read and processed
 * by the upper layer (ELF loader).
 */

struct buf_ree_fs_ta_handle {
	struct user_ta_store_handle *h; /* Note: a REE FS TA store handle */
	size_t ta_size;
	tee_mm_entry_t *mm;
	uint8_t *buf;
	size_t offs;
	uint8_t *tag;
	unsigned int tag_len;
};

static TEE_Result buf_ta_open(const TEE_UUID *uuid,
			      struct user_ta_store_handle **h)
{
	struct buf_ree_fs_ta_handle *handle = NULL;
	TEE_Result res = TEE_SUCCESS;

	handle = calloc(1, sizeof(*handle));
	if (!handle)
		return TEE_ERROR_OUT_OF_MEMORY;
	res = ree_fs_ta_open(uuid, &handle->h);
	if (res)
		goto err2;
	res = ree_fs_ta_get_size(handle->h, &handle->ta_size);
	if (res)
		goto err;

	res = ree_fs_ta_get_tag(handle->h, NULL, &handle->tag_len);
	if (res != TEE_ERROR_SHORT_BUFFER) {
		res = TEE_ERROR_GENERIC;
		goto err;
	}
	handle->tag = malloc(handle->tag_len);
	if (!handle->tag) {
		res = TEE_ERROR_OUT_OF_MEMORY;
		goto err;
	}
	res = ree_fs_ta_get_tag(handle->h, handle->tag, &handle->tag_len);
	if (res)
		goto err;

	handle->mm = tee_mm_alloc(&tee_mm_sec_ddr, handle->ta_size);
	if (!handle->mm) {
		res = TEE_ERROR_OUT_OF_MEMORY;
		goto err;
	}
	handle->buf = phys_to_virt(tee_mm_get_smem(handle->mm),
				   MEM_AREA_TA_RAM);
	if (!handle->buf) {
		res = TEE_ERROR_OUT_OF_MEMORY;
		goto err;
	}
	res = ree_fs_ta_read(handle->h, handle->buf, handle->ta_size);
	if (res)
		goto err;
	*h = (struct user_ta_store_handle *)handle;
err:
	ree_fs_ta_close(handle->h);
err2:
	if (res) {
		tee_mm_free(handle->mm);
		free(handle->tag);
		free(handle);
	}
	return res;
}

static TEE_Result buf_ta_get_size(const struct user_ta_store_handle *h,
				  size_t *size)
{
	struct buf_ree_fs_ta_handle *handle = (struct buf_ree_fs_ta_handle *)h;

	*size = handle->ta_size;
	return TEE_SUCCESS;
}

static TEE_Result buf_ta_read(struct user_ta_store_handle *h, void *data,
			      size_t len)
{
	struct buf_ree_fs_ta_handle *handle = (struct buf_ree_fs_ta_handle *)h;
	uint8_t *src = handle->buf + handle->offs;

	if (handle->offs + len > handle->ta_size)
		return TEE_ERROR_BAD_PARAMETERS;
	if (data)
		memcpy(data, src, len);
	handle->offs += len;
	return TEE_SUCCESS;
}

static TEE_Result buf_ta_get_tag(const struct user_ta_store_handle *h,
				 uint8_t *tag, unsigned int *tag_len)
{
	struct buf_ree_fs_ta_handle *handle = (struct buf_ree_fs_ta_handle *)h;

	*tag_len = handle->tag_len;
	if (!tag || *tag_len < handle->tag_len)
		return TEE_ERROR_SHORT_BUFFER;

	memcpy(tag, handle->tag, handle->tag_len);

	return TEE_SUCCESS;
}

static void buf_ta_close(struct user_ta_store_handle *h)
{
	struct buf_ree_fs_ta_handle *handle = (struct buf_ree_fs_ta_handle *)h;

	if (!handle)
		return;
	tee_mm_free(handle->mm);
	free(handle->tag);
	free(handle);
}

TEE_TA_REGISTER_TA_STORE(9) = {
	.description = "REE [buffered]",
	.open = buf_ta_open,
	.get_size = buf_ta_get_size,
	.get_tag = buf_ta_get_tag,
	.read = buf_ta_read,
	.close = buf_ta_close,
};

#endif /* CFG_REE_FS_TA_BUFFERED */
