# NIST DRBGs

NIST SP 800-90A added three Deterministic Random Bit Generators (DRBGs) to secede the retired ANSI X9.17 and X9.31 generators. Crypto++ 5.7 added support for DRBGs at Commit 5c932fcc3b6333e4. The initial commit added the `Hash_DRBG` and CAVP test vectors. Later, Commit 2868452193e32156 added `HMAC_DRBG` and additional CAVP test vectors.

The NIST generators are provided header-only, so you can fetch the include file and use it in any version of the Crypto++ library. Just drop it in place and use it as if it was part of the release ZIP.

Using a NIST generator is a little trickier than using a typical RandomNumberGenerator from the library. They are trickier because they have randomness requirements during instantiation and reseed, and the source of the randomness matters. In addition, they accept at least three other types of randomness distinct from the entropy and randomness required during instantiation. This page will explain how to use them.

The Crypto++ NIST DRBGs provide *Backtracking Resistance (BR)*. BR is a design feature, and all NIST DRBGs have it. The library's implementation does not provide *Predictive Resistance (PR)* as specified in SP 800-90A, Section 8.8, Prediction Resistance and Backtracking Resistance.

Though the generators are NIST approved and they complete the CAVP test vectors, the classes are *not* FIPS validated since the library and classes have not undergone CMVP testing.

## Contents

## Classes

The NIST deterministic generators are found in `drbg.h`. The base class is called `NIST_DRBG`, and it provides the interface for both `Hash_DRBG` and `HMAC_DRBG`. Both `Hash_DRBG` and `HMAC_DRBG` are templates, and they require a hash, a security strength in bytes, and a seed length in bytes.

### Construction

Hash_DRBG(const byte* entropy, size_t entropyLength=STRENGTH, const byte* nonce=NULL, size_t nonceLength=0, const byte* personalization=NULL, size_t personalizationLength=0)

HMAC_DRBG(const byte* entropy, size_t entropyLength=STRENGTH, const byte* nonce=NULL, size_t nonceLength=0, const byte* personalization=NULL, size_t personalizationLength=0)

`entropy` is a pointer to a byte array generated by a NIST SP 800-90C generator. `NonblockingRng`, RDRAND and RDSEED generators satisfy SP 800-90C. Also see Randomness Source below.

`entropyLength` is the size of the `entropy` buffer. The constant `STRENGTH` is the minimum entropy required to instantiate the generator. The parameter's value will change depending on the generator and the security strength.

`nonce` is additional entropy used to instantiate the generator. The nonce buffer is optional. The parameter is "weaker" than entropy, but "stronger" than the personalization string. Also see Randomness Source below.

`nonceLength` is the size of the `nonce` buffer.

`personalization` is additional entropy used to instantiate the generator. The personalization string is optional. The parameter is "weaker" than both entropy and nonce. Also see Randomness Source below.

`personalizationLength` is the size of the `personalization` buffer.

## Randomness Source

The following discusses requirements of `entropy`, `nonce`, `persoanlization` and `additional` input.

### Entropy

SP 800-90A, Section 8.6.5 Randomness Source states the following. Entropy is always required for instantiation and reseed.

A DRBG mechanism requires an approved randomness source during instantiation and reseeding, including whenever prediction resistance is requested (see Section 8.8). This input is requested using the

Get_entropy_inputfunction introduced in Section 9 and is specified in more detail in SP 800-90C.

An approved randomness source is an entropy source that conforms to SP 800-90B, or an RBG that conforms to SP 800-90C − either a DRBG or an NRBG.

### Nonce

SP 800-90A, Section 8.6.7, Nonce states the following when a nonce is required:

- A random value that is generated anew for each nonce, using an approved random bit generator.
- A timestamp of sufficient resolution (detail) so that it is different each time it is used.
- A monotonically increasing sequence number, or
- A combination of a timestamp and a monotonically increasing sequence number, such that the sequence number is reset when and only when the timestamp changes

### Personalization

SP 800-90A, Section 8.7.1, Personalization String states the following:

A personalization string is an optional (but recommended) input to the instantiate function and is used to derive the seed (see Section 8.6.1). The personalization string may be obtained from inside or outside a cryptographic module, and may be an empty string.

