// SPDX-License-Identifier: GPL-2.0-only
/*
 * AMD Cryptographic Coprocessor (CCP) crypto API support
 *
 * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
 *
 * Author: Tom Lendacky <thomas.lendacky@amd.com>
 */

#include <crypto/internal/akcipher.h>
#include <crypto/internal/hash.h>
#include <crypto/internal/skcipher.h>
#include <linux/ccp.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/spinlock.h>

#include "ccp-crypto.h"

MODULE_AUTHOR("Tom Lendacky <thomas.lendacky@amd.com>");
MODULE_LICENSE("GPL");
MODULE_VERSION("1.0.0");
MODULE_DESCRIPTION("AMD Cryptographic Coprocessor crypto API support");

static unsigned int aes_disable;
module_param(aes_disable, uint, 0444);
MODULE_PARM_DESC(aes_disable, "Disable use of AES - any non-zero value");

static unsigned int sha_disable;
module_param(sha_disable, uint, 0444);
MODULE_PARM_DESC(sha_disable, "Disable use of SHA - any non-zero value");

static unsigned int des3_disable;
module_param(des3_disable, uint, 0444);
MODULE_PARM_DESC(des3_disable, "Disable use of 3DES - any non-zero value");

static unsigned int rsa_disable;
module_param(rsa_disable, uint, 0444);
MODULE_PARM_DESC(rsa_disable, "Disable use of RSA - any non-zero value");

/* List heads for the supported algorithms */
static LIST_HEAD(hash_algs);
static LIST_HEAD(skcipher_algs);
static LIST_HEAD(aead_algs);
static LIST_HEAD(akcipher_algs);

/* For any tfm, requests for that tfm must be returned on the order
 * received.  With multiple queues available, the CCP can process more
 * than one cmd at a time.  Therefore we must maintain a cmd list to insure
 * the proper ordering of requests on a given tfm.
 */
struct ccp_crypto_queue {
	struct list_head cmds;
	struct list_head *backlog;
	unsigned int cmd_count;
};

#define CCP_CRYPTO_MAX_QLEN	100

static struct ccp_crypto_queue req_queue;
static DEFINE_SPINLOCK(req_queue_lock);

struct ccp_crypto_cmd {
	struct list_head entry;

	struct ccp_cmd *cmd;

	/* Save the crypto_tfm and crypto_async_request addresses
	 * separately to avoid any reference to a possibly invalid
	 * crypto_async_request structure after invoking the request
	 * callback
	 */
	struct crypto_async_request *req;
	struct crypto_tfm *tfm;

	/* Used for held command processing to determine state */
	int ret;
};

static inline bool ccp_crypto_success(int err)
{
	if (err && (err != -EINPROGRESS) && (err != -EBUSY))
		return false;

	return true;
}

static struct ccp_crypto_cmd *ccp_crypto_cmd_complete(
	struct ccp_crypto_cmd *crypto_cmd, struct ccp_crypto_cmd **backlog)
{
	struct ccp_crypto_cmd *held = NULL, *tmp;
	unsigned long flags;

	*backlog = NULL;

	spin_lock_irqsave(&req_queue_lock, flags);

	/* Held cmds will be after the current cmd in the queue so start
	 * searching for a cmd with a matching tfm for submission.
	 */
	tmp = crypto_cmd;
	list_for_each_entry_continue(tmp, &req_queue.cmds, entry) {
		if (crypto_cmd->tfm != tmp->tfm)
			continue;
		held = tmp;
		break;
	}

	/* Process the backlog:
	 *   Because cmds can be executed from any point in the cmd list
	 *   special precautions have to be taken when handling the backlog.
	 */
	if (req_queue.backlog != &req_queue.cmds) {
		/* Skip over this cmd if it is the next backlog cmd */
		if (req_queue.backlog == &crypto_cmd->entry)
			req_queue.backlog = crypto_cmd->entry.next;

		*backlog = container_of(req_queue.backlog,
					struct ccp_crypto_cmd, entry);
		req_queue.backlog = req_queue.backlog->next;

		/* Skip over this cmd if it is now the next backlog cmd */
		if (req_queue.backlog == &crypto_cmd->entry)
			req_queue.backlog = crypto_cmd->entry.next;
	}

	/* Remove the cmd entry from the list of cmds */
	req_queue.cmd_count--;
	list_del(&crypto_cmd->entry);

	spin_unlock_irqrestore(&req_queue_lock, flags);

	return held;
}

