Collecting entropy from device_attach() times.
David O'Brien
obrien at FreeBSD.org
Wed Sep 19 22:35:00 UTC 2012
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'
More information about the freebsd-security
mailing list