NAME
RND,
rnd_attach_source,
rnd_detach_source,
rnd_add_data,
rnd_add_uint32 —
functions to make a
device available for entropy collection
SYNOPSIS
#include <sys/rndsource.h>
void
rnd_attach_source(
krndsource_t
*rnd_source,
char
*devname,
uint32_t
source_type,
uint32_t
flags);
void
rnd_detach_source(
krndsource_t
*rnd_source);
void
rnd_add_data(
krndsource_t
*rnd_source,
void
*data,
uint32_t len,
uint32_t entropy);
void
rnd_add_uint32(
krndsource_t
*rnd_source,
uint32_t
datum);
DESCRIPTION
These
RND functions make a device available for entropy
collection for the kernel entropy pool, which provides key material for the
cprng(9) and
rnd(4)
(
/dev/random) interfaces.
Ideally the first argument
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
rnd_source structures between two devices.
-
-
- 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 rnd_source is used in any of the following
functions.
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
rndctl(8).
source_type is
RND_TYPE_NET
for network devices, RND_TYPE_DISK
for physical
disks, RND_TYPE_TAPE
for a tape drive,
RND_TYPE_TTY
for a tty,
RND_TYPE_RNG
for a random number generator, and
RND_TYPE_ENV
for an environment sensor.
RND_TYPE_UNKNOWN
is not to be used as a type. It
is used internally to the rnd system.
flags are the logical OR of
RND_FLAG_COLLECT_VALUE
(mix data provided by this
source into the pool) RND_FLAG_COLLECT_TIME
(mix
timestamps from this source into the pool)
RND_FLAG_ESTIMATE_VALUE
(use a delta estimator to
count bits of entropy from this source's data towards the pool estimate)
RND_FLAG_ESTIMATE_TIME
(use a delta estimator to
count bits of entropy from this source's timestamps towards the pool
estimate). For many devices, RND_FLAG_DEFAULT
(RND_FLAG_COLLECT_VALUE
|
RND_FLAG_COLLECT_TIME
|
RND_FLAG_ESTIMATE_TIME
) is the best choice. Note
that devices of type RND_TYPE_NET
default to
RND_FLAG_COLLECT_VALUE
|
RND_FLAG_COLLECT_TIME
(no entropy counted).
-
-
- rnd_detach_source(krndsource_t
*rnd_source)
- This function disconnects the device from entropy
collection.
-
-
- rnd_add_uint32(krndsource_t
*rnd_source, uint32_t datum)
- This function adds the value of 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.
Note that using a constant for 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.
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.
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.
If it is desired to mix in the datum and to add in a
timestamp, but not to actually estimate entropy from a source of
randomness, passing
NULL
for
rnd_source is permitted, and the device does not
need to be attached.
-
-
- rnd_add_data(krndsource_t
*rnd_source, void *data,
uint32_t len, uint32_t
entropy)
- adds (hopefully) random data to the
entropy pool. len is the number of bytes in
data and entropy is an
"entropy quality" measurement. If every bit of
data is known to be random,
entropy is the number of bits in
data.
Timing information is also used to add entropy into the system, using
inter-event timings.
If it is desired to mix in the data and to add in a
timestamp, but not to actually estimate entropy from a source of
randomness, passing
NULL
for
rnd_source is permitted, and the device does not
need to be attached.
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.
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).
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.
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.
In the
NetBSD kernel, values should be extracted from
the entropy pool
only via the
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.
FILES
These functions are declared in src/sys/sys/rndsource.h and defined in
src/sys/kern/kern_rndq.c.
SEE ALSO
rnd(4),
rndctl(8),
cprng(9)
HISTORY
The random device was introduced in
NetBSD 1.3.
AUTHORS
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.
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".