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
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 /// \note On Linux the /dev/random interface is effectively deprecated. According to the
119 /// Kernel Crypto developers, /dev/urandom or getrandom(2) should be used instead. Also
120 /// see <A HREF="https://lkml.org/lkml/2017/7/20/993">[RFC PATCH v12 3/4] Linux Random
121 /// Number Generator</A> on the kernel-crypto mailing list.
122 class CRYPTOPP_DLL BlockingRng : public RandomNumberGenerator
123 {
124 public:
125  CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "BlockingRng"; }
126 
127  ~BlockingRng();
128 
129  /// \brief Construct a BlockingRng
130  BlockingRng();
131 
132  /// \brief Generate random array of bytes
133  /// \param output the byte buffer
134  /// \param size the length of the buffer, in bytes
135  /// \details GenerateIntoBufferedTransformation() calls are routed to GenerateBlock().
136  void GenerateBlock(byte *output, size_t size);
137 
138 protected:
139  int m_fd;
140 };
141 
142 #endif
143 
144 /// OS_GenerateRandomBlock
145 /// \brief Generate random array of bytes
146 /// \param blocking specifies whther a bobcking or non-blocking generator should be used
147 /// \param output the byte buffer
148 /// \param size the length of the buffer, in bytes
149 /// \details OS_GenerateRandomBlock() uses the underlying operating system's
150 /// random number generator. On Windows, CryptGenRandom() is called using NonblockingRng.
151 /// \details On Unix and compatibles, /dev/urandom is called if blocking is false using
152 /// NonblockingRng. If blocking is true, then either /dev/randomd or /dev/srandom is used
153 /// by way of BlockingRng, if available.
154 CRYPTOPP_DLL void CRYPTOPP_API OS_GenerateRandomBlock(bool blocking, byte *output, size_t size);
155 
156 /// \class AutoSeededRandomPool
157 /// \brief Automatically Seeded Randomness Pool
158 /// \details This class seeds itself using an operating system provided RNG.
159 /// AutoSeededRandomPool was suggested by Leonard Janke.
160 class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool
161 {
162 public:
163  CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "AutoSeededRandomPool"; }
164 
166 
167  /// \brief Construct an AutoSeededRandomPool
168  /// \param blocking controls seeding with BlockingRng or NonblockingRng
169  /// \param seedSize the size of the seed, in bytes
170  /// \details Use blocking to choose seeding with BlockingRng or NonblockingRng.
171  /// The parameter is ignored if only one of these is available.
172  explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32)
173  {Reseed(blocking, seedSize);}
174 
175  /// \brief Reseed an AutoSeededRandomPool
176  /// \param blocking controls seeding with BlockingRng or NonblockingRng
177  /// \param seedSize the size of the seed, in bytes
178  void Reseed(bool blocking = false, unsigned int seedSize = 32);
179 };
180 
181 /// \class AutoSeededX917RNG
182 /// \tparam BLOCK_CIPHER a block cipher
183 /// \brief Automatically Seeded X9.17 RNG
184 /// \details AutoSeededX917RNG is from ANSI X9.17 Appendix C, seeded using an OS provided RNG.
185 /// If 3-key TripleDES (DES_EDE3) is used, then its a X9.17 conforming generator. If AES is
186 /// used, then its a X9.31 conforming generator.
187 /// \details Though ANSI X9 prescribes 3-key TripleDES, the template parameter BLOCK_CIPHER can be any
188 /// BlockTransformation derived class.
189 /// \sa X917RNG, DefaultAutoSeededRNG
190 template <class BLOCK_CIPHER>
192 {
193 public:
194  static std::string StaticAlgorithmName() { return std::string("AutoSeededX917RNG(") + BLOCK_CIPHER::StaticAlgorithmName() + std::string(")"); }
195 
196  ~AutoSeededX917RNG() {}
197 
198  /// \brief Construct an AutoSeededX917RNG
199  /// \param blocking controls seeding with BlockingRng or NonblockingRng
200  /// \param autoSeed controls auto seeding of the generator
201  /// \details Use blocking to choose seeding with BlockingRng or NonblockingRng.
202  /// The parameter is ignored if only one of these is available.
203  /// \sa X917RNG
204  explicit AutoSeededX917RNG(bool blocking = false, bool autoSeed = true)
205  {if (autoSeed) Reseed(blocking);}
206 
207  /// \brief Reseed an AutoSeededX917RNG
208  /// \param blocking controls seeding with BlockingRng or NonblockingRng
209  /// \param additionalEntropy additional entropy to add to the generator
210  /// \param length the size of the additional entropy, in bytes
211  /// \details Internally, the generator uses SHA256 to extract the entropy from
212  /// from the seed and then stretch the material for the block cipher's key
213  /// and initialization vector.
214  void Reseed(bool blocking = false, const byte *additionalEntropy = NULLPTR, size_t length = 0);
215 
216  /// \brief Deterministically reseed an AutoSeededX917RNG for testing
217  /// \param key the key to use for the deterministic reseeding
218  /// \param keylength the size of the key, in bytes
219  /// \param seed the seed to use for the deterministic reseeding
220  /// \param timeVector a time vector to use for deterministic reseeding
221  /// \details This is a testing interface for testing purposes, and should \a NOT
222  /// be used in production.
223  void Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector);
224 
225  bool CanIncorporateEntropy() const {return true;}
226  void IncorporateEntropy(const byte *input, size_t length) {Reseed(false, input, length);}
227  void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
228  {m_rng->GenerateIntoBufferedTransformation(target, channel, length);}
229 
230 private:
232 };
233 
234 template <class BLOCK_CIPHER>
235 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector)
236 {
237  m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector));
238 }
239 
240 template <class BLOCK_CIPHER>
241 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking, const byte *input, size_t length)
242 {
243  SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH);
244  const byte *key;
245  do
246  {
247  OS_GenerateRandomBlock(blocking, seed, seed.size());
248  if (length > 0)
249  {
250  SHA256 hash;
251  hash.Update(seed, seed.size());
252  hash.Update(input, length);
253  hash.TruncatedFinal(seed, UnsignedMin(hash.DigestSize(), seed.size()));
254  }
255  key = seed + BLOCK_CIPHER::BLOCKSIZE;
256  } // check that seed and key don't have same value
257  while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0);
258 
259  Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, NULLPTR);
260 }
261 
262 CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG<AES>;
263 
264 #if defined(CRYPTOPP_DOXYGEN_PROCESSING)
265 /// \class DefaultAutoSeededRNG
266 /// \brief A typedef providing a default generator
267 /// \details DefaultAutoSeededRNG is a typedef of either AutoSeededX917RNG<AES> or AutoSeededRandomPool.
268 /// If CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 is defined, then DefaultAutoSeededRNG is
269 /// AutoSeededX917RNG<AES>. Otherwise, DefaultAutoSeededRNG is AutoSeededRandomPool.
271 #else
272 // AutoSeededX917RNG<AES> in FIPS mode, otherwise it's AutoSeededRandomPool
273 #if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
275 #else
277 #endif
278 #endif // CRYPTOPP_DOXYGEN_PROCESSING
279 
280 NAMESPACE_END
281 
282 #endif
283 
284 #endif
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:157
AutoSeededRandomPool(bool blocking=false, unsigned int seedSize=32)
Construct an AutoSeededRandomPool.
Definition: osrng.h:172
Wrapper for Microsoft crypto service provider.
Definition: osrng.h:39
Randomness Pool based on AES-256.
Definition: randpool.h:42
SHA-256 message digest.
Definition: sha.h:62
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:241
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: cryptlib.cpp:309
ANSI X9.17 RNG.
Definition: rng.h:48
bool CanIncorporateEntropy() const
Determines if a generator can accept additional entropy.
Definition: osrng.h:225
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:1339
SecBlock<byte> typedef.
Definition: secblock.h:828
Interface for buffered transformations.
Definition: cryptlib.h:1486
void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
Generate random bytes into a BufferedTransformation.
Definition: osrng.h:227
Exception thrown when an operating system error is encountered.
Definition: osrng.h:25
Automatically Seeded Randomness Pool.
Definition: osrng.h:160
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:544
unsigned int DigestSize() const
Provides the digest size of the hash.
Definition: iterhash.h:171
Miscellaneous classes for RNGs.
Automatically Seeded X9.17 RNG.
Definition: osrng.h:191
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:506
Classes for SHA-1 and SHA-2 family of message digests.
Wrapper class for /dev/random and /dev/srandom.
Definition: osrng.h:122
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:204
Crypto++ library namespace.
ProviderHandle GetProviderHandle() const
Retrieves the provider handle.
Definition: osrng.h:67
Ensures an object is not copyable.
Definition: misc.h:230
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:566
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: osrng.h:226
A typedef providing a default generator.
Definition: osrng.h:270