BearSSL
Data Structures | Typedefs | Functions | Variables
bearssl_rand.h File Reference
Include dependency graph for bearssl_rand.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  br_prng_class
 Class type for PRNG implementations. More...
 
struct  br_hmac_drbg_context
 Context for HMAC_DRBG. More...
 
struct  br_aesctr_drbg_context
 Context for AESCTR_DRBG. More...
 

Typedefs

typedef int(* br_prng_seeder) (const br_prng_class **ctx)
 Type for a provider of entropy seeds. More...
 

Functions

void br_hmac_drbg_init (br_hmac_drbg_context *ctx, const br_hash_class *digest_class, const void *seed, size_t seed_len)
 HMAC_DRBG initialisation. More...
 
void br_hmac_drbg_generate (br_hmac_drbg_context *ctx, void *out, size_t len)
 Random bytes generation with HMAC_DRBG. More...
 
void br_hmac_drbg_update (br_hmac_drbg_context *ctx, const void *seed, size_t seed_len)
 Inject additional seed bytes in HMAC_DRBG. More...
 
static const br_hash_class * br_hmac_drbg_get_hash (const br_hmac_drbg_context *ctx)
 Get the hash function implementation used by a given instance of HMAC_DRBG. More...
 
br_prng_seeder br_prng_seeder_system (const char **name)
 Get a seeder backed by the operating system or hardware. More...
 
void br_aesctr_drbg_init (br_aesctr_drbg_context *ctx, const br_block_ctr_class *aesctr, const void *seed, size_t seed_len)
 AESCTR_DRBG initialisation. More...
 
void br_aesctr_drbg_generate (br_aesctr_drbg_context *ctx, void *out, size_t len)
 Random bytes generation with AESCTR_DRBG. More...
 
void br_aesctr_drbg_update (br_aesctr_drbg_context *ctx, const void *seed, size_t seed_len)
 Inject additional seed bytes in AESCTR_DRBG. More...
 

Variables

const br_prng_class br_hmac_drbg_vtable
 Statically allocated, constant vtable for HMAC_DRBG. More...
 
const br_prng_class br_aesctr_drbg_vtable
 Statically allocated, constant vtable for AESCTR_DRBG. More...
 

Detailed Description

Pseudo-Random Generators

A PRNG is a state-based engine that outputs pseudo-random bytes on demand. It is initialized with an initial seed, and additional seed bytes can be added afterwards. Bytes produced depend on the seeds and also on the exact sequence of calls (including sizes requested for each call).

Procedural and OOP API

For the PRNG of name "`xxx`", two API are provided. The procedural API defined a context structure br_xxx_context and three functions:

The initialisation function sets the first context field (vtable) to a pointer to the vtable that supports the OOP API. The OOP API provides access to the same functions through function pointers, named init(), generate() and update().

Note that the context initialisation method may accept additional parameters, provided as a 'const void *' pointer at API level. These additional parameters depend on the implemented PRNG.

HMAC_DRBG

HMAC_DRBG is defined in NIST SP 800-90A Revision 1. It uses HMAC repeatedly, over some configurable underlying hash function. In BearSSL, it is implemented under the "`hmac_drbg`" name. The "extra parameters" pointer for context initialisation should be set to a pointer to the vtable for the underlying hash function (e.g. pointer to br_sha256_vtable to use HMAC_DRBG with SHA-256).

According to the NIST standard, each request shall produce up to 219 bits (i.e. 64 kB of data); moreover, the context shall be reseeded at least once every 248 requests. This implementation does not maintain the reseed counter (the threshold is too high to be reached in practice) and does not object to producing more than 64 kB in a single request; thus, the code cannot fail, which corresponds to the fact that the API has no room for error codes. However, this implies that requesting more than 64 kB in one generate() request, or making more than 248 requests without reseeding, is formally out of NIST specification. There is no currently known security penalty for exceeding the NIST limits, and, in any case, HMAC_DRBG usage in implementing SSL/TLS always stays much below these thresholds.

AESCTR_DRBG

AESCTR_DRBG is a custom PRNG based on AES-128 in CTR mode. This is meant to be used only in situations where you are desperate for speed, and have an hardware-optimized AES/CTR implementation. Whether this will yield perceptible improvements depends on what you use the pseudorandom bytes for, and how many you want; for instance, RSA key pair generation uses a substantial amount of randomness, and using AESCTR_DRBG instead of HMAC_DRBG yields a 15 to 20% increase in key generation speed on a recent x86 CPU (Intel Core i7-6567U at 3.30 GHz).

Internally, it uses CTR mode with successive counter values, starting at zero (counter value expressed over 128 bits, big-endian convention). The counter is not allowed to reach 32768; thus, every 32768*16 bytes at most, the update() function is run (on an empty seed, if none is provided). The update() function computes the new AES-128 key by applying a custom hash function to the concatenation of a state-dependent word (encryption of an all-one block with the current key) and the new seed. The custom hash function uses Hirose's construction over AES-256; see the comments in aesctr_drbg.c for details.

This DRBG does not follow an existing standard, and thus should be considered as inadequate for production use until it has been properly analysed.

Typedef Documentation

◆ br_prng_seeder

typedef int(* br_prng_seeder) (const br_prng_class **ctx)

Type for a provider of entropy seeds.

