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 | } | ||
