Crypto++  8.2
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 "hkdf.h"
18 #include "rng.h"
19 #include "aes.h"
20 #include "sha.h"
21 
22 NAMESPACE_BEGIN(CryptoPP)
23 
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 /// \brief Wrapper for Microsoft crypto service provider
37 /// \sa \def USE_MS_CRYPTOAPI, \def USE_MS_CNGAPI
38 class CRYPTOPP_DLL MicrosoftCryptoProvider
39 {
40 public:
41  /// \brief Construct a MicrosoftCryptoProvider
44 
45 // type HCRYPTPROV and BCRYPT_ALG_HANDLE, avoid #include <windows.h>
46 #if defined(USE_MS_CRYPTOAPI)
47 # if defined(__CYGWIN__) && defined(__x86_64__)
48  typedef unsigned long long ProviderHandle;
49 # elif defined(WIN64) || defined(_WIN64)
50  typedef unsigned __int64 ProviderHandle;
51 # else
52  typedef unsigned long ProviderHandle;
53 # endif
54 #elif defined(USE_MS_CNGAPI)
55  typedef void *PVOID;
56  typedef PVOID ProviderHandle;
57 #endif // USE_MS_CRYPTOAPI or USE_MS_CNGAPI
58 
59  /// \brief Retrieves the provider handle
60  /// \returns CryptoAPI provider handle
61  /// \details If USE_MS_CRYPTOAPI is in effect, then CryptAcquireContext()
62  /// acquires then handle and CryptReleaseContext() releases the handle
63  /// upon destruction. If USE_MS_CNGAPI is in effect, then
64  /// BCryptOpenAlgorithmProvider() acquires then handle and
65  /// BCryptCloseAlgorithmProvider() releases the handle upon destruction.
66  ProviderHandle GetProviderHandle() const {return m_hProvider;}
67 
68 private:
69  ProviderHandle m_hProvider;
70 };
71 
72 #if defined(_MSC_VER) && defined(USE_MS_CRYPTOAPI)
73 # pragma comment(lib, "advapi32.lib")
74 #endif
75 
76 #if defined(_MSC_VER) && defined(USE_MS_CNGAPI)
77 # pragma comment(lib, "bcrypt.lib")
78 #endif
79 
80 #endif // CRYPTOPP_WIN32_AVAILABLE
81 
82 /// \brief Wrapper class for /dev/random and /dev/srandom
83 /// \details Encapsulates CryptoAPI's CryptGenRandom() or CryptoNG's BCryptGenRandom()
84 /// on Windows, or /dev/urandom on Unix and compatibles.
85 class CRYPTOPP_DLL NonblockingRng : public RandomNumberGenerator
86 {
87 public:
88  CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "NonblockingRng"; }
89 
90  ~NonblockingRng();
91 
92  /// \brief Construct a NonblockingRng
94 
95  /// \brief Generate random array of bytes
96  /// \param output the byte buffer
97  /// \param size the length of the buffer, in bytes
98  /// \details GenerateIntoBufferedTransformation() calls are routed to GenerateBlock().
99  void GenerateBlock(byte *output, size_t size);
100 
101 protected:
102 #ifdef CRYPTOPP_WIN32_AVAILABLE
103  MicrosoftCryptoProvider m_Provider;
104 #else
105  int m_fd;
106 #endif
107 };
108 
109 #endif
110 
111 #if defined(BLOCKING_RNG_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
112 
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 /// \note On Linux the /dev/random interface is effectively deprecated. According to the
116 /// Kernel Crypto developers, /dev/urandom or getrandom(2) should be used instead. Also
117 /// see <A HREF="https://lkml.org/lkml/2017/7/20/993">[RFC PATCH v12 3/4] Linux Random
118 /// Number Generator</A> on the kernel-crypto mailing list.
119 class CRYPTOPP_DLL BlockingRng : public RandomNumberGenerator
120 {
121 public:
122  CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "BlockingRng"; }
123 
124  ~BlockingRng();
125 
126  /// \brief Construct a BlockingRng
127  BlockingRng();
128 
129  /// \brief Generate random array of bytes
130  /// \param output the byte buffer
131  /// \param size the length of the buffer, in bytes
132  /// \details GenerateIntoBufferedTransformation() calls are routed to GenerateBlock().
133  void GenerateBlock(byte *output, size_t size);
134 
135 protected:
136  int m_fd;
137 };
138 
139 #endif
140 
141 /// OS_GenerateRandomBlock
142 /// \brief Generate random array of bytes
143 /// \param blocking specifies whther a bobcking or non-blocking generator should be used
144 /// \param output the byte buffer
145 /// \param size the length of the buffer, in bytes
146 /// \details OS_GenerateRandomBlock() uses the underlying operating system's
147 /// random number generator. On Windows, CryptGenRandom() is called using NonblockingRng.
148 /// \details On Unix and compatibles, /dev/urandom is called if blocking is false using
149 /// NonblockingRng. If blocking is true, then either /dev/randomd or /dev/srandom is used
150 /// by way of BlockingRng, if available.
151 CRYPTOPP_DLL void CRYPTOPP_API OS_GenerateRandomBlock(bool blocking, byte *output, size_t size);
152 
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 /// \tparam BLOCK_CIPHER a block cipher
178 /// \brief Automatically Seeded X9.17 RNG
179 /// \details AutoSeededX917RNG is from ANSI X9.17 Appendix C, seeded using an OS provided RNG.
180 /// If 3-key TripleDES (DES_EDE3) is used, then its a X9.17 conforming generator. If AES is
181 /// used, then its a X9.31 conforming generator.
182 /// \details Though ANSI X9 prescribes 3-key TripleDES, the template parameter BLOCK_CIPHER can be any
183 /// BlockTransformation derived class.
184 /// \sa X917RNG, DefaultAutoSeededRNG
185 template <class BLOCK_CIPHER>
187 {
188 public:
189  static std::string StaticAlgorithmName() {
190  return std::string("AutoSeededX917RNG(") + BLOCK_CIPHER::StaticAlgorithmName() + std::string(")");
191  }
192 
193  ~AutoSeededX917RNG() {}
194 
195  /// \brief Construct an AutoSeededX917RNG
196  /// \param blocking controls seeding with BlockingRng or NonblockingRng
197  /// \param autoSeed controls auto seeding of the generator
198  /// \details Use blocking to choose seeding with BlockingRng or NonblockingRng.
199  /// The parameter is ignored if only one of these is available.
200  /// \sa X917RNG
201  explicit AutoSeededX917RNG(bool blocking = false, bool autoSeed = true)
202  {if (autoSeed) Reseed(blocking);}
203 
204  /// \brief Reseed an AutoSeededX917RNG
205  /// \param blocking controls seeding with BlockingRng or NonblockingRng
206  /// \param additionalEntropy additional entropy to add to the generator
207  /// \param length the size of the additional entropy, in bytes
208  /// \details Internally, the generator uses SHA256 to extract the entropy from
209  /// from the seed and then stretch the material for the block cipher's key
210  /// and initialization vector.
211  void Reseed(bool blocking = false, const byte *additionalEntropy = NULLPTR, size_t length = 0);
212 
213  /// \brief Deterministically reseed an AutoSeededX917RNG for testing
214  /// \param key the key to use for the deterministic reseeding
215  /// \param keylength the size of the key, in bytes
216  /// \param seed the seed to use for the deterministic reseeding
217  /// \param timeVector a time vector to use for deterministic reseeding
218  /// \details This is a testing interface for testing purposes, and should \a NOT
219  /// be used in production.
220  void Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector);
221 
222  bool CanIncorporateEntropy() const {return true;}
223  void IncorporateEntropy(const byte *input, size_t length) {Reseed(false, input, length);}
224  void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
225  {m_rng->GenerateIntoBufferedTransformation(target, channel, length);}
226 
227  std::string AlgorithmProvider() const;
228 
229 private:
231 };
232 
233 template <class BLOCK_CIPHER>
234 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector)
235 {
236  m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector));
237 }
238 
239 template <class BLOCK_CIPHER>
240 void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking, const byte *input, size_t length)
241 {
242  enum {BlockSize=BLOCK_CIPHER::BLOCKSIZE};
243  enum {KeyLength=BLOCK_CIPHER::DEFAULT_KEYLENGTH};
244  enum {SeedSize=BlockSize + KeyLength};
245 
246  SecByteBlock seed(SeedSize), temp(SeedSize);
247  const byte label[] = "X9.17 key generation";
248  const byte *key=NULLPTR;
249 
250  do
251  {
252  OS_GenerateRandomBlock(blocking, temp, temp.size());
253 
254  HKDF<SHA256> hkdf;
255  hkdf.DeriveKey(
256  seed, seed.size(), // derived secret
257  temp, temp.size(), // instance secret
258  input, length, // user secret
259  label, 20 // unique label
260  );
261 
262  key = seed + BlockSize;
263  } // check that seed and key don't have same value
264  while (memcmp(key, seed, STDMIN((size_t)BlockSize, (size_t)KeyLength)) == 0);
265 
266  Reseed(key, KeyLength, seed, NULLPTR);
267 }
268 
269 template <class BLOCK_CIPHER>
271 {
272  // Hack for now... We need to instantiate one
273  typename BLOCK_CIPHER::Encryption bc;
274  return bc.AlgorithmProvider();
275 }
276 
277 CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG<AES>;
278 
279 #if defined(CRYPTOPP_DOXYGEN_PROCESSING)
280 /// \brief A typedef providing a default generator
281 /// \details DefaultAutoSeededRNG is a typedef of either AutoSeededX917RNG<AES> or AutoSeededRandomPool.
282 /// If CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 is defined, then DefaultAutoSeededRNG is
283 /// AutoSeededX917RNG<AES>. Otherwise, DefaultAutoSeededRNG is AutoSeededRandomPool.
285 #else
286 // AutoSeededX917RNG<AES> in FIPS mode, otherwise it's AutoSeededRandomPool
287 #if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
289 #else
291 #endif
292 #endif // CRYPTOPP_DOXYGEN_PROCESSING
293 
294 NAMESPACE_END
295 
296 #endif
297 
298 #endif
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:158
AutoSeededRandomPool(bool blocking=false, unsigned int seedSize=32)
Construct an AutoSeededRandomPool.
Definition: osrng.h:168
Randomness Pool based on AES-256.
Definition: randpool.h:41
Wrapper class for /dev/random and /dev/srandom.
Definition: osrng.h:85
Class file for Randomness Pool.
void Reseed(bool blocking=false, const byte *additionalEntropy=NULL, size_t length=0)
Reseed an AutoSeededX917RNG.
Definition: osrng.h:240
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: cryptlib.cpp:311
ANSI X9.17 RNG.
Definition: rng.h:47
Classes for HKDF from RFC 5869.
Extract-and-Expand Key Derivation Function (HKDF)
Definition: hkdf.h:25
bool CanIncorporateEntropy() const
Determines if a generator can accept additional entropy.
Definition: osrng.h:222
Abstract base classes that provide a uniform interface to this library.
Classes for automatic resource management.
size_t DeriveKey(byte *derived, size_t derivedLen, const byte *secret, size_t secretLen, const NameValuePairs &params) const
Derive a key from a seed.
Definition: hkdf.h:101
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Definition: osrng.h:270
Library configuration file.
Interface for random number generators.
Definition: cryptlib.h:1413
SecBlock<byte> typedef.
Definition: secblock.h:1090
Interface for buffered transformations.
Definition: cryptlib.h:1630
void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
Generate random bytes into a BufferedTransformation.
Definition: osrng.h:224
CRYPTOPP_DLL void CRYPTOPP_API OS_GenerateRandomBlock(bool blocking, byte *output, size_t size)
OS_GenerateRandomBlock.
Definition: osrng.cpp:266
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)
Miscellaneous classes for RNGs.
Automatically Seeded X9.17 RNG.
Definition: osrng.h:186
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:630
const char * BlockSize()
int, in bytes
Definition: argnames.h:27
Classes for SHA-1 and SHA-2 family of message digests.
Wrapper class for /dev/random and /dev/srandom.
Definition: osrng.h:119
Classes and functions for the FIPS 140-2 validated library.
AutoSeededX917RNG(bool blocking=false, bool autoSeed=true)
Construct an AutoSeededX917RNG.
Definition: osrng.h:201
Crypto++ library namespace.
ProviderHandle GetProviderHandle() const
Retrieves the provider handle.
Definition: osrng.h:66
Ensures an object is not copyable.
Definition: misc.h:236
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:828
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: osrng.h:223
A typedef providing a default generator.
Definition: osrng.h:284