aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 */