aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/rng/hmac_rng/hmac_rng.cpp70
1 files changed, 43 insertions, 27 deletions
diff --git a/src/rng/hmac_rng/hmac_rng.cpp b/src/rng/hmac_rng/hmac_rng.cpp
index 86f6acb10..ffc5549e2 100644
--- a/src/rng/hmac_rng/hmac_rng.cpp
+++ b/src/rng/hmac_rng/hmac_rng.cpp
@@ -37,9 +37,13 @@ void hmac_prf(MessageAuthenticationCode* prf,
*************************************************/
void HMAC_RNG::randomize(byte out[], u32bit length)
{
- /* Attempt to seed if we are either unseeded or have generated
- enouch counters that it seems wise to roll over keys */
- if(!is_seeded() || counter >= 16 * 1024)
+ /* Attempt to seed if we are currently not seeded, or if the
+ counter is greater than 2^20
+
+ If HMAC_RNG is wrapped in an X9.31/AES PRNG (the default), this
+ means a reseed will be kicked off every 16 MiB of RNG output.
+ */
+ if(!is_seeded() || counter >= 0x100000)
{
reseed();
@@ -61,10 +65,8 @@ void HMAC_RNG::randomize(byte out[], u32bit length)
length -= copied;
}
- hmac_prf(prf, K, counter, "rng");
-
/* Every once in a while do a fast poll of a entropy source */
- if(entropy_sources.size() && (counter % 1024 == 0))
+ if(entropy_sources.size() && (counter % 65536 == 0))
{
u32bit got = entropy_sources.at(source_index)->fast_poll(io_buffer, io_buffer.size());
source_index = (source_index + 1) % entropy_sources.size();
@@ -77,8 +79,6 @@ void HMAC_RNG::randomize(byte out[], u32bit length)
*/
void HMAC_RNG::reseed_with_input(const byte input[], u32bit input_length)
{
- Entropy_Estimator estimate;
-
if(entropy_sources.size())
{
/**
@@ -90,28 +90,45 @@ void HMAC_RNG::reseed_with_input(const byte input[], u32bit input_length)
feedback of the current PRK value, into the extractor function.
*/
+ /*
+ Previously this function did entropy estimation. However the paper
+
+ "Boaz Barak, Shai Halevi: A model and architecture for
+ pseudo-random generation with applications to /dev/random. ACM
+ Conference on Computer and Communications Security 2005."
+
+ provides a pretty strong case to not even try, since what we are
+ really interested in is the *conditional* entropy from the point
+ of view of an unknown attacker, which is impossible to
+ calculate. They recommend, if an entropy estimate of some kind
+ is needed, to use a low static estimate instead. We use here an
+ estimate of 1 bit per byte.
+
+ One thing I had been concerned about initially was that people
+ without any randomness source enabled (much more likely in the
+ days when you had to enable them manually) would find the RNG
+ was unseeded and then pull the manuever some OpenSSL users did
+ and seed the RNG with a constant string. However, upon further
+ thought, I've decided that people who do that deserve to lose
+ anyway.
+ */
+
for(u32bit j = 0; j < entropy_sources.size(); ++j)
{
- u32bit got = entropy_sources[j]->fast_poll(io_buffer, io_buffer.size());
+ const u32bit got =
+ entropy_sources[j]->fast_poll(io_buffer, io_buffer.size());
+
+ entropy += got;
extractor->update(io_buffer, got);
- estimate.update(io_buffer, got, 96);
}
- /* Limit assumed entropy from fast polls (to ensure we do at
- least a few slow polls) */
- estimate.set_upper_bound(256);
-
- /* Then do a slow poll, until we think we have got enough entropy
- */
for(u32bit j = 0; j != entropy_sources.size(); ++j)
{
- u32bit got = entropy_sources[j]->slow_poll(io_buffer, io_buffer.size());
+ const u32bit got =
+ entropy_sources[j]->slow_poll(io_buffer, io_buffer.size());
+ entropy += got;
extractor->update(io_buffer, got);
- estimate.update(io_buffer, got, 256);
-
- if(estimate.value() > 8 * extractor->OUTPUT_LENGTH)
- break;
}
}
@@ -121,7 +138,7 @@ void HMAC_RNG::reseed_with_input(const byte input[], u32bit input_length)
if(input_length)
{
extractor->update(input, input_length);
- estimate.update(input, input_length);
+ entropy += input_length;
}
/*
@@ -141,8 +158,8 @@ void HMAC_RNG::reseed_with_input(const byte input[], u32bit input_length)
hmac_prf(prf, K, counter, "reseed");
extractor->update(K); // K is the CTXinfo=reseed PRF output
- /* Now derive the new PRK using everything that has been fed into the extractor,
- and set the PRF key to that*/
+ /* Now derive the new PRK using everything that has been fed into
+ the extractor, and set the PRF key to that */
prf->set_key(extractor->final());
// Now generate a new PRF output to use as the XTS extractor salt
@@ -153,9 +170,8 @@ void HMAC_RNG::reseed_with_input(const byte input[], u32bit input_length)
K.clear();
counter = 0;
- // Increase entropy estimate (for is_seeded)
- entropy = std::min<u32bit>(entropy + estimate.value(),
- 8 * extractor->OUTPUT_LENGTH);
+ // Upper bound entropy estimate at the extractor output size
+ entropy = std::min<u32bit>(entropy, 8 * extractor->OUTPUT_LENGTH);
}
/**