Crypto++  5.6.5
Free C++ class library of cryptographic schemes
osrng.h
Go to the documentation of this file.
1 // osrng.h - originally 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(NO_OS_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  CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "NonblockingRng"; }
91 
92  ~NonblockingRng();
93 
94  //! \brief Construct a NonblockingRng
96 
97  //! \brief Generate random array of bytes
98  //! \param output the byte buffer
99  //! \param size the length of the buffer, in bytes
100  //! \details GenerateIntoBufferedTransformation() calls are routed to GenerateBlock().
101  void GenerateBlock(byte *output, size_t size);
102 
103 protected:
104 #ifdef CRYPTOPP_WIN32_AVAILABLE
105  MicrosoftCryptoProvider m_Provider;
106 #else
107  int m_fd;
108 #endif
109 };
110 
111 #endif
112 
113 #if defined(BLOCKING_RNG_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
114 
115 //! \class BlockingRng
116 //! \brief Wrapper class for /dev/random and /dev/srandom
117 //! \details Encapsulates /dev/random on Linux, OS X and Unix; and /dev/srandom on the BSDs.
118 class CRYPTOPP_DLL BlockingRng : public RandomNumberGenerator
119 {
120 public:
121  CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "BlockingRng"; }
122 
123  ~BlockingRng();
124 
125  //! \brief Construct a BlockingRng
126  BlockingRng();
127 
128  //! \brief Generate random array of bytes
129  //! \param output the byte buffer
130  //! \param size the length of the buffer, in bytes
131  //! \details GenerateIntoBufferedTransformation() calls are routed to GenerateBlock().
132  void GenerateBlock(byte *output, size_t size);
133 
134 protected:
135  int m_fd;
136 };
137 
138 #endif
139 
140 //! OS_GenerateRandomBlock
141 //! \brief Generate random array of bytes
142 //! \param blocking specifies whther a bobcking or non-blocking generator should be used
143 //! \param output the byte buffer
144 //! \param size the length of the buffer, in bytes
145 //! \details OS_GenerateRandomBlock() uses the underlying operating system's
146 //! random number generator. On Windows, CryptGenRandom() is called using NonblockingRng.
147 //! \details On Unix and compatibles, /dev/urandom is called if blocking is false using
148 //! NonblockingRng. If blocking is true, then either /dev/randomd or /dev/srandom is used
149 //! by way of BlockingRng, if available.
150 CRYPTOPP_DLL void CRYPTOPP_API OS_GenerateRandomBlock(bool blocking, byte *output, size_t size);
151 
152 //! \class AutoSeededRandomPool
153 //! \brief Automatically Seeded Randomness Pool
154 //! \details This class seeds itself using an operating system provided RNG.
155 //! AutoSeededRandomPool was suggested by Leonard Janke.
156 class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool
157 {
158 public:
159  CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "AutoSeededRandomPool"; }
160 
162 
163  //! \brief Construct an AutoSeededRandomPool
164  //! \param blocking controls seeding with BlockingRng or NonblockingRng
165  //! \param seedSize the size of the seed, in bytes
166  //! \details Use blocking to choose seeding with BlockingRng or NonblockingRng.
167  //! The parameter is ignored if only one of these is available.
168  explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32)
169  {Reseed(blocking, seedSize);}
170 
171  //! \brief Reseed an AutoSeededRandomPool
172  //! \param blocking controls seeding with BlockingRng or NonblockingRng
173  //! \param seedSize the size of the seed, in bytes
174  void Reseed(bool blocking = false, unsigned int seedSize = 32);
175 };
176 
177 //! \class AutoSeededX917RNG
178 //! \tparam BLOCK_CIPHER a block cipher
179 //! \brief Automatically Seeded X9.17 RNG
180 //! \details AutoSeededX917RNG is from ANSI X9.17 Appendix C, seeded using an OS provided RNG.
181 //! If 3-key TripleDES (DES_EDE3) is used, then its a X9.17 conforming generator. If AES is
182 //! used, then its a X9.31 conforming generator.
183 //! \details Though ANSI X9 prescribes 3-key TripleDES, the template parameter BLOCK_CIPHER can be any
184 //! BlockTransformation derived class.
185 //! \sa X917RNG, DefaultAutoSeededRNG
186 template <class BLOCK_CIPHER>
188 {
189 public:
190  static std::string StaticAlgorithmName() { return std::string("AutoSeededX917RNG(") + BLOCK_CIPHER::StaticAlgorithmName() + std::string(")"); }
191 
192  ~AutoSeededX917RNG() {}
193 
194  //! \brief Construct an AutoSeededX917RNG
195  //! \param blocking controls seeding with BlockingRng or NonblockingRng
196  //! \param autoSeed controls auto seeding of the generator
197  //! \details Use blocking to choose seeding with BlockingRng or NonblockingRng.
198  //! The parameter is ignored if only one of these is available.
199  //! \sa X917RNG
200  explicit AutoSeededX917RNG(bool blocking = false, bool autoSeed = true)
201  {if (autoSeed) Reseed(blocking);}
202 
203  //! \brief Reseed an AutoSeededX917RNG
204  //! \param blocking controls seeding with BlockingRng or NonblockingRng
205  //! \param additionalEntropy additional entropy to add to the generator
206  //! \param length the size of the additional entropy, in bytes
207  //! \details Internally, the generator uses SHA256 to extract the entropy from
208  //! from the seed and then stretch the material for the block cipher's key
209  //! and initialization vector.
210  void Reseed(bool blocking = false, const byte *additionalEntropy = NULLPTR, size_t length = 0);
211 
212  //! \brief Deterministically reseed an AutoSeededX917RNG for testing
213  //! \param key the key to use for the deterministic reseeding
214  //! \param keylength the size of the key, in bytes
215  //! \param seed the seed to use for the deterministic reseeding
216  //! \param timeVector a time vector to use for deterministic reseeding
217  //! \details This is a testing interface for testing purposes, and should \a NOT
218  //! be used in production.
219  void Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector);
220 
221  bool CanIncorporateEntropy() const {return true;}
222  void IncorporateEntropy(const byte *input, size_t length) {Reseed(false, input, length);}
223  void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
224  {m_rng->GenerateIntoBufferedTransformation(target, channel, length);}
225 
226 private:
228 };
229 
230 template <class BLOCK_CIPHER>
231 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector)
232 {
233  m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector));
234 }
235 
236 template <class BLOCK_CIPHER>
237 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking, const byte *input, size_t length)
238 {
239  SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH);
240  const byte *key;
241  do
242  {
243  OS_GenerateRandomBlock(blocking, seed, seed.size());
244  if (length > 0)
245  {
246  SHA256 hash;
247  hash.Update(seed, seed.size());
248  hash.Update(input, length);
249  hash.TruncatedFinal(seed, UnsignedMin(hash.DigestSize(), seed.size()));
250  }
251  key = seed + BLOCK_CIPHER::BLOCKSIZE;
252  } // check that seed and key don't have same value
253  while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0);
254 
255  Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, NULLPTR);
256 }
257 
258 CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG<AES>;
259 
260 #if defined(CRYPTOPP_DOXYGEN_PROCESSING)
261 //! \class DefaultAutoSeededRNG
262 //! \brief A typedef providing a default generator
263 //! \details DefaultAutoSeededRNG is a typedef of either AutoSeededX917RNG<AES> or AutoSeededRandomPool.
264 //! If CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 is defined, then DefaultAutoSeededRNG is
265 //! AutoSeededX917RNG<AES>. Otherwise, DefaultAutoSeededRNG is AutoSeededRandomPool.
267 #else
268 // AutoSeededX917RNG<AES> in FIPS mode, otherwise it's AutoSeededRandomPool
269 #if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
271 #else
273 #endif
274 #endif // CRYPTOPP_DOXYGEN_PROCESSING
275 
276 NAMESPACE_END
277 
278 #endif
279 
280 #endif
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:150
AutoSeededRandomPool(bool blocking=false, unsigned int seedSize=32)
Construct an AutoSeededRandomPool.
Definition: osrng.h:168
Wrapper for Microsoft crypto service provider.
Definition: osrng.h:39
Randomness Pool based on AES-256.
Definition: randpool.h:49
SHA-256 message digest.
Definition: sha.h:40
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:237
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: cryptlib.cpp:298
ANSI X9.17 RNG.
Definition: rng.h:48
bool CanIncorporateEntropy() const
Determines if a generator can accept additional entropy.
Definition: osrng.h:221
Abstract base classes that provide a uniform interface to this library.
Classes for automatic resource management.
Library configuration file.
void Update(const byte *input, size_t length)
Updates a hash with additional input.
Definition: iterhash.cpp:13
Interface for random number generators.
Definition: cryptlib.h:1188
SecBlock<byte> typedef.
Definition: secblock.h:810
Interface for buffered transformations.
Definition: cryptlib.h:1343
void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
Generate random bytes into a BufferedTransformation.
Definition: osrng.h:223
Exception thrown when an operating system error is encountered.
Definition: osrng.h:25
Automatically Seeded Randomness Pool.
Definition: osrng.h:156
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:552
unsigned int DigestSize() const
Provides the digest size of the hash.
Definition: iterhash.h:161
Miscellaneous classes for RNGs.
Automatically Seeded X9.17 RNG.
Definition: osrng.h:187
void TruncatedFinal(byte *digest, size_t digestSize)
Computes the hash of the current message.
Definition: iterhash.cpp:129
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:514
Classes for SHA-1 and SHA-2 family of message digests.
Wrapper class for /dev/random and /dev/srandom.
Definition: osrng.h:118
Classes and functions for the FIPS 140-2 validated library.
void OS_GenerateRandomBlock(bool blocking, byte *output, size_t size)
OS_GenerateRandomBlock.
Definition: osrng.cpp:234
AutoSeededX917RNG(bool blocking=false, bool autoSeed=true)
Construct an AutoSeededX917RNG.
Definition: osrng.h:200
Crypto++ library namespace.
ProviderHandle GetProviderHandle() const
Retrieves the provider handle.
Definition: osrng.h:67
Ensures an object is not copyable.
Definition: misc.h:245
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:570
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: osrng.h:222
A typedef providing a default generator.
Definition: osrng.h:266