aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2008-08-03 09:15:23 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2008-08-29 01:49:57 -0400
commit73d3864a4823abda19ebc4387b6ddcbf416e3a77 (patch)
tree2939754dc2532f412c34a974e5f22dde112c525d
parentda7f033ddc9fdebb3223b0bf88a2a2ab5b797608 (diff)
crypto: api - Use test infrastructure
This patch makes use of the new testing infrastructure by requiring algorithms to pass a run-time test before they're made available to users. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/algapi.c143
-rw-r--r--crypto/algboss.c75
-rw-r--r--crypto/api.c73
-rw-r--r--crypto/internal.h7
-rw-r--r--crypto/proc.c3
-rw-r--r--include/linux/crypto.h8
6 files changed, 267 insertions, 42 deletions
diff --git a/crypto/algapi.c b/crypto/algapi.c
index e9154c1347ca..7c41e7405c41 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -21,6 +21,8 @@
21 21
22#include "internal.h" 22#include "internal.h"
23 23
24static void crypto_remove_final(struct list_head *list);
25
24static LIST_HEAD(crypto_template_list); 26static LIST_HEAD(crypto_template_list);
25 27
26void crypto_larval_error(const char *name, u32 type, u32 mask) 28void crypto_larval_error(const char *name, u32 type, u32 mask)
@@ -126,23 +128,97 @@ static void crypto_remove_spawns(struct list_head *spawns,
126 } 128 }
127} 129}
128 130
129static int __crypto_register_alg(struct crypto_alg *alg, 131static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
130 struct list_head *list)
131{ 132{
132 struct crypto_alg *q; 133 struct crypto_alg *q;
134 struct crypto_larval *larval;
133 int ret = -EAGAIN; 135 int ret = -EAGAIN;
134 136
135 if (crypto_is_dead(alg)) 137 if (crypto_is_dead(alg))
136 goto out; 138 goto err;
137 139
138 INIT_LIST_HEAD(&alg->cra_users); 140 INIT_LIST_HEAD(&alg->cra_users);
139 141
142 /* No cheating! */
143 alg->cra_flags &= ~CRYPTO_ALG_TESTED;
144
140 ret = -EEXIST; 145 ret = -EEXIST;
141 146
142 atomic_set(&alg->cra_refcnt, 1); 147 atomic_set(&alg->cra_refcnt, 1);
143 list_for_each_entry(q, &crypto_alg_list, cra_list) { 148 list_for_each_entry(q, &crypto_alg_list, cra_list) {
144 if (q == alg) 149 if (q == alg)
145 goto out; 150 goto err;
151
152 if (crypto_is_larval(q)) {
153 if (!strcmp(alg->cra_driver_name, q->cra_driver_name))
154 goto err;
155 continue;
156 }
157
158 if (!strcmp(q->cra_driver_name, alg->cra_name) ||
159 !strcmp(q->cra_name, alg->cra_driver_name))
160 goto err;
161 }
162
163 larval = crypto_larval_alloc(alg->cra_name,
164 alg->cra_flags | CRYPTO_ALG_TESTED, 0);
165 if (IS_ERR(larval))
166 goto out;
167
168 ret = -ENOENT;
169 larval->adult = crypto_mod_get(alg);
170 if (!larval->adult)
171 goto free_larval;
172
173 atomic_set(&larval->alg.cra_refcnt, 1);
174 memcpy(larval->alg.cra_driver_name, alg->cra_driver_name,
175 CRYPTO_MAX_ALG_NAME);
176 larval->alg.cra_priority = alg->cra_priority;
177
178 list_add(&alg->cra_list, &crypto_alg_list);
179 list_add(&larval->alg.cra_list, &crypto_alg_list);
180
181out:
182 return larval;
183
184free_larval:
185 kfree(larval);
186err:
187 larval = ERR_PTR(ret);
188 goto out;
189}
190
191void crypto_alg_tested(const char *name, int err)
192{
193 struct crypto_larval *test;
194 struct crypto_alg *alg;
195 struct crypto_alg *q;
196 LIST_HEAD(list);
197
198 down_write(&crypto_alg_sem);
199 list_for_each_entry(q, &crypto_alg_list, cra_list) {
200 if (!crypto_is_larval(q))
201 continue;
202
203 test = (struct crypto_larval *)q;
204
205 if (!strcmp(q->cra_driver_name, name))
206 goto found;
207 }
208
209 printk(KERN_ERR "alg: Unexpected test result for %s: %d\n", name, err);
210 goto unlock;
211
212found:
213 alg = test->adult;
214 if (err || list_empty(&alg->cra_list))
215 goto complete;
216
217 alg->cra_flags |= CRYPTO_ALG_TESTED;
218
219 list_for_each_entry(q, &crypto_alg_list, cra_list) {
220 if (q == alg)
221 continue;
146 222
147 if (crypto_is_moribund(q)) 223 if (crypto_is_moribund(q))
148 continue; 224 continue;
@@ -178,17 +254,18 @@ static int __crypto_register_alg(struct crypto_alg *alg,
178 q->cra_priority > alg->cra_priority) 254 q->cra_priority > alg->cra_priority)
179 continue; 255 continue;
180 256
181 crypto_remove_spawns(&q->cra_users, list, alg->cra_flags); 257 crypto_remove_spawns(&q->cra_users, &list, alg->cra_flags);
182 } 258 }
183
184 list_add(&alg->cra_list, &crypto_alg_list);
185 259
186 crypto_notify(CRYPTO_MSG_ALG_REGISTER, alg); 260complete:
187 ret = 0; 261 complete_all(&test->completion);
188 262
189out: 263unlock:
190 return ret; 264 up_write(&crypto_alg_sem);
265
266 crypto_remove_final(&list);
191} 267}
268EXPORT_SYMBOL_GPL(crypto_alg_tested);
192 269
193static void crypto_remove_final(struct list_head *list) 270static void crypto_remove_final(struct list_head *list)
194{ 271{
@@ -201,9 +278,27 @@ static void crypto_remove_final(struct list_head *list)
201 } 278 }
202} 279}
203 280
281static void crypto_wait_for_test(struct crypto_larval *larval)
282{
283 int err;
284
285 err = crypto_probing_notify(CRYPTO_MSG_ALG_REGISTER, larval->adult);
286 if (err != NOTIFY_STOP) {
287 if (WARN_ON(err != NOTIFY_DONE))
288 goto out;
289 crypto_alg_tested(larval->alg.cra_driver_name, 0);
290 }
291
292 err = wait_for_completion_interruptible(&larval->completion);
293 WARN_ON(err);
294
295out:
296 crypto_larval_kill(&larval->alg);
297}
298
204int crypto_register_alg(struct crypto_alg *alg) 299int crypto_register_alg(struct crypto_alg *alg)
205{ 300{
206 LIST_HEAD(list); 301 struct crypto_larval *larval;
207 int err; 302 int err;
208 303
209 err = crypto_check_alg(alg); 304 err = crypto_check_alg(alg);
@@ -211,11 +306,14 @@ int crypto_register_alg(struct crypto_alg *alg)
211 return err; 306 return err;
212 307
213 down_write(&crypto_alg_sem); 308 down_write(&crypto_alg_sem);
214 err = __crypto_register_alg(alg, &list); 309 larval = __crypto_register_alg(alg);
215 up_write(&crypto_alg_sem); 310 up_write(&crypto_alg_sem);
216 311
217 crypto_remove_final(&list); 312 if (IS_ERR(larval))
218 return err; 313 return PTR_ERR(larval);
314
315 crypto_wait_for_test(larval);
316 return 0;
219} 317}
220EXPORT_SYMBOL_GPL(crypto_register_alg); 318EXPORT_SYMBOL_GPL(crypto_register_alg);
221 319
@@ -333,8 +431,8 @@ EXPORT_SYMBOL_GPL(crypto_lookup_template);
333int crypto_register_instance(struct crypto_template *tmpl, 431int crypto_register_instance(struct crypto_template *tmpl,
334 struct crypto_instance *inst) 432 struct crypto_instance *inst)
335{ 433{
336 LIST_HEAD(list); 434 struct crypto_larval *larval;
337 int err = -EINVAL; 435 int err;
338 436
339 err = crypto_check_alg(&inst->alg); 437 err = crypto_check_alg(&inst->alg);
340 if (err) 438 if (err)
@@ -344,8 +442,8 @@ int crypto_register_instance(struct crypto_template *tmpl,
344 442
345 down_write(&crypto_alg_sem); 443 down_write(&crypto_alg_sem);
346 444
347 err = __crypto_register_alg(&inst->alg, &list); 445 larval = __crypto_register_alg(&inst->alg);
348 if (err) 446 if (IS_ERR(larval))
349 goto unlock; 447 goto unlock;
350 448
351 hlist_add_head(&inst->list, &tmpl->instances); 449 hlist_add_head(&inst->list, &tmpl->instances);
@@ -354,7 +452,12 @@ int crypto_register_instance(struct crypto_template *tmpl,
354unlock: 452unlock:
355 up_write(&crypto_alg_sem); 453 up_write(&crypto_alg_sem);
356 454
357 crypto_remove_final(&list); 455 err = PTR_ERR(larval);
456 if (IS_ERR(larval))
457 goto err;
458
459 crypto_wait_for_test(larval);
460 err = 0;
358 461
359err: 462err:
360 return err; 463 return err;
diff --git a/crypto/algboss.c b/crypto/algboss.c
index 2662ac014841..ed9f663c82c6 100644
--- a/crypto/algboss.c
+++ b/crypto/algboss.c
@@ -45,6 +45,15 @@ struct cryptomgr_param {
45 45
46 char larval[CRYPTO_MAX_ALG_NAME]; 46 char larval[CRYPTO_MAX_ALG_NAME];
47 char template[CRYPTO_MAX_ALG_NAME]; 47 char template[CRYPTO_MAX_ALG_NAME];
48
49 u32 otype;
50 u32 omask;
51};
52
53struct crypto_test_param {
54 char driver[CRYPTO_MAX_ALG_NAME];
55 char alg[CRYPTO_MAX_ALG_NAME];
56 u32 type;
48}; 57};
49 58
50static int cryptomgr_probe(void *data) 59static int cryptomgr_probe(void *data)
@@ -76,8 +85,7 @@ out:
76 module_put_and_exit(0); 85 module_put_and_exit(0);
77 86
78err: 87err:
79 crypto_larval_error(param->larval, param->type.data.type, 88 crypto_larval_error(param->larval, param->otype, param->omask);
80 param->type.data.mask);
81 goto out; 89 goto out;
82} 90}
83 91
@@ -169,13 +177,68 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
169 177
170 param->type.attr.rta_len = sizeof(param->type); 178 param->type.attr.rta_len = sizeof(param->type);
171 param->type.attr.rta_type = CRYPTOA_TYPE; 179 param->type.attr.rta_type = CRYPTOA_TYPE;
172 param->type.data.type = larval->alg.cra_flags; 180 param->type.data.type = larval->alg.cra_flags & ~CRYPTO_ALG_TESTED;
173 param->type.data.mask = larval->mask; 181 param->type.data.mask = larval->mask & ~CRYPTO_ALG_TESTED;
174 param->tb[0] = &param->type.attr; 182 param->tb[0] = &param->type.attr;
175 183
184 param->otype = larval->alg.cra_flags;
185 param->omask = larval->mask;
186
176 memcpy(param->larval, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME); 187 memcpy(param->larval, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME);
177 188
178 thread = kthread_run(cryptomgr_probe, param, "cryptomgr"); 189 thread = kthread_run(cryptomgr_probe, param, "cryptomgr_probe");
190 if (IS_ERR(thread))
191 goto err_free_param;
192
193 return NOTIFY_STOP;
194
195err_free_param:
196 kfree(param);
197err_put_module:
198 module_put(THIS_MODULE);
199err:
200 return NOTIFY_OK;
201}
202
203static int cryptomgr_test(void *data)
204{
205 struct crypto_test_param *param = data;
206 u32 type = param->type;
207 int err = 0;
208
209 if (!((type ^ CRYPTO_ALG_TYPE_BLKCIPHER) &
210 CRYPTO_ALG_TYPE_BLKCIPHER_MASK) && !(type & CRYPTO_ALG_GENIV))
211 goto skiptest;
212
213 if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER)
214 goto skiptest;
215
216 err = alg_test(param->driver, param->alg, 0, CRYPTO_ALG_TESTED);
217
218skiptest:
219 crypto_alg_tested(param->driver, err);
220
221 kfree(param);
222 module_put_and_exit(0);
223}
224
225static int cryptomgr_schedule_test(struct crypto_alg *alg)
226{
227 struct task_struct *thread;
228 struct crypto_test_param *param;
229
230 if (!try_module_get(THIS_MODULE))
231 goto err;
232
233 param = kzalloc(sizeof(*param), GFP_KERNEL);
234 if (!param)
235 goto err_put_module;
236
237 memcpy(param->driver, alg->cra_driver_name, sizeof(param->driver));
238 memcpy(param->alg, alg->cra_name, sizeof(param->alg));
239 param->type = alg->cra_flags;
240
241 thread = kthread_run(cryptomgr_test, param, "cryptomgr_test");
179 if (IS_ERR(thread)) 242 if (IS_ERR(thread))
180 goto err_free_param; 243 goto err_free_param;
181 244
@@ -195,6 +258,8 @@ static int cryptomgr_notify(struct notifier_block *this, unsigned long msg,
195 switch (msg) { 258 switch (msg) {
196 case CRYPTO_MSG_ALG_REQUEST: 259 case CRYPTO_MSG_ALG_REQUEST:
197 return cryptomgr_schedule_probe(data); 260 return cryptomgr_schedule_probe(data);
261 case CRYPTO_MSG_ALG_REGISTER:
262 return cryptomgr_schedule_test(data);
198 } 263 }
199 264
200 return NOTIFY_DONE; 265 return NOTIFY_DONE;
diff --git a/crypto/api.c b/crypto/api.c
index 0906cedd4521..0444d242e985 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -55,6 +55,11 @@ void crypto_mod_put(struct crypto_alg *alg)
55} 55}
56EXPORT_SYMBOL_GPL(crypto_mod_put); 56EXPORT_SYMBOL_GPL(crypto_mod_put);
57 57
58static inline int crypto_is_test_larval(struct crypto_larval *larval)
59{
60 return larval->alg.cra_driver_name[0];
61}
62
58static struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, 63static struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type,
59 u32 mask) 64 u32 mask)
60{ 65{
@@ -71,6 +76,7 @@ static struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type,
71 continue; 76 continue;
72 77
73 if (crypto_is_larval(q) && 78 if (crypto_is_larval(q) &&
79 !crypto_is_test_larval((struct crypto_larval *)q) &&
74 ((struct crypto_larval *)q)->mask != mask) 80 ((struct crypto_larval *)q)->mask != mask)
75 continue; 81 continue;
76 82
@@ -104,10 +110,8 @@ static void crypto_larval_destroy(struct crypto_alg *alg)
104 kfree(larval); 110 kfree(larval);
105} 111}
106 112
107static struct crypto_alg *crypto_larval_alloc(const char *name, u32 type, 113struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask)
108 u32 mask)
109{ 114{
110 struct crypto_alg *alg;
111 struct crypto_larval *larval; 115 struct crypto_larval *larval;
112 116
113 larval = kzalloc(sizeof(*larval), GFP_KERNEL); 117 larval = kzalloc(sizeof(*larval), GFP_KERNEL);
@@ -119,10 +123,25 @@ static struct crypto_alg *crypto_larval_alloc(const char *name, u32 type,
119 larval->alg.cra_priority = -1; 123 larval->alg.cra_priority = -1;
120 larval->alg.cra_destroy = crypto_larval_destroy; 124 larval->alg.cra_destroy = crypto_larval_destroy;
121 125
122 atomic_set(&larval->alg.cra_refcnt, 2);
123 strlcpy(larval->alg.cra_name, name, CRYPTO_MAX_ALG_NAME); 126 strlcpy(larval->alg.cra_name, name, CRYPTO_MAX_ALG_NAME);
124 init_completion(&larval->completion); 127 init_completion(&larval->completion);
125 128
129 return larval;
130}
131EXPORT_SYMBOL_GPL(crypto_larval_alloc);
132
133static struct crypto_alg *crypto_larval_add(const char *name, u32 type,
134 u32 mask)
135{
136 struct crypto_alg *alg;
137 struct crypto_larval *larval;
138
139 larval = crypto_larval_alloc(name, type, mask);
140 if (IS_ERR(larval))
141 return ERR_CAST(larval);
142
143 atomic_set(&larval->alg.cra_refcnt, 2);
144
126 down_write(&crypto_alg_sem); 145 down_write(&crypto_alg_sem);
127 alg = __crypto_alg_lookup(name, type, mask); 146 alg = __crypto_alg_lookup(name, type, mask);
128 if (!alg) { 147 if (!alg) {
@@ -152,14 +171,23 @@ EXPORT_SYMBOL_GPL(crypto_larval_kill);
152static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg) 171static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
153{ 172{
154 struct crypto_larval *larval = (void *)alg; 173 struct crypto_larval *larval = (void *)alg;
174 long timeout;
175
176 timeout = wait_for_completion_interruptible_timeout(
177 &larval->completion, 60 * HZ);
155 178
156 wait_for_completion_interruptible_timeout(&larval->completion, 60 * HZ);
157 alg = larval->adult; 179 alg = larval->adult;
158 if (alg) { 180 if (timeout < 0)
159 if (!crypto_mod_get(alg)) 181 alg = ERR_PTR(-EINTR);
160 alg = ERR_PTR(-EAGAIN); 182 else if (!timeout)
161 } else 183 alg = ERR_PTR(-ETIMEDOUT);
184 else if (!alg)
162 alg = ERR_PTR(-ENOENT); 185 alg = ERR_PTR(-ENOENT);
186 else if (crypto_is_test_larval(larval) &&
187 !(alg->cra_flags & CRYPTO_ALG_TESTED))
188 alg = ERR_PTR(-EAGAIN);
189 else if (!crypto_mod_get(alg))
190 alg = ERR_PTR(-EAGAIN);
163 crypto_mod_put(&larval->alg); 191 crypto_mod_put(&larval->alg);
164 192
165 return alg; 193 return alg;
@@ -192,25 +220,40 @@ struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask)
192 if (alg) 220 if (alg)
193 return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg; 221 return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg;
194 222
195 return crypto_larval_alloc(name, type, mask); 223 return crypto_larval_add(name, type, mask);
196} 224}
197EXPORT_SYMBOL_GPL(crypto_larval_lookup); 225EXPORT_SYMBOL_GPL(crypto_larval_lookup);
198 226
227int crypto_probing_notify(unsigned long val, void *v)
228{
229 int ok;
230
231 ok = blocking_notifier_call_chain(&crypto_chain, val, v);
232 if (ok == NOTIFY_DONE) {
233 request_module("cryptomgr");
234 ok = blocking_notifier_call_chain(&crypto_chain, val, v);
235 }
236
237 return ok;
238}
239EXPORT_SYMBOL_GPL(crypto_probing_notify);
240
199struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask) 241struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
200{ 242{
201 struct crypto_alg *alg; 243 struct crypto_alg *alg;
202 struct crypto_alg *larval; 244 struct crypto_alg *larval;
203 int ok; 245 int ok;
204 246
247 if (!(mask & CRYPTO_ALG_TESTED)) {
248 type |= CRYPTO_ALG_TESTED;
249 mask |= CRYPTO_ALG_TESTED;
250 }
251
205 larval = crypto_larval_lookup(name, type, mask); 252 larval = crypto_larval_lookup(name, type, mask);
206 if (IS_ERR(larval) || !crypto_is_larval(larval)) 253 if (IS_ERR(larval) || !crypto_is_larval(larval))
207 return larval; 254 return larval;
208 255
209 ok = crypto_notify(CRYPTO_MSG_ALG_REQUEST, larval); 256 ok = crypto_probing_notify(CRYPTO_MSG_ALG_REQUEST, larval);
210 if (ok == NOTIFY_DONE) {
211 request_module("cryptomgr");
212 ok = crypto_notify(CRYPTO_MSG_ALG_REQUEST, larval);
213 }
214 257
215 if (ok == NOTIFY_STOP) 258 if (ok == NOTIFY_STOP)
216 alg = crypto_larval_wait(larval); 259 alg = crypto_larval_wait(larval);
diff --git a/crypto/internal.h b/crypto/internal.h
index 48cb70416d59..fc93743c5d3e 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -94,9 +94,11 @@ void crypto_exit_digest_ops(struct crypto_tfm *tfm);
94void crypto_exit_cipher_ops(struct crypto_tfm *tfm); 94void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
95void crypto_exit_compress_ops(struct crypto_tfm *tfm); 95void crypto_exit_compress_ops(struct crypto_tfm *tfm);
96 96
97struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask);
97void crypto_larval_kill(struct crypto_alg *alg); 98void crypto_larval_kill(struct crypto_alg *alg);
98struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask); 99struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask);
99void crypto_larval_error(const char *name, u32 type, u32 mask); 100void crypto_larval_error(const char *name, u32 type, u32 mask);
101void crypto_alg_tested(const char *name, int err);
100 102
101void crypto_shoot_alg(struct crypto_alg *alg); 103void crypto_shoot_alg(struct crypto_alg *alg);
102struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type, 104struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
@@ -107,6 +109,7 @@ int crypto_register_instance(struct crypto_template *tmpl,
107 109
108int crypto_register_notifier(struct notifier_block *nb); 110int crypto_register_notifier(struct notifier_block *nb);
109int crypto_unregister_notifier(struct notifier_block *nb); 111int crypto_unregister_notifier(struct notifier_block *nb);
112int crypto_probing_notify(unsigned long val, void *v);
110 113
111int __init testmgr_init(void); 114int __init testmgr_init(void);
112void testmgr_exit(void); 115void testmgr_exit(void);
@@ -142,9 +145,9 @@ static inline int crypto_is_moribund(struct crypto_alg *alg)
142 return alg->cra_flags & (CRYPTO_ALG_DEAD | CRYPTO_ALG_DYING); 145 return alg->cra_flags & (CRYPTO_ALG_DEAD | CRYPTO_ALG_DYING);
143} 146}
144 147
145static inline int crypto_notify(unsigned long val, void *v) 148static inline void crypto_notify(unsigned long val, void *v)
146{ 149{
147 return blocking_notifier_call_chain(&crypto_chain, val, v); 150 blocking_notifier_call_chain(&crypto_chain, val, v);
148} 151}
149 152
150#endif /* _CRYPTO_INTERNAL_H */ 153#endif /* _CRYPTO_INTERNAL_H */
diff --git a/crypto/proc.c b/crypto/proc.c
index c6ede1e9c875..1d616adead0d 100644
--- a/crypto/proc.c
+++ b/crypto/proc.c
@@ -46,6 +46,9 @@ static int c_show(struct seq_file *m, void *p)
46 seq_printf(m, "module : %s\n", module_name(alg->cra_module)); 46 seq_printf(m, "module : %s\n", module_name(alg->cra_module));
47 seq_printf(m, "priority : %d\n", alg->cra_priority); 47 seq_printf(m, "priority : %d\n", alg->cra_priority);
48 seq_printf(m, "refcnt : %d\n", atomic_read(&alg->cra_refcnt)); 48 seq_printf(m, "refcnt : %d\n", atomic_read(&alg->cra_refcnt));
49 seq_printf(m, "selftest : %s\n",
50 (alg->cra_flags & CRYPTO_ALG_TESTED) ?
51 "passed" : "unknown");
49 52
50 switch (alg->cra_flags & (CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_LARVAL)) { 53 switch (alg->cra_flags & (CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_LARVAL)) {
51 case CRYPTO_ALG_TYPE_CIPHER: 54 case CRYPTO_ALG_TYPE_CIPHER:
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 7ea0a4bc4ced..81d994a3bdaf 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -61,6 +61,14 @@
61#define CRYPTO_ALG_GENIV 0x00000200 61#define CRYPTO_ALG_GENIV 0x00000200
62 62
63/* 63/*
64 * Set if the algorithm has passed automated run-time testing. Note that
65 * if there is no run-time testing for a given algorithm it is considered
66 * to have passed.
67 */
68
69#define CRYPTO_ALG_TESTED 0x00000400
70
71/*
64 * Transform masks and values (for crt_flags). 72 * Transform masks and values (for crt_flags).
65 */ 73 */
66#define CRYPTO_TFM_REQ_MASK 0x000fff00 74#define CRYPTO_TFM_REQ_MASK 0x000fff00