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 1614df4d80SHerbert Xu #include <crypto/internal/aead.h> 170a270321SHerbert Xu #include <crypto/internal/skcipher.h> 18a0f000ecSHerbert Xu #include <crypto/rng.h> 190a270321SHerbert Xu #include <linux/err.h> 200a270321SHerbert Xu #include <linux/init.h> 210a270321SHerbert Xu #include <linux/kernel.h> 220a270321SHerbert Xu #include <linux/module.h> 235a0e3ad6STejun Heo #include <linux/slab.h> 240a270321SHerbert Xu #include <linux/spinlock.h> 250a270321SHerbert Xu #include <linux/string.h> 260a270321SHerbert Xu 270a270321SHerbert Xu struct seqiv_ctx { 280a270321SHerbert Xu spinlock_t lock; 290a270321SHerbert Xu u8 salt[] __attribute__ ((aligned(__alignof__(u32)))); 300a270321SHerbert Xu }; 310a270321SHerbert Xu 320a270321SHerbert Xu static void seqiv_complete2(struct skcipher_givcrypt_request *req, int err) 330a270321SHerbert Xu { 340a270321SHerbert Xu struct ablkcipher_request *subreq = skcipher_givcrypt_reqctx(req); 350a270321SHerbert Xu struct crypto_ablkcipher *geniv; 360a270321SHerbert Xu 370a270321SHerbert Xu if (err == -EINPROGRESS) 380a270321SHerbert Xu return; 390a270321SHerbert Xu 400a270321SHerbert Xu if (err) 410a270321SHerbert Xu goto out; 420a270321SHerbert Xu 430a270321SHerbert Xu geniv = skcipher_givcrypt_reqtfm(req); 440a270321SHerbert Xu memcpy(req->creq.info, subreq->info, crypto_ablkcipher_ivsize(geniv)); 450a270321SHerbert Xu 460a270321SHerbert Xu out: 470a270321SHerbert Xu kfree(subreq->info); 480a270321SHerbert Xu } 490a270321SHerbert Xu 500a270321SHerbert Xu static void seqiv_complete(struct crypto_async_request *base, int err) 510a270321SHerbert Xu { 520a270321SHerbert Xu struct skcipher_givcrypt_request *req = base->data; 530a270321SHerbert Xu 540a270321SHerbert Xu seqiv_complete2(req, err); 550a270321SHerbert Xu skcipher_givcrypt_complete(req, err); 560a270321SHerbert Xu } 570a270321SHerbert Xu 5814df4d80SHerbert Xu static void seqiv_aead_complete2(struct aead_givcrypt_request *req, int err) 5914df4d80SHerbert Xu { 6014df4d80SHerbert Xu struct aead_request *subreq = aead_givcrypt_reqctx(req); 6114df4d80SHerbert Xu struct crypto_aead *geniv; 6214df4d80SHerbert Xu 6314df4d80SHerbert Xu if (err == -EINPROGRESS) 6414df4d80SHerbert Xu return; 6514df4d80SHerbert Xu 6614df4d80SHerbert Xu if (err) 6714df4d80SHerbert Xu goto out; 6814df4d80SHerbert Xu 6914df4d80SHerbert Xu geniv = aead_givcrypt_reqtfm(req); 7014df4d80SHerbert Xu memcpy(req->areq.iv, subreq->iv, crypto_aead_ivsize(geniv)); 7114df4d80SHerbert Xu 7214df4d80SHerbert Xu out: 7314df4d80SHerbert Xu kfree(subreq->iv); 7414df4d80SHerbert Xu } 7514df4d80SHerbert Xu 7614df4d80SHerbert Xu static void seqiv_aead_complete(struct crypto_async_request *base, int err) 7714df4d80SHerbert Xu { 7814df4d80SHerbert Xu struct aead_givcrypt_request *req = base->data; 7914df4d80SHerbert Xu 8014df4d80SHerbert Xu seqiv_aead_complete2(req, err); 8114df4d80SHerbert Xu aead_givcrypt_complete(req, err); 8214df4d80SHerbert Xu } 8314df4d80SHerbert Xu 8414df4d80SHerbert Xu static void seqiv_geniv(struct seqiv_ctx *ctx, u8 *info, u64 seq, 8514df4d80SHerbert Xu unsigned int ivsize) 8614df4d80SHerbert Xu { 8714df4d80SHerbert Xu unsigned int len = ivsize; 8814df4d80SHerbert Xu 8914df4d80SHerbert Xu if (ivsize > sizeof(u64)) { 9014df4d80SHerbert Xu memset(info, 0, ivsize - sizeof(u64)); 9114df4d80SHerbert Xu len = sizeof(u64); 9214df4d80SHerbert Xu } 9314df4d80SHerbert Xu seq = cpu_to_be64(seq); 9414df4d80SHerbert Xu memcpy(info + ivsize - len, &seq, len); 9514df4d80SHerbert Xu crypto_xor(info, ctx->salt, ivsize); 9614df4d80SHerbert Xu } 9714df4d80SHerbert Xu 980a270321SHerbert Xu static int seqiv_givencrypt(struct skcipher_givcrypt_request *req) 990a270321SHerbert Xu { 1000a270321SHerbert Xu struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req); 1010a270321SHerbert Xu struct seqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv); 1020a270321SHerbert Xu struct ablkcipher_request *subreq = skcipher_givcrypt_reqctx(req); 1033e3dc25fSMark Rustad crypto_completion_t compl; 1040a270321SHerbert Xu void *data; 1050a270321SHerbert Xu u8 *info; 1060a270321SHerbert Xu unsigned int ivsize; 1070a270321SHerbert Xu int err; 1080a270321SHerbert Xu 1090a270321SHerbert Xu ablkcipher_request_set_tfm(subreq, skcipher_geniv_cipher(geniv)); 1100a270321SHerbert Xu 1113e3dc25fSMark Rustad compl = req->creq.base.complete; 1120a270321SHerbert Xu data = req->creq.base.data; 1130a270321SHerbert Xu info = req->creq.info; 1140a270321SHerbert Xu 1150a270321SHerbert Xu ivsize = crypto_ablkcipher_ivsize(geniv); 1160a270321SHerbert Xu 1170a270321SHerbert Xu if (unlikely(!IS_ALIGNED((unsigned long)info, 1180a270321SHerbert Xu crypto_ablkcipher_alignmask(geniv) + 1))) { 1190a270321SHerbert Xu info = kmalloc(ivsize, req->creq.base.flags & 1200a270321SHerbert Xu CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL: 1210a270321SHerbert Xu GFP_ATOMIC); 1220a270321SHerbert Xu if (!info) 1230a270321SHerbert Xu return -ENOMEM; 1240a270321SHerbert Xu 1253e3dc25fSMark Rustad compl = seqiv_complete; 1260a270321SHerbert Xu data = req; 1270a270321SHerbert Xu } 1280a270321SHerbert Xu 1293e3dc25fSMark Rustad ablkcipher_request_set_callback(subreq, req->creq.base.flags, compl, 1300a270321SHerbert Xu data); 1310a270321SHerbert Xu ablkcipher_request_set_crypt(subreq, req->creq.src, req->creq.dst, 1320a270321SHerbert Xu req->creq.nbytes, info); 1330a270321SHerbert Xu 13414df4d80SHerbert Xu seqiv_geniv(ctx, info, req->seq, ivsize); 1350a270321SHerbert Xu memcpy(req->giv, info, ivsize); 1360a270321SHerbert Xu 1370a270321SHerbert Xu err = crypto_ablkcipher_encrypt(subreq); 1380a270321SHerbert Xu if (unlikely(info != req->creq.info)) 1390a270321SHerbert Xu seqiv_complete2(req, err); 1400a270321SHerbert Xu return err; 1410a270321SHerbert Xu } 1420a270321SHerbert Xu 14314df4d80SHerbert Xu static int seqiv_aead_givencrypt(struct aead_givcrypt_request *req) 14414df4d80SHerbert Xu { 14514df4d80SHerbert Xu struct crypto_aead *geniv = aead_givcrypt_reqtfm(req); 14614df4d80SHerbert Xu struct seqiv_ctx *ctx = crypto_aead_ctx(geniv); 14714df4d80SHerbert Xu struct aead_request *areq = &req->areq; 14814df4d80SHerbert Xu struct aead_request *subreq = aead_givcrypt_reqctx(req); 1493e3dc25fSMark Rustad crypto_completion_t compl; 15014df4d80SHerbert Xu void *data; 15114df4d80SHerbert Xu u8 *info; 15214df4d80SHerbert Xu unsigned int ivsize; 15314df4d80SHerbert Xu int err; 15414df4d80SHerbert Xu 15514df4d80SHerbert Xu aead_request_set_tfm(subreq, aead_geniv_base(geniv)); 15614df4d80SHerbert Xu 1573e3dc25fSMark Rustad compl = areq->base.complete; 15814df4d80SHerbert Xu data = areq->base.data; 15914df4d80SHerbert Xu info = areq->iv; 16014df4d80SHerbert Xu 16114df4d80SHerbert Xu ivsize = crypto_aead_ivsize(geniv); 16214df4d80SHerbert Xu 16314df4d80SHerbert Xu if (unlikely(!IS_ALIGNED((unsigned long)info, 16414df4d80SHerbert Xu crypto_aead_alignmask(geniv) + 1))) { 16514df4d80SHerbert Xu info = kmalloc(ivsize, areq->base.flags & 16614df4d80SHerbert Xu CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL: 16714df4d80SHerbert Xu GFP_ATOMIC); 16814df4d80SHerbert Xu if (!info) 16914df4d80SHerbert Xu return -ENOMEM; 17014df4d80SHerbert Xu 1713e3dc25fSMark Rustad compl = seqiv_aead_complete; 17214df4d80SHerbert Xu data = req; 17314df4d80SHerbert Xu } 17414df4d80SHerbert Xu 1753e3dc25fSMark Rustad aead_request_set_callback(subreq, areq->base.flags, compl, data); 17614df4d80SHerbert Xu aead_request_set_crypt(subreq, areq->src, areq->dst, areq->cryptlen, 17714df4d80SHerbert Xu info); 17814df4d80SHerbert Xu aead_request_set_assoc(subreq, areq->assoc, areq->assoclen); 17914df4d80SHerbert Xu 18014df4d80SHerbert Xu seqiv_geniv(ctx, info, req->seq, ivsize); 18114df4d80SHerbert Xu memcpy(req->giv, info, ivsize); 18214df4d80SHerbert Xu 18314df4d80SHerbert Xu err = crypto_aead_encrypt(subreq); 18414df4d80SHerbert Xu if (unlikely(info != areq->iv)) 18514df4d80SHerbert Xu seqiv_aead_complete2(req, err); 18614df4d80SHerbert Xu return err; 18714df4d80SHerbert Xu } 18814df4d80SHerbert Xu 1890a270321SHerbert Xu static int seqiv_givencrypt_first(struct skcipher_givcrypt_request *req) 1900a270321SHerbert Xu { 1910a270321SHerbert Xu struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req); 1920a270321SHerbert Xu struct seqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv); 193a0f000ecSHerbert Xu int err = 0; 1940a270321SHerbert Xu 1950a270321SHerbert Xu spin_lock_bh(&ctx->lock); 1960a270321SHerbert Xu if (crypto_ablkcipher_crt(geniv)->givencrypt != seqiv_givencrypt_first) 1970a270321SHerbert Xu goto unlock; 1980a270321SHerbert Xu 1990a270321SHerbert Xu crypto_ablkcipher_crt(geniv)->givencrypt = seqiv_givencrypt; 200a0f000ecSHerbert Xu err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt, 201a0f000ecSHerbert Xu crypto_ablkcipher_ivsize(geniv)); 2020a270321SHerbert Xu 2030a270321SHerbert Xu unlock: 2040a270321SHerbert Xu spin_unlock_bh(&ctx->lock); 2050a270321SHerbert Xu 206a0f000ecSHerbert Xu if (err) 207a0f000ecSHerbert Xu return err; 208a0f000ecSHerbert Xu 2090a270321SHerbert Xu return seqiv_givencrypt(req); 2100a270321SHerbert Xu } 2110a270321SHerbert Xu 21214df4d80SHerbert Xu static int seqiv_aead_givencrypt_first(struct aead_givcrypt_request *req) 21314df4d80SHerbert Xu { 21414df4d80SHerbert Xu struct crypto_aead *geniv = aead_givcrypt_reqtfm(req); 21514df4d80SHerbert Xu struct seqiv_ctx *ctx = crypto_aead_ctx(geniv); 216a0f000ecSHerbert Xu int err = 0; 21714df4d80SHerbert Xu 21814df4d80SHerbert Xu spin_lock_bh(&ctx->lock); 21914df4d80SHerbert Xu if (crypto_aead_crt(geniv)->givencrypt != seqiv_aead_givencrypt_first) 22014df4d80SHerbert Xu goto unlock; 22114df4d80SHerbert Xu 22214df4d80SHerbert Xu crypto_aead_crt(geniv)->givencrypt = seqiv_aead_givencrypt; 223a0f000ecSHerbert Xu err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt, 224a0f000ecSHerbert Xu crypto_aead_ivsize(geniv)); 22514df4d80SHerbert Xu 22614df4d80SHerbert Xu unlock: 22714df4d80SHerbert Xu spin_unlock_bh(&ctx->lock); 22814df4d80SHerbert Xu 229a0f000ecSHerbert Xu if (err) 230a0f000ecSHerbert Xu return err; 231a0f000ecSHerbert Xu 23214df4d80SHerbert Xu return seqiv_aead_givencrypt(req); 23314df4d80SHerbert Xu } 23414df4d80SHerbert Xu 2350a270321SHerbert Xu static int seqiv_init(struct crypto_tfm *tfm) 2360a270321SHerbert Xu { 2370a270321SHerbert Xu struct crypto_ablkcipher *geniv = __crypto_ablkcipher_cast(tfm); 2380a270321SHerbert Xu struct seqiv_ctx *ctx = crypto_ablkcipher_ctx(geniv); 2390a270321SHerbert Xu 2400a270321SHerbert Xu spin_lock_init(&ctx->lock); 2410a270321SHerbert Xu 2420a270321SHerbert Xu tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request); 2430a270321SHerbert Xu 2440a270321SHerbert Xu return skcipher_geniv_init(tfm); 2450a270321SHerbert Xu } 2460a270321SHerbert Xu 24714df4d80SHerbert Xu static int seqiv_aead_init(struct crypto_tfm *tfm) 24814df4d80SHerbert Xu { 24914df4d80SHerbert Xu struct crypto_aead *geniv = __crypto_aead_cast(tfm); 25014df4d80SHerbert Xu struct seqiv_ctx *ctx = crypto_aead_ctx(geniv); 25114df4d80SHerbert Xu 25214df4d80SHerbert Xu spin_lock_init(&ctx->lock); 25314df4d80SHerbert Xu 25414df4d80SHerbert Xu tfm->crt_aead.reqsize = sizeof(struct aead_request); 25514df4d80SHerbert Xu 25614df4d80SHerbert Xu return aead_geniv_init(tfm); 25714df4d80SHerbert Xu } 25814df4d80SHerbert Xu 2590a270321SHerbert Xu static struct crypto_template seqiv_tmpl; 2600a270321SHerbert Xu 26114df4d80SHerbert Xu static struct crypto_instance *seqiv_ablkcipher_alloc(struct rtattr **tb) 2620a270321SHerbert Xu { 2630a270321SHerbert Xu struct crypto_instance *inst; 2640a270321SHerbert Xu 2650a270321SHerbert Xu inst = skcipher_geniv_alloc(&seqiv_tmpl, tb, 0, 0); 26614df4d80SHerbert Xu 2670a270321SHerbert Xu if (IS_ERR(inst)) 2680a270321SHerbert Xu goto out; 2690a270321SHerbert Xu 270c0ecf891SHerbert Xu if (inst->alg.cra_ablkcipher.ivsize < sizeof(u64)) { 271c0ecf891SHerbert Xu skcipher_geniv_free(inst); 272c0ecf891SHerbert Xu inst = ERR_PTR(-EINVAL); 273c0ecf891SHerbert Xu goto out; 274c0ecf891SHerbert Xu } 275c0ecf891SHerbert Xu 2760a270321SHerbert Xu inst->alg.cra_ablkcipher.givencrypt = seqiv_givencrypt_first; 2770a270321SHerbert Xu 2780a270321SHerbert Xu inst->alg.cra_init = seqiv_init; 2790a270321SHerbert Xu inst->alg.cra_exit = skcipher_geniv_exit; 2800a270321SHerbert Xu 2810a270321SHerbert Xu inst->alg.cra_ctxsize += inst->alg.cra_ablkcipher.ivsize; 2820a270321SHerbert Xu 2830a270321SHerbert Xu out: 2840a270321SHerbert Xu return inst; 2850a270321SHerbert Xu } 2860a270321SHerbert Xu 28714df4d80SHerbert Xu static struct crypto_instance *seqiv_aead_alloc(struct rtattr **tb) 28814df4d80SHerbert Xu { 28914df4d80SHerbert Xu struct crypto_instance *inst; 29014df4d80SHerbert Xu 29114df4d80SHerbert Xu inst = aead_geniv_alloc(&seqiv_tmpl, tb, 0, 0); 29214df4d80SHerbert Xu 29314df4d80SHerbert Xu if (IS_ERR(inst)) 29414df4d80SHerbert Xu goto out; 29514df4d80SHerbert Xu 296c0ecf891SHerbert Xu if (inst->alg.cra_aead.ivsize < sizeof(u64)) { 297c0ecf891SHerbert Xu aead_geniv_free(inst); 298c0ecf891SHerbert Xu inst = ERR_PTR(-EINVAL); 299c0ecf891SHerbert Xu goto out; 300c0ecf891SHerbert Xu } 301c0ecf891SHerbert Xu 30214df4d80SHerbert Xu inst->alg.cra_aead.givencrypt = seqiv_aead_givencrypt_first; 30314df4d80SHerbert Xu 30414df4d80SHerbert Xu inst->alg.cra_init = seqiv_aead_init; 30514df4d80SHerbert Xu inst->alg.cra_exit = aead_geniv_exit; 30614df4d80SHerbert Xu 30714df4d80SHerbert Xu inst->alg.cra_ctxsize = inst->alg.cra_aead.ivsize; 30814df4d80SHerbert Xu 30914df4d80SHerbert Xu out: 31014df4d80SHerbert Xu return inst; 31114df4d80SHerbert Xu } 31214df4d80SHerbert Xu 31314df4d80SHerbert Xu static struct crypto_instance *seqiv_alloc(struct rtattr **tb) 31414df4d80SHerbert Xu { 31514df4d80SHerbert Xu struct crypto_attr_type *algt; 31614df4d80SHerbert Xu struct crypto_instance *inst; 31714df4d80SHerbert Xu int err; 31814df4d80SHerbert Xu 31914df4d80SHerbert Xu algt = crypto_get_attr_type(tb); 32014df4d80SHerbert Xu if (IS_ERR(algt)) 3213e8afe35SJulia Lawall return ERR_CAST(algt); 32214df4d80SHerbert Xu 323a0f000ecSHerbert Xu err = crypto_get_default_rng(); 324a0f000ecSHerbert Xu if (err) 325a0f000ecSHerbert Xu return ERR_PTR(err); 326a0f000ecSHerbert Xu 32714df4d80SHerbert Xu if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK) 32814df4d80SHerbert Xu inst = seqiv_ablkcipher_alloc(tb); 32914df4d80SHerbert Xu else 33014df4d80SHerbert Xu inst = seqiv_aead_alloc(tb); 33114df4d80SHerbert Xu 33214df4d80SHerbert Xu if (IS_ERR(inst)) 333a0f000ecSHerbert Xu goto put_rng; 33414df4d80SHerbert Xu 33514df4d80SHerbert Xu inst->alg.cra_alignmask |= __alignof__(u32) - 1; 33614df4d80SHerbert Xu inst->alg.cra_ctxsize += sizeof(struct seqiv_ctx); 33714df4d80SHerbert Xu 33814df4d80SHerbert Xu out: 33914df4d80SHerbert Xu return inst; 340a0f000ecSHerbert Xu 341a0f000ecSHerbert Xu put_rng: 342a0f000ecSHerbert Xu crypto_put_default_rng(); 343a0f000ecSHerbert Xu goto out; 34414df4d80SHerbert Xu } 34514df4d80SHerbert Xu 34614df4d80SHerbert Xu static void seqiv_free(struct crypto_instance *inst) 34714df4d80SHerbert Xu { 34814df4d80SHerbert Xu if ((inst->alg.cra_flags ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK) 34914df4d80SHerbert Xu skcipher_geniv_free(inst); 35014df4d80SHerbert Xu else 35114df4d80SHerbert Xu aead_geniv_free(inst); 352a0f000ecSHerbert Xu crypto_put_default_rng(); 35314df4d80SHerbert Xu } 35414df4d80SHerbert Xu 3550a270321SHerbert Xu static struct crypto_template seqiv_tmpl = { 3560a270321SHerbert Xu .name = "seqiv", 3570a270321SHerbert Xu .alloc = seqiv_alloc, 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 { 3640a270321SHerbert 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