// SPDX-License-Identifier: GPL-2.0-only
/*
 * AMD Cryptographic Coprocessor (CCP) RSA crypto API support
 *
 * Copyright (C) 2017 Advanced Micro Devices, Inc.
 *
 * Author: Gary R Hook <gary.hook@amd.com>
 */

#include <linux/module.h>
#include <linux/sched.h>
#include <linux/scatterlist.h>
#include <linux/crypto.h>
#include <crypto/algapi.h>
#include <crypto/internal/rsa.h>
#include <crypto/internal/akcipher.h>
#include <crypto/akcipher.h>
#include <crypto/scatterwalk.h>

#include "ccp-crypto.h"

static inline struct akcipher_request *akcipher_request_cast(
	struct crypto_async_request *req)
{
	return container_of(req, struct akcipher_request, base);
}

static inline int ccp_copy_and_save_keypart(u8 **kpbuf, unsigned int *kplen,
					    const u8 *buf, size_t sz)
{
	int nskip;

	for (nskip = 0; nskip < sz; nskip++)
		if (buf[nskip])
			break;
	*kplen = sz - nskip;
	*kpbuf = kmemdup(buf + nskip, *kplen, GFP_KERNEL);
	if (!*kpbuf)
		return -ENOMEM;

	return 0;
}

static int ccp_rsa_complete(struct crypto_async_request *async_req, int ret)
{
	struct akcipher_request *req = akcipher_request_cast(async_req);
	struct ccp_rsa_req_ctx *rctx = akcipher_request_ctx_dma(req);

	if (ret)
		return ret;

	req->dst_len = rctx->cmd.u.rsa.key_size >> 3;

	return 0;
}

static unsigned int ccp_rsa_maxsize(struct crypto_akcipher *tfm)
{
	struct ccp_ctx *ctx = akcipher_tfm_ctx_dma(tfm);

	return ctx->u.rsa.n_len;
}

static int ccp_rsa_crypt(struct akcipher_request *req, bool encrypt)
{
	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
	struct ccp_ctx *ctx = akcipher_tfm_ctx_dma(tfm);
	struct ccp_rsa_req_ctx *rctx = akcipher_request_ctx_dma(req);
	int ret = 0;

	memset(&rctx->cmd, 0, sizeof(rctx->cmd));
	INIT_LIST_HEAD(&rctx->cmd.entry);
	rctx->cmd.engine = CCP_ENGINE_RSA;

	rctx->cmd.u.rsa.key_size = ctx->u.rsa.key_len; /* in bits */
	if (encrypt) {
		rctx->cmd.u.rsa.exp = &ctx->u.rsa.e_sg;
		rctx->cmd.u.rsa.exp_len = ctx->u.rsa.e_len;
	} else {
		rctx->cmd.u.rsa.exp = &ctx->u.rsa.d_sg;
		rctx->cmd.u.rsa.exp_len = ctx->u.rsa.d_len;
	}
	rctx->cmd.u.rsa.mod = &ctx->u.rsa.n_sg;
	rctx->cmd.u.rsa.mod_len = ctx->u.rsa.n_len;
	rctx->cmd.u.rsa.src = req->src;
	rctx->cmd.u.rsa.src_len = req->src_len;
	rctx->cmd.u.rsa.dst = req->dst;

	ret = ccp_crypto_enqueue_request(&req->base, &rctx->cmd);

	return ret;
}

static int ccp_rsa_encrypt(struct akcipher_request *req)
{
	return ccp_rsa_crypt(req, true);
}

static int ccp_rsa_decrypt(struct akcipher_request *req)
{
	return ccp_rsa_crypt(req, false);
}

static int ccp_check_key_length(unsigned int len)
{
	/* In bits */
	if (len < 8 || len > 4096)
		return -EINVAL;
	return 0;
}

static void ccp_rsa_free_key_bufs(struct ccp_ctx *ctx)
{
	/* Clean up old key data */
	kfree_sensitive(ctx->u.rsa.e_buf);
	ctx->u.rsa.e_buf = NULL;
	ctx->u.rsa.e_len = 0;
	kfree_sensitive(ctx->u.rsa.n_buf);
	ctx->u.rsa.n_buf = NULL;
	ctx->u.rsa.n_len = 0;
	kfree_sensitive(ctx->u.rsa.d_buf);
	ctx->u.rsa.d_buf = NULL;
	ctx->u.rsa.d_len = 0;
}

