On Wed, Sep 19, 2012 at 03:34:59PM -0700, David O'Brien wrote:
> On Tue, Sep 18, 2012 at 11:14:22PM +0200, Pawel Jakub Dawidek wrote:
> > I experimented a bit with collecting entropy from the time it takes for
> > device_attach() to run (in CPU cycles). It seems that those times have
> > enough variation that we can use it for entropy harvesting. It happens
> > even before root is mounted, so pretty early.
> 
> I like it.  Microsoft harvests from something like 900 events/things.
> The more good things like this we find improves our security.
> 
> > The patch is here:
> >     http://people.freebsd.org/~pjd/patches/harvest_device_attach.patch
> > Comments?
> 
> Embelishments:

Note that adding sysctl to turn off entropy harvesting from
device_attach() is pretty useless, as sysctls can be changed once we
start userland and then all device_attach() are already called (modulo
drivers loaded later). What I'd like to see is for all those sysctls to
have corresponding tunables, then it would make more sense.

> Index: sys/dev/random/randomdev_soft.c
> ===================================================================
> --- sys/dev/random/randomdev_soft.c   (revision 240694)
> +++ sys/dev/random/randomdev_soft.c   (working copy)
> @@ -158,6 +185,11 @@ random_yarrow_init(void)
>           "Harvest serial net entropy");
>       SYSCTL_ADD_PROC(&random_clist,
>           SYSCTL_CHILDREN(random_sys_harvest_o),
> +         OID_AUTO, "devprobe", CTLTYPE_INT | CTLFLAG_RW,
> +         &harvest.devprobe, 1, random_check_boolean, "I",
> +         "Harvest Device Probe entropy");
> +     SYSCTL_ADD_PROC(&random_clist,
> +         SYSCTL_CHILDREN(random_sys_harvest_o),
>           OID_AUTO, "interrupt", CTLTYPE_INT | CTLFLAG_RW,
>           &harvest.interrupt, 1, random_check_boolean, "I",
>           "Harvest IRQ entropy");
> @@ -303,7 +341,7 @@ random_harvest_internal(u_int64_t someco
>       KASSERT(origin == RANDOM_START || origin == RANDOM_WRITE ||
>              origin == RANDOM_KEYBOARD || origin == RANDOM_MOUSE ||
>              origin == RANDOM_NET || origin == RANDOM_INTERRUPT ||
> -            origin == RANDOM_PURE,
> +            origin == RANDOM_PURE || origin == RANDOM_DEVICE,
>           ("random_harvest_internal: origin %d invalid\n", origin));
>  
>       /* Lockless read to avoid lock operations if fifo is full. */
> Index: sys/dev/random/harvest.c
> ===================================================================
> --- sys/dev/random/harvest.c  (revision 240694)
> +++ sys/dev/random/harvest.c  (working copy)
> @@ -48,7 +48,13 @@ __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,      /*ethernet*/
> +     1,      /*pt2pt*/
> +     1,      /*intr*/
> +     0,      /*swi*/
> +     1,      /*devprobe*/
> +};
>  static int warned = 0;
>  
>  /* hold the address of the routine which is actually called if
> Index: sys/sys/random.h
> ===================================================================
> --- sys/sys/random.h  (revision 240495)
> +++ sys/sys/random.h  (working copy)
> @@ -45,6 +45,7 @@ enum esource {
>       RANDOM_NET,
>       RANDOM_INTERRUPT,
>       RANDOM_PURE,
> +     RANDOM_DEVICE,
>       ENTROPYSOURCE
>  };
>  void random_harvest(void *, u_int, u_int, u_int, enum esource);
> @@ -57,6 +58,7 @@ struct harvest_select {
>       int point_to_point;
>       int interrupt;
>       int swi;
> +     int device;
>  };
>  
>  extern struct harvest_select harvest;
> Index: sys/kern/subr_bus.c
> ===================================================================
> --- sys/kern/subr_bus.c       (revision 240495)
> +++ sys/kern/subr_bus.c       (working copy)
> @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
>  #include <sys/condvar.h>
>  #include <sys/queue.h>
>  #include <machine/bus.h>
> +#include <sys/random.h>
>  #include <sys/rman.h>
>  #include <sys/selinfo.h>
>  #include <sys/signalvar.h>
> @@ -53,6 +54,7 @@ __FBSDID("$FreeBSD$");
>  #include <sys/bus.h>
>  #include <sys/interrupt.h>
>  
> +#include <machine/cpu.h>
>  #include <machine/stdarg.h>
>  
>  #include <vm/uma.h>
> @@ -2760,8 +2762,10 @@ device_probe_and_attach(device_t dev)
>  int
>  device_attach(device_t dev)
>  {
> +     uint64_t attachtime;
>       int error;
>  
> +     attachtime = get_cyclecount();
>       device_sysctl_init(dev);
>       if (!device_is_quiet(dev))
>               device_print_child(dev->parent, dev);
> @@ -2784,6 +2788,10 @@ device_attach(device_t dev)
>               dev->state = DS_ATTACHED;
>       dev->flags &= ~DF_DONENOMATCH;
>       devadded(dev);
> +     if (harvest.devprobe)
> +             random_harvest(&attachtime, sizeof(attachtime), 4, 0,
> +                 RANDOM_DEVICE);
> +
>       return (0);
>  }
>  
> Index: etc/defaults/rc.conf
> ===================================================================
> --- etc/defaults/rc.conf      (revision 239610)
> +++ etc/defaults/rc.conf      (working copy)
> @@ -642,6 +642,7 @@ entropy_file="/entropy"   # Set to NO to d
>  entropy_dir="/var/db/entropy" # Set to NO to disable caching entropy via 
> cron.
>  entropy_save_sz="2048"       # Size of the entropy cache files.
>  entropy_save_num="8" # Number of entropy cache files to save.
> +harvest_devprobe="YES"       # Entropy device harvests device probe 
> randomness
>  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
> Index: etc/rc.d/initrandom
> ===================================================================
> --- etc/rc.d/initrandom       (revision 239610)
> +++ etc/rc.d/initrandom       (working copy)
> @@ -41,6 +63,12 @@ initrandom_start()
>       if [ \! -z "${soft_random_generator}" ] ; then
>  
>               if [ -w /dev/random ]; then
> +                     if checkyesno harvest_devprobe; then
> +                             ${SYSCTL} kern.random.sys.harvest.devprobe=1 
> >/dev/null
> +                             echo -n ' interrupts'
> +                     else
> +                             ${SYSCTL} kern.random.sys.harvest.devprobe=0 
> >/dev/null
> +                     fi
>                       if checkyesno harvest_interrupt; then
>                               ${SYSCTL} kern.random.sys.harvest.interrupt=1 
> >/dev/null
>                               echo -n ' interrupts'

-- 
Pawel Jakub Dawidek                       http://www.wheelsystems.com
FreeBSD committer                         http://www.FreeBSD.org
Am I Evil? Yes, I Am!                     http://tupytaj.pl

Attachment: pgpmuBG9qeeDI.pgp
Description: PGP signature

Reply via email to