This implements a hardware random number generator for UML which attaches
itself to the host's /dev/random.
Signed-off-by: Jeff Dike <[email protected]>
Index: linux-2.6.11/arch/um/Kconfig_char
===================================================================
--- linux-2.6.11.orig/arch/um/Kconfig_char 2005-03-08 20:13:55.000000000 -0500
+++ linux-2.6.11/arch/um/Kconfig_char 2005-03-08 20:22:24.000000000 -0500
@@ -190,5 +190,19 @@
tristate
default UML_SOUND
+config UML_RANDOM
+ tristate "Hardware random number generator"
+ help
+ This option enables UML's "hardware" random number generator. It
+ attaches itself to the host's /dev/random, supplying as much entropy
+ as the host has, rather than the small amount the UML gets from its
+ own drivers. It registers itself as a standard hardware random number
+ generator, major 10, minor 183, and the canonical device name is
+ /dev/hwrng.
+ The way to make use of this is to install the rng-tools package
+ (check your distro, or download from
+ http://sourceforge.net/projects/gkernel/). rngd periodically reads
+ /dev/hwrng and injects the entropy into /dev/random.
+
endmenu
Index: linux-2.6.11/arch/um/defconfig
===================================================================
--- linux-2.6.11.orig/arch/um/defconfig 2005-03-08 20:13:55.000000000 -0500
+++ linux-2.6.11/arch/um/defconfig 2005-03-08 20:22:24.000000000 -0500
@@ -111,6 +111,7 @@
CONFIG_UML_SOUND=m
CONFIG_SOUND=m
CONFIG_HOSTAUDIO=m
+CONFIG_UML_RANDOM=y
#
# Block devices
Index: linux-2.6.11/arch/um/drivers/Makefile
===================================================================
--- linux-2.6.11.orig/arch/um/drivers/Makefile 2005-03-08 20:17:34.000000000 -0500
+++ linux-2.6.11/arch/um/drivers/Makefile 2005-03-08 20:22:24.000000000 -0500
@@ -3,7 +3,7 @@
# Licensed under the GPL
#
-CHAN_OBJS := chan_kern.o chan_user.o line.o
+CHAN_OBJS := chan_kern.o chan_user.o line.o
# pcap is broken in 2.5 because kbuild doesn't allow pcap.a to be linked
# in to pcap.o
@@ -41,7 +41,7 @@
obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
obj-$(CONFIG_UML_WATCHDOG) += harddog.o
obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
-
+obj-$(CONFIG_UML_RANDOM) += random.o
USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
Index: linux-2.6.11/arch/um/drivers/random.c
===================================================================
--- linux-2.6.11.orig/arch/um/drivers/random.c 2003-09-15 09:40:47.000000000 -0400
+++ linux-2.6.11/arch/um/drivers/random.c 2005-03-08 20:22:24.000000000 -0500
@@ -0,0 +1,122 @@
+/* Much of this ripped from hw_random.c */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include "os.h"
+
+/*
+ * core module and version information
+ */
+#define RNG_VERSION "1.0.0"
+#define RNG_MODULE_NAME "random"
+#define RNG_DRIVER_NAME RNG_MODULE_NAME " virtual driver " RNG_VERSION
+#define PFX RNG_MODULE_NAME ": "
+
+#define RNG_MISCDEV_MINOR 183 /* official */
+
+static int random_fd = -1;
+
+static int rng_dev_open (struct inode *inode, struct file *filp)
+{
+ /* enforce read-only access to this chrdev */
+ if ((filp->f_mode & FMODE_READ) == 0)
+ return -EINVAL;
+ if (filp->f_mode & FMODE_WRITE)
+ return -EINVAL;
+
+ return 0;
+}
+
+static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
+ loff_t * offp)
+{
+ u32 data;
+ int n, ret = 0, have_data;
+
+ while(size){
+ n = os_read_file(random_fd, &data, sizeof(data));
+ if(n > 0){
+ have_data = n;
+ while (have_data && size) {
+ if (put_user((u8)data, buf++)) {
+ ret = ret ? : -EFAULT;
+ break;
+ }
+ size--;
+ ret++;
+ have_data--;
+ data>>=8;
+ }
+ }
+ else if(n == -EAGAIN){
+ if (filp->f_flags & O_NONBLOCK)
+ return ret ? : -EAGAIN;
+
+ if(need_resched()){
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(1);
+ }
+ }
+ else return n;
+ if (signal_pending (current))
+ return ret ? : -ERESTARTSYS;
+ }
+ return ret;
+}
+
+static struct file_operations rng_chrdev_ops = {
+ .owner = THIS_MODULE,
+ .open = rng_dev_open,
+ .read = rng_dev_read,
+};
+
+static struct miscdevice rng_miscdev = {
+ RNG_MISCDEV_MINOR,
+ RNG_MODULE_NAME,
+ &rng_chrdev_ops,
+};
+
+/*
+ * rng_init - initialize RNG module
+ */
+static int __init rng_init (void)
+{
+ int err;
+
+ err = os_open_file("/dev/random", of_read(OPENFLAGS()), 0);
+ if(err < 0)
+ goto out;
+
+ random_fd = err;
+
+ err = os_set_fd_block(random_fd, 0);
+ if(err)
+ goto err_out_cleanup_hw;
+
+ err = misc_register (&rng_miscdev);
+ if (err) {
+ printk (KERN_ERR PFX "misc device register failed\n");
+ goto err_out_cleanup_hw;
+ }
+
+ out:
+ return err;
+
+ err_out_cleanup_hw:
+ random_fd = -1;
+ goto out;
+}
+
+/*
+ * rng_cleanup - shutdown RNG module
+ */
+static void __exit rng_cleanup (void)
+{
+ misc_deregister (&rng_miscdev);
+}
+
+module_init (rng_init);
+module_exit (rng_cleanup);
On Wednesday 09 March 2005 09:15 pm, Jeff Dike wrote:
> This implements a hardware random number generator for UML which attaches
> itself to the host's /dev/random.
Direct use of /dev/random always makes me nervous. I've had a recurring
problem with /dev/random blocking, and generally configure as much as
possible to use /dev/urandom instead. It's really easy for a normal user to
drain the /dev/random entropy pool on a server (at least one that doesn't
have a sound card you can tell it to read white noise from). cat /dev/random
> /dev/null
I like /dev/urandom because it'll feed you as much entropy as it's got, but
won't block, and will presumably round-robin insert real entropy in the
streams that multiple users get from /dev/urandom. (I realize this may not
be the best place to get gpg keys from.)
I'm just thinking about those UML hosting farms, with several UML instances
per machine, on machines which haven't got a keyboard attached constantly
feeding entropy into the pool. If just ONE of them is serving ssl
connections from its own /dev/urandom, that would drain the /dev/random
entropy pool on the host machine almost immediately...
Admittedly if UML used /dev/urandom instead of /dev/random, it wouldn't know
how much "real" randomness it was getting and how much synthetic randomness,
but this makes predicting the numbers it's producing easier how?
Rob
[email protected] said:
> I'm just thinking about those UML hosting farms, with several UML
> instances per machine, on machines which haven't got a keyboard
> attached constantly feeding entropy into the pool. If just ONE of
> them is serving ssl connections from its own /dev/urandom, that would
> drain the /dev/random entropy pool on the host machine almost
> immediately...
All true (except for that last reference to urandom), but also irrelevant to
whether UML's hwrng should be hooked up to the host's /dev/random or not.
As far as I can see, the only thing that matters is that hwrng should produce
real randomness, and that can only be had by reading /dev/random (or maybe
the host's /dev/hwrng, but that's supposed to be fed into /dev/random anyway).
So, hooking up the UML /dev/hwrng to the host's /dev/urandom would be lying.
If the host's entropy pool gets drained as a result, I would say that's an
application bug, and not a reason for UML to get its randomness from the
host's /dev/urandom.
Jeff
On Thursday 10 March 2005 19:41, Rob Landley wrote:
> On Wednesday 09 March 2005 09:15 pm, Jeff Dike wrote:
> > This implements a hardware random number generator for UML which attaches
> > itself to the host's /dev/random.
>
> Direct use of /dev/random always makes me nervous. I've had a recurring
> problem with /dev/random blocking,
The fd is set in non-blocking mode on opening, so when there is no data UML
will not block but get -EAGAIN (which is then handled by waiting and
retrying).
> and generally configure as much as
> possible to use /dev/urandom instead. It's really easy for a normal user
> to drain the /dev/random entropy pool on a server (at least one that
> doesn't have a sound card you can tell it to read white noise from).
> cat /dev/random > /dev/null
> I like /dev/urandom because it'll feed you as much entropy as it's got,
Yes, and entropy will gradually degrade...
> but
> won't block, and will presumably round-robin insert real entropy in the
> streams that multiple users get from /dev/urandom. (I realize this may not
> be the best place to get gpg keys from.)
> Admittedly if UML used /dev/urandom instead of /dev/random, it wouldn't
> know how much "real" randomness it was getting and how much synthetic
> randomness, but this makes predicting the numbers it's producing easier
> how?
Don't ask us..., we just recycle the others knowledge... however in short when
you say that "randomness" (or entropy) is not the maximum, you mean that
there is some redundancy, i.e. some law to ease predicting subsequent
numbers. For instance some character is more frequent than another... And
this is also the same kind of things that is exploited during compression...
the more compressed are your data, the less entropy they have before
compression (I'm not an expert of Shannon information entropy theories,
however, but this is what I grasped).
--
Paolo Giarrusso, aka Blaisorblade
Linux registered user n. 292729
http://www.user-mode-linux.org/~blaisorblade
Jeff Dike wrote:
> [email protected] said:
>
>>I'm just thinking about those UML hosting farms, with several UML
>>instances per machine, on machines which haven't got a keyboard
>>attached constantly feeding entropy into the pool.
That's when you set the network links to feed entropy. It may not be
very good entropy, but it's probably better than nothing (especially in
a UML virtual-system instance, where the real NIC is handling traffic
for all hosted systems).
Chris
Rob Landley wrote:
> On Wednesday 09 March 2005 09:15 pm, Jeff Dike wrote:
>
>>This implements a hardware random number generator for UML which attaches
>>itself to the host's /dev/random.
>
>
> Direct use of /dev/random always makes me nervous. I've had a recurring
> problem with /dev/random blocking, and generally configure as much as
> possible to use /dev/urandom instead. It's really easy for a normal user to
> drain the /dev/random entropy pool on a server (at least one that doesn't
> have a sound card you can tell it to read white noise from). cat /dev/random
>
>>/dev/null
>
>
> I like /dev/urandom because it'll feed you as much entropy as it's got, but
> won't block, and will presumably round-robin insert real entropy in the
> streams that multiple users get from /dev/urandom. (I realize this may not
> be the best place to get gpg keys from.)
>
> I'm just thinking about those UML hosting farms, with several UML instances
> per machine, on machines which haven't got a keyboard attached constantly
> feeding entropy into the pool. If just ONE of them is serving ssl
> connections from its own /dev/urandom, that would drain the /dev/random
> entropy pool on the host machine almost immediately...
>
> Admittedly if UML used /dev/urandom instead of /dev/random, it wouldn't know
> how much "real" randomness it was getting and how much synthetic randomness,
> but this makes predicting the numbers it's producing easier how?
Use of a "hardware" RNG patch without a real hardware RNG could do all
that. I would add a caution to the help warning of this problem if you
lack real hardware RNG capability. The really paranoid could insist that
at least one hardware driver be configured, but how much do you need to
protect people from themselves?
--
-bill davidsen ([email protected])
"The secret to procrastination is to put things off until the
last possible moment - but no longer" -me