summaryrefslogtreecommitdiffstats
path: root/sys/dev/random/randomdev.c
diff options
context:
space:
mode:
authormarkm <markm@FreeBSD.org>2013-10-04 06:55:06 +0000
committermarkm <markm@FreeBSD.org>2013-10-04 06:55:06 +0000
commitb28953010e0b4d9208d7f9dcc8933e6d56f16ce3 (patch)
treec4e072a0e767bef2275921e88362a12f29adf3c2 /sys/dev/random/randomdev.c
parent4655fd3ead80b03639e139ad19759e0307eb10df (diff)
downloadFreeBSD-src-b28953010e0b4d9208d7f9dcc8933e6d56f16ce3.zip
FreeBSD-src-b28953010e0b4d9208d7f9dcc8933e6d56f16ce3.tar.gz
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 <arthurmesh@gmail.com> (the first item)
Diffstat (limited to 'sys/dev/random/randomdev.c')
-rw-r--r--sys/dev/random/randomdev.c78
1 files changed, 28 insertions, 50 deletions
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 <arthurmesh@gmail.com>
- * 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 <sys/poll.h>
#include <sys/priv.h>
#include <sys/proc.h>
+#include <sys/random.h>
#include <sys/selinfo.h>
#include <sys/uio.h>
#include <sys/unistd.h>
@@ -52,11 +53,11 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
#include <dev/random/random_adaptors.h>
+#include <dev/random/live_entropy_sources.h>
#include <dev/random/randomdev.h>
#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;
OpenPOWER on IntegriCloud