// 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 <command.h>
#include <efi_loader.h>
#include <efi_variable.h>
#include <env.h>
#include <exports.h>
#include <hexdump.h>
#include <malloc.h>
#include <mapmem.h>
#include <rtc.h>
#include <u-boot/uuid.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"},
	{EFI_VARIABLE_READ_ONLY, "RO"},
};

/**
 * 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;
	u64 time;
	struct rtc_time tm;
	efi_uintn_t size;
	int count, i;
	efi_status_t ret;

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

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

	rtc_to_tm(time, &tm);
	printf("%ls:\n    %pUl (%pUs)\n", name, guid, guid);
	if (attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)
		printf("    %04d-%02d-%02d %02d:%02d:%02d\n", tm.tm_year,
		       tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
	printf("    ");
	for (count = 0, i = 0; i < ARRAY_SIZE(efi_var_attrs); i++)
		if (attributes & efi_var_attrs[i].mask) {
			if (count)
				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);
}

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;
	bool match = false;

	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_get_next_variable_name_int(&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_get_next_variable_name_int(&size, var_name16,
							     &guid);
		}
		if (ret != EFI_SUCCESS) {
			free(var_name16);
			return CMD_RET_FAILURE;
		}

		if (guid_p && guidcmp(guid_p, &guid))
			continue;
		if (!argc || match_name(argc, argv, var_name16)) {
			match = true;
			efi_dump_single_var(var_name16, &guid, verbose);
		}
	}
	free(var_name16);

	if (!match && argc == 1) {
		printf("Error: \"%s\" not defined\n", argv[0]);
		return CMD_RET_FAILURE;
	}

	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(struct cmd_tbl *cmdtp, int flag, int argc,
		     char *const argv[])
{
	const efi_guid_t *guid_p = NULL;
	efi_guid_t guid;
	bool verbose = true;
	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;
	}

	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))
				return CMD_RET_USAGE;
			guid_p = (const efi_guid_t *)guid.b;
		} else if (!strcmp(argv[0], "-n")) {
			verbose = false;
		} else {
			return CMD_RET_USAGE;
		}
	}

	/* 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", 3)) { /* 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(struct cmd_tbl *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;
	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)) {
				return CMD_RET_USAGE;
			}
			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 = hextoul(argv[0], &ep);
			if (*ep != ':')
				return CMD_RET_USAGE;

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

			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: %pUl (%pUs)\n", &guid, &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);
	}

	var_name16 = efi_convert_string(var_name);
	if (!var_name16) {
		printf("## Out of memory\n");
		ret = CMD_RET_FAILURE;
		goto out;
	}
	ret = efi_set_variable_int(var_name16, &guid, attributes, size, value,
				   true);
	free(var_name16);
	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);

	return ret;
}
