BearSSL: bearssl_rand.h File Reference

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:

- `br_xxx_init()`

  Initialise the context with an initial seed.

- `br_xxx_generate()`

  Produce some pseudo-random bytes.

- `br_xxx_update()`

  Inject some additional seed.

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

  ctx | PRNG 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

  ctx | AESCTR_DRBG context.
  out | output buffer.
  len | number 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

  ctx | AESCTR_DRBG context to initialise.
  aesctr | vtable for the AES/CTR implementation.
  seed | initial seed (can be `NULL` if `seed_len` is zero).
  seed_len | initial 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

  ctx | AESCTR_DRBG context.
  seed | additional seed.
  seed_len | additional 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

  ctx | HMAC_DRBG context.
  out | output buffer.
  len | number 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

  ctx | HMAC_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

  ctx | HMAC_DRBG context to initialise.
  digest_class | vtable for the underlying hash function.
  seed | initial seed.
  seed_len | initial 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

  ctx | HMAC_DRBG context.
  seed | additional seed.
  seed_len | additional 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

  name | receiver 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
| extern

Statically allocated, constant vtable for AESCTR_DRBG.

## ◆ br_hmac_drbg_vtable

const br_prng_class br_hmac_drbg_vtable
| extern

Statically allocated, constant vtable for HMAC_DRBG.