9#ifndef CRYPTOPP_NIST_DRBG_H 
   10#define CRYPTOPP_NIST_DRBG_H 
   33        explicit Err(
const std::string &c, 
const std::string &m)
 
 
   66    virtual void IncorporateEntropy(
const byte *entropy, 
size_t entropyLength, 
const byte* additional, 
size_t additionaLength)=0;
 
   85    virtual void GenerateBlock(
const byte* additional, 
size_t additionaLength, 
byte *output, 
size_t size)=0;
 
  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;
 
  145    virtual void DRBG_Reseed(
const byte* entropy, 
size_t entropyLength, 
const byte* additional, 
size_t additionaLength)=0;
 
 
  166template <
typename HASH=
SHA256, 
unsigned int STRENGTH=128/8, 
unsigned int SEEDLENGTH=440/8>
 
  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);
 
  183    static std::string StaticAlgorithmName() { 
return std::string(
"Hash_DRBG(") + HASH::StaticAlgorithmName() + std::string(
")"); }
 
  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)
 
  215            std::memset(m_c.
data(), 0x00, m_c.
size());
 
  217            std::memset(m_v.
data(), 0x00, m_v.
size());
 
  219        if (entropy != NULLPTR && entropyLength != 0)
 
  220            DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
 
 
  233        {
return DRBG_Reseed(input, length, NULLPTR, 0);}
 
 
  235    void IncorporateEntropy(
const byte *entropy, 
size_t entropyLength, 
const byte* additional, 
size_t additionaLength)
 
  236        {
return DRBG_Reseed(entropy, entropyLength, additional, additionaLength);}
 
 
  239        {
return Hash_Generate(NULLPTR, 0, output, size);}
 
 
  241    void GenerateBlock(
const byte* additional, 
size_t additionaLength, 
byte *output, 
size_t size)
 
  242        {
return Hash_Generate(additional, additionaLength, output, size);}
 
 
  245        {HASH hash; 
return hash.AlgorithmProvider();}
 
 
  249    void DRBG_Instantiate(
const byte* entropy, 
size_t entropyLength, 
const byte* nonce, 
size_t nonceLength,
 
  250        const byte* personalization, 
size_t personalizationLength);
 
  253    void DRBG_Reseed(
const byte* entropy, 
size_t entropyLength, 
const byte* additional, 
size_t additionaLength);
 
  256    void Hash_Generate(
const byte* additional, 
size_t additionaLength, 
byte *output, 
size_t size);
 
  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);
 
 
  290template <
typename HASH=
SHA256, 
unsigned int STRENGTH=128/8, 
unsigned int SEEDLENGTH=440/8>
 
  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);
 
  307    static std::string StaticAlgorithmName() { 
return std::string(
"HMAC_DRBG(") + HASH::StaticAlgorithmName() + std::string(
")"); }
 
  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)
 
  339            std::memset(m_k, 0x00, m_k.
size());
 
  341            std::memset(m_v, 0x00, m_v.
size());
 
  343        if (entropy != NULLPTR && entropyLength != 0)
 
  344            DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
 
 
  357        {
return DRBG_Reseed(input, length, NULLPTR, 0);}
 
 
  359    void IncorporateEntropy(
const byte *entropy, 
size_t entropyLength, 
const byte* additional, 
size_t additionaLength)
 
  360        {
return DRBG_Reseed(entropy, entropyLength, additional, additionaLength);}
 
 
  363        {
return HMAC_Generate(NULLPTR, 0, output, size);}
 
 
  365    void GenerateBlock(
const byte* additional, 
size_t additionaLength, 
byte *output, 
size_t size)
 
  366        {
return HMAC_Generate(additional, additionaLength, output, size);}
 
 
  369        {HASH hash; 
return hash.AlgorithmProvider();}
 
 
  373    void DRBG_Instantiate(
const byte* entropy, 
size_t entropyLength, 
const byte* nonce, 
size_t nonceLength,
 
  374        const byte* personalization, 
size_t personalizationLength);
 
  377    void DRBG_Reseed(
const byte* entropy, 
size_t entropyLength, 
const byte* additional, 
size_t additionaLength);
 
  380    void HMAC_Generate(
const byte* additional, 
size_t additionaLength, 
byte *output, 
size_t size);
 
  383    void HMAC_Update(
const byte* input1, 
size_t inlen1, 
const byte* input2, 
size_t inlen2, 
const byte* input3, 
size_t inlen3);
 
 
  399template <
