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 | |
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
-rw-r--r-- | checks/check.cpp | 4 | ||||
-rw-r--r-- | src/libstate/global_rng.cpp (renamed from src/rng/auto_rng/auto_rng.cpp) | 73 | ||||
-rw-r--r-- | src/libstate/info.txt | 3 | ||||
-rw-r--r-- | src/libstate/libstate.cpp | 29 | ||||
-rw-r--r-- | src/libstate/libstate.h | 15 | ||||
-rw-r--r-- | src/pubkey/blinding.cpp | 27 | ||||
-rw-r--r-- | src/pubkey/blinding.h | 7 | ||||
-rw-r--r-- | src/pubkey/dh/dh.cpp | 3 | ||||
-rw-r--r-- | src/pubkey/elgamal/elgamal.cpp | 3 | ||||
-rw-r--r-- | src/pubkey/rsa/rsa.cpp | 3 | ||||
-rw-r--r-- | src/rng/auto_rng/auto_rng.h | 17 | ||||
-rw-r--r-- | src/rng/auto_rng/info.txt | 3 |
12 files changed, 121 insertions, 66 deletions
diff --git a/checks/check.cpp b/checks/check.cpp index 1f46b5b4c..952384a19 100644 --- a/checks/check.cpp +++ b/checks/check.cpp @@ -106,8 +106,6 @@ int main(int argc, char* argv[]) Botan::LibraryInitializer init("thread_safe=no"); - Botan::AutoSeeded_RNG rng; - if(opts.is_set("help") || argc <= 1) { std::cerr << "Test driver for " @@ -121,6 +119,8 @@ int main(int argc, char* argv[]) return 1; } + Botan::AutoSeeded_RNG rng; + if(opts.is_set("validate") || opts.is_set("test")) { return run_test_suite(rng); diff --git a/src/rng/auto_rng/auto_rng.cpp b/src/libstate/global_rng.cpp index 78a7ca21d..c18705a3a 100644 --- a/src/rng/auto_rng/auto_rng.cpp +++ b/src/libstate/global_rng.cpp @@ -1,13 +1,12 @@ /* -* Auto Seeded RNG -* (C) 2008 Jack Lloyd +* Global PRNG +* (C) 2008-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ -#include <botan/auto_rng.h> #include <botan/libstate.h> -#include <botan/parsing.h> +#include <botan/mutex.h> #if defined(BOTAN_HAS_RANDPOOL) #include <botan/randpool.h> @@ -103,13 +102,67 @@ void add_entropy_sources(RandomNumberGenerator* rng) #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; + }; + } -AutoSeeded_RNG::AutoSeeded_RNG(u32bit poll_bits) +RandomNumberGenerator* Library_State::make_global_rng(Algorithm_Factory& af, + Mutex* mutex) { - rng = 0; - - Algorithm_Factory& af = global_state().algorithm_factory(); + RandomNumberGenerator* rng = 0; #if defined(BOTAN_HAS_HMAC_RNG) @@ -135,7 +188,9 @@ AutoSeeded_RNG::AutoSeeded_RNG(u32bit poll_bits) add_entropy_sources(rng); - rng->reseed(poll_bits); + 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; diff --git a/src/pubkey/blinding.cpp b/src/pubkey/blinding.cpp index 819d0dd20..c4c0e3b6e 100644 --- a/src/pubkey/blinding.cpp +++ b/src/pubkey/blinding.cpp @@ -7,11 +7,6 @@ #include <botan/blinding.h> #include <botan/numthry.h> -#include <botan/libstate.h> -#include <botan/hash.h> -#include <botan/time.h> -#include <botan/loadstor.h> -#include <memory> namespace Botan { @@ -28,28 +23,6 @@ Blinder::Blinder(const BigInt& e, const BigInt& d, const BigInt& n) this->d = d; } -BigInt Blinder::choose_nonce(const BigInt& x, const BigInt& mod) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - - std::auto_ptr<HashFunction> hash(af.make_hash_function("SHA-512")); - - u64bit ns_clock = get_nanoseconds_clock(); - for(size_t i = 0; i != sizeof(ns_clock); ++i) - hash->update(get_byte(i, ns_clock)); - - hash->update(BigInt::encode(x)); - hash->update(BigInt::encode(mod)); - - u64bit timestamp = system_time(); - for(size_t i = 0; i != sizeof(timestamp); ++i) - hash->update(get_byte(i, timestamp)); - - SecureVector<byte> r = hash->final(); - - return BigInt::decode(r) % mod; - } - /* * Blind a number */ diff --git a/src/pubkey/blinding.h b/src/pubkey/blinding.h index 3398f8c6f..03c9043dd 100644 --- a/src/pubkey/blinding.h +++ b/src/pubkey/blinding.h @@ -24,13 +24,6 @@ class BOTAN_DLL Blinder bool initialized() const { return reducer.initialized(); } - /** - * Choose a nonce to use for blinding - * @param x a secret seed value - * @param mod the modulus - */ - static BigInt choose_nonce(const BigInt& x, const BigInt& mod); - Blinder() {} /** diff --git a/src/pubkey/dh/dh.cpp b/src/pubkey/dh/dh.cpp index 1a6c6986d..f7d1838ce 100644 --- a/src/pubkey/dh/dh.cpp +++ b/src/pubkey/dh/dh.cpp @@ -7,6 +7,7 @@ #include <botan/dh.h> #include <botan/numthry.h> +#include <botan/libstate.h> #include <botan/internal/workfactor.h> namespace Botan { @@ -78,7 +79,7 @@ MemoryVector<byte> DH_PrivateKey::public_value() const DH_KA_Operation::DH_KA_Operation(const DH_PrivateKey& dh) : p(dh.group_p()), powermod_x_p(dh.get_x(), p) { - BigInt k = Blinder::choose_nonce(powermod_x_p(dh.get_y()), p); + BigInt k(global_state().global_rng(), p.bits() - 1); blinder = Blinder(k, powermod_x_p(inverse_mod(k, p)), p); } diff --git a/src/pubkey/elgamal/elgamal.cpp b/src/pubkey/elgamal/elgamal.cpp index 3ae0f5aae..5640a4400 100644 --- a/src/pubkey/elgamal/elgamal.cpp +++ b/src/pubkey/elgamal/elgamal.cpp @@ -7,6 +7,7 @@ #include <botan/elgamal.h> #include <botan/numthry.h> +#include <botan/libstate.h> #include <botan/keypair.h> #include <botan/internal/workfactor.h> @@ -118,7 +119,7 @@ ElGamal_Decryption_Operation::ElGamal_Decryption_Operation(const ElGamal_Private powermod_x_p = Fixed_Exponent_Power_Mod(key.get_x(), p); mod_p = Modular_Reducer(p); - BigInt k = Blinder::choose_nonce(powermod_x_p(key.get_y()), p); + BigInt k(global_state().global_rng(), p.bits() - 1); blinder = Blinder(k, powermod_x_p(k), p); } diff --git a/src/pubkey/rsa/rsa.cpp b/src/pubkey/rsa/rsa.cpp index 19ca27f40..3222b5113 100644 --- a/src/pubkey/rsa/rsa.cpp +++ b/src/pubkey/rsa/rsa.cpp @@ -6,6 +6,7 @@ */ #include <botan/rsa.h> +#include <botan/libstate.h> #include <botan/parsing.h> #include <botan/numthry.h> #include <botan/keypair.h> @@ -80,7 +81,7 @@ RSA_Private_Operation::RSA_Private_Operation(const RSA_PrivateKey& rsa) : powermod_d2_q(rsa.get_d2(), rsa.get_q()), mod_p(rsa.get_p()) { - BigInt k = Blinder::choose_nonce(powermod_e_n(q), n); + BigInt k(global_state().global_rng(), n.bits() - 1); blinder = Blinder(powermod_e_n(k), inverse_mod(k, n), n); } diff --git a/src/rng/auto_rng/auto_rng.h b/src/rng/auto_rng/auto_rng.h index a15b11b13..9a93fee8f 100644 --- a/src/rng/auto_rng/auto_rng.h +++ b/src/rng/auto_rng/auto_rng.h @@ -9,31 +9,32 @@ #define BOTAN_AUTO_SEEDING_RNG_H__ #include <botan/rng.h> +#include <botan/libstate.h> #include <string> namespace Botan { -/** -* RNG that attempts to seed itself -*/ class BOTAN_DLL AutoSeeded_RNG : public RandomNumberGenerator { public: void randomize(byte out[], u32bit len) { rng->randomize(out, len); } - bool is_seeded() const - { return rng->is_seeded(); } + + bool is_seeded() const { return rng->is_seeded(); } + void clear() { rng->clear(); } - std::string name() const - { return "AutoSeeded(" + rng->name() + ")"; } + + std::string name() const { return rng->name(); } void reseed(u32bit poll_bits = 256) { rng->reseed(poll_bits); } + void add_entropy_source(EntropySource* es) { rng->add_entropy_source(es); } + void add_entropy(const byte in[], u32bit len) { rng->add_entropy(in, len); } - AutoSeeded_RNG(u32bit poll_bits = 256); + AutoSeeded_RNG() { rng = &global_state().global_rng(); } ~AutoSeeded_RNG() { delete rng; } private: RandomNumberGenerator* rng; diff --git a/src/rng/auto_rng/info.txt b/src/rng/auto_rng/info.txt index 0f7cee282..6f98a65f4 100644 --- a/src/rng/auto_rng/info.txt +++ b/src/rng/auto_rng/info.txt @@ -1,6 +1,5 @@ define AUTO_SEEDING_RNG <requires> -hmac -sha2 +libstate </requires> |