version 1.16, 2010/03/22 18:58:31 |
version 1.17, 2011/12/17 20:05:38 |
|
|
.Sh DESCRIPTION |
.Sh DESCRIPTION |
The |
The |
.Nm |
.Nm |
pseudo-device uses event timing information collected from many |
pseudo-device has three purposes. On read, it returns cryptographically |
devices, and mixes this into an entropy pool. |
strong random data from a generator keyed from the kernel entropy pool. |
This pool is stirred with a cryptographically strong hash function |
On write, data may be added to the entropy pool. By ioctl, the behavior |
when data is extracted from the pool. |
of the entropy pool (which sources are used; how their entropy is |
.Sh INTERNAL ENTROPY POOL MANAGEMENT |
estimated, etc.) may be controlled. |
When a hardware event occurs (such as completion of a hard drive |
.Pp |
transfer or an interrupt from a network device) a timestamp is |
The kernel uses event timing information collected from many |
generated. |
devices, and mixes this into an entropy pool. This pool is used to |
This timestamp is compared to the previous timestamp |
key a stream generator (the CTR_DRBG generator specified by NIST |
recorded for the device, and the first, second, and third order |
SP 800-90) which is used to generate values returned to userspace when |
differentials are calculated. |
the pseudo-device is read. |
.Pp |
.Pp |
If any of these differentials is zero, no entropy is assumed to |
The pseudodevice is cloning, which means that each time it is opened, |
have been gathered. |
a new instance of the stream generator is created. Interposing a stream |
If all are non-zero, one bit is assumed. |
generator between the entropy pool and readers in this manner protects |
Next, data is mixed into the entropy pool using an LFSR (linear |
readers from each other (each reader's random stream is generated from a |
feedback shift register). |
unique key) and protects all users of the entropy pool from any attack |
.Pp |
which might correlate its successive outputs to each other, such as |
To extract data from the entropy pool, a cryptographically strong hash |
iterative guessing attacks. |
function is used. |
.Pp |
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 |
.Sh USER ACCESS |
User code can obtain random values from the kernel in two ways. |
User code can obtain random values from the kernel in two ways. |
.Pp |
.Pp |
Reading from |
Reading from |
.Pa /dev/random |
.Pa /dev/random |
will only return values while sufficient entropy exists in the |
provides information-theoretic properties desirable for some callers: |
internal pool. |
it will guarantee that the stream generator never outputs more bits |
When sufficient entropy does not exist, |
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 |
.Er EAGAIN |
is returned for non-blocking reads, or the read will block for |
(for non-blocking reads), block, or return less data than requested, if |
blocking reads. |
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 |
.Pp |
Reading from |
Reading from |
.Pa /dev/urandom |
.Pa /dev/urandom |
will return as many values as requested, even when the entropy pool is |
will return as many values as requested. The stream generator may be |
empty. |
initially keyed from the entropy pool even if the pool's estimate of |
This data is not as good as reading from |
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 |
.Pa /dev/random |
since when the pool is empty, data is still returned, degenerating to a |
pseudodevice's continual rekeying of the stream generator will cause |
pseudo-random generator. |
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 |
.Pp |
Writing to either device will mix the data written into the pool using |
Excessive use of |
the LFSR as above, without modifying the entropy estimation for the |
.Pa /dev/random |
pool. |
can deplete the entropy pool (or, at least, its estimate of how many |
.Sh RANDOM SOURCE STRUCTURE |
bits of entropy it "contains") and reduce security for other consumers |
Each source has a state structure which the kernel uses to hold the |
of randomness both in userspace |
timing information and other state for that source. |
.Em and within the kernel. |
|
Some system administrators may wish therefore to remove the /dev/random |
|
device node and replace it with a second copy of the node for the |
|
nonblocking /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 |
.Bd -literal -offset indent |
typedef struct { |
typedef struct { |
char name[16]; |
char name[16]; |
uint32_t last_time; |
uint32_t total; |
uint32_t last_delta; |
uint32_t type; |
uint32_t last_delta2; |
|
uint32_t total; |
|
uint32_t type; |
|
uint32_t flags; |
uint32_t flags; |
} rndsource_t; |
} rndsource_t; |
.Ed |
.Ed |
.Pp |
|
This structure holds the internal representation of a device's timing |
|
state. |
|
The |
The |
.Va name |
.Va name |
field holes the device name, as known to the kernel. |
field holds 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 |
The |
.Va type |
.Va type |
field holds the device type. |
field holds the device type. |
Line 152 Do not assume any entropy is in the timi |
|
Line 192 Do not assume any entropy is in the timi |
|
.It Dv RND_FLAG_NO_COLLECT |
.It Dv RND_FLAG_NO_COLLECT |
Do not even add timing information to the pool. |
Do not even add timing information to the pool. |
.El |
.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 |
|
.In sys/rnd.h |
|
file, along with the data types and constants. |
|
.Pp |
.Pp |
.Bl -tag -width RNDADDTOENTCNT |
.Bl -tag -width RNDADDTOENTCNT |
.It Dv RNDGETENTCNT |
.It Dv RNDGETENTCNT |
Line 248 are to be set or cleared. |
|
Line 280 are to be set or cleared. |
|
.Pq Li "rnddata_t" |
.Pq Li "rnddata_t" |
.Bd -literal -offset indent |
.Bd -literal -offset indent |
typedef struct { |
typedef struct { |
uint32_t len; |
uint32_t len; |
uint32_t entropy; |
uint32_t entropy; |
u_char data[RND_POOLWORDS * 4]; |
u_char data[RND_SAVEWORDS * sizeof(uint32_t)]; |
} rnddata_t; |
} rnddata_t; |
.Ed |
.Ed |
.El |
.El |
Line 259 typedef struct { |
|
Line 291 typedef struct { |
|
.It Pa /dev/random |
.It Pa /dev/random |
Returns ``good'' values only |
Returns ``good'' values only |
.It Pa /dev/urandom |
.It Pa /dev/urandom |
Always returns data, degenerates to a pseudo-random generator |
Always returns data. |
.El |
.El |
.Sh SEE ALSO |
.Sh SEE ALSO |
.Xr rndctl 8 , |
.Xr rndctl 8 , |
Line 268 Always returns data, degenerates to a ps |
|
Line 300 Always returns data, degenerates to a ps |
|
The random device was first made available in |
The random device was first made available in |
.Nx 1.3 . |
.Nx 1.3 . |
.Sh AUTHORS |
.Sh AUTHORS |
This implementation was written by Michael Graff \*[Lt]explorer@flame.org\*[Gt] |
This implementation was written by Thor Lancelot Simon. It retains |
using ideas and algorithms gathered from many sources, including |
some code (particularly for the ioctl interface) from the earlier |
the driver written by Ted Ts'o. |
implementation by Michael Graff \*[Lt]explorer@flame.org\*[Gt]. |