// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2018 Patrick Wildt <patrick@blueri.se>
 * Copyright (c) 2019 Linaro Limited, Author: AKASHI Takahiro
 */

#include <common.h>
#include <charset.h>
#include <efi_loader.h>
#include <image.h>
#include <hexdump.h>
#include <malloc.h>
#include <linux/compat.h>
#include <linux/oid_registry.h>
#include <u-boot/rsa.h>
#include <u-boot/sha256.h>
#include "../lib/crypto/pkcs7_parser.h"

const efi_guid_t efi_guid_image_security_database =
		EFI_IMAGE_SECURITY_DATABASE_GUID;
const efi_guid_t efi_guid_sha256 = EFI_CERT_SHA256_GUID;
const efi_guid_t efi_guid_cert_rsa2048 = EFI_CERT_RSA2048_GUID;
const efi_guid_t efi_guid_cert_x509 = EFI_CERT_X509_GUID;
const efi_guid_t efi_guid_cert_x509_sha256 = EFI_CERT_X509_SHA256_GUID;

#ifdef CONFIG_EFI_SECURE_BOOT

/**
 * efi_hash_regions - calculate a hash value
 * @regs:	List of regions
 * @hash:	Pointer to a pointer to buffer holding a hash value
 * @size:	Size of buffer to be returned
 *
 * Calculate a sha256 value of @regs and return a value in @hash.
 *
 * Return:	true on success, false on error
 */
static bool efi_hash_regions(struct efi_image_regions *regs, void **hash,
			     size_t *size)
{
	*size = 0;
	*hash = calloc(1, SHA256_SUM_LEN);
	if (!*hash) {
		debug("Out of memory\n");
		return false;
	}
	*size = SHA256_SUM_LEN;

	hash_calculate("sha256", regs->reg, regs->num, *hash);
#ifdef DEBUG
	debug("hash calculated:\n");
	print_hex_dump("    ", DUMP_PREFIX_OFFSET, 16, 1,
		       *hash, SHA256_SUM_LEN, false);
#endif

	return true;
}

/**
 * efi_hash_msg_content - calculate a hash value of contentInfo
 * @msg:	Signature
 * @hash:	Pointer to a pointer to buffer holding a hash value
 * @size:	Size of buffer to be returned
 *
 * Calculate a sha256 value of contentInfo in @msg and return a value in @hash.
 *
 * Return:	true on success, false on error
 */
static bool efi_hash_msg_content(struct pkcs7_message *msg, void **hash,
				 size_t *size)
{
	struct image_region regtmp;

	*size = 0;
	*hash = calloc(1, SHA256_SUM_LEN);
	if (!*hash) {
		debug("Out of memory\n");
		free(msg);
		return false;
	}
	*size = SHA256_SUM_LEN;

	regtmp.data = msg->data;
	regtmp.size = msg->data_len;

	hash_calculate("sha256", &regtmp, 1, *hash);
#ifdef DEBUG
	debug("hash calculated based on contentInfo:\n");
	print_hex_dump("    ", DUMP_PREFIX_OFFSET, 16, 1,
		       *hash, SHA256_SUM_LEN, false);
#endif

	return true;
}

/**
 * efi_signature_verify - verify a signature with a certificate
 * @regs:		List of regions to be authenticated
 * @signed_info:	Pointer to PKCS7's signed_info
 * @cert:		x509 certificate
 *
 * Signature pointed to by @signed_info against image pointed to by @regs
 * is verified by a certificate pointed to by @cert.
 * @signed_info holds a signature, including a message digest which is to be
 * compared with a hash value calculated from @regs.
 *
 * Return:	true if signature is verified, false if not
 */
static bool efi_signature_verify(struct efi_image_regions *regs,
				 struct pkcs7_message *msg,
				 struct pkcs7_signed_info *ps_info,
				 struct x509_certificate *cert)
{
	struct image_sign_info info;
	struct image_region regtmp[2];
	void *hash;
	size_t size;
	char c;
	bool verified;

	debug("%s: Enter, %p, %p, %p(issuer: %s, subject: %s)\n", __func__,
	      regs, ps_info, cert, cert->issuer, cert->subject);

