// SPDX-License-Identifier: GPL-2.0+
/*
 *  Menu-driven UEFI Secure Boot Key Maintenance
 *
 *  Copyright (c) 2022 Masahisa Kojima, Linaro Limited
 */

#include <ansi.h>
#include <common.h>
#include <charset.h>
#include <hexdump.h>
#include <log.h>
#include <malloc.h>
#include <menu.h>
#include <efi_loader.h>
#include <efi_config.h>
#include <efi_variable.h>
#include <crypto/pkcs7_parser.h>

struct eficonfig_sig_data {
	struct efi_signature_list *esl;
	struct efi_signature_data *esd;
	struct list_head list;
	u16 *varname;
};

enum efi_sbkey_signature_type {
	SIG_TYPE_X509 = 0,
	SIG_TYPE_HASH,
	SIG_TYPE_CRL,
	SIG_TYPE_RSA2048,
};

struct eficonfig_sigtype_to_str {
	efi_guid_t sig_type;
	char *str;
	enum efi_sbkey_signature_type type;
};

static const struct eficonfig_sigtype_to_str sigtype_to_str[] = {
	{EFI_CERT_X509_GUID,		"X509",			SIG_TYPE_X509},
	{EFI_CERT_SHA256_GUID,		"SHA256",		SIG_TYPE_HASH},
	{EFI_CERT_X509_SHA256_GUID,	"X509_SHA256 CRL",	SIG_TYPE_CRL},
	{EFI_CERT_X509_SHA384_GUID,	"X509_SHA384 CRL",	SIG_TYPE_CRL},
	{EFI_CERT_X509_SHA512_GUID,	"X509_SHA512 CRL",	SIG_TYPE_CRL},
	/* U-Boot does not support the following signature types */
/*	{EFI_CERT_RSA2048_GUID,		"RSA2048",		SIG_TYPE_RSA2048}, */
/*	{EFI_CERT_RSA2048_SHA256_GUID,	"RSA2048_SHA256",	SIG_TYPE_RSA2048}, */
/*	{EFI_CERT_SHA1_GUID,		"SHA1",			SIG_TYPE_HASH}, */
/*	{EFI_CERT_RSA2048_SHA_GUID,	"RSA2048_SHA",		SIG_TYPE_RSA2048 }, */
/*	{EFI_CERT_SHA224_GUID,		"SHA224",		SIG_TYPE_HASH}, */
/*	{EFI_CERT_SHA384_GUID,		"SHA384",		SIG_TYPE_HASH}, */
/*	{EFI_CERT_SHA512_GUID,		"SHA512",		SIG_TYPE_HASH}, */
};

/**
 * file_have_auth_header() - check file has EFI_VARIABLE_AUTHENTICATION_2 header
 * @buf:	pointer to file
 * @size:	file size
 * Return:	true if file has auth header, false otherwise
 */
static bool file_have_auth_header(void *buf, efi_uintn_t size)
{
	struct efi_variable_authentication_2 *auth = buf;

	if (auth->auth_info.hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID)
		return false;

	if (guidcmp(&auth->auth_info.cert_type, &efi_guid_cert_type_pkcs7))
		return false;

	return true;
}

/**
 * eficonfig_process_enroll_key() - enroll key into signature database
 *
 * @data:	pointer to the data for each entry
 * Return:	status code
 */
