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

osrng.h

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

Generated on Wed Jul 21 19:15:30 2004 for Crypto++ by doxygen 1.3.7-20040704