// SPDX-License-Identifier: BSD-2-Clause
/*
 * SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/queue.h>
#include "jetson_ekb_user_key_management.h"

static TAILQ_HEAD(user_keys, user_key) user_keys =
		TAILQ_HEAD_INITIALIZER(user_keys);

TEE_Result jetson_ekb_extraction_parse_key(void *decrypted_ekb_content)
{
	TEE_Result rc = TEE_SUCCESS;
	struct user_key *ekb_key = NULL, *next = NULL;
	uint8_t *p = NULL;

	p = decrypted_ekb_content;
	/* Parse the EKB keys */
	while (true) {
		ekb_key = malloc(sizeof(struct user_key));
		if (!ekb_key) {
			rc = TEE_ERROR_OUT_OF_MEMORY;
			break;
		}

		memcpy(&ekb_key->type, p, sizeof(ekb_key->type));
		p = p + sizeof(ekb_key->type);
		memcpy(&ekb_key->len, p, sizeof(ekb_key->len));
		if ((ekb_key->type == 0) && (ekb_key->len == 0)) {
			free(ekb_key);
			break;
		}
		p = p + sizeof(ekb_key->len);
		ekb_key->data = malloc(ekb_key->len);
		if (!(ekb_key->data)) {
			free(ekb_key);
			rc = TEE_ERROR_OUT_OF_MEMORY;
			break;
		}
		memcpy(ekb_key->data, p, ekb_key->len);
		p += ekb_key->len;
		TAILQ_INSERT_TAIL(&user_keys, ekb_key, link);
	}

	if (rc) {
		TAILQ_FOREACH_SAFE(ekb_key, &user_keys, link, next) {
			if (ekb_key && ekb_key->data)
				free(ekb_key->data);
			free(ekb_key);
		}
	}

	return rc;
}

/*
 * Get keys from ekb without check.
 *
 * NOTE:
 * Since this function can get any key from ekb without checking,
 * the caller should take the responsibility of checking the key type.
 */
TEE_Result jetson_pta_get_key_by_type(struct user_key **ekb_key, uint32_t key_type)
{
	struct user_key *tmp_key;

	TAILQ_FOREACH(tmp_key, &user_keys, link)
		if (tmp_key->type == key_type) {
			*ekb_key = tmp_key;
			return TEE_SUCCESS;
		}

	return TEE_ERROR_ITEM_NOT_FOUND;
}
