/* SPDX-License-Identifier: GPL-2.0-or-later */

#include "vs.h"

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "udk2017.h"
#include "utils.h"

static size_t get_var_hdr_size(bool auth_vars)
{
	if (auth_vars)
		return sizeof(AUTHENTICATED_VARIABLE_HEADER);
	return sizeof(VARIABLE_HEADER);
}

struct var_store_t vs_load(struct mem_range_t vs_data, bool auth_vars)
{
	uint8_t *var_hdr = vs_data.start;

	struct var_store_t vs = {
		.auth_vars = auth_vars,
		.vars = NULL,
	};

	struct var_t *last_var = NULL;

	const size_t var_hdr_size = get_var_hdr_size(auth_vars);
	while (var_hdr + var_hdr_size < vs_data.start + vs_data.length) {
		uint16_t start_id;
		uint8_t state;
		struct var_t var = {0};
		uint8_t *var_data = var_hdr;

		if (auth_vars) {
			const AUTHENTICATED_VARIABLE_HEADER *auth_hdr =
				(void *)var_data;

			start_id = auth_hdr->StartId;
			state = auth_hdr->State;

			var.reserved = auth_hdr->Reserved;
			var.attrs = auth_hdr->Attributes;
			var.name_size = auth_hdr->NameSize;
			var.data_size = auth_hdr->DataSize;
			var.guid = auth_hdr->VendorGuid;
		} else {
			const VARIABLE_HEADER *no_auth_hdr = (void *)var_data;

			start_id = no_auth_hdr->StartId;
			state = no_auth_hdr->State;

			var.reserved = no_auth_hdr->Reserved;
			var.attrs = no_auth_hdr->Attributes;
			var.name_size = no_auth_hdr->NameSize;
			var.data_size = no_auth_hdr->DataSize;
			var.guid = no_auth_hdr->VendorGuid;
		}

		var_hdr += HEADER_ALIGN(var_hdr_size +
					var.name_size +
					var.data_size);

		if (start_id != VARIABLE_DATA)
			break;

		if (state != VAR_ADDED)
			continue;

		if (var.data_size == UINT32_MAX ||
		    var.name_size == UINT32_MAX ||
		    var.attrs == UINT32_MAX)
			continue;

		CHAR16 *name = (void *)(var_data + var_hdr_size);
		var.name = xmalloc(var.name_size);
		memcpy(var.name, name, var.name_size);

		uint8_t *data =
			(void *)(var_data + var_hdr_size + var.name_size);
		var.data = xmalloc(var.data_size);
		memcpy(var.data, data, var.data_size);

		struct var_t *var_node = xmalloc(sizeof(*var_node));
		*var_node = var;
		if (last_var != NULL)
			last_var->next = var_node;
		else if (vs.vars == NULL)
			vs.vars = var_node;
		last_var = var_node;
	}

	return vs;
}

static void store_var(const struct var_t *var, bool auth_vars, uint8_t *data)
{
	if (auth_vars) {
		AUTHENTICATED_VARIABLE_HEADER hdr;
		memset(&hdr, 0xff, sizeof(hdr));

		hdr.StartId = VARIABLE_DATA;
		hdr.State = VAR_ADDED;
		hdr.Reserved = var->reserved;
		hdr.Attributes = var->attrs;
		hdr.VendorGuid = var->guid;
		hdr.NameSize = var->name_size;
		hdr.DataSize = var->data_size;

		memcpy(data, &hdr, sizeof(hdr));
		data += sizeof(hdr);
	} else {
		VARIABLE_HEADER hdr;
		memset(&hdr, 0xff, sizeof(hdr));

		hdr.StartId = VARIABLE_DATA;
		hdr.State = VAR_ADDED;
		hdr.Reserved = var->reserved;
		hdr.Attributes = var->attrs;
		hdr.VendorGuid = var->guid;
		hdr.NameSize = var->name_size;
		hdr.DataSize = var->data_size;

		memcpy(data, &hdr, sizeof(hdr));
		data += sizeof(hdr);
	}

	memcpy(data, var->name, var->name_size);
	memcpy(data + var->name_size, var->data, var->data_size);
}

bool vs_store(struct var_store_t *vs, struct mem_range_t vs_data)
{
	uint8_t *out_data = vs_data.start;

	const size_t var_hdr_size = get_var_hdr_size(vs->auth_vars);
	for (struct var_t *var = vs->vars; var != NULL; var = var->next) {
		const size_t var_size =
			var_hdr_size + var->name_size + var->data_size;
		if (out_data + var_size > vs_data.start + vs_data.length) {
			fprintf(stderr,
				"Not enough space to serialize Variable Store.\n");
			return false;
		}

		store_var(var, vs->auth_vars, out_data);
		out_data += HEADER_ALIGN(var_size);
	}

	// The rest is "uninitialized".
	memset(out_data, 0xff, vs_data.length - (out_data - vs_data.start));

	return true;
}

struct var_t *vs_new_var(struct var_store_t *vs)
{
	struct var_t *new_var = xmalloc(sizeof(*new_var));

	memset(new_var, 0, sizeof(*new_var));
	new_var->attrs = EFI_VARIABLE_NON_VOLATILE
				   | EFI_VARIABLE_BOOTSERVICE_ACCESS
				   | EFI_VARIABLE_RUNTIME_ACCESS;

	struct var_t *var = vs->vars;
	if (var == NULL) {
		vs->vars = new_var;
	} else {
		while (var->next != NULL)
			var = var->next;
		var->next = new_var;
	}

	return new_var;
}

struct var_t *vs_find(struct var_store_t *vs,
		      const char name[],
		      const EFI_GUID *guid)
{
	size_t name_size;
	CHAR16 *uchar_name = to_uchars(name, &name_size);

	struct var_t *var;
	for (var = vs->vars; var != NULL; var = var->next) {
		if (var->name_size != name_size)
			continue;
		if (memcmp(var->name, uchar_name, name_size) != 0)
			continue;
		if (memcmp(&var->guid, guid, sizeof(*guid)) != 0)
			continue;
		break;
	}

	free(uchar_name);
	return var;
}

static void free_var(struct var_t *var)
{
	free(var->name);
	free(var->data);
	free(var);
}

void vs_delete(struct var_store_t *vs, struct var_t *var)
{
	if (vs->vars == var) {
		vs->vars = var->next;
		free_var(var);
		return;
	}

	for (struct var_t *v = vs->vars; v != NULL; v = v->next) {
		if (v->next == var) {
			v->next = var->next;
			free_var(var);
			return;
		}
	}
}

void vs_free(struct var_store_t *vs)
{
	for (struct var_t *next, *var = vs->vars; var != NULL; var = next) {
		next = var->next;
		free_var(var);
	}
}
