aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/algapi.c8
-rw-r--r--crypto/cryptomgr.c95
-rw-r--r--include/linux/crypto.h8
3 files changed, 84 insertions, 27 deletions
diff --git a/crypto/algapi.c b/crypto/algapi.c
index 38aa9e994703..d9559609b525 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -439,13 +439,15 @@ EXPORT_SYMBOL_GPL(crypto_unregister_notifier);
439 439
440struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb) 440struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb)
441{ 441{
442 struct rtattr *rta = tb[CRYPTOA_TYPE - 1]; 442 struct rtattr *rta = tb[0];
443 struct crypto_attr_type *algt; 443 struct crypto_attr_type *algt;
444 444
445 if (!rta) 445 if (!rta)
446 return ERR_PTR(-ENOENT); 446 return ERR_PTR(-ENOENT);
447 if (RTA_PAYLOAD(rta) < sizeof(*algt)) 447 if (RTA_PAYLOAD(rta) < sizeof(*algt))
448 return ERR_PTR(-EINVAL); 448 return ERR_PTR(-EINVAL);
449 if (rta->rta_type != CRYPTOA_TYPE)
450 return ERR_PTR(-EINVAL);
449 451
450 algt = RTA_DATA(rta); 452 algt = RTA_DATA(rta);
451 453
@@ -470,13 +472,15 @@ EXPORT_SYMBOL_GPL(crypto_check_attr_type);
470 472
471struct crypto_alg *crypto_get_attr_alg(struct rtattr **tb, u32 type, u32 mask) 473struct crypto_alg *crypto_get_attr_alg(struct rtattr **tb, u32 type, u32 mask)
472{ 474{
473 struct rtattr *rta = tb[CRYPTOA_ALG - 1]; 475 struct rtattr *rta = tb[1];
474 struct crypto_attr_alg *alga; 476 struct crypto_attr_alg *alga;
475 477
476 if (!rta) 478 if (!rta)
477 return ERR_PTR(-ENOENT); 479 return ERR_PTR(-ENOENT);
478 if (RTA_PAYLOAD(rta) < sizeof(*alga)) 480 if (RTA_PAYLOAD(rta) < sizeof(*alga))
479 return ERR_PTR(-EINVAL); 481 return ERR_PTR(-EINVAL);
482 if (rta->rta_type != CRYPTOA_ALG)
483 return ERR_PTR(-EINVAL);
480 484
481 alga = RTA_DATA(rta); 485 alga = RTA_DATA(rta);
482 alga->name[CRYPTO_MAX_ALG_NAME - 1] = 0; 486 alga->name[CRYPTO_MAX_ALG_NAME - 1] = 0;
diff --git a/crypto/cryptomgr.c b/crypto/cryptomgr.c
index e5fb7cca5107..c83884fec5f9 100644
--- a/crypto/cryptomgr.c
+++ b/crypto/cryptomgr.c
@@ -24,22 +24,26 @@
24#include "internal.h" 24#include "internal.h"
25 25
26struct cryptomgr_param { 26struct cryptomgr_param {
27 struct rtattr *tb[CRYPTOA_MAX]; 27 struct rtattr *tb[CRYPTO_MAX_ATTRS + 2];
28 28
29 struct { 29 struct {
30 struct rtattr attr; 30 struct rtattr attr;
31 struct crypto_attr_type data; 31 struct crypto_attr_type data;
32 } type; 32 } type;
33 33
34 struct { 34 union {
35 struct rtattr attr; 35 struct rtattr attr;
36 struct crypto_attr_alg data; 36 struct {
37 } alg; 37 struct rtattr attr;
38 38 struct crypto_attr_alg data;
39 struct { 39 } alg;
40 char name[CRYPTO_MAX_ALG_NAME]; 40 struct {
41 } larval; 41 struct rtattr attr;
42 42 struct crypto_attr_u32 data;
43 } nu32;
44 } attrs[CRYPTO_MAX_ATTRS];
45
46 char larval[CRYPTO_MAX_ALG_NAME];
43 char template[CRYPTO_MAX_ALG_NAME]; 47 char template[CRYPTO_MAX_ALG_NAME];
44}; 48};
45 49
@@ -72,7 +76,7 @@ out:
72 module_put_and_exit(0); 76 module_put_and_exit(0);
73 77
74err: 78err:
75 crypto_larval_error(param->larval.name, param->type.data.type, 79 crypto_larval_error(param->larval, param->type.data.type,
76 param->type.data.mask); 80 param->type.data.mask);
77 goto out; 81 goto out;
78} 82}
@@ -84,6 +88,7 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
84 const char *name = larval->alg.cra_name; 88 const char *name = larval->alg.cra_name;
85 const char *p; 89 const char *p;
86 unsigned int len; 90 unsigned int len;
91 int i;
87 92
88 if (!try_module_get(THIS_MODULE)) 93 if (!try_module_get(THIS_MODULE))
89 goto err; 94 goto err;
@@ -101,33 +106,73 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
101 106
102 memcpy(param->template, name, len); 107 memcpy(param->template, name, len);
103 108
104 name = p + 1; 109 i = 0;
105 len = 0; 110 for (;;) {
106 for (p = name; *p; p++) { 111 int notnum = 0;
107 for (; isalnum(*p) || *p == '-' || *p == '_' || *p == '('; p++)
108 ;
109 112
110 if (*p != ')') 113 name = ++p;
111 goto err_free_param; 114 len = 0;
115
116 for (; isalnum(*p) || *p == '-' || *p == '_'; p++)
117 notnum |= !isdigit(*p);
118
119 if (*p == '(') {
120 int recursion = 0;
121
122 for (;;) {
123 if (!*++p)
124 goto err_free_param;
125 if (*p == '(')
126 recursion++;
127 else if (*p == ')' && !recursion--)
128 break;
129 }
130
131 notnum = 1;
132 }
112 133
113 len = p - name; 134 len = p - name;
135 if (!len)
136 goto err_free_param;
137
138 if (notnum) {
139 param->attrs[i].alg.attr.rta_len =
140 sizeof(param->attrs[i].alg);
141 param->attrs[i].alg.attr.rta_type = CRYPTOA_ALG;
142 memcpy(param->attrs[i].alg.data.name, name, len);
143 } else {
144 param->attrs[i].nu32.attr.rta_len =
145 sizeof(param->attrs[i].nu32);
146 param->attrs[i].nu32.attr.rta_type = CRYPTOA_U32;
147 param->attrs[i].nu32.data.num =
148 simple_strtol(name, NULL, 0);
149 }
150
151 param->tb[i + 1] = &param->attrs[i].attr;
152 i++;
153
154 if (WARN_ON(i >= CRYPTO_MAX_ATTRS))
155 goto err_free_param;
156
157 if (*p == ')')
158 break;
159
160 if (*p != ',')
161 goto err_free_param;
114 } 162 }
115 163
116 if (!len || name[len + 1]) 164 if (!i)
117 goto err_free_param; 165 goto err_free_param;
118 166
167 param->tb[i + 1] = NULL;
168
119 param->type.attr.rta_len = sizeof(param->type); 169 param->type.attr.rta_len = sizeof(param->type);
120 param->type.attr.rta_type = CRYPTOA_TYPE; 170 param->type.attr.rta_type = CRYPTOA_TYPE;
121 param->type.data.type = larval->alg.cra_flags; 171 param->type.data.type = larval->alg.cra_flags;
122 param->type.data.mask = larval->mask; 172 param->type.data.mask = larval->mask;
123 param->tb[CRYPTOA_TYPE - 1] = &param->type.attr; 173 param->tb[0] = &param->type.attr;
124
125 param->alg.attr.rta_len = sizeof(param->alg);
126 param->alg.attr.rta_type = CRYPTOA_ALG;
127 memcpy(param->alg.data.name, name, len);
128 param->tb[CRYPTOA_ALG - 1] = &param->alg.attr;
129 174
130 memcpy(param->larval.name, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME); 175 memcpy(param->larval, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME);
131 176
132 thread = kthread_run(cryptomgr_probe, param, "cryptomgr"); 177 thread = kthread_run(cryptomgr_probe, param, "cryptomgr");
133 if (IS_ERR(thread)) 178 if (IS_ERR(thread))
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 1072f9abaef6..da09b4ac3ae9 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -425,11 +425,15 @@ enum {
425 CRYPTOA_UNSPEC, 425 CRYPTOA_UNSPEC,
426 CRYPTOA_ALG, 426 CRYPTOA_ALG,
427 CRYPTOA_TYPE, 427 CRYPTOA_TYPE,
428 CRYPTOA_U32,
428 __CRYPTOA_MAX, 429 __CRYPTOA_MAX,
429}; 430};
430 431
431#define CRYPTOA_MAX (__CRYPTOA_MAX - 1) 432#define CRYPTOA_MAX (__CRYPTOA_MAX - 1)
432 433
434/* Maximum number of (rtattr) parameters for each template. */
435#define CRYPTO_MAX_ATTRS 32
436
433struct crypto_attr_alg { 437struct crypto_attr_alg {
434 char name[CRYPTO_MAX_ALG_NAME]; 438 char name[CRYPTO_MAX_ALG_NAME];
435}; 439};
@@ -439,6 +443,10 @@ struct crypto_attr_type {
439 u32 mask; 443 u32 mask;
440}; 444};
441 445
446struct crypto_attr_u32 {
447 u32 num;
448};
449
442/* 450/*
443 * Transform user interface. 451 * Transform user interface.
444 */ 452 */