/*
 * seqiv: Sequence Number IV Generator
 *
 * This generator generates an IV based on a sequence number by xoring it
 * with a salt.  This algorithm is mainly useful for CTR and similar modes.
 *
 * Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 */

#include <crypto/internal/aead.h>
#include <crypto/internal/skcipher.h>
#include <crypto/null.h>
#include <crypto/rng.h>
#include <crypto/scatterwalk.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>

struct seqniv_request_ctx {
	struct scatterlist dst[2];
	struct aead_request subreq;
};

struct seqiv_ctx {
	spinlock_t lock;
	u8 salt[] __attribute__ ((aligned(__alignof__(u32))));
};

struct seqiv_aead_ctx {
	struct crypto_aead *child;
	spinlock_t lock;
	struct crypto_blkcipher *null;
	u8 salt[] __attribute__ ((aligned(__alignof__(u32))));
};

static void seqiv_free(struct crypto_instance *inst);

static int seqiv_aead_setkey(struct crypto_aead *tfm,
			     const u8 *key, unsigned int keylen)
{
	struct seqiv_aead_ctx *ctx = crypto_aead_ctx(tfm);

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

static int seqiv_aead_setauthsize(struct crypto_aead *tfm,
				  unsigned int authsize)
{
	struct seqiv_aead_ctx *ctx = crypto_aead_ctx(tfm);

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

static void seqiv_complete2(struct skcipher_givcrypt_request *req, int err)
{
	struct ablkcipher_request *subreq = skcipher_givcrypt_reqctx(req);
	struct crypto_ablkcipher *geniv;

	if (err == -EINPROGRESS)
		return;

	if (err)
		goto out;

	geniv = skcipher_givcrypt_reqtfm(req);
	memcpy(req->creq.info, subreq->info, crypto_ablkcipher_ivsize(geniv));

out:
	kfree(subreq->info);
}

static void seqiv_complete(struct crypto_async_request *base, int err)
{
	struct skcipher_givcrypt_request *req = base->data;

	seqiv_complete2(req, err);
	skcipher_givcrypt_complete(req, err);
}

static void seqiv_aead_complete2(struct aead_givcrypt_request *req, int err)
{
	struct aead_request *subreq = aead_givcrypt_reqctx(req);
	struct crypto_aead *geniv;

	if (err == -EINPROGRESS)
		return;

	if (err)
		goto out;

	geniv = aead_givcrypt_reqtfm(req);
	memcpy(req->areq.iv, subreq->iv, crypto_aead_ivsize(geniv));

out:
	kfree(subreq->iv);
}

static void seqiv_aead_complete(struct crypto_async_request *base, int err)
{
	struct aead_givcrypt_request *req = base->data;

	seqiv_aead_complete2(req, err);
	aead_givcrypt_complete(req, err);
}

static void seqiv_aead_encrypt_complete2(struct aead_request *req, int err)
{
	struct aead_request *subreq = aead_request_ctx(req);
	struct crypto_aead *geniv;

	if (err == -EINPROGRESS)
		return;

	if (err)
		goto out;

	geniv = crypto_aead_reqtfm(req);
	memcpy(req->iv, subreq->iv, crypto_aead_ivsize(geniv));

out:
	kzfree(subreq->iv);
}

static void seqiv_aead_encrypt_complete(struct crypto_async_request *base,
					int err)
{
	struct aead_request *req = base->data;

	seqiv_aead_encrypt_complete2(req, err);
	aead_request_complete(req, err);
}

static void seqniv_aead_encrypt_complete2(struct aead_request *req, int err)
{
	unsigned int ivsize = 8;
	u8 data[20];

	if (err == -EINPROGRESS)
		return;

	/* Swap IV and ESP header back to correct order. */
	scatterwalk_map_and_copy(data, req->dst, 0, req->assoclen + ivsize, 0);
	scatterwalk_map_and_copy(data + ivsize, req->dst, 0, req->assoclen, 1);
	scatterwalk_map_and_copy(data, req->dst, req->assoclen, ivsize, 1);
}

static void seqniv_aead_encrypt_complete(struct crypto_async_request *base,
					int err)
{
	struct aead_request *req = base->data;

	seqniv_aead_encrypt_complete2(req, err);
	aead_request_complete(req, err);
}

static void seqniv_aead_decrypt_complete2(struct aead_request *req, int err)
{
	u8 data[4];

	if (err == -EINPROGRESS)
		return;

	/* Move ESP header back to correct location. */
	scatterwalk_map_and_copy(data, req->dst, 16, req->assoclen - 8, 0);
	scatterwalk_map_and_copy(data, req->dst, 8, req->assoclen - 8, 1);
}

static void seqniv_aead_decrypt_complete(struct crypto_async_request *base,
					 int err)
{
	struct aead_request *req = base->data;

	seqniv_aead_decrypt_complete2(req, err);
	aead_request_complete(req, err);
}

static void seqiv_geniv(struct seqiv_ctx *ctx, u8 *info, u64 seq,
			unsigned int ivsize)
{
	unsigned int len = ivsize;

	if (ivsize > sizeof(u64)) {
		memset(info, 0, ivsize - sizeof(u64));
		len = sizeof(u64);
	}
	seq = cpu_to_be64(seq);
	memcpy(info + ivsize - len, &seq, len);
	crypto_xor(info, ctx->salt, ivsize);
}

static int seqiv_givencrypt(struct skcipher_givcrypt_request *req)
{
	struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
	struct seqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
	struct ablkcipher_request *subreq = skcipher_givcrypt_reqctx(req);
	crypto_completion_t compl;
	void *data;
	u8 *info;
	unsigned int ivsize;
	int err;

	ablkcipher_request_set_tfm(subreq, skcipher_geniv_cipher(geniv));

	compl = req->creq.base.complete;
	data = req->creq.base.data;
	info = req->creq.info;

	ivsize = crypto_ablkcipher_ivsize(geniv);

	if (unlikely(!IS_ALIGNED((unsigned long)info,
				 crypto_ablkcipher_alignmask(geniv) + 1))) {
		info = kmalloc(ivsize, req->creq.base.flags &
				       CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL:
								  GFP_ATOMIC);
		if (!info)
			return -ENOMEM;

		compl = seqiv_complete;
		data = req;
	}

	ablkcipher_request_set_callback(subreq, req->creq.base.flags, compl,
					data);
	ablkcipher_request_set_crypt(subreq, req->creq.src, req->creq.dst,
				     req->creq.nbytes, info);

	seqiv_geniv(ctx, info, req->seq, ivsize);
	memcpy(req->giv, info, ivsize);

	err = crypto_ablkcipher_encrypt(subreq);
	if (unlikely(info != req->creq.info))
		seqiv_complete2(req, err);
	return err;
}

static int seqiv_aead_givencrypt(struct aead_givcrypt_request *req)
{
	struct crypto_aead *geniv = aead_givcrypt_reqtfm(req);
	struct seqiv_ctx *ctx = crypto_aead_ctx(geniv);
	struct aead_request *areq = &req->areq;
	struct aead_request *subreq = aead_givcrypt_reqctx(req);
	crypto_completion_t compl;
	void *data;
	u8 *info;
	unsigned int ivsize;
	int err;

	aead_request_set_tfm(subreq, aead_geniv_base(geniv));

	compl = areq->base.complete;
	data = areq->base.data;
	info = areq->iv;

	ivsize = crypto_aead_ivsize(geniv);

	if (unlikely(!IS_ALIGNED((unsigned long)info,
				 crypto_aead_alignmask(geniv) + 1))) {
		info = kmalloc(ivsize, areq->base.flags &
				       CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL:
								  GFP_ATOMIC);
		if (!info)
			return -ENOMEM;

		compl = seqiv_aead_complete;
		data = req;
	}

	aead_request_set_callback(subreq, areq->base.flags, compl, data);
	aead_request_set_crypt(subreq, areq->src, areq->dst, areq->cryptlen,
			       info);
	aead_request_set_assoc(subreq, areq->assoc, areq->assoclen);

	seqiv_geniv(ctx, info, req->seq, ivsize);
	memcpy(req->giv, info, ivsize);

	err = crypto_aead_encrypt(subreq);
	if (unlikely(info != areq->iv))
		seqiv_aead_complete2(req, err);
	return err;
}

static int seqiv_aead_encrypt_compat(struct aead_request *req)
{
	struct crypto_aead *geniv = crypto_aead_reqtfm(req);
	struct seqiv_aead_ctx *ctx = crypto_aead_ctx(geniv);
	struct seqniv_request_ctx *rctx = aead_request_ctx(req);
	struct aead_request *subreq = &rctx->subreq;
	struct scatterlist *dst;
	crypto_completion_t compl;
	void *data;
	unsigned int ivsize = 8;
	u8 buf[20] __attribute__ ((aligned(__alignof__(u32))));
	int err;

	if (req->cryptlen < ivsize)
		return -EINVAL;

	/* ESP AD is at most 12 bytes (ESN). */
	if (req->assoclen > 12)
		return -EINVAL;

	aead_request_set_tfm(subreq, ctx->child);

	compl = seqniv_aead_encrypt_complete;
	data = req;

	if (req->src != req->dst) {
		struct scatterlist srcbuf[2];
		struct scatterlist dstbuf[2];
		struct blkcipher_desc desc = {
			.tfm = ctx->null,
		};

		err = crypto_blkcipher_encrypt(
			&desc,
			scatterwalk_ffwd(dstbuf, req->dst,
					 req->assoclen + ivsize),
			scatterwalk_ffwd(srcbuf, req->src,
					 req->assoclen + ivsize),
			req->cryptlen - ivsize);
		if (err)
			return err;
	}

	dst = scatterwalk_ffwd(rctx->dst, req->dst, ivsize);

	aead_request_set_callback(subreq, req->base.flags, compl, data);
	aead_request_set_crypt(subreq, dst, dst,
			       req->cryptlen - ivsize, req->iv);
	aead_request_set_ad(subreq, req->assoclen);

	memcpy(buf, req->iv, ivsize);
	crypto_xor(buf, ctx->salt, ivsize);
	memcpy(req->iv, buf, ivsize);

	/* Swap order of IV and ESP AD for ICV generation. */
	scatterwalk_map_and_copy(buf + ivsize, req->dst, 0, req->assoclen, 0);
	scatterwalk_map_and_copy(buf, req->dst, 0, req->assoclen + ivsize, 1);

	err = crypto_aead_encrypt(subreq);
	seqniv_aead_encrypt_complete2(req, err);
	return err;
}

static int seqiv_aead_encrypt(struct aead_request *req)
{
	struct crypto_aead *geniv = crypto_aead_reqtfm(req);
	struct seqiv_aead_ctx *ctx = crypto_aead_ctx(geniv);
	struct aead_request *subreq = aead_request_ctx(req);
	crypto_completion_t compl;
	void *data;
	u8 *info;
	unsigned int ivsize = 8;
	int err;

	if (req->cryptlen < ivsize)
		return -EINVAL;

	aead_request_set_tfm(subreq, ctx->child);

	compl = req->base.complete;
	data = req->base.data;
	info = req->iv;

	if (req->src != req->dst) {
		struct scatterlist src[2];
		struct scatterlist dst[2];
		struct blkcipher_desc desc = {
			.tfm = ctx->null,
		};

		err = crypto_blkcipher_encrypt(
			&desc,
			scatterwalk_ffwd(dst, req->dst,
					 req->assoclen + ivsize),
			scatterwalk_ffwd(src, req->src,
					 req->assoclen + ivsize),
			req->cryptlen - ivsize);
		if (err)
			return err;
	}

	if (unlikely(!IS_ALIGNED((unsigned long)info,
				 crypto_aead_alignmask(geniv) + 1))) {
		info = kmalloc(ivsize, req->base.flags &
				       CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL:
								  GFP_ATOMIC);
		if (!info)
			return -ENOMEM;

		memcpy(info, req->iv, ivsize);
		compl = seqiv_aead_encrypt_complete;
		data = req;
	}

	aead_request_set_callback(subreq, req->base.flags, compl, data);
	aead_request_set_crypt(subreq, req->dst, req->dst,
			       req->cryptlen - ivsize, info);
	aead_request_set_ad(subreq, req->assoclen + ivsize);

	crypto_xor(info, ctx->salt, ivsize);
	scatterwalk_map_and_copy(info, req->dst, req->assoclen, ivsize, 1);

	err = crypto_aead_encrypt(subreq);
	if (unlikely(info != req->iv))
		seqiv_aead_encrypt_complete2(req, err);
	return err;
}

static int seqiv_aead_decrypt_compat(struct aead_request *req)
{
	struct crypto_aead *geniv = crypto_aead_reqtfm(req);
	struct seqiv_aead_ctx *ctx = crypto_aead_ctx(geniv);
	struct seqniv_request_ctx *rctx = aead_request_ctx(req);
	struct aead_request *subreq = &rctx->subreq;
	struct scatterlist *dst;
	crypto_completion_t compl;
	void *data;
	unsigned int ivsize = 8;
	u8 buf[20];
	int err;

	if (req->cryptlen < ivsize + crypto_aead_authsize(geniv))
		return -EINVAL;

	aead_request_set_tfm(subreq, ctx->child);

	compl = req->base.complete;
	data = req->base.data;

	if (req->assoclen > 12)
		return -EINVAL;
	else if (req->assoclen > 8) {
		compl = seqniv_aead_decrypt_complete;
		data = req;
	}

	if (req->src != req->dst) {
		struct scatterlist srcbuf[2];
		struct scatterlist dstbuf[2];
		struct blkcipher_desc desc = {
			.tfm = ctx->null,
		};

		err = crypto_blkcipher_encrypt(
			&desc,
			scatterwalk_ffwd(dstbuf, req->dst,
					 req->assoclen + ivsize),
			scatterwalk_ffwd(srcbuf, req->src,
					 req->assoclen + ivsize),
			req->cryptlen - ivsize);
		if (err)
			return err;
	}

	/* Move ESP AD forward for ICV generation. */
	scatterwalk_map_and_copy(buf, req->dst, 0, req->assoclen + ivsize, 0);
	memcpy(req->iv, buf + req->assoclen, ivsize);
	scatterwalk_map_and_copy(buf, req->dst, ivsize, req->assoclen, 1);

	dst = scatterwalk_ffwd(rctx->dst, req->dst, ivsize);

	aead_request_set_callback(subreq, req->base.flags, compl, data);
	aead_request_set_crypt(subreq, dst, dst,
			       req->cryptlen - ivsize, req->iv);
	aead_request_set_ad(subreq, req->assoclen);

	err = crypto_aead_decrypt(subreq);
	if (req->assoclen > 8)
		seqniv_aead_decrypt_complete2(req, err);
	return err;
}

static int seqiv_aead_decrypt(struct aead_request *req)
{
	struct crypto_aead *geniv = crypto_aead_reqtfm(req);
	struct seqiv_aead_ctx *ctx = crypto_aead_ctx(geniv);
	struct aead_request *subreq = aead_request_ctx(req);
	crypto_completion_t compl;
	void *data;
	unsigned int ivsize = 8;

	if (req->cryptlen < ivsize + crypto_aead_authsize(geniv))
		return -EINVAL;

	aead_request_set_tfm(subreq, ctx->child);

	compl = req->base.complete;
	data = req->base.data;

	aead_request_set_callback(subreq, req->base.flags, compl, data);
	aead_request_set_crypt(subreq, req->src, req->dst,
			       req->cryptlen - ivsize, req->iv);
	aead_request_set_ad(subreq, req->assoclen + ivsize);

	scatterwalk_map_and_copy(req->iv, req->src, req->assoclen, ivsize, 0);
	if (req->src != req->dst)
		scatterwalk_map_and_copy(req->iv, req->dst,
					 req->assoclen, ivsize, 1);

	return crypto_aead_decrypt(subreq);
}

static int seqiv_givencrypt_first(struct skcipher_givcrypt_request *req)
{
	struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
	struct seqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
	int err = 0;

	spin_lock_bh(&ctx->lock);
	if (crypto_ablkcipher_crt(geniv)->givencrypt != seqiv_givencrypt_first)
		goto unlock;

	crypto_ablkcipher_crt(geniv)->givencrypt = seqiv_givencrypt;
	err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
				   crypto_ablkcipher_ivsize(geniv));

unlock:
	spin_unlock_bh(&ctx->lock);

	if (err)
		return err;

	return seqiv_givencrypt(req);
}

static int seqiv_aead_givencrypt_first(struct aead_givcrypt_request *req)
{
	struct crypto_aead *geniv = aead_givcrypt_reqtfm(req);
	struct seqiv_ctx *ctx = crypto_aead_ctx(geniv);
	int err = 0;

	spin_lock_bh(&ctx->lock);
	if (crypto_aead_crt(geniv)->givencrypt != seqiv_aead_givencrypt_first)
		goto unlock;

	crypto_aead_crt(geniv)->givencrypt = seqiv_aead_givencrypt;
	err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
				   crypto_aead_ivsize(geniv));

unlock:
	spin_unlock_bh(&ctx->lock);

	if (err)
		return err;

	return seqiv_aead_givencrypt(req);
}

