Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1385797 > unrolled thread

[PATCH v2 0/6] /dev/random - a new approach

Started byStephan Mueller <smueller@chronox.de>
First post2016-04-24 12:50 +0200
Last post2016-04-24 18:50 +0200
Articles 7 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v2 0/6] /dev/random - a new approach Stephan Mueller <smueller@chronox.de> - 2016-04-24 12:50 +0200
    [PATCH v2 4/6] crypto: LRNG - enable compile Stephan Mueller <smueller@chronox.de> - 2016-04-24 12:50 +0200
    [PATCH v2 6/6] hyperv IRQ handler: trigger LRNG Stephan Mueller <smueller@chronox.de> - 2016-04-24 12:50 +0200
    [PATCH v2 1/6] crypto: DRBG - externalize DRBG functions for LRNG Stephan Mueller <smueller@chronox.de> - 2016-04-24 12:50 +0200
    Re: [PATCH v2 3/6] crypto: Linux Random Number Generator Joe Perches <joe@perches.com> - 2016-04-24 13:40 +0200
      Re: [PATCH v2 3/6] crypto: Linux Random Number Generator Stephan Mueller <smueller@chronox.de> - 2016-04-24 16:20 +0200
        Re: [PATCH v2 3/6] crypto: Linux Random Number Generator Joe Perches <joe@perches.com> - 2016-04-24 18:50 +0200

#1385797 — [PATCH v2 0/6] /dev/random - a new approach

FromStephan Mueller <smueller@chronox.de>
Date2016-04-24 12:50 +0200
Subject[PATCH v2 0/6] /dev/random - a new approach
Message-ID<rrpLY-31I-5@gated-at.bofh.it>
Hi Herbert, Ted,

The following patch set provides a different approach to /dev/random which
I call Linux Random Number Generator (LRNG) to collect entropy within the Linux
kernel. The main improvements compared to the legacy /dev/random is to provide
sufficient entropy during boot time as well as in virtual environments and when
using SSDs. A secondary design goal is to limit the impact of the entropy
collection on massive parallel systems and also allow the use accelerated
cryptographic primitives. Also, all steps of the entropic data processing are
testable. Finally massive performance improvements are visible at /dev/urandom
and get_random_bytes.

The design and implementation is driven by a set of goals described in [1]
that the LRNG completely implements. Furthermore, [1] includes a
comparison with RNG design suggestions such as SP800-90B, SP800-90C, and
AIS20/31.

Changes v2:
* Removal of the Jitter RNG fast noise source as requested by Ted
* Addition of processing of add_input_randomness as suggested by Ted
* Update documentation and testing in [1] to cover the updates
* Addition of a SystemTap script to test add_input_randomness
* To clarify the question whether sufficient entropy is present during boot
  I added one more test in 3.3.1 [1] which demonstrates the providing of
  sufficient entropy during initialization. In the worst case of no fast noise
  sources, in the worst case of a virtual machine with only very few hardware
  devices, the testing shows that the secondary DRBG is fully seeded with 256
  bits of entropy before user space injects the random data obtained
  during shutdown of the previous boot (i.e. the requirement phrased by the
  legacy /dev/random implementation). As the writing of the random data into
  /dev/random by user space will happen before any cryptographic service
  is initialized in user space, this test demonstrates that sufficient
  entropy is already present in the LRNG at the time user space requires it
  for seeding cryptographic daemons. Note, this test result was obtained
  for different architectures, such as x86 64 bit, x86 32 bit, ARM 32 bit and
  MIPS 32 bit.

[1] http://www.chronox.de/lrng/doc/lrng.pdf

[2] http://www.chronox.de/lrng.html

Stephan Mueller (6):
  crypto: DRBG - externalize DRBG functions for LRNG
  random: conditionally compile code depending on LRNG
  crypto: Linux Random Number Generator
  crypto: LRNG - enable compile
  crypto: LRNG - hook LRNG into interrupt handler
  hyperv IRQ handler: trigger LRNG

 crypto/Kconfig         |   10 +
 crypto/Makefile        |    1 +
 crypto/drbg.c          |   11 +-
 crypto/lrng.c          | 1743 ++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/char/random.c  |    8 +
 drivers/hv/vmbus_drv.c |    3 +
 include/crypto/drbg.h  |    7 +
 include/linux/genhd.h  |    5 +
 include/linux/random.h |    9 +-
 kernel/irq/handle.c    |    1 +
 10 files changed, 1791 insertions(+), 7 deletions(-)
 create mode 100644 crypto/lrng.c

-- 
2.5.5

[toc] | [next] | [standalone]


#1385798 — [PATCH v2 4/6] crypto: LRNG - enable compile

FromStephan Mueller <smueller@chronox.de>
Date2016-04-24 12:50 +0200
Subject[PATCH v2 4/6] crypto: LRNG - enable compile
Message-ID<rrpLY-31I-17@gated-at.bofh.it>
In reply to#1385797
Add LRNG compilation support.

Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
 crypto/Kconfig  | 10 ++++++++++
 crypto/Makefile |  1 +
 2 files changed, 11 insertions(+)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 93a1fdc..938f2dc 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -1587,6 +1587,16 @@ config CRYPTO_JITTERENTROPY
 	  random numbers. This Jitterentropy RNG registers with
 	  the kernel crypto API and can be used by any caller.
 
+config CRYPTO_LRNG
+	bool "Linux Random Number Generator"
+	select CRYPTO_DRBG_MENU
+	help
+	  The Linux Random Number Generator (LRNG) is the replacement
+	  of the legacy /dev/random provided with drivers/char/random.c.
+	  It generates entropy from different noise sources and
+	  delivers significant entropy during boot. The LRNG only
+	  works with the presence of a high-resolution timer.
+
 config CRYPTO_USER_API
 	tristate
 
diff --git a/crypto/Makefile b/crypto/Makefile
index 4f4ef7e..7f91c8e 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -114,6 +114,7 @@ obj-$(CONFIG_CRYPTO_DRBG) += drbg.o
 obj-$(CONFIG_CRYPTO_JITTERENTROPY) += jitterentropy_rng.o
 CFLAGS_jitterentropy.o = -O0
 jitterentropy_rng-y := jitterentropy.o jitterentropy-kcapi.o
+obj-$(CONFIG_CRYPTO_LRNG) += lrng.o
 obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
 obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o
 obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1385799 — [PATCH v2 6/6] hyperv IRQ handler: trigger LRNG

FromStephan Mueller <smueller@chronox.de>
Date2016-04-24 12:50 +0200
Subject[PATCH v2 6/6] hyperv IRQ handler: trigger LRNG
Message-ID<rrpLY-31I-21@gated-at.bofh.it>
In reply to#1385797
The Hyper-V Linux Integration Services use the VMBus implementation for
communication with the Hypervisor. VMBus registers its own interrupt
handler that completely bypasses the common Linux interrupt handling.

The interrupt handler is now added the invocation of the LRNG IRQ
collection function to also benefit from entropy under Hyper-V.

If the implementation of the VMBus and its subordinate drivers is
changed such that they resemble the Xen implementation where the
received IRQs are forwarded to the standard Linux interrupt handling
logic, this patch should be dropped.

Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
 drivers/hv/vmbus_drv.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 64713ff..afa2de0 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -41,6 +41,7 @@
 #include <linux/ptrace.h>
 #include <linux/screen_info.h>
 #include <linux/kdebug.h>
+#include <linux/random.h>
 #include "hyperv_vmbus.h"
 
 static struct acpi_device  *hv_acpi_dev;
@@ -801,6 +802,8 @@ static void vmbus_isr(void)
 		else
 			tasklet_schedule(hv_context.msg_dpc[cpu]);
 	}
+
+	lrng_irq_process();
 }
 
 
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1385800 — [PATCH v2 1/6] crypto: DRBG - externalize DRBG functions for LRNG

