// SPDX-License-Identifier: GPL-2.0-only

/*
 * Copyright (C) 2021, Linaro Limited. All rights reserved.
 */
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <crypto/gcm.h>
#include <crypto/authenc.h>
#include <crypto/internal/aead.h>
#include <crypto/internal/des.h>
#include <crypto/sha1.h>
#include <crypto/sha2.h>
#include <crypto/scatterwalk.h>
#include "aead.h"

#define CCM_NONCE_ADATA_SHIFT		6
#define CCM_NONCE_AUTHSIZE_SHIFT	3
#define MAX_CCM_ADATA_HEADER_LEN        6

static LIST_HEAD(aead_algs);

static void qce_aead_done(void *data)
{
	struct crypto_async_request *async_req = data;
	struct aead_request *req = aead_request_cast(async_req);
	struct qce_aead_reqctx *rctx = aead_request_ctx(req);
	struct qce_aead_ctx *ctx = crypto_tfm_ctx(async_req->tfm);
	struct qce_alg_template *tmpl = to_aead_tmpl(crypto_aead_reqtfm(req));
	struct qce_device *qce = tmpl->qce;
	struct qce_result_dump *result_buf = qce->dma.result_buf;
	enum dma_data_direction dir_src, dir_dst;
	bool diff_dst;
	int error;
	u32 status;
	unsigned int totallen;
	unsigned char tag[SHA256_DIGEST_SIZE] = {0};
	int ret = 0;

	diff_dst = (req->src != req->dst) ? true : false;
	dir_src = diff_dst ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL;
	dir_dst = diff_dst ? DMA_FROM_DEVICE : DMA_BIDIRECTIONAL;

	error = qce_dma_terminate_all(&qce->dma);
	if (error)
		dev_dbg(qce->dev, "aead dma termination error (%d)\n",
			error);
	if (diff_dst)
		dma_unmap_sg(qce->dev, rctx->src_sg, rctx->src_nents, dir_src);

	dma_unmap_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst);

	if (IS_CCM(rctx->flags)) {
		if (req->assoclen) {
			sg_free_table(&rctx->src_tbl);
			if (diff_dst)
				sg_free_table(&rctx->dst_tbl);
		} else {
			if (!(IS_DECRYPT(rctx->flags) && !diff_dst))
				sg_free_table(&rctx->dst_tbl);
		}
	} else {
		sg_free_table(&rctx->dst_tbl);
	}

	error = qce_check_status(qce, &status);
	if (error < 0 && (error != -EBADMSG))
		dev_err(qce->dev, "aead operation error (%x)\n", status);

	if (IS_ENCRYPT(rctx->flags)) {
		totallen = req->cryptlen + req->assoclen;
		if (IS_CCM(rctx->flags))
			scatterwalk_map_and_copy(rctx->ccmresult_buf, req->dst,
						 totallen, ctx->authsize, 1);
		else
			scatterwalk_map_and_copy(result_buf->auth_iv, req->dst,
						 totallen, ctx->authsize, 1);

	} else if (!IS_CCM(rctx->flags)) {
		totallen = req->cryptlen + req->assoclen - ctx->authsize;
		scatterwalk_map_and_copy(tag, req->src, totallen, ctx->authsize, 0);
		ret = memcmp(result_buf->auth_iv, tag, ctx->authsize);
		if (ret) {
			pr_err("Bad message error\n");
			error = -EBADMSG;
		}
	}

	qce->async_req_done(qce, error);
}

static struct scatterlist *
qce_aead_prepare_result_buf(struct sg_table *tbl, struct aead_request *req)
{
	struct qce_aead_reqctx *rctx = aead_request_ctx(req);
	struct qce_alg_template *tmpl = to_aead_tmpl(crypto_aead_reqtfm(req));
	struct qce_device *qce = tmpl->qce;

	sg_init_one(&rctx->result_sg, qce->dma.result_buf, QCE_RESULT_BUF_SZ);
	return qce_sgtable_add(tbl, &rctx->result_sg, QCE_RESULT_BUF_SZ);
}

