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
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;
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
00044 class CRYPTOPP_DLL NonblockingRng : public RandomNumberGenerator
00045 {
00046 public:
00047 NonblockingRng();
00048 ~NonblockingRng();
00049 byte GenerateByte();
00050 void GenerateBlock(byte *output, size_t 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
00067 class CRYPTOPP_DLL BlockingRng : public RandomNumberGenerator
00068 {
00069 public:
00070 BlockingRng();
00071 ~BlockingRng();
00072 byte GenerateByte();
00073 void GenerateBlock(byte *output, size_t size);
00074
00075 protected:
00076 int m_fd;
00077 };
00078
00079 #endif
00080
00081 CRYPTOPP_DLL void CRYPTOPP_API OS_GenerateRandomBlock(bool blocking, byte *output, size_t size);
00082
00083
00084
00085 class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool
00086 {
00087 public:
00088
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
00095 template <class BLOCK_CIPHER>
00096 class AutoSeededX917RNG : public RandomNumberGenerator, public NotCopyable
00097 {
00098 public:
00099
00100 explicit AutoSeededX917RNG(bool blocking = false)
00101 {Reseed(blocking);}
00102 void Reseed(bool blocking = false);
00103
00104 void Reseed(const byte *key, size_t keylength, const byte *seed, const byte *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 template <class BLOCK_CIPHER>
00116 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector)
00117 {
00118 m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector));
00119
00120
00121 m_lastBlock.resize(16);
00122 m_rng->GenerateBlock(m_lastBlock, m_lastBlock.size());
00123 m_counter = 0;
00124 m_isDifferent = false;
00125 }
00126
00127 template <class BLOCK_CIPHER>
00128 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking)
00129 {
00130 SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH);
00131 const byte *key;
00132 do
00133 {
00134 OS_GenerateRandomBlock(blocking, seed, seed.size());
00135 key = seed + BLOCK_CIPHER::BLOCKSIZE;
00136 }
00137 while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0);
00138
00139 Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, NULL);
00140 }
00141
00142 template <class BLOCK_CIPHER>
00143 byte AutoSeededX917RNG<BLOCK_CIPHER>::GenerateByte()
00144 {
00145 byte b = m_rng->GenerateByte();
00146
00147
00148 m_isDifferent = m_isDifferent || b != m_lastBlock[m_counter];
00149 m_lastBlock[m_counter] = b;
00150 ++m_counter;
00151 if (m_counter == m_lastBlock.size())
00152 {
00153 if (!m_isDifferent)
00154 throw SelfTestFailure("AutoSeededX917RNG: Continuous random number generator test failed.");
00155 m_counter = 0;
00156 m_isDifferent = false;
00157 }
00158
00159 return b;
00160 }
00161
00162 CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG<DES_EDE3>;
00163
00164 NAMESPACE_END
00165
00166 #endif
00167
00168 #endif