// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * RSA Signature Scheme with Appendix - PKCS #1 v1.5 (RFC 8017 sec 8.2)
 *
 * https://www.rfc-editor.org/rfc/rfc8017#section-8.2
 *
 * Copyright (c) 2015 - 2024 Intel Corporation
 */

#include <linux/module.h>
#include <linux/scatterlist.h>
#include <crypto/akcipher.h>
#include <crypto/algapi.h>
#include <crypto/hash.h>
#include <crypto/sig.h>
#include <crypto/internal/akcipher.h>
#include <crypto/internal/rsa.h>
#include <crypto/internal/sig.h>

/*
 * Full Hash Prefix for EMSA-PKCS1-v1_5 encoding method (RFC 9580 table 24)
 *
 * RSA keys are usually much larger than the hash of the message to be signed.
 * The hash is therefore prepended by the Full Hash Prefix and a 0xff padding.
 * The Full Hash Prefix is an ASN.1 SEQUENCE containing the hash algorithm OID.
 *
 * https://www.rfc-editor.org/rfc/rfc9580#table-24
 */

static const u8 hash_prefix_none[] = { };

static const u8 hash_prefix_md5[] = {
	0x30, 0x20, 0x30, 0x0c, 0x06, 0x08,	  /* SEQUENCE (SEQUENCE (OID */
	0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05,	/*	<algorithm>, */
	0x05, 0x00, 0x04, 0x10		      /* NULL), OCTET STRING <hash>) */
};

static const u8 hash_prefix_sha1[] = {
	0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
	0x2b, 0x0e, 0x03, 0x02, 0x1a,
	0x05, 0x00, 0x04, 0x14
};

static const u8 hash_prefix_rmd160[] = {
	0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
	0x2b, 0x24, 0x03, 0x02, 0x01,
	0x05, 0x00, 0x04, 0x14
};

static const u8 hash_prefix_sha224[] = {
	0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
	0x05, 0x00, 0x04, 0x1c
};

static const u8 hash_prefix_sha256[] = {
	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
	0x05, 0x00, 0x04, 0x20
};

static const u8 hash_prefix_sha384[] = {
	0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
	0x05, 0x00, 0x04, 0x30
};

static const u8 hash_prefix_sha512[] = {
	0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
	0x05, 0x00, 0x04, 0x40
};

static const u8 hash_prefix_sha3_256[] = {
	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x08,
	0x05, 0x00, 0x04, 0x20
};

static const u8 hash_prefix_sha3_384[] = {
	0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x09,
	0x05, 0x00, 0x04, 0x30
};

static const u8 hash_prefix_sha3_512[] = {
	0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0a,
	0x05, 0x00, 0x04, 0x40
};

static const struct hash_prefix {
	const char	*name;
	const u8	*data;
	size_t		size;
} hash_prefixes[] = {
#define _(X) { #X, hash_prefix_##X, sizeof(hash_prefix_##X) }
	_(none),
	_(md5),
	_(sha1),
	_(rmd160),
	_(sha256),
	_(sha384),
	_(sha512),
	_(sha224),
#undef _
#define _(X) { "sha3-" #X, hash_prefix_sha3_##X, sizeof(hash_prefix_sha3_##X) }
	_(256),
	_(384),
	_(512),
#undef _
	{ NULL }
};

static const struct hash_prefix *rsassa_pkcs1_find_hash_prefix(const char *name)
{
	const struct hash_prefix *p;

	for (p = hash_prefixes; p->name; p++)
		if (strcmp(name, p->name) == 0)
			return p;
	return NULL;
}

static bool rsassa_pkcs1_invalid_hash_len(unsigned int len,
					  const struct hash_prefix *p)
{
	/*
	 * Legacy protocols such as TLS 1.1 or earlier and IKE version 1
	 * do not prepend a Full Hash Prefix to the hash.  In that case,
	 * the size of the Full Hash Prefix is zero.
	 */
	if (p->data == hash_prefix_none)
		return false;

	/*
	 * The final byte of the Full Hash Prefix encodes the hash length.
	 *
	 * This needs to be revisited should hash algorithms with more than
	 * 1016 bits (127 bytes * 8) ever be added.  The length would then
	 * be encoded into more than one byte by ASN.1.
	 */
	static_assert(HASH_MAX_DIGESTSIZE <= 127);

	return len != p->data[p->size - 1];
}

struct rsassa_pkcs1_ctx {
	struct crypto_akcipher *child;
	unsigned int key_size;
};

struct rsassa_pkcs1_inst_ctx {
	struct crypto_akcipher_spawn spawn;
	const struct hash_prefix *hash_prefix;
};