static int seqiv_aead_encrypt_compat_first(struct aead_request *req)
{
	struct crypto_aead *geniv = crypto_aead_reqtfm(req);
	struct seqiv_aead_ctx *ctx = crypto_aead_ctx(geniv);
	int err = 0;

	spin_lock_bh(&ctx->lock);
	if (geniv->encrypt != seqiv_aead_encrypt_compat_first)
		goto unlock;

	geniv->encrypt = seqiv_aead_encrypt_compat;
	err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
				   crypto_aead_ivsize(geniv));

unlock:
	spin_unlock_bh(&ctx->lock);

	if (err)
		return err;

	return seqiv_aead_encrypt_compat(req);
}

static int seqiv_aead_encrypt_first(struct aead_request *req)
{
	struct crypto_aead *geniv = crypto_aead_reqtfm(req);
	struct seqiv_aead_ctx *ctx = crypto_aead_ctx(geniv);
	int err = 0;

	spin_lock_bh(&ctx->lock);
	if (geniv->encrypt != seqiv_aead_encrypt_first)
		goto unlock;

	geniv->encrypt = seqiv_aead_encrypt;
	err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
				   crypto_aead_ivsize(geniv));

unlock:
	spin_unlock_bh(&ctx->lock);

	if (err)
		return err;

	return seqiv_aead_encrypt(req);
}

