From 67d8ca19f502999c3e2010317e43a9cdbc36ba25 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Thu, 7 Dec 2017 10:43:07 +0100 Subject: [PATCH] ensure that fortuna has been seeded properly (cherry picked from commit 04ce8cf613f635a8445b5de09cdd58847f0fcd64) --- src/prngs/fortuna.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/prngs/fortuna.c b/src/prngs/fortuna.c index 7b1ecb6..225eedc 100644 --- a/src/prngs/fortuna.c +++ b/src/prngs/fortuna.c @@ -66,9 +66,9 @@ static int _fortuna_reseed(prng_state *prng) { unsigned char tmp[MAXBLOCKSIZE]; hash_state md; + ulong64 reset_cnt; int err, x; - ++prng->fortuna.reset_cnt; /* new K == LTC_SHA256(K || s) where s == LTC_SHA256(P0) || LTC_SHA256(P1) ... */ sha256_init(&md); @@ -77,8 +77,10 @@ static int _fortuna_reseed(prng_state *prng) return err; } + reset_cnt = prng->fortuna.reset_cnt + 1; + for (x = 0; x < LTC_FORTUNA_POOLS; x++) { - if (x == 0 || ((prng->fortuna.reset_cnt >> (x-1)) & 1) == 0) { + if (x == 0 || ((reset_cnt >> (x-1)) & 1) == 0) { /* terminate this hash */ if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) { sha256_done(&md, tmp); @@ -108,9 +110,10 @@ static int _fortuna_reseed(prng_state *prng) } _fortuna_update_iv(prng); - /* reset pool len */ + /* reset/update internals */ prng->fortuna.pool0_len = 0; prng->fortuna.wd = 0; + prng->fortuna.reset_cnt = reset_cnt; #ifdef LTC_CLEAN_STACK @@ -251,6 +254,11 @@ unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state } } + /* ensure that one reseed happened before allowing to read */ + if (prng->fortuna.reset_cnt == 0) { + goto LBL_UNLOCK; + } + /* now generate the blocks required */ tlen = outlen;