- Main Page
- Namespaces
- Classes
- Files

# 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