diff options
-rw-r--r-- | crypto/algapi.c | 42 | ||||
-rw-r--r-- | crypto/cbc.c | 11 | ||||
-rw-r--r-- | crypto/cryptomgr.c | 28 | ||||
-rw-r--r-- | crypto/ecb.c | 11 | ||||
-rw-r--r-- | crypto/hmac.c | 11 | ||||
-rw-r--r-- | crypto/lrw.c | 11 | ||||
-rw-r--r-- | crypto/pcbc.c | 11 | ||||
-rw-r--r-- | crypto/xcbc.c | 12 | ||||
-rw-r--r-- | include/crypto/algapi.h | 8 | ||||
-rw-r--r-- | include/linux/crypto.h | 9 |
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 | } |
426 | EXPORT_SYMBOL_GPL(crypto_unregister_notifier); | 426 | EXPORT_SYMBOL_GPL(crypto_unregister_notifier); |
427 | 427 | ||
428 | struct crypto_alg *crypto_get_attr_alg(void *param, unsigned int len, | 428 | struct 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 | } | ||
442 | EXPORT_SYMBOL_GPL(crypto_get_attr_type); | ||
443 | |||
444 | int 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 | } | ||
457 | EXPORT_SYMBOL_GPL(crypto_check_attr_type); | ||
458 | |||
459 | struct 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 | ||
278 | static struct crypto_instance *crypto_cbc_alloc(void *param, unsigned int len) | 278 | static 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 @@ | |||
26 | struct cryptomgr_param { | 26 | struct 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(¶m->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 | ||
72 | err: | 77 | err: |
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] = ¶m->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] = ¶m->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(¶m->work, cryptomgr_probe); | 124 | INIT_WORK(¶m->work, cryptomgr_probe); |
117 | schedule_work(¶m->work); | 125 | schedule_work(¶m->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 | ||
118 | static struct crypto_instance *crypto_ecb_alloc(void *param, unsigned int len) | 118 | static 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 | ||
200 | static struct crypto_instance *hmac_alloc(void *param, unsigned int len) | 200 | static 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 | ||
231 | static struct crypto_instance *alloc(void *param, unsigned int len) | 231 | static 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 | ||
282 | static struct crypto_instance *crypto_pcbc_alloc(void *param, unsigned int len) | 282 | static 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 | ||
291 | static struct crypto_instance *xcbc_alloc(void *param, unsigned int len) | 291 | static 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 | ||
17 | struct module; | 17 | struct module; |
18 | struct rtattr; | ||
18 | struct seq_file; | 19 | struct seq_file; |
19 | 20 | ||
20 | struct crypto_type { | 21 | struct 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); | |||
96 | struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type, | 97 | struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type, |
97 | u32 mask); | 98 | u32 mask); |
98 | 99 | ||
99 | struct crypto_alg *crypto_get_attr_alg(void *param, unsigned int len, | 100 | struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb); |
100 | u32 type, u32 mask); | 101 | int crypto_check_attr_type(struct rtattr **tb, u32 type); |
102 | struct crypto_alg *crypto_get_attr_alg(struct rtattr **tb, u32 type, u32 mask); | ||
101 | struct crypto_instance *crypto_alloc_instance(const char *name, | 103 | struct 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 { | |||
372 | enum { | 372 | enum { |
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 | |||
377 | struct crypto_attr_alg { | 381 | struct crypto_attr_alg { |
378 | char name[CRYPTO_MAX_ALG_NAME]; | 382 | char name[CRYPTO_MAX_ALG_NAME]; |
379 | }; | 383 | }; |
380 | 384 | ||
385 | struct crypto_attr_type { | ||
386 | u32 type; | ||
387 | u32 mask; | ||
388 | }; | ||
389 | |||
381 | /* | 390 | /* |
382 | * Transform user interface. | 391 | * Transform user interface. |
383 | */ | 392 | */ |