Crypto++

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

osrng.h
Go to the documentation of this file.

    00001 #ifndef CRYPTOPP_OSRNG_H
    00002 #define CRYPTOPP_OSRNG_H
    00003
    00004 //! \file
    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 //! Exception class for Operating-System Random Number Generator.
    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;    // type HCRYPTPROV, avoid #include <windows.h>
    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 //! encapsulate CryptoAPI's CryptGenRandom or /dev/urandom
    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 //! encapsulate /dev/random, or /dev/srandom on OpenBSD
    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 //! Automaticly Seeded Randomness Pool
    00085 /*! This class seeds itself using an operating system provided RNG. */
    00086 class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool
    00087 {
    00088 public:
    00089     //! use blocking to choose seeding with BlockingRng or NonblockingRng. the parameter is ignored if only one of these is available
    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 //! RNG from ANSI X9.17 Appendix C, seeded using an OS provided RNG
    00096 template <class BLOCK_CIPHER>
    00097 class AutoSeededX917RNG : public RandomNumberGenerator, public NotCopyable
    00098 {
    00099 public:
    00100     //! use blocking to choose seeding with BlockingRng or NonblockingRng. the parameter is ignored if only one of these is available
    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     // exposed for testing
    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     }   // check that seed and key don't have same value
    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 //! this is AutoSeededX917RNG<AES> in FIPS mode, otherwise it's AutoSeededRandomPool
    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