// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright (c) 2014, STMicroelectronics International N.V.
 */
#include <stdlib.h>
#include <string.h>

#include <tee_api.h>
#include <utee_syscalls.h>
#include "tee_api_private.h"

#define TEE_USAGE_DEFAULT   0xffffffff

#define TEE_ATTR_BIT_VALUE                  (1 << 29)
#define TEE_ATTR_BIT_PROTECTED              (1 << 28)

void __utee_from_attr(struct utee_attribute *ua, const TEE_Attribute *attrs,
			uint32_t attr_count)
{
	size_t n;

	for (n = 0; n < attr_count; n++) {
		ua[n].attribute_id = attrs[n].attributeID;
		if (attrs[n].attributeID & TEE_ATTR_BIT_VALUE) {
			ua[n].a = attrs[n].content.value.a;
			ua[n].b = attrs[n].content.value.b;
		} else {
			ua[n].a = (uintptr_t)attrs[n].content.ref.buffer;
			ua[n].b = attrs[n].content.ref.length;
		}
	}
}

/* Data and Key Storage API  - Generic Object Functions */
/*
 * Use of this function is deprecated
 * new code SHOULD use the TEE_GetObjectInfo1 function instead
 * These functions will be removed at some future major revision of
 * this specification
 */
void TEE_GetObjectInfo(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo)
{
	TEE_Result res;

	res = utee_cryp_obj_get_info((unsigned long)object, objectInfo);

	if (res != TEE_SUCCESS)
		TEE_Panic(res);

	if (objectInfo->objectType == TEE_TYPE_CORRUPTED_OBJECT) {
		objectInfo->keySize = 0;
		objectInfo->maxKeySize = 0;
		objectInfo->objectUsage = 0;
		objectInfo->dataSize = 0;
		objectInfo->dataPosition = 0;
		objectInfo->handleFlags = 0;
	}
}

TEE_Result TEE_GetObjectInfo1(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo)
{
	TEE_Result res;

	res = utee_cryp_obj_get_info((unsigned long)object, objectInfo);

	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_CORRUPT_OBJECT &&
	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
		TEE_Panic(res);

	return res;
}

/*
 * Use of this function is deprecated
 * new code SHOULD use the TEE_RestrictObjectUsage1 function instead
 * These functions will be removed at some future major revision of
 * this specification
 */
void TEE_RestrictObjectUsage(TEE_ObjectHandle object, uint32_t objectUsage)
{
	TEE_Result res;
	TEE_ObjectInfo objectInfo;

	res = utee_cryp_obj_get_info((unsigned long)object, &objectInfo);
	if (objectInfo.objectType == TEE_TYPE_CORRUPTED_OBJECT)
		return;

	res = TEE_RestrictObjectUsage1(object, objectUsage);

	if (res != TEE_SUCCESS)
		TEE_Panic(res);
}

TEE_Result TEE_RestrictObjectUsage1(TEE_ObjectHandle object, uint32_t objectUsage)
{
	TEE_Result res;

	res = utee_cryp_obj_restrict_usage((unsigned long)object, objectUsage);

	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_CORRUPT_OBJECT &&
	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
		TEE_Panic(res);

	return res;
}

TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object,
					uint32_t attributeID, void *buffer,
					uint32_t *size)
{
	TEE_Result res;
	TEE_ObjectInfo info;
	uint64_t sz;

	res = utee_cryp_obj_get_info((unsigned long)object, &info);
	if (res != TEE_SUCCESS)
		goto exit;

	/* This function only supports reference attributes */
	if ((attributeID & TEE_ATTR_BIT_VALUE)) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto exit;
	}

	sz = *size;
	res = utee_cryp_obj_get_attr((unsigned long)object, attributeID,
				     buffer, &sz);
	*size = sz;

exit:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_ITEM_NOT_FOUND &&
	    res != TEE_ERROR_SHORT_BUFFER &&
	    res != TEE_ERROR_CORRUPT_OBJECT &&
	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
		TEE_Panic(res);

	return res;
}

