Go to the documentation of this file.00001 #ifndef CRYPTOPP_OSRNG_H
00002 #define CRYPTOPP_OSRNG_H
00003
00004
00005
00006 #include "config.h"
00007
00008 #ifdef OS_RNG_AVAILABLE
00009
00010 #include "randpool.h"
00011 #include "rng.h"
00012 #include "aes.h"
00013 #include "sha.h"
00014 #include "fips140.h"
00015
00016 NAMESPACE_BEGIN(CryptoPP)
00017
00018
00019 class CRYPTOPP_DLL OS_RNG_Err : public Exception
00020 {
00021 public:
00022 OS_RNG_Err(const std::string &operation);
00023 };
00024
00025 #ifdef NONBLOCKING_RNG_AVAILABLE
00026
00027 #ifdef CRYPTOPP_WIN32_AVAILABLE
00028 class CRYPTOPP_DLL MicrosoftCryptoProvider
00029 {
00030 public:
00031 MicrosoftCryptoProvider();
00032 ~MicrosoftCryptoProvider();
00033 #if defined(_WIN64)
00034 typedef unsigned __int64 ProviderHandle;
00035 #else
00036 typedef unsigned long ProviderHandle;
00037 #endif
00038 ProviderHandle GetProviderHandle() const {return m_hProvider;}
00039 private:
00040 ProviderHandle m_hProvider;
00041 };
00042
00043 #pragma comment(lib, "advapi32.lib")
00044 #endif
00045
00046
00047 class CRYPTOPP_DLL NonblockingRng : public RandomNumberGenerator
00048 {
00049 public:
00050 NonblockingRng();
00051 ~NonblockingRng();
00052 void GenerateBlock(byte *output, size_t size);
00053
00054 protected:
00055 #ifdef CRYPTOPP_WIN32_AVAILABLE
00056 # ifndef WORKAROUND_MS_BUG_Q258000
00057 MicrosoftCryptoProvider m_Provider;
00058 # endif
00059 #else
00060 int m_fd;
00061 #endif
00062 };
00063
00064 #endif
00065
00066 #ifdef BLOCKING_RNG_AVAILABLE
00067
00068
00069 class CRYPTOPP_DLL BlockingRng : public RandomNumberGenerator
00070 {
00071 public:
00072 BlockingRng();
00073 ~BlockingRng();
00074 void GenerateBlock(byte *output, size_t size);
00075
00076 protected:
00077 int m_fd;
00078 };
00079
00080 #endif
00081
00082 CRYPTOPP_DLL void CRYPTOPP_API OS_GenerateRandomBlock(bool blocking, byte *output, size_t size);
00083
00084
00085
00086 class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool
00087 {
00088 public:
00089
00090 explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32)
00091 {Reseed(blocking, seedSize);}
00092 void Reseed(bool blocking = false, unsigned int seedSize = 32);
00093 };
00094
00095
00096 template <class BLOCK_CIPHER>
00097 class AutoSeededX917RNG : public RandomNumberGenerator, public NotCopyable
00098 {
00099 public:
00100
00101 explicit AutoSeededX917RNG(bool blocking = false, bool autoSeed = true)
00102 {if (autoSeed) Reseed(blocking);}
00103 void Reseed(bool blocking = false, const byte *additionalEntropy = NULL, size_t length = 0);
00104
00105 void Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector);
00106
00107 bool CanIncorporateEntropy() const {return true;}
00108 void IncorporateEntropy(const byte *input, size_t length) {Reseed(false, input, length);}
00109 void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length) {m_rng->GenerateIntoBufferedTransformation(target, channel, length);}
00110
00111 private:
00112 member_ptr<RandomNumberGenerator> m_rng;
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 template <class BLOCK_CIPHER>
00122 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking, const byte *input, size_t length)
00123 {
00124 SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH);
00125 const byte *key;
00126 do
00127 {
00128 OS_GenerateRandomBlock(blocking, seed, seed.size());
00129 if (length > 0)
00130 {
00131 SHA256 hash;
00132 hash.Update(seed, seed.size());
00133 hash.Update(input, length);
00134 hash.TruncatedFinal(seed, UnsignedMin(hash.DigestSize(), seed.size()));
00135 }
00136 key = seed + BLOCK_CIPHER::BLOCKSIZE;
00137 }
00138 while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0);
00139
00140 Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, NULL);
00141 }
00142
00143 CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG<AES>;
00144
00145
00146 #if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
00147 typedef AutoSeededX917RNG<AES> DefaultAutoSeededRNG;
00148 #else
00149 typedef AutoSeededRandomPool DefaultAutoSeededRNG;
00150 #endif
00151
00152 NAMESPACE_END
00153
00154 #endif
00155
00156 #endif