NetBSD/share/man/man4/rnd.4

351 lines
12 KiB
Groff

.\" $NetBSD: rnd.4,v 1.20 2012/04/17 08:28:20 wiz 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 April 17, 2012
.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 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.
.Pp
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.
.Pp
The pseudodevice is cloning, which means that each time it is opened,
a new instance of the stream generator may be 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.
.Pp
Certain programs make very short reads from
.Pa /dev/urandom
each time they begin execution.
One program with this behavior is
.Xr perl 1 .
If such a program is run repeatedly (for example from a network
service or shell script), the resulting repeated keying of the stream
generator can quickly drain the entropy pool dry.
As an optimization for such cases, a separate per-CPU instance of
the stream generator is used to handle reads from
.Pa /dev/urandom
which are smaller than the key length of the underlying cipher.
Any read of a larger size causes an immediate allocation of a
private instance of the stream generator for the reader.
Since all stream
generators are automatically rekeyed upon use when sufficient entropy
is available, the shared short-request generators do still offer
some protection against other consumers of
.Pa /dev/urandom ,
though less than is provided for consumers making larger requests.
.Sh USER ACCESS
User code can obtain random values from the kernel in two ways.
.Pp
Reading from
.Pa /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.
.Pp
Reading from
.Pa /dev/random
may return
.Er 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.
.Pp
Reading from
.Pa /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").
.Pp
In some sense, this data is not as good as reading from
.Pa /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.
.Pp
However, reading large amounts of data from a single opened instance of
.Pa /dev/urandom
will
.Em 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.
.Pp
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
.Pa /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
.Pa /dev/urandom
interface, which is guaranteed to rekey the stream generator as often
as it can.
.Pp
Excessive use of
.Pa /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
.Em and within the kernel .
Some system administrators may wish therefore to remove the
.Pa /dev/random
device node and replace it with a second copy of the node for the nonblocking
.Pa /dev/urandom
device.
.Pp
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
.Pa /dev/random
pseudodevice, since no practical cryptographic algorithm in current
use is believed to have a security strength greater than 256 bits.
.Pp
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
.Xr 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.
.Sh IOCTL INTERFACE
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
.In sys/rnd.h
file, along with the data types and constants.
The structures and ioctl functions are also listed below.
.Sh DATA TYPES
Each source has a state structure which summarizes the kernel's state
for that entropy source.
.Bd -literal -offset indent
typedef struct {
char name[16];
uint32_t total;
uint32_t type;
uint32_t flags;
} rndsource_t;
.Ed
The
.Va name
field holds the device name, as known to the kernel.
The
.Va type
field holds the device type.
.Pp
Currently, these types are defined:
.Bl -tag -width RND_TYPE_DISK
.It Dv RND_TYPE_DISK
The device is a physical hard drive.
.It Dv RND_TYPE_ENV
The device is an environmental sensor such as a temperature sensor or
a fan speed sensor.
.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_POWER
The device is a sensor returning changes in the power state of the
system, such as battery charge state or A/C adapter state.
.It Dv RND_TYPE_RNG
The device is a random number generator.
.It Dv RND_TYPE_SKEW
The "device" is a measurement of the skew between two clocks, such as a
periodic device interrupt and the system timecounter, a timecounter and
an audio codec, or some other source of pairs of events where each
member of each pair is derived from a different instance of some
recurring physical process.
.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_VM
The "device" consists of timings of virtual memory system events.
.El
.Pp
.Va flags
is a bitfield.
.Bl -tag -width RND_FLAG_NO_ESTIMATE
.It Dv RND_FLAG_NO_COLLECT
Do not even add timing information to the pool.
.It Dv RND_FLAG_NO_ESTIMATE
Do not assume any entropy is in the timing information.
.El
.Pp
.Bl -tag -width RNDADDTOENTCNT
.It Dv RNDGETENTCNT
.Pq Li "uint32_t"
Return the current entropy count (in bits).
.It Dv RNDGETPOOLSTAT
.Pq Li "rndpoolstat_t"
.Bd -literal -offset indent
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;
.Ed
.Pp
Return statistics on the current state of the random collection pool.
.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_SAVEWORDS * sizeof(uint32_t)];
} 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.
.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 Thor Lancelot Simon.
It retains
some code (particularly for the ioctl interface) from the earlier
implementation by Michael Graff
.Aq explorer@flame.org .