The intent of a personalization string is to introduce additional input into the instantiation of a DRBG. This personalization string might contain values unknown to an attacker, or values that tend to differentiate this DRBG instantiation from all others. Ideally, a personalization string will be set to some bitstring that is as unique as possible. Good sources for the personalization string contents include:

- Application identifiers
- Device serial numbers
- User identification
- Per-module or per-device values
- Timestamps
- Network addresses
- Special key values for this specific DRBG instantiation
- Protocol version identifiers
- Random numbers and Nonces
- Outputs from other approved or non-approved random bit generators

### Additional Input

SP 800-90A, Section 8.7.2 Additional Input states the following:

Additional input may optionally be provided to the reseed and generate functions during requests. The additional input may be obtained from inside or outside a cryptographic module, and may include secret or public information.

## Generator Testing

The NIST generators are tested in `validat1.cpp` in functions `ValidateHash_DRBG()` and `ValidateHmac_DRBG()`. The test vectors were taken from NIST's CAVP Testing: Random Number Generators.

You can execute the `Hash_DRBG` test vectors using `cryptest.exe v 77` (`HMAC_DRBG` is 78). The tests exercise various instantiations of the generator using different combinations of `entropy` (E), `nonce` (N), `additional` entropy (A), and `personalization` strings (P).

$ ./cryptest.exe v 77 Using seed: 1483211134 Testing NIST DRBG generators... passed Hash_DRBG SHA1/128/440 (COUNT=0, E=16, N=8) passed Hash_DRBG SHA1/128/440 (COUNT=1, E=16, N=8) passed Hash_DRBG SHA1/128/440 (C0UNT=0, E=16, N=8, A=16) passed Hash_DRBG SHA1/128/440 (C0UNT=1, E=16, N=8, A=16) passed Hash_DRBG SHA1/128/440 (C0UNT=0, E=16, N=8, A=0, P=16) passed Hash_DRBG SHA1/128/440 (C0UNT=1, E=16, N=8, A=0, P=16) passed Hash_DRBG SHA1/128/440 (C0UNT=0, E=16, N=8, A=16, P=16) passed Hash_DRBG SHA1/128/440 (C0UNT=1, E=16, N=8, A=16, P=16) passed Hash_DRBG SHA256/128/440 (C0UNT=0, E=32, N=16, A=32, P=32) passed Hash_DRBG SHA256/128/440 (C0UNT=1, E=32, N=16, A=32, P=32) passed Hash_DRBG SHA512/256/888 (C0UNT=0, E=32, N=16, A=32, P=32) passed Hash_DRBG SHA512/256/888 (C0UNT=1, E=32, N=16, A=32, P=32) Test ended at Sat Dec 31 14:05:34 2016

## Sample Programs

The following shows how you might use the NIST generators. The generators are unique becuase they effectively need an external generator to provide the initial entropy used during instantiation and entropy used during reseed.

An example of instantiating a SHA256 generator is shown below. The example provides more entropy than required for SHA256. The NonblockingRng meets the requirements of NIST SP 800-90B. RDRAND and RDSEED generators would work as well.

NIST instantiation requirements demand the generator is constructed with at least `MINIMUM_ENTROPY` entropy, which is 16 in the case of SHA256. However, a 32-byte entropy string is provided below. A nonce is not required for `Hash_DRBG`, but a 16 byte nonce is provided (other NIST DRBGs require a nonce).

SecByteBlock entropy(48), result(128); NonblockingRng prng; RandomNumberSource rns(prng, entropy.size(), new ArraySink(entropy, entropy.size())); Hash_DRBG<SHA256, 128/8, 440/8> drbg(entropy, 32, entropy+32, 16); drbg.GenerateBlock(result, result.size()); ...

The generator has the same entropy requirements during reseed operations (there are no nonce requirements). If you reseed after each generate operation, than you satisfy the requirements for *Predictive Resistance (PR)*.

prng.GenerateBlock(entropy, entropy.size()); drbg.IncorporateEntropy(entropy, entropy.size()); drbg.GenerateBlock(result, result.size()); ...