static int seqiv_init(struct crypto_tfm *tfm)
{
	struct crypto_ablkcipher *geniv = __crypto_ablkcipher_cast(tfm);
	struct seqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);

	spin_lock_init(&ctx->lock);

	tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request);

	return skcipher_geniv_init(tfm);
}

static int seqiv_old_aead_init(struct crypto_tfm *tfm)
{
	struct crypto_aead *geniv = __crypto_aead_cast(tfm);
	struct seqiv_ctx *ctx = crypto_aead_ctx(geniv);

	spin_lock_init(&ctx->lock);

	crypto_aead_set_reqsize(__crypto_aead_cast(tfm),
				sizeof(struct aead_request));

	return aead_geniv_init(tfm);
}

static int seqiv_aead_init_common(struct crypto_tfm *tfm, unsigned int reqsize)
{
	struct crypto_aead *geniv = __crypto_aead_cast(tfm);
	struct seqiv_aead_ctx *ctx = crypto_aead_ctx(geniv);
	int err;

	spin_lock_init(&ctx->lock);

	crypto_aead_set_reqsize(geniv, sizeof(struct aead_request));

	ctx->null = crypto_get_default_null_skcipher();
	err = PTR_ERR(ctx->null);
	if (IS_ERR(ctx->null))
		goto out;

	err = aead_geniv_init(tfm);
	if (err)
		goto drop_null;

	ctx->child = geniv->child;
	geniv->child = geniv;

out:
	return err;

drop_null:
	crypto_put_default_null_skcipher();
	goto out;
}

