// SPDX-License-Identifier: GPL-2.0+
/*
 * PKCS#7 parser using MbedTLS PKCS#7 library
 *
 * Copyright (c) 2024 Linaro Limited
 * Author: Raymond Mao <raymond.mao@linaro.org>
 */

#include <log.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <crypto/public_key.h>
#include <crypto/pkcs7_parser.h>

static void pkcs7_free_mbedtls_ctx(struct pkcs7_mbedtls_ctx *ctx)
{
	if (ctx) {
		kfree(ctx->content_data);
		kfree(ctx);
	}
}

static void pkcs7_free_sinfo_mbedtls_ctx(struct pkcs7_sinfo_mbedtls_ctx *ctx)
{
	if (ctx) {
		kfree(ctx->authattrs_data);
		kfree(ctx->content_data_digest);
		kfree(ctx);
	}
}

/*
 * Parse Authenticate Attributes
 * TODO: Shall we consider to integrate decoding of authenticate attribute into
 *	 MbedTLS library?
 *
 * There are two kinds of structure for the Authenticate Attributes being used
 * in U-Boot.
 *
 * Type 1 - contains in a PE/COFF EFI image:
 *
 * [C.P.0] {
 *   U.P.SEQUENCE {
 *     U.P.OBJECTIDENTIFIER 1.2.840.113549.1.9.3 (OID_contentType)
 *     U.P.SET {
 *        U.P.OBJECTIDENTIFIER 1.3.6.1.4.1.311.2.1.4 (OID_msIndirectData)
 *     }
 *  }
 *  U.P.SEQUENCE {
 *     U.P.OBJECTIDENTIFIER 1.2.840.113549.1.9.5 (OID_signingTime)
 *     U.P.SET {
 *        U.P.UTCTime '<siging_time>'
 *     }
 *  }
 *  U.P.SEQUENCE {
 *     U.P.OBJECTIDENTIFIER 1.2.840.113549.1.9.4 (OID_messageDigest)
 *     U.P.SET {
 *        U.P.OCTETSTRING <digest>
 *     }
 *  }
 *    U.P.SEQUENCE {
 *        U.P.OBJECTIDENTIFIER 1.2.840.113549.1.9.15 (OID_smimeCapabilites)
 *       U.P.SET {
 *          U.P.SEQUENCE {
 *             <...>
 *          }
 *       }
 *    }
 * }
 *
 * Type 2 - contains in an EFI Capsule:
 *
 * [C.P.0] {
 *   U.P.SEQUENCE {
 *      U.P.OBJECTIDENTIFIER 1.2.840.113549.1.9.3 (OID_contentType)
 *      U.P.SET {
 *         U.P.OBJECTIDENTIFIER 1.2.840.113549.1.7.1 (OID_data)
 *      }
 *   }
 *   U.P.SEQUENCE {
 *      U.P.OBJECTIDENTIFIER 1.2.840.113549.1.9.5 (OID_signingTime)
 *      U.P.SET {
 *         U.P.UTCTime '<siging_time>'
 *      }
 *   }
 *   U.P.SEQUENCE {
 *      U.P.OBJECTIDENTIFIER 1.2.840.113549.1.9.4 (OID_messageDigest)
 *      U.P.SET {
 *         U.P.OCTETSTRING <digest>
 *      }
 *  }
 *}
 *
 * Note:
 * They have different Content Type (OID_msIndirectData or OID_data).
 * OID_smimeCapabilites only exists in a PE/COFF EFI image.
 */
static int authattrs_parse(struct pkcs7_message *msg, void *aa, size_t aa_len,
			   struct pkcs7_signed_info *sinfo)
{
	unsigned char *p = aa;
	unsigned char *end = (unsigned char *)aa + aa_len;
	size_t len = 0;
	int ret;
	unsigned char *inner_p;
	size_t seq_len = 0;

	ret = mbedtls_asn1_get_tag(&p, end, &seq_len,
				   MBEDTLS_ASN1_CONTEXT_SPECIFIC |
				   MBEDTLS_ASN1_CONSTRUCTED);
	if (ret)
		return ret;

