// SPDX-License-Identifier: GPL-2.0+
/*
 *  Integrate UEFI variables to u-boot env interface
 *
 *  Copyright (c) 2018 AKASHI Takahiro, Linaro Limited
 */

#include <charset.h>
#include <common.h>
#include <command.h>
#include <efi_loader.h>
#include <env.h>
#include <exports.h>
#include <hexdump.h>
#include <malloc.h>
#include <mapmem.h>
#include <linux/kernel.h>

/*
 * From efi_variable.c,
 *
 * Mapping between UEFI variables and u-boot variables:
 *
 *   efi_$guid_$varname = {attributes}(type)value
 */

static const struct {
	u32 mask;
	char *text;
} efi_var_attrs[] = {
	{EFI_VARIABLE_NON_VOLATILE, "NV"},
	{EFI_VARIABLE_BOOTSERVICE_ACCESS, "BS"},
	{EFI_VARIABLE_RUNTIME_ACCESS, "RT"},
	{EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, "AW"},
	{EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, "AT"},
};

static const struct {
	efi_guid_t guid;
	char *text;
} efi_guid_text[] = {
	/* signature database */
	{EFI_GLOBAL_VARIABLE_GUID, "EFI_GLOBAL_VARIABLE_GUID"},
	{EFI_IMAGE_SECURITY_DATABASE_GUID, "EFI_IMAGE_SECURITY_DATABASE_GUID"},
	/* certificate type */
	{EFI_CERT_SHA256_GUID, "EFI_CERT_SHA256_GUID"},
	{EFI_CERT_X509_GUID, "EFI_CERT_X509_GUID"},
	{EFI_CERT_TYPE_PKCS7_GUID, "EFI_CERT_TYPE_PKCS7_GUID"},
};

/* "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" */
static char unknown_guid[37];

/**
 * efi_guid_to_str() - convert guid to readable name
 *
 * @guid:	GUID
 * Return:	string for GUID
 *
 * convert guid to readable name
 */
static const char *efi_guid_to_str(const efi_guid_t *guid)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(efi_guid_text); i++)
		if (!guidcmp(guid, &efi_guid_text[i].guid))
			return efi_guid_text[i].text;

	uuid_bin_to_str((unsigned char *)guid->b, unknown_guid,
			UUID_STR_FORMAT_GUID);

	return unknown_guid;
}

/**
 * efi_dump_single_var() - show information about a UEFI variable
 *
 * @name:	Name of the variable
 * @guid:	Vendor GUID
 * @verbose:	if true, dump data
 *
 * Show information encoded in one UEFI variable
 */
static void efi_dump_single_var(u16 *name, const efi_guid_t *guid, bool verbose)
{
	u32 attributes;
	u8 *data;
	efi_uintn_t size;
	int count, i;
	efi_status_t ret;

	data = NULL;
	size = 0;
	ret = EFI_CALL(efi_get_variable(name, guid, &attributes, &size, data));
	if (ret == EFI_BUFFER_TOO_SMALL) {
		data = malloc(size);
		if (!data)
			goto out;

		ret = EFI_CALL(efi_get_variable(name, guid, &attributes, &size,
						data));
	}
	if (ret == EFI_NOT_FOUND) {
		printf("Error: \"%ls\" not defined\n", name);
		goto out;
	}
	if (ret != EFI_SUCCESS)
		goto out;

	printf("%ls:\n    %s:", name, efi_guid_to_str(guid));
	for (count = 0, i = 0; i < ARRAY_SIZE(efi_var_attrs); i++)
		if (attributes & efi_var_attrs[i].mask) {
			if (count)
				putc('|');
			else
				putc(' ');
			count++;
			puts(efi_var_attrs[i].text);
		}
	printf(", DataSize = 0x%zx\n", size);
	if (verbose)
		print_hex_dump("    ", DUMP_PREFIX_OFFSET, 16, 1,
			       data, size, true);

out:
	free(data);
}

/**
 * efi_dump_vars() - show information about named UEFI variables
 *
 * @argc:	Number of arguments (variables)
 * @argv:	Argument (variable name) array
 * @verbose:	if true, dump data
 * Return:	CMD_RET_SUCCESS on success, or CMD_RET_RET_FAILURE
 *
 * Show information encoded in named UEFI variables
 */
