Rewrite /dev/random man page.
- Describe application usage up front. - State the security model. - Explain entropy. - Describe current implementation strategy near the bottom.
This commit is contained in:
parent
ca5e6fe73f
commit
ede4dd9ede
|
@ -1,8 +1,11 @@
|
|||
.\" $NetBSD: rnd.4,v 1.20 2012/04/17 08:28:20 wiz Exp $
|
||||
.\" $NetBSD: rnd.4,v 1.21 2015/01/07 18:50:18 riastradh Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1997 Michael Graff
|
||||
.\" Copyright (c) 2014 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to The NetBSD Foundation
|
||||
.\" by Taylor R. Campbell.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
|
@ -11,340 +14,596 @@
|
|||
.\" 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.
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
.\" ``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 FOUNDATION OR CONTRIBUTORS
|
||||
.\" 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
|
||||
.Dd November 16, 2014
|
||||
.Dt RND 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rnd
|
||||
.Nd in kernel entropy collection and random number generation
|
||||
.Sh SYNOPSIS
|
||||
.Cd pseudo-device rnd
|
||||
.Nd random number generator
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Pa /dev/random
|
||||
and
|
||||
.Pa /dev/urandom
|
||||
devices generate bytes randomly with uniform distribution.
|
||||
Every read from them is independent.
|
||||
.Bl -tag -width /dev/urandom
|
||||
.It Pa /dev/urandom
|
||||
Never blocks.
|
||||
.It Pa /dev/random
|
||||
Sometimes blocks.
|
||||
Will block early at boot if the system's state is known to be
|
||||
predictable.
|
||||
.El
|
||||
.Pp
|
||||
Applications should read from
|
||||
.Pa /dev/urandom
|
||||
when they need randomly generated data, e.g. key material for
|
||||
cryptography or seeds for simulations.
|
||||
.Pp
|
||||
Systems should be engineered to judiciously read at least once from
|
||||
.Pa /dev/random
|
||||
at boot before running any services that talk to the internet or
|
||||
otherwise require cryptography, in order to avoid generating keys
|
||||
predictably.
|
||||
.Pp
|
||||
.Pa /dev/random
|
||||
may block at any time, so programs that read from it must be prepared
|
||||
to handle blocking.
|
||||
Interactive programs that block due to reads from
|
||||
.Pa /dev/random
|
||||
can be especially frustrating.
|
||||
.Pp
|
||||
If interrupted by a signal, reads from either
|
||||
.Pa /dev/random
|
||||
or
|
||||
.Pa /dev/urandom
|
||||
may return short, so programs that handle signals must be prepared to
|
||||
retry reads.
|
||||
.Pp
|
||||
Writing to either
|
||||
.Pa /dev/random
|
||||
or
|
||||
.Pa /dev/urandom
|
||||
influences subsequent output of both devices, guaranteed to take
|
||||
effect at next open.
|
||||
.Pp
|
||||
If you have a coin in your pocket, you can flip it 256 times and feed
|
||||
the outputs to
|
||||
.Pa /dev/random
|
||||
to guarantee your system is in a state that nobody but you and the
|
||||
bored security guard watching the surveillance camera in your office
|
||||
can guess:
|
||||
.Bd -literal -offset abcd
|
||||
% echo tthhhhhthhhththtthhhhthtththttth... > /dev/random
|
||||
.Ed
|
||||
.Pp
|
||||
(Sequence generated from a genuine US quarter dollar, guaranteed
|
||||
random.)
|
||||
.Sh SECURITY MODEL
|
||||
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.
|
||||
subsystem provides the following security properties against two
|
||||
different classes of attackers, provided that there is enough entropy
|
||||
from entropy sources not seen by attackers:
|
||||
.Bl -bullet -offset abcd
|
||||
.It
|
||||
An attacker who has seen some outputs and can supply some entropy
|
||||
sources' inputs to the operating system cannot predict past or future
|
||||
unseen outputs.
|
||||
.It
|
||||
An attacker who has seen the entire state of the machine cannot predict
|
||||
past outputs.
|
||||
.El
|
||||
.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.
|
||||
One
|
||||
.Sq output
|
||||
means a single read, no matter how short it is.
|
||||
.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
|
||||
.Sq Cannot predict
|
||||
means it is conjectured of the cryptography in
|
||||
.Fa /dev/random
|
||||
that any computationally bounded attacker who tries to distinguish
|
||||
outputs from uniform random cannot do more than negligibly better than
|
||||
uniform random guessing.
|
||||
.Sh ENTROPY
|
||||
The operating system contiuously makes observations of hardware
|
||||
devices, such as network packet timings, disk seek delays, and
|
||||
keystrokes.
|
||||
The observations are combined into a seed for a cryptographic
|
||||
pseudorandom number generator (PRNG) which is used to generate the
|
||||
outputs of both
|
||||
.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.
|
||||
and
|
||||
.Pa /dev/urandom .
|
||||
.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.
|
||||
An attacker may be able to guess with nonnegligible chance of success
|
||||
what your last keystroke was, but guessing every observation the
|
||||
operating system may have made is more difficult.
|
||||
The difficulty of the best strategy at guessing a random variable is
|
||||
analyzed as the -log_2 of the highest probability of any outcome,
|
||||
measured in bits, and called its
|
||||
.Em min-entropy ,
|
||||
or
|
||||
.Em entropy
|
||||
for short in cryptography.
|
||||
For example:
|
||||
.Bl -bullet -offset abcd -compact
|
||||
.It
|
||||
A fair coin toss has one bit of entropy.
|
||||
.It
|
||||
A fair (six-sided) die roll has a little over 2.5 bits of entropy.
|
||||
.It
|
||||
A string of two independent fair coin tosses has two bits of entropy.
|
||||
.It
|
||||
The toss of a pair of fair coins that are glued together has one bit of
|
||||
entropy.
|
||||
.It
|
||||
A uniform random distribution with
|
||||
.Fa n
|
||||
possibilities has log_2
|
||||
.Fa n
|
||||
bits of entropy.
|
||||
.It
|
||||
An utterance from an accounting troll who always says
|
||||
.Sq nine
|
||||
has zero bits of entropy.
|
||||
.El
|
||||
.Pp
|
||||
Reading from
|
||||
Note that entropy is a property of an observable physical process, not
|
||||
of a particular sample obtained by observing it.
|
||||
There are also kinds of entropy in information theory other than
|
||||
min-entropy, including the more well-known Shannon entropy, but they
|
||||
are not relevant here.
|
||||
.Pp
|
||||
Hardware devices that the operating system monitors for observations
|
||||
are called
|
||||
.Em "entropy sources" ,
|
||||
and the observations are combined into an
|
||||
.Em "entropy pool" .
|
||||
The
|
||||
.Xr rndctl 8
|
||||
command queries information about entropy sources and the entropy pool,
|
||||
and can control which entropy sources the operating system uses or
|
||||
ignores.
|
||||
.Pp
|
||||
256 bits of entropy is typically considered intractible to guess with
|
||||
classical computers and with current models of the capabilities of
|
||||
quantum computers.
|
||||
.Pp
|
||||
Systems with nonvolatile storage should store a secret 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").
|
||||
on disk during installation or shutdown, and feed it back during boot,
|
||||
so that the work the operating system has done to gather entropy --
|
||||
including the work its operator may have done to flip a coin! -- can be
|
||||
saved from one boot to the next, and so that newly installed systems
|
||||
are not vulnerable to generating cryptographic keys predictably.
|
||||
.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.
|
||||
The boot loaders in some
|
||||
.Nx
|
||||
ports support a command to load a seed from disk before the
|
||||
kernel has started.
|
||||
For those that don't, the
|
||||
.Xr rndctl 8
|
||||
command can do it once userland has started, for example by setting
|
||||
.Dq Va rndctl=YES
|
||||
in
|
||||
.Pa /etc/rc.conf ;
|
||||
see
|
||||
.Xr rc.conf 5 .
|
||||
.Sh LIMITATIONS
|
||||
Some people worry about recovery from state compromise -- that is,
|
||||
ensuring that even if an attacker sees the entire state of the
|
||||
operating system, then the attacker will be unable to predict any new
|
||||
future outputs as long as the operating system gathers fresh entropy
|
||||
quickly enough.
|
||||
.Pp
|
||||
However, reading large amounts of data from a single opened instance of
|
||||
.Pa /dev/urandom
|
||||
will
|
||||
But if an attacker has seen the entire state of your machine,
|
||||
refreshing entropy is probably the least of your worries, so we do not
|
||||
address that threat model here.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
subsystem does
|
||||
.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.
|
||||
automatically defend against hardware colluding with an attacker to
|
||||
influence entropy sources based on the state of the operating 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
|
||||
For example, a PCI device or CPU instruction for random number
|
||||
generation which has no side channel to an attacker other than 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
|
||||
device could be bugged to observe all other entropy sources, and to
|
||||
carefully craft
|
||||
.Sq observations
|
||||
that cause a certain number of bits of
|
||||
.Pa /dev/urandom
|
||||
device.
|
||||
output to be ciphertext that either is predictable to an attacker or
|
||||
conveys a message to an attacker.
|
||||
.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.
|
||||
No amount of scrutiny by the system's operator could detect this.
|
||||
The only way to prevent this attack would be for the operator to
|
||||
disable all entropy sources that may be colluding with an attacker.
|
||||
If you're not sure which ones are not, you can always disable all of
|
||||
them and fall back to the coin in your pocket.
|
||||
.Sh IOCTLS
|
||||
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
|
||||
.Pa /dev/random
|
||||
and
|
||||
.Pa /dev/urandom
|
||||
devices support a number of ioctls, 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
|
||||
header file, for querying and controlling the entropy pool.
|
||||
.Pp
|
||||
Since timing between hardware events contributes to the entropy pool,
|
||||
statistics about the entropy pool over time may serve as a side channel
|
||||
for the state of the pool, so access to such statistics is restricted
|
||||
to the super-user and should be used with caution.
|
||||
.Pp
|
||||
Several ioctls are concerned with particular entropy sources, described
|
||||
by the following structure:
|
||||
.Bd -literal
|
||||
typedef struct {
|
||||
char name[16];
|
||||
uint32_t total;
|
||||
uint32_t type;
|
||||
uint32_t flags;
|
||||
char name[16]; /* symbolic name */
|
||||
uint32_t total; /* estimate of entropy provided */
|
||||
uint32_t type; /* RND_TYPE_* value */
|
||||
uint32_t flags; /* RND_FLAG_* mask */
|
||||
} 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;
|
||||
#define RND_TYPE_UNKNOWN
|
||||
#define RND_TYPE_DISK /* disk device */
|
||||
#define RND_TYPE_ENV /* environment sensor (temp, fan, &c.) */
|
||||
#define RND_TYPE_NET /* network device */
|
||||
#define RND_TYPE_POWER /* power events */
|
||||
#define RND_TYPE_RNG /* hardware RNG */
|
||||
#define RND_TYPE_SKEW /* clock skew */
|
||||
#define RND_TYPE_TAPE /* tape drive */
|
||||
#define RND_TYPE_TTY /* tty device */
|
||||
#define RND_TYPE_VM /* virtual memory faults */
|
||||
|
||||
#define RND_TYPE_MAX /* value of highest-numbered type */
|
||||
|
||||
#define RND_FLAG_COLLECT_TIME /* use timings of samples */
|
||||
#define RND_FLAG_COLLECT_VALUE /* use values of samples */
|
||||
#define RND_FLAG_ESTIMATE_TIME /* estimate entropy of timings */
|
||||
#define RND_FLAG_ESTIMATE_VALUE /* estimate entropy of values */
|
||||
#define RND_FLAG_NO_COLLECT /* ignore samples from this */
|
||||
#define RND_FLAG_NO_ESTIMATE /* do not estimate entropy */
|
||||
.Ed
|
||||
.Pp
|
||||
Return statistics on the current state of the random collection pool.
|
||||
.It Dv RNDGETSRCNUM
|
||||
.Pq Li "rndstat_t"
|
||||
.Bd -literal -offset indent
|
||||
The following ioctls are supported:
|
||||
.Bl -tag -width abcd
|
||||
.It Dv RNDGETENTCNT Pq Vt uint32_t
|
||||
Return the number of bits of entropy the system is estimated to have.
|
||||
.It Dv RNDGETSRCNUM Pq Vt rndstat_t
|
||||
.Bd -literal
|
||||
typedef struct {
|
||||
uint32_t start;
|
||||
uint32_t count;
|
||||
rndsource_t source[RND_MAXSTATCOUNT];
|
||||
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
|
||||
Fill the
|
||||
.Fa sources
|
||||
array with information about up to
|
||||
.Fa count
|
||||
entropy sources, starting at
|
||||
.Fa start .
|
||||
The actual number of sources described is returned in
|
||||
.Fa count .
|
||||
At most
|
||||
.Dv RND_MAXSTATCOUNT
|
||||
sources may be requested at once.
|
||||
.It Dv RNDGETSRCNAME Pq Vt rndstat_name_t
|
||||
.Bd -literal
|
||||
typedef struct {
|
||||
char name[16];
|
||||
rndsource_t source;
|
||||
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
|
||||
Fill
|
||||
.Fa source
|
||||
with information about the entropy source named
|
||||
.Fa name ,
|
||||
or fail with
|
||||
.Dv ENOENT
|
||||
if there is none.
|
||||
.It Dv RNDCTL Pq Vt rndctl_t
|
||||
.Bd -literal
|
||||
typedef struct {
|
||||
char name[16];
|
||||
uint32_t type;
|
||||
uint32_t flags;
|
||||
uint32_t mask;
|
||||
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
|
||||
For each entropy source of the type
|
||||
.Fa type ,
|
||||
or if
|
||||
.Fa type
|
||||
is
|
||||
.Li 0xff
|
||||
then for the entropy source named
|
||||
.Fa name ,
|
||||
replace the flags in
|
||||
.Fa mask
|
||||
by
|
||||
.Fa flags .
|
||||
.It Dv RNDADDDATA Pq Vt rnddata_t
|
||||
.Bd -literal
|
||||
typedef struct {
|
||||
uint32_t len;
|
||||
uint32_t entropy;
|
||||
u_char data[RND_SAVEWORDS * sizeof(uint32_t)];
|
||||
uint32_t len;
|
||||
uint32_t entropy;
|
||||
unsigned char data[RND_SAVEWORDS * sizeof(uint32_t)];
|
||||
} rnddata_t;
|
||||
.Ed
|
||||
.Pp
|
||||
Feed
|
||||
.Fa len
|
||||
bytes of data to the entropy pool.
|
||||
The sample is expected to have been drawn with at least
|
||||
.Fa entropy
|
||||
bits of entropy.
|
||||
.Pp
|
||||
This ioctl can be used only once per boot.
|
||||
It is intended for a system that saves entropy to disk on shutdown and
|
||||
restores it on boot, so that the system can immediately be
|
||||
unpredictable without having to wait to gather entropy.
|
||||
.Pp
|
||||
This ioctl is the only way for userland to directly change the system's
|
||||
entropy estimate.
|
||||
.It Dv RNDGETPOOLSTAT Pq Vt rndpoolstat_t
|
||||
.Bd -literal
|
||||
typedef struct {
|
||||
uint32_t poolsize; /* size of each LFSR in pool */
|
||||
uint32_t threshold; /* no. bytes of pool hash returned */
|
||||
uint32_t maxentropy; /* total size of pool in bits */
|
||||
uint32_t added; /* no. bits of entropy ever added */
|
||||
uint32_t curentropy; /* current entropy `balance' */
|
||||
uint32_t discarded; /* no. bits dropped when pool full */
|
||||
uint32_t generated; /* no. bits yielded by pool while
|
||||
curentropy is zero */
|
||||
} rndpoolstat_t;
|
||||
.Ed
|
||||
.Pp
|
||||
Return various statistics about entropy.
|
||||
.El
|
||||
.Sh IMPLEMENTATION NOTES
|
||||
(This section describes the current implementation of the
|
||||
.Nm
|
||||
subsystem at the time of writing.
|
||||
It may be out-of-date by the time you read it, and nothing in here
|
||||
should be construed as a guarantee about the behaviour of the
|
||||
.Pa /dev/random
|
||||
and
|
||||
.Pa /dev/urandom
|
||||
devices.)
|
||||
.Pp
|
||||
Samples from entropy sources are fed 32 bits at a time into the entropy
|
||||
pool, which is an array of 4096 bits, or 128 32-bit words, representing
|
||||
32 linear feedback shift registers each 128 bits long.
|
||||
.\" XXX Finish this description so it is implementable.
|
||||
.Pp
|
||||
When a user process opens
|
||||
.Pa /dev/random
|
||||
or
|
||||
.Pa /dev/urandom
|
||||
and first reads from it, the kernel draws from the entropy pool to seed
|
||||
a cryptographic pseudorandom number generator, the NIST CTR_DRBG
|
||||
(counter-mode deterministic random bit generator) with AES-128 as the
|
||||
block cipher, and uses that to generate data.
|
||||
.Pp
|
||||
To draw a seed from the entropy pool, the kernel
|
||||
.Bl -bullet -offset abcd -compact
|
||||
.It
|
||||
computes the SHA-1 hash of the entropy pool,
|
||||
.It
|
||||
feeds the SHA-1 hash word-by-word back into the entropy pool like an
|
||||
entropy source, and
|
||||
.It
|
||||
yields the xor of bytes
|
||||
.Pf 0.. Fa n
|
||||
with bytes
|
||||
.Fa n Ns +0.. Ns Fa n Ns Pf + Fa n
|
||||
of the hash, where
|
||||
.Fa n
|
||||
is
|
||||
.Dv RND_ENTROPY_THRESHOLD
|
||||
(currently 10).
|
||||
.El
|
||||
The kernel repeats the process, concatenating the results, until it has
|
||||
filled the seed.
|
||||
.Pp
|
||||
For each entropy source, the kernel estimates based on the previous
|
||||
samples how much entropy the source is providing in each new sample.
|
||||
The kernel maintains a count of the
|
||||
.Sq amount of entropy
|
||||
or
|
||||
.Sq number of bits of entropy
|
||||
in the pool.
|
||||
Each sample
|
||||
.Sq credits
|
||||
to the amount of entropy.
|
||||
Every time the kernel draws a PRNG seed from the entropy pool, it
|
||||
.Sq debits
|
||||
from the amount of entropy.
|
||||
.Pp
|
||||
Every open from
|
||||
.Pa /dev/urandom
|
||||
seeds an independent PRNG which is reseeded at the convenience of the
|
||||
kernel after a billion requests for output.
|
||||
Reads from
|
||||
.Pa /dev/urandom
|
||||
never block, even if the kernel estimates its state to be totally
|
||||
predictable.
|
||||
.Pp
|
||||
Every open from
|
||||
.Pa /dev/random
|
||||
seeds an independent PRNG which is reseeded after every 16 bytes of
|
||||
output.
|
||||
Reads from
|
||||
.Pa /dev/random
|
||||
block if the PRNG needs to be (re)seeded and the kernel's entropy
|
||||
estimate is too low.
|
||||
.Pp
|
||||
It is possible to fool the kernel's entropy estimator, in which case
|
||||
reads from
|
||||
.Pa /dev/random
|
||||
may return immediately even if the kernel is in a totally predictable
|
||||
state.
|
||||
.Pp
|
||||
Writes to
|
||||
.Pa /dev/random
|
||||
and
|
||||
.Pa /dev/urandom
|
||||
devices do not change the kernel's entropy estimate.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /dev/urandomx -compact
|
||||
.Bl -tag -width /dev/urandom -compact
|
||||
.It Pa /dev/random
|
||||
Returns ``good'' values only
|
||||
Uniform random byte source.
|
||||
May block.
|
||||
.It Pa /dev/urandom
|
||||
Always returns data.
|
||||
Uniform random byte source.
|
||||
Never blocks.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr arc4random 3 ,
|
||||
.Xr rndctl 8 ,
|
||||
.Xr rnd 9
|
||||
.Xr cprng 9
|
||||
.Rs
|
||||
.%A Elaine Barker
|
||||
.%A John Kelsey
|
||||
.%T Recommendation for Random Number Generation Using Deterministic Random Bit Generators
|
||||
.%D January 2012
|
||||
.%I National Institute of Standards and Technology
|
||||
.%O NIST Special Publication 800-90A
|
||||
.%U http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
|
||||
.Re
|
||||
.Rs
|
||||
.%A Daniel J. Bernstein
|
||||
.%T Entropy Attacks!
|
||||
.%D 2014-02-05
|
||||
.%U http://blog.cr.yp.to/20140205-entropy.html
|
||||
.Re
|
||||
.Rs
|
||||
.%A Nadia Heninger
|
||||
.%A Zakir Durumeric
|
||||
.%A Eric Wustrow
|
||||
.%A J. Alex Halderman
|
||||
.%T Mining Your Ps and Qs: Detection of Widespread Weak Keys in Network Devices
|
||||
.%B Proceedings of the 21st USENIX Security Symposium
|
||||
.%I USENIX
|
||||
.%D August 2012
|
||||
.%P 205-220
|
||||
.%U https://www.usenix.org/conference/usenixsecurity12/technical-sessions/presentation/heninger
|
||||
.%U https://factorable.net/
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
The random device was first made available in
|
||||
The
|
||||
.Pa /dev/random
|
||||
and
|
||||
.Pa /dev/urandom
|
||||
devices first appeared 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 .
|
||||
The
|
||||
.Nm
|
||||
subsystem was first implemented by
|
||||
.An Michael Graff Aq Mt explorer@flame.org ,
|
||||
and was then largely rewritten by
|
||||
.An Thor Lancelot Simon Aq Mt tls@NetBSD.org
|
||||
with later contributions by
|
||||
.An Taylor R. Campbell Aq Mt riastradh@NetBSD.org .
|
||||
.Sh BUGS
|
||||
There is no way to disable all entropy sources, in this and subsequent
|
||||
boots and no matter what USB devices you plug in against your mother's
|
||||
sage advice, in order to defend against the colluding hardware attack.
|
||||
.Pp
|
||||
The implementation confuses the number of bits in the entropy pool's
|
||||
physical representation, as a set of 32 128-bit LFSRs, with the number
|
||||
of bits of entropy that a system needs in order to be unpredictable, so
|
||||
even if entropy estimates were accurate and high, it takes unreasonably
|
||||
long for
|
||||
.Pa /dev/random
|
||||
to stop blocking.
|
||||
.Pp
|
||||
Many people are confused about what
|
||||
.Pa /dev/random
|
||||
and
|
||||
.Pa /dev/urandom
|
||||
mean.
|
||||
Unfortunately, no amount of software engineering can fix that.
|
||||
.Sh ENTROPY ACCOUNTING
|
||||
The entropy accounting described here is not grounded in any
|
||||
cryptography theory.
|
||||
It is done because it was always done, and because it gives people a
|
||||
warm fuzzy feeling about information theory.
|
||||
.Pp
|
||||
The folklore is that every
|
||||
.Fa n Ns -bit
|
||||
output of
|
||||
.Fa /dev/random
|
||||
is not merely indistinguishable from uniform random to a
|
||||
computationally bounded attacker, but information-theoretically is
|
||||
independent and has
|
||||
.Fa n
|
||||
bits of entropy even to a computationally
|
||||
.Em unbounded
|
||||
attacker -- that is, an attacker who can recover AES keys, compute
|
||||
SHA-1 preimages, etc.
|
||||
This property is not provided, nor was it ever provided in any
|
||||
implementation of
|
||||
.Fa /dev/random
|
||||
known to the author.
|
||||
.Pp
|
||||
This property would require that, after each read, the system discard
|
||||
all measurements from hardware in the entropy pool and begin anew.
|
||||
All work done to make the system unpredictable would be thrown out, and
|
||||
the system would immediately become predictable again.
|
||||
Reverting the system to being predictable every time a process reads
|
||||
from
|
||||
.Fa /dev/random
|
||||
would give attackers a tremendous advantage in predicting future
|
||||
outputs, especially if they can fool the entropy estimator, e.g. by
|
||||
sending carefully timed network packets.
|
||||
.Pp
|
||||
If you filled your entropy pool by flipping a coin 256 times, you would
|
||||
have to flip it again 256 times for the next output, and so on.
|
||||
In that case, if you really want information-theoretic guarantees, you
|
||||
might as well take
|
||||
.Fa /dev/random
|
||||
out of the picture and use your coin flips verbatim.
|
||||
.Pp
|
||||
On the other hand, every cryptographic protocol in practice, including
|
||||
HTTPS, SSH, PGP, etc., expands short secrets deterministically into
|
||||
long streams of bits, and their security relies on conjectures that a
|
||||
computationally bounded attacker cannot distinguish the long streams
|
||||
from uniform random.
|
||||
If we couldn't do that for
|
||||
.Fa /dev/random ,
|
||||
it would be hopeless to assume we could for HTTPS, SSH, PGP, etc.
|
||||
.Pp
|
||||
History is littered with examples of broken entropy sources and failed
|
||||
system engineering for random number generators.
|
||||
Nobody has ever reported distinguishing AES ciphertext from uniform
|
||||
random without side channels, nor reported computing SHA-1 preimages
|
||||
faster than brute force.
|
||||
The folklore information-theoretic defence against computationally
|
||||
unbounded attackers replaces system engineering that successfully
|
||||
defends against realistic threat models by imaginary theory that
|
||||
defends only against fantasy threat models.
|
||||
|
|
Loading…
Reference in New Issue