NAME
cprng
,
cprng_strong_create
,
cprng_strong_destroy
,
cprng_strong
,
cprng_strong32
,
cprng_strong64
, cprng_fast
,
cprng_fast32
, cprng_fast64
,
— cryptographic pseudorandom
number generators
SYNOPSIS
#include
<sys/cprng.h>
cprng_strong_t *
cprng_strong_create
(const
char *name, int
ipl, int
flags);
void
cprng_strong_destroy
(cprng_strong_t
*cprng);
size_t
cprng_strong
(cprng_strong_t
*cprng, void *buf,
size_t len,
int flags);
uint32_t
cprng_strong32
(void);
uint64_t
cprng_strong64
(void);
size_t
cprng_fast
(void
*buf, size_t
len);
uint32_t
cprng_fast32
(void);
uint64_t
cprng_fast64
(void);
#define CPRNG_MAX_LEN 524288
DESCRIPTION
The cprng
family of functions provide
cryptographic pseudorandom number generators automatically seeded from the
kernel entropy pool. All applications in the kernel requiring random data or
random choices should use the cprng_strong
family of
functions, unless performance constraints demand otherwise.
The cprng_fast
family of functions may be
used in applications that can tolerate exposure of past random data, such as
initialization vectors or transaction ids that are sent over the internet
anyway, if the applications require higher throughput or lower per-request
latency than the cprng_strong
family of functions
provide. If in doubt, choose cprng_strong
.
A single instance of the fast generator
serves the entire kernel. A well-known instance of the strong generator,
kern_cprng
, may be used by any in-kernel caller, but
separately seeded instances of the strong generator can also be created by
calling
cprng_strong_create
().
The cprng
functions may be used at interrupt priority level
IPL_VM
or below, except for
cprng_strong_create
()
and cprng_strong_destroy
() which are allowed only at
IPL_NONE
; see
spl(9).
The cprng
functions replace the legacy
arc4random(9) and
rnd_extract_data(9) functions.
FUNCTIONS
cprng_strong_create
(name, ipl, flags)- Create an instance of the cprng_strong generator. This generator currently
implements the NIST SP 800-90A CTR_DRBG with AES-128 as the block
transform.
The name argument is used to “personalize” the CTR_DRBG according to the standard, so that its initial state will depend both on seed material from the entropy pool and also on the personalization string (name).
The ipl argument specifies the interrupt priority level for the mutex which will serialize access to the new instance of the generator (see spl(9)), and must be no higher than
IPL_VM
.The flags argument controls the behavior of the generator:
CPRNG_INIT_ANY
- Suppress a warning message to the console if, during
cprng_strong_create
(), only partial entropy for the generator is available from the entropy pool. CPRNG_REKEY_ANY
- Suppress a warning message to the console if, during
cprng_strong
() after the generator has been exhausted and must be reseeded, only partial entropy for the generator is available from the entropy pool. CPRNG_USE_CV
- Make
cprng_strong
() sleep if the generator has not been seeded with full entropy until full entropy is available. Otherwise,cprng_strong
() will never sleep when passed this generator. CPRNG_HARD
- Limit the number of bits of output from the generator before reseeding to the number of bits in its seed, so that it approximates the information-theoretic entropy of its seed. Otherwise, the generator may provide many more bits of output than it was seeded with.
Creation will succeed even if full entropy for the generator is not available. In this case, the first request to read from the generator may cause reseeding.
cprng_strong_create
() may sleep to allocate memory. cprng_strong_destroy
(cprng)- Destroy cprng.
cprng_strong_destroy
() may sleep. cprng_strong
(cprng, buf, len, flags)- Fill memory location buf with up to
len bytes from the generator
cprng, and return the number of bytes.
len must be at most
CPRNG_MAX_LEN
.If cprng was created with the
CPRNG_USE_CV
flag and has been exhausted, thencprng_strong
() may sleep until full entropy can be obtained from the entropy pool to reseed it. However, if flags includes theFNONBLOCK
flag, thencprng_strong
() will immediately return zero in this case instead.If cprng was created with the
CPRNG_HARD
flag, thencprng_strong
() will return at most as many bytes as are left from its seed size since the last reseeding.If cprng was created with neither the
CPRNG_USE_CV
flag nor theCPRNG_HARD
flag, thencprng_strong
() is guaranteed to return as many bytes as requested, up toCPRNG_MAX_LEN
, without sleeping. cprng_strong32
()- Generate 32 bits using the
kern_cprng
strong generator.cprng_strong32
() does not sleep. cprng_strong64
()- Generate 64 bits using the
kern_cprng
strong generator.cprng_strong64
() does not sleep. cprng_fast
(buf, len)- Fill memory location buf with
len bytes from the fast generator.
cprng_fast
() does not sleep. cprng_fast32
()- Generate 32 bits using the fast generator.
cprng_fast32
() does not sleep. cprng_fast64
()- Generate 64 bits using the fast generator.
cprng_fast64
() does not sleep.
SECURITY MODEL
The cprng
family of functions provide the
following security properties:
- An attacker who has seen some outputs of any of the
cprng
functions cannot predict past or future unseen outputs. - An attacker who has compromised kernel memory cannot predict past outputs
of the
cprng_strong
functions. However, such an attacker may be able to predict past outputs of thecprng_fast
functions.
The second property is sometimes called “backtracking
resistance”, “forward secrecy”, or “key
erasure” in the cryptography literature. The
cprng_strong
functions provide backtracking
resistance; the cprng_fast
functions do not.
CODE REFERENCES
The cprng_strong
functions are implemented
in sys/kern/subr_cprng.c, and use the NIST SP
800-90A CTR_DRBG implementation in
sys/crypto/nist_ctr_drbg. The
cprng_fast
functions are implemented in
sys/crypto/cprng_fast/cprng_fast.c, and use the
ChaCha8 stream cipher.
SEE ALSO
Elaine Barker and John Kelsey, Recommendation for Random Number Generation Using Deterministic Random Bit Generators (Revised), National Institute of Standards and Technology, 2011, NIST Special Publication 800-90A, Rev 1.
Daniel J. Bernstein, ChaCha, a variant of Salsa20, http://cr.yp.to/papers.html#chacha, 2008-01-28, Document ID: 4027b5256e17b9796842e6d0f68b0b5e.
HISTORY
The cprng family of functions first appeared in NetBSD 6.0.