Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

osrng.h

00001 #ifndef CRYPTOPP_OSRNG_H 00002 #define CRYPTOPP_OSRNG_H 00003 00004 #include "cryptopp_config.h" 00005 00006 #ifdef OS_RNG_AVAILABLE 00007 00008 #include "randpool.h" 00009 #include "rng.h" 00010 00011 NAMESPACE_BEGIN(CryptoPP) 00012 00013 //! Exception class for Operating-System Random Number Generator. 00014 class OS_RNG_Err : public Exception 00015 { 00016 public: 00017 OS_RNG_Err(const std::string &operation); 00018 }; 00019 00020 #ifdef NONBLOCKING_RNG_AVAILABLE 00021 00022 #ifdef CRYPTOPP_WIN32_AVAILABLE 00023 class MicrosoftCryptoProvider 00024 { 00025 public: 00026 MicrosoftCryptoProvider(); 00027 ~MicrosoftCryptoProvider(); 00028 #if defined(_WIN64) 00029 typedef unsigned __int64 ProviderHandle; // type HCRYPTPROV, avoid #include <windows.h> 00030 #else 00031 typedef unsigned long ProviderHandle; 00032 #endif 00033 ProviderHandle GetProviderHandle() const {return m_hProvider;} 00034 private: 00035 ProviderHandle m_hProvider; 00036 }; 00037 #endif 00038 00039 //! encapsulate CryptoAPI's CryptGenRandom or /dev/urandom 00040 class NonblockingRng : public RandomNumberGenerator 00041 { 00042 public: 00043 NonblockingRng(); 00044 ~NonblockingRng(); 00045 byte GenerateByte(); 00046 void GenerateBlock(byte *output, unsigned int size); 00047 00048 protected: 00049 #ifdef CRYPTOPP_WIN32_AVAILABLE 00050 # ifndef WORKAROUND_MS_BUG_Q258000 00051 MicrosoftCryptoProvider m_Provider; 00052 # endif 00053 #else 00054 int m_fd; 00055 #endif 00056 }; 00057 00058 #endif 00059 00060 #ifdef BLOCKING_RNG_AVAILABLE 00061 00062 //! encapsulate /dev/random 00063 class BlockingRng : public RandomNumberGenerator 00064 { 00065 public: 00066 BlockingRng(); 00067 ~BlockingRng(); 00068 byte GenerateByte(); 00069 void GenerateBlock(byte *output, unsigned int size); 00070 00071 protected: 00072 int m_fd; 00073 }; 00074 00075 #endif 00076 00077 void OS_GenerateRandomBlock(bool blocking, byte *output, unsigned int size); 00078 00079 //! Automaticly Seeded Randomness Pool 00080 /*! This class seeds itself using an operating system provided RNG. */ 00081 class AutoSeededRandomPool : public RandomPool 00082 { 00083 public: 00084 //! blocking will be ignored if the prefered RNG isn't available 00085 explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32) 00086 {Reseed(blocking, seedSize);} 00087 void Reseed(bool blocking = false, unsigned int seedSize = 32); 00088 }; 00089 00090 //! RNG from ANSI X9.17 Appendix C, seeded using an OS provided RNG 00091 template <class BLOCK_CIPHER> 00092 class AutoSeededX917RNG : public RandomNumberGenerator 00093 { 00094 public: 00095 //! blocking will be ignored if the prefered RNG isn't available 00096 explicit AutoSeededX917RNG(bool blocking = false) 00097 {Reseed(blocking);} 00098 void Reseed(bool blocking = false); 00099 // exposed for testing 00100 void Reseed(const byte *key, unsigned int keylength, const byte *seed, unsigned long timeVector); 00101 00102 byte GenerateByte(); 00103 00104 private: 00105 member_ptr<RandomNumberGenerator> m_rng; 00106 SecByteBlock m_lastBlock; 00107 bool m_isDifferent; 00108 unsigned int m_counter; 00109 }; 00110 00111 template <class BLOCK_CIPHER> 00112 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, unsigned int keylength, const byte *seed, unsigned long timeVector) 00113 { 00114 m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector)); 00115 00116 // for FIPS 140-2 00117 m_lastBlock.resize(16); 00118 m_rng->GenerateBlock(m_lastBlock, m_lastBlock.size()); 00119 m_counter = 0; 00120 m_isDifferent = false; 00121 } 00122 00123 template <class BLOCK_CIPHER> 00124 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking) 00125 { 00126 SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH); 00127 const byte *key; 00128 do 00129 { 00130 OS_GenerateRandomBlock(blocking, seed, seed.size()); 00131 key = seed + BLOCK_CIPHER::BLOCKSIZE; 00132 } // check that seed and key don't have same value 00133 while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0); 00134 00135 Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, 0); 00136 } 00137 00138 template <class BLOCK_CIPHER> 00139 byte AutoSeededX917RNG<BLOCK_CIPHER>::GenerateByte() 00140 { 00141 byte b = m_rng->GenerateByte(); 00142 00143 // for FIPS 140-2 00144 m_isDifferent = m_isDifferent || b != m_lastBlock[m_counter]; 00145 m_lastBlock[m_counter] = b; 00146 ++m_counter; 00147 if (m_counter == m_lastBlock.size()) 00148 { 00149 if (!m_isDifferent) 00150 throw SelfTestFailure("AutoSeededX917RNG: Continuous random number generator test failed."); 00151 m_counter = 0; 00152 m_isDifferent = false; 00153 } 00154 00155 return b; 00156 } 00157 00158 NAMESPACE_END 00159 00160 #endif 00161 00162 #endif

Generated on Wed Jul 28 08:07:08 2004 for Crypto++ by doxygen 1.3.7