179 lines
7.9 KiB
Groff
179 lines
7.9 KiB
Groff
|
.\"
|
||
|
.\" random.c -- A strong random number generator
|
||
|
.\"
|
||
|
.\" Version 0.92, last modified 21-Sep-95
|
||
|
.\"
|
||
|
.\" Copyright Theodore Ts'o, 1994, 1995. 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, and the entire permission notice in its entirety,
|
||
|
.\" including the disclaimer of warranties.
|
||
|
.\" 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.
|
||
|
.\"
|
||
|
.\" ALTERNATIVELY, this product may be distributed under the terms of
|
||
|
.\" the GNU Public License, in which case the provisions of the GPL are
|
||
|
.\" required INSTEAD OF the above restrictions. (This clause is
|
||
|
.\" necessary due to a potential bad interaction between the GPL and
|
||
|
.\" the restrictions contained in a BSD-style copyright.)
|
||
|
.\"
|
||
|
.\" THIS SOFTWARE IS PROVIDED ``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.
|
||
|
.\"
|
||
|
.\" $Id$
|
||
|
.\"
|
||
|
.Dd October 21, 1995
|
||
|
.Dt RANDOM 4 i386
|
||
|
.Os
|
||
|
.Sh NAME
|
||
|
.Nm random ,
|
||
|
.Nm urandom
|
||
|
.Nd random number devices
|
||
|
.Sh DESCRIPTION
|
||
|
This device gathers environmental noise from device drivers, etc.,
|
||
|
and returns good random numbers, suitable for cryptographic use.
|
||
|
Besides the obvious cryptographic uses, these numbers are also good
|
||
|
for seeding TCP sequence numbers, and other places where it is
|
||
|
desireable to have numbers which are not only random, but hard to
|
||
|
predict by an attacker.
|
||
|
.Ss Theory of operation
|
||
|
Computers are very predictable devices. Hence it is extremely hard
|
||
|
to produce truly random numbers on a computer \(em as opposed to
|
||
|
pseudo-random numbers, which can easily generated by using a
|
||
|
algorithm. Unfortunately, it is very easy for attackers to guess
|
||
|
the sequence of pseudo-random number generators, and for some
|
||
|
applications this is not acceptable. So instead, we must try to
|
||
|
gather "environmental noise" from the computer's environment, which
|
||
|
must be hard for outside attackers to observe, and use that to
|
||
|
generate random numbers. In a Unix environment, this is best done
|
||
|
from inside the kernel.
|
||
|
.Pp
|
||
|
Sources of randomness from the environment include inter-keyboard
|
||
|
timings, inter-interrupt timings from some interrupts, and other
|
||
|
events which are both (a) non-deterministic and (b) hard for an
|
||
|
outside observer to measure. Randomness from these sources are
|
||
|
added to an "entropy pool", which is periodically mixed using the
|
||
|
MD5 compression function in CBC mode. As random bytes are mixed
|
||
|
into the entropy pool, the routines keep an
|
||
|
.Em estimate
|
||
|
of how many bits of randomness have been stored into the random number
|
||
|
generator's internal state.
|
||
|
.Pp
|
||
|
When random bytes are desired, they are obtained by taking the MD5
|
||
|
hash of a counter plus the contents of the "entropy pool". The
|
||
|
reason for the MD5 hash is so that we can avoid exposing the
|
||
|
internal state of random number generator. Although the MD5 hash
|
||
|
does protect the pool, as each random byte which is generated from
|
||
|
the pool reveals some information which was derived from the
|
||
|
internal state, and thus increasing the amount of information an
|
||
|
outside attacker has available to try to make some guesses about
|
||
|
the random number generator's internal state. For this reason,
|
||
|
the routine decreases its internal estimate of how many bits of
|
||
|
"true randomness" are contained in the entropy pool as it outputs
|
||
|
random numbers.
|
||
|
.Pp
|
||
|
If this estimate goes to zero, the routine can still generate random
|
||
|
numbers; however it may now be possible for an attacker to analyze
|
||
|
the output of the random number generator, and the MD5 algorithm,
|
||
|
and thus have some success in guessing the output of the routine.
|
||
|
Phil Karn (who devised this mechanism of using MD5 plus a counter
|
||
|
to extract random numbers from an entropy pool) calls this
|
||
|
"practical randomness", since in the worse case this is equivalent
|
||
|
to hashing MD5 with a counter and an undisclosed secret. If MD5 is
|
||
|
a strong cryptographic hash, this should be fairly resistant to attack.
|
||
|
.Ss Exported interfaces \(em output
|
||
|
There are three exported interfaces; the first is one designed to
|
||
|
be used from within the kernel:
|
||
|
.Pp
|
||
|
.Bl -tag -width Pa -compact
|
||
|
.It Pa void get_random_bytes(void *buf, int nbytes);
|
||
|
.El
|
||
|
.Pp
|
||
|
This interface will return the requested number of random bytes,
|
||
|
and place it in the requested buffer.
|
||
|
.Pp
|
||
|
The two other interfaces are two character devices
|
||
|
.Nm /dev/random
|
||
|
and
|
||
|
.Nm /dev/urandom . /dev/random
|
||
|
is suitable for use when very high quality randomness is desired
|
||
|
(for example, for key generation.), as it will only return a maximum
|
||
|
of the number of bits of randomness (as estimated by the random number
|
||
|
generator) contained in the entropy pool.
|
||
|
.Pp
|
||
|
The
|
||
|
.Nm /dev/urandom
|
||
|
device does not have this limit, and will return as many bytes as are
|
||
|
requested. As more and more random bytes are requested without giving
|
||
|
time for the entropy pool to recharge, this will result in lower quality
|
||
|
random numbers. For many applications, however, this is acceptable.
|
||
|
.Ss Exported interfaces \(em input
|
||
|
The two current exported interfaces for gathering environmental
|
||
|
noise from the devices are:
|
||
|
.Pp
|
||
|
.Bl -tag -width Pa -compact
|
||
|
.It Pa void add_keyboard_randomness(unsigned char scancode);
|
||
|
.It Pa void add_interrupt_randomness(int irq);
|
||
|
.El
|
||
|
.Pp
|
||
|
The first function uses the inter-keypress timing, as well as the
|
||
|
scancode as random inputs into the "entropy pool".
|
||
|
.Pp
|
||
|
The second function uses the inter-interrupt timing as random
|
||
|
inputs to the entropy pool. Note that not all interrupts are good
|
||
|
sources of randomness! For example, the timer interrupts is not a
|
||
|
good choice, because the periodicity of the interrupts is to
|
||
|
regular, and hence predictable to an attacker. Disk interrupts are
|
||
|
a better measure, since the timing of the disk interrupts are more
|
||
|
unpredictable. The routines try to estimate how many bits of
|
||
|
randomness a particular interrupt channel offers, by keeping track
|
||
|
of the first and second order deltas in the interrupt timings.
|
||
|
.Sh ACKNOWLEDGEMENTS
|
||
|
The original core code was written by Theodore Ts'o, and was intended
|
||
|
for the Linux platform. This was ported to FreeBSD by Mark Murray,
|
||
|
who also wrote the rndcontrol utility.
|
||
|
.Pp
|
||
|
Ideas for constructing this random number generator were derived
|
||
|
from the Pretty Good Privacy's random number generator, and from
|
||
|
private discussions with Phil Karn. This design has been further
|
||
|
modified by myself, so any flaws are solely my responsibility, and
|
||
|
should not be attributed to the authors of PGP or to Phil.
|
||
|
.Pp
|
||
|
The code for MD5 transform was taken from Colin Plumb's
|
||
|
implementation, which has been placed in the public domain. The
|
||
|
MD5 cryptographic checksum was devised by Ronald Rivest, and is
|
||
|
documented in RFC 1321, "The MD5 Message Digest Algorithm".
|
||
|
.Pp
|
||
|
Further background information on this topic may be obtained from
|
||
|
RFC 1750, "Randomness Recommendations for Security", by Donald
|
||
|
Eastlake, Steve Crocker, and Jeff Schiller.
|
||
|
.Sh "SEE ALSO"
|
||
|
.Xr rndcontrol 8
|
||
|
.Sh FILES
|
||
|
.Bl -tag -width Pa -compact
|
||
|
.It Pa /dev/random
|
||
|
.It Pa /dev/urandom
|
||
|
.El
|
||
|
.Sh HISTORY
|
||
|
The
|
||
|
.Nm random ,
|
||
|
.Nm urandom
|
||
|
files appeared in
|
||
|
FreeBSD v2.2 .
|