diff options
author | lloyd <[email protected]> | 2010-03-19 15:59:45 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2010-03-19 15:59:45 +0000 |
commit | 1418ba24b73b8d9e4af67950fee38a02e7f1ac75 (patch) | |
tree | feeb7add6cc5cd172579cb1326bfe3fcd6f4830e /src/libstate | |
parent | 87cb43641ca7000b6d97dcb4d8a5e716a07fcf76 (diff) |
There are some nasty API problems that are caused by having to pass a
PRNG everywhere. The removal of the global PRNG was generated by a
desire to remove the global library state entirely. However the real
point of this was to remove the use of globally visible _mutable_
state; of the mutable state, the PRNG is probably the least important,
and the most useful to share. And it seems unlikely that thread
contention would be a major issue in the PRNG.
Add back a global PRNG to Library_State. Use lazy initialization, so
apps that don't ever use a PRNG don't need a seeding step. Then have
AutoSeeded_RNG call that global PRNG.
Offer once again
RandomNumberGenerator& Library_State::global_rng();
which returns a reference to the global PRNG.
This RNG object serializes access to itself with a mutex.
Remove the hack known as Blinding::choose_nonce, replace with using
the global PRNG to choose a blinding nonce
Diffstat (limited to 'src/libstate')
-rw-r--r-- | src/libstate/global_rng.cpp | 196 | ||||
-rw-r--r-- | src/libstate/info.txt | 3 | ||||
-rw-r--r-- | src/libstate/libstate.cpp | 29 | ||||
-rw-r--r-- | src/libstate/libstate.h | 15 |
4 files changed, 235 insertions, 8 deletions
diff --git a/src/libstate/global_rng.cpp b/src/libstate/global_rng.cpp new file mode 100644 index 000000000..c18705a3a --- /dev/null +++ b/src/libstate/global_rng.cpp @@ -0,0 +1,196 @@ +/* +* Global PRNG +* (C) 2008-2010 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/libstate.h> +#include <botan/mutex.h> + +#if defined(BOTAN_HAS_RANDPOOL) + #include <botan/randpool.h> +#endif + +#if defined(BOTAN_HAS_HMAC_RNG) + #include <botan/hmac_rng.h> +#endif + +#if defined(BOTAN_HAS_X931_RNG) + #include <botan/x931_rng.h> +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_HIGH_RESOLUTION_TIMER) + #include <botan/internal/hres_timer.h> +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM) + #include <botan/internal/dev_random.h> +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_EGD) + #include <botan/internal/es_egd.h> +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_UNIX) + #include <botan/internal/es_unix.h> +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_BEOS) + #include <botan/internal/es_beos.h> +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_CAPI) + #include <botan/internal/es_capi.h> +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32) + #include <botan/internal/es_win32.h> +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_FTW) + #include <botan/internal/es_ftw.h> +#endif + +namespace Botan { + +namespace { + +/** +* Add any known entropy sources to this RNG +*/ +void add_entropy_sources(RandomNumberGenerator* rng) + { +#if defined(BOTAN_HAS_ENTROPY_SRC_HIGH_RESOLUTION_TIMER) + rng->add_entropy_source(new High_Resolution_Timestamp); +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM) + rng->add_entropy_source( + new Device_EntropySource( + split_on("/dev/urandom:/dev/random:/dev/srandom", ':') + ) + ); +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_EGD) + rng->add_entropy_source( + new EGD_EntropySource(split_on("/var/run/egd-pool:/dev/egd-pool", ':')) + ); +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_CAPI) + rng->add_entropy_source(new Win32_CAPI_EntropySource); +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_FTW) + rng->add_entropy_source(new FTW_EntropySource("/proc")); +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32) + rng->add_entropy_source(new Win32_EntropySource); +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_BEOS) + rng->add_entropy_source(new BeOS_EntropySource); +#endif + +#if defined(BOTAN_HAS_ENTROPY_SRC_UNIX) + rng->add_entropy_source( + new Unix_EntropySource(split_on("/bin:/sbin:/usr/bin:/usr/sbin", ':')) + ); +#endif + } + +class Serialized_PRNG : public RandomNumberGenerator + { + public: + void randomize(byte out[], u32bit len) + { + Mutex_Holder lock(mutex); + rng->randomize(out, len); + } + + bool is_seeded() const + { + Mutex_Holder lock(mutex); + return rng->is_seeded(); + } + + void clear() + { + Mutex_Holder lock(mutex); + rng->clear(); + } + + std::string name() const + { + Mutex_Holder lock(mutex); + return rng->name(); + } + + void reseed(u32bit poll_bits) + { + Mutex_Holder lock(mutex); + rng->reseed(poll_bits); + } + + void add_entropy_source(EntropySource* es) + { + Mutex_Holder lock(mutex); + rng->add_entropy_source(es); + } + + void add_entropy(const byte in[], u32bit len) + { + Mutex_Holder lock(mutex); + rng->add_entropy(in, len); + } + + // We do not own the mutex; Library_State does + Serialized_PRNG(RandomNumberGenerator* r, Mutex* m) : + mutex(m), rng(r) {} + + ~Serialized_PRNG() { delete rng; } + private: + Mutex* mutex; + RandomNumberGenerator* rng; + }; + +} + +RandomNumberGenerator* Library_State::make_global_rng(Algorithm_Factory& af, + Mutex* mutex) + { + RandomNumberGenerator* rng = 0; + +#if defined(BOTAN_HAS_HMAC_RNG) + + rng = new HMAC_RNG(af.make_mac("HMAC(SHA-512)"), + af.make_mac("HMAC(SHA-256)")); + +#elif defined(BOTAN_HAS_RANDPOOL) && defined(BOTAN_HAS_AES) + + rng = new Randpool(af.make_block_cipher("AES-256"), + af.make_mac("HMAC(SHA-256)")); + +#endif + + if(!rng) + throw Internal_Error("No usable RNG found enabled in build"); + + /* If X9.31 is available, use it to wrap the other RNG as a failsafe */ +#if defined(BOTAN_HAS_X931_RNG) && defined(BOTAN_HAS_AES) + + rng = new ANSI_X931_RNG(af.make_block_cipher("AES-256"), rng); + +#endif + + add_entropy_sources(rng); + + rng->reseed(256); + + return new Serialized_PRNG(rng, mutex); + } + +} diff --git a/src/libstate/info.txt b/src/libstate/info.txt index 3992d25bd..905675109 100644 --- a/src/libstate/info.txt +++ b/src/libstate/info.txt @@ -14,6 +14,7 @@ scan_name.h <source> get_enc.cpp init.cpp +global_rng.cpp libstate.cpp lookup.cpp policy.cpp @@ -29,6 +30,7 @@ def_engine engine filters hash +hmac kdf mac mode_pad @@ -38,6 +40,7 @@ pk_pad pubkey rng s2k +sha2 stream system_alloc </requires> diff --git a/src/libstate/libstate.cpp b/src/libstate/libstate.cpp index 7706cef28..c62bd08db 100644 --- a/src/libstate/libstate.cpp +++ b/src/libstate/libstate.cpp @@ -214,8 +214,8 @@ std::string Library_State::deref_alias(const std::string& key) const return result; } -/** -Return a reference to the Algorithm_Factory +/* +* Return a reference to the Algorithm_Factory */ Algorithm_Factory& Library_State::algorithm_factory() const { @@ -225,6 +225,20 @@ Algorithm_Factory& Library_State::algorithm_factory() const } /* +* Return a reference to the global PRNG +*/ +RandomNumberGenerator& Library_State::global_rng() + { + Mutex_Holder lock(global_rng_lock); + + if(!global_rng_ptr) + global_rng_ptr = make_global_rng(algorithm_factory(), + global_rng_lock); + + return *global_rng_ptr; + } + +/* * Load a set of modules */ void Library_State::initialize(bool thread_safe) @@ -249,17 +263,20 @@ void Library_State::initialize(bool thread_safe) #endif } - allocator_lock = mutex_factory->make(); - config_lock = mutex_factory->make(); + allocator_lock = get_mutex(); + config_lock = get_mutex(); + global_rng_lock = get_mutex(); + + global_rng_ptr = 0; cached_default_allocator = 0; default_allocator_name = has_mlock() ? "locking" : "malloc"; add_allocator(new Malloc_Allocator); - add_allocator(new Locking_Allocator(mutex_factory->make())); + add_allocator(new Locking_Allocator(get_mutex())); #if defined(BOTAN_HAS_ALLOC_MMAP) - add_allocator(new MemoryMapping_Allocator(mutex_factory->make())); + add_allocator(new MemoryMapping_Allocator(get_mutex())); #endif load_default_config(); diff --git a/src/libstate/libstate.h b/src/libstate/libstate.h index ade17c17e..4674eca88 100644 --- a/src/libstate/libstate.h +++ b/src/libstate/libstate.h @@ -8,9 +8,9 @@ #ifndef BOTAN_LIB_STATE_H__ #define BOTAN_LIB_STATE_H__ -#include <botan/types.h> #include <botan/allocate.h> #include <botan/algo_factory.h> +#include <botan/rng.h> #include <string> #include <vector> @@ -37,6 +37,11 @@ class BOTAN_DLL Library_State Algorithm_Factory& algorithm_factory() const; /** + * @return the global RandomNumberGenerator + */ + RandomNumberGenerator& global_rng(); + + /** * @param name the name of the allocator * @return allocator matching this name, or NULL */ @@ -107,6 +112,9 @@ class BOTAN_DLL Library_State */ Mutex* get_mutex() const; private: + static RandomNumberGenerator* make_global_rng(Algorithm_Factory& af, + Mutex* mutex); + void load_default_config(); Library_State(const Library_State&) {} @@ -114,8 +122,11 @@ class BOTAN_DLL Library_State class Mutex_Factory* mutex_factory; - std::map<std::string, std::string> config; + Mutex* global_rng_lock; + RandomNumberGenerator* global_rng_ptr; + Mutex* config_lock; + std::map<std::string, std::string> config; Mutex* allocator_lock; std::string default_allocator_name; |