	verified = false;

	memset(&info, '\0', sizeof(info));
	info.padding = image_get_padding_algo("pkcs-1.5");
	/*
	 * Note: image_get_[checksum|crypto]_algo takes an string
	 * argument like "<checksum>,<crypto>"
	 * TODO: support other hash algorithms
	 */
	if (!strcmp(ps_info->sig->hash_algo, "sha1")) {
		info.checksum = image_get_checksum_algo("sha1,rsa2048");
		info.name = "sha1,rsa2048";
	} else if (!strcmp(ps_info->sig->hash_algo, "sha256")) {
		info.checksum = image_get_checksum_algo("sha256,rsa2048");
		info.name = "sha256,rsa2048";
	} else {
		debug("unknown msg digest algo: %s\n", ps_info->sig->hash_algo);
		goto out;
	}
	info.crypto = image_get_crypto_algo(info.name);

	info.key = cert->pub->key;
	info.keylen = cert->pub->keylen;

	/* verify signature */
	debug("%s: crypto: %s, signature len:%x\n", __func__,
	      info.name, ps_info->sig->s_size);
	if (ps_info->aa_set & (1UL << sinfo_has_message_digest)) {
		debug("%s: RSA verify authentication attribute\n", __func__);
		/*
		 * NOTE: This path will be executed only for
		 * PE image authentication
		 */

		/* check if hash matches digest first */
		debug("checking msg digest first, len:0x%x\n",
		      ps_info->msgdigest_len);

#ifdef DEBUG
		debug("hash in database:\n");
		print_hex_dump("    ", DUMP_PREFIX_OFFSET, 16, 1,
			       ps_info->msgdigest, ps_info->msgdigest_len,
			       false);
#endif
		/* against contentInfo first */
		if ((msg->data && efi_hash_msg_content(msg, &hash, &size)) ||
				/* for signed image */
		    efi_hash_regions(regs, &hash, &size)) {
				/* for authenticated variable */
			if (ps_info->msgdigest_len != size ||
			    memcmp(hash, ps_info->msgdigest, size)) {
				debug("Digest doesn't match\n");
				free(hash);
				goto out;
			}

			free(hash);
		} else {
			debug("Digesting image failed\n");
			goto out;
		}

		/* against digest */
		c = 0x31;
		regtmp[0].data = &c;
		regtmp[0].size = 1;
		regtmp[1].data = ps_info->authattrs;
		regtmp[1].size = ps_info->authattrs_len;

		if (!rsa_verify(&info, regtmp, 2,
				ps_info->sig->s, ps_info->sig->s_size))
			verified = true;
	} else {
		debug("%s: RSA verify content data\n", __func__);
		/* against all data */
		if (!rsa_verify(&info, regs->reg, regs->num,
				ps_info->sig->s, ps_info->sig->s_size))
			verified = true;
	}

out:
	debug("%s: Exit, verified: %d\n", __func__, verified);
	return verified;
}

/**
 * efi_signature_verify_with_list - verify a signature with signature list
 * @regs:		List of regions to be authenticated
 * @msg:		Signature
 * @signed_info:	Pointer to PKCS7's signed_info
 * @siglist:		Signature list for certificates
 * @valid_cert:		x509 certificate that verifies this signature
 *
 * Signature pointed to by @signed_info against image pointed to by @regs
 * is verified by signature list pointed to by @siglist.
 * Signature database is a simple concatenation of one or more
 * signature list(s).
 *
 * Return:	true if signature is verified, false if not
 */
static
bool efi_signature_verify_with_list(struct efi_image_regions *regs,
				    struct pkcs7_message *msg,
				    struct pkcs7_signed_info *signed_info,
				    struct efi_signature_store *siglist,
				    struct x509_certificate **valid_cert)
{
	struct x509_certificate *cert;
	struct efi_sig_data *sig_data;
	bool verified = false;

	debug("%s: Enter, %p, %p, %p, %p\n", __func__,
	      regs, signed_info, siglist, valid_cert);

