• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • 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 "aes.h"
00011 #include "sha.h"
00012 #include "fips140.h"
00013 
00014 NAMESPACE_BEGIN(CryptoPP)
00015 
00016 //! Exception class for Operating-System Random Number Generator.
00017 class CRYPTOPP_DLL OS_RNG_Err : public Exception
00018 {
00019 public:
00020     OS_RNG_Err(const std::string &operation);
00021 };
00022 
00023 #ifdef NONBLOCKING_RNG_AVAILABLE
00024 
00025 #ifdef CRYPTOPP_WIN32_AVAILABLE
00026 class CRYPTOPP_DLL MicrosoftCryptoProvider
00027 {
00028 public:
00029     MicrosoftCryptoProvider();
00030     ~MicrosoftCryptoProvider();
00031 #if defined(_WIN64)
00032     typedef unsigned __int64 ProviderHandle;    // type HCRYPTPROV, avoid #include <windows.h>
00033 #else
00034     typedef unsigned long ProviderHandle;
00035 #endif
00036     ProviderHandle GetProviderHandle() const {return m_hProvider;}
00037 private:
00038     ProviderHandle m_hProvider;
00039 };
00040 
00041 #pragma comment(lib, "advapi32.lib")
00042 #endif
00043 
00044 //! encapsulate CryptoAPI's CryptGenRandom or /dev/urandom
00045 class CRYPTOPP_DLL NonblockingRng : public RandomNumberGenerator
00046 {
00047 public:
00048     NonblockingRng();
00049     ~NonblockingRng();
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 //! encapsulate /dev/random, or /dev/srandom on OpenBSD
00067 class CRYPTOPP_DLL BlockingRng : public RandomNumberGenerator
00068 {
00069 public:
00070     BlockingRng();
00071     ~BlockingRng();
00072     void GenerateBlock(byte *output, size_t size);
00073 
00074 protected:
00075     int m_fd;
00076 };
00077 
00078 #endif
00079 
00080 CRYPTOPP_DLL void CRYPTOPP_API OS_GenerateRandomBlock(bool blocking, byte *output, size_t size);
00081 
00082 //! Automaticly Seeded Randomness Pool
00083 /*! This class seeds itself using an operating system provided RNG. */
00084 class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool
00085 {
00086 public:
00087     //! use blocking to choose seeding with BlockingRng or NonblockingRng. the parameter is ignored if only one of these is available
00088     explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32)
00089         {Reseed(blocking, seedSize);}
00090     void Reseed(bool blocking = false, unsigned int seedSize = 32);
00091 };
00092 
00093 //! RNG from ANSI X9.17 Appendix C, seeded using an OS provided RNG
00094 template <class BLOCK_CIPHER>
00095 class AutoSeededX917RNG : public RandomNumberGenerator, public NotCopyable
00096 {
00097 public:
00098     //! use blocking to choose seeding with BlockingRng or NonblockingRng. the parameter is ignored if only one of these is available
00099     explicit AutoSeededX917RNG(bool blocking = false)
00100         {Reseed(blocking);}
00101     void Reseed(bool blocking = false, const byte *additionalEntropy = NULL, size_t length = 0);
00102     // exposed for testing
00103     void Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector);
00104 
00105     bool CanIncorporateEntropy() const {return true;}
00106     void IncorporateEntropy(const byte *input, size_t length) {Reseed(false, input, length);}
00107     void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length) {m_rng->GenerateIntoBufferedTransformation(target, channel, length);}
00108 
00109 private:
00110     member_ptr<RandomNumberGenerator> m_rng;
00111 };
00112 
00113 template <class BLOCK_CIPHER>
00114 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector)
00115 {
00116     m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector));
00117 }
00118 
00119 template <class BLOCK_CIPHER>
00120 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking, const byte *input, size_t length)
00121 {
00122     SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH);
00123     const byte *key;
00124     do
00125     {
00126         OS_GenerateRandomBlock(blocking, seed, seed.size());
00127         if (length > 0)
00128         {
00129             SHA256 hash;
00130             hash.Update(seed, seed.size());
00131             hash.Update(input, length);
00132             hash.TruncatedFinal(seed, UnsignedMin(hash.DigestSize(), seed.size()));
00133         }
00134         key = seed + BLOCK_CIPHER::BLOCKSIZE;
00135     }   // check that seed and key don't have same value
00136     while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0);
00137 
00138     Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, NULL);
00139 }
00140 
00141 CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG<AES>;
00142 
00143 #if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
00144 typedef AutoSeededX917RNG<AES> DefaultAutoSeededRNG;
00145 #else
00146 typedef AutoSeededRandomPool DefaultAutoSeededRNG;
00147 #endif
00148 
00149 NAMESPACE_END
00150 
00151 #endif
00152 
00153 #endif

Generated on Sun Jul 25 2010 14:44:11 for Crypto++ by  doxygen 1.7.1