CPRNG(9)

CPRNG(9) | Kernel Developer's Manual | CPRNG(9)

# 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 in soft interrupt context, except for `cprng_strong_create`() and `cprng_strong_destroy`() which are allowed only at `IPL_NONE` in thread context; 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 Hash_DRBG with SHA-256 as the hash function.

  The name argument is used to “personalize” the Hash_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_SOFTSERIAL`.

  The flags argument must be zero.

  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`. flags must be zero.
`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 Hash_DRBG implementation in sys/crypto/nist_hash_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.

August 16, 2020 | NetBSD 11.0