aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/api.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2006-09-20 21:35:17 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2006-09-20 21:35:17 -0400
commit492e2b63eb10c28f4f0b694264d74a8755cd1be0 (patch)
treed882a2df15d939b2edf9064963d73c71c5985b9b /crypto/api.c
parent2b8c19dbdc692e81243a328725a02efb77b144a5 (diff)
[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 <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
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);