diff options
-rw-r--r-- | crypto/drbg.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/crypto/drbg.c b/crypto/drbg.c index c9b4c4906d9b..dba5ed2f83b6 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c | |||
@@ -562,7 +562,21 @@ out: | |||
562 | return ret; | 562 | return ret; |
563 | } | 563 | } |
564 | 564 | ||
565 | /* update function of CTR DRBG as defined in 10.2.1.2 */ | 565 | /* |
566 | * update function of CTR DRBG as defined in 10.2.1.2 | ||
567 | * | ||
568 | * The reseed variable has an enhanced meaning compared to the update | ||
569 | * functions of the other DRBGs as follows: | ||
570 | * 0 => initial seed from initialization | ||
571 | * 1 => reseed via drbg_seed | ||
572 | * 2 => first invocation from drbg_ctr_update when addtl is present. In | ||
573 | * this case, the df_data scratchpad is not deleted so that it is | ||
574 | * available for another calls to prevent calling the DF function | ||
575 | * again. | ||
576 | * 3 => second invocation from drbg_ctr_update. When the update function | ||
577 | * was called with addtl, the df_data memory already contains the | ||
578 | * DFed addtl information and we do not need to call DF again. | ||
579 | */ | ||
566 | static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed, | 580 | static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed, |
567 | int reseed) | 581 | int reseed) |
568 | { | 582 | { |
@@ -577,7 +591,8 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed, | |||
577 | unsigned char prefix = DRBG_PREFIX1; | 591 | unsigned char prefix = DRBG_PREFIX1; |
578 | 592 | ||
579 | memset(temp, 0, drbg_statelen(drbg) + drbg_blocklen(drbg)); | 593 | memset(temp, 0, drbg_statelen(drbg) + drbg_blocklen(drbg)); |
580 | memset(df_data, 0, drbg_statelen(drbg)); | 594 | if (3 > reseed) |
595 | memset(df_data, 0, drbg_statelen(drbg)); | ||
581 | 596 | ||
582 | /* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */ | 597 | /* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */ |
583 | if (seed) { | 598 | if (seed) { |
@@ -619,7 +634,8 @@ static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed, | |||
619 | 634 | ||
620 | out: | 635 | out: |
621 | memset(temp, 0, drbg_statelen(drbg) + drbg_blocklen(drbg)); | 636 | memset(temp, 0, drbg_statelen(drbg) + drbg_blocklen(drbg)); |
622 | memset(df_data, 0, drbg_statelen(drbg)); | 637 | if (2 != reseed) |
638 | memset(df_data, 0, drbg_statelen(drbg)); | ||
623 | return ret; | 639 | return ret; |
624 | } | 640 | } |
625 | 641 | ||
@@ -644,7 +660,7 @@ static int drbg_ctr_generate(struct drbg_state *drbg, | |||
644 | LIST_HEAD(addtllist); | 660 | LIST_HEAD(addtllist); |
645 | 661 | ||
646 | list_add_tail(&addtl->list, &addtllist); | 662 | list_add_tail(&addtl->list, &addtllist); |
647 | ret = drbg_ctr_update(drbg, &addtllist, 1); | 663 | ret = drbg_ctr_update(drbg, &addtllist, 2); |
648 | if (ret) | 664 | if (ret) |
649 | return 0; | 665 | return 0; |
650 | } | 666 | } |
@@ -675,21 +691,8 @@ static int drbg_ctr_generate(struct drbg_state *drbg, | |||
675 | drbg_add_buf(drbg->V, drbg_blocklen(drbg), &prefix, 1); | 691 | drbg_add_buf(drbg->V, drbg_blocklen(drbg), &prefix, 1); |
676 | } | 692 | } |
677 | 693 | ||
678 | /* | 694 | /* 10.2.1.5.2 step 6 */ |
679 | * 10.2.1.5.2 step 6 | 695 | ret = drbg_ctr_update(drbg, NULL, 3); |
680 | * The following call invokes the DF function again which could be | ||
681 | * optimized. In step 2, the "additional_input" after step 2 is the | ||
682 | * output of the DF function. If this result would be saved, the DF | ||
683 | * function would not need to be invoked again at this point. | ||
684 | */ | ||
685 | if (addtl && 0 < addtl->len) { | ||
686 | LIST_HEAD(addtllist); | ||
687 | |||
688 | list_add_tail(&addtl->list, &addtllist); | ||
689 | ret = drbg_ctr_update(drbg, &addtllist, 1); | ||
690 | } else { | ||
691 | ret = drbg_ctr_update(drbg, NULL, 1); | ||
692 | } | ||
693 | if (ret) | 696 | if (ret) |
694 | len = ret; | 697 | len = ret; |
695 | 698 | ||