NetBSD/share/man/man9/rnd.9

313 lines
9.8 KiB
Groff

.\" $NetBSD: rnd.9,v 1.25.18.1 2020/07/15 13:47:40 martin Exp $
.\"
.\" Copyright (c) 1997 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This documentation is derived from text contributed to The NetBSD
.\" Foundation by S.P.Zeidler (aka stargazer).
.\"
.\" 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.
.\"
.\" 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 August 10, 2014
.Dt RND 9
.Os
.Sh NAME
.Nm RND ,
.Nm rnd_attach_source ,
.Nm rnd_detach_source ,
.Nm rnd_add_data ,
.Nm rnd_add_data_sync ,
.Nm rnd_add_uint32
.Nd functions to make a device available for entropy collection
.Sh SYNOPSIS
.In sys/rndsource.h
.Ft void
.Fn rndsource_setcb "krndsource_t *rnd_source" "void (*callback)(size_t, void *)" "void *cookie"
.Ft void
.Fn rnd_attach_source "krndsource_t *rnd_source" "char *devname" "uint32_t source_type" "uint32_t flags"
.Ft void
.Fn rnd_detach_source "krndsource_t *rnd_source"
.Ft void
.Fn rnd_add_data "krndsource_t *rnd_source" "void *data" "uint32_t len" "uint32_t entropy"
.Ft void
.Fn rnd_add_data_sync "krndsource_t *rnd_source" "void *data" "uint32_t len" "uint32_t entropy"
.Ft void
.Fn rnd_add_uint32 "krndsource_t *rnd_source" "uint32_t datum"
.Sh DESCRIPTION
These
.Nm
functions make a device available for entropy collection for
the kernel entropy pool, which provides key material for the
.Xr cprng 9
and
.Xr rnd 4
.Pa ( /dev/random )
interfaces.
.Pp
The caller must zero an
.Fa rnd_source
object before using it.
Ideally the first argument
.Fa rnd_source
of these functions gets included in the devices' entity struct,
but any means to permanently (statically) attach one such argument
to one incarnation of the device is ok.
Do not share
.Fa rnd_source
structures between two devices, and make sure to serialize all access
to each
.Fa rnd_source ,
for example with
.Xr mutex 9 .
.Bl -tag -width 8n
.It Fn rndsource_setcb "krndsource_t *rnd_source" "void (*callback)(size_t, void *)" "void *cookie"
This function sets a callback to be invoked when the kernel entropy
pool is hungry.
It is optional; if used, it must be used
.Em before
.Fn rnd_attach_source ,
and the caller must pass
.Dv RND_FLAG_HASCB
to
.Fn rnd_attach_source
in order for the callback to be used.
The callback is invoked as
.Fa callback ( Fa nbytes , Fa cookie ) ,
where
.Fa nbytes
is the number of bytes requested for the entropy pool, and
.Fa cookie
is the cookie that was passed to
.Fn rndsource_setcb .
The callback normally does one of two things:
.Bl -dash
.It
Sends a request to a hardware device for entropy and returns.
The hardware will later return data asynchronously by an interrupt, and
the callback will use
.Fn rnd_add_data
or
.Fn rnd_add_uint32
to add the data to the pool.
.It
Synchronously gathers entropy from hardware \(em for example, by a CPU
instruction like Intel RDSEED.
In this case, in order to add data to the pool
.Em before
returning, the callback
.Em must
use
.Fn rnd_add_data_sync ,
not
.Fn rnd_add_data
or
.Fn rnd_add_uint32 .
.El
.It Fn rnd_attach_source "krndsource_t *rnd_source" "char *devname" "uint32_t source_type" "uint32_t flags"
This function announces the availability of a device for entropy collection.
It must be called before the source struct pointed to by
.Fa rnd_source
is used in any of the following functions.
.Pp
.Fa devname
is the name of the device.
It is used to print a message (if the kernel is compiled with
``options RND_VERBOSE'') and also for status information printed with
.Xr rndctl 8 .
.Pp
.Fa source_type
is
.Dv RND_TYPE_NET
for network devices,
.Dv RND_TYPE_DISK
for physical disks,
.Dv RND_TYPE_TAPE
for a tape drive,
.Dv RND_TYPE_TTY
for a tty,
.Dv RND_TYPE_RNG
for a random number generator, and
.Dv RND_TYPE_ENV
for an environment sensor.
.Dv RND_TYPE_UNKNOWN
is not to be used as a type.
It is used internally to the rnd system.
.Pp
.Fa flags
are the logical OR of
.Dv RND_FLAG_COLLECT_VALUE
(mix data provided by this source into the pool)
.Dv RND_FLAG_COLLECT_TIME
(mix timestamps from this source into the pool)
.Dv RND_FLAG_ESTIMATE_VALUE
(use a delta estimator to count bits of entropy from this source's data towards
the pool estimate)
.Dv RND_FLAG_ESTIMATE_TIME
(use a delta estimator to count bits of entropy from this source's timestamps
towards the pool estimate)
.Dv RND_FLAG_HASCB
(caller specified a callback with
.Fn rndsource_setcb ) .
For many devices,
.Dv RND_FLAG_DEFAULT
.Dv ( RND_FLAG_COLLECT_VALUE | RND_FLAG_COLLECT_TIME | RND_FLAG_ESTIMATE_TIME )
is the best choice.
Note that devices of type
.Dv RND_TYPE_NET
default to
.Dv RND_FLAG_COLLECT_VALUE | RND_FLAG_COLLECT_TIME
(no entropy counted).
.It Fn rnd_detach_source "krndsource_t *rnd_source"
This function disconnects the device from entropy collection.
.It Fn rnd_add_uint32 "krndsource_t *rnd_source" "uint32_t datum"
This function adds the value of
.Va datum
to the entropy pool.
No entropy is assumed to be collected from this value, it merely helps
stir the entropy pool.
All entropy is gathered from jitter between the timing of events.
.Pp
Note that using a constant for
.Va datum
does not weaken security, but it does
not help.
Try to use something that can change, such as an interrupt status register
which might have a bit set for receive ready or transmit ready, or other
device status information.
.Pp
To allow the system to gather the timing information accurately, this call
should be placed within the actual hardware interrupt service routine.
Care must be taken to ensure that the interrupt was actually serviced by
the interrupt handler, since on some systems interrupts can be shared.
.Pp
This function loses nearly all usefulness if it is called from a scheduled
software interrupt.
If that is the only way to add the device as an entropy source, don't.
.Pp
If it is desired to mix in the
.Va datum
and to add in a timestamp, but not to actually estimate entropy from a source
of randomness, passing
.Dv NULL
for
.Va rnd_source
is permitted, and the device does not need to be attached.
.Pp
.Fn rnd_add_uint32
.Em must not
be used during a callback as set with
.Fn rndsource_setcb ;
use
.Fn rnd_add_data_sync
instead.
.It Fn rnd_add_data "krndsource_t *rnd_source" "void *data" "uint32_t len" "uint32_t entropy"
adds (hopefully) random
.Fa data
to the entropy pool.
.Fa len
is the number of bytes in
.Fa data
and
.Fa entropy
is an "entropy quality" measurement.
If every bit of
.Fa data
is known to be random,
.Fa entropy
is the number of bits in
.Fa data .
.Pp
Timing information is also used to add entropy into the system, using
inter-event timings.
.Pp
If it is desired to mix in the
.Va data
and to add in a timestamp, but not to actually estimate entropy from a source
of randomness, passing
.Dv NULL
for
.Va rnd_source
is permitted, and the device does not need to be attached.
.Pp
.Fn rnd_add_data
.Em must not
be used during a callback as set with
.Fn rndsource_setcb ;
use
.Fn rnd_add_data_sync
instead.
.El
.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.
.Pp
In the
.Nx
kernel, values should be extracted from the entropy pool
.Em only
via the
.Xr cprng 9
interface.
Direct access to the entropy pool is unsupported and may be dangerous.
There is no supported API for direct access to the output of the entropy pool.
.\" .Sh ERRORS
.Sh FILES
These functions are declared in src/sys/sys/rndsource.h and defined in
src/sys/kern/kern_rndq.c.
.Sh SEE ALSO
.Xr rnd 4 ,
.Xr rndctl 8 ,
.Xr cprng 9
.Sh HISTORY
The random device was introduced in
.Nx 1.3 .
.Sh AUTHORS
This implementation was written by
.An Michael Graff Aq Mt explorer@flame.org
using ideas and algorithms gathered from many sources, including
the driver written by Ted Ts'o.
.Sh BUGS
The only good sources of randomness are quantum mechanical, and most
computers avidly avoid having true sources of randomness included.
Don't expect to surpass "pretty good".