TEE_Result TEE_GetObjectValueAttribute(TEE_ObjectHandle object,
				       uint32_t attributeID, uint32_t *a,
				       uint32_t *b)
{
	TEE_Result res;
	TEE_ObjectInfo info;
	uint32_t buf[2];
	uint64_t size = sizeof(buf);

	res = utee_cryp_obj_get_info((unsigned long)object, &info);
	if (res != TEE_SUCCESS)
		goto exit;

	/* This function only supports value attributes */
	if (!(attributeID & TEE_ATTR_BIT_VALUE)) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto exit;
	}

	res = utee_cryp_obj_get_attr((unsigned long)object, attributeID, buf,
				     &size);

exit:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_ITEM_NOT_FOUND &&
	    res != TEE_ERROR_CORRUPT_OBJECT &&
	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
		TEE_Panic(res);

	if (size != sizeof(buf))
		TEE_Panic(0);

	if (res == TEE_SUCCESS) {
		if (a)
			*a = buf[0];
		if (b)
			*b = buf[1];
	}

	return res;
}

void TEE_CloseObject(TEE_ObjectHandle object)
{
	TEE_Result res;

	if (object == TEE_HANDLE_NULL)
		return;

	res = utee_cryp_obj_close((unsigned long)object);
	if (res != TEE_SUCCESS)
		TEE_Panic(res);
}

/* Data and Key Storage API  - Transient Object Functions */

TEE_Result TEE_AllocateTransientObject(TEE_ObjectType objectType,
				       uint32_t maxKeySize,
				       TEE_ObjectHandle *object)
{
	TEE_Result res;
	uint32_t obj;

	res = utee_cryp_obj_alloc(objectType, maxKeySize, &obj);

	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_OUT_OF_MEMORY &&
	    res != TEE_ERROR_NOT_SUPPORTED)
		TEE_Panic(res);

	if (res == TEE_SUCCESS)
		*object = (TEE_ObjectHandle)(uintptr_t)obj;

	return res;
}

void TEE_FreeTransientObject(TEE_ObjectHandle object)
{
	TEE_Result res;
	TEE_ObjectInfo info;

	if (object == TEE_HANDLE_NULL)
		return;

	res = utee_cryp_obj_get_info((unsigned long)object, &info);
	if (res != TEE_SUCCESS)
		TEE_Panic(res);

	if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
		TEE_Panic(0);

	res = utee_cryp_obj_close((unsigned long)object);
	if (res != TEE_SUCCESS)
		TEE_Panic(res);
}

void TEE_ResetTransientObject(TEE_ObjectHandle object)
{
	TEE_Result res;
	TEE_ObjectInfo info;

	if (object == TEE_HANDLE_NULL)
		return;

	res = utee_cryp_obj_get_info((unsigned long)object, &info);
	if (res != TEE_SUCCESS)
		TEE_Panic(res);

	if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
		TEE_Panic(0);

	res = utee_cryp_obj_reset((unsigned long)object);
	if (res != TEE_SUCCESS)
		TEE_Panic(res);
}

TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object,
				       const TEE_Attribute *attrs,
				       uint32_t attrCount)
{
	TEE_Result res;
	TEE_ObjectInfo info;
	struct utee_attribute ua[attrCount];

	res = utee_cryp_obj_get_info((unsigned long)object, &info);
	if (res != TEE_SUCCESS)
		TEE_Panic(res);

	/* Must be a transient object */
	if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
		TEE_Panic(0);

	/* Must not be initialized already */
	if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
		TEE_Panic(0);

	__utee_from_attr(ua, attrs, attrCount);
	res = utee_cryp_obj_populate((unsigned long)object, ua, attrCount);
	if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS)
		TEE_Panic(res);
	return res;
}

