diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-02 09:40:24 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-02 09:40:24 -0700 |
commit | 8f6b7676ceecc1f40df77d5a4d6a8bae87594a2d (patch) | |
tree | aaac7c2858dab9817af579f2ad39f2f18ce4dbd8 /crypto/crypto_user.c | |
parent | 143418d0c87fda0c587205c45094d8b05222fd49 (diff) | |
parent | 5219a5342ab13650ae0f0c62319407268c48d0ab (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto fixes from Herbert Xu:
- Fix for CPU hotplug hang in padata.
- Avoid using cpu_active inappropriately in pcrypt and padata.
- Fix for user-space algorithm lookup hang with IV generators.
- Fix for netlink dump of algorithms where stuff went missing due to
incorrect calculation of message size.
* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6:
crypto: user - Fix size of netlink dump message
crypto: user - Fix lookup of algorithms with IV generator
crypto: pcrypt - Use the online cpumask as the default
padata: Fix cpu hotplug
padata: Use the online cpumask as the default
padata: Add a reference to the api documentation
Diffstat (limited to 'crypto/crypto_user.c')
-rw-r--r-- | crypto/crypto_user.c | 80 |
1 files changed, 79 insertions, 1 deletions
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c index f76e42bcc6e7..f1ea0a064135 100644 --- a/crypto/crypto_user.c +++ b/crypto/crypto_user.c @@ -21,9 +21,13 @@ #include <linux/module.h> #include <linux/crypto.h> #include <linux/cryptouser.h> +#include <linux/sched.h> #include <net/netlink.h> #include <linux/security.h> #include <net/net_namespace.h> +#include <crypto/internal/aead.h> +#include <crypto/internal/skcipher.h> + #include "internal.h" DEFINE_MUTEX(crypto_cfg_mutex); @@ -301,6 +305,60 @@ static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh, return crypto_unregister_instance(alg); } +static struct crypto_alg *crypto_user_skcipher_alg(const char *name, u32 type, + u32 mask) +{ + int err; + struct crypto_alg *alg; + + type = crypto_skcipher_type(type); + mask = crypto_skcipher_mask(mask); + + for (;;) { + alg = crypto_lookup_skcipher(name, type, mask); + if (!IS_ERR(alg)) + return alg; + + err = PTR_ERR(alg); + if (err != -EAGAIN) + break; + if (signal_pending(current)) { + err = -EINTR; + break; + } + } + + return ERR_PTR(err); +} + +static struct crypto_alg *crypto_user_aead_alg(const char *name, u32 type, + u32 mask) +{ + int err; + struct crypto_alg *alg; + + type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV); + type |= CRYPTO_ALG_TYPE_AEAD; + mask &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV); + mask |= CRYPTO_ALG_TYPE_MASK; + + for (;;) { + alg = crypto_lookup_aead(name, type, mask); + if (!IS_ERR(alg)) + return alg; + + err = PTR_ERR(alg); + if (err != -EAGAIN) + break; + if (signal_pending(current)) { + err = -EINTR; + break; + } + } + + return ERR_PTR(err); +} + static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh, struct nlattr **attrs) { @@ -325,7 +383,19 @@ static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh, else name = p->cru_name; - alg = crypto_alg_mod_lookup(name, p->cru_type, p->cru_mask); + switch (p->cru_type & p->cru_mask & CRYPTO_ALG_TYPE_MASK) { + case CRYPTO_ALG_TYPE_AEAD: + alg = crypto_user_aead_alg(name, p->cru_type, p->cru_mask); + break; + case CRYPTO_ALG_TYPE_GIVCIPHER: + case CRYPTO_ALG_TYPE_BLKCIPHER: + case CRYPTO_ALG_TYPE_ABLKCIPHER: + alg = crypto_user_skcipher_alg(name, p->cru_type, p->cru_mask); + break; + default: + alg = crypto_alg_mod_lookup(name, p->cru_type, p->cru_mask); + } + if (IS_ERR(alg)) return PTR_ERR(alg); @@ -387,12 +457,20 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) && (nlh->nlmsg_flags & NLM_F_DUMP))) { + struct crypto_alg *alg; + u16 dump_alloc = 0; + if (link->dump == NULL) return -EINVAL; + + list_for_each_entry(alg, &crypto_alg_list, cra_list) + dump_alloc += CRYPTO_REPORT_MAXSIZE; + { struct netlink_dump_control c = { .dump = link->dump, .done = link->done, + .min_dump_alloc = dump_alloc, }; return netlink_dump_start(crypto_nlsk, skb, nlh, &c); } |