static int seqiv_aead_init(struct crypto_tfm *tfm)
{
	return seqiv_aead_init_common(tfm, sizeof(struct aead_request));
}

static int seqniv_aead_init(struct crypto_tfm *tfm)
{
	return seqiv_aead_init_common(tfm, sizeof(struct seqniv_request_ctx));
}

static void seqiv_aead_exit(struct crypto_tfm *tfm)
{
	struct seqiv_aead_ctx *ctx = crypto_tfm_ctx(tfm);

	crypto_free_aead(ctx->child);
	crypto_put_default_null_skcipher();
}

static int seqiv_ablkcipher_create(struct crypto_template *tmpl,
				   struct rtattr **tb)
{
	struct crypto_instance *inst;
	int err;

	inst = skcipher_geniv_alloc(tmpl, tb, 0, 0);

	if (IS_ERR(inst))
		return PTR_ERR(inst);

	err = -EINVAL;
	if (inst->alg.cra_ablkcipher.ivsize < sizeof(u64))
		goto free_inst;

	inst->alg.cra_ablkcipher.givencrypt = seqiv_givencrypt_first;

	inst->alg.cra_init = seqiv_init;
	inst->alg.cra_exit = skcipher_geniv_exit;

	inst->alg.cra_ctxsize += inst->alg.cra_ablkcipher.ivsize;
	inst->alg.cra_ctxsize += sizeof(struct seqiv_ctx);