	if (!signed_info) {
		void *hash;
		size_t size;

		debug("%s: unsigned image\n", __func__);
		/*
		 * verify based on calculated hash value
		 * TODO: support other hash algorithms
		 */
		if (guidcmp(&siglist->sig_type, &efi_guid_sha256)) {
			debug("Digest algorithm is not supported: %pUl\n",
			      &siglist->sig_type);
			goto out;
		}

		if (!efi_hash_regions(regs, &hash, &size)) {
			debug("Digesting unsigned image failed\n");
			goto out;
		}

		/* go through the list */
		for (sig_data = siglist->sig_data_list; sig_data;
		     sig_data = sig_data->next) {
#ifdef DEBUG
			debug("Msg digest in database:\n");
			print_hex_dump("    ", DUMP_PREFIX_OFFSET, 16, 1,
				       sig_data->data, sig_data->size, false);
#endif
			if ((sig_data->size == size) &&
			    !memcmp(sig_data->data, hash, size)) {
				verified = true;
				free(hash);
				goto out;
			}
		}
		free(hash);
		goto out;
	}

	debug("%s: signed image\n", __func__);
	if (guidcmp(&siglist->sig_type, &efi_guid_cert_x509)) {
		debug("Signature type is not supported: %pUl\n",
		      &siglist->sig_type);
		goto out;
	}

	/* go through the list */
	for (sig_data = siglist->sig_data_list; sig_data;
	     sig_data = sig_data->next) {
		/* TODO: support owner check based on policy */

		cert = x509_cert_parse(sig_data->data, sig_data->size);
		if (IS_ERR(cert)) {
			debug("Parsing x509 certificate failed\n");
			goto out;
		}

		verified = efi_signature_verify(regs, msg, signed_info, cert);

		if (verified) {
			if (valid_cert)
				*valid_cert = cert;
			else
				x509_free_certificate(cert);
			break;
		}
		x509_free_certificate(cert);
	}

out:
	debug("%s: Exit, verified: %d\n", __func__, verified);
	return verified;
}

/**
 * efi_signature_verify_with_sigdb - verify a signature with db
 * @regs:	List of regions to be authenticated
 * @msg:	Signature
 * @db:		Signature database for trusted certificates
 * @cert:	x509 certificate that verifies this signature
 *
 * Signature pointed to by @msg against image pointed to by @regs
 * is verified by signature database pointed to by @db.
 *
 * Return:	true if signature is verified, false if not
 */
bool efi_signature_verify_with_sigdb(struct efi_image_regions *regs,
				     struct pkcs7_message *msg,
				     struct efi_signature_store *db,
				     struct x509_certificate **cert)
{
	struct pkcs7_signed_info *info;
	struct efi_signature_store *siglist;
	bool verified = false;

	debug("%s: Enter, %p, %p, %p, %p\n", __func__, regs, msg, db, cert);

	if (!db)
		goto out;

	if (!db->sig_data_list)
		goto out;

	/* for unsigned image */
	if (!msg) {
		debug("%s: Verify unsigned image with db\n", __func__);
		for (siglist = db; siglist; siglist = siglist->next)
			if (efi_signature_verify_with_list(regs, NULL, NULL,
							   siglist, cert)) {
				verified = true;
				goto out;
			}

		goto out;
	}

	/* for signed image or variable */
	debug("%s: Verify signed image with db\n", __func__);
	for (info = msg->signed_infos; info; info = info->next) {
		debug("Signed Info: digest algo: %s, pkey algo: %s\n",
		      info->sig->hash_algo, info->sig->pkey_algo);

		for (siglist = db; siglist; siglist = siglist->next) {
			if (efi_signature_verify_with_list(regs, msg, info,
							   siglist, cert)) {
				verified = true;
				goto out;
			}
		}
	}

out:
	debug("%s: Exit, verified: %d\n", __func__, verified);
	return verified;
}

/**
 * efi_search_siglist - search signature list for a certificate
 * @cert:	x509 certificate
 * @siglist:	Signature list
 * @revoc_time:	Pointer to buffer for revocation time
 *
 * Search signature list pointed to by @siglist and find a certificate
 * pointed to by @cert.
 * If found, revocation time that is specified in signature database is
 * returned in @revoc_time.
 *
 * Return:	true if certificate is found, false if not
 */