typename HASH, 
unsigned int STRENGTH, 
unsigned int SEEDLENGTH>
 
  401    const byte* personalization, 
size_t personalizationLength)
 
  409    if (entropyLength < MINIMUM_ENTROPY)
 
  410        throw NIST_DRBG::Err(
"Hash_DRBG", 
"Insufficient entropy during instantiate");
 
  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());
 
  423    m_v.swap(t1); m_c.swap(t2);
 
  428template <
typename HASH, 
unsigned int STRENGTH, 
unsigned int SEEDLENGTH>
 
  437    if (entropyLength < MINIMUM_ENTROPY)
 
  438        throw NIST_DRBG::Err(
"Hash_DRBG", 
"Insufficient entropy during reseed");
 
  445    const byte zero = 0, one = 1;
 
  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());
 
  450    m_v.swap(t1); m_c.swap(t2);
 
  455template <
typename HASH, 
unsigned int STRENGTH, 
unsigned int SEEDLENGTH>
 
  459    if (
static_cast<word64>(m_reseed) >= 
static_cast<word64>(MaxRequestBeforeReseed()))
 
  462    if (size > MaxBytesPerRequest())
 
  470    if (additional && additionaLength)
 
  473        m_temp.New(HASH::DIGESTSIZE);
 
  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);
 
  481        int carry=0, j=HASH::DIGESTSIZE-1, i=SEEDLENGTH-1;
 
  484            carry = m_v[i] + m_temp[j] + carry;
 
  485            m_v[i] = 
static_cast<byte>(carry);
 
  486            i--; j--; carry >>= 8;
 
  490            carry = m_v[i] + carry;
 
  491            m_v[i] = 
static_cast<byte>(carry);
 
  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);
 
  506            size -= count; output += count;
 
  512        const byte three = 3;
 
  513        m_temp.New(HASH::DIGESTSIZE);
 
  515        m_hash.Update(&three, 1);
 
  516        m_hash.Update(m_v, m_v.size());
 
  517        m_hash.Final(m_temp);
 
  521        int carry=0, k=
sizeof(m_reseed)-1, j=HASH::DIGESTSIZE-1, i=SEEDLENGTH-1;
 
  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;
 
  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;
 
  539            carry = m_v[i] + m_c[i] + carry;
 
  540            m_v[i] = 
static_cast<byte>(carry);
 
  549template <
typename HASH, 
unsigned int STRENGTH, 
unsigned int SEEDLENGTH>
 
  551    const byte* input3, 
size_t inlen3, 
const byte* input4, 
size_t inlen4, 
byte* output, 
size_t outlen)
 
  558        m_hash.Update(&counter, 1);
 
  559        m_hash.Update(
reinterpret_cast<const byte*
>(&bits), 4);
 
  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);
 
  570        size_t count = 
STDMIN(outlen, (
size_t)HASH::DIGESTSIZE);
 
  571        m_hash.TruncatedFinal(output, count);
 
  573        output += count; outlen -= count;
 
  581template <
typename HASH, 
unsigned int STRENGTH, 
unsigned int SEEDLENGTH>
 
  583    const byte* personalization, 