	inst->alg.cra_alignmask |= __alignof__(u32) - 1;

	err = crypto_register_instance(tmpl, inst);
	if (err)
		goto free_inst;

out:
	return err;

free_inst:
	skcipher_geniv_free(inst);
	goto out;
}

static int seqiv_old_aead_create(struct crypto_template *tmpl,
				 struct aead_instance *aead)
{
	struct crypto_instance *inst = aead_crypto_instance(aead);
	int err = -EINVAL;

	if (inst->alg.cra_aead.ivsize < sizeof(u64))
		goto free_inst;

	inst->alg.cra_aead.givencrypt = seqiv_aead_givencrypt_first;

	inst->alg.cra_init = seqiv_old_aead_init;
	inst->alg.cra_exit = aead_geniv_exit;

	inst->alg.cra_ctxsize = inst->alg.cra_aead.ivsize;
	inst->alg.cra_ctxsize += sizeof(struct seqiv_ctx);

	err = crypto_register_instance(tmpl, inst);
	if (err)
		goto free_inst;

out:
	return err;

free_inst:
	aead_geniv_free(aead);
	goto out;
}

static int seqiv_aead_create(struct crypto_template *tmpl, struct rtattr **tb)
{
	struct aead_instance *inst;
	struct crypto_aead_spawn *spawn;
	struct aead_alg *alg;
	int err;

	inst = aead_geniv_alloc(tmpl, tb, 0, 0);

	if (IS_ERR(inst))
		return PTR_ERR(inst);

	inst->alg.base.cra_alignmask |= __alignof__(u32) - 1;

	if (inst->alg.base.cra_aead.encrypt)
		return seqiv_old_aead_create(tmpl, inst);

	err = -EINVAL;
	if (inst->alg.ivsize != sizeof(u64))
		goto free_inst;

	spawn = aead_instance_ctx(inst);
	alg = crypto_spawn_aead_alg(spawn);

	inst->alg.setkey = seqiv_aead_setkey;
	inst->alg.setauthsize = seqiv_aead_setauthsize;
	inst->alg.encrypt = seqiv_aead_encrypt_first;
	inst->alg.decrypt = seqiv_aead_decrypt;

	inst->alg.base.cra_init = seqiv_aead_init;
	inst->alg.base.cra_exit = seqiv_aead_exit;

	inst->alg.base.cra_ctxsize = sizeof(struct seqiv_aead_ctx);
	inst->alg.base.cra_ctxsize += inst->alg.base.cra_aead.ivsize;

	if (alg->base.cra_aead.encrypt) {
		inst->alg.encrypt = seqiv_aead_encrypt_compat_first;
		inst->alg.decrypt = seqiv_aead_decrypt_compat;

		inst->alg.base.cra_init = seqniv_aead_init;
		inst->alg.base.cra_exit = seqiv_aead_exit;
	}

	err = aead_register_instance(tmpl, inst);
	if (err)
		goto free_inst;

out:
	return err;

free_inst:
	aead_geniv_free(inst);
	goto out;
}

