Commit df309064 authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds

[PATCH] uml: "Hardware" random number generator

This implements a hardware random number generator for UML which attaches
itself to the host's /dev/random.
Signed-off-by: default avatarJeff Dike <jdike@addtoit.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent a98c04a3
...@@ -190,5 +190,19 @@ config HOSTAUDIO ...@@ -190,5 +190,19 @@ config HOSTAUDIO
tristate tristate
default UML_SOUND 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 endmenu
...@@ -111,6 +111,7 @@ CONFIG_LEGACY_PTY_COUNT=256 ...@@ -111,6 +111,7 @@ CONFIG_LEGACY_PTY_COUNT=256
CONFIG_UML_SOUND=m CONFIG_UML_SOUND=m
CONFIG_SOUND=m CONFIG_SOUND=m
CONFIG_HOSTAUDIO=m CONFIG_HOSTAUDIO=m
CONFIG_UML_RANDOM=y
# #
# Block devices # Block devices
......
...@@ -39,7 +39,7 @@ obj-$(CONFIG_TTY_CHAN) += tty.o ...@@ -39,7 +39,7 @@ obj-$(CONFIG_TTY_CHAN) += tty.o
obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
obj-$(CONFIG_UML_WATCHDOG) += harddog.o obj-$(CONFIG_UML_WATCHDOG) += harddog.o
obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.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)) USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
......
/* 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);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment