aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/drbg.c233
-rw-r--r--include/crypto/drbg.h7
2 files changed, 128 insertions, 112 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
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index b507c5b6020a..4065dfca146a 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -50,6 +50,7 @@
50#include <crypto/rng.h> 50#include <crypto/rng.h>
51#include <linux/fips.h> 51#include <linux/fips.h>
52#include <linux/spinlock.h> 52#include <linux/spinlock.h>
53#include <linux/list.h>
53 54
54/* 55/*
55 * Concatenation Helper and string operation helper 56 * Concatenation Helper and string operation helper
@@ -64,7 +65,7 @@
64struct drbg_string { 65struct drbg_string {
65 const unsigned char *buf; 66 const unsigned char *buf;
66 size_t len; 67 size_t len;
67 struct drbg_string *next; 68 struct list_head list;
68}; 69};
69 70
70static inline void drbg_string_fill(struct drbg_string *string, 71static inline void drbg_string_fill(struct drbg_string *string,
@@ -72,7 +73,7 @@ static inline void drbg_string_fill(struct drbg_string *string,
72{ 73{
73 string->buf = buf; 74 string->buf = buf;
74 string->len = len; 75 string->len = len;
75 string->next = NULL; 76 INIT_LIST_HEAD(&string->list);
76} 77}
77 78
78struct drbg_state; 79struct drbg_state;
@@ -97,7 +98,7 @@ struct drbg_core {
97}; 98};
98 99
99struct drbg_state_ops { 100struct drbg_state_ops {
100 int (*update)(struct drbg_state *drbg, struct drbg_string *seed, 101 int (*update)(struct drbg_state *drbg, struct list_head *seed,
101 int reseed); 102 int reseed);
102 int (*generate)(struct drbg_state *drbg, 103 int (*generate)(struct drbg_state *drbg,
103 unsigned char *buf, unsigned int buflen, 104 unsigned char *buf, unsigned int buflen,