237 lines
7.6 KiB
Groff
237 lines
7.6 KiB
Groff
.\" $NetBSD: rnd.4,v 1.7 2001/06/11 01:23:24 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 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];
|
|
u_int32_t last_time;
|
|
u_int32_t last_delta;
|
|
u_int32_t last_delta2;
|
|
u_int32_t total;
|
|
u_int32_t type;
|
|
u_int32_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.
|
|
.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 "u_int32_t"
|
|
Return the current entropy count (in bits).
|
|
.It Dv RNDGETSRCNUM
|
|
.Pq Li "rndstat_t"
|
|
.Bd -literal -offset indent
|
|
typedef struct {
|
|
u_int32_t start;
|
|
u_int32_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];
|
|
u_int32_t type;
|
|
u_int32_t flags;
|
|
u_int32_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 {
|
|
u_int32_t len;
|
|
u_int32_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 HISTORY
|
|
The random device was first made available in
|
|
.Nx 1.3 .
|
|
.Sh AUTHOR
|
|
This implementation was written by Michael Graff <explorer@flame.org>
|
|
using ideas and algorithms gathered from many sources, including
|
|
the driver written by Ted Ts'o.
|
|
.Sh SEE ALSO
|
|
.Xr rndctl 8 ,
|
|
.Xr rnd 9
|