Hi:

[CRYPTO] api: Allow algorithm lookup by type

This patch also adds the infrastructure to pick an algorithm based on
their type.  For example, this allows you to select the encryption
algorithm "aes", instead of any algorithm registered under the name
"aes".  For now this is only accessible internally.  Eventually it
will be made available through crypto_alloc_tfm.

Signed-off-by: Herbert Xu <[EMAIL PROTECTED]>

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[EMAIL PROTECTED]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff --git a/crypto/api.c b/crypto/api.c
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -53,11 +53,12 @@ static struct crypto_alg *crypto_mod_get
        return try_module_get(alg->cra_module) ? crypto_alg_get(alg) : NULL;
 }
 
-static void crypto_mod_put(struct crypto_alg *alg)
+void crypto_mod_put(struct crypto_alg *alg)
 {
        crypto_alg_put(alg);
        module_put(alg->cra_module);
 }
+EXPORT_SYMBOL_GPL(crypto_mod_put);
 
 static inline int crypto_is_larval(struct crypto_alg *alg)
 {
@@ -69,7 +70,8 @@ static inline int crypto_notify(unsigned
        return blocking_notifier_call_chain(&crypto_chain, val, v);
 }
 
-static struct crypto_alg *__crypto_alg_lookup(const char *name)
+static struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type,
+                                             u32 mask)
 {
        struct crypto_alg *q, *alg = NULL;
        int best = -2;
@@ -77,6 +79,13 @@ static struct crypto_alg *__crypto_alg_l
        list_for_each_entry(q, &crypto_alg_list, cra_list) {
                int exact, fuzzy;
 
+               if ((q->cra_flags ^ type) & mask)
+                       continue;
+
+               if (crypto_is_larval(q) &&
+                   ((struct crypto_larval *)q)->mask != mask)
+                       continue;
+
                exact = !strcmp(q->cra_driver_name, name);
                fuzzy = !strcmp(q->cra_name, name);
                if (!exact && !(fuzzy && q->cra_priority > best))
@@ -107,7 +116,8 @@ static void crypto_larval_destroy(struct
        kfree(larval);
 }
 
-static struct crypto_alg *crypto_larval_alloc(const char *name)
+static struct crypto_alg *crypto_larval_alloc(const char *name, u32 type,
+                                             u32 mask)
 {
        struct crypto_alg *alg;
        struct crypto_larval *larval;
@@ -116,7 +126,8 @@ static struct crypto_alg *crypto_larval_
        if (!larval)
                return NULL;
 
-       larval->alg.cra_flags = CRYPTO_ALG_LARVAL;
+       larval->mask = mask;
+       larval->alg.cra_flags = CRYPTO_ALG_LARVAL | type;
        larval->alg.cra_priority = -1;
        larval->alg.cra_destroy = crypto_larval_destroy;
 
@@ -125,7 +136,7 @@ static struct crypto_alg *crypto_larval_
        init_completion(&larval->completion);
 
        down_write(&crypto_alg_sem);
-       alg = __crypto_alg_lookup(name);
+       alg = __crypto_alg_lookup(name, type, mask);
        if (!alg) {
                alg = &larval->alg;
                list_add(&alg->cra_list, &crypto_alg_list);
@@ -162,12 +173,12 @@ static struct crypto_alg *crypto_larval_
        return alg;
 }
 
-void crypto_larval_error(const char *name)
+void crypto_larval_error(const char *name, u32 type, u32 mask)
 {
        struct crypto_alg *alg;
 
        down_read(&crypto_alg_sem);
-       alg = __crypto_alg_lookup(name);
+       alg = __crypto_alg_lookup(name, type, mask);
        up_read(&crypto_alg_sem);
 
        if (alg) {
@@ -180,7 +191,8 @@ void crypto_larval_error(const char *nam
 }
 EXPORT_SYMBOL_GPL(crypto_larval_error);
 
-static struct crypto_alg *crypto_alg_lookup(const char *name)
+static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
+                                           u32 mask)
 {
        struct crypto_alg *alg;
 
@@ -188,25 +200,27 @@ static struct crypto_alg *crypto_alg_loo
                return NULL;
 
        down_read(&crypto_alg_sem);
-       alg = __crypto_alg_lookup(name);
+       alg = __crypto_alg_lookup(name, type, mask);
        up_read(&crypto_alg_sem);
 
        return alg;
 }
 
-/* A far more intelligent version of this is planned.  For now, just
- * try an exact match on the name of the algorithm. */
-static struct crypto_alg *crypto_alg_mod_lookup(const char *name)
+struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
 {
        struct crypto_alg *alg;
        struct crypto_alg *larval;
        int ok;
 
-       alg = try_then_request_module(crypto_alg_lookup(name), name);
+       mask &= ~CRYPTO_ALG_LARVAL;
+       type &= mask;
+
+       alg = try_then_request_module(crypto_alg_lookup(name, type, mask),
+                                     name);
        if (alg)
                return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg;
 
-       larval = crypto_larval_alloc(name);
+       larval = crypto_larval_alloc(name, type, mask);
        if (!larval || !crypto_is_larval(larval))
                return larval;
 
@@ -225,6 +239,7 @@ static struct crypto_alg *crypto_alg_mod
        crypto_larval_kill(larval);
        return alg;
 }
+EXPORT_SYMBOL_GPL(crypto_alg_mod_lookup);
 
 static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
 {
@@ -320,7 +335,7 @@ struct crypto_tfm *crypto_alloc_tfm(cons
        struct crypto_alg *alg;
        unsigned int tfm_size;
 
-       alg = crypto_alg_mod_lookup(name);
+       alg = crypto_alg_mod_lookup(name, 0, 0);
        if (alg == NULL)
                goto out;
 
@@ -420,6 +435,8 @@ static int __crypto_register_alg(struct 
                     !strcmp(alg->cra_driver_name, q->cra_name))) {
                        struct crypto_larval *larval = (void *)q;
 
+                       if ((q->cra_flags ^ alg->cra_flags) & larval->mask)
+                               continue;
                        if (!crypto_mod_get(alg))
                                continue;
                        larval->adult = alg;
@@ -582,7 +599,7 @@ EXPORT_SYMBOL_GPL(crypto_register_instan
 int crypto_alg_available(const char *name, u32 flags)
 {
        int ret = 0;
-       struct crypto_alg *alg = crypto_alg_mod_lookup(name);
+       struct crypto_alg *alg = crypto_alg_mod_lookup(name, 0, 0);
        
        if (alg) {
                crypto_mod_put(alg);
diff --git a/crypto/cryptomgr.c b/crypto/cryptomgr.c
--- a/crypto/cryptomgr.c
+++ b/crypto/cryptomgr.c
@@ -80,7 +80,8 @@ static int cryptomgr_probe(struct crypto
        return NOTIFY_STOP;
 
 err:
-       crypto_larval_error(larval->alg.cra_name);
+       crypto_larval_error(larval->alg.cra_name, larval->alg.cra_flags,
+                           larval->mask);
        return NOTIFY_STOP;
 }
 
diff --git a/crypto/internal.h b/crypto/internal.h
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/rwsem.h>
 #include <linux/slab.h>
+#include <linux/types.h>
 #include <asm/kmap_types.h>
 
 /* Crypto notification events. */
@@ -61,6 +62,7 @@ struct crypto_larval {
        struct crypto_alg alg;
        struct crypto_alg *adult;
        struct completion completion;
+       u32 mask;
 };
 
 extern struct list_head crypto_alg_list;
@@ -148,7 +150,9 @@ void crypto_exit_digest_ops(struct crypt
 void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
 void crypto_exit_compress_ops(struct crypto_tfm *tfm);
 
-void crypto_larval_error(const char *name);
+void crypto_mod_put(struct crypto_alg *alg);
+void crypto_larval_error(const char *name, u32 type, u32 mask);
+struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask);
 
 int crypto_register_template(struct crypto_template *tmpl);
 void crypto_unregister_template(struct crypto_template *tmpl);
-
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to