static int efi_dump_vars(int argc,  char * const argv[],
			 const efi_guid_t *guid, bool verbose)
{
	u16 *var_name16, *p;
	efi_uintn_t buf_size, size;

	buf_size = 128;
	var_name16 = malloc(buf_size);
	if (!var_name16)
		return CMD_RET_FAILURE;

	for (; argc > 0; argc--, argv++) {
		size = (utf8_utf16_strlen(argv[0]) + 1) * sizeof(u16);
		if (buf_size < size) {
			buf_size = size;
			p = realloc(var_name16, buf_size);
			if (!p) {
				free(var_name16);
				return CMD_RET_FAILURE;
			}
			var_name16 = p;
		}

		p = var_name16;
		utf8_utf16_strcpy(&p, argv[0]);

		efi_dump_single_var(var_name16, guid, verbose);
	}

	free(var_name16);

	return CMD_RET_SUCCESS;
}

static bool match_name(int argc, char * const argv[], u16 *var_name16)
{
	char *buf, *p;
	size_t buflen;
	int i;
	bool result = false;

	buflen = utf16_utf8_strlen(var_name16) + 1;
	buf = calloc(1, buflen);
	if (!buf)
		return result;

	p = buf;
	utf16_utf8_strcpy(&p, var_name16);

	for (i = 0; i < argc; argc--, argv++) {
		if (!strcmp(buf, argv[i])) {
			result = true;
			goto out;
		}
	}

out:
	free(buf);

	return result;
}

/**
 * efi_dump_var_all() - show information about all the UEFI variables
 *
 * @argc:	Number of arguments (variables)
 * @argv:	Argument (variable name) array
 * @verbose:	if true, dump data
 * Return:	CMD_RET_SUCCESS on success, or CMD_RET_RET_FAILURE
 *
 * Show information encoded in all the UEFI variables
 */
static int efi_dump_var_all(int argc,  char * const argv[],
			    const efi_guid_t *guid_p, bool verbose)
{
	u16 *var_name16, *p;
	efi_uintn_t buf_size, size;
	efi_guid_t guid;
	efi_status_t ret;

	if (argc && guid_p)
		/* simplified case */
		return efi_dump_vars(argc, argv, guid_p, verbose);

	buf_size = 128;
	var_name16 = malloc(buf_size);
	if (!var_name16)
		return CMD_RET_FAILURE;

	var_name16[0] = 0;
	for (;;) {
		size = buf_size;
		ret = EFI_CALL(efi_get_next_variable_name(&size, var_name16,
							  &guid));
		if (ret == EFI_NOT_FOUND)
			break;
		if (ret == EFI_BUFFER_TOO_SMALL) {
			buf_size = size;
			p = realloc(var_name16, buf_size);
			if (!p) {
				free(var_name16);
				return CMD_RET_FAILURE;
			}
			var_name16 = p;
			ret = EFI_CALL(efi_get_next_variable_name(&size,
								  var_name16,
								  &guid));
		}
		if (ret != EFI_SUCCESS) {
			free(var_name16);
			return CMD_RET_FAILURE;
		}

		if ((!guid_p || !guidcmp(guid_p, &guid)) &&
		    (!argc || match_name(argc, argv, var_name16)))
			efi_dump_single_var(var_name16, &guid, verbose);
	}

	free(var_name16);

	return CMD_RET_SUCCESS;
}

/**
 * do_env_print_efi() - show information about UEFI variables
 *
 * @cmdtp:	Command table
 * @flag:	Command flag
 * @argc:	Number of arguments
 * @argv:	Argument array
 * Return:	CMD_RET_SUCCESS on success, or CMD_RET_RET_FAILURE
 *
 * This function is for "env print -e" or "printenv -e" command:
 *   => env print -e [-n] [-guid <guid> | -all] [var [...]]
 * If one or more variable names are specified, show information
 * named UEFI variables, otherwise show all the UEFI variables.
 */
int do_env_print_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	efi_guid_t guid;
	const efi_guid_t *guid_p;
	bool default_guid, guid_any, verbose;
	efi_status_t ret;

	/* Initialize EFI drivers */
	ret = efi_init_obj_list();
	if (ret != EFI_SUCCESS) {
		printf("Error: Cannot initialize UEFI sub-system, r = %lu\n",
		       ret & ~EFI_ERROR_MASK);
		return CMD_RET_FAILURE;
	}

	default_guid = true;
	guid_any = false;
	verbose = true;
	for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
		if (!strcmp(argv[0], "-guid")) {
			if (argc == 1)
				return CMD_RET_USAGE;

			/* -a already specified */
			if (!default_guid && guid_any)
				return CMD_RET_USAGE;

			argc--;
			argv++;
			if (uuid_str_to_bin(argv[0], guid.b,
					    UUID_STR_FORMAT_GUID))
				return CMD_RET_USAGE;
			default_guid = false;
		} else if (!strcmp(argv[0], "-all")) {
			/* -guid already specified */
			if (!default_guid && !guid_any)
				return CMD_RET_USAGE;

			guid_any = true;
			default_guid = false;
		} else if (!strcmp(argv[0], "-n")) {
			verbose = false;
		} else {
			return CMD_RET_USAGE;
		}
	}

	if (guid_any)
		guid_p = NULL;
	else if (default_guid)
		guid_p = &efi_global_variable_guid;
	else
		guid_p = (const efi_guid_t *)guid.b;

	/* enumerate and show all UEFI variables */
	return efi_dump_var_all(argc, argv, guid_p, verbose);
}

