Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

osrng.h

00001 #ifndef CRYPTOPP_OSRNG_H
00002 #define CRYPTOPP_OSRNG_H
00003 
00004 #include "cryptopp_config.h"
00005 
00006 #ifdef OS_RNG_AVAILABLE
00007 
00008 #include "randpool.h"
00009 #include "rng.h"
00010 
00011 NAMESPACE_BEGIN(CryptoPP)
00012 
00013 //! Exception class for Operating-System Random Number Generator.
00014 class OS_RNG_Err : public Exception
00015 {
00016 public:
00017         OS_RNG_Err(const std::string &operation);
00018 };
00019 
00020 #ifdef NONBLOCKING_RNG_AVAILABLE
00021 
00022 #ifdef CRYPTOPP_WIN32_AVAILABLE
00023 class MicrosoftCryptoProvider
00024 {
00025 public:
00026         MicrosoftCryptoProvider();
00027         ~MicrosoftCryptoProvider();
00028 #if defined(_WIN64)
00029         typedef unsigned __int64 ProviderHandle;        // type HCRYPTPROV, avoid #include <windows.h>
00030 #else
00031         typedef unsigned long ProviderHandle;
00032 #endif
00033         ProviderHandle GetProviderHandle() const {return m_hProvider;}
00034 private:
00035         ProviderHandle m_hProvider;
00036 };
00037 #endif
00038 
00039 //! encapsulate CryptoAPI's CryptGenRandom or /dev/urandom
00040 class NonblockingRng : public RandomNumberGenerator
00041 {
00042 public:
00043         NonblockingRng();
00044         ~NonblockingRng();
00045         byte GenerateByte();
00046         void GenerateBlock(byte *output, unsigned int size);
00047 
00048 protected:
00049 #ifdef CRYPTOPP_WIN32_AVAILABLE
00050 #       ifndef WORKAROUND_MS_BUG_Q258000
00051                 MicrosoftCryptoProvider m_Provider;
00052 #       endif
00053 #else
00054         int m_fd;
00055 #endif
00056 };
00057 
00058 #endif
00059 
00060 #ifdef BLOCKING_RNG_AVAILABLE
00061 
00062 //! encapsulate /dev/random
00063 class BlockingRng : public RandomNumberGenerator
00064 {
00065 public:
00066         BlockingRng();
00067         ~BlockingRng();
00068         byte GenerateByte();
00069         void GenerateBlock(byte *output, unsigned int size);
00070 
00071 protected:
00072         int m_fd;
00073 };
00074 
00075 #endif
00076 
00077 void OS_GenerateRandomBlock(bool blocking, byte *output, unsigned int size);
00078 
00079 //! Automaticly Seeded Randomness Pool
00080 /*! This class seeds itself using an operating system provided RNG. */
00081 class AutoSeededRandomPool : public RandomPool
00082 {
00083 public:
00084         //! blocking will be ignored if the prefered RNG isn't available
00085         explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32)
00086                 {Reseed(blocking, seedSize);}
00087         void Reseed(bool blocking = false, unsigned int seedSize = 32);
00088 };
00089 
00090 //! RNG from ANSI X9.17 Appendix C, seeded using an OS provided RNG
00091 template <class BLOCK_CIPHER>
00092 class AutoSeededX917RNG : public RandomNumberGenerator
00093 {
00094 public:
00095         //! blocking will be ignored if the prefered RNG isn't available
00096         explicit AutoSeededX917RNG(bool blocking = false)
00097                 {Reseed(blocking);}
00098         void Reseed(bool blocking = false);
00099         // exposed for testing
00100         void Reseed(const byte *key, unsigned int keylength, const byte *seed, unsigned long timeVector);
00101 
00102         byte GenerateByte();
00103 
00104 private:
00105         member_ptr<RandomNumberGenerator> m_rng;
00106         SecByteBlock m_lastBlock;
00107         bool m_isDifferent;
00108         unsigned int m_counter;
00109 };
00110 
00111 template <class BLOCK_CIPHER>
00112 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, unsigned int keylength, const byte *seed, unsigned long timeVector)
00113 {
00114         m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector));
00115 
00116         // for FIPS 140-2
00117         m_lastBlock.resize(16);
00118         m_rng->GenerateBlock(m_lastBlock, m_lastBlock.size());
00119         m_counter = 0;
00120         m_isDifferent = false;
00121 }
00122 
00123 template <class BLOCK_CIPHER>
00124 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking)
00125 {
00126         SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH);
00127         const byte *key;
00128         do
00129         {
00130                 OS_GenerateRandomBlock(blocking, seed, seed.size());
00131                 key = seed + BLOCK_CIPHER::BLOCKSIZE;
00132         }       // check that seed and key don't have same value
00133         while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0);
00134 
00135         Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, 0);
00136 }
00137 
00138 template <class BLOCK_CIPHER>
00139 byte AutoSeededX917RNG<BLOCK_CIPHER>::GenerateByte()
00140 {
00141         byte b = m_rng->GenerateByte();
00142 
00143         // for FIPS 140-2
00144         m_isDifferent = m_isDifferent || b != m_lastBlock[m_counter];
00145         m_lastBlock[m_counter] = b;
00146         ++m_counter;
00147         if (m_counter == m_lastBlock.size())
00148         {
00149                 if (!m_isDifferent)
00150                         throw SelfTestFailure("AutoSeededX917RNG: Continuous random number generator test failed.");
00151                 m_counter = 0;
00152                 m_isDifferent = false;
00153         }
00154 
00155         return b;
00156 }
00157 
00158 NAMESPACE_END
00159 
00160 #endif
00161 
00162 #endif

Generated on Sun Mar 14 20:44:27 2004 for Crypto++ by doxygen 1.3.6-20040222