Crypto++  8.2
Free C++ class library of cryptographic schemes
drbg.h
Go to the documentation of this file.
1 // drbg.h - written and placed in public domain by Jeffrey Walton.
2 
3 /// \file drbg.h
4 /// \brief Classes for NIST DRBGs from SP 800-90A
5 /// \sa <A HREF="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf">Recommendation
6 /// for Random Number Generation Using Deterministic Random Bit Generators, Rev 1 (June 2015)</A>
7 /// \since Crypto++ 6.0
8 
9 #ifndef CRYPTOPP_NIST_DRBG_H
10 #define CRYPTOPP_NIST_DRBG_H
11 
12 #include "cryptlib.h"
13 #include "secblock.h"
14 #include "hmac.h"
15 #include "sha.h"
16 
17 NAMESPACE_BEGIN(CryptoPP)
18 
19 /// \brief Interface for NIST DRBGs from SP 800-90A
20 /// \details NIST_DRBG is the base class interface for NIST DRBGs from SP 800-90A Rev 1 (June 2015)
21 /// \details You should reseed the generator after a fork() to avoid multiple generators
22 /// with the same internal state.
23 /// \sa <A HREF="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf">Recommendation
24 /// for Random Number Generation Using Deterministic Random Bit Generators, Rev 1 (June 2015)</A>
25 /// \since Crypto++ 6.0
27 {
28 public:
29  /// \brief Exception thrown when a NIST DRBG encounters an error
30  class Err : public Exception
31  {
32  public:
33  explicit Err(const std::string &c, const std::string &m)
34  : Exception(OTHER_ERROR, c + ": " + m) {}
35  };
36 
37 public:
38  virtual ~NIST_DRBG() {}
39 
40  /// \brief Determines if a generator can accept additional entropy
41  /// \return true
42  /// \details All NIST_DRBG return true
43  virtual bool CanIncorporateEntropy() const {return true;}
44 
45  /// \brief Update RNG state with additional unpredictable values
46  /// \param input the entropy to add to the generator
47  /// \param length the size of the input buffer
48  /// \throws NIST_DRBG::Err if the generator is reseeded with insufficient entropy
49  /// \details NIST instantiation and reseed requirements demand the generator is constructed
50  /// with at least <tt>MINIMUM_ENTROPY</tt> entropy. The byte array for <tt>input</tt> must
51  /// meet <A HREF ="http://csrc.nist.gov/publications/PubsSPs.html">NIST SP 800-90B or
52  /// SP 800-90C</A> requirements.
53  virtual void IncorporateEntropy(const byte *input, size_t length)=0;
54 
55  /// \brief Update RNG state with additional unpredictable values
56  /// \param entropy the entropy to add to the generator
57  /// \param entropyLength the size of the input buffer
58  /// \param additional additional input to add to the generator
59  /// \param additionaLength the size of the additional input buffer
60  /// \throws NIST_DRBG::Err if the generator is reseeded with insufficient entropy
61  /// \details IncorporateEntropy() is an overload provided to match NIST requirements. NIST
62  /// instantiation and reseed requirements demand the generator is constructed with at least
63  /// <tt>MINIMUM_ENTROPY</tt> entropy. The byte array for <tt>entropy</tt> must meet
64  /// <A HREF ="http://csrc.nist.gov/publications/PubsSPs.html">NIST SP 800-90B or
65  ///! SP 800-90C</A> requirements.
66  virtual void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte* additional, size_t additionaLength)=0;
67 
68  /// \brief Generate random array of bytes
69  /// \param output the byte buffer
70  /// \param size the length of the buffer, in bytes
71  /// \throws NIST_DRBG::Err if a reseed is required
72  /// \throws NIST_DRBG::Err if the size exceeds <tt>MAXIMUM_BYTES_PER_REQUEST</tt>
73  virtual void GenerateBlock(byte *output, size_t size)=0;
74 
75  /// \brief Generate random array of bytes
76  /// \param additional additional input to add to the generator
77  /// \param additionaLength the size of the additional input buffer
78  /// \param output the byte buffer
79  /// \param size the length of the buffer, in bytes
80  /// \throws NIST_DRBG::Err if a reseed is required
81  /// \throws NIST_DRBG::Err if the size exceeds <tt>MAXIMUM_BYTES_PER_REQUEST</tt>
82  /// \details GenerateBlock() is an overload provided to match NIST requirements. The byte
83  /// array for <tt>additional</tt> input is optional. If present the additional randomness
84  /// is mixed before generating the output bytes.
85  virtual void GenerateBlock(const byte* additional, size_t additionaLength, byte *output, size_t size)=0;
86 
87  /// \brief Provides the security strength
88  /// \returns The security strength of the generator, in bytes
89  /// \details The equivalent class constant is <tt>SECURITY_STRENGTH</tt>
90  virtual unsigned int SecurityStrength() const=0;
91 
92  /// \brief Provides the seed length
93  /// \returns The seed size of the generator, in bytes
94  /// \details The equivalent class constant is <tt>SEED_LENGTH</tt>. The size is
95  /// used to maintain internal state of <tt>V</tt> and <tt>C</tt>.
96  virtual unsigned int SeedLength() const=0;
97 
98  /// \brief Provides the minimum entropy size
99  /// \returns The minimum entropy size required by the generator, in bytes
100  /// \details The equivalent class constant is <tt>MINIMUM_ENTROPY</tt>. All NIST DRBGs must
101  /// be instaniated with at least <tt>MINIMUM_ENTROPY</tt> bytes of entropy. The bytes must
102  /// meet <A HREF="http://csrc.nist.gov/publications/PubsSPs.html">NIST SP 800-90B or
103  /// SP 800-90C</A> requirements.
104  virtual unsigned int MinEntropyLength() const=0;
105 
106  /// \brief Provides the maximum entropy size
107  /// \returns The maximum entropy size that can be consumed by the generator, in bytes
108  /// \details The equivalent class constant is <tt>MAXIMUM_ENTROPY</tt>. The bytes must
109  /// meet <A HREF="http://csrc.nist.gov/publications/PubsSPs.html">NIST SP 800-90B or
110  /// SP 800-90C</A> requirements. <tt>MAXIMUM_ENTROPY</tt> has been reduced from
111  /// 2<sup>35</sup> to <tt>INT_MAX</tt> to fit the underlying C++ datatype.
112  virtual unsigned int MaxEntropyLength() const=0;
113 
114  /// \brief Provides the minimum nonce size
115  /// \returns The minimum nonce size recommended for the generator, in bytes
116  /// \details The equivalent class constant is <tt>MINIMUM_NONCE</tt>. If a nonce is not
117  /// required then <tt>MINIMUM_NONCE</tt> is 0. <tt>Hash_DRBG</tt> does not require a
118  /// nonce, while <tt>HMAC_DRBG</tt> and <tt>CTR_DRBG</tt> require a nonce.
119  virtual unsigned int MinNonceLength() const=0;
120 
121  /// \brief Provides the maximum nonce size
122  /// \returns The maximum nonce that can be consumed by the generator, in bytes
123  /// \details The equivalent class constant is <tt>MAXIMUM_NONCE</tt>. <tt>MAXIMUM_NONCE</tt>
124  /// has been reduced from 2<sup>35</sup> to <tt>INT_MAX</tt> to fit the underlying C++ datatype.
125  /// If a nonce is not required then <tt>MINIMUM_NONCE</tt> is 0. <tt>Hash_DRBG</tt> does not
126  /// require a nonce, while <tt>HMAC_DRBG</tt> and <tt>CTR_DRBG</tt> require a nonce.
127  virtual unsigned int MaxNonceLength() const=0;
128 
129  /// \brief Provides the maximum size of a request to GenerateBlock
130  /// \returns The the maximum size of a request to GenerateBlock(), in bytes
131  /// \details The equivalent class constant is <tt>MAXIMUM_BYTES_PER_REQUEST</tt>
132  virtual unsigned int MaxBytesPerRequest() const=0;
133 
134  /// \brief Provides the maximum number of requests before a reseed
135  /// \returns The the maximum number of requests before a reseed, in bytes
136  /// \details The equivalent class constant is <tt>MAXIMUM_REQUESTS_BEFORE_RESEED</tt>.
137  /// <tt>MAXIMUM_REQUESTS_BEFORE_RESEED</tt> has been reduced from 2<sup>48</sup> to <tt>INT_MAX</tt>
138  /// to fit the underlying C++ datatype.
139  virtual unsigned int MaxRequestBeforeReseed() const=0;
140 
141 protected:
142  virtual void DRBG_Instantiate(const byte* entropy, size_t entropyLength,
143  const byte* nonce, size_t nonceLength, const byte* personalization, size_t personalizationLength)=0;
144 
145  virtual void DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength)=0;
146 };
147 
148 // *************************************************************
149 
150 /// \tparam HASH NIST approved hash derived from HashTransformation
151 /// \tparam STRENGTH security strength, in bytes
152 /// \tparam SEEDLENGTH seed length, in bytes
153 /// \brief Hash_DRBG from SP 800-90A Rev 1 (June 2015)
154 /// \details The NIST Hash DRBG is instantiated with a number of parameters. Two of the parameters,
155 /// Security Strength and Seed Length, depend on the hash and are specified as template parameters.
156 /// The remaining parameters are included in the class. The parameters and their values are listed
157 /// in NIST SP 800-90A Rev. 1, Table 2: Definitions for Hash-Based DRBG Mechanisms (p.38).
158 /// \details Some parameters have been reduce to fit C++ datatypes. For example, NIST allows upto
159 /// 2<sup>48</sup> requests before a reseed. However, Hash_DRBG limits it to <tt>INT_MAX</tt> due
160 /// to the limited data range of an int.
161 /// \details You should reseed the generator after a fork() to avoid multiple generators
162 /// with the same internal state.
163 /// \sa <A HREF="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf">Recommendation
164 /// for Random Number Generation Using Deterministic Random Bit Generators, Rev 1 (June 2015)</A>
165 /// \since Crypto++ 6.0
166 template <typename HASH=SHA256, unsigned int STRENGTH=128/8, unsigned int SEEDLENGTH=440/8>
167 class Hash_DRBG : public NIST_DRBG, public NotCopyable
168 {
169 public:
170  CRYPTOPP_CONSTANT(SECURITY_STRENGTH=STRENGTH);
171  CRYPTOPP_CONSTANT(SEED_LENGTH=SEEDLENGTH);
172  CRYPTOPP_CONSTANT(MINIMUM_ENTROPY=STRENGTH);
173  CRYPTOPP_CONSTANT(MINIMUM_NONCE=0);
174  CRYPTOPP_CONSTANT(MINIMUM_ADDITIONAL=0);
175  CRYPTOPP_CONSTANT(MINIMUM_PERSONALIZATION=0);
176  CRYPTOPP_CONSTANT(MAXIMUM_ENTROPY=INT_MAX);
177  CRYPTOPP_CONSTANT(MAXIMUM_NONCE=INT_MAX);
178  CRYPTOPP_CONSTANT(MAXIMUM_ADDITIONAL=INT_MAX);
179  CRYPTOPP_CONSTANT(MAXIMUM_PERSONALIZATION=INT_MAX);
180  CRYPTOPP_CONSTANT(MAXIMUM_BYTES_PER_REQUEST=65536);
181  CRYPTOPP_CONSTANT(MAXIMUM_REQUESTS_BEFORE_RESEED=INT_MAX);
182 
183  static std::string StaticAlgorithmName() { return std::string("Hash_DRBG(") + HASH::StaticAlgorithmName() + std::string(")"); }
184 
185  /// \brief Construct a Hash DRBG
186  /// \param entropy the entropy to instantiate the generator
187  /// \param entropyLength the size of the entropy buffer
188  /// \param nonce additional input to instantiate the generator
189  /// \param nonceLength the size of the nonce buffer
190  /// \param personalization additional input to instantiate the generator
191  /// \param personalizationLength the size of the personalization buffer
192  /// \throws NIST_DRBG::Err if the generator is instantiated with insufficient entropy
193  /// \details All NIST DRBGs must be instaniated with at least <tt>MINIMUM_ENTROPY</tt> bytes of entropy.
194  /// The byte array for <tt>entropy</tt> must meet <A HREF ="http://csrc.nist.gov/publications/PubsSPs.html">NIST
195  /// SP 800-90B or SP 800-90C</A> requirements.
196  /// \details The <tt>nonce</tt> and <tt>personalization</tt> are optional byte arrays. If <tt>nonce</tt> is supplied,
197  /// then it should be at least <tt>MINIMUM_NONCE</tt> bytes of entropy.
198  /// \details An example of instantiating a SHA256 generator is shown below.
199  /// The example provides more entropy than required for SHA256. The <tt>NonblockingRng</tt> meets the
200  /// requirements of <A HREF ="http://csrc.nist.gov/publications/PubsSPs.html">NIST SP 800-90B or SP 800-90C</A>.
201  /// RDRAND() and RDSEED() generators would work as well.
202  /// <pre>
203  /// SecByteBlock entropy(48), result(128);
204  /// NonblockingRng prng;
205  /// RandomNumberSource rns(prng, entropy.size(), new ArraySink(entropy, entropy.size()));
206  ///
207  /// Hash_DRBG<SHA256, 128/8, 440/8> drbg(entropy, 32, entropy+32, 16);
208  /// drbg.GenerateBlock(result, result.size());
209  /// </pre>
210  Hash_DRBG(const byte* entropy=NULLPTR, size_t entropyLength=STRENGTH, const byte* nonce=NULLPTR,
211  size_t nonceLength=0, const byte* personalization=NULLPTR, size_t personalizationLength=0)
212  : NIST_DRBG(), m_c(SEEDLENGTH), m_v(SEEDLENGTH), m_reseed(0)
213  {
214  std::memset(m_c, 0x00, m_c.size());
215  std::memset(m_v, 0x00, m_v.size());
216 
217  if (entropy != NULLPTR && entropyLength != 0)
218  DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
219  }
220 
221  unsigned int SecurityStrength() const {return SECURITY_STRENGTH;}
222  unsigned int SeedLength() const {return SEED_LENGTH;}
223  unsigned int MinEntropyLength() const {return MINIMUM_ENTROPY;}
224  unsigned int MaxEntropyLength() const {return MAXIMUM_ENTROPY;}
225  unsigned int MinNonceLength() const {return MINIMUM_NONCE;}
226  unsigned int MaxNonceLength() const {return MAXIMUM_NONCE;}
227  unsigned int MaxBytesPerRequest() const {return MAXIMUM_BYTES_PER_REQUEST;}
228  unsigned int MaxRequestBeforeReseed() const {return MAXIMUM_REQUESTS_BEFORE_RESEED;}
229 
230  void IncorporateEntropy(const byte *input, size_t length)
231  {return DRBG_Reseed(input, length, NULLPTR, 0);}
232 
233  void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte* additional, size_t additionaLength)
234  {return DRBG_Reseed(entropy, entropyLength, additional, additionaLength);}
235 
236  void GenerateBlock(byte *output, size_t size)
237  {return Hash_Generate(NULLPTR, 0, output, size);}
238 
239  void GenerateBlock(const byte* additional, size_t additionaLength, byte *output, size_t size)
240  {return Hash_Generate(additional, additionaLength, output, size);}
241 
242  std::string AlgorithmProvider() const
243  {/*Hack*/HASH hash; return hash.AlgorithmProvider();}
244 
245 protected:
246  // 10.1.1.2 Instantiation of Hash_DRBG (p.39)
247  void DRBG_Instantiate(const byte* entropy, size_t entropyLength, const byte* nonce, size_t nonceLength,
248  const byte* personalization, size_t personalizationLength);
249 
250  // 10.1.1.3 Reseeding a Hash_DRBG Instantiation (p.40)
251  void DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength);
252 
253  // 10.1.1.4 Generating Pseudorandom Bits Using Hash_DRBG (p.41)
254  void Hash_Generate(const byte* additional, size_t additionaLength, byte *output, size_t size);
255 
256  // 10.3.1 Derivation Function Using a Hash Function (Hash_df) (p.49)
257  void Hash_Update(const byte* input1, size_t inlen1, const byte* input2, size_t inlen2,
258  const byte* input3, size_t inlen3, const byte* input4, size_t inlen4, byte* output, size_t outlen);
259 
260 private:
261  HASH m_hash;
262  SecByteBlock m_c, m_v, m_temp;
263  word64 m_reseed;
264 };
265 
266 // typedef Hash_DRBG<SHA1, 128/8, 440/8> Hash_SHA1_DRBG;
267 // typedef Hash_DRBG<SHA256, 128/8, 440/8> Hash_SHA256_DRBG;
268 // typedef Hash_DRBG<SHA384, 256/8, 888/8> Hash_SHA384_DRBG;
269 // typedef Hash_DRBG<SHA512, 256/8, 888/8> Hash_SHA512_DRBG;
270 
271 // *************************************************************
272 
273 /// \tparam HASH NIST approved hash derived from HashTransformation
274 /// \tparam STRENGTH security strength, in bytes
275 /// \tparam SEEDLENGTH seed length, in bytes
276 /// \brief HMAC_DRBG from SP 800-90A Rev 1 (June 2015)
277 /// \details The NIST HMAC DRBG is instantiated with a number of parameters. Two of the parameters,
278 /// Security Strength and Seed Length, depend on the hash and are specified as template parameters.
279 /// The remaining parameters are included in the class. The parameters and their values are listed
280 /// in NIST SP 800-90A Rev. 1, Table 2: Definitions for Hash-Based DRBG Mechanisms (p.38).
281 /// \details Some parameters have been reduce to fit C++ datatypes. For example, NIST allows upto 2<sup>48</sup> requests
282 /// before a reseed. However, HMAC_DRBG limits it to <tt>INT_MAX</tt> due to the limited data range of an int.
283 /// \details You should reseed the generator after a fork() to avoid multiple generators
284 /// with the same internal state.
285 /// \sa <A HREF="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf">Recommendation
286 /// for Random Number Generation Using Deterministic Random Bit Generators, Rev 1 (June 2015)</A>
287 /// \since Crypto++ 6.0
288 template <typename HASH=SHA256, unsigned int STRENGTH=128/8, unsigned int SEEDLENGTH=440/8>
289 class HMAC_DRBG : public NIST_DRBG, public NotCopyable
290 {
291 public:
292  CRYPTOPP_CONSTANT(SECURITY_STRENGTH=STRENGTH);
293  CRYPTOPP_CONSTANT(SEED_LENGTH=SEEDLENGTH);
294  CRYPTOPP_CONSTANT(MINIMUM_ENTROPY=STRENGTH);
295  CRYPTOPP_CONSTANT(MINIMUM_NONCE=0);
296  CRYPTOPP_CONSTANT(MINIMUM_ADDITIONAL=0);
297  CRYPTOPP_CONSTANT(MINIMUM_PERSONALIZATION=0);
298  CRYPTOPP_CONSTANT(MAXIMUM_ENTROPY=INT_MAX);
299  CRYPTOPP_CONSTANT(MAXIMUM_NONCE=INT_MAX);
300  CRYPTOPP_CONSTANT(MAXIMUM_ADDITIONAL=INT_MAX);
301  CRYPTOPP_CONSTANT(MAXIMUM_PERSONALIZATION=INT_MAX);
302  CRYPTOPP_CONSTANT(MAXIMUM_BYTES_PER_REQUEST=65536);
303  CRYPTOPP_CONSTANT(MAXIMUM_REQUESTS_BEFORE_RESEED=INT_MAX);
304 
305  static std::string StaticAlgorithmName() { return std::string("HMAC_DRBG(") + HASH::StaticAlgorithmName() + std::string(")"); }
306 
307  /// \brief Construct a HMAC DRBG
308  /// \param entropy the entropy to instantiate the generator
309  /// \param entropyLength the size of the entropy buffer
310  /// \param nonce additional input to instantiate the generator
311  /// \param nonceLength the size of the nonce buffer
312  /// \param personalization additional input to instantiate the generator
313  /// \param personalizationLength the size of the personalization buffer
314  /// \throws NIST_DRBG::Err if the generator is instantiated with insufficient entropy
315  /// \details All NIST DRBGs must be instaniated with at least <tt>MINIMUM_ENTROPY</tt> bytes of entropy.
316  /// The byte array for <tt>entropy</tt> must meet <A HREF ="http://csrc.nist.gov/publications/PubsSPs.html">NIST
317  /// SP 800-90B or SP 800-90C</A> requirements.
318  /// \details The <tt>nonce</tt> and <tt>personalization</tt> are optional byte arrays. If <tt>nonce</tt> is supplied,
319  /// then it should be at least <tt>MINIMUM_NONCE</tt> bytes of entropy.
320  /// \details An example of instantiating a SHA256 generator is shown below.
321  /// The example provides more entropy than required for SHA256. The <tt>NonblockingRng</tt> meets the
322  /// requirements of <A HREF ="http://csrc.nist.gov/publications/PubsSPs.html">NIST SP 800-90B or SP 800-90C</A>.
323  /// RDRAND() and RDSEED() generators would work as well.
324  /// <pre>
325  /// SecByteBlock entropy(48), result(128);
326  /// NonblockingRng prng;
327  /// RandomNumberSource rns(prng, entropy.size(), new ArraySink(entropy, entropy.size()));
328  ///
329  /// HMAC_DRBG<SHA256, 128/8, 440/8> drbg(entropy, 32, entropy+32, 16);
330  /// drbg.GenerateBlock(result, result.size());
331  /// </pre>
332  HMAC_DRBG(const byte* entropy=NULLPTR, size_t entropyLength=STRENGTH, const byte* nonce=NULLPTR,
333  size_t nonceLength=0, const byte* personalization=NULLPTR, size_t personalizationLength=0)
334  : NIST_DRBG(), m_k(HASH::DIGESTSIZE), m_v(HASH::DIGESTSIZE), m_reseed(0)
335  {
336  std::memset(m_k, 0x00, m_k.size());
337  std::memset(m_v, 0x00, m_v.size());
338 
339  if (entropy != NULLPTR && entropyLength != 0)
340  DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
341  }
342 
343  unsigned int SecurityStrength() const {return SECURITY_STRENGTH;}
344  unsigned int SeedLength() const {return SEED_LENGTH;}
345  unsigned int MinEntropyLength() const {return MINIMUM_ENTROPY;}
346  unsigned int MaxEntropyLength() const {return MAXIMUM_ENTROPY;}
347  unsigned int MinNonceLength() const {return MINIMUM_NONCE;}
348  unsigned int MaxNonceLength() const {return MAXIMUM_NONCE;}
349  unsigned int MaxBytesPerRequest() const {return MAXIMUM_BYTES_PER_REQUEST;}
350  unsigned int MaxRequestBeforeReseed() const {return MAXIMUM_REQUESTS_BEFORE_RESEED;}
351 
352  void IncorporateEntropy(const byte *input, size_t length)
353  {return DRBG_Reseed(input, length, NULLPTR, 0);}
354 
355  void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte* additional, size_t additionaLength)
356  {return DRBG_Reseed(entropy, entropyLength, additional, additionaLength);}
357 
358  void GenerateBlock(byte *output, size_t size)
359  {return HMAC_Generate(NULLPTR, 0, output, size);}
360 
361  void GenerateBlock(const byte* additional, size_t additionaLength, byte *output, size_t size)
362  {return HMAC_Generate(additional, additionaLength, output, size);}
363 
364  std::string AlgorithmProvider() const
365  {/*Hack*/HASH hash; return hash.AlgorithmProvider();}
366 
367 protected:
368  // 10.1.2.3 Instantiation of HMAC_DRBG (p.45)
369  void DRBG_Instantiate(const byte* entropy, size_t entropyLength, const byte* nonce, size_t nonceLength,
370  const byte* personalization, size_t personalizationLength);
371 
372  // 10.1.2.4 Reseeding a HMAC_DRBG Instantiation (p.46)
373  void DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength);
374 
375  // 10.1.2.5 Generating Pseudorandom Bits Using HMAC_DRBG (p.46)
376  void HMAC_Generate(const byte* additional, size_t additionaLength, byte *output, size_t size);
377 
378  // 10.1.2.2 Derivation Function Using a HMAC Function (HMAC_Update) (p.44)
379  void HMAC_Update(const byte* input1, size_t inlen1, const byte* input2, size_t inlen2, const byte* input3, size_t inlen3);
380 
381 private:
382  HMAC<HASH> m_hmac;
383  SecByteBlock m_k, m_v;
384  word64 m_reseed;
385 };
386 
387 // typedef HMAC_DRBG<SHA1, 128/8, 440/8> HMAC_SHA1_DRBG;
388 // typedef HMAC_DRBG<SHA256, 128/8, 440/8> HMAC_SHA256_DRBG;
389 // typedef HMAC_DRBG<SHA384, 256/8, 888/8> HMAC_SHA384_DRBG;
390 // typedef HMAC_DRBG<SHA512, 256/8, 888/8> HMAC_SHA512_DRBG;
391 
392 // *************************************************************
393 
394 // 10.1.1.2 Instantiation of Hash_DRBG (p.39)
395 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
396 void Hash_DRBG<HASH, STRENGTH, SEEDLENGTH>::DRBG_Instantiate(const byte* entropy, size_t entropyLength, const byte* nonce, size_t nonceLength,
397  const byte* personalization, size_t personalizationLength)
398 {
399  // SP 800-90A, 8.6.3: The entropy input shall have entropy that is equal to or greater than the security
400  // strength of the instantiation. Additional entropy may be provided in the nonce or the optional
401  // personalization string during instantiation, or in the additional input during reseeding and generation,
402  // but this is not required and does not increase the "official" security strength of the DRBG
403  // instantiation that is recorded in the internal state.
404  CRYPTOPP_ASSERT(entropyLength >= MINIMUM_ENTROPY);
405  if (entropyLength < MINIMUM_ENTROPY)
406  throw NIST_DRBG::Err("Hash_DRBG", "Insufficient entropy during instantiate");
407 
408  // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
409  // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
410  CRYPTOPP_ASSERT(entropyLength <= MAXIMUM_ENTROPY);
411  CRYPTOPP_ASSERT(nonceLength <= MAXIMUM_NONCE);
412  CRYPTOPP_ASSERT(personalizationLength <= MAXIMUM_PERSONALIZATION);
413 
414  const byte zero = 0;
415  SecByteBlock t1(SEEDLENGTH), t2(SEEDLENGTH);
416  Hash_Update(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength, NULLPTR, 0, t1, t1.size());
417  Hash_Update(&zero, 1, t1, t1.size(), NULLPTR, 0, NULLPTR, 0, t2, t2.size());
418 
419  m_v.swap(t1); m_c.swap(t2);
420  m_reseed = 1;
421 }
422 
423 // 10.1.1.3 Reseeding a Hash_DRBG Instantiation (p.40)
424 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
425 void Hash_DRBG<HASH, STRENGTH, SEEDLENGTH>::DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength)
426 {
427  // SP 800-90A, 8.6.3: The entropy input shall have entropy that is equal to or greater than the security
428  // strength of the instantiation. Additional entropy may be provided in the nonce or the optional
429  // personalization string during instantiation, or in the additional input during reseeding and generation,
430  // but this is not required and does not increase the "official" security strength of the DRBG
431  // instantiation that is recorded in the internal state..
432  CRYPTOPP_ASSERT(entropyLength >= MINIMUM_ENTROPY);
433  if (entropyLength < MINIMUM_ENTROPY)
434  throw NIST_DRBG::Err("Hash_DRBG", "Insufficient entropy during reseed");
435 
436  // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
437  // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
438  CRYPTOPP_ASSERT(entropyLength <= MAXIMUM_ENTROPY);
439  CRYPTOPP_ASSERT(additionaLength <= MAXIMUM_ADDITIONAL);
440 
441  const byte zero = 0, one = 1;
442  SecByteBlock t1(SEEDLENGTH), t2(SEEDLENGTH);
443  Hash_Update(&one, 1, m_v, m_v.size(), entropy, entropyLength, additional, additionaLength, t1, t1.size());
444  Hash_Update(&zero, 1, t1, t1.size(), NULLPTR, 0, NULLPTR, 0, t2, t2.size());
445 
446  m_v.swap(t1); m_c.swap(t2);
447  m_reseed = 1;
448 }
449 
450 // 10.1.1.4 Generating Pseudorandom Bits Using Hash_DRBG (p.41)
451 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
452 void Hash_DRBG<HASH, STRENGTH, SEEDLENGTH>::Hash_Generate(const byte* additional, size_t additionaLength, byte *output, size_t size)
453 {
454  // Step 1
455  if (static_cast<word64>(m_reseed) >= static_cast<word64>(MaxRequestBeforeReseed()))
456  throw NIST_DRBG::Err("Hash_DRBG", "Reseed required");
457 
458  if (size > MaxBytesPerRequest())
459  throw NIST_DRBG::Err("Hash_DRBG", "Request size exceeds limit");
460 
461  // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
462  // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
463  CRYPTOPP_ASSERT(additionaLength <= MAXIMUM_ADDITIONAL);
464 
465  // Step 2
466  if (additional && additionaLength)
467  {
468  const byte two = 2;
469  m_temp.New(HASH::DIGESTSIZE);
470 
471  m_hash.Update(&two, 1);
472  m_hash.Update(m_v, m_v.size());
473  m_hash.Update(additional, additionaLength);
474  m_hash.Final(m_temp);
475 
476  CRYPTOPP_ASSERT(SEEDLENGTH >= HASH::DIGESTSIZE);
477  int carry=0, j=HASH::DIGESTSIZE-1, i=SEEDLENGTH-1;
478  while (j>=0)
479  {
480  carry = m_v[i] + m_temp[j] + carry;
481  m_v[i] = static_cast<byte>(carry);
482  i--; j--; carry >>= 8;
483  }
484  while (i>=0)
485  {
486  carry = m_v[i] + carry;
487  m_v[i] = static_cast<byte>(carry);
488  i--; carry >>= 8;
489  }
490  }
491 
492  // Step 3
493  {
494  m_temp.Assign(m_v);
495  while (size)
496  {
497  m_hash.Update(m_temp, m_temp.size());
498  size_t count = STDMIN(size, (size_t)HASH::DIGESTSIZE);
499  m_hash.TruncatedFinal(output, count);
500 
501  IncrementCounterByOne(m_temp, static_cast<unsigned int>(m_temp.size()));
502  size -= count; output += count;
503  }
504  }
505 
506  // Steps 4-7
507  {
508  const byte three = 3;
509  m_temp.New(HASH::DIGESTSIZE);
510 
511  m_hash.Update(&three, 1);
512  m_hash.Update(m_v, m_v.size());
513  m_hash.Final(m_temp);
514 
515  CRYPTOPP_ASSERT(SEEDLENGTH >= HASH::DIGESTSIZE);
516  CRYPTOPP_ASSERT(HASH::DIGESTSIZE >= sizeof(m_reseed));
517  int carry=0, k=sizeof(m_reseed)-1, j=HASH::DIGESTSIZE-1, i=SEEDLENGTH-1;
518 
519  while (k>=0)
520  {
521  carry = m_v[i] + m_c[i] + m_temp[j] + GetByte<word64>(BIG_ENDIAN_ORDER, m_reseed, k) + carry;
522  m_v[i] = static_cast<byte>(carry);
523  i--; j--; k--; carry >>= 8;
524  }
525 
526  while (j>=0)
527  {
528  carry = m_v[i] + m_c[i] + m_temp[j] + carry;
529  m_v[i] = static_cast<byte>(carry);
530  i--; j--; carry >>= 8;
531  }
532 
533  while (i>=0)
534  {
535  carry = m_v[i] + m_c[i] + carry;
536  m_v[i] = static_cast<byte>(carry);
537  i--; carry >>= 8;
538  }
539  }
540 
541  m_reseed++;
542 }
543 
544 // 10.3.1 Derivation Function Using a Hash Function (Hash_df) (p.49)
545 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
546 void Hash_DRBG<HASH, STRENGTH, SEEDLENGTH>::Hash_Update(const byte* input1, size_t inlen1, const byte* input2, size_t inlen2,
547  const byte* input3, size_t inlen3, const byte* input4, size_t inlen4, byte* output, size_t outlen)
548 {
549  byte counter = 1;
550  word32 bits = ConditionalByteReverse(BIG_ENDIAN_ORDER, static_cast<word32>(outlen*8));
551 
552  while (outlen)
553  {
554  m_hash.Update(&counter, 1);
555  m_hash.Update(reinterpret_cast<const byte*>(&bits), 4);
556 
557  if (input1 && inlen1)
558  m_hash.Update(input1, inlen1);
559  if (input2 && inlen2)
560  m_hash.Update(input2, inlen2);
561  if (input3 && inlen3)
562  m_hash.Update(input3, inlen3);
563  if (input4 && inlen4)
564  m_hash.Update(input4, inlen4);
565 
566  size_t count = STDMIN(outlen, (size_t)HASH::DIGESTSIZE);
567  m_hash.TruncatedFinal(output, count);
568 
569  output += count; outlen -= count;
570  counter++;
571  }
572 }
573 
574 // *************************************************************
575 
576 // 10.1.2.3 Instantiation of HMAC_DRBG (p.45)
577 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
578 void HMAC_DRBG<HASH, STRENGTH, SEEDLENGTH>::DRBG_Instantiate(const byte* entropy, size_t entropyLength, const byte* nonce, size_t nonceLength,
579  const byte* personalization, size_t personalizationLength)
580 {
581  // SP 800-90A, 8.6.3: The entropy input shall have entropy that is equal to or greater than the security
582  // strength of the instantiation. Additional entropy may be provided in the nonce or the optional
583  // personalization string during instantiation, or in the additional input during reseeding and generation,
584  // but this is not required and does not increase the "official" security strength of the DRBG
585  // instantiation that is recorded in the internal state.
586  CRYPTOPP_ASSERT(entropyLength >= MINIMUM_ENTROPY);
587  if (entropyLength < MINIMUM_ENTROPY)
588  throw NIST_DRBG::Err("HMAC_DRBG", "Insufficient entropy during instantiate");
589 
590  // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
591  // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
592  CRYPTOPP_ASSERT(entropyLength <= MAXIMUM_ENTROPY);
593  CRYPTOPP_ASSERT(nonceLength <= MAXIMUM_NONCE);
594  CRYPTOPP_ASSERT(personalizationLength <= MAXIMUM_PERSONALIZATION);
595 
596  std::fill(m_k.begin(), m_k.begin()+m_k.size(), byte(0));
597  std::fill(m_v.begin(), m_v.begin()+m_v.size(), byte(1));
598 
599  HMAC_Update(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
600  m_reseed = 1;
601 }
602 
603 // 10.1.2.4 Reseeding a HMAC_DRBG Instantiation (p.46)
604 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
605 void HMAC_DRBG<HASH, STRENGTH, SEEDLENGTH>::DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength)
606 {
607  // SP 800-90A, 8.6.3: The entropy input shall have entropy that is equal to or greater than the security
608  // strength of the instantiation. Additional entropy may be provided in the nonce or the optional
609  // personalization string during instantiation, or in the additional input during reseeding and generation,
610  // but this is not required and does not increase the "official" security strength of the DRBG
611  // instantiation that is recorded in the internal state..
612  CRYPTOPP_ASSERT(entropyLength >= MINIMUM_ENTROPY);
613  if (entropyLength < MINIMUM_ENTROPY)
614  throw NIST_DRBG::Err("HMAC_DRBG", "Insufficient entropy during reseed");
615 
616  // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
617  // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
618  CRYPTOPP_ASSERT(entropyLength <= MAXIMUM_ENTROPY);
619  CRYPTOPP_ASSERT(additionaLength <= MAXIMUM_ADDITIONAL);
620 
621  HMAC_Update(entropy, entropyLength, additional, additionaLength, NULLPTR, 0);
622  m_reseed = 1;
623 }
624 
625 // 10.1.2.5 Generating Pseudorandom Bits Using HMAC_DRBG (p.46)
626 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
627 void HMAC_DRBG<HASH, STRENGTH, SEEDLENGTH>::HMAC_Generate(const byte* additional, size_t additionaLength, byte *output, size_t size)
628 {
629  // Step 1
630  if (static_cast<word64>(m_reseed) >= static_cast<word64>(MaxRequestBeforeReseed()))
631  throw NIST_DRBG::Err("HMAC_DRBG", "Reseed required");
632 
633  if (size > MaxBytesPerRequest())
634  throw NIST_DRBG::Err("HMAC_DRBG", "Request size exceeds limit");
635 
636  // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
637  // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
638  CRYPTOPP_ASSERT(additionaLength <= MAXIMUM_ADDITIONAL);
639 
640  // Step 2
641  if (additional && additionaLength)
642  HMAC_Update(additional, additionaLength, NULLPTR, 0, NULLPTR, 0);
643 
644  // Step 3
645  m_hmac.SetKey(m_k, m_k.size());
646 
647  while (size)
648  {
649  m_hmac.Update(m_v, m_v.size());
650  m_hmac.TruncatedFinal(m_v, m_v.size());
651 
652  size_t count = STDMIN(size, (size_t)HASH::DIGESTSIZE);
653  memcpy(output, m_v, count);
654  size -= count; output += count;
655  }
656 
657  HMAC_Update(additional, additionaLength, NULLPTR, 0, NULLPTR, 0);
658  m_reseed++;
659 }
660 
661 // 10.1.2.2 Derivation Function Using a HMAC Function (HMAC_Update) (p.44)
662 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
663 void HMAC_DRBG<HASH, STRENGTH, SEEDLENGTH>::HMAC_Update(const byte* input1, size_t inlen1, const byte* input2, size_t inlen2, const byte* input3, size_t inlen3)
664 {
665  const byte zero = 0, one = 1;
666 
667  // Step 1
668  m_hmac.SetKey(m_k, m_k.size());
669  m_hmac.Update(m_v, m_v.size());
670  m_hmac.Update(&zero, 1);
671 
672  if (input1 && inlen1)
673  m_hmac.Update(input1, inlen1);
674  if (input2 && inlen2)
675  m_hmac.Update(input2, inlen2);
676  if (input3 && inlen3)
677  m_hmac.Update(input3, inlen3);
678 
679  m_hmac.TruncatedFinal(m_k, m_k.size());
680 
681  // Step 2
682  m_hmac.SetKey(m_k, m_k.size());
683  m_hmac.Update(m_v, m_v.size());
684 
685  m_hmac.TruncatedFinal(m_v, m_v.size());
686 
687  // Step 3
688  if ((inlen1 | inlen2 | inlen3) == 0)
689  return;
690 
691  // Step 4
692  m_hmac.SetKey(m_k, m_k.size());
693  m_hmac.Update(m_v, m_v.size());
694  m_hmac.Update(&one, 1);
695 
696  if (input1 && inlen1)
697  m_hmac.Update(input1, inlen1);
698  if (input2 && inlen2)
699  m_hmac.Update(input2, inlen2);
700  if (input3 && inlen3)
701  m_hmac.Update(input3, inlen3);
702 
703  m_hmac.TruncatedFinal(m_k, m_k.size());
704 
705  // Step 5
706  m_hmac.SetKey(m_k, m_k.size());
707  m_hmac.Update(m_v, m_v.size());
708 
709  m_hmac.TruncatedFinal(m_v, m_v.size());
710 }
711 
712 NAMESPACE_END
713 
714 #endif // CRYPTOPP_NIST_DRBG_H
Hash_DRBG(const byte *entropy=NULL, size_t entropyLength=STRENGTH, const byte *nonce=NULL, size_t nonceLength=0, const byte *personalization=NULL, size_t personalizationLength=0)
Construct a Hash DRBG.
Definition: drbg.h:210
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:158
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: drbg.h:352
unsigned int SecurityStrength() const
Provides the security strength.
Definition: drbg.h:221
HMAC_DRBG(const byte *entropy=NULL, size_t entropyLength=STRENGTH, const byte *nonce=NULL, size_t nonceLength=0, const byte *personalization=NULL, size_t personalizationLength=0)
Construct a HMAC DRBG.
Definition: drbg.h:332
SHA-256 message digest.
Definition: sha.h:64
unsigned int MaxRequestBeforeReseed() const
Provides the maximum number of requests before a reseed.
Definition: drbg.h:228
void IncrementCounterByOne(byte *inout, unsigned int size)
Performs an addition with carry on a block of bytes.
Definition: misc.h:1279
unsigned int SeedLength() const
Provides the seed length.
Definition: drbg.h:344
void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte *additional, size_t additionaLength)
Update RNG state with additional unpredictable values.
Definition: drbg.h:233
unsigned int MinEntropyLength() const
Provides the minimum entropy size.
Definition: drbg.h:345
Abstract base classes that provide a uniform interface to this library.
void GenerateBlock(const byte *additional, size_t additionaLength, byte *output, size_t size)
Generate random array of bytes.
Definition: drbg.h:361
Interface for random number generators.
Definition: cryptlib.h:1413
SecBlock<byte> typedef.
Definition: secblock.h:1090
unsigned int MinEntropyLength() const
Provides the minimum entropy size.
Definition: drbg.h:223
Classes and functions for secure memory allocations.
Classes for HMAC message authentication codes.
unsigned int MinNonceLength() const
Provides the minimum nonce size.
Definition: drbg.h:225
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: drbg.h:230
void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte *additional, size_t additionaLength)
Update RNG state with additional unpredictable values.
Definition: drbg.h:355
Exception thrown when a NIST DRBG encounters an error.
Definition: drbg.h:30
void GenerateBlock(const byte *additional, size_t additionaLength, byte *output, size_t size)
Generate random array of bytes.
Definition: drbg.h:239
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianness.
Definition: misc.h:2168
void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: drbg.h:236
HMAC_DRBG from SP 800-90A Rev 1 (June 2015)
Definition: drbg.h:289
unsigned int MinNonceLength() const
Provides the minimum nonce size.
Definition: drbg.h:347
unsigned int SeedLength() const
Provides the seed length.
Definition: drbg.h:222
byte order is big-endian
Definition: cryptlib.h:147
unsigned int MaxBytesPerRequest() const
Provides the maximum size of a request to GenerateBlock.
Definition: drbg.h:227
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:630
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:69
Classes for SHA-1 and SHA-2 family of message digests.
Hash_DRBG from SP 800-90A Rev 1 (June 2015)
Definition: drbg.h:167
Interface for NIST DRBGs from SP 800-90A.
Definition: drbg.h:26
unsigned int MaxRequestBeforeReseed() const
Provides the maximum number of requests before a reseed.
Definition: drbg.h:350
unsigned int MaxEntropyLength() const
Provides the maximum entropy size.
Definition: drbg.h:224
unsigned int MaxNonceLength() const
Provides the maximum nonce size.
Definition: drbg.h:226
unsigned int MaxBytesPerRequest() const
Provides the maximum size of a request to GenerateBlock.
Definition: drbg.h:349
unsigned int MaxEntropyLength() const
Provides the maximum entropy size.
Definition: drbg.h:346
virtual bool CanIncorporateEntropy() const
Determines if a generator can accept additional entropy.
Definition: drbg.h:43
Crypto++ library namespace.
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Definition: drbg.h:242
Ensures an object is not copyable.
Definition: misc.h:236
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Definition: drbg.h:364
unsigned int MaxNonceLength() const
Provides the maximum nonce size.
Definition: drbg.h:348
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:828
void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: drbg.h:358
unsigned int SecurityStrength() const
Provides the security strength.
Definition: drbg.h:343