RND(4)

RND(4) | Kernel Interfaces Manual | RND(4)

# NAME

rnd — in kernel entropy collection and random number generation

# SYNOPSIS

pseudo-device rnd

# DESCRIPTION

The rnd pseudo-device has three purposes. On read, it returns cryptographically strong random data from a generator keyed from the kernel entropy pool. On write, data may be added to the entropy pool. By ioctl, the behavior of the entropy pool (which sources are used; how their entropy is estimated, etc.) may be controlled.

The kernel uses event timing information collected from many devices, and mixes this into an entropy pool. This pool is used to key a stream generator (the CTR_DRBG generator specified by NIST SP 800-90) which is used to generate values returned to userspace when the pseudo-device is read.

The pseudodevice is cloning, which means that each time it is opened, a new instance of the stream generator is created. Interposing a stream generator between the entropy pool and readers in this manner protects readers from each other (each reader's random stream is generated from a unique key) and protects all users of the entropy pool from any attack which might correlate its successive outputs to each other, such as iterative guessing attacks.

# USER ACCESS

User code can obtain random values from the kernel in two ways.

Reading from /dev/random provides information-theoretic properties desirable for some callers: it will guarantee that the stream generator never outputs more bits than the length of its key, which may in some sense mean that all the entropy provided to it by the entropy pool is "preserved" in its output.

Reading from /dev/random may return EAGAIN (for non-blocking reads), block, or return less data than requested, if the pool does not have sufficient entropy to provide a new key for the stream generator when sufficient bits have been read to require rekeying.

Reading from /dev/urandom will return as many values as requested. The stream generator may be initially keyed from the entropy pool even if the pool's estimate of its own entropy is less than the number of bits in the stream generator's key. If this occurs, the generator will be rekeyed with fresh entropy from the pool as soon as sufficient entropy becomes available. The generator will also be rekeyed whenever the pool's entropy estimate exceeds the size of the pool's internal state (when the pool "is full").

In some sense, this data is not as good as reading from /dev/random, for at least two reasons. First, the generator may initially be keyed from a pool that has never had as many bits of entropy mixed into it as there are bits in the generator's key. Second, the generator may produce many more bits of output than are contained in its own key, though it will never produce more output on one key than is allowed by the CTR_DRBG specification.

However, reading large amounts of data from a single opened instance of /dev/urandom will not deplete the kernel entropy pool, as it would with some other implementations. This preserves entropy for other callers and will produce a more fair distribution of the available entropy over many potential readers on the same system.

Users of these interfaces must carefully consider their application's actual security requirements and the characteristics of the system on which they are reading from the pseudodevice. For many applications, the depletion of the entropy pool caused by the /dev/random pseudodevice's continual rekeying of the stream generator will cause application behavior (or, perhaps more precisely, nonbehavior) which is less secure than relying on the /dev/urandom interface, which is guaranteed to rekey the stream generator as often as it can.

Excessive use of /dev/random can deplete the entropy pool (or, at least, its estimate of how many bits of entropy it "contains") and reduce security for other consumers of randomness both in userspace and within the kernel. Some system administrators may wish therefore to remove the /dev/random device node and replace it with a second copy of the node for the nonblocking /dev/urandom device.

In any event, as the Linux manual page notes, one should be very suspicious of any application which attempts to read more than 32 bytes (256 bits) from the blocking /dev/random pseudodevice, since no practical cryptographic algorithm in current use is believed to have a security strength greater than 256 bits.

Writing to either device node will mix the data written into the entropy pool, but will have no effect on the pool's entropy estimate. The ioctl(2) interface to the device may be used -- once only, and only when the system is in insecure mode at security level 0 or lower -- to add data with an explicit entropy estimate.

# IOCTL INTERFACE

Various ioctl(2) functions are available to control device behavior, gather statistics, and add data to the entropy pool. These are all defined in the <sys/rnd.h> file, along with the data types and constants. The structures and ioctl functions are also listed below.

# DATA TYPES

Each source has a state structure which summarizes the kernel's state for that entropy source.

    typedef struct {
            char            name[16];
            uint32_t	total;
            uint32_t	type;
    	uint32_t	flags;
    } rndsource_t;

The name field holds the device name, as known to the kernel. The type field holds the device type.

Currently, these types are defined:

RND_TYPE_DISK
  The device is a physical hard drive.
RND_TYPE_NET
  The device is a network interface. By default, timing information is collected from this source type, but entropy is not estimated.
RND_TYPE_TAPE
  The device is a tape device.
RND_TYPE_TTY
  The device is a terminal, mouse, or other user input device.
RND_TYPE_RNG
  The device is a random number generator.

flags is a bitfield.

RND_FLAG_NO_ESTIMATE
  Do not assume any entropy is in the timing information.
RND_FLAG_NO_COLLECT
  Do not even add timing information to the pool.

RNDGETENTCNT
  (`uint32_t`) Return the current entropy count (in bits).
RNDGETPOOLSTAT
  (`rndpoolstat_t`)

      typedef struct
      {
      	uint32_t	poolsize;
      	uint32_t 	threshold;
      	uint32_t	maxentropy;

      	uint32_t	added;
      	uint32_t	curentropy;
      	uint32_t	removed;
      	uint32_t	discarded;
      	uint32_t	generated;
      } rndpoolstat_t;

  Return statistics on the current state of the random collection pool.

RNDGETSRCNUM
  (`rndstat_t`)

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

  Return data for sources, starting at start and returning at most count sources.

  The values returned are actual in-kernel snapshots of the entropy status for devices. Leaking the internal timing information will weaken security.

RNDGETSRCNAME
  (`rndstat_name_t`)

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

  Return the device state for a named device.

RNDCTL
  (`rndctl_t`)

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

  Change bits in the device state information. If type is 0xff, only the device name stored in name is used. If it is any other value, all devices of type type are altered. This allows all network interfaces to be disabled for entropy collection with one call, for example. The flags and mask work together to change flag bits. The mask field specifies which bits in flags are to be set or cleared.

RNDADDDATA
  (`rnddata_t`)

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

# FILES

/dev/random
  Returns ``good'' values only
/dev/urandom
  Always returns data.

# SEE ALSO

rndctl(8), rnd(9)

# HISTORY

The random device was first made available in NetBSD 1.3.

# AUTHORS

This implementation was written by Thor Lancelot Simon. It retains some code (particularly for the ioctl interface) from the earlier implementation by Michael Graff <explorer@flame.org>.

December 17, 2011 | NetBSD 5.99