aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/ablkcipher.c158
-rw-r--r--crypto/api.c19
-rw-r--r--crypto/blkcipher.c4
-rw-r--r--crypto/internal.h2
-rw-r--r--include/crypto/internal/skcipher.h2
-rw-r--r--include/linux/crypto.h9
6 files changed, 181 insertions, 13 deletions
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c
index 092d9659b861..d1df528c8fa3 100644
--- a/crypto/ablkcipher.c
+++ b/crypto/ablkcipher.c
@@ -18,6 +18,8 @@
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/rtnetlink.h>
22#include <linux/sched.h>
21#include <linux/slab.h> 23#include <linux/slab.h>
22#include <linux/seq_file.h> 24#include <linux/seq_file.h>
23 25
@@ -68,6 +70,16 @@ static unsigned int crypto_ablkcipher_ctxsize(struct crypto_alg *alg, u32 type,
68 return alg->cra_ctxsize; 70 return alg->cra_ctxsize;
69} 71}
70 72
73int skcipher_null_givencrypt(struct skcipher_givcrypt_request *req)
74{
75 return crypto_ablkcipher_encrypt(&req->creq);
76}
77
78int skcipher_null_givdecrypt(struct skcipher_givcrypt_request *req)
79{
80 return crypto_ablkcipher_decrypt(&req->creq);
81}
82
71static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type, 83static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type,
72 u32 mask) 84 u32 mask)
73{ 85{
@@ -80,6 +92,10 @@ static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type,
80 crt->setkey = setkey; 92 crt->setkey = setkey;
81 crt->encrypt = alg->encrypt; 93 crt->encrypt = alg->encrypt;
82 crt->decrypt = alg->decrypt; 94 crt->decrypt = alg->decrypt;
95 if (!alg->ivsize) {
96 crt->givencrypt = skcipher_null_givencrypt;
97 crt->givdecrypt = skcipher_null_givdecrypt;
98 }
83 crt->base = __crypto_ablkcipher_cast(tfm); 99 crt->base = __crypto_ablkcipher_cast(tfm);
84 crt->ivsize = alg->ivsize; 100 crt->ivsize = alg->ivsize;
85 101
@@ -163,6 +179,108 @@ const char *crypto_default_geniv(const struct crypto_alg *alg)
163 return alg->cra_flags & CRYPTO_ALG_ASYNC ? "eseqiv" : "chainiv"; 179 return alg->cra_flags & CRYPTO_ALG_ASYNC ? "eseqiv" : "chainiv";
164} 180}
165 181
182static int crypto_givcipher_default(struct crypto_alg *alg, u32 type, u32 mask)
183{
184 struct rtattr *tb[3];
185 struct {
186 struct rtattr attr;
187 struct crypto_attr_type data;
188 } ptype;
189 struct {
190 struct rtattr attr;
191 struct crypto_attr_alg data;
192 } palg;
193 struct crypto_template *tmpl;
194 struct crypto_instance *inst;
195 struct crypto_alg *larval;
196 const char *geniv;
197 int err;
198
199 larval = crypto_larval_lookup(alg->cra_driver_name,
200 CRYPTO_ALG_TYPE_GIVCIPHER,
201 CRYPTO_ALG_TYPE_MASK);
202 err = PTR_ERR(larval);
203 if (IS_ERR(larval))
204 goto out;
205
206 err = -EAGAIN;
207 if (!crypto_is_larval(larval))
208 goto drop_larval;
209
210 ptype.attr.rta_len = sizeof(ptype);
211 ptype.attr.rta_type = CRYPTOA_TYPE;
212 ptype.data.type = type | CRYPTO_ALG_GENIV;
213 /* GENIV tells the template that we're making a default geniv. */
214 ptype.data.mask = mask | CRYPTO_ALG_GENIV;
215 tb[0] = &ptype.attr;
216
217 palg.attr.rta_len = sizeof(palg);
218 palg.attr.rta_type = CRYPTOA_ALG;
219 /* Must use the exact name to locate ourselves. */
220 memcpy(palg.data.name, alg->cra_driver_name, CRYPTO_MAX_ALG_NAME);
221 tb[1] = &palg.attr;
222
223 tb[2] = NULL;
224
225 if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
226 CRYPTO_ALG_TYPE_BLKCIPHER)
227 geniv = alg->cra_blkcipher.geniv;
228 else
229 geniv = alg->cra_ablkcipher.geniv;
230
231 if (!geniv)
232 geniv = crypto_default_geniv(alg);
233
234 tmpl = crypto_lookup_template(geniv);
235 err = -ENOENT;
236 if (!tmpl)
237 goto kill_larval;
238
239 inst = tmpl->alloc(tb);
240 err = PTR_ERR(inst);
241 if (IS_ERR(inst))
242 goto put_tmpl;
243
244 if ((err = crypto_register_instance(tmpl, inst))) {
245 tmpl->free(inst);
246 goto put_tmpl;
247 }
248
249 /* Redo the lookup to use the instance we just registered. */
250 err = -EAGAIN;
251
252put_tmpl:
253 crypto_tmpl_put(tmpl);
254kill_larval:
255 crypto_larval_kill(larval);
256drop_larval:
257 crypto_mod_put(larval);
258out:
259 crypto_mod_put(alg);
260 return err;
261}
262
263static struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type,
264 u32 mask)
265{
266 struct crypto_alg *alg;
267
268 alg = crypto_alg_mod_lookup(name, type, mask);
269 if (IS_ERR(alg))
270 return alg;
271
272 if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
273 CRYPTO_ALG_TYPE_GIVCIPHER)
274 return alg;
275
276 if (!((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) ==
277 CRYPTO_ALG_TYPE_BLKCIPHER ? alg->cra_blkcipher.ivsize :
278 alg->cra_ablkcipher.ivsize))
279 return alg;
280
281 return ERR_PTR(crypto_givcipher_default(alg, type, mask));
282}
283
166int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name, 284int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name,
167 u32 type, u32 mask) 285 u32 type, u32 mask)
168{ 286{
@@ -172,7 +290,7 @@ int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name,
172 type = crypto_skcipher_type(type); 290 type = crypto_skcipher_type(type);
173 mask = crypto_skcipher_mask(mask); 291 mask = crypto_skcipher_mask(mask);
174 292
175 alg = crypto_alg_mod_lookup(name, type, mask); 293 alg = crypto_lookup_skcipher(name, type, mask);
176 if (IS_ERR(alg)) 294 if (IS_ERR(alg))
177 return PTR_ERR(alg); 295 return PTR_ERR(alg);
178 296
@@ -182,5 +300,43 @@ int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name,
182} 300}
183EXPORT_SYMBOL_GPL(crypto_grab_skcipher); 301EXPORT_SYMBOL_GPL(crypto_grab_skcipher);
184 302
303struct crypto_ablkcipher *crypto_alloc_ablkcipher(const char *alg_name,
304 u32 type, u32 mask)
305{
306 struct crypto_tfm *tfm;
307 int err;
308
309 type = crypto_skcipher_type(type);
310 mask = crypto_skcipher_mask(mask);
311
312 for (;;) {
313 struct crypto_alg *alg;
314
315 alg = crypto_lookup_skcipher(alg_name, type, mask);
316 if (IS_ERR(alg)) {
317 err = PTR_ERR(alg);
318 goto err;
319 }
320
321 tfm = __crypto_alloc_tfm(alg, type, mask);
322 if (!IS_ERR(tfm))
323 return __crypto_ablkcipher_cast(tfm);
324
325 crypto_mod_put(alg);
326 err = PTR_ERR(tfm);
327
328err:
329 if (err != -EAGAIN)
330 break;
331 if (signal_pending(current)) {
332 err = -EINTR;
333 break;
334 }
335 }
336
337 return ERR_PTR(err);
338}
339EXPORT_SYMBOL_GPL(crypto_alloc_ablkcipher);
340
185MODULE_LICENSE("GPL"); 341MODULE_LICENSE("GPL");
186MODULE_DESCRIPTION("Asynchronous block chaining cipher type"); 342MODULE_DESCRIPTION("Asynchronous block chaining cipher type");
diff --git a/crypto/api.c b/crypto/api.c
index 1f5c72477356..a2496d1bc6d4 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -137,7 +137,7 @@ static struct crypto_alg *crypto_larval_alloc(const char *name, u32 type,
137 return alg; 137 return alg;
138} 138}
139 139
140static void crypto_larval_kill(struct crypto_alg *alg) 140void crypto_larval_kill(struct crypto_alg *alg)
141{ 141{
142 struct crypto_larval *larval = (void *)alg; 142 struct crypto_larval *larval = (void *)alg;
143 143
@@ -147,6 +147,7 @@ static void crypto_larval_kill(struct crypto_alg *alg)
147 complete_all(&larval->completion); 147 complete_all(&larval->completion);
148 crypto_alg_put(alg); 148 crypto_alg_put(alg);
149} 149}
150EXPORT_SYMBOL_GPL(crypto_larval_kill);
150 151
151static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg) 152static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
152{ 153{
@@ -176,11 +177,9 @@ static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
176 return alg; 177 return alg;
177} 178}
178 179
179struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask) 180struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask)
180{ 181{
181 struct crypto_alg *alg; 182 struct crypto_alg *alg;
182 struct crypto_alg *larval;
183 int ok;
184 183
185 if (!name) 184 if (!name)
186 return ERR_PTR(-ENOENT); 185 return ERR_PTR(-ENOENT);
@@ -193,7 +192,17 @@ struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
193 if (alg) 192 if (alg)
194 return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg; 193 return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg;
195 194
196 larval = crypto_larval_alloc(name, type, mask); 195 return crypto_larval_alloc(name, type, mask);
196}
197EXPORT_SYMBOL_GPL(crypto_larval_lookup);
198
199struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
200{
201 struct crypto_alg *alg;
202 struct crypto_alg *larval;
203 int ok;
204
205 larval = crypto_larval_lookup(name, type, mask);
197 if (IS_ERR(larval) || !crypto_is_larval(larval)) 206 if (IS_ERR(larval) || !crypto_is_larval(larval))
198 return larval; 207 return larval;
199 208
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
index ca6ef065cded..4a7e65c4df4d 100644
--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -450,6 +450,10 @@ static int crypto_init_blkcipher_ops_async(struct crypto_tfm *tfm)
450 crt->setkey = async_setkey; 450 crt->setkey = async_setkey;
451 crt->encrypt = async_encrypt; 451 crt->encrypt = async_encrypt;
452 crt->decrypt = async_decrypt; 452 crt->decrypt = async_decrypt;
453 if (!alg->ivsize) {
454 crt->givencrypt = skcipher_null_givencrypt;
455 crt->givdecrypt = skcipher_null_givdecrypt;
456 }
453 crt->base = __crypto_ablkcipher_cast(tfm); 457 crt->base = __crypto_ablkcipher_cast(tfm);
454 crt->ivsize = alg->ivsize; 458 crt->ivsize = alg->ivsize;
455 459
diff --git a/crypto/internal.h b/crypto/internal.h
index cb13952f82bf..32f4c2145603 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -93,6 +93,8 @@ void crypto_exit_digest_ops(struct crypto_tfm *tfm);
93void crypto_exit_cipher_ops(struct crypto_tfm *tfm); 93void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
94void crypto_exit_compress_ops(struct crypto_tfm *tfm); 94void crypto_exit_compress_ops(struct crypto_tfm *tfm);
95 95
96void crypto_larval_kill(struct crypto_alg *alg);
97struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask);
96void crypto_larval_error(const char *name, u32 type, u32 mask); 98void crypto_larval_error(const char *name, u32 type, u32 mask);
97 99
98void crypto_shoot_alg(struct crypto_alg *alg); 100void crypto_shoot_alg(struct crypto_alg *alg);
diff --git a/include/crypto/internal/skcipher.h b/include/crypto/internal/skcipher.h
index 80c5bfb14a60..2071999d4b5e 100644
--- a/include/crypto/internal/skcipher.h
+++ b/include/crypto/internal/skcipher.h
@@ -53,6 +53,8 @@ static inline struct crypto_ablkcipher *crypto_spawn_skcipher(
53 crypto_skcipher_mask(0))); 53 crypto_skcipher_mask(0)));
54} 54}
55 55
56int skcipher_null_givencrypt(struct skcipher_givcrypt_request *req);
57int skcipher_null_givdecrypt(struct skcipher_givcrypt_request *req);
56const char *crypto_default_geniv(const struct crypto_alg *alg); 58const char *crypto_default_geniv(const struct crypto_alg *alg);
57 59
58struct crypto_instance *skcipher_geniv_alloc(struct crypto_template *tmpl, 60struct crypto_instance *skcipher_geniv_alloc(struct crypto_template *tmpl,
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index fa7afa9b9f4f..835dcaf3fe4e 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -561,13 +561,8 @@ static inline u32 crypto_skcipher_mask(u32 mask)
561 return mask; 561 return mask;
562} 562}
563 563
564static inline struct crypto_ablkcipher *crypto_alloc_ablkcipher( 564struct crypto_ablkcipher *crypto_alloc_ablkcipher(const char *alg_name,
565 const char *alg_name, u32 type, u32 mask) 565 u32 type, u32 mask);
566{
567 return __crypto_ablkcipher_cast(
568 crypto_alloc_base(alg_name, crypto_skcipher_type(type),
569 crypto_skcipher_mask(mask)));
570}
571 566
572static inline struct crypto_tfm *crypto_ablkcipher_tfm( 567static inline struct crypto_tfm *crypto_ablkcipher_tfm(
573 struct crypto_ablkcipher *tfm) 568 struct crypto_ablkcipher *tfm)