static struct scatterlist *
qce_aead_prepare_ccm_result_buf(struct sg_table *tbl, struct aead_request *req)
{
	struct qce_aead_reqctx *rctx = aead_request_ctx(req);

	sg_init_one(&rctx->result_sg, rctx->ccmresult_buf, QCE_BAM_BURST_SIZE);
	return qce_sgtable_add(tbl, &rctx->result_sg, QCE_BAM_BURST_SIZE);
}

static struct scatterlist *
qce_aead_prepare_dst_buf(struct aead_request *req)
{
	struct qce_aead_reqctx *rctx = aead_request_ctx(req);
	struct qce_alg_template *tmpl = to_aead_tmpl(crypto_aead_reqtfm(req));
	struct qce_device *qce = tmpl->qce;
	struct scatterlist *sg, *msg_sg, __sg[2];
	gfp_t gfp;
	unsigned int assoclen = req->assoclen;
	unsigned int totallen;
	int ret;

	totallen = rctx->cryptlen + assoclen;
	rctx->dst_nents = sg_nents_for_len(req->dst, totallen);
	if (rctx->dst_nents < 0) {
		dev_err(qce->dev, "Invalid numbers of dst SG.\n");
		return ERR_PTR(-EINVAL);
	}
	if (IS_CCM(rctx->flags))
		rctx->dst_nents += 2;
	else
		rctx->dst_nents += 1;

	gfp = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
						GFP_KERNEL : GFP_ATOMIC;
	ret = sg_alloc_table(&rctx->dst_tbl, rctx->dst_nents, gfp);
	if (ret)
		return ERR_PTR(ret);

	if (IS_CCM(rctx->flags) && assoclen) {
		/* Get the dst buffer */
		msg_sg = scatterwalk_ffwd(__sg, req->dst, assoclen);

		sg = qce_sgtable_add(&rctx->dst_tbl, &rctx->adata_sg,
				     rctx->assoclen);
		if (IS_ERR(sg)) {
			ret = PTR_ERR(sg);
			goto dst_tbl_free;
		}
		/* dst buffer */
		sg = qce_sgtable_add(&rctx->dst_tbl, msg_sg, rctx->cryptlen);
		if (IS_ERR(sg)) {
			ret = PTR_ERR(sg);
			goto dst_tbl_free;
		}
		totallen = rctx->cryptlen + rctx->assoclen;
	} else {
		if (totallen) {
			sg = qce_sgtable_add(&rctx->dst_tbl, req->dst, totallen);
			if (IS_ERR(sg))
				goto dst_tbl_free;
		}
	}
	if (IS_CCM(rctx->flags))
		sg = qce_aead_prepare_ccm_result_buf(&rctx->dst_tbl, req);
	else
		sg = qce_aead_prepare_result_buf(&rctx->dst_tbl, req);

	if (IS_ERR(sg))
		goto dst_tbl_free;

	sg_mark_end(sg);
	rctx->dst_sg = rctx->dst_tbl.sgl;
	rctx->dst_nents = sg_nents_for_len(rctx->dst_sg, totallen) + 1;

	return sg;

dst_tbl_free:
	sg_free_table(&rctx->dst_tbl);
	return sg;
}

