From b28953010e0b4d9208d7f9dcc8933e6d56f16ce3 Mon Sep 17 00:00:00 2001 From: markm Date: Fri, 4 Oct 2013 06:55:06 +0000 Subject: Snapshot. This passes the build test, but has not yet been finished or debugged. Contains: * Refactor the hardware RNG CPU instruction sources to feed into the software mixer. This is unfinished. The actual harvesting needs to be sorted out. Modified by me (see below). * Remove 'frac' parameter from random_harvest(). This was never used and adds extra code for no good reason. * Remove device write entropy harvesting. This provided a weak attack vector, was not very good at bootstrapping the device. To follow will be a replacement explicit reseed knob. * Separate out all the RANDOM_PURE sources into separate harvest entities. This adds some secuity in the case where more than one is present. * Review all the code and fix anything obviously messy or inconsistent. Address som review concerns while I'm here, like rename the pseudo-rng to 'dummy'. Submitted by: Arthur Mesh (the first item) --- sys/dev/random/randomdev.c | 78 +++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 50 deletions(-) (limited to 'sys/dev/random/randomdev.c') diff --git a/sys/dev/random/randomdev.c b/sys/dev/random/randomdev.c index 2d24dd5..990324e 100644 --- a/sys/dev/random/randomdev.c +++ b/sys/dev/random/randomdev.c @@ -1,6 +1,6 @@ /*- + * Copyright (c) 2000-2013 Mark R V Murray * Copyright (c) 2013 Arthur Mesh - * Copyright (c) 2000-2004 Mark R V Murray * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -52,11 +53,11 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #define RANDOM_MINOR 0 -static d_close_t random_close; static d_read_t random_read; static d_write_t random_write; static d_ioctl_t random_ioctl; @@ -64,7 +65,6 @@ static d_poll_t random_poll; static struct cdevsw random_cdevsw = { .d_version = D_VERSION, - .d_close = random_close, .d_read = random_read, .d_write = random_write, .d_ioctl = random_ioctl, @@ -72,34 +72,9 @@ static struct cdevsw random_cdevsw = { .d_name = "random", }; -static eventhandler_tag attach_tag; -static int random_inited; - /* For use with make_dev(9)/destroy_dev(9). */ static struct cdev *random_dev; -struct random_adaptor * -random_get_active_adaptor(void) -{ - - return (random_adaptor); -} - -/* ARGSUSED */ -static int -random_close(struct cdev *dev __unused, int flags, int fmt __unused, - struct thread *td) -{ - if ((flags & FWRITE) && (priv_check(td, PRIV_RANDOM_RESEED) == 0) - && (securelevel_gt(td->td_ucred, 0) == 0)) { - (*random_adaptor->reseed)(); - random_adaptor->seeded = 1; - arc4rand(NULL, 0, 1); /* Reseed arc4random as well. */ - } - - return (0); -} - /* ARGSUSED */ static int random_read(struct cdev *dev __unused, struct uio *uio, int flag) @@ -107,6 +82,10 @@ random_read(struct cdev *dev __unused, struct uio *uio, int flag) int c, error = 0; void *random_buf; + /* XXX: Harvest some entropy from live entropy sources, if available */ + live_entropy_sources_feed(65); /* 65 is meaningless -- + need to decide appropriate value */ + /* Blocking logic */ if (!random_adaptor->seeded) error = (*random_adaptor->block)(flag); @@ -121,6 +100,9 @@ random_read(struct cdev *dev __unused, struct uio *uio, int flag) c = (*random_adaptor->read)(random_buf, c); error = uiomove(random_buf, c, uio); } + /* Finished reading; let the source know so it can do some + * optional housekeeping */ + (*random_adaptor->read)(NULL, 0); free(random_buf, M_TEMP); @@ -133,22 +115,16 @@ random_read(struct cdev *dev __unused, struct uio *uio, int flag) static int random_write(struct cdev *dev __unused, struct uio *uio, int flag __unused) { - int c, error = 0; - void *random_buf; - - random_buf = (void *)malloc(PAGE_SIZE, M_TEMP, M_WAITOK); - - while (uio->uio_resid > 0) { - c = MIN((int)uio->uio_resid, PAGE_SIZE); - error = uiomove(random_buf, c, uio); - if (error) - break; - (*random_adaptor->write)(random_buf, c); - } - free(random_buf, M_TEMP); + /* We used to allow this to insert userland entropy. + * We don't any more because (1) this so-called entropy + * is usually lousy and (b) its vaguely possible to + * mess with entropy harvesting by overdoing a write. + * Now we just ignore input like /dev/null does. + */ + uio->uio_resid = 0; - return (error); + return (0); } /* ARGSUSED */ @@ -179,7 +155,7 @@ random_poll(struct cdev *dev __unused, int events, struct thread *td) if (random_adaptor->seeded) revents = events & (POLLIN | POLLRDNORM); else - revents = (*random_adaptor->poll) (events,td); + revents = (*random_adaptor->poll)(events, td); } return (revents); } @@ -187,6 +163,8 @@ random_poll(struct cdev *dev __unused, int events, struct thread *td) static void random_initialize(void *p, struct random_adaptor *s) { + static int random_inited = 0; + if (random_inited) { printf("random: <%s> already initialized\n", random_adaptor->ident); @@ -199,9 +177,10 @@ random_initialize(void *p, struct random_adaptor *s) printf("random: <%s> initialized\n", s->ident); + /* Use an appropriately evil mode for those who are concerned + * with daemons */ random_dev = make_dev_credf(MAKEDEV_ETERNAL_KLD, &random_cdevsw, RANDOM_MINOR, NULL, UID_ROOT, GID_WHEEL, 0666, "random"); - make_dev_alias(random_dev, "urandom"); /* XXX Deprecated */ /* mark random(4) as initialized, to avoid being called again */ random_inited = 1; @@ -211,6 +190,7 @@ random_initialize(void *p, struct random_adaptor *s) static int random_modevent(module_t mod __unused, int type, void *data __unused) { + static eventhandler_tag attach_tag = NULL; int error = 0; switch (type) { @@ -218,13 +198,12 @@ random_modevent(module_t mod __unused, int type, void *data __unused) random_adaptor_choose(&random_adaptor); if (random_adaptor == NULL) { - printf( - "random: No random adaptor attached, postponing initialization\n"); + printf("random: No random adaptor attached, " + "postponing initialization\n"); attach_tag = EVENTHANDLER_REGISTER(random_adaptor_attach, random_initialize, NULL, EVENTHANDLER_PRI_ANY); - } else { + } else random_initialize(NULL, random_adaptor); - } break; @@ -234,10 +213,9 @@ random_modevent(module_t mod __unused, int type, void *data __unused) destroy_dev(random_dev); } /* Unregister the event handler */ - if (attach_tag != NULL) { + if (attach_tag != NULL) EVENTHANDLER_DEREGISTER(random_adaptor_attach, attach_tag); - } break; -- cgit v1.1