summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/algapi.c6
-rw-r--r--crypto/api.c39
-rw-r--r--crypto/cryptomgr.c7
-rw-r--r--crypto/internal.h6
4 files changed, 40 insertions, 18 deletions
diff --git a/crypto/algapi.c b/crypto/algapi.c
index f0df85fc1f50..acea250677c0 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -21,12 +21,12 @@
static LIST_HEAD(crypto_template_list);
-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) {
@@ -87,6 +87,8 @@ static int __crypto_register_alg(struct crypto_alg *alg)
!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;
diff --git a/crypto/api.c b/crypto/api.c
index 67cd6f87b74a..ddf6a767acdd 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -57,7 +57,7 @@ void crypto_mod_put(struct crypto_alg *alg)
}
EXPORT_SYMBOL_GPL(crypto_mod_put);
-struct crypto_alg *__crypto_alg_lookup(const char *name)
+struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask)
{
struct crypto_alg *q, *alg = NULL;
int best = -2;
@@ -65,6 +65,13 @@ struct crypto_alg *__crypto_alg_lookup(const char *name)
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))
@@ -96,7 +103,8 @@ static void crypto_larval_destroy(struct crypto_alg *alg)
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;
@@ -105,7 +113,8 @@ static struct crypto_alg *crypto_larval_alloc(const char *name)
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;
@@ -114,7 +123,7 @@ static struct crypto_alg *crypto_larval_alloc(const char *name)
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);
@@ -151,7 +160,8 @@ static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
return alg;
}
-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;
@@ -159,25 +169,27 @@ static struct crypto_alg *crypto_alg_lookup(const char *name)
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;
@@ -196,6 +208,7 @@ static struct crypto_alg *crypto_alg_mod_lookup(const char *name)
crypto_larval_kill(larval);
return alg;
}
+EXPORT_SYMBOL_GPL(crypto_alg_mod_lookup);
static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
{
@@ -291,7 +304,7 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
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;
@@ -346,7 +359,7 @@ void crypto_free_tfm(struct crypto_tfm *tfm)
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
index e0ebe1b44b99..ae54942e3b31 100644
--- a/crypto/cryptomgr.c
+++ b/crypto/cryptomgr.c
@@ -31,6 +31,8 @@ struct cryptomgr_param {
} alg;
struct {
+ u32 type;
+ u32 mask;
char name[CRYPTO_MAX_ALG_NAME];
} larval;
@@ -62,7 +64,8 @@ out:
return;
err:
- crypto_larval_error(param->larval.name);
+ crypto_larval_error(param->larval.name, param->larval.type,
+ param->larval.mask);
goto out;
}
@@ -101,6 +104,8 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
param->alg.data.name[len] = 0;
memcpy(param->larval.name, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME);
+ param->larval.type = larval->alg.cra_flags;
+ param->larval.mask = larval->mask;
INIT_WORK(&param->work, cryptomgr_probe, param);
schedule_work(&param->work);
diff --git a/crypto/internal.h b/crypto/internal.h
index 3a08d25fba45..c08d93bdadc4 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -43,6 +43,7 @@ struct crypto_larval {
struct crypto_alg alg;
struct crypto_alg *adult;
struct completion completion;
+ u32 mask;
};
extern struct list_head crypto_alg_list;
@@ -124,7 +125,8 @@ static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg,
struct crypto_alg *crypto_mod_get(struct crypto_alg *alg);
void crypto_mod_put(struct crypto_alg *alg);
-struct crypto_alg *__crypto_alg_lookup(const char *name);
+struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask);
+struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask);
int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
@@ -138,7 +140,7 @@ void crypto_exit_digest_ops(struct crypto_tfm *tfm);
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_larval_error(const char *name, u32 type, u32 mask);
int crypto_register_instance(struct crypto_template *tmpl,
struct crypto_instance *inst);