From c3e6a24425bc9986da0d0a5a8c92e0b9ed7f18fa Mon Sep 17 00:00:00 2001 From: "Srivatsa S. Bhat" <srivatsa@csail.mit.edu> Date: Thu, 28 Jun 2018 08:51:18 -0700 Subject: [PATCH] hwrng: rdrand - Add RNG driver based on x86 rdrand instruction Add a Hardware Random Number Generator driver, which uses the 'rdrand' instruction available on modern Intel and AMD CPUs. This can be used to feed the kernel's entropy pool on entropy-starved virtual machines. Signed-off-by: Srivatsa S. Bhat <srivatsa@csail.mit.edu> --- drivers/char/hw_random/Kconfig | 14 +++++++++ drivers/char/hw_random/Makefile | 1 + drivers/char/hw_random/rdrand-rng.c | 61 +++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 drivers/char/hw_random/rdrand-rng.c diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index dbf2271..b4e558d 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -62,6 +62,20 @@ config HW_RANDOM_AMD If unsure, say Y. +config HW_RANDOM_RDRAND + tristate "x86 rdrand Random Number Generator support" + depends on (X86_32 || X86_64) && ARCH_RANDOM + default HW_RANDOM + ---help--- + This driver provides kernel-side support for a Random Number + Generator that uses the 'rdrand' instruction on modern Intel + and AMD CPUs. + + To compile this driver as a module, choose M here: the + module will be called rdrand-rng. + + If unsure, say N. + config HW_RANDOM_ATMEL tristate "Atmel Random Number Generator support" depends on ARCH_AT91 && HAVE_CLK && OF diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index 5ad3976..c186ddb 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile @@ -7,6 +7,7 @@ rng-core-y := core.o obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += timeriomem-rng.o obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o +obj-$(CONFIG_HW_RANDOM_RDRAND) += rdrand-rng.o obj-$(CONFIG_HW_RANDOM_ATMEL) += atmel-rng.o obj-$(CONFIG_HW_RANDOM_BCM63XX) += bcm63xx-rng.o obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o diff --git a/drivers/char/hw_random/rdrand-rng.c b/drivers/char/hw_random/rdrand-rng.c new file mode 100644 index 0000000..e1cf7f3 --- /dev/null +++ b/drivers/char/hw_random/rdrand-rng.c @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * RNG driver that uses the 'rdrand' instruction (found on modern + * Intel and AMD CPUs). + * + * Author: Srivatsa S. Bhat <srivatsa@csail.mit.edu> + * + */ + +#include <linux/hw_random.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <asm/archrandom.h> + +#define PFX KBUILD_MODNAME ": " + +static int rdrand_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) +{ + unsigned long *data = buf; + size_t read = 0; + + while (read < max) { + arch_get_random_long(data); + data++; + read += sizeof(unsigned long); + } + + return read; +} + +static struct hwrng rdrand_rng = { + .name = KBUILD_MODNAME, + .quality = 1000, + .read = rdrand_rng_read, +}; + +static int __init mod_init(void) +{ + int err = -ENODEV; + + if (!arch_has_random()) + return err; /* rdrand not available. */ + + err = hwrng_register(&rdrand_rng); + if (err) + pr_err(PFX "RNG registration failed (%d)\n", err); + + return err; +} + +static void __exit mod_exit(void) +{ + hwrng_unregister(&rdrand_rng); +} + +module_init(mod_init); +module_exit(mod_exit); + +MODULE_AUTHOR("Srivatsa S. Bhat <srivatsa@csail.mit.edu>"); +MODULE_DESCRIPTION("H/W RNG driver for x86 CPUs that support rdrand"); +MODULE_LICENSE("GPL"); -- 2.7.4