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