void TEE_InitRefAttribute(TEE_Attribute *attr, uint32_t attributeID,
			  const void *buffer, uint32_t length)
{
	if (attr == NULL)
		TEE_Panic(0);
	if ((attributeID & TEE_ATTR_BIT_VALUE) != 0)
		TEE_Panic(0);
	attr->attributeID = attributeID;
	attr->content.ref.buffer = (void *)buffer;
	attr->content.ref.length = length;
}

void TEE_InitValueAttribute(TEE_Attribute *attr, uint32_t attributeID,
			    uint32_t a, uint32_t b)
{
	if (attr == NULL)
		TEE_Panic(0);
	if ((attributeID & TEE_ATTR_BIT_VALUE) == 0)
		TEE_Panic(0);
	attr->attributeID = attributeID;
	attr->content.value.a = a;
	attr->content.value.b = b;
}

/*
 * Use of this function is deprecated
 * new code SHOULD use the TEE_CopyObjectAttributes1 function instead
 * These functions will be removed at some future major revision of
 * this specification
 */
void TEE_CopyObjectAttributes(TEE_ObjectHandle destObject,
			      TEE_ObjectHandle srcObject)
{
	TEE_Result res;
	TEE_ObjectInfo src_info;

	res = utee_cryp_obj_get_info((unsigned long)srcObject, &src_info);
	if (src_info.objectType == TEE_TYPE_CORRUPTED_OBJECT)
		return;

	res = TEE_CopyObjectAttributes1(destObject, srcObject);
	if (res != TEE_SUCCESS)
		TEE_Panic(res);
}

TEE_Result TEE_CopyObjectAttributes1(TEE_ObjectHandle destObject,
			      TEE_ObjectHandle srcObject)
{
	TEE_Result res;
	TEE_ObjectInfo dst_info;
	TEE_ObjectInfo src_info;

	res = utee_cryp_obj_get_info((unsigned long)destObject, &dst_info);
	if (res != TEE_SUCCESS)
		goto exit;

	res = utee_cryp_obj_get_info((unsigned long)srcObject, &src_info);
	if (res != TEE_SUCCESS)
		goto exit;

	if (!(src_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED))
		TEE_Panic(0);

	if ((dst_info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT))
		TEE_Panic(0);

	if ((dst_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED))
		TEE_Panic(0);

	res = utee_cryp_obj_copy((unsigned long)destObject,
				 (unsigned long)srcObject);

exit:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_CORRUPT_OBJECT &&
	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
		TEE_Panic(res);

	return res;
}

TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize,
			   const TEE_Attribute *params, uint32_t paramCount)
{
	TEE_Result res;
	struct utee_attribute ua[paramCount];

	__utee_from_attr(ua, params, paramCount);
	res = utee_cryp_obj_generate_key((unsigned long)object, keySize,
					 ua, paramCount);

	if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS)
		TEE_Panic(res);

	return res;
}

/* Data and Key Storage API  - Persistent Object Functions */

TEE_Result TEE_OpenPersistentObject(uint32_t storageID, const void *objectID,
				    uint32_t objectIDLen, uint32_t flags,
				    TEE_ObjectHandle *object)
{
	TEE_Result res;
	uint32_t obj;

	if (!objectID) {
		res = TEE_ERROR_ITEM_NOT_FOUND;
		goto exit;
	}

	if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto exit;
	}

	res = utee_storage_obj_open(storageID, objectID, objectIDLen, flags,
				     &obj);
	if (res == TEE_SUCCESS)
		*object = (TEE_ObjectHandle)(uintptr_t)obj;

exit:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_ITEM_NOT_FOUND &&
	    res != TEE_ERROR_ACCESS_CONFLICT &&
	    res != TEE_ERROR_OUT_OF_MEMORY &&
	    res != TEE_ERROR_CORRUPT_OBJECT &&
	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
		TEE_Panic(res);

	if (res != TEE_SUCCESS)
		*object = TEE_HANDLE_NULL;

	return res;
}