/**
 * append_value() - encode UEFI variable's value
 * @bufp:	Buffer of encoded UEFI variable's value
 * @sizep:	Size of buffer
 * @data:	data to be encoded into the value
 * Return:	0 on success, -1 otherwise
 *
 * Interpret a given data string and append it to buffer.
 * Buffer will be realloc'ed if necessary.
 *
 * Currently supported formats are:
 *   =0x0123...:		Hexadecimal number
 *   =H0123...:			Hexadecimal-byte array
 *   ="...", =S"..." or <string>:
 *				String
 */
static int append_value(char **bufp, size_t *sizep, char *data)
{
	char *tmp_buf = NULL, *new_buf = NULL, *value;
	unsigned long len = 0;

	if (!strncmp(data, "=0x", 2)) { /* hexadecimal number */
		union {
			u8 u8;
			u16 u16;
			u32 u32;
			u64 u64;
		} tmp_data;
		unsigned long hex_value;
		void *hex_ptr;

		data += 3;
		len = strlen(data);
		if ((len & 0x1)) /* not multiple of two */
			return -1;

		len /= 2;
		if (len > 8)
			return -1;
		else if (len > 4)
			len = 8;
		else if (len > 2)
			len = 4;

		/* convert hex hexadecimal number */
		if (strict_strtoul(data, 16, &hex_value) < 0)
			return -1;

		tmp_buf = malloc(len);
		if (!tmp_buf)
			return -1;

		if (len == 1) {
			tmp_data.u8 = hex_value;
			hex_ptr = &tmp_data.u8;
		} else if (len == 2) {
			tmp_data.u16 = hex_value;
			hex_ptr = &tmp_data.u16;
		} else if (len == 4) {
			tmp_data.u32 = hex_value;
			hex_ptr = &tmp_data.u32;
		} else {
			tmp_data.u64 = hex_value;
			hex_ptr = &tmp_data.u64;
		}
		memcpy(tmp_buf, hex_ptr, len);
		value = tmp_buf;

	} else if (!strncmp(data, "=H", 2)) { /* hexadecimal-byte array */
		data += 2;
		len = strlen(data);
		if (len & 0x1) /* not multiple of two */
			return -1;

		len /= 2;
		tmp_buf = malloc(len);
		if (!tmp_buf)
			return -1;

		if (hex2bin((u8 *)tmp_buf, data, len) < 0) {
			printf("Error: illegal hexadecimal string\n");
			free(tmp_buf);
			return -1;
		}

		value = tmp_buf;
	} else { /* string */
		if (!strncmp(data, "=\"", 2) || !strncmp(data, "=S\"", 3)) {
			if (data[1] == '"')
				data += 2;
			else
				data += 3;
			value = data;
			len = strlen(data) - 1;
			if (data[len] != '"')
				return -1;
		} else {
			value = data;
			len = strlen(data);
		}
	}

	new_buf = realloc(*bufp, *sizep + len);
	if (!new_buf)
		goto out;

	memcpy(new_buf + *sizep, value, len);
	*bufp = new_buf;
	*sizep += len;

out:
	free(tmp_buf);

	return 0;
}

/**
 * do_env_set_efi() - set UEFI variable
 *
 * @cmdtp:	Command table
 * @flag:	Command flag
 * @argc:	Number of arguments
 * @argv:	Argument array
 * Return:	CMD_RET_SUCCESS on success, or CMD_RET_RET_FAILURE
 *
 * This function is for "env set -e" or "setenv -e" command:
 *   => env set -e [-guid guid][-nv][-bs][-rt][-at][-a][-v]
 *		   [-i address,size] var, or
 *                 var [value ...]
 * Encode values specified and set given UEFI variable.
 * If no value is specified, delete the variable.
 */
