351 lines
12 KiB
Groff
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 .
|