.. | .. |
---|
| 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"); |
---|