9 #ifndef CRYPTOPP_NIST_DRBG_H 10 #define CRYPTOPP_NIST_DRBG_H 31 explicit Err(
const std::string &c,
const std::string &m)
51 virtual void IncorporateEntropy(
const byte *input,
size_t length)=0;
64 virtual void IncorporateEntropy(
const byte *entropy,
size_t entropyLength,
const byte* additional,
size_t additionaLength)=0;
71 virtual void GenerateBlock(byte *output,
size_t size)=0;
83 virtual void GenerateBlock(
const byte* additional,
size_t additionaLength, byte *output,
size_t size)=0;
88 virtual unsigned int SecurityStrength()
const=0;
94 virtual unsigned int SeedLength()
const=0;
102 virtual unsigned int MinEntropyLength()
const=0;
110 virtual unsigned int MaxEntropyLength()
const=0;
117 virtual unsigned int MinNonceLength()
const=0;
125 virtual unsigned int MaxNonceLength()
const=0;
130 virtual unsigned int MaxBytesPerRequest()
const=0;
137 virtual unsigned int MaxRequestBeforeReseed()
const=0;
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;
143 virtual void DRBG_Reseed(
const byte* entropy,
size_t entropyLength,
const byte* additional,
size_t additionaLength)=0;
162 template <
typename HASH=
SHA256,
unsigned int STRENGTH=128/8,
unsigned int SEEDLENGTH=440/8>
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)
179 static std::string StaticAlgorithmName() {
return std::string(
"Hash_DRBG(") + HASH::StaticAlgorithmName() + std::string(
")"); }
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)
210 if (entropy != NULLPTR && entropyLength != 0)
211 DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
224 {
return DRBG_Reseed(input, length, NULLPTR, 0);}
226 void IncorporateEntropy(
const byte *entropy,
size_t entropyLength,
const byte* additional,
size_t additionaLength)
227 {
return DRBG_Reseed(entropy, entropyLength, additional, additionaLength);}
230 {
return Hash_Generate(NULLPTR, 0, output, size);}
232 void GenerateBlock(
const byte* additional,
size_t additionaLength, byte *output,
size_t size)
233 {
return Hash_Generate(additional, additionaLength, output, size);}
236 {HASH hash;
return hash.AlgorithmProvider();}
240 void DRBG_Instantiate(
const byte* entropy,
size_t entropyLength,
const byte* nonce,
size_t nonceLength,
241 const byte* personalization,
size_t personalizationLength);
244 void DRBG_Reseed(
const byte* entropy,
size_t entropyLength,
const byte* additional,
size_t additionaLength);
247 void Hash_Generate(
const byte* additional,
size_t additionaLength, byte *output,
size_t size);
250 void Hash_Update(
const byte* input1,
size_t inlen1,
const byte* input2,
size_t inlen2,
251 const byte* input3,
size_t inlen3,
const byte* input4,
size_t inlen4, byte* output,
size_t outlen);
279 template <
typename HASH=
SHA256,
unsigned int STRENGTH=128/8,
unsigned int SEEDLENGTH=440/8>
283 CRYPTOPP_CONSTANT(SECURITY_STRENGTH=STRENGTH)
284 CRYPTOPP_CONSTANT(SEED_LENGTH=SEEDLENGTH)
285 CRYPTOPP_CONSTANT(MINIMUM_ENTROPY=STRENGTH)
286 CRYPTOPP_CONSTANT(MINIMUM_NONCE=0)
287 CRYPTOPP_CONSTANT(MINIMUM_ADDITIONAL=0)
288 CRYPTOPP_CONSTANT(MINIMUM_PERSONALIZATION=0)
289 CRYPTOPP_CONSTANT(MAXIMUM_ENTROPY=INT_MAX)
290 CRYPTOPP_CONSTANT(MAXIMUM_NONCE=INT_MAX)
291 CRYPTOPP_CONSTANT(MAXIMUM_ADDITIONAL=INT_MAX)
292 CRYPTOPP_CONSTANT(MAXIMUM_PERSONALIZATION=INT_MAX)
293 CRYPTOPP_CONSTANT(MAXIMUM_BYTES_PER_REQUEST=65536)
294 CRYPTOPP_CONSTANT(MAXIMUM_REQUESTS_BEFORE_RESEED=INT_MAX)
296 static std::string StaticAlgorithmName() {
return std::string(
"HMAC_DRBG(") + HASH::StaticAlgorithmName() + std::string(
")"); }
323 HMAC_DRBG(
const byte* entropy=NULLPTR,
size_t entropyLength=STRENGTH,
const byte* nonce=NULLPTR,
324 size_t nonceLength=0,
const byte* personalization=NULLPTR,
size_t personalizationLength=0)
325 :
NIST_DRBG(), m_k(HASH::DIGESTSIZE), m_v(HASH::DIGESTSIZE), m_reseed(0)
327 if (entropy != NULLPTR && entropyLength != 0)
328 DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
341 {
return DRBG_Reseed(input, length, NULLPTR, 0);}
343 void IncorporateEntropy(
const byte *entropy,
size_t entropyLength,
const byte* additional,
size_t additionaLength)
344 {
return DRBG_Reseed(entropy, entropyLength, additional, additionaLength);}
347 {
return HMAC_Generate(NULLPTR, 0, output, size);}
349 void GenerateBlock(
const byte* additional,
size_t additionaLength, byte *output,
size_t size)
350 {
return HMAC_Generate(additional, additionaLength, output, size);}
353 {HASH hash;
return hash.AlgorithmProvider();}
357 void DRBG_Instantiate(
const byte* entropy,
size_t entropyLength,
const byte* nonce,
size_t nonceLength,
358 const byte* personalization,
size_t personalizationLength);
361 void DRBG_Reseed(
const byte* entropy,
size_t entropyLength,
const byte* additional,
size_t additionaLength);
364 void HMAC_Generate(
const byte* additional,
size_t additionaLength, byte *output,
size_t size);
367 void HMAC_Update(
const byte* input1,
size_t inlen1,
const byte* input2,
size_t inlen2,
const byte* input3,
size_t inlen3);
383 template <
typename HASH,
unsigned int STRENGTH,
unsigned int SEEDLENGTH>
385 const byte* personalization,
size_t personalizationLength)
393 if (entropyLength < MINIMUM_ENTROPY)
394 throw NIST_DRBG::Err(
"Hash_DRBG",
"Insufficient entropy during instantiate");
404 Hash_Update(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength, NULLPTR, 0, t1, t1.size());
405 Hash_Update(&zero, 1, t1, t1.size(), NULLPTR, 0, NULLPTR, 0, t2, t2.size());
407 m_v.swap(t1); m_c.swap(t2);
412 template <
typename HASH,
unsigned int STRENGTH,
unsigned int SEEDLENGTH>
421 if (entropyLength < MINIMUM_ENTROPY)
422 throw NIST_DRBG::Err(
"Hash_DRBG",
"Insufficient entropy during reseed");
429 const byte zero = 0, one = 1;
431 Hash_Update(&one, 1, m_v, m_v.size(), entropy, entropyLength, additional, additionaLength, t1, t1.size());
432 Hash_Update(&zero, 1, t1, t1.size(), NULLPTR, 0, NULLPTR, 0, t2, t2.size());
434 m_v.swap(t1); m_c.swap(t2);
439 template <
typename HASH,
unsigned int STRENGTH,
unsigned int SEEDLENGTH>
443 if (static_cast<word64>(m_reseed) >= static_cast<word64>(MaxRequestBeforeReseed()))
446 if (size > MaxBytesPerRequest())
454 if (additional && additionaLength)
457 m_temp.New(HASH::DIGESTSIZE);
459 m_hash.Update(&two, 1);
460 m_hash.Update(m_v, m_v.size());
461 m_hash.Update(additional, additionaLength);
462 m_hash.Final(m_temp);
465 int carry=0, j=HASH::DIGESTSIZE-1, i=SEEDLENGTH-1;
468 carry = m_v[i] + m_temp[j] + carry;
469 m_v[i] =
static_cast<byte
>(carry);
470 i--; j--; carry >>= 8;
474 carry = m_v[i] + carry;
475 m_v[i] =
static_cast<byte
>(carry);
485 m_hash.Update(m_temp, m_temp.size());
486 size_t count =
STDMIN(size, (
size_t)HASH::DIGESTSIZE);
487 m_hash.TruncatedFinal(output, count);
490 size -= count; output += count;
496 const byte three = 3;
497 m_temp.New(HASH::DIGESTSIZE);
499 m_hash.Update(&three, 1);
500 m_hash.Update(m_v, m_v.size());
501 m_hash.Final(m_temp);
505 int carry=0, k=
sizeof(m_reseed)-1, j=HASH::DIGESTSIZE-1, i=SEEDLENGTH-1;
509 carry = m_v[i] + m_c[i] + m_temp[j] + GetByte<word64>(
BIG_ENDIAN_ORDER, m_reseed, k) + carry;
510 m_v[i] =
static_cast<byte
>(carry);
511 i--; j--; k--; carry >>= 8;
516 carry = m_v[i] + m_c[i] + m_temp[j] + carry;
517 m_v[i] =
static_cast<byte
>(carry);
518 i--; j--; carry >>= 8;
523 carry = m_v[i] + m_c[i] + carry;
524 m_v[i] =
static_cast<byte
>(carry);
533 template <
typename HASH,
unsigned int STRENGTH,
unsigned int SEEDLENGTH>
535 const byte* input3,
size_t inlen3,
const byte* input4,
size_t inlen4, byte* output,
size_t outlen)
542 m_hash.Update(&counter, 1);
543 m_hash.Update(reinterpret_cast<const byte*>(&bits), 4);
545 if (input1 && inlen1)
546 m_hash.Update(input1, inlen1);
547 if (input2 && inlen2)
548 m_hash.Update(input2, inlen2);
549 if (input3 && inlen3)
550 m_hash.Update(input3, inlen3);
551 if (input4 && inlen4)
552 m_hash.Update(input4, inlen4);
554 size_t count =
STDMIN(outlen, (
size_t)HASH::DIGESTSIZE);
555 m_hash.TruncatedFinal(output, count);
557 output += count; outlen -= count;
565 template <
typename HASH,
unsigned int STRENGTH,
unsigned int SEEDLENGTH>
567 const byte* personalization,
size_t personalizationLength)
575 if (entropyLength < MINIMUM_ENTROPY)
576 throw NIST_DRBG::Err(
"HMAC_DRBG",
"Insufficient entropy during instantiate");
584 std::fill(m_k.begin(), m_k.begin()+m_k.size(), byte(0));
585 std::fill(m_v.begin(), m_v.begin()+m_v.size(), byte(1));
587 HMAC_Update(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
592 template <
typename HASH,
unsigned int STRENGTH,
unsigned int SEEDLENGTH>
601 if (entropyLength < MINIMUM_ENTROPY)
602 throw NIST_DRBG::Err(
"HMAC_DRBG",
"Insufficient entropy during reseed");
609 HMAC_Update(entropy, entropyLength, additional, additionaLength, NULLPTR, 0);
614 template <
typename HASH,
unsigned int STRENGTH,
unsigned int SEEDLENGTH>
618 if (static_cast<word64>(m_reseed) >= static_cast<word64>(MaxRequestBeforeReseed()))
621 if (size > MaxBytesPerRequest())
629 if (additional && additionaLength)
630 HMAC_Update(additional, additionaLength, NULLPTR, 0, NULLPTR, 0);
633 m_hmac.SetKey(m_k, m_k.size());
637 m_hmac.Update(m_v, m_v.size());
638 m_hmac.TruncatedFinal(m_v, m_v.size());
640 size_t count =
STDMIN(size, (
size_t)HASH::DIGESTSIZE);
641 memcpy(output, m_v, count);
642 size -= count; output += count;
645 HMAC_Update(additional, additionaLength, NULLPTR, 0, NULLPTR, 0);
650 template <
typename HASH,
unsigned int STRENGTH,
unsigned int SEEDLENGTH>
653 const byte zero = 0, one = 1;
656 m_hmac.SetKey(m_k, m_k.size());
657 m_hmac.Update(m_v, m_v.size());
658 m_hmac.Update(&zero, 1);
660 if (input1 && inlen1)
661 m_hmac.Update(input1, inlen1);
662 if (input2 && inlen2)
663 m_hmac.Update(input2, inlen2);
664 if (input3 && inlen3)
665 m_hmac.Update(input3, inlen3);
667 m_hmac.TruncatedFinal(m_k, m_k.size());
670 m_hmac.SetKey(m_k, m_k.size());
671 m_hmac.Update(m_v, m_v.size());
673 m_hmac.TruncatedFinal(m_v, m_v.size());
676 if ((inlen1 | inlen2 | inlen3) == 0)
680 m_hmac.SetKey(m_k, m_k.size());
681 m_hmac.Update(m_v, m_v.size());
682 m_hmac.Update(&one, 1);
684 if (input1 && inlen1)
685 m_hmac.Update(input1, inlen1);
686 if (input2 && inlen2)
687 m_hmac.Update(input2, inlen2);
688 if (input3 && inlen3)
689 m_hmac.Update(input3, inlen3);
691 m_hmac.TruncatedFinal(m_k, m_k.size());
694 m_hmac.SetKey(m_k, m_k.size());
695 m_hmac.Update(m_v, m_v.size());
697 m_hmac.TruncatedFinal(m_v, m_v.size());
702 #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.
Base class for all exceptions thrown by the library.
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
unsigned int SecurityStrength() const
Provides the security strength.
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.
unsigned int MaxRequestBeforeReseed() const
Provides the maximum number of requests before a reseed.
void IncrementCounterByOne(byte *inout, unsigned int size)
Performs an addition with carry on a block of bytes.
unsigned int SeedLength() const
Provides the seed length.
void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte *additional, size_t additionaLength)
Update RNG state with additional unpredictable values.
unsigned int MinEntropyLength() const
Provides the minimum entropy size.
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.
Interface for random number generators.
unsigned int MinEntropyLength() const
Provides the minimum entropy size.
Classes and functions for secure memory allocations.
Classes for HMAC message authentication codes.
unsigned int MinNonceLength() const
Provides the minimum nonce size.
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte *additional, size_t additionaLength)
Update RNG state with additional unpredictable values.
Exception thrown when a NIST DRBG encounters an error.
void GenerateBlock(const byte *additional, size_t additionaLength, byte *output, size_t size)
Generate random array of bytes.
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianness.
void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
HMAC_DRBG from SP 800-90A Rev 1 (June 2015)
unsigned int MinNonceLength() const
Provides the minimum nonce size.
unsigned int SeedLength() const
Provides the seed length.
unsigned int MaxBytesPerRequest() const
Provides the maximum size of a request to GenerateBlock.
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Classes for SHA-1 and SHA-2 family of message digests.
Hash_DRBG from SP 800-90A Rev 1 (June 2015)
Interface for NIST DRBGs from SP 800-90A.
unsigned int MaxRequestBeforeReseed() const
Provides the maximum number of requests before a reseed.
unsigned int MaxEntropyLength() const
Provides the maximum entropy size.
unsigned int MaxNonceLength() const
Provides the maximum nonce size.
unsigned int MaxBytesPerRequest() const
Provides the maximum size of a request to GenerateBlock.
unsigned int MaxEntropyLength() const
Provides the maximum entropy size.
virtual bool CanIncorporateEntropy() const
Determines if a generator can accept additional entropy.
Crypto++ library namespace.
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Ensures an object is not copyable.
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
unsigned int MaxNonceLength() const
Provides the maximum nonce size.
void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
unsigned int SecurityStrength() const
Provides the security strength.