BearSSL
|
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... | |
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).
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 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 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 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.
ctx | PRNG context to seed. |
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.
ctx | AESCTR_DRBG context. |
out | output buffer. |
len | number of pseudorandom bytes to produce. |
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.
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). |
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.
ctx | AESCTR_DRBG context. |
seed | additional seed. |
seed_len | additional seed length (in bytes). |
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).
ctx | HMAC_DRBG context. |
out | output buffer. |
len | number of pseudorandom bytes to produce. |
|
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.
ctx | HMAC_DRBG context. |
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.
ctx | HMAC_DRBG context to initialise. |
digest_class | vtable for the underlying hash function. |
seed | initial seed. |
seed_len | initial seed length (in bytes). |
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.
ctx | HMAC_DRBG context. |
seed | additional seed. |
seed_len | additional seed length (in bytes). |
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"
.
name | receiver for seeder name, or NULL . |
const br_prng_class br_aesctr_drbg_vtable |
Statically allocated, constant vtable for AESCTR_DRBG.
const br_prng_class br_hmac_drbg_vtable |
Statically allocated, constant vtable for HMAC_DRBG.