diff options
author | lloyd <[email protected]> | 2008-06-27 18:30:07 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2008-06-27 18:30:07 +0000 |
commit | e2a465b75d8baeac912e3f4d428ebc5e03fd76f1 (patch) | |
tree | 7490308782cbac8b0ec9ca0cc23d73ec8a0a7b68 /src | |
parent | d84a769cc563aebeae3893f952cba1659562e430 (diff) |
New structure for entropy sources + RNGs. The entropy sources are owned by
Randpool, it will query them as needed (or if asked to do so). New function
make_rng() that creates an RNG (X9.31 backed by a Randpool) and seeds it.
Remove the entropy source related code from the Modules/Builtin_Modules
classes.
Diffstat (limited to 'src')
-rw-r--r-- | src/modules.cpp | 98 | ||||
-rw-r--r-- | src/randpool.cpp | 99 | ||||
-rw-r--r-- | src/rng.cpp | 109 | ||||
-rw-r--r-- | src/x931_rng.cpp | 27 |
4 files changed, 169 insertions, 164 deletions
diff --git a/src/modules.cpp b/src/modules.cpp index 089281e61..a5016aa8c 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -1,6 +1,6 @@ /************************************************* * Module Factory Source File * -* (C) 1999-2007 Jack Lloyd * +* (C) 1999-2008 Jack Lloyd * *************************************************/ #include <botan/modules.h> @@ -21,16 +21,6 @@ #include <botan/mmap_mem.h> #endif -#if defined(BOTAN_EXT_TIMER_HARDWARE) - #include <botan/tm_hard.h> -#elif defined(BOTAN_EXT_TIMER_POSIX) - #include <botan/tm_posix.h> -#elif defined(BOTAN_EXT_TIMER_UNIX) - #include <botan/tm_unix.h> -#elif defined(BOTAN_EXT_TIMER_WIN32) - #include <botan/tm_win32.h> -#endif - #if defined(BOTAN_EXT_ENGINE_GNU_MP) #include <botan/eng_gmp.h> #endif @@ -39,34 +29,6 @@ #include <botan/eng_ossl.h> #endif -#if defined(BOTAN_EXT_ENTROPY_SRC_DEVICE) - #include <botan/es_dev.h> -#endif - -#if defined(BOTAN_EXT_ENTROPY_SRC_EGD) - #include <botan/es_egd.h> -#endif - -#if defined(BOTAN_EXT_ENTROPY_SRC_UNIX) - #include <botan/es_unix.h> -#endif - -#if defined(BOTAN_EXT_ENTROPY_SRC_BEOS) - #include <botan/es_beos.h> -#endif - -#if defined(BOTAN_EXT_ENTROPY_SRC_CAPI) - #include <botan/es_capi.h> -#endif - -#if defined(BOTAN_EXT_ENTROPY_SRC_WIN32) - #include <botan/es_win32.h> -#endif - -#if defined(BOTAN_EXT_ENTROPY_SRC_FTW) - #include <botan/es_ftw.h> -#endif - namespace Botan { /************************************************* @@ -120,64 +82,6 @@ std::string Builtin_Modules::default_allocator() const } /************************************************* -* Register any usable entropy sources * -*************************************************/ -std::vector<EntropySource*> Builtin_Modules::entropy_sources() const - { - std::vector<EntropySource*> sources; - -#if defined(BOTAN_EXT_TIMER_HARDWARE) - sources.push_back(new Hardware_Timer); -#elif defined(BOTAN_EXT_TIMER_POSIX) - sources.push_back(new POSIX_Timer); -#elif defined(BOTAN_EXT_TIMER_UNIX) - sources.push_back(new Unix_Timer); -#elif defined(BOTAN_EXT_TIMER_WIN32) - sources.push_back(new Win32_Timer); -#else - sources.push_back(new Timer); -#endif - -#if defined(BOTAN_EXT_ENTROPY_SRC_EGD) - sources.push_back( - new EGD_EntropySource(split_on("/var/run/egd-pool:/dev/egd-pool", ':')) - ); -#endif - -#if defined(BOTAN_EXT_ENTROPY_SRC_DEVICE) - sources.push_back( - new Device_EntropySource( - split_on("/dev/random:/dev/srandom:/dev/urandom", ':') - ) - ); -#endif - -#if defined(BOTAN_EXT_ENTROPY_SRC_CAPI) - sources.push_back(new Win32_CAPI_EntropySource); -#endif - -#if defined(BOTAN_EXT_ENTROPY_SRC_WIN32) - sources.push_back(new Win32_EntropySource); -#endif - -#if defined(BOTAN_EXT_ENTROPY_SRC_UNIX) - sources.push_back( - new Unix_EntropySource(split_on("/bin:/sbin:/usr/bin:/usr/sbin", ':')) - ); -#endif - -#if defined(BOTAN_EXT_ENTROPY_SRC_BEOS) - sources.push_back(new BeOS_EntropySource); -#endif - -#if defined(BOTAN_EXT_ENTROPY_SRC_FTW) - sources.push_back(new FTW_EntropySource("/proc")); -#endif - - return sources; - } - -/************************************************* * Find any usable engines * *************************************************/ std::vector<Engine*> Builtin_Modules::engines() const diff --git a/src/randpool.cpp b/src/randpool.cpp index abb75c1f0..24086c984 100644 --- a/src/randpool.cpp +++ b/src/randpool.cpp @@ -1,6 +1,6 @@ /************************************************* * Randpool Source File * -* (C) 1999-2007 Jack Lloyd * +* (C) 1999-2008 Jack Lloyd * *************************************************/ #include <botan/randpool.h> @@ -8,6 +8,7 @@ #include <botan/loadstor.h> #include <botan/bit_ops.h> #include <botan/util.h> +#include <botan/stl_util.h> #include <algorithm> namespace Botan { @@ -18,21 +19,11 @@ namespace { * PRF based on a MAC * *************************************************/ enum RANDPOOL_PRF_TAG { - USER_INPUT = 0, - CIPHER_KEY = 1, - MAC_KEY = 2, - GEN_OUTPUT = 3 + CIPHER_KEY = 0, + MAC_KEY = 1, + GEN_OUTPUT = 2 }; -SecureVector<byte> randpool_prf(MessageAuthenticationCode* mac, - RANDPOOL_PRF_TAG tag, - const byte in[], u32bit length) - { - mac->update(static_cast<byte>(tag)); - mac->update(in, length); - return mac->final(); - } - } /************************************************* @@ -41,7 +32,12 @@ SecureVector<byte> randpool_prf(MessageAuthenticationCode* mac, void Randpool::randomize(byte out[], u32bit length) { if(!is_seeded()) - throw PRNG_Unseeded(name()); + { + reseed(); + + if(!is_seeded()) + throw PRNG_Unseeded(name()); + } update_buffer(); while(length) @@ -66,18 +62,16 @@ void Randpool::update_buffer() break; store_be(timestamp, counter + 4); - SecureVector<byte> mac_val = randpool_prf(mac, GEN_OUTPUT, - counter, counter.size()); + mac->update(static_cast<byte>(GEN_OUTPUT)); + mac->update(counter, counter.size()); + SecureVector<byte> mac_val = mac->final(); for(u32bit j = 0; j != mac_val.size(); ++j) buffer[j % buffer.size()] ^= mac_val[j]; cipher->encrypt(buffer); if(counter[0] % ITERATIONS_BEFORE_RESEED == 0) - { mix_pool(); - update_buffer(); - } } /************************************************* @@ -87,8 +81,13 @@ void Randpool::mix_pool() { const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE; - mac->set_key(randpool_prf(mac, MAC_KEY, pool, pool.size())); - cipher->set_key(randpool_prf(mac, CIPHER_KEY, pool, pool.size())); + mac->update(static_cast<byte>(MAC_KEY)); + mac->update(pool, pool.size()); + mac->set_key(mac->final()); + + mac->update(static_cast<byte>(CIPHER_KEY)); + mac->update(pool, pool.size()); + cipher->set_key(mac->final()); xor_buf(pool, buffer, BLOCK_SIZE); cipher->encrypt(pool); @@ -99,20 +98,54 @@ void Randpool::mix_pool() xor_buf(this_block, previous_block, BLOCK_SIZE); cipher->encrypt(this_block); } + + update_buffer(); } /************************************************* -* Add entropy to the internal state * +* Reseed the internal state * *************************************************/ -void Randpool::add_randomness(const byte data[], u32bit length) +void Randpool::reseed() { - u32bit this_entropy = entropy_estimate(data, length); - entropy += std::min(this_entropy, 8*mac->OUTPUT_LENGTH); - entropy = std::min(entropy, 8 * pool.size()); + SecureVector<byte> buffer(1024); + u32bit gathered_entropy = 0; + + for(u32bit j = 0; j != entropy_sources.size(); ++j) + { + u32bit got = entropy_sources[j]->slow_poll(buffer, buffer.size()); + + mac->update(buffer, got); + + gathered_entropy += entropy_estimate(buffer, got); + if(gathered_entropy > 512) + break; + } - SecureVector<byte> mac_val = randpool_prf(mac, USER_INPUT, data, length); + SecureVector<byte> mac_val = mac->final(); xor_buf(pool, mac_val, mac_val.size()); mix_pool(); + + entropy += gathered_entropy; + } + +/************************************************* +* Add user-supplied entropy * +*************************************************/ +void Randpool::add_entropy(const byte input[], u32bit length) + { + SecureVector<byte> mac_val = mac->process(input, length); + xor_buf(pool, mac_val, mac_val.size()); + mix_pool(); + + entropy += entropy_estimate(input, length); + } + +/************************************************* +* Add another entropy source to the list * +*************************************************/ +void Randpool::add_entropy_source(EntropySource* src) + { + entropy_sources.push_back(src); } /************************************************* @@ -120,7 +153,7 @@ void Randpool::add_randomness(const byte data[], u32bit length) *************************************************/ bool Randpool::is_seeded() const { - return (entropy >= 256); + return (entropy >= 384); } /************************************************* @@ -149,7 +182,7 @@ std::string Randpool::name() const *************************************************/ Randpool::Randpool(const std::string& cipher_name, const std::string& mac_name) : - ITERATIONS_BEFORE_RESEED(8), POOL_BLOCKS(32) + ITERATIONS_BEFORE_RESEED(128), POOL_BLOCKS(32) { cipher = get_block_cipher(cipher_name); mac = get_mac(mac_name); @@ -171,8 +204,6 @@ Randpool::Randpool(const std::string& cipher_name, pool.create(POOL_BLOCKS * BLOCK_SIZE); counter.create(12); entropy = 0; - - mix_pool(); } /************************************************* @@ -182,6 +213,10 @@ Randpool::~Randpool() { delete cipher; delete mac; + + std::for_each(entropy_sources.begin(), entropy_sources.end(), + del_fun<EntropySource>()); + entropy = 0; } diff --git a/src/rng.cpp b/src/rng.cpp index 59d4e576d..5b1bf6915 100644 --- a/src/rng.cpp +++ b/src/rng.cpp @@ -4,8 +4,48 @@ *************************************************/ #include <botan/rng.h> -#include <botan/secmem.h> +#include <botan/randpool.h> +#include <botan/x931_rng.h> #include <botan/util.h> +#include <botan/parsing.h> + +#if defined(BOTAN_EXT_TIMER_HARDWARE) + #include <botan/tm_hard.h> +#elif defined(BOTAN_EXT_TIMER_POSIX) + #include <botan/tm_posix.h> +#elif defined(BOTAN_EXT_TIMER_UNIX) + #include <botan/tm_unix.h> +#elif defined(BOTAN_EXT_TIMER_WIN32) + #include <botan/tm_win32.h> +#endif + +#if defined(BOTAN_EXT_ENTROPY_SRC_DEVICE) + #include <botan/es_dev.h> +#endif + +#if defined(BOTAN_EXT_ENTROPY_SRC_EGD) + #include <botan/es_egd.h> +#endif + +#if defined(BOTAN_EXT_ENTROPY_SRC_UNIX) + #include <botan/es_unix.h> +#endif + +#if defined(BOTAN_EXT_ENTROPY_SRC_BEOS) + #include <botan/es_beos.h> +#endif + +#if defined(BOTAN_EXT_ENTROPY_SRC_CAPI) + #include <botan/es_capi.h> +#endif + +#if defined(BOTAN_EXT_ENTROPY_SRC_WIN32) + #include <botan/es_win32.h> +#endif + +#if defined(BOTAN_EXT_ENTROPY_SRC_FTW) + #include <botan/es_ftw.h> +#endif namespace Botan { @@ -28,30 +68,61 @@ byte RandomNumberGenerator::next_byte() } /************************************************* -* Add entropy to internal state * +* Create and seed a new RNG object * *************************************************/ -void RandomNumberGenerator::add_entropy(const byte random[], u32bit length) +RandomNumberGenerator* make_rng() { - this->add_randomness(random, length); - } + Randpool* randpool = new Randpool("AES-256", "HMAC(SHA-256)"); -/************************************************* -* Add entropy to internal state * -*************************************************/ -u32bit RandomNumberGenerator::add_entropy(EntropySource& source, - bool slow_poll) - { - SecureVector<byte> buffer(1024); - u32bit bytes_gathered = 0; +#if defined(BOTAN_EXT_TIMER_HARDWARE) + randpool->add_entropy_source(new Hardware_Timer); +#elif defined(BOTAN_EXT_TIMER_POSIX) + randpool->add_entropy_source(new POSIX_Timer); +#elif defined(BOTAN_EXT_TIMER_UNIX) + randpool->add_entropy_source(new Unix_Timer); +#elif defined(BOTAN_EXT_TIMER_WIN32) + randpool->add_entropy_source(new Win32_Timer); +#else + randpool->add_entropy_source(new Timer); +#endif + +#if defined(BOTAN_EXT_ENTROPY_SRC_DEVICE) + randpool->add_entropy_source( + new Device_EntropySource( + split_on("/dev/random:/dev/srandom:/dev/urandom", ':') + ) + ); +#endif + +#if defined(BOTAN_EXT_ENTROPY_SRC_EGD) + randpool->add_entropy_source( + new EGD_EntropySource(split_on("/var/run/egd-pool:/dev/egd-pool", ':')) + ); +#endif + +#if defined(BOTAN_EXT_ENTROPY_SRC_CAPI) + randpool->add_entropy_source(new Win32_CAPI_EntropySource); +#endif + +#if defined(BOTAN_EXT_ENTROPY_SRC_WIN32) + randpool->add_entropy_source(new Win32_EntropySource); +#endif + +#if defined(BOTAN_EXT_ENTROPY_SRC_UNIX) + randpool->add_entropy_source( + new Unix_EntropySource(split_on("/bin:/sbin:/usr/bin:/usr/sbin", ':')) + ); +#endif - if(slow_poll) - bytes_gathered = source.slow_poll(buffer, buffer.size()); - else - bytes_gathered = source.fast_poll(buffer, buffer.size()); +#if defined(BOTAN_EXT_ENTROPY_SRC_BEOS) + randpool->add_entropy_source(new BeOS_EntropySource); +#endif - this->add_entropy(buffer, bytes_gathered); +#if defined(BOTAN_EXT_ENTROPY_SRC_FTW) + randpool->add_entropy_source(new FTW_EntropySource("/proc")); +#endif - return entropy_estimate(buffer, bytes_gathered); + return new ANSI_X931_RNG("AES-256", randpool); } } diff --git a/src/x931_rng.cpp b/src/x931_rng.cpp index d9ac69296..24b5059f1 100644 --- a/src/x931_rng.cpp +++ b/src/x931_rng.cpp @@ -1,6 +1,6 @@ /************************************************* * ANSI X9.31 RNG Source File * -* (C) 1999-2007 Jack Lloyd * +* (C) 1999-2008 Jack Lloyd * *************************************************/ #include <botan/x931_rng.h> @@ -16,7 +16,7 @@ namespace Botan { void ANSI_X931_RNG::randomize(byte out[], u32bit length) { if(!is_seeded()) - throw PRNG_Unseeded(name()); + reseed(); while(length) { @@ -52,24 +52,19 @@ void ANSI_X931_RNG::update_buffer() } /************************************************* -* Add entropy to internal state * +* Reseed the internal state * *************************************************/ -void ANSI_X931_RNG::add_randomness(const byte data[], u32bit length) +void ANSI_X931_RNG::reseed() { - prng->add_entropy(data, length); + SecureVector<byte> key(cipher->MAXIMUM_KEYLENGTH); + prng->randomize(key, key.size()); + cipher->set_key(key, key.size()); - if(prng->is_seeded()) - { - SecureVector<byte> key(cipher->MAXIMUM_KEYLENGTH); - prng->randomize(key, key.size()); - cipher->set_key(key, key.size()); - - if(V.size() != cipher->BLOCK_SIZE) - V.create(cipher->BLOCK_SIZE); - prng->randomize(V, V.size()); + if(V.size() != cipher->BLOCK_SIZE) + V.create(cipher->BLOCK_SIZE); + prng->randomize(V, V.size()); - update_buffer(); - } + update_buffer(); } /************************************************* |