static void ccp_crypto_complete(void *data, int err)
{
	struct ccp_crypto_cmd *crypto_cmd = data;
	struct ccp_crypto_cmd *held, *next, *backlog;
	struct crypto_async_request *req = crypto_cmd->req;
	struct ccp_ctx *ctx = crypto_tfm_ctx_dma(req->tfm);
	int ret;

	if (err == -EINPROGRESS) {
		/* Only propagate the -EINPROGRESS if necessary */
		if (crypto_cmd->ret == -EBUSY) {
			crypto_cmd->ret = -EINPROGRESS;
			crypto_request_complete(req, -EINPROGRESS);
		}

		return;
	}

	/* Operation has completed - update the queue before invoking
	 * the completion callbacks and retrieve the next cmd (cmd with
	 * a matching tfm) that can be submitted to the CCP.
	 */
	held = ccp_crypto_cmd_complete(crypto_cmd, &backlog);
	if (backlog) {
		backlog->ret = -EINPROGRESS;
		crypto_request_complete(backlog->req, -EINPROGRESS);
	}

	/* Transition the state from -EBUSY to -EINPROGRESS first */
	if (crypto_cmd->ret == -EBUSY)
		crypto_request_complete(req, -EINPROGRESS);

	/* Completion callbacks */
	ret = err;
	if (ctx->complete)
		ret = ctx->complete(req, ret);
	crypto_request_complete(req, ret);

	/* Submit the next cmd */
	while (held) {
		/* Since we have already queued the cmd, we must indicate that
		 * we can backlog so as not to "lose" this request.
		 */
		held->cmd->flags |= CCP_CMD_MAY_BACKLOG;
		ret = ccp_enqueue_cmd(held->cmd);
		if (ccp_crypto_success(ret))
			break;

		/* Error occurred, report it and get the next entry */
		ctx = crypto_tfm_ctx_dma(held->req->tfm);
		if (ctx->complete)
			ret = ctx->complete(held->req, ret);
		crypto_request_complete(held->req, ret);

		next = ccp_crypto_cmd_complete(held, &backlog);
		if (backlog) {
			backlog->ret = -EINPROGRESS;
			crypto_request_complete(backlog->req, -EINPROGRESS);
		}

		kfree(held);
		held = next;
	}

	kfree(crypto_cmd);
}

static int ccp_crypto_enqueue_cmd(struct ccp_crypto_cmd *crypto_cmd)
{
	struct ccp_crypto_cmd *active = NULL, *tmp;
	unsigned long flags;
	bool free_cmd = true;
	int ret;

	spin_lock_irqsave(&req_queue_lock, flags);

	/* Check if the cmd can/should be queued */
	if (req_queue.cmd_count >= CCP_CRYPTO_MAX_QLEN) {
		if (!(crypto_cmd->cmd->flags & CCP_CMD_MAY_BACKLOG)) {
			ret = -ENOSPC;
			goto e_lock;
		}
	}

	/* Look for an entry with the same tfm.  If there is a cmd
	 * with the same tfm in the list then the current cmd cannot
	 * be submitted to the CCP yet.
	 */
	list_for_each_entry(tmp, &req_queue.cmds, entry) {
		if (crypto_cmd->tfm != tmp->tfm)
			continue;
		active = tmp;
		break;
	}

	ret = -EINPROGRESS;
	if (!active) {
		ret = ccp_enqueue_cmd(crypto_cmd->cmd);
		if (!ccp_crypto_success(ret))
			goto e_lock;	/* Error, don't queue it */
	}

	if (req_queue.cmd_count >= CCP_CRYPTO_MAX_QLEN) {
		ret = -EBUSY;
		if (req_queue.backlog == &req_queue.cmds)
			req_queue.backlog = &crypto_cmd->entry;
	}
	crypto_cmd->ret = ret;

	req_queue.cmd_count++;
	list_add_tail(&crypto_cmd->entry, &req_queue.cmds);

	free_cmd = false;

e_lock:
	spin_unlock_irqrestore(&req_queue_lock, flags);

	if (free_cmd)
		kfree(crypto_cmd);

	return ret;
}

/**
 * ccp_crypto_enqueue_request - queue an crypto async request for processing
 *				by the CCP
 *
 * @req: crypto_async_request struct to be processed
 * @cmd: ccp_cmd struct to be sent to the CCP
 */
int ccp_crypto_enqueue_request(struct crypto_async_request *req,
			       struct ccp_cmd *cmd)
{
	struct ccp_crypto_cmd *crypto_cmd;
	gfp_t gfp;