static int
qce_aead_ccm_prepare_buf_assoclen(struct aead_request *req)
{
	struct scatterlist *sg, *msg_sg, __sg[2];
	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
	struct qce_aead_reqctx *rctx = aead_request_ctx(req);
	struct qce_aead_ctx *ctx = crypto_aead_ctx(tfm);
	unsigned int assoclen = rctx->assoclen;
	unsigned int adata_header_len, cryptlen, totallen;
	gfp_t gfp;
	bool diff_dst;
	int ret;

	if (IS_DECRYPT(rctx->flags))
		cryptlen = rctx->cryptlen + ctx->authsize;
	else
		cryptlen = rctx->cryptlen;
	totallen = cryptlen + req->assoclen;

	/* Get the msg */
	msg_sg = scatterwalk_ffwd(__sg, req->src, req->assoclen);

	rctx->adata = kzalloc((ALIGN(assoclen, 16) + MAX_CCM_ADATA_HEADER_LEN) *
			       sizeof(unsigned char), GFP_ATOMIC);
	if (!rctx->adata)
		return -ENOMEM;

	/*
	 * Format associated data (RFC3610 and NIST 800-38C)
	 * Even though specification allows for AAD to be up to 2^64 - 1 bytes,
	 * the assoclen field in aead_request is unsigned int and thus limits
	 * the AAD to be up to 2^32 - 1 bytes. So we handle only two scenarios
	 * while forming the header for AAD.
	 */
	if (assoclen < 0xff00) {
		adata_header_len = 2;
		*(__be16 *)rctx->adata = cpu_to_be16(assoclen);
	} else {
		adata_header_len = 6;
		*(__be16 *)rctx->adata = cpu_to_be16(0xfffe);
		*(__be32 *)(rctx->adata + 2) = cpu_to_be32(assoclen);
	}

	/* Copy the associated data */
	if (sg_copy_to_buffer(req->src, sg_nents_for_len(req->src, assoclen),
			      rctx->adata + adata_header_len,
			      assoclen) != assoclen)
		return -EINVAL;

	/* Pad associated data to block size */
	rctx->assoclen = ALIGN(assoclen + adata_header_len, 16);

	diff_dst = (req->src != req->dst) ? true : false;

	if (diff_dst)
		rctx->src_nents = sg_nents_for_len(req->src, totallen) + 1;
	else
		rctx->src_nents = sg_nents_for_len(req->src, totallen) + 2;

	gfp = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? GFP_KERNEL : GFP_ATOMIC;
	ret = sg_alloc_table(&rctx->src_tbl, rctx->src_nents, gfp);
	if (ret)
		return ret;

	/* Associated Data */
	sg_init_one(&rctx->adata_sg, rctx->adata, rctx->assoclen);
	sg = qce_sgtable_add(&rctx->src_tbl, &rctx->adata_sg,
			     rctx->assoclen);
	if (IS_ERR(sg)) {
		ret = PTR_ERR(sg);
		goto err_free;
	}
	/* src msg */
	sg = qce_sgtable_add(&rctx->src_tbl, msg_sg, cryptlen);
	if (IS_ERR(sg)) {
		ret = PTR_ERR(sg);
		goto err_free;
	}
	if (!diff_dst) {
		/*
		 * For decrypt, when src and dst buffers are same, there is already space
		 * in the buffer for padded 0's which is output in lieu of
		 * the MAC that is input. So skip the below.
		 */
		if (!IS_DECRYPT(rctx->flags)) {
			sg = qce_aead_prepare_ccm_result_buf(&rctx->src_tbl, req);
			if (IS_ERR(sg)) {
				ret = PTR_ERR(sg);
				goto err_free;
			}
		}
	}
	sg_mark_end(sg);
	rctx->src_sg = rctx->src_tbl.sgl;
	totallen = cryptlen + rctx->assoclen;
	rctx->src_nents = sg_nents_for_len(rctx->src_sg, totallen);

	if (diff_dst) {
		sg = qce_aead_prepare_dst_buf(req);
		if (IS_ERR(sg)) {
			ret = PTR_ERR(sg);
			goto err_free;
		}
	} else {
		if (IS_ENCRYPT(rctx->flags))
			rctx->dst_nents = rctx->src_nents + 1;
		else
			rctx->dst_nents = rctx->src_nents;
		rctx->dst_sg = rctx->src_sg;
	}

	return 0;
err_free:
	sg_free_table(&rctx->src_tbl);
	return ret;
}

static int qce_aead_prepare_buf(struct aead_request *req)
{
	struct qce_aead_reqctx *rctx = aead_request_ctx(req);
	struct qce_alg_template *tmpl = to_aead_tmpl(crypto_aead_reqtfm(req));
	struct qce_device *qce = tmpl->qce;
	struct scatterlist *sg;
	bool diff_dst = (req->src != req->dst) ? true : false;
	unsigned int totallen;

	totallen = rctx->cryptlen + rctx->assoclen;

	sg = qce_aead_prepare_dst_buf(req);
	if (IS_ERR(sg))
		return PTR_ERR(sg);
	if (diff_dst) {
		rctx->src_nents = sg_nents_for_len(req->src, totallen);
		if (rctx->src_nents < 0) {
			dev_err(qce->dev, "Invalid numbers of src SG.\n");
			return -EINVAL;
		}
		rctx->src_sg = req->src;
	} else {
		rctx->src_nents = rctx->dst_nents - 1;
		rctx->src_sg = rctx->dst_sg;
	}
	return 0;
}