size_t personalizationLength)
 
  591    if (entropyLength < MINIMUM_ENTROPY)
 
  592        throw NIST_DRBG::Err(
"HMAC_DRBG", 
"Insufficient entropy during instantiate");
 
  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));
 
  603    HMAC_Update(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
 
  608template <
typename HASH, 
unsigned int STRENGTH, 
unsigned int SEEDLENGTH>
 
  617    if (entropyLength < MINIMUM_ENTROPY)
 
  618        throw NIST_DRBG::Err(
"HMAC_DRBG", 
"Insufficient entropy during reseed");
 
  625    HMAC_Update(entropy, entropyLength, additional, additionaLength, NULLPTR, 0);
 
  630template <
typename HASH, 
unsigned int STRENGTH, 
unsigned int SEEDLENGTH>
 
  634    if (
static_cast<word64>(m_reseed) >= 
static_cast<word64>(MaxRequestBeforeReseed()))
 
  637    if (size > MaxBytesPerRequest())
 
  645    if (additional && additionaLength)
 
  646        HMAC_Update(additional, additionaLength, NULLPTR, 0, NULLPTR, 0);
 
  649    m_hmac.SetKey(m_k, m_k.size());
 
  653        m_hmac.Update(m_v, m_v.size());
 
  654        m_hmac.TruncatedFinal(m_v, m_v.size());
 
  656        size_t count = 
STDMIN(size, (
size_t)HASH::DIGESTSIZE);
 
  657        std::memcpy(output, m_v, count);
 
  658        size -= count; output += count;
 
  661    HMAC_Update(additional, additionaLength, NULLPTR, 0, NULLPTR, 0);
 
  666template <
typename HASH, 
unsigned int STRENGTH, 
unsigned int SEEDLENGTH>
 
  669    const byte zero = 0, one = 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);
 
  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);
 
  683    m_hmac.TruncatedFinal(m_k, m_k.size());
 
  686    m_hmac.SetKey(m_k, m_k.size());
 
  687    m_hmac.Update(m_v, m_v.size());
 
  689    m_hmac.TruncatedFinal(m_v, m_v.size());
 
  692    if ((inlen1 | inlen2 | inlen3) == 0)
 
  696    m_hmac.SetKey(m_k, m_k.size());
 
  697    m_hmac.Update(m_v, m_v.size());
 
  698    m_hmac.Update(&one, 1);
 
  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);
 
  707    m_hmac.TruncatedFinal(m_k, m_k.size());
 
  710    m_hmac.SetKey(m_k, m_k.size());
 
  711    m_hmac.Update(m_v, m_v.size());
 
  713    m_hmac.TruncatedFinal(m_v, m_v.size());
 
Base class for all exceptions thrown by the library.
 
HMAC_DRBG from SP 800-90A Rev 1 (June 2015)
 
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
 
unsigned int SeedLength() const
Provides the seed length.
 
unsigned int MaxRequestBeforeReseed() const
Provides the maximum number of requests before a reseed.
 
unsigned int MinEntropyLength() const
Provides the minimum entropy size.
 
void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte *additional, size_t additionaLength)
Update RNG state with additional unpredictable values.
 
void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
 
unsigned int SecurityStrength() const
Provides the security strength.
 
unsigned int MaxBytesPerRequest() const
Provides the maximum size of a request to GenerateBlock.
 
unsigned int MinNonceLength() const
Provides the minimum nonce size.
 
unsigned int MaxEntropyLength() const
Provides the maximum entropy size.
 
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
 
void GenerateBlock(const byte *additional, size_t additionaLength, byte *output, size_t size)
Generate random array of bytes.
 
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 MaxNonceLength() const
Provides the maximum nonce size.
 
Hash_DRBG from SP 800-90A Rev 1 (June 2015)
 
unsigned int MinNonceLength() const
Provides the minimum nonce size.
 
unsigned int MaxEntropyLength() const
Provides the maximum entropy size.
 
void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
 
unsigned int SeedLength() const
Provides the seed length.
 
void GenerateBlock(const byte *additional, size_t additionaLength, byte *output, size_t size)
Generate random array of bytes.
 
unsigned int MaxRequestBeforeReseed() const
Provides the maximum number of requests before a reseed.
 
unsigned int MaxBytesPerRequest() const
Provides the maximum size of a request to GenerateBlock.
 
void IncorporateEntropy(const byte *entropy, size_t entropyLength, const byte *additional, size_t additionaLength)
Update RNG state with additional unpredictable values.
 
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
 
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.
 
void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
 
unsigned int SecurityStrength() const
Provides the security strength.
 
unsigned int MaxNonceLength() const
Provides the maximum nonce size.
 
unsigned int MinEntropyLength() const
Provides the minimum entropy size.
 
Exception thrown when a NIST DRBG encounters an error.
 
Interface for NIST DRBGs from SP 800-90A.
 
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.
 
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.
 
Interface for random number generators.
 
A::pointer data()
Provides a pointer to the first element in the memory block.
 
size_type size() const
Provides the count of elements in the SecBlock.
 
unsigned int word32
32-bit unsigned datatype
 
unsigned long long word64
64-bit unsigned datatype
 
Abstract base classes that provide a uniform interface to this library.
 
@ BIG_ENDIAN_ORDER
byte order is big-endian
 
Classes for HMAC message authentication codes.
 
void IncrementCounterByOne(byte *inout, unsigned int size)
Performs an addition with carry on a block of bytes.
 
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
 
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianness.
 
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.