aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/examples/rng_test.cpp2
-rw-r--r--doc/examples/test_es.cpp23
-rw-r--r--src/entropy/dev_random/es_dev.cpp13
-rw-r--r--src/entropy/entropy_src.h39
-rw-r--r--src/entropy/unix_procs/es_unix.cpp9
-rw-r--r--src/rng/hmac_rng/hmac_rng.cpp21
-rw-r--r--src/rng/hmac_rng/hmac_rng.h4
-rw-r--r--src/rng/randpool/randpool.cpp24
-rw-r--r--src/rng/randpool/randpool.h4
-rw-r--r--src/rng/x931_rng/x931_rng.cpp82
-rw-r--r--src/rng/x931_rng/x931_rng.h15
-rw-r--r--src/utils/mem_ops.h16
12 files changed, 129 insertions, 123 deletions
diff --git a/doc/examples/rng_test.cpp b/doc/examples/rng_test.cpp
index e38628d15..9ecb04e78 100644
--- a/doc/examples/rng_test.cpp
+++ b/doc/examples/rng_test.cpp
@@ -58,6 +58,8 @@ class Fixed_Output_RNG : public RandomNumberGenerator
std::string name() const { return "Fixed_Output_RNG"; }
+ void reseed(u32bit) {}
+
void clear() throw() {}
void add_entropy(const byte in[], u32bit len)
diff --git a/doc/examples/test_es.cpp b/doc/examples/test_es.cpp
index b7b2e9162..5d0c1ae5a 100644
--- a/doc/examples/test_es.cpp
+++ b/doc/examples/test_es.cpp
@@ -32,19 +32,21 @@
using namespace Botan;
-class Saver_Of_Bytes : public BufferedComputation
+class Saver_Of_Bytes : public Entropy_Accumulator
{
public:
- Saver_Of_Bytes() : BufferedComputation(0), outbuf(64), written(0) {}
- void add_data(const byte in[], u32bit length)
+ Saver_Of_Bytes(u32bit bits) :
+ Entropy_Accumulator(bits), outbuf(64), written(0) {}
+
+ void add_bytes(const byte in[], u32bit length)
{
for(size_t i = 0; i != length; ++i)
outbuf[i % outbuf.size()] ^= in[i];
written += length;
- //outbuf.insert(outbuf.end(), in, in+length);
}
- void final_result(byte[]) { if(written < 64) outbuf.resize(written); }
+
+ void trunc() { if(written < 64) outbuf.resize(written); }
std::vector<byte> outbuf;
u32bit written;
@@ -56,16 +58,15 @@ void test_entropy_source(EntropySource* es)
printf("Polling '%s':\n", es->name().c_str());
- Saver_Of_Bytes save;
+ Saver_Of_Bytes accum(128);
- Entropy_Accumulator accum(save, 128);
es->poll(accum);
- save.final_result(0);
+ accum.trunc();
- printf("Got %d bytes\n", save.written);
- for(size_t i = 0; i != save.outbuf.size(); ++i)
- printf("%02X", save.outbuf[i]);
+ printf("Got %d bytes\n", accum.written);
+ for(size_t i = 0; i != accum.outbuf.size(); ++i)
+ printf("%02X", accum.outbuf[i]);
printf("\n");
delete es;
diff --git a/src/entropy/dev_random/es_dev.cpp b/src/entropy/dev_random/es_dev.cpp
index 60e1a4df6..89f981373 100644
--- a/src/entropy/dev_random/es_dev.cpp
+++ b/src/entropy/dev_random/es_dev.cpp
@@ -51,12 +51,7 @@ u32bit Device_EntropySource::Device_Reader::get(byte out[], u32bit length,
if(got <= 0)
return 0;
- const u32bit ret = static_cast<u32bit>(got);
-
- if(ret > length)
- return 0;
-
- return ret;
+ return static_cast<u32bit>(got);
}
/**
@@ -106,16 +101,16 @@ Device_EntropySource::~Device_EntropySource()
*/
void Device_EntropySource::poll(Entropy_Accumulator& accum)
{
- const u32bit MAX_READ_WAIT_MILLISECONDS = 50;
+ u32bit go_get = std::min<u32bit>(accum.desired_remaining_bits() / 8, 16);
- u32bit go_get = std::min<u32bit>(accum.desired_remaining_bits() / 8, 32);
+ u32bit read_wait_ms = go_get / 16;
MemoryRegion<byte>& io_buffer = accum.get_io_buffer(go_get);
for(size_t i = 0; i != devices.size(); ++i)
{
u32bit got = devices[i].get(io_buffer.begin(), io_buffer.size(),
- MAX_READ_WAIT_MILLISECONDS);
+ read_wait_ms);
if(got)
{
diff --git a/src/entropy/entropy_src.h b/src/entropy/entropy_src.h
index 96ffcad0b..eb3a841b4 100644
--- a/src/entropy/entropy_src.h
+++ b/src/entropy/entropy_src.h
@@ -18,8 +18,10 @@ namespace Botan {
class Entropy_Accumulator
{
public:
- Entropy_Accumulator(BufferedComputation& sink, u32bit goal) :
- entropy_sink(sink), entropy_goal(goal), collected_bits(0) {}
+ Entropy_Accumulator(u32bit goal) :
+ entropy_goal(goal), collected_bits(0) {}
+
+ virtual ~Entropy_Accumulator() {}
/**
@return cached I/O buffer for repeated polls
@@ -27,20 +29,23 @@ class Entropy_Accumulator
MemoryRegion<byte>& get_io_buffer(u32bit size)
{ io_buffer.create(size); return io_buffer; }
- u32bit bits_collected() const { return collected_bits; }
+ u32bit bits_collected() const
+ { return static_cast<u32bit>(collected_bits); }
bool polling_goal_achieved() const
{ return (collected_bits >= entropy_goal); }
u32bit desired_remaining_bits() const
{
- return (collected_bits >= entropy_goal) ? 0 : (entropy_goal - collected_bits);
+ if(collected_bits >= entropy_goal)
+ return 0;
+ return (entropy_goal - collected_bits);
}
void add(const void* bytes, u32bit length, double entropy_bits_per_byte)
{
- entropy_sink.update(reinterpret_cast<const byte*>(bytes), length);
- collected_bits += std::min<u32bit>(8, entropy_bits_per_byte) * length;
+ add_bytes(reinterpret_cast<const byte*>(bytes), length);
+ collected_bits += entropy_bits_per_byte * length;
}
template<typename T>
@@ -49,9 +54,27 @@ class Entropy_Accumulator
add(&v, sizeof(T), entropy_bits_per_byte);
}
private:
- BufferedComputation& entropy_sink;
+ virtual void add_bytes(const byte bytes[], u32bit length) = 0;
+
SecureVector<byte> io_buffer;
- u32bit entropy_goal, collected_bits;
+ u32bit entropy_goal;
+ double collected_bits;
+ };
+
+class Entropy_Accumulator_BufferedComputation : public Entropy_Accumulator
+ {
+ public:
+ Entropy_Accumulator_BufferedComputation(BufferedComputation& sink,
+ u32bit goal) :
+ Entropy_Accumulator(goal), entropy_sink(sink) {}
+
+ private:
+ virtual void add_bytes(const byte bytes[], u32bit length)
+ {
+ entropy_sink.update(bytes, length);
+ }
+
+ BufferedComputation& entropy_sink;
};
/**
diff --git a/src/entropy/unix_procs/es_unix.cpp b/src/entropy/unix_procs/es_unix.cpp
index 3ac8cd8d3..c8cf6daec 100644
--- a/src/entropy/unix_procs/es_unix.cpp
+++ b/src/entropy/unix_procs/es_unix.cpp
@@ -66,7 +66,7 @@ void Unix_EntropySource::poll(Entropy_Accumulator& accum)
struct stat statbuf;
clear_mem(&statbuf, 1);
::stat(stat_targets[j], &statbuf);
- accum.add(&statbuf, sizeof(statbuf), .05);
+ accum.add(&statbuf, sizeof(statbuf), .005);
}
accum.add(::getpid(), 0);
@@ -79,13 +79,10 @@ void Unix_EntropySource::poll(Entropy_Accumulator& accum)
struct ::rusage usage;
::getrusage(RUSAGE_SELF, &usage);
- accum.add(usage, .05);
+ accum.add(usage, .005);
::getrusage(RUSAGE_CHILDREN, &usage);
- accum.add(usage, .05);
-
- if(accum.desired_remaining_bits() < 128)
- return;
+ accum.add(usage, .005);
const u32bit MINIMAL_WORKING = 16;
diff --git a/src/rng/hmac_rng/hmac_rng.cpp b/src/rng/hmac_rng/hmac_rng.cpp
index ffdfdc60d..458118e11 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(*extractor, poll_bits);
+ Entropy_Accumulator_BufferedComputation accum(*extractor, poll_bits);
for(u32bit i = 0; i < entropy_sources.size(); ++i)
{
@@ -112,9 +112,8 @@ void HMAC_RNG::reseed_with_input(u32bit poll_bits,
K.clear();
counter = 0;
- // Upper bound entropy estimate at the extractor output size
- entropy = std::min<u32bit>(entropy + accum.bits_collected(),
- 8 * extractor->OUTPUT_LENGTH);
+ if(input_length || accum.bits_collected() >= poll_bits)
+ seeded = true;
}
/**
@@ -142,14 +141,6 @@ void HMAC_RNG::add_entropy_source(EntropySource* src)
entropy_sources.push_back(src);
}
-/**
-* Check if the the pool is seeded
-*/
-bool HMAC_RNG::is_seeded() const
- {
- return (entropy >= 8 * prf->OUTPUT_LENGTH);
- }
-
/*
* Clear memory of sensitive data
*/
@@ -158,8 +149,8 @@ void HMAC_RNG::clear() throw()
extractor->clear();
prf->clear();
K.clear();
- entropy = 0;
counter = 0;
+ seeded = false;
}
/**
@@ -177,11 +168,10 @@ HMAC_RNG::HMAC_RNG(MessageAuthenticationCode* extractor_mac,
MessageAuthenticationCode* prf_mac) :
extractor(extractor_mac), prf(prf_mac)
{
- entropy = 0;
-
// First PRF inputs are all zero, as specified in section 2
K.create(prf->OUTPUT_LENGTH);
counter = 0;
+ seeded = false;
/*
Normally we want to feedback PRF output into the input to the
@@ -223,7 +213,6 @@ HMAC_RNG::~HMAC_RNG()
std::for_each(entropy_sources.begin(), entropy_sources.end(),
del_fun<EntropySource>());
- entropy = 0;
counter = 0;
}
diff --git a/src/rng/hmac_rng/hmac_rng.h b/src/rng/hmac_rng/hmac_rng.h
index fbfa8df19..16adddd60 100644
--- a/src/rng/hmac_rng/hmac_rng.h
+++ b/src/rng/hmac_rng/hmac_rng.h
@@ -26,7 +26,7 @@ class BOTAN_DLL HMAC_RNG : public RandomNumberGenerator
{
public:
void randomize(byte buf[], u32bit len);
- bool is_seeded() const;
+ bool is_seeded() const { return seeded; }
void clear() throw();
std::string name() const;
@@ -46,7 +46,7 @@ class BOTAN_DLL HMAC_RNG : public RandomNumberGenerator
MessageAuthenticationCode* prf;
std::vector<EntropySource*> entropy_sources;
- u32bit entropy;
+ bool seeded;
SecureVector<byte> K, io_buffer;
u32bit counter, source_index;
diff --git a/src/rng/randpool/randpool.cpp b/src/rng/randpool/randpool.cpp
index 41a8ca23a..af36c335f 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(*mac, poll_bits);
+ Entropy_Accumulator_BufferedComputation accum(*mac, poll_bits);
for(u32bit i = 0; i != entropy_sources.size(); ++i)
{
@@ -116,8 +116,8 @@ void Randpool::reseed(u32bit poll_bits)
xor_buf(pool, mac_val, mac_val.size());
mix_pool();
- entropy = std::min<u32bit>(entropy + accum.bits_collected(),
- 8 * mac_val.size());
+ if(accum.bits_collected() >= poll_bits)
+ seeded = true;
}
/**
@@ -129,8 +129,8 @@ void Randpool::add_entropy(const byte input[], u32bit length)
xor_buf(pool, mac_val, mac_val.size());
mix_pool();
- // Assume 1 bit conditional entropy per byte of input
- entropy = std::min<u32bit>(entropy + length, 8 * mac_val.size());
+ if(length)
+ seeded = true;
}
/**
@@ -142,14 +142,6 @@ void Randpool::add_entropy_source(EntropySource* src)
}
/**
-* Check if the the pool is seeded
-*/
-bool Randpool::is_seeded() const
- {
- return (entropy >= 7 * mac->OUTPUT_LENGTH);
- }
-
-/**
* Clear memory of sensitive data
*/
void Randpool::clear() throw()
@@ -159,7 +151,7 @@ void Randpool::clear() throw()
pool.clear();
buffer.clear();
counter.clear();
- entropy = 0;
+ seeded = false;
}
/**
@@ -198,7 +190,7 @@ Randpool::Randpool(BlockCipher* cipher_in,
buffer.create(BLOCK_SIZE);
pool.create(POOL_BLOCKS * BLOCK_SIZE);
counter.create(12);
- entropy = 0;
+ seeded = false;
}
/**
@@ -211,8 +203,6 @@ Randpool::~Randpool()
std::for_each(entropy_sources.begin(), entropy_sources.end(),
del_fun<EntropySource>());
-
- entropy = 0;
}
}
diff --git a/src/rng/randpool/randpool.h b/src/rng/randpool/randpool.h
index 46683934e..f44527609 100644
--- a/src/rng/randpool/randpool.h
+++ b/src/rng/randpool/randpool.h
@@ -20,7 +20,7 @@ class BOTAN_DLL Randpool : public RandomNumberGenerator
{
public:
void randomize(byte[], u32bit);
- bool is_seeded() const;
+ bool is_seeded() const { return seeded; }
void clear() throw();
std::string name() const;
@@ -43,7 +43,7 @@ class BOTAN_DLL Randpool : public RandomNumberGenerator
std::vector<EntropySource*> entropy_sources;
SecureVector<byte> pool, buffer, counter;
- u32bit entropy;
+ bool seeded;
};
}
diff --git a/src/rng/x931_rng/x931_rng.cpp b/src/rng/x931_rng/x931_rng.cpp
index 4b33f4c5e..e77f04ae4 100644
--- a/src/rng/x931_rng/x931_rng.cpp
+++ b/src/rng/x931_rng/x931_rng.cpp
@@ -1,7 +1,7 @@
-/*************************************************
-* ANSI X9.31 RNG Source File *
-* (C) 1999-2008 Jack Lloyd *
-*************************************************/
+/*
+* ANSI X9.31 RNG Source File
+* (C) 1999-2009 Jack Lloyd
+*/
#include <botan/x931_rng.h>
#include <botan/xor_buf.h>
@@ -9,9 +9,9 @@
namespace Botan {
-/*************************************************
-* Generate a buffer of random bytes *
-*************************************************/
+/**
+* Generate a buffer of random bytes
+*/
void ANSI_X931_RNG::randomize(byte out[], u32bit length)
{
if(!is_seeded())
@@ -31,9 +31,9 @@ void ANSI_X931_RNG::randomize(byte out[], u32bit length)
}
}
-/*************************************************
-* Refill the internal state *
-*************************************************/
+/**
+* Refill the internal state
+*/
void ANSI_X931_RNG::update_buffer()
{
SecureVector<byte> DT(cipher->BLOCK_SIZE);
@@ -50,13 +50,11 @@ void ANSI_X931_RNG::update_buffer()
position = 0;
}
-/*************************************************
-* Reseed the internal state *
-*************************************************/
-void ANSI_X931_RNG::reseed(u32bit poll_bits)
+/**
+* Reset V and the cipher key with new values
+*/
+void ANSI_X931_RNG::rekey()
{
- prng->reseed(poll_bits);
-
if(prng->is_seeded())
{
SecureVector<byte> key(cipher->MAXIMUM_KEYLENGTH);
@@ -71,33 +69,43 @@ void ANSI_X931_RNG::reseed(u32bit poll_bits)
}
}
-/*************************************************
-* Add a entropy source to the underlying PRNG *
-*************************************************/
+/**
+* Reseed the internal state
+*/
+void ANSI_X931_RNG::reseed(u32bit poll_bits)
+ {
+ prng->reseed(poll_bits);
+ rekey();
+ }
+
+/**
+* Add a entropy source to the underlying PRNG
+*/
void ANSI_X931_RNG::add_entropy_source(EntropySource* src)
{
prng->add_entropy_source(src);
}
-/*************************************************
-* Add some entropy to the underlying PRNG *
-*************************************************/
+/**
+* Add some entropy to the underlying PRNG
+*/
void ANSI_X931_RNG::add_entropy(const byte input[], u32bit length)
{
prng->add_entropy(input, length);
+ rekey();
}
-/*************************************************
-* Check if the the PRNG is seeded *
-*************************************************/
+/**
+* Check if the the PRNG is seeded
+*/
bool ANSI_X931_RNG::is_seeded() const
{
return V.has_items();
}
-/*************************************************
-* Clear memory of sensitive data *
-*************************************************/
+/**
+* Clear memory of sensitive data
+*/
void ANSI_X931_RNG::clear() throw()
{
cipher->clear();
@@ -108,17 +116,17 @@ void ANSI_X931_RNG::clear() throw()
position = 0;
}
-/*************************************************
-* Return the name of this type *
-*************************************************/
+/**
+* Return the name of this type
+*/
std::string ANSI_X931_RNG::name() const
{
return "X9.31(" + cipher->name() + ")";
}
-/*************************************************
-* ANSI X931 RNG Constructor *
-*************************************************/
+/**
+* ANSI X931 RNG Constructor
+*/
ANSI_X931_RNG::ANSI_X931_RNG(BlockCipher* cipher_in,
RandomNumberGenerator* prng_in)
{
@@ -132,9 +140,9 @@ ANSI_X931_RNG::ANSI_X931_RNG(BlockCipher* cipher_in,
position = 0;
}
-/*************************************************
-* ANSI X931 RNG Destructor *
-*************************************************/
+/**
+* ANSI X931 RNG Destructor
+*/
ANSI_X931_RNG::~ANSI_X931_RNG()
{
delete cipher;
diff --git a/src/rng/x931_rng/x931_rng.h b/src/rng/x931_rng/x931_rng.h
index 2c68b9cb4..b1cef8df3 100644
--- a/src/rng/x931_rng/x931_rng.h
+++ b/src/rng/x931_rng/x931_rng.h
@@ -1,7 +1,7 @@
-/*************************************************
-* ANSI X9.31 RNG Header File *
-* (C) 1999-2008 Jack Lloyd *
-*************************************************/
+/*
+* ANSI X9.31 RNG Header File
+* (C) 1999-2009 Jack Lloyd
+*/
#ifndef BOTAN_ANSI_X931_RNG_H__
#define BOTAN_ANSI_X931_RNG_H__
@@ -11,9 +11,9 @@
namespace Botan {
-/*************************************************
-* ANSI X9.31 RNG *
-*************************************************/
+/**
+* ANSI X9.31 RNG
+*/
class BOTAN_DLL ANSI_X931_RNG : public RandomNumberGenerator
{
public:
@@ -29,6 +29,7 @@ class BOTAN_DLL ANSI_X931_RNG : public RandomNumberGenerator
ANSI_X931_RNG(BlockCipher*, RandomNumberGenerator*);
~ANSI_X931_RNG();
private:
+ void rekey();
void update_buffer();
BlockCipher* cipher;
diff --git a/src/utils/mem_ops.h b/src/utils/mem_ops.h
index 810356bce..e72269e6a 100644
--- a/src/utils/mem_ops.h
+++ b/src/utils/mem_ops.h
@@ -1,7 +1,7 @@
-/*************************************************
-* Memory Operations Header File *
-* (C) 1999-2007 Jack Lloyd *
-*************************************************/
+/*
+* Memory Operations Header File
+* (C) 1999-2009 Jack Lloyd
+*/
#ifndef BOTAN_MEMORY_OPS_H__
#define BOTAN_MEMORY_OPS_H__
@@ -11,14 +11,14 @@
namespace Botan {
-/*************************************************
-* Memory Manipulation Functions *
-*************************************************/
+/*
+* Memory Manipulation Functions
+*/
template<typename T> inline void copy_mem(T* out, const T* in, u32bit n)
{ std::memmove(out, in, sizeof(T)*n); }
template<typename T> inline void clear_mem(T* ptr, u32bit n)
- { std::memset(ptr, 0, sizeof(T)*n); }
+ { if(n) std::memset(ptr, 0, sizeof(T)*n); }
template<typename T> inline void set_mem(T* ptr, u32bit n, byte val)
{ std::memset(ptr, val, sizeof(T)*n); }