static int qce_aead_ccm_prepare_buf(struct aead_request *req)
{
	struct qce_aead_reqctx *rctx = aead_request_ctx(req);
	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
	struct qce_aead_ctx *ctx = crypto_aead_ctx(tfm);
	struct scatterlist *sg;
	bool diff_dst = (req->src != req->dst) ? true : false;
	unsigned int cryptlen;

	if (rctx->assoclen)
		return qce_aead_ccm_prepare_buf_assoclen(req);

	if (IS_ENCRYPT(rctx->flags))
		return qce_aead_prepare_buf(req);

	cryptlen = rctx->cryptlen + ctx->authsize;
	if (diff_dst) {
		rctx->src_nents = sg_nents_for_len(req->src, cryptlen);
		rctx->src_sg = req->src;
		sg = qce_aead_prepare_dst_buf(req);
		if (IS_ERR(sg))
			return PTR_ERR(sg);
	} else {
		rctx->src_nents = sg_nents_for_len(req->src, cryptlen);
		rctx->src_sg = req->src;
		rctx->dst_nents = rctx->src_nents;
		rctx->dst_sg = rctx->src_sg;
	}

	return 0;
}

static int qce_aead_create_ccm_nonce(struct qce_aead_reqctx *rctx, struct qce_aead_ctx *ctx)
{
	unsigned int msglen_size, ivsize;
	u8 msg_len[4];
	int i;

	if (!rctx || !rctx->iv)
		return -EINVAL;

	msglen_size = rctx->iv[0] + 1;

	/* Verify that msg len size is valid */
	if (msglen_size < 2 || msglen_size > 8)
		return -EINVAL;

	ivsize = rctx->ivsize;

	/*
	 * Clear the msglen bytes in IV.
	 * Else the h/w engine and nonce will use any stray value pending there.
	 */
	if (!IS_CCM_RFC4309(rctx->flags)) {
		for (i = 0; i < msglen_size; i++)
			rctx->iv[ivsize - i - 1] = 0;
	}

	/*
	 * The crypto framework encodes cryptlen as unsigned int. Thus, even though
	 * spec allows for upto 8 bytes to encode msg_len only 4 bytes are needed.
	 */
	if (msglen_size > 4)
		msglen_size = 4;

	memcpy(&msg_len[0], &rctx->cryptlen, 4);

	memcpy(&rctx->ccm_nonce[0], rctx->iv, rctx->ivsize);
	if (rctx->assoclen)
		rctx->ccm_nonce[0] |= 1 << CCM_NONCE_ADATA_SHIFT;
	rctx->ccm_nonce[0] |= ((ctx->authsize - 2) / 2) <<
				CCM_NONCE_AUTHSIZE_SHIFT;
	for (i = 0; i < msglen_size; i++)
		rctx->ccm_nonce[QCE_MAX_NONCE - i - 1] = msg_len[i];

	return 0;
}