TEE_Result TEE_CreatePersistentObject(uint32_t storageID, const void *objectID,
				      uint32_t objectIDLen, uint32_t flags,
				      TEE_ObjectHandle attributes,
				      const void *initialData,
				      uint32_t initialDataLen,
				      TEE_ObjectHandle *object)
{
	TEE_Result res;
	uint32_t obj;

	if (!objectID) {
		res = TEE_ERROR_ITEM_NOT_FOUND;
		goto exit;
	}

	if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto exit;
	}

	res = utee_storage_obj_create(storageID, objectID, objectIDLen, flags,
				      (unsigned long)attributes, initialData,
				      initialDataLen, &obj);

	if (res == TEE_SUCCESS)
		*object = (TEE_ObjectHandle)(uintptr_t)obj;

exit:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_ITEM_NOT_FOUND &&
	    res != TEE_ERROR_ACCESS_CONFLICT &&
	    res != TEE_ERROR_OUT_OF_MEMORY &&
	    res != TEE_ERROR_STORAGE_NO_SPACE &&
	    res != TEE_ERROR_CORRUPT_OBJECT &&
	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
		TEE_Panic(res);

	if (res != TEE_SUCCESS)
		*object = TEE_HANDLE_NULL;

	return res;
}

/*
 * Use of this function is deprecated
 * new code SHOULD use the TEE_CloseAndDeletePersistentObject1 function instead
 * These functions will be removed at some future major revision of
 * this specification
 */
void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object)
{
	TEE_Result res;

	if (object == TEE_HANDLE_NULL)
		return;

	res = TEE_CloseAndDeletePersistentObject1(object);

	if (res != TEE_SUCCESS)
		TEE_Panic(0);
}

TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object)
{
	TEE_Result res;

	if (object == TEE_HANDLE_NULL)
		return TEE_ERROR_STORAGE_NOT_AVAILABLE;

	res = utee_storage_obj_del((unsigned long)object);

	if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
		TEE_Panic(res);

	return res;
}


TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object,
				      const void *newObjectID,
				      uint32_t newObjectIDLen)
{
	TEE_Result res;

	if (object == TEE_HANDLE_NULL) {
		res = TEE_ERROR_ITEM_NOT_FOUND;
		goto out;
	}

	if (!newObjectID) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (newObjectIDLen > TEE_OBJECT_ID_MAX_LEN) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	res = utee_storage_obj_rename((unsigned long)object, newObjectID,
				      newObjectIDLen);

out:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_ACCESS_CONFLICT &&
	    res != TEE_ERROR_CORRUPT_OBJECT &&
	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
		TEE_Panic(res);

	return res;
}

TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle *
						  objectEnumerator)
{
	TEE_Result res;
	uint32_t oe;

	if (!objectEnumerator)
		return TEE_ERROR_BAD_PARAMETERS;

	res = utee_storage_alloc_enum(&oe);

	if (res != TEE_SUCCESS)
		oe = TEE_HANDLE_NULL;

	*objectEnumerator = (TEE_ObjectEnumHandle)(uintptr_t)oe;

	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_ACCESS_CONFLICT)
		TEE_Panic(res);

	return res;
}

void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
{
	TEE_Result res;

	if (objectEnumerator == TEE_HANDLE_NULL)
		return;

	res = utee_storage_free_enum((unsigned long)objectEnumerator);

	if (res != TEE_SUCCESS)
		TEE_Panic(res);
}

void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
{
	TEE_Result res;

	if (objectEnumerator == TEE_HANDLE_NULL)
		return;

	res = utee_storage_reset_enum((unsigned long)objectEnumerator);

	if (res != TEE_SUCCESS)
		TEE_Panic(res);
}

TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle
					       objectEnumerator,
					       uint32_t storageID)
{
	TEE_Result res;

	res = utee_storage_start_enum((unsigned long)objectEnumerator,
				      storageID);

	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_ITEM_NOT_FOUND &&
	    res != TEE_ERROR_CORRUPT_OBJECT &&
	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
		TEE_Panic(res);

	return res;
}

TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator,
				       TEE_ObjectInfo *objectInfo,
				       void *objectID, uint32_t *objectIDLen)
{
	TEE_Result res;
	uint64_t len;
	TEE_ObjectInfo local_info;
	TEE_ObjectInfo *pt_info;

	if (!objectID) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (!objectIDLen) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (objectInfo)
		pt_info = objectInfo;
	else
		pt_info = &local_info;
	len = *objectIDLen;
	res = utee_storage_next_enum((unsigned long)objectEnumerator,
				     pt_info, objectID, &len);
	*objectIDLen = len;

out:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_ITEM_NOT_FOUND &&
	    res != TEE_ERROR_CORRUPT_OBJECT &&
	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
		TEE_Panic(res);

	return res;
}

/* Data and Key Storage API  - Data Stream Access Functions */

TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer,
			      uint32_t size, uint32_t *count)
{
	TEE_Result res;
	uint64_t cnt64;

	if (object == TEE_HANDLE_NULL) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	cnt64 = *count;
	res = utee_storage_obj_read((unsigned long)object, buffer, size,
				    &cnt64);
	*count = cnt64;

out:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_CORRUPT_OBJECT &&
	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
		TEE_Panic(res);

	return res;
}

TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, const void *buffer,
			       uint32_t size)
{
	TEE_Result res;

	if (object == TEE_HANDLE_NULL) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	if (size > TEE_DATA_MAX_POSITION) {
		res = TEE_ERROR_OVERFLOW;
		goto out;
	}

	res = utee_storage_obj_write((unsigned long)object, buffer, size);

out:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_STORAGE_NO_SPACE &&
	    res != TEE_ERROR_OVERFLOW &&
	    res != TEE_ERROR_CORRUPT_OBJECT &&
	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
		TEE_Panic(res);

	return res;
}

TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size)
{
	TEE_Result res;

	if (object == TEE_HANDLE_NULL) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	res = utee_storage_obj_trunc((unsigned long)object, size);

out:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_STORAGE_NO_SPACE &&
	    res != TEE_ERROR_CORRUPT_OBJECT &&
	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
		TEE_Panic(res);

	return res;
}

TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset,
			      TEE_Whence whence)
{
	TEE_Result res;
	TEE_ObjectInfo info;

	if (object == TEE_HANDLE_NULL) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	res = utee_cryp_obj_get_info((unsigned long)object, &info);
	if (res != TEE_SUCCESS)
		goto out;

	switch (whence) {
	case TEE_DATA_SEEK_SET:
		if (offset > 0 && (uint32_t)offset > TEE_DATA_MAX_POSITION) {
			res = TEE_ERROR_OVERFLOW;
			goto out;
		}
		break;
	case TEE_DATA_SEEK_CUR:
		if (offset > 0 &&
		    ((uint32_t)offset + info.dataPosition >
		     TEE_DATA_MAX_POSITION ||
		     (uint32_t)offset + info.dataPosition <
		     info.dataPosition)) {
			res = TEE_ERROR_OVERFLOW;
			goto out;
		}
		break;
	case TEE_DATA_SEEK_END:
		if (offset > 0 &&
		    ((uint32_t)offset + info.dataSize > TEE_DATA_MAX_POSITION ||
		     (uint32_t)offset + info.dataSize < info.dataSize)) {
			res = TEE_ERROR_OVERFLOW;
			goto out;
		}
		break;
	default:
		res = TEE_ERROR_ITEM_NOT_FOUND;
		goto out;
	}

	res = utee_storage_obj_seek((unsigned long)object, offset, whence);

out:
	if (res != TEE_SUCCESS &&
	    res != TEE_ERROR_OVERFLOW &&
	    res != TEE_ERROR_CORRUPT_OBJECT &&
	    res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
		TEE_Panic(res);

	return res;
}
