Index: . =================================================================== --- . (revision 86762) +++ . (working copy) @@ -38,6 +38,7 @@ #if defined(_MSC_VER) #pragma warning(push) // Save warning settings. #pragma warning(disable : 4996) // Disable deprecated std::fopen +#include // for CryptAcquireContextA, CryptGenRandom, CryptReleaseContext #endif #ifdef BOOST_NO_STDC_NAMESPACE @@ -78,7 +79,9 @@ seed_rng() : rd_index_(5) , random_(std::fopen( "/dev/urandom", "rb" )) - {} + { + std::memset(rd_, 0, sizeof(rd_)); + } ~seed_rng() { @@ -109,11 +112,12 @@ } private: + BOOST_STATIC_CONSTANT(std::size_t, internal_state_size = 5); inline void ignore_size(size_t) {} static unsigned int * sha1_random_digest_state_() { - static unsigned int state[ 5 ]; + static unsigned int state[ internal_state_size ]; return state; } @@ -121,12 +125,29 @@ { boost::uuids::detail::sha1 sha; - unsigned int * ps = sha1_random_digest_state_(); - unsigned int state[ 5 ]; - std::memcpy( state, ps, sizeof( state ) ); // harmless data race + // intentionally left uninitialized + unsigned char state[ 20 ]; + { +#if defined(BOOST_WINDOWS) + HCRYPTPROV hCryptProv; + if (CryptAcquireContextA(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { + CryptGenRandom(hCryptProv, sizeof(state), state); + } + CryptReleaseContext(hCryptProv, 0); +#endif + if (random_) + { + ignore_size(std::fread( state, 1, sizeof(state), random_ )); + } - sha.process_bytes( (unsigned char const*)state, sizeof( state ) ); + // using an uninitialized buffer[] if fopen or CryptGenRandom fails + // intentional, we rely on its contents being random + sha.process_bytes( state, sizeof( state ) ); + } + + unsigned int * ps = sha1_random_digest_state_(); + sha.process_bytes( ps, internal_state_size * sizeof( unsigned int ) ); sha.process_bytes( (unsigned char const*)&ps, sizeof( ps ) ); { @@ -149,27 +170,13 @@ } { - // intentionally left uninitialized - unsigned char buffer[ 20 ]; - - if(random_) - { - ignore_size(std::fread( buffer, 1, 20, random_ )); - } - - // using an uninitialized buffer[] if fopen fails - // intentional, we rely on its contents being random - sha.process_bytes( buffer, sizeof( buffer ) ); - } - - { - // *p is intentionally left uninitialized - unsigned int * p = new unsigned int; - - sha.process_bytes( (unsigned char const*)p, sizeof( *p ) ); + unsigned int * p = new unsigned int; sha.process_bytes( (unsigned char const*)&p, sizeof( p ) ); - delete p; + + const seed_rng* this_ptr = this; + sha.process_bytes( (unsigned char const*)&this_ptr, sizeof( this_ptr ) ); + sha.process_bytes( (unsigned char const*)&std::rand, sizeof( void(*)() ) ); } sha.process_bytes( (unsigned char const*)rd_, sizeof( rd_ ) );