From cdd57fd49c847250ce5d8e3cc39b7d882a529fc3 Mon Sep 17 00:00:00 2001 From: weidai Date: Fri, 4 May 2007 15:04:58 +0000 Subject: reduce risk of random number reuse after VM rollback git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@328 57ff6487-cd31-0410-9ec3-f628ee90f5f0 --- osrng.h | 54 +++++++++++++++++++----------------------------------- 1 file changed, 19 insertions(+), 35 deletions(-) (limited to 'osrng.h') diff --git a/osrng.h b/osrng.h index 448a905..2fa9713 100644 --- a/osrng.h +++ b/osrng.h @@ -7,7 +7,7 @@ #include "randpool.h" #include "rng.h" -#include "des.h" +#include "aes.h" #include "fips140.h" NAMESPACE_BEGIN(CryptoPP) @@ -46,7 +46,6 @@ class CRYPTOPP_DLL NonblockingRng : public RandomNumberGenerator public: NonblockingRng(); ~NonblockingRng(); - byte GenerateByte(); void GenerateBlock(byte *output, size_t size); protected: @@ -69,7 +68,6 @@ class CRYPTOPP_DLL BlockingRng : public RandomNumberGenerator public: BlockingRng(); ~BlockingRng(); - byte GenerateByte(); void GenerateBlock(byte *output, size_t size); protected: @@ -99,39 +97,39 @@ public: //! use blocking to choose seeding with BlockingRng or NonblockingRng. the parameter is ignored if only one of these is available explicit AutoSeededX917RNG(bool blocking = false) {Reseed(blocking);} - void Reseed(bool blocking = false); + void Reseed(bool blocking = false, const byte *additionalEntropy = NULL, size_t length = 0); // exposed for testing void Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector); - byte GenerateByte(); + bool CanIncorporateEntropy() const {return true;} + void IncorporateEntropy(const byte *input, size_t length) {Reseed(false, input, length);} + void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length) {m_rng->GenerateIntoBufferedTransformation(target, channel, length);} private: member_ptr m_rng; - SecByteBlock m_lastBlock; - bool m_isDifferent; - unsigned int m_counter; }; template void AutoSeededX917RNG::Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector) { m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector)); - - // for FIPS 140-2 - m_lastBlock.resize(16); - m_rng->GenerateBlock(m_lastBlock, m_lastBlock.size()); - m_counter = 0; - m_isDifferent = false; } template -void AutoSeededX917RNG::Reseed(bool blocking) +void AutoSeededX917RNG::Reseed(bool blocking, const byte *input, size_t length) { SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH); const byte *key; do { OS_GenerateRandomBlock(blocking, seed, seed.size()); + if (length > 0) + { + SHA256 hash; + hash.Update(seed, seed.size()); + hash.Update(input, length); + hash.TruncatedFinal(seed, UnsignedMin(hash.DigestSize(), seed.size())); + } key = seed + BLOCK_CIPHER::BLOCKSIZE; } // check that seed and key don't have same value while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0); @@ -139,27 +137,13 @@ void AutoSeededX917RNG::Reseed(bool blocking) Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, NULL); } -template -byte AutoSeededX917RNG::GenerateByte() -{ - byte b = m_rng->GenerateByte(); - - // for FIPS 140-2 - m_isDifferent = m_isDifferent || b != m_lastBlock[m_counter]; - m_lastBlock[m_counter] = b; - ++m_counter; - if (m_counter == m_lastBlock.size()) - { - if (!m_isDifferent) - throw SelfTestFailure("AutoSeededX917RNG: Continuous random number generator test failed."); - m_counter = 0; - m_isDifferent = false; - } +CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG; - return b; -} - -CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG; +#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 +typedef AutoSeededX917RNG DefaultAutoSeededRNG; +#else +typedef AutoSeededRandomPool DefaultAutoSeededRNG; +#endif NAMESPACE_END -- cgit v1.2.1