static bool efi_search_siglist(struct x509_certificate *cert,
			       struct efi_signature_store *siglist,
			       time64_t *revoc_time)
{
	struct image_region reg[1];
	void *hash = NULL, *msg = NULL;
	struct efi_sig_data *sig_data;
	bool found = false;

	/* can be null */
	if (!siglist->sig_data_list)
		return false;

	if (guidcmp(&siglist->sig_type, &efi_guid_cert_x509_sha256)) {
		/* TODO: other hash algos */
		debug("Certificate's digest type is not supported: %pUl\n",
		      &siglist->sig_type);
		goto out;
	}

	/* calculate hash of TBSCertificate */
	msg = calloc(1, SHA256_SUM_LEN);
	if (!msg) {
		debug("Out of memory\n");
		goto out;
	}

	hash = calloc(1, SHA256_SUM_LEN);
	if (!hash) {
		debug("Out of memory\n");
		goto out;
	}

	reg[0].data = cert->tbs;
	reg[0].size = cert->tbs_size;
	hash_calculate("sha256", reg, 1, msg);

	/* go through signature list */
	for (sig_data = siglist->sig_data_list; sig_data;
	     sig_data = sig_data->next) {
		/*
		 * struct efi_cert_x509_sha256 {
		 *	u8 tbs_hash[256/8];
		 *	time64_t revocation_time;
		 * };
		 */
		if ((sig_data->size == SHA256_SUM_LEN) &&
		    !memcmp(sig_data->data, hash, SHA256_SUM_LEN)) {
			memcpy(revoc_time, sig_data->data + SHA256_SUM_LEN,
			       sizeof(*revoc_time));
			found = true;
			goto out;
		}
	}

out:
	free(hash);
	free(msg);

	return found;
}

/**
 * efi_signature_verify_cert - verify a certificate with dbx
 * @cert:	x509 certificate
 * @dbx:	Signature database
 *
 * Search signature database pointed to by @dbx and find a certificate
 * pointed to by @cert.
 * This function is expected to be used against "dbx".
 *
 * Return:	true if a certificate is not rejected, false otherwise.
 */
bool efi_signature_verify_cert(struct x509_certificate *cert,
			       struct efi_signature_store *dbx)
{
	struct efi_signature_store *siglist;
	time64_t revoc_time;
	bool found = false;

	debug("%s: Enter, %p, %p\n", __func__, dbx, cert);

	if (!cert)
		return false;

	for (siglist = dbx; siglist; siglist = siglist->next) {
		if (efi_search_siglist(cert, siglist, &revoc_time)) {
			/* TODO */
			/* compare signing time with revocation time */

			found = true;
			break;
		}
	}

	debug("%s: Exit, verified: %d\n", __func__, !found);
	return !found;
}

/**
 * efi_signature_verify_signers - verify signers' certificates with dbx
 * @msg:	Signature
 * @dbx:	Signature database
 *
 * Determine if any of signers' certificates in @msg may be verified
 * by any of certificates in signature database pointed to by @dbx.
 * This function is expected to be used against "dbx".
 *
 * Return:	true if none of certificates is rejected, false otherwise.
 */
bool efi_signature_verify_signers(struct pkcs7_message *msg,
				  struct efi_signature_store *dbx)
{
	struct pkcs7_signed_info *info;
	bool found = false;

	debug("%s: Enter, %p, %p\n", __func__, msg, dbx);

	if (!msg)
		goto out;

	for (info = msg->signed_infos; info; info = info->next) {
		if (info->signer &&
		    !efi_signature_verify_cert(info->signer, dbx)) {
			found = true;
			goto out;
		}
	}
out:
	debug("%s: Exit, verified: %d\n", __func__, !found);
	return !found;
}

/**
 * efi_image_region_add - add an entry of region
 * @regs:	Pointer to array of regions
 * @start:	Start address of region
 * @end:	End address of region
 * @nocheck:	flag against overlapped regions
 *
 * Take one entry of region [@start, @end] and append it to the list
 * pointed to by @regs. If @nocheck is false, overlapping among entries
 * will be checked first.
 *
 * Return:	0 on success, status code (negative) on error
 */
