Commit 8c98716601bc05091ff49aa8ebf5299a0c6604a0

Authored by Stephan Mueller
Committed by Herbert Xu
1 parent 8fecaad77f

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>

Showing 2 changed files with 128 additions and 112 deletions Side-by-side Diff

... ... @@ -370,13 +370,12 @@
370 370 /* BCC function for CTR DRBG as defined in 10.4.3 */
371 371 static int drbg_ctr_bcc(struct drbg_state *drbg,
372 372 unsigned char *out, const unsigned char *key,
373   - struct drbg_string *in)
  373 + struct list_head *in)
374 374 {
375   - int ret = -EFAULT;
376   - struct drbg_string *curr = in;
377   - size_t inpos = curr->len;
378   - const unsigned char *pos = curr->buf;
  375 + int ret = 0;
  376 + struct drbg_string *curr = NULL;
379 377 struct drbg_string data;
  378 + short cnt = 0;
380 379  
381 380 drbg_string_fill(&data, out, drbg_blocklen(drbg));
382 381  
383 382  
384 383  
385 384  
386 385  
... ... @@ -384,39 +383,29 @@
384 383 memset(out, 0, drbg_blocklen(drbg));
385 384  
386 385 /* 10.4.3 step 2 / 4 */
387   - while (inpos) {
388   - short cnt = 0;
  386 + list_for_each_entry(curr, in, list) {
  387 + const unsigned char *pos = curr->buf;
  388 + size_t len = curr->len;
389 389 /* 10.4.3 step 4.1 */
390   - for (cnt = 0; cnt < drbg_blocklen(drbg); cnt++) {
391   - out[cnt] ^= *pos;
392   - pos++; inpos--;
393   - /*
394   - * The following branch implements the linked list
395   - * iteration of drbg_string *in. If we are at the
396   - * end of the current list member, we have to start
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   - }
  390 + while (len) {
  391 + /* 10.4.3 step 4.2 */
  392 + if (drbg_blocklen(drbg) == cnt) {
  393 + cnt = 0;
  394 + ret = drbg_kcapi_sym(drbg, key, out, &data);
  395 + if (ret)
  396 + return ret;
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 /*
423 412  
... ... @@ -461,13 +450,13 @@
461 450 /* Derivation Function for CTR DRBG as defined in 10.4.2 */
462 451 static int drbg_ctr_df(struct drbg_state *drbg,
463 452 unsigned char *df_data, size_t bytes_to_return,
464   - struct drbg_string *addtl)
  453 + struct list_head *seedlist)
465 454 {
466 455 int ret = -EFAULT;
467 456 unsigned char L_N[8];
468 457 /* S3 is input */
469 458 struct drbg_string S1, S2, S4, cipherin;
470   - struct drbg_string *tempstr = addtl;
  459 + LIST_HEAD(bcc_list);
471 460 unsigned char *pad = df_data + drbg_statelen(drbg);
472 461 unsigned char *iv = pad + drbg_blocklen(drbg);
473 462 unsigned char *temp = iv + drbg_blocklen(drbg);
... ... @@ -484,6 +473,7 @@
484 473 unsigned char *X;
485 474 size_t generated_len = 0;
486 475 size_t inputlen = 0;
  476 + struct drbg_string *seed = NULL;
487 477  
488 478 memset(pad, 0, drbg_blocklen(drbg));
489 479 memset(iv, 0, drbg_blocklen(drbg));
... ... @@ -496,8 +486,8 @@
496 486 return -EINVAL;
497 487  
498 488 /* 10.4.2 step 2 -- calculate the entire length of all input data */
499   - for (; NULL != tempstr; tempstr = tempstr->next)
500   - inputlen += tempstr->len;
  489 + list_for_each_entry(seed, seedlist, list)
  490 + inputlen += seed->len;
501 491 drbg_int2byte(&L_N[0], inputlen, 4);
502 492  
503 493 /* 10.4.2 step 3 */
504 494  
505 495  
506 496  
... ... @@ -518,21 +508,13 @@
518 508  
519 509 /* 10.4.2 step 4 -- first fill the linked list and then order it */
520 510 drbg_string_fill(&S1, iv, drbg_blocklen(drbg));
  511 + list_add_tail(&S1.list, &bcc_list);
521 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 515 drbg_string_fill(&S4, pad, padlen);
523   - S1.next = &S2;
524   - S2.next = addtl;
  516 + list_add_tail(&S4.list, &bcc_list);
525 517  
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   -
536 518 /* 10.4.2 step 9 */
537 519 while (templen < (drbg_keylen(drbg) + (drbg_blocklen(drbg)))) {
538 520 /*
... ... @@ -542,7 +524,7 @@
542 524 */
543 525 drbg_int2byte(iv, i, 4);
544 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 528 if (ret)
547 529 goto out;
548 530 /* 10.4.2 step 9.3 */
... ... @@ -586,8 +568,8 @@
586 568 }
587 569  
588 570 /* update function of CTR DRBG as defined in 10.2.1.2 */
589   -static int drbg_ctr_update(struct drbg_state *drbg,
590   - struct drbg_string *addtl, int reseed)
  571 +static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed,
  572 + int reseed)
591 573 {
592 574 int ret = -EFAULT;
593 575 /* 10.2.1.2 step 1 */
... ... @@ -603,9 +585,8 @@
603 585 memset(df_data, 0, drbg_statelen(drbg));
604 586  
605 587 /* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */
606   - if (addtl && 0 < addtl->len) {
607   - ret = drbg_ctr_df(drbg, df_data, drbg_statelen(drbg),
608   - addtl);
  588 + if (seed) {
  589 + ret = drbg_ctr_df(drbg, df_data, drbg_statelen(drbg), seed);
609 590 if (ret)
610 591 goto out;
611 592 }
... ... @@ -665,8 +646,10 @@
665 646  
666 647 /* 10.2.1.5.2 step 2 */
667 648 if (addtl && 0 < addtl->len) {
668   - addtl->next = NULL;
669   - ret = drbg_ctr_update(drbg, addtl, 1);
  649 + LIST_HEAD(addtllist);
  650 +
  651 + list_add_tail(&addtl->list, &addtllist);
  652 + ret = drbg_ctr_update(drbg, &addtllist, 1);
670 653 if (ret)
671 654 return 0;
672 655 }
673 656  
674 657  
... ... @@ -697,16 +680,21 @@
697 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 685 * The following call invokes the DF function again which could be
705 686 * optimized. In step 2, the "additional_input" after step 2 is the
706 687 * output of the DF function. If this result would be saved, the DF
707 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 698 if (ret)
711 699 len = ret;
712 700  
713 701  
714 702  
... ... @@ -729,19 +717,21 @@
729 717  
730 718 #if defined(CONFIG_CRYPTO_DRBG_HASH) || defined(CONFIG_CRYPTO_DRBG_HMAC)
731 719 static 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);
733 721 static int drbg_init_hash_kernel(struct drbg_state *drbg);
734 722 static int drbg_fini_hash_kernel(struct drbg_state *drbg);
735 723 #endif /* (CONFIG_CRYPTO_DRBG_HASH || CONFIG_CRYPTO_DRBG_HMAC) */
736 724  
737 725 #ifdef CONFIG_CRYPTO_DRBG_HMAC
738 726 /* update function of HMAC DRBG as defined in 10.1.2.2 */
739   -static int drbg_hmac_update(struct drbg_state *drbg,
740   - struct drbg_string *seed, int reseed)
  727 +static int drbg_hmac_update(struct drbg_state *drbg, struct list_head *seed,
  728 + int reseed)
741 729 {
742 730 int ret = -EFAULT;
743 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 736 if (!reseed) {
747 737 /* 10.1.2.3 step 2 */
748 738  
749 739  
750 740  
... ... @@ -750,13 +740,16 @@
750 740 }
751 741  
752 742 drbg_string_fill(&seed1, drbg->V, drbg_statelen(drbg));
  743 + list_add_tail(&seed1.list, &seedlist);
753 744 /* buffer of seed2 will be filled in for loop below with one byte */
754 745 drbg_string_fill(&seed2, NULL, 1);
755   - seed1.next = &seed2;
  746 + list_add_tail(&seed2.list, &seedlist);
756 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 753 for (i = 2; 0 < i; i--) {
761 754 /* first round uses 0x0, second 0x1 */
762 755 unsigned char prefix = DRBG_PREFIX0;
763 756  
764 757  
... ... @@ -764,17 +757,17 @@
764 757 prefix = DRBG_PREFIX1;
765 758 /* 10.1.2.2 step 1 and 4 -- concatenation and HMAC for key */
766 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 761 if (ret)
769 762 return ret;
770 763  
771 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 766 if (ret)
774 767 return ret;
775 768  
776 769 /* 10.1.2.2 step 3 */
777   - if (!seed || 0 == seed->len)
  770 + if (!seed)
778 771 return ret;
779 772 }
780 773  
781 774  
782 775  
783 776  
... ... @@ -790,20 +783,24 @@
790 783 int len = 0;
791 784 int ret = 0;
792 785 struct drbg_string data;
  786 + LIST_HEAD(datalist);
793 787  
794 788 /* 10.1.2.5 step 2 */
795 789 if (addtl && 0 < addtl->len) {
796   - addtl->next = NULL;
797   - ret = drbg_hmac_update(drbg, addtl, 1);
  790 + LIST_HEAD(addtllist);
  791 +
  792 + list_add_tail(&addtl->list, &addtllist);
  793 + ret = drbg_hmac_update(drbg, &addtllist, 1);
798 794 if (ret)
799 795 return ret;
800 796 }
801 797  
802 798 drbg_string_fill(&data, drbg->V, drbg_statelen(drbg));
  799 + list_add_tail(&data.list, &datalist);
803 800 while (len < buflen) {
804 801 unsigned int outlen = 0;
805 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 804 if (ret)
808 805 return ret;
809 806 outlen = (drbg_blocklen(drbg) < (buflen - len)) ?
... ... @@ -817,9 +814,14 @@
817 814 }
818 815  
819 816 /* 10.1.2.5 step 6 */
820   - if (addtl)
821   - addtl->next = NULL;
822   - ret = drbg_hmac_update(drbg, addtl, 1);
  817 + if (addtl && 0 < addtl->len) {
  818 + LIST_HEAD(addtllist);
  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 825 if (ret)
824 826 return ret;
825 827  
826 828  
... ... @@ -858,13 +860,13 @@
858 860 /* Derivation Function for Hash DRBG as defined in 10.4.1 */
859 861 static int drbg_hash_df(struct drbg_state *drbg,
860 862 unsigned char *outval, size_t outlen,
861   - struct drbg_string *entropy)
  863 + struct list_head *entropylist)
862 864 {
863 865 int ret = 0;
864 866 size_t len = 0;
865 867 unsigned char input[5];
866 868 unsigned char *tmp = drbg->scratchpad + drbg_statelen(drbg);
867   - struct drbg_string data1;
  869 + struct drbg_string data;
868 870  
869 871 memset(tmp, 0, drbg_blocklen(drbg));
870 872  
871 873  
... ... @@ -873,14 +875,14 @@
873 875 drbg_int2byte(&input[1], (outlen * 8), 4);
874 876  
875 877 /* 10.4.1 step 4.1 -- concatenation of data for input into hash */
876   - drbg_string_fill(&data1, input, 5);
877   - data1.next = entropy;
  878 + drbg_string_fill(&data, input, 5);
  879 + list_add(&data.list, entropylist);
878 880  
879 881 /* 10.4.1 step 4 */
880 882 while (len < outlen) {
881 883 short blocklen = 0;
882 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 886 if (ret)
885 887 goto out;
886 888 /* 10.4.1 step 4.2 */
887 889  
... ... @@ -897,11 +899,13 @@
897 899 }
898 900  
899 901 /* update function for Hash DRBG as defined in 10.1.1.2 / 10.1.1.3 */
900   -static int drbg_hash_update(struct drbg_state *drbg, struct drbg_string *seed,
  902 +static int drbg_hash_update(struct drbg_state *drbg, struct list_head *seed,
901 903 int reseed)
902 904 {
903 905 int ret = 0;
904 906 struct drbg_string data1, data2;
  907 + LIST_HEAD(datalist);
  908 + LIST_HEAD(datalist2);
905 909 unsigned char *V = drbg->scratchpad;
906 910 unsigned char prefix = DRBG_PREFIX1;
907 911  
908 912  
909 913  
910 914  
911 915  
912 916  
913 917  
... ... @@ -913,26 +917,25 @@
913 917 /* 10.1.1.3 step 1 */
914 918 memcpy(V, drbg->V, drbg_statelen(drbg));
915 919 drbg_string_fill(&data1, &prefix, 1);
  920 + list_add_tail(&data1.list, &datalist);
916 921 drbg_string_fill(&data2, V, drbg_statelen(drbg));
917   - data1.next = &data2;
918   - data2.next = seed;
919   - } else {
920   - drbg_string_fill(&data1, seed->buf, seed->len);
921   - data1.next = seed->next;
  922 + list_add_tail(&data2.list, &datalist);
922 923 }
  924 + list_splice_tail(seed, &datalist);
923 925  
924 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 928 if (ret)
927 929 goto out;
928 930  
929 931 /* 10.1.1.2 / 10.1.1.3 step 4 */
930 932 prefix = DRBG_PREFIX0;
931 933 drbg_string_fill(&data1, &prefix, 1);
  934 + list_add_tail(&data1.list, &datalist2);
932 935 drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg));
933   - data1.next = &data2;
  936 + list_add_tail(&data2.list, &datalist2);
934 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  
937 940 out:
938 941 memset(drbg->scratchpad, 0, drbg_statelen(drbg));
... ... @@ -945,7 +948,7 @@
945 948 {
946 949 int ret = 0;
947 950 struct drbg_string data1, data2;
948   - struct drbg_string *data3;
  951 + LIST_HEAD(datalist);
949 952 unsigned char prefix = DRBG_PREFIX2;
950 953  
951 954 /* this is value w as per documentation */
... ... @@ -958,11 +961,10 @@
958 961 /* 10.1.1.4 step 2a */
959 962 drbg_string_fill(&data1, &prefix, 1);
960 963 drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg));
961   - data3 = addtl;
962   - data1.next = &data2;
963   - data2.next = data3;
964   - data3->next = NULL;
965   - ret = drbg_kcapi_hash(drbg, NULL, drbg->scratchpad, &data1);
  964 + list_add_tail(&data1.list, &datalist);
  965 + list_add_tail(&data2.list, &datalist);
  966 + list_add_tail(&addtl->list, &datalist);
  967 + ret = drbg_kcapi_hash(drbg, NULL, drbg->scratchpad, &datalist);
966 968 if (ret)
967 969 goto out;
968 970  
... ... @@ -985,6 +987,7 @@
985 987 unsigned char *src = drbg->scratchpad;
986 988 unsigned char *dst = drbg->scratchpad + drbg_statelen(drbg);
987 989 struct drbg_string data;
  990 + LIST_HEAD(datalist);
988 991 unsigned char prefix = DRBG_PREFIX1;
989 992  
990 993 memset(src, 0, drbg_statelen(drbg));
991 994  
... ... @@ -994,10 +997,11 @@
994 997 memcpy(src, drbg->V, drbg_statelen(drbg));
995 998  
996 999 drbg_string_fill(&data, src, drbg_statelen(drbg));
  1000 + list_add_tail(&data.list, &datalist);
997 1001 while (len < buflen) {
998 1002 unsigned int outlen = 0;
999 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 1005 if (ret) {
1002 1006 len = ret;
1003 1007 goto out;
... ... @@ -1032,6 +1036,7 @@
1032 1036 unsigned char req[8];
1033 1037 unsigned char prefix = DRBG_PREFIX3;
1034 1038 struct drbg_string data1, data2;
  1039 + LIST_HEAD(datalist);
1035 1040  
1036 1041 /* 10.1.1.4 step 2 */
1037 1042 ret = drbg_hash_process_addtl(drbg, addtl);
1038 1043  
... ... @@ -1044,9 +1049,10 @@
1044 1049 memset(drbg->scratchpad, 0, drbg_blocklen(drbg));
1045 1050 /* 10.1.1.4 step 4 */
1046 1051 drbg_string_fill(&data1, &prefix, 1);
  1052 + list_add_tail(&data1.list, &datalist);
1047 1053 drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg));
1048   - data1.next = &data2;
1049   - ret = drbg_kcapi_hash(drbg, NULL, drbg->scratchpad, &data1);
  1054 + list_add_tail(&data2.list, &datalist);
  1055 + ret = drbg_kcapi_hash(drbg, NULL, drbg->scratchpad, &datalist);
1050 1056 if (ret) {
1051 1057 len = ret;
1052 1058 goto out;
... ... @@ -1099,6 +1105,7 @@
1099 1105 unsigned char *entropy = NULL;
1100 1106 size_t entropylen = 0;
1101 1107 struct drbg_string data1;
  1108 + LIST_HEAD(seedlist);
1102 1109  
1103 1110 /* 9.1 / 9.2 / 9.3.1 step 3 */
1104 1111 if (pers && pers->len > (drbg_max_addtl(drbg))) {
1105 1112  
1106 1113  
... ... @@ -1133,18 +1140,19 @@
1133 1140 get_random_bytes(entropy, entropylen);
1134 1141 drbg_string_fill(&data1, entropy, entropylen);
1135 1142 }
  1143 + list_add_tail(&data1.list, &seedlist);
1136 1144  
1137 1145 /*
1138 1146 * concatenation of entropy with personalization str / addtl input)
1139 1147 * the variable pers is directly handed in by the caller, so check its
1140 1148 * contents whether it is appropriate
1141 1149 */
1142   - if (pers && pers->buf && 0 < pers->len && NULL == pers->next) {
1143   - data1.next = pers;
  1150 + if (pers && pers->buf && 0 < pers->len) {
  1151 + list_add_tail(&pers->list, &seedlist);
1144 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 1156 if (ret)
1149 1157 goto out;
1150 1158  
1151 1159  
1152 1160  
... ... @@ -1642,15 +1650,16 @@
1642 1650 }
1643 1651  
1644 1652 static 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 1655 struct sdesc *sdesc = (struct sdesc *)drbg->priv_data;
  1656 + struct drbg_string *input = NULL;
1648 1657  
1649 1658 if (key)
1650 1659 crypto_shash_setkey(sdesc->shash.tfm, key, drbg_statelen(drbg));
1651 1660 crypto_shash_init(&sdesc->shash);
1652   - for (; NULL != in; in = in->next)
1653   - crypto_shash_update(&sdesc->shash, in->buf, in->len);
  1661 + list_for_each_entry(input, in, list)
  1662 + crypto_shash_update(&sdesc->shash, input->buf, input->len);
1654 1663 return crypto_shash_final(&sdesc->shash, outval);
1655 1664 }
1656 1665 #endif /* (CONFIG_CRYPTO_DRBG_HASH || CONFIG_CRYPTO_DRBG_HMAC) */
1657 1666  
1658 1667  
... ... @@ -1785,12 +1794,15 @@
1785 1794 return drbg_generate_long(drbg, rdata, dlen, NULL);
1786 1795 } else {
1787 1796 struct drbg_gen *data = (struct drbg_gen *)rdata;
  1797 + struct drbg_string addtl;
1788 1798 /* catch NULL pointer */
1789 1799 if (!data)
1790 1800 return 0;
1791 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 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 @@
1820 1832 if (!data)
1821 1833 return drbg_instantiate(drbg, NULL, coreref, pr);
1822 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  
include/crypto/drbg.h
... ... @@ -50,6 +50,7 @@
50 50 #include <crypto/rng.h>
51 51 #include <linux/fips.h>
52 52 #include <linux/spinlock.h>
  53 +#include <linux/list.h>
53 54  
54 55 /*
55 56 * Concatenation Helper and string operation helper
... ... @@ -64,7 +65,7 @@
64 65 struct drbg_string {
65 66 const unsigned char *buf;
66 67 size_t len;
67   - struct drbg_string *next;
  68 + struct list_head list;
68 69 };
69 70  
70 71 static inline void drbg_string_fill(struct drbg_string *string,
... ... @@ -72,7 +73,7 @@
72 73 {
73 74 string->buf = buf;
74 75 string->len = len;
75   - string->next = NULL;
  76 + INIT_LIST_HEAD(&string->list);
76 77 }
77 78  
78 79 struct drbg_state;
... ... @@ -97,7 +98,7 @@
97 98 };
98 99  
99 100 struct 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 102 int reseed);
102 103 int (*generate)(struct drbg_state *drbg,
103 104 unsigned char *buf, unsigned int buflen,