| RND(4) | Device Drivers Manual | RND(4) | 
rnd —
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.)
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:
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.
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:
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).
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.
<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)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.
rnd can be set by privileged users:
kern.entropy.collection
    (bool)RNDADDDATA ioctl.kern.entropy.depletion
    (bool)kern.entropy.consolidate
    (int)# sysctl -w
      kern.entropy.consolidate=1The following read-only sysctl(8) variables provide information to privileged users about the state of the entropy pool:
kern.entropy.needed
    (unsigned int)kern.entropy.pending
    (unsigned int)kern.entropy.consolidate.kern.entropy.epoch
    (unsigned int)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.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=1Short 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.
rnd subsystem may print the following warnings to
  the console likely indicating security issues:
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.
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:
random_seed=YES can serve instead.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önmez 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.
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>.
| August 7, 2023 | NetBSD 10.0 |