	while (!mbedtls_asn1_get_tag(&p, end, &seq_len,
				     MBEDTLS_ASN1_CONSTRUCTED |
				     MBEDTLS_ASN1_SEQUENCE)) {
		inner_p = p;
		ret = mbedtls_asn1_get_tag(&inner_p, p + seq_len, &len,
					   MBEDTLS_ASN1_OID);
		if (ret)
			return ret;

		if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS9_CONTENTTYPE, inner_p, len)) {
			inner_p += len;
			ret = mbedtls_asn1_get_tag(&inner_p, p + seq_len, &len,
						   MBEDTLS_ASN1_CONSTRUCTED |
						   MBEDTLS_ASN1_SET);
			if (ret)
				return ret;

			ret = mbedtls_asn1_get_tag(&inner_p, p + seq_len, &len,
						   MBEDTLS_ASN1_OID);
			if (ret)
				return ret;

			/*
			 * We should only support 1.2.840.113549.1.7.1 (OID_data)
			 * for PKCS7 DATA that is used in EFI Capsule and
			 * 1.3.6.1.4.1.311.2.1.4 (OID_msIndirectData) for
			 * MicroSoft Authentication Code that is used in EFI
			 * Secure Boot.
			 */
			if (MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_MICROSOFT_INDIRECTDATA,
						inner_p, len) &&
			    MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS7_DATA,
						inner_p, len))
				return -EINVAL;

			if (__test_and_set_bit(sinfo_has_content_type, &sinfo->aa_set))
				return -EINVAL;
		} else if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS9_MESSAGEDIGEST, inner_p,
						len)) {
			inner_p += len;
			ret = mbedtls_asn1_get_tag(&inner_p, p + seq_len, &len,
						   MBEDTLS_ASN1_CONSTRUCTED |
						   MBEDTLS_ASN1_SET);
			if (ret)
				return ret;

			ret = mbedtls_asn1_get_tag(&inner_p, p + seq_len, &len,
						   MBEDTLS_ASN1_OCTET_STRING);
			if (ret)
				return ret;

			sinfo->msgdigest = inner_p;
			sinfo->msgdigest_len = len;

			if (__test_and_set_bit(sinfo_has_message_digest, &sinfo->aa_set))
				return -EINVAL;
		} else if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS9_SIGNINGTIME, inner_p,
						len)) {
			mbedtls_x509_time st;

			inner_p += len;
			ret = mbedtls_asn1_get_tag(&inner_p, p + seq_len, &len,
						   MBEDTLS_ASN1_CONSTRUCTED |
						   MBEDTLS_ASN1_SET);
			if (ret)
				return ret;

			ret = mbedtls_x509_get_time(&inner_p, p + seq_len, &st);
			if (ret)
				return ret;
			sinfo->signing_time = x509_get_timestamp(&st);

			if (__test_and_set_bit(sinfo_has_signing_time, &sinfo->aa_set))
				return -EINVAL;
		} else if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_PKCS9_SMIMECAP, inner_p,
						len)) {
			if (__test_and_set_bit(sinfo_has_smime_caps, &sinfo->aa_set))
				return -EINVAL;

			if (msg->data_type != OID_msIndirectData &&
			    msg->data_type != OID_data)
				return -EINVAL;
		} else if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_MICROSOFT_SPOPUSINFO, inner_p,
						len)) {
			if (__test_and_set_bit(sinfo_has_ms_opus_info, &sinfo->aa_set))
				return -EINVAL;
		} else if (!MBEDTLS_OID_CMP_RAW(MBEDTLS_OID_MICROSOFT_STATETYPE, inner_p,
						len)) {
			if (__test_and_set_bit(sinfo_has_ms_statement_type, &sinfo->aa_set))
				return -EINVAL;
		}

		p += seq_len;
	}

	if (ret && ret !=  MBEDTLS_ERR_ASN1_OUT_OF_DATA)
		return ret;

	msg->have_authattrs = true;

	/*
	 * Skip the leading tag byte (MBEDTLS_ASN1_CONTEXT_SPECIFIC |
	 * MBEDTLS_ASN1_CONSTRUCTED) to satisfy pkcs7_digest() when calculating
	 * the digest of authattrs.
	 */
	sinfo->authattrs = aa + 1;
	sinfo->authattrs_len = aa_len - 1;

	return 0;
}

static int x509_populate_content_data(struct pkcs7_message *msg,
				      mbedtls_pkcs7 *pkcs7_ctx)
{
	struct pkcs7_mbedtls_ctx *mctx;

	if (!pkcs7_ctx->content_data.data ||
	    !pkcs7_ctx->content_data.data_len)
		return 0;

	mctx = kzalloc(sizeof(*mctx), GFP_KERNEL);
	if (!mctx)
		return -ENOMEM;

	mctx->content_data = kmemdup(pkcs7_ctx->content_data.data,
				     pkcs7_ctx->content_data.data_len,
				     GFP_KERNEL);
	if (!mctx->content_data) {
		pkcs7_free_mbedtls_ctx(mctx);
		return -ENOMEM;
	}

	msg->data = mctx->content_data;
	msg->data_len = pkcs7_ctx->content_data.data_len;
	msg->data_hdrlen = pkcs7_ctx->content_data.data_hdrlen;
	msg->data_type = pkcs7_ctx->content_data.data_type;

	msg->mbedtls_ctx = mctx;
	return 0;
}

