// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright (c) 2014, STMicroelectronics International N.V.
 */

#include <kernel/mutex.h>
#include <stdlib.h>
#include <string.h>
#include <tee/tee_pobj.h>
#include <trace.h>

static TAILQ_HEAD(tee_pobjs, tee_pobj) tee_pobjs =
		TAILQ_HEAD_INITIALIZER(tee_pobjs);
static struct mutex pobjs_mutex = MUTEX_INITIALIZER;

static TEE_Result tee_pobj_check_access(uint32_t oflags, uint32_t nflags)
{
	/* meta is exclusive */
	if ((oflags & TEE_DATA_FLAG_ACCESS_WRITE_META) ||
	    (nflags & TEE_DATA_FLAG_ACCESS_WRITE_META))
		return TEE_ERROR_ACCESS_CONFLICT;

	/*
	 * Excerpt of TEE Internal Core API Specification v1.1:
	 * If more than one handle is opened on the same  object, and if any
	 * of these object handles was opened with the flag
	 * TEE_DATA_FLAG_ACCESS_READ, then all the object handles MUST have been
	 * opened with the flag TEE_DATA_FLAG_SHARE_READ
	 */
	if (((oflags & TEE_DATA_FLAG_ACCESS_READ) ||
	     (nflags & TEE_DATA_FLAG_ACCESS_READ)) &&
	    !((nflags & TEE_DATA_FLAG_SHARE_READ) &&
	      (oflags & TEE_DATA_FLAG_SHARE_READ)))
		return TEE_ERROR_ACCESS_CONFLICT;

	/*
	 * Excerpt of TEE Internal Core API Specification v1.1:
	 * An object can be opened with only share flags, which locks the access
	 * to an object against a given mode.
	 * An object can be opened with no flag set, which completely locks all
	 * subsequent attempts to access the object
	 */
	if ((nflags & TEE_DATA_FLAG_SHARE_READ) !=
	    (oflags & TEE_DATA_FLAG_SHARE_READ))
		return TEE_ERROR_ACCESS_CONFLICT;

	/* Same on WRITE access */
	if (((oflags & TEE_DATA_FLAG_ACCESS_WRITE) ||
	     (nflags & TEE_DATA_FLAG_ACCESS_WRITE)) &&
	    !((nflags & TEE_DATA_FLAG_SHARE_WRITE) &&
	      (oflags & TEE_DATA_FLAG_SHARE_WRITE)))
		return TEE_ERROR_ACCESS_CONFLICT;
	if ((nflags & TEE_DATA_FLAG_SHARE_WRITE) !=
	    (oflags & TEE_DATA_FLAG_SHARE_WRITE))
		return TEE_ERROR_ACCESS_CONFLICT;

	return TEE_SUCCESS;
}

TEE_Result tee_pobj_get(TEE_UUID *uuid, void *obj_id, uint32_t obj_id_len,
			uint32_t flags, bool temporary,
			const struct tee_file_operations *fops,
			struct tee_pobj **obj)
{
	struct tee_pobj *o;
	TEE_Result res;

	*obj = NULL;

	mutex_lock(&pobjs_mutex);
	/* Check if file is open */
	TAILQ_FOREACH(o, &tee_pobjs, link) {
		if ((obj_id_len == o->obj_id_len) &&
		    (memcmp(obj_id, o->obj_id, obj_id_len) == 0) &&
		    (memcmp(uuid, &o->uuid, sizeof(TEE_UUID)) == 0) &&
		    (fops == o->fops)) {
			*obj = o;
		}
	}

	if (*obj) {
		if (temporary != (*obj)->temporary) {
			res = TEE_ERROR_ACCESS_CONFLICT;
			goto out;
		}
		res = tee_pobj_check_access((*obj)->flags, flags);
		if (res == TEE_SUCCESS)
			(*obj)->refcnt++;
		goto out;
	}

	/* new file */
	o = calloc(1, sizeof(struct tee_pobj));
	if (!o) {
		res = TEE_ERROR_OUT_OF_MEMORY;
		goto out;
	}

	o->refcnt = 1;
	memcpy(&o->uuid, uuid, sizeof(TEE_UUID));
	o->flags = flags;
	o->fops = fops;
	o->temporary = temporary;

	o->obj_id = malloc(obj_id_len);
	if (o->obj_id == NULL) {
		free(o);
		res = TEE_ERROR_OUT_OF_MEMORY;
		goto out;
	}
	memcpy(o->obj_id, obj_id, obj_id_len);
	o->obj_id_len = obj_id_len;

	TAILQ_INSERT_TAIL(&tee_pobjs, o, link);
	*obj = o;

	res = TEE_SUCCESS;
out:
	if (res != TEE_SUCCESS)
		*obj = NULL;
	mutex_unlock(&pobjs_mutex);
	return res;
}

TEE_Result tee_pobj_release(struct tee_pobj *obj)
{
	if (obj == NULL)
		return TEE_ERROR_BAD_PARAMETERS;

	mutex_lock(&pobjs_mutex);
	obj->refcnt--;
	if (obj->refcnt == 0) {
		TAILQ_REMOVE(&tee_pobjs, obj, link);
		free(obj->obj_id);
		free(obj);
	}
	mutex_unlock(&pobjs_mutex);

	return TEE_SUCCESS;
}

TEE_Result tee_pobj_rename(struct tee_pobj *obj, void *obj_id,
			   uint32_t obj_id_len)
{
	TEE_Result res = TEE_SUCCESS;
	void *new_obj_id = NULL;

	if (obj == NULL || obj_id == NULL)
		return TEE_ERROR_BAD_PARAMETERS;

	mutex_lock(&pobjs_mutex);
	if (obj->refcnt != 1) {
		res = TEE_ERROR_BAD_STATE;
		goto exit;
	}

	new_obj_id = malloc(obj_id_len);
	if (new_obj_id == NULL) {
		res = TEE_ERROR_OUT_OF_MEMORY;
		goto exit;
	}
	memcpy(new_obj_id, obj_id, obj_id_len);

	/* update internal data */
	free(obj->obj_id);
	obj->obj_id = new_obj_id;
	obj->obj_id_len = obj_id_len;
	new_obj_id = NULL;

exit:
	mutex_unlock(&pobjs_mutex);
	free(new_obj_id);
	return res;
}