static efi_status_t eficonfig_process_enroll_key(void *data)
{
	u32 attr;
	char *buf = NULL;
	efi_uintn_t size;
	efi_status_t ret;
	struct efi_file_handle *f = NULL;
	struct efi_device_path *full_dp = NULL;
	struct eficonfig_select_file_info file_info;

	file_info.current_path = calloc(1, EFICONFIG_FILE_PATH_BUF_SIZE);
	if (!file_info.current_path) {
		ret = EFI_OUT_OF_RESOURCES;
		goto out;
	}

	ret = eficonfig_process_select_file(&file_info);
	if (ret != EFI_SUCCESS)
		goto out;

	full_dp = eficonfig_create_device_path(file_info.dp_volume, file_info.current_path);
	if (!full_dp) {
		ret = EFI_OUT_OF_RESOURCES;
		goto out;
	}
	f = efi_file_from_path(full_dp);
	if (!f) {
		ret = EFI_NOT_FOUND;
		goto out;
	}

	size = 0;
	ret = EFI_CALL(f->getinfo(f, &efi_file_info_guid, &size, NULL));
	if (ret != EFI_BUFFER_TOO_SMALL)
		goto out;

	buf = malloc(size);
	if (!buf) {
		ret = EFI_OUT_OF_RESOURCES;
		goto out;
	}
	ret = EFI_CALL(f->getinfo(f, &efi_file_info_guid, &size, buf));
	if (ret != EFI_SUCCESS)
		goto out;

	size = ((struct efi_file_info *)buf)->file_size;
	free(buf);

	if (!size) {
		eficonfig_print_msg("ERROR! File is empty.");
		ret = EFI_INVALID_PARAMETER;
		goto out;
	}

	buf = malloc(size);
	if (!buf) {
		ret = EFI_OUT_OF_RESOURCES;
		goto out;
	}

	ret = EFI_CALL(f->read(f, &size, buf));
	if (ret != EFI_SUCCESS) {
		eficonfig_print_msg("ERROR! Failed to read file.");
		goto out;
	}
	if (!file_have_auth_header(buf, size)) {
		eficonfig_print_msg("ERROR! Invalid file format. Only .auth variables is allowed.");
		ret = EFI_INVALID_PARAMETER;
		goto out;
	}

	attr = EFI_VARIABLE_NON_VOLATILE |
	       EFI_VARIABLE_BOOTSERVICE_ACCESS |
	       EFI_VARIABLE_RUNTIME_ACCESS |
	       EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;

	/* PK can enroll only one certificate */
	if (u16_strcmp(data, u"PK")) {
		efi_uintn_t db_size = 0;

		/* check the variable exists. If exists, add APPEND_WRITE attribute */
		ret = efi_get_variable_int(data, efi_auth_var_get_guid(data), NULL,
					   &db_size, NULL,  NULL);
		if (ret == EFI_BUFFER_TOO_SMALL)
			attr |= EFI_VARIABLE_APPEND_WRITE;
	}

	ret = efi_set_variable_int((u16 *)data, efi_auth_var_get_guid((u16 *)data),
				   attr, size, buf, false);
	if (ret != EFI_SUCCESS)
		eficonfig_print_msg("ERROR! Failed to update signature database");

out:
	free(file_info.current_path);
	free(buf);
	efi_free_pool(full_dp);
	if (f)
		EFI_CALL(f->close(f));

	/* return to the parent menu */
	ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret;

	return ret;
}

/**
 * eficonfig_process_show_siglist() - show signature list content
 *
 * @data:	pointer to the data for each entry
 * Return:	status code
 */
static efi_status_t eficonfig_process_show_siglist(void *data)
{
	u32 i;
	struct eficonfig_sig_data *sg = data;

	puts(ANSI_CURSOR_HIDE);
	puts(ANSI_CLEAR_CONSOLE);
	printf(ANSI_CURSOR_POSITION, 1, 1);

	printf("\n  ** Show Signature Database (%ls) **\n\n"
	       "    Owner GUID:\n"
	       "      %pUL\n",
	       sg->varname, sg->esd->signature_owner.b);

	for (i = 0; i < ARRAY_SIZE(sigtype_to_str); i++) {
		if (!guidcmp(&sg->esl->signature_type, &sigtype_to_str[i].sig_type)) {
			printf("    Signature Type:\n"
			       "      %s\n", sigtype_to_str[i].str);

			switch (sigtype_to_str[i].type) {
			case SIG_TYPE_X509:
			{
				struct x509_certificate *cert_tmp;

				cert_tmp = x509_cert_parse(sg->esd->signature_data,
							   sg->esl->signature_size);
				printf("    Subject:\n"
				       "      %s\n"
				       "    Issuer:\n"
				       "      %s\n",
				       cert_tmp->subject, cert_tmp->issuer);
				break;
			}
			case SIG_TYPE_CRL:
			{
				u32 hash_size = sg->esl->signature_size - sizeof(efi_guid_t) -
						sizeof(struct efi_time);
				struct efi_time *time =
					(struct efi_time *)((u8 *)sg->esd->signature_data +
					hash_size);

				printf("    ToBeSignedHash:\n");
				print_hex_dump("      ", DUMP_PREFIX_NONE, 16, 1,
					       sg->esd->signature_data, hash_size, false);
				printf("    TimeOfRevocation:\n"
				       "      %d-%d-%d %02d:%02d:%02d\n",
				       time->year, time->month, time->day,
				       time->hour, time->minute, time->second);
				break;
			}
			case SIG_TYPE_HASH:
			{
				u32 hash_size = sg->esl->signature_size - sizeof(efi_guid_t);

				printf("    Hash:\n");
				print_hex_dump("      ", DUMP_PREFIX_NONE, 16, 1,
					       sg->esd->signature_data, hash_size, false);
				break;
			}
			default:
				eficonfig_print_msg("ERROR! Unsupported format.");
				return EFI_INVALID_PARAMETER;
			}
		}
	}

	while (tstc())
		getchar();

	printf("\n\n  Press any key to continue");
	getchar();

	return EFI_SUCCESS;
}

