.\" $NetBSD: rnd.4,v 1.12 2005/12/26 19:48:12 perry Exp $ .\" .\" Copyright (c) 1997 Michael Graff .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. The name of the author may not be used to endorse or promote products .\" derived from this software without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, .\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; .\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED .\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, .\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .Dd October 12, 1997 .Dt RND 4 .Os .Sh NAME .Nm rnd .Nd in kernel entropy collection and random number generation .Sh SYNOPSIS .Cd pseudo-device rnd .Sh DESCRIPTION The .Nm pseudo-device uses event timing information collected from many devices, and mixes this into an entropy pool. This pool is stirred with a cryptographically strong hash function when data is extracted from the pool. .Sh INTERNAL ENTROPY POOL MANAGEMENT When a hardware event occurs (such as completion of a hard drive transfer or an interrupt from a network device) a timestamp is generated. This timestamp is compared to the previous timestamp recorded for the device, and the first, second, and third order differentials are calculated. .Pp If any of these differentials is zero, no entropy is assumed to have been gathered. If all are non-zero, one bit is assumed. Next, data is mixed into the entropy pool using an LFSR (linear feedback shift register). .Pp To extract data from the entropy pool, a cryptographically strong hash function is used. The output of this hash is mixed back into the pool using the LFSR, and then folded in half before being returned to the caller. .Pp Mixing the actual hash into the pool causes the next extraction to return a different value, even if no timing events were added to the pool. Folding the data in half prevents the caller to derive the actual hash of the pool, preventing some attacks. .Sh USER ACCESS User code can obtain random values from the kernel in two ways. .Pp Reading from .Pa /dev/random will only return values while sufficient entropy exists in the internal pool. When sufficient entropy does not exist, EAGAIN is returned for non-blocking reads, or the read will block for blocking reads. .Pp Reading from .Pa /dev/urandom will return as many values as requested, even when the entropy pool is empty. This data is not as good as reading from .Pa /dev/random since when the pool is empty, data is still returned, degenerating to a pseudo-random generator. .Pp Writing to either device will mix the data written into the pool using the LFSR as above, without modifying the entropy estimation for the pool. .Sh RANDOM SOURCE STRUCTURE Each source has a state structure which the kernel uses to hold the timing information and other state for that source. .Bd -literal -offset indent typedef struct { char name[16]; uint32_t last_time; uint32_t last_delta; uint32_t last_delta2; uint32_t total; uint32_t type; uint32_t flags; } rndsource_t; .Ed .Pp This structure holds the internal representation of a device's timing state. The .Va name field holes the device name, as known to the kernel. The .Va last_time entry is the timestamp of the last time this device generated an event. It is for internal use only, and not in any specific representation. The .Va last_delta and .Va last_delta2 fields hold the last first- and second-order deltas. The .Va total field holds a count of how many bits this device has potentially generated. This is not the same as how many bits were used from it. The .Va type field holds the device type. .Pp .Bl -tag -width RND_TYPE_DISK Currently, these types are defined: .It Dv RND_TYPE_DISK The device is a physical hard drive. .It Dv RND_TYPE_NET The device is a network interface. By default, timing information is collected from this source type, but entropy is not estimated. .It Dv RND_TYPE_TAPE The device is a tape device. .It Dv RND_TYPE_TTY The device is a terminal, mouse, or other user input device. .It Dv RND_TYPE_RNG The device is a random number generator. .El .Pp .Va flags is a bitfield. .Bl -tag -width RND_FLAG_NO_ESTIMATE .It Dv RND_FLAG_NO_ESTIMATE Do not assume any entropy is in the timing information. .It Dv RND_FLAG_NO_COLLECT Do not even add timing information to the pool. .El .Sh IOCTL Various .Xr ioctl 2 functions are available to control device behavior, gather statistics, and add data to the entropy pool. These are all defined in the .Aq Pa sys/rnd.h file, along with the data types and constants. .Pp .Bl -tag -width RNDADDTOENTCNT .It Dv RNDGETENTCNT .Pq Li "uint32_t" Return the current entropy count (in bits). .It Dv RNDGETSRCNUM .Pq Li "rndstat_t" .Bd -literal -offset indent typedef struct { uint32_t start; uint32_t count; rndsource_t source[RND_MAXSTATCOUNT]; } rndstat_t; .Ed .Pp Return data for sources, starting at .Va start and returning at most .Va count sources. .Pp The values returned are actual in-kernel snapshots of the entropy status for devices. Leaking the internal timing information will weaken security. .It Dv RNDGETSRCNAME .Pq Li "rndstat_name_t" .Bd -literal -offset indent typedef struct { char name[16]; rndsource_t source; } rndstat_name_t; .Ed .Pp Return the device state for a named device. .It Dv RNDCTL .Pq Li "rndctl_t" .Bd -literal -offset indent typedef struct { char name[16]; uint32_t type; uint32_t flags; uint32_t mask; } rndctl_t; .Ed .Pp Change bits in the device state information. If .Va type is 0xff, only the device name stored in .Va name is used. If it is any other value, all devices of type .Va type are altered. This allows all network interfaces to be disabled for entropy collection with one call, for example. The .Va flags and .Va mask work together to change flag bits. The .Va mask field specifies which bits in .Va flags are to be set or cleared. .It Dv RNDADDDATA .Pq Li "rnddata_t" .Bd -literal -offset indent typedef struct { uint32_t len; uint32_t entropy; u_char data[RND_POOLWORDS * 4]; } rnddata_t; .Ed .El .Sh FILES .Bl -tag -width /dev/urandomx -compact .It Pa /dev/random Returns ``good'' values only .It Pa /dev/urandom Always returns data, degenerates to a pseudo-random generator .El .Sh SEE ALSO .Xr rndctl 8 , .Xr rnd 9 .Sh HISTORY The random device was first made available in .Nx 1.3 . .Sh AUTHORS This implementation was written by Michael Graff \*[Lt]explorer@flame.org\*[Gt] using ideas and algorithms gathered from many sources, including the driver written by Ted Ts'o.