// 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_dma(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_dma(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_dma(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_dma(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_dma(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_dma(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_dma(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_dma(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_dma(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_dma(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,
};
