^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * seqiv: Sequence Number IV Generator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This generator generates an IV based on a sequence number by xoring it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * with a salt. This algorithm is mainly useful for CTR and similar modes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <crypto/internal/geniv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <crypto/scatterwalk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <crypto/skcipher.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static void seqiv_aead_encrypt_complete2(struct aead_request *req, int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct aead_request *subreq = aead_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct crypto_aead *geniv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (err == -EINPROGRESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) geniv = crypto_aead_reqtfm(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) memcpy(req->iv, subreq->iv, crypto_aead_ivsize(geniv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) kfree_sensitive(subreq->iv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static void seqiv_aead_encrypt_complete(struct crypto_async_request *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct aead_request *req = base->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) seqiv_aead_encrypt_complete2(req, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) aead_request_complete(req, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static int seqiv_aead_encrypt(struct aead_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct crypto_aead *geniv = crypto_aead_reqtfm(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct aead_geniv_ctx *ctx = crypto_aead_ctx(geniv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct aead_request *subreq = aead_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) crypto_completion_t compl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) u8 *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) unsigned int ivsize = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (req->cryptlen < ivsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) aead_request_set_tfm(subreq, ctx->child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) compl = req->base.complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) data = req->base.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) info = req->iv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (req->src != req->dst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) SYNC_SKCIPHER_REQUEST_ON_STACK(nreq, ctx->sknull);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) skcipher_request_set_sync_tfm(nreq, ctx->sknull);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) skcipher_request_set_callback(nreq, req->base.flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) skcipher_request_set_crypt(nreq, req->src, req->dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) req->assoclen + req->cryptlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) err = crypto_skcipher_encrypt(nreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (unlikely(!IS_ALIGNED((unsigned long)info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) crypto_aead_alignmask(geniv) + 1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) info = kmemdup(req->iv, ivsize, req->base.flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) compl = seqiv_aead_encrypt_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) data = req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) aead_request_set_callback(subreq, req->base.flags, compl, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) aead_request_set_crypt(subreq, req->dst, req->dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) req->cryptlen - ivsize, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) aead_request_set_ad(subreq, req->assoclen + ivsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) crypto_xor(info, ctx->salt, ivsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) scatterwalk_map_and_copy(info, req->dst, req->assoclen, ivsize, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) err = crypto_aead_encrypt(subreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (unlikely(info != req->iv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) seqiv_aead_encrypt_complete2(req, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static int seqiv_aead_decrypt(struct aead_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct crypto_aead *geniv = crypto_aead_reqtfm(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct aead_geniv_ctx *ctx = crypto_aead_ctx(geniv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct aead_request *subreq = aead_request_ctx(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) crypto_completion_t compl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) unsigned int ivsize = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (req->cryptlen < ivsize + crypto_aead_authsize(geniv))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) aead_request_set_tfm(subreq, ctx->child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) compl = req->base.complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) data = req->base.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) aead_request_set_callback(subreq, req->base.flags, compl, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) aead_request_set_crypt(subreq, req->src, req->dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) req->cryptlen - ivsize, req->iv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) aead_request_set_ad(subreq, req->assoclen + ivsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) scatterwalk_map_and_copy(req->iv, req->src, req->assoclen, ivsize, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return crypto_aead_decrypt(subreq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static int seqiv_aead_create(struct crypto_template *tmpl, struct rtattr **tb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct aead_instance *inst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) inst = aead_geniv_alloc(tmpl, tb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (IS_ERR(inst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return PTR_ERR(inst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (inst->alg.ivsize != sizeof(u64))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) goto free_inst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) inst->alg.encrypt = seqiv_aead_encrypt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) inst->alg.decrypt = seqiv_aead_decrypt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) inst->alg.init = aead_init_geniv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) inst->alg.exit = aead_exit_geniv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) inst->alg.base.cra_ctxsize += inst->alg.ivsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) err = aead_register_instance(tmpl, inst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) free_inst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) inst->free(inst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static struct crypto_template seqiv_tmpl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .name = "seqiv",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) .create = seqiv_aead_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static int __init seqiv_module_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return crypto_register_template(&seqiv_tmpl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static void __exit seqiv_module_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) crypto_unregister_template(&seqiv_tmpl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) subsys_initcall(seqiv_module_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) module_exit(seqiv_module_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) MODULE_DESCRIPTION("Sequence Number IV Generator");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) MODULE_ALIAS_CRYPTO("seqiv");