efi_status_t efi_image_region_add(struct efi_image_regions *regs,
				  const void *start, const void *end,
				  int nocheck)
{
	struct image_region *reg;
	int i, j;

	if (regs->num >= regs->max) {
		debug("%s: no more room for regions\n", __func__);
		return EFI_OUT_OF_RESOURCES;
	}

	if (end < start)
		return EFI_INVALID_PARAMETER;

	for (i = 0; i < regs->num; i++) {
		reg = &regs->reg[i];
		if (nocheck)
			continue;

		if (start > reg->data + reg->size)
			continue;

		if ((start >= reg->data && start < reg->data + reg->size) ||
		    (end > reg->data && end < reg->data + reg->size)) {
			debug("%s: new region already part of another\n",
			      __func__);
			return EFI_INVALID_PARAMETER;
		}

		if (start < reg->data && end < reg->data + reg->size) {
			for (j = regs->num - 1; j >= i; j--)
				memcpy(&regs->reg[j], &regs->reg[j + 1],
				       sizeof(*reg));
			break;
		}
	}

	reg = &regs->reg[i];
	reg->data = start;
	reg->size = end - start;
	regs->num++;

	return EFI_SUCCESS;
}

/**
 * efi_sigstore_free - free signature store
 * @sigstore:	Pointer to signature store structure
 *
 * Feee all the memories held in signature store and itself,
 * which were allocated by efi_sigstore_parse_sigdb().
 */
void efi_sigstore_free(struct efi_signature_store *sigstore)
{
	struct efi_signature_store *sigstore_next;
	struct efi_sig_data *sig_data, *sig_data_next;

	while (sigstore) {
		sigstore_next = sigstore->next;

		sig_data = sigstore->sig_data_list;
		while (sig_data) {
			sig_data_next = sig_data->next;
			free(sig_data->data);
			free(sig_data);
			sig_data = sig_data_next;
		}

		free(sigstore);
		sigstore = sigstore_next;
	}
}

/**
 * efi_sigstore_parse_siglist - parse a signature list
 * @name:	Pointer to signature list
 *
 * Parse signature list and instantiate a signature store structure.
 * Signature database is a simple concatenation of one or more
 * signature list(s).
 *
 * Return:	Pointer to signature store on success, NULL on error
 */
static struct efi_signature_store *
efi_sigstore_parse_siglist(struct efi_signature_list *esl)
{
	struct efi_signature_store *siglist = NULL;
	struct efi_sig_data *sig_data, *sig_data_next;
	struct efi_signature_data *esd;
	size_t left;

	/*
	 * UEFI specification defines certificate types:
	 *   for non-signed images,
	 *	EFI_CERT_SHA256_GUID
	 *	EFI_CERT_RSA2048_GUID
	 *	EFI_CERT_RSA2048_SHA256_GUID
	 *	EFI_CERT_SHA1_GUID
	 *	EFI_CERT_RSA2048_SHA_GUID
	 *	EFI_CERT_SHA224_GUID
	 *	EFI_CERT_SHA384_GUID
	 *	EFI_CERT_SHA512_GUID
	 *
	 *   for signed images,
	 *	EFI_CERT_X509_GUID
	 *	NOTE: Each certificate will normally be in a separate
	 *	EFI_SIGNATURE_LIST as the size may vary depending on
	 *	its algo's.
	 *
	 *   for timestamp revocation of certificate,
	 *	EFI_CERT_X509_SHA512_GUID
	 *	EFI_CERT_X509_SHA256_GUID
	 *	EFI_CERT_X509_SHA384_GUID
	 */

	if (esl->signature_list_size
			<= (sizeof(*esl) + esl->signature_header_size)) {
		debug("Siglist in wrong format\n");
		return NULL;
	}

	/* Create a head */
	siglist = calloc(sizeof(*siglist), 1);
	if (!siglist) {
		debug("Out of memory\n");
		goto err;
	}
	memcpy(&siglist->sig_type, &esl->signature_type, sizeof(efi_guid_t));

	/* Go through the list */
	sig_data_next = NULL;
	left = esl->signature_list_size
			- (sizeof(*esl) + esl->signature_header_size);
	esd = (struct efi_signature_data *)
			((u8 *)esl + sizeof(*esl) + esl->signature_header_size);

	while ((left > 0) && left >= esl->signature_size) {
		/* Signature must exist if there is remaining data. */
		if (left < esl->signature_size) {
			debug("Certificate is too small\n");
			goto err;
		}

		sig_data = calloc(esl->signature_size
					- sizeof(esd->signature_owner), 1);
		if (!sig_data) {
			debug("Out of memory\n");
			goto err;
		}

		/* Append signature data */
		memcpy(&sig_data->owner, &esd->signature_owner,
		       sizeof(efi_guid_t));
		sig_data->size = esl->signature_size
					- sizeof(esd->signature_owner);
		sig_data->data = malloc(sig_data->size);
		if (!sig_data->data) {
			debug("Out of memory\n");
			goto err;
		}
		memcpy(sig_data->data, esd->signature_data, sig_data->size);

		sig_data->next = sig_data_next;
		sig_data_next = sig_data;

		/* Next */
		esd = (struct efi_signature_data *)
				((u8 *)esd + esl->signature_size);
		left -= esl->signature_size;
	}
	siglist->sig_data_list = sig_data_next;

	return siglist;

err:
	efi_sigstore_free(siglist);

	return NULL;
}

