Updated: 2021/Apr/14


RND(4)                       Device Drivers Manual                      RND(4)

NAME
     rnd - random number generator

DESCRIPTION
     The /dev/random and /dev/urandom devices generate bytes randomly with
     uniform distribution.  Every read from them is independent.

     /dev/urandom  Never blocks.

     /dev/random   Sometimes blocks.  Will block early at boot if the system's
                   state is known to be predictable.

     Applications should read from /dev/urandom, or the sysctl(7) variable
     kern.arandom, when they need randomly generated data, e.g. key material
     for cryptography or seeds for simulations.  (The sysctl(7) variable
     kern.arandom is limited to 256 bytes per read, but is otherwise
     equivalent to reading from /dev/urandom and always works even in a
     chroot(8) environment without requiring a populated /dev tree and without
     opening a file descriptor, so kern.arandom may be preferable to use in
     libraries.)

     Systems should be engineered to judiciously read at least once from
     /dev/random at boot before running any services that talk to the internet
     or otherwise require cryptography, in order to avoid generating keys
     predictably.  /dev/random may block at any time, so programs that read
     from it must be prepared to handle blocking.  Interactive programs that
     block due to reads from /dev/random can be especially frustrating.

     If interrupted by a signal, reads from either /dev/random or /dev/urandom
     may return short, so programs that handle signals must be prepared to
     retry reads.

     Writing to either /dev/random or /dev/urandom influences subsequent
     output of both devices, guaranteed to take effect at next open.  If you
     have a coin in your pocket, you can flip it 256 times and feed the
     outputs to /dev/random to guarantee your system is in a state that nobody
     but you and the bored security guard watching the surveillance camera in
     your office can guess:

         % echo tthhhhhthhhththtthhhhthtththttth... > /dev/random

     (Sequence generated from a genuine US quarter dollar, guaranteed random.)

SECURITY MODEL
     The rnd subsystem provides the following security properties against two
     different classes of attackers, provided that there is enough entropy
     from entropy sources not seen by attackers:

            An attacker who has seen some outputs and can supply some entropy
             sources' inputs to the operating system cannot predict past or
             future unseen outputs.

            An attacker who has seen the entire state of the machine cannot
             predict past outputs.

     One `output' means a single read, no matter how short it is.

     `Cannot predict' means it is conjectured of the cryptography in
     /dev/random that any computationally bounded attacker who tries to
     distinguish outputs from uniform random cannot do more than negligibly
     better than uniform random guessing.

ENTROPY
     The operating system continuously makes observations of hardware devices,
     such as network packet timings, disk seek delays, and keystrokes.  The
     observations are combined into a seed for a cryptographic pseudorandom
     number generator (PRNG) which is used to generate the outputs of both
     /dev/random and /dev/urandom.

     An attacker may be able to guess with nonnegligible chance of success
     what your last keystroke was, but guessing every observation the
     operating system may have made is more difficult.  The difficulty of the
     best strategy at guessing a random variable is analyzed as the -log_2 of
     the highest probability of any outcome, measured in bits, and called its
     min-entropy, or entropy for short in cryptography.  For example:
            A fair coin toss has one bit of entropy.
            A fair (six-sided) die roll has a little over 2.5 bits of
             entropy.
            A string of two independent fair coin tosses has two bits of
             entropy.
            The toss of a pair of fair coins that are glued together has one
             bit of entropy.
            A uniform random distribution with n possibilities has log_2 n
             bits of entropy.
            An utterance from an accounting troll who always says `nine' has
             zero bits of entropy.

     Note that entropy is a property of an observable physical process, like a
     coin toss, or of a state of knowledge about that physical process; it is
     not a property of a specific sample obtained by observing it, like the
     string `tthhhhht'.  There are also kinds of entropy in information theory
     other than min-entropy, including the more well-known Shannon entropy,
     but they are not relevant here.

     Hardware devices that the operating system monitors for observations are
     called entropy sources, and the observations are combined into an entropy
     pool.  The rndctl(8) command queries information about entropy sources
     and the entropy pool, and can control which entropy sources the operating
     system uses or ignores.

     256 bits of entropy is typically considered intractable to guess with
     classical computers and with current models of the capabilities of
     quantum computers.

     Systems with nonvolatile storage should store a secret from /dev/urandom
     on disk during installation or shutdown, and feed it back during boot, so
     that the work the operating system has done to gather entropy --
     including the work its operator may have done to flip a coin! -- can be
     saved from one boot to the next, and so that newly installed systems are
     not vulnerable to generating cryptographic keys predictably.

     The boot loaders in some NetBSD ports support a command to load a seed
     from disk before the kernel has started.  For those that don't, the
     rndctl(8) command can do it once userland has started, for example by
     setting "random_seed=YES" in /etc/rc.conf, which is enabled by default;
     see rc.conf(5).

