aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorStephan Mueller <smueller@chronox.de>2014-07-05 20:24:35 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2014-07-08 09:18:24 -0400
commit72e7c25aa6d73df2951229d2ce0a35065de66d3a (patch)
tree5d242f50c32207d375766ca579b375f30fbb42a8 /crypto
parenta9089571f2fc203c3ba6595a60f0045f048494da (diff)
crypto: drbg - Call CTR DRBG DF function only once
The CTR DRBG requires the update function to be called twice when generating a random number. In both cases, update function must process the additional information string by using the DF function. As the DF produces the same result in both cases, we can save one invocation of the DF function when the first DF function result is reused. The result of the DF function is stored in the scratchpad storage. The patch ensures that the scratchpad is not cleared when we want to reuse the DF result. For achieving this, the CTR DRBG update function must know by whom and in which scenario it is called. This information is provided with the reseed parameter to the update function. Signed-off-by: Stephan Mueller <smueller@chronox.de> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-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