• 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

Generated on Mon Aug 9 2010 15:56:35 for Crypto++ by  doxygen 1.7.1