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 /// \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  std::memset(m_c, 0x00, m_c.size());
211  std::memset(m_v, 0x00, m_v.size());
212 
213  if (entropy != NULLPTR && entropyLength != 0)
214  DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
215  }
216 
217  unsigned int SecurityStrength() const {return SECURITY_STRENGTH;}
218  unsigned int SeedLength() const {return SEED_LENGTH;}
219  unsigned int MinEntropyLength() const {return MINIMUM_ENTROPY;}
220  unsigned int MaxEntropyLength() const {return MAXIMUM_ENTROPY;}
221  unsigned int MinNonceLength() const {return MINIMUM_NONCE;}
222  unsigned int MaxNonceLength() const {return MAXIMUM_NONCE;}
223  unsigned int MaxBytesPerRequest() const {return MAXIMUM_BYTES_PER_REQUEST;}
224  unsigned int MaxRequestBeforeReseed() const {return MAXIMUM_REQUESTS_BEFORE_RESEED;}
225 
226  void IncorporateEntropy(const byte *input, size_t length)
227  {return DRBG_Reseed(input, length, NULLPTR, 0);}
228 
229  void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte* additional, size_t additionaLength)
230  {return DRBG_Reseed(entropy, entropyLength, additional, additionaLength);}
231 
232  void GenerateBlock(byte *output, size_t size)
233  {return Hash_Generate(NULLPTR, 0, output, size);}
234 
235  void GenerateBlock(const byte* additional, size_t additionaLength, byte *output, size_t size)
236  {return Hash_Generate(additional, additionaLength, output, size);}
237 
238  std::string AlgorithmProvider() const
239  {/*Hack*/HASH hash; return hash.AlgorithmProvider();}
240 
241 protected:
242  // 10.1.1.2 Instantiation of Hash_DRBG (p.39)
243  void DRBG_Instantiate(const byte* entropy, size_t entropyLength, const byte* nonce, size_t nonceLength,
244  const byte* personalization, size_t personalizationLength);
245 
246  // 10.1.1.3 Reseeding a Hash_DRBG Instantiation (p.40)
247  void DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength);
248 
249  // 10.1.1.4 Generating Pseudorandom Bits Using Hash_DRBG (p.41)
250  void Hash_Generate(const byte* additional, size_t additionaLength, byte *output, size_t size);
251 
252  // 10.3.1 Derivation Function Using a Hash Function (Hash_df) (p.49)
253  void Hash_Update(const byte* input1, size_t inlen1, const byte* input2, size_t inlen2,
254  const byte* input3, size_t inlen3, const byte* input4, size_t inlen4, byte* output, size_t outlen);
255 
256 private:
257  HASH m_hash;
258  SecByteBlock m_c, m_v, m_temp;
259  word64 m_reseed;
260 };
261 
262 // typedef Hash_DRBG<SHA1, 128/8, 440/8> Hash_SHA1_DRBG;
263 // typedef Hash_DRBG<SHA256, 128/8, 440/8> Hash_SHA256_DRBG;
264 // typedef Hash_DRBG<SHA384, 256/8, 888/8> Hash_SHA384_DRBG;
265 // typedef Hash_DRBG<SHA512, 256/8, 888/8> Hash_SHA512_DRBG;
266 
267 // *************************************************************
268 
269 /// \tparam HASH NIST approved hash derived from HashTransformation
270 /// \tparam STRENGTH security strength, in bytes
271 /// \tparam SEEDLENGTH seed length, in bytes
272 /// \brief HMAC_DRBG from SP 800-90A Rev 1 (June 2015)
273 /// \details The NIST HMAC DRBG is instantiated with a number of parameters. Two of the parameters,
274 /// Security Strength and Seed Length, depend on the hash and are specified as template parameters.
275 /// The remaining parameters are included in the class. The parameters and their values are listed
276 /// in NIST SP 800-90A Rev. 1, Table 2: Definitions for Hash-Based DRBG Mechanisms (p.38).
277 /// \details Some parameters have been reduce to fit C++ datatypes. For example, NIST allows upto 2<sup>48</sup> requests
278 /// before a reseed. However, HMAC_DRBG limits it to <tt>INT_MAX</tt> due to the limited data range of an int.
279 /// \sa <A HREF="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf">Recommendation
280 /// for Random Number Generation Using Deterministic Random Bit Generators, Rev 1 (June 2015)</A>
281 /// \since Crypto++ 6.0
282 template <typename HASH=SHA256, unsigned int STRENGTH=128/8, unsigned int SEEDLENGTH=440/8>
283 class HMAC_DRBG : public NIST_DRBG, public NotCopyable
284 {
285 public:
286  CRYPTOPP_CONSTANT(SECURITY_STRENGTH=STRENGTH)
287  CRYPTOPP_CONSTANT(SEED_LENGTH=SEEDLENGTH)
288  CRYPTOPP_CONSTANT(MINIMUM_ENTROPY=STRENGTH)
289  CRYPTOPP_CONSTANT(MINIMUM_NONCE=0)
290  CRYPTOPP_CONSTANT(MINIMUM_ADDITIONAL=0)
291  CRYPTOPP_CONSTANT(MINIMUM_PERSONALIZATION=0)
292  CRYPTOPP_CONSTANT(MAXIMUM_ENTROPY=INT_MAX)
293  CRYPTOPP_CONSTANT(MAXIMUM_NONCE=INT_MAX)
294  CRYPTOPP_CONSTANT(MAXIMUM_ADDITIONAL=INT_MAX)
295  CRYPTOPP_CONSTANT(MAXIMUM_PERSONALIZATION=INT_MAX)
296  CRYPTOPP_CONSTANT(MAXIMUM_BYTES_PER_REQUEST=65536)
297  CRYPTOPP_CONSTANT(MAXIMUM_REQUESTS_BEFORE_RESEED=INT_MAX)
298 
299  static std::string StaticAlgorithmName() { return std::string("HMAC_DRBG(") + HASH::StaticAlgorithmName() + std::string(")"); }
300 
301  /// \brief Construct a HMAC DRBG
302  /// \param entropy the entropy to instantiate the generator
303  /// \param entropyLength the size of the entropy buffer
304  /// \param nonce additional input to instantiate the generator
305  /// \param nonceLength the size of the nonce buffer
306  /// \param personalization additional input to instantiate the generator
307  /// \param personalizationLength the size of the personalization buffer
308  /// \throws NIST_DRBG::Err if the generator is instantiated with insufficient entropy
309  /// \details All NIST DRBGs must be instaniated with at least <tt>MINIMUM_ENTROPY</tt> bytes of entropy.
310  /// The byte array for <tt>entropy</tt> must meet <A HREF ="http://csrc.nist.gov/publications/PubsSPs.html">NIST
311  /// SP 800-90B or SP 800-90C</A> requirements.
312  /// \details The <tt>nonce</tt> and <tt>personalization</tt> are optional byte arrays. If <tt>nonce</tt> is supplied,
313  /// then it should be at least <tt>MINIMUM_NONCE</tt> bytes of entropy.
314  /// \details An example of instantiating a SHA256 generator is shown below.
315  /// The example provides more entropy than required for SHA256. The <tt>NonblockingRng</tt> meets the
316  /// requirements of <A HREF ="http://csrc.nist.gov/publications/PubsSPs.html">NIST SP 800-90B or SP 800-90C</A>.
317  /// RDRAND() and RDSEED() generators would work as well.
318  /// <pre>
319  /// SecByteBlock entropy(48), result(128);
320  /// NonblockingRng prng;
321  /// RandomNumberSource rns(prng, entropy.size(), new ArraySink(entropy, entropy.size()));
322  ///
323  /// HMAC_DRBG<SHA256, 128/8, 440/8> drbg(entropy, 32, entropy+32, 16);
324  /// drbg.GenerateBlock(result, result.size());
325  /// </pre>
326  HMAC_DRBG(const byte* entropy=NULLPTR, size_t entropyLength=STRENGTH, const byte* nonce=NULLPTR,
327  size_t nonceLength=0, const byte* personalization=NULLPTR, size_t personalizationLength=0)
328  : NIST_DRBG(), m_k(HASH::DIGESTSIZE), m_v(HASH::DIGESTSIZE), m_reseed(0)
329  {
330  std::memset(m_k, 0x00, m_k.size());
331  std::memset(m_v, 0x00, m_v.size());
332 
333  if (entropy != NULLPTR && entropyLength != 0)
334  DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
335  }
336 
337  unsigned int SecurityStrength() const {return SECURITY_STRENGTH;}
338  unsigned int SeedLength() const {return SEED_LENGTH;}
339  unsigned int MinEntropyLength() const {return MINIMUM_ENTROPY;}
340  unsigned int MaxEntropyLength() const {return MAXIMUM_ENTROPY;}
341  unsigned int MinNonceLength() const {return MINIMUM_NONCE;}
342  unsigned int MaxNonceLength() const {return MAXIMUM_NONCE;}
343  unsigned int MaxBytesPerRequest() const {return MAXIMUM_BYTES_PER_REQUEST;}
344  unsigned int MaxRequestBeforeReseed() const {return MAXIMUM_REQUESTS_BEFORE_RESEED;}
345 
346  void IncorporateEntropy(const byte *input, size_t length)
347  {return DRBG_Reseed(input, length, NULLPTR, 0);}
348 
349  void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte* additional, size_t additionaLength)
350  {return DRBG_Reseed(entropy, entropyLength, additional, additionaLength);}
351 
352  void GenerateBlock(byte *output, size_t size)
353  {return HMAC_Generate(NULLPTR, 0, output, size);}
354 
355  void GenerateBlock(const byte* additional, size_t additionaLength, byte *output, size_t size)
356  {return HMAC_Generate(additional, additionaLength, output, size);}
357 
358  std::string AlgorithmProvider() const
359  {/*Hack*/HASH hash; return hash.AlgorithmProvider();}
360 
361 protected:
362  // 10.1.2.3 Instantiation of HMAC_DRBG (p.45)
363  void DRBG_Instantiate(const byte* entropy, size_t entropyLength, const byte* nonce, size_t nonceLength,
364  const byte* personalization, size_t personalizationLength);
365 
366  // 10.1.2.4 Reseeding a HMAC_DRBG Instantiation (p.46)
367  void DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength);
368 
369  // 10.1.2.5 Generating Pseudorandom Bits Using HMAC_DRBG (p.46)
370  void HMAC_Generate(const byte* additional, size_t additionaLength, byte *output, size_t size);
371 
372  // 10.1.2.2 Derivation Function Using a HMAC Function (HMAC_Update) (p.44)
373  void HMAC_Update(const byte* input1, size_t inlen1, const byte* input2, size_t inlen2, const byte* input3, size_t inlen3);
374 
375 private:
376  HMAC<HASH> m_hmac;
377  SecByteBlock m_k, m_v;
378  word64 m_reseed;
379 };
380 
381 // typedef HMAC_DRBG<SHA1, 128/8, 440/8> HMAC_SHA1_DRBG;
382 // typedef HMAC_DRBG<SHA256, 128/8, 440/8> HMAC_SHA256_DRBG;
383 // typedef HMAC_DRBG<SHA384, 256/8, 888/8> HMAC_SHA384_DRBG;
384 // typedef HMAC_DRBG<SHA512, 256/8, 888/8> HMAC_SHA512_DRBG;
385 
386 // *************************************************************
387 
388 // 10.1.1.2 Instantiation of Hash_DRBG (p.39)
389 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
390 void Hash_DRBG<HASH, STRENGTH, SEEDLENGTH>::DRBG_Instantiate(const byte* entropy, size_t entropyLength, const byte* nonce, size_t nonceLength,
391  const byte* personalization, size_t personalizationLength)
392 {
393  // SP 800-90A, 8.6.3: The entropy input shall have entropy that is equal to or greater than the security
394  // strength of the instantiation. Additional entropy may be provided in the nonce or the optional
395  // personalization string during instantiation, or in the additional input during reseeding and generation,
396  // but this is not required and does not increase the "official" security strength of the DRBG
397  // instantiation that is recorded in the internal state.
398  CRYPTOPP_ASSERT(entropyLength >= MINIMUM_ENTROPY);
399  if (entropyLength < MINIMUM_ENTROPY)
400  throw NIST_DRBG::Err("Hash_DRBG", "Insufficient entropy during instantiate");
401 
402  // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
403  // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
404  CRYPTOPP_ASSERT(entropyLength <= MAXIMUM_ENTROPY);
405  CRYPTOPP_ASSERT(nonceLength <= MAXIMUM_NONCE);
406  CRYPTOPP_ASSERT(personalizationLength <= MAXIMUM_PERSONALIZATION);
407 
408  const byte zero = 0;
409  SecByteBlock t1(SEEDLENGTH), t2(SEEDLENGTH);
410  Hash_Update(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength, NULLPTR, 0, t1, t1.size());
411  Hash_Update(&zero, 1, t1, t1.size(), NULLPTR, 0, NULLPTR, 0, t2, t2.size());
412 
413  m_v.swap(t1); m_c.swap(t2);
414  m_reseed = 1;
415 }
416 
417 // 10.1.1.3 Reseeding a Hash_DRBG Instantiation (p.40)
418 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
419 void Hash_DRBG<HASH, STRENGTH, SEEDLENGTH>::DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength)
420 {
421  // SP 800-90A, 8.6.3: The entropy input shall have entropy that is equal to or greater than the security
422  // strength of the instantiation. Additional entropy may be provided in the nonce or the optional
423  // personalization string during instantiation, or in the additional input during reseeding and generation,
424  // but this is not required and does not increase the "official" security strength of the DRBG
425  // instantiation that is recorded in the internal state..
426  CRYPTOPP_ASSERT(entropyLength >= MINIMUM_ENTROPY);
427  if (entropyLength < MINIMUM_ENTROPY)
428  throw NIST_DRBG::Err("Hash_DRBG", "Insufficient entropy during reseed");
429 
430  // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
431  // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
432  CRYPTOPP_ASSERT(entropyLength <= MAXIMUM_ENTROPY);
433  CRYPTOPP_ASSERT(additionaLength <= MAXIMUM_ADDITIONAL);
434 
435  const byte zero = 0, one = 1;
436  SecByteBlock t1(SEEDLENGTH), t2(SEEDLENGTH);
437  Hash_Update(&one, 1, m_v, m_v.size(), entropy, entropyLength, additional, additionaLength, t1, t1.size());
438  Hash_Update(&zero, 1, t1, t1.size(), NULLPTR, 0, NULLPTR, 0, t2, t2.size());
439 
440  m_v.swap(t1); m_c.swap(t2);
441  m_reseed = 1;
442 }
443 
444 // 10.1.1.4 Generating Pseudorandom Bits Using Hash_DRBG (p.41)
445 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
446 void Hash_DRBG<HASH, STRENGTH, SEEDLENGTH>::Hash_Generate(const byte* additional, size_t additionaLength, byte *output, size_t size)
447 {
448  // Step 1
449  if (static_cast<word64>(m_reseed) >= static_cast<word64>(MaxRequestBeforeReseed()))
450  throw NIST_DRBG::Err("Hash_DRBG", "Reseed required");
451 
452  if (size > MaxBytesPerRequest())
453  throw NIST_DRBG::Err("Hash_DRBG", "Request size exceeds limit");
454 
455  // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
456  // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
457  CRYPTOPP_ASSERT(additionaLength <= MAXIMUM_ADDITIONAL);
458 
459  // Step 2
460  if (additional && additionaLength)
461  {
462  const byte two = 2;
463  m_temp.New(HASH::DIGESTSIZE);
464 
465  m_hash.Update(&two, 1);
466  m_hash.Update(m_v, m_v.size());
467  m_hash.Update(additional, additionaLength);
468  m_hash.Final(m_temp);
469 
470  CRYPTOPP_ASSERT(SEEDLENGTH >= HASH::DIGESTSIZE);
471  int carry=0, j=HASH::DIGESTSIZE-1, i=SEEDLENGTH-1;
472  while (j>=0)
473  {
474  carry = m_v[i] + m_temp[j] + carry;
475  m_v[i] = static_cast<byte>(carry);
476  i--; j--; carry >>= 8;
477  }
478  while (i>=0)
479  {
480  carry = m_v[i] + carry;
481  m_v[i] = static_cast<byte>(carry);
482  i--; carry >>= 8;
483  }
484  }
485 
486  // Step 3
487  {
488  m_temp.Assign(m_v);
489  while (size)
490  {
491  m_hash.Update(m_temp, m_temp.size());
492  size_t count = STDMIN(size, (size_t)HASH::DIGESTSIZE);
493  m_hash.TruncatedFinal(output, count);
494 
495  IncrementCounterByOne(m_temp, static_cast<unsigned int>(m_temp.size()));
496  size -= count; output += count;
497  }
498  }
499 
500  // Steps 4-7
501  {
502  const byte three = 3;
503  m_temp.New(HASH::DIGESTSIZE);
504 
505  m_hash.Update(&three, 1);
506  m_hash.Update(m_v, m_v.size());
507  m_hash.Final(m_temp);
508 
509  CRYPTOPP_ASSERT(SEEDLENGTH >= HASH::DIGESTSIZE);
510  CRYPTOPP_ASSERT(HASH::DIGESTSIZE >= sizeof(m_reseed));
511  int carry=0, k=sizeof(m_reseed)-1, j=HASH::DIGESTSIZE-1, i=SEEDLENGTH-1;
512 
513  while (k>=0)
514  {
515  carry = m_v[i] + m_c[i] + m_temp[j] + GetByte<word64>(BIG_ENDIAN_ORDER, m_reseed, k) + carry;
516  m_v[i] = static_cast<byte>(carry);
517  i--; j--; k--; carry >>= 8;
518  }
519 
520  while (j>=0)
521  {
522  carry = m_v[i] + m_c[i] + m_temp[j] + carry;
523  m_v[i] = static_cast<byte>(carry);
524  i--; j--; carry >>= 8;
525  }
526 
527  while (i>=0)
528  {
529  carry = m_v[i] + m_c[i] + carry;
530  m_v[i] = static_cast<byte>(carry);
531  i--; carry >>= 8;
532  }
533  }
534 
535  m_reseed++;
536 }
537 
538 // 10.3.1 Derivation Function Using a Hash Function (Hash_df) (p.49)
539 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
540 void Hash_DRBG<HASH, STRENGTH, SEEDLENGTH>::Hash_Update(const byte* input1, size_t inlen1, const byte* input2, size_t inlen2,
541  const byte* input3, size_t inlen3, const byte* input4, size_t inlen4, byte* output, size_t outlen)
542 {
543  byte counter = 1;
544  word32 bits = ConditionalByteReverse(BIG_ENDIAN_ORDER, static_cast<word32>(outlen*8));
545 
546  while (outlen)
547  {
548  m_hash.Update(&counter, 1);
549  m_hash.Update(reinterpret_cast<const byte*>(&bits), 4);
550 
551  if (input1 && inlen1)
552  m_hash.Update(input1, inlen1);
553  if (input2 && inlen2)
554  m_hash.Update(input2, inlen2);
555  if (input3 && inlen3)
556  m_hash.Update(input3, inlen3);
557  if (input4 && inlen4)
558  m_hash.Update(input4, inlen4);
559 
560  size_t count = STDMIN(outlen, (size_t)HASH::DIGESTSIZE);
561  m_hash.TruncatedFinal(output, count);
562 
563  output += count; outlen -= count;
564  counter++;
565  }
566 }
567 
568 // *************************************************************
569 
570 // 10.1.2.3 Instantiation of HMAC_DRBG (p.45)
571 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
572 void HMAC_DRBG<HASH, STRENGTH, SEEDLENGTH>::DRBG_Instantiate(const byte* entropy, size_t entropyLength, const byte* nonce, size_t nonceLength,
573  const byte* personalization, size_t personalizationLength)
574 {
575  // SP 800-90A, 8.6.3: The entropy input shall have entropy that is equal to or greater than the security
576  // strength of the instantiation. Additional entropy may be provided in the nonce or the optional
577  // personalization string during instantiation, or in the additional input during reseeding and generation,
578  // but this is not required and does not increase the "official" security strength of the DRBG
579  // instantiation that is recorded in the internal state.
580  CRYPTOPP_ASSERT(entropyLength >= MINIMUM_ENTROPY);
581  if (entropyLength < MINIMUM_ENTROPY)
582  throw NIST_DRBG::Err("HMAC_DRBG", "Insufficient entropy during instantiate");
583 
584  // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
585  // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
586  CRYPTOPP_ASSERT(entropyLength <= MAXIMUM_ENTROPY);
587  CRYPTOPP_ASSERT(nonceLength <= MAXIMUM_NONCE);
588  CRYPTOPP_ASSERT(personalizationLength <= MAXIMUM_PERSONALIZATION);
589 
590  std::fill(m_k.begin(), m_k.begin()+m_k.size(), byte(0));
591  std::fill(m_v.begin(), m_v.begin()+m_v.size(), byte(1));
592 
593  HMAC_Update(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
594  m_reseed = 1;
595 }
596 
597 // 10.1.2.4 Reseeding a HMAC_DRBG Instantiation (p.46)
598 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
599 void HMAC_DRBG<HASH, STRENGTH, SEEDLENGTH>::DRBG_Reseed(const byte* entropy, size_t entropyLength, const byte* additional, size_t additionaLength)
600 {
601  // SP 800-90A, 8.6.3: The entropy input shall have entropy that is equal to or greater than the security
602  // strength of the instantiation. Additional entropy may be provided in the nonce or the optional
603  // personalization string during instantiation, or in the additional input during reseeding and generation,
604  // but this is not required and does not increase the "official" security strength of the DRBG
605  // instantiation that is recorded in the internal state..
606  CRYPTOPP_ASSERT(entropyLength >= MINIMUM_ENTROPY);
607  if (entropyLength < MINIMUM_ENTROPY)
608  throw NIST_DRBG::Err("HMAC_DRBG", "Insufficient entropy during reseed");
609 
610  // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
611  // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
612  CRYPTOPP_ASSERT(entropyLength <= MAXIMUM_ENTROPY);
613  CRYPTOPP_ASSERT(additionaLength <= MAXIMUM_ADDITIONAL);
614 
615  HMAC_Update(entropy, entropyLength, additional, additionaLength, NULLPTR, 0);
616  m_reseed = 1;
617 }
618 
619 // 10.1.2.5 Generating Pseudorandom Bits Using HMAC_DRBG (p.46)
620 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
621 void HMAC_DRBG<HASH, STRENGTH, SEEDLENGTH>::HMAC_Generate(const byte* additional, size_t additionaLength, byte *output, size_t size)
622 {
623  // Step 1
624  if (static_cast<word64>(m_reseed) >= static_cast<word64>(MaxRequestBeforeReseed()))
625  throw NIST_DRBG::Err("HMAC_DRBG", "Reseed required");
626 
627  if (size > MaxBytesPerRequest())
628  throw NIST_DRBG::Err("HMAC_DRBG", "Request size exceeds limit");
629 
630  // SP 800-90A, Section 9, says we should throw if we have too much entropy, too large a nonce,
631  // or too large a persoanlization string. We warn in Debug builds, but do nothing in Release builds.
632  CRYPTOPP_ASSERT(additionaLength <= MAXIMUM_ADDITIONAL);
633 
634  // Step 2
635  if (additional && additionaLength)
636  HMAC_Update(additional, additionaLength, NULLPTR, 0, NULLPTR, 0);
637 
638  // Step 3
639  m_hmac.SetKey(m_k, m_k.size());
640 
641  while (size)
642  {
643  m_hmac.Update(m_v, m_v.size());
644  m_hmac.TruncatedFinal(m_v, m_v.size());
645 
646  size_t count = STDMIN(size, (size_t)HASH::DIGESTSIZE);
647  memcpy(output, m_v, count);
648  size -= count; output += count;
649  }
650 
651  HMAC_Update(additional, additionaLength, NULLPTR, 0, NULLPTR, 0);
652  m_reseed++;
653 }
654 
655 // 10.1.2.2 Derivation Function Using a HMAC Function (HMAC_Update) (p.44)
656 template <typename HASH, unsigned int STRENGTH, unsigned int SEEDLENGTH>
657 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)
658 {
659  const byte zero = 0, one = 1;
660 
661  // Step 1
662  m_hmac.SetKey(m_k, m_k.size());
663  m_hmac.Update(m_v, m_v.size());
664  m_hmac.Update(&zero, 1);
665 
666  if (input1 && inlen1)
667  m_hmac.Update(input1, inlen1);
668  if (input2 && inlen2)
669  m_hmac.Update(input2, inlen2);
670  if (input3 && inlen3)
671  m_hmac.Update(input3, inlen3);
672 
673  m_hmac.TruncatedFinal(m_k, m_k.size());
674 
675  // Step 2
676  m_hmac.SetKey(m_k, m_k.size());
677  m_hmac.Update(m_v, m_v.size());
678 
679  m_hmac.TruncatedFinal(m_v, m_v.size());
680 
681  // Step 3
682  if ((inlen1 | inlen2 | inlen3) == 0)
683  return;
684 
685  // Step 4
686  m_hmac.SetKey(m_k, m_k.size());
687  m_hmac.Update(m_v, m_v.size());
688  m_hmac.Update(&one, 1);
689 
690  if (input1 && inlen1)
691  m_hmac.Update(input1, inlen1);
692  if (input2 && inlen2)
693  m_hmac.Update(input2, inlen2);
694  if (input3 && inlen3)
695  m_hmac.Update(input3, inlen3);
696 
697  m_hmac.TruncatedFinal(m_k, m_k.size());
698 
699  // Step 5
700  m_hmac.SetKey(m_k, m_k.size());
701  m_hmac.Update(m_v, m_v.size());
702 
703  m_hmac.TruncatedFinal(m_v, m_v.size());
704 }
705 
706 NAMESPACE_END
707 
708 #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:158
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: drbg.h:346
unsigned int SecurityStrength() const
Provides the security strength.
Definition: drbg.h:217
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:326
SHA-256 message digest.
Definition: sha.h:64
unsigned int MaxRequestBeforeReseed() const
Provides the maximum number of requests before a reseed.
Definition: drbg.h:224
void IncrementCounterByOne(byte *inout, unsigned int size)
Performs an addition with carry on a block of bytes.
Definition: misc.h:1262
unsigned int SeedLength() const
Provides the seed length.
Definition: drbg.h:338
void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte *additional, size_t additionaLength)
Update RNG state with additional unpredictable values.
Definition: drbg.h:229
unsigned int MinEntropyLength() const
Provides the minimum entropy size.
Definition: drbg.h:339
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:355
Interface for random number generators.
Definition: cryptlib.h:1383
SecBlock<byte> typedef.
Definition: secblock.h:1058
unsigned int MinEntropyLength() const
Provides the minimum entropy size.
Definition: drbg.h:219
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:221
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition: drbg.h:226
void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte *additional, size_t additionaLength)
Update RNG state with additional unpredictable values.
Definition: drbg.h:349
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:235
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianness.
Definition: misc.h:2191
void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: drbg.h:232
HMAC_DRBG from SP 800-90A Rev 1 (June 2015)
Definition: drbg.h:283
unsigned int MinNonceLength() const
Provides the minimum nonce size.
Definition: drbg.h:341
unsigned int SeedLength() const
Provides the seed length.
Definition: drbg.h:218
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:223
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:602
#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:163
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:344
unsigned int MaxEntropyLength() const
Provides the maximum entropy size.
Definition: drbg.h:220
unsigned int MaxNonceLength() const
Provides the maximum nonce size.
Definition: drbg.h:222
unsigned int MaxBytesPerRequest() const
Provides the maximum size of a request to GenerateBlock.
Definition: drbg.h:343
unsigned int MaxEntropyLength() const
Provides the maximum entropy size.
Definition: drbg.h:340
virtual bool CanIncorporateEntropy() const
Determines if a generator can accept additional entropy.
Definition: drbg.h:41
Crypto++ library namespace.
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Definition: drbg.h:238
Ensures an object is not copyable.
Definition: misc.h:230
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Definition: drbg.h:358
unsigned int MaxNonceLength() const
Provides the maximum nonce size.
Definition: drbg.h:342
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:797
void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
Definition: drbg.h:352
unsigned int SecurityStrength() const
Provides the security strength.
Definition: drbg.h:337