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);
uint32_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, then
cprng_strong() may sleep until full entropy can be
obtained from the entropy pool to reseed it. However, if
flags includes the FNONBLOCK
flag, then cprng_strong() will immediately return zero
in this case instead.
If cprng was created with the
CPRNG_HARD
flag, then
cprng_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 the
CPRNG_HARD
flag, then
cprng_strong() is guaranteed to return as many bytes as
requested, up to CPRNG_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 the
cprng_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
condvar(9),
rnd(9),
spl(9)
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.