svn commit: r256377 - in head: etc/defaults etc/rc.d share/examples/kld/random_adaptor share/man/man4 sys/boot/forth sys/conf sys/dev/glxsb sys/dev/hifn sys/dev/random sys/dev/rndtest sys/dev/safe ...

Adrian Chadd adrian at freebsd.org
Sat Oct 12 16:27:25 UTC 2013


hihi,

I've just test booted this on a MIPS board. It doesn't hang at boot waiting
for entropy.

http://people.freebsd.org/~adrian/mips/20131012-ar9344-boot-1.txt

Thanks!


-adrian



On 12 October 2013 05:57, Mark Murray <markm at freebsd.org> wrote:

> Author: markm
> Date: Sat Oct 12 12:57:57 2013
> New Revision: 256377
> URL: http://svnweb.freebsd.org/changeset/base/256377
>
> Log:
>   Merge from project branch. Uninteresting commits are trimmed.
>
>   Refactor of /dev/random device. Main points include:
>
>   * Userland seeding is no longer used. This auto-seeds at boot time
>   on PC/Desktop setups; this may need some tweeking and intelligence
>   from those folks setting up embedded boxes, but the work is believed
>   to be minimal.
>
>   * An entropy cache is written to /entropy (even during installation)
>   and the kernel uses this at next boot.
>
>   * An entropy file written to /boot/entropy can be loaded by loader(8)
>
>   * Hardware sources such as rdrand are fed into Yarrow, and are no
>   longer available raw.
>
>   ------------------------------------------------------------------------
>   r256240 | des | 2013-10-09 21:14:16 +0100 (Wed, 09 Oct 2013) | 4 lines
>
>   Add a RANDOM_RWFILE option and hide the entropy cache code behind it.
>   Rename YARROW_RNG and FORTUNA_RNG to RANDOM_YARROW and RANDOM_FORTUNA.
>   Add the RANDOM_* options to LINT.
>
>   ------------------------------------------------------------------------
>   r256239 | des | 2013-10-09 21:12:59 +0100 (Wed, 09 Oct 2013) | 2 lines
>
>   Define RANDOM_PURE_RNDTEST for rndtest(4).
>
>   ------------------------------------------------------------------------
>   r256204 | des | 2013-10-09 18:51:38 +0100 (Wed, 09 Oct 2013) | 2 lines
>
>   staticize struct random_hardware_source
>
>   ------------------------------------------------------------------------
>   r256203 | markm | 2013-10-09 18:50:36 +0100 (Wed, 09 Oct 2013) | 2 lines
>
>   Wrap some policy-rich code in 'if NOTYET' until we can thresh out
>   what it really needs to do.
>
>   ------------------------------------------------------------------------
>   r256184 | des | 2013-10-09 10:13:12 +0100 (Wed, 09 Oct 2013) | 2 lines
>
>   Re-add /dev/urandom for compatibility purposes.
>
>   ------------------------------------------------------------------------
>   r256182 | des | 2013-10-09 10:11:14 +0100 (Wed, 09 Oct 2013) | 3 lines
>
>   Add missing include guards and move the existing ones out of the
>   implementation namespace.
>
>   ------------------------------------------------------------------------
>   r256168 | markm | 2013-10-08 23:14:07 +0100 (Tue, 08 Oct 2013) | 10 lines
>
>   Fix some just-noticed problems:
>
>   o Allow this to work with "nodevice random" by fixing where the
>   MALLOC pool is defined.
>
>   o Fix the explicit reseed code. This was correct as submitted, but
>   in the project branch doesn't need to set the "seeded" bit as this
>   is done correctly in the "unblock" function.
>
>   o Remove some debug ifdeffing.
>
>   o Adjust comments.
>
>   ------------------------------------------------------------------------
>   r256159 | markm | 2013-10-08 19:48:11 +0100 (Tue, 08 Oct 2013) | 6 lines
>
>   Time to eat crow for me.
>
>   I replaced the sx_* locks that Arthur used with regular mutexes;
>   this turned out the be the wrong thing to do as the locks need to
>   be sleepable. Revert this folly.
>
>   # Submitted by:       Arthur Mesh <arthurmesh at gmail.com> (In original
> diff)
>
>   ------------------------------------------------------------------------
>   r256138 | des | 2013-10-08 12:05:26 +0100 (Tue, 08 Oct 2013) | 10 lines
>
>   Add YARROW_RNG and FORTUNA_RNG to sys/conf/options.
>
>   Add a SYSINIT that forces a reseed during proc0 setup, which happens
>   fairly late in the boot process.
>
>   Add a RANDOM_DEBUG option which enables some debugging printf()s.
>
>   Add a new RANDOM_ATTACH entropy source which harvests entropy from the
>   get_cyclecount() delta across each call to a device attach method.
>
>   ------------------------------------------------------------------------
>   r256135 | markm | 2013-10-08 07:54:52 +0100 (Tue, 08 Oct 2013) | 8 lines
>
>   Debugging. My attempt at EVENTHANDLER(multiuser) was a failure; use
>   EVENTHANDLER(mountroot) instead.
>
>   This means we can't count on /var being present, so something will
>   need to be done about harvesting /var/db/entropy/... .
>
>   Some policy now needs to be sorted out, and a pre-sync cache needs
>   to be written, but apart from that we are now ready to go.
>
>   Over to review.
>
>   ------------------------------------------------------------------------
>   r256094 | markm | 2013-10-06 23:45:02 +0100 (Sun, 06 Oct 2013) | 8 lines
>
>   Snapshot.
>
>   Looking pretty good; this mostly works now. New code includes:
>
>   * Read cached entropy at startup, both from files and from loader(8)
>   preloaded entropy. Failures are soft, but announced. Untested.
>
>   * Use EVENTHANDLER to do above just before we go multiuser. Untested.
>
>   ------------------------------------------------------------------------
>   r256088 | markm | 2013-10-06 14:01:42 +0100 (Sun, 06 Oct 2013) | 2 lines
>
>   Fix up the man page for random(4). This mainly removes no-longer-relevant
>   details about HW RNGs, reseeding explicitly and user-supplied
>   entropy.
>
>   ------------------------------------------------------------------------
>   r256087 | markm | 2013-10-06 13:43:42 +0100 (Sun, 06 Oct 2013) | 6 lines
>
>   As userland writing to /dev/random is no more, remove the "better
>   than nothing" bootstrap mode.
>
>   Add SWI harvesting to the mix.
>
>   My box seeds Yarrow by itself in a few seconds! YMMV; more to follow.
>
>   ------------------------------------------------------------------------
>   r256086 | markm | 2013-10-06 13:40:32 +0100 (Sun, 06 Oct 2013) | 11 lines
>
>   Debug run. This now works, except that the "live" sources haven't
>   been tested. With all sources turned on, this unlocks itself in
>   a couple of seconds! That is no my box, and there is no guarantee
>   that this will be the case everywhere.
>
>   * Cut debug prints.
>
>   * Use the same locks/mutexes all the way through.
>
>   * Be a tad more conservative about entropy estimates.
>
>   ------------------------------------------------------------------------
>   r256084 | markm | 2013-10-06 13:35:29 +0100 (Sun, 06 Oct 2013) | 5 lines
>
>   Don't use the "real" assembler mnemonics; older compilers may not
>   understand them (like when building CURRENT on 9.x).
>
>   # Submitted by:       Konstantin Belousov <kostikbel at gmail.com>
>
>   ------------------------------------------------------------------------
>   r256081 | markm | 2013-10-06 10:55:28 +0100 (Sun, 06 Oct 2013) | 12 lines
>
>   SNAPSHOT.
>
>   Simplify the malloc pools; We only need one for this device.
>
>   Simplify the harvest queue.
>
>   Marginally improve the entropy pool hashing, making it a bit faster
>   in the process.
>
>   Connect up the hardware "live" source harvesting. This is simplistic
>   for now, and will need to be made rate-adaptive.
>
>   All of the above passes a compile test but needs to be debugged.
>
>   ------------------------------------------------------------------------
>   r256042 | markm | 2013-10-04 07:55:06 +0100 (Fri, 04 Oct 2013) | 25 lines
>
>   Snapshot. This passes the build test, but has not yet been finished or
> debugged.
>
>   Contains:
>
>   * Refactor the hardware RNG CPU instruction sources to feed into
>   the software mixer. This is unfinished. The actual harvesting needs
>   to be sorted out. Modified by me (see below).
>
>   * Remove 'frac' parameter from random_harvest(). This was never
>   used and adds extra code for no good reason.
>
>   * Remove device write entropy harvesting. This provided a weak
>   attack vector, was not very good at bootstrapping the device. To
>   follow will be a replacement explicit reseed knob.
>
>   * Separate out all the RANDOM_PURE sources into separate harvest
>   entities. This adds some secuity in the case where more than one
>   is present.
>
>   * Review all the code and fix anything obviously messy or inconsistent.
>   Address som review concerns while I'm here, like rename the pseudo-rng
>   to 'dummy'.
>
>   # Submitted by:       Arthur Mesh <arthurmesh at gmail.com> (the first
> item)
>
>   ------------------------------------------------------------------------
>   r255319 | markm | 2013-09-06 18:51:52 +0100 (Fri, 06 Sep 2013) | 4 lines
>
>   Yarrow wants entropy estimations to be conservative; the usual idea
>   is that if you are certain you have N bits of entropy, you declare
>   N/2.
>
>   ------------------------------------------------------------------------
>   r255075 | markm | 2013-08-30 18:47:53 +0100 (Fri, 30 Aug 2013) | 4 lines
>
>   Remove short-lived idea; thread to harvest (eg) RDRAND enropy into the
>   usual harvest queues. It was a nifty idea, but too heavyweight.
>
>   # Submitted by:       Arthur Mesh <arthurmesh at gmail.com>
>
>   ------------------------------------------------------------------------
>   r255071 | markm | 2013-08-30 12:42:57 +0100 (Fri, 30 Aug 2013) | 4 lines
>
>   Separate out the Software RNG entropy harvesting queue and thread
>   into its own files.
>
>   # Submitted by:        Arthur Mesh <arthurmesh at gmail.com>
>
>   ------------------------------------------------------------------------
>   r254934 | markm | 2013-08-26 20:07:03 +0100 (Mon, 26 Aug 2013) | 2 lines
>
>   Remove the short-lived namei experiment.
>
>   ------------------------------------------------------------------------
>   r254928 | markm | 2013-08-26 19:35:21 +0100 (Mon, 26 Aug 2013) | 2 lines
>
>   Snapshot; Do some running repairs on entropy harvesting. More needs
>   to follow.
>
>   ------------------------------------------------------------------------
>   r254927 | markm | 2013-08-26 19:29:51 +0100 (Mon, 26 Aug 2013) | 15 lines
>
>   Snapshot of current work;
>
>   1) Clean up namespace; only use "Yarrow" where it is Yarrow-specific
>   or close enough to the Yarrow algorithm. For the rest use a neutral
>   name.
>
>   2) Tidy up headers; put private stuff in private places. More could
>   be done here.
>
>   3) Streamline the hashing/encryption; no need for a 256-bit counter;
>   128 bits will last for long enough.
>
>   There are bits of debug code lying around; these will be removed
>   at a later stage.
>
>   ------------------------------------------------------------------------
>   r254784 | markm | 2013-08-24 14:54:56 +0100 (Sat, 24 Aug 2013) | 39 lines
>
>   1) example (partially humorous random_adaptor, that I call "EXAMPLE")
>    * It's not meant to be used in a real system, it's there to show how
>      the basics of how to create interfaces for random_adaptors. Perhaps
>      it should belong in a manual page
>
>   2) Move probe.c's functionality in to random_adaptors.c
>    * rename random_ident_hardware() to random_adaptor_choose()
>
>   3) Introduce a new way to choose (or select) random_adaptors via tunable
>   "rngs_want" It's a list of comma separated names of adaptors, ordered
>   by preferences. I.e.:
>   rngs_want="yarrow,rdrand"
>
>   Such setting would cause yarrow to be preferred to rdrand. If neither of
>   them are available (or registered), then system will default to
>   something reasonable (currently yarrow). If yarrow is not present, then
>   we fall back to the adaptor that's first on the list of registered
>   adaptors.
>
>   4) Introduce a way where RNGs can play a role of entropy source. This is
>   mostly useful for HW rngs.
>
>   The way I envision this is that every HW RNG will use this
>   functionality by default. Functionality to disable this is also present.
>   I have an example of how to use this in random_adaptor_example.c (see
>   modload event, and init function)
>
>   5) fix kern.random.adaptors from
>   kern.random.adaptors: yarrowpanicblock
>   to
>   kern.random.adaptors: yarrow,panic,block
>
>   6) add kern.random.active_adaptor to indicate currently selected
>   adaptor:
>   root at freebsd04:~ # sysctl kern.random.active_adaptor
>   kern.random.active_adaptor: yarrow
>
>   # Submitted by:       Arthur Mesh <arthurmesh at gmail.com>
>
>   Submitted by: Dag-Erling Smørgrav <des at FreeBSD.org>, Arthur Mesh <
> arthurmesh at gmail.com>
>   Reviewed by:  des at FreeBSD.org
>   Approved by:  re (delphij)
>   Approved by:  secteam (des,delphij)
>
> Added:
>   head/sys/dev/random/dummy_rng.c
>      - copied unchanged from r256243,
> projects/random_number_generator/sys/dev/random/dummy_rng.c
>   head/sys/dev/random/live_entropy_sources.c
>      - copied unchanged from r256243,
> projects/random_number_generator/sys/dev/random/live_entropy_sources.c
>   head/sys/dev/random/live_entropy_sources.h
>      - copied unchanged from r256243,
> projects/random_number_generator/sys/dev/random/live_entropy_sources.h
>   head/sys/dev/random/rwfile.c
>      - copied unchanged from r256243,
> projects/random_number_generator/sys/dev/random/rwfile.c
>   head/sys/dev/random/rwfile.h
>      - copied unchanged from r256243,
> projects/random_number_generator/sys/dev/random/rwfile.h
> Deleted:
>   head/sys/dev/random/pseudo_rng.c
> Modified:
>   head/etc/defaults/rc.conf
>   head/etc/rc.d/initrandom
>   head/share/examples/kld/random_adaptor/random_adaptor_example.c
> (contents, props changed)
>   head/share/man/man4/random.4
>   head/sys/boot/forth/loader.conf
>   head/sys/conf/NOTES
>   head/sys/conf/files
>   head/sys/conf/files.amd64
>   head/sys/conf/files.i386
>   head/sys/conf/options
>   head/sys/dev/glxsb/glxsb.c
>   head/sys/dev/hifn/hifn7751.c
>   head/sys/dev/random/harvest.c
>   head/sys/dev/random/hash.h
>   head/sys/dev/random/ivy.c
>   head/sys/dev/random/nehemiah.c
>   head/sys/dev/random/random_adaptors.c
>   head/sys/dev/random/random_adaptors.h
>   head/sys/dev/random/random_harvestq.c
>   head/sys/dev/random/random_harvestq.h
>   head/sys/dev/random/randomdev.c
>   head/sys/dev/random/randomdev.h
>   head/sys/dev/random/randomdev_soft.c
>   head/sys/dev/random/randomdev_soft.h
>   head/sys/dev/random/yarrow.c
>   head/sys/dev/random/yarrow.h
>   head/sys/dev/rndtest/rndtest.c
>   head/sys/dev/safe/safe.c
>   head/sys/dev/syscons/scmouse.c
>   head/sys/dev/syscons/syscons.c
>   head/sys/dev/ubsec/ubsec.c
>   head/sys/kern/kern_intr.c
>   head/sys/kern/subr_bus.c
>   head/sys/mips/cavium/octeon_rnd.c
>   head/sys/modules/random/Makefile
>   head/sys/net/if_ethersubr.c
>   head/sys/net/if_tun.c
>   head/sys/netgraph/ng_iface.c
>   head/sys/sys/random.h
> Directory Properties:
>   head/   (props changed)
>
> Modified: head/etc/defaults/rc.conf
>
> ==============================================================================
> --- head/etc/defaults/rc.conf   Sat Oct 12 12:34:19 2013        (r256376)
> +++ head/etc/defaults/rc.conf   Sat Oct 12 12:57:57 2013        (r256377)
> @@ -651,6 +651,7 @@ entropy_save_num="8"        # Number of entropy
>  harvest_interrupt="YES"        # Entropy device harvests interrupt
> randomness
>  harvest_ethernet="YES" # Entropy device harvests ethernet randomness
>  harvest_p_to_p="YES"   # Entropy device harvests point-to-point randomness
> +harvest_swi="YES"      # Entropy device harvests internal SWI randomness
>  dmesg_enable="YES"     # Save dmesg(8) to /var/run/dmesg.boot
>  watchdogd_enable="NO"  # Start the software watchdog daemon
>  watchdogd_flags=""     # Flags to watchdogd (if enabled)
>
> Modified: head/etc/rc.d/initrandom
>
> ==============================================================================
> --- head/etc/rc.d/initrandom    Sat Oct 12 12:34:19 2013        (r256376)
> +++ head/etc/rc.d/initrandom    Sat Oct 12 12:57:57 2013        (r256377)
> @@ -14,26 +14,6 @@ name="initrandom"
>  start_cmd="initrandom_start"
>  stop_cmd=":"
>
> -feed_dev_random()
> -{
> -       if [ -f "${1}" -a -r "${1}" -a -s "${1}" ]; then
> -               cat "${1}" | dd of=/dev/random bs=8k 2>/dev/null
> -       fi
> -}
> -
> -better_than_nothing()
> -{
> -       # XXX temporary until we can improve the entropy
> -       # harvesting rate.
> -       # Entropy below is not great, but better than nothing.
> -       # This unblocks the generator at startup
> -       # Note: commands are ordered to cause the most variance across
> reboots.
> -       ( kenv; dmesg; df -ib; ps -fauxww; date; sysctl -a ) \
> -           | dd of=/dev/random bs=8k 2>/dev/null
> -       /sbin/sha256 -q `sysctl -n kern.bootfile` \
> -           | dd of=/dev/random bs=8k 2>/dev/null
> -}
> -
>  initrandom_start()
>  {
>         soft_random_generator=`sysctl kern.random 2>/dev/null`
> @@ -63,23 +43,15 @@ initrandom_start()
>                         else
>                                 ${SYSCTL}
> kern.random.sys.harvest.point_to_point=0 >/dev/null
>                         fi
> -               fi
>
> -               # First pass at reseeding /dev/random.
> -               #
> -               case ${entropy_file} in
> -               [Nn][Oo] | '')
> -                       ;;
> -               *)
> -                       if [ -w /dev/random ]; then
> -                               feed_dev_random "${entropy_file}"
> +                       if checkyesno harvest_swi; then
> +                               ${SYSCTL} kern.random.sys.harvest.swi=1
> >/dev/null
> +                               echo -n ' swi'
> +                       else
> +                               ${SYSCTL} kern.random.sys.harvest.swi=0
> >/dev/null
>                         fi
> -                       ;;
> -               esac
> -
> -               better_than_nothing
> +               fi
>
> -               echo -n ' kickstart'
>         fi
>
>         echo '.'
>
> Modified: head/share/examples/kld/random_adaptor/random_adaptor_example.c
>
> ==============================================================================
> --- head/share/examples/kld/random_adaptor/random_adaptor_example.c
> Sat Oct 12 12:34:19 2013        (r256376)
> +++ head/share/examples/kld/random_adaptor/random_adaptor_example.c
> Sat Oct 12 12:57:57 2013        (r256377)
> @@ -30,32 +30,29 @@ __FBSDID("$FreeBSD$");
>
>  #include <sys/param.h>
>  #include <sys/kernel.h>
> +#include <sys/lock.h>
>  #include <sys/module.h>
> -#include <sys/selinfo.h>
> +#include <sys/random.h>
>  #include <sys/systm.h>
>
> +#include <dev/random/live_entropy_sources.h>
>  #include <dev/random/random_adaptors.h>
>  #include <dev/random/randomdev.h>
>
> -#define RNG_NAME "example"
> -
>  static int random_example_read(void *, int);
>
>  struct random_adaptor random_example = {
>         .ident = "Example RNG",
> -       .init = (random_init_func_t *)random_null_func,
> -       .deinit = (random_deinit_func_t *)random_null_func,
> +       .source = RANDOM_PURE_BOGUS,    /* Make sure this is in
> +                                        * sys/random.h and is unique */
>         .read = random_example_read,
> -       .write = (random_write_func_t *)random_null_func,
> -       .reseed = (random_reseed_func_t *)random_null_func,
> -       .seeded = 1,
>  };
>
>  /*
>   * Used under the license provided @ http://xkcd.com/221/
>   * http://creativecommons.org/licenses/by-nc/2.5/
>   */
> -static u_char
> +static uint8_t
>  getRandomNumber(void)
>  {
>         return 4;   /* chosen by fair dice roll, guaranteed to be random */
> @@ -64,14 +61,13 @@ getRandomNumber(void)
>  static int
>  random_example_read(void *buf, int c)
>  {
> -       u_char *b;
> +       uint8_t *b;
>         int count;
>
>         b = buf;
>
> -       for (count = 0; count < c; count++) {
> +       for (count = 0; count < c; count++)
>                 b[count] = getRandomNumber();
> -       }
>
>         printf("returning %d bytes of pure randomness\n", c);
>         return (c);
> @@ -80,15 +76,26 @@ random_example_read(void *buf, int c)
>  static int
>  random_example_modevent(module_t mod, int type, void *unused)
>  {
> +       int error = 0;
>
>         switch (type) {
>         case MOD_LOAD:
> -               random_adaptor_register(RNG_NAME, &random_example);
> -               EVENTHANDLER_INVOKE(random_adaptor_attach,
> &random_example);
> -               return (0);
> +               live_entropy_source_register(&random_example);
> +               break;
> +
> +       case MOD_UNLOAD:
> +               live_entropy_source_deregister(&random_example);
> +               break;
> +
> +       case MOD_SHUTDOWN:
> +               break;
> +
> +       default:
> +               error = EOPNOTSUPP;
> +               break;
>         }
>
> -       return (EINVAL);
> +       return (error);
>  }
>
> -RANDOM_ADAPTOR_MODULE(random_example, random_example_modevent, 1);
> +LIVE_ENTROPY_SRC_MODULE(live_entropy_source_example,
> random_example_modevent, 1);
>
> Modified: head/share/man/man4/random.4
>
> ==============================================================================
> --- head/share/man/man4/random.4        Sat Oct 12 12:34:19 2013
>  (r256376)
> +++ head/share/man/man4/random.4        Sat Oct 12 12:57:57 2013
>  (r256377)
> @@ -1,4 +1,4 @@
> -.\" Copyright (c) 2001 Mark R V Murray.  All rights reserved.
> +.\" Copyright (c) 2001-2013    Mark R V Murray.  All rights reserved.
>  .\"
>  .\" Redistribution and use in source and binary forms, with or without
>  .\" modification, are permitted provided that the following conditions
> @@ -23,7 +23,7 @@
>  .\"
>  .\" $FreeBSD$
>  .\"
> -.Dd August 7, 2013
> +.Dd October 12, 2013
>  .Dt RANDOM 4
>  .Os
>  .Sh NAME
> @@ -43,35 +43,48 @@ The device will probe for
>  certain hardware entropy sources,
>  and use these in preference to the fallback,
>  which is a generator implemented in software.
> -If the kernel environment MIB's
> -.Va hw.nehemiah_rng_enable
> -or
> -.Va hw.ivy_rng_enable
> -are set to
> -.Dq Li 0 ,
> -the associated hardware entropy source will be ignored.
> -.Pp
> -If the device is using
> -the software generator,
> -writing data to
> -.Nm
> -would perturb the internal state.
> -This perturbation of the internal state
> -is the only userland method of introducing
> -extra entropy into the device.
> -If the writer has superuser privilege,
> -then closing the device after writing
> -will make the software generator reseed itself.
> -This can be used for extra security,
> -as it immediately introduces any/all new entropy
> -into the PRNG.
> -The hardware generators will generate
> -sufficient quantities of entropy,
> -and will therefore ignore user-supplied input.
> -The software
> -.Nm
> -device may be controlled with
> -.Xr sysctl 8 .
> +.Pp
> +The software generator will start in an
> +.Em unseeded
> +state, and will block reads until
> +it is (re)seeded.
> +This may cause trouble at system boot
> +when keys and the like
> +are generated from
> +/dev/random
> +so steps should be taken to ensure a
> +reseed as soon as possible.
> +The
> +.Xr sysctl 8
> +controlling the
> +.Em seeded
> +status (see below) may be used
> +if security is not an issue
> +or for convenience
> +during setup or development.
> +.Pp
> +This initial seeding
> +of random number generators
> +is a bootstrapping problem
> +that needs very careful attention.
> +In some cases,
> +it may be difficult
> +to find enough randomness
> +to seed a random number generator
> +until a system is fully operational,
> +but the system requires random numbers
> +to become fully operational.
> +It is (or more accurately should be)
> +critically important that the
> +.Nm
> +device is seeded
> +before the first time it is used.
> +In the case where a dummy or "blocking-only"
> +device is used,
> +it is the responsibility
> +of the system architect
> +to ensure that no blocking reads
> +hold up critical processes.
>  .Pp
>  To see the current settings of the software
>  .Nm
> @@ -81,22 +94,20 @@ device, use the command line:
>  .Pp
>  which results in something like:
>  .Bd -literal -offset indent
> -kern.random.adaptors: yarrow
> +kern.random.adaptors: yarrow,dummy
> +kern.random.active_adaptor: yarrow
> +kern.random.yarrow.gengateinterval: 10
> +kern.random.yarrow.bins: 10
> +kern.random.yarrow.fastthresh: 96
> +kern.random.yarrow.slowthresh: 128
> +kern.random.yarrow.slowoverthresh: 2
>  kern.random.sys.seeded: 1
>  kern.random.sys.harvest.ethernet: 1
>  kern.random.sys.harvest.point_to_point: 1
>  kern.random.sys.harvest.interrupt: 1
> -kern.random.sys.harvest.swi: 0
> -kern.random.yarrow.gengateinterval: 10
> -kern.random.yarrow.bins: 10
> -kern.random.yarrow.fastthresh: 192
> -kern.random.yarrow.slowthresh: 256
> -kern.random.yarrow.slowoverthresh: 2
> +kern.random.sys.harvest.swi: 1
>  .Ed
>  .Pp
> -(These would not be seen if a
> -hardware generator is present.)
> -.Pp
>  Other than
>  .Dl kern.random.adaptors
>  all settings are read/write.
> @@ -107,9 +118,10 @@ variable indicates whether or not the
>  .Nm
>  device is in an acceptably secure state
>  as a result of reseeding.
> -If set to 0, the device will block (on read) until the next reseed
> -(which can be from an explicit write,
> -or as a result of entropy harvesting).
> +If set to 0,
> +the device will block (on read)
> +until the next reseed
> +as a result of entropy harvesting.
>  A reseed will set the value to 1 (non-blocking).
>  .Pp
>  The
> @@ -276,19 +288,6 @@ the generator produce independent sequen
>  However, the guessability or reproducibility of the sequence is
> unimportant,
>  unlike the previous cases.
>  .Pp
> -One final consideration for the seeding of random number generators
> -is a bootstrapping problem.
> -In some cases, it may be difficult to find enough randomness to
> -seed a random number generator until a system is fully operational,
> -but the system requires random numbers to become fully operational.
> -There is no substitute for careful thought here,
> -but the
> -.Fx
> -.Nm
> -device,
> -which is based on the Yarrow system,
> -should be of some help in this area.
> -.Pp
>  .Fx
>  does also provide the traditional
>  .Xr rand 3
> @@ -325,17 +324,7 @@ and is an implementation of the
>  .Em Yarrow
>  algorithm by Bruce Schneier,
>  .Em et al .
> -The only hardware implementations
> -currently are for the
> -.Tn VIA C3 Nehemiah
> -(stepping 3 or greater)
> -CPU
> -and the
> -.Tn Intel
> -.Dq Bull Mountain
> -.Em RdRand
> -instruction and underlying random number generator (RNG).
> -More will be added in the future.
> +Significant infrastructure work was done by Arthur Mesh.
>  .Pp
>  The author gratefully acknowledges
>  significant assistance from VIA Technologies, Inc.
>
> Modified: head/sys/boot/forth/loader.conf
>
> ==============================================================================
> --- head/sys/boot/forth/loader.conf     Sat Oct 12 12:34:19 2013
>  (r256376)
> +++ head/sys/boot/forth/loader.conf     Sat Oct 12 12:57:57 2013
>  (r256377)
> @@ -39,6 +39,17 @@ bitmap_type="splash_image_data" # and pl
>
>
>  ##############################################################
> +###  Random number generator configuration ###################
> +##############################################################
> +
> +entropy_cache_load="NO"                        # Set this to YES to load
> entropy at boot time
> +entropy_cache_name="/boot/entropy"     # Set this to the name of the file
> +entropy_cache_type="/boot/entropy"
> +#kern.random.sys.seeded="0"            # Set this to 1 to start
> /dev/random
> +                                       # without waiting for a (re)seed.
> +
> +
> +##############################################################
>  ###  Loader settings  ########################################
>  ##############################################################
>
>
> Modified: head/sys/conf/NOTES
>
> ==============================================================================
> --- head/sys/conf/NOTES Sat Oct 12 12:34:19 2013        (r256376)
> +++ head/sys/conf/NOTES Sat Oct 12 12:57:57 2013        (r256377)
> @@ -2962,3 +2962,8 @@ options   RCTL
>  options        BROOKTREE_ALLOC_PAGES=(217*4+1)
>  options        MAXFILES=999
>
> +# Random number generator
> +options        RANDOM_YARROW   # Yarrow RNG
> +##options      RANDOM_FORTUNA  # Fortuna RNG - not yet implemented
> +options        RANDOM_DEBUG    # Debugging messages
> +options        RANDOM_RWFILE   # Read and write entropy cache
>
> Modified: head/sys/conf/files
>
> ==============================================================================
> --- head/sys/conf/files Sat Oct 12 12:34:19 2013        (r256376)
> +++ head/sys/conf/files Sat Oct 12 12:57:57 2013        (r256377)
> @@ -2043,13 +2043,15 @@ rt2860.fw                       optional rt2860fw
> | ralfw               \
>         no-obj no-implicit-rule                                         \
>         clean           "rt2860.fw"
>  dev/random/harvest.c           standard
> -dev/random/hash.c              optional random
> -dev/random/pseudo_rng.c                standard
> +dev/random/dummy_rng.c         standard
>  dev/random/random_adaptors.c   standard
> -dev/random/random_harvestq.c   standard
> +dev/random/live_entropy_sources.c      optional random
> +dev/random/random_harvestq.c   optional random
>  dev/random/randomdev.c         optional random
>  dev/random/randomdev_soft.c    optional random
>  dev/random/yarrow.c            optional random
> +dev/random/hash.c              optional random
> +dev/random/rwfile.c            optional random
>  dev/rc/rc.c                    optional rc
>  dev/re/if_re.c                 optional re
>  dev/rndtest/rndtest.c          optional rndtest
>
> Modified: head/sys/conf/files.amd64
>
> ==============================================================================
> --- head/sys/conf/files.amd64   Sat Oct 12 12:34:19 2013        (r256376)
> +++ head/sys/conf/files.amd64   Sat Oct 12 12:57:57 2013        (r256377)
> @@ -259,8 +259,8 @@ dev/nvme/nvme_sysctl.c              optional
>  nvme
>  dev/nvme/nvme_test.c           optional        nvme
>  dev/nvme/nvme_util.c           optional        nvme
>  dev/nvram/nvram.c              optional        nvram isa
> -dev/random/ivy.c               optional        random rdrand_rng
> -dev/random/nehemiah.c          optional        random padlock_rng
> +dev/random/ivy.c               optional        rdrand_rng
> +dev/random/nehemiah.c          optional        padlock_rng
>  dev/qlxge/qls_dbg.c            optional        qlxge pci
>  dev/qlxge/qls_dump.c           optional        qlxge pci
>  dev/qlxge/qls_hw.c             optional        qlxge pci
>
> Modified: head/sys/conf/files.i386
>
> ==============================================================================
> --- head/sys/conf/files.i386    Sat Oct 12 12:34:19 2013        (r256376)
> +++ head/sys/conf/files.i386    Sat Oct 12 12:57:57 2013        (r256377)
> @@ -257,8 +257,8 @@ dev/nvme/nvme_test.c                optional nvme
>  dev/nvme/nvme_util.c           optional nvme
>  dev/nvram/nvram.c              optional nvram isa
>  dev/pcf/pcf_isa.c              optional pcf
> -dev/random/ivy.c               optional random rdrand_rng
> -dev/random/nehemiah.c          optional random padlock_rng
> +dev/random/ivy.c               optional rdrand_rng
> +dev/random/nehemiah.c          optional padlock_rng
>  dev/sbni/if_sbni.c             optional sbni
>  dev/sbni/if_sbni_isa.c         optional sbni isa
>  dev/sbni/if_sbni_pci.c         optional sbni pci
>
> Modified: head/sys/conf/options
>
> ==============================================================================
> --- head/sys/conf/options       Sat Oct 12 12:34:19 2013        (r256376)
> +++ head/sys/conf/options       Sat Oct 12 12:57:57 2013        (r256377)
> @@ -904,3 +904,9 @@ RACCT               opt_global.h
>
>  # Resource Limits
>  RCTL           opt_global.h
> +
> +# Random number generator(s)
> +RANDOM_YARROW  opt_random.h
> +RANDOM_FORTUNA opt_random.h
> +RANDOM_DEBUG   opt_random.h
> +RANDOM_RWFILE  opt_random.h
>
> Modified: head/sys/dev/glxsb/glxsb.c
>
> ==============================================================================
> --- head/sys/dev/glxsb/glxsb.c  Sat Oct 12 12:34:19 2013        (r256376)
> +++ head/sys/dev/glxsb/glxsb.c  Sat Oct 12 12:57:57 2013        (r256377)
> @@ -476,7 +476,7 @@ glxsb_rnd(void *v)
>         if (status & SB_RNS_TRNG_VALID) {
>                 value = bus_read_4(sc->sc_sr, SB_RANDOM_NUM);
>                 /* feed with one uint32 */
> -               random_harvest(&value, 4, 32/2, 0, RANDOM_PURE);
> +               random_harvest(&value, 4, 32/2, RANDOM_PURE_GLXSB);
>         }
>
>         callout_reset(&sc->sc_rngco, sc->sc_rnghz, glxsb_rnd, sc);
>
> Modified: head/sys/dev/hifn/hifn7751.c
>
> ==============================================================================
> --- head/sys/dev/hifn/hifn7751.c        Sat Oct 12 12:34:19 2013
>  (r256376)
> +++ head/sys/dev/hifn/hifn7751.c        Sat Oct 12 12:57:57 2013
>  (r256377)
> @@ -258,7 +258,7 @@ hifn_partname(struct hifn_softc *sc)
>  static void
>  default_harvest(struct rndtest_state *rsp, void *buf, u_int count)
>  {
> -       random_harvest(buf, count, count*NBBY/2, 0, RANDOM_PURE);
> +       random_harvest(buf, count, count*NBBY/2, RANDOM_PURE_HIFN);
>  }
>
>  static u_int
>
> Copied: head/sys/dev/random/dummy_rng.c (from r256243,
> projects/random_number_generator/sys/dev/random/dummy_rng.c)
>
> ==============================================================================
> --- /dev/null   00:00:00 1970   (empty, because file is newly added)
> +++ head/sys/dev/random/dummy_rng.c     Sat Oct 12 12:57:57 2013
>  (r256377, copy of r256243,
> projects/random_number_generator/sys/dev/random/dummy_rng.c)
> @@ -0,0 +1,123 @@
> +/*-
> + * Copyright (c) 2013 Arthur Mesh <arthurmesh at gmail.com>
> + * All rights reserved.
> + *
> + * 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
> + *    in this position and unchanged.
> + * 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 AUTHOR ``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 AUTHOR 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.
> + *
> + */
> +#include <sys/cdefs.h>
> +__FBSDID("$FreeBSD$");
> +
> +#include <sys/param.h>
> +#include <sys/fcntl.h>
> +#include <sys/kernel.h>
> +#include <sys/malloc.h>
> +#include <sys/module.h>
> +#include <sys/random.h>
> +#include <sys/selinfo.h>
> +#include <sys/systm.h>
> +#include <sys/time.h>
> +
> +#include <dev/random/random_adaptors.h>
> +#include <dev/random/randomdev.h>
> +
> +static struct mtx      dummy_random_mtx;
> +
> +/* Used to fake out unused random calls in random_adaptor */
> +static void
> +random_null_func(void)
> +{
> +}
> +
> +static int
> +dummy_random_poll(int events __unused, struct thread *td __unused)
> +{
> +
> +       return (0);
> +}
> +
> +static int
> +dummy_random_block(int flag)
> +{
> +       int error = 0;
> +
> +       mtx_lock(&dummy_random_mtx);
> +
> +       /* Blocking logic */
> +       while (!error) {
> +               if (flag & O_NONBLOCK)
> +                       error = EWOULDBLOCK;
> +               else {
> +                       printf("random: dummy device blocking on read.\n");
> +                       error = msleep(&dummy_random_block,
> +                           &dummy_random_mtx,
> +                           PUSER | PCATCH, "block", 0);
> +               }
> +       }
> +       mtx_unlock(&dummy_random_mtx);
> +
> +       return (error);
> +}
> +
> +static void
> +dummy_random_init(void)
> +{
> +
> +       mtx_init(&dummy_random_mtx, "sleep mtx for dummy_random",
> +           NULL, MTX_DEF);
> +}
> +
> +static void
> +dummy_random_deinit(void)
> +{
> +
> +       mtx_destroy(&dummy_random_mtx);
> +}
> +
> +struct random_adaptor dummy_random = {
> +       .ident = "Dummy entropy device that always blocks",
> +       .init = dummy_random_init,
> +       .deinit = dummy_random_deinit,
> +       .block = dummy_random_block,
> +       .poll = dummy_random_poll,
> +       .read = (random_read_func_t *)random_null_func,
> +       .reseed = (random_reseed_func_t *)random_null_func,
> +       .seeded = 0, /* This device can never be seeded */
> +};
> +
> +static int
> +dummy_random_modevent(module_t mod __unused, int type, void *unused
> __unused)
> +{
> +
> +       switch (type) {
> +       case MOD_LOAD:
> +               random_adaptor_register("dummy", &dummy_random);
> +               EVENTHANDLER_INVOKE(random_adaptor_attach,
> +                   &dummy_random);
> +
> +               return (0);
> +       }
> +
> +       return (EINVAL);
> +}
> +
> +RANDOM_ADAPTOR_MODULE(dummy, dummy_random_modevent, 1);
>
> Modified: head/sys/dev/random/harvest.c
>
> ==============================================================================
> --- head/sys/dev/random/harvest.c       Sat Oct 12 12:34:19 2013
>  (r256376)
> +++ head/sys/dev/random/harvest.c       Sat Oct 12 12:57:57 2013
>  (r256377)
> @@ -48,20 +48,20 @@ __FBSDID("$FreeBSD$");
>  static int read_random_phony(void *, int);
>
>  /* Structure holding the desired entropy sources */
> -struct harvest_select harvest = { 1, 1, 1, 0 };
> +struct harvest_select harvest = { 1, 1, 1, 1 };
>  static int warned = 0;
>
>  /* hold the address of the routine which is actually called if
>   * the randomdev is loaded
>   */
> -static void (*reap_func)(u_int64_t, const void *, u_int, u_int, u_int,
> +static void (*reap_func)(u_int64_t, const void *, u_int, u_int,
>      enum esource) = NULL;
>  static int (*read_func)(void *, int) = read_random_phony;
>
>  /* Initialise the harvester at load time */
>  void
>  randomdev_init_harvester(void (*reaper)(u_int64_t, const void *, u_int,
> -    u_int, u_int, enum esource), int (*reader)(void *, int))
> +    u_int, enum esource), int (*reader)(void *, int))
>  {
>         reap_func = reaper;
>         read_func = reader;
> @@ -86,12 +86,10 @@ randomdev_deinit_harvester(void)
>   * read which can be quite expensive.
>   */
>  void
> -random_harvest(void *entropy, u_int count, u_int bits, u_int frac,
> -    enum esource origin)
> +random_harvest(void *entropy, u_int count, u_int bits, enum esource
> origin)
>  {
>         if (reap_func)
> -               (*reap_func)(get_cyclecount(), entropy, count, bits, frac,
> -                   origin);
> +               (*reap_func)(get_cyclecount(), entropy, count, bits,
> origin);
>  }
>
>  /* Userland-visible version of read_random */
>
> Modified: head/sys/dev/random/hash.h
>
> ==============================================================================
> --- head/sys/dev/random/hash.h  Sat Oct 12 12:34:19 2013        (r256376)
> +++ head/sys/dev/random/hash.h  Sat Oct 12 12:57:57 2013        (r256377)
> @@ -26,6 +26,9 @@
>   * $FreeBSD$
>   */
>
> +#ifndef SYS_DEV_RANDOM_HASH_H_INCLUDED
> +#define SYS_DEV_RANDOM_HASH_H_INCLUDED
> +
>  #define        KEYSIZE         32      /* (in bytes) == 256 bits */
>  #define        BLOCKSIZE       16      /* (in bytes) == 128 bits */
>
> @@ -43,3 +46,5 @@ void randomdev_hash_iterate(struct rando
>  void randomdev_hash_finish(struct randomdev_hash *, void *);
>  void randomdev_encrypt_init(struct randomdev_key *, void *);
>  void randomdev_encrypt(struct randomdev_key *context, void *, void *,
> unsigned);
> +
> +#endif
>
> Modified: head/sys/dev/random/ivy.c
>
> ==============================================================================
> --- head/sys/dev/random/ivy.c   Sat Oct 12 12:34:19 2013        (r256376)
> +++ head/sys/dev/random/ivy.c   Sat Oct 12 12:57:57 2013        (r256377)
> @@ -30,38 +30,35 @@
>  __FBSDID("$FreeBSD$");
>
>  #include <sys/param.h>
> -#include <sys/time.h>
>  #include <sys/kernel.h>
>  #include <sys/lock.h>
> +#include <sys/malloc.h>
>  #include <sys/module.h>
> -#include <sys/mutex.h>
> +#include <sys/random.h>
>  #include <sys/selinfo.h>
>  #include <sys/systm.h>
>
>  #include <machine/md_var.h>
>  #include <machine/specialreg.h>
>
> -#include <dev/random/random_adaptors.h>
>  #include <dev/random/randomdev.h>
> +#include <dev/random/randomdev_soft.h>
> +#include <dev/random/random_harvestq.h>
> +#include <dev/random/live_entropy_sources.h>
> +#include <dev/random/random_adaptors.h>
>
>  #define        RETRY_COUNT     10
>
> -static void random_ivy_init(void);
> -static void random_ivy_deinit(void);
>  static int random_ivy_read(void *, int);
>
> -struct random_adaptor random_ivy = {
> +static struct random_hardware_source random_ivy = {
>         .ident = "Hardware, Intel IvyBridge+ RNG",
> -       .init = random_ivy_init,
> -       .deinit = random_ivy_deinit,
> -       .read = random_ivy_read,
> -       .write = (random_write_func_t *)random_null_func,
> -       .reseed = (random_reseed_func_t *)random_null_func,
> -       .seeded = 1,
> +       .source = RANDOM_PURE_RDRAND,
> +       .read = random_ivy_read
>  };
>
>  static inline int
> -ivy_rng_store(long *tmp)
> +ivy_rng_store(uint64_t *tmp)
>  {
>  #ifdef __GNUCLIKE_ASM
>         uint32_t count;
> @@ -86,34 +83,26 @@ ivy_rng_store(long *tmp)
>  #endif
>  }
>
> -static void
> -random_ivy_init(void)
> -{
> -}
> -
> -void
> -random_ivy_deinit(void)
> -{
> -}
> -
>  static int
>  random_ivy_read(void *buf, int c)
>  {
> -       char *b;
> -       long tmp;
> -       int count, res, retry;
> +       uint8_t *b;
> +       int count, ret, retry;
> +       uint64_t tmp;
>
> -       for (count = c, b = buf; count > 0; count -= res, b += res) {
> +       b = buf;
> +       for (count = c; count > 0; count -= ret) {
>                 for (retry = 0; retry < RETRY_COUNT; retry++) {
> -                       res = ivy_rng_store(&tmp);
> -                       if (res != 0)
> +                       ret = ivy_rng_store(&tmp);
> +                       if (ret != 0)
>                                 break;
>                 }
> -               if (res == 0)
> +               if (ret == 0)
>                         break;
> -               if (res > count)
> -                       res = count;
> -               memcpy(b, &tmp, res);
> +               if (ret > count)
> +                       ret = count;
> +               memcpy(b, &tmp, ret);
> +               b += ret;
>         }
>         return (c - count);
>  }
> @@ -121,25 +110,35 @@ random_ivy_read(void *buf, int c)
>  static int
>  rdrand_modevent(module_t mod, int type, void *unused)
>  {
> +       int error = 0;
>
>         switch (type) {
>         case MOD_LOAD:
> -               if (cpu_feature2 & CPUID2_RDRAND) {
> -                       random_adaptor_register("rdrand", &random_ivy);
> -                       EVENTHANDLER_INVOKE(random_adaptor_attach,
> &random_ivy);
> -                       return (0);
> -               } else {
> +               if (cpu_feature2 & CPUID2_RDRAND)
> +                       live_entropy_source_register(&random_ivy);
> +               else
>  #ifndef KLD_MODULE
>                         if (bootverbose)
>  #endif
> -                               printf(
> -                           "%s: RDRAND feature is not present on this
> CPU\n",
> +                               printf("%s: RDRAND is not present\n",
>                                     random_ivy.ident);
> -                       return (0);
> -               }
> +               break;
> +
> +       case MOD_UNLOAD:
> +               if (cpu_feature2 & CPUID2_RDRAND)
> +                       live_entropy_source_deregister(&random_ivy);
> +               break;
> +
> +       case MOD_SHUTDOWN:
> +               break;
> +
> +       default:
> +               error = EOPNOTSUPP;
> +               break;
> +
>         }
>
> -       return (EINVAL);
> +       return (error);
>  }
>
> -RANDOM_ADAPTOR_MODULE(random_rdrand, rdrand_modevent, 1);
> +LIVE_ENTROPY_SRC_MODULE(random_rdrand, rdrand_modevent, 1);
>
> Copied: head/sys/dev/random/live_entropy_sources.c (from r256243,
> projects/random_number_generator/sys/dev/random/live_entropy_sources.c)
>
> ==============================================================================
> --- /dev/null   00:00:00 1970   (empty, because file is newly added)
> +++ head/sys/dev/random/live_entropy_sources.c  Sat Oct 12 12:57:57 2013
>      (r256377, copy of r256243,
> projects/random_number_generator/sys/dev/random/live_entropy_sources.c)
> @@ -0,0 +1,195 @@
> +/*-
> + * Copyright (c) 2013 Arthur Mesh <arthurmesh at gmail.com>
> + * Copyright (c) 2013 Mark R V Murray
> + * All rights reserved.
> + *
> + * 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
> + *    in this position and unchanged.
> + * 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 AUTHOR ``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 AUTHOR 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.
> + */
> +
> +#include <sys/param.h>
> +__FBSDID("$FreeBSD$");
> +
> +#include <sys/kernel.h>
> +#include <sys/libkern.h>
> +#include <sys/lock.h>
> +#include <sys/malloc.h>
> +#include <sys/queue.h>
> +#include <sys/random.h>
> +#include <sys/selinfo.h>
> +#include <sys/sx.h>
> +#include <sys/sysctl.h>
> +#include <sys/systm.h>
> +#include <sys/unistd.h>
> +
> +#include <machine/cpu.h>
> +
> +#include <dev/random/randomdev.h>
> +#include <dev/random/randomdev_soft.h>
> +#include <dev/random/random_adaptors.h>
> +#include <dev/random/random_harvestq.h>
> +
> +#include "live_entropy_sources.h"
> +
> +LIST_HEAD(les_head, live_entropy_sources);
> +static struct les_head sources = LIST_HEAD_INITIALIZER(sources);
> +
> +/*
> + * The live_lock protects the consistency of the "struct les_head sources"
> + */
> +static struct sx les_lock; /* need a sleepable lock */
> +
> +void
> +live_entropy_source_register(struct random_hardware_source *rsource)
> +{
> +       struct live_entropy_sources *les;
> +
> +       KASSERT(rsource != NULL, ("invalid input to %s", __func__));
> +
> +       les = malloc(sizeof(struct live_entropy_sources), M_ENTROPY,
> M_WAITOK);
> +       les->rsource = rsource;
> +
> +       sx_xlock(&les_lock);
> +       LIST_INSERT_HEAD(&sources, les, entries);
> +       sx_xunlock(&les_lock);
> +}
> +
> +void
> +live_entropy_source_deregister(struct random_hardware_source *rsource)
> +{
> +       struct live_entropy_sources *les = NULL;
> +
> +       KASSERT(rsource != NULL, ("invalid input to %s", __func__));
> +
> +       sx_xlock(&les_lock);
> +       LIST_FOREACH(les, &sources, entries)
> +               if (les->rsource == rsource) {
> +                       LIST_REMOVE(les, entries);
> +                       break;
> +               }
> +       sx_xunlock(&les_lock);
> +       if (les != NULL)
> +               free(les, M_ENTROPY);
> +}
> +
> +static int
> +live_entropy_source_handler(SYSCTL_HANDLER_ARGS)
> +{
> +       struct live_entropy_sources *les;
> +       int error, count;
> +
> +       count = error = 0;
> +
> +       sx_slock(&les_lock);
> +
> +       if (LIST_EMPTY(&sources))
> +               error = SYSCTL_OUT(req, "", 0);
> +       else {
> +               LIST_FOREACH(les, &sources, entries) {
> +
> +                       error = SYSCTL_OUT(req, ",", count++ ? 1 : 0);
> +                       if (error)
> +                               break;
> +
> +                       error = SYSCTL_OUT(req, les->rsource->ident,
> strlen(les->rsource->ident));
> +                       if (error)
> +                               break;
> +               }
> +       }
> +
> +       sx_sunlock(&les_lock);
> +
> +       return (error);
> +}
> +
> +static void
> +live_entropy_sources_init(void *unused)
> +{
> +
> +       SYSCTL_PROC(_kern_random, OID_AUTO, live_entropy_sources,
> +           CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
> +           NULL, 0, live_entropy_source_handler, "",
> +           "List of Active Live Entropy Sources");
> +
> +       sx_init(&les_lock, "live_entropy_sources");
> +}
> +
> +/*
> + * Run through all "live" sources reading entropy for the given
> + * number of rounds, which should be a multiple of the number
> + * of entropy accumulation pools in use; 2 for Yarrow and 32
> + * for Fortuna.
> + *
> + * BEWARE!!!
> + * This function runs inside the RNG thread! Don't do anything silly!
> + * Remember that we are NOT holding harvest_mtx on entry!
> + */
> +void
> +live_entropy_sources_feed(int rounds, event_proc_f entropy_processor)
> +{
> +       static struct harvest event;
> +       static uint8_t buf[HARVESTSIZE];
> +       struct live_entropy_sources *les;
> +       int i, n;
> +
> +       sx_slock(&les_lock);
> +
> +       /*
> +        * Walk over all of live entropy sources, and feed their output
> +        * to the system-wide RNG.
> +        */
> +       LIST_FOREACH(les, &sources, entries) {
> +
> +               for (i = 0; i < rounds; i++) {
> +                       /*
> +                        * This should be quick, since it's a live entropy
> +                        * source.
> +                        */
> +                       /* FIXME: Whine loudly if this didn't work. */
> +                       n = les->rsource->read(buf, sizeof(buf));
> +                       n = MIN(n, HARVESTSIZE);
> +
> +                       event.somecounter = get_cyclecount();
> +                       event.size = n;
> +                       event.bits = (n*8)/2;
> +                       event.source = les->rsource->source;
> +                       memcpy(event.entropy, buf, n);
> +
> +                       /* Do the actual entropy insertion */
> +                       entropy_processor(&event);
> +               }
> +
> +       }
> +
> +       sx_sunlock(&les_lock);
> +}
> +
> +static void
> +live_entropy_sources_deinit(void *unused)
> +{
> +
> +       sx_destroy(&les_lock);
> +}
> +
> +SYSINIT(random_adaptors, SI_SUB_DRIVERS, SI_ORDER_FIRST,
> +    live_entropy_sources_init, NULL);
> +SYSUNINIT(random_adaptors, SI_SUB_DRIVERS, SI_ORDER_FIRST,
> +    live_entropy_sources_deinit, NULL);
>
> Copied: head/sys/dev/random/live_entropy_sources.h (from r256243,
> projects/random_number_generator/sys/dev/random/live_entropy_sources.h)
>
> ==============================================================================
> --- /dev/null   00:00:00 1970   (empty, because file is newly added)
> +++ head/sys/dev/random/live_entropy_sources.h  Sat Oct 12 12:57:57 2013
>      (r256377, copy of r256243,
> projects/random_number_generator/sys/dev/random/live_entropy_sources.h)
> @@ -0,0 +1,60 @@
> +/*-
> + * Copyright (c) 2013 Arthur Mesh <arthurmesh at gmail.com>
> + * Copyright (c) 2013 Mark R V Murray
> + * All rights reserved.
> + *
> + * 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
> + *    in this position and unchanged.
> + * 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 AUTHOR ``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 AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
>
> *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
>


More information about the svn-src-all mailing list