aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2008-07-31 00:23:53 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2008-08-29 01:48:57 -0400
commitf139cfa7cdccd0b315fad098889897b5fcd389b0 (patch)
tree365985f84f6dade6125f7d9a0e8cffcf30b87fa0 /crypto
parenta7581a01fbc69771a2b391de4220ba670c0aa261 (diff)
crypto: tcrypt - Avoid using contiguous pages
If tcrypt is to be used as a run-time integrity test, it needs to be more resilient in a hostile environment. For a start allocating 32K of physically contiguous memory is definitely out. This patch teaches it to use separate pages instead. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/tcrypt.c304
-rw-r--r--crypto/tcrypt.h8
2 files changed, 157 insertions, 155 deletions
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 66368022e0bf..b6d4b5ce00a3 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -31,10 +31,10 @@
31#include "tcrypt.h" 31#include "tcrypt.h"
32 32
33/* 33/*
34 * Need to kmalloc() memory for testing. 34 * Need slab memory for testing (size in number of pages).
35 */ 35 */
36#define TVMEMSIZE 16384 36#define TVMEMSIZE 4
37#define XBUFSIZE 32768 37#define XBUFSIZE 8
38 38
39/* 39/*
40 * Indexes into the xbuf to simulate cross-page access. 40 * Indexes into the xbuf to simulate cross-page access.
@@ -67,9 +67,9 @@ static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
67static unsigned int sec; 67static unsigned int sec;
68 68
69static int mode; 69static int mode;
70static char *xbuf; 70static char *xbuf[XBUFSIZE];
71static char *axbuf; 71static char *axbuf[XBUFSIZE];
72static char *tvmem; 72static char *tvmem[TVMEMSIZE];
73 73
74static char *check[] = { 74static char *check[] = {
75 "des", "md5", "des3_ede", "rot13", "sha1", "sha224", "sha256", 75 "des", "md5", "des3_ede", "rot13", "sha1", "sha224", "sha256",
@@ -133,9 +133,7 @@ static void test_hash(char *algo, struct hash_testvec *template,
133 printk("test %u:\n", i + 1); 133 printk("test %u:\n", i + 1);
134 memset(result, 0, 64); 134 memset(result, 0, 64);
135 135
136 hash_buff = kzalloc(template[i].psize, GFP_KERNEL); 136 hash_buff = xbuf[0];
137 if (!hash_buff)
138 continue;
139 137
140 memcpy(hash_buff, template[i].plaintext, template[i].psize); 138 memcpy(hash_buff, template[i].plaintext, template[i].psize);
141 sg_init_one(&sg[0], hash_buff, template[i].psize); 139 sg_init_one(&sg[0], hash_buff, template[i].psize);
@@ -146,7 +144,6 @@ static void test_hash(char *algo, struct hash_testvec *template,
146 template[i].ksize); 144 template[i].ksize);
147 if (ret) { 145 if (ret) {
148 printk("setkey() failed ret=%d\n", ret); 146 printk("setkey() failed ret=%d\n", ret);
149 kfree(hash_buff);
150 goto out; 147 goto out;
151 } 148 }
152 } 149 }
@@ -167,7 +164,6 @@ static void test_hash(char *algo, struct hash_testvec *template,
167 /* fall through */ 164 /* fall through */
168 default: 165 default:
169 printk("digest () failed ret=%d\n", ret); 166 printk("digest () failed ret=%d\n", ret);
170 kfree(hash_buff);
171 goto out; 167 goto out;
172 } 168 }
173 169
@@ -176,14 +172,10 @@ static void test_hash(char *algo, struct hash_testvec *template,
176 memcmp(result, template[i].digest, 172 memcmp(result, template[i].digest,
177 crypto_ahash_digestsize(tfm)) ? 173 crypto_ahash_digestsize(tfm)) ?
178 "fail" : "pass"); 174 "fail" : "pass");
179 kfree(hash_buff);
180 } 175 }
181 176
182 printk("testing %s across pages\n", algo); 177 printk("testing %s across pages\n", algo);
183 178
184 /* setup the dummy buffer first */
185 memset(xbuf, 0, XBUFSIZE);
186
187 j = 0; 179 j = 0;
188 for (i = 0; i < tcount; i++) { 180 for (i = 0; i < tcount; i++) {
189 if (template[i].np) { 181 if (template[i].np) {
@@ -194,12 +186,13 @@ static void test_hash(char *algo, struct hash_testvec *template,
194 temp = 0; 186 temp = 0;
195 sg_init_table(sg, template[i].np); 187 sg_init_table(sg, template[i].np);
196 for (k = 0; k < template[i].np; k++) { 188 for (k = 0; k < template[i].np; k++) {
197 memcpy(&xbuf[IDX[k]], 189 sg_set_buf(&sg[k],
198 template[i].plaintext + temp, 190 memcpy(xbuf[IDX[k] >> PAGE_SHIFT] +
199 template[i].tap[k]); 191 offset_in_page(IDX[k]),
192 template[i].plaintext + temp,
193 template[i].tap[k]),
194 template[i].tap[k]);
200 temp += template[i].tap[k]; 195 temp += template[i].tap[k];
201 sg_set_buf(&sg[k], &xbuf[IDX[k]],
202 template[i].tap[k]);
203 } 196 }
204 197
205 if (template[i].ksize) { 198 if (template[i].ksize) {
@@ -298,15 +291,8 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
298 /* some tepmplates have no input data but they will 291 /* some tepmplates have no input data but they will
299 * touch input 292 * touch input
300 */ 293 */
301 input = kzalloc(template[i].ilen + template[i].rlen, GFP_KERNEL); 294 input = xbuf[0];
302 if (!input) 295 assoc = axbuf[0];
303 continue;
304
305 assoc = kzalloc(template[i].alen, GFP_KERNEL);
306 if (!assoc) {
307 kfree(input);
308 continue;
309 }
310 296
311 memcpy(input, template[i].input, template[i].ilen); 297 memcpy(input, template[i].input, template[i].ilen);
312 memcpy(assoc, template[i].assoc, template[i].alen); 298 memcpy(assoc, template[i].assoc, template[i].alen);
@@ -320,10 +306,7 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
320 crypto_aead_set_flags( 306 crypto_aead_set_flags(
321 tfm, CRYPTO_TFM_REQ_WEAK_KEY); 307 tfm, CRYPTO_TFM_REQ_WEAK_KEY);
322 308
323 if (template[i].key) 309 key = template[i].key;
324 key = template[i].key;
325 else
326 key = kzalloc(template[i].klen, GFP_KERNEL);
327 310
328 ret = crypto_aead_setkey(tfm, key, 311 ret = crypto_aead_setkey(tfm, key,
329 template[i].klen); 312 template[i].klen);
@@ -332,7 +315,7 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
332 crypto_aead_get_flags(tfm)); 315 crypto_aead_get_flags(tfm));
333 316
334 if (!template[i].fail) 317 if (!template[i].fail)
335 goto next_one; 318 continue;
336 } 319 }
337 320
338 authsize = abs(template[i].rlen - template[i].ilen); 321 authsize = abs(template[i].rlen - template[i].ilen);
@@ -341,7 +324,7 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
341 printk(KERN_INFO 324 printk(KERN_INFO
342 "failed to set authsize = %u\n", 325 "failed to set authsize = %u\n",
343 authsize); 326 authsize);
344 goto next_one; 327 continue;
345 } 328 }
346 329
347 sg_init_one(&sg[0], input, 330 sg_init_one(&sg[0], input,
@@ -373,7 +356,7 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
373 default: 356 default:
374 printk(KERN_INFO "%s () failed err=%d\n", 357 printk(KERN_INFO "%s () failed err=%d\n",
375 e, -ret); 358 e, -ret);
376 goto next_one; 359 continue;
377 } 360 }
378 361
379 q = input; 362 q = input;
@@ -382,16 +365,10 @@ static void test_aead(char *algo, int enc, struct aead_testvec *template,
382 printk(KERN_INFO "enc/dec: %s\n", 365 printk(KERN_INFO "enc/dec: %s\n",
383 memcmp(q, template[i].result, 366 memcmp(q, template[i].result,
384 template[i].rlen) ? "fail" : "pass"); 367 template[i].rlen) ? "fail" : "pass");
385next_one:
386 if (!template[i].key)
387 kfree(key);
388 kfree(assoc);
389 kfree(input);
390 } 368 }
391 } 369 }
392 370
393 printk(KERN_INFO "\ntesting %s %s across pages (chunking)\n", algo, e); 371 printk(KERN_INFO "\ntesting %s %s across pages (chunking)\n", algo, e);
394 memset(axbuf, 0, XBUFSIZE);
395 372
396 for (i = 0, j = 0; i < tcount; i++) { 373 for (i = 0, j = 0; i < tcount; i++) {
397 if (template[i].np) { 374 if (template[i].np) {
@@ -418,18 +395,30 @@ next_one:
418 goto out; 395 goto out;
419 } 396 }
420 397
421 memset(xbuf, 0, XBUFSIZE); 398 authsize = abs(template[i].rlen - template[i].ilen);
399
422 sg_init_table(sg, template[i].np); 400 sg_init_table(sg, template[i].np);
423 for (k = 0, temp = 0; k < template[i].np; k++) { 401 for (k = 0, temp = 0; k < template[i].np; k++) {
424 memcpy(&xbuf[IDX[k]], 402 if (WARN_ON(offset_in_page(IDX[k]) +
425 template[i].input + temp, 403 template[i].tap[k] > PAGE_SIZE))
404 goto out;
405
406 q = xbuf[IDX[k] >> PAGE_SHIFT] +
407 offset_in_page(IDX[k]);
408
409 memcpy(q, template[i].input + temp,
426 template[i].tap[k]); 410 template[i].tap[k]);
411
412 n = template[i].tap[k];
413 if (k == template[i].np - 1 && enc)
414 n += authsize;
415 if (offset_in_page(q) + n < PAGE_SIZE)
416 q[n] = 0;
417
418 sg_set_buf(&sg[k], q, template[i].tap[k]);
427 temp += template[i].tap[k]; 419 temp += template[i].tap[k];
428 sg_set_buf(&sg[k], &xbuf[IDX[k]],
429 template[i].tap[k]);
430 } 420 }
431 421
432 authsize = abs(template[i].rlen - template[i].ilen);
433 ret = crypto_aead_setauthsize(tfm, authsize); 422 ret = crypto_aead_setauthsize(tfm, authsize);
434 if (ret) { 423 if (ret) {
435 printk(KERN_INFO 424 printk(KERN_INFO
@@ -438,17 +427,24 @@ next_one:
438 goto out; 427 goto out;
439 } 428 }
440 429
441 if (enc) 430 if (enc) {
431 if (WARN_ON(sg[k - 1].offset +
432 sg[k - 1].length + authsize >
433 PAGE_SIZE))
434 goto out;
435
442 sg[k - 1].length += authsize; 436 sg[k - 1].length += authsize;
437 }
443 438
444 sg_init_table(asg, template[i].anp); 439 sg_init_table(asg, template[i].anp);
445 for (k = 0, temp = 0; k < template[i].anp; k++) { 440 for (k = 0, temp = 0; k < template[i].anp; k++) {
446 memcpy(&axbuf[IDX[k]], 441 sg_set_buf(&asg[k],
447 template[i].assoc + temp, 442 memcpy(axbuf[IDX[k] >> PAGE_SHIFT] +
448 template[i].atap[k]); 443 offset_in_page(IDX[k]),
449 temp += template[i].atap[k]; 444 template[i].assoc + temp,
450 sg_set_buf(&asg[k], &axbuf[IDX[k]], 445 template[i].atap[k]),
451 template[i].atap[k]); 446 template[i].atap[k]);
447 temp += template[i].atap[k];
452 } 448 }
453 449
454 aead_request_set_crypt(req, sg, sg, 450 aead_request_set_crypt(req, sg, sg,
@@ -481,7 +477,8 @@ next_one:
481 477
482 for (k = 0, temp = 0; k < template[i].np; k++) { 478 for (k = 0, temp = 0; k < template[i].np; k++) {
483 printk(KERN_INFO "page %u\n", k); 479 printk(KERN_INFO "page %u\n", k);
484 q = &xbuf[IDX[k]]; 480 q = xbuf[IDX[k] >> PAGE_SHIFT] +
481 offset_in_page(IDX[k]);
485 482
486 n = template[i].tap[k]; 483 n = template[i].tap[k];
487 if (k == template[i].np - 1) 484 if (k == template[i].np - 1)
@@ -499,7 +496,8 @@ next_one:
499 else 496 else
500 n = 0; 497 n = 0;
501 } else { 498 } else {
502 for (n = 0; q[n]; n++) 499 for (n = 0; offset_in_page(q + n) &&
500 q[n]; n++)
503 ; 501 ;
504 } 502 }
505 if (n) { 503 if (n) {
@@ -558,12 +556,6 @@ static void test_cipher(char *algo, int enc,
558 556
559 j = 0; 557 j = 0;
560 for (i = 0; i < tcount; i++) { 558 for (i = 0; i < tcount; i++) {
561
562 data = kzalloc(template[i].ilen, GFP_KERNEL);
563 if (!data)
564 continue;
565
566 memcpy(data, template[i].input, template[i].ilen);
567 if (template[i].iv) 559 if (template[i].iv)
568 memcpy(iv, template[i].iv, MAX_IVLEN); 560 memcpy(iv, template[i].iv, MAX_IVLEN);
569 else 561 else
@@ -574,6 +566,9 @@ static void test_cipher(char *algo, int enc,
574 printk("test %u (%d bit key):\n", 566 printk("test %u (%d bit key):\n",
575 j, template[i].klen * 8); 567 j, template[i].klen * 8);
576 568
569 data = xbuf[0];
570 memcpy(data, template[i].input, template[i].ilen);
571
577 crypto_ablkcipher_clear_flags(tfm, ~0); 572 crypto_ablkcipher_clear_flags(tfm, ~0);
578 if (template[i].wk) 573 if (template[i].wk)
579 crypto_ablkcipher_set_flags( 574 crypto_ablkcipher_set_flags(
@@ -585,10 +580,8 @@ static void test_cipher(char *algo, int enc,
585 printk("setkey() failed flags=%x\n", 580 printk("setkey() failed flags=%x\n",
586 crypto_ablkcipher_get_flags(tfm)); 581 crypto_ablkcipher_get_flags(tfm));
587 582
588 if (!template[i].fail) { 583 if (!template[i].fail)
589 kfree(data);
590 goto out; 584 goto out;
591 }
592 } 585 }
593 586
594 sg_init_one(&sg[0], data, template[i].ilen); 587 sg_init_one(&sg[0], data, template[i].ilen);
@@ -613,7 +606,6 @@ static void test_cipher(char *algo, int enc,
613 /* fall through */ 606 /* fall through */
614 default: 607 default:
615 printk("%s () failed err=%d\n", e, -ret); 608 printk("%s () failed err=%d\n", e, -ret);
616 kfree(data);
617 goto out; 609 goto out;
618 } 610 }
619 611
@@ -624,7 +616,6 @@ static void test_cipher(char *algo, int enc,
624 memcmp(q, template[i].result, 616 memcmp(q, template[i].result,
625 template[i].rlen) ? "fail" : "pass"); 617 template[i].rlen) ? "fail" : "pass");
626 } 618 }
627 kfree(data);
628 } 619 }
629 620
630 printk("\ntesting %s %s across pages (chunking)\n", algo, e); 621 printk("\ntesting %s %s across pages (chunking)\n", algo, e);
@@ -642,7 +633,6 @@ static void test_cipher(char *algo, int enc,
642 printk("test %u (%d bit key):\n", 633 printk("test %u (%d bit key):\n",
643 j, template[i].klen * 8); 634 j, template[i].klen * 8);
644 635
645 memset(xbuf, 0, XBUFSIZE);
646 crypto_ablkcipher_clear_flags(tfm, ~0); 636 crypto_ablkcipher_clear_flags(tfm, ~0);
647 if (template[i].wk) 637 if (template[i].wk)
648 crypto_ablkcipher_set_flags( 638 crypto_ablkcipher_set_flags(
@@ -661,12 +651,23 @@ static void test_cipher(char *algo, int enc,
661 temp = 0; 651 temp = 0;
662 sg_init_table(sg, template[i].np); 652 sg_init_table(sg, template[i].np);
663 for (k = 0; k < template[i].np; k++) { 653 for (k = 0; k < template[i].np; k++) {
664 memcpy(&xbuf[IDX[k]], 654 if (WARN_ON(offset_in_page(IDX[k]) +
665 template[i].input + temp, 655 template[i].tap[k] > PAGE_SIZE))
666 template[i].tap[k]); 656 goto out;
657
658 q = xbuf[IDX[k] >> PAGE_SHIFT] +
659 offset_in_page(IDX[k]);
660
661 memcpy(q, template[i].input + temp,
662 template[i].tap[k]);
663
664 if (offset_in_page(q) + template[i].tap[k] <
665 PAGE_SIZE)
666 q[template[i].tap[k]] = 0;
667
668 sg_set_buf(&sg[k], q, template[i].tap[k]);
669
667 temp += template[i].tap[k]; 670 temp += template[i].tap[k];
668 sg_set_buf(&sg[k], &xbuf[IDX[k]],
669 template[i].tap[k]);
670 } 671 }
671 672
672 ablkcipher_request_set_crypt(req, sg, sg, 673 ablkcipher_request_set_crypt(req, sg, sg,
@@ -696,19 +697,21 @@ static void test_cipher(char *algo, int enc,
696 temp = 0; 697 temp = 0;
697 for (k = 0; k < template[i].np; k++) { 698 for (k = 0; k < template[i].np; k++) {
698 printk("page %u\n", k); 699 printk("page %u\n", k);
699 q = &xbuf[IDX[k]]; 700 q = xbuf[IDX[k] >> PAGE_SHIFT] +
701 offset_in_page(IDX[k]);
700 hexdump(q, template[i].tap[k]); 702 hexdump(q, template[i].tap[k]);
701 printk("%s\n", 703 printk("%s\n",
702 memcmp(q, template[i].result + temp, 704 memcmp(q, template[i].result + temp,
703 template[i].tap[k]) ? "fail" : 705 template[i].tap[k]) ? "fail" :
704 "pass"); 706 "pass");
705 707
706 for (n = 0; q[template[i].tap[k] + n]; n++) 708 q += template[i].tap[k];
709 for (n = 0; offset_in_page(q + n) && q[n]; n++)
707 ; 710 ;
708 if (n) { 711 if (n) {
709 printk("Result buffer corruption %u " 712 printk("Result buffer corruption %u "
710 "bytes:\n", n); 713 "bytes:\n", n);
711 hexdump(&q[template[i].tap[k]], n); 714 hexdump(q, n);
712 } 715 }
713 temp += template[i].tap[k]; 716 temp += template[i].tap[k];
714 } 717 }
@@ -719,16 +722,13 @@ out:
719 ablkcipher_request_free(req); 722 ablkcipher_request_free(req);
720} 723}
721 724
722static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc, char *p, 725static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc,
723 int blen, int sec) 726 struct scatterlist *sg, int blen, int sec)
724{ 727{
725 struct scatterlist sg[1];
726 unsigned long start, end; 728 unsigned long start, end;
727 int bcount; 729 int bcount;
728 int ret; 730 int ret;
729 731
730 sg_init_one(sg, p, blen);
731
732 for (start = jiffies, end = start + sec * HZ, bcount = 0; 732 for (start = jiffies, end = start + sec * HZ, bcount = 0;
733 time_before(jiffies, end); bcount++) { 733 time_before(jiffies, end); bcount++) {
734 if (enc) 734 if (enc)
@@ -745,16 +745,13 @@ static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc, char *p,
745 return 0; 745 return 0;
746} 746}
747 747
748static int test_cipher_cycles(struct blkcipher_desc *desc, int enc, char *p, 748static int test_cipher_cycles(struct blkcipher_desc *desc, int enc,
749 int blen) 749 struct scatterlist *sg, int blen)
750{ 750{
751 struct scatterlist sg[1];
752 unsigned long cycles = 0; 751 unsigned long cycles = 0;
753 int ret = 0; 752 int ret = 0;
754 int i; 753 int i;
755 754
756 sg_init_one(sg, p, blen);
757
758 local_bh_disable(); 755 local_bh_disable();
759 local_irq_disable(); 756 local_irq_disable();
760 757
@@ -804,7 +801,7 @@ static void test_cipher_speed(char *algo, int enc, unsigned int sec,
804 unsigned int tcount, u8 *keysize) 801 unsigned int tcount, u8 *keysize)
805{ 802{
806 unsigned int ret, i, j, iv_len; 803 unsigned int ret, i, j, iv_len;
807 unsigned char *key, *p, iv[128]; 804 unsigned char *key, iv[128];
808 struct crypto_blkcipher *tfm; 805 struct crypto_blkcipher *tfm;
809 struct blkcipher_desc desc; 806 struct blkcipher_desc desc;
810 const char *e; 807 const char *e;
@@ -832,27 +829,28 @@ static void test_cipher_speed(char *algo, int enc, unsigned int sec,
832 829
833 b_size = block_sizes; 830 b_size = block_sizes;
834 do { 831 do {
832 struct scatterlist sg[TVMEMSIZE];
835 833
836 if ((*keysize + *b_size) > TVMEMSIZE) { 834 if ((*keysize + *b_size) > TVMEMSIZE * PAGE_SIZE) {
837 printk("template (%u) too big for tvmem (%u)\n", 835 printk("template (%u) too big for "
838 *keysize + *b_size, TVMEMSIZE); 836 "tvmem (%lu)\n", *keysize + *b_size,
837 TVMEMSIZE * PAGE_SIZE);
839 goto out; 838 goto out;
840 } 839 }
841 840
842 printk("test %u (%d bit key, %d byte blocks): ", i, 841 printk("test %u (%d bit key, %d byte blocks): ", i,
843 *keysize * 8, *b_size); 842 *keysize * 8, *b_size);
844 843
845 memset(tvmem, 0xff, *keysize + *b_size); 844 memset(tvmem[0], 0xff, PAGE_SIZE);
846 845
847 /* set key, plain text and IV */ 846 /* set key, plain text and IV */
848 key = (unsigned char *)tvmem; 847 key = (unsigned char *)tvmem[0];
849 for (j = 0; j < tcount; j++) { 848 for (j = 0; j < tcount; j++) {
850 if (template[j].klen == *keysize) { 849 if (template[j].klen == *keysize) {
851 key = template[j].key; 850 key = template[j].key;
852 break; 851 break;
853 } 852 }
854 } 853 }
855 p = (unsigned char *)tvmem + *keysize;
856 854
857 ret = crypto_blkcipher_setkey(tfm, key, *keysize); 855 ret = crypto_blkcipher_setkey(tfm, key, *keysize);
858 if (ret) { 856 if (ret) {
@@ -861,6 +859,14 @@ static void test_cipher_speed(char *algo, int enc, unsigned int sec,
861 goto out; 859 goto out;
862 } 860 }
863 861
862 sg_init_table(sg, TVMEMSIZE);
863 sg_set_buf(sg, tvmem[0] + *keysize,
864 PAGE_SIZE - *keysize);
865 for (j = 1; j < TVMEMSIZE; j++) {
866 sg_set_buf(sg + j, tvmem[j], PAGE_SIZE);
867 memset (tvmem[j], 0xff, PAGE_SIZE);
868 }
869
864 iv_len = crypto_blkcipher_ivsize(tfm); 870 iv_len = crypto_blkcipher_ivsize(tfm);
865 if (iv_len) { 871 if (iv_len) {
866 memset(&iv, 0xff, iv_len); 872 memset(&iv, 0xff, iv_len);
@@ -868,9 +874,11 @@ static void test_cipher_speed(char *algo, int enc, unsigned int sec,
868 } 874 }
869 875
870 if (sec) 876 if (sec)
871 ret = test_cipher_jiffies(&desc, enc, p, *b_size, sec); 877 ret = test_cipher_jiffies(&desc, enc, sg,
878 *b_size, sec);
872 else 879 else
873 ret = test_cipher_cycles(&desc, enc, p, *b_size); 880 ret = test_cipher_cycles(&desc, enc, sg,
881 *b_size);
874 882
875 if (ret) { 883 if (ret) {
876 printk("%s() failed flags=%x\n", e, desc.flags); 884 printk("%s() failed flags=%x\n", e, desc.flags);
@@ -886,19 +894,16 @@ out:
886 crypto_free_blkcipher(tfm); 894 crypto_free_blkcipher(tfm);
887} 895}
888 896
889static int test_hash_jiffies_digest(struct hash_desc *desc, char *p, int blen, 897static int test_hash_jiffies_digest(struct hash_desc *desc,
898 struct scatterlist *sg, int blen,
890 char *out, int sec) 899 char *out, int sec)
891{ 900{
892 struct scatterlist sg[1];
893 unsigned long start, end; 901 unsigned long start, end;
894 int bcount; 902 int bcount;
895 int ret; 903 int ret;
896 904
897 sg_init_table(sg, 1);
898
899 for (start = jiffies, end = start + sec * HZ, bcount = 0; 905 for (start = jiffies, end = start + sec * HZ, bcount = 0;
900 time_before(jiffies, end); bcount++) { 906 time_before(jiffies, end); bcount++) {
901 sg_set_buf(sg, p, blen);
902 ret = crypto_hash_digest(desc, sg, blen, out); 907 ret = crypto_hash_digest(desc, sg, blen, out);
903 if (ret) 908 if (ret)
904 return ret; 909 return ret;
@@ -910,18 +915,15 @@ static int test_hash_jiffies_digest(struct hash_desc *desc, char *p, int blen,
910 return 0; 915 return 0;
911} 916}
912 917
913static int test_hash_jiffies(struct hash_desc *desc, char *p, int blen, 918static int test_hash_jiffies(struct hash_desc *desc, struct scatterlist *sg,
914 int plen, char *out, int sec) 919 int blen, int plen, char *out, int sec)
915{ 920{
916 struct scatterlist sg[1];
917 unsigned long start, end; 921 unsigned long start, end;
918 int bcount, pcount; 922 int bcount, pcount;
919 int ret; 923 int ret;
920 924
921 if (plen == blen) 925 if (plen == blen)
922 return test_hash_jiffies_digest(desc, p, blen, out, sec); 926 return test_hash_jiffies_digest(desc, sg, blen, out, sec);
923
924 sg_init_table(sg, 1);
925 927
926 for (start = jiffies, end = start + sec * HZ, bcount = 0; 928 for (start = jiffies, end = start + sec * HZ, bcount = 0;
927 time_before(jiffies, end); bcount++) { 929 time_before(jiffies, end); bcount++) {
@@ -929,7 +931,6 @@ static int test_hash_jiffies(struct hash_desc *desc, char *p, int blen,
929 if (ret) 931 if (ret)
930 return ret; 932 return ret;
931 for (pcount = 0; pcount < blen; pcount += plen) { 933 for (pcount = 0; pcount < blen; pcount += plen) {
932 sg_set_buf(sg, p + pcount, plen);
933 ret = crypto_hash_update(desc, sg, plen); 934 ret = crypto_hash_update(desc, sg, plen);
934 if (ret) 935 if (ret)
935 return ret; 936 return ret;
@@ -946,22 +947,18 @@ static int test_hash_jiffies(struct hash_desc *desc, char *p, int blen,
946 return 0; 947 return 0;
947} 948}
948 949
949static int test_hash_cycles_digest(struct hash_desc *desc, char *p, int blen, 950static int test_hash_cycles_digest(struct hash_desc *desc,
950 char *out) 951 struct scatterlist *sg, int blen, char *out)
951{ 952{
952 struct scatterlist sg[1];
953 unsigned long cycles = 0; 953 unsigned long cycles = 0;
954 int i; 954 int i;
955 int ret; 955 int ret;
956 956
957 sg_init_table(sg, 1);
958
959 local_bh_disable(); 957 local_bh_disable();
960 local_irq_disable(); 958 local_irq_disable();
961 959
962 /* Warm-up run. */ 960 /* Warm-up run. */
963 for (i = 0; i < 4; i++) { 961 for (i = 0; i < 4; i++) {
964 sg_set_buf(sg, p, blen);
965 ret = crypto_hash_digest(desc, sg, blen, out); 962 ret = crypto_hash_digest(desc, sg, blen, out);
966 if (ret) 963 if (ret)
967 goto out; 964 goto out;
@@ -973,7 +970,6 @@ static int test_hash_cycles_digest(struct hash_desc *desc, char *p, int blen,
973 970
974 start = get_cycles(); 971 start = get_cycles();
975 972
976 sg_set_buf(sg, p, blen);
977 ret = crypto_hash_digest(desc, sg, blen, out); 973 ret = crypto_hash_digest(desc, sg, blen, out);
978 if (ret) 974 if (ret)
979 goto out; 975 goto out;
@@ -996,18 +992,15 @@ out:
996 return 0; 992 return 0;
997} 993}
998 994
999static int test_hash_cycles(struct hash_desc *desc, char *p, int blen, 995static int test_hash_cycles(struct hash_desc *desc, struct scatterlist *sg,
1000 int plen, char *out) 996 int blen, int plen, char *out)
1001{ 997{
1002 struct scatterlist sg[1];
1003 unsigned long cycles = 0; 998 unsigned long cycles = 0;
1004 int i, pcount; 999 int i, pcount;
1005 int ret; 1000 int ret;
1006 1001
1007 if (plen == blen) 1002 if (plen == blen)
1008 return test_hash_cycles_digest(desc, p, blen, out); 1003 return test_hash_cycles_digest(desc, sg, blen, out);
1009
1010 sg_init_table(sg, 1);
1011 1004
1012 local_bh_disable(); 1005 local_bh_disable();
1013 local_irq_disable(); 1006 local_irq_disable();
@@ -1018,7 +1011,6 @@ static int test_hash_cycles(struct hash_desc *desc, char *p, int blen,
1018 if (ret) 1011 if (ret)
1019 goto out; 1012 goto out;
1020 for (pcount = 0; pcount < blen; pcount += plen) { 1013 for (pcount = 0; pcount < blen; pcount += plen) {
1021 sg_set_buf(sg, p + pcount, plen);
1022 ret = crypto_hash_update(desc, sg, plen); 1014 ret = crypto_hash_update(desc, sg, plen);
1023 if (ret) 1015 if (ret)
1024 goto out; 1016 goto out;
@@ -1038,7 +1030,6 @@ static int test_hash_cycles(struct hash_desc *desc, char *p, int blen,
1038 if (ret) 1030 if (ret)
1039 goto out; 1031 goto out;
1040 for (pcount = 0; pcount < blen; pcount += plen) { 1032 for (pcount = 0; pcount < blen; pcount += plen) {
1041 sg_set_buf(sg, p + pcount, plen);
1042 ret = crypto_hash_update(desc, sg, plen); 1033 ret = crypto_hash_update(desc, sg, plen);
1043 if (ret) 1034 if (ret)
1044 goto out; 1035 goto out;
@@ -1068,6 +1059,7 @@ out:
1068static void test_hash_speed(char *algo, unsigned int sec, 1059static void test_hash_speed(char *algo, unsigned int sec,
1069 struct hash_speed *speed) 1060 struct hash_speed *speed)
1070{ 1061{
1062 struct scatterlist sg[TVMEMSIZE];
1071 struct crypto_hash *tfm; 1063 struct crypto_hash *tfm;
1072 struct hash_desc desc; 1064 struct hash_desc desc;
1073 char output[1024]; 1065 char output[1024];
@@ -1093,23 +1085,27 @@ static void test_hash_speed(char *algo, unsigned int sec,
1093 goto out; 1085 goto out;
1094 } 1086 }
1095 1087
1088 sg_init_table(sg, TVMEMSIZE);
1089 for (i = 0; i < TVMEMSIZE; i++) {
1090 sg_set_buf(sg + i, tvmem[i], PAGE_SIZE);
1091 memset(tvmem[i], 0xff, PAGE_SIZE);
1092 }
1093
1096 for (i = 0; speed[i].blen != 0; i++) { 1094 for (i = 0; speed[i].blen != 0; i++) {
1097 if (speed[i].blen > TVMEMSIZE) { 1095 if (speed[i].blen > TVMEMSIZE * PAGE_SIZE) {
1098 printk("template (%u) too big for tvmem (%u)\n", 1096 printk("template (%u) too big for tvmem (%lu)\n",
1099 speed[i].blen, TVMEMSIZE); 1097 speed[i].blen, TVMEMSIZE * PAGE_SIZE);
1100 goto out; 1098 goto out;
1101 } 1099 }
1102 1100
1103 printk("test%3u (%5u byte blocks,%5u bytes per update,%4u updates): ", 1101 printk("test%3u (%5u byte blocks,%5u bytes per update,%4u updates): ",
1104 i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen); 1102 i, speed[i].blen, speed[i].plen, speed[i].blen / speed[i].plen);
1105 1103
1106 memset(tvmem, 0xff, speed[i].blen);
1107
1108 if (sec) 1104 if (sec)
1109 ret = test_hash_jiffies(&desc, tvmem, speed[i].blen, 1105 ret = test_hash_jiffies(&desc, sg, speed[i].blen,
1110 speed[i].plen, output, sec); 1106 speed[i].plen, output, sec);
1111 else 1107 else
1112 ret = test_hash_cycles(&desc, tvmem, speed[i].blen, 1108 ret = test_hash_cycles(&desc, sg, speed[i].blen,
1113 speed[i].plen, output); 1109 speed[i].plen, output);
1114 1110
1115 if (ret) { 1111 if (ret) {
@@ -1128,7 +1124,6 @@ static void test_comp(char *algo, struct comp_testvec *ctemplate,
1128 unsigned int i; 1124 unsigned int i;
1129 char result[COMP_BUF_SIZE]; 1125 char result[COMP_BUF_SIZE];
1130 struct crypto_comp *tfm; 1126 struct crypto_comp *tfm;
1131 unsigned int tsize;
1132 1127
1133 printk("\ntesting %s compression\n", algo); 1128 printk("\ntesting %s compression\n", algo);
1134 1129
@@ -1159,14 +1154,6 @@ static void test_comp(char *algo, struct comp_testvec *ctemplate,
1159 1154
1160 printk("\ntesting %s decompression\n", algo); 1155 printk("\ntesting %s decompression\n", algo);
1161 1156
1162 tsize = sizeof(struct comp_testvec);
1163 tsize *= dtcount;
1164 if (tsize > TVMEMSIZE) {
1165 printk("template (%u) too big for tvmem (%u)\n", tsize,
1166 TVMEMSIZE);
1167 goto out;
1168 }
1169
1170 for (i = 0; i < dtcount; i++) { 1157 for (i = 0; i < dtcount; i++) {
1171 int ilen, ret, dlen = COMP_BUF_SIZE; 1158 int ilen, ret, dlen = COMP_BUF_SIZE;
1172 1159
@@ -1185,7 +1172,7 @@ static void test_comp(char *algo, struct comp_testvec *ctemplate,
1185 memcmp(result, dtemplate[i].output, dlen) ? "fail" : "pass", 1172 memcmp(result, dtemplate[i].output, dlen) ? "fail" : "pass",
1186 ilen, dlen); 1173 ilen, dlen);
1187 } 1174 }
1188out: 1175
1189 crypto_free_comp(tfm); 1176 crypto_free_comp(tfm);
1190} 1177}
1191 1178
@@ -1917,18 +1904,25 @@ static void do_test(void)
1917static int __init tcrypt_mod_init(void) 1904static int __init tcrypt_mod_init(void)
1918{ 1905{
1919 int err = -ENOMEM; 1906 int err = -ENOMEM;
1907 int i;
1920 1908
1921 tvmem = kmalloc(TVMEMSIZE, GFP_KERNEL); 1909 for (i = 0; i < TVMEMSIZE; i++) {
1922 if (tvmem == NULL) 1910 tvmem[i] = (void *)__get_free_page(GFP_KERNEL);
1923 return err; 1911 if (!tvmem[i])
1912 goto err_free_tv;
1913 }
1924 1914
1925 xbuf = kmalloc(XBUFSIZE, GFP_KERNEL); 1915 for (i = 0; i < XBUFSIZE; i++) {
1926 if (xbuf == NULL) 1916 xbuf[i] = (void *)__get_free_page(GFP_KERNEL);
1927 goto err_free_tv; 1917 if (!xbuf[i])
1918 goto err_free_xbuf;
1919 }
1928 1920
1929 axbuf = kmalloc(XBUFSIZE, GFP_KERNEL); 1921 for (i = 0; i < XBUFSIZE; i++) {
1930 if (axbuf == NULL) 1922 axbuf[i] = (void *)__get_free_page(GFP_KERNEL);
1931 goto err_free_xbuf; 1923 if (!axbuf[i])
1924 goto err_free_axbuf;
1925 }
1932 1926
1933 do_test(); 1927 do_test();
1934 1928
@@ -1940,11 +1934,15 @@ static int __init tcrypt_mod_init(void)
1940 */ 1934 */
1941 err = -EAGAIN; 1935 err = -EAGAIN;
1942 1936
1943 kfree(axbuf); 1937err_free_axbuf:
1944 err_free_xbuf: 1938 for (i = 0; i < XBUFSIZE && axbuf[i]; i++)
1945 kfree(xbuf); 1939 free_page((unsigned long)axbuf[i]);
1946 err_free_tv: 1940err_free_xbuf:
1947 kfree(tvmem); 1941 for (i = 0; i < XBUFSIZE && xbuf[i]; i++)
1942 free_page((unsigned long)xbuf[i]);
1943err_free_tv:
1944 for (i = 0; i < TVMEMSIZE && tvmem[i]; i++)
1945 free_page((unsigned long)tvmem[i]);
1948 1946
1949 return err; 1947 return err;
1950} 1948}
diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h
index 801e0c288862..c6254a1776fe 100644
--- a/crypto/tcrypt.h
+++ b/crypto/tcrypt.h
@@ -39,7 +39,7 @@ struct cipher_testvec {
39 char *iv; 39 char *iv;
40 char *input; 40 char *input;
41 char *result; 41 char *result;
42 unsigned char tap[MAX_TAP]; 42 unsigned short tap[MAX_TAP];
43 int np; 43 int np;
44 unsigned char fail; 44 unsigned char fail;
45 unsigned char wk; /* weak key flag */ 45 unsigned char wk; /* weak key flag */
@@ -5111,6 +5111,8 @@ static struct cipher_testvec aes_ctr_enc_tv_template[] = {
5111 "\x4b\xef\x31\x18\xea\xac\xb1\x84" 5111 "\x4b\xef\x31\x18\xea\xac\xb1\x84"
5112 "\x21\xed\xda\x86", 5112 "\x21\xed\xda\x86",
5113 .rlen = 4100, 5113 .rlen = 4100,
5114 .np = 2,
5115 .tap = { 4064, 36 },
5114 }, 5116 },
5115}; 5117};
5116 5118
@@ -8126,7 +8128,9 @@ static struct cipher_testvec salsa20_stream_enc_tv_template[] = {
8126 "\xfc\x3f\x09\x7a\x0b\xdc\xc5\x1b" 8128 "\xfc\x3f\x09\x7a\x0b\xdc\xc5\x1b"
8127 "\x87\x13\xc6\x5b\x59\x8d\xf2\xc8" 8129 "\x87\x13\xc6\x5b\x59\x8d\xf2\xc8"
8128 "\xaf\xdf\x11\x95", 8130 "\xaf\xdf\x11\x95",
8129 .rlen = 4100, 8131 .rlen = 4100,
8132 .np = 2,
8133 .tap = { 4064, 36 },
8130 }, 8134 },
8131}; 8135};
8132 8136