FromStephan Mueller <smueller@chronox.de>
Date2016-04-24 12:50 +0200
Subject[PATCH v2 1/6] crypto: DRBG - externalize DRBG functions for LRNG
Message-ID<rrpLY-31I-19@gated-at.bofh.it>
In reply to#1385797
This patch allows several DRBG functions to be called by the LRNG kernel
code paths outside the drbg.c file.

Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
 crypto/drbg.c         | 11 +++++------
 include/crypto/drbg.h |  7 +++++++
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index 0a3538f..c339a2e 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -113,7 +113,7 @@
  * the SHA256 / AES 256 over other ciphers. Thus, the favored
  * DRBGs are the latest entries in this array.
  */
-static const struct drbg_core drbg_cores[] = {
+struct drbg_core drbg_cores[] = {
 #ifdef CONFIG_CRYPTO_DRBG_CTR
 	{
 		.flags = DRBG_CTR | DRBG_STRENGTH128,
@@ -205,7 +205,7 @@ static int drbg_uninstantiate(struct drbg_state *drbg);
  * Return: normalized strength in *bytes* value or 32 as default
  *	   to counter programming errors
  */
-static inline unsigned short drbg_sec_strength(drbg_flag_t flags)
+unsigned short drbg_sec_strength(drbg_flag_t flags)
 {
 	switch (flags & DRBG_STRENGTH_MASK) {
 	case DRBG_STRENGTH128:
@@ -1140,7 +1140,7 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
 }
 
 /* Free all substructures in a DRBG state without the DRBG state structure */
-static inline void drbg_dealloc_state(struct drbg_state *drbg)
+void drbg_dealloc_state(struct drbg_state *drbg)
 {
 	if (!drbg)
 		return;
@@ -1159,7 +1159,7 @@ static inline void drbg_dealloc_state(struct drbg_state *drbg)
  * Allocate all sub-structures for a DRBG state.
  * The DRBG state structure must already be allocated.
  */
-static inline int drbg_alloc_state(struct drbg_state *drbg)
+int drbg_alloc_state(struct drbg_state *drbg)
 {
 	int ret = -ENOMEM;
 	unsigned int sb_size = 0;
@@ -1682,8 +1682,7 @@ static int drbg_kcapi_sym(struct drbg_state *drbg, const unsigned char *key,
  *
  * return: flags
  */
-static inline void drbg_convert_tfm_core(const char *cra_driver_name,
-					 int *coreref, bool *pr)
+void drbg_convert_tfm_core(const char *cra_driver_name, int *coreref, bool *pr)
 {
 	int i = 0;
 	size_t start = 0;
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index d961b2b..d24ec22 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -268,4 +268,11 @@ enum drbg_prefixes {
 	DRBG_PREFIX3
 };
 
+extern int drbg_alloc_state(struct drbg_state *drbg);
+extern void drbg_dealloc_state(struct drbg_state *drbg);
+extern void drbg_convert_tfm_core(const char *cra_driver_name, int *coreref,
+				  bool *pr);
+extern struct drbg_core drbg_cores[];
+extern unsigned short drbg_sec_strength(drbg_flag_t flags);
+
 #endif /* _DRBG_H */
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1385808 — Re: [PATCH v2 3/6] crypto: Linux Random Number Generator

FromJoe Perches <joe@perches.com>
Date2016-04-24 13:40 +0200
SubjectRe: [PATCH v2 3/6] crypto: Linux Random Number Generator
Message-ID<rrqyl-3EV-5@gated-at.bofh.it>
In reply to#1385797
On Sun, 2016-04-24 at 12:40 +0200, Stephan Mueller wrote:
> The LRNG with all its properties is documented in [1]. This
> documentation covers the functional discussion as well as testing of all
> aspects of entropy processing. In addition, the documentation explains
> the conducted regression tests to verify that the LRNG is API and ABI
> compatible with the legacy /dev/random implementation.
> 
> [1] http://www.chronox.de/lrng.html

Thanks.

Links get stale.

It may be better to put an ascii version of the pdf
in Documentation/ and the test code in tools/

and some trivial notes:

> diff --git a/crypto/lrng.c b/crypto/lrng.c
[]
> +/* debug macro */
> +#define DRIVER_NAME "lrng"

Using
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
before any #include would be a lot more common.

> +#if 0
> +#define dbg(fmt, ...) pr_info(DRIVER_NAME": " fmt, ##__VA_ARGS__)
> +#else
> +#define dbg(fmt, ...)
> +#endif

pr_debug or is there some interaction with
dynamic_debug you want to avoid?

And it's generally better to use something like

#if 0
#define dbg(fmt, ...) pr_info(fmt, ##__VA_ARGS__)
#else
#define dbg(fmt, ...) no_printk(fmt, ##__VA_ARGS__)

so that new dbg statements would not have
format/argument mismatches and argument
evaluation side-effects are still eliminated.

> +static void lrng_pdrbg_init_ops(u32 entropy_bits)
> +{
> +	if (lrng_pdrbg.pdrbg_fully_seeded)
> +		return;
> +
> +	BUILD_BUG_ON(LRNG_IRQ_MIN_NUM % LRNG_POOL_WORD_BITS);
> +	BUILD_BUG_ON((LRNG_MIN_SEED_ENTROPY_BITS * LRNG_IRQ_ENTROPY_BITS /
> +		     LRNG_DRBG_SECURITY_STRENGTH_BITS) > LRNG_IRQ_MIN_NUM);
> +
> +	/* DRBG is seeded with full security strength */
> +	if (entropy_bits >= LRNG_DRBG_SECURITY_STRENGTH_BITS) {
> +		lrng_pdrbg.pdrbg_fully_seeded = true;
> +		lrng_pdrbg.pdrbg_min_seeded = true;
> +		pr_info(DRIVER_NAME": primary DRBG fully seeded\n");

Using pr_fmt eliminates the need for these
DRIVER_NAME ": " prefix inclusions in the format
> +static int __init lrng_init(void)
> +{
[]
> +	pr_info(DRIVER_NAME": deactivating initial RNG - %d bytes delivered",
> +		atomic_read(&lrng_initrng_bytes));

Should use \n to terminate the format.

[toc] | [prev] | [next] | [standalone]


#1385817 — Re: [PATCH v2 3/6] crypto: Linux Random Number Generator

FromStephan Mueller <smueller@chronox.de>
Date2016-04-24 16:20 +0200
SubjectRe: [PATCH v2 3/6] crypto: Linux Random Number Generator
Message-ID<rrt3b-5YK-1@gated-at.bofh.it>
In reply to#1385808
Am Sonntag, 24. April 2016, 04:30:24 schrieb Joe Perches:

Hi Joe,

thank you very much for your comments.

> On Sun, 2016-04-24 at 12:40 +0200, Stephan Mueller wrote:
> > The LRNG with all its properties is documented in [1]. This
> > documentation covers the functional discussion as well as testing of all
> > aspects of entropy processing. In addition, the documentation explains
> > the conducted regression tests to verify that the LRNG is API and ABI
> > compatible with the legacy /dev/random implementation.
> > 
> > [1] http://www.chronox.de/lrng.html
> 
> Thanks.
> 
> Links get stale.
> 
> It may be better to put an ascii version of the pdf
> in Documentation/ and the test code in tools/

I surely can do that. What would you think would be the proper location to add 
such documentation? Simply Documentation/lrng.txt?

How would you propose to handle the pictures (at least the big picture)?

Regarding the tests: those are no regression tests, but tests to allow other 
researches to verify whether the LRNG operates appropriately. Thus, would 
adding it to a new directory of tools/crypto/rng be appropriate?
> 
> and some trivial notes:
> > diff --git a/crypto/lrng.c b/crypto/lrng.c
> 
> []
> 
> > +/* debug macro */
> > +#define DRIVER_NAME "lrng"
> 
> Using
> #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> before any #include would be a lot more common.

Fixed
> 
> > +#if 0
> > +#define dbg(fmt, ...) pr_info(DRIVER_NAME": " fmt, ##__VA_ARGS__)
> > +#else
> > +#define dbg(fmt, ...)
> > +#endif
> 
> pr_debug or is there some interaction with
> dynamic_debug you want to avoid?
> 
> And it's generally better to use something like
> 
> #if 0
> #define dbg(fmt, ...) pr_info(fmt, ##__VA_ARGS__)
> #else
> #define dbg(fmt, ...) no_printk(fmt, ##__VA_ARGS__)
> 
> so that new dbg statements would not have
> format/argument mismatches and argument
> evaluation side-effects are still eliminated.

Fixed: I have replaced all invocations with pr_debug.
> 
> > +static void lrng_pdrbg_init_ops(u32 entropy_bits)
> > +{
> > +	if (lrng_pdrbg.pdrbg_fully_seeded)
> > +		return;
> > +
> > +	BUILD_BUG_ON(LRNG_IRQ_MIN_NUM % LRNG_POOL_WORD_BITS);
> > +	BUILD_BUG_ON((LRNG_MIN_SEED_ENTROPY_BITS * LRNG_IRQ_ENTROPY_BITS /
> > +		     LRNG_DRBG_SECURITY_STRENGTH_BITS) > LRNG_IRQ_MIN_NUM);
> > +
> > +	/* DRBG is seeded with full security strength */
> > +	if (entropy_bits >= LRNG_DRBG_SECURITY_STRENGTH_BITS) {
> > +		lrng_pdrbg.pdrbg_fully_seeded = true;
> > +		lrng_pdrbg.pdrbg_min_seeded = true;
> > +		pr_info(DRIVER_NAME": primary DRBG fully seeded\n");
> 
> Using pr_fmt eliminates the need for these
> DRIVER_NAME ": " prefix inclusions in the format

All occurrences corrected.
> 
> > +static int __init lrng_init(void)
> > +{
> 
> []
> 
> > +	pr_info(DRIVER_NAME": deactivating initial RNG - %d bytes delivered",
> > +		atomic_read(&lrng_initrng_bytes));
> 
> Should use \n to terminate the format.

Thank you, fixed. Though, I am wondering why I do see the line feed in dmesg. 
Whatever, it is fixed.

I have cover the fixes in my code. I will wait for more comments and release 
these changes in a couple of days.

Thanks a lot.


Ciao
Stephan

[toc] | [prev] | [next] | [standalone]


#1385838 — Re: [PATCH v2 3/6] crypto: Linux Random Number Generator

FromJoe Perches <joe@perches.com>
Date2016-04-24 18:50 +0200
SubjectRe: [PATCH v2 3/6] crypto: Linux Random Number Generator
Message-ID<rrvol-7Fr-11@gated-at.bofh.it>
In reply to#1385817
On Sun, 2016-04-24 at 16:12 +0200, Stephan Mueller wrote:
> Am Sonntag, 24. April 2016, 04:30:24 schrieb Joe Perches:
> > On Sun, 2016-04-24 at 12:40 +0200, Stephan Mueller wrote:
> > > The LRNG with all its properties is documented in [1]. This
> > > documentation covers the functional discussion as well as testing of all
> > > aspects of entropy processing. In addition, the documentation explains
> > > the conducted regression tests to verify that the LRNG is API and ABI
> > > compatible with the legacy /dev/random implementation.
> > > [1] http://www.chronox.de/lrng.html
> > Links get stale.
> > It may be better to put an ascii version of the pdf
> > in Documentation/ and the test code in tools/
> I surely can do that. What would you think would be the proper location to add 
> such documentation? Simply Documentation/lrng.txt?
> 
> How would you propose to handle the pictures (at least the big picture)?

I think figure 2.1 could look ok using something like asciio.
http://search.cpan.org/dist/App-Asciio/lib/App/Asciio.pm

> Regarding the tests: those are no regression tests, but tests to allow other 
> researches to verify whether the LRNG operates appropriately. Thus, would 
> adding it to a new directory of tools/crypto/rng be appropriate?

Whatever you think best would be fine with me.

> > > +	pr_info(DRIVER_NAME": deactivating initial RNG - %d bytes delivered",
> > > +		atomic_read(&lrng_initrng_bytes));
> > Should use \n to terminate the format.
> Thank you, fixed. Though, I am wondering why I do see the line feed in dmesg. 

The kernel will add a newline to dmesg output whenever a new
KERN_<LEVEL> is used, but there can be unprefixed content or
KERN_CONT uses from another thread before another message
that can unintentionally extend an old message without a
newline termination.

cheers, Joe

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web