aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/api.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/api.c')
-rw-r--r--crypto/api.c39
1 files changed, 26 insertions, 13 deletions
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)
57} 57}
58EXPORT_SYMBOL_GPL(crypto_mod_put); 58EXPORT_SYMBOL_GPL(crypto_mod_put);
59 59
60struct crypto_alg *__crypto_alg_lookup(const char *name) 60struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask)
61{ 61{
62 struct crypto_alg *q, *alg = NULL; 62 struct crypto_alg *q, *alg = NULL;
63 int best = -2; 63 int best = -2;
@@ -65,6 +65,13 @@ struct crypto_alg *__crypto_alg_lookup(const char *name)
65 list_for_each_entry(q, &crypto_alg_list, cra_list) { 65 list_for_each_entry(q, &crypto_alg_list, cra_list) {
66 int exact, fuzzy; 66 int exact, fuzzy;
67 67
68 if ((q->cra_flags ^ type) & mask)
69 continue;
70
71 if (crypto_is_larval(q) &&
72 ((struct crypto_larval *)q)->mask != mask)
73 continue;
74
68 exact = !strcmp(q->cra_driver_name, name); 75 exact = !strcmp(q->cra_driver_name, name);
69 fuzzy = !strcmp(q->cra_name, name); 76 fuzzy = !strcmp(q->cra_name, name);
70 if (!exact && !(fuzzy && q->cra_priority > best)) 77 if (!exact && !(fuzzy && q->cra_priority > best))
@@ -96,7 +103,8 @@ static void crypto_larval_destroy(struct crypto_alg *alg)
96 kfree(larval); 103 kfree(larval);
97} 104}
98 105
99static struct crypto_alg *crypto_larval_alloc(const char *name) 106static struct crypto_alg *crypto_larval_alloc(const char *name, u32 type,
107 u32 mask)
100{ 108{
101 struct crypto_alg *alg; 109 struct crypto_alg *alg;
102 struct crypto_larval *larval; 110 struct crypto_larval *larval;
@@ -105,7 +113,8 @@ static struct crypto_alg *crypto_larval_alloc(const char *name)
105 if (!larval) 113 if (!larval)
106 return NULL; 114 return NULL;
107 115
108 larval->alg.cra_flags = CRYPTO_ALG_LARVAL; 116 larval->mask = mask;
117 larval->alg.cra_flags = CRYPTO_ALG_LARVAL | type;
109 larval->alg.cra_priority = -1; 118 larval->alg.cra_priority = -1;
110 larval->alg.cra_destroy = crypto_larval_destroy; 119 larval->alg.cra_destroy = crypto_larval_destroy;
111 120
@@ -114,7 +123,7 @@ static struct crypto_alg *crypto_larval_alloc(const char *name)
114 init_completion(&larval->completion); 123 init_completion(&larval->completion);
115 124
116 down_write(&crypto_alg_sem); 125 down_write(&crypto_alg_sem);
117 alg = __crypto_alg_lookup(name); 126 alg = __crypto_alg_lookup(name, type, mask);
118 if (!alg) { 127 if (!alg) {
119 alg = &larval->alg; 128 alg = &larval->alg;
120 list_add(&alg->cra_list, &crypto_alg_list); 129 list_add(&alg->cra_list, &crypto_alg_list);
@@ -151,7 +160,8 @@ static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
151 return alg; 160 return alg;
152} 161}
153 162
154static struct crypto_alg *crypto_alg_lookup(const char *name) 163static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
164 u32 mask)
155{ 165{
156 struct crypto_alg *alg; 166 struct crypto_alg *alg;
157 167
@@ -159,25 +169,27 @@ static struct crypto_alg *crypto_alg_lookup(const char *name)
159 return NULL; 169 return NULL;
160 170
161 down_read(&crypto_alg_sem); 171 down_read(&crypto_alg_sem);
162 alg = __crypto_alg_lookup(name); 172 alg = __crypto_alg_lookup(name, type, mask);
163 up_read(&crypto_alg_sem); 173 up_read(&crypto_alg_sem);
164 174
165 return alg; 175 return alg;
166} 176}
167 177
168/* A far more intelligent version of this is planned. For now, just 178struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
169 * try an exact match on the name of the algorithm. */
170static struct crypto_alg *crypto_alg_mod_lookup(const char *name)
171{ 179{
172 struct crypto_alg *alg; 180 struct crypto_alg *alg;
173 struct crypto_alg *larval; 181 struct crypto_alg *larval;
174 int ok; 182 int ok;
175 183
176 alg = try_then_request_module(crypto_alg_lookup(name), name); 184 mask &= ~CRYPTO_ALG_LARVAL;
185 type &= mask;
186
187 alg = try_then_request_module(crypto_alg_lookup(name, type, mask),
188 name);
177 if (alg) 189 if (alg)
178 return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg; 190 return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg;
179 191
180 larval = crypto_larval_alloc(name); 192 larval = crypto_larval_alloc(name, type, mask);
181 if (!larval || !crypto_is_larval(larval)) 193 if (!larval || !crypto_is_larval(larval))
182 return larval; 194 return larval;
183 195
@@ -196,6 +208,7 @@ static struct crypto_alg *crypto_alg_mod_lookup(const char *name)
196 crypto_larval_kill(larval); 208 crypto_larval_kill(larval);
197 return alg; 209 return alg;
198} 210}
211EXPORT_SYMBOL_GPL(crypto_alg_mod_lookup);
199 212
200static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags) 213static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
201{ 214{
@@ -291,7 +304,7 @@ struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
291 struct crypto_alg *alg; 304 struct crypto_alg *alg;
292 unsigned int tfm_size; 305 unsigned int tfm_size;
293 306
294 alg = crypto_alg_mod_lookup(name); 307 alg = crypto_alg_mod_lookup(name, 0, 0);
295 if (alg == NULL) 308 if (alg == NULL)
296 goto out; 309 goto out;
297 310
@@ -346,7 +359,7 @@ void crypto_free_tfm(struct crypto_tfm *tfm)
346int crypto_alg_available(const char *name, u32 flags) 359int crypto_alg_available(const char *name, u32 flags)
347{ 360{
348 int ret = 0; 361 int ret = 0;
349 struct crypto_alg *alg = crypto_alg_mod_lookup(name); 362 struct crypto_alg *alg = crypto_alg_mod_lookup(name, 0, 0);
350 363
351 if (alg) { 364 if (alg) {
352 crypto_mod_put(alg); 365 crypto_mod_put(alg);