int do_env_set_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	char *var_name, *value, *ep;
	ulong addr;
	efi_uintn_t size;
	efi_guid_t guid;
	u32 attributes;
	bool default_guid, verbose, value_on_memory;
	u16 *var_name16 = NULL, *p;
	size_t len;
	efi_status_t ret;

	if (argc == 1)
		return CMD_RET_USAGE;

	/* Initialize EFI drivers */
	ret = efi_init_obj_list();
	if (ret != EFI_SUCCESS) {
		printf("Error: Cannot initialize UEFI sub-system, r = %lu\n",
		       ret & ~EFI_ERROR_MASK);
		return CMD_RET_FAILURE;
	}

	/*
	 * attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
	 *	     EFI_VARIABLE_RUNTIME_ACCESS;
	 */
	value = NULL;
	size = 0;
	attributes = 0;
	guid = efi_global_variable_guid;
	default_guid = true;
	verbose = false;
	value_on_memory = false;
	for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
		if (!strcmp(argv[0], "-guid")) {
			if (argc == 1)
				return CMD_RET_USAGE;

			argc--;
			argv++;
			if (uuid_str_to_bin(argv[0], guid.b,
					    UUID_STR_FORMAT_GUID)) {
				printf("## Guid not specified or in XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX format\n");
				return CMD_RET_FAILURE;
			}
			default_guid = false;
		} else if (!strcmp(argv[0], "-bs")) {
			attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
		} else if (!strcmp(argv[0], "-rt")) {
			attributes |= EFI_VARIABLE_RUNTIME_ACCESS;
		} else if (!strcmp(argv[0], "-nv")) {
			attributes |= EFI_VARIABLE_NON_VOLATILE;
		} else if (!strcmp(argv[0], "-at")) {
			attributes |=
			  EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
		} else if (!strcmp(argv[0], "-a")) {
			attributes |= EFI_VARIABLE_APPEND_WRITE;
		} else if (!strcmp(argv[0], "-i")) {
			/* data comes from memory */
			if (argc == 1)
				return CMD_RET_USAGE;

			argc--;
			argv++;
			addr = simple_strtoul(argv[0], &ep, 16);
			if (*ep != ',')
				return CMD_RET_USAGE;

			/* 0 should be allowed for delete */
			size = simple_strtoul(++ep, NULL, 16);

			value_on_memory = true;
		} else if (!strcmp(argv[0], "-v")) {
			verbose = true;
		} else {
			return CMD_RET_USAGE;
		}
	}
	if (!argc)
		return CMD_RET_USAGE;

	var_name = argv[0];
	if (default_guid) {
		if (!strcmp(var_name, "db") || !strcmp(var_name, "dbx") ||
		    !strcmp(var_name, "dbt"))
			guid = efi_guid_image_security_database;
		else
			guid = efi_global_variable_guid;
	}

	if (verbose) {
		printf("GUID: %s\n", efi_guid_to_str((const efi_guid_t *)
						     &guid));
		printf("Attributes: 0x%x\n", attributes);
	}

	/* for value */
	if (value_on_memory)
		value = map_sysmem(addr, 0);
	else if (argc > 1)
		for (argc--, argv++; argc > 0; argc--, argv++)
			if (append_value(&value, &size, argv[0]) < 0) {
				printf("## Failed to process an argument, %s\n",
				       argv[0]);
				ret = CMD_RET_FAILURE;
				goto out;
			}

	if (size && verbose) {
		printf("Value:\n");
		print_hex_dump("    ", DUMP_PREFIX_OFFSET,
			       16, 1, value, size, true);
	}

	len = utf8_utf16_strnlen(var_name, strlen(var_name));
	var_name16 = malloc((len + 1) * 2);
	if (!var_name16) {
		printf("## Out of memory\n");
		ret = CMD_RET_FAILURE;
		goto out;
	}
	p = var_name16;
	utf8_utf16_strncpy(&p, var_name, len + 1);

	ret = EFI_CALL(efi_set_variable(var_name16, &guid, attributes,
					size, value));
	unmap_sysmem(value);
	if (ret == EFI_SUCCESS) {
		ret = CMD_RET_SUCCESS;
	} else {
		const char *msg;

		switch (ret) {
		case EFI_NOT_FOUND:
			msg = " (not found)";
			break;
		case EFI_WRITE_PROTECTED:
			msg = " (read only)";
			break;
		case EFI_INVALID_PARAMETER:
			msg = " (invalid parameter)";
			break;
		case EFI_SECURITY_VIOLATION:
			msg = " (validation failed)";
			break;
		case EFI_OUT_OF_RESOURCES:
			msg = " (out of memory)";
			break;
		default:
			msg = "";
			break;
		}
		printf("## Failed to set EFI variable%s\n", msg);
		ret = CMD_RET_FAILURE;
	}
out:
	if (value_on_memory)
		unmap_sysmem(value);
	else
		free(value);
	free(var_name16);

	return ret;
}