static int x509_populate_sinfo(struct pkcs7_message *msg,
			       mbedtls_pkcs7_signer_info *mb_sinfo,
			       struct pkcs7_signed_info **sinfo)
{
	struct pkcs7_signed_info *signed_info;
	struct public_key_signature *s;
	mbedtls_md_type_t md_alg;
	struct pkcs7_sinfo_mbedtls_ctx *mctx;
	int ret;

	signed_info = kzalloc(sizeof(*signed_info), GFP_KERNEL);
	if (!signed_info)
		return -ENOMEM;

	s = kzalloc(sizeof(*s), GFP_KERNEL);
	if (!s) {
		ret = -ENOMEM;
		goto out_no_sig;
	}

	mctx = kzalloc(sizeof(*mctx), GFP_KERNEL);
	if (!mctx) {
		ret = -ENOMEM;
		goto out_no_mctx;
	}

	/*
	 * Hash algorithm:
	 *
	 * alg_identifier =	digestAlgorithm (DigestAlgorithmIdentifier)
	 *			MbedTLS internally checks this field to ensure
	 *			it is the same as digest_alg_identifiers.
	 * sig_alg_identifier =	digestEncryptionAlgorithm
	 *			(DigestEncryptionAlgorithmIdentifier)
	 *			MbedTLS just saves this field without any actions.
	 * See function pkcs7_get_signer_info() for reference.
	 *
	 * Public key algorithm:
	 * No information related to public key algorithm under MbedTLS signer
	 * info. Assume that we are using RSA.
	 */
	ret = mbedtls_oid_get_md_alg(&mb_sinfo->alg_identifier, &md_alg);
	if (ret)
		goto out_err_sinfo;
	s->pkey_algo = "rsa";

	/* Translate the hash algorithm */
	switch (md_alg) {
	case MBEDTLS_MD_SHA1:
		s->hash_algo = "sha1";
		s->digest_size = SHA1_SUM_LEN;
		break;
	case MBEDTLS_MD_SHA256:
		s->hash_algo = "sha256";
		s->digest_size = SHA256_SUM_LEN;
		break;
	case MBEDTLS_MD_SHA384:
		s->hash_algo = "sha384";
		s->digest_size = SHA384_SUM_LEN;
		break;
	case MBEDTLS_MD_SHA512:
		s->hash_algo = "sha512";
		s->digest_size = SHA512_SUM_LEN;
		break;
	/* Unsupported algo */
	case MBEDTLS_MD_MD5:
	case MBEDTLS_MD_SHA224:
	default:
		ret = -EINVAL;
		goto out_err_sinfo;
	}

	/*
	 * auth_ids holds AuthorityKeyIdentifier, aka akid
	 * auth_ids[0]:
	 *	[PKCS#7 or CMS ver 1] - generated from "Issuer + Serial number"
	 *	[CMS ver 3] - generated from skid (subjectKeyId)
	 * auth_ids[1]: generated from skid (subjectKeyId)
	 *
	 * Assume that we are using PKCS#7 (msg->version=1),
	 * not CMS ver 3 (msg->version=3).
	 */
	s->auth_ids[0] = asymmetric_key_generate_id(mb_sinfo->serial.p,
						    mb_sinfo->serial.len,
						    mb_sinfo->issuer_raw.p,
						    mb_sinfo->issuer_raw.len);
	if (!s->auth_ids[0]) {
		ret = -ENOMEM;
		goto out_err_sinfo;
	}

	/* skip s->auth_ids[1], no subjectKeyId in MbedTLS signer info ctx */

	/*
	 * Encoding can be pkcs1 or raw, but only pkcs1 is supported.
	 * Set the encoding explicitly to pkcs1.
	 */
	s->encoding = "pkcs1";

	/* Copy the signature data */
	s->s = kmemdup(mb_sinfo->sig.p, mb_sinfo->sig.len, GFP_KERNEL);
	if (!s->s) {
		ret = -ENOMEM;
		goto out_err_sinfo;
	}
	s->s_size = mb_sinfo->sig.len;
	signed_info->sig = s;

	/* Save the Authenticate Attributes data if exists */
	if (!mb_sinfo->authattrs.data || !mb_sinfo->authattrs.data_len)
		goto no_authattrs;