static int
qce_aead_async_req_handle(struct crypto_async_request *async_req)
{
	struct aead_request *req = aead_request_cast(async_req);
	struct qce_aead_reqctx *rctx = aead_request_ctx(req);
	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
	struct qce_aead_ctx *ctx = crypto_tfm_ctx(async_req->tfm);
	struct qce_alg_template *tmpl = to_aead_tmpl(crypto_aead_reqtfm(req));
	struct qce_device *qce = tmpl->qce;
	enum dma_data_direction dir_src, dir_dst;
	bool diff_dst;
	int dst_nents, src_nents, ret;

	if (IS_CCM_RFC4309(rctx->flags)) {
		memset(rctx->ccm_rfc4309_iv, 0, QCE_MAX_IV_SIZE);
		rctx->ccm_rfc4309_iv[0] = 3;
		memcpy(&rctx->ccm_rfc4309_iv[1], ctx->ccm4309_salt, QCE_CCM4309_SALT_SIZE);
		memcpy(&rctx->ccm_rfc4309_iv[4], req->iv, 8);
		rctx->iv = rctx->ccm_rfc4309_iv;
		rctx->ivsize = AES_BLOCK_SIZE;
	} else {
		rctx->iv = req->iv;
		rctx->ivsize = crypto_aead_ivsize(tfm);
	}
	if (IS_CCM_RFC4309(rctx->flags))
		rctx->assoclen = req->assoclen - 8;
	else
		rctx->assoclen = req->assoclen;

	diff_dst = (req->src != req->dst) ? true : false;
	dir_src = diff_dst ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL;
	dir_dst = diff_dst ? DMA_FROM_DEVICE : DMA_BIDIRECTIONAL;

	if (IS_CCM(rctx->flags)) {
		ret = qce_aead_create_ccm_nonce(rctx, ctx);
		if (ret)
			return ret;
	}
	if (IS_CCM(rctx->flags))
		ret = qce_aead_ccm_prepare_buf(req);
	else
		ret = qce_aead_prepare_buf(req);

	if (ret)
		return ret;
	dst_nents = dma_map_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst);
	if (!dst_nents) {
		ret = -EIO;
		goto error_free;
	}

	if (diff_dst) {
		src_nents = dma_map_sg(qce->dev, rctx->src_sg, rctx->src_nents, dir_src);
		if (src_nents < 0) {
			ret = src_nents;
			goto error_unmap_dst;
		}
	} else {
		if (IS_CCM(rctx->flags) && IS_DECRYPT(rctx->flags))
			src_nents = dst_nents;
		else
			src_nents = dst_nents - 1;
	}

	ret = qce_dma_prep_sgs(&qce->dma, rctx->src_sg, src_nents, rctx->dst_sg, dst_nents,
			       qce_aead_done, async_req);
	if (ret)
		goto error_unmap_src;

	qce_dma_issue_pending(&qce->dma);

	ret = qce_start(async_req, tmpl->crypto_alg_type);
	if (ret)
		goto error_terminate;

	return 0;

error_terminate:
	qce_dma_terminate_all(&qce->dma);
error_unmap_src:
	if (diff_dst)
		dma_unmap_sg(qce->dev, req->src, rctx->src_nents, dir_src);
error_unmap_dst:
	dma_unmap_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst);
error_free:
	if (IS_CCM(rctx->flags) && rctx->assoclen) {
		sg_free_table(&rctx->src_tbl);
		if (diff_dst)
			sg_free_table(&rctx->dst_tbl);
	} else {
		sg_free_table(&rctx->dst_tbl);
	}
	return ret;
}

static int qce_aead_crypt(struct aead_request *req, int encrypt)
{
	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
	struct qce_aead_reqctx *rctx = aead_request_ctx(req);
	struct qce_aead_ctx *ctx = crypto_aead_ctx(tfm);
	struct qce_alg_template *tmpl = to_aead_tmpl(tfm);
	unsigned int blocksize = crypto_aead_blocksize(tfm);

	rctx->flags  = tmpl->alg_flags;
	rctx->flags |= encrypt ? QCE_ENCRYPT : QCE_DECRYPT;

	if (encrypt)
		rctx->cryptlen = req->cryptlen;
	else
		rctx->cryptlen = req->cryptlen - ctx->authsize;

	/* CE does not handle 0 length messages */
	if (!rctx->cryptlen) {
		if (!(IS_CCM(rctx->flags) && IS_DECRYPT(rctx->flags)))
			ctx->need_fallback = true;
	}

	/* If fallback is needed, schedule and exit */
	if (ctx->need_fallback) {
		/* Reset need_fallback in case the same ctx is used for another transaction */
		ctx->need_fallback = false;

		aead_request_set_tfm(&rctx->fallback_req, ctx->fallback);
		aead_request_set_callback(&rctx->fallback_req, req->base.flags,
					  req->base.complete, req->base.data);
		aead_request_set_crypt(&rctx->fallback_req, req->src,
				       req->dst, req->cryptlen, req->iv);
		aead_request_set_ad(&rctx->fallback_req, req->assoclen);

		return encrypt ? crypto_aead_encrypt(&rctx->fallback_req) :
				 crypto_aead_decrypt(&rctx->fallback_req);
	}

	/*
	 * CBC algorithms require message lengths to be
	 * multiples of block size.
	 */
	if (IS_CBC(rctx->flags) && !IS_ALIGNED(rctx->cryptlen, blocksize))
		return -EINVAL;

	/* RFC4309 supported AAD size 16 bytes/20 bytes */
	if (IS_CCM_RFC4309(rctx->flags))
		if (crypto_ipsec_check_assoclen(req->assoclen))
			return -EINVAL;

	return tmpl->qce->async_req_enqueue(tmpl->qce, &req->base);
}

