aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-01-01 02:37:02 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2007-05-02 00:38:31 -0400
commitebc610e5bc76df073221e64e86c3f7533a09ea40 (patch)
treed53f4fa3da412f6df4b5891e23ca7c7607a3a5ce
parent6158efc09016d3186263f6fd3a50667446ec4008 (diff)
[CRYPTO] templates: Pass type/mask when creating instances
This patch passes the type/mask along when constructing instances of templates. This is in preparation for templates that may support multiple types of instances depending on what is requested. For example, the planned software async crypto driver will use this construct. For the moment this allows us to check whether the instance constructed is of the correct type and avoid returning success if the type does not match. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/algapi.c42
-rw-r--r--crypto/cbc.c11
-rw-r--r--crypto/cryptomgr.c28
-rw-r--r--crypto/ecb.c11
-rw-r--r--crypto/hmac.c11
-rw-r--r--crypto/lrw.c11
-rw-r--r--crypto/pcbc.c11
-rw-r--r--crypto/xcbc.c12
-rw-r--r--include/crypto/algapi.h8
-rw-r--r--include/linux/crypto.h9
10 files changed, 117 insertions, 37 deletions
diff --git a/crypto/algapi.c b/crypto/algapi.c
index f7d2185b2c8f..491205e11cbe 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -425,15 +425,45 @@ int crypto_unregister_notifier(struct notifier_block *nb)
425} 425}
426EXPORT_SYMBOL_GPL(crypto_unregister_notifier); 426EXPORT_SYMBOL_GPL(crypto_unregister_notifier);
427 427
428struct crypto_alg *crypto_get_attr_alg(void *param, unsigned int len, 428struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb)
429 u32 type, u32 mask)
430{ 429{
431 struct rtattr *rta = param; 430 struct rtattr *rta = tb[CRYPTOA_TYPE - 1];
431 struct crypto_attr_type *algt;
432
433 if (!rta)
434 return ERR_PTR(-ENOENT);
435 if (RTA_PAYLOAD(rta) < sizeof(*algt))
436 return ERR_PTR(-EINVAL);
437
438 algt = RTA_DATA(rta);
439
440 return algt;
441}
442EXPORT_SYMBOL_GPL(crypto_get_attr_type);
443
444int crypto_check_attr_type(struct rtattr **tb, u32 type)
445{
446 struct crypto_attr_type *algt;
447
448 algt = crypto_get_attr_type(tb);
449 if (IS_ERR(algt))
450 return PTR_ERR(algt);
451
452 if ((algt->type ^ type) & algt->mask)
453 return -EINVAL;
454
455 return 0;
456}
457EXPORT_SYMBOL_GPL(crypto_check_attr_type);
458
459struct crypto_alg *crypto_get_attr_alg(struct rtattr **tb, u32 type, u32 mask)
460{
461 struct rtattr *rta = tb[CRYPTOA_ALG - 1];
432 struct crypto_attr_alg *alga; 462 struct crypto_attr_alg *alga;
433 463
434 if (!RTA_OK(rta, len)) 464 if (!rta)
435 return ERR_PTR(-EBADR); 465 return ERR_PTR(-ENOENT);
436 if (rta->rta_type != CRYPTOA_ALG || RTA_PAYLOAD(rta) < sizeof(*alga)) 466 if (RTA_PAYLOAD(rta) < sizeof(*alga))
437 return ERR_PTR(-EINVAL); 467 return ERR_PTR(-EINVAL);
438 468
439 alga = RTA_DATA(rta); 469 alga = RTA_DATA(rta);
diff --git a/crypto/cbc.c b/crypto/cbc.c
index 136fea7e7000..1f2649e13b42 100644
--- a/crypto/cbc.c
+++ b/crypto/cbc.c
@@ -275,13 +275,18 @@ static void crypto_cbc_exit_tfm(struct crypto_tfm *tfm)
275 crypto_free_cipher(ctx->child); 275 crypto_free_cipher(ctx->child);
276} 276}
277 277
278static struct crypto_instance *crypto_cbc_alloc(void *param, unsigned int len) 278static struct crypto_instance *crypto_cbc_alloc(struct rtattr **tb)
279{ 279{
280 struct crypto_instance *inst; 280 struct crypto_instance *inst;
281 struct crypto_alg *alg; 281 struct crypto_alg *alg;
282 int err;
283
284 err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER);
285 if (err)
286 return ERR_PTR(err);
282 287
283 alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER, 288 alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER,
284 CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); 289 CRYPTO_ALG_TYPE_MASK);
285 if (IS_ERR(alg)) 290 if (IS_ERR(alg))
286 return ERR_PTR(PTR_ERR(alg)); 291 return ERR_PTR(PTR_ERR(alg));
287 292
diff --git a/crypto/cryptomgr.c b/crypto/cryptomgr.c
index 2ebffb84f1d9..7a3df9b41218 100644
--- a/crypto/cryptomgr.c
+++ b/crypto/cryptomgr.c
@@ -26,14 +26,19 @@
26struct cryptomgr_param { 26struct cryptomgr_param {
27 struct work_struct work; 27 struct work_struct work;
28 28
29 struct rtattr *tb[CRYPTOA_MAX];
30
31 struct {
32 struct rtattr attr;
33 struct crypto_attr_type data;
34 } type;
35
29 struct { 36 struct {
30 struct rtattr attr; 37 struct rtattr attr;
31 struct crypto_attr_alg data; 38 struct crypto_attr_alg data;
32 } alg; 39 } alg;
33 40
34 struct { 41 struct {
35 u32 type;
36 u32 mask;
37 char name[CRYPTO_MAX_ALG_NAME]; 42 char name[CRYPTO_MAX_ALG_NAME];
38 } larval; 43 } larval;
39 44
@@ -53,7 +58,7 @@ static void cryptomgr_probe(struct work_struct *work)
53 goto err; 58 goto err;
54 59
55 do { 60 do {
56 inst = tmpl->alloc(&param->alg, sizeof(param->alg)); 61 inst = tmpl->alloc(param->tb);
57 if (IS_ERR(inst)) 62 if (IS_ERR(inst))
58 err = PTR_ERR(inst); 63 err = PTR_ERR(inst);
59 else if ((err = crypto_register_instance(tmpl, inst))) 64 else if ((err = crypto_register_instance(tmpl, inst)))
@@ -70,8 +75,8 @@ out:
70 return; 75 return;
71 76
72err: 77err:
73 crypto_larval_error(param->larval.name, param->larval.type, 78 crypto_larval_error(param->larval.name, param->type.data.type,
74 param->larval.mask); 79 param->type.data.mask);
75 goto out; 80 goto out;
76} 81}
77 82
@@ -82,7 +87,7 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
82 const char *p; 87 const char *p;
83 unsigned int len; 88 unsigned int len;
84 89
85 param = kmalloc(sizeof(*param), GFP_KERNEL); 90 param = kzalloc(sizeof(*param), GFP_KERNEL);
86 if (!param) 91 if (!param)
87 goto err; 92 goto err;
88 93
@@ -94,7 +99,6 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
94 goto err_free_param; 99 goto err_free_param;
95 100
96 memcpy(param->template, name, len); 101 memcpy(param->template, name, len);
97 param->template[len] = 0;
98 102
99 name = p + 1; 103 name = p + 1;
100 for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++) 104 for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++)
@@ -104,14 +108,18 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
104 if (!len || *p != ')' || p[1]) 108 if (!len || *p != ')' || p[1])
105 goto err_free_param; 109 goto err_free_param;
106 110
111 param->type.attr.rta_len = sizeof(param->type);
112 param->type.attr.rta_type = CRYPTOA_TYPE;
113 param->type.data.type = larval->alg.cra_flags;
114 param->type.data.mask = larval->mask;
115 param->tb[CRYPTOA_TYPE - 1] = &param->type.attr;
116
107 param->alg.attr.rta_len = sizeof(param->alg); 117 param->alg.attr.rta_len = sizeof(param->alg);
108 param->alg.attr.rta_type = CRYPTOA_ALG; 118 param->alg.attr.rta_type = CRYPTOA_ALG;
109 memcpy(param->alg.data.name, name, len); 119 memcpy(param->alg.data.name, name, len);
110 param->alg.data.name[len] = 0; 120 param->tb[CRYPTOA_ALG - 1] = &param->alg.attr;
111 121
112 memcpy(param->larval.name, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME); 122 memcpy(param->larval.name, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME);
113 param->larval.type = larval->alg.cra_flags;
114 param->larval.mask = larval->mask;
115 123
116 INIT_WORK(&param->work, cryptomgr_probe); 124 INIT_WORK(&param->work, cryptomgr_probe);
117 schedule_work(&param->work); 125 schedule_work(&param->work);
diff --git a/crypto/ecb.c b/crypto/ecb.c
index 839a0aed8c22..6310387a872c 100644
--- a/crypto/ecb.c
+++ b/crypto/ecb.c
@@ -115,13 +115,18 @@ static void crypto_ecb_exit_tfm(struct crypto_tfm *tfm)
115 crypto_free_cipher(ctx->child); 115 crypto_free_cipher(ctx->child);
116} 116}
117 117
118static struct crypto_instance *crypto_ecb_alloc(void *param, unsigned int len) 118static struct crypto_instance *crypto_ecb_alloc(struct rtattr **tb)
119{ 119{
120 struct crypto_instance *inst; 120 struct crypto_instance *inst;
121 struct crypto_alg *alg; 121 struct crypto_alg *alg;
122 int err;
123
124 err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER);
125 if (err)
126 return ERR_PTR(err);
122 127
123 alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER, 128 alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER,
124 CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); 129 CRYPTO_ALG_TYPE_MASK);
125 if (IS_ERR(alg)) 130 if (IS_ERR(alg))
126 return ERR_PTR(PTR_ERR(alg)); 131 return ERR_PTR(PTR_ERR(alg));
127 132
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 44187c5ee593..8802fb6dd5a6 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -197,13 +197,18 @@ static void hmac_free(struct crypto_instance *inst)
197 kfree(inst); 197 kfree(inst);
198} 198}
199 199
200static struct crypto_instance *hmac_alloc(void *param, unsigned int len) 200static struct crypto_instance *hmac_alloc(struct rtattr **tb)
201{ 201{
202 struct crypto_instance *inst; 202 struct crypto_instance *inst;
203 struct crypto_alg *alg; 203 struct crypto_alg *alg;
204 int err;
205
206 err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_HASH);
207 if (err)
208 return ERR_PTR(err);
204 209
205 alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_HASH, 210 alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_HASH,
206 CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC); 211 CRYPTO_ALG_TYPE_HASH_MASK);
207 if (IS_ERR(alg)) 212 if (IS_ERR(alg))
208 return ERR_PTR(PTR_ERR(alg)); 213 return ERR_PTR(PTR_ERR(alg));
209 214
diff --git a/crypto/lrw.c b/crypto/lrw.c
index b4105080ac7a..621095db28b3 100644
--- a/crypto/lrw.c
+++ b/crypto/lrw.c
@@ -228,13 +228,18 @@ static void exit_tfm(struct crypto_tfm *tfm)
228 crypto_free_cipher(ctx->child); 228 crypto_free_cipher(ctx->child);
229} 229}
230 230
231static struct crypto_instance *alloc(void *param, unsigned int len) 231static struct crypto_instance *alloc(struct rtattr **tb)
232{ 232{
233 struct crypto_instance *inst; 233 struct crypto_instance *inst;
234 struct crypto_alg *alg; 234 struct crypto_alg *alg;
235 int err;
236
237 err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER);
238 if (err)
239 return ERR_PTR(err);
235 240
236 alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER, 241 alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER,
237 CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); 242 CRYPTO_ALG_TYPE_MASK);
238 if (IS_ERR(alg)) 243 if (IS_ERR(alg))
239 return ERR_PTR(PTR_ERR(alg)); 244 return ERR_PTR(PTR_ERR(alg));
240 245
diff --git a/crypto/pcbc.c b/crypto/pcbc.c
index 5174d7fdad6e..c3ed8a1c9f46 100644
--- a/crypto/pcbc.c
+++ b/crypto/pcbc.c
@@ -279,13 +279,18 @@ static void crypto_pcbc_exit_tfm(struct crypto_tfm *tfm)
279 crypto_free_cipher(ctx->child); 279 crypto_free_cipher(ctx->child);
280} 280}
281 281
282static struct crypto_instance *crypto_pcbc_alloc(void *param, unsigned int len) 282static struct crypto_instance *crypto_pcbc_alloc(struct rtattr **tb)
283{ 283{
284 struct crypto_instance *inst; 284 struct crypto_instance *inst;
285 struct crypto_alg *alg; 285 struct crypto_alg *alg;
286 int err;
287
288 err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER);
289 if (err)
290 return ERR_PTR(err);
286 291
287 alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER, 292 alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER,
288 CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC); 293 CRYPTO_ALG_TYPE_MASK);
289 if (IS_ERR(alg)) 294 if (IS_ERR(alg))
290 return ERR_PTR(PTR_ERR(alg)); 295 return ERR_PTR(PTR_ERR(alg));
291 296
diff --git a/crypto/xcbc.c b/crypto/xcbc.c
index 53e8ccbf0f5f..9f502b86e0ea 100644
--- a/crypto/xcbc.c
+++ b/crypto/xcbc.c
@@ -288,12 +288,18 @@ static void xcbc_exit_tfm(struct crypto_tfm *tfm)
288 crypto_free_cipher(ctx->child); 288 crypto_free_cipher(ctx->child);
289} 289}
290 290
291static struct crypto_instance *xcbc_alloc(void *param, unsigned int len) 291static struct crypto_instance *xcbc_alloc(struct rtattr **tb)
292{ 292{
293 struct crypto_instance *inst; 293 struct crypto_instance *inst;
294 struct crypto_alg *alg; 294 struct crypto_alg *alg;
295 alg = crypto_get_attr_alg(param, len, CRYPTO_ALG_TYPE_CIPHER, 295 int err;
296 CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC); 296
297 err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_HASH);
298 if (err)
299 return ERR_PTR(err);
300
301 alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER,
302 CRYPTO_ALG_TYPE_MASK);
297 if (IS_ERR(alg)) 303 if (IS_ERR(alg))
298 return ERR_PTR(PTR_ERR(alg)); 304 return ERR_PTR(PTR_ERR(alg));
299 305
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
index 4e05e93ff681..d0c190b4d02f 100644
--- a/include/crypto/algapi.h
+++ b/include/crypto/algapi.h
@@ -15,6 +15,7 @@
15#include <linux/crypto.h> 15#include <linux/crypto.h>
16 16
17struct module; 17struct module;
18struct rtattr;
18struct seq_file; 19struct seq_file;
19 20
20struct crypto_type { 21struct crypto_type {
@@ -38,7 +39,7 @@ struct crypto_template {
38 struct hlist_head instances; 39 struct hlist_head instances;
39 struct module *module; 40 struct module *module;
40 41
41 struct crypto_instance *(*alloc)(void *param, unsigned int len); 42 struct crypto_instance *(*alloc)(struct rtattr **tb);
42 void (*free)(struct crypto_instance *inst); 43 void (*free)(struct crypto_instance *inst);
43 44
44 char name[CRYPTO_MAX_ALG_NAME]; 45 char name[CRYPTO_MAX_ALG_NAME];
@@ -96,8 +97,9 @@ void crypto_drop_spawn(struct crypto_spawn *spawn);
96struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type, 97struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type,
97 u32 mask); 98 u32 mask);
98 99
99struct crypto_alg *crypto_get_attr_alg(void *param, unsigned int len, 100struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb);
100 u32 type, u32 mask); 101int crypto_check_attr_type(struct rtattr **tb, u32 type);
102struct crypto_alg *crypto_get_attr_alg(struct rtattr **tb, u32 type, u32 mask);
101struct crypto_instance *crypto_alloc_instance(const char *name, 103struct crypto_instance *crypto_alloc_instance(const char *name,
102 struct crypto_alg *alg); 104 struct crypto_alg *alg);
103 105
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index d4d05313280c..67830e7c2c31 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -372,12 +372,21 @@ struct crypto_hash {
372enum { 372enum {
373 CRYPTOA_UNSPEC, 373 CRYPTOA_UNSPEC,
374 CRYPTOA_ALG, 374 CRYPTOA_ALG,
375 CRYPTOA_TYPE,
376 __CRYPTOA_MAX,
375}; 377};
376 378
379#define CRYPTOA_MAX (__CRYPTOA_MAX - 1)
380
377struct crypto_attr_alg { 381struct crypto_attr_alg {
378 char name[CRYPTO_MAX_ALG_NAME]; 382 char name[CRYPTO_MAX_ALG_NAME];
379}; 383};
380 384
385struct crypto_attr_type {
386 u32 type;
387 u32 mask;
388};
389
381/* 390/*
382 * Transform user interface. 391 * Transform user interface.
383 */ 392 */