	gfp = req->flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC;

	crypto_cmd = kzalloc(sizeof(*crypto_cmd), gfp);
	if (!crypto_cmd)
		return -ENOMEM;

	/* The tfm pointer must be saved and not referenced from the
	 * crypto_async_request (req) pointer because it is used after
	 * completion callback for the request and the req pointer
	 * might not be valid anymore.
	 */
	crypto_cmd->cmd = cmd;
	crypto_cmd->req = req;
	crypto_cmd->tfm = req->tfm;

	cmd->callback = ccp_crypto_complete;
	cmd->data = crypto_cmd;

	if (req->flags & CRYPTO_TFM_REQ_MAY_BACKLOG)
		cmd->flags |= CCP_CMD_MAY_BACKLOG;
	else
		cmd->flags &= ~CCP_CMD_MAY_BACKLOG;

	return ccp_crypto_enqueue_cmd(crypto_cmd);
}

struct scatterlist *ccp_crypto_sg_table_add(struct sg_table *table,
					    struct scatterlist *sg_add)
{
	struct scatterlist *sg, *sg_last = NULL;

	for (sg = table->sgl; sg; sg = sg_next(sg))
		if (!sg_page(sg))
			break;
	if (WARN_ON(!sg))
		return NULL;

	for (; sg && sg_add; sg = sg_next(sg), sg_add = sg_next(sg_add)) {
		sg_set_page(sg, sg_page(sg_add), sg_add->length,
			    sg_add->offset);
		sg_last = sg;
	}
	if (WARN_ON(sg_add))
		return NULL;

	return sg_last;
}

static int ccp_register_algs(void)
{
	int ret;

	if (!aes_disable) {
		ret = ccp_register_aes_algs(&skcipher_algs);
		if (ret)
			return ret;

		ret = ccp_register_aes_cmac_algs(&hash_algs);
		if (ret)
			return ret;

		ret = ccp_register_aes_xts_algs(&skcipher_algs);
		if (ret)
			return ret;

		ret = ccp_register_aes_aeads(&aead_algs);
		if (ret)
			return ret;
	}

	if (!des3_disable) {
		ret = ccp_register_des3_algs(&skcipher_algs);
		if (ret)
			return ret;
	}

	if (!sha_disable) {
		ret = ccp_register_sha_algs(&hash_algs);
		if (ret)
			return ret;
	}

	if (!rsa_disable) {
		ret = ccp_register_rsa_algs(&akcipher_algs);
		if (ret)
			return ret;
	}

	return 0;
}

static void ccp_unregister_algs(void)
{
	struct ccp_crypto_ahash_alg *ahash_alg, *ahash_tmp;
	struct ccp_crypto_skcipher_alg *ablk_alg, *ablk_tmp;
	struct ccp_crypto_aead *aead_alg, *aead_tmp;
	struct ccp_crypto_akcipher_alg *akc_alg, *akc_tmp;

	list_for_each_entry_safe(ahash_alg, ahash_tmp, &hash_algs, entry) {
		crypto_unregister_ahash(&ahash_alg->alg);
		list_del(&ahash_alg->entry);
		kfree(ahash_alg);
	}

	list_for_each_entry_safe(ablk_alg, ablk_tmp, &skcipher_algs, entry) {
		crypto_unregister_skcipher(&ablk_alg->alg);
		list_del(&ablk_alg->entry);
		kfree(ablk_alg);
	}

	list_for_each_entry_safe(aead_alg, aead_tmp, &aead_algs, entry) {
		crypto_unregister_aead(&aead_alg->alg);
		list_del(&aead_alg->entry);
		kfree(aead_alg);
	}

	list_for_each_entry_safe(akc_alg, akc_tmp, &akcipher_algs, entry) {
		crypto_unregister_akcipher(&akc_alg->alg);
		list_del(&akc_alg->entry);
		kfree(akc_alg);
	}
}

static int __init ccp_crypto_init(void)
{
	int ret;

	ret = ccp_present();
	if (ret) {
		pr_err("Cannot load: there are no available CCPs\n");
		return ret;
	}

	INIT_LIST_HEAD(&req_queue.cmds);
	req_queue.backlog = &req_queue.cmds;
	req_queue.cmd_count = 0;

	ret = ccp_register_algs();
	if (ret)
		ccp_unregister_algs();

	return ret;
}

static void __exit ccp_crypto_exit(void)
{
	ccp_unregister_algs();
}

module_init(ccp_crypto_init);
module_exit(ccp_crypto_exit);