static int qce_aead_encrypt(struct aead_request *req)
{
	return qce_aead_crypt(req, 1);
}

static int qce_aead_decrypt(struct aead_request *req)
{
	return qce_aead_crypt(req, 0);
}

static int qce_aead_ccm_setkey(struct crypto_aead *tfm, const u8 *key,
			       unsigned int keylen)
{
	struct qce_aead_ctx *ctx = crypto_aead_ctx(tfm);
	unsigned long flags = to_aead_tmpl(tfm)->alg_flags;

	if (IS_CCM_RFC4309(flags)) {
		if (keylen < QCE_CCM4309_SALT_SIZE)
			return -EINVAL;
		keylen -= QCE_CCM4309_SALT_SIZE;
		memcpy(ctx->ccm4309_salt, key + keylen, QCE_CCM4309_SALT_SIZE);
	}

	if (keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_256 && keylen != AES_KEYSIZE_192)
		return -EINVAL;

	ctx->enc_keylen = keylen;
	ctx->auth_keylen = keylen;

	memcpy(ctx->enc_key, key, keylen);
	memcpy(ctx->auth_key, key, keylen);

	if (keylen == AES_KEYSIZE_192)
		ctx->need_fallback = true;

	return IS_CCM_RFC4309(flags) ?
		crypto_aead_setkey(ctx->fallback, key, keylen + QCE_CCM4309_SALT_SIZE) :
		crypto_aead_setkey(ctx->fallback, key, keylen);
}

static int qce_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen)
{
	struct qce_aead_ctx *ctx = crypto_aead_ctx(tfm);
	struct crypto_authenc_keys authenc_keys;
	unsigned long flags = to_aead_tmpl(tfm)->alg_flags;
	u32 _key[6];
	int err;

	err = crypto_authenc_extractkeys(&authenc_keys, key, keylen);
	if (err)
		return err;

	if (authenc_keys.enckeylen > QCE_MAX_KEY_SIZE ||
	    authenc_keys.authkeylen > QCE_MAX_KEY_SIZE)
		return -EINVAL;

	if (IS_DES(flags)) {
		err = verify_aead_des_key(tfm, authenc_keys.enckey, authenc_keys.enckeylen);
		if (err)
			return err;
	} else if (IS_3DES(flags)) {
		err = verify_aead_des3_key(tfm, authenc_keys.enckey, authenc_keys.enckeylen);
		if (err)
			return err;
		/*
		 * The crypto engine does not support any two keys
		 * being the same for triple des algorithms. The
		 * verify_skcipher_des3_key does not check for all the
		 * below conditions. Schedule fallback in this case.
		 */
		memcpy(_key, authenc_keys.enckey, DES3_EDE_KEY_SIZE);
		if (!((_key[0] ^ _key[2]) | (_key[1] ^ _key[3])) ||
		    !((_key[2] ^ _key[4]) | (_key[3] ^ _key[5])) ||
		    !((_key[0] ^ _key[4]) | (_key[1] ^ _key[5])))
			ctx->need_fallback = true;
	} else if (IS_AES(flags)) {
		/* No random key sizes */
		if (authenc_keys.enckeylen != AES_KEYSIZE_128 &&
		    authenc_keys.enckeylen != AES_KEYSIZE_192 &&
		    authenc_keys.enckeylen != AES_KEYSIZE_256)
			return -EINVAL;
		if (authenc_keys.enckeylen == AES_KEYSIZE_192)
			ctx->need_fallback = true;
	}

	ctx->enc_keylen = authenc_keys.enckeylen;
	ctx->auth_keylen = authenc_keys.authkeylen;

	memcpy(ctx->enc_key, authenc_keys.enckey, authenc_keys.enckeylen);

	memset(ctx->auth_key, 0, sizeof(ctx->auth_key));
	memcpy(ctx->auth_key, authenc_keys.authkey, authenc_keys.authkeylen);

	return crypto_aead_setkey(ctx->fallback, key, keylen);
}

