diff options
Diffstat (limited to 'crypto/testmgr.c')
-rw-r--r-- | crypto/testmgr.c | 470 |
1 files changed, 365 insertions, 105 deletions
diff --git a/crypto/testmgr.c b/crypto/testmgr.c index b50c3c6b17a2..e9e9d84293b9 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/scatterlist.h> | 19 | #include <linux/scatterlist.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/string.h> | 21 | #include <linux/string.h> |
22 | #include <crypto/rng.h> | ||
22 | 23 | ||
23 | #include "internal.h" | 24 | #include "internal.h" |
24 | #include "testmgr.h" | 25 | #include "testmgr.h" |
@@ -84,10 +85,16 @@ struct hash_test_suite { | |||
84 | unsigned int count; | 85 | unsigned int count; |
85 | }; | 86 | }; |
86 | 87 | ||
88 | struct cprng_test_suite { | ||
89 | struct cprng_testvec *vecs; | ||
90 | unsigned int count; | ||
91 | }; | ||
92 | |||
87 | struct alg_test_desc { | 93 | struct alg_test_desc { |
88 | const char *alg; | 94 | const char *alg; |
89 | int (*test)(const struct alg_test_desc *desc, const char *driver, | 95 | int (*test)(const struct alg_test_desc *desc, const char *driver, |
90 | u32 type, u32 mask); | 96 | u32 type, u32 mask); |
97 | int fips_allowed; /* set if alg is allowed in fips mode */ | ||
91 | 98 | ||
92 | union { | 99 | union { |
93 | struct aead_test_suite aead; | 100 | struct aead_test_suite aead; |
@@ -95,14 +102,12 @@ struct alg_test_desc { | |||
95 | struct comp_test_suite comp; | 102 | struct comp_test_suite comp; |
96 | struct pcomp_test_suite pcomp; | 103 | struct pcomp_test_suite pcomp; |
97 | struct hash_test_suite hash; | 104 | struct hash_test_suite hash; |
105 | struct cprng_test_suite cprng; | ||
98 | } suite; | 106 | } suite; |
99 | }; | 107 | }; |
100 | 108 | ||
101 | static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 }; | 109 | static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 }; |
102 | 110 | ||
103 | static char *xbuf[XBUFSIZE]; | ||
104 | static char *axbuf[XBUFSIZE]; | ||
105 | |||
106 | static void hexdump(unsigned char *buf, unsigned int len) | 111 | static void hexdump(unsigned char *buf, unsigned int len) |
107 | { | 112 | { |
108 | print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET, | 113 | print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET, |
@@ -121,6 +126,33 @@ static void tcrypt_complete(struct crypto_async_request *req, int err) | |||
121 | complete(&res->completion); | 126 | complete(&res->completion); |
122 | } | 127 | } |
123 | 128 | ||
129 | static int testmgr_alloc_buf(char *buf[XBUFSIZE]) | ||
130 | { | ||
131 | int i; | ||
132 | |||
133 | for (i = 0; i < XBUFSIZE; i++) { | ||
134 | buf[i] = (void *)__get_free_page(GFP_KERNEL); | ||
135 | if (!buf[i]) | ||
136 | goto err_free_buf; | ||
137 | } | ||
138 | |||
139 | return 0; | ||
140 | |||
141 | err_free_buf: | ||
142 | while (i-- > 0) | ||
143 | free_page((unsigned long)buf[i]); | ||
144 | |||
145 | return -ENOMEM; | ||
146 | } | ||
147 | |||
148 | static void testmgr_free_buf(char *buf[XBUFSIZE]) | ||
149 | { | ||
150 | int i; | ||
151 | |||
152 | for (i = 0; i < XBUFSIZE; i++) | ||
153 | free_page((unsigned long)buf[i]); | ||
154 | } | ||
155 | |||
124 | static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, | 156 | static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, |
125 | unsigned int tcount) | 157 | unsigned int tcount) |
126 | { | 158 | { |
@@ -130,8 +162,12 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, | |||
130 | char result[64]; | 162 | char result[64]; |
131 | struct ahash_request *req; | 163 | struct ahash_request *req; |
132 | struct tcrypt_result tresult; | 164 | struct tcrypt_result tresult; |
133 | int ret; | ||
134 | void *hash_buff; | 165 | void *hash_buff; |
166 | char *xbuf[XBUFSIZE]; | ||
167 | int ret = -ENOMEM; | ||
168 | |||
169 | if (testmgr_alloc_buf(xbuf)) | ||
170 | goto out_nobuf; | ||
135 | 171 | ||
136 | init_completion(&tresult.completion); | 172 | init_completion(&tresult.completion); |
137 | 173 | ||
@@ -139,17 +175,25 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, | |||
139 | if (!req) { | 175 | if (!req) { |
140 | printk(KERN_ERR "alg: hash: Failed to allocate request for " | 176 | printk(KERN_ERR "alg: hash: Failed to allocate request for " |
141 | "%s\n", algo); | 177 | "%s\n", algo); |
142 | ret = -ENOMEM; | ||
143 | goto out_noreq; | 178 | goto out_noreq; |
144 | } | 179 | } |
145 | ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | 180 | ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, |
146 | tcrypt_complete, &tresult); | 181 | tcrypt_complete, &tresult); |
147 | 182 | ||
183 | j = 0; | ||
148 | for (i = 0; i < tcount; i++) { | 184 | for (i = 0; i < tcount; i++) { |
185 | if (template[i].np) | ||
186 | continue; | ||
187 | |||
188 | j++; | ||
149 | memset(result, 0, 64); | 189 | memset(result, 0, 64); |
150 | 190 | ||
151 | hash_buff = xbuf[0]; | 191 | hash_buff = xbuf[0]; |
152 | 192 | ||
193 | ret = -EINVAL; | ||
194 | if (WARN_ON(template[i].psize > PAGE_SIZE)) | ||
195 | goto out; | ||
196 | |||
153 | memcpy(hash_buff, template[i].plaintext, template[i].psize); | 197 | memcpy(hash_buff, template[i].plaintext, template[i].psize); |
154 | sg_init_one(&sg[0], hash_buff, template[i].psize); | 198 | sg_init_one(&sg[0], hash_buff, template[i].psize); |
155 | 199 | ||
@@ -159,7 +203,7 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, | |||
159 | template[i].ksize); | 203 | template[i].ksize); |
160 | if (ret) { | 204 | if (ret) { |
161 | printk(KERN_ERR "alg: hash: setkey failed on " | 205 | printk(KERN_ERR "alg: hash: setkey failed on " |
162 | "test %d for %s: ret=%d\n", i + 1, algo, | 206 | "test %d for %s: ret=%d\n", j, algo, |
163 | -ret); | 207 | -ret); |
164 | goto out; | 208 | goto out; |
165 | } | 209 | } |
@@ -181,14 +225,14 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, | |||
181 | /* fall through */ | 225 | /* fall through */ |
182 | default: | 226 | default: |
183 | printk(KERN_ERR "alg: hash: digest failed on test %d " | 227 | printk(KERN_ERR "alg: hash: digest failed on test %d " |
184 | "for %s: ret=%d\n", i + 1, algo, -ret); | 228 | "for %s: ret=%d\n", j, algo, -ret); |
185 | goto out; | 229 | goto out; |
186 | } | 230 | } |
187 | 231 | ||
188 | if (memcmp(result, template[i].digest, | 232 | if (memcmp(result, template[i].digest, |
189 | crypto_ahash_digestsize(tfm))) { | 233 | crypto_ahash_digestsize(tfm))) { |
190 | printk(KERN_ERR "alg: hash: Test %d failed for %s\n", | 234 | printk(KERN_ERR "alg: hash: Test %d failed for %s\n", |
191 | i + 1, algo); | 235 | j, algo); |
192 | hexdump(result, crypto_ahash_digestsize(tfm)); | 236 | hexdump(result, crypto_ahash_digestsize(tfm)); |
193 | ret = -EINVAL; | 237 | ret = -EINVAL; |
194 | goto out; | 238 | goto out; |
@@ -203,7 +247,11 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, | |||
203 | 247 | ||
204 | temp = 0; | 248 | temp = 0; |
205 | sg_init_table(sg, template[i].np); | 249 | sg_init_table(sg, template[i].np); |
250 | ret = -EINVAL; | ||
206 | for (k = 0; k < template[i].np; k++) { | 251 | for (k = 0; k < template[i].np; k++) { |
252 | if (WARN_ON(offset_in_page(IDX[k]) + | ||
253 | template[i].tap[k] > PAGE_SIZE)) | ||
254 | goto out; | ||
207 | sg_set_buf(&sg[k], | 255 | sg_set_buf(&sg[k], |
208 | memcpy(xbuf[IDX[k] >> PAGE_SHIFT] + | 256 | memcpy(xbuf[IDX[k] >> PAGE_SHIFT] + |
209 | offset_in_page(IDX[k]), | 257 | offset_in_page(IDX[k]), |
@@ -265,6 +313,8 @@ static int test_hash(struct crypto_ahash *tfm, struct hash_testvec *template, | |||
265 | out: | 313 | out: |
266 | ahash_request_free(req); | 314 | ahash_request_free(req); |
267 | out_noreq: | 315 | out_noreq: |
316 | testmgr_free_buf(xbuf); | ||
317 | out_nobuf: | ||
268 | return ret; | 318 | return ret; |
269 | } | 319 | } |
270 | 320 | ||
@@ -273,7 +323,7 @@ static int test_aead(struct crypto_aead *tfm, int enc, | |||
273 | { | 323 | { |
274 | const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)); | 324 | const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)); |
275 | unsigned int i, j, k, n, temp; | 325 | unsigned int i, j, k, n, temp; |
276 | int ret = 0; | 326 | int ret = -ENOMEM; |
277 | char *q; | 327 | char *q; |
278 | char *key; | 328 | char *key; |
279 | struct aead_request *req; | 329 | struct aead_request *req; |
@@ -285,6 +335,13 @@ static int test_aead(struct crypto_aead *tfm, int enc, | |||
285 | void *input; | 335 | void *input; |
286 | void *assoc; | 336 | void *assoc; |
287 | char iv[MAX_IVLEN]; | 337 | char iv[MAX_IVLEN]; |
338 | char *xbuf[XBUFSIZE]; | ||
339 | char *axbuf[XBUFSIZE]; | ||
340 | |||
341 | if (testmgr_alloc_buf(xbuf)) | ||
342 | goto out_noxbuf; | ||
343 | if (testmgr_alloc_buf(axbuf)) | ||
344 | goto out_noaxbuf; | ||
288 | 345 | ||
289 | if (enc == ENCRYPT) | 346 | if (enc == ENCRYPT) |
290 | e = "encryption"; | 347 | e = "encryption"; |
@@ -297,7 +354,6 @@ static int test_aead(struct crypto_aead *tfm, int enc, | |||
297 | if (!req) { | 354 | if (!req) { |
298 | printk(KERN_ERR "alg: aead: Failed to allocate request for " | 355 | printk(KERN_ERR "alg: aead: Failed to allocate request for " |
299 | "%s\n", algo); | 356 | "%s\n", algo); |
300 | ret = -ENOMEM; | ||
301 | goto out; | 357 | goto out; |
302 | } | 358 | } |
303 | 359 | ||
@@ -314,6 +370,11 @@ static int test_aead(struct crypto_aead *tfm, int enc, | |||
314 | input = xbuf[0]; | 370 | input = xbuf[0]; |
315 | assoc = axbuf[0]; | 371 | assoc = axbuf[0]; |
316 | 372 | ||
373 | ret = -EINVAL; | ||
374 | if (WARN_ON(template[i].ilen > PAGE_SIZE || | ||
375 | template[i].alen > PAGE_SIZE)) | ||
376 | goto out; | ||
377 | |||
317 | memcpy(input, template[i].input, template[i].ilen); | 378 | memcpy(input, template[i].input, template[i].ilen); |
318 | memcpy(assoc, template[i].assoc, template[i].alen); | 379 | memcpy(assoc, template[i].assoc, template[i].alen); |
319 | if (template[i].iv) | 380 | if (template[i].iv) |
@@ -363,6 +424,16 @@ static int test_aead(struct crypto_aead *tfm, int enc, | |||
363 | 424 | ||
364 | switch (ret) { | 425 | switch (ret) { |
365 | case 0: | 426 | case 0: |
427 | if (template[i].novrfy) { | ||
428 | /* verification was supposed to fail */ | ||
429 | printk(KERN_ERR "alg: aead: %s failed " | ||
430 | "on test %d for %s: ret was 0, " | ||
431 | "expected -EBADMSG\n", | ||
432 | e, j, algo); | ||
433 | /* so really, we got a bad message */ | ||
434 | ret = -EBADMSG; | ||
435 | goto out; | ||
436 | } | ||
366 | break; | 437 | break; |
367 | case -EINPROGRESS: | 438 | case -EINPROGRESS: |
368 | case -EBUSY: | 439 | case -EBUSY: |
@@ -372,6 +443,10 @@ static int test_aead(struct crypto_aead *tfm, int enc, | |||
372 | INIT_COMPLETION(result.completion); | 443 | INIT_COMPLETION(result.completion); |
373 | break; | 444 | break; |
374 | } | 445 | } |
446 | case -EBADMSG: | ||
447 | if (template[i].novrfy) | ||
448 | /* verification failure was expected */ | ||
449 | continue; | ||
375 | /* fall through */ | 450 | /* fall through */ |
376 | default: | 451 | default: |
377 | printk(KERN_ERR "alg: aead: %s failed on test " | 452 | printk(KERN_ERR "alg: aead: %s failed on test " |
@@ -459,7 +534,11 @@ static int test_aead(struct crypto_aead *tfm, int enc, | |||
459 | } | 534 | } |
460 | 535 | ||
461 | sg_init_table(asg, template[i].anp); | 536 | sg_init_table(asg, template[i].anp); |
537 | ret = -EINVAL; | ||
462 | for (k = 0, temp = 0; k < template[i].anp; k++) { | 538 | for (k = 0, temp = 0; k < template[i].anp; k++) { |
539 | if (WARN_ON(offset_in_page(IDX[k]) + | ||
540 | template[i].atap[k] > PAGE_SIZE)) | ||
541 | goto out; | ||
463 | sg_set_buf(&asg[k], | 542 | sg_set_buf(&asg[k], |
464 | memcpy(axbuf[IDX[k] >> PAGE_SHIFT] + | 543 | memcpy(axbuf[IDX[k] >> PAGE_SHIFT] + |
465 | offset_in_page(IDX[k]), | 544 | offset_in_page(IDX[k]), |
@@ -481,6 +560,16 @@ static int test_aead(struct crypto_aead *tfm, int enc, | |||
481 | 560 | ||
482 | switch (ret) { | 561 | switch (ret) { |
483 | case 0: | 562 | case 0: |
563 | if (template[i].novrfy) { | ||
564 | /* verification was supposed to fail */ | ||
565 | printk(KERN_ERR "alg: aead: %s failed " | ||
566 | "on chunk test %d for %s: ret " | ||
567 | "was 0, expected -EBADMSG\n", | ||
568 | e, j, algo); | ||
569 | /* so really, we got a bad message */ | ||
570 | ret = -EBADMSG; | ||
571 | goto out; | ||
572 | } | ||
484 | break; | 573 | break; |
485 | case -EINPROGRESS: | 574 | case -EINPROGRESS: |
486 | case -EBUSY: | 575 | case -EBUSY: |
@@ -490,6 +579,10 @@ static int test_aead(struct crypto_aead *tfm, int enc, | |||
490 | INIT_COMPLETION(result.completion); | 579 | INIT_COMPLETION(result.completion); |
491 | break; | 580 | break; |
492 | } | 581 | } |
582 | case -EBADMSG: | ||
583 | if (template[i].novrfy) | ||
584 | /* verification failure was expected */ | ||
585 | continue; | ||
493 | /* fall through */ | 586 | /* fall through */ |
494 | default: | 587 | default: |
495 | printk(KERN_ERR "alg: aead: %s failed on " | 588 | printk(KERN_ERR "alg: aead: %s failed on " |
@@ -546,6 +639,10 @@ static int test_aead(struct crypto_aead *tfm, int enc, | |||
546 | 639 | ||
547 | out: | 640 | out: |
548 | aead_request_free(req); | 641 | aead_request_free(req); |
642 | testmgr_free_buf(axbuf); | ||
643 | out_noaxbuf: | ||
644 | testmgr_free_buf(xbuf); | ||
645 | out_noxbuf: | ||
549 | return ret; | 646 | return ret; |
550 | } | 647 | } |
551 | 648 | ||
@@ -554,10 +651,14 @@ static int test_cipher(struct crypto_cipher *tfm, int enc, | |||
554 | { | 651 | { |
555 | const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm)); | 652 | const char *algo = crypto_tfm_alg_driver_name(crypto_cipher_tfm(tfm)); |
556 | unsigned int i, j, k; | 653 | unsigned int i, j, k; |
557 | int ret; | ||
558 | char *q; | 654 | char *q; |
559 | const char *e; | 655 | const char *e; |
560 | void *data; | 656 | void *data; |
657 | char *xbuf[XBUFSIZE]; | ||
658 | int ret = -ENOMEM; | ||
659 | |||
660 | if (testmgr_alloc_buf(xbuf)) | ||
661 | goto out_nobuf; | ||
561 | 662 | ||
562 | if (enc == ENCRYPT) | 663 | if (enc == ENCRYPT) |
563 | e = "encryption"; | 664 | e = "encryption"; |
@@ -571,6 +672,10 @@ static int test_cipher(struct crypto_cipher *tfm, int enc, | |||
571 | 672 | ||
572 | j++; | 673 | j++; |
573 | 674 | ||
675 | ret = -EINVAL; | ||
676 | if (WARN_ON(template[i].ilen > PAGE_SIZE)) | ||
677 | goto out; | ||
678 | |||
574 | data = xbuf[0]; | 679 | data = xbuf[0]; |
575 | memcpy(data, template[i].input, template[i].ilen); | 680 | memcpy(data, template[i].input, template[i].ilen); |
576 | 681 | ||
@@ -611,6 +716,8 @@ static int test_cipher(struct crypto_cipher *tfm, int enc, | |||
611 | ret = 0; | 716 | ret = 0; |
612 | 717 | ||
613 | out: | 718 | out: |
719 | testmgr_free_buf(xbuf); | ||
720 | out_nobuf: | ||
614 | return ret; | 721 | return ret; |
615 | } | 722 | } |
616 | 723 | ||
@@ -620,7 +727,6 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc, | |||
620 | const char *algo = | 727 | const char *algo = |
621 | crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm)); | 728 | crypto_tfm_alg_driver_name(crypto_ablkcipher_tfm(tfm)); |
622 | unsigned int i, j, k, n, temp; | 729 | unsigned int i, j, k, n, temp; |
623 | int ret; | ||
624 | char *q; | 730 | char *q; |
625 | struct ablkcipher_request *req; | 731 | struct ablkcipher_request *req; |
626 | struct scatterlist sg[8]; | 732 | struct scatterlist sg[8]; |
@@ -628,6 +734,11 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc, | |||
628 | struct tcrypt_result result; | 734 | struct tcrypt_result result; |
629 | void *data; | 735 | void *data; |
630 | char iv[MAX_IVLEN]; | 736 | char iv[MAX_IVLEN]; |
737 | char *xbuf[XBUFSIZE]; | ||
738 | int ret = -ENOMEM; | ||
739 | |||
740 | if (testmgr_alloc_buf(xbuf)) | ||
741 | goto out_nobuf; | ||
631 | 742 | ||
632 | if (enc == ENCRYPT) | 743 | if (enc == ENCRYPT) |
633 | e = "encryption"; | 744 | e = "encryption"; |
@@ -640,7 +751,6 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc, | |||
640 | if (!req) { | 751 | if (!req) { |
641 | printk(KERN_ERR "alg: skcipher: Failed to allocate request " | 752 | printk(KERN_ERR "alg: skcipher: Failed to allocate request " |
642 | "for %s\n", algo); | 753 | "for %s\n", algo); |
643 | ret = -ENOMEM; | ||
644 | goto out; | 754 | goto out; |
645 | } | 755 | } |
646 | 756 | ||
@@ -657,6 +767,10 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc, | |||
657 | if (!(template[i].np)) { | 767 | if (!(template[i].np)) { |
658 | j++; | 768 | j++; |
659 | 769 | ||
770 | ret = -EINVAL; | ||
771 | if (WARN_ON(template[i].ilen > PAGE_SIZE)) | ||
772 | goto out; | ||
773 | |||
660 | data = xbuf[0]; | 774 | data = xbuf[0]; |
661 | memcpy(data, template[i].input, template[i].ilen); | 775 | memcpy(data, template[i].input, template[i].ilen); |
662 | 776 | ||
@@ -825,6 +939,8 @@ static int test_skcipher(struct crypto_ablkcipher *tfm, int enc, | |||
825 | 939 | ||
826 | out: | 940 | out: |
827 | ablkcipher_request_free(req); | 941 | ablkcipher_request_free(req); |
942 | testmgr_free_buf(xbuf); | ||
943 | out_nobuf: | ||
828 | return ret; | 944 | return ret; |
829 | } | 945 | } |
830 | 946 | ||
@@ -837,7 +953,8 @@ static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate, | |||
837 | int ret; | 953 | int ret; |
838 | 954 | ||
839 | for (i = 0; i < ctcount; i++) { | 955 | for (i = 0; i < ctcount; i++) { |
840 | int ilen, dlen = COMP_BUF_SIZE; | 956 | int ilen; |
957 | unsigned int dlen = COMP_BUF_SIZE; | ||
841 | 958 | ||
842 | memset(result, 0, sizeof (result)); | 959 | memset(result, 0, sizeof (result)); |
843 | 960 | ||
@@ -869,7 +986,8 @@ static int test_comp(struct crypto_comp *tfm, struct comp_testvec *ctemplate, | |||
869 | } | 986 | } |
870 | 987 | ||
871 | for (i = 0; i < dtcount; i++) { | 988 | for (i = 0; i < dtcount; i++) { |
872 | int ilen, dlen = COMP_BUF_SIZE; | 989 | int ilen; |
990 | unsigned int dlen = COMP_BUF_SIZE; | ||
873 | 991 | ||
874 | memset(result, 0, sizeof (result)); | 992 | memset(result, 0, sizeof (result)); |
875 | 993 | ||
@@ -914,24 +1032,25 @@ static int test_pcomp(struct crypto_pcomp *tfm, | |||
914 | const char *algo = crypto_tfm_alg_driver_name(crypto_pcomp_tfm(tfm)); | 1032 | const char *algo = crypto_tfm_alg_driver_name(crypto_pcomp_tfm(tfm)); |
915 | unsigned int i; | 1033 | unsigned int i; |
916 | char result[COMP_BUF_SIZE]; | 1034 | char result[COMP_BUF_SIZE]; |
917 | int error; | 1035 | int res; |
918 | 1036 | ||
919 | for (i = 0; i < ctcount; i++) { | 1037 | for (i = 0; i < ctcount; i++) { |
920 | struct comp_request req; | 1038 | struct comp_request req; |
1039 | unsigned int produced = 0; | ||
921 | 1040 | ||
922 | error = crypto_compress_setup(tfm, ctemplate[i].params, | 1041 | res = crypto_compress_setup(tfm, ctemplate[i].params, |
923 | ctemplate[i].paramsize); | 1042 | ctemplate[i].paramsize); |
924 | if (error) { | 1043 | if (res) { |
925 | pr_err("alg: pcomp: compression setup failed on test " | 1044 | pr_err("alg: pcomp: compression setup failed on test " |
926 | "%d for %s: error=%d\n", i + 1, algo, error); | 1045 | "%d for %s: error=%d\n", i + 1, algo, res); |
927 | return error; | 1046 | return res; |
928 | } | 1047 | } |
929 | 1048 | ||
930 | error = crypto_compress_init(tfm); | 1049 | res = crypto_compress_init(tfm); |
931 | if (error) { | 1050 | if (res) { |
932 | pr_err("alg: pcomp: compression init failed on test " | 1051 | pr_err("alg: pcomp: compression init failed on test " |
933 | "%d for %s: error=%d\n", i + 1, algo, error); | 1052 | "%d for %s: error=%d\n", i + 1, algo, res); |
934 | return error; | 1053 | return res; |
935 | } | 1054 | } |
936 | 1055 | ||
937 | memset(result, 0, sizeof(result)); | 1056 | memset(result, 0, sizeof(result)); |
@@ -941,32 +1060,37 @@ static int test_pcomp(struct crypto_pcomp *tfm, | |||
941 | req.next_out = result; | 1060 | req.next_out = result; |
942 | req.avail_out = ctemplate[i].outlen / 2; | 1061 | req.avail_out = ctemplate[i].outlen / 2; |
943 | 1062 | ||
944 | error = crypto_compress_update(tfm, &req); | 1063 | res = crypto_compress_update(tfm, &req); |
945 | if (error && (error != -EAGAIN || req.avail_in)) { | 1064 | if (res < 0 && (res != -EAGAIN || req.avail_in)) { |
946 | pr_err("alg: pcomp: compression update failed on test " | 1065 | pr_err("alg: pcomp: compression update failed on test " |
947 | "%d for %s: error=%d\n", i + 1, algo, error); | 1066 | "%d for %s: error=%d\n", i + 1, algo, res); |
948 | return error; | 1067 | return res; |
949 | } | 1068 | } |
1069 | if (res > 0) | ||
1070 | produced += res; | ||
950 | 1071 | ||
951 | /* Add remaining input data */ | 1072 | /* Add remaining input data */ |
952 | req.avail_in += (ctemplate[i].inlen + 1) / 2; | 1073 | req.avail_in += (ctemplate[i].inlen + 1) / 2; |
953 | 1074 | ||
954 | error = crypto_compress_update(tfm, &req); | 1075 | res = crypto_compress_update(tfm, &req); |
955 | if (error && (error != -EAGAIN || req.avail_in)) { | 1076 | if (res < 0 && (res != -EAGAIN || req.avail_in)) { |
956 | pr_err("alg: pcomp: compression update failed on test " | 1077 | pr_err("alg: pcomp: compression update failed on test " |
957 | "%d for %s: error=%d\n", i + 1, algo, error); | 1078 | "%d for %s: error=%d\n", i + 1, algo, res); |
958 | return error; | 1079 | return res; |
959 | } | 1080 | } |
1081 | if (res > 0) | ||
1082 | produced += res; | ||
960 | 1083 | ||
961 | /* Provide remaining output space */ | 1084 | /* Provide remaining output space */ |
962 | req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2; | 1085 | req.avail_out += COMP_BUF_SIZE - ctemplate[i].outlen / 2; |
963 | 1086 | ||
964 | error = crypto_compress_final(tfm, &req); | 1087 | res = crypto_compress_final(tfm, &req); |
965 | if (error) { | 1088 | if (res < 0) { |
966 | pr_err("alg: pcomp: compression final failed on test " | 1089 | pr_err("alg: pcomp: compression final failed on test " |
967 | "%d for %s: error=%d\n", i + 1, algo, error); | 1090 | "%d for %s: error=%d\n", i + 1, algo, res); |
968 | return error; | 1091 | return res; |
969 | } | 1092 | } |
1093 | produced += res; | ||
970 | 1094 | ||
971 | if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) { | 1095 | if (COMP_BUF_SIZE - req.avail_out != ctemplate[i].outlen) { |
972 | pr_err("alg: comp: Compression test %d failed for %s: " | 1096 | pr_err("alg: comp: Compression test %d failed for %s: " |
@@ -976,6 +1100,13 @@ static int test_pcomp(struct crypto_pcomp *tfm, | |||
976 | return -EINVAL; | 1100 | return -EINVAL; |
977 | } | 1101 | } |
978 | 1102 | ||
1103 | if (produced != ctemplate[i].outlen) { | ||
1104 | pr_err("alg: comp: Compression test %d failed for %s: " | ||
1105 | "returned len = %u (expected %d)\n", i + 1, | ||
1106 | algo, produced, ctemplate[i].outlen); | ||
1107 | return -EINVAL; | ||
1108 | } | ||
1109 | |||
979 | if (memcmp(result, ctemplate[i].output, ctemplate[i].outlen)) { | 1110 | if (memcmp(result, ctemplate[i].output, ctemplate[i].outlen)) { |
980 | pr_err("alg: pcomp: Compression test %d failed for " | 1111 | pr_err("alg: pcomp: Compression test %d failed for " |
981 | "%s\n", i + 1, algo); | 1112 | "%s\n", i + 1, algo); |
@@ -986,21 +1117,21 @@ static int test_pcomp(struct crypto_pcomp *tfm, | |||
986 | 1117 | ||
987 | for (i = 0; i < dtcount; i++) { | 1118 | for (i = 0; i < dtcount; i++) { |
988 | struct comp_request req; | 1119 | struct comp_request req; |
1120 | unsigned int produced = 0; | ||
989 | 1121 | ||
990 | error = crypto_decompress_setup(tfm, dtemplate[i].params, | 1122 | res = crypto_decompress_setup(tfm, dtemplate[i].params, |
991 | dtemplate[i].paramsize); | 1123 | dtemplate[i].paramsize); |
992 | if (error) { | 1124 | if (res) { |
993 | pr_err("alg: pcomp: decompression setup failed on " | 1125 | pr_err("alg: pcomp: decompression setup failed on " |
994 | "test %d for %s: error=%d\n", i + 1, algo, | 1126 | "test %d for %s: error=%d\n", i + 1, algo, res); |
995 | error); | 1127 | return res; |
996 | return error; | ||
997 | } | 1128 | } |
998 | 1129 | ||
999 | error = crypto_decompress_init(tfm); | 1130 | res = crypto_decompress_init(tfm); |
1000 | if (error) { | 1131 | if (res) { |
1001 | pr_err("alg: pcomp: decompression init failed on test " | 1132 | pr_err("alg: pcomp: decompression init failed on test " |
1002 | "%d for %s: error=%d\n", i + 1, algo, error); | 1133 | "%d for %s: error=%d\n", i + 1, algo, res); |
1003 | return error; | 1134 | return res; |
1004 | } | 1135 | } |
1005 | 1136 | ||
1006 | memset(result, 0, sizeof(result)); | 1137 | memset(result, 0, sizeof(result)); |
@@ -1010,35 +1141,38 @@ static int test_pcomp(struct crypto_pcomp *tfm, | |||
1010 | req.next_out = result; | 1141 | req.next_out = result; |
1011 | req.avail_out = dtemplate[i].outlen / 2; | 1142 | req.avail_out = dtemplate[i].outlen / 2; |
1012 | 1143 | ||
1013 | error = crypto_decompress_update(tfm, &req); | 1144 | res = crypto_decompress_update(tfm, &req); |
1014 | if (error && (error != -EAGAIN || req.avail_in)) { | 1145 | if (res < 0 && (res != -EAGAIN || req.avail_in)) { |
1015 | pr_err("alg: pcomp: decompression update failed on " | 1146 | pr_err("alg: pcomp: decompression update failed on " |
1016 | "test %d for %s: error=%d\n", i + 1, algo, | 1147 | "test %d for %s: error=%d\n", i + 1, algo, res); |
1017 | error); | 1148 | return res; |
1018 | return error; | ||
1019 | } | 1149 | } |
1150 | if (res > 0) | ||
1151 | produced += res; | ||
1020 | 1152 | ||
1021 | /* Add remaining input data */ | 1153 | /* Add remaining input data */ |
1022 | req.avail_in += (dtemplate[i].inlen + 1) / 2; | 1154 | req.avail_in += (dtemplate[i].inlen + 1) / 2; |
1023 | 1155 | ||
1024 | error = crypto_decompress_update(tfm, &req); | 1156 | res = crypto_decompress_update(tfm, &req); |
1025 | if (error && (error != -EAGAIN || req.avail_in)) { | 1157 | if (res < 0 && (res != -EAGAIN || req.avail_in)) { |
1026 | pr_err("alg: pcomp: decompression update failed on " | 1158 | pr_err("alg: pcomp: decompression update failed on " |
1027 | "test %d for %s: error=%d\n", i + 1, algo, | 1159 | "test %d for %s: error=%d\n", i + 1, algo, res); |
1028 | error); | 1160 | return res; |
1029 | return error; | ||
1030 | } | 1161 | } |
1162 | if (res > 0) | ||
1163 | produced += res; | ||
1031 | 1164 | ||
1032 | /* Provide remaining output space */ | 1165 | /* Provide remaining output space */ |
1033 | req.avail_out += COMP_BUF_SIZE - dtemplate[i].outlen / 2; | 1166 | req.avail_out += COMP_BUF_SIZE - dtemplate[i].outlen / 2; |
1034 | 1167 | ||
1035 | error = crypto_decompress_final(tfm, &req); | 1168 | res = crypto_decompress_final(tfm, &req); |
1036 | if (error && (error != -EAGAIN || req.avail_in)) { | 1169 | if (res < 0 && (res != -EAGAIN || req.avail_in)) { |
1037 | pr_err("alg: pcomp: decompression final failed on " | 1170 | pr_err("alg: pcomp: decompression final failed on " |
1038 | "test %d for %s: error=%d\n", i + 1, algo, | 1171 | "test %d for %s: error=%d\n", i + 1, algo, res); |
1039 | error); | 1172 | return res; |
1040 | return error; | ||
1041 | } | 1173 | } |
1174 | if (res > 0) | ||
1175 | produced += res; | ||
1042 | 1176 | ||
1043 | if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) { | 1177 | if (COMP_BUF_SIZE - req.avail_out != dtemplate[i].outlen) { |
1044 | pr_err("alg: comp: Decompression test %d failed for " | 1178 | pr_err("alg: comp: Decompression test %d failed for " |
@@ -1048,6 +1182,13 @@ static int test_pcomp(struct crypto_pcomp *tfm, | |||
1048 | return -EINVAL; | 1182 | return -EINVAL; |
1049 | } | 1183 | } |
1050 | 1184 | ||
1185 | if (produced != dtemplate[i].outlen) { | ||
1186 | pr_err("alg: comp: Decompression test %d failed for " | ||
1187 | "%s: returned len = %u (expected %d)\n", i + 1, | ||
1188 | algo, produced, dtemplate[i].outlen); | ||
1189 | return -EINVAL; | ||
1190 | } | ||
1191 | |||
1051 | if (memcmp(result, dtemplate[i].output, dtemplate[i].outlen)) { | 1192 | if (memcmp(result, dtemplate[i].output, dtemplate[i].outlen)) { |
1052 | pr_err("alg: pcomp: Decompression test %d failed for " | 1193 | pr_err("alg: pcomp: Decompression test %d failed for " |
1053 | "%s\n", i + 1, algo); | 1194 | "%s\n", i + 1, algo); |
@@ -1059,6 +1200,68 @@ static int test_pcomp(struct crypto_pcomp *tfm, | |||
1059 | return 0; | 1200 | return 0; |
1060 | } | 1201 | } |
1061 | 1202 | ||
1203 | |||
1204 | static int test_cprng(struct crypto_rng *tfm, struct cprng_testvec *template, | ||
1205 | unsigned int tcount) | ||
1206 | { | ||
1207 | const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm)); | ||
1208 | int err, i, j, seedsize; | ||
1209 | u8 *seed; | ||
1210 | char result[32]; | ||
1211 | |||
1212 | seedsize = crypto_rng_seedsize(tfm); | ||
1213 | |||
1214 | seed = kmalloc(seedsize, GFP_KERNEL); | ||
1215 | if (!seed) { | ||
1216 | printk(KERN_ERR "alg: cprng: Failed to allocate seed space " | ||
1217 | "for %s\n", algo); | ||
1218 | return -ENOMEM; | ||
1219 | } | ||
1220 | |||
1221 | for (i = 0; i < tcount; i++) { | ||
1222 | memset(result, 0, 32); | ||
1223 | |||
1224 | memcpy(seed, template[i].v, template[i].vlen); | ||
1225 | memcpy(seed + template[i].vlen, template[i].key, | ||
1226 | template[i].klen); | ||
1227 | memcpy(seed + template[i].vlen + template[i].klen, | ||
1228 | template[i].dt, template[i].dtlen); | ||
1229 | |||
1230 | err = crypto_rng_reset(tfm, seed, seedsize); | ||
1231 | if (err) { | ||
1232 | printk(KERN_ERR "alg: cprng: Failed to reset rng " | ||
1233 | "for %s\n", algo); | ||
1234 | goto out; | ||
1235 | } | ||
1236 | |||
1237 | for (j = 0; j < template[i].loops; j++) { | ||
1238 | err = crypto_rng_get_bytes(tfm, result, | ||
1239 | template[i].rlen); | ||
1240 | if (err != template[i].rlen) { | ||
1241 | printk(KERN_ERR "alg: cprng: Failed to obtain " | ||
1242 | "the correct amount of random data for " | ||
1243 | "%s (requested %d, got %d)\n", algo, | ||
1244 | template[i].rlen, err); | ||
1245 | goto out; | ||
1246 | } | ||
1247 | } | ||
1248 | |||
1249 | err = memcmp(result, template[i].result, | ||
1250 | template[i].rlen); | ||
1251 | if (err) { | ||
1252 | printk(KERN_ERR "alg: cprng: Test %d failed for %s\n", | ||
1253 | i, algo); | ||
1254 | hexdump(result, template[i].rlen); | ||
1255 | err = -EINVAL; | ||
1256 | goto out; | ||
1257 | } | ||
1258 | } | ||
1259 | |||
1260 | out: | ||
1261 | kfree(seed); | ||
1262 | return err; | ||
1263 | } | ||
1264 | |||
1062 | static int alg_test_aead(const struct alg_test_desc *desc, const char *driver, | 1265 | static int alg_test_aead(const struct alg_test_desc *desc, const char *driver, |
1063 | u32 type, u32 mask) | 1266 | u32 type, u32 mask) |
1064 | { | 1267 | { |
@@ -1258,11 +1461,42 @@ out: | |||
1258 | return err; | 1461 | return err; |
1259 | } | 1462 | } |
1260 | 1463 | ||
1464 | static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver, | ||
1465 | u32 type, u32 mask) | ||
1466 | { | ||
1467 | struct crypto_rng *rng; | ||
1468 | int err; | ||
1469 | |||
1470 | rng = crypto_alloc_rng(driver, type, mask); | ||
1471 | if (IS_ERR(rng)) { | ||
1472 | printk(KERN_ERR "alg: cprng: Failed to load transform for %s: " | ||
1473 | "%ld\n", driver, PTR_ERR(rng)); | ||
1474 | return PTR_ERR(rng); | ||
1475 | } | ||
1476 | |||
1477 | err = test_cprng(rng, desc->suite.cprng.vecs, desc->suite.cprng.count); | ||
1478 | |||
1479 | crypto_free_rng(rng); | ||
1480 | |||
1481 | return err; | ||
1482 | } | ||
1483 | |||
1261 | /* Please keep this list sorted by algorithm name. */ | 1484 | /* Please keep this list sorted by algorithm name. */ |
1262 | static const struct alg_test_desc alg_test_descs[] = { | 1485 | static const struct alg_test_desc alg_test_descs[] = { |
1263 | { | 1486 | { |
1487 | .alg = "ansi_cprng", | ||
1488 | .test = alg_test_cprng, | ||
1489 | .fips_allowed = 1, | ||
1490 | .suite = { | ||
1491 | .cprng = { | ||
1492 | .vecs = ansi_cprng_aes_tv_template, | ||
1493 | .count = ANSI_CPRNG_AES_TEST_VECTORS | ||
1494 | } | ||
1495 | } | ||
1496 | }, { | ||
1264 | .alg = "cbc(aes)", | 1497 | .alg = "cbc(aes)", |
1265 | .test = alg_test_skcipher, | 1498 | .test = alg_test_skcipher, |
1499 | .fips_allowed = 1, | ||
1266 | .suite = { | 1500 | .suite = { |
1267 | .cipher = { | 1501 | .cipher = { |
1268 | .enc = { | 1502 | .enc = { |
@@ -1338,6 +1572,7 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1338 | }, { | 1572 | }, { |
1339 | .alg = "cbc(des3_ede)", | 1573 | .alg = "cbc(des3_ede)", |
1340 | .test = alg_test_skcipher, | 1574 | .test = alg_test_skcipher, |
1575 | .fips_allowed = 1, | ||
1341 | .suite = { | 1576 | .suite = { |
1342 | .cipher = { | 1577 | .cipher = { |
1343 | .enc = { | 1578 | .enc = { |
@@ -1368,6 +1603,7 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1368 | }, { | 1603 | }, { |
1369 | .alg = "ccm(aes)", | 1604 | .alg = "ccm(aes)", |
1370 | .test = alg_test_aead, | 1605 | .test = alg_test_aead, |
1606 | .fips_allowed = 1, | ||
1371 | .suite = { | 1607 | .suite = { |
1372 | .aead = { | 1608 | .aead = { |
1373 | .enc = { | 1609 | .enc = { |
@@ -1383,6 +1619,7 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1383 | }, { | 1619 | }, { |
1384 | .alg = "crc32c", | 1620 | .alg = "crc32c", |
1385 | .test = alg_test_crc32c, | 1621 | .test = alg_test_crc32c, |
1622 | .fips_allowed = 1, | ||
1386 | .suite = { | 1623 | .suite = { |
1387 | .hash = { | 1624 | .hash = { |
1388 | .vecs = crc32c_tv_template, | 1625 | .vecs = crc32c_tv_template, |
@@ -1390,6 +1627,22 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1390 | } | 1627 | } |
1391 | } | 1628 | } |
1392 | }, { | 1629 | }, { |
1630 | .alg = "ctr(aes)", | ||
1631 | .test = alg_test_skcipher, | ||
1632 | .fips_allowed = 1, | ||
1633 | .suite = { | ||
1634 | .cipher = { | ||
1635 | .enc = { | ||
1636 | .vecs = aes_ctr_enc_tv_template, | ||
1637 | .count = AES_CTR_ENC_TEST_VECTORS | ||
1638 | }, | ||
1639 | .dec = { | ||
1640 | .vecs = aes_ctr_dec_tv_template, | ||
1641 | .count = AES_CTR_DEC_TEST_VECTORS | ||
1642 | } | ||
1643 | } | ||
1644 | } | ||
1645 | }, { | ||
1393 | .alg = "cts(cbc(aes))", | 1646 | .alg = "cts(cbc(aes))", |
1394 | .test = alg_test_skcipher, | 1647 | .test = alg_test_skcipher, |
1395 | .suite = { | 1648 | .suite = { |
@@ -1422,6 +1675,7 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1422 | }, { | 1675 | }, { |
1423 | .alg = "ecb(aes)", | 1676 | .alg = "ecb(aes)", |
1424 | .test = alg_test_skcipher, | 1677 | .test = alg_test_skcipher, |
1678 | .fips_allowed = 1, | ||
1425 | .suite = { | 1679 | .suite = { |
1426 | .cipher = { | 1680 | .cipher = { |
1427 | .enc = { | 1681 | .enc = { |
@@ -1527,6 +1781,7 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1527 | }, { | 1781 | }, { |
1528 | .alg = "ecb(des)", | 1782 | .alg = "ecb(des)", |
1529 | .test = alg_test_skcipher, | 1783 | .test = alg_test_skcipher, |
1784 | .fips_allowed = 1, | ||
1530 | .suite = { | 1785 | .suite = { |
1531 | .cipher = { | 1786 | .cipher = { |
1532 | .enc = { | 1787 | .enc = { |
@@ -1542,6 +1797,7 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1542 | }, { | 1797 | }, { |
1543 | .alg = "ecb(des3_ede)", | 1798 | .alg = "ecb(des3_ede)", |
1544 | .test = alg_test_skcipher, | 1799 | .test = alg_test_skcipher, |
1800 | .fips_allowed = 1, | ||
1545 | .suite = { | 1801 | .suite = { |
1546 | .cipher = { | 1802 | .cipher = { |
1547 | .enc = { | 1803 | .enc = { |
@@ -1677,6 +1933,7 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1677 | }, { | 1933 | }, { |
1678 | .alg = "gcm(aes)", | 1934 | .alg = "gcm(aes)", |
1679 | .test = alg_test_aead, | 1935 | .test = alg_test_aead, |
1936 | .fips_allowed = 1, | ||
1680 | .suite = { | 1937 | .suite = { |
1681 | .aead = { | 1938 | .aead = { |
1682 | .enc = { | 1939 | .enc = { |
@@ -1719,6 +1976,7 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1719 | }, { | 1976 | }, { |
1720 | .alg = "hmac(sha1)", | 1977 | .alg = "hmac(sha1)", |
1721 | .test = alg_test_hash, | 1978 | .test = alg_test_hash, |
1979 | .fips_allowed = 1, | ||
1722 | .suite = { | 1980 | .suite = { |
1723 | .hash = { | 1981 | .hash = { |
1724 | .vecs = hmac_sha1_tv_template, | 1982 | .vecs = hmac_sha1_tv_template, |
@@ -1728,6 +1986,7 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1728 | }, { | 1986 | }, { |
1729 | .alg = "hmac(sha224)", | 1987 | .alg = "hmac(sha224)", |
1730 | .test = alg_test_hash, | 1988 | .test = alg_test_hash, |
1989 | .fips_allowed = 1, | ||
1731 | .suite = { | 1990 | .suite = { |
1732 | .hash = { | 1991 | .hash = { |
1733 | .vecs = hmac_sha224_tv_template, | 1992 | .vecs = hmac_sha224_tv_template, |
@@ -1737,6 +1996,7 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1737 | }, { | 1996 | }, { |
1738 | .alg = "hmac(sha256)", | 1997 | .alg = "hmac(sha256)", |
1739 | .test = alg_test_hash, | 1998 | .test = alg_test_hash, |
1999 | .fips_allowed = 1, | ||
1740 | .suite = { | 2000 | .suite = { |
1741 | .hash = { | 2001 | .hash = { |
1742 | .vecs = hmac_sha256_tv_template, | 2002 | .vecs = hmac_sha256_tv_template, |
@@ -1746,6 +2006,7 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1746 | }, { | 2006 | }, { |
1747 | .alg = "hmac(sha384)", | 2007 | .alg = "hmac(sha384)", |
1748 | .test = alg_test_hash, | 2008 | .test = alg_test_hash, |
2009 | .fips_allowed = 1, | ||
1749 | .suite = { | 2010 | .suite = { |
1750 | .hash = { | 2011 | .hash = { |
1751 | .vecs = hmac_sha384_tv_template, | 2012 | .vecs = hmac_sha384_tv_template, |
@@ -1755,6 +2016,7 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1755 | }, { | 2016 | }, { |
1756 | .alg = "hmac(sha512)", | 2017 | .alg = "hmac(sha512)", |
1757 | .test = alg_test_hash, | 2018 | .test = alg_test_hash, |
2019 | .fips_allowed = 1, | ||
1758 | .suite = { | 2020 | .suite = { |
1759 | .hash = { | 2021 | .hash = { |
1760 | .vecs = hmac_sha512_tv_template, | 2022 | .vecs = hmac_sha512_tv_template, |
@@ -1836,15 +2098,32 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1836 | }, { | 2098 | }, { |
1837 | .alg = "rfc3686(ctr(aes))", | 2099 | .alg = "rfc3686(ctr(aes))", |
1838 | .test = alg_test_skcipher, | 2100 | .test = alg_test_skcipher, |
2101 | .fips_allowed = 1, | ||
1839 | .suite = { | 2102 | .suite = { |
1840 | .cipher = { | 2103 | .cipher = { |
1841 | .enc = { | 2104 | .enc = { |
1842 | .vecs = aes_ctr_enc_tv_template, | 2105 | .vecs = aes_ctr_rfc3686_enc_tv_template, |
1843 | .count = AES_CTR_ENC_TEST_VECTORS | 2106 | .count = AES_CTR_3686_ENC_TEST_VECTORS |
1844 | }, | 2107 | }, |
1845 | .dec = { | 2108 | .dec = { |
1846 | .vecs = aes_ctr_dec_tv_template, | 2109 | .vecs = aes_ctr_rfc3686_dec_tv_template, |
1847 | .count = AES_CTR_DEC_TEST_VECTORS | 2110 | .count = AES_CTR_3686_DEC_TEST_VECTORS |
2111 | } | ||
2112 | } | ||
2113 | } | ||
2114 | }, { | ||
2115 | .alg = "rfc4309(ccm(aes))", | ||
2116 | .test = alg_test_aead, | ||
2117 | .fips_allowed = 1, | ||
2118 | .suite = { | ||
2119 | .aead = { | ||
2120 | .enc = { | ||
2121 | .vecs = aes_ccm_rfc4309_enc_tv_template, | ||
2122 | .count = AES_CCM_4309_ENC_TEST_VECTORS | ||
2123 | }, | ||
2124 | .dec = { | ||
2125 | .vecs = aes_ccm_rfc4309_dec_tv_template, | ||
2126 | .count = AES_CCM_4309_DEC_TEST_VECTORS | ||
1848 | } | 2127 | } |
1849 | } | 2128 | } |
1850 | } | 2129 | } |
@@ -1898,6 +2177,7 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1898 | }, { | 2177 | }, { |
1899 | .alg = "sha1", | 2178 | .alg = "sha1", |
1900 | .test = alg_test_hash, | 2179 | .test = alg_test_hash, |
2180 | .fips_allowed = 1, | ||
1901 | .suite = { | 2181 | .suite = { |
1902 | .hash = { | 2182 | .hash = { |
1903 | .vecs = sha1_tv_template, | 2183 | .vecs = sha1_tv_template, |
@@ -1907,6 +2187,7 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1907 | }, { | 2187 | }, { |
1908 | .alg = "sha224", | 2188 | .alg = "sha224", |
1909 | .test = alg_test_hash, | 2189 | .test = alg_test_hash, |
2190 | .fips_allowed = 1, | ||
1910 | .suite = { | 2191 | .suite = { |
1911 | .hash = { | 2192 | .hash = { |
1912 | .vecs = sha224_tv_template, | 2193 | .vecs = sha224_tv_template, |
@@ -1916,6 +2197,7 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1916 | }, { | 2197 | }, { |
1917 | .alg = "sha256", | 2198 | .alg = "sha256", |
1918 | .test = alg_test_hash, | 2199 | .test = alg_test_hash, |
2200 | .fips_allowed = 1, | ||
1919 | .suite = { | 2201 | .suite = { |
1920 | .hash = { | 2202 | .hash = { |
1921 | .vecs = sha256_tv_template, | 2203 | .vecs = sha256_tv_template, |
@@ -1925,6 +2207,7 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1925 | }, { | 2207 | }, { |
1926 | .alg = "sha384", | 2208 | .alg = "sha384", |
1927 | .test = alg_test_hash, | 2209 | .test = alg_test_hash, |
2210 | .fips_allowed = 1, | ||
1928 | .suite = { | 2211 | .suite = { |
1929 | .hash = { | 2212 | .hash = { |
1930 | .vecs = sha384_tv_template, | 2213 | .vecs = sha384_tv_template, |
@@ -1934,6 +2217,7 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
1934 | }, { | 2217 | }, { |
1935 | .alg = "sha512", | 2218 | .alg = "sha512", |
1936 | .test = alg_test_hash, | 2219 | .test = alg_test_hash, |
2220 | .fips_allowed = 1, | ||
1937 | .suite = { | 2221 | .suite = { |
1938 | .hash = { | 2222 | .hash = { |
1939 | .vecs = sha512_tv_template, | 2223 | .vecs = sha512_tv_template, |
@@ -2077,60 +2361,36 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask) | |||
2077 | if (i < 0) | 2361 | if (i < 0) |
2078 | goto notest; | 2362 | goto notest; |
2079 | 2363 | ||
2080 | return alg_test_cipher(alg_test_descs + i, driver, type, mask); | 2364 | if (fips_enabled && !alg_test_descs[i].fips_allowed) |
2365 | goto non_fips_alg; | ||
2366 | |||
2367 | rc = alg_test_cipher(alg_test_descs + i, driver, type, mask); | ||
2368 | goto test_done; | ||
2081 | } | 2369 | } |
2082 | 2370 | ||
2083 | i = alg_find_test(alg); | 2371 | i = alg_find_test(alg); |
2084 | if (i < 0) | 2372 | if (i < 0) |
2085 | goto notest; | 2373 | goto notest; |
2086 | 2374 | ||
2375 | if (fips_enabled && !alg_test_descs[i].fips_allowed) | ||
2376 | goto non_fips_alg; | ||
2377 | |||
2087 | rc = alg_test_descs[i].test(alg_test_descs + i, driver, | 2378 | rc = alg_test_descs[i].test(alg_test_descs + i, driver, |
2088 | type, mask); | 2379 | type, mask); |
2380 | test_done: | ||
2089 | if (fips_enabled && rc) | 2381 | if (fips_enabled && rc) |
2090 | panic("%s: %s alg self test failed in fips mode!\n", driver, alg); | 2382 | panic("%s: %s alg self test failed in fips mode!\n", driver, alg); |
2091 | 2383 | ||
2384 | if (fips_enabled && !rc) | ||
2385 | printk(KERN_INFO "alg: self-tests for %s (%s) passed\n", | ||
2386 | driver, alg); | ||
2387 | |||
2092 | return rc; | 2388 | return rc; |
2093 | 2389 | ||
2094 | notest: | 2390 | notest: |
2095 | printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver); | 2391 | printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver); |
2096 | return 0; | 2392 | return 0; |
2393 | non_fips_alg: | ||
2394 | return -EINVAL; | ||
2097 | } | 2395 | } |
2098 | EXPORT_SYMBOL_GPL(alg_test); | 2396 | EXPORT_SYMBOL_GPL(alg_test); |
2099 | |||
2100 | int __init testmgr_init(void) | ||
2101 | { | ||
2102 | int i; | ||
2103 | |||
2104 | for (i = 0; i < XBUFSIZE; i++) { | ||
2105 | xbuf[i] = (void *)__get_free_page(GFP_KERNEL); | ||
2106 | if (!xbuf[i]) | ||
2107 | goto err_free_xbuf; | ||
2108 | } | ||
2109 | |||
2110 | for (i = 0; i < XBUFSIZE; i++) { | ||
2111 | axbuf[i] = (void *)__get_free_page(GFP_KERNEL); | ||
2112 | if (!axbuf[i]) | ||
2113 | goto err_free_axbuf; | ||
2114 | } | ||
2115 | |||
2116 | return 0; | ||
2117 | |||
2118 | err_free_axbuf: | ||
2119 | for (i = 0; i < XBUFSIZE && axbuf[i]; i++) | ||
2120 | free_page((unsigned long)axbuf[i]); | ||
2121 | err_free_xbuf: | ||
2122 | for (i = 0; i < XBUFSIZE && xbuf[i]; i++) | ||
2123 | free_page((unsigned long)xbuf[i]); | ||
2124 | |||
2125 | return -ENOMEM; | ||
2126 | } | ||
2127 | |||
2128 | void testmgr_exit(void) | ||
2129 | { | ||
2130 | int i; | ||
2131 | |||
2132 | for (i = 0; i < XBUFSIZE; i++) | ||
2133 | free_page((unsigned long)axbuf[i]); | ||
2134 | for (i = 0; i < XBUFSIZE; i++) | ||
2135 | free_page((unsigned long)xbuf[i]); | ||
2136 | } | ||