static int rsassa_pkcs1_sign(struct crypto_sig *tfm,
			     const void *src, unsigned int slen,
			     void *dst, unsigned int dlen)
{
	struct sig_instance *inst = sig_alg_instance(tfm);
	struct rsassa_pkcs1_inst_ctx *ictx = sig_instance_ctx(inst);
	const struct hash_prefix *hash_prefix = ictx->hash_prefix;
	struct rsassa_pkcs1_ctx *ctx = crypto_sig_ctx(tfm);
	unsigned int pad_len;
	unsigned int ps_end;
	unsigned int len;
	u8 *in_buf;
	int err;

	if (!ctx->key_size)
		return -EINVAL;

	if (dlen < ctx->key_size)
		return -EOVERFLOW;

	if (rsassa_pkcs1_invalid_hash_len(slen, hash_prefix))
		return -EINVAL;

	if (slen + hash_prefix->size > ctx->key_size - 11)
		return -EOVERFLOW;

	pad_len = ctx->key_size - slen - hash_prefix->size - 1;

	/* RFC 8017 sec 8.2.1 step 1 - EMSA-PKCS1-v1_5 encoding generation */
	in_buf = dst;
	memmove(in_buf + pad_len + hash_prefix->size, src, slen);
	memcpy(in_buf + pad_len, hash_prefix->data, hash_prefix->size);

	ps_end = pad_len - 1;
	in_buf[0] = 0x01;
	memset(in_buf + 1, 0xff, ps_end - 1);
	in_buf[ps_end] = 0x00;


	/* RFC 8017 sec 8.2.1 step 2 - RSA signature */
	err = crypto_akcipher_sync_decrypt(ctx->child, in_buf,
					   ctx->key_size - 1, in_buf,
					   ctx->key_size);
	if (err < 0)
		return err;

	len = err;
	pad_len = ctx->key_size - len;

	/* Four billion to one */
	if (unlikely(pad_len)) {
		memmove(dst + pad_len, dst, len);
		memset(dst, 0, pad_len);
	}

	return ctx->key_size;
}

static int rsassa_pkcs1_verify(struct crypto_sig *tfm,
			       const void *src, unsigned int slen,
			       const void *digest, unsigned int dlen)
{
	struct sig_instance *inst = sig_alg_instance(tfm);
	struct rsassa_pkcs1_inst_ctx *ictx = sig_instance_ctx(inst);
	const struct hash_prefix *hash_prefix = ictx->hash_prefix;
	struct rsassa_pkcs1_ctx *ctx = crypto_sig_ctx(tfm);
	unsigned int child_reqsize = crypto_akcipher_reqsize(ctx->child);
	struct akcipher_request *child_req __free(kfree_sensitive) = NULL;
	struct crypto_wait cwait;
	struct scatterlist sg;
	unsigned int dst_len;
	unsigned int pos;
	u8 *out_buf;
	int err;

	/* RFC 8017 sec 8.2.2 step 1 - length checking */
	if (!ctx->key_size ||
	    slen != ctx->key_size ||
	    rsassa_pkcs1_invalid_hash_len(dlen, hash_prefix))
		return -EINVAL;

	/* RFC 8017 sec 8.2.2 step 2 - RSA verification */
	child_req = kmalloc(sizeof(*child_req) + child_reqsize + ctx->key_size,
			    GFP_KERNEL);
	if (!child_req)
		return -ENOMEM;

	out_buf = (u8 *)(child_req + 1) + child_reqsize;
	memcpy(out_buf, src, slen);

	crypto_init_wait(&cwait);
	sg_init_one(&sg, out_buf, slen);
	akcipher_request_set_tfm(child_req, ctx->child);
	akcipher_request_set_crypt(child_req, &sg, &sg, slen, slen);
	akcipher_request_set_callback(child_req, CRYPTO_TFM_REQ_MAY_SLEEP,
				      crypto_req_done, &cwait);

	err = crypto_akcipher_encrypt(child_req);
	err = crypto_wait_req(err, &cwait);
	if (err)
		return err;

	/* RFC 8017 sec 8.2.2 step 3 - EMSA-PKCS1-v1_5 encoding verification */
	dst_len = child_req->dst_len;
	if (dst_len < ctx->key_size - 1)
		return -EINVAL;

	if (dst_len == ctx->key_size) {
		if (out_buf[0] != 0x00)
			/* Encrypted value had no leading 0 byte */
			return -EINVAL;

		dst_len--;
		out_buf++;
	}

	if (out_buf[0] != 0x01)
		return -EBADMSG;

	for (pos = 1; pos < dst_len; pos++)
		if (out_buf[pos] != 0xff)
			break;

	if (pos < 9 || pos == dst_len || out_buf[pos] != 0x00)
		return -EBADMSG;
	pos++;

	if (hash_prefix->size > dst_len - pos)
		return -EBADMSG;
	if (crypto_memneq(out_buf + pos, hash_prefix->data, hash_prefix->size))
		return -EBADMSG;
	pos += hash_prefix->size;

	/* RFC 8017 sec 8.2.2 step 4 - comparison of digest with out_buf */
	if (dlen != dst_len - pos)
		return -EKEYREJECTED;
	if (memcmp(digest, out_buf + pos, dlen) != 0)
		return -EKEYREJECTED;

	return 0;
}