	mctx->authattrs_data = kmemdup(mb_sinfo->authattrs.data,
				       mb_sinfo->authattrs.data_len,
				       GFP_KERNEL);
	if (!mctx->authattrs_data) {
		ret = -ENOMEM;
		goto out_err_sinfo;
	}
	signed_info->mbedtls_ctx = mctx;

	/* If authattrs exists, decode it and parse msgdigest from it */
	ret = authattrs_parse(msg, mctx->authattrs_data,
			      mb_sinfo->authattrs.data_len,
			      signed_info);
	if (ret)
		goto out_err_sinfo;

no_authattrs:
	*sinfo = signed_info;
	return 0;

out_err_sinfo:
	pkcs7_free_sinfo_mbedtls_ctx(mctx);
out_no_mctx:
	public_key_signature_free(s);
out_no_sig:
	kfree(signed_info);
	return ret;
}

/*
 * Free a signed information block.
 */
static void pkcs7_free_signed_info(struct pkcs7_signed_info *sinfo)
{
	if (sinfo) {
		public_key_signature_free(sinfo->sig);
		pkcs7_free_sinfo_mbedtls_ctx(sinfo->mbedtls_ctx);
		kfree(sinfo);
	}
}

/**
 * pkcs7_free_message - Free a PKCS#7 message
 * @pkcs7: The PKCS#7 message to free
 */
void pkcs7_free_message(struct pkcs7_message *pkcs7)
{
	struct x509_certificate *cert;
	struct pkcs7_signed_info *sinfo;

	if (pkcs7) {
		while (pkcs7->certs) {
			cert = pkcs7->certs;
			pkcs7->certs = cert->next;
			x509_free_certificate(cert);
		}
		while (pkcs7->crl) {
			cert = pkcs7->crl;
			pkcs7->crl = cert->next;
			x509_free_certificate(cert);
		}
		while (pkcs7->signed_infos) {
			sinfo = pkcs7->signed_infos;
			pkcs7->signed_infos = sinfo->next;
			pkcs7_free_signed_info(sinfo);
		}
		pkcs7_free_mbedtls_ctx(pkcs7->mbedtls_ctx);
		kfree(pkcs7);
	}
}

struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen)
{
	int i;
	int ret;
	mbedtls_pkcs7 pkcs7_ctx;
	mbedtls_pkcs7_signer_info *mb_sinfos;
	mbedtls_x509_crt *mb_certs;
	struct pkcs7_message *msg;
	struct x509_certificate **cert;
	struct pkcs7_signed_info **sinfos;

	msg = kzalloc(sizeof(*msg), GFP_KERNEL);
	if (!msg) {
		ret = -ENOMEM;
		goto out_no_msg;
	}

	/* Parse the DER encoded PKCS#7 message using MbedTLS */
	mbedtls_pkcs7_init(&pkcs7_ctx);
	ret = mbedtls_pkcs7_parse_der(&pkcs7_ctx, data, datalen);
	/* Check if it is a PKCS#7 message with signed data */
	if (ret != MBEDTLS_PKCS7_SIGNED_DATA)
		goto parse_fail;

	/* Assume that we are using PKCS#7, not CMS ver 3 */
	msg->version = 1;	/* 1 for [PKCS#7 or CMS ver 1] */

	/* Populate the certs to msg->certs */
	for (i = 0, cert = &msg->certs, mb_certs = &pkcs7_ctx.signed_data.certs;
	     i < pkcs7_ctx.signed_data.no_of_certs && mb_certs;
	     i++, cert = &(*cert)->next, mb_certs = mb_certs->next) {
		ret = x509_populate_cert(mb_certs, cert);
		if (ret)
			goto parse_fail;

		(*cert)->index = i + 1;
	}

	/*
	 * Skip populating crl, that is not currently in-use.
	 */

	/* Populate content data */
	ret = x509_populate_content_data(msg, &pkcs7_ctx);
	if (ret)
		goto parse_fail;

	/* Populate signed info to msg->signed_infos */
	for (i = 0, sinfos = &msg->signed_infos,
	     mb_sinfos = &pkcs7_ctx.signed_data.signers;
	     i < pkcs7_ctx.signed_data.no_of_signers && mb_sinfos;
	     i++, sinfos = &(*sinfos)->next, mb_sinfos = mb_sinfos->next) {
		ret = x509_populate_sinfo(msg, mb_sinfos, sinfos);
		if (ret)
			goto parse_fail;

		(*sinfos)->index = i + 1;
	}

	mbedtls_pkcs7_free(&pkcs7_ctx);
	return msg;

parse_fail:
	mbedtls_pkcs7_free(&pkcs7_ctx);
	pkcs7_free_message(msg);
out_no_msg:
	msg = ERR_PTR(ret);
	return msg;
}