LIMITATIONS
     Some people worry about recovery from state compromise -- that is,
     ensuring that even if an attacker sees the entire state of the operating
     system, then the attacker will be unable to predict any new future
     outputs as long as the operating system gathers fresh entropy quickly
     enough.

     But if an attacker has seen the entire state of your machine, refreshing
     entropy is probably the least of your worries, so we do not address that
     threat model here.

     The rnd subsystem does not automatically defend against hardware
     colluding with an attacker to influence entropy sources based on the
     state of the operating system.

     For example, a PCI device or CPU instruction for random number generation
     which has no side channel to an attacker other than the /dev/urandom
     device could be bugged to observe all other entropy sources, and to
     carefully craft `observations' that cause a certain number of bits of
     /dev/urandom output to be ciphertext that either is predictable to an
     attacker or conveys a message to an attacker.

     No amount of scrutiny by the system's operator could detect this.  The
     only way to prevent this attack would be for the operator to disable all
     entropy sources that may be colluding with an attacker.  If you're not
     sure which ones are not, you can always disable all of them and fall back
     to the coin in your pocket.

IOCTLS
     The /dev/random and /dev/urandom devices support a number of ioctls,
     defined in the <sys/rndio.h> header file, for querying and controlling
     the entropy pool.

     Since timing between hardware events contributes to the entropy pool,
     statistics about the entropy pool over time may serve as a side channel
     for the state of the pool, so access to such statistics is restricted to
     the super-user and should be used with caution.

     Several ioctls are concerned with particular entropy sources, described
     by the following structure:

     typedef struct {
             char            name[16];       /* symbolic name */
             uint32_t        total;          /* estimate of entropy provided */
             uint32_t        type;           /* RND_TYPE_* value */
             uint32_t        flags;          /* RND_FLAG_* mask */
     } rndsource_t;

     #define RND_TYPE_UNKNOWN
     #define RND_TYPE_DISK           /* disk device */
     #define RND_TYPE_ENV            /* environment sensor (temp, fan, &c.) */
     #define RND_TYPE_NET            /* network device */
     #define RND_TYPE_POWER          /* power events */
     #define RND_TYPE_RNG            /* hardware RNG */
     #define RND_TYPE_SKEW           /* clock skew */
     #define RND_TYPE_TAPE           /* tape drive */
     #define RND_TYPE_TTY            /* tty device */
     #define RND_TYPE_VM             /* virtual memory faults */

     #define RND_TYPE_MAX            /* value of highest-numbered type */

     #define RND_FLAG_COLLECT_TIME           /* use timings of samples */
     #define RND_FLAG_COLLECT_VALUE          /* use values of samples */
     #define RND_FLAG_ESTIMATE_TIME          /* estimate entropy of timings */
     #define RND_FLAG_ESTIMATE_VALUE         /* estimate entropy of values */
     #define RND_FLAG_NO_COLLECT             /* ignore samples from this */
     #define RND_FLAG_NO_ESTIMATE            /* do not estimate entropy */

     The following ioctls are supported:

     RNDGETENTCNT (uint32_t)
           Return the number of bits of entropy the system is estimated to
           have.

     RNDGETSRCNUM (rndstat_t)

           typedef struct {
                   uint32_t        start;
                   uint32_t        count;
                   rndsource_t     source[RND_MAXSTATCOUNT];
           } rndstat_t;

           Fill the sources array with information about up to count entropy
           sources, starting at start.  The actual number of sources described
           is returned in count.  At most RND_MAXSTATCOUNT sources may be
           requested at once.

     RNDGETSRCNAME (rndstat_name_t)

           typedef struct {
                   char            name[16];
                   rndsource_t     source;
           } rndstat_name_t;

           Fill source with information about the entropy source named name,
           or fail with ENOENT if there is none.

     RNDCTL (rndctl_t)

           typedef struct {
                   char            name[16];
                   uint32_t        type;
                   uint32_t        flags;
                   uint32_t        mask;
           } rndctl_t;

           For each entropy source of the type type, or if type is 0xff then
           for the entropy source named name, replace the flags in mask by
           flags.

     RNDADDDATA (rnddata_t)

           typedef struct {
                   uint32_t        len;
                   uint32_t        entropy;
                   unsigned char   data[RND_SAVEWORDS * sizeof(uint32_t)];
           } rnddata_t;

           Feed len bytes of data to the entropy pool.  The sample is expected
           to have been drawn with at least entropy bits of entropy.

           This ioctl can be used only once per boot.  It is intended for a
           system that saves entropy to disk on shutdown and restores it on
           boot, so that the system can immediately be unpredictable without
           having to wait to gather entropy.

     RNDGETPOOLSTAT (rndpoolstat_t)

           typedef struct {
                   uint32_t poolsize;      /* size of each LFSR in pool */
                   uint32_t threshold;     /* no. bytes of pool hash returned */
                   uint32_t maxentropy;    /* total size of pool in bits */
                   uint32_t added;         /* no. bits of entropy ever added */
                   uint32_t curentropy;    /* current entropy `balance' */
                   uint32_t discarded;     /* no. bits dropped when pool full */
                   uint32_t generated;     /* no. bits yielded by pool while
                                              curentropy is zero */
           } rndpoolstat_t;

           Return various statistics about entropy.

