diff options
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/drbg.c | 59 |
1 files changed, 35 insertions, 24 deletions
diff --git a/crypto/drbg.c b/crypto/drbg.c index 2a7860f73288..a76b3cb03cf4 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c | |||
@@ -646,7 +646,7 @@ out: | |||
646 | /* Generate function of CTR DRBG as defined in 10.2.1.5.2 */ | 646 | /* Generate function of CTR DRBG as defined in 10.2.1.5.2 */ |
647 | static int drbg_ctr_generate(struct drbg_state *drbg, | 647 | static int drbg_ctr_generate(struct drbg_state *drbg, |
648 | unsigned char *buf, unsigned int buflen, | 648 | unsigned char *buf, unsigned int buflen, |
649 | struct drbg_string *addtl) | 649 | struct list_head *addtl) |
650 | { | 650 | { |
651 | int len = 0; | 651 | int len = 0; |
652 | int ret = 0; | 652 | int ret = 0; |
@@ -656,11 +656,8 @@ static int drbg_ctr_generate(struct drbg_state *drbg, | |||
656 | memset(drbg->scratchpad, 0, drbg_blocklen(drbg)); | 656 | memset(drbg->scratchpad, 0, drbg_blocklen(drbg)); |
657 | 657 | ||
658 | /* 10.2.1.5.2 step 2 */ | 658 | /* 10.2.1.5.2 step 2 */ |
659 | if (addtl && 0 < addtl->len) { | 659 | if (addtl && !list_empty(addtl)) { |
660 | LIST_HEAD(addtllist); | 660 | ret = drbg_ctr_update(drbg, addtl, 2); |
661 | |||
662 | list_add_tail(&addtl->list, &addtllist); | ||
663 | ret = drbg_ctr_update(drbg, &addtllist, 2); | ||
664 | if (ret) | 661 | if (ret) |
665 | return 0; | 662 | return 0; |
666 | } | 663 | } |
@@ -777,7 +774,7 @@ static int drbg_hmac_update(struct drbg_state *drbg, struct list_head *seed, | |||
777 | static int drbg_hmac_generate(struct drbg_state *drbg, | 774 | static int drbg_hmac_generate(struct drbg_state *drbg, |
778 | unsigned char *buf, | 775 | unsigned char *buf, |
779 | unsigned int buflen, | 776 | unsigned int buflen, |
780 | struct drbg_string *addtl) | 777 | struct list_head *addtl) |
781 | { | 778 | { |
782 | int len = 0; | 779 | int len = 0; |
783 | int ret = 0; | 780 | int ret = 0; |
@@ -785,11 +782,8 @@ static int drbg_hmac_generate(struct drbg_state *drbg, | |||
785 | LIST_HEAD(datalist); | 782 | LIST_HEAD(datalist); |
786 | 783 | ||
787 | /* 10.1.2.5 step 2 */ | 784 | /* 10.1.2.5 step 2 */ |
788 | if (addtl && 0 < addtl->len) { | 785 | if (addtl && !list_empty(addtl)) { |
789 | LIST_HEAD(addtllist); | 786 | ret = drbg_hmac_update(drbg, addtl, 1); |
790 | |||
791 | list_add_tail(&addtl->list, &addtllist); | ||
792 | ret = drbg_hmac_update(drbg, &addtllist, 1); | ||
793 | if (ret) | 787 | if (ret) |
794 | return ret; | 788 | return ret; |
795 | } | 789 | } |
@@ -813,14 +807,10 @@ static int drbg_hmac_generate(struct drbg_state *drbg, | |||
813 | } | 807 | } |
814 | 808 | ||
815 | /* 10.1.2.5 step 6 */ | 809 | /* 10.1.2.5 step 6 */ |
816 | if (addtl && 0 < addtl->len) { | 810 | if (addtl && !list_empty(addtl)) |
817 | LIST_HEAD(addtllist); | 811 | ret = drbg_hmac_update(drbg, addtl, 1); |
818 | 812 | else | |
819 | list_add_tail(&addtl->list, &addtllist); | ||
820 | ret = drbg_hmac_update(drbg, &addtllist, 1); | ||
821 | } else { | ||
822 | ret = drbg_hmac_update(drbg, NULL, 1); | 813 | ret = drbg_hmac_update(drbg, NULL, 1); |
823 | } | ||
824 | if (ret) | 814 | if (ret) |
825 | return ret; | 815 | return ret; |
826 | 816 | ||
@@ -944,7 +934,7 @@ out: | |||
944 | 934 | ||
945 | /* processing of additional information string for Hash DRBG */ | 935 | /* processing of additional information string for Hash DRBG */ |
946 | static int drbg_hash_process_addtl(struct drbg_state *drbg, | 936 | static int drbg_hash_process_addtl(struct drbg_state *drbg, |
947 | struct drbg_string *addtl) | 937 | struct list_head *addtl) |
948 | { | 938 | { |
949 | int ret = 0; | 939 | int ret = 0; |
950 | struct drbg_string data1, data2; | 940 | struct drbg_string data1, data2; |
@@ -955,7 +945,7 @@ static int drbg_hash_process_addtl(struct drbg_state *drbg, | |||
955 | memset(drbg->scratchpad, 0, drbg_blocklen(drbg)); | 945 | memset(drbg->scratchpad, 0, drbg_blocklen(drbg)); |
956 | 946 | ||
957 | /* 10.1.1.4 step 2 */ | 947 | /* 10.1.1.4 step 2 */ |
958 | if (!addtl || 0 == addtl->len) | 948 | if (!addtl || list_empty(addtl)) |
959 | return 0; | 949 | return 0; |
960 | 950 | ||
961 | /* 10.1.1.4 step 2a */ | 951 | /* 10.1.1.4 step 2a */ |
@@ -963,7 +953,7 @@ static int drbg_hash_process_addtl(struct drbg_state *drbg, | |||
963 | drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg)); | 953 | drbg_string_fill(&data2, drbg->V, drbg_statelen(drbg)); |
964 | list_add_tail(&data1.list, &datalist); | 954 | list_add_tail(&data1.list, &datalist); |
965 | list_add_tail(&data2.list, &datalist); | 955 | list_add_tail(&data2.list, &datalist); |
966 | list_add_tail(&addtl->list, &datalist); | 956 | list_splice_tail(addtl, &datalist); |
967 | ret = drbg_kcapi_hash(drbg, NULL, drbg->scratchpad, &datalist); | 957 | ret = drbg_kcapi_hash(drbg, NULL, drbg->scratchpad, &datalist); |
968 | if (ret) | 958 | if (ret) |
969 | goto out; | 959 | goto out; |
@@ -1029,7 +1019,7 @@ out: | |||
1029 | /* generate function for Hash DRBG as defined in 10.1.1.4 */ | 1019 | /* generate function for Hash DRBG as defined in 10.1.1.4 */ |
1030 | static int drbg_hash_generate(struct drbg_state *drbg, | 1020 | static int drbg_hash_generate(struct drbg_state *drbg, |
1031 | unsigned char *buf, unsigned int buflen, | 1021 | unsigned char *buf, unsigned int buflen, |
1032 | struct drbg_string *addtl) | 1022 | struct list_head *addtl) |
1033 | { | 1023 | { |
1034 | int len = 0; | 1024 | int len = 0; |
1035 | int ret = 0; | 1025 | int ret = 0; |
@@ -1347,6 +1337,12 @@ static int drbg_generate(struct drbg_state *drbg, | |||
1347 | { | 1337 | { |
1348 | int len = 0; | 1338 | int len = 0; |
1349 | struct drbg_state *shadow = NULL; | 1339 | struct drbg_state *shadow = NULL; |
1340 | LIST_HEAD(addtllist); | ||
1341 | struct drbg_string timestamp; | ||
1342 | union { | ||
1343 | cycles_t cycles; | ||
1344 | unsigned char char_cycles[sizeof(cycles_t)]; | ||
1345 | } now; | ||
1350 | 1346 | ||
1351 | if (0 == buflen || !buf) { | 1347 | if (0 == buflen || !buf) { |
1352 | pr_devel("DRBG: no output buffer provided\n"); | 1348 | pr_devel("DRBG: no output buffer provided\n"); |
@@ -1407,8 +1403,23 @@ static int drbg_generate(struct drbg_state *drbg, | |||
1407 | /* 9.3.1 step 7.4 */ | 1403 | /* 9.3.1 step 7.4 */ |
1408 | addtl = NULL; | 1404 | addtl = NULL; |
1409 | } | 1405 | } |
1406 | |||
1407 | /* | ||
1408 | * Mix the time stamp into the DRBG state if the DRBG is not in | ||
1409 | * test mode. If there are two callers invoking the DRBG at the same | ||
1410 | * time, i.e. before the first caller merges its shadow state back, | ||
1411 | * both callers would obtain the same random number stream without | ||
1412 | * changing the state here. | ||
1413 | */ | ||
1414 | if (!drbg->test_data) { | ||
1415 | now.cycles = random_get_entropy(); | ||
1416 | drbg_string_fill(×tamp, now.char_cycles, sizeof(cycles_t)); | ||
1417 | list_add_tail(×tamp.list, &addtllist); | ||
1418 | } | ||
1419 | if (addtl && 0 < addtl->len) | ||
1420 | list_add_tail(&addtl->list, &addtllist); | ||
1410 | /* 9.3.1 step 8 and 10 */ | 1421 | /* 9.3.1 step 8 and 10 */ |
1411 | len = shadow->d_ops->generate(shadow, buf, buflen, addtl); | 1422 | len = shadow->d_ops->generate(shadow, buf, buflen, &addtllist); |
1412 | 1423 | ||
1413 | /* 10.1.1.4 step 6, 10.1.2.5 step 7, 10.2.1.5.2 step 7 */ | 1424 | /* 10.1.1.4 step 6, 10.1.2.5 step 7, 10.2.1.5.2 step 7 */ |
1414 | shadow->reseed_ctr++; | 1425 | shadow->reseed_ctr++; |