diff options
author | Steffen Klassert <steffen.klassert@secunet.com> | 2012-03-29 03:03:47 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2012-03-29 07:52:47 -0400 |
commit | 1e1229940045a537c61fb69f86010a8774e576d0 (patch) | |
tree | 3a594eef2d1cda7e49f7b62f70853d6f6a021d61 /crypto | |
parent | fbf0ca1bf852fe224cec5400a69cd755ddc4ddcb (diff) |
crypto: user - Fix lookup of algorithms with IV generator
We lookup algorithms with crypto_alg_mod_lookup() when instantiating via
crypto_add_alg(). However, algorithms that are wrapped by an IV genearator
(e.g. aead or genicv type algorithms) need special care. The userspace
process hangs until it gets a timeout when we use crypto_alg_mod_lookup()
to lookup these algorithms. So export the lookup functions for these
algorithms and use them in crypto_add_alg().
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/ablkcipher.c | 4 | ||||
-rw-r--r-- | crypto/aead.c | 4 | ||||
-rw-r--r-- | crypto/crypto_user.c | 72 |
3 files changed, 75 insertions, 5 deletions
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c index a0f768c1d9aa..8d3a056ebeea 100644 --- a/crypto/ablkcipher.c +++ b/crypto/ablkcipher.c | |||
@@ -613,8 +613,7 @@ out: | |||
613 | return err; | 613 | return err; |
614 | } | 614 | } |
615 | 615 | ||
616 | static struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type, | 616 | struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type, u32 mask) |
617 | u32 mask) | ||
618 | { | 617 | { |
619 | struct crypto_alg *alg; | 618 | struct crypto_alg *alg; |
620 | 619 | ||
@@ -652,6 +651,7 @@ static struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type, | |||
652 | 651 | ||
653 | return ERR_PTR(crypto_givcipher_default(alg, type, mask)); | 652 | return ERR_PTR(crypto_givcipher_default(alg, type, mask)); |
654 | } | 653 | } |
654 | EXPORT_SYMBOL_GPL(crypto_lookup_skcipher); | ||
655 | 655 | ||
656 | int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name, | 656 | int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name, |
657 | u32 type, u32 mask) | 657 | u32 type, u32 mask) |
diff --git a/crypto/aead.c b/crypto/aead.c index 04add3dca6fe..e4cb35159be4 100644 --- a/crypto/aead.c +++ b/crypto/aead.c | |||
@@ -470,8 +470,7 @@ out: | |||
470 | return err; | 470 | return err; |
471 | } | 471 | } |
472 | 472 | ||
473 | static struct crypto_alg *crypto_lookup_aead(const char *name, u32 type, | 473 | struct crypto_alg *crypto_lookup_aead(const char *name, u32 type, u32 mask) |
474 | u32 mask) | ||
475 | { | 474 | { |
476 | struct crypto_alg *alg; | 475 | struct crypto_alg *alg; |
477 | 476 | ||
@@ -503,6 +502,7 @@ static struct crypto_alg *crypto_lookup_aead(const char *name, u32 type, | |||
503 | 502 | ||
504 | return ERR_PTR(crypto_nivaead_default(alg, type, mask)); | 503 | return ERR_PTR(crypto_nivaead_default(alg, type, mask)); |
505 | } | 504 | } |
505 | EXPORT_SYMBOL_GPL(crypto_lookup_aead); | ||
506 | 506 | ||
507 | int crypto_grab_aead(struct crypto_aead_spawn *spawn, const char *name, | 507 | int crypto_grab_aead(struct crypto_aead_spawn *spawn, const char *name, |
508 | u32 type, u32 mask) | 508 | u32 type, u32 mask) |
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c index f76e42bcc6e7..e91c16111ed3 100644 --- a/crypto/crypto_user.c +++ b/crypto/crypto_user.c | |||
@@ -21,9 +21,13 @@ | |||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/crypto.h> | 22 | #include <linux/crypto.h> |
23 | #include <linux/cryptouser.h> | 23 | #include <linux/cryptouser.h> |
24 | #include <linux/sched.h> | ||
24 | #include <net/netlink.h> | 25 | #include <net/netlink.h> |
25 | #include <linux/security.h> | 26 | #include <linux/security.h> |
26 | #include <net/net_namespace.h> | 27 | #include <net/net_namespace.h> |
28 | #include <crypto/internal/aead.h> | ||
29 | #include <crypto/internal/skcipher.h> | ||
30 | |||
27 | #include "internal.h" | 31 | #include "internal.h" |
28 | 32 | ||
29 | DEFINE_MUTEX(crypto_cfg_mutex); | 33 | DEFINE_MUTEX(crypto_cfg_mutex); |
@@ -301,6 +305,60 @@ static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
301 | return crypto_unregister_instance(alg); | 305 | return crypto_unregister_instance(alg); |
302 | } | 306 | } |
303 | 307 | ||
308 | static struct crypto_alg *crypto_user_skcipher_alg(const char *name, u32 type, | ||
309 | u32 mask) | ||
310 | { | ||
311 | int err; | ||
312 | struct crypto_alg *alg; | ||
313 | |||
314 | type = crypto_skcipher_type(type); | ||
315 | mask = crypto_skcipher_mask(mask); | ||
316 | |||
317 | for (;;) { | ||
318 | alg = crypto_lookup_skcipher(name, type, mask); | ||
319 | if (!IS_ERR(alg)) | ||
320 | return alg; | ||
321 | |||
322 | err = PTR_ERR(alg); | ||
323 | if (err != -EAGAIN) | ||
324 | break; | ||
325 | if (signal_pending(current)) { | ||
326 | err = -EINTR; | ||
327 | break; | ||
328 | } | ||
329 | } | ||
330 | |||
331 | return ERR_PTR(err); | ||
332 | } | ||
333 | |||
334 | static struct crypto_alg *crypto_user_aead_alg(const char *name, u32 type, | ||
335 | u32 mask) | ||
336 | { | ||
337 | int err; | ||
338 | struct crypto_alg *alg; | ||
339 | |||
340 | type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV); | ||
341 | type |= CRYPTO_ALG_TYPE_AEAD; | ||
342 | mask &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV); | ||
343 | mask |= CRYPTO_ALG_TYPE_MASK; | ||
344 | |||
345 | for (;;) { | ||
346 | alg = crypto_lookup_aead(name, type, mask); | ||
347 | if (!IS_ERR(alg)) | ||
348 | return alg; | ||
349 | |||
350 | err = PTR_ERR(alg); | ||
351 | if (err != -EAGAIN) | ||
352 | break; | ||
353 | if (signal_pending(current)) { | ||
354 | err = -EINTR; | ||
355 | break; | ||
356 | } | ||
357 | } | ||
358 | |||
359 | return ERR_PTR(err); | ||
360 | } | ||
361 | |||
304 | static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh, | 362 | static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh, |
305 | struct nlattr **attrs) | 363 | struct nlattr **attrs) |
306 | { | 364 | { |
@@ -325,7 +383,19 @@ static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
325 | else | 383 | else |
326 | name = p->cru_name; | 384 | name = p->cru_name; |
327 | 385 | ||
328 | alg = crypto_alg_mod_lookup(name, p->cru_type, p->cru_mask); | 386 | switch (p->cru_type & p->cru_mask & CRYPTO_ALG_TYPE_MASK) { |
387 | case CRYPTO_ALG_TYPE_AEAD: | ||
388 | alg = crypto_user_aead_alg(name, p->cru_type, p->cru_mask); | ||
389 | break; | ||
390 | case CRYPTO_ALG_TYPE_GIVCIPHER: | ||
391 | case CRYPTO_ALG_TYPE_BLKCIPHER: | ||
392 | case CRYPTO_ALG_TYPE_ABLKCIPHER: | ||
393 | alg = crypto_user_skcipher_alg(name, p->cru_type, p->cru_mask); | ||
394 | break; | ||
395 | default: | ||
396 | alg = crypto_alg_mod_lookup(name, p->cru_type, p->cru_mask); | ||
397 | } | ||
398 | |||
329 | if (IS_ERR(alg)) | 399 | if (IS_ERR(alg)) |
330 | return PTR_ERR(alg); | 400 | return PTR_ERR(alg); |
331 | 401 | ||