aboutsummaryrefslogtreecommitdiffstats
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
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>
-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 @@
21 21
22static LIST_HEAD(crypto_template_list); 22static LIST_HEAD(crypto_template_list);
23 23
24void crypto_larval_error(const char *name) 24void crypto_larval_error(const char *name, u32 type, u32 mask)
25{ 25{
26 struct crypto_alg *alg; 26 struct crypto_alg *alg;
27 27
28 down_read(&crypto_alg_sem); 28 down_read(&crypto_alg_sem);
29 alg = __crypto_alg_lookup(name); 29 alg = __crypto_alg_lookup(name, type, mask);
30 up_read(&crypto_alg_sem); 30 up_read(&crypto_alg_sem);
31 31
32 if (alg) { 32 if (alg) {
@@ -87,6 +87,8 @@ static int __crypto_register_alg(struct crypto_alg *alg)
87 !strcmp(alg->cra_driver_name, q->cra_name))) { 87 !strcmp(alg->cra_driver_name, q->cra_name))) {
88 struct crypto_larval *larval = (void *)q; 88 struct crypto_larval *larval = (void *)q;
89 89
90 if ((q->cra_flags ^ alg->cra_flags) & larval->mask)
91 continue;
90 if (!crypto_mod_get(alg)) 92 if (!crypto_mod_get(alg))
91 continue; 93 continue;
92 larval->adult = alg; 94 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)
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);
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 {
31 } alg; 31 } alg;
32 32
33 struct { 33 struct {
34 u32 type;
35 u32 mask;
34 char name[CRYPTO_MAX_ALG_NAME]; 36 char name[CRYPTO_MAX_ALG_NAME];
35 } larval; 37 } larval;
36 38
@@ -62,7 +64,8 @@ out:
62 return; 64 return;
63 65
64err: 66err:
65 crypto_larval_error(param->larval.name); 67 crypto_larval_error(param->larval.name, param->larval.type,
68 param->larval.mask);
66 goto out; 69 goto out;
67} 70}
68 71
@@ -101,6 +104,8 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
101 param->alg.data.name[len] = 0; 104 param->alg.data.name[len] = 0;
102 105
103 memcpy(param->larval.name, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME); 106 memcpy(param->larval.name, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME);
107 param->larval.type = larval->alg.cra_flags;
108 param->larval.mask = larval->mask;
104 109
105 INIT_WORK(&param->work, cryptomgr_probe, param); 110 INIT_WORK(&param->work, cryptomgr_probe, param);
106 schedule_work(&param->work); 111 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 {
43 struct crypto_alg alg; 43 struct crypto_alg alg;
44 struct crypto_alg *adult; 44 struct crypto_alg *adult;
45 struct completion completion; 45 struct completion completion;
46 u32 mask;
46}; 47};
47 48
48extern struct list_head crypto_alg_list; 49extern struct list_head crypto_alg_list;
@@ -124,7 +125,8 @@ static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg,
124 125
125struct crypto_alg *crypto_mod_get(struct crypto_alg *alg); 126struct crypto_alg *crypto_mod_get(struct crypto_alg *alg);
126void crypto_mod_put(struct crypto_alg *alg); 127void crypto_mod_put(struct crypto_alg *alg);
127struct crypto_alg *__crypto_alg_lookup(const char *name); 128struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask);
129struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask);
128 130
129int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags); 131int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
130int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags); 132int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
@@ -138,7 +140,7 @@ void crypto_exit_digest_ops(struct crypto_tfm *tfm);
138void crypto_exit_cipher_ops(struct crypto_tfm *tfm); 140void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
139void crypto_exit_compress_ops(struct crypto_tfm *tfm); 141void crypto_exit_compress_ops(struct crypto_tfm *tfm);
140 142
141void crypto_larval_error(const char *name); 143void crypto_larval_error(const char *name, u32 type, u32 mask);
142 144
143int crypto_register_instance(struct crypto_template *tmpl, 145int crypto_register_instance(struct crypto_template *tmpl,
144 struct crypto_instance *inst); 146 struct crypto_instance *inst);