00001
00002
00003
00004
00005
00006
00007 #ifndef CRYPTOPP_OSRNG_H
00008 #define CRYPTOPP_OSRNG_H
00009
00010 #include "config.h"
00011
00012 #ifdef OS_RNG_AVAILABLE
00013
00014 #include "cryptlib.h"
00015 #include "randpool.h"
00016 #include "smartptr.h"
00017 #include "fips140.h"
00018 #include "rng.h"
00019 #include "aes.h"
00020 #include "sha.h"
00021
00022 NAMESPACE_BEGIN(CryptoPP)
00023
00024
00025
00026 class CRYPTOPP_DLL OS_RNG_Err : public Exception
00027 {
00028 public:
00029
00030
00031 OS_RNG_Err(const std::string &operation);
00032 };
00033
00034 #ifdef NONBLOCKING_RNG_AVAILABLE
00035
00036 #ifdef CRYPTOPP_WIN32_AVAILABLE
00037
00038
00039
00040 class CRYPTOPP_DLL MicrosoftCryptoProvider
00041 {
00042 public:
00043
00044 MicrosoftCryptoProvider();
00045 ~MicrosoftCryptoProvider();
00046
00047
00048 #if defined(__CYGWIN__) && defined(__x86_64__)
00049 typedef unsigned long long ProviderHandle;
00050 #elif defined(WIN64) || defined(_WIN64)
00051 typedef unsigned __int64 ProviderHandle;
00052 #else
00053 typedef unsigned long ProviderHandle;
00054 #endif
00055
00056
00057
00058
00059
00060 ProviderHandle GetProviderHandle() const {return m_hProvider;}
00061
00062 private:
00063 ProviderHandle m_hProvider;
00064 };
00065
00066 #if defined(_MSC_VER)
00067 # pragma comment(lib, "advapi32.lib")
00068 #endif
00069
00070 #endif //CRYPTOPP_WIN32_AVAILABLE
00071
00072
00073
00074
00075 class CRYPTOPP_DLL NonblockingRng : public RandomNumberGenerator
00076 {
00077 public:
00078
00079 NonblockingRng();
00080 ~NonblockingRng();
00081
00082
00083
00084
00085
00086 void GenerateBlock(byte *output, size_t size);
00087
00088 protected:
00089 #ifdef CRYPTOPP_WIN32_AVAILABLE
00090 # ifndef WORKAROUND_MS_BUG_Q258000
00091 MicrosoftCryptoProvider m_Provider;
00092 # endif
00093 #else
00094 int m_fd;
00095 #endif
00096 };
00097
00098 #endif
00099
00100 #if defined(BLOCKING_RNG_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
00101
00102
00103
00104
00105 class CRYPTOPP_DLL BlockingRng : public RandomNumberGenerator
00106 {
00107 public:
00108
00109 BlockingRng();
00110 ~BlockingRng();
00111
00112
00113
00114
00115
00116 void GenerateBlock(byte *output, size_t size);
00117
00118 protected:
00119 int m_fd;
00120 };
00121
00122 #endif
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 CRYPTOPP_DLL void CRYPTOPP_API OS_GenerateRandomBlock(bool blocking, byte *output, size_t size);
00135
00136
00137
00138
00139
00140 class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool
00141 {
00142 public:
00143
00144
00145
00146
00147
00148 explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32)
00149 {Reseed(blocking, seedSize);}
00150
00151
00152
00153
00154 void Reseed(bool blocking = false, unsigned int seedSize = 32);
00155 };
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 template <class BLOCK_CIPHER>
00167 class AutoSeededX917RNG : public RandomNumberGenerator, public NotCopyable
00168 {
00169 public:
00170
00171
00172
00173
00174
00175
00176 explicit AutoSeededX917RNG(bool blocking = false, bool autoSeed = true)
00177 {if (autoSeed) Reseed(blocking);}
00178
00179
00180
00181
00182
00183
00184
00185
00186 void Reseed(bool blocking = false, const byte *additionalEntropy = NULL, size_t length = 0);
00187
00188
00189
00190
00191
00192
00193
00194
00195 void Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector);
00196
00197 bool CanIncorporateEntropy() const {return true;}
00198 void IncorporateEntropy(const byte *input, size_t length) {Reseed(false, input, length);}
00199 void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
00200 {m_rng->GenerateIntoBufferedTransformation(target, channel, length);}
00201
00202 private:
00203 member_ptr<RandomNumberGenerator> m_rng;
00204 };
00205
00206 template <class BLOCK_CIPHER>
00207 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector)
00208 {
00209 m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector));
00210 }
00211
00212 template <class BLOCK_CIPHER>
00213 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking, const byte *input, size_t length)
00214 {
00215 SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH);
00216 const byte *key;
00217 do
00218 {
00219 OS_GenerateRandomBlock(blocking, seed, seed.size());
00220 if (length > 0)
00221 {
00222 SHA256 hash;
00223 hash.Update(seed, seed.size());
00224 hash.Update(input, length);
00225 hash.TruncatedFinal(seed, UnsignedMin(hash.DigestSize(), seed.size()));
00226 }
00227 key = seed + BLOCK_CIPHER::BLOCKSIZE;
00228 }
00229 while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0);
00230
00231 Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, NULL);
00232 }
00233
00234 CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG<AES>;
00235
00236 #if defined(CRYPTOPP_DOXYGEN_PROCESSING)
00237
00238
00239
00240
00241
00242 class DefaultAutoSeededRNG {}
00243 #else
00244
00245 #if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
00246 typedef AutoSeededX917RNG<AES> DefaultAutoSeededRNG;
00247 #else
00248 typedef AutoSeededRandomPool DefaultAutoSeededRNG;
00249 #endif
00250 #endif // CRYPTOPP_DOXYGEN_PROCESSING
00251
00252 NAMESPACE_END
00253
00254 #endif
00255
00256 #endif