static int ccp_rsa_setkey(struct crypto_akcipher *tfm, const void *key,
			  unsigned int keylen, bool private)
{
	struct ccp_ctx *ctx = akcipher_tfm_ctx_dma(tfm);
	struct rsa_key raw_key;
	int ret;

	ccp_rsa_free_key_bufs(ctx);
	memset(&raw_key, 0, sizeof(raw_key));

	/* Code borrowed from crypto/rsa.c */
	if (private)
		ret = rsa_parse_priv_key(&raw_key, key, keylen);
	else
		ret = rsa_parse_pub_key(&raw_key, key, keylen);
	if (ret)
		goto n_key;

	ret = ccp_copy_and_save_keypart(&ctx->u.rsa.n_buf, &ctx->u.rsa.n_len,
					raw_key.n, raw_key.n_sz);
	if (ret)
		goto key_err;
	sg_init_one(&ctx->u.rsa.n_sg, ctx->u.rsa.n_buf, ctx->u.rsa.n_len);

	ctx->u.rsa.key_len = ctx->u.rsa.n_len << 3; /* convert to bits */
	if (ccp_check_key_length(ctx->u.rsa.key_len)) {
		ret = -EINVAL;
		goto key_err;
	}

	ret = ccp_copy_and_save_keypart(&ctx->u.rsa.e_buf, &ctx->u.rsa.e_len,
					raw_key.e, raw_key.e_sz);
	if (ret)
		goto key_err;
	sg_init_one(&ctx->u.rsa.e_sg, ctx->u.rsa.e_buf, ctx->u.rsa.e_len);

	if (private) {
		ret = ccp_copy_and_save_keypart(&ctx->u.rsa.d_buf,
						&ctx->u.rsa.d_len,
						raw_key.d, raw_key.d_sz);
		if (ret)
			goto key_err;
		sg_init_one(&ctx->u.rsa.d_sg,
			    ctx->u.rsa.d_buf, ctx->u.rsa.d_len);
	}

	return 0;

key_err:
	ccp_rsa_free_key_bufs(ctx);

n_key:
	return ret;
}

static int ccp_rsa_setprivkey(struct crypto_akcipher *tfm, const void *key,
			      unsigned int keylen)
{
	return ccp_rsa_setkey(tfm, key, keylen, true);
}

static int ccp_rsa_setpubkey(struct crypto_akcipher *tfm, const void *key,
			     unsigned int keylen)
{
	return ccp_rsa_setkey(tfm, key, keylen, false);
}

static int ccp_rsa_init_tfm(struct crypto_akcipher *tfm)
{
	struct ccp_ctx *ctx = akcipher_tfm_ctx_dma(tfm);

	akcipher_set_reqsize_dma(tfm, sizeof(struct ccp_rsa_req_ctx));
	ctx->complete = ccp_rsa_complete;

	return 0;
}

static void ccp_rsa_exit_tfm(struct crypto_akcipher *tfm)
{
	struct ccp_ctx *ctx = akcipher_tfm_ctx_dma(tfm);

	ccp_rsa_free_key_bufs(ctx);
}

static struct akcipher_alg ccp_rsa_defaults = {
	.encrypt = ccp_rsa_encrypt,
	.decrypt = ccp_rsa_decrypt,
	.set_pub_key = ccp_rsa_setpubkey,
	.set_priv_key = ccp_rsa_setprivkey,
	.max_size = ccp_rsa_maxsize,
	.init = ccp_rsa_init_tfm,
	.exit = ccp_rsa_exit_tfm,
	.base = {
		.cra_name = "rsa",
		.cra_driver_name = "rsa-ccp",
		.cra_priority = CCP_CRA_PRIORITY,
		.cra_module = THIS_MODULE,
		.cra_ctxsize = 2 * sizeof(struct ccp_ctx) + CRYPTO_DMA_PADDING,
	},
};

struct ccp_rsa_def {
	unsigned int version;
	const char *name;
	const char *driver_name;
	unsigned int reqsize;
	struct akcipher_alg *alg_defaults;
};

static struct ccp_rsa_def rsa_algs[] = {
	{
		.version	= CCP_VERSION(3, 0),
		.name		= "rsa",
		.driver_name	= "rsa-ccp",
		.reqsize	= sizeof(struct ccp_rsa_req_ctx),
		.alg_defaults	= &ccp_rsa_defaults,
	}
};

static int ccp_register_rsa_alg(struct list_head *head,
			        const struct ccp_rsa_def *def)
{
	struct ccp_crypto_akcipher_alg *ccp_alg;
	struct akcipher_alg *alg;
	int ret;

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

	INIT_LIST_HEAD(&ccp_alg->entry);

	alg = &ccp_alg->alg;
	*alg = *def->alg_defaults;
	snprintf(alg->base.cra_name, CRYPTO_MAX_ALG_NAME, "%s", def->name);
	snprintf(alg->base.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
		 def->driver_name);
	ret = crypto_register_akcipher(alg);
	if (ret) {
		pr_err("%s akcipher algorithm registration error (%d)\n",
		       alg->base.cra_name, ret);
		kfree(ccp_alg);
		return ret;
	}

	list_add(&ccp_alg->entry, head);

	return 0;
}

int ccp_register_rsa_algs(struct list_head *head)
{
	int i, ret;
	unsigned int ccpversion = ccp_version();

	/* Register the RSA algorithm in standard mode
	 * This works for CCP v3 and later
	 */
	for (i = 0; i < ARRAY_SIZE(rsa_algs); i++) {
		if (rsa_algs[i].version > ccpversion)
			continue;
		ret = ccp_register_rsa_alg(head, &rsa_algs[i]);
		if (ret)
			return ret;
	}

	return 0;
}