/**
 * efi_sigstore_parse_sigdb - parse a signature database variable
 * @name:	Variable's name
 *
 * Read in a value of signature database variable pointed to by
 * @name, parse it and instantiate a signature store structure.
 *
 * Return:	Pointer to signature store on success, NULL on error
 */
struct efi_signature_store *efi_sigstore_parse_sigdb(u16 *name)
{
	struct efi_signature_store *sigstore = NULL, *siglist;
	struct efi_signature_list *esl;
	const efi_guid_t *vendor;
	void *db;
	efi_uintn_t db_size;
	efi_status_t ret;

	if (!u16_strcmp(name, L"PK") || !u16_strcmp(name, L"KEK")) {
		vendor = &efi_global_variable_guid;
	} else if (!u16_strcmp(name, L"db") || !u16_strcmp(name, L"dbx")) {
		vendor = &efi_guid_image_security_database;
	} else {
		debug("unknown signature database, %ls\n", name);
		return NULL;
	}

	/* retrieve variable data */
	db_size = 0;
	ret = EFI_CALL(efi_get_variable(name, vendor, NULL, &db_size, NULL));
	if (ret == EFI_NOT_FOUND) {
		debug("variable, %ls, not found\n", name);
		sigstore = calloc(sizeof(*sigstore), 1);
		return sigstore;
	} else if (ret != EFI_BUFFER_TOO_SMALL) {
		debug("Getting variable, %ls, failed\n", name);
		return NULL;
	}

	db = malloc(db_size);
	if (!db) {
		debug("Out of memory\n");
		return NULL;
	}

	ret = EFI_CALL(efi_get_variable(name, vendor, NULL, &db_size, db));
	if (ret != EFI_SUCCESS) {
		debug("Getting variable, %ls, failed\n", name);
		goto err;
	}

	/* Parse siglist list */
	esl = db;
	while (db_size > 0) {
		/* List must exist if there is remaining data. */
		if (db_size < sizeof(*esl)) {
			debug("variable, %ls, in wrong format\n", name);
			goto err;
		}

		if (db_size < esl->signature_list_size) {
			debug("variable, %ls, in wrong format\n", name);
			goto err;
		}

		/* Parse a single siglist. */
		siglist = efi_sigstore_parse_siglist(esl);
		if (!siglist) {
			debug("Parsing signature list of %ls failed\n", name);
			goto err;
		}

		/* Append siglist */
		siglist->next = sigstore;
		sigstore = siglist;

		/* Next */
		db_size -= esl->signature_list_size;
		esl = (void *)esl + esl->signature_list_size;
	}
	free(db);

	return sigstore;

err:
	efi_sigstore_free(sigstore);
	free(db);

	return NULL;
}
#endif /* CONFIG_EFI_SECURE_BOOT */