A "seeder" is a function that is able to obtain random values from some source and inject them as entropy seed in a PRNG. A seeder shall guarantee that the total entropy of the injected seed is large enough to seed a PRNG for purposes of cryptographic key generation (i.e. at least 128 bits).

A seeder may report a failure to obtain adequate entropy. Seeders shall endeavour to fix themselves transient errors by trying again; thus, callers may consider reported errors as permanent.

Parameters
ctxPRNG context to seed.
Returns
1 on success, 0 on error.

Function Documentation

◆ br_aesctr_drbg_generate()

void br_aesctr_drbg_generate ( br_aesctr_drbg_context ctx,
void *  out,
size_t  len 
)

Random bytes generation with AESCTR_DRBG.

This method produces len pseudorandom bytes, in the out buffer. The context is updated accordingly.

Parameters
ctxAESCTR_DRBG context.
outoutput buffer.
lennumber of pseudorandom bytes to produce.

◆ br_aesctr_drbg_init()

void br_aesctr_drbg_init ( br_aesctr_drbg_context ctx,
const br_block_ctr_class *  aesctr,
const void *  seed,
size_t  seed_len 
)

AESCTR_DRBG initialisation.

The context to initialise is provided as a pointer to its first field (the vtable pointer); this function sets that first field to a pointer to the vtable.

The internal AES key is first set to the all-zero key; then, the br_aesctr_drbg_update() function is called with the provided seed. The call is performed even if the seed length (seed_len) is zero.

The aesctr parameter defines the underlying AES/CTR implementation.

Parameters
ctxAESCTR_DRBG context to initialise.
aesctrvtable for the AES/CTR implementation.
seedinitial seed (can be NULL if seed_len is zero).
seed_leninitial seed length (in bytes).

◆ br_aesctr_drbg_update()

void br_aesctr_drbg_update ( br_aesctr_drbg_context ctx,
const void *  seed,
size_t  seed_len 
)

Inject additional seed bytes in AESCTR_DRBG.

The provided seed bytes are added into the AESCTR_DRBG internal entropy pool. The process does not replace existing entropy, thus pushing non-random bytes (i.e. bytes which are known to the attackers) does not degrade the overall quality of generated bytes.

Parameters
ctxAESCTR_DRBG context.
seedadditional seed.
seed_lenadditional seed length (in bytes).

◆ br_hmac_drbg_generate()

void br_hmac_drbg_generate ( br_hmac_drbg_context ctx,
void *  out,
size_t  len 
)

Random bytes generation with HMAC_DRBG.

This method produces len pseudorandom bytes, in the out buffer. The context is updated accordingly. Formally, requesting more than 65536 bytes in one request falls out of specification limits (but it won't fail).

Parameters
ctxHMAC_DRBG context.
outoutput buffer.
lennumber of pseudorandom bytes to produce.

◆ br_hmac_drbg_get_hash()

static const br_hash_class* br_hmac_drbg_get_hash ( const br_hmac_drbg_context ctx)
inlinestatic

Get the hash function implementation used by a given instance of HMAC_DRBG.

This calls MUST NOT be performed on a context which was not previously initialised.

Parameters
ctxHMAC_DRBG context.
Returns
the hash function vtable.

◆ br_hmac_drbg_init()

void br_hmac_drbg_init ( br_hmac_drbg_context ctx,
const br_hash_class *  digest_class,
const void *  seed,
size_t  seed_len 
)

HMAC_DRBG initialisation.

The context to initialise is provided as a pointer to its first field (the vtable pointer); this function sets that first field to a pointer to the vtable.

The seed value is what is called, in NIST terminology, the concatenation of the "seed", "nonce" and "personalization string", in that order.

The digest_class parameter defines the underlying hash function. Formally, the NIST standard specifies that the hash function shall be only SHA-1 or one of the SHA-2 functions. This implementation also works with any other implemented hash function (such as MD5), but this is non-standard and therefore not recommended.

Parameters
ctxHMAC_DRBG context to initialise.
digest_classvtable for the underlying hash function.
seedinitial seed.
seed_leninitial seed length (in bytes).

◆ br_hmac_drbg_update()

void br_hmac_drbg_update ( br_hmac_drbg_context ctx,
const void *  seed,
size_t  seed_len 
)

Inject additional seed bytes in HMAC_DRBG.

The provided seed bytes are added into the HMAC_DRBG internal entropy pool. The process does not replace existing entropy, thus pushing non-random bytes (i.e. bytes which are known to the attackers) does not degrade the overall quality of generated bytes.

Parameters
ctxHMAC_DRBG context.
seedadditional seed.
seed_lenadditional seed length (in bytes).

◆ br_prng_seeder_system()

br_prng_seeder br_prng_seeder_system ( const char **  name)

Get a seeder backed by the operating system or hardware.

Get a seeder that feeds on RNG facilities provided by the current operating system or hardware. If no such facility is known, then 0 is returned.

If name is not NULL, then *name is set to a symbolic string that identifies the seeder implementation. If no seeder is returned and name is not NULL, then *name is set to a pointer to the constant string "none".

Parameters
namereceiver for seeder name, or NULL.
Returns
the system seeder, if available, or 0.

Variable Documentation

◆ br_aesctr_drbg_vtable

const br_prng_class br_aesctr_drbg_vtable

Statically allocated, constant vtable for AESCTR_DRBG.

◆ br_hmac_drbg_vtable

const br_prng_class br_hmac_drbg_vtable

Statically allocated, constant vtable for HMAC_DRBG.