diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2006-09-20 21:35:17 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2006-09-20 21:35:17 -0400 |
commit | 492e2b63eb10c28f4f0b694264d74a8755cd1be0 (patch) | |
tree | d882a2df15d939b2edf9064963d73c71c5985b9b /crypto/api.c | |
parent | 2b8c19dbdc692e81243a328725a02efb77b144a5 (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.c | 39 |
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 | } |
58 | EXPORT_SYMBOL_GPL(crypto_mod_put); | 58 | EXPORT_SYMBOL_GPL(crypto_mod_put); |
59 | 59 | ||
60 | struct crypto_alg *__crypto_alg_lookup(const char *name) | 60 | struct 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 | ||
99 | static struct crypto_alg *crypto_larval_alloc(const char *name) | 106 | static 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 | ||
154 | static struct crypto_alg *crypto_alg_lookup(const char *name) | 163 | static 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 | 178 | struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask) |
169 | * try an exact match on the name of the algorithm. */ | ||
170 | static 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 | } |
211 | EXPORT_SYMBOL_GPL(crypto_alg_mod_lookup); | ||
199 | 212 | ||
200 | static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags) | 213 | static 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) | |||
346 | int crypto_alg_available(const char *name, u32 flags) | 359 | int 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); |