// 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 <crypto/pkcs7_parser.h>
#include <linux/compat.h>
#include <linux/oid_registry.h>
#include <u-boot/rsa.h>
#include <u-boot/sha256.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) {
		/* 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 */