/**
 * prepare_signature_list_menu() - create the signature list menu entry
 *
 * @efimenu:	pointer to the efimenu structure
 * @varname:	pointer to the variable name
 * @db:		pointer to the variable raw data
 * @db_size:	variable data size
 * @func:	callback of each entry
 * Return:	status code
 */
static efi_status_t prepare_signature_list_menu(struct efimenu *efi_menu, void *varname,
						void *db, efi_uintn_t db_size,
						eficonfig_entry_func func)
{
	u32 num = 0;
	efi_uintn_t size;
	struct eficonfig_sig_data *sg;
	struct efi_signature_list *esl;
	struct efi_signature_data *esd;
	efi_status_t ret = EFI_SUCCESS;

	INIT_LIST_HEAD(&efi_menu->list);

	esl = db;
	size = db_size;
	while (size > 0) {
		u32 remain;

		esd = (struct efi_signature_data *)((u8 *)esl +
						    (sizeof(struct efi_signature_list) +
						    esl->signature_header_size));
		remain = esl->signature_list_size - sizeof(struct efi_signature_list) -
			 esl->signature_header_size;
		for (; remain > 0; remain -= esl->signature_size) {
			char buf[37];
			char *title;

			if (num >= EFICONFIG_ENTRY_NUM_MAX - 1) {
				ret = EFI_OUT_OF_RESOURCES;
				goto out;
			}

			sg = calloc(1, sizeof(struct eficonfig_sig_data));
			if (!sg) {
				ret = EFI_OUT_OF_RESOURCES;
				goto err;
			}

			snprintf(buf, sizeof(buf), "%pUL", &esd->signature_owner);
			title = strdup(buf);
			if (!title) {
				free(sg);
				ret = EFI_OUT_OF_RESOURCES;
				goto err;
			}

			sg->esl = esl;
			sg->esd = esd;
			sg->varname = varname;
			ret = eficonfig_append_menu_entry(efi_menu, title, func, sg);
			if (ret != EFI_SUCCESS) {
				free(sg);
				free(title);
				goto err;
			}
			esd = (struct efi_signature_data *)((u8 *)esd + esl->signature_size);
			num++;
		}

		size -= esl->signature_list_size;
		esl = (struct efi_signature_list *)((u8 *)esl + esl->signature_list_size);
	}
out:
	ret = eficonfig_append_quit_entry(efi_menu);
err:
	return ret;
}

/**
 * enumerate_and_show_signature_database() - enumerate and show the signature database
 *
 * @data:	pointer to the data for each entry
 * Return:	status code
 */
