aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorlloyd <[email protected]>2009-01-27 06:27:40 +0000
committerlloyd <[email protected]>2009-01-27 06:27:40 +0000
commit092c6d68006a2d953d8b622ce2c181a6394aed4e (patch)
treeb10582379b69bd2cd4e4af0b66597342f0d28b72 /src
parent497e3656c1141098ab76dc0fb7922e9e9d5b6bc8 (diff)
Have Entropy_Accumulator dump everything into a BufferedComputation.
Since both Randpool and HMAC_RNG fed the input into a MAC anyway, this works nicely. (It would be nicer to use tr1::function but, argh, don't want to fully depend on TR1 quite yet. C++0x cannot come soon enough). This avoids requiring to do run length encoding, it just dumps everything as-is into the MAC. This ensures the buffer is not a potential narrow pipe for the entropy (for instance, one might imagine an entropy source which outputs one random byte every 16 bytes, and the rest some repeating pattern - using a 16 byte buffer, you would only get 8 bits of entropy total, no matter how many times you sampled).
Diffstat (limited to 'src')
-rw-r--r--src/entropy/entropy_acc.cpp87
-rw-r--r--src/entropy/entropy_src.h38
-rw-r--r--src/entropy/info.txt1
-rw-r--r--src/rng/hmac_rng/hmac_rng.cpp4
-rw-r--r--src/rng/randpool/randpool.cpp4
5 files changed, 26 insertions, 108 deletions
diff --git a/src/entropy/entropy_acc.cpp b/src/entropy/entropy_acc.cpp
deleted file mode 100644
index 9dc0f1405..000000000
--- a/src/entropy/entropy_acc.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
-* Entropy Accumulator
-* (C) 1999-2009 Jack Lloyd
-*/
-
-#include <botan/entropy_src.h>
-
-namespace Botan {
-
-void Entropy_Accumulator::reset_goal(u32bit entropy_goal)
- {
- goal_bits = entropy_goal;
- collected_bits = 0;
-
- /*
- * The buffer is large enough to hold 2*goal_bits of entropy,
- * or 128 bits, whichever is larger
- */
- entropy_buf.create(std::max<u32bit>(goal_bits / 4, 16));
- io_buffer.destroy();
- }
-
-MemoryRegion<byte>& Entropy_Accumulator::get_io_buffer(u32bit size)
- {
- io_buffer.create(size);
- return io_buffer;
- }
-
-u32bit Entropy_Accumulator::desired_remaining_bits() const
- {
- if(collected_bits >= goal_bits)
- return 0;
- return (goal_bits - collected_bits);
- }
-
-bool Entropy_Accumulator::polling_goal_achieved() const
- {
- return (collected_bits >= goal_bits);
- }
-
-void Entropy_Accumulator::add(const void* in_void,
- u32bit length,
- double entropy_bits_per_byte)
- {
- if(length == 0)
- return;
-
- entropy_bits_per_byte = std::max(0.0, std::min(entropy_bits_per_byte, 8.0));
-
- const byte* in = static_cast<const byte*>(in_void);
-
- u32bit buf_i = 0; // write index into entropy_buf
- u32bit bytes_collected = 0;
-
- byte last = 0;
- byte count = 0;
-
- for(u32bit i = 0; i != length; ++i)
- {
- if(in[i] != last) // run length encode the input
- {
- entropy_buf[buf_i] ^= last;
- buf_i = (buf_i + 1) % entropy_buf.size();
-
- if(count > 1)
- {
- entropy_buf[buf_i] ^= count;
- buf_i = (buf_i + 1) % entropy_buf.size();
- }
-
- ++bytes_collected;
-
- last = in[i];
- count = 1;
- }
- else
- ++count;
- }
-
- entropy_buf[0] ^= last;
- entropy_buf[1] ^= count;
-
- collected_bits += static_cast<u32bit>(entropy_bits_per_byte * bytes_collected);
- collected_bits = std::min(collected_bits, 8 * entropy_buf.size());
- }
-
-}
diff --git a/src/entropy/entropy_src.h b/src/entropy/entropy_src.h
index 603bbae15..aea6ad8f2 100644
--- a/src/entropy/entropy_src.h
+++ b/src/entropy/entropy_src.h
@@ -18,32 +18,40 @@ namespace Botan {
class Entropy_Accumulator
{
public:
- Entropy_Accumulator(u32bit entropy_goal)
- { reset_goal(entropy_goal); }
+ Entropy_Accumulator(BufferedComputation& sink, u32bit goal) :
+ entropy_sink(sink), entropy_goal(goal), collected_bits(0) {}
- const MemoryRegion<byte>& get_entropy_buffer() const
- { return entropy_buf; }
-
- MemoryRegion<byte>& get_io_buffer(u32bit size);
-
- void reset_goal(u32bit entropy_goal);
+ /**
+ @return cached I/O buffer for repeated polls
+ */
+ MemoryRegion<byte>& get_io_buffer(u32bit size)
+ { io_buffer.create(size); return io_buffer; }
u32bit bits_collected() const { return collected_bits; }
- bool polling_goal_achieved() const;
+ bool polling_goal_achieved() const
+ { return (collected_bits >= entropy_goal); }
- u32bit desired_remaining_bits() const;
+ u32bit desired_remaining_bits() const
+ {
+ return (collected_bits >= entropy_goal) ? 0 : (entropy_goal - collected_bits);
+ }
- void add(const void* bytes, u32bit length, double bits_per_byte);
+ void add(const void* bytes, u32bit length, u32bit estimated_entropy)
+ {
+ entropy_sink.update(reinterpret_cast<const byte*>(bytes), length);
+ collected_bits += std::min(estimated_entropy, length * 8);
+ }
template<typename T>
- void add(const T& v, double bits_per_byte)
+ void add(const T& v, u32bit estimated_entropy)
{
- add(&v, sizeof(T), bits_per_byte);
+ add(&v, sizeof(T), estimated_entropy);
}
private:
- SecureVector<byte> io_buffer, entropy_buf;
- u32bit collected_bits, goal_bits;
+ BufferedComputation& entropy_sink;
+ SecureVector<byte> io_buffer;
+ u32bit entropy_goal, collected_bits;
};
/**
diff --git a/src/entropy/info.txt b/src/entropy/info.txt
index e0b0320b1..bac1d593f 100644
--- a/src/entropy/info.txt
+++ b/src/entropy/info.txt
@@ -4,5 +4,4 @@ load_on auto
<add>
entropy_src.h
-entropy_acc.cpp
</add>
diff --git a/src/rng/hmac_rng/hmac_rng.cpp b/src/rng/hmac_rng/hmac_rng.cpp
index f495dda4d..ffdfdc60d 100644
--- a/src/rng/hmac_rng/hmac_rng.cpp
+++ b/src/rng/hmac_rng/hmac_rng.cpp
@@ -69,7 +69,7 @@ void HMAC_RNG::reseed_with_input(u32bit poll_bits,
feedback of the current PRK value, into the extractor function.
*/
- Entropy_Accumulator accum(poll_bits);
+ Entropy_Accumulator accum(*extractor, poll_bits);
for(u32bit i = 0; i < entropy_sources.size(); ++i)
{
@@ -83,8 +83,6 @@ void HMAC_RNG::reseed_with_input(u32bit poll_bits,
if(input_length)
accum.add(input, input_length, 1);
- extractor->update(accum.get_entropy_buffer());
-
/*
It is necessary to feed forward poll data. Otherwise, a good poll
(collecting a large amount of conditional entropy) followed by a
diff --git a/src/rng/randpool/randpool.cpp b/src/rng/randpool/randpool.cpp
index 1a111e20e..41a8ca23a 100644
--- a/src/rng/randpool/randpool.cpp
+++ b/src/rng/randpool/randpool.cpp
@@ -101,7 +101,7 @@ void Randpool::mix_pool()
*/
void Randpool::reseed(u32bit poll_bits)
{
- Entropy_Accumulator accum(poll_bits);
+ Entropy_Accumulator accum(*mac, poll_bits);
for(u32bit i = 0; i != entropy_sources.size(); ++i)
{
@@ -111,7 +111,7 @@ void Randpool::reseed(u32bit poll_bits)
break;
}
- SecureVector<byte> mac_val = mac->process(accum.get_entropy_buffer());
+ SecureVector<byte> mac_val = mac->final();
xor_buf(pool, mac_val, mac_val.size());
mix_pool();