rnd(9) - NetBSD Manual Pages

Command: Section: Arch: Collection:  
RND(9)                 NetBSD Kernel Developer's Manual                 RND(9)

RND, rnd_attach_source, rnd_detach_source, rnd_add_data, rnd_add_data_sync, rnd_add_uint32 -- functions to make a device available for entropy collection
#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);
The RND functions enable drivers to collect samples of physical observa- tions, 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: 1. Allocate and zero a struct krndsource object before using the RND functions. 2. Optionally, set a callback with rndsource_setcb() if appropriate, e.g. for an on-demand hardware random number generator. 3. Attach the random source with rnd_attach_source(). 4. Enter data with rnd_add_data() or rnd_add_uint32(), or, if in the callback, rnd_add_data_sync(). 5. When the driver is done, detach it with rnd_detach_source(). The following types of random sources are defined: RND_TYPE_DISK Disk devices, typically sampling seek timings. RND_TYPE_ENV Environmental sensors. RND_TYPE_POWER Power sensors and timing of power-related events. RND_TYPE_NET Network interfaces, typically sampling packet tim- ings. By default, sample from network interfaces are ignored, for hysterical raisins. RND_TYPE_RNG Hardware random number generators. RND_TYPE_SKEW Skew between clocks. RND_TYPE_TAPE Tape devices, typically sampling I/O timings. RND_TYPE_TTY Tty devices, typically sampling interrupt timings. RND_TYPE_VM Virtual memory fault timings. RND_TYPE_UNKNOWN Unknown sources, or sources not otherwise classi- fied.
rndsource_setcb(rnd_source, callback, cookie) Sets a callback to be invoked when the entropy pool is hungry to draw data from this source on demand. Optional; if used, must be used before 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: - Sends a request to a hardware device for entropy and returns. The hardware will later return data asynchronously by an inter- rupt, and the callback will use rnd_add_data() or rnd_add_uint32() to add the data to the pool. - Synchronously gathers entropy from hardware -- for example, by a CPU instruction like Intel RDSEED. In this case, in order to add data to the pool before returning, the callback must use rnd_add_data_sync(), not rnd_add_data() or rnd_add_uint32(). rnd_attach_source(rnd_source, devname, type, flags) Makes rnd_source available for entropy collection. Must be called before the source struct pointed to by rnd_source is used in any of the following functions. If a callback was specified with 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_HASCB The random source has a callback, which must have been set with rndsource_setcb(). RND_FLAG_COLLECT_TIME Enter the timing of each rnd_add_*() call into the entropy pool. If not set, at most only the data arguments to rnd_add_*() will be entered. RND_FLAG_COLLECT_VALUE Enter the data arguments passed to the rnd_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_DEFAULT Equivalent to RND_FLAG_COLLECT_TIME | RND_FLAG_COLLECT_VALUE. RND_FLAG_ESTIMATE_TIME, RND_FLAG_ESTIMATE_VALUE Legacy options no longer used. rnd_detach_source(rnd_source) Disconnects rnd_source from entropy collection. The kernel will cease to invoke the callback, if any, and the caller must not use rnd_source with any of the 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) Enters len bytes at data into the entropy pool, if RND_FLAG_COLLECT_VALUE was specified for rnd_source, and a time- stamp, if RND_FLAG_COLLECT_TIME was specified. The argument entropy provides a conservative estimate for the num- ber 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) Like rnd_add_data(), but may be used in a callback as set with rndsource_setcb(). rnd_add_uint32(rnd_source, datum) Equivalent to 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.
These functions are declared in src/sys/sys/rndsource.h and defined in src/sys/kern/kern_entropy.c.
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); ... }
rnd(4), rndctl(8), cprng(9)
The random device was introduced in NetBSD 1.3. It was substantially rewritten in NetBSD 6.0, and again in NetBSD 10.0.
This implementation was written by Taylor R Campbell <riastradh@NetBSD.org>. NetBSD 9.99 April 25, 2020 NetBSD 9.99
Powered by man-cgi (2021-06-01). Maintained for NetBSD by Kimmo Suominen. Based on man-cgi by Panagiotis Christias.