aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorStephan Mueller <smueller@chronox.de>2014-06-28 15:58:24 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2014-07-04 09:09:20 -0400
commit8c98716601bc05091ff49aa8ebf5299a0c6604a0 (patch)
treeab302f2028b8616cdc666b5a6689e636c1003fa6 /crypto
parent8fecaad77fb9e076daa462ac1596330a604e23ad (diff)
crypto: drbg - use of kernel linked list
The DRBG-style linked list to manage input data that is fed into the cipher invocations is replaced with the kernel linked list implementation. The change is transparent to users of the interfaces offered by the DRBG. Therefore, no changes to the testmgr code is needed. Reported-by: kbuild test robot <fengguang.wu@intel.com> Signed-off-by: Stephan Mueller <smueller@chronox.de> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/drbg.c233
1 files changed, 124 insertions, 109 deletions
diff --git a/crypto/drbg.c b/crypto/drbg.c
index 3f0b7e0f8bac..d6621a6181d7 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -370,13 +370,12 @@ static int drbg_fini_sym_kernel(struct drbg_state *drbg);
370/* BCC function for CTR DRBG as defined in 10.4.3 */ 370/* BCC function for CTR DRBG as defined in 10.4.3 */
371static int drbg_ctr_bcc(struct drbg_state *drbg, 371static int drbg_ctr_bcc(struct drbg_state *drbg,
372 unsigned char *out, const unsigned char *key, 372 unsigned char *out, const unsigned char *key,
373 struct drbg_string *in) 373 struct list_head *in)
374{ 374{
375 int ret = -EFAULT; 375 int ret = 0;
376 struct drbg_string *curr = in; 376 struct drbg_string *curr = NULL;
377 size_t inpos = curr->len;
378 const unsigned char *pos = curr->buf;
379 struct drbg_string data; 377 struct drbg_string data;
378 short cnt = 0;
380 379
381 drbg_string_fill(&data, out, drbg_blocklen(drbg)); 380 drbg_string_fill(&data, out, drbg_blocklen(drbg));
382 381
@@ -384,39 +383,29 @@ static int drbg_ctr_bcc(struct drbg_state *drbg,
384 memset(out, 0, drbg_blocklen(drbg)); 383 memset(out, 0, drbg_blocklen(drbg));
385 384
386 /* 10.4.3 step 2 / 4 */ 385 /* 10.4.3 step 2 / 4 */
387 while (inpos) { 386 list_for_each_entry(curr, in, list) {
388 short cnt = 0; 387 const unsigned char *pos = curr->buf;
388 size_t len = curr->len;
389 /* 10.4.3 step 4.1 */ 389 /* 10.4.3 step 4.1 */
390 for (cnt = 0; cnt < drbg_blocklen(drbg); cnt++) { 390 while (len) {
391 out[cnt] ^= *pos; 391 /* 10.4.3 step 4.2 */
392 pos++; inpos--; 392 if (drbg_blocklen(drbg) == cnt) {
393 /* 393 cnt = 0;
394 * The following branch implements the linked list 394 ret = drbg_kcapi_sym(drbg, key, out, &data);
395 * iteration of drbg_string *in. If we are at the 395 if (ret)
396 * end of the current list member, we have to start 396 return ret;
397 * using the next member if available. The inpos
398 * value always points to the current byte and will
399 * be zero if we have processed the last byte of
400 * the last linked list member.
401 */
402 if (0 == inpos) {
403 curr = curr->next;
404 if (NULL != curr) {
405 pos = curr->buf;
406 inpos = curr->len;
407 } else {
408 inpos = 0;
409 break;
410 }
411 } 397 }
398 out[cnt] ^= *pos;
399 pos++;
400 cnt++;
401 len--;
412 } 402 }
413 /* 10.4.3 step 4.2 */
414 ret = drbg_kcapi_sym(drbg, key, out, &data);
415 if (ret)
416 return ret;
417 /* 10.4.3 step 2 */
418 } 403 }
419 return 0; 404 /* 10.4.3 step 4.2 for last block */
405 if (cnt)
406 ret = drbg_kcapi_sym(drbg, key, out, &data);
407
408 return ret;
420} 409}
421 410
422/* 411/*
@@ -461,13 +450,13 @@ static int drbg_ctr_bcc(struct drbg_state *drbg,
461/* Derivation Function for CTR DRBG as defined in 10.4.2 */ 450/* Derivation Function for CTR DRBG as defined in 10.4.2 */
462static int drbg_ctr_df(struct drbg_state *drbg, 451static int drbg_ctr_df(struct drbg_state *drbg,
463 unsigned char *df_data, size_t bytes_to_return, 452 unsigned char *df_data, size_t bytes_to_return,
464 struct drbg_string *addtl) 453 struct list_head *seedlist)
465{ 454{
466 int ret = -EFAULT; 455 int ret = -EFAULT;
467 unsigned char L_N[8]; 456 unsigned char L_N[8];
468 /* S3 is input */ 457 /* S3 is input */
469 struct drbg_string S1, S2, S4, cipherin; 458 struct drbg_string S1, S2, S4, cipherin;
470 struct drbg_string *tempstr = addtl; 459 LIST_HEAD(bcc_list);
471 unsigned char *pad = df_data + drbg_statelen(drbg); 460 unsigned char *pad = df_data + drbg_statelen(drbg);
472 unsigned char *iv = pad + drbg_blocklen(drbg); 461 unsigned char *iv = pad + drbg_blocklen(drbg);
473 unsigned char *temp = iv + drbg_blocklen(drbg); 462 unsigned char *temp = iv + drbg_blocklen(drbg);
@@ -484,6 +473,7 @@ static int drbg_ctr_df(struct drbg_state *drbg,
484 unsigned char *X; 473 unsigned char *X;
485 size_t generated_len = 0; 474 size_t generated_len = 0;
486 size_t inputlen = 0; 475 size_t inputlen = 0;
476 struct drbg_string *seed = NULL;
487 477
488 memset(pad, 0, drbg_blocklen(drbg)); 478 memset(pad, 0, drbg_blocklen(drbg));
489 memset(iv, 0, drbg_blocklen(drbg)); 479 memset(iv, 0, drbg_blocklen(drbg));
@@ -496,8 +486,8 @@ static int drbg_ctr_df(struct drbg_state *drbg,
496 return -EINVAL; 486 return -EINVAL;
497 487
498 /* 10.4.2 step 2 -- calculate the entire length of all input data */ 488 /* 10.4.2 step 2 -- calculate the entire length of all input data */
499 for (; NULL != tempstr; tempstr = tempstr->next) 489 list_for_each_entry(seed, seedlist, list)
500 inputlen += tempstr->len; 490 inputlen += seed->len;
501 drbg_int2byte(&L_N[0], inputlen, 4); 491 drbg_int2byte(&L_N[0], inputlen, 4);
502 492
503 /* 10.4.2 step 3 */ 493 /* 10.4.2 step 3 */
@@ -518,20 +508,12 @@ static int drbg_ctr_df(struct drbg_state *drbg,
518 508
519 /* 10.4.2 step 4 -- first fill the linked list and then order it */ 509 /* 10.4.2 step 4 -- first fill the linked list and then order it */
520 drbg_string_fill(&S1, iv, drbg_blocklen(drbg)); 510 drbg_string_fill(&S1, iv, drbg_blocklen(drbg));
511 list_add_tail(&S1.list, &bcc_list);
521 drbg_string_fill(&S2, L_N, sizeof(L_N)); 512 drbg_string_fill(&S2, L_N, sizeof(L_N));
513 list_add_tail(&S2.list, &bcc_list);
514 list_splice_tail(seedlist, &bcc_list);
522 drbg_string_fill(&S4, pad, padlen); 515 drbg_string_fill(&S4, pad, padlen);
523 S1.next = &S2; 516 list_add_tail(&S4.list, &bcc_list);
524 S2.next = addtl;
525
526 /*
527 * Splice in addtl between S2 and S4 -- we place S4 at the end
528 * of the input data chain. As this code is only triggered when
529 * addtl is not NULL, no NULL checks are necessary.
530 */
531 tempstr = addtl;
532 while (tempstr->next)
533 tempstr = tempstr->next;
534 tempstr->next = &S4;
535 517
536 /* 10.4.2 step 9 */ 518 /* 10.4.2 step 9 */
537 while (templen < (drbg_keylen(drbg) + (drbg_blocklen(drbg)))) { 519 while (templen < (drbg_keylen(drbg) + (drbg_blocklen(drbg)))) {
@@ -542,7 +524,7 @@ static int drbg_ctr_df(struct drbg_state *drbg,
542 */ 524 */
543 drbg_int2byte(iv, i, 4); 525 drbg_int2byte(iv, i, 4);
544 /* 10.4.2 step 9.2 -- BCC and concatenation with temp */ 526 /* 10.4.2 step 9.2 -- BCC and concatenation with temp */
545 ret = drbg_ctr_bcc(drbg, temp + templen, K, &S1); 527 ret = drbg_ctr_bcc(drbg, temp + templen, K, &bcc_list);
546 if (ret) 528 if (ret)
547 goto out; 529 goto out;
548 /* 10.4.2 step 9.3 */ 530 /* 10.4.2 step 9.3 */
@@ -586,8 +568,8 @@ out:
586} 568}
587 569
588/* update function of CTR DRBG as defined in 10.2.1.2 */ 570/* update function of CTR DRBG as defined in 10.2.1.2 */
589static int drbg_ctr_update(struct drbg_state *drbg, 571static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed,
590 struct drbg_string *addtl, int reseed) 572 int reseed)
591{ 573{
592 int ret = -EFAULT; 574 int ret = -EFAULT;
593 /* 10.2.1.2 step 1 */ 575 /* 10.2.1.2 step 1 */
@@ -603,9 +585,8 @@ static int drbg_ctr_update(struct drbg_state *drbg,
603 memset(df_data, 0, drbg_statelen(drbg)); 585 memset(df_data, 0, drbg_statelen(drbg));
604 586
605 /* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */ 587 /* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */
606 if (addtl && 0 < addtl->len) { 588 if (seed) {
607 ret = drbg_ctr_df(drbg, df_data, drbg_statelen(drbg), 589 ret = drbg_ctr_df(drbg, df_data, drbg_statelen(drbg), seed);
608 addtl);
609 if (ret) 590 if (ret)
610 goto out; 591 goto out;
611 } 592 }
@@ -665,8 +646,10 @@ static int drbg_ctr_generate(struct drbg_state *drbg,
665 646
666 /* 10.2.1.5.2 step 2 */ 647 /* 10.2.1.5.2 step 2 */
667 if (addtl && 0 < addtl->len) { 648 if (addtl && 0 < addtl->len) {
668 addtl->next = NULL; 649 LIST_HEAD(addtllist);
669 ret = drbg_ctr_update(drbg, addtl, 1); 650
651 list_add_tail(&addtl->list, &addtllist);
652 ret = drbg_ctr_update(drbg, &addtllist, 1);
670 if (ret) 653 if (ret)
671 return 0; 654 return 0;
672 } 655 }
@@ -697,16 +680,21 @@ static int drbg_ctr_generate(struct drbg_state *drbg,
697 drbg_add_buf(drbg->V, drbg_blocklen(drbg), &prefix, 1); 680 drbg_add_buf(drbg->V, drbg_blocklen(drbg), &prefix, 1);
698 } 681 }
699 682
700 /* 10.2.1.5.2 step 6 */
701 if (addtl)
702 addtl->next = NULL;
703 /* 683 /*
684 * 10.2.1.5.2 step 6
704 * The following call invokes the DF function again which could be 685 * The following call invokes the DF function again which could be
705 * optimized. In step 2, the "additional_input" after step 2 is the 686 * optimized. In step 2, the "additional_input" after step 2 is the
706 * output of the DF function. If this result would be saved, the DF 687 * output of the DF function. If this result would be saved, the DF
707 * function would not need to be invoked again at this point. 688 * function would not need to be invoked again at this point.
708 */ 689 */
709 ret = drbg_ctr_update(drbg, addtl, 1); 690 if (addtl && 0 < addtl->len) {
691 LIST_HEAD(addtllist);
692
693 list_add_tail(&addtl->list, &addtllist);
694 ret = drbg_ctr_update(drbg, &addtllist, 1);
695 } else {
696 ret = drbg_ctr_update(drbg, NULL, 1);
697 }
710 if (ret) 698 if (ret)
711 len = ret; 699 len = ret;
712 700
@@ -729,19 +717,21 @@ static struct drbg_state_ops drbg_ctr_ops = {
729 717
730#if defined(CONFIG_CRYPTO_DRBG_HASH) || defined(CONFIG_CRYPTO_DRBG_HMAC) 718#if defined(CONFIG_CRYPTO_DRBG_HASH) || defined(CONFIG_CRYPTO_DRBG_HMAC)
731static int drbg_kcapi_hash(struct drbg_state *drbg, const unsigned char *key, 719static int drbg_kcapi_hash(struct drbg_state *drbg, const unsigned char *key,
732 unsigned char *outval, const struct drbg_string *in); 720 unsigned char *outval, const struct list_head *in);
733static int drbg_init_hash_kernel(struct drbg_state *drbg); 721static int drbg_init_hash_kernel(struct drbg_state *drbg);
734static int drbg_fini_hash_kernel(struct drbg_state *drbg); 722static int drbg_fini_hash_kernel(struct drbg_state *drbg);
735#endif /* (CONFIG_CRYPTO_DRBG_HASH || CONFIG_CRYPTO_DRBG_HMAC) */ 723#endif /* (CONFIG_CRYPTO_DRBG_HASH || CONFIG_CRYPTO_DRBG_HMAC) */
736 724
737#ifdef CONFIG_CRYPTO_DRBG_HMAC 725#ifdef CONFIG_CRYPTO_DRBG_HMAC
738/* update function of HMAC DRBG as defined in 10.1.2.2 */ 726/* update function of HMAC DRBG as defined in 10.1.2.2 */
739static int drbg_hmac_update(struct drbg_state *drbg, 727static int drbg_hmac_update(struct drbg_state *drbg, struct list_head *seed,
740 struct drbg_string *seed, int reseed) 728 int reseed)
741{ 729{
742 int ret = -EFAULT; 730 int ret = -EFAULT;
743 int i = 0; 731 int i = 0;
744 struct drbg_string seed1, seed2, cipherin; 732 struct drbg_string seed1, seed2, vdata;
733 LIST_HEAD(seedlist);
734 LIST_HEAD(vdatalist);
745 735
746 if (!reseed) { 736 if (!reseed) {
747 /* 10.1.2.3 step 2 */ 737 /* 10.1.2.3 step 2 */
@@ -750,13 +740,16 @@ static int drbg_hmac_update(struct drbg_state *drbg,
750 } 740 }
751 741
752 drbg_string_fill(&seed1, drbg->V, drbg_statelen(drbg)); 742 drbg_string_fill(&seed1, drbg->V, drbg_statelen(drbg));
743 list_add_tail(&seed1.list, &seedlist);
753 /* buffer of seed2 will be filled in for loop below with one byte */ 744 /* buffer of seed2 will be filled in for loop below with one byte */
754 drbg_string_fill(&seed2, NULL, 1); 745 drbg_string_fill(&seed2, NULL, 1);
755 seed1.next = &seed2; 746 list_add_tail(&seed2.list, &seedlist);
756 /* input data of seed is allowed to be NULL at this point */ 747 /* input data of seed is allowed to be NULL at this point */
757 seed2.next = seed; 748 if (seed)
749 list_splice_tail(seed, &seedlist);
758 750
759 drbg_string_fill(&cipherin, drbg->V, drbg_statelen(drbg)); 751 drbg_string_fill(&vdata, drbg->V, drbg_statelen(drbg));
752 list_add_tail(&vdata.list, &vdatalist);
760 for (i = 2; 0 < i; i--) { 753 for (i = 2; 0 < i; i--) {
761 /* first round uses 0x0, second 0x1 */ 754 /* first round uses 0x0, second 0x1 */
762 unsigned char prefix = DRBG_PREFIX0; 755 unsigned char prefix = DRBG_PREFIX0;
@@ -764,17 +757,17 @@ static int drbg_hmac_update(struct drbg_state *drbg,
764 prefix = DRBG_PREFIX1; 757 prefix = DRBG_PREFIX1;
765 /* 10.1.2.2 step 1 and 4 -- concatenation and HMAC for key */ 758 /* 10.1.2.2 step 1 and 4 -- concatenation and HMAC for key */
766 seed2.buf = &prefix; 759 seed2.buf = &prefix;
767 ret = drbg_kcapi_hash(drbg, drbg->C, drbg->C, &seed1); 760 ret = drbg_kcapi_hash(drbg, drbg->C, drbg->C, &seedlist);
768 if (ret) 761 if (ret)
769 return ret; 762 return ret;
770 763
771 /* 10.1.2.2 step 2 and 5 -- HMAC for V */ 764 /* 10.1.2.2 step 2 and 5 -- HMAC for V */
772 ret = drbg_kcapi_hash(drbg, drbg->C, drbg->V, &cipherin); 765 ret = drbg_kcapi_hash(drbg, drbg->C, drbg->V, &vdatalist);
773 if (ret) 766 if (ret)
774 return ret; 767 return ret;
775 768
776 /* 10.1.2.2 step 3 */ 769 /* 10.1.2.2 step 3 */
777 if (!seed || 0 == seed->len) 770 if (!seed)
778 return ret; 771 return ret;
779 } 772 }
780 773
@@ -790,20 +783,24 @@ static int drbg_hmac_generate(struct drbg_state *drbg,
790 int len = 0; 783 int len = 0;
791 int ret = 0; 784 int ret = 0;
792 struct drbg_string data; 785 struct drbg_string data;
786 LIST_HEAD(datalist);
793 787
794 /* 10.1.2.5 step 2 */ 788 /* 10.1.2.5 step 2 */
795 if (addtl && 0 < addtl->len) { 789 if (addtl && 0 < addtl->len) {
796 addtl->next = NULL; 790 LIST_HEAD(addtllist);
797 ret = drbg_hmac_update(drbg, addtl, 1); 791
792 list_add_tail(&addtl->list, &addtllist);
793 ret = drbg_hmac_update(drbg, &addtllist, 1);
798 if (ret) 794 if (ret)
799 return ret; 795 return ret;
800 } 796 }
801 797
802 drbg_string_fill(&data, drbg->V, drbg_statelen(drbg)); 798 drbg_string_fill(&data, drbg->V, drbg_statelen(drbg));
799 list_add_tail(&data.list, &datalist);
803 while (len < buflen) { 800 while (len < buflen) {
804 unsigned int outlen = 0; 801 unsigned int outlen = 0;
805 /* 10.1.2.5 step 4.1 */ 802 /* 10.1.2.5 step 4.1 */
806 ret = drbg_kcapi_hash(drbg, drbg->C, drbg->V, &data); 803 ret = drbg_kcapi_hash(drbg, drbg->C, drbg->V, &datalist);
807 if (ret) 804 if (ret)
808 return ret; 805 return ret;
809 outlen = (drbg_blocklen(drbg) < (buflen - len)) ? 806 outlen = (drbg_blocklen(drbg) < (buflen - len)) ?
@@ -817,9 +814,14 @@ static int drbg_hmac_generate(struct drbg_state *drbg,
817 } 814 }
818 815
819 /* 10.1.2.5 step 6 */ 816 /* 10.1.2.5 step 6 */
820 if (addtl) 817 if (addtl && 0 < addtl->len) {
821 addtl->next = NULL; 818 LIST_HEAD(addtllist);
822 ret = drbg_hmac_update(drbg, addtl, 1); 819
820 list_add_tail(&addtl->list, &addtllist);
821 ret = drbg_hmac_update(drbg, &addtllist, 1);
822 } else {
823 ret = drbg_hmac_update(drbg, NULL, 1);
824 }
823 if (ret) 825 if (ret)
824 return ret; 826 return ret;
825 827
@@ -858,13 +860,13 @@ static struct drbg_state_ops drbg_hmac_ops = {
858/* Derivation Function for Hash DRBG as defined in 10.4.1 */ 860/* Derivation Function for Hash DRBG as defined in 10.4.1 */
859static int drbg_hash_df(struct drbg_state *drbg, 861static int drbg_hash_df(struct drbg_state *drbg,
860 unsigned char *outval, size_t outlen, 862 unsigned char *outval, size_t outlen,
861 struct drbg_string *entropy) 863 struct list_head *entropylist)
862{ 864{
863 int ret = 0; 865 int ret = 0;
864 size_t len = 0; 866 size_t len = 0;
865 unsigned char input[5]; 867 unsigned char input[5];
866 unsigned char *tmp = drbg->scratchpad + drbg_statelen(drbg); 868 unsigned char *tmp = drbg->scratchpad + drbg_statelen(drbg);
867 struct drbg_string data1; 869 struct drbg_string data;
868 870
869 memset(tmp, 0, drbg_blocklen(drbg)); 871 memset(tmp, 0, drbg_blocklen(drbg));
870 872
@@ -873,14 +875,14 @@ static int drbg_hash_df(struct drbg_state *drbg,
873 drbg_int2byte(&input[1], (outlen * 8), 4); 875 drbg_int2byte(&input[1], (outlen * 8), 4);
874 876
875 /* 10.4.1 step 4.1 -- concatenation of data for input into hash */ 877 /* 10.4.1 step 4.1 -- concatenation of data for input into hash */
876 drbg_string_fill(&data1, input, 5); 878 drbg_string_fill(&data, input, 5);
877 data1.next = entropy; 879 list_add(&data.list, entropylist);
878 880
879 /* 10.4.1 step 4 */ 881 /* 10.4.1 step 4 */
880 while (len < outlen) { 882 while (len < outlen) {
881 short blocklen = 0; 883 short blocklen = 0;
882 /* 10.4.1 step 4.1 */ 884 /* 10.4.1 step 4.1 */
883 ret = drbg_kcapi_hash(drbg, NULL, tmp, &data1); 885 ret = drbg_kcapi_hash(drbg, NULL, tmp, entropylist);
884 if (ret) 886 if (ret)
885 goto out; 887 goto out;
886 /* 10.4.1 step 4.2 */ 888 /* 10.4.1 step 4.2 */
@@ -897,11 +899,13 @@ out:
897} 899}
898 900
899/* update function for Hash DRBG as defined in 10.1.1.2 / 10.1.1.3 */ 901/* update function for Hash DRBG as defined in 10.1.1.2 / 10.1.1.3 */
900static int drbg_hash_update(struct drbg_state *drbg, struct drbg_string *seed, 902static int drbg_hash_update(struct drbg_state *drbg, struct list_head *seed,
901 int reseed) 903 int reseed)
902{ 904{
903 int ret = 0; 905 int ret = 0;
904 struct drbg_string data1, data2; 906 struct drbg_string data1, data2;
907 LIST_HEAD(datalist);
908 LIST_HEAD(datalist2);
905 unsigned char *V = drbg->scratchpad; 909 unsigned char *V = drbg->scratchpad;
906 unsigned char prefix = DRBG_PREFIX1; 910 unsigned char prefix = DRBG_PREFIX1;
907 911
@@ -913,26 +917,25 @@ static int drbg_hash_update(struct drbg_state *drbg, struct drbg_string *seed,
913 /* 10.1.1.3 step 1 */ 917 /* 10.1.1.3 step 1 */
914 memcpy(V, drbg->V, drbg_statelen(drbg)); 918 memcpy(V, drbg->V, drbg_statelen(drbg));
915 drbg_string_fill(&data1, &prefix, 1); 919 drbg_string_fill(&data1, &prefix, 1);
920 list_add_tail(&data1.list, &datalist);
916 drbg_string_fill(&data2, V, drbg_statelen(drbg)); 921 drbg_string_fill(&data2, V, drbg_statelen(drbg));
917 data1.next = &data2; 922 list_add_tail(&data2.list, &datalist);
918 data2.next = seed;
919 } else {
920 drbg_string_fill(&data1, seed->buf, seed->len);
921 data1.next = seed->next;
922 } 923 }
924 list_splice_tail(seed, &datalist);
923 925
924 /* 10.1.1.2 / 10.1.1.3 step 2 and 3 */ 926 /* 10.1.1.2 / 10.1.1.3 step 2 and 3 */
925 ret = drbg_hash_df(drbg, drbg->V, drbg_statelen(drbg), &data1); 927 ret = drbg_hash_df(drbg, drbg->V, drbg_statelen(drbg), &datalist);
926 if (ret) 928 if (ret)
927 goto out; 929 goto out;
928 930
929 /* 10.1.1.2 / 10.1.1.3 step 4 */ 931 /* 10.1.1.2 / 10.1.1.3 step 4 */
930 prefix = DRBG_PREFIX0; 932 prefix = DRBG_PREFIX0;
931 drbg_string_fill(&data1, &prefix, 1); 933 drbg_string_fill(&data1, &prefix, 1);
934 list_add_tail(&data1.list, &datalist2);
932 drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg)); 935 drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg));
933 data1.next = &data2; 936 list_add_tail(&data2.list, &datalist2);
934 /* 10.1.1.2 / 10.1.1.3 step 4 */ 937 /* 10.1.1.2 / 10.1.1.3 step 4 */
935 ret = drbg_hash_df(drbg, drbg->C, drbg_statelen(drbg), &data1); 938 ret = drbg_hash_df(drbg, drbg->C, drbg_statelen(drbg), &datalist2);
936 939
937out: 940out:
938 memset(drbg->scratchpad, 0, drbg_statelen(drbg)); 941 memset(drbg->scratchpad, 0, drbg_statelen(drbg));
@@ -945,7 +948,7 @@ static int drbg_hash_process_addtl(struct drbg_state *drbg,
945{ 948{
946 int ret = 0; 949 int ret = 0;
947 struct drbg_string data1, data2; 950 struct drbg_string data1, data2;
948 struct drbg_string *data3; 951 LIST_HEAD(datalist);
949 unsigned char prefix = DRBG_PREFIX2; 952 unsigned char prefix = DRBG_PREFIX2;
950 953
951 /* this is value w as per documentation */ 954 /* this is value w as per documentation */
@@ -958,11 +961,10 @@ static int drbg_hash_process_addtl(struct drbg_state *drbg,
958 /* 10.1.1.4 step 2a */ 961 /* 10.1.1.4 step 2a */
959 drbg_string_fill(&data1, &prefix, 1); 962 drbg_string_fill(&data1, &prefix, 1);
960 drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg)); 963 drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg));
961 data3 = addtl; 964 list_add_tail(&data1.list, &datalist);
962 data1.next = &data2; 965 list_add_tail(&data2.list, &datalist);
963 data2.next = data3; 966 list_add_tail(&addtl->list, &datalist);
964 data3->next = NULL; 967 ret = drbg_kcapi_hash(drbg, NULL, drbg->scratchpad, &datalist);
965 ret = drbg_kcapi_hash(drbg, NULL, drbg->scratchpad, &data1);
966 if (ret) 968 if (ret)
967 goto out; 969 goto out;
968 970
@@ -985,6 +987,7 @@ static int drbg_hash_hashgen(struct drbg_state *drbg,
985 unsigned char *src = drbg->scratchpad; 987 unsigned char *src = drbg->scratchpad;
986 unsigned char *dst = drbg->scratchpad + drbg_statelen(drbg); 988 unsigned char *dst = drbg->scratchpad + drbg_statelen(drbg);
987 struct drbg_string data; 989 struct drbg_string data;
990 LIST_HEAD(datalist);
988 unsigned char prefix = DRBG_PREFIX1; 991 unsigned char prefix = DRBG_PREFIX1;
989 992
990 memset(src, 0, drbg_statelen(drbg)); 993 memset(src, 0, drbg_statelen(drbg));
@@ -994,10 +997,11 @@ static int drbg_hash_hashgen(struct drbg_state *drbg,
994 memcpy(src, drbg->V, drbg_statelen(drbg)); 997 memcpy(src, drbg->V, drbg_statelen(drbg));
995 998
996 drbg_string_fill(&data, src, drbg_statelen(drbg)); 999 drbg_string_fill(&data, src, drbg_statelen(drbg));
1000 list_add_tail(&data.list, &datalist);
997 while (len < buflen) { 1001 while (len < buflen) {
998 unsigned int outlen = 0; 1002 unsigned int outlen = 0;
999 /* 10.1.1.4 step hashgen 4.1 */ 1003 /* 10.1.1.4 step hashgen 4.1 */
1000 ret = drbg_kcapi_hash(drbg, NULL, dst, &data); 1004 ret = drbg_kcapi_hash(drbg, NULL, dst, &datalist);
1001 if (ret) { 1005 if (ret) {
1002 len = ret; 1006 len = ret;
1003 goto out; 1007 goto out;
@@ -1032,6 +1036,7 @@ static int drbg_hash_generate(struct drbg_state *drbg,
1032 unsigned char req[8]; 1036 unsigned char req[8];
1033 unsigned char prefix = DRBG_PREFIX3; 1037 unsigned char prefix = DRBG_PREFIX3;
1034 struct drbg_string data1, data2; 1038 struct drbg_string data1, data2;
1039 LIST_HEAD(datalist);
1035 1040
1036 /* 10.1.1.4 step 2 */ 1041 /* 10.1.1.4 step 2 */
1037 ret = drbg_hash_process_addtl(drbg, addtl); 1042 ret = drbg_hash_process_addtl(drbg, addtl);
@@ -1044,9 +1049,10 @@ static int drbg_hash_generate(struct drbg_state *drbg,
1044 memset(drbg->scratchpad, 0, drbg_blocklen(drbg)); 1049 memset(drbg->scratchpad, 0, drbg_blocklen(drbg));
1045 /* 10.1.1.4 step 4 */ 1050 /* 10.1.1.4 step 4 */
1046 drbg_string_fill(&data1, &prefix, 1); 1051 drbg_string_fill(&data1, &prefix, 1);
1052 list_add_tail(&data1.list, &datalist);
1047 drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg)); 1053 drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg));
1048 data1.next = &data2; 1054 list_add_tail(&data2.list, &datalist);
1049 ret = drbg_kcapi_hash(drbg, NULL, drbg->scratchpad, &data1); 1055 ret = drbg_kcapi_hash(drbg, NULL, drbg->scratchpad, &datalist);
1050 if (ret) { 1056 if (ret) {
1051 len = ret; 1057 len = ret;
1052 goto out; 1058 goto out;
@@ -1099,6 +1105,7 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
1099 unsigned char *entropy = NULL; 1105 unsigned char *entropy = NULL;
1100 size_t entropylen = 0; 1106 size_t entropylen = 0;
1101 struct drbg_string data1; 1107 struct drbg_string data1;
1108 LIST_HEAD(seedlist);
1102 1109
1103 /* 9.1 / 9.2 / 9.3.1 step 3 */ 1110 /* 9.1 / 9.2 / 9.3.1 step 3 */
1104 if (pers && pers->len > (drbg_max_addtl(drbg))) { 1111 if (pers && pers->len > (drbg_max_addtl(drbg))) {
@@ -1133,18 +1140,19 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
1133 get_random_bytes(entropy, entropylen); 1140 get_random_bytes(entropy, entropylen);
1134 drbg_string_fill(&data1, entropy, entropylen); 1141 drbg_string_fill(&data1, entropy, entropylen);
1135 } 1142 }
1143 list_add_tail(&data1.list, &seedlist);
1136 1144
1137 /* 1145 /*
1138 * concatenation of entropy with personalization str / addtl input) 1146 * concatenation of entropy with personalization str / addtl input)
1139 * the variable pers is directly handed in by the caller, so check its 1147 * the variable pers is directly handed in by the caller, so check its
1140 * contents whether it is appropriate 1148 * contents whether it is appropriate
1141 */ 1149 */
1142 if (pers && pers->buf && 0 < pers->len && NULL == pers->next) { 1150 if (pers && pers->buf && 0 < pers->len) {
1143 data1.next = pers; 1151 list_add_tail(&pers->list, &seedlist);
1144 pr_devel("DRBG: using personalization string\n"); 1152 pr_devel("DRBG: using personalization string\n");
1145 } 1153 }
1146 1154
1147 ret = drbg->d_ops->update(drbg, &data1, reseed); 1155 ret = drbg->d_ops->update(drbg, &seedlist, reseed);
1148 if (ret) 1156 if (ret)
1149 goto out; 1157 goto out;
1150 1158
@@ -1642,15 +1650,16 @@ static int drbg_fini_hash_kernel(struct drbg_state *drbg)
1642} 1650}
1643 1651
1644static int drbg_kcapi_hash(struct drbg_state *drbg, const unsigned char *key, 1652static int drbg_kcapi_hash(struct drbg_state *drbg, const unsigned char *key,
1645 unsigned char *outval, const struct drbg_string *in) 1653 unsigned char *outval, const struct list_head *in)
1646{ 1654{
1647 struct sdesc *sdesc = (struct sdesc *)drbg->priv_data; 1655 struct sdesc *sdesc = (struct sdesc *)drbg->priv_data;
1656 struct drbg_string *input = NULL;
1648 1657
1649 if (key) 1658 if (key)
1650 crypto_shash_setkey(sdesc->shash.tfm, key, drbg_statelen(drbg)); 1659 crypto_shash_setkey(sdesc->shash.tfm, key, drbg_statelen(drbg));
1651 crypto_shash_init(&sdesc->shash); 1660 crypto_shash_init(&sdesc->shash);
1652 for (; NULL != in; in = in->next) 1661 list_for_each_entry(input, in, list)
1653 crypto_shash_update(&sdesc->shash, in->buf, in->len); 1662 crypto_shash_update(&sdesc->shash, input->buf, input->len);
1654 return crypto_shash_final(&sdesc->shash, outval); 1663 return crypto_shash_final(&sdesc->shash, outval);
1655} 1664}
1656#endif /* (CONFIG_CRYPTO_DRBG_HASH || CONFIG_CRYPTO_DRBG_HMAC) */ 1665#endif /* (CONFIG_CRYPTO_DRBG_HASH || CONFIG_CRYPTO_DRBG_HMAC) */
@@ -1785,12 +1794,15 @@ static int drbg_kcapi_random(struct crypto_rng *tfm, u8 *rdata,
1785 return drbg_generate_long(drbg, rdata, dlen, NULL); 1794 return drbg_generate_long(drbg, rdata, dlen, NULL);
1786 } else { 1795 } else {
1787 struct drbg_gen *data = (struct drbg_gen *)rdata; 1796 struct drbg_gen *data = (struct drbg_gen *)rdata;
1797 struct drbg_string addtl;
1788 /* catch NULL pointer */ 1798 /* catch NULL pointer */
1789 if (!data) 1799 if (!data)
1790 return 0; 1800 return 0;
1791 drbg_set_testdata(drbg, data->test_data); 1801 drbg_set_testdata(drbg, data->test_data);
1802 /* linked list variable is now local to allow modification */
1803 drbg_string_fill(&addtl, data->addtl->buf, data->addtl->len);
1792 return drbg_generate_long(drbg, data->outbuf, data->outlen, 1804 return drbg_generate_long(drbg, data->outbuf, data->outlen,
1793 data->addtl); 1805 &addtl);
1794 } 1806 }
1795} 1807}
1796 1808
@@ -1820,7 +1832,10 @@ static int drbg_kcapi_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen)
1820 if (!data) 1832 if (!data)
1821 return drbg_instantiate(drbg, NULL, coreref, pr); 1833 return drbg_instantiate(drbg, NULL, coreref, pr);
1822 drbg_set_testdata(drbg, data->test_data); 1834 drbg_set_testdata(drbg, data->test_data);
1823 return drbg_instantiate(drbg, data->addtl, coreref, pr); 1835 /* linked list variable is now local to allow modification */
1836 drbg_string_fill(&seed_string, data->addtl->buf,
1837 data->addtl->len);
1838 return drbg_instantiate(drbg, &seed_string, coreref, pr);
1824 } 1839 }
1825} 1840}
1826 1841