| 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>
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 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.
The caller must zero an rnd_source object before using it. 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, and make sure to serialize all access to each rnd_source, for example with mutex(9).
rndsource_setcb(krndsource_t
    *rnd_source, void (*callback)(size_t, void *),
    void *cookie)rnd_attach_source(), and
      the caller must pass RND_FLAG_HASCB to
      rnd_attach_source() in order for the callback to
      be used. 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(krndsource_t
    *rnd_source, char *devname,
    uint32_t source_type, uint32_t
    flags)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) RND_FLAG_HASCB (caller
        specified a callback with rndsource_setcb()).
        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)rnd_add_uint32(krndsource_t
    *rnd_source, uint32_t datum)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_uint32() must
        not be used during a callback as set with
        rndsource_setcb(); use
        rnd_add_data_sync() instead.
rnd_add_data(krndsource_t
    *rnd_source, void *data,
    uint32_t len, uint32_t
    entropy)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.
rnd_add_data() must
        not be used during a callback as set with
        rndsource_setcb(); use
        rnd_add_data_sync() instead.
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.
| August 10, 2014 | NetBSD 9.3 |