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