static int qce_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize)
{
	struct qce_aead_ctx *ctx = crypto_aead_ctx(tfm);
	unsigned long flags = to_aead_tmpl(tfm)->alg_flags;

	if (IS_CCM(flags)) {
		if (authsize < 4 || authsize > 16 || authsize % 2)
			return -EINVAL;
		if (IS_CCM_RFC4309(flags) && (authsize < 8 || authsize % 4))
			return -EINVAL;
	}
	ctx->authsize = authsize;

	return crypto_aead_setauthsize(ctx->fallback, authsize);
}

static int qce_aead_init(struct crypto_aead *tfm)
{
	struct qce_aead_ctx *ctx = crypto_aead_ctx(tfm);

	ctx->need_fallback = false;
	ctx->fallback = crypto_alloc_aead(crypto_tfm_alg_name(&tfm->base),
					  0, CRYPTO_ALG_NEED_FALLBACK);

	if (IS_ERR(ctx->fallback))
		return PTR_ERR(ctx->fallback);

	crypto_aead_set_reqsize(tfm, sizeof(struct qce_aead_reqctx) +
				crypto_aead_reqsize(ctx->fallback));
	return 0;
}

static void qce_aead_exit(struct crypto_aead *tfm)
{
	struct qce_aead_ctx *ctx = crypto_aead_ctx(tfm);

	crypto_free_aead(ctx->fallback);
}

struct qce_aead_def {
	unsigned long flags;
	const char *name;
	const char *drv_name;
	unsigned int blocksize;
	unsigned int chunksize;
	unsigned int ivsize;
	unsigned int maxauthsize;
};

static const struct qce_aead_def aead_def[] = {
	{
		.flags          = QCE_ALG_DES | QCE_MODE_CBC | QCE_HASH_SHA1_HMAC,
		.name           = "authenc(hmac(sha1),cbc(des))",
		.drv_name       = "authenc-hmac-sha1-cbc-des-qce",
		.blocksize      = DES_BLOCK_SIZE,
		.ivsize         = DES_BLOCK_SIZE,
		.maxauthsize	= SHA1_DIGEST_SIZE,
	},
	{
		.flags          = QCE_ALG_3DES | QCE_MODE_CBC | QCE_HASH_SHA1_HMAC,
		.name           = "authenc(hmac(sha1),cbc(des3_ede))",
		.drv_name       = "authenc-hmac-sha1-cbc-3des-qce",
		.blocksize      = DES3_EDE_BLOCK_SIZE,
		.ivsize         = DES3_EDE_BLOCK_SIZE,
		.maxauthsize	= SHA1_DIGEST_SIZE,
	},
	{
		.flags          = QCE_ALG_DES | QCE_MODE_CBC | QCE_HASH_SHA256_HMAC,
		.name           = "authenc(hmac(sha256),cbc(des))",
		.drv_name       = "authenc-hmac-sha256-cbc-des-qce",
		.blocksize      = DES_BLOCK_SIZE,
		.ivsize         = DES_BLOCK_SIZE,
		.maxauthsize	= SHA256_DIGEST_SIZE,
	},
	{
		.flags          = QCE_ALG_3DES | QCE_MODE_CBC | QCE_HASH_SHA256_HMAC,
		.name           = "authenc(hmac(sha256),cbc(des3_ede))",
		.drv_name       = "authenc-hmac-sha256-cbc-3des-qce",
		.blocksize      = DES3_EDE_BLOCK_SIZE,
		.ivsize         = DES3_EDE_BLOCK_SIZE,
		.maxauthsize	= SHA256_DIGEST_SIZE,
	},
	{
		.flags          =  QCE_ALG_AES | QCE_MODE_CBC | QCE_HASH_SHA256_HMAC,
		.name           = "authenc(hmac(sha256),cbc(aes))",
		.drv_name       = "authenc-hmac-sha256-cbc-aes-qce",
		.blocksize      = AES_BLOCK_SIZE,
		.ivsize         = AES_BLOCK_SIZE,
		.maxauthsize	= SHA256_DIGEST_SIZE,
	},
	{
		.flags          =  QCE_ALG_AES | QCE_MODE_CCM,
		.name           = "ccm(aes)",
		.drv_name       = "ccm-aes-qce",
		.blocksize	= 1,
		.ivsize         = AES_BLOCK_SIZE,
		.maxauthsize	= AES_BLOCK_SIZE,
	},
	{
		.flags          =  QCE_ALG_AES | QCE_MODE_CCM | QCE_MODE_CCM_RFC4309,
		.name           = "rfc4309(ccm(aes))",
		.drv_name       = "rfc4309-ccm-aes-qce",
		.blocksize	= 1,
		.ivsize         = 8,
		.maxauthsize	= AES_BLOCK_SIZE,
	},
};

