| RND(9) | Kernel Developer's Manual | RND(9) |
RND, rnd_attach_source,
rnd_detach_source,
rnd_add_data,
rnd_add_data_sync,
rnd_add_uint32 —
#include <sys/rndsource.h>
typedef struct krndsource krndsource_t;
void
rndsource_setcb(krndsource_t
*rnd_source, void
(*callback)(size_t, void *),
void *cookie);
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_data_sync(krndsource_t
*rnd_source, void
*data, uint32_t
len, uint32_t
entropy);
void
rnd_add_uint32(krndsource_t
*rnd_source, uint32_t
datum);
RND functions enable drivers to collect samples of
physical observations, such as network packet timings or hardware random
number generator outputs, into a kernel entropy pool to derive key material
for cprng(9) and
rnd(4)
(/dev/random, /dev/urandom).
Usage model:
RND functions.rndsource_setcb()
if appropriate, e.g. for an on-demand hardware random number
generator.rnd_attach_source().rnd_add_data() or
rnd_add_uint32(), or, if in the callback,
rnd_add_data_sync().rnd_detach_source().The following types of random sources are defined:
RND_TYPE_DISKRND_TYPE_ENVRND_TYPE_POWERRND_TYPE_NETRND_TYPE_RNGRND_TYPE_SKEWRND_TYPE_TAPERND_TYPE_TTYRND_TYPE_VMRND_TYPE_UNKNOWNrndsource_setcb(rnd_source,
callback, cookie)rnd_attach_source(), and
the caller must pass RND_FLAG_HASCB to
rnd_attach_source().
The callback is invoked as
callback(nbytes,
cookie);, where nbytes is
the number of bytes requested for the entropy pool, and
cookie is the cookie that was passed to
rndsource_setcb(). The callback normally does
one of two things:
rnd_add_data() or
rnd_add_uint32() to add the data to the
pool.rnd_add_data_sync(), not
rnd_add_data() or
rnd_add_uint32().rnd_attach_source(rnd_source,
devname, type,
flags)rndsource_setcb(), the kernel may invoke it at any
time after rnd_attach_source() until
rnd_detach_source(), so the callback must be ready
to be invoked before calling
rnd_attach_source().
The devname is exposed via
rnd(4) and
rndctl(8). The
type must be one of the
RND_TYPE_* constants above. The
flags are the bitwise-or of any of the following
constants:
RND_FLAG_HASCBrndsource_setcb().RND_FLAG_COLLECT_TIMErnd_add_*() call into
the entropy pool. If not set, at most only the data arguments to
rnd_add_*() will be entered.RND_FLAG_COLLECT_VALUErnd_add_*() functions into the pool. If not
set, the data will be ignored; at most the timing of the sample will
be entered.RND_FLAG_DEFAULTRND_FLAG_COLLECT_TIME |
RND_FLAG_COLLECT_VALUE.RND_FLAG_ESTIMATE_TIME,
RND_FLAG_ESTIMATE_VALUErnd_detach_source(rnd_source)rnd_add_*() functions after
rnd_detach_source(). The caller may release the
memory for rnd_source afterward.rnd_add_data(rnd_source,
data, len,
entropy)RND_FLAG_COLLECT_VALUE was
specified for rnd_source, and a timestamp, if
RND_FLAG_COLLECT_TIME was specified.
The argument entropy provides a conservative estimate for the number of bits of entropy in the physical process that generated the data, given all the past samples. Drivers for devices for which this is not known should pass zero; typically only drivers for hardware random number generators pass nonzero values. Hardware random number generator drivers should perform on-line self-tests before advertising nonzero entropy for samples.
rnd_add_data() must
not be used during a callback as set with
rndsource_setcb(); use
rnd_add_data_sync() instead.
rnd_add_data_sync(rnd_source,
data, len,
entropy)rnd_add_data(), but may be used in a callback
as set with rndsource_setcb().rnd_add_uint32(rnd_source,
datum)rnd_add_data(rnd_source,
&datum,
4, 0).
rnd_add_uint32() must
not be used during a callback as set with
rndsource_setcb(); use
rnd_add_data_sync() instead.
struct xyz_softc {
...
struct krndsource sc_rndsource;
};
static void
xyz_attach(device_t parent, device_t self, void *aux)
{
struct xyz_softc *sc = device_private(self);
...
rndsource_setcb(&sc->sc_rndsource, xyz_get, sc);
rnd_attach_source(&sc->sc_rndsource, device_xname(self),
RND_TYPE_RNG, RND_FLAG_DEFAULT);
}
static int
xyz_detach(device_t self, int flags)
{
...
rnd_detach_source(&sc->sc_rndsource);
...
return 0;
}
static void
xyz_get(size_t nbytes, void *cookie)
{
struct xyz_softc *sc = cookie;
uint32_t v;
unsigned timo = 10;
while (nbytes) {
while (bus_space_read_4(sc->sc_bst, sc->sc_bsh,
XYZ_RNGREADY) == 0) {
if (--timo == 0)
return;
DELAY(10);
}
v = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
XYZ_RNGDATUM);
/* data sheet sez 18 bits entropy in 32-bit sample */
rnd_add_data_sync(&sc->sc_rndsource, &v, sizeof v, 18);
nbytes -= 18/NBBY;
}
}
static void
xyz_intr(void *cookie)
{
struct xyz_softc *sc = cookie;
uint32_t isr;
isr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, XYZ_ISR);
bus_space_write_4(sc->sc_bst, sc->sc_bsh, XYZ_ISR, isr);
rnd_add_uint32(&sc->sc_rndsource, isr);
...
}
| April 25, 2020 | NetBSD 9.99 |