static unsigned int rsassa_pkcs1_key_size(struct crypto_sig *tfm)
{
	struct rsassa_pkcs1_ctx *ctx = crypto_sig_ctx(tfm);

	return ctx->key_size;
}

static int rsassa_pkcs1_set_pub_key(struct crypto_sig *tfm,
				    const void *key, unsigned int keylen)
{
	struct rsassa_pkcs1_ctx *ctx = crypto_sig_ctx(tfm);

	return rsa_set_key(ctx->child, &ctx->key_size, RSA_PUB, key, keylen);
}

static int rsassa_pkcs1_set_priv_key(struct crypto_sig *tfm,
				     const void *key, unsigned int keylen)
{
	struct rsassa_pkcs1_ctx *ctx = crypto_sig_ctx(tfm);

	return rsa_set_key(ctx->child, &ctx->key_size, RSA_PRIV, key, keylen);
}

static int rsassa_pkcs1_init_tfm(struct crypto_sig *tfm)
{
	struct sig_instance *inst = sig_alg_instance(tfm);
	struct rsassa_pkcs1_inst_ctx *ictx = sig_instance_ctx(inst);
	struct rsassa_pkcs1_ctx *ctx = crypto_sig_ctx(tfm);
	struct crypto_akcipher *child_tfm;

	child_tfm = crypto_spawn_akcipher(&ictx->spawn);
	if (IS_ERR(child_tfm))
		return PTR_ERR(child_tfm);

	ctx->child = child_tfm;

	return 0;
}

static void rsassa_pkcs1_exit_tfm(struct crypto_sig *tfm)
{
	struct rsassa_pkcs1_ctx *ctx = crypto_sig_ctx(tfm);

	crypto_free_akcipher(ctx->child);
}

static void rsassa_pkcs1_free(struct sig_instance *inst)
{
	struct rsassa_pkcs1_inst_ctx *ctx = sig_instance_ctx(inst);
	struct crypto_akcipher_spawn *spawn = &ctx->spawn;

	crypto_drop_akcipher(spawn);
	kfree(inst);
}

static int rsassa_pkcs1_create(struct crypto_template *tmpl, struct rtattr **tb)
{
	struct rsassa_pkcs1_inst_ctx *ctx;
	struct akcipher_alg *rsa_alg;
	struct sig_instance *inst;
	const char *hash_name;
	u32 mask;
	int err;

	err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SIG, &mask);
	if (err)
		return err;

	inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
	if (!inst)
		return -ENOMEM;

	ctx = sig_instance_ctx(inst);

	err = crypto_grab_akcipher(&ctx->spawn, sig_crypto_instance(inst),
				   crypto_attr_alg_name(tb[1]), 0, mask);
	if (err)
		goto err_free_inst;

	rsa_alg = crypto_spawn_akcipher_alg(&ctx->spawn);

	if (strcmp(rsa_alg->base.cra_name, "rsa") != 0) {
		err = -EINVAL;
		goto err_free_inst;
	}

	hash_name = crypto_attr_alg_name(tb[2]);
	if (IS_ERR(hash_name)) {
		err = PTR_ERR(hash_name);
		goto err_free_inst;
	}

	ctx->hash_prefix = rsassa_pkcs1_find_hash_prefix(hash_name);
	if (!ctx->hash_prefix) {
		err = -EINVAL;
		goto err_free_inst;
	}

	err = -ENAMETOOLONG;
	if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
		     "pkcs1(%s,%s)", rsa_alg->base.cra_name,
		     hash_name) >= CRYPTO_MAX_ALG_NAME)
		goto err_free_inst;

	if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
		     "pkcs1(%s,%s)", rsa_alg->base.cra_driver_name,
		     hash_name) >= CRYPTO_MAX_ALG_NAME)
		goto err_free_inst;

	inst->alg.base.cra_priority = rsa_alg->base.cra_priority;
	inst->alg.base.cra_ctxsize = sizeof(struct rsassa_pkcs1_ctx);

	inst->alg.init = rsassa_pkcs1_init_tfm;
	inst->alg.exit = rsassa_pkcs1_exit_tfm;

	inst->alg.sign = rsassa_pkcs1_sign;
	inst->alg.verify = rsassa_pkcs1_verify;
	inst->alg.key_size = rsassa_pkcs1_key_size;
	inst->alg.set_pub_key = rsassa_pkcs1_set_pub_key;
	inst->alg.set_priv_key = rsassa_pkcs1_set_priv_key;

	inst->free = rsassa_pkcs1_free;

	err = sig_register_instance(tmpl, inst);
	if (err) {
err_free_inst:
		rsassa_pkcs1_free(inst);
	}
	return err;
}

struct crypto_template rsassa_pkcs1_tmpl = {
	.name = "pkcs1",
	.create = rsassa_pkcs1_create,
	.module = THIS_MODULE,
};

MODULE_ALIAS_CRYPTO("pkcs1");