static efi_status_t enumerate_and_show_signature_database(void *varname)
{
	void *db;
	char buf[50];
	efi_status_t ret;
	efi_uintn_t db_size;
	struct efimenu *efi_menu;
	struct list_head *pos, *n;
	struct eficonfig_entry *entry;

	db = efi_get_var(varname, efi_auth_var_get_guid(varname), &db_size);
	if (!db) {
		eficonfig_print_msg("There is no entry in the signature database.");
		return EFI_NOT_FOUND;
	}

	efi_menu = calloc(1, sizeof(struct efimenu));
	if (!efi_menu) {
		free(db);
		return EFI_OUT_OF_RESOURCES;
	}

	ret = prepare_signature_list_menu(efi_menu, varname, db, db_size,
					  eficonfig_process_show_siglist);
	if (ret != EFI_SUCCESS)
		goto out;

	snprintf(buf, sizeof(buf), "  ** Show Signature Database (%ls) **", (u16 *)varname);
	ret = eficonfig_process_common(efi_menu, buf);
out:
	list_for_each_safe(pos, n, &efi_menu->list) {
		entry = list_entry(pos, struct eficonfig_entry, list);
		free(entry->data);
	}
	eficonfig_destroy(efi_menu);
	free(db);

	return ret;
}

/**
 * eficonfig_process_show_signature_database() - process show signature database
 *
 * @data:	pointer to the data for each entry
 * Return:	status code
 */
static efi_status_t eficonfig_process_show_signature_database(void *data)
{
	efi_status_t ret;

	while (1) {
		ret = enumerate_and_show_signature_database(data);
		if (ret != EFI_SUCCESS && ret != EFI_NOT_READY)
			break;
	}

	/* return to the parent menu */
	ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret;

	return ret;
}

static struct eficonfig_item key_config_menu_items[] = {
	{"Enroll New Key", eficonfig_process_enroll_key},
	{"Show Signature Database", eficonfig_process_show_signature_database},
	{"Quit", eficonfig_process_quit},
};

/**
 * eficonfig_process_set_secure_boot_key() - display the key configuration menu
 *
 * @data:	pointer to the data for each entry
 * Return:	status code
 */
static efi_status_t eficonfig_process_set_secure_boot_key(void *data)
{
	u32 i;
	efi_status_t ret;
	char header_str[32];
	struct efimenu *efi_menu;

	for (i = 0; i < ARRAY_SIZE(key_config_menu_items); i++)
		key_config_menu_items[i].data = data;

	snprintf(header_str, sizeof(header_str), "  ** Configure %ls **", (u16 *)data);

	while (1) {
		efi_menu = eficonfig_create_fixed_menu(key_config_menu_items,
						       ARRAY_SIZE(key_config_menu_items));

		ret = eficonfig_process_common(efi_menu, header_str);
		eficonfig_destroy(efi_menu);

		if (ret == EFI_ABORTED)
			break;
	}

	/* return to the parent menu */
	ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret;

	return ret;
}

static const struct eficonfig_item secure_boot_menu_items[] = {
	{"PK", eficonfig_process_set_secure_boot_key, u"PK"},
	{"KEK", eficonfig_process_set_secure_boot_key, u"KEK"},
	{"db", eficonfig_process_set_secure_boot_key, u"db"},
	{"dbx", eficonfig_process_set_secure_boot_key, u"dbx"},
	{"Quit", eficonfig_process_quit},
};

/**
 * eficonfig_process_secure_boot_config() - display the key list menu
 *
 * @data:	pointer to the data for each entry
 * Return:	status code
 */
efi_status_t eficonfig_process_secure_boot_config(void *data)
{
	efi_status_t ret;
	struct efimenu *efi_menu;

	while (1) {
		char header_str[64];

		snprintf(header_str, sizeof(header_str),
			 "  ** UEFI Secure Boot Key Configuration (SecureBoot : %s) **",
			 (efi_secure_boot_enabled() ? "ON" : "OFF"));

		efi_menu = eficonfig_create_fixed_menu(secure_boot_menu_items,
						       ARRAY_SIZE(secure_boot_menu_items));
		if (!efi_menu) {
			ret = EFI_OUT_OF_RESOURCES;
			break;
		}

		ret = eficonfig_process_common(efi_menu, header_str);
		eficonfig_destroy(efi_menu);

		if (ret == EFI_ABORTED)
			break;
	}

	/* return to the parent menu */
	ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret;

	return ret;
}
