aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/drbg.c41
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 */
566static int drbg_ctr_update(struct drbg_state *drbg, struct list_head *seed, 580static 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
620out: 635out:
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