Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Sep 2012 15:34:59 -0700
From:      David O'Brien <obrien@FreeBSD.org>
To:        Pawel Jakub Dawidek <pjd@FreeBSD.org>
Cc:        freebsd-security@FreeBSD.org
Subject:   Re: Collecting entropy from device_attach() times.
Message-ID:  <20120919223459.GC25606@dragon.NUXI.org>
In-Reply-To: <20120918211422.GA1400@garage.freebsd.pl>
References:  <20120918211422.GA1400@garage.freebsd.pl>

next in thread | previous in thread | raw e-mail | index | archive | help
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:

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'



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120919223459.GC25606>