aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2009-05-06 02:15:47 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2009-06-02 00:04:45 -0400
commitf8b0d4d09dc9d0a73fcdcf6c2724650529ec417d (patch)
tree922fed01215af467ce07778268466b3c50b09120 /crypto
parent29ecd4ab3d3aa8bb231361937165dfbbbc534e9a (diff)
crypto: testmgr - Dynamically allocate xbuf and axbuf
We currently allocate temporary memory that is used for testing statically. This renders the testing engine non-reentrant. As algorithms may nest, i.e., one may construct another in order to carry out a part of its operation, this is unacceptable. For example, it has been reported that an AEAD implementation allocates a cipher in its setkey function, which causes it to fail during testing as the temporary memory is overwritten. This patch replaces the static memory with dynamically allocated buffers. We need a maximum of 16 pages so this slightly increases the chances of an algorithm failing due to memory shortage. However, as testing usually occurs at registration, this shouldn't be a big problem. Reported-by: Shasi Pulijala <spulijala@amcc.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/algboss.c18
-rw-r--r--crypto/internal.h3
-rw-r--r--crypto/testmgr.c108
3 files changed, 61 insertions, 68 deletions
diff --git a/crypto/algboss.c b/crypto/algboss.c
index 6906f92aeac0..9908dd830c26 100644
--- a/crypto/algboss.c
+++ b/crypto/algboss.c
@@ -280,29 +280,13 @@ static struct notifier_block cryptomgr_notifier = {
280 280
281static int __init cryptomgr_init(void) 281static int __init cryptomgr_init(void)
282{ 282{
283 int err; 283 return crypto_register_notifier(&cryptomgr_notifier);
284
285 err = testmgr_init();
286 if (err)
287 return err;
288
289 err = crypto_register_notifier(&cryptomgr_notifier);
290 if (err)
291 goto free_testmgr;
292
293 return 0;
294
295free_testmgr:
296 testmgr_exit();
297 return err;
298} 284}
299 285
300static void __exit cryptomgr_exit(void) 286static void __exit cryptomgr_exit(void)
301{ 287{
302 int err = crypto_unregister_notifier(&cryptomgr_notifier); 288 int err = crypto_unregister_notifier(&cryptomgr_notifier);
303 BUG_ON(err); 289 BUG_ON(err);
304
305 testmgr_exit();
306} 290}
307 291
308subsys_initcall(cryptomgr_init); 292subsys_initcall(cryptomgr_init);
diff --git a/crypto/internal.h b/crypto/internal.h
index fc76e1f37fc3..113579a82dff 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -121,9 +121,6 @@ int crypto_register_notifier(struct notifier_block *nb);
121int crypto_unregister_notifier(struct notifier_block *nb); 121int crypto_unregister_notifier(struct notifier_block *nb);
122int crypto_probing_notify(unsigned long val, void *v); 122int crypto_probing_notify(unsigned long val, void *v);
123 123
124int __init testmgr_init(void);
125void testmgr_exit(void);
126
127static inline void crypto_alg_put(struct crypto_alg *alg) 124static inline void crypto_alg_put(struct crypto_alg *alg)
128{ 125{
129 if (atomic_dec_and_test(&alg->cra_refcnt) && alg->cra_destroy) 126 if (atomic_dec_and_test(&alg->cra_refcnt) && alg->cra_destroy)
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index e76af78d2fa0..c5550943411d 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -107,9 +107,6 @@ struct alg_test_desc {
107 107
108static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 }; 108static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
109 109
110static char *xbuf[XBUFSIZE];
111static char *axbuf[XBUFSIZE];
112
113static void hexdump(unsigned char *buf, unsigned int len) 110static void hexdump(unsigned char *buf, unsigned int len)
114{ 111{
115 print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET, 112 print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET,
@@ -128,6 +125,33 @@ static void tcrypt_complete(struct crypto_async_request *req, int err)
128 complete(&res->completion); 125 complete(&res->completion);
129} 126}
130 127
128static int testmgr_alloc_buf(char *buf[XBUFSIZE])
129{
130 int i;
131
132 for (i = 0; i < XBUFSIZE; i++) {
133 buf[i] = (void *)__get_free_page(GFP_KERNEL);
134 if (!buf[i])
135 goto err_free_buf;
136 }
137
138 return 0;
139
140err_free_buf:
141 while (i-- > 0)
142 free_page((unsigned long)buf[i]);
143
144 return -ENOMEM;
145}
146
147static void testmgr_free_buf(char *buf[XBUFSIZE])
148{
149 int i;
150
151 for (i = 0; i < XBUFSIZE; i++)
152 free_page((unsigned long)buf[i]);
153}
154
131static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, 155static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
132 unsigned int tcount) 156 unsigned int tcount)
133{ 157{
@@ -137,8 +161,12 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
137 char result[64]; 161 char result[64];
138 struct ahash_request *req; 162 struct ahash_request *req;
139 struct tcrypt_result tresult; 163 struct tcrypt_result tresult;
140 int ret;
141 void *hash_buff; 164 void *hash_buff;
165 char *xbuf[XBUFSIZE];
166 int ret = -ENOMEM;
167
168 if (testmgr_alloc_buf(xbuf))
169 goto out_nobuf;
142 170
143 init_completion(&tresult.completion); 171 init_completion(&tresult.completion);
144 172
@@ -146,7 +174,6 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
146 if (!req) { 174 if (!req) {
147 printk(KERN_ERR "alg: hash: Failed to allocate request for " 175 printk(KERN_ERR "alg: hash: Failed to allocate request for "
148 "%s\n", algo); 176 "%s\n", algo);
149 ret = -ENOMEM;
150 goto out_noreq; 177 goto out_noreq;
151 } 178 }
152 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 179 ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
@@ -272,6 +299,8 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
272out: 299out:
273 ahash_request_free(req); 300 ahash_request_free(req);
274out_noreq: 301out_noreq:
302 testmgr_free_buf(xbuf);
303out_nobuf:
275 return ret; 304 return ret;
276} 305}
277 306
@@ -280,7 +309,7 @@ static int test_aead(struct crypto_aead *tfm, int enc,
280{ 309{
281 const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)); 310 const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm));
282 unsigned int i, j, k, n, temp; 311 unsigned int i, j, k, n, temp;
283 int ret = 0; 312 int ret = -ENOMEM;
284 char *q; 313 char *q;
285 char *key; 314 char *key;
286 struct aead_request *req; 315 struct aead_request *req;
@@ -292,6 +321,13 @@ static int test_aead(struct crypto_aead *tfm, int enc,
292 void *input; 321 void *input;
293 void *assoc; 322 void *assoc;
294 char iv[MAX_IVLEN]; 323 char iv[MAX_IVLEN];
324 char *xbuf[XBUFSIZE];
325 char *axbuf[XBUFSIZE];
326
327 if (testmgr_alloc_buf(xbuf))
328 goto out_noxbuf;
329 if (testmgr_alloc_buf(axbuf))
330 goto out_noaxbuf;
295 331
296 if (enc == ENCRYPT) 332 if (enc == ENCRYPT)
297 e = "encryption"; 333 e = "encryption";
@@ -304,7 +340,6 @@ static int test_aead(struct crypto_aead *tfm, int enc,
304 if (!req) { 340 if (!req) {
305 printk(KERN_ERR "alg: aead: Failed to allocate request for " 341 printk(KERN_ERR "alg: aead: Failed to allocate request for "
306 "%s\n", algo); 342 "%s\n", algo);
307 ret = -ENOMEM;
308 goto out; 343 goto out;
309 } 344 }
310 345
@@ -581,6 +616,10 @@ static int test_aead(struct crypto_aead *tfm, int enc,
581 616
582out: 617out:
583 aead_request_free(req); 618 aead_request_free(req);
619 testmgr_free_buf(axbuf);
620out_noaxbuf:
621 testmgr_free_buf(xbuf);
622out_noxbuf:
584 return ret; 623 return ret;
585} 624}
586 625
@@ -589,10 +628,14 @@ static int test_cipher(struct crypto_cipher *tfm, int enc,
589{ 628{
590 const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm)); 629 const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm));
591 unsigned int i, j, k; 630 unsigned int i, j, k;
592 int ret;
593 char *q; 631 char *q;
594 const char *e; 632 const char *e;
595 void *data; 633 void *data;
634 char *xbuf[XBUFSIZE];
635 int ret = -ENOMEM;
636
637 if (testmgr_alloc_buf(xbuf))
638 goto out_nobuf;
596 639
597 if (enc == ENCRYPT) 640 if (enc == ENCRYPT)
598 e = "encryption"; 641 e = "encryption";
@@ -646,6 +689,8 @@ static int test_cipher(struct crypto_cipher *tfm, int enc,
646 ret = 0; 689 ret = 0;
647 690
648out: 691out:
692 testmgr_free_buf(xbuf);
693out_nobuf:
649 return ret; 694 return ret;
650} 695}
651 696
@@ -655,7 +700,6 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
655 const char *algo = 700 const char *algo =
656 crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm)); 701 crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm));
657 unsigned int i, j, k, n, temp; 702 unsigned int i, j, k, n, temp;
658 int ret;
659 char *q; 703 char *q;
660 struct ablkcipher_request *req; 704 struct ablkcipher_request *req;
661 struct scatterlist sg[8]; 705 struct scatterlist sg[8];
@@ -663,6 +707,11 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
663 struct tcrypt_result result; 707 struct tcrypt_result result;
664 void *data; 708 void *data;
665 char iv[MAX_IVLEN]; 709 char iv[MAX_IVLEN];
710 char *xbuf[XBUFSIZE];
711 int ret = -ENOMEM;
712
713 if (testmgr_alloc_buf(xbuf))
714 goto out_nobuf;
666 715
667 if (enc == ENCRYPT) 716 if (enc == ENCRYPT)
668 e = "encryption"; 717 e = "encryption";
@@ -675,7 +724,6 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
675 if (!req) { 724 if (!req) {
676 printk(KERN_ERR "alg: skcipher: Failed to allocate request " 725 printk(KERN_ERR "alg: skcipher: Failed to allocate request "
677 "for %s\n", algo); 726 "for %s\n", algo);
678 ret = -ENOMEM;
679 goto out; 727 goto out;
680 } 728 }
681 729
@@ -860,6 +908,8 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc,
860 908
861out: 909out:
862 ablkcipher_request_free(req); 910 ablkcipher_request_free(req);
911 testmgr_free_buf(xbuf);
912out_nobuf:
863 return ret; 913 return ret;
864} 914}
865 915
@@ -2245,41 +2295,3 @@ notest:
2245 return 0; 2295 return 0;
2246} 2296}
2247EXPORT_SYMBOL_GPL(alg_test); 2297EXPORT_SYMBOL_GPL(alg_test);
2248
2249int __init testmgr_init(void)
2250{
2251 int i;
2252
2253 for (i = 0; i < XBUFSIZE; i++) {
2254 xbuf[i] = (void *)__get_free_page(GFP_KERNEL);
2255 if (!xbuf[i])
2256 goto err_free_xbuf;
2257 }
2258
2259 for (i = 0; i < XBUFSIZE; i++) {
2260 axbuf[i] = (void *)__get_free_page(GFP_KERNEL);
2261 if (!axbuf[i])
2262 goto err_free_axbuf;
2263 }
2264
2265 return 0;
2266
2267err_free_axbuf:
2268 for (i = 0; i < XBUFSIZE && axbuf[i]; i++)
2269 free_page((unsigned long)axbuf[i]);
2270err_free_xbuf:
2271 for (i = 0; i < XBUFSIZE && xbuf[i]; i++)
2272 free_page((unsigned long)xbuf[i]);
2273
2274 return -ENOMEM;
2275}
2276
2277void testmgr_exit(void)
2278{
2279 int i;
2280
2281 for (i = 0; i < XBUFSIZE; i++)
2282 free_page((unsigned long)axbuf[i]);
2283 for (i = 0; i < XBUFSIZE; i++)
2284 free_page((unsigned long)xbuf[i]);
2285}