static int qce_aead_register_one(const struct qce_aead_def *def, struct qce_device *qce)
{
	struct qce_alg_template *tmpl;
	struct aead_alg *alg;
	int ret;

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

	alg = &tmpl->alg.aead;

	snprintf(alg->base.cra_name, CRYPTO_MAX_ALG_NAME, "%s", def->name);
	snprintf(alg->base.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
		 def->drv_name);

	alg->base.cra_blocksize		= def->blocksize;
	alg->chunksize			= def->chunksize;
	alg->ivsize			= def->ivsize;
	alg->maxauthsize		= def->maxauthsize;
	if (IS_CCM(def->flags))
		alg->setkey		= qce_aead_ccm_setkey;
	else
		alg->setkey		= qce_aead_setkey;
	alg->setauthsize		= qce_aead_setauthsize;
	alg->encrypt			= qce_aead_encrypt;
	alg->decrypt			= qce_aead_decrypt;
	alg->init			= qce_aead_init;
	alg->exit			= qce_aead_exit;

	alg->base.cra_priority		= 300;
	alg->base.cra_flags		= CRYPTO_ALG_ASYNC |
					  CRYPTO_ALG_ALLOCATES_MEMORY |
					  CRYPTO_ALG_KERN_DRIVER_ONLY |
					  CRYPTO_ALG_NEED_FALLBACK;
	alg->base.cra_ctxsize		= sizeof(struct qce_aead_ctx);
	alg->base.cra_alignmask		= 0;
	alg->base.cra_module		= THIS_MODULE;

	INIT_LIST_HEAD(&tmpl->entry);
	tmpl->crypto_alg_type = CRYPTO_ALG_TYPE_AEAD;
	tmpl->alg_flags = def->flags;
	tmpl->qce = qce;

	ret = crypto_register_aead(alg);
	if (ret) {
		dev_err(qce->dev, "%s registration failed\n", alg->base.cra_name);
		kfree(tmpl);
		return ret;
	}

	list_add_tail(&tmpl->entry, &aead_algs);
	dev_dbg(qce->dev, "%s is registered\n", alg->base.cra_name);
	return 0;
}

static void qce_aead_unregister(struct qce_device *qce)
{
	struct qce_alg_template *tmpl, *n;

	list_for_each_entry_safe(tmpl, n, &aead_algs, entry) {
		crypto_unregister_aead(&tmpl->alg.aead);
		list_del(&tmpl->entry);
		kfree(tmpl);
	}
}

static int qce_aead_register(struct qce_device *qce)
{
	int ret, i;

	for (i = 0; i < ARRAY_SIZE(aead_def); i++) {
		ret = qce_aead_register_one(&aead_def[i], qce);
		if (ret)
			goto err;
	}

	return 0;
err:
	qce_aead_unregister(qce);
	return ret;
}

const struct qce_algo_ops aead_ops = {
	.type = CRYPTO_ALG_TYPE_AEAD,
	.register_algs = qce_aead_register,
	.unregister_algs = qce_aead_unregister,
	.async_req_handle = qce_aead_async_req_handle,
};
