Crypto++  5.6.3
Free C++ class library of cryptographic schemes
osrng.h
Go to the documentation of this file.
1 // osrng.h - written and placed in the public domain by Wei Dai
2 
3 //! \file osrng.h
4 //! \brief Classes for access to the operating system's random number generators
5 
6 #ifndef CRYPTOPP_OSRNG_H
7 #define CRYPTOPP_OSRNG_H
8 
9 #include "config.h"
10 
11 #if !defined(OS_NO_DEPENDENCE) && defined(OS_RNG_AVAILABLE)
12 
13 #include "cryptlib.h"
14 #include "randpool.h"
15 #include "smartptr.h"
16 #include "fips140.h"
17 #include "rng.h"
18 #include "aes.h"
19 #include "sha.h"
20 
21 NAMESPACE_BEGIN(CryptoPP)
22 
23 //! \class OS_RNG_Err
24 //! \brief Exception thrown when an operating system error is encountered
25 class CRYPTOPP_DLL OS_RNG_Err : public Exception
26 {
27 public:
28  //! \brief Constructs an OS_RNG_Err
29  //! \param operation the operation or API call when the error occurs
30  OS_RNG_Err(const std::string &operation);
31 };
32 
33 #ifdef NONBLOCKING_RNG_AVAILABLE
34 
35 #ifdef CRYPTOPP_WIN32_AVAILABLE
36 //! \class MicrosoftCryptoProvider
37 //! \brief Wrapper for Microsoft crypto service provider
38 //! \sa \def USE_MS_CRYPTOAPI, \def USE_MS_CNGAPI, \def WORKAROUND_MS_BUG_Q258000
39 class CRYPTOPP_DLL MicrosoftCryptoProvider
40 {
41 public:
42  //! \brief Construct a MicrosoftCryptoProvider
45 
46 // type HCRYPTPROV and BCRYPT_ALG_HANDLE, avoid #include <windows.h>
47 #if defined(USE_MS_CRYPTOAPI)
48 # if defined(__CYGWIN__) && defined(__x86_64__)
49  typedef unsigned long long ProviderHandle;
50 # elif defined(WIN64) || defined(_WIN64)
51  typedef unsigned __int64 ProviderHandle;
52 # else
53  typedef unsigned long ProviderHandle;
54 # endif
55 #elif defined(USE_MS_CNGAPI)
56  typedef void *PVOID;
57  typedef PVOID ProviderHandle;
58 #endif // USE_MS_CRYPTOAPI or USE_MS_CNGAPI
59 
60  //! \brief Retrieves the provider handle
61  //! \returns CryptoAPI provider handle
62  //! \details If USE_MS_CRYPTOAPI is in effect, then CryptAcquireContext()
63  //! acquires then handle and CryptReleaseContext() releases the handle
64  //! upon destruction. If USE_MS_CNGAPI is in effect, then
65  //! BCryptOpenAlgorithmProvider() acquires then handle and
66  //! BCryptCloseAlgorithmProvider() releases the handle upon destruction.
67  ProviderHandle GetProviderHandle() const {return m_hProvider;}
68 
69 private:
70  ProviderHandle m_hProvider;
71 };
72 
73 #if defined(_MSC_VER) && defined(USE_MS_CRYPTOAPI)
74 # pragma comment(lib, "advapi32.lib")
75 #endif
76 
77 #if defined(_MSC_VER) && defined(USE_MS_CNGAPI)
78 # pragma comment(lib, "bcrypt.lib")
79 #endif
80 
81 #endif //CRYPTOPP_WIN32_AVAILABLE
82 
83 //! \class NonblockingRng
84 //! \brief Wrapper class for /dev/random and /dev/srandom
85 //! \details Encapsulates CryptoAPI's CryptGenRandom() or CryptoNG's BCryptGenRandom()
86 //! on Windows, or /dev/urandom on Unix and compatibles.
87 class CRYPTOPP_DLL NonblockingRng : public RandomNumberGenerator
88 {
89 public:
90  //! \brief Construct a NonblockingRng
92  ~NonblockingRng();
93 
94  //! \brief Generate random array of bytes
95  //! \param output the byte buffer
96  //! \param size the length of the buffer, in bytes
97  //! \details GenerateIntoBufferedTransformation() calls are routed to GenerateBlock().
98  void GenerateBlock(byte *output, size_t size);
99 
100 protected:
101 #ifdef CRYPTOPP_WIN32_AVAILABLE
102  MicrosoftCryptoProvider m_Provider;
103 #else
104  int m_fd;
105 #endif
106 };
107 
108 #endif
109 
110 #if defined(BLOCKING_RNG_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
111 
112 //! \class BlockingRng
113 //! \brief Wrapper class for /dev/random and /dev/srandom
114 //! \details Encapsulates /dev/random on Linux, OS X and Unix; and /dev/srandom on the BSDs.
115 class CRYPTOPP_DLL BlockingRng : public RandomNumberGenerator
116 {
117 public:
118  //! \brief Construct a BlockingRng
119  BlockingRng();
120  ~BlockingRng();
121 
122  //! \brief Generate random array of bytes
123  //! \param output the byte buffer
124  //! \param size the length of the buffer, in bytes
125  //! \details GenerateIntoBufferedTransformation() calls are routed to GenerateBlock().
126  void GenerateBlock(byte *output, size_t size);
127 
128 protected:
129  int m_fd;
130 };
131 
132 #endif
133 
134 //! OS_GenerateRandomBlock
135 //! \brief Generate random array of bytes
136 //! \param blocking specifies whther a bobcking or non-blocking generator should be used
137 //! \param output the byte buffer
138 //! \param size the length of the buffer, in bytes
139 //! \details OS_GenerateRandomBlock() uses the underlying operating system's
140 //! random number generator. On Windows, CryptGenRandom() is called using NonblockingRng.
141 //! \details On Unix and compatibles, /dev/urandom is called if blocking is false using
142 //! NonblockingRng. If blocking is true, then either /dev/randomd or /dev/srandom is used
143 //! by way of BlockingRng, if available.
144 CRYPTOPP_DLL void CRYPTOPP_API OS_GenerateRandomBlock(bool blocking, byte *output, size_t size);
145 
146 
147 //! \class AutoSeededRandomPool
148 //! \brief Automatically Seeded Randomness Pool
149 //! \details This class seeds itself using an operating system provided RNG.
150 //! AutoSeededRandomPool was suggested by Leonard Janke.
151 class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool
152 {
153 public:
154  //! \brief Construct an AutoSeededRandomPool
155  //! \param blocking controls seeding with BlockingRng or NonblockingRng
156  //! \param seedSize the size of the seed, in bytes
157  //! \details Use blocking to choose seeding with BlockingRng or NonblockingRng.
158  //! The parameter is ignored if only one of these is available.
159  explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32)
160  {Reseed(blocking, seedSize);}
161 
162  //! \brief Reseed an AutoSeededRandomPool
163  //! \param blocking controls seeding with BlockingRng or NonblockingRng
164  //! \param seedSize the size of the seed, in bytes
165  void Reseed(bool blocking = false, unsigned int seedSize = 32);
166 };
167 
168 //! \class AutoSeededX917RNG
169 //! \tparam BLOCK_CIPHER a block cipher
170 //! \brief Automatically Seeded X9.17 RNG
171 //! \details AutoSeededX917RNG is from ANSI X9.17 Appendix C, seeded using an OS provided RNG.
172 //! If 3-key TripleDES (DES_EDE3) is used, then its a X9.17 conforming generator. If AES is
173 //! used, then its a X9.31 conforming generator.
174 //! \details Though ANSI X9 prescribes 3-key TripleDES, the template parameter BLOCK_CIPHER can be any
175 //! BlockTransformation derived class.
176 //! \sa X917RNG, DefaultAutoSeededRNG
177 template <class BLOCK_CIPHER>
179 {
180 public:
181  //! \brief Construct an AutoSeededX917RNG
182  //! \param blocking controls seeding with BlockingRng or NonblockingRng
183  //! \param autoSeed controls auto seeding of the generator
184  //! \details Use blocking to choose seeding with BlockingRng or NonblockingRng.
185  //! The parameter is ignored if only one of these is available.
186  //! \sa X917RNG
187  explicit AutoSeededX917RNG(bool blocking = false, bool autoSeed = true)
188  {if (autoSeed) Reseed(blocking);}
189 
190  //! \brief Reseed an AutoSeededX917RNG
191  //! \param blocking controls seeding with BlockingRng or NonblockingRng
192  //! \param additionalEntropy additional entropy to add to the generator
193  //! \param length the size of the additional entropy, in bytes
194  //! \details Internally, the generator uses SHA256 to extract the entropy from
195  //! from the seed and then stretch the material for the block cipher's key
196  //! and initialization vector.
197  void Reseed(bool blocking = false, const byte *additionalEntropy = NULL, size_t length = 0);
198 
199  //! \brief Deterministically reseed an AutoSeededX917RNG for testing
200  //! \param key the key to use for the deterministic reseeding
201  //! \param keylength the size of the key, in bytes
202  //! \param seed the seed to use for the deterministic reseeding
203  //! \param timeVector a time vector to use for deterministic reseeding
204  //! \details This is a testing interface for testing purposes, and should \a NOT
205  //! be used in production.
206  void Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector);
207 
208  bool CanIncorporateEntropy() const {return true;}
209  void IncorporateEntropy(const byte *input, size_t length) {Reseed(false, input, length);}
210  void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
211  {m_rng->GenerateIntoBufferedTransformation(target, channel, length);}
212 
213 private:
215 };
216 
217 template <class BLOCK_CIPHER>
218 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector)
219 {
220  m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector));
221 }
222 
223 template <class BLOCK_CIPHER>
224 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking, const byte *input, size_t length)
225 {
226  SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH);
227  const byte *key;
228  do
229  {
230  OS_GenerateRandomBlock(blocking, seed, seed.size());
231  if (length > 0)
232  {
233  SHA256 hash;
234  hash.Update(seed, seed.size());
235  hash.Update(input, length);
236  hash.TruncatedFinal(seed, UnsignedMin(hash.DigestSize(), seed.size()));
237  }
238  key = seed + BLOCK_CIPHER::BLOCKSIZE;
239  } // check that seed and key don't have same value
240  while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0);
241 
242  Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, NULL);
243 }
244 
245 CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG<AES>;
246 
247 #if defined(CRYPTOPP_DOXYGEN_PROCESSING)
248 //! \class DefaultAutoSeededRNG
249 //! \brief A typedef providing a default generator
250 //! \details DefaultAutoSeededRNG is a typedef of either AutoSeededX917RNG<AES> or AutoSeededRandomPool.
251 //! If CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 is defined, then DefaultAutoSeededRNG is
252 //! AutoSeededX917RNG<AES>. Otherwise, DefaultAutoSeededRNG is AutoSeededRandomPool.
254 #else
255 // AutoSeededX917RNG<AES> in FIPS mode, otherwise it's AutoSeededRandomPool
256 #if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
258 #else
260 #endif
261 #endif // CRYPTOPP_DOXYGEN_PROCESSING
262 
263 NAMESPACE_END
264 
265 #endif
266 
267 #endif
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:139
AutoSeededRandomPool(bool blocking=false, unsigned int seedSize=32)
Construct an AutoSeededRandomPool.
Definition: osrng.h:159
Wrapper for Microsoft crypto service provider.
Definition: osrng.h:39
Randomness Pool.
Definition: randpool.h:25
implements the SHA-256 standard
Definition: sha.h:32
Wrapper class for /dev/random and /dev/srandom.
Definition: osrng.h:87
Class file for Randomness Pool.
void Reseed(bool blocking=false, const byte *additionalEntropy=NULL, size_t length=0)
Reseed an AutoSeededX917RNG.
Definition: osrng.h:224
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: cryptlib.cpp:330
ANSI X9.17 RNG.
Definition: rng.h:48
Abstract base classes that provide a uniform interface to this library.
unsigned int DigestSize() const
Provides the digest size of the hash.
Definition: iterhash.h:85
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:521
Classes for automatic resource management.
Library configuration file.
Interface for random number generators.
Definition: cryptlib.h:1186
SecBlock typedef.
Definition: secblock.h:728
Interface for buffered transformations.
Definition: cryptlib.h:1352
void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
Generate random bytes into a BufferedTransformation.
Definition: osrng.h:210
Exception thrown when an operating system error is encountered.
Definition: osrng.h:25
Automatically Seeded Randomness Pool.
Definition: osrng.h:151
Class file for the AES cipher (Rijndael)
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be neagtive and incorrectly promoted.
Definition: misc.h:503
Miscellaneous classes for RNGs.
Automatically Seeded X9.17 RNG.
Definition: osrng.h:178
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:467
Classes for SHA-1 and SHA-2 family of message digests.
Wrapper class for /dev/random and /dev/srandom.
Definition: osrng.h:115
Classes and functions for the FIPS 140-2 validated library.
bool CanIncorporateEntropy() const
Determines if a generator can accept additional entropy.
Definition: osrng.h:208
void OS_GenerateRandomBlock(bool blocking, byte *output, size_t size)
OS_GenerateRandomBlock.
Definition: osrng.cpp:238
AutoSeededX917RNG(bool blocking=false, bool autoSeed=true)
Construct an AutoSeededX917RNG.
Definition: osrng.h:187
ProviderHandle GetProviderHandle() const
Retrieves the provider handle.
Definition: osrng.h:67
Crypto++ library namespace.
Ensures an object is not copyable.
Definition: misc.h:210
virtual void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
Generate random bytes into a BufferedTransformation.
Definition: cryptlib.cpp:348
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: osrng.h:209
A typedef providing a default generator.
Definition: osrng.h:253