xref: /linux/crypto/seqiv.c (revision 84a73014d86fd660822a20c032625e3afe99ca58)
10a270321SHerbert Xu /*
20a270321SHerbert Xu  * seqiv: Sequence Number IV Generator
30a270321SHerbert Xu  *
40a270321SHerbert Xu  * This generator generates an IV based on a sequence number by xoring it
50a270321SHerbert Xu  * with a salt.  This algorithm is mainly useful for CTR and similar modes.
60a270321SHerbert Xu  *
70a270321SHerbert Xu  * Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au>
80a270321SHerbert Xu  *
90a270321SHerbert Xu  * This program is free software; you can redistribute it and/or modify it
100a270321SHerbert Xu  * under the terms of the GNU General Public License as published by the Free
110a270321SHerbert Xu  * Software Foundation; either version 2 of the License, or (at your option)
120a270321SHerbert Xu  * any later version.
130a270321SHerbert Xu  *
140a270321SHerbert Xu  */
150a270321SHerbert Xu 
16661cfd0eSHerbert Xu #include <crypto/internal/geniv.h>
170a270321SHerbert Xu #include <crypto/internal/skcipher.h>
18a0f000ecSHerbert Xu #include <crypto/rng.h>
19856e3f40SHerbert Xu #include <crypto/scatterwalk.h>
200a270321SHerbert Xu #include <linux/err.h>
210a270321SHerbert Xu #include <linux/init.h>
220a270321SHerbert Xu #include <linux/kernel.h>
230a270321SHerbert Xu #include <linux/module.h>
245a0e3ad6STejun Heo #include <linux/slab.h>
250a270321SHerbert Xu #include <linux/spinlock.h>
260a270321SHerbert Xu #include <linux/string.h>
270a270321SHerbert Xu 
280a270321SHerbert Xu struct seqiv_ctx {
290a270321SHerbert Xu 	spinlock_t lock;
300a270321SHerbert Xu 	u8 salt[] __attribute__ ((aligned(__alignof__(u32))));
310a270321SHerbert Xu };
320a270321SHerbert Xu 
330677157bSHerbert Xu static void seqiv_free(struct crypto_instance *inst);
340677157bSHerbert Xu 
350a270321SHerbert Xu static void seqiv_complete2(struct skcipher_givcrypt_request *req, int err)
360a270321SHerbert Xu {
370a270321SHerbert Xu 	struct ablkcipher_request *subreq = skcipher_givcrypt_reqctx(req);
380a270321SHerbert Xu 	struct crypto_ablkcipher *geniv;
390a270321SHerbert Xu 
400a270321SHerbert Xu 	if (err == -EINPROGRESS)
410a270321SHerbert Xu 		return;
420a270321SHerbert Xu 
430a270321SHerbert Xu 	if (err)
440a270321SHerbert Xu 		goto out;
450a270321SHerbert Xu 
460a270321SHerbert Xu 	geniv = skcipher_givcrypt_reqtfm(req);
470a270321SHerbert Xu 	memcpy(req->creq.info, subreq->info, crypto_ablkcipher_ivsize(geniv));
480a270321SHerbert Xu 
490a270321SHerbert Xu out:
500a270321SHerbert Xu 	kfree(subreq->info);
510a270321SHerbert Xu }
520a270321SHerbert Xu 
530a270321SHerbert Xu static void seqiv_complete(struct crypto_async_request *base, int err)
540a270321SHerbert Xu {
550a270321SHerbert Xu 	struct skcipher_givcrypt_request *req = base->data;
560a270321SHerbert Xu 
570a270321SHerbert Xu 	seqiv_complete2(req, err);
580a270321SHerbert Xu 	skcipher_givcrypt_complete(req, err);
590a270321SHerbert Xu }
600a270321SHerbert Xu 
61856e3f40SHerbert Xu static void seqiv_aead_encrypt_complete2(struct aead_request *req, int err)
62856e3f40SHerbert Xu {
63856e3f40SHerbert Xu 	struct aead_request *subreq = aead_request_ctx(req);
64856e3f40SHerbert Xu 	struct crypto_aead *geniv;
65856e3f40SHerbert Xu 
66856e3f40SHerbert Xu 	if (err == -EINPROGRESS)
67856e3f40SHerbert Xu 		return;
68856e3f40SHerbert Xu 
69856e3f40SHerbert Xu 	if (err)
70856e3f40SHerbert Xu 		goto out;
71856e3f40SHerbert Xu 
72856e3f40SHerbert Xu 	geniv = crypto_aead_reqtfm(req);
73856e3f40SHerbert Xu 	memcpy(req->iv, subreq->iv, crypto_aead_ivsize(geniv));
74856e3f40SHerbert Xu 
75856e3f40SHerbert Xu out:
76856e3f40SHerbert Xu 	kzfree(subreq->iv);
77856e3f40SHerbert Xu }
78856e3f40SHerbert Xu 
79856e3f40SHerbert Xu static void seqiv_aead_encrypt_complete(struct crypto_async_request *base,
80856e3f40SHerbert Xu 					int err)
81856e3f40SHerbert Xu {
82856e3f40SHerbert Xu 	struct aead_request *req = base->data;
83856e3f40SHerbert Xu 
84856e3f40SHerbert Xu 	seqiv_aead_encrypt_complete2(req, err);
85856e3f40SHerbert Xu 	aead_request_complete(req, err);
86856e3f40SHerbert Xu }
87856e3f40SHerbert Xu 
8814df4d80SHerbert Xu static void seqiv_geniv(struct seqiv_ctx *ctx, u8 *info, u64 seq,
8914df4d80SHerbert Xu 			unsigned int ivsize)
9014df4d80SHerbert Xu {
9114df4d80SHerbert Xu 	unsigned int len = ivsize;
9214df4d80SHerbert Xu 
9314df4d80SHerbert Xu 	if (ivsize > sizeof(u64)) {
9414df4d80SHerbert Xu 		memset(info, 0, ivsize - sizeof(u64));
9514df4d80SHerbert Xu 		len = sizeof(u64);
9614df4d80SHerbert Xu 	}
9714df4d80SHerbert Xu 	seq = cpu_to_be64(seq);
9814df4d80SHerbert Xu 	memcpy(info + ivsize - len, &seq, len);
9914df4d80SHerbert Xu 	crypto_xor(info, ctx->salt, ivsize);
10014df4d80SHerbert Xu }
10114df4d80SHerbert Xu 
1020a270321SHerbert Xu static int seqiv_givencrypt(struct skcipher_givcrypt_request *req)
1030a270321SHerbert Xu {
1040a270321SHerbert Xu 	struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
1050a270321SHerbert Xu 	struct seqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
1060a270321SHerbert Xu 	struct ablkcipher_request *subreq = skcipher_givcrypt_reqctx(req);
1073e3dc25fSMark Rustad 	crypto_completion_t compl;
1080a270321SHerbert Xu 	void *data;
1090a270321SHerbert Xu 	u8 *info;
1100a270321SHerbert Xu 	unsigned int ivsize;
1110a270321SHerbert Xu 	int err;
1120a270321SHerbert Xu 
1130a270321SHerbert Xu 	ablkcipher_request_set_tfm(subreq, skcipher_geniv_cipher(geniv));
1140a270321SHerbert Xu 
1153e3dc25fSMark Rustad 	compl = req->creq.base.complete;
1160a270321SHerbert Xu 	data = req->creq.base.data;
1170a270321SHerbert Xu 	info = req->creq.info;
1180a270321SHerbert Xu 
1190a270321SHerbert Xu 	ivsize = crypto_ablkcipher_ivsize(geniv);
1200a270321SHerbert Xu 
1210a270321SHerbert Xu 	if (unlikely(!IS_ALIGNED((unsigned long)info,
1220a270321SHerbert Xu 				 crypto_ablkcipher_alignmask(geniv) + 1))) {
1230a270321SHerbert Xu 		info = kmalloc(ivsize, req->creq.base.flags &
1240a270321SHerbert Xu 				       CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL:
1250a270321SHerbert Xu 								  GFP_ATOMIC);
1260a270321SHerbert Xu 		if (!info)
1270a270321SHerbert Xu 			return -ENOMEM;
1280a270321SHerbert Xu 
1293e3dc25fSMark Rustad 		compl = seqiv_complete;
1300a270321SHerbert Xu 		data = req;
1310a270321SHerbert Xu 	}
1320a270321SHerbert Xu 
1333e3dc25fSMark Rustad 	ablkcipher_request_set_callback(subreq, req->creq.base.flags, compl,
1340a270321SHerbert Xu 					data);
1350a270321SHerbert Xu 	ablkcipher_request_set_crypt(subreq, req->creq.src, req->creq.dst,
1360a270321SHerbert Xu 				     req->creq.nbytes, info);
1370a270321SHerbert Xu 
13814df4d80SHerbert Xu 	seqiv_geniv(ctx, info, req->seq, ivsize);
1390a270321SHerbert Xu 	memcpy(req->giv, info, ivsize);
1400a270321SHerbert Xu 
1410a270321SHerbert Xu 	err = crypto_ablkcipher_encrypt(subreq);
1420a270321SHerbert Xu 	if (unlikely(info != req->creq.info))
1430a270321SHerbert Xu 		seqiv_complete2(req, err);
1440a270321SHerbert Xu 	return err;
1450a270321SHerbert Xu }
1460a270321SHerbert Xu 
147856e3f40SHerbert Xu static int seqiv_aead_encrypt(struct aead_request *req)
148856e3f40SHerbert Xu {
149856e3f40SHerbert Xu 	struct crypto_aead *geniv = crypto_aead_reqtfm(req);
150659e7f52SHerbert Xu 	struct aead_geniv_ctx *ctx = crypto_aead_ctx(geniv);
151856e3f40SHerbert Xu 	struct aead_request *subreq = aead_request_ctx(req);
152856e3f40SHerbert Xu 	crypto_completion_t compl;
153856e3f40SHerbert Xu 	void *data;
154856e3f40SHerbert Xu 	u8 *info;
155dd04446eSHerbert Xu 	unsigned int ivsize = 8;
156856e3f40SHerbert Xu 	int err;
157856e3f40SHerbert Xu 
158dd04446eSHerbert Xu 	if (req->cryptlen < ivsize)
159dd04446eSHerbert Xu 		return -EINVAL;
160dd04446eSHerbert Xu 
161659e7f52SHerbert Xu 	aead_request_set_tfm(subreq, ctx->child);
162856e3f40SHerbert Xu 
163856e3f40SHerbert Xu 	compl = req->base.complete;
164856e3f40SHerbert Xu 	data = req->base.data;
165856e3f40SHerbert Xu 	info = req->iv;
166856e3f40SHerbert Xu 
167856e3f40SHerbert Xu 	if (req->src != req->dst) {
168856e3f40SHerbert Xu 		struct blkcipher_desc desc = {
169856e3f40SHerbert Xu 			.tfm = ctx->null,
170856e3f40SHerbert Xu 		};
171856e3f40SHerbert Xu 
172d0ad1b24SHerbert Xu 		err = crypto_blkcipher_encrypt(&desc, req->dst, req->src,
173d0ad1b24SHerbert Xu 					       req->assoclen + req->cryptlen);
174856e3f40SHerbert Xu 		if (err)
175856e3f40SHerbert Xu 			return err;
176856e3f40SHerbert Xu 	}
177856e3f40SHerbert Xu 
178856e3f40SHerbert Xu 	if (unlikely(!IS_ALIGNED((unsigned long)info,
179856e3f40SHerbert Xu 				 crypto_aead_alignmask(geniv) + 1))) {
180856e3f40SHerbert Xu 		info = kmalloc(ivsize, req->base.flags &
181856e3f40SHerbert Xu 				       CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL:
182856e3f40SHerbert Xu 								  GFP_ATOMIC);
183856e3f40SHerbert Xu 		if (!info)
184856e3f40SHerbert Xu 			return -ENOMEM;
185856e3f40SHerbert Xu 
186856e3f40SHerbert Xu 		memcpy(info, req->iv, ivsize);
187856e3f40SHerbert Xu 		compl = seqiv_aead_encrypt_complete;
188856e3f40SHerbert Xu 		data = req;
189856e3f40SHerbert Xu 	}
190856e3f40SHerbert Xu 
191856e3f40SHerbert Xu 	aead_request_set_callback(subreq, req->base.flags, compl, data);
192856e3f40SHerbert Xu 	aead_request_set_crypt(subreq, req->dst, req->dst,
193856e3f40SHerbert Xu 			       req->cryptlen - ivsize, info);
194374d4ad1SHerbert Xu 	aead_request_set_ad(subreq, req->assoclen + ivsize);
195856e3f40SHerbert Xu 
196856e3f40SHerbert Xu 	crypto_xor(info, ctx->salt, ivsize);
197856e3f40SHerbert Xu 	scatterwalk_map_and_copy(info, req->dst, req->assoclen, ivsize, 1);
198856e3f40SHerbert Xu 
199856e3f40SHerbert Xu 	err = crypto_aead_encrypt(subreq);
200856e3f40SHerbert Xu 	if (unlikely(info != req->iv))
201856e3f40SHerbert Xu 		seqiv_aead_encrypt_complete2(req, err);
202856e3f40SHerbert Xu 	return err;
203856e3f40SHerbert Xu }
204856e3f40SHerbert Xu 
205856e3f40SHerbert Xu static int seqiv_aead_decrypt(struct aead_request *req)
206856e3f40SHerbert Xu {
207856e3f40SHerbert Xu 	struct crypto_aead *geniv = crypto_aead_reqtfm(req);
208659e7f52SHerbert Xu 	struct aead_geniv_ctx *ctx = crypto_aead_ctx(geniv);
209856e3f40SHerbert Xu 	struct aead_request *subreq = aead_request_ctx(req);
210856e3f40SHerbert Xu 	crypto_completion_t compl;
211856e3f40SHerbert Xu 	void *data;
212dd04446eSHerbert Xu 	unsigned int ivsize = 8;
213dd04446eSHerbert Xu 
214dd04446eSHerbert Xu 	if (req->cryptlen < ivsize + crypto_aead_authsize(geniv))
215dd04446eSHerbert Xu 		return -EINVAL;
216856e3f40SHerbert Xu 
217659e7f52SHerbert Xu 	aead_request_set_tfm(subreq, ctx->child);
218856e3f40SHerbert Xu 
219856e3f40SHerbert Xu 	compl = req->base.complete;
220856e3f40SHerbert Xu 	data = req->base.data;
221856e3f40SHerbert Xu 
222856e3f40SHerbert Xu 	aead_request_set_callback(subreq, req->base.flags, compl, data);
223856e3f40SHerbert Xu 	aead_request_set_crypt(subreq, req->src, req->dst,
224856e3f40SHerbert Xu 			       req->cryptlen - ivsize, req->iv);
225374d4ad1SHerbert Xu 	aead_request_set_ad(subreq, req->assoclen + ivsize);
226856e3f40SHerbert Xu 
227856e3f40SHerbert Xu 	scatterwalk_map_and_copy(req->iv, req->src, req->assoclen, ivsize, 0);
228856e3f40SHerbert Xu 
229856e3f40SHerbert Xu 	return crypto_aead_decrypt(subreq);
230856e3f40SHerbert Xu }
231856e3f40SHerbert Xu 
2320a270321SHerbert Xu static int seqiv_init(struct crypto_tfm *tfm)
2330a270321SHerbert Xu {
2340a270321SHerbert Xu 	struct crypto_ablkcipher *geniv = __crypto_ablkcipher_cast(tfm);
2350a270321SHerbert Xu 	struct seqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv);
236eeee12aaSHerbert Xu 	int err;
2370a270321SHerbert Xu 
2380a270321SHerbert Xu 	spin_lock_init(&ctx->lock);
2390a270321SHerbert Xu 
2400a270321SHerbert Xu 	tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request);
2410a270321SHerbert Xu 
242eeee12aaSHerbert Xu 	err = 0;
243eeee12aaSHerbert Xu 	if (!crypto_get_default_rng()) {
244eeee12aaSHerbert Xu 		crypto_ablkcipher_crt(geniv)->givencrypt = seqiv_givencrypt;
245eeee12aaSHerbert Xu 		err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
246eeee12aaSHerbert Xu 					   crypto_ablkcipher_ivsize(geniv));
247eeee12aaSHerbert Xu 		crypto_put_default_rng();
248eeee12aaSHerbert Xu 	}
249eeee12aaSHerbert Xu 
250eeee12aaSHerbert Xu 	return err ?: skcipher_geniv_init(tfm);
2510a270321SHerbert Xu }
2520a270321SHerbert Xu 
2530677157bSHerbert Xu static int seqiv_ablkcipher_create(struct crypto_template *tmpl,
2540677157bSHerbert Xu 				   struct rtattr **tb)
2550a270321SHerbert Xu {
2560a270321SHerbert Xu 	struct crypto_instance *inst;
2570677157bSHerbert Xu 	int err;
2580a270321SHerbert Xu 
2590677157bSHerbert Xu 	inst = skcipher_geniv_alloc(tmpl, tb, 0, 0);
26014df4d80SHerbert Xu 
2610a270321SHerbert Xu 	if (IS_ERR(inst))
2620677157bSHerbert Xu 		return PTR_ERR(inst);
2630a270321SHerbert Xu 
2640677157bSHerbert Xu 	err = -EINVAL;
2650677157bSHerbert Xu 	if (inst->alg.cra_ablkcipher.ivsize < sizeof(u64))
2660677157bSHerbert Xu 		goto free_inst;
267c0ecf891SHerbert Xu 
2680a270321SHerbert Xu 	inst->alg.cra_init = seqiv_init;
2690a270321SHerbert Xu 	inst->alg.cra_exit = skcipher_geniv_exit;
2700a270321SHerbert Xu 
2710a270321SHerbert Xu 	inst->alg.cra_ctxsize += inst->alg.cra_ablkcipher.ivsize;
272856e3f40SHerbert Xu 	inst->alg.cra_ctxsize += sizeof(struct seqiv_ctx);
2730a270321SHerbert Xu 
2740677157bSHerbert Xu 	inst->alg.cra_alignmask |= __alignof__(u32) - 1;
2750677157bSHerbert Xu 
2760677157bSHerbert Xu 	err = crypto_register_instance(tmpl, inst);
2770677157bSHerbert Xu 	if (err)
2780677157bSHerbert Xu 		goto free_inst;
2790677157bSHerbert Xu 
2800a270321SHerbert Xu out:
2810677157bSHerbert Xu 	return err;
2820677157bSHerbert Xu 
2830677157bSHerbert Xu free_inst:
2840677157bSHerbert Xu 	skcipher_geniv_free(inst);
2850677157bSHerbert Xu 	goto out;
2860a270321SHerbert Xu }
2870a270321SHerbert Xu 
2880677157bSHerbert Xu static int seqiv_aead_create(struct crypto_template *tmpl, struct rtattr **tb)
28914df4d80SHerbert Xu {
290856e3f40SHerbert Xu 	struct aead_instance *inst;
291856e3f40SHerbert Xu 	struct crypto_aead_spawn *spawn;
292856e3f40SHerbert Xu 	struct aead_alg *alg;
2930677157bSHerbert Xu 	int err;
29414df4d80SHerbert Xu 
2950677157bSHerbert Xu 	inst = aead_geniv_alloc(tmpl, tb, 0, 0);
29614df4d80SHerbert Xu 
29714df4d80SHerbert Xu 	if (IS_ERR(inst))
2980677157bSHerbert Xu 		return PTR_ERR(inst);
2990677157bSHerbert Xu 
3000677157bSHerbert Xu 	inst->alg.base.cra_alignmask |= __alignof__(u32) - 1;
30114df4d80SHerbert Xu 
302661cfd0eSHerbert Xu 	spawn = aead_instance_ctx(inst);
303661cfd0eSHerbert Xu 	alg = crypto_spawn_aead_alg(spawn);
304661cfd0eSHerbert Xu 
3050677157bSHerbert Xu 	err = -EINVAL;
306dd04446eSHerbert Xu 	if (inst->alg.ivsize != sizeof(u64))
3070677157bSHerbert Xu 		goto free_inst;
308c0ecf891SHerbert Xu 
309b7dcfab4SHerbert Xu 	inst->alg.encrypt = seqiv_aead_encrypt;
310856e3f40SHerbert Xu 	inst->alg.decrypt = seqiv_aead_decrypt;
31114df4d80SHerbert Xu 
312659e7f52SHerbert Xu 	inst->alg.init = aead_init_geniv;
313659e7f52SHerbert Xu 	inst->alg.exit = aead_exit_geniv;
314856e3f40SHerbert Xu 
315659e7f52SHerbert Xu 	inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx);
3165964f26cSHerbert Xu 	inst->alg.base.cra_ctxsize += inst->alg.ivsize;
317856e3f40SHerbert Xu 
3180677157bSHerbert Xu 	err = aead_register_instance(tmpl, inst);
3190677157bSHerbert Xu 	if (err)
3200677157bSHerbert Xu 		goto free_inst;
3210677157bSHerbert Xu 
32214df4d80SHerbert Xu out:
3230677157bSHerbert Xu 	return err;
3240677157bSHerbert Xu 
3250677157bSHerbert Xu free_inst:
3260677157bSHerbert Xu 	aead_geniv_free(inst);
3270677157bSHerbert Xu 	goto out;
32814df4d80SHerbert Xu }
32914df4d80SHerbert Xu 
3300677157bSHerbert Xu static int seqiv_create(struct crypto_template *tmpl, struct rtattr **tb)
33114df4d80SHerbert Xu {
33214df4d80SHerbert Xu 	struct crypto_attr_type *algt;
33314df4d80SHerbert Xu 	int err;
33414df4d80SHerbert Xu 
33514df4d80SHerbert Xu 	algt = crypto_get_attr_type(tb);
33614df4d80SHerbert Xu 	if (IS_ERR(algt))
3370677157bSHerbert Xu 		return PTR_ERR(algt);
33814df4d80SHerbert Xu 
33914df4d80SHerbert Xu 	if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK)
3400677157bSHerbert Xu 		err = seqiv_ablkcipher_create(tmpl, tb);
34114df4d80SHerbert Xu 	else
3420677157bSHerbert Xu 		err = seqiv_aead_create(tmpl, tb);
34314df4d80SHerbert Xu 
3440677157bSHerbert Xu 	return err;
34514df4d80SHerbert Xu }
34614df4d80SHerbert Xu 
34714df4d80SHerbert Xu static void seqiv_free(struct crypto_instance *inst)
34814df4d80SHerbert Xu {
34914df4d80SHerbert Xu 	if ((inst->alg.cra_flags ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK)
35014df4d80SHerbert Xu 		skcipher_geniv_free(inst);
35114df4d80SHerbert Xu 	else
352856e3f40SHerbert Xu 		aead_geniv_free(aead_instance(inst));
35314df4d80SHerbert Xu }
35414df4d80SHerbert Xu 
3550a270321SHerbert Xu static struct crypto_template seqiv_tmpl = {
3560a270321SHerbert Xu 	.name = "seqiv",
3570677157bSHerbert Xu 	.create = seqiv_create,
35814df4d80SHerbert Xu 	.free = seqiv_free,
3590a270321SHerbert Xu 	.module = THIS_MODULE,
3600a270321SHerbert Xu };
3610a270321SHerbert Xu 
3620a270321SHerbert Xu static int __init seqiv_module_init(void)
3630a270321SHerbert Xu {
3648a2cd1c4SHerbert Xu 	return crypto_register_template(&seqiv_tmpl);
3650a270321SHerbert Xu }
3660a270321SHerbert Xu 
3670a270321SHerbert Xu static void __exit seqiv_module_exit(void)
3680a270321SHerbert Xu {
3690a270321SHerbert Xu 	crypto_unregister_template(&seqiv_tmpl);
3700a270321SHerbert Xu }
3710a270321SHerbert Xu 
3720a270321SHerbert Xu module_init(seqiv_module_init);
3730a270321SHerbert Xu module_exit(seqiv_module_exit);
3740a270321SHerbert Xu 
3750a270321SHerbert Xu MODULE_LICENSE("GPL");
3760a270321SHerbert Xu MODULE_DESCRIPTION("Sequence Number IV Generator");
3774943ba16SKees Cook MODULE_ALIAS_CRYPTO("seqiv");
378