Collecting entropy from device_attach() times.

Pawel Jakub Dawidek pjd at FreeBSD.org
Fri Sep 21 05:35:31 UTC 2012


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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-security/attachments/20120921/ffab21b2/attachment.pgp


More information about the freebsd-security mailing list