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);}
237 void DRBG_Instantiate(
const byte* entropy,
size_t entropyLength,
const byte* nonce,
size_t nonceLength,
238 const byte* personalization,
size_t personalizationLength);
241 void DRBG_Reseed(
const byte* entropy,
size_t entropyLength,
const byte* additional,
size_t additionaLength);
244 void Hash_Generate(
const byte* additional,
size_t additionaLength, byte *output,
size_t size);
247 void Hash_Update(
const byte* input1,
size_t inlen1,
const byte* input2,
size_t inlen2,
248 const byte* input3,
size_t inlen3,
const byte* input4,
size_t inlen4, byte* output,
size_t outlen);
275 template <
typename HASH=
SHA256,
unsigned int STRENGTH=128/8,
unsigned int SEEDLENGTH=440/8>
279 CRYPTOPP_CONSTANT(SECURITY_STRENGTH=STRENGTH)
280 CRYPTOPP_CONSTANT(SEED_LENGTH=SEEDLENGTH)
281 CRYPTOPP_CONSTANT(MINIMUM_ENTROPY=STRENGTH)
282 CRYPTOPP_CONSTANT(MINIMUM_NONCE=0)
283 CRYPTOPP_CONSTANT(MINIMUM_ADDITIONAL=0)
284 CRYPTOPP_CONSTANT(MINIMUM_PERSONALIZATION=0)
285 CRYPTOPP_CONSTANT(MAXIMUM_ENTROPY=INT_MAX)
286 CRYPTOPP_CONSTANT(MAXIMUM_NONCE=INT_MAX)
287 CRYPTOPP_CONSTANT(MAXIMUM_ADDITIONAL=INT_MAX)
288 CRYPTOPP_CONSTANT(MAXIMUM_PERSONALIZATION=INT_MAX)
289 CRYPTOPP_CONSTANT(MAXIMUM_BYTES_PER_REQUEST=65536)
290 CRYPTOPP_CONSTANT(MAXIMUM_REQUESTS_BEFORE_RESEED=INT_MAX)
292 static std::string StaticAlgorithmName() {
return std::string(
"HMAC_DRBG(") + HASH::StaticAlgorithmName() + std::string(
")"); }
319 HMAC_DRBG(
const byte* entropy=NULLPTR,
size_t entropyLength=STRENGTH,
const byte* nonce=NULLPTR,
320 size_t nonceLength=0,
const byte* personalization=NULLPTR,
size_t personalizationLength=0)
321 :
NIST_DRBG(), m_k(HASH::DIGESTSIZE), m_v(HASH::DIGESTSIZE), m_reseed(0)
323 if (entropy != NULLPTR && entropyLength != 0)
324 DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
337 {
return DRBG_Reseed(input, length, NULLPTR, 0);}
339 void IncorporateEntropy(
const byte *entropy,
size_t entropyLength,
const byte* additional,
size_t additionaLength)
340 {
return DRBG_Reseed(entropy, entropyLength, additional, additionaLength);}
343 {
return HMAC_Generate(NULLPTR, 0, output, size);}
345 void GenerateBlock(
const byte* additional,
size_t additionaLength, byte *output,
size_t size)
346 {
return HMAC_Generate(additional, additionaLength, output, size);}
350 void DRBG_Instantiate(
const byte* entropy,
size_t entropyLength,
const byte* nonce,
size_t nonceLength,
351 const byte* personalization,
size_t personalizationLength);
354 void DRBG_Reseed(
const byte* entropy,
size_t entropyLength,
const byte* additional,
size_t additionaLength);
357 void HMAC_Generate(
const byte* additional,
size_t additionaLength, byte *output,
size_t size);
360 void HMAC_Update(
const byte* input1,
size_t inlen1,
const byte* input2,
size_t inlen2,
const byte* input3,
size_t inlen3);
375 template <
typename HASH,
unsigned int STRENGTH,
unsigned int SEEDLENGTH>
377 const byte* personalization,
size_t personalizationLength)
385 if (entropyLength < MINIMUM_ENTROPY)
386 throw NIST_DRBG::Err(
"Hash_DRBG",
"Insufficient entropy during instantiate");
396 Hash_Update(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength, NULLPTR, 0, t1, t1.size());
397 Hash_Update(&zero, 1, t1, t1.size(), NULLPTR, 0, NULLPTR, 0, t2, t2.
size());
399 m_v.swap(t1); m_c.swap(t2);
404 template <
typename HASH,
unsigned int STRENGTH,
unsigned int SEEDLENGTH>
413 if (entropyLength < MINIMUM_ENTROPY)
414 throw NIST_DRBG::Err(
"Hash_DRBG",
"Insufficient entropy during reseed");
421 const byte zero = 0, one = 1;
423 Hash_Update(&one, 1, m_v, m_v.size(), entropy, entropyLength, additional, additionaLength, t1, t1.size());
424 Hash_Update(&zero, 1, t1, t1.size(), NULLPTR, 0, NULLPTR, 0, t2, t2.
size());
426 m_v.swap(t1); m_c.swap(t2);
431 template <
typename HASH,
unsigned int STRENGTH,
unsigned int SEEDLENGTH>
435 if (static_cast<word64>(m_reseed) >= static_cast<word64>(MaxRequestBeforeReseed()))
438 if (size > MaxBytesPerRequest())
446 if (additional && additionaLength)
452 hash.Update(&two, 1);
453 hash.Update(m_v, m_v.size());
454 hash.Update(additional, additionaLength);
458 int carry=0, j=HASH::DIGESTSIZE-1, i=SEEDLENGTH-1;
461 carry = m_v[i] + w[j] + carry;
462 m_v[i] =
static_cast<byte
>(carry);
463 i--; j--; carry >>= 8;
467 carry = m_v[i] + carry;
468 m_v[i] =
static_cast<byte
>(carry);
480 hash.Update(data, data.
size());
481 size_t count =
STDMIN(size, (
size_t)HASH::DIGESTSIZE);
482 hash.TruncatedFinal(output, count);
485 size -= count; output += count;
492 const byte three = 3;
495 hash.Update(&three, 1);
496 hash.Update(m_v, m_v.size());
501 int carry=0, k=
sizeof(m_reseed)-1, j=HASH::DIGESTSIZE-1, i=SEEDLENGTH-1;
505 #if defined(CRYPTOPP_WORD128_AVAILABLE) 506 byte* p1 = m_v.begin()+SEEDLENGTH-8;
507 byte* p2 = m_c.begin()+SEEDLENGTH-8;
508 byte* p3 = h.
begin()+HASH::DIGESTSIZE-8;
513 const word64 w4 = m_reseed;
515 word128 r =
static_cast<word128
>(w1) + w2 + w3 + w4;
516 PutWord(
false, BIG_ENDIAN_ORDER, p1, static_cast<word64>(r));
517 i -= 8; j -= 8; k=0; carry =
static_cast<int>(r >> 64);
521 #elif defined(CRYPTOPP_MSC_VERSION) 522 byte* p1 = m_v.begin()+SEEDLENGTH-8;
523 byte* p2 = m_c.begin()+SEEDLENGTH-8;
524 byte* p3 = h.
begin()+HASH::DIGESTSIZE-8;
529 const word64 w4 = m_reseed;
531 const word64 r1 = (w1 & 0xffffffff) + (w2 & 0xffffffff) + (w3 & 0xffffffff) + (w4 & 0xffffffff);
532 carry =
static_cast<int>(r1 >> 32);
533 const word64 r2 = (w1 >> 32) + (w2 >> 32) + (w3 >> 32) + (w4 >> 32) + carry;
534 carry =
static_cast<int>(r2 >> 32);
536 const word64 r = (r2 << 32) + (r1 & 0xffffffff);
537 PutWord(
false, BIG_ENDIAN_ORDER, p1, r);
544 carry = m_v[i] + m_c[i] + h[j] + GetByte<word64>(
BIG_ENDIAN_ORDER, m_reseed, k) + carry;
545 m_v[i] =
static_cast<byte
>(carry);
546 i--; j--; k--; carry >>= 8;
552 carry = m_v[i] + m_c[i] + h[j] + carry;
553 m_v[i] =
static_cast<byte
>(carry);
554 i--; j--; carry >>= 8;
559 carry = m_v[i] + m_c[i] + carry;
560 m_v[i] =
static_cast<byte
>(carry);
572 template <
typename HASH,
unsigned int STRENGTH,
unsigned int SEEDLENGTH>
574 const byte* input3,
size_t inlen3,
const byte* input4,
size_t inlen4, byte* output,
size_t outlen)
582 hash.Update(&counter, 1);
583 hash.Update(reinterpret_cast<const byte*>(&bits), 4);
585 if (input1 && inlen1)
586 hash.Update(input1, inlen1);
587 if (input2 && inlen2)
588 hash.Update(input2, inlen2);
589 if (input3 && inlen3)
590 hash.Update(input3, inlen3);
591 if (input4 && inlen4)
592 hash.Update(input4, inlen4);
594 size_t count =
STDMIN(outlen, (
size_t)HASH::DIGESTSIZE);
595 hash.TruncatedFinal(output, count);
597 output += count; outlen -= count;
605 template <
typename HASH,
unsigned int STRENGTH,
unsigned int SEEDLENGTH>
607 const byte* personalization,
size_t personalizationLength)
615 if (entropyLength < MINIMUM_ENTROPY)
616 throw NIST_DRBG::Err(
"HMAC_DRBG",
"Insufficient entropy during instantiate");
624 std::fill(m_k.begin(), m_k.begin()+m_k.size(), byte(0));
625 std::fill(m_v.begin(), m_v.begin()+m_v.size(), byte(1));
627 HMAC_Update(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
632 template <
typename HASH,
unsigned int STRENGTH,
unsigned int SEEDLENGTH>
641 if (entropyLength < MINIMUM_ENTROPY)
642 throw NIST_DRBG::Err(
"HMAC_DRBG",
"Insufficient entropy during reseed");
649 HMAC_Update(entropy, entropyLength, additional, additionaLength, NULLPTR, 0);
654 template <
typename HASH,
unsigned int STRENGTH,
unsigned int SEEDLENGTH>
658 if (static_cast<word64>(m_reseed) >= static_cast<word64>(MaxRequestBeforeReseed()))
661 if (size > MaxBytesPerRequest())
669 if (additional && additionaLength)
670 HMAC_Update(additional, additionaLength, NULLPTR, 0, NULLPTR, 0);
674 hmac.
SetKey(m_k, m_k.size());
678 hmac.
Update(m_v, m_v.size());
681 size_t count =
STDMIN(size, (
size_t)HASH::DIGESTSIZE);
682 memcpy(output, m_v, count);
684 size -= count; output += count;
687 HMAC_Update(additional, additionaLength, NULLPTR, 0, NULLPTR, 0);
692 template <
typename HASH,
unsigned int STRENGTH,
unsigned int SEEDLENGTH>
695 const byte zero = 0, one = 1;
699 hmac.
SetKey(m_k, m_k.size());
700 hmac.
Update(m_v, m_v.size());
703 if (input1 && inlen1)
704 hmac.
Update(input1, inlen1);
705 if (input2 && inlen2)
706 hmac.
Update(input2, inlen2);
707 if (input3 && inlen3)
708 hmac.
Update(input3, inlen3);
713 hmac.
SetKey(m_k, m_k.size());
714 hmac.
Update(m_v, m_v.size());
719 if ((inlen1 | inlen2 | inlen3) == 0)
723 hmac.
SetKey(m_k, m_k.size());
724 hmac.
Update(m_v, m_v.size());
727 if (input1 && inlen1)
728 hmac.
Update(input1, inlen1);
729 if (input2 && inlen2)
730 hmac.
Update(input2, inlen2);
731 if (input3 && inlen3)
732 hmac.
Update(input3, inlen3);
737 hmac.
SetKey(m_k, m_k.size());
738 hmac.
Update(m_v, m_v.size());
745 #endif // CRYPTOPP_NIST_DRBG_H Hash_DRBG(const byte *entropy=NULL, size_t entropyLength=STRENGTH, const byte *nonce=NULL, size_t nonceLength=0, const byte *personalization=NULL, size_t personalizationLength=0)
Construct a Hash DRBG.
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.
virtual void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms=g_nullNameValuePairs)
Sets or reset the key of this object.
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.
void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock=NULL)
Access a block of memory.
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 Update(const byte *input, size_t length)
Updates a hash with additional input.
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.
void TruncatedFinal(byte *mac, size_t size)
Computes the hash of the current message.
Classes for SHA-1 and SHA-2 family of message digests.
iterator begin()
Provides an iterator pointing to the first element in the memory block.
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.
Ensures an object is not copyable.
unsigned int MaxNonceLength() const
Provides the maximum nonce size.
size_type size() const
Provides the count of elements in the SecBlock.
void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
unsigned int SecurityStrength() const
Provides the security strength.