SYSCTLS
     The following sysctl(8) variables provided by rnd can be set by
     privileged users:

     kern.entropy.collection (bool)
           (Default on.)  Enables entering data into the entropy pool.  If
           disabled, no new data can be entered into the entropy pool, whether
           by device drivers, by writes to /dev/random or /dev/urandom, or by
           the RNDADDDATA ioctl.

     kern.entropy.depletion (bool)
           (Default off.)  Enables `entropy depletion', meaning that even
           after attaining full entropy, the kernel subtracts the number of
           bits read out of the entropy pool from its estimate of the system
           entropy.  This is not justified by modern cryptography -- an
           adversary will never guess the 256-bit secret in a Keccak sponge no
           matter how much output from the sponge they see -- but may be
           useful for testing.

     kern.entropy.consolidate (int)
           Trigger for entropy consolidation: executing
                 # sysctl -w kern.entropy.consolidate=1
           causes the system to consolidate pending entropy from per-CPU pools
           into the global pool, and waits until done.

     The following read-only sysctl(8) variables provide information to
     privileged users about the state of the entropy pool:

     kern.entropy.needed (unsigned int)
           Number of bits of entropy the system is waiting for in the global
           pool before reads from /dev/random will return without blocking.
           When zero, the system is considered to have full entropy.

     kern.entropy.pending (unsigned int)
           Number of bits of entropy pending in per-CPU pools.  This is the
           amount of entropy that will be contributed to the global pool at
           the next consolidation, such as from triggering
           kern.entropy.consolidate.

     kern.entropy.epoch (unsigned int)
           Number of times system has reached full entropy, or entropy has
           been consolidated with kern.entropy.consolidate, as an unsigned
           32-bit integer.  Consulted inside the kernel by subsystems such as
           cprng(9) to decide whether to reseed.  Initially set to 2^32 - 1
           (i.e., (unsigned)-1) meaning the system has never reached full
           entropy and the entropy has never been consolidated; never again
           set to 2^32 - 1.  Never zero, so applications can initialize a
           cache of the epoch to zero to ensure they reseed the next time they
           check whether it is different from the stored epoch.

IMPLEMENTATION NOTES
     (This section describes the current implementation of the rnd subsystem
     at the time of writing.  It may be out-of-date by the time you read it,
     and nothing in here should be construed as a guarantee about the
     behaviour of the /dev/random and /dev/urandom devices.)

     Device drivers gather samples from entropy sources and absorb them into a
     collection of per-CPU Keccak sponges called `entropy pools' using the
     rnd(9) kernel API.  The device driver furnishes an estimate for the
     entropy of the sampling process, under the assumption that each sample is
     independent.  When the estimate of entropy pending among the per-CPU
     entropy pools reaches a threshold of 256 bits, the entropy is drawn from
     the per-CPU pools and consolidated into a global pool.  Keys for
     /dev/random, /dev/urandom, kern.arandom, and the in-kernel cprng(9)
     subsystem are extracted from the global pool.

     Early after boot, before CPUs have been detected, device drivers instead
     enter directly into the global pool.  If anything in the system extracts
     data from the pool before the threshold has been reached at least once,
     the system will print a warning to the console and reset the entropy
     estimate to zero.  The reason for resetting the entropy estimate to zero
     in this case is that an adversary who can witness output from the pool
     with partial entropy -- say, 32 bits -- can undergo a feasible brute
     force search to ascertain the complete state of the pool; as such, the
     entropy of the adversary's state of knowledge about the pool is zero.

     If the operator is confident that the drivers' estimates of the entropy
     of the sampling processes are too conservative, the operator can issue
           # sysctl -w kern.entropy.consolidate=1
     to force consolidation into the global pool.  The operator can also fool
     the system into thinking it has more entropy than it does by feeding data
     from /dev/urandom into /dev/random, but this voids the security model and
     should be limited to testing purposes.

     Short reads from /dev/urandom are served by a persistent per-CPU
     Hash_DRBG instance that is reseeded from the entropy pool after any
     entropy consolidation.  Reads from /dev/random and long reads from
     /dev/urandom are served by a temporary Hash_DRBG seeded from the entropy
     pool on each read.

     When `entropy depletion' is enabled by setting the sysctl variable
     kern.entropy.depletion=1, every read from /dev/random is limited to 256
     bits, since reading more than that would nearly always block again.

FILES
     /dev/random   Uniform random byte source.  May block.
     /dev/urandom  Uniform random byte source.  Never blocks.

DIAGNOSTICS
     The rnd subsystem may print the following warnings to the console likely
     indicating security issues:

           entropy: WARNING: extracting entropy too early  Something requested
           extraction of entropy from the pool before it has ever reached full
           entropy in the system's estimation.

           The entropy may be low enough that an adversary who sees the output
           could guess the state of the pool by brute force, so in this event
           the system resets its estimate of entropy to none.

           This message is rate-limited to happen no more often than once per
           minute, so if you want to make sure it is gone you should consult
           kern.entropy.needed to confirm it is zero.

           entropy: WARNING: consolidating less than full entropy  The
           operator triggered consolidation of entropy pending in per-CPU
           pools into the global pool when the system's estimate of the amount
           of entropy was still below the 256-bit threshold.

           This message can be safely ignored if the operator knows something
           the system doesn't, e.g. if the operator has flipped a coin 256
           times and written the outcomes to /dev/random.

           This message is rate-limited to happen no more often than once per
           minute.

     The rnd subsystem may print any of various messages about obtaining an
     entropy seed from the bootloader to diagnose saving and loading seeds on
     disk:

           entropy: entering seed from bootloader with N bits of entropy  The
           bootloader provided an entropy seed to the kernel, which recorded
           an estimate of N bits of entropy in the process that generated it.

           entropy: no seed from bootloader  The bootloader did not provide an
           entropy seed to the kernel before starting the kernel.  This does
           not necessarily indicate a problem; not all bootloaders support the
           option, and the rc.conf(5) setting random_seed=YES can serve
           instead.

           entropy: invalid seed length N, expected sizeof(rndsave_t) = M  The
           bootloader provided an entropy seed of the wrong size to the
           kernel.  This may indicate a bug in rndctl(8).  The seed will be
           ignored.

           entropy: invalid seed checksum  The entropy seed provided by the
           bootloader was malformed.  The seed will be entered into the
           entropy pool, but it will be considered to contribute no entropy.

           entropy: double-seeded by bootloader  A buggy bootloader tried to
           provide an entropy seed more than once to the kernel.  Subsequent
           seeds will be entered into the entropy pool, but they will be
           considered to contribute no entropy.

           entropy: ready  The system has full entropy for the first time.

SEE ALSO
     arc4random(3), entropy(7), rndctl(8), cprng(9), rnd(9)

     Elaine Barker and John Kelsey, Recommendation for Random Number
     Generation Using Deterministic Random Bit Generators, National Institute
     of Standards and Technology,
     https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final, United
     States Department of Commerce, June 2015, NIST Special Publication
     800-90A, Revision 1.

     Meltem S"onmez Turan, Elaine Barker, John Kelsey, Kerry A. McKay, Mary L.
     Baish, and Mike Boyle, Recommendations for the Entropy Sources Used for
     Random Bit Generation, National Institute of Standards and Technology,
     https://csrc.nist.gov/publications/detail/sp/800-90b/final, United States
     Department of Commerce, January 2018, NIST Special Publication 800-90B.

     Daniel J. Bernstein, Entropy Attacks!,
     http://blog.cr.yp.to/20140205-entropy.html, 2014-02-05.

     Nadia Heninger, Zakir Durumeric, Eric Wustrow, and J. Alex Halderman,
     "Mining Your Ps and Qs: Detection of Widespread Weak Keys in Network
     Devices", Proceedings of the 21st USENIX Security Symposium, USENIX,
     https://www.usenix.org/conference/usenixsecurity12/technical-sessions/presentation/heninger,
     https://factorable.net/, 205-220, August 2012.

     Edwin T. Jaynes, Probability Theory: The Logic of Science, Cambridge
     University Press, https://bayes.wustl.edu/, 2003.

HISTORY
     The /dev/random and /dev/urandom devices first appeared in NetBSD 1.3.

AUTHORS
     The rnd subsystem was first implemented by Michael Graff
     <explorer@flame.org>, was then largely rewritten by Thor Lancelot Simon
     <tls@NetBSD.org>, and was most recently largely rewritten by Taylor R.
     Campbell <riastradh@NetBSD.org>.

BUGS
     Many people are confused about what /dev/random and /dev/urandom mean.
     Unfortunately, no amount of software engineering can fix that.

NetBSD 9.99                       May 1, 2020                      NetBSD 9.99