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