| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * seqiv: Sequence Number IV Generator |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 5 | 6 | * with a salt. This algorithm is mainly useful for CTR and similar modes. |
|---|
| 6 | 7 | * |
|---|
| 7 | 8 | * Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au> |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 10 | | - * under the terms of the GNU General Public License as published by the Free |
|---|
| 11 | | - * Software Foundation; either version 2 of the License, or (at your option) |
|---|
| 12 | | - * any later version. |
|---|
| 13 | | - * |
|---|
| 14 | 9 | */ |
|---|
| 15 | 10 | |
|---|
| 16 | 11 | #include <crypto/internal/geniv.h> |
|---|
| .. | .. |
|---|
| 23 | 18 | #include <linux/slab.h> |
|---|
| 24 | 19 | #include <linux/string.h> |
|---|
| 25 | 20 | |
|---|
| 26 | | -static void seqiv_free(struct crypto_instance *inst); |
|---|
| 27 | | - |
|---|
| 28 | 21 | static void seqiv_aead_encrypt_complete2(struct aead_request *req, int err) |
|---|
| 29 | 22 | { |
|---|
| 30 | 23 | struct aead_request *subreq = aead_request_ctx(req); |
|---|
| 31 | 24 | struct crypto_aead *geniv; |
|---|
| 32 | 25 | |
|---|
| 33 | | - if (err == -EINPROGRESS) |
|---|
| 26 | + if (err == -EINPROGRESS || err == -EBUSY) |
|---|
| 34 | 27 | return; |
|---|
| 35 | 28 | |
|---|
| 36 | 29 | if (err) |
|---|
| .. | .. |
|---|
| 40 | 33 | memcpy(req->iv, subreq->iv, crypto_aead_ivsize(geniv)); |
|---|
| 41 | 34 | |
|---|
| 42 | 35 | out: |
|---|
| 43 | | - kzfree(subreq->iv); |
|---|
| 36 | + kfree_sensitive(subreq->iv); |
|---|
| 44 | 37 | } |
|---|
| 45 | 38 | |
|---|
| 46 | 39 | static void seqiv_aead_encrypt_complete(struct crypto_async_request *base, |
|---|
| .. | .. |
|---|
| 73 | 66 | info = req->iv; |
|---|
| 74 | 67 | |
|---|
| 75 | 68 | if (req->src != req->dst) { |
|---|
| 76 | | - SKCIPHER_REQUEST_ON_STACK(nreq, ctx->sknull); |
|---|
| 69 | + SYNC_SKCIPHER_REQUEST_ON_STACK(nreq, ctx->sknull); |
|---|
| 77 | 70 | |
|---|
| 78 | | - skcipher_request_set_tfm(nreq, ctx->sknull); |
|---|
| 71 | + skcipher_request_set_sync_tfm(nreq, ctx->sknull); |
|---|
| 79 | 72 | skcipher_request_set_callback(nreq, req->base.flags, |
|---|
| 80 | 73 | NULL, NULL); |
|---|
| 81 | 74 | skcipher_request_set_crypt(nreq, req->src, req->dst, |
|---|
| .. | .. |
|---|
| 89 | 82 | |
|---|
| 90 | 83 | if (unlikely(!IS_ALIGNED((unsigned long)info, |
|---|
| 91 | 84 | crypto_aead_alignmask(geniv) + 1))) { |
|---|
| 92 | | - info = kmalloc(ivsize, req->base.flags & |
|---|
| 93 | | - CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL: |
|---|
| 94 | | - GFP_ATOMIC); |
|---|
| 85 | + info = kmemdup(req->iv, ivsize, req->base.flags & |
|---|
| 86 | + CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : |
|---|
| 87 | + GFP_ATOMIC); |
|---|
| 95 | 88 | if (!info) |
|---|
| 96 | 89 | return -ENOMEM; |
|---|
| 97 | 90 | |
|---|
| 98 | | - memcpy(info, req->iv, ivsize); |
|---|
| 99 | 91 | compl = seqiv_aead_encrypt_complete; |
|---|
| 100 | 92 | data = req; |
|---|
| 101 | 93 | } |
|---|
| .. | .. |
|---|
| 146 | 138 | struct aead_instance *inst; |
|---|
| 147 | 139 | int err; |
|---|
| 148 | 140 | |
|---|
| 149 | | - inst = aead_geniv_alloc(tmpl, tb, 0, 0); |
|---|
| 141 | + inst = aead_geniv_alloc(tmpl, tb); |
|---|
| 150 | 142 | |
|---|
| 151 | 143 | if (IS_ERR(inst)) |
|---|
| 152 | 144 | return PTR_ERR(inst); |
|---|
| .. | .. |
|---|
| 165 | 157 | inst->alg.base.cra_ctxsize += inst->alg.ivsize; |
|---|
| 166 | 158 | |
|---|
| 167 | 159 | err = aead_register_instance(tmpl, inst); |
|---|
| 168 | | - if (err) |
|---|
| 169 | | - goto free_inst; |
|---|
| 170 | | - |
|---|
| 171 | | -out: |
|---|
| 172 | | - return err; |
|---|
| 173 | | - |
|---|
| 160 | + if (err) { |
|---|
| 174 | 161 | free_inst: |
|---|
| 175 | | - aead_geniv_free(inst); |
|---|
| 176 | | - goto out; |
|---|
| 177 | | -} |
|---|
| 178 | | - |
|---|
| 179 | | -static int seqiv_create(struct crypto_template *tmpl, struct rtattr **tb) |
|---|
| 180 | | -{ |
|---|
| 181 | | - struct crypto_attr_type *algt; |
|---|
| 182 | | - |
|---|
| 183 | | - algt = crypto_get_attr_type(tb); |
|---|
| 184 | | - if (IS_ERR(algt)) |
|---|
| 185 | | - return PTR_ERR(algt); |
|---|
| 186 | | - |
|---|
| 187 | | - if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK) |
|---|
| 188 | | - return -EINVAL; |
|---|
| 189 | | - |
|---|
| 190 | | - return seqiv_aead_create(tmpl, tb); |
|---|
| 191 | | -} |
|---|
| 192 | | - |
|---|
| 193 | | -static void seqiv_free(struct crypto_instance *inst) |
|---|
| 194 | | -{ |
|---|
| 195 | | - aead_geniv_free(aead_instance(inst)); |
|---|
| 162 | + inst->free(inst); |
|---|
| 163 | + } |
|---|
| 164 | + return err; |
|---|
| 196 | 165 | } |
|---|
| 197 | 166 | |
|---|
| 198 | 167 | static struct crypto_template seqiv_tmpl = { |
|---|
| 199 | 168 | .name = "seqiv", |
|---|
| 200 | | - .create = seqiv_create, |
|---|
| 201 | | - .free = seqiv_free, |
|---|
| 169 | + .create = seqiv_aead_create, |
|---|
| 202 | 170 | .module = THIS_MODULE, |
|---|
| 203 | 171 | }; |
|---|
| 204 | 172 | |
|---|
| .. | .. |
|---|
| 212 | 180 | crypto_unregister_template(&seqiv_tmpl); |
|---|
| 213 | 181 | } |
|---|
| 214 | 182 | |
|---|
| 215 | | -module_init(seqiv_module_init); |
|---|
| 183 | +subsys_initcall(seqiv_module_init); |
|---|
| 216 | 184 | module_exit(seqiv_module_exit); |
|---|
| 217 | 185 | |
|---|
| 218 | 186 | MODULE_LICENSE("GPL"); |
|---|