static int seqiv_create(struct crypto_template *tmpl, struct rtattr **tb)
{
	struct crypto_attr_type *algt;
	int err;

	algt = crypto_get_attr_type(tb);
	if (IS_ERR(algt))
		return PTR_ERR(algt);

	err = crypto_get_default_rng();
	if (err)
		return err;

	if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK)
		err = seqiv_ablkcipher_create(tmpl, tb);
	else
		err = seqiv_aead_create(tmpl, tb);

	if (err)
		crypto_put_default_rng();

	return err;
}

static int seqniv_create(struct crypto_template *tmpl, struct rtattr **tb)
{
	struct aead_instance *inst;
	struct crypto_aead_spawn *spawn;
	struct aead_alg *alg;
	int err;

	err = crypto_get_default_rng();
	if (err)
		return err;

	inst = aead_geniv_alloc(tmpl, tb, 0, 0);
	err = PTR_ERR(inst);
	if (IS_ERR(inst))
		goto put_rng;

	err = -EINVAL;
	if (inst->alg.ivsize != sizeof(u64))
		goto free_inst;

	spawn = aead_instance_ctx(inst);
	alg = crypto_spawn_aead_alg(spawn);

	inst->alg.setkey = seqiv_aead_setkey;
	inst->alg.setauthsize = seqiv_aead_setauthsize;
	inst->alg.encrypt = seqiv_aead_encrypt_compat_first;
	inst->alg.decrypt = seqiv_aead_decrypt_compat;

	inst->alg.base.cra_init = seqniv_aead_init;
	inst->alg.base.cra_exit = seqiv_aead_exit;

	inst->alg.base.cra_alignmask |= __alignof__(u32) - 1;
	inst->alg.base.cra_ctxsize = sizeof(struct seqiv_aead_ctx);
	inst->alg.base.cra_ctxsize += inst->alg.base.cra_aead.ivsize;

	err = aead_register_instance(tmpl, inst);
	if (err)
		goto free_inst;

out:
	return err;

free_inst:
	aead_geniv_free(inst);
put_rng:
	crypto_put_default_rng();
	goto out;
}

static void seqiv_free(struct crypto_instance *inst)
{
	if ((inst->alg.cra_flags ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK)
		skcipher_geniv_free(inst);
	else
		aead_geniv_free(aead_instance(inst));
	crypto_put_default_rng();
}

static struct crypto_template seqiv_tmpl = {
	.name = "seqiv",
	.create = seqiv_create,
	.free = seqiv_free,
	.module = THIS_MODULE,
};

static struct crypto_template seqniv_tmpl = {
	.name = "seqniv",
	.create = seqniv_create,
	.free = seqiv_free,
	.module = THIS_MODULE,
};

static int __init seqiv_module_init(void)
{
	int err;

	err = crypto_register_template(&seqiv_tmpl);
	if (err)
		goto out;

	err = crypto_register_template(&seqniv_tmpl);
	if (err)
		goto out_undo_niv;

out:
	return err;

out_undo_niv:
	crypto_unregister_template(&seqiv_tmpl);
	goto out;
}

static void __exit seqiv_module_exit(void)
{
	crypto_unregister_template(&seqiv_tmpl);
}

module_init(seqiv_module_init);
module_exit(seqiv_module_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Sequence Number IV Generator");
MODULE_ALIAS_CRYPTO("seqiv");
MODULE_ALIAS_CRYPTO("seqniv");
