aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2010-03-19 15:59:45 +0000
committerlloyd <[email protected]>2010-03-19 15:59:45 +0000
commit1418ba24b73b8d9e4af67950fee38a02e7f1ac75 (patch)
treefeeb7add6cc5cd172579cb1326bfe3fcd6f4830e
parent87cb43641ca7000b6d97dcb4d8a5e716a07fcf76 (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.cpp4
-rw-r--r--src/libstate/global_rng.cpp (renamed from src/rng/auto_rng/auto_rng.cpp)73
-rw-r--r--src/libstate/info.txt3
-rw-r--r--src/libstate/libstate.cpp29
-rw-r--r--src/libstate/libstate.h15
-rw-r--r--src/pubkey/blinding.cpp27
-rw-r--r--src/pubkey/blinding.h7
-rw-r--r--src/pubkey/dh/dh.cpp3
-rw-r--r--src/pubkey/elgamal/elgamal.cpp3
-rw-r--r--src/pubkey/rsa/rsa.cpp3
-rw-r--r--src/rng/auto_rng/auto_rng.h17
-rw-r--r--src/rng/auto_rng/info.txt3
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>