[PATCH v38 03/13] LRNG - sysctls and /proc interface

2021-02-27 Thread Stephan Müller
The LRNG sysctl interface provides the same controls as the existing
/dev/random implementation. These sysctls behave identically and are
implemented identically. The goal is to allow a possible merge of the
existing /dev/random implementation with this implementation which
implies that this patch tries have a very close similarity. Yet, all
sysctls are documented at [1].

In addition, it provides the file lrng_type which provides details about
the LRNG:

- the name of the DRNG that produces the random numbers for /dev/random,
/dev/urandom, getrandom(2)

- the hash used to produce random numbers from the entropy pool

- the number of secondary DRNG instances

- indicator whether the LRNG operates SP800-90B compliant

- indicator whether a high-resolution timer is identified - only with a
high-resolution timer the interrupt noise source will deliver sufficient
entropy

- indicator whether the LRNG has been minimally seeded (i.e. is the
secondary DRNG seeded with at least 128 bits of of entropy)

- indicator whether the LRNG has been fully seeded (i.e. is the
secondary DRNG seeded with at least 256 bits of entropy)

[1] https://www.chronox.de/lrng.html

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Makefile  |   1 +
 drivers/char/lrng/lrng_interfaces.c |   2 -
 drivers/char/lrng/lrng_internal.h   |   4 +
 drivers/char/lrng/lrng_proc.c   | 184 
 4 files changed, 189 insertions(+), 2 deletions(-)
 create mode 100644 drivers/char/lrng/lrng_proc.c

diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 29724c65287d..ac97f0b11cb7 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -9,3 +9,4 @@ obj-y   += lrng_pool.o lrng_aux.o \
   lrng_interfaces.o
 
 obj-$(CONFIG_NUMA) += lrng_numa.o
+obj-$(CONFIG_SYSCTL)   += lrng_proc.o
diff --git a/drivers/char/lrng/lrng_interfaces.c 
b/drivers/char/lrng/lrng_interfaces.c
index efcadcfa79f2..8121ba495844 100644
--- a/drivers/char/lrng/lrng_interfaces.c
+++ b/drivers/char/lrng/lrng_interfaces.c
@@ -38,8 +38,6 @@ static DECLARE_WAIT_QUEUE_HEAD(lrng_write_wait);
 static DECLARE_WAIT_QUEUE_HEAD(lrng_init_wait);
 static struct fasync_struct *fasync;
 
-struct ctl_table random_table[];
-
 /** Helper ***/
 
 /* Is the DRNG seed level too low? */
diff --git a/drivers/char/lrng/lrng_internal.h 
b/drivers/char/lrng/lrng_internal.h
index 1bfb3710c767..0a9af852a8fe 100644
--- a/drivers/char/lrng/lrng_internal.h
+++ b/drivers/char/lrng/lrng_internal.h
@@ -108,7 +108,11 @@ void lrng_cc20_init_state_boot(struct chacha20_state 
*state);
 
 /** /proc 
*/
 
+#ifdef CONFIG_SYSCTL
+void lrng_pool_inc_numa_node(void);
+#else
 static inline void lrng_pool_inc_numa_node(void) { }
+#endif
 
 /** LRNG interfaces 
***/
 
diff --git a/drivers/char/lrng/lrng_proc.c b/drivers/char/lrng/lrng_proc.c
new file mode 100644
index ..244681679b39
--- /dev/null
+++ b/drivers/char/lrng/lrng_proc.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG proc and sysctl interfaces
+ *
+ * Copyright (C) 2016 - 2021, Stephan Mueller 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "lrng_internal.h"
+#include "lrng_sw_noise.h"
+
+/*
+ * This function is used to return both the bootid UUID, and random
+ * UUID.  The difference is in whether table->data is NULL; if it is,
+ * then a new UUID is generated and returned to the user.
+ *
+ * If the user accesses this via the proc interface, the UUID will be
+ * returned as an ASCII string in the standard UUID format; if via the
+ * sysctl system call, as 16 bytes of binary data.
+ */
+static int lrng_proc_do_uuid(struct ctl_table *table, int write,
+void *buffer, size_t *lenp, loff_t *ppos)
+{
+   struct ctl_table fake_table;
+   unsigned char buf[64], tmp_uuid[16], *uuid;
+
+   uuid = table->data;
+   if (!uuid) {
+   uuid = tmp_uuid;
+   generate_random_uuid(uuid);
+   } else {
+   static DEFINE_SPINLOCK(bootid_spinlock);
+
+   spin_lock(_spinlock);
+   if (!uuid[8])
+   generate_random_uuid(uuid);
+   

[PATCH v38 06/13] crypto: DRBG - externalize DRBG functions for LRNG

2021-02-27 Thread Stephan Müller
This patch allows several DRBG functions to be called by the LRNG kernel
code paths outside the drbg.c file.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 crypto/drbg.c | 16 ++--
 include/crypto/drbg.h |  7 +++
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index 3132967a1749..58b1de903def 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[] = {
+const struct drbg_core drbg_cores[] = {
 #ifdef CONFIG_CRYPTO_DRBG_CTR
{
.flags = DRBG_CTR | DRBG_STRENGTH128,
@@ -190,6 +190,7 @@ static const struct drbg_core drbg_cores[] = {
},
 #endif /* CONFIG_CRYPTO_DRBG_HMAC */
 };
+EXPORT_SYMBOL(drbg_cores);
 
 static int drbg_uninstantiate(struct drbg_state *drbg);
 
@@ -205,7 +206,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:
@@ -218,6 +219,7 @@ static inline unsigned short drbg_sec_strength(drbg_flag_t 
flags)
return 32;
}
 }
+EXPORT_SYMBOL(drbg_sec_strength);
 
 /*
  * FIPS 140-2 continuous self test for the noise source
@@ -1214,7 +1216,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;
@@ -1235,12 +1237,13 @@ static inline void drbg_dealloc_state(struct drbg_state 
*drbg)
drbg->fips_primed = false;
}
 }
+EXPORT_SYMBOL(drbg_dealloc_state);
 
 /*
  * 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;
@@ -1321,6 +1324,7 @@ static inline int drbg_alloc_state(struct drbg_state 
*drbg)
drbg_dealloc_state(drbg);
return ret;
 }
+EXPORT_SYMBOL(drbg_alloc_state);
 
 /*
  * DRBG interface functions
@@ -1890,8 +1894,7 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
  *
  * 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;
@@ -1918,6 +1921,7 @@ static inline void drbg_convert_tfm_core(const char 
*cra_driver_name,
}
}
 }
+EXPORT_SYMBOL(drbg_convert_tfm_core);
 
 static int drbg_kcapi_init(struct crypto_tfm *tfm)
 {
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index c4165126937e..71d53e028e6d 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -278,4 +278,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 const struct drbg_core drbg_cores[];
+extern unsigned short drbg_sec_strength(drbg_flag_t flags);
+
 #endif /* _DRBG_H */
-- 
2.29.2






[PATCH v38 09/13] crypto: provide access to a static Jitter RNG state

2021-02-27 Thread Stephan Müller
To support the LRNG operation which uses the Jitter RNG separately
from the kernel crypto API, at a time where potentially the regular
memory management is not yet initialized, the Jitter RNG needs to
provide a state whose memory is defined at compile time. As only once
instance will ever be needed by the LRNG, define once static memory
block which is solely to be used by the LRNG.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 crypto/jitterentropy-kcapi.c  |  3 +-
 crypto/jitterentropy.c| 31 ++-
 .../crypto/internal}/jitterentropy.h  |  3 ++
 3 files changed, 34 insertions(+), 3 deletions(-)
 rename {crypto => include/crypto/internal}/jitterentropy.h (84%)

diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c
index e8a4165a1874..c90e60910827 100644
--- a/crypto/jitterentropy-kcapi.c
+++ b/crypto/jitterentropy-kcapi.c
@@ -43,8 +43,7 @@
 #include 
 #include 
 #include 
-
-#include "jitterentropy.h"
+#include 
 
 /***
  * Helper function
diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c
index 6e147c43fc18..fa1459f09b01 100644
--- a/crypto/jitterentropy.c
+++ b/crypto/jitterentropy.c
@@ -117,7 +117,7 @@ struct rand_data {
 #define JENT_EHEALTH   9 /* Health test failed during initialization */
 #define JENT_ERCT  10 /* RCT failed during initialization */
 
-#include "jitterentropy.h"
+#include 
 
 /***
  * Adaptive Proportion Test
@@ -854,3 +854,32 @@ int jent_entropy_init(void)
 
return 0;
 }
+
+struct rand_data *jent_lrng_entropy_collector(void)
+{
+   static unsigned char lrng_jent_mem[JENT_MEMORY_SIZE];
+   static struct rand_data lrng_jent_state = {
+   .data   = 0,
+   .old_data   = 0,
+   .prev_time  = 0,
+   .last_delta = 0,
+   .last_delta2= 0,
+   .osr= 1,
+   .mem= lrng_jent_mem,
+   .memlocation= 0,
+   .memblocks  = JENT_MEMORY_BLOCKSIZE,
+   .memblocksize   = JENT_MEMORY_BLOCKS,
+   .memaccessloops = JENT_MEMORY_ACCESSLOOPS,
+   .rct_count  = 0,
+   .apt_observations = 0,
+   .apt_count  = 0,
+   .apt_base   = 0,
+   .apt_base_set   = 0,
+   .health_failure = 0
+   };
+
+   if (jent_entropy_init())
+   return NULL;
+
+   return _jent_state;
+}
diff --git a/crypto/jitterentropy.h b/include/crypto/internal/jitterentropy.h
similarity index 84%
rename from crypto/jitterentropy.h
rename to include/crypto/internal/jitterentropy.h
index c83fff32d130..6e07d86eac82 100644
--- a/crypto/jitterentropy.h
+++ b/include/crypto/internal/jitterentropy.h
@@ -15,3 +15,6 @@ extern int jent_read_entropy(struct rand_data *ec, unsigned 
char *data,
 extern struct rand_data *jent_entropy_collector_alloc(unsigned int osr,
  unsigned int flags);
 extern void jent_entropy_collector_free(struct rand_data *entropy_collector);
+
+/* Access to statically allocated Jitter RNG instance */
+extern struct rand_data *jent_lrng_entropy_collector(void);
-- 
2.29.2






[PATCH v38 12/13] LRNG - add interface for gathering of raw entropy

2021-02-27 Thread Stephan Müller
The test interface allows a privileged process to capture the raw
unconditioned noise that is collected by the LRNG for statistical
analysis. Such testing allows the analysis how much entropy
the interrupt noise source provides on a given platform.
Extracted noise data is not used to seed the LRNG. This
is a test interface and not appropriate for production systems.
Yet, the interface is considered to be sufficiently secured for
production systems.

Access to the data is given through the lrng_raw debugfs file. The
data buffer should be multiples of sizeof(u32) to fill the entire
buffer. Using the option lrng_testing.boot_test=1 the raw noise of
the first 1000 entropy events since boot can be sampled.

This test interface allows generating the data required for
analysis whether the LRNG is in compliance with SP800-90B
sections 3.1.3 and 3.1.4.

In addition, the test interface allows gathering of the concatenated raw
entropy data to verify that the concatenation works appropriately.
This includes sampling of the following raw data:

* high-resolution time stamp

* Jiffies

* IRQ number

* IRQ flags

* return instruction pointer

* interrupt register state

* array logic batching the high-resolution time stamp

Also, a testing interface to support ACVT of the hash implementation
is provided. The reason why only hash testing is supported (as
opposed to also provide testing for the DRNG) is the fact that the
LRNG software hash implementation contains glue code that may
warrant testing in addition to the testing of the software ciphers
via the kernel crypto API. Also, for testing the CTR-DRBG, the
underlying AES implementation would need to be tested. However,
such AES test interface cannot be provided by the LRNG as it has no
means to access the AES operation.

Finally, the execution duration for processing a time stamp can be
obtained with the LRNG raw entropy interface.

If a test interface is not compiled, its code is a noop which has no
impact on the performance.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig| 150 +++
 drivers/char/lrng/Makefile   |   1 +
 drivers/char/lrng/lrng_testing.c | 689 +++
 3 files changed, 840 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_testing.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index 743f717d6c19..3e57068ccdff 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -224,4 +224,154 @@ config LRNG_APT_CUTOFF
default 325 if !LRNG_APT_BROKEN
default 32 if LRNG_APT_BROKEN
 
+menuconfig LRNG_TESTING_MENU
+   bool "LRNG testing interfaces"
+   depends on DEBUG_FS
+   help
+ Enable one or more of the following test interfaces.
+
+ If unsure, say N.
+
+if LRNG_TESTING_MENU
+
+config LRNG_RAW_HIRES_ENTROPY
+   bool "Enable entropy test interface to hires timer noise source"
+   default y
+   help
+ The test interface allows a privileged process to capture
+ the raw unconditioned high resolution time stamp noise that
+ is collected by the LRNG for statistical analysis. Extracted
+ noise data is not used to seed the LRNG.
+
+ The raw noise data can be obtained using the lrng_raw_hires
+ debugfs file. Using the option lrng_testing.boot_raw_hires_test=1
+ the raw noise of the first 1000 entropy events since boot
+ can be sampled.
+
+config LRNG_RAW_JIFFIES_ENTROPY
+   bool "Enable entropy test interface to Jiffies noise source"
+   help
+ The test interface allows a privileged process to capture
+ the raw unconditioned Jiffies that is collected by
+ the LRNG for statistical analysis. This data is used for
+ seeding the LRNG if a high-resolution time stamp is not
+ available. If a high-resolution time stamp is detected,
+ the Jiffies value is not collected by the LRNG and no
+ data is provided via the test interface. Extracted noise
+ data is not used to seed the random number generator.
+
+ The raw noise data can be obtained using the lrng_raw_jiffies
+ debugfs file. Using the option lrng_testing.boot_raw_jiffies_test=1
+ the raw noise of the first 1000 entropy events since boot
+ can be sampled.
+
+config LRNG_RAW_IRQ_ENTROPY
+   bool "Enable entropy test interface to IRQ number noise source"
+   help
+ The test interface allows a privileged process to capture
+

[PATCH v38 01/13] Linux Random Number Generator

2021-02-27 Thread Stephan Müller
In an effort to provide a flexible implementation for a random number
generator that also delivers entropy during early boot time, allows
replacement of the deterministic random number generation mechanism,
implement the various components in separate code for easier
maintenance, and provide compliance to SP800-90[A|B|C], introduce
the Linux Random Number Generator (LRNG) framework.

The general design is as follows. Additional implementation details
are given in [1]. The LRNG consists of the following components:

1. The LRNG implements a DRNG. The DRNG always generates the
requested amount of output. When using the SP800-90A terminology
it operates without prediction resistance. The secondary DRNG
maintains a counter of how many bytes were generated since last
re-seed and a timer of the elapsed time since last re-seed. If either
the counter or the timer reaches a threshold, the secondary DRNG is
seeded from the entropy pool.

In case the Linux kernel detects a NUMA system, one secondary DRNG
instance per NUMA node is maintained.

2. The DRNG is seeded by concatenating the data from the
following sources:

(a) the output of the entropy pool,

(b) the Jitter RNG if available and enabled, and

(c) the CPU-based noise source such as Intel RDRAND if available and
enabled.

The entropy estimate of the data of all noise sources are added to
form the entropy estimate of the data used to seed the DRNG with.
The LRNG ensures, however, that the DRNG after seeding is at
maximum the security strength of the DRNG.

The LRNG is designed such that none of these noise sources can dominate
the other noise sources to provide seed data to the DRNG during due to
the following:

(a) During boot time, the amount of received interrupts are the trigger
points to (re)seed the DRNG.

(b) At runtime, the available entropy from the slow noise source is
concatenated with a pre-defined amount of data from the fast noise
sources. In addition, each DRNG reseed operation triggers external
noise source providers to deliver one block of data.

3. The entropy pool accumulates entropy obtained from certain events,
which will henceforth be collectively called "slow noise sources".
The entropy pool collects noise data from slow noise sources. Any data
received by the LRNG from the slow noise sources is inserted into a
per-CPU entropy pool using a hash operation that can be changed during
runtime. Per default, SHA-256 is used.

 (a) When an interrupt occurs, the high-resolution time stamp is mixed
into the per-CPU entropy pool. This time stamp is credited with
heuristically implied entropy.

 (b) HID event data like the key stroke or the mouse coordinates are
mixed into the per-CPU entropy pool. This data is not credited with
entropy by the LRNG.

 (c) Device drivers may provide data that is mixed into an auxiliary
pool using the same hash that is used to process the per-CPU entropy
pool. This data is not credited with entropy by the LRNG.

Any data provided from user space by either writing to /dev/random,
/dev/urandom or the IOCTL of RNDADDENTROPY on both device files
are always injected into the auxiliary pool.

In addition, when a hardware random number generator covered by the
Linux kernel HW generator framework wants to deliver random numbers,
it is injected into the auxiliary pool as well. HW generator noise source
is handled separately from the other noise source due to the fact that
the HW generator framework may decide by itself when to deliver data
whereas the other noise sources always requested for data driven by the
LRNG operation. Similarly any user space provided data is inserted into
the entropy pool.

When seed data for the DRNG is to be generated, all per-CPU
entropy pools and the auxiliary pool are hashed. The message digest
forms the new auxiliary pool state. At the same time, this data
is used for seeding the DRNG.

To speed up the interrupt handling code of the LRNG, the time stamp
collected for an interrupt event is truncated to the 8 least
significant bits. 64 truncated time stamps are concatenated and then
jointly inserted into the per-CPU entropy pool. During boot time,
until the fully seeded stage is reached, each time stamp with its
32 least significant bits is are concatenated. When 16 such events
are received, they are injected into the per-CPU entropy pool.

The LRNG allows the DRNG mechanism to be changed at runtime. Per default,
a ChaCha20-based DRNG is used. The ChaCha20-DRNG implemented for the
LRNG is also provided as a stand-alone user space deterministic random
number generator. The LRNG also offers an SP800-90A DRBG based on the
Linux kernel crypto API DRBG implementation.

The processing of entropic data from the noise source before injecting
them into the DRNG is performed with the following mathematical
operations:

1. Truncation: The received time stamps are truncated to 8 least
significant bits (or 32 least significant bits during boot time)

2. Concatenation: The received and truncated time stamps 

[PATCH v38 00/13] /dev/random - a new approach

2021-02-27 Thread Stephan Müller
Hi,

The following patch set provides a different approach to /dev/random which
is called Linux Random Number Generator (LRNG) to collect entropy within
the Linux kernel. It provides the same API and ABI and can be used as a
drop-in replacement.

The LRNG implements at least all features of the existing /dev/random such as
NUMA-node-local DRNGs. Patches 1 through 3 provide the code that is feature-
identical. The following advantages compared to the existing /dev/random
implementation are present:

* Sole use of crypto for data processing:

 - Exclusive use of a hash operation for conditioning entropy data with
   a clear mathematical description as given in [2] section 2.2 -
   non-cryptographic operations like LFSR are not used.

 - The LRNG uses only properly defined and implemented cryptographic
   algorithms unlike the use of the SHA-1 transformation in the existing
   /dev/random implementation.

 - Hash operations use NUMA-node-local hash instances to benefit large
   parallel systems.

 - LRNG uses limited number of data post-processing steps as documented in
   [2] section 2.2 compared to the large variation of different
   post-processing steps in the existing /dev/random implementation that
   have no apparent mathematical description (see [2] section 4.5).

* Performance

 - Faster by up to 130% in the critical code path of the interrupt handler
   depending on data collection size configurable at kernel compile time -
   the default is now set such that the highest performance is achieved as
   outlined in [2] section 4.2.

 - Configurable data collection sizes to accommodate small environments
   and big environments via CONFIG_LRNG_COLLECTION_SIZE.

 - Entropy collection using an almost never contended lock to benefit
   large parallel systems – worst case rate of contention is the number
   of DRNG reseeds, usually the number of potential contentions per 10
   minutes is equal to number of NUMA nodes.

 - ChaCha20 DRNG is significantly faster as implemented in the existing
   /dev/random as demonstrated with [2] table 2.

 - Faster entropy collection during boot time to reach fully seeded
   level, including on virtual systems or systems with SSDs as outlined
   in [2] section 4.1.

* Testing

 - Availability of run-time health tests of the raw unconditioned
   noise source to identify degradation of the available entropy as
   documented in [2] section 2.5.4. Such health tests are important
   today due to virtual machine monitors reducing the resolution of
   or disabling the high-resolution timer.

 - Heuristic entropy estimation is based on quantitative measurements
   and analysis following SP800-90B and not on coincidental
   underestimation of entropy applied by the existing /dev/random as
   outlined in [4] section 4.4.

 - Power-on self tests for critical deterministic components (ChaCha20
   DRNG, software hash implementation, and entropy collection logic)
   not already covered by power-up tests of the kernel crypto API as
   documented in [2] section 2.14.

 - Availability of test interfaces for all operational stages of the
   LRNG including boot-time raw entropy event data sampling as outlined
   in [2] section 2.15.

 - Fully testable ChaCha20 DRNG via a userspace ChaCha20 DRNG
   implementation [3].

 - In case of using the kernel crypto API SHASH hash implementation, it
   is fully testable and tested via the NIST ACVP test framework, for
   example certificates A734, A737, and A738.

 - The LRNG offers a test interface to validate the used software hash
   implementation and in particular that the LRNG invokes the hash
   correctly, allowing a NIST ACVP-compliant test cycle - see [2]
   section 2.15.

 - Availability of stress testing covering the different code paths for
   data and mechanism (de)allocations and code paths covered with locks.

* Entropy collection

 - The LRNG is shipped with test tools allowing the collection of
   raw unconditioned entropy during runtime and boot time available at
   [1].

 - Full entropy assessment and description is provided with [2] chapter 3,
   specifically section 3.2.6.

 - Guarantee that entropy events are not credited with entropy twice
   (the existing /dev/random implementation credits HID/disk and
   interrupt events with entropy which are a derivative of each other).

* Configurable

 - LRNG kernel configuration allows configuration that is functionally
   equivalent to the existing /dev/random. Non-compiled additional code
   is folded into no-ops.

 - The following additional functions are compile-time selectable
   independent of each other:

  + Enabling of switchable cryptographic implementation support. This
allows enabling an SP800-90A DRBG.

  + Enabling of using Jitter RNG noise source.

  + Enabling of noise source health tests.

  + Enabling of test interface allowing to enable each test interface
individually.

  + Enabling of the power-up self test.

 - At boot-time, the SP800-90B health tests can be 

[PATCH v38 11/13] LRNG - add SP800-90B compliant health tests

2021-02-27 Thread Stephan Müller
Implement health tests for LRNG's slow noise sources as mandated by
SP-800-90B The file contains the following health tests:

- stuck test: The stuck test calculates the first, second and third
  discrete derivative of the time stamp to be processed by the hash
  for the per-CPU entropy pool. Only if all three values are non-zero,
  the received time delta is considered to be non-stuck.

- SP800-90B Repetition Count Test (RCT): The LRNG uses an enhanced
  version of the RCT specified in SP800-90B section 4.4.1. Instead of
  counting identical back-to-back values, the input to the RCT is the
  counting of the stuck values during the processing of received
  interrupt events. The RCT is applied with alpha=2^-30 compliant to
  the recommendation of FIPS 140-2 IG 9.8. During the counting operation,
  the LRNG always calculates the RCT cut-off value of C. If that value
  exceeds the allowed cut-off value, the LRNG will trigger the health
  test failure discussed below. An error is logged to the kernel log
  that such RCT failure occurred. This test is only applied and
  enforced in FIPS mode, i.e. when the kernel compiled with
  CONFIG_CONFIG_FIPS is started with fips=1.

- SP800-90B Adaptive Proportion Test (APT): The LRNG implements the
  APT as defined in SP800-90B section 4.4.2. The applied significance
  level again is alpha=2^-30 compliant to the recommendation of FIPS
  140-2 IG 9.8.

The aforementioned health tests are applied to the first 1,024 time stamps
obtained from interrupt events. In case one error is identified for either
the RCT, or the APT, the collected entropy is invalidated and the
SP800-90B startup health test is restarted.

As long as the SP800-90B startup health test is not completed, all LRNG
random number output interfaces that may block will block and not generate
any data. This implies that only those potentially blocking interfaces are
defined to provide random numbers that are seeded with the interrupt noise
source being SP800-90B compliant. All other output interfaces will not be
affected by the SP800-90B startup test and thus are not considered
SP800-90B compliant.

At runtime, the SP800-90B APT and RCT are applied to each time stamp
generated for a received interrupt. When either the APT and RCT indicates
a noise source failure, the LRNG is reset to a state it has immediately
after boot:

- all entropy counters are set to zero

- the SP800-90B startup tests are re-performed which implies that
getrandom(2) would block again until new entropy was collected

To summarize, the following rules apply:

• SP800-90B compliant output interfaces

  - /dev/random

  - getrandom(2) system call

  -  get_random_bytes kernel-internal interface when being triggered by
 the callback registered with add_random_ready_callback

• SP800-90B non-compliant output interfaces

  - /dev/urandom

  - get_random_bytes kernel-internal interface called directly

  - randomize_page kernel-internal interface

  - get_random_u32 and get_random_u64 kernel-internal interfaces

  - get_random_u32_wait, get_random_u64_wait, get_random_int_wait, and
get_random_long_wait kernel-internal interfaces

If either the RCT, or the APT health test fails irrespective whether
during initialization or runtime, the following actions occur:

  1. The entropy of the entire entropy pool is invalidated.

  2. All DRNGs are reset which imply that they are treated as being
 not seeded and require a reseed during next invocation.

  3. The SP800-90B startup health test are initiated with all
 implications of the startup tests. That implies that from that point
 on, new events must be observed and its entropy must be inserted into
 the entropy pool before random numbers are calculated from the
 entropy pool.

Further details on the SP800-90B compliance and the availability of all
test tools required to perform all tests mandated by SP800-90B are
provided at [1].

The entire health testing code is compile-time configurable.

The patch provides a CONFIG_BROKEN configuration of the APT / RCT cutoff
values which have a high likelihood to trigger the health test failure.
The BROKEN APT cutoff is set to the exact mean of the expected value if
the time stamps are equally distributed (512 time stamps divided by 16
possible values due to using the 4 LSB of the time stamp). The BROKEN
RCT cutoff value is set to 1 which is likely to be triggered during
regular operation.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig   |  56 +
 

[PATCH v38 04/13] LRNG - add switchable DRNG support

2021-02-27 Thread Stephan Müller
The DRNG switch support allows replacing the DRNG mechanism of the
LRNG. The switching support rests on the interface definition of
include/linux/lrng.h. A new DRNG is implemented by filling in the
interface defined in this header file.

In addition to the DRNG, the extension also has to provide a hash
implementation that is used to hash the entropy pool for random number
extraction.

Note: It is permissible to implement a DRNG whose operations may sleep.
However, the hash function must not sleep.

The switchable DRNG support allows replacing the DRNG at runtime.
However, only one DRNG extension is allowed to be loaded at any given
time. Before replacing it with another DRNG implementation, the possibly
existing DRNG extension must be unloaded.

The switchable DRNG extension activates the new DRNG during load time.
It is expected, however, that such a DRNG switch would be done only once
by an administrator to load the intended DRNG implementation.

It is permissible to compile DRNG extensions either as kernel modules or
statically. The initialization of the DRNG extension should be performed
with a late_initcall to ensure the extension is available when user
space starts but after all other initialization completed.
The initialization is performed by registering the function call data
structure with the lrng_set_drng_cb function. In order to unload the
DRNG extension, lrng_set_drng_cb must be invoked with the NULL
parameter.

The DRNG extension should always provide a security strength that is at
least as strong as LRNG_DRNG_SECURITY_STRENGTH_BITS.

The hash extension must not sleep and must not maintain a separate
state.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig   |   7 ++
 drivers/char/lrng/Makefile  |   1 +
 drivers/char/lrng/lrng_switch.c | 207 
 3 files changed, 215 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_switch.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index 23b219093b07..fe6a7eaeabb0 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -119,4 +119,11 @@ config LRNG_COLLECTION_SIZE
default 4096 if LRNG_COLLECTION_SIZE_4096
default 8192 if LRNG_COLLECTION_SIZE_8192
 
+menuconfig LRNG_DRNG_SWITCH
+   bool "Support DRNG runtime switching"
+   help
+ The Linux RNG per default uses a ChaCha20 DRNG that is
+ accessible via the external interfaces. With this configuration
+ option other DRNGs can be selected and loaded at runtime.
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index ac97f0b11cb7..0eb4a6849c88 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -10,3 +10,4 @@ obj-y += lrng_pool.o lrng_aux.o \
 
 obj-$(CONFIG_NUMA) += lrng_numa.o
 obj-$(CONFIG_SYSCTL)   += lrng_proc.o
+obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
diff --git a/drivers/char/lrng/lrng_switch.c b/drivers/char/lrng/lrng_switch.c
new file mode 100644
index ..40cea72fe06a
--- /dev/null
+++ b/drivers/char/lrng/lrng_switch.c
@@ -0,0 +1,207 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG DRNG switching support
+ *
+ * Copyright (C) 2016 - 2021, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+
+#include "lrng_internal.h"
+
+static int lrng_drng_switch(struct lrng_drng *drng_store,
+   const struct lrng_crypto_cb *cb, int node)
+{
+   const struct lrng_crypto_cb *old_cb;
+   unsigned long flags = 0, flags2 = 0;
+   int ret;
+   u8 seed[LRNG_DRNG_SECURITY_STRENGTH_BYTES];
+   void *new_drng = cb->lrng_drng_alloc(LRNG_DRNG_SECURITY_STRENGTH_BYTES);
+   void *old_drng, *new_hash, *old_hash;
+   u32 current_security_strength;
+   bool sl = false, reset_drng = !lrng_get_available();
+
+   if (IS_ERR(new_drng)) {
+   pr_warn("could not allocate new DRNG for NUMA node %d (%ld)\n",
+   node, PTR_ERR(new_drng));
+   return PTR_ERR(new_drng);
+   }
+
+   new_hash = cb->lrng_hash_alloc();
+   if (IS_ERR(new_hash)) {
+   pr_warn("could not allocate new LRNG pool hash (%ld)\n",
+   PTR_ERR(new_hash));
+   cb->lrng_drng_dealloc(new_drng);
+   return PTR_ERR(new_hash);
+   }
+
+   if (cb->lrng_hash_digestsize(new_hash) > 

[PATCH v38 08/13] LRNG - add kernel crypto API PRNG extension

2021-02-27 Thread Stephan Müller
Add runtime-pluggable support for all PRNGs that are accessible via
the kernel crypto API, including hardware PRNGs. The PRNG is selected
with the module parameter drng_name where the name must be one that the
kernel crypto API can resolve into an RNG.

This allows using of the kernel crypto API PRNG implementations that
provide an interface to hardware PRNGs. Using this extension,
the LRNG uses the hardware PRNGs to generate random numbers. An
example is the S390 CPACF support providing such a PRNG.

The hash is provided by a kernel crypto API SHASH whose digest size
complies with the seedsize of the PRNG.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig  |  13 ++
 drivers/char/lrng/Makefile |   1 +
 drivers/char/lrng/lrng_kcapi.c | 225 +
 3 files changed, 239 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_kcapi.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index 0b94a96e4729..f16bd237ab9e 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -141,6 +141,19 @@ config LRNG_DRBG
  Enable the SP800-90A DRBG support for the LRNG. Once the
  module is loaded, output from /dev/random, /dev/urandom,
  getrandom(2), or get_random_bytes_full is provided by a DRBG.
+
+config LRNG_KCAPI
+   tristate "Kernel Crypto API support for the LRNG"
+   depends on CRYPTO
+   depends on !LRNG_DRBG
+   select CRYPTO_RNG
+   select LRNG_KCAPI_HASH
+   help
+ Enable the support for generic pseudo-random number
+ generators offered by the kernel crypto API with the
+ LRNG. Once the module is loaded, output from /dev/random,
+ /dev/urandom, getrandom(2), or get_random_bytes is
+ provided by the selected kernel crypto API RNG.
 endif # LRNG_DRNG_SWITCH
 
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 6ebd252db12f..97d2b13d3227 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_SYSCTL)  += lrng_proc.o
 obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
 obj-$(CONFIG_LRNG_KCAPI_HASH)  += lrng_kcapi_hash.o
 obj-$(CONFIG_LRNG_DRBG)+= lrng_drbg.o
+obj-$(CONFIG_LRNG_KCAPI)   += lrng_kcapi.o
diff --git a/drivers/char/lrng/lrng_kcapi.c b/drivers/char/lrng/lrng_kcapi.c
new file mode 100644
index ..caecb3841f5b
--- /dev/null
+++ b/drivers/char/lrng/lrng_kcapi.c
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Backend for the LRNG providing the cryptographic primitives using the
+ * kernel crypto API.
+ *
+ * Copyright (C) 2018 - 2021, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "lrng_kcapi_hash.h"
+
+static char *drng_name = NULL;
+module_param(drng_name, charp, 0444);
+MODULE_PARM_DESC(drng_name, "Kernel crypto API name of DRNG");
+
+static char *pool_hash = "sha512";
+module_param(pool_hash, charp, 0444);
+MODULE_PARM_DESC(pool_hash,
+"Kernel crypto API name of hash or keyed message digest to 
read the entropy pool");
+
+static char *seed_hash = NULL;
+module_param(seed_hash, charp, 0444);
+MODULE_PARM_DESC(seed_hash,
+"Kernel crypto API name of hash with output size equal to 
seedsize of DRNG to bring seed string to the size required by the DRNG");
+
+struct lrng_drng_info {
+   struct crypto_rng *kcapi_rng;
+   void *lrng_hash;
+};
+
+static void *lrng_kcapi_drng_hash_alloc(void)
+{
+   return lrng_kcapi_hash_alloc(pool_hash);
+}
+
+static int lrng_kcapi_drng_seed_helper(void *drng, const u8 *inbuf,
+  u32 inbuflen)
+{
+   SHASH_DESC_ON_STACK(shash, NULL);
+   struct lrng_drng_info *lrng_drng_info = (struct lrng_drng_info *)drng;
+   struct crypto_rng *kcapi_rng = lrng_drng_info->kcapi_rng;
+   void *hash = lrng_drng_info->lrng_hash;
+   u32 digestsize = lrng_kcapi_hash_digestsize(hash);
+   u8 digest[64] __aligned(8);
+   int ret;
+
+   if (!hash)
+   return crypto_rng_reset(kcapi_rng, inbuf, inbuflen);
+
+   BUG_ON(digestsize > sizeof(digest));
+
+   ret = lrng_kcapi_hash_init(shash, hash) ?:
+ lrng_kcapi_hash_update(shash, inbuf, inbuflen) ?:
+ lrng_kcapi_hash_final(shash, digest);
+   if (ret)
+   return ret;
+
+   ret 

[PATCH v38 07/13] LRNG - add SP800-90A DRBG extension

2021-02-27 Thread Stephan Müller
Using the LRNG switchable DRNG support, the SP800-90A DRBG extension is
implemented.

The DRBG uses the kernel crypto API DRBG implementation. In addition, it
uses the kernel crypto API SHASH support to provide the hashing
operation.

The DRBG supports the choice of either a CTR DRBG using AES-256, HMAC
DRBG with SHA-512 core or Hash DRBG with SHA-512 core. The used core can
be selected with the module parameter lrng_drbg_type. The default is the
CTR DRBG.

When compiling the DRBG extension statically, the DRBG is loaded at
late_initcall stage which implies that with the start of user space, the
user space interfaces of getrandom(2), /dev/random and /dev/urandom
provide random data produced by an SP800-90A DRBG.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig |  10 ++
 drivers/char/lrng/Makefile|   1 +
 drivers/char/lrng/lrng_drbg.c | 197 ++
 3 files changed, 208 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_drbg.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index 423d54c64149..0b94a96e4729 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -131,6 +131,16 @@ if LRNG_DRNG_SWITCH
 config LRNG_KCAPI_HASH
bool
 
+config LRNG_DRBG
+   tristate "SP800-90A support for the LRNG"
+   depends on CRYPTO
+   select CRYPTO_DRBG_MENU
+   select CRYPTO_SHA512
+   select LRNG_KCAPI_HASH
+   help
+ Enable the SP800-90A DRBG support for the LRNG. Once the
+ module is loaded, output from /dev/random, /dev/urandom,
+ getrandom(2), or get_random_bytes_full is provided by a DRBG.
 endif # LRNG_DRNG_SWITCH
 
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 40f8826edeeb..6ebd252db12f 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_NUMA)+= lrng_numa.o
 obj-$(CONFIG_SYSCTL)   += lrng_proc.o
 obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
 obj-$(CONFIG_LRNG_KCAPI_HASH)  += lrng_kcapi_hash.o
+obj-$(CONFIG_LRNG_DRBG)+= lrng_drbg.o
diff --git a/drivers/char/lrng/lrng_drbg.c b/drivers/char/lrng/lrng_drbg.c
new file mode 100644
index ..d083ceb188fe
--- /dev/null
+++ b/drivers/char/lrng/lrng_drbg.c
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Backend for the LRNG providing the cryptographic primitives using the
+ * kernel crypto API and its DRBG.
+ *
+ * Copyright (C) 2016 - 2021, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+
+#include "lrng_kcapi_hash.h"
+
+/*
+ * Define a DRBG plus a hash / MAC used to extract data from the entropy pool.
+ * For LRNG_HASH_NAME you can use a hash or a MAC (HMAC or CMAC) of your choice
+ * (Note, you should use the suggested selections below -- using SHA-1 or MD5
+ * is not wise). The idea is that the used cipher primitive can be selected to
+ * be the same as used for the DRBG. I.e. the LRNG only uses one cipher
+ * primitive using the same cipher implementation with the options offered in
+ * the following. This means, if the CTR DRBG is selected and AES-NI is 
present,
+ * both the CTR DRBG and the selected cmac(aes) use AES-NI.
+ *
+ * The security strengths of the DRBGs are all 256 bits according to
+ * SP800-57 section 5.6.1.
+ *
+ * This definition is allowed to be changed.
+ */
+#ifdef CONFIG_CRYPTO_DRBG_CTR
+static unsigned int lrng_drbg_type = 0;
+#elif defined CONFIG_CRYPTO_DRBG_HMAC
+static unsigned int lrng_drbg_type = 1;
+#elif defined CONFIG_CRYPTO_DRBG_HASH
+static unsigned int lrng_drbg_type = 2;
+#else
+#error "Unknown DRBG in use"
+#endif
+
+/* The parameter must be r/o in sysfs as otherwise races appear. */
+module_param(lrng_drbg_type, uint, 0444);
+MODULE_PARM_DESC(lrng_drbg_type, "DRBG type used for LRNG (0->CTR_DRBG, 
1->HMAC_DRBG, 2->Hash_DRBG)");
+
+struct lrng_drbg {
+   const char *hash_name;
+   const char *drbg_core;
+};
+
+static const struct lrng_drbg lrng_drbg_types[] = {
+   {   /* CTR_DRBG with AES-256 using derivation function */
+   .hash_name = "sha512",
+   .drbg_core = "drbg_nopr_ctr_aes256",
+   }, {/* HMAC_DRBG with SHA-512 */
+   .hash_name = "sha512",
+   .drbg_core = "drbg_nopr_hmac_sha512",
+   }, {/* Hash_DRBG with SHA-512 using derivation function */
+   .hash_name = "sha512",
+   

[PATCH v38 13/13] LRNG - add power-on and runtime self-tests

2021-02-27 Thread Stephan Müller
Parts of the LRNG are already covered by self-tests, including:

* Self-test of SP800-90A DRBG provided by the Linux kernel crypto API.

* Self-test of the PRNG provided by the Linux kernel crypto API.

* Raw noise source data testing including SP800-90B compliant
  tests when enabling CONFIG_LRNG_HEALTH_TESTS

This patch adds the self-tests for the remaining critical functions of
the LRNG that are essential to maintain entropy and provide
cryptographic strong random numbers. The following self-tests are
implemented:

* Self-test of the time array maintenance. This test verifies whether
the time stamp array management to store multiple values in one integer
implements a concatenation of the data.

* Self-test of the software hash implementation ensures that this
function operates compliant to the FIPS 180-4 specification. The
self-test performs a hash operation of a zeroized per-CPU data array.

* Self-test of the ChaCha20 DRNG is based on the self-tests that are
already present and implemented with the stand-alone user space
ChaCha20 DRNG implementation available at [1]. The self-tests cover
different use cases of the DRNG seeded with known seed data.

The status of the LRNG self-tests is provided with the selftest_status
SysFS file. If the file contains a zero, the self-tests passed. The
value 0x means that the self-tests were not executed. Any other
value indicates a self-test failure.

The self-test may be compiled to panic the system if the self-test
fails.

All self-tests operate on private state data structures. This implies
that none of the self-tests have any impact on the regular LRNG
operations. This allows the self-tests to be repeated at runtime by
writing anything into the selftest_status SysFS file.

[1] https://www.chronox.de/chacha20.html

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
CC: Marcelo Henrique Cerri 
CC: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig |  26 +++
 drivers/char/lrng/Makefile|   1 +
 drivers/char/lrng/lrng_selftest.c | 351 ++
 3 files changed, 378 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_selftest.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index 3e57068ccdff..2a7347e25834 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -374,4 +374,30 @@ config LRNG_TESTING
 
 endif #LRNG_TESTING_MENU
 
+config LRNG_SELFTEST
+   bool "Enable power-on and on-demand self-tests"
+   help
+ The power-on self-tests are executed during boot time
+ covering the ChaCha20 DRNG, the hash operation used for
+ processing the entropy pools and the auxiliary pool, and
+ the time stamp management of the LRNG.
+
+ The on-demand self-tests are triggered by writing any
+ value into the SysFS file selftest_status. At the same
+ time, when reading this file, the test status is
+ returned. A zero indicates that all tests were executed
+ successfully.
+
+ If unsure, say Y.
+
+if LRNG_SELFTEST
+
+config LRNG_SELFTEST_PANIC
+   bool "Panic the kernel upon self-test failure"
+   help
+ If the option is enabled, the kernel is terminated if an
+ LRNG power-on self-test failure is detected.
+
+endif # LRNG_SELFTEST
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 532501b38a00..a633638af991 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_LRNG_KCAPI)  += lrng_kcapi.o
 obj-$(CONFIG_LRNG_JENT)+= lrng_jent.o
 obj-$(CONFIG_LRNG_HEALTH_TESTS)+= lrng_health.o
 obj-$(CONFIG_LRNG_TESTING) += lrng_testing.o
+obj-$(CONFIG_LRNG_SELFTEST)+= lrng_selftest.o
diff --git a/drivers/char/lrng/lrng_selftest.c 
b/drivers/char/lrng/lrng_selftest.c
new file mode 100644
index ..9540424cd073
--- /dev/null
+++ b/drivers/char/lrng/lrng_selftest.c
@@ -0,0 +1,351 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG power-on and on-demand self-test
+ *
+ * Copyright (C) 2016 - 2021, Stephan Mueller 
+ */
+
+/*
+ * In addition to the self-tests below, the following LRNG components
+ * are covered with self-tests during regular operation:
+ *
+ * * power-on self-test: SP800-90A DRBG provided by the Linux kernel crypto API
+ * * power-on self-test: PRNG provided by the Linux kernel crypto API
+ * * runtime test: Raw noise source data testing including SP800-90B compliant
+ *tests when enabling CONFIG_LRNG_HEALTH_TESTS
+ *
+ * Additional developer tests present with LRNG code:
+ * * SP800-90B APT and RCT test 

[PATCH v38 05/13] LRNG - add common generic hash support

2021-02-27 Thread Stephan Müller
The LRNG switchable DRNG support also allows the replacement of the hash
implementation used as conditioning component. The common generic hash
support code provides the required callbacks using the synchronous hash
implementations of the kernel crypto API.

All synchronous hash implementations supported by the kernel crypto API
can be used as part of the LRNG with this generic support.

The generic support is intended to be configured by separate switchable
DRNG backends.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
CC: "Peter, Matthias" 
CC: Roman Drahtmueller 
CC: Marcelo Henrique Cerri 
CC: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig   |  7 +++
 drivers/char/lrng/Makefile  |  1 +
 drivers/char/lrng/lrng_kcapi_hash.c | 97 +
 drivers/char/lrng/lrng_kcapi_hash.h | 19 ++
 4 files changed, 124 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_kcapi_hash.c
 create mode 100644 drivers/char/lrng/lrng_kcapi_hash.h

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index fe6a7eaeabb0..423d54c64149 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -126,4 +126,11 @@ menuconfig LRNG_DRNG_SWITCH
  accessible via the external interfaces. With this configuration
  option other DRNGs can be selected and loaded at runtime.
 
+if LRNG_DRNG_SWITCH
+
+config LRNG_KCAPI_HASH
+   bool
+
+endif # LRNG_DRNG_SWITCH
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 0eb4a6849c88..40f8826edeeb 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -11,3 +11,4 @@ obj-y += lrng_pool.o lrng_aux.o \
 obj-$(CONFIG_NUMA) += lrng_numa.o
 obj-$(CONFIG_SYSCTL)   += lrng_proc.o
 obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
+obj-$(CONFIG_LRNG_KCAPI_HASH)  += lrng_kcapi_hash.o
diff --git a/drivers/char/lrng/lrng_kcapi_hash.c 
b/drivers/char/lrng/lrng_kcapi_hash.c
new file mode 100644
index ..37363c2b6ab2
--- /dev/null
+++ b/drivers/char/lrng/lrng_kcapi_hash.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Backend for providing the hash primitive using the kernel crypto API.
+ *
+ * Copyright (C) 2021, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+
+#include "lrng_kcapi_hash.h"
+
+struct lrng_hash_info {
+   struct crypto_shash *tfm;
+};
+
+static inline void _lrng_kcapi_hash_free(struct lrng_hash_info *lrng_hash)
+{
+   struct crypto_shash *tfm = lrng_hash->tfm;
+
+   crypto_free_shash(tfm);
+   kfree(lrng_hash);
+}
+
+void *lrng_kcapi_hash_alloc(const char *name)
+{
+   struct lrng_hash_info *lrng_hash;
+   struct crypto_shash *tfm;
+   int ret;
+
+   if (!name) {
+   pr_err("Hash name missing\n");
+   return ERR_PTR(-EINVAL);
+   }
+
+   tfm = crypto_alloc_shash(name, 0, 0);
+   if (IS_ERR(tfm)) {
+   pr_err("could not allocate hash %s\n", name);
+   return ERR_CAST(tfm);
+   }
+
+   ret = sizeof(struct lrng_hash_info);
+   lrng_hash = kmalloc(ret, GFP_KERNEL);
+   if (!lrng_hash) {
+   crypto_free_shash(tfm);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   lrng_hash->tfm = tfm;
+
+   pr_info("Hash %s allocated\n", name);
+
+   return lrng_hash;
+}
+EXPORT_SYMBOL(lrng_kcapi_hash_alloc);
+
+u32 lrng_kcapi_hash_digestsize(void *hash)
+{
+   struct lrng_hash_info *lrng_hash = (struct lrng_hash_info *)hash;
+   struct crypto_shash *tfm = lrng_hash->tfm;
+
+   return crypto_shash_digestsize(tfm);
+}
+EXPORT_SYMBOL(lrng_kcapi_hash_digestsize);
+
+void lrng_kcapi_hash_dealloc(void *hash)
+{
+   struct lrng_hash_info *lrng_hash = (struct lrng_hash_info *)hash;
+
+   _lrng_kcapi_hash_free(lrng_hash);
+   pr_info("Hash deallocated\n");
+}
+EXPORT_SYMBOL(lrng_kcapi_hash_dealloc);
+
+int lrng_kcapi_hash_init(struct shash_desc *shash, void *hash)
+{
+   struct lrng_hash_info *lrng_hash = (struct lrng_hash_info *)hash;
+   struct crypto_shash *tfm = lrng_hash->tfm;
+
+   shash->tfm = tfm;
+   return crypto_shash_init(shash);
+}
+EXPORT_SYMBOL(lrng_kcapi_hash_init);
+
+int lrng_kcapi_hash_update(struct shash_desc *shash, const u8 *inbuf,
+  u32 inbuflen)
+{
+   return crypto_shash_update(shash, inbuf, inbuflen);
+}
+EXPORT_SYMBOL(lrng_kcapi_hash_update);
+
+int lrng_kcapi_hash_final(struct shash_desc *shash, u8 *digest)
+{
+   return crypto_shash_final(shash, digest);
+}
+EXPORT_SYMBOL(lrng_kcapi_hash_final);
diff 

[PATCH v38 02/13] LRNG - allocate one DRNG instance per NUMA node

2021-02-27 Thread Stephan Müller
In order to improve NUMA-locality when serving getrandom(2) requests,
allocate one DRNG instance per node.

The DRNG instance that is present right from the start of the kernel is
reused as the first per-NUMA-node DRNG. For all remaining online NUMA
nodes a new DRNG instance is allocated.

During boot time, the multiple DRNG instances are seeded sequentially.
With this, the first DRNG instance (referenced as the initial DRNG
in the code) is completely seeded with 256 bits of entropy before the
next DRNG instance is completely seeded.

When random numbers are requested, the NUMA-node-local DRNG is checked
whether it has been already fully seeded. If this is not the case, the
initial DRNG is used to serve the request.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
CC: Eric Biggers 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Makefile|   2 +
 drivers/char/lrng/lrng_internal.h |   5 ++
 drivers/char/lrng/lrng_numa.c | 120 ++
 3 files changed, 127 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_numa.c

diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index e72e01c15bb9..29724c65287d 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -7,3 +7,5 @@ obj-y   += lrng_pool.o lrng_aux.o \
   lrng_sw_noise.o lrng_archrandom.o \
   lrng_drng.o lrng_chacha20.o \
   lrng_interfaces.o
+
+obj-$(CONFIG_NUMA) += lrng_numa.o
diff --git a/drivers/char/lrng/lrng_internal.h 
b/drivers/char/lrng/lrng_internal.h
index d398ac6b5674..1bfb3710c767 100644
--- a/drivers/char/lrng/lrng_internal.h
+++ b/drivers/char/lrng/lrng_internal.h
@@ -214,8 +214,13 @@ int lrng_drng_get_sleep(u8 *outbuf, u32 outbuflen);
 void lrng_drng_force_reseed(void);
 void lrng_drng_seed_work(struct work_struct *dummy);
 
+#ifdef CONFIG_NUMA
+struct lrng_drng **lrng_drng_instances(void);
+void lrng_drngs_numa_alloc(void);
+#else  /* CONFIG_NUMA */
 static inline struct lrng_drng **lrng_drng_instances(void) { return NULL; }
 static inline void lrng_drngs_numa_alloc(void) { return; }
+#endif /* CONFIG_NUMA */
 
 /** Entropy pool management 
***/
 
diff --git a/drivers/char/lrng/lrng_numa.c b/drivers/char/lrng/lrng_numa.c
new file mode 100644
index ..37817771b97a
--- /dev/null
+++ b/drivers/char/lrng/lrng_numa.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG NUMA support
+ *
+ * Copyright (C) 2016 - 2021, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+
+#include "lrng_internal.h"
+
+static struct lrng_drng **lrng_drng __read_mostly = NULL;
+
+struct lrng_drng **lrng_drng_instances(void)
+{
+   return smp_load_acquire(_drng);
+}
+
+/* Allocate the data structures for the per-NUMA node DRNGs */
+static void _lrng_drngs_numa_alloc(struct work_struct *work)
+{
+   struct lrng_drng **drngs;
+   struct lrng_drng *lrng_drng_init = lrng_drng_init_instance();
+   u32 node;
+   bool init_drng_used = false;
+
+   mutex_lock(_crypto_cb_update);
+
+   /* per-NUMA-node DRNGs are already present */
+   if (lrng_drng)
+   goto unlock;
+
+   drngs = kcalloc(nr_node_ids, sizeof(void *), GFP_KERNEL|__GFP_NOFAIL);
+   for_each_online_node(node) {
+   struct lrng_drng *drng;
+
+   if (!init_drng_used) {
+   drngs[node] = lrng_drng_init;
+   init_drng_used = true;
+   continue;
+   }
+
+   drng = kmalloc_node(sizeof(struct lrng_drng),
+GFP_KERNEL|__GFP_NOFAIL, node);
+   memset(drng, 0, sizeof(lrng_drng));
+
+   drng->crypto_cb = lrng_drng_init->crypto_cb;
+   drng->drng = drng->crypto_cb->lrng_drng_alloc(
+   LRNG_DRNG_SECURITY_STRENGTH_BYTES);
+   if (IS_ERR(drng->drng)) {
+   kfree(drng);
+   goto err;
+   }
+
+   drng->hash = drng->crypto_cb->lrng_hash_alloc();
+   if (IS_ERR(drng->hash)) {
+   drng->crypto_cb->lrng_drng_dealloc(drng->drng);
+   kfree(drng);
+   goto err;
+   }
+
+   mutex_init(>lock);
+   

[PATCH v38 10/13] LRNG - add Jitter RNG fast noise source

2021-02-27 Thread Stephan Müller
The Jitter RNG fast noise source implemented as part of the kernel
crypto API is queried for 256 bits of entropy at the time the seed
buffer managed by the LRNG is about to be filled.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig | 12 +
 drivers/char/lrng/Makefile|  1 +
 drivers/char/lrng/lrng_jent.c | 88 +++
 3 files changed, 101 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_jent.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index f16bd237ab9e..01185b985af4 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -156,4 +156,16 @@ config LRNG_KCAPI
  provided by the selected kernel crypto API RNG.
 endif # LRNG_DRNG_SWITCH
 
+config LRNG_JENT
+   bool "Enable Jitter RNG as LRNG Seed Source"
+   depends on CRYPTO
+   select CRYPTO_JITTERENTROPY
+   help
+ The Linux RNG may use the Jitter RNG as noise source. Enabling
+ this option enables the use of the Jitter RNG. Its default
+ entropy level is 16 bits of entropy per 256 data bits delivered
+ by the Jitter RNG. This entropy level can be changed at boot
+ time or at runtime with the lrng_base.jitterrng configuration
+ variable.
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 97d2b13d3227..6be88156010a 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_LRNG_DRNG_SWITCH)+= lrng_switch.o
 obj-$(CONFIG_LRNG_KCAPI_HASH)  += lrng_kcapi_hash.o
 obj-$(CONFIG_LRNG_DRBG)+= lrng_drbg.o
 obj-$(CONFIG_LRNG_KCAPI)   += lrng_kcapi.o
+obj-$(CONFIG_LRNG_JENT)+= lrng_jent.o
diff --git a/drivers/char/lrng/lrng_jent.c b/drivers/char/lrng/lrng_jent.c
new file mode 100644
index ..9cae59678c1e
--- /dev/null
+++ b/drivers/char/lrng/lrng_jent.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG Fast Noise Source: Jitter RNG
+ *
+ * Copyright (C) 2016 - 2021, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+
+#include "lrng_internal.h"
+
+/*
+ * Estimated entropy of data is a 16th of LRNG_DRNG_SECURITY_STRENGTH_BITS.
+ * Albeit a full entropy assessment is provided for the noise source indicating
+ * that it provides high entropy rates and considering that it deactivates
+ * when it detects insufficient hardware, the chosen under estimation of
+ * entropy is considered to be acceptable to all reviewers.
+ */
+static u32 jitterrng = LRNG_DRNG_SECURITY_STRENGTH_BITS>>4;
+module_param(jitterrng, uint, 0644);
+MODULE_PARM_DESC(jitterrng, "Entropy in bits of 256 data bits from Jitter RNG 
noise source");
+
+/**
+ * lrng_get_jent() - Get Jitter RNG entropy
+ *
+ * @outbuf: buffer to store entropy
+ * @outbuflen: length of buffer
+ *
+ * Return:
+ * * > 0 on success where value provides the added entropy in bits
+ * * 0 if no fast source was available
+ */
+static struct rand_data *lrng_jent_state;
+
+u32 lrng_get_jent(u8 *outbuf, unsigned int outbuflen)
+{
+   int ret;
+   u32 ent_bits = jitterrng;
+   unsigned long flags;
+   static DEFINE_SPINLOCK(lrng_jent_lock);
+   static int lrng_jent_initialized = 0;
+
+   spin_lock_irqsave(_jent_lock, flags);
+
+   if (!ent_bits || (lrng_jent_initialized == -1)) {
+   spin_unlock_irqrestore(_jent_lock, flags);
+   return 0;
+   }
+
+   if (!lrng_jent_initialized) {
+   lrng_jent_state = jent_lrng_entropy_collector();
+   if (!lrng_jent_state) {
+   jitterrng = 0;
+   lrng_jent_initialized = -1;
+   spin_unlock_irqrestore(_jent_lock, flags);
+   pr_info("Jitter RNG unusable on current system\n");
+   return 0;
+   }
+   lrng_jent_initialized = 1;
+   pr_debug("Jitter RNG working on current system\n");
+   }
+   ret = jent_read_entropy(lrng_jent_state, outbuf, outbuflen);
+   spin_unlock_irqrestore(_jent_lock, flags);
+
+   if (ret) {
+   pr_debug("Jitter RNG failed with %d\n", ret);
+   return 0;
+   }
+
+   /* Obtain entropy statement */
+   if (outbuflen != LRNG_DRNG_SECURITY_STRENGTH_BYTES)
+   ent_bits = (ent_bits * outbuflen<<3) /
+  

Re: [PATCH v2 0/7] Add KDF implementations to crypto API

2021-01-24 Thread Stephan Müller
Am Sonntag, 24. Januar 2021, 15:32:59 CET schrieb Ard Biesheuvel:

Hi Ard,

> On Sun, 24 Jan 2021 at 15:23, Ard Biesheuvel  wrote:
> > On Sun, 24 Jan 2021 at 15:10, Stephan Müller  wrote:
> > > Hi,
> > > 
> > > The key derviation functions are considered to be a cryptographic
> > > operation. As cryptographic operations are provided via the kernel
> > > crypto API, this patch set consolidates the KDF implementations into the
> > > crypto API.
> > > 
> > > The KDF implementations are provided as service functions. Yet, the
> > > interface to the two provided KDFs are identical with the goal to allow
> > > them to be transformed into a crypto API template eventually.
> > 
> > Why? There are typically two reasons to use the crypto API abstractions:
> > - the algorithm is not known at compile time, so we need the runtime
> > dispatch that the crypto API implements,
> > - the algorithm may be implemented by a h/w accelerator which is
> > discovered at runtime via the driver stack
> > 
> > In other cases, a library API is much more suitable, even in the case
> > where we may provide arch-specific accelerated implementations of such
> > an algorithm.
> 
> Hmm, apologies if I got the wrong end of the stick here - this prose
> and the naming of some of the crypto_hkdf_xxx routines and function
> pointers in the test code made me think that this is more than it
> actually is.
> 
> What we are talking about are basically library wrappers around shash
> instances to perform HKDF, right?

Sorry, our emails just crossed each other.

Yes, you are absolutely correct. The KDF implementations are wrappers around 
the SHASH API. Conceptually the provided API is what templates actually should 
do.

As mentioned in the other email, however, adding a template was and is not 
considered appropriate at the time. Yet, I would like to keep the path open to 
transform the KDF implementations into a template.

Ciao
Stephan




Re: [PATCH v2 0/7] Add KDF implementations to crypto API

2021-01-24 Thread Stephan Müller
Am Sonntag, 24. Januar 2021, 15:23:29 CET schrieb Ard Biesheuvel:

Hi Ard,

> On Sun, 24 Jan 2021 at 15:10, Stephan Müller  wrote:
> > Hi,
> > 
> > The key derviation functions are considered to be a cryptographic
> > operation. As cryptographic operations are provided via the kernel
> > crypto API, this patch set consolidates the KDF implementations into the
> > crypto API.
> > 
> > The KDF implementations are provided as service functions. Yet, the
> > interface to the two provided KDFs are identical with the goal to allow
> > them to be transformed into a crypto API template eventually.
> 
> Why? There are typically two reasons to use the crypto API abstractions:
> - the algorithm is not known at compile time, so we need the runtime
> dispatch that the crypto API implements,
> - the algorithm may be implemented by a h/w accelerator which is
> discovered at runtime via the driver stack
> 
> In other cases, a library API is much more suitable, even in the case
> where we may provide arch-specific accelerated implementations of such
> an algorithm.

In case your "why" refers to why I stated that the KDF implementations are 
similar to eventually consolidate them into a template eventually:

A KDF is conceptually a logic on top of a (hash) algorithm like a block 
chaining mode on top of a block cipher or a deterministic RNG on top of an 
underlying cipher.

So, conceptually with the kernel crypto API, we would have a KDF template that 
can be used like hkdf(sha256) or hkdf(sha256-avx2).

The behavior of a KDF is identical to a deterministic RNG. Thus, a long time 
ago, I had a patch developed that adds a very small addition to the existing 
RNG API to allow the KDFs to be used. See [1]. Yet, that was not desired at 
the time due to different reasons.

Yet, the crypto API as it stands today knows of templates and basic 
algorithms. Having a separate library API providing a crypto algorithm is new 
to the crypto API. You see that with the test manager which works well with 
the templates / algorithms but does not provide any helpers for some "library 
APIs".



In case your "why" refers to whether I am not using a template to begin with:

Some time back I provided the patch using a template (see [1] for example). At 
that time, Herbert wanted to have a service API instead.

[1] http://www.chronox.de/kdf.html

Ciao
Stephan




[PATCH v2 7/7] fs: HKDF - remove duplicate memory clearing

2021-01-24 Thread Stephan Müller
The clearing of the OKM memory buffer in case of an error is already
performed by the HKDF implementation crypto_hkdf_expand. Thus, the
code clearing is not needed any more in the file system code base.

Signed-off-by: Stephan Mueller 
---
 fs/crypto/hkdf.c | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/fs/crypto/hkdf.c b/fs/crypto/hkdf.c
index ae236b42b1f0..c48dd8ca3a46 100644
--- a/fs/crypto/hkdf.c
+++ b/fs/crypto/hkdf.c
@@ -102,13 +102,10 @@ int fscrypt_hkdf_expand(const struct fscrypt_hkdf *hkdf, 
u8 context,
.iov_base = (u8 *)info,
.iov_len = infolen,
} };
-   int err = crypto_hkdf_expand(hkdf->hmac_tfm,
-info_iov, ARRAY_SIZE(info_iov),
-okm, okmlen);
 
-   if (unlikely(err))
-   memzero_explicit(okm, okmlen); /* so caller doesn't need to */
-   return err;
+   return crypto_hkdf_expand(hkdf->hmac_tfm,
+ info_iov, ARRAY_SIZE(info_iov),
+ okm, okmlen);
 }
 
 void fscrypt_destroy_hkdf(struct fscrypt_hkdf *hkdf)
-- 
2.26.2






[PATCH v2 4/7] security: DH - remove dead code for zero padding

2021-01-24 Thread Stephan Müller
Remove the specific code that adds a zero padding that was intended
to be invoked when the DH operation result was smaller than the
modulus. However, this cannot occur any more these days because the
function mpi_write_to_sgl is used in the code path that calculates the
shared secret in dh_compute_value. This MPI service function guarantees
that leading zeros are introduced as needed to ensure the resulting data
is exactly as long as the modulus. This implies that the specific code
to add zero padding is dead code which can be safely removed.

Signed-off-by: Stephan Mueller 
---
 security/keys/dh.c | 25 -
 1 file changed, 4 insertions(+), 21 deletions(-)

diff --git a/security/keys/dh.c b/security/keys/dh.c
index 1abfa70ed6e1..56e12dae4534 100644
--- a/security/keys/dh.c
+++ b/security/keys/dh.c
@@ -141,7 +141,7 @@ static void kdf_dealloc(struct kdf_sdesc *sdesc)
  * 'dlen' must be a multiple of the digest size.
  */
 static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen,
-  u8 *dst, unsigned int dlen, unsigned int zlen)
+  u8 *dst, unsigned int dlen)
 {
struct shash_desc *desc = >shash;
unsigned int h = crypto_shash_digestsize(desc->tfm);
@@ -158,22 +158,6 @@ static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, 
unsigned int slen,
if (err)
goto err;
 
-   if (zlen && h) {
-   u8 tmpbuffer[32];
-   size_t chunk = min_t(size_t, zlen, sizeof(tmpbuffer));
-   memset(tmpbuffer, 0, chunk);
-
-   do {
-   err = crypto_shash_update(desc, tmpbuffer,
- chunk);
-   if (err)
-   goto err;
-
-   zlen -= chunk;
-   chunk = min_t(size_t, zlen, sizeof(tmpbuffer));
-   } while (zlen);
-   }
-
if (src && slen) {
err = crypto_shash_update(desc, src, slen);
if (err)
@@ -198,7 +182,7 @@ static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, 
unsigned int slen,
 
 static int keyctl_dh_compute_kdf(struct kdf_sdesc *sdesc,
 char __user *buffer, size_t buflen,
-uint8_t *kbuf, size_t kbuflen, size_t lzero)
+uint8_t *kbuf, size_t kbuflen)
 {
uint8_t *outbuf = NULL;
int ret;
@@ -211,7 +195,7 @@ static int keyctl_dh_compute_kdf(struct kdf_sdesc *sdesc,
goto err;
}
 
-   ret = kdf_ctr(sdesc, kbuf, kbuflen, outbuf, outbuf_len, lzero);
+   ret = kdf_ctr(sdesc, kbuf, kbuflen, outbuf, outbuf_len);
if (ret)
goto err;
 
@@ -384,8 +368,7 @@ long __keyctl_dh_compute(struct keyctl_dh_params __user 
*params,
}
 
ret = keyctl_dh_compute_kdf(sdesc, buffer, buflen, outbuf,
-   req->dst_len + 
kdfcopy->otherinfolen,
-   outlen - req->dst_len);
+   req->dst_len + 
kdfcopy->otherinfolen);
} else if (copy_to_user(buffer, outbuf, req->dst_len) == 0) {
ret = req->dst_len;
} else {
-- 
2.26.2






[PATCH v2 0/7] Add KDF implementations to crypto API

2021-01-24 Thread Stephan Müller
Hi,

The key derviation functions are considered to be a cryptographic
operation. As cryptographic operations are provided via the kernel
crypto API, this patch set consolidates the KDF implementations into the
crypto API.

The KDF implementations are provided as service functions. Yet, the
interface to the two provided KDFs are identical with the goal to allow
them to be transformed into a crypto API template eventually.

The KDFs execute a power-on self test with test vectors from commonly
known sources.

Tbe SP800-108 KDF implementation is used to replace the implementation
in the keys subsystem. The implementation was verified using the
keyutils command line test code provided in
tests/keyctl/dh_compute/valid. All tests show that the expected values
are calculated with the new code.

The HKDF addition is used to replace the implementation in the filesystem
crypto extension. This code was tested by using an EXT4 encrypted file
system that was created and contains files written to by the current
implementation. Using the new implementation a successful read of the
existing files was possible and new files / directories were created
and read successfully. These newly added file system objects could be
successfully read using the current code. Yet if there is a test suite
to validate whether the invokcation of the HKDF calculates the same
result as the existing implementation, I would be happy to validate
the implementation accordingly.

Changes v2:

* change HKDF function names
* change HKDF/SP800-108 KDF extract / seed function prototype
* ensure clearing of memory of destination buffer in KDF implementation
  if KDF operation fails
* security DH: split the removal of dead code into separate patch

Stephan Mueller (7):
  crypto: Add key derivation self-test support code
  crypto: add SP800-108 counter key derivation function
  crypto: add RFC5869 HKDF
  security: DH - remove dead code for zero padding
  security: DH - use KDF implementation from crypto API
  fs: use HKDF implementation from kernel crypto API
  fs: HKDF - remove duplicate memory clearing

 crypto/Kconfig |  14 ++
 crypto/Makefile|   6 +
 crypto/hkdf.c  | 199 +
 crypto/kdf_sp800108.c  | 149 ++
 fs/crypto/Kconfig  |   2 +-
 fs/crypto/hkdf.c   | 103 +++--
 include/crypto/hkdf.h  |  48 ++
 include/crypto/internal/kdf_selftest.h |  71 +
 include/crypto/kdf_sp800108.h  |  61 
 security/keys/Kconfig  |   2 +-
 security/keys/dh.c | 118 ++-
 11 files changed, 586 insertions(+), 187 deletions(-)
 create mode 100644 crypto/hkdf.c
 create mode 100644 crypto/kdf_sp800108.c
 create mode 100644 include/crypto/hkdf.h
 create mode 100644 include/crypto/internal/kdf_selftest.h
 create mode 100644 include/crypto/kdf_sp800108.h

-- 
2.26.2






[PATCH v2 3/7] crypto: add RFC5869 HKDF

2021-01-24 Thread Stephan Müller
RFC5869 specifies an extract and expand two-step key derivation
function. The HKDF implementation is provided as a service function that
operates on a caller-provided HMAC handle. The caller has to allocate
the HMAC shash handle and then can invoke the HKDF service functions.
The HKDF implementation ensures that the entire state is kept with the
HMAC shash handle which implies that no additional state is required to
be maintained by the HKDF implementation.

The extract function is invoked via the crypto_hkdf_extract call. RFC5869
allows two optional parameters to be provided to the extract operation:
the salt and input key material (IKM). Both are to be provided with the
seed parameter where the salt is the first entry of the seed parameter
and all subsequent entries are handled as IKM. If the caller intends to
invoke the HKDF without salt, it has to provide a NULL/0 entry as first
entry in seed.

The expand function is invoked via crypto_hkdf_expand and can be
invoked multiple times. This function allows the caller to provide a
context for the key derivation operation. As specified in RFC5869, it is
optional. In case such context is not provided, the caller must provide
NULL / 0 for the info / info_nvec parameters.

Signed-off-by: Stephan Mueller 
---
 crypto/Kconfig|   7 ++
 crypto/Makefile   |   1 +
 crypto/hkdf.c | 199 ++
 include/crypto/hkdf.h |  48 ++
 4 files changed, 255 insertions(+)
 create mode 100644 crypto/hkdf.c
 create mode 100644 include/crypto/hkdf.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 9f375c2350f5..661287d7283b 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -1862,6 +1862,13 @@ config CRYPTO_JITTERENTROPY
  random numbers. This Jitterentropy RNG registers with
  the kernel crypto API and can be used by any caller.
 
+config CRYPTO_HKDF
+   tristate "Extract and Expand HKDF (RFC 5869)"
+   select CRYPTO_HASH
+   help
+ Enable the extract and expand key derivation function compliant
+ to RFC 5869.
+
 config CRYPTO_KDF800108_CTR
tristate "Counter KDF (SP800-108)"
select CRYPTO_HASH
diff --git a/crypto/Makefile b/crypto/Makefile
index 46845a70850d..55a4d8c31a45 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -201,4 +201,5 @@ obj-$(CONFIG_CRYPTO_SIMD) += crypto_simd.o
 #
 # Key derivation function
 #
+obj-$(CONFIG_CRYPTO_HKDF) += hkdf.o
 obj-$(CONFIG_CRYPTO_KDF800108_CTR) += kdf_sp800108.o
diff --git a/crypto/hkdf.c b/crypto/hkdf.c
new file mode 100644
index ..8e80eca202e7
--- /dev/null
+++ b/crypto/hkdf.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * HMAC-based Extract-and-Expand Key Derivation Function (conformant to 
RFC5869)
+ *
+ * Copyright (C) 2020, Stephan Mueller 
+ */
+
+#include 
+#include 
+#include 
+
+/*
+ * HKDF expand phase
+ */
+int crypto_hkdf_expand(struct crypto_shash *kmd,
+  const struct kvec *info, unsigned int info_nvec,
+  u8 *dst, unsigned int dlen)
+{
+   SHASH_DESC_ON_STACK(desc, kmd);
+   const unsigned int h = crypto_shash_digestsize(kmd), dlen_orig = dlen;
+   unsigned int i;
+   int err = 0;
+   u8 *dst_orig = dst;
+   const u8 *prev = NULL;
+   u8 ctr = 0x01;
+
+   if (dlen > h * 255)
+   return -EINVAL;
+
+   desc->tfm = kmd;
+
+   /* T(1) and following */
+   while (dlen) {
+   err = crypto_shash_init(desc);
+   if (err)
+   goto out;
+
+   if (prev) {
+   err = crypto_shash_update(desc, prev, h);
+   if (err)
+   goto out;
+   }
+
+   for (i = 0; i < info_nvec; i++) {
+   err = crypto_shash_update(desc, info[i].iov_base,
+ info[i].iov_len);
+   if (err)
+   goto out;
+   }
+
+   if (dlen < h) {
+   u8 tmpbuffer[HASH_MAX_DIGESTSIZE];
+
+   err = crypto_shash_finup(desc, , 1, tmpbuffer);
+   if (err)
+   goto out;
+   memcpy(dst, tmpbuffer, dlen);
+   memzero_explicit(tmpbuffer, h);
+   goto out;
+   }
+
+   err = crypto_shash_finup(desc, , 1, dst);
+   if (err)
+   goto out;
+
+   prev = dst;
+   dst += h;
+   dlen -= h;
+   ctr++;
+   }
+
+out:
+   if (err)
+   memzero_explicit(dst_orig, dlen_orig);
+   shash_desc_zero(desc);
+   return err;
+}
+EXPORT_SYMBOL(crypto_hkdf_expand);
+
+/*
+ * HKDF extract phase.
+ */
+int crypto_hkdf_extract(struct crypto_shash *kmd,
+   const u8 *salt, size_t saltlen,
+

[PATCH v2 2/7] crypto: add SP800-108 counter key derivation function

2021-01-24 Thread Stephan Müller
SP800-108 defines three KDFs - this patch provides the counter KDF
implementation.

The KDF is implemented as a service function where the caller has to
maintain the hash / HMAC state. Apart from this hash/HMAC state, no
additional state is required to be maintained by either the caller or
the KDF implementation.

The key for the KDF is set with the crypto_kdf108_setkey function which
is intended to be invoked before the caller requests a key derivation
operation via crypto_kdf108_ctr_generate.

SP800-108 allows the use of either a HMAC or a hash as crypto primitive
for the KDF. When a HMAC primtive is intended to be used,
crypto_kdf108_setkey must be used to set the HMAC key. Otherwise, for a
hash crypto primitve crypto_kdf108_ctr_generate can be used immediately
after allocating the hash handle.

Signed-off-by: Stephan Mueller 
---
 crypto/Kconfig|   7 ++
 crypto/Makefile   |   5 ++
 crypto/kdf_sp800108.c | 149 ++
 include/crypto/kdf_sp800108.h |  61 ++
 4 files changed, 222 insertions(+)
 create mode 100644 crypto/kdf_sp800108.c
 create mode 100644 include/crypto/kdf_sp800108.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index a367fcfeb5d4..9f375c2350f5 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -1862,6 +1862,13 @@ config CRYPTO_JITTERENTROPY
  random numbers. This Jitterentropy RNG registers with
  the kernel crypto API and can be used by any caller.
 
+config CRYPTO_KDF800108_CTR
+   tristate "Counter KDF (SP800-108)"
+   select CRYPTO_HASH
+   help
+ Enable the key derivation function in counter mode compliant to
+ SP800-108.
+
 config CRYPTO_USER_API
tristate
 
diff --git a/crypto/Makefile b/crypto/Makefile
index b279483fba50..46845a70850d 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -197,3 +197,8 @@ obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys/
 obj-$(CONFIG_CRYPTO_HASH_INFO) += hash_info.o
 crypto_simd-y := simd.o
 obj-$(CONFIG_CRYPTO_SIMD) += crypto_simd.o
+
+#
+# Key derivation function
+#
+obj-$(CONFIG_CRYPTO_KDF800108_CTR) += kdf_sp800108.o
diff --git a/crypto/kdf_sp800108.c b/crypto/kdf_sp800108.c
new file mode 100644
index ..84b45e0cadf5
--- /dev/null
+++ b/crypto/kdf_sp800108.c
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * SP800-108 Key-derivation function
+ *
+ * Copyright (C) 2020, Stephan Mueller 
+ */
+
+#include 
+#include 
+#include 
+
+/*
+ * SP800-108 CTR KDF implementation
+ */
+int crypto_kdf108_ctr_generate(struct crypto_shash *kmd,
+  const struct kvec *info, unsigned int info_nvec,
+  u8 *dst, unsigned int dlen)
+{
+   SHASH_DESC_ON_STACK(desc, kmd);
+   __be32 counter = cpu_to_be32(1);
+   const unsigned int h = crypto_shash_digestsize(kmd), dlen_orig = dlen;
+   unsigned int i;
+   int err = 0;
+   u8 *dst_orig = dst;
+
+   desc->tfm = kmd;
+
+   while (dlen) {
+   err = crypto_shash_init(desc);
+   if (err)
+   goto out;
+
+   err = crypto_shash_update(desc, (u8 *), sizeof(__be32));
+   if (err)
+   goto out;
+
+   for (i = 0; i < info_nvec; i++) {
+   err = crypto_shash_update(desc, info[i].iov_base,
+ info[i].iov_len);
+   if (err)
+   goto out;
+   }
+
+   if (dlen < h) {
+   u8 tmpbuffer[HASH_MAX_DIGESTSIZE];
+
+   err = crypto_shash_final(desc, tmpbuffer);
+   if (err)
+   goto out;
+   memcpy(dst, tmpbuffer, dlen);
+   memzero_explicit(tmpbuffer, h);
+   goto out;
+   }
+
+   err = crypto_shash_final(desc, dst);
+   if (err)
+   goto out;
+
+   dlen -= h;
+   dst += h;
+   counter = cpu_to_be32(be32_to_cpu(counter) + 1);
+   }
+
+out:
+   if (err)
+   memzero_explicit(dst_orig, dlen_orig);
+   shash_desc_zero(desc);
+   return err;
+}
+EXPORT_SYMBOL(crypto_kdf108_ctr_generate);
+
+/*
+ * The seeding of the KDF
+ */
+int crypto_kdf108_setkey(struct crypto_shash *kmd,
+const u8 *key, size_t keylen,
+const u8 *ikm, size_t ikmlen)
+{
+   unsigned int ds = crypto_shash_digestsize(kmd);
+
+   /* SP800-108 does not support IKM */
+   if (ikm || ikmlen)
+   return -EINVAL;
+
+   /* Check according to SP800-108 section 7.2 */
+   if (ds > keylen)
+   return -EINVAL;
+
+   /*
+* We require that we operate on a MAC -- if we do not operate on a
+* MAC, this function returns an error.
+*/
+  

[PATCH v2 5/7] security: DH - use KDF implementation from crypto API

2021-01-24 Thread Stephan Müller
The kernel crypto API provides the SP800-108 counter KDF implementation.
Thus, the separate implementation provided as part of the keys subsystem
can be replaced with calls to the KDF offered by the kernel crypto API.

The keys subsystem uses the counter KDF with a hash primitive. Thus,
it only uses the call to crypto_kdf108_ctr_generate.

Signed-off-by: Stephan Mueller 
---
 security/keys/Kconfig |  2 +-
 security/keys/dh.c| 97 +++
 2 files changed, 15 insertions(+), 84 deletions(-)

diff --git a/security/keys/Kconfig b/security/keys/Kconfig
index 83bc23409164..e6604499f0a8 100644
--- a/security/keys/Kconfig
+++ b/security/keys/Kconfig
@@ -106,7 +106,7 @@ config KEY_DH_OPERATIONS
bool "Diffie-Hellman operations on retained keys"
depends on KEYS
select CRYPTO
-   select CRYPTO_HASH
+   select CRYPTO_KDF800108_CTR
select CRYPTO_DH
help
 This option provides support for calculating Diffie-Hellman
diff --git a/security/keys/dh.c b/security/keys/dh.c
index 56e12dae4534..46fa442b81ec 100644
--- a/security/keys/dh.c
+++ b/security/keys/dh.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "internal.h"
 
@@ -79,16 +80,9 @@ static void dh_crypto_done(struct crypto_async_request *req, 
int err)
complete(>completion);
 }
 
-struct kdf_sdesc {
-   struct shash_desc shash;
-   char ctx[];
-};
-
-static int kdf_alloc(struct kdf_sdesc **sdesc_ret, char *hashname)
+static int kdf_alloc(struct crypto_shash **hash, char *hashname)
 {
struct crypto_shash *tfm;
-   struct kdf_sdesc *sdesc;
-   int size;
int err;
 
/* allocate synchronous hash */
@@ -102,14 +96,7 @@ static int kdf_alloc(struct kdf_sdesc **sdesc_ret, char 
*hashname)
if (crypto_shash_digestsize(tfm) == 0)
goto out_free_tfm;
 
-   err = -ENOMEM;
-   size = sizeof(struct shash_desc) + crypto_shash_descsize(tfm);
-   sdesc = kmalloc(size, GFP_KERNEL);
-   if (!sdesc)
-   goto out_free_tfm;
-   sdesc->shash.tfm = tfm;
-
-   *sdesc_ret = sdesc;
+   *hash = tfm;
 
return 0;
 
@@ -118,76 +105,20 @@ static int kdf_alloc(struct kdf_sdesc **sdesc_ret, char 
*hashname)
return err;
 }
 
-static void kdf_dealloc(struct kdf_sdesc *sdesc)
-{
-   if (!sdesc)
-   return;
-
-   if (sdesc->shash.tfm)
-   crypto_free_shash(sdesc->shash.tfm);
-
-   kfree_sensitive(sdesc);
-}
-
-/*
- * Implementation of the KDF in counter mode according to SP800-108 section 5.1
- * as well as SP800-56A section 5.8.1 (Single-step KDF).
- *
- * SP800-56A:
- * The src pointer is defined as Z || other info where Z is the shared secret
- * from DH and other info is an arbitrary string (see SP800-56A section
- * 5.8.1.2).
- *
- * 'dlen' must be a multiple of the digest size.
- */
-static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen,
-  u8 *dst, unsigned int dlen)
+static void kdf_dealloc(struct crypto_shash *hash)
 {
-   struct shash_desc *desc = >shash;
-   unsigned int h = crypto_shash_digestsize(desc->tfm);
-   int err = 0;
-   u8 *dst_orig = dst;
-   __be32 counter = cpu_to_be32(1);
-
-   while (dlen) {
-   err = crypto_shash_init(desc);
-   if (err)
-   goto err;
-
-   err = crypto_shash_update(desc, (u8 *), sizeof(__be32));
-   if (err)
-   goto err;
-
-   if (src && slen) {
-   err = crypto_shash_update(desc, src, slen);
-   if (err)
-   goto err;
-   }
-
-   err = crypto_shash_final(desc, dst);
-   if (err)
-   goto err;
-
-   dlen -= h;
-   dst += h;
-   counter = cpu_to_be32(be32_to_cpu(counter) + 1);
-   }
-
-   return 0;
-
-err:
-   memzero_explicit(dst_orig, dlen);
-   return err;
+   if (hash)
+   crypto_free_shash(hash);
 }
 
-static int keyctl_dh_compute_kdf(struct kdf_sdesc *sdesc,
+static int keyctl_dh_compute_kdf(struct crypto_shash *hash,
 char __user *buffer, size_t buflen,
 uint8_t *kbuf, size_t kbuflen)
 {
+   struct kvec kbuf_iov = { .iov_base = kbuf, .iov_len = kbuflen };
uint8_t *outbuf = NULL;
int ret;
-   size_t outbuf_len = roundup(buflen,
-   crypto_shash_digestsize(sdesc->shash.tfm));
+   size_t outbuf_len = roundup(buflen, crypto_shash_digestsize(hash));
 
outbuf = kmalloc(outbuf_len, GFP_KERNEL);
if (!outbuf) {
@@ -195,7 +126,7 @@ static int keyctl_dh_compute_kdf(struct kdf_sdesc *sdesc,
goto err;
}
 
-   ret = kdf_ctr(sdesc, kbuf, kbuflen, outbuf, outbuf_len);
+  

[PATCH v2 1/7] crypto: Add key derivation self-test support code

2021-01-24 Thread Stephan Müller
As a preparation to add the key derivation implementations, the
self-test data structure definition and the common test code is made
available.

The test framework follows the testing applied by the NIST CAVP test
approach.

The structure of the test code follows the implementations found in
crypto/testmgr.c|h. In case the KDF implementations will be made
available via a kernel crypto API templates, the test code is intended
to be merged into testmgr.c|h.

Signed-off-by: Stephan Mueller 
---
 include/crypto/internal/kdf_selftest.h | 71 ++
 1 file changed, 71 insertions(+)
 create mode 100644 include/crypto/internal/kdf_selftest.h

diff --git a/include/crypto/internal/kdf_selftest.h 
b/include/crypto/internal/kdf_selftest.h
new file mode 100644
index ..373fcb11f2fa
--- /dev/null
+++ b/include/crypto/internal/kdf_selftest.h
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * Copyright (C) 2020, Stephan Mueller 
+ */
+
+#ifndef _CRYPTO_KDF_SELFTEST_H
+#define _CRYPTO_KDF_SELFTEST_H
+
+#include 
+#include 
+
+struct kdf_testvec {
+   unsigned char *key;
+   size_t keylen;
+   unsigned char *ikm;
+   size_t ikmlen;
+   struct kvec info;
+   unsigned char *expected;
+   size_t expectedlen;
+};
+
+static inline int
+kdf_test(const struct kdf_testvec *test, const char *name,
+int (*crypto_kdf_setkey)(struct crypto_shash *kmd,
+ const u8 *key, size_t keylen,
+ const u8 *ikm, size_t ikmlen),
+int (*crypto_kdf_generate)(struct crypto_shash *kmd,
+   const struct kvec *info,
+   unsigned int info_nvec,
+   u8 *dst, unsigned int dlen))
+{
+   struct crypto_shash *kmd;
+   int ret;
+   u8 *buf = kzalloc(test->expectedlen, GFP_KERNEL);
+
+   if (!buf)
+   return -ENOMEM;
+
+   kmd = crypto_alloc_shash(name, 0, 0);
+   if (IS_ERR(kmd)) {
+   pr_err("alg: kdf: could not allocate hash handle for %s\n",
+  name);
+   kfree(buf);
+   return -ENOMEM;
+   }
+
+   ret = crypto_kdf_setkey(kmd, test->key, test->keylen,
+   test->ikm, test->ikmlen);
+   if (ret) {
+   pr_err("alg: kdf: could not set key derivation key\n");
+   goto err;
+   }
+
+   ret = crypto_kdf_generate(kmd, >info, 1, buf, test->expectedlen);
+   if (ret) {
+   pr_err("alg: kdf: could not obtain key data\n");
+   goto err;
+   }
+
+   ret = memcmp(test->expected, buf, test->expectedlen);
+   if (ret)
+   ret = -EINVAL;
+
+err:
+   crypto_free_shash(kmd);
+   kfree(buf);
+   return ret;
+}
+
+#endif /* _CRYPTO_KDF_SELFTEST_H */
-- 
2.26.2






[PATCH v2 6/7] fs: use HKDF implementation from kernel crypto API

2021-01-24 Thread Stephan Müller
As the kernel crypto API implements HKDF, replace the
file-system-specific HKDF implementation with the generic HKDF
implementation.

Signed-off-by: Stephan Mueller 
---
 fs/crypto/Kconfig |  2 +-
 fs/crypto/hkdf.c  | 98 +--
 2 files changed, 20 insertions(+), 80 deletions(-)

diff --git a/fs/crypto/Kconfig b/fs/crypto/Kconfig
index a5f5c30368a2..9450e958f1d1 100644
--- a/fs/crypto/Kconfig
+++ b/fs/crypto/Kconfig
@@ -2,7 +2,7 @@
 config FS_ENCRYPTION
bool "FS Encryption (Per-file encryption)"
select CRYPTO
-   select CRYPTO_HASH
+   select CRYPTO_HKDF
select CRYPTO_SKCIPHER
select CRYPTO_LIB_SHA256
select KEYS
diff --git a/fs/crypto/hkdf.c b/fs/crypto/hkdf.c
index e0ec21055505..ae236b42b1f0 100644
--- a/fs/crypto/hkdf.c
+++ b/fs/crypto/hkdf.c
@@ -9,7 +9,7 @@
  * Copyright 2019 Google LLC
  */
 
-#include 
+#include 
 #include 
 
 #include "fscrypt_private.h"
@@ -37,23 +37,7 @@
  * unnecessarily long master keys.  Thus fscrypt still does HKDF-Extract.  No
  * salt is used, since fscrypt master keys should already be pseudorandom and
  * there's no way to persist a random salt per master key from kernel mode.
- */
-
-/* HKDF-Extract (RFC 5869 section 2.2), unsalted */
-static int hkdf_extract(struct crypto_shash *hmac_tfm, const u8 *ikm,
-   unsigned int ikmlen, u8 prk[HKDF_HASHLEN])
-{
-   static const u8 default_salt[HKDF_HASHLEN];
-   int err;
-
-   err = crypto_shash_setkey(hmac_tfm, default_salt, HKDF_HASHLEN);
-   if (err)
-   return err;
-
-   return crypto_shash_tfm_digest(hmac_tfm, ikm, ikmlen, prk);
-}
-
-/*
+ *
  * Compute HKDF-Extract using the given master key as the input keying 
material,
  * and prepare an HMAC transform object keyed by the resulting pseudorandom 
key.
  *
@@ -64,7 +48,6 @@ int fscrypt_init_hkdf(struct fscrypt_hkdf *hkdf, const u8 
*master_key,
  unsigned int master_key_size)
 {
struct crypto_shash *hmac_tfm;
-   u8 prk[HKDF_HASHLEN];
int err;
 
hmac_tfm = crypto_alloc_shash(HKDF_HMAC_ALG, 0, 0);
@@ -74,16 +57,14 @@ int fscrypt_init_hkdf(struct fscrypt_hkdf *hkdf, const u8 
*master_key,
return PTR_ERR(hmac_tfm);
}
 
-   if (WARN_ON(crypto_shash_digestsize(hmac_tfm) != sizeof(prk))) {
+   if (WARN_ON(crypto_shash_digestsize(hmac_tfm) != HKDF_HASHLEN)) {
err = -EINVAL;
goto err_free_tfm;
}
 
-   err = hkdf_extract(hmac_tfm, master_key, master_key_size, prk);
-   if (err)
-   goto err_free_tfm;
-
-   err = crypto_shash_setkey(hmac_tfm, prk, sizeof(prk));
+   /* HKDF-Extract (RFC 5869 section 2.2), unsalted */
+   err = crypto_hkdf_extract(hmac_tfm, NULL, 0,
+ master_key, master_key_size);
if (err)
goto err_free_tfm;
 
@@ -93,7 +74,6 @@ int fscrypt_init_hkdf(struct fscrypt_hkdf *hkdf, const u8 
*master_key,
 err_free_tfm:
crypto_free_shash(hmac_tfm);
 out:
-   memzero_explicit(prk, sizeof(prk));
return err;
 }
 
@@ -112,62 +92,22 @@ int fscrypt_hkdf_expand(const struct fscrypt_hkdf *hkdf, 
u8 context,
const u8 *info, unsigned int infolen,
u8 *okm, unsigned int okmlen)
 {
-   SHASH_DESC_ON_STACK(desc, hkdf->hmac_tfm);
-   u8 prefix[9];
-   unsigned int i;
-   int err;
-   const u8 *prev = NULL;
-   u8 counter = 1;
-   u8 tmp[HKDF_HASHLEN];
-
-   if (WARN_ON(okmlen > 255 * HKDF_HASHLEN))
-   return -EINVAL;
-
-   desc->tfm = hkdf->hmac_tfm;
-
-   memcpy(prefix, "fscrypt\0", 8);
-   prefix[8] = context;
-
-   for (i = 0; i < okmlen; i += HKDF_HASHLEN) {
+   const struct kvec info_iov[] = { {
+   .iov_base = "fscrypt\0",
+   .iov_len = 8,
+   }, {
+   .iov_base = ,
+   .iov_len = 1,
+   }, {
+   .iov_base = (u8 *)info,
+   .iov_len = infolen,
+   } };
+   int err = crypto_hkdf_expand(hkdf->hmac_tfm,
+info_iov, ARRAY_SIZE(info_iov),
+okm, okmlen);
 
-   err = crypto_shash_init(desc);
-   if (err)
-   goto out;
-
-   if (prev) {
-   err = crypto_shash_update(desc, prev, HKDF_HASHLEN);
-   if (err)
-   goto out;
-   }
-
-   err = crypto_shash_update(desc, prefix, sizeof(prefix));
-   if (err)
-   goto out;
-
-   err = crypto_shash_update(desc, info, infolen);
-   if (err)
-   goto out;
-
-   BUILD_BUG_ON(sizeof(counter) != 1);
-   if (okmlen - i < HKDF_HASHLEN) {
-   err = 

[PATCH 1/5] crypto: Add key derivation self-test support code

2021-01-04 Thread Stephan Müller
As a preparation to add the key derivation implementations, the
self-test data structure definition and the common test code is made
available.

The test framework follows the testing applied by the NIST CAVP test
approach.

The structure of the test code follows the implementations found in
crypto/testmgr.c|h. In case the KDF implementations will be made
available via a kernel crypto API templates, the test code is intended
to be merged into testmgr.c|h.

Signed-off-by: Stephan Mueller 
---
 include/crypto/internal/kdf_selftest.h | 68 ++
 1 file changed, 68 insertions(+)
 create mode 100644 include/crypto/internal/kdf_selftest.h

diff --git a/include/crypto/internal/kdf_selftest.h 
b/include/crypto/internal/kdf_selftest.h
new file mode 100644
index ..c4f80d2cc61c
--- /dev/null
+++ b/include/crypto/internal/kdf_selftest.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * Copyright (C) 2020, Stephan Mueller 
+ */
+
+#ifndef _CRYPTO_KDF_SELFTEST_H
+#define _CRYPTO_KDF_SELFTEST_H
+
+#include 
+#include 
+
+struct kdf_testvec {
+   struct kvec seed[2];
+   unsigned int seed_nvec;
+   struct kvec info;
+   unsigned char *expected;
+   size_t expectedlen;
+};
+
+static inline int
+kdf_test(const struct kdf_testvec *test, const char *name,
+int (*crypto_kdf_setkey)(struct crypto_shash *kmd,
+ const struct kvec *seed,
+ unsigned int seed_nvec),
+int (*crypto_kdf_generate)(struct crypto_shash *kmd,
+   const struct kvec *info,
+   unsigned int info_nvec,
+   u8 *dst, unsigned int dlen))
+{
+   struct crypto_shash *kmd;
+   int ret;
+   u8 *buf = kzalloc(test->expectedlen, GFP_KERNEL);
+
+   if (!buf)
+   return -ENOMEM;
+
+   kmd = crypto_alloc_shash(name, 0, 0);
+   if (IS_ERR(kmd)) {
+   pr_err("alg: kdf: could not allocate cipher handle for %s\n",
+  name);
+   kfree(buf);
+   return -ENOMEM;
+   }
+
+   ret = crypto_kdf_setkey(kmd, test->seed, test->seed_nvec);
+   if (ret) {
+   pr_err("alg: kdf: could not set key derivation key\n");
+   goto err;
+   }
+
+   ret = crypto_kdf_generate(kmd, >info, 1, buf, test->expectedlen);
+   if (ret) {
+   pr_err("alg: kdf: could not obtain key data\n");
+   goto err;
+   }
+
+   ret = memcmp(test->expected, buf, test->expectedlen);
+   if (ret)
+   ret = -EINVAL;
+
+err:
+   crypto_free_shash(kmd);
+   kfree(buf);
+   return ret;
+}
+
+#endif /* _CRYPTO_KDF_SELFTEST_H */
-- 
2.26.2






[PATCH 0/5] Add KDF implementations to crypto API

2021-01-04 Thread Stephan Müller
Hi,

The key derviation functions are considered to be a cryptographic
operation. As cryptographic operations are provided via the kernel
crypto API, this patch set consolidates the KDF implementations into the
crypto API.

The KDF implementations are provided as service functions. Yet, the
interface to the two provided KDFs are identical with the goal to allow
them to be transformed into a crypto API template eventually.

The KDFs execute a power-on self test with test vectors from commonly
known sources.

Tbe SP800-108 KDF implementation is used to replace the implementation
in the keys subsystem. The implementation was verified using the
keyutils command line test code provided in
tests/keyctl/dh_compute/valid. All tests show that the expected values
are calculated with the new code.

The HKDF addition is used to replace the implementation in the filesystem
crypto extension. This code was tested by using an EXT4 encrypted file
system that was created and contains files written to by the current
implementation. Using the new implementation a successful read of the
existing files was possible and new files / directories were created
and read successfully. These newly added file system objects could be
successfully read using the current code. Yet if there is a test suite
to validate whether the invokcation of the HKDF calculates the same
result as the existing implementation, I would be happy to validate
the implementation accordingly.

Stephan Mueller (5):
  crypto: Add key derivation self-test support code
  crypto: add SP800-108 counter key derivation function
  crypto: add RFC5869 HKDF
  security: DH - use KDF implementation from crypto API
  fs: use HKDF implementation from kernel crypto API

 crypto/Kconfig |  14 ++
 crypto/Makefile|   6 +
 crypto/hkdf.c  | 226 +
 crypto/kdf_sp800108.c  | 149 
 fs/crypto/Kconfig  |   2 +-
 fs/crypto/fscrypt_private.h|   4 +-
 fs/crypto/hkdf.c   | 108 +++-
 include/crypto/hkdf.h  |  48 ++
 include/crypto/internal/kdf_selftest.h |  68 
 include/crypto/kdf_sp800108.h  |  59 +++
 security/keys/Kconfig  |   2 +-
 security/keys/dh.c | 118 ++---
 12 files changed, 617 insertions(+), 187 deletions(-)
 create mode 100644 crypto/hkdf.c
 create mode 100644 crypto/kdf_sp800108.c
 create mode 100644 include/crypto/hkdf.h
 create mode 100644 include/crypto/internal/kdf_selftest.h
 create mode 100644 include/crypto/kdf_sp800108.h

-- 
2.26.2






[PATCH 2/5] crypto: add SP800-108 counter key derivation function

2021-01-04 Thread Stephan Müller
SP800-108 defines three KDFs - this patch provides the counter KDF
implementation.

The KDF is implemented as a service function where the caller has to
maintain the hash / HMAC state. Apart from this hash/HMAC state, no
additional state is required to be maintained by either the caller or
the KDF implementation.

The key for the KDF is set with the crypto_kdf108_setkey function which
is intended to be invoked before the caller requests a key derivation
operation via crypto_kdf108_ctr_generate.

SP800-108 allows the use of either a HMAC or a hash as crypto primitive
for the KDF. When a HMAC cipher primtive is intended to be used,
crypto_kdf108_setkey must be used to set the HMAC key. Otherwise, for a
hash crypto primitve crypto_kdf108_ctr_generate can be used immediately
after allocating the cipher handle.

Signed-off-by: Stephan Mueller 
---
 crypto/Kconfig|   7 ++
 crypto/Makefile   |   5 ++
 crypto/kdf_sp800108.c | 149 ++
 include/crypto/kdf_sp800108.h |  59 ++
 4 files changed, 220 insertions(+)
 create mode 100644 crypto/kdf_sp800108.c
 create mode 100644 include/crypto/kdf_sp800108.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index a367fcfeb5d4..9f375c2350f5 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -1862,6 +1862,13 @@ config CRYPTO_JITTERENTROPY
  random numbers. This Jitterentropy RNG registers with
  the kernel crypto API and can be used by any caller.
 
+config CRYPTO_KDF800108_CTR
+   tristate "Counter KDF (SP800-108)"
+   select CRYPTO_HASH
+   help
+ Enable the key derivation function in counter mode compliant to
+ SP800-108.
+
 config CRYPTO_USER_API
tristate
 
diff --git a/crypto/Makefile b/crypto/Makefile
index b279483fba50..46845a70850d 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -197,3 +197,8 @@ obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys/
 obj-$(CONFIG_CRYPTO_HASH_INFO) += hash_info.o
 crypto_simd-y := simd.o
 obj-$(CONFIG_CRYPTO_SIMD) += crypto_simd.o
+
+#
+# Key derivation function
+#
+obj-$(CONFIG_CRYPTO_KDF800108_CTR) += kdf_sp800108.o
diff --git a/crypto/kdf_sp800108.c b/crypto/kdf_sp800108.c
new file mode 100644
index ..325dbd9dba38
--- /dev/null
+++ b/crypto/kdf_sp800108.c
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * SP800-108 Key-derivation function
+ *
+ * Copyright (C) 2020, Stephan Mueller 
+ */
+
+#include 
+#include 
+#include 
+
+/*
+ * SP800-108 CTR KDF implementation
+ */
+int crypto_kdf108_ctr_generate(struct crypto_shash *kmd,
+  const struct kvec *info, unsigned int info_nvec,
+  u8 *dst, unsigned int dlen)
+{
+   SHASH_DESC_ON_STACK(desc, kmd);
+   __be32 counter = cpu_to_be32(1);
+   const unsigned int h = crypto_shash_digestsize(kmd);
+   unsigned int i;
+   int err = 0;
+   u8 *dst_orig = dst;
+
+   desc->tfm = kmd;
+
+   while (dlen) {
+   err = crypto_shash_init(desc);
+   if (err)
+   goto out;
+
+   err = crypto_shash_update(desc, (u8 *), sizeof(__be32));
+   if (err)
+   goto out;
+
+   for (i = 0; i < info_nvec; i++) {
+   err = crypto_shash_update(desc, info[i].iov_base,
+ info[i].iov_len);
+   if (err)
+   goto out;
+   }
+
+   if (dlen < h) {
+   u8 tmpbuffer[HASH_MAX_DIGESTSIZE];
+
+   err = crypto_shash_final(desc, tmpbuffer);
+   if (err)
+   goto out;
+   memcpy(dst, tmpbuffer, dlen);
+   memzero_explicit(tmpbuffer, h);
+   goto out;
+   }
+
+   err = crypto_shash_final(desc, dst);
+   if (err)
+   goto out;
+
+   dlen -= h;
+   dst += h;
+   counter = cpu_to_be32(be32_to_cpu(counter) + 1);
+   }
+
+out:
+   if (err)
+   memzero_explicit(dst_orig, dlen);
+   shash_desc_zero(desc);
+   return err;
+}
+EXPORT_SYMBOL(crypto_kdf108_ctr_generate);
+
+/*
+ * The seeding of the KDF
+ */
+int crypto_kdf108_setkey(struct crypto_shash *kmd,
+const struct kvec *seed, unsigned int seed_nvec)
+{
+   unsigned int ds = crypto_shash_digestsize(kmd);
+
+   if (seed_nvec != 1)
+   return -EINVAL;
+
+   /* Check according to SP800-108 section 7.2 */
+   if (ds > seed[0].iov_len)
+   return -EINVAL;
+
+   /*
+* We require that we operate on a MAC -- if we do not operate on a
+* MAC, this function returns an error.
+*/
+   return crypto_shash_setkey(kmd, seed[0].iov_base, seed[0].iov_len);
+}

[PATCH 3/5] crypto: add RFC5869 HKDF

2021-01-04 Thread Stephan Müller
RFC5869 specifies an extract and expand two-step key derivation
function. The HKDF implementation is provided as a service function that
operates on a caller-provided HMAC cipher handle. The caller has to
allocate the HMAC cipher and then can invoke the HKDF service functions.
The HKDF implementation ensures that the entire state is kept with the
HMAC cipher handle which implies that no additional state is required to
be maintained by the HKDF implementation.

The extract function is invoked via the crypto_hkdf_setkey call. RFC5869
allows two optional parameters to be provided to the extract operation:
the salt and additional information. Both are to be provided with the
seed parameter where the salt is the first entry of the seed parameter
and all subsequent entries are handled as additional information. If
the caller intends to invoke the HKDF without salt, it has to provide a
NULL/0 entry as first entry in seed.

The expand function is invoked via the crypto_hkdf_generate and can be
invoked multiple times. This function allows the caller to provide a
context for the key derivation operation. As specified in RFC5869, it is
optional. In case such context is not provided, the caller must provide
NULL / 0 for the info / info_nvec parameters.

Signed-off-by: Stephan Mueller 
---
 crypto/Kconfig|   7 ++
 crypto/Makefile   |   1 +
 crypto/hkdf.c | 226 ++
 include/crypto/hkdf.h |  48 +
 4 files changed, 282 insertions(+)
 create mode 100644 crypto/hkdf.c
 create mode 100644 include/crypto/hkdf.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 9f375c2350f5..661287d7283b 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -1862,6 +1862,13 @@ config CRYPTO_JITTERENTROPY
  random numbers. This Jitterentropy RNG registers with
  the kernel crypto API and can be used by any caller.
 
+config CRYPTO_HKDF
+   tristate "Extract and Expand HKDF (RFC 5869)"
+   select CRYPTO_HASH
+   help
+ Enable the extract and expand key derivation function compliant
+ to RFC 5869.
+
 config CRYPTO_KDF800108_CTR
tristate "Counter KDF (SP800-108)"
select CRYPTO_HASH
diff --git a/crypto/Makefile b/crypto/Makefile
index 46845a70850d..55a4d8c31a45 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -201,4 +201,5 @@ obj-$(CONFIG_CRYPTO_SIMD) += crypto_simd.o
 #
 # Key derivation function
 #
+obj-$(CONFIG_CRYPTO_HKDF) += hkdf.o
 obj-$(CONFIG_CRYPTO_KDF800108_CTR) += kdf_sp800108.o
diff --git a/crypto/hkdf.c b/crypto/hkdf.c
new file mode 100644
index ..a3bf6d6b07ea
--- /dev/null
+++ b/crypto/hkdf.c
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * HMAC-based Extract-and-Expand Key Derivation Function (conformant to 
RFC5869)
+ *
+ * Copyright (C) 2020, Stephan Mueller 
+ */
+
+#include 
+#include 
+#include 
+
+/*
+ * HKDF expand phase
+ */
+int crypto_hkdf_generate(struct crypto_shash *kmd,
+const struct kvec *info, unsigned int info_nvec,
+u8 *dst, unsigned int dlen)
+{
+   SHASH_DESC_ON_STACK(desc, kmd);
+   const unsigned int h = crypto_shash_digestsize(kmd);
+   unsigned int i;
+   int err = 0;
+   u8 *dst_orig = dst;
+   const u8 *prev = NULL;
+   u8 ctr = 0x01;
+
+   if (dlen > h * 255)
+   return -EINVAL;
+
+   desc->tfm = kmd;
+
+   /* T(1) and following */
+   while (dlen) {
+   err = crypto_shash_init(desc);
+   if (err)
+   goto out;
+
+   if (prev) {
+   err = crypto_shash_update(desc, prev, h);
+   if (err)
+   goto out;
+   }
+
+   for (i = 0; i < info_nvec; i++) {
+   err = crypto_shash_update(desc, info[i].iov_base,
+ info[i].iov_len);
+   if (err)
+   goto out;
+   }
+
+   if (dlen < h) {
+   u8 tmpbuffer[HASH_MAX_DIGESTSIZE];
+
+   err = crypto_shash_finup(desc, , 1, tmpbuffer);
+   if (err)
+   goto out;
+   memcpy(dst, tmpbuffer, dlen);
+   memzero_explicit(tmpbuffer, h);
+   goto out;
+   }
+
+   err = crypto_shash_finup(desc, , 1, dst);
+   if (err)
+   goto out;
+
+   prev = dst;
+   dst += h;
+   dlen -= h;
+   ctr++;
+   }
+
+out:
+   if (err)
+   memzero_explicit(dst_orig, dlen);
+   shash_desc_zero(desc);
+   return err;
+}
+EXPORT_SYMBOL(crypto_hkdf_generate);
+
+/*
+ * HKDF extract phase.
+ */
+int crypto_hkdf_setkey(struct crypto_shash *kmd,
+  const struct kvec *seed, 

[PATCH 4/5] security: DH - use KDF implementation from crypto API

2021-01-04 Thread Stephan Müller
The kernel crypto API provides the SP800-108 counter KDF implementation.
Thus, the separate implementation provided as part of the keys subsystem
can be replaced with calls to the KDF offered by the kernel crypto API.

The keys subsystem uses the counter KDF with a hash cipher primitive.
Thus, it only uses the call to crypto_kdf108_ctr_generate.

The change removes the specific code that adds a zero padding that was
intended to be invoked when the DH operation result was smaller than the
modulus. However, this cannot occur any more these days because the
function mpi_write_to_sgl is used in the code path that calculates the
shared secret in dh_compute_value. This MPI service function guarantees
that leading zeros are introduced as needed to ensure the resulting data
is exactly as long as the modulus. This implies that the specific code
to add zero padding is dead code which can be safely removed.

Signed-off-by: Stephan Mueller 
---
 security/keys/Kconfig |   2 +-
 security/keys/dh.c| 118 ++
 2 files changed, 17 insertions(+), 103 deletions(-)

diff --git a/security/keys/Kconfig b/security/keys/Kconfig
index 83bc23409164..e6604499f0a8 100644
--- a/security/keys/Kconfig
+++ b/security/keys/Kconfig
@@ -106,7 +106,7 @@ config KEY_DH_OPERATIONS
bool "Diffie-Hellman operations on retained keys"
depends on KEYS
select CRYPTO
-   select CRYPTO_HASH
+   select CRYPTO_KDF800108_CTR
select CRYPTO_DH
help
 This option provides support for calculating Diffie-Hellman
diff --git a/security/keys/dh.c b/security/keys/dh.c
index 1abfa70ed6e1..46fa442b81ec 100644
--- a/security/keys/dh.c
+++ b/security/keys/dh.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "internal.h"
 
@@ -79,16 +80,9 @@ static void dh_crypto_done(struct crypto_async_request *req, 
int err)
complete(>completion);
 }
 
-struct kdf_sdesc {
-   struct shash_desc shash;
-   char ctx[];
-};
-
-static int kdf_alloc(struct kdf_sdesc **sdesc_ret, char *hashname)
+static int kdf_alloc(struct crypto_shash **hash, char *hashname)
 {
struct crypto_shash *tfm;
-   struct kdf_sdesc *sdesc;
-   int size;
int err;
 
/* allocate synchronous hash */
@@ -102,14 +96,7 @@ static int kdf_alloc(struct kdf_sdesc **sdesc_ret, char 
*hashname)
if (crypto_shash_digestsize(tfm) == 0)
goto out_free_tfm;
 
-   err = -ENOMEM;
-   size = sizeof(struct shash_desc) + crypto_shash_descsize(tfm);
-   sdesc = kmalloc(size, GFP_KERNEL);
-   if (!sdesc)
-   goto out_free_tfm;
-   sdesc->shash.tfm = tfm;
-
-   *sdesc_ret = sdesc;
+   *hash = tfm;
 
return 0;
 
@@ -118,92 +105,20 @@ static int kdf_alloc(struct kdf_sdesc **sdesc_ret, char 
*hashname)
return err;
 }
 
-static void kdf_dealloc(struct kdf_sdesc *sdesc)
-{
-   if (!sdesc)
-   return;
-
-   if (sdesc->shash.tfm)
-   crypto_free_shash(sdesc->shash.tfm);
-
-   kfree_sensitive(sdesc);
-}
-
-/*
- * Implementation of the KDF in counter mode according to SP800-108 section 5.1
- * as well as SP800-56A section 5.8.1 (Single-step KDF).
- *
- * SP800-56A:
- * The src pointer is defined as Z || other info where Z is the shared secret
- * from DH and other info is an arbitrary string (see SP800-56A section
- * 5.8.1.2).
- *
- * 'dlen' must be a multiple of the digest size.
- */
-static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen,
-  u8 *dst, unsigned int dlen, unsigned int zlen)
+static void kdf_dealloc(struct crypto_shash *hash)
 {
-   struct shash_desc *desc = >shash;
-   unsigned int h = crypto_shash_digestsize(desc->tfm);
-   int err = 0;
-   u8 *dst_orig = dst;
-   __be32 counter = cpu_to_be32(1);
-
-   while (dlen) {
-   err = crypto_shash_init(desc);
-   if (err)
-   goto err;
-
-   err = crypto_shash_update(desc, (u8 *), sizeof(__be32));
-   if (err)
-   goto err;
-
-   if (zlen && h) {
-   u8 tmpbuffer[32];
-   size_t chunk = min_t(size_t, zlen, sizeof(tmpbuffer));
-   memset(tmpbuffer, 0, chunk);
-
-   do {
-   err = crypto_shash_update(desc, tmpbuffer,
- chunk);
-   if (err)
-   goto err;
-
-   zlen -= chunk;
-   chunk = min_t(size_t, zlen, sizeof(tmpbuffer));
-   } while (zlen);
-   }
-
-   if (src && slen) {
-   err = crypto_shash_update(desc, src, slen);
-   if (err)
-   goto err;
-   

[PATCH 5/5] fs: use HKDF implementation from kernel crypto API

2021-01-04 Thread Stephan Müller
As the kernel crypto API implements HKDF, replace the
file-system-specific HKDF implementation with the generic HKDF
implementation.

Signed-off-by: Stephan Mueller 
---
 fs/crypto/Kconfig   |   2 +-
 fs/crypto/fscrypt_private.h |   4 +-
 fs/crypto/hkdf.c| 108 +---
 3 files changed, 30 insertions(+), 84 deletions(-)

diff --git a/fs/crypto/Kconfig b/fs/crypto/Kconfig
index a5f5c30368a2..9450e958f1d1 100644
--- a/fs/crypto/Kconfig
+++ b/fs/crypto/Kconfig
@@ -2,7 +2,7 @@
 config FS_ENCRYPTION
bool "FS Encryption (Per-file encryption)"
select CRYPTO
-   select CRYPTO_HASH
+   select CRYPTO_HKDF
select CRYPTO_SKCIPHER
select CRYPTO_LIB_SHA256
select KEYS
diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
index 3fa965eb3336..0d6871838099 100644
--- a/fs/crypto/fscrypt_private.h
+++ b/fs/crypto/fscrypt_private.h
@@ -304,7 +304,7 @@ struct fscrypt_hkdf {
struct crypto_shash *hmac_tfm;
 };
 
-int fscrypt_init_hkdf(struct fscrypt_hkdf *hkdf, const u8 *master_key,
+int fscrypt_init_hkdf(struct fscrypt_hkdf *hkdf, u8 *master_key,
  unsigned int master_key_size);
 
 /*
@@ -323,7 +323,7 @@ int fscrypt_init_hkdf(struct fscrypt_hkdf *hkdf, const u8 
*master_key,
 #define HKDF_CONTEXT_INODE_HASH_KEY7 /* info=   */
 
 int fscrypt_hkdf_expand(const struct fscrypt_hkdf *hkdf, u8 context,
-   const u8 *info, unsigned int infolen,
+   u8 *info, unsigned int infolen,
u8 *okm, unsigned int okmlen);
 
 void fscrypt_destroy_hkdf(struct fscrypt_hkdf *hkdf);
diff --git a/fs/crypto/hkdf.c b/fs/crypto/hkdf.c
index e0ec21055505..f837cb8ec0a5 100644
--- a/fs/crypto/hkdf.c
+++ b/fs/crypto/hkdf.c
@@ -9,7 +9,7 @@
  * Copyright 2019 Google LLC
  */
 
-#include 
+#include 
 #include 
 
 #include "fscrypt_private.h"
@@ -37,34 +37,25 @@
  * unnecessarily long master keys.  Thus fscrypt still does HKDF-Extract.  No
  * salt is used, since fscrypt master keys should already be pseudorandom and
  * there's no way to persist a random salt per master key from kernel mode.
- */
-
-/* HKDF-Extract (RFC 5869 section 2.2), unsalted */
-static int hkdf_extract(struct crypto_shash *hmac_tfm, const u8 *ikm,
-   unsigned int ikmlen, u8 prk[HKDF_HASHLEN])
-{
-   static const u8 default_salt[HKDF_HASHLEN];
-   int err;
-
-   err = crypto_shash_setkey(hmac_tfm, default_salt, HKDF_HASHLEN);
-   if (err)
-   return err;
-
-   return crypto_shash_tfm_digest(hmac_tfm, ikm, ikmlen, prk);
-}
-
-/*
+ *
  * Compute HKDF-Extract using the given master key as the input keying 
material,
  * and prepare an HMAC transform object keyed by the resulting pseudorandom 
key.
  *
  * Afterwards, the keyed HMAC transform object can be used for HKDF-Expand many
  * times without having to recompute HKDF-Extract each time.
  */
-int fscrypt_init_hkdf(struct fscrypt_hkdf *hkdf, const u8 *master_key,
+int fscrypt_init_hkdf(struct fscrypt_hkdf *hkdf, u8 *master_key,
  unsigned int master_key_size)
 {
+   /* HKDF-Extract (RFC 5869 section 2.2), unsalted */
+   const struct kvec seed[] = { {
+   .iov_base = NULL,
+   .iov_len = 0
+   }, {
+   .iov_base = master_key,
+   .iov_len = master_key_size
+   } };
struct crypto_shash *hmac_tfm;
-   u8 prk[HKDF_HASHLEN];
int err;
 
hmac_tfm = crypto_alloc_shash(HKDF_HMAC_ALG, 0, 0);
@@ -74,16 +65,12 @@ int fscrypt_init_hkdf(struct fscrypt_hkdf *hkdf, const u8 
*master_key,
return PTR_ERR(hmac_tfm);
}
 
-   if (WARN_ON(crypto_shash_digestsize(hmac_tfm) != sizeof(prk))) {
+   if (WARN_ON(crypto_shash_digestsize(hmac_tfm) != HKDF_HASHLEN)) {
err = -EINVAL;
goto err_free_tfm;
}
 
-   err = hkdf_extract(hmac_tfm, master_key, master_key_size, prk);
-   if (err)
-   goto err_free_tfm;
-
-   err = crypto_shash_setkey(hmac_tfm, prk, sizeof(prk));
+   err = crypto_hkdf_setkey(hmac_tfm, seed, ARRAY_SIZE(seed));
if (err)
goto err_free_tfm;
 
@@ -93,7 +80,6 @@ int fscrypt_init_hkdf(struct fscrypt_hkdf *hkdf, const u8 
*master_key,
 err_free_tfm:
crypto_free_shash(hmac_tfm);
 out:
-   memzero_explicit(prk, sizeof(prk));
return err;
 }
 
@@ -109,65 +95,25 @@ int fscrypt_init_hkdf(struct fscrypt_hkdf *hkdf, const u8 
*master_key,
  * accidentally repeat an info string when using HKDF for different purposes.)
  */
 int fscrypt_hkdf_expand(const struct fscrypt_hkdf *hkdf, u8 context,
-   const u8 *info, unsigned int infolen,
+   u8 *info, unsigned int infolen,
u8 *okm, unsigned int okmlen)
 {
-   SHASH_DESC_ON_STACK(desc, hkdf->hmac_tfm);
-   u8 prefix[9];
-   

Re: [PATCH v4 4/5] crypto: hisilicon/hpre - add 'ECDH' algorithm

2020-12-19 Thread Stephan Müller
Am Donnerstag, 17. Dezember 2020, 04:07:30 CET schrieb yumeng:

Hi yumeng,

> 
> I see in "SEC 2: Recommended Elliptic Curve Domain ParametersVersion2.0"
> that 'Recommend Elliptic Curve Domain Parameters over Fp' are secp192,
> secp224, secp256, secp384, and secp521, secp128 and secp320 are not
> recommended.
> So you mean it's better not to include secp128 and secp320, right?

Precisely because I do not see the use case in the kernel.
> 
> Thanks,


Ciao
Stephan




[PATCH v36 03/13] LRNG - sysctls and /proc interface

2020-10-19 Thread Stephan Müller
The LRNG sysctl interface provides the same controls as the existing
/dev/random implementation. These sysctls behave identically and are
implemented identically. The goal is to allow a possible merge of the
existing /dev/random implementation with this implementation which
implies that this patch tries have a very close similarity. Yet, all
sysctls are documented at [1].

In addition, it provides the file lrng_type which provides details about
the LRNG:

- the name of the DRNG that produces the random numbers for /dev/random,
/dev/urandom, getrandom(2)

- the hash used to produce random numbers from the entropy pool

- the number of secondary DRNG instances

- indicator whether the LRNG operates SP800-90B compliant

- indicator whether a high-resolution timer is identified - only with a
high-resolution timer the interrupt noise source will deliver sufficient
entropy

- indicator whether the LRNG has been minimally seeded (i.e. is the
secondary DRNG seeded with at least 128 bits of of entropy)

- indicator whether the LRNG has been fully seeded (i.e. is the
secondary DRNG seeded with at least 256 bits of entropy)

[1] https://www.chronox.de/lrng.html

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Makefile  |   1 +
 drivers/char/lrng/lrng_interfaces.c |   2 -
 drivers/char/lrng/lrng_internal.h   |   4 +
 drivers/char/lrng/lrng_proc.c   | 182 
 4 files changed, 187 insertions(+), 2 deletions(-)
 create mode 100644 drivers/char/lrng/lrng_proc.c

diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 29724c65287d..ac97f0b11cb7 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -9,3 +9,4 @@ obj-y   += lrng_pool.o lrng_aux.o \
   lrng_interfaces.o
 
 obj-$(CONFIG_NUMA) += lrng_numa.o
+obj-$(CONFIG_SYSCTL)   += lrng_proc.o
diff --git a/drivers/char/lrng/lrng_interfaces.c 
b/drivers/char/lrng/lrng_interfaces.c
index 19d01d3f7492..b55de97523ad 100644
--- a/drivers/char/lrng/lrng_interfaces.c
+++ b/drivers/char/lrng/lrng_interfaces.c
@@ -38,8 +38,6 @@ static DECLARE_WAIT_QUEUE_HEAD(lrng_write_wait);
 static DECLARE_WAIT_QUEUE_HEAD(lrng_init_wait);
 static struct fasync_struct *fasync;
 
-struct ctl_table random_table[];
-
 /** Helper ***/
 
 /* Is the DRNG seed level too low? */
diff --git a/drivers/char/lrng/lrng_internal.h 
b/drivers/char/lrng/lrng_internal.h
index f858effcf710..2f8c14ffbaf3 100644
--- a/drivers/char/lrng/lrng_internal.h
+++ b/drivers/char/lrng/lrng_internal.h
@@ -113,7 +113,11 @@ void lrng_cc20_init_state_boot(struct chacha20_state 
*state);
 
 /** /proc 
*/
 
+#ifdef CONFIG_SYSCTL
+void lrng_pool_inc_numa_node(void);
+#else
 static inline void lrng_pool_inc_numa_node(void) { }
+#endif
 
 /** LRNG interfaces 
***/
 
diff --git a/drivers/char/lrng/lrng_proc.c b/drivers/char/lrng/lrng_proc.c
new file mode 100644
index ..b2985a2ae0f7
--- /dev/null
+++ b/drivers/char/lrng/lrng_proc.c
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG proc and sysctl interfaces
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "lrng_internal.h"
+#include "lrng_sw_noise.h"
+
+/*
+ * This function is used to return both the bootid UUID, and random
+ * UUID.  The difference is in whether table->data is NULL; if it is,
+ * then a new UUID is generated and returned to the user.
+ *
+ * If the user accesses this via the proc interface, the UUID will be
+ * returned as an ASCII string in the standard UUID format; if via the
+ * sysctl system call, as 16 bytes of binary data.
+ */
+static int lrng_proc_do_uuid(struct ctl_table *table, int write,
+void *buffer, size_t *lenp, loff_t *ppos)
+{
+   struct ctl_table fake_table;
+   unsigned char buf[64], tmp_uuid[16], *uuid;
+
+   uuid = table->data;
+   if (!uuid) {
+   uuid = tmp_uuid;
+   generate_random_uuid(uuid);
+   } else {
+   static DEFINE_SPINLOCK(bootid_spinlock);
+
+   spin_lock(_spinlock);
+   if (!uuid[8])
+   generate_random_uuid(uuid);
+   

[PATCH v36 06/13] crypto: DRBG - externalize DRBG functions for LRNG

2020-10-19 Thread Stephan Müller
This patch allows several DRBG functions to be called by the LRNG kernel
code paths outside the drbg.c file.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 crypto/drbg.c | 16 ++--
 include/crypto/drbg.h |  7 +++
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index 3132967a1749..58b1de903def 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[] = {
+const struct drbg_core drbg_cores[] = {
 #ifdef CONFIG_CRYPTO_DRBG_CTR
{
.flags = DRBG_CTR | DRBG_STRENGTH128,
@@ -190,6 +190,7 @@ static const struct drbg_core drbg_cores[] = {
},
 #endif /* CONFIG_CRYPTO_DRBG_HMAC */
 };
+EXPORT_SYMBOL(drbg_cores);
 
 static int drbg_uninstantiate(struct drbg_state *drbg);
 
@@ -205,7 +206,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:
@@ -218,6 +219,7 @@ static inline unsigned short drbg_sec_strength(drbg_flag_t 
flags)
return 32;
}
 }
+EXPORT_SYMBOL(drbg_sec_strength);
 
 /*
  * FIPS 140-2 continuous self test for the noise source
@@ -1214,7 +1216,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;
@@ -1235,12 +1237,13 @@ static inline void drbg_dealloc_state(struct drbg_state 
*drbg)
drbg->fips_primed = false;
}
 }
+EXPORT_SYMBOL(drbg_dealloc_state);
 
 /*
  * 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;
@@ -1321,6 +1324,7 @@ static inline int drbg_alloc_state(struct drbg_state 
*drbg)
drbg_dealloc_state(drbg);
return ret;
 }
+EXPORT_SYMBOL(drbg_alloc_state);
 
 /*
  * DRBG interface functions
@@ -1890,8 +1894,7 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
  *
  * 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;
@@ -1918,6 +1921,7 @@ static inline void drbg_convert_tfm_core(const char 
*cra_driver_name,
}
}
 }
+EXPORT_SYMBOL(drbg_convert_tfm_core);
 
 static int drbg_kcapi_init(struct crypto_tfm *tfm)
 {
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index c4165126937e..71d53e028e6d 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -278,4 +278,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 const struct drbg_core drbg_cores[];
+extern unsigned short drbg_sec_strength(drbg_flag_t flags);
+
 #endif /* _DRBG_H */
-- 
2.26.2






[PATCH v36 01/13] Linux Random Number Generator

2020-10-19 Thread Stephan Müller
In an effort to provide a flexible implementation for a random number
generator that also delivers entropy during early boot time, allows
replacement of the deterministic random number generation mechanism,
implement the various components in separate code for easier
maintenance, and provide compliance to SP800-90[A|B|C], introduce
the Linux Random Number Generator (LRNG) framework.

The general design is as follows. Additional implementation details
are given in [1]. The LRNG consists of the following components:

1. The LRNG implements a DRNG. The DRNG always generates the
requested amount of output. When using the SP800-90A terminology
it operates without prediction resistance. The secondary DRNG
maintains a counter of how many bytes were generated since last
re-seed and a timer of the elapsed time since last re-seed. If either
the counter or the timer reaches a threshold, the secondary DRNG is
seeded from the entropy pool.

In case the Linux kernel detects a NUMA system, one secondary DRNG
instance per NUMA node is maintained.

2. The DRNG is seeded by concatenating the data from the
following sources:

(a) the output of the entropy pool,

(b) the Jitter RNG if available and enabled, and

(c) the CPU-based noise source such as Intel RDRAND if available and
enabled.

The entropy estimate of the data of all noise sources are added to
form the entropy estimate of the data used to seed the DRNG with.
The LRNG ensures, however, that the DRNG after seeding is at
maximum the security strength of the DRNG.

The LRNG is designed such that none of these noise sources can dominate
the other noise sources to provide seed data to the DRNG during due to
the following:

(a) During boot time, the amount of received interrupts are the trigger
points to (re)seed the DRNG.

(b) At runtime, the available entropy from the slow noise source is
concatenated with a pre-defined amount of data from the fast noise
sources. In addition, each DRNG reseed operation triggers external
noise source providers to deliver one block of data.

3. The entropy pool accumulates entropy obtained from certain events,
which will henceforth be collectively called "slow noise sources".
The entropy pool collects noise data from slow noise sources. Any data
received by the LRNG from the slow noise sources is inserted into a
per-CPU entropy pool using a hash operation that can be changed during
runtime. Per default, SHA-256 is used.

 (a) When an interrupt occurs, the high-resolution time stamp is mixed
into the per-CPU entropy pool. This time stamp is credited with
heuristically implied entropy.

 (b) HID event data like the key stroke or the mouse coordinates are
mixed into the per-CPU entropy pool. This data is not credited with
entropy by the LRNG.

 (c) Device drivers may provide data that is mixed into an auxiliary
pool using the same hash that is used to process the per-CPU entropy
pool. This data is not credited with entropy by the LRNG.

Any data provided from user space by either writing to /dev/random,
/dev/urandom or the IOCTL of RNDADDENTROPY on both device files
are always injected into the auxiliary pool.

In addition, when a hardware random number generator covered by the
Linux kernel HW generator framework wants to deliver random numbers,
it is injected into the auxiliary pool as well. HW generator noise source
is handled separately from the other noise source due to the fact that
the HW generator framework may decide by itself when to deliver data
whereas the other noise sources always requested for data driven by the
LRNG operation. Similarly any user space provided data is inserted into
the entropy pool.

When seed data for the DRNG is to be generated, all per-CPU
entropy pools and the auxiliary pool are hashed. The message digest
forms the new auxiliary pool state. At the same time, this data
is used for seeding the DRNG.

To speed up the interrupt handling code of the LRNG, the time stamp
collected for an interrupt event is truncated to the 8 least
significant bits. 64 truncated time stamps are concatenated and then
jointly inserted into the per-CPU entropy pool. During boot time,
until the fully seeded stage is reached, each time stamp with its
32 least significant bits is are concatenated. When 16 such events
are received, they are injected into the per-CPU entropy pool.

The LRNG allows the DRNG mechanism to be changed at runtime. Per default,
a ChaCha20-based DRNG is used. The ChaCha20-DRNG implemented for the
LRNG is also provided as a stand-alone user space deterministic random
number generator. The LRNG also offers an SP800-90A DRBG based on the
Linux kernel crypto API DRBG implementation.

The processing of entropic data from the noise source before injecting
them into the DRNG is performed with the following mathematical
operations:

1. Truncation: The received time stamps are truncated to 8 least
significant bits (or 32 least significant bits during boot time)

2. Concatenation: The received and truncated time stamps 

[PATCH v36 02/13] LRNG - allocate one DRNG instance per NUMA node

2020-10-19 Thread Stephan Müller
In order to improve NUMA-locality when serving getrandom(2) requests,
allocate one DRNG instance per node.

The DRNG instance that is present right from the start of the kernel is
reused as the first per-NUMA-node DRNG. For all remaining online NUMA
nodes a new DRNG instance is allocated.

During boot time, the multiple DRNG instances are seeded sequentially.
With this, the first DRNG instance (referenced as the initial DRNG
in the code) is completely seeded with 256 bits of entropy before the
next DRNG instance is completely seeded.

When random numbers are requested, the NUMA-node-local DRNG is checked
whether it has been already fully seeded. If this is not the case, the
initial DRNG is used to serve the request.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
CC: Eric Biggers 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Makefile|   2 +
 drivers/char/lrng/lrng_internal.h |   5 ++
 drivers/char/lrng/lrng_numa.c | 108 ++
 3 files changed, 115 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_numa.c

diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index e72e01c15bb9..29724c65287d 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -7,3 +7,5 @@ obj-y   += lrng_pool.o lrng_aux.o \
   lrng_sw_noise.o lrng_archrandom.o \
   lrng_drng.o lrng_chacha20.o \
   lrng_interfaces.o
+
+obj-$(CONFIG_NUMA) += lrng_numa.o
diff --git a/drivers/char/lrng/lrng_internal.h 
b/drivers/char/lrng/lrng_internal.h
index f9b80ce42341..f858effcf710 100644
--- a/drivers/char/lrng/lrng_internal.h
+++ b/drivers/char/lrng/lrng_internal.h
@@ -219,8 +219,13 @@ int lrng_drng_get_sleep(u8 *outbuf, u32 outbuflen);
 void lrng_drng_force_reseed(void);
 void lrng_drng_seed_work(struct work_struct *dummy);
 
+#ifdef CONFIG_NUMA
+struct lrng_drng **lrng_drng_instances(void);
+void lrng_drngs_numa_alloc(void);
+#else  /* CONFIG_NUMA */
 static inline struct lrng_drng **lrng_drng_instances(void) { return NULL; }
 static inline void lrng_drngs_numa_alloc(void) { return; }
+#endif /* CONFIG_NUMA */
 
 /** Entropy pool management 
***/
 
diff --git a/drivers/char/lrng/lrng_numa.c b/drivers/char/lrng/lrng_numa.c
new file mode 100644
index ..7f1f0dade1b6
--- /dev/null
+++ b/drivers/char/lrng/lrng_numa.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG NUMA support
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+
+#include "lrng_internal.h"
+
+static struct lrng_drng **lrng_drng __read_mostly = NULL;
+
+struct lrng_drng **lrng_drng_instances(void)
+{
+   return smp_load_acquire(_drng);
+}
+
+/* Allocate the data structures for the per-NUMA node DRNGs */
+static void _lrng_drngs_numa_alloc(struct work_struct *work)
+{
+   struct lrng_drng **drngs;
+   struct lrng_drng *lrng_drng_init = lrng_drng_init_instance();
+   u32 node;
+   bool init_drng_used = false;
+
+   mutex_lock(_crypto_cb_update);
+
+   /* per-NUMA-node DRNGs are already present */
+   if (lrng_drng)
+   goto unlock;
+
+   drngs = kcalloc(nr_node_ids, sizeof(void *), GFP_KERNEL|__GFP_NOFAIL);
+   for_each_online_node(node) {
+   struct lrng_drng *drng;
+
+   if (!init_drng_used) {
+   drngs[node] = lrng_drng_init;
+   init_drng_used = true;
+   continue;
+   }
+
+   drng = kmalloc_node(sizeof(struct lrng_drng),
+GFP_KERNEL|__GFP_NOFAIL, node);
+   memset(drng, 0, sizeof(lrng_drng));
+
+   drng->crypto_cb = lrng_drng_init->crypto_cb;
+   drng->drng = drng->crypto_cb->lrng_drng_alloc(
+   LRNG_DRNG_SECURITY_STRENGTH_BYTES);
+   if (IS_ERR(drng->drng)) {
+   kfree(drng);
+   goto err;
+   }
+
+   drng->hash = drng->crypto_cb->lrng_hash_alloc();
+   if (IS_ERR(drng->hash)) {
+   drng->crypto_cb->lrng_drng_dealloc(drng->drng);
+   kfree(drng);
+   goto err;
+   }
+
+   mutex_init(>lock);
+   

[PATCH v36 11/13] LRNG - add SP800-90B compliant health tests

2020-10-19 Thread Stephan Müller
Implement health tests for LRNG's slow noise sources as mandated by
SP-800-90B The file contains the following health tests:

- stuck test: The stuck test calculates the first, second and third
  discrete derivative of the time stamp to be processed by the hash
  for the per-CPU entropy pool. Only if all three values are non-zero,
  the received time delta is considered to be non-stuck.

- SP800-90B Repetition Count Test (RCT): The LRNG uses an enhanced
  version of the RCT specified in SP800-90B section 4.4.1. Instead of
  counting identical back-to-back values, the input to the RCT is the
  counting of the stuck values during the processing of received
  interrupt events. The RCT is applied with alpha=2^-30 compliant to
  the recommendation of FIPS 140-2 IG 9.8. During the counting operation,
  the LRNG always calculates the RCT cut-off value of C. If that value
  exceeds the allowed cut-off value, the LRNG will trigger the health
  test failure discussed below. An error is logged to the kernel log
  that such RCT failure occurred. This test is only applied and
  enforced in FIPS mode, i.e. when the kernel compiled with
  CONFIG_CONFIG_FIPS is started with fips=1.

- SP800-90B Adaptive Proportion Test (APT): The LRNG implements the
  APT as defined in SP800-90B section 4.4.2. The applied significance
  level again is alpha=2^-30 compliant to the recommendation of FIPS
  140-2 IG 9.8.

The aforementioned health tests are applied to the first 1,024 time stamps
obtained from interrupt events. In case one error is identified for either
the RCT, or the APT, the collected entropy is invalidated and the
SP800-90B startup health test is restarted.

As long as the SP800-90B startup health test is not completed, all LRNG
random number output interfaces that may block will block and not generate
any data. This implies that only those potentially blocking interfaces are
defined to provide random numbers that are seeded with the interrupt noise
source being SP800-90B compliant. All other output interfaces will not be
affected by the SP800-90B startup test and thus are not considered
SP800-90B compliant.

At runtime, the SP800-90B APT and RCT are applied to each time stamp
generated for a received interrupt. When either the APT and RCT indicates
a noise source failure, the LRNG is reset to a state it has immediately
after boot:

- all entropy counters are set to zero

- the SP800-90B startup tests are re-performed which implies that
getrandom(2) would block again until new entropy was collected

To summarize, the following rules apply:

• SP800-90B compliant output interfaces

  - /dev/random

  - getrandom(2) system call

  -  get_random_bytes kernel-internal interface when being triggered by
 the callback registered with add_random_ready_callback

• SP800-90B non-compliant output interfaces

  - /dev/urandom

  - get_random_bytes kernel-internal interface called directly

  - randomize_page kernel-internal interface

  - get_random_u32 and get_random_u64 kernel-internal interfaces

  - get_random_u32_wait, get_random_u64_wait, get_random_int_wait, and
get_random_long_wait kernel-internal interfaces

If either the RCT, or the APT health test fails irrespective whether
during initialization or runtime, the following actions occur:

  1. The entropy of the entire entropy pool is invalidated.

  2. All DRNGs are reset which imply that they are treated as being
 not seeded and require a reseed during next invocation.

  3. The SP800-90B startup health test are initiated with all
 implications of the startup tests. That implies that from that point
 on, new events must be observed and its entropy must be inserted into
 the entropy pool before random numbers are calculated from the
 entropy pool.

Further details on the SP800-90B compliance and the availability of all
test tools required to perform all tests mandated by SP800-90B are
provided at [1].

The entire health testing code is compile-time configurable.

The patch provides a CONFIG_BROKEN configuration of the APT / RCT cutoff
values which have a high likelihood to trigger the health test failure.
The BROKEN APT cutoff is set to the exact mean of the expected value if
the time stamps are equally distributed (512 time stamps divided by 16
possible values due to using the 4 LSB of the time stamp). The BROKEN
RCT cutoff value is set to 1 which is likely to be triggered during
regular operation.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig   |  56 +
 

[PATCH v36 07/13] LRNG - add SP800-90A DRBG extension

2020-10-19 Thread Stephan Müller
Using the LRNG switchable DRNG support, the SP800-90A DRBG extension is
implemented.

The DRBG uses the kernel crypto API DRBG implementation. In addition, it
uses the kernel crypto API SHASH support to provide the hashing
operation.

The DRBG supports the choice of either a CTR DRBG using AES-256, HMAC
DRBG with SHA-512 core or Hash DRBG with SHA-512 core. The used core can
be selected with the module parameter lrng_drbg_type. The default is the
CTR DRBG.

When compiling the DRBG extension statically, the DRBG is loaded at
late_initcall stage which implies that with the start of user space, the
user space interfaces of getrandom(2), /dev/random and /dev/urandom
provide random data produced by an SP800-90A DRBG.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig |  10 ++
 drivers/char/lrng/Makefile|   1 +
 drivers/char/lrng/lrng_drbg.c | 197 ++
 3 files changed, 208 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_drbg.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index daa2057248ac..a3c4cd153f35 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -81,6 +81,16 @@ if LRNG_DRNG_SWITCH
 config LRNG_KCAPI_HASH
bool
 
+config LRNG_DRBG
+   tristate "SP800-90A support for the LRNG"
+   depends on CRYPTO
+   select CRYPTO_DRBG_MENU
+   select CRYPTO_SHA512
+   select LRNG_KCAPI_HASH
+   help
+ Enable the SP800-90A DRBG support for the LRNG. Once the
+ module is loaded, output from /dev/random, /dev/urandom,
+ getrandom(2), or get_random_bytes_full is provided by a DRBG.
 endif # LRNG_DRNG_SWITCH
 
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 40f8826edeeb..6ebd252db12f 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_NUMA)+= lrng_numa.o
 obj-$(CONFIG_SYSCTL)   += lrng_proc.o
 obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
 obj-$(CONFIG_LRNG_KCAPI_HASH)  += lrng_kcapi_hash.o
+obj-$(CONFIG_LRNG_DRBG)+= lrng_drbg.o
diff --git a/drivers/char/lrng/lrng_drbg.c b/drivers/char/lrng/lrng_drbg.c
new file mode 100644
index ..c428d41af64d
--- /dev/null
+++ b/drivers/char/lrng/lrng_drbg.c
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Backend for the LRNG providing the cryptographic primitives using the
+ * kernel crypto API and its DRBG.
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+
+#include "lrng_kcapi_hash.h"
+
+/*
+ * Define a DRBG plus a hash / MAC used to extract data from the entropy pool.
+ * For LRNG_HASH_NAME you can use a hash or a MAC (HMAC or CMAC) of your choice
+ * (Note, you should use the suggested selections below -- using SHA-1 or MD5
+ * is not wise). The idea is that the used cipher primitive can be selected to
+ * be the same as used for the DRBG. I.e. the LRNG only uses one cipher
+ * primitive using the same cipher implementation with the options offered in
+ * the following. This means, if the CTR DRBG is selected and AES-NI is 
present,
+ * both the CTR DRBG and the selected cmac(aes) use AES-NI.
+ *
+ * The security strengths of the DRBGs are all 256 bits according to
+ * SP800-57 section 5.6.1.
+ *
+ * This definition is allowed to be changed.
+ */
+#ifdef CONFIG_CRYPTO_DRBG_CTR
+static unsigned int lrng_drbg_type = 0;
+#elif defined CONFIG_CRYPTO_DRBG_HMAC
+static unsigned int lrng_drbg_type = 1;
+#elif defined CONFIG_CRYPTO_DRBG_HASH
+static unsigned int lrng_drbg_type = 2;
+#else
+#error "Unknown DRBG in use"
+#endif
+
+/* The parameter must be r/o in sysfs as otherwise races appear. */
+module_param(lrng_drbg_type, uint, 0444);
+MODULE_PARM_DESC(lrng_drbg_type, "DRBG type used for LRNG (0->CTR_DRBG, 
1->HMAC_DRBG, 2->Hash_DRBG)");
+
+struct lrng_drbg {
+   const char *hash_name;
+   const char *drbg_core;
+};
+
+static const struct lrng_drbg lrng_drbg_types[] = {
+   {   /* CTR_DRBG with AES-256 using derivation function */
+   .hash_name = "sha512",
+   .drbg_core = "drbg_nopr_ctr_aes256",
+   }, {/* HMAC_DRBG with SHA-512 */
+   .hash_name = "sha512",
+   .drbg_core = "drbg_nopr_hmac_sha512",
+   }, {/* Hash_DRBG with SHA-512 using derivation function */
+   .hash_name = "sha512",
+   

[PATCH v36 04/13] LRNG - add switchable DRNG support

2020-10-19 Thread Stephan Müller
The DRNG switch support allows replacing the DRNG mechanism of the
LRNG. The switching support rests on the interface definition of
include/linux/lrng.h. A new DRNG is implemented by filling in the
interface defined in this header file.

In addition to the DRNG, the extension also has to provide a hash
implementation that is used to hash the entropy pool for random number
extraction.

Note: It is permissible to implement a DRNG whose operations may sleep.
However, the hash function must not sleep.

The switchable DRNG support allows replacing the DRNG at runtime.
However, only one DRNG extension is allowed to be loaded at any given
time. Before replacing it with another DRNG implementation, the possibly
existing DRNG extension must be unloaded.

The switchable DRNG extension activates the new DRNG during load time.
It is expected, however, that such a DRNG switch would be done only once
by an administrator to load the intended DRNG implementation.

It is permissible to compile DRNG extensions either as kernel modules or
statically. The initialization of the DRNG extension should be performed
with a late_initcall to ensure the extension is available when user
space starts but after all other initialization completed.
The initialization is performed by registering the function call data
structure with the lrng_set_drng_cb function. In order to unload the
DRNG extension, lrng_set_drng_cb must be invoked with the NULL
parameter.

The DRNG extension should always provide a security strength that is at
least as strong as LRNG_DRNG_SECURITY_STRENGTH_BITS.

The hash extension must not sleep and must not maintain a separate
state.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig   |   7 ++
 drivers/char/lrng/Makefile  |   1 +
 drivers/char/lrng/lrng_switch.c | 203 
 3 files changed, 211 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_switch.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index fbbcf2ef43b6..e211fcf5aa8b 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -69,4 +69,11 @@ config LRNG_COLLECTION_SIZE
default 512 if LRNG_COLLECTION_SIZE_512
default 1024 if LRNG_COLLECTION_SIZE_1024
 
+menuconfig LRNG_DRNG_SWITCH
+   bool "Support DRNG runtime switching"
+   help
+ The Linux RNG per default uses a ChaCha20 DRNG that is
+ accessible via the external interfaces. With this configuration
+ option other DRNGs can be selected and loaded at runtime.
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index ac97f0b11cb7..0eb4a6849c88 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -10,3 +10,4 @@ obj-y += lrng_pool.o lrng_aux.o \
 
 obj-$(CONFIG_NUMA) += lrng_numa.o
 obj-$(CONFIG_SYSCTL)   += lrng_proc.o
+obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
diff --git a/drivers/char/lrng/lrng_switch.c b/drivers/char/lrng/lrng_switch.c
new file mode 100644
index ..cbaf5cd544aa
--- /dev/null
+++ b/drivers/char/lrng/lrng_switch.c
@@ -0,0 +1,203 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG DRNG switching support
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+
+#include "lrng_internal.h"
+
+static int lrng_drng_switch(struct lrng_drng *drng_store,
+   const struct lrng_crypto_cb *cb, int node)
+{
+   const struct lrng_crypto_cb *old_cb;
+   unsigned long flags = 0, flags2 = 0;
+   int ret;
+   u8 seed[LRNG_DRNG_SECURITY_STRENGTH_BYTES];
+   void *new_drng = cb->lrng_drng_alloc(LRNG_DRNG_SECURITY_STRENGTH_BYTES);
+   void *old_drng, *new_hash, *old_hash;
+   u32 current_security_strength;
+   bool sl = false, reset_drng = !lrng_get_available();
+
+   if (IS_ERR(new_drng)) {
+   pr_warn("could not allocate new DRNG for NUMA node %d (%ld)\n",
+   node, PTR_ERR(new_drng));
+   return PTR_ERR(new_drng);
+   }
+
+   new_hash = cb->lrng_hash_alloc();
+   if (IS_ERR(new_hash)) {
+   pr_warn("could not allocate new LRNG pool hash (%ld)\n",
+   PTR_ERR(new_hash));
+   cb->lrng_drng_dealloc(new_drng);
+   return PTR_ERR(new_hash);
+   }
+
+   if (cb->lrng_hash_digestsize(new_hash) > 

[PATCH v36 12/13] LRNG - add interface for gathering of raw entropy

2020-10-19 Thread Stephan Müller
The test interface allows a privileged process to capture the raw
unconditioned noise that is collected by the LRNG for statistical
analysis. Such testing allows the analysis how much entropy
the interrupt noise source provides on a given platform.
Extracted noise data is not used to seed the LRNG. This
is a test interface and not appropriate for production systems.
Yet, the interface is considered to be sufficiently secured for
production systems.

Access to the data is given through the lrng_raw debugfs file. The
data buffer should be multiples of sizeof(u32) to fill the entire
buffer. Using the option lrng_testing.boot_test=1 the raw noise of
the first 1000 entropy events since boot can be sampled.

This test interface allows generating the data required for
analysis whether the LRNG is in compliance with SP800-90B
sections 3.1.3 and 3.1.4.

In addition, the test interface allows gathering of the concatenated raw
entropy data to verify that the concatenation works appropriately.
This includes sampling of the following raw data:

* high-resolution time stamp

* Jiffies

* IRQ number

* IRQ flags

* return instruction pointer

* interrupt register state

* array logic batching the high-resolution time stamp

Also, a testing interface to support ACVT of the hash implementation
is provided. The reason why only hash testing is supported (as
opposed to also provide testing for the DRNG) is the fact that the
LRNG software hash implementation contains glue code that may
warrant testing in addition to the testing of the software ciphers
via the kernel crypto API. Also, for testing the CTR-DRBG, the
underlying AES implementation would need to be tested. However,
such AES test interface cannot be provided by the LRNG as it has no
means to access the AES operation.

Finally, the execution duration for processing a time stamp can be
obtained with the LRNG raw entropy interface.

If a test interface is not compiled, its code is a noop which has no
impact on the performance.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig| 150 +++
 drivers/char/lrng/Makefile   |   1 +
 drivers/char/lrng/lrng_testing.c | 689 +++
 3 files changed, 840 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_testing.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index a059da0b2f5d..bb785bc61abb 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -174,4 +174,154 @@ config LRNG_APT_CUTOFF
default 325 if !LRNG_APT_BROKEN
default 32 if LRNG_APT_BROKEN
 
+menuconfig LRNG_TESTING_MENU
+   bool "LRNG testing interfaces"
+   depends on DEBUG_FS
+   help
+ Enable one or more of the following test interfaces.
+
+ If unsure, say N.
+
+if LRNG_TESTING_MENU
+
+config LRNG_RAW_HIRES_ENTROPY
+   bool "Enable entropy test interface to hires timer noise source"
+   default y
+   help
+ The test interface allows a privileged process to capture
+ the raw unconditioned high resolution time stamp noise that
+ is collected by the LRNG for statistical analysis. Extracted
+ noise data is not used to seed the LRNG.
+
+ The raw noise data can be obtained using the lrng_raw_hires
+ debugfs file. Using the option lrng_testing.boot_raw_hires_test=1
+ the raw noise of the first 1000 entropy events since boot
+ can be sampled.
+
+config LRNG_RAW_JIFFIES_ENTROPY
+   bool "Enable entropy test interface to Jiffies noise source"
+   help
+ The test interface allows a privileged process to capture
+ the raw unconditioned Jiffies that is collected by
+ the LRNG for statistical analysis. This data is used for
+ seeding the LRNG if a high-resolution time stamp is not
+ available. If a high-resolution time stamp is detected,
+ the Jiffies value is not collected by the LRNG and no
+ data is provided via the test interface. Extracted noise
+ data is not used to seed the random number generator.
+
+ The raw noise data can be obtained using the lrng_raw_jiffies
+ debugfs file. Using the option lrng_testing.boot_raw_jiffies_test=1
+ the raw noise of the first 1000 entropy events since boot
+ can be sampled.
+
+config LRNG_RAW_IRQ_ENTROPY
+   bool "Enable entropy test interface to IRQ number noise source"
+   help
+ The test interface allows a privileged process to capture
+

[PATCH v36 00/13] /dev/random - a new approach

2020-10-19 Thread Stephan Müller
Hi,

The following patch set provides a different approach to /dev/random which
is called Linux Random Number Generator (LRNG) to collect entropy within
the Linux kernel. It provides the same API and ABI and can be used as a
drop-in replacement.

The LRNG implements at least all features of the existing /dev/random such as
NUMA-node-local DRNGs. Patches 1 through 3 provide the code that is feature-
identical. The following advantages compared to the existing /dev/random
implementation are present:

* Sole use of crypto for data processing:

 - Exclusive use of a hash operation for conditioning entropy data with
   a clear mathematical description as given in [2] section 2.2 -
   non-cryptographic operations like LFSR are not used.

 - The LRNG uses only properly defined and implemented cryptographic
   algorithms unlike the use of the SHA-1 transformation in the existing
   /dev/random implementation.

 - Hash operations use NUMA-node-local hash instances to benefit large
   parallel systems.

 - LRNG uses limited number of data post-processing steps as documented in
   [2] section 2.2 compared to the large variation of different
   post-processing steps in the existing /dev/random implementation that
   have no apparent mathematical description (see [2] section 4.5).

* Performance

 - Faster by up to 75% in the critical code path of the interrupt handler
   depending on data collection size configurable at kernel compile time -
   the default is about equal in performance with existing /dev/random as
   outlined in [2] section 4.2.

 - Configurable data collection sizes to accommodate small environments
   and big environments via CONFIG_LRNG_COLLECTION_SIZE.

 - Entropy collection using an almost never contended lock to benefit
   large parallel systems – worst case rate of contention is the number
   of DRNG reseeds, usually the number of potential contentions per 10
   minutes is equal to number of NUMA nodes.

 - ChaCha20 DRNG is significantly faster as implemented in the existing
   /dev/random as demonstrated with [2] table 2.

 - Faster entropy collection during boot time to reach fully seeded
   level, including on virtual systems or systems with SSDs as outlined
   in [2] section 4.1.

* Testing

 - Availablility of run-time health tests of the raw unconditioned
   noise source to identify degradation of the available entropy as
   documented in [2] section 2.5.4. Such health tests are important
   today due to virtual machine monitors reducing the resolution of
   or disabling the high-resolution timer.

 - Heuristic entropy estimation is based on quantitative measurements
   and analysis following SP800-90B and not on coincidental
   underestimation of entropy applied by the existing /dev/random as
   outlined in [4] section 4.4.

 - Power-on self tests for critical deterministic components (ChaCha20
   DRNG, software hash implementation, and entropy collection logic)
   not already covered by power-up tests of the kernel crypto API as
   documented in [2] section 2.14.

 - Availability of test interfaces for all operational stages of the
   LRNG including boot-time raw entropy event data sampling as outlined
   in [2] section 2.15.

 - Fully testable ChaCha20 DRNG via a userspace ChaCha20 DRNG
   implementation [3].

 - In case of using the kernel crypto API SHASH hash implementation, it
   is fully testable and tested via the NIST ACVP test framework, for
   example certificates A734, A737, and A738.

 - The LRNG offers a test interface to validate the used software hash
   implementation and in particular that the LRNG invokes the hash
   correctly, allowing a NIST ACVP-compliant test cycle - see [2]
   section 2.15.

 - Availability of stress testing covering the different code paths for
   data and mechanism (de)allocations and code paths covered with locks.

* Entropy collection

 - The LRNG is shipped with test tools allowing the collection of
   raw unconditioned entropy during runtime and boot time available at
   [1].

 - Full entropy assessment and description is provided with [2] chapter 3,
   specifically section 3.2.6.

 - Guarantee that entropy events are not credited with entropy twice
   (the existing /dev/random implementation credits HID/disk and
   interrupt events with entropy which are a derivative of each other)
   and guarantee that entropy data is not reused for two different use
   cases (as done in the existing /dev/random implementation when
   injecting a part of fast_pool into the net_rand_state).

* Configurable

 - LRNG kernel configuration allows configuration that is functionally
   equivalent to the existing /dev/random. Non-compiled additional code
   is folded into no-ops.

 - The following additional functions are compile-time selectable
   independent of each other:

  + Enabling of switchable cryptographic implementation support. This
allows enabling an SP800-90A DRBG.

  + Enabling of using Jitter RNG noise source.

  + Enabling of noise source 

[PATCH v36 10/13] LRNG - add Jitter RNG fast noise source

2020-10-19 Thread Stephan Müller
The Jitter RNG fast noise source implemented as part of the kernel
crypto API is queried for 256 bits of entropy at the time the seed
buffer managed by the LRNG is about to be filled.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig | 12 +
 drivers/char/lrng/Makefile|  1 +
 drivers/char/lrng/lrng_jent.c | 88 +++
 3 files changed, 101 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_jent.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index af487b3391e0..87682f57efb8 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -106,4 +106,16 @@ config LRNG_KCAPI
  provided by the selected kernel crypto API RNG.
 endif # LRNG_DRNG_SWITCH
 
+config LRNG_JENT
+   bool "Enable Jitter RNG as LRNG Seed Source"
+   depends on CRYPTO
+   select CRYPTO_JITTERENTROPY
+   help
+ The Linux RNG may use the Jitter RNG as noise source. Enabling
+ this option enables the use of the Jitter RNG. Its default
+ entropy level is 16 bits of entropy per 256 data bits delivered
+ by the Jitter RNG. This entropy level can be changed at boot
+ time or at runtime with the lrng_base.jitterrng configuration
+ variable.
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 97d2b13d3227..6be88156010a 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_LRNG_DRNG_SWITCH)+= lrng_switch.o
 obj-$(CONFIG_LRNG_KCAPI_HASH)  += lrng_kcapi_hash.o
 obj-$(CONFIG_LRNG_DRBG)+= lrng_drbg.o
 obj-$(CONFIG_LRNG_KCAPI)   += lrng_kcapi.o
+obj-$(CONFIG_LRNG_JENT)+= lrng_jent.o
diff --git a/drivers/char/lrng/lrng_jent.c b/drivers/char/lrng/lrng_jent.c
new file mode 100644
index ..225505271fcb
--- /dev/null
+++ b/drivers/char/lrng/lrng_jent.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG Fast Noise Source: Jitter RNG
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+
+#include "lrng_internal.h"
+
+/*
+ * Estimated entropy of data is a 16th of LRNG_DRNG_SECURITY_STRENGTH_BITS.
+ * Albeit a full entropy assessment is provided for the noise source indicating
+ * that it provides high entropy rates and considering that it deactivates
+ * when it detects insufficient hardware, the chosen under estimation of
+ * entropy is considered to be acceptable to all reviewers.
+ */
+static u32 jitterrng = LRNG_DRNG_SECURITY_STRENGTH_BITS>>4;
+module_param(jitterrng, uint, 0644);
+MODULE_PARM_DESC(jitterrng, "Entropy in bits of 256 data bits from Jitter RNG 
noise source");
+
+/**
+ * lrng_get_jent() - Get Jitter RNG entropy
+ *
+ * @outbuf: buffer to store entropy
+ * @outbuflen: length of buffer
+ *
+ * Return:
+ * * > 0 on success where value provides the added entropy in bits
+ * * 0 if no fast source was available
+ */
+static struct rand_data *lrng_jent_state;
+
+u32 lrng_get_jent(u8 *outbuf, unsigned int outbuflen)
+{
+   int ret;
+   u32 ent_bits = jitterrng;
+   unsigned long flags;
+   static DEFINE_SPINLOCK(lrng_jent_lock);
+   static int lrng_jent_initialized = 0;
+
+   spin_lock_irqsave(_jent_lock, flags);
+
+   if (!ent_bits || (lrng_jent_initialized == -1)) {
+   spin_unlock_irqrestore(_jent_lock, flags);
+   return 0;
+   }
+
+   if (!lrng_jent_initialized) {
+   lrng_jent_state = jent_lrng_entropy_collector();
+   if (!lrng_jent_state) {
+   jitterrng = 0;
+   lrng_jent_initialized = -1;
+   spin_unlock_irqrestore(_jent_lock, flags);
+   pr_info("Jitter RNG unusable on current system\n");
+   return 0;
+   }
+   lrng_jent_initialized = 1;
+   pr_debug("Jitter RNG working on current system\n");
+   }
+   ret = jent_read_entropy(lrng_jent_state, outbuf, outbuflen);
+   spin_unlock_irqrestore(_jent_lock, flags);
+
+   if (ret) {
+   pr_debug("Jitter RNG failed with %d\n", ret);
+   return 0;
+   }
+
+   /* Obtain entropy statement */
+   if (outbuflen != LRNG_DRNG_SECURITY_STRENGTH_BYTES)
+   ent_bits = (ent_bits * outbuflen<<3) /
+  

[PATCH v36 09/13] crypto: provide access to a static Jitter RNG state

2020-10-19 Thread Stephan Müller
To support the LRNG operation which uses the Jitter RNG separately
from the kernel crypto API, at a time where potentially the regular
memory management is not yet initialized, the Jitter RNG needs to
provide a state whose memory is defined at compile time. As only once
instance will ever be needed by the LRNG, define once static memory
block which is solely to be used by the LRNG.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 crypto/jitterentropy-kcapi.c  |  3 +-
 crypto/jitterentropy.c| 31 ++-
 .../crypto/internal}/jitterentropy.h  |  3 ++
 3 files changed, 34 insertions(+), 3 deletions(-)
 rename {crypto => include/crypto/internal}/jitterentropy.h (84%)

diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c
index eb7d1dd506bf..25a192f5984e 100644
--- a/crypto/jitterentropy-kcapi.c
+++ b/crypto/jitterentropy-kcapi.c
@@ -43,8 +43,7 @@
 #include 
 #include 
 #include 
-
-#include "jitterentropy.h"
+#include 
 
 /***
  * Helper function
diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c
index 6e147c43fc18..fa1459f09b01 100644
--- a/crypto/jitterentropy.c
+++ b/crypto/jitterentropy.c
@@ -117,7 +117,7 @@ struct rand_data {
 #define JENT_EHEALTH   9 /* Health test failed during initialization */
 #define JENT_ERCT  10 /* RCT failed during initialization */
 
-#include "jitterentropy.h"
+#include 
 
 /***
  * Adaptive Proportion Test
@@ -854,3 +854,32 @@ int jent_entropy_init(void)
 
return 0;
 }
+
+struct rand_data *jent_lrng_entropy_collector(void)
+{
+   static unsigned char lrng_jent_mem[JENT_MEMORY_SIZE];
+   static struct rand_data lrng_jent_state = {
+   .data   = 0,
+   .old_data   = 0,
+   .prev_time  = 0,
+   .last_delta = 0,
+   .last_delta2= 0,
+   .osr= 1,
+   .mem= lrng_jent_mem,
+   .memlocation= 0,
+   .memblocks  = JENT_MEMORY_BLOCKSIZE,
+   .memblocksize   = JENT_MEMORY_BLOCKS,
+   .memaccessloops = JENT_MEMORY_ACCESSLOOPS,
+   .rct_count  = 0,
+   .apt_observations = 0,
+   .apt_count  = 0,
+   .apt_base   = 0,
+   .apt_base_set   = 0,
+   .health_failure = 0
+   };
+
+   if (jent_entropy_init())
+   return NULL;
+
+   return _jent_state;
+}
diff --git a/crypto/jitterentropy.h b/include/crypto/internal/jitterentropy.h
similarity index 84%
rename from crypto/jitterentropy.h
rename to include/crypto/internal/jitterentropy.h
index c83fff32d130..6e07d86eac82 100644
--- a/crypto/jitterentropy.h
+++ b/include/crypto/internal/jitterentropy.h
@@ -15,3 +15,6 @@ extern int jent_read_entropy(struct rand_data *ec, unsigned 
char *data,
 extern struct rand_data *jent_entropy_collector_alloc(unsigned int osr,
  unsigned int flags);
 extern void jent_entropy_collector_free(struct rand_data *entropy_collector);
+
+/* Access to statically allocated Jitter RNG instance */
+extern struct rand_data *jent_lrng_entropy_collector(void);
-- 
2.26.2






[PATCH v36 13/13] LRNG - add power-on and runtime self-tests

2020-10-19 Thread Stephan Müller
Parts of the LRNG are already covered by self-tests, including:

* Self-test of SP800-90A DRBG provided by the Linux kernel crypto API.

* Self-test of the PRNG provided by the Linux kernel crypto API.

* Raw noise source data testing including SP800-90B compliant
  tests when enabling CONFIG_LRNG_HEALTH_TESTS

This patch adds the self-tests for the remaining critical functions of
the LRNG that are essential to maintain entropy and provide
cryptographic strong random numbers. The following self-tests are
implemented:

* Self-test of the time array maintenance. This test verifies whether
the time stamp array management to store multiple values in one integer
implements a concatenation of the data.

* Self-test of the software hash implementation ensures that this
function operates compliant to the FIPS 180-4 specification. The
self-test performs a hash operation of a zeroized per-CPU data array.

* Self-test of the ChaCha20 DRNG is based on the self-tests that are
already present and implemented with the stand-alone user space
ChaCha20 DRNG implementation available at [1]. The self-tests cover
different use cases of the DRNG seeded with known seed data.

The status of the LRNG self-tests is provided with the selftest_status
SysFS file. If the file contains a zero, the self-tests passed. The
value 0x means that the self-tests were not executed. Any other
value indicates a self-test failure.

The self-test may be compiled to panic the system if the self-test
fails.

All self-tests operate on private state data structures. This implies
that none of the self-tests have any impact on the regular LRNG
operations. This allows the self-tests to be repeated at runtime by
writing anything into the selftest_status SysFS file.

[1] https://www.chronox.de/chacha20.html

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
CC: Marcelo Henrique Cerri 
CC: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig |  26 +++
 drivers/char/lrng/Makefile|   1 +
 drivers/char/lrng/lrng_selftest.c | 344 ++
 3 files changed, 371 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_selftest.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index bb785bc61abb..6f180641a5da 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -324,4 +324,30 @@ config LRNG_TESTING
 
 endif #LRNG_TESTING_MENU
 
+config LRNG_SELFTEST
+   bool "Enable power-on and on-demand self-tests"
+   help
+ The power-on self-tests are executed during boot time
+ covering the ChaCha20 DRNG, the hash operation used for
+ processing the entropy pools and the auxiliary pool, and
+ the time stamp management of the LRNG.
+
+ The on-demand self-tests are triggered by writing any
+ value into the SysFS file selftest_status. At the same
+ time, when reading this file, the test status is
+ returned. A zero indicates that all tests were executed
+ successfully.
+
+ If unsure, say Y.
+
+if LRNG_SELFTEST
+
+config LRNG_SELFTEST_PANIC
+   bool "Panic the kernel upon self-test failure"
+   help
+ If the option is enabled, the kernel is terminated if an
+ LRNG power-on self-test failure is detected.
+
+endif # LRNG_SELFTEST
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 532501b38a00..a633638af991 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_LRNG_KCAPI)  += lrng_kcapi.o
 obj-$(CONFIG_LRNG_JENT)+= lrng_jent.o
 obj-$(CONFIG_LRNG_HEALTH_TESTS)+= lrng_health.o
 obj-$(CONFIG_LRNG_TESTING) += lrng_testing.o
+obj-$(CONFIG_LRNG_SELFTEST)+= lrng_selftest.o
diff --git a/drivers/char/lrng/lrng_selftest.c 
b/drivers/char/lrng/lrng_selftest.c
new file mode 100644
index ..4c7d124d24a4
--- /dev/null
+++ b/drivers/char/lrng/lrng_selftest.c
@@ -0,0 +1,344 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG power-on and on-demand self-test
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+/*
+ * In addition to the self-tests below, the following LRNG components
+ * are covered with self-tests during regular operation:
+ *
+ * * power-on self-test: SP800-90A DRBG provided by the Linux kernel crypto API
+ * * power-on self-test: PRNG provided by the Linux kernel crypto API
+ * * runtime test: Raw noise source data testing including SP800-90B compliant
+ *tests when enabling CONFIG_LRNG_HEALTH_TESTS
+ *
+ * Additional developer tests present with LRNG code:
+ * * SP800-90B APT and RCT test 

[PATCH v36 05/13] LRNG - add common generic hash support

2020-10-19 Thread Stephan Müller
The LRNG switchable DRNG support also allows the replacement of the hash
implementation used as conditioning component. The common generic hash
support code provides the required callbacks using the synchronous hash
implementations of the kernel crypto API.

All synchronous hash implementations supported by the kernel crypto API
can be used as part of the LRNG with this generic support.

The generic support is intended to be configured by separate switchable
DRNG backends.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
CC: "Peter, Matthias" 
CC: Roman Drahtmueller 
CC: Marcelo Henrique Cerri 
CC: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig   |  7 +++
 drivers/char/lrng/Makefile  |  1 +
 drivers/char/lrng/lrng_kcapi_hash.c | 97 +
 drivers/char/lrng/lrng_kcapi_hash.h | 19 ++
 4 files changed, 124 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_kcapi_hash.c
 create mode 100644 drivers/char/lrng/lrng_kcapi_hash.h

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index e211fcf5aa8b..daa2057248ac 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -76,4 +76,11 @@ menuconfig LRNG_DRNG_SWITCH
  accessible via the external interfaces. With this configuration
  option other DRNGs can be selected and loaded at runtime.
 
+if LRNG_DRNG_SWITCH
+
+config LRNG_KCAPI_HASH
+   bool
+
+endif # LRNG_DRNG_SWITCH
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 0eb4a6849c88..40f8826edeeb 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -11,3 +11,4 @@ obj-y += lrng_pool.o lrng_aux.o \
 obj-$(CONFIG_NUMA) += lrng_numa.o
 obj-$(CONFIG_SYSCTL)   += lrng_proc.o
 obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
+obj-$(CONFIG_LRNG_KCAPI_HASH)  += lrng_kcapi_hash.o
diff --git a/drivers/char/lrng/lrng_kcapi_hash.c 
b/drivers/char/lrng/lrng_kcapi_hash.c
new file mode 100644
index ..c5ddc71f5f8c
--- /dev/null
+++ b/drivers/char/lrng/lrng_kcapi_hash.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Backend for providing the hash primitive using the kernel crypto API.
+ *
+ * Copyright (C) 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+
+#include "lrng_kcapi_hash.h"
+
+struct lrng_hash_info {
+   struct crypto_shash *tfm;
+};
+
+static inline void _lrng_kcapi_hash_free(struct lrng_hash_info *lrng_hash)
+{
+   struct crypto_shash *tfm = lrng_hash->tfm;
+
+   crypto_free_shash(tfm);
+   kfree(lrng_hash);
+}
+
+void *lrng_kcapi_hash_alloc(const char *name)
+{
+   struct lrng_hash_info *lrng_hash;
+   struct crypto_shash *tfm;
+   int ret;
+
+   if (!name) {
+   pr_err("Hash name missing\n");
+   return ERR_PTR(-EINVAL);
+   }
+
+   tfm = crypto_alloc_shash(name, 0, 0);
+   if (IS_ERR(tfm)) {
+   pr_err("could not allocate hash %s\n", name);
+   return ERR_CAST(tfm);
+   }
+
+   ret = sizeof(struct lrng_hash_info);
+   lrng_hash = kmalloc(ret, GFP_KERNEL);
+   if (!lrng_hash) {
+   crypto_free_shash(tfm);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   lrng_hash->tfm = tfm;
+
+   pr_info("Hash %s allocated\n", name);
+
+   return lrng_hash;
+}
+EXPORT_SYMBOL(lrng_kcapi_hash_alloc);
+
+u32 lrng_kcapi_hash_digestsize(void *hash)
+{
+   struct lrng_hash_info *lrng_hash = (struct lrng_hash_info *)hash;
+   struct crypto_shash *tfm = lrng_hash->tfm;
+
+   return crypto_shash_digestsize(tfm);
+}
+EXPORT_SYMBOL(lrng_kcapi_hash_digestsize);
+
+void lrng_kcapi_hash_dealloc(void *hash)
+{
+   struct lrng_hash_info *lrng_hash = (struct lrng_hash_info *)hash;
+
+   _lrng_kcapi_hash_free(lrng_hash);
+   pr_info("Hash deallocated\n");
+}
+EXPORT_SYMBOL(lrng_kcapi_hash_dealloc);
+
+int lrng_kcapi_hash_init(struct shash_desc *shash, void *hash)
+{
+   struct lrng_hash_info *lrng_hash = (struct lrng_hash_info *)hash;
+   struct crypto_shash *tfm = lrng_hash->tfm;
+
+   shash->tfm = tfm;
+   return crypto_shash_init(shash);
+}
+EXPORT_SYMBOL(lrng_kcapi_hash_init);
+
+int lrng_kcapi_hash_update(struct shash_desc *shash, const u8 *inbuf,
+  u32 inbuflen)
+{
+   return crypto_shash_update(shash, inbuf, inbuflen);
+}
+EXPORT_SYMBOL(lrng_kcapi_hash_update);
+
+int lrng_kcapi_hash_final(struct shash_desc *shash, u8 *digest)
+{
+   return crypto_shash_final(shash, digest);
+}
+EXPORT_SYMBOL(lrng_kcapi_hash_final);
diff 

[PATCH v36 08/13] LRNG - add kernel crypto API PRNG extension

2020-10-19 Thread Stephan Müller
Add runtime-pluggable support for all PRNGs that are accessible via
the kernel crypto API, including hardware PRNGs. The PRNG is selected
with the module parameter drng_name where the name must be one that the
kernel crypto API can resolve into an RNG.

This allows using of the kernel crypto API PRNG implementations that
provide an interface to hardware PRNGs. Using this extension,
the LRNG uses the hardware PRNGs to generate random numbers. An
example is the S390 CPACF support providing such a PRNG.

The hash is provided by a kernel crypto API SHASH whose digest size
complies with the seedsize of the PRNG.

CC: Torsten Duwe 
CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig  |  13 ++
 drivers/char/lrng/Makefile |   1 +
 drivers/char/lrng/lrng_kcapi.c | 228 +
 3 files changed, 242 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_kcapi.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index a3c4cd153f35..af487b3391e0 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -91,6 +91,19 @@ config LRNG_DRBG
  Enable the SP800-90A DRBG support for the LRNG. Once the
  module is loaded, output from /dev/random, /dev/urandom,
  getrandom(2), or get_random_bytes_full is provided by a DRBG.
+
+config LRNG_KCAPI
+   tristate "Kernel Crypto API support for the LRNG"
+   depends on CRYPTO
+   depends on !LRNG_DRBG
+   select CRYPTO_RNG
+   select LRNG_KCAPI_HASH
+   help
+ Enable the support for generic pseudo-random number
+ generators offered by the kernel crypto API with the
+ LRNG. Once the module is loaded, output from /dev/random,
+ /dev/urandom, getrandom(2), or get_random_bytes is
+ provided by the selected kernel crypto API RNG.
 endif # LRNG_DRNG_SWITCH
 
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 6ebd252db12f..97d2b13d3227 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_SYSCTL)  += lrng_proc.o
 obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
 obj-$(CONFIG_LRNG_KCAPI_HASH)  += lrng_kcapi_hash.o
 obj-$(CONFIG_LRNG_DRBG)+= lrng_drbg.o
+obj-$(CONFIG_LRNG_KCAPI)   += lrng_kcapi.o
diff --git a/drivers/char/lrng/lrng_kcapi.c b/drivers/char/lrng/lrng_kcapi.c
new file mode 100644
index ..197dc84552e9
--- /dev/null
+++ b/drivers/char/lrng/lrng_kcapi.c
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Backend for the LRNG providing the cryptographic primitives using the
+ * kernel crypto API.
+ *
+ * Copyright (C) 2018 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "lrng_kcapi_hash.h"
+
+static char *drng_name = NULL;
+module_param(drng_name, charp, 0444);
+MODULE_PARM_DESC(drng_name, "Kernel crypto API name of DRNG");
+
+static char *pool_hash = "sha512";
+module_param(pool_hash, charp, 0444);
+MODULE_PARM_DESC(pool_hash,
+"Kernel crypto API name of hash or keyed message digest to 
read the entropy pool");
+
+static char *seed_hash = NULL;
+module_param(seed_hash, charp, 0444);
+MODULE_PARM_DESC(seed_hash,
+"Kernel crypto API name of hash with output size equal to 
seedsize of DRNG to bring seed string to the size required by the DRNG");
+
+struct lrng_drng_info {
+   struct crypto_rng *kcapi_rng;
+   void *lrng_hash;
+};
+
+static void *lrng_kcapi_drng_hash_alloc(void)
+{
+   return lrng_kcapi_hash_alloc(pool_hash);
+}
+
+static int lrng_kcapi_drng_seed_helper(void *drng, const u8 *inbuf,
+  u32 inbuflen)
+{
+   SHASH_DESC_ON_STACK(shash, NULL);
+   struct lrng_drng_info *lrng_drng_info = (struct lrng_drng_info *)drng;
+   struct crypto_rng *kcapi_rng = lrng_drng_info->kcapi_rng;
+   void *hash = lrng_drng_info->lrng_hash;
+   u32 digestsize = lrng_kcapi_hash_digestsize(hash);
+   u8 digest[64] __aligned(8);
+   int ret;
+
+   if (!hash)
+   return crypto_rng_reset(kcapi_rng, inbuf, inbuflen);
+
+   BUG_ON(digestsize > sizeof(digest));
+
+   ret = lrng_kcapi_hash_init(shash, hash) ?:
+ lrng_kcapi_hash_update(shash, inbuf, inbuflen) ?:
+ lrng_kcapi_hash_final(shash, digest);
+   if (ret)
+   return ret;
+
+   ret = 

[PATCH] crypto: jitterentropy - bind statically into kernel

2020-10-04 Thread Stephan Müller
The RISC-V architecture is about to implement the callback
random_get_entropy with a function that is not exported to modules.
Thus, the Jitter RNG is changed to be only bound statically into the
kernel removing the option to compile it as module.

Reported-by: Christoph Hellwig 
Signed-off-by: Stephan Mueller 
---
 crypto/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 094ef56ab7b4..5b20087b117f 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -1853,7 +1853,7 @@ config CRYPTO_DRBG
 endif  # if CRYPTO_DRBG_MENU
 
 config CRYPTO_JITTERENTROPY
-   tristate "Jitterentropy Non-Deterministic Random Number Generator"
+   bool "Jitterentropy Non-Deterministic Random Number Generator"
select CRYPTO_RNG
help
  The Jitterentropy RNG is a noise that is intended
-- 
2.26.2






[PATCH v35 04/13] LRNG - add switchable DRNG support

2020-09-18 Thread Stephan Müller
The DRNG switch support allows replacing the DRNG mechanism of the
LRNG. The switching support rests on the interface definition of
include/linux/lrng.h. A new DRNG is implemented by filling in the
interface defined in this header file.

In addition to the DRNG, the extension also has to provide a hash
implementation that is used to hash the entropy pool for random number
extraction.

Note: It is permissible to implement a DRNG whose operations may sleep.
However, the hash function must not sleep.

The switchable DRNG support allows replacing the DRNG at runtime.
However, only one DRNG extension is allowed to be loaded at any given
time. Before replacing it with another DRNG implementation, the possibly
existing DRNG extension must be unloaded.

The switchable DRNG extension activates the new DRNG during load time.
It is expected, however, that such a DRNG switch would be done only once
by an administrator to load the intended DRNG implementation.

It is permissible to compile DRNG extensions either as kernel modules or
statically. The initialization of the DRNG extension should be performed
with a late_initcall to ensure the extension is available when user
space starts but after all other initialization completed.
The initialization is performed by registering the function call data
structure with the lrng_set_drng_cb function. In order to unload the
DRNG extension, lrng_set_drng_cb must be invoked with the NULL
parameter.

The DRNG extension should always provide a security strength that is at
least as strong as LRNG_DRNG_SECURITY_STRENGTH_BITS.

The hash extension must not sleep and must not maintain a separate
state.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig   |   7 ++
 drivers/char/lrng/Makefile  |   1 +
 drivers/char/lrng/lrng_switch.c | 203 
 3 files changed, 211 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_switch.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index fbbcf2ef43b6..e211fcf5aa8b 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -69,4 +69,11 @@ config LRNG_COLLECTION_SIZE
default 512 if LRNG_COLLECTION_SIZE_512
default 1024 if LRNG_COLLECTION_SIZE_1024
 
+menuconfig LRNG_DRNG_SWITCH
+   bool "Support DRNG runtime switching"
+   help
+ The Linux RNG per default uses a ChaCha20 DRNG that is
+ accessible via the external interfaces. With this configuration
+ option other DRNGs can be selected and loaded at runtime.
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index ac97f0b11cb7..0eb4a6849c88 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -10,3 +10,4 @@ obj-y += lrng_pool.o lrng_aux.o \
 
 obj-$(CONFIG_NUMA) += lrng_numa.o
 obj-$(CONFIG_SYSCTL)   += lrng_proc.o
+obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
diff --git a/drivers/char/lrng/lrng_switch.c b/drivers/char/lrng/lrng_switch.c
new file mode 100644
index ..cbaf5cd544aa
--- /dev/null
+++ b/drivers/char/lrng/lrng_switch.c
@@ -0,0 +1,203 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG DRNG switching support
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+
+#include "lrng_internal.h"
+
+static int lrng_drng_switch(struct lrng_drng *drng_store,
+   const struct lrng_crypto_cb *cb, int node)
+{
+   const struct lrng_crypto_cb *old_cb;
+   unsigned long flags = 0, flags2 = 0;
+   int ret;
+   u8 seed[LRNG_DRNG_SECURITY_STRENGTH_BYTES];
+   void *new_drng = cb->lrng_drng_alloc(LRNG_DRNG_SECURITY_STRENGTH_BYTES);
+   void *old_drng, *new_hash, *old_hash;
+   u32 current_security_strength;
+   bool sl = false, reset_drng = !lrng_get_available();
+
+   if (IS_ERR(new_drng)) {
+   pr_warn("could not allocate new DRNG for NUMA node %d (%ld)\n",
+   node, PTR_ERR(new_drng));
+   return PTR_ERR(new_drng);
+   }
+
+   new_hash = cb->lrng_hash_alloc();
+   if (IS_ERR(new_hash)) {
+   pr_warn("could not allocate new LRNG pool hash (%ld)\n",
+   PTR_ERR(new_hash));
+   cb->lrng_drng_dealloc(new_drng);
+   return PTR_ERR(new_hash);
+   }
+
+   if (cb->lrng_hash_digestsize(new_hash) > LRNG_MAX_DIGESTSIZE) {
+

[PATCH v35 10/13] LRNG - add Jitter RNG fast noise source

2020-09-18 Thread Stephan Müller
The Jitter RNG fast noise source implemented as part of the kernel
crypto API is queried for 256 bits of entropy at the time the seed
buffer managed by the LRNG is about to be filled.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig | 12 +
 drivers/char/lrng/Makefile|  1 +
 drivers/char/lrng/lrng_jent.c | 88 +++
 3 files changed, 101 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_jent.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index af487b3391e0..87682f57efb8 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -106,4 +106,16 @@ config LRNG_KCAPI
  provided by the selected kernel crypto API RNG.
 endif # LRNG_DRNG_SWITCH
 
+config LRNG_JENT
+   bool "Enable Jitter RNG as LRNG Seed Source"
+   depends on CRYPTO
+   select CRYPTO_JITTERENTROPY
+   help
+ The Linux RNG may use the Jitter RNG as noise source. Enabling
+ this option enables the use of the Jitter RNG. Its default
+ entropy level is 16 bits of entropy per 256 data bits delivered
+ by the Jitter RNG. This entropy level can be changed at boot
+ time or at runtime with the lrng_base.jitterrng configuration
+ variable.
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 97d2b13d3227..6be88156010a 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_LRNG_DRNG_SWITCH)+= lrng_switch.o
 obj-$(CONFIG_LRNG_KCAPI_HASH)  += lrng_kcapi_hash.o
 obj-$(CONFIG_LRNG_DRBG)+= lrng_drbg.o
 obj-$(CONFIG_LRNG_KCAPI)   += lrng_kcapi.o
+obj-$(CONFIG_LRNG_JENT)+= lrng_jent.o
diff --git a/drivers/char/lrng/lrng_jent.c b/drivers/char/lrng/lrng_jent.c
new file mode 100644
index ..225505271fcb
--- /dev/null
+++ b/drivers/char/lrng/lrng_jent.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG Fast Noise Source: Jitter RNG
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+
+#include "lrng_internal.h"
+
+/*
+ * Estimated entropy of data is a 16th of LRNG_DRNG_SECURITY_STRENGTH_BITS.
+ * Albeit a full entropy assessment is provided for the noise source indicating
+ * that it provides high entropy rates and considering that it deactivates
+ * when it detects insufficient hardware, the chosen under estimation of
+ * entropy is considered to be acceptable to all reviewers.
+ */
+static u32 jitterrng = LRNG_DRNG_SECURITY_STRENGTH_BITS>>4;
+module_param(jitterrng, uint, 0644);
+MODULE_PARM_DESC(jitterrng, "Entropy in bits of 256 data bits from Jitter RNG 
noise source");
+
+/**
+ * lrng_get_jent() - Get Jitter RNG entropy
+ *
+ * @outbuf: buffer to store entropy
+ * @outbuflen: length of buffer
+ *
+ * Return:
+ * * > 0 on success where value provides the added entropy in bits
+ * * 0 if no fast source was available
+ */
+static struct rand_data *lrng_jent_state;
+
+u32 lrng_get_jent(u8 *outbuf, unsigned int outbuflen)
+{
+   int ret;
+   u32 ent_bits = jitterrng;
+   unsigned long flags;
+   static DEFINE_SPINLOCK(lrng_jent_lock);
+   static int lrng_jent_initialized = 0;
+
+   spin_lock_irqsave(_jent_lock, flags);
+
+   if (!ent_bits || (lrng_jent_initialized == -1)) {
+   spin_unlock_irqrestore(_jent_lock, flags);
+   return 0;
+   }
+
+   if (!lrng_jent_initialized) {
+   lrng_jent_state = jent_lrng_entropy_collector();
+   if (!lrng_jent_state) {
+   jitterrng = 0;
+   lrng_jent_initialized = -1;
+   spin_unlock_irqrestore(_jent_lock, flags);
+   pr_info("Jitter RNG unusable on current system\n");
+   return 0;
+   }
+   lrng_jent_initialized = 1;
+   pr_debug("Jitter RNG working on current system\n");
+   }
+   ret = jent_read_entropy(lrng_jent_state, outbuf, outbuflen);
+   spin_unlock_irqrestore(_jent_lock, flags);
+
+   if (ret) {
+   pr_debug("Jitter RNG failed with %d\n", ret);
+   return 0;
+   }
+
+   /* Obtain entropy statement */
+   if (outbuflen != LRNG_DRNG_SECURITY_STRENGTH_BYTES)
+   ent_bits = (ent_bits * outbuflen<<3) /
+  

[PATCH v35 05/13] LRNG - add common generic hash support

2020-09-18 Thread Stephan Müller
The LRNG switchable DRNG support also allows the replacement of the hash
implementation used as conditioning component. The common generic hash
support code provides the required callbacks using the synchronous hash
implementations of the kernel crypto API.

All synchronous hash implementations supported by the kernel crypto API
can be used as part of the LRNG with this generic support.

The generic support is intended to be configured by separate switchable
DRNG backends.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
CC: "Peter, Matthias" 
CC: Roman Drahtmueller 
CC: Marcelo Henrique Cerri 
CC: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig   |  7 +++
 drivers/char/lrng/Makefile  |  1 +
 drivers/char/lrng/lrng_kcapi_hash.c | 97 +
 drivers/char/lrng/lrng_kcapi_hash.h | 19 ++
 4 files changed, 124 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_kcapi_hash.c
 create mode 100644 drivers/char/lrng/lrng_kcapi_hash.h

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index e211fcf5aa8b..daa2057248ac 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -76,4 +76,11 @@ menuconfig LRNG_DRNG_SWITCH
  accessible via the external interfaces. With this configuration
  option other DRNGs can be selected and loaded at runtime.
 
+if LRNG_DRNG_SWITCH
+
+config LRNG_KCAPI_HASH
+   bool
+
+endif # LRNG_DRNG_SWITCH
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 0eb4a6849c88..40f8826edeeb 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -11,3 +11,4 @@ obj-y += lrng_pool.o lrng_aux.o \
 obj-$(CONFIG_NUMA) += lrng_numa.o
 obj-$(CONFIG_SYSCTL)   += lrng_proc.o
 obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
+obj-$(CONFIG_LRNG_KCAPI_HASH)  += lrng_kcapi_hash.o
diff --git a/drivers/char/lrng/lrng_kcapi_hash.c 
b/drivers/char/lrng/lrng_kcapi_hash.c
new file mode 100644
index ..c5ddc71f5f8c
--- /dev/null
+++ b/drivers/char/lrng/lrng_kcapi_hash.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Backend for providing the hash primitive using the kernel crypto API.
+ *
+ * Copyright (C) 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+
+#include "lrng_kcapi_hash.h"
+
+struct lrng_hash_info {
+   struct crypto_shash *tfm;
+};
+
+static inline void _lrng_kcapi_hash_free(struct lrng_hash_info *lrng_hash)
+{
+   struct crypto_shash *tfm = lrng_hash->tfm;
+
+   crypto_free_shash(tfm);
+   kfree(lrng_hash);
+}
+
+void *lrng_kcapi_hash_alloc(const char *name)
+{
+   struct lrng_hash_info *lrng_hash;
+   struct crypto_shash *tfm;
+   int ret;
+
+   if (!name) {
+   pr_err("Hash name missing\n");
+   return ERR_PTR(-EINVAL);
+   }
+
+   tfm = crypto_alloc_shash(name, 0, 0);
+   if (IS_ERR(tfm)) {
+   pr_err("could not allocate hash %s\n", name);
+   return ERR_CAST(tfm);
+   }
+
+   ret = sizeof(struct lrng_hash_info);
+   lrng_hash = kmalloc(ret, GFP_KERNEL);
+   if (!lrng_hash) {
+   crypto_free_shash(tfm);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   lrng_hash->tfm = tfm;
+
+   pr_info("Hash %s allocated\n", name);
+
+   return lrng_hash;
+}
+EXPORT_SYMBOL(lrng_kcapi_hash_alloc);
+
+u32 lrng_kcapi_hash_digestsize(void *hash)
+{
+   struct lrng_hash_info *lrng_hash = (struct lrng_hash_info *)hash;
+   struct crypto_shash *tfm = lrng_hash->tfm;
+
+   return crypto_shash_digestsize(tfm);
+}
+EXPORT_SYMBOL(lrng_kcapi_hash_digestsize);
+
+void lrng_kcapi_hash_dealloc(void *hash)
+{
+   struct lrng_hash_info *lrng_hash = (struct lrng_hash_info *)hash;
+
+   _lrng_kcapi_hash_free(lrng_hash);
+   pr_info("Hash deallocated\n");
+}
+EXPORT_SYMBOL(lrng_kcapi_hash_dealloc);
+
+int lrng_kcapi_hash_init(struct shash_desc *shash, void *hash)
+{
+   struct lrng_hash_info *lrng_hash = (struct lrng_hash_info *)hash;
+   struct crypto_shash *tfm = lrng_hash->tfm;
+
+   shash->tfm = tfm;
+   return crypto_shash_init(shash);
+}
+EXPORT_SYMBOL(lrng_kcapi_hash_init);
+
+int lrng_kcapi_hash_update(struct shash_desc *shash, const u8 *inbuf,
+  u32 inbuflen)
+{
+   return crypto_shash_update(shash, inbuf, inbuflen);
+}
+EXPORT_SYMBOL(lrng_kcapi_hash_update);
+
+int lrng_kcapi_hash_final(struct shash_desc *shash, u8 *digest)
+{
+   return crypto_shash_final(shash, digest);
+}
+EXPORT_SYMBOL(lrng_kcapi_hash_final);
diff --git 

[PATCH v35 11/13] LRNG - add SP800-90B compliant health tests

2020-09-18 Thread Stephan Müller
Implement health tests for LRNG's slow noise sources as mandated by
SP-800-90B The file contains the following health tests:

- stuck test: The stuck test calculates the first, second and third
  discrete derivative of the time stamp to be processed by the hash
  for the per-CPU entropy pool. Only if all three values are non-zero,
  the received time delta is considered to be non-stuck.

- SP800-90B Repetition Count Test (RCT): The LRNG uses an enhanced
  version of the RCT specified in SP800-90B section 4.4.1. Instead of
  counting identical back-to-back values, the input to the RCT is the
  counting of the stuck values during the processing of received
  interrupt events. The RCT is applied with alpha=2^-30 compliant to
  the recommendation of FIPS 140-2 IG 9.8. During the counting operation,
  the LRNG always calculates the RCT cut-off value of C. If that value
  exceeds the allowed cut-off value, the LRNG will trigger the health
  test failure discussed below. An error is logged to the kernel log
  that such RCT failure occurred. This test is only applied and
  enforced in FIPS mode, i.e. when the kernel compiled with
  CONFIG_CONFIG_FIPS is started with fips=1.

- SP800-90B Adaptive Proportion Test (APT): The LRNG implements the
  APT as defined in SP800-90B section 4.4.2. The applied significance
  level again is alpha=2^-30 compliant to the recommendation of FIPS
  140-2 IG 9.8.

The aforementioned health tests are applied to the first 1,024 time stamps
obtained from interrupt events. In case one error is identified for either
the RCT, or the APT, the collected entropy is invalidated and the
SP800-90B startup health test is restarted.

As long as the SP800-90B startup health test is not completed, all LRNG
random number output interfaces that may block will block and not generate
any data. This implies that only those potentially blocking interfaces are
defined to provide random numbers that are seeded with the interrupt noise
source being SP800-90B compliant. All other output interfaces will not be
affected by the SP800-90B startup test and thus are not considered
SP800-90B compliant.

At runtime, the SP800-90B APT and RCT are applied to each time stamp
generated for a received interrupt. When either the APT and RCT indicates
a noise source failure, the LRNG is reset to a state it has immediately
after boot:

- all entropy counters are set to zero

- the SP800-90B startup tests are re-performed which implies that
getrandom(2) would block again until new entropy was collected

To summarize, the following rules apply:

• SP800-90B compliant output interfaces

  - /dev/random

  - getrandom(2) system call

  -  get_random_bytes kernel-internal interface when being triggered by
 the callback registered with add_random_ready_callback

• SP800-90B non-compliant output interfaces

  - /dev/urandom

  - get_random_bytes kernel-internal interface called directly

  - randomize_page kernel-internal interface

  - get_random_u32 and get_random_u64 kernel-internal interfaces

  - get_random_u32_wait, get_random_u64_wait, get_random_int_wait, and
get_random_long_wait kernel-internal interfaces

If either the RCT, or the APT health test fails irrespective whether
during initialization or runtime, the following actions occur:

  1. The entropy of the entire entropy pool is invalidated.

  2. All DRNGs are reset which imply that they are treated as being
 not seeded and require a reseed during next invocation.

  3. The SP800-90B startup health test are initiated with all
 implications of the startup tests. That implies that from that point
 on, new events must be observed and its entropy must be inserted into
 the entropy pool before random numbers are calculated from the
 entropy pool.

Further details on the SP800-90B compliance and the availability of all
test tools required to perform all tests mandated by SP800-90B are
provided at [1].

The entire health testing code is compile-time configurable.

The patch provides a CONFIG_BROKEN configuration of the APT / RCT cutoff
values which have a high likelihood to trigger the health test failure.
The BROKEN APT cutoff is set to the exact mean of the expected value if
the time stamps are equally distributed (512 time stamps divided by 16
possible values due to using the 4 LSB of the time stamp). The BROKEN
RCT cutoff value is set to 1 which is likely to be triggered during
regular operation.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig   |  56 +
 

[PATCH v35 12/13] LRNG - add interface for gathering of raw entropy

2020-09-18 Thread Stephan Müller
The test interface allows a privileged process to capture the raw
unconditioned noise that is collected by the LRNG for statistical
analysis. Such testing allows the analysis how much entropy
the interrupt noise source provides on a given platform.
Extracted noise data is not used to seed the LRNG. This
is a test interface and not appropriate for production systems.
Yet, the interface is considered to be sufficiently secured for
production systems.

Access to the data is given through the lrng_raw debugfs file. The
data buffer should be multiples of sizeof(u32) to fill the entire
buffer. Using the option lrng_testing.boot_test=1 the raw noise of
the first 1000 entropy events since boot can be sampled.

This test interface allows generating the data required for
analysis whether the LRNG is in compliance with SP800-90B
sections 3.1.3 and 3.1.4.

In addition, the test interface allows gathering of the concatenated raw
entropy data to verify that the concatenation works appropriately.
This includes sampling of the following raw data:

* high-resolution time stamp

* Jiffies

* IRQ number

* IRQ flags

* return instruction pointer

* interrupt register state

* array logic batching the high-resolution time stamp

Also, a testing interface to support ACVT of the hash implementation
is provided. The reason why only hash testing is supported (as
opposed to also provide testing for the DRNG) is the fact that the
LRNG software hash implementation contains glue code that may
warrant testing in addition to the testing of the software ciphers
via the kernel crypto API. Also, for testing the CTR-DRBG, the
underlying AES implementation would need to be tested. However,
such AES test interface cannot be provided by the LRNG as it has no
means to access the AES operation.

Finally, the execution duration for processing a time stamp can be
obtained with the LRNG raw entropy interface.

If a test interface is not compiled, its code is a noop which has no
impact on the performance.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig| 150 +++
 drivers/char/lrng/Makefile   |   1 +
 drivers/char/lrng/lrng_testing.c | 687 +++
 3 files changed, 838 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_testing.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index a059da0b2f5d..bb785bc61abb 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -174,4 +174,154 @@ config LRNG_APT_CUTOFF
default 325 if !LRNG_APT_BROKEN
default 32 if LRNG_APT_BROKEN
 
+menuconfig LRNG_TESTING_MENU
+   bool "LRNG testing interfaces"
+   depends on DEBUG_FS
+   help
+ Enable one or more of the following test interfaces.
+
+ If unsure, say N.
+
+if LRNG_TESTING_MENU
+
+config LRNG_RAW_HIRES_ENTROPY
+   bool "Enable entropy test interface to hires timer noise source"
+   default y
+   help
+ The test interface allows a privileged process to capture
+ the raw unconditioned high resolution time stamp noise that
+ is collected by the LRNG for statistical analysis. Extracted
+ noise data is not used to seed the LRNG.
+
+ The raw noise data can be obtained using the lrng_raw_hires
+ debugfs file. Using the option lrng_testing.boot_raw_hires_test=1
+ the raw noise of the first 1000 entropy events since boot
+ can be sampled.
+
+config LRNG_RAW_JIFFIES_ENTROPY
+   bool "Enable entropy test interface to Jiffies noise source"
+   help
+ The test interface allows a privileged process to capture
+ the raw unconditioned Jiffies that is collected by
+ the LRNG for statistical analysis. This data is used for
+ seeding the LRNG if a high-resolution time stamp is not
+ available. If a high-resolution time stamp is detected,
+ the Jiffies value is not collected by the LRNG and no
+ data is provided via the test interface. Extracted noise
+ data is not used to seed the random number generator.
+
+ The raw noise data can be obtained using the lrng_raw_jiffies
+ debugfs file. Using the option lrng_testing.boot_raw_jiffies_test=1
+ the raw noise of the first 1000 entropy events since boot
+ can be sampled.
+
+config LRNG_RAW_IRQ_ENTROPY
+   bool "Enable entropy test interface to IRQ number noise source"
+   help
+ The test interface allows a privileged process to capture
+ the raw 

[PATCH v35 01/13] Linux Random Number Generator

2020-09-18 Thread Stephan Müller
In an effort to provide a flexible implementation for a random number
generator that also delivers entropy during early boot time, allows
replacement of the deterministic random number generation mechanism,
implement the various components in separate code for easier
maintenance, and provide compliance to SP800-90[A|B|C], introduce
the Linux Random Number Generator (LRNG) framework.

The general design is as follows. Additional implementation details
are given in [1]. The LRNG consists of the following components:

1. The LRNG implements a DRNG. The DRNG always generates the
requested amount of output. When using the SP800-90A terminology
it operates without prediction resistance. The secondary DRNG
maintains a counter of how many bytes were generated since last
re-seed and a timer of the elapsed time since last re-seed. If either
the counter or the timer reaches a threshold, the secondary DRNG is
seeded from the entropy pool.

In case the Linux kernel detects a NUMA system, one secondary DRNG
instance per NUMA node is maintained.

2. The DRNG is seeded by concatenating the data from the
following sources:

(a) the output of the entropy pool,

(b) the Jitter RNG if available and enabled, and

(c) the CPU-based noise source such as Intel RDRAND if available and
enabled.

The entropy estimate of the data of all noise sources are added to
form the entropy estimate of the data used to seed the DRNG with.
The LRNG ensures, however, that the DRNG after seeding is at
maximum the security strength of the DRNG.

The LRNG is designed such that none of these noise sources can dominate
the other noise sources to provide seed data to the DRNG during due to
the following:

(a) During boot time, the amount of received interrupts are the trigger
points to (re)seed the DRNG.

(b) At runtime, the available entropy from the slow noise source is
concatenated with a pre-defined amount of data from the fast noise
sources. In addition, each DRNG reseed operation triggers external
noise source providers to deliver one block of data.

3. The entropy pool accumulates entropy obtained from certain events,
which will henceforth be collectively called "slow noise sources".
The entropy pool collects noise data from slow noise sources. Any data
received by the LRNG from the slow noise sources is inserted into a
per-CPU entropy pool using a hash operation that can be changed during
runtime. Per default, SHA-256 is used.

 (a) When an interrupt occurs, the high-resolution time stamp is mixed
into the per-CPU entropy pool. This time stamp is credited with
heuristically implied entropy.

 (b) HID event data like the key stroke or the mouse coordinates are
mixed into the per-CPU entropy pool. This data is not credited with
entropy by the LRNG.

 (c) Device drivers may provide data that is mixed into an auxiliary
pool using the same hash that is used to process the per-CPU entropy
pool. This data is not credited with entropy by the LRNG.

Any data provided from user space by either writing to /dev/random,
/dev/urandom or the IOCTL of RNDADDENTROPY on both device files
are always injected into the auxiliary pool.

In addition, when a hardware random number generator covered by the
Linux kernel HW generator framework wants to deliver random numbers,
it is injected into the auxiliary pool as well. HW generator noise source
is handled separately from the other noise source due to the fact that
the HW generator framework may decide by itself when to deliver data
whereas the other noise sources always requested for data driven by the
LRNG operation. Similarly any user space provided data is inserted into
the entropy pool.

When seed data for the DRNG is to be generated, all per-CPU
entropy pools and the auxiliary pool are hashed. The message digest
forms the new auxiliary pool state. At the same time, this data
is used for seeding the DRNG.

To speed up the interrupt handling code of the LRNG, the time stamp
collected for an interrupt event is truncated to the 8 least
significant bits. 64 truncated time stamps are concatenated and then
jointly inserted into the per-CPU entropy pool. During boot time,
until the fully seeded stage is reached, each time stamp with its
32 least significant bits is are concatenated. When 16 such events
are received, they are injected into the per-CPU entropy pool.

The LRNG allows the DRNG mechanism to be changed at runtime. Per default,
a ChaCha20-based DRNG is used. The ChaCha20-DRNG implemented for the
LRNG is also provided as a stand-alone user space deterministic random
number generator. The LRNG also offers an SP800-90A DRBG based on the
Linux kernel crypto API DRBG implementation.

The processing of entropic data from the noise source before injecting
them into the DRNG is performed with the following mathematical
operations:

1. Truncation: The received time stamps are truncated to 8 least
significant bits (or 32 least significant bits during boot time)

2. Concatenation: The received and truncated time stamps 

[PATCH v35 02/13] LRNG - allocate one DRNG instance per NUMA node

2020-09-18 Thread Stephan Müller
In order to improve NUMA-locality when serving getrandom(2) requests,
allocate one DRNG instance per node.

The DRNG instance that is present right from the start of the kernel is
reused as the first per-NUMA-node DRNG. For all remaining online NUMA
nodes a new DRNG instance is allocated.

During boot time, the multiple DRNG instances are seeded sequentially.
With this, the first DRNG instance (referenced as the initial DRNG
in the code) is completely seeded with 256 bits of entropy before the
next DRNG instance is completely seeded.

When random numbers are requested, the NUMA-node-local DRNG is checked
whether it has been already fully seeded. If this is not the case, the
initial DRNG is used to serve the request.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
CC: Eric Biggers 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Makefile|   2 +
 drivers/char/lrng/lrng_internal.h |   5 ++
 drivers/char/lrng/lrng_numa.c | 108 ++
 3 files changed, 115 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_numa.c

diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index e72e01c15bb9..29724c65287d 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -7,3 +7,5 @@ obj-y   += lrng_pool.o lrng_aux.o \
   lrng_sw_noise.o lrng_archrandom.o \
   lrng_drng.o lrng_chacha20.o \
   lrng_interfaces.o
+
+obj-$(CONFIG_NUMA) += lrng_numa.o
diff --git a/drivers/char/lrng/lrng_internal.h 
b/drivers/char/lrng/lrng_internal.h
index bf0b32eb9113..c405cbf379d6 100644
--- a/drivers/char/lrng/lrng_internal.h
+++ b/drivers/char/lrng/lrng_internal.h
@@ -219,8 +219,13 @@ int lrng_drng_get_sleep(u8 *outbuf, u32 outbuflen);
 void lrng_drng_force_reseed(void);
 void lrng_drng_seed_work(struct work_struct *dummy);
 
+#ifdef CONFIG_NUMA
+struct lrng_drng **lrng_drng_instances(void);
+void lrng_drngs_numa_alloc(void);
+#else  /* CONFIG_NUMA */
 static inline struct lrng_drng **lrng_drng_instances(void) { return NULL; }
 static inline void lrng_drngs_numa_alloc(void) { return; }
+#endif /* CONFIG_NUMA */
 
 /** Entropy pool management 
***/
 
diff --git a/drivers/char/lrng/lrng_numa.c b/drivers/char/lrng/lrng_numa.c
new file mode 100644
index ..7f1f0dade1b6
--- /dev/null
+++ b/drivers/char/lrng/lrng_numa.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG NUMA support
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+
+#include "lrng_internal.h"
+
+static struct lrng_drng **lrng_drng __read_mostly = NULL;
+
+struct lrng_drng **lrng_drng_instances(void)
+{
+   return smp_load_acquire(_drng);
+}
+
+/* Allocate the data structures for the per-NUMA node DRNGs */
+static void _lrng_drngs_numa_alloc(struct work_struct *work)
+{
+   struct lrng_drng **drngs;
+   struct lrng_drng *lrng_drng_init = lrng_drng_init_instance();
+   u32 node;
+   bool init_drng_used = false;
+
+   mutex_lock(_crypto_cb_update);
+
+   /* per-NUMA-node DRNGs are already present */
+   if (lrng_drng)
+   goto unlock;
+
+   drngs = kcalloc(nr_node_ids, sizeof(void *), GFP_KERNEL|__GFP_NOFAIL);
+   for_each_online_node(node) {
+   struct lrng_drng *drng;
+
+   if (!init_drng_used) {
+   drngs[node] = lrng_drng_init;
+   init_drng_used = true;
+   continue;
+   }
+
+   drng = kmalloc_node(sizeof(struct lrng_drng),
+GFP_KERNEL|__GFP_NOFAIL, node);
+   memset(drng, 0, sizeof(lrng_drng));
+
+   drng->crypto_cb = lrng_drng_init->crypto_cb;
+   drng->drng = drng->crypto_cb->lrng_drng_alloc(
+   LRNG_DRNG_SECURITY_STRENGTH_BYTES);
+   if (IS_ERR(drng->drng)) {
+   kfree(drng);
+   goto err;
+   }
+
+   drng->hash = drng->crypto_cb->lrng_hash_alloc();
+   if (IS_ERR(drng->hash)) {
+   drng->crypto_cb->lrng_drng_dealloc(drng->drng);
+   kfree(drng);
+   goto err;
+   }
+
+   mutex_init(>lock);
+   

[PATCH v35 00/13] /dev/random - a new approach

2020-09-18 Thread Stephan Müller
Hi,

The following patch set provides a different approach to /dev/random which
is called Linux Random Number Generator (LRNG) to collect entropy within
the Linux kernel.

The following advantages compared to the existing /dev/random
implementation are present:

* Sole use of crypto for data processing:

 - exclusive use of a hash operation for conditioning entropy data with
   a clear mathematical description as given in [2] section 2.2 -
   non-cryptographic operations like LFSR are not used

 - accelerated SHA-512 and software SHA-256 hash are available - LRNG works
   even if the kernel crypto API is not compiled

 - hash operations use NUMA-node-local hash instances to benefit large
   parallel systems

 - runtime-switchable DRNG and hash implementations which allows
   the use of an SP800-90A DRBG or other types of DRNGs

* Performance

 - faster by up to 75% in the critical code path of the interrupt handler
   depending on data collection size configurable at kernel compile time -
   the default is about equal in performance with existing /dev/random

 - configurable data collection sizes to accommodate small environments and
   big environments

 - entropy collection using an almost never contended lock to benefit
   large parallel systems - worst case rate of contention is the number
   of DRNG reseeds, usually the number of potential contentions per 5
   minutes is equal to number of NUMA nodes.

 - ChaCha20 DRNG is significantly faster as implemented in random.c

 - faster entropy collection during boot time to reach fully seeded level,
   including on virtual systems or systems with SSDs

* Testing

 - heuristic entropy estimation is based on analysis following SP800-90B
   and not on coincidental underestimation of entropy

 - power-on self tests for critical deterministic components
   (ChaCha20 DRNG, hash, and entropy collection logic) not already
   covered by power-up tests of the kernel crypto API

 - availability of test interfaces for all operational stages of the LRNG
   including boot-time raw entropy event data sampling

 - fully testable ChaCha20 DRNG - see [3]

* Entropy collection

 - The LRNG is fully compliant to SP800-90B requirements and is shipped with
   a full SP800-90B assessment and all required test tools in [1]. The
   existing /dev/random implementation on the other hand has architectural
   limitations which does not easily allow to bring the implementation in
   compliance with SP800-90B. The existing /dev/random is not easily made
   compliant with SP800-90B as outlined in [2] section 4.5.

 - full entropy assessment and description provided with [2], specifically
   section 3.2.6

 - guarantee that entropy events are not credited with entropy twice
   (the existing /dev/random implementation credits HID/disk and interrupt
   events with entropy which are a derivative of each other) and
   guarantee that entropy data is not reused for two different use cases
   (as done in the existing /dev/random implementation when injecting a
   part of fast_pool into the net_rand_state)

The LRNG patch set allows a user to select use of the existing /dev/random
or the LRNG during compile time. As the LRNG provides API and ABI compatible
interfaces to the existing /dev/random implementation, the user can freely
chose the RNG implementation without affecting kernel or user space
operations.

For users that are not interested in SP800-90B, the entire code for the
compliance as well as test interfaces can be deselected at compile time.

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

The LRNG provides a complete separation of the noise source maintenance
and the collection of entropy into per-CPU entropy pools from the
post-processing using a pseudo-random number generator. Different
DRNGs are supported, including:

* Built-in ChaCha20 DRNG which has no dependency to other kernel
  frameworks.

* SP800-90A DRBG using the kernel crypto API including its accelerated
  raw cipher implementations. This implies that the output of /dev/random,
  getrandom(2), /dev/urandom or get_random_bytes is fully compliant to
  SP800-90A.

* Arbitrary DRNGs registered with the kernel crypto API

Booting the patch with the kernel command line option
"dyndbg=file drivers/char/lrng/* +p" generates logs indicating the
operation of the LRNG. Each log is pre-pended with "lrng".

The LRNG has a flexible design by allowing an easy replacement of the
deterministic random number generator component as well as hash
component.

Full SP800-90B testing is performed on the following systems - details
are given in [2] appendix C:

* x86 KVM virtualized guest 32 and 64 bit systems

* x86 bare metal

* older and newer ARMv7 system

* ARM64

* POWER7 LE and POWER 8 BE

* IBM Z System mainframe

* old 

[PATCH v35 03/13] LRNG - sysctls and /proc interface

2020-09-18 Thread Stephan Müller
The LRNG sysctl interface provides the same controls as the existing
/dev/random implementation. These sysctls behave identically and are
implemented identically. The goal is to allow a possible merge of the
existing /dev/random implementation with this implementation which
implies that this patch tries have a very close similarity. Yet, all
sysctls are documented at [1].

In addition, it provides the file lrng_type which provides details about
the LRNG:

- the name of the DRNG that produces the random numbers for /dev/random,
/dev/urandom, getrandom(2)

- the hash used to produce random numbers from the entropy pool

- the number of secondary DRNG instances

- indicator whether the LRNG operates SP800-90B compliant

- indicator whether a high-resolution timer is identified - only with a
high-resolution timer the interrupt noise source will deliver sufficient
entropy

- indicator whether the LRNG has been minimally seeded (i.e. is the
secondary DRNG seeded with at least 128 bits of of entropy)

- indicator whether the LRNG has been fully seeded (i.e. is the
secondary DRNG seeded with at least 256 bits of entropy)

[1] https://www.chronox.de/lrng.html

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Makefile  |   1 +
 drivers/char/lrng/lrng_interfaces.c |   2 -
 drivers/char/lrng/lrng_internal.h   |   4 +
 drivers/char/lrng/lrng_proc.c   | 181 
 4 files changed, 186 insertions(+), 2 deletions(-)
 create mode 100644 drivers/char/lrng/lrng_proc.c

diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 29724c65287d..ac97f0b11cb7 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -9,3 +9,4 @@ obj-y   += lrng_pool.o lrng_aux.o \
   lrng_interfaces.o
 
 obj-$(CONFIG_NUMA) += lrng_numa.o
+obj-$(CONFIG_SYSCTL)   += lrng_proc.o
diff --git a/drivers/char/lrng/lrng_interfaces.c 
b/drivers/char/lrng/lrng_interfaces.c
index 19d01d3f7492..b55de97523ad 100644
--- a/drivers/char/lrng/lrng_interfaces.c
+++ b/drivers/char/lrng/lrng_interfaces.c
@@ -38,8 +38,6 @@ static DECLARE_WAIT_QUEUE_HEAD(lrng_write_wait);
 static DECLARE_WAIT_QUEUE_HEAD(lrng_init_wait);
 static struct fasync_struct *fasync;
 
-struct ctl_table random_table[];
-
 /** Helper ***/
 
 /* Is the DRNG seed level too low? */
diff --git a/drivers/char/lrng/lrng_internal.h 
b/drivers/char/lrng/lrng_internal.h
index c405cbf379d6..42014df47028 100644
--- a/drivers/char/lrng/lrng_internal.h
+++ b/drivers/char/lrng/lrng_internal.h
@@ -113,7 +113,11 @@ void lrng_cc20_init_state_boot(struct chacha20_state 
*state);
 
 /** /proc 
*/
 
+#ifdef CONFIG_SYSCTL
+void lrng_pool_inc_numa_node(void);
+#else
 static inline void lrng_pool_inc_numa_node(void) { }
+#endif
 
 /** LRNG interfaces 
***/
 
diff --git a/drivers/char/lrng/lrng_proc.c b/drivers/char/lrng/lrng_proc.c
new file mode 100644
index ..7cd1628d823f
--- /dev/null
+++ b/drivers/char/lrng/lrng_proc.c
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG proc and sysctl interfaces
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "lrng_internal.h"
+#include "lrng_sw_noise.h"
+
+/*
+ * This function is used to return both the bootid UUID, and random
+ * UUID.  The difference is in whether table->data is NULL; if it is,
+ * then a new UUID is generated and returned to the user.
+ *
+ * If the user accesses this via the proc interface, the UUID will be
+ * returned as an ASCII string in the standard UUID format; if via the
+ * sysctl system call, as 16 bytes of binary data.
+ */
+static int lrng_proc_do_uuid(struct ctl_table *table, int write,
+void *buffer, size_t *lenp, loff_t *ppos)
+{
+   struct ctl_table fake_table;
+   unsigned char buf[64], tmp_uuid[16], *uuid;
+
+   uuid = table->data;
+   if (!uuid) {
+   uuid = tmp_uuid;
+   generate_random_uuid(uuid);
+   } else {
+   static DEFINE_SPINLOCK(bootid_spinlock);
+
+   spin_lock(_spinlock);
+   if (!uuid[8])
+   generate_random_uuid(uuid);
+   spin_unlock(_spinlock);
+   }
+

[PATCH v35 06/13] crypto: DRBG - externalize DRBG functions for LRNG

2020-09-18 Thread Stephan Müller
This patch allows several DRBG functions to be called by the LRNG kernel
code paths outside the drbg.c file.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 crypto/drbg.c | 16 ++--
 include/crypto/drbg.h |  7 +++
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index 3132967a1749..58b1de903def 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[] = {
+const struct drbg_core drbg_cores[] = {
 #ifdef CONFIG_CRYPTO_DRBG_CTR
{
.flags = DRBG_CTR | DRBG_STRENGTH128,
@@ -190,6 +190,7 @@ static const struct drbg_core drbg_cores[] = {
},
 #endif /* CONFIG_CRYPTO_DRBG_HMAC */
 };
+EXPORT_SYMBOL(drbg_cores);
 
 static int drbg_uninstantiate(struct drbg_state *drbg);
 
@@ -205,7 +206,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:
@@ -218,6 +219,7 @@ static inline unsigned short drbg_sec_strength(drbg_flag_t 
flags)
return 32;
}
 }
+EXPORT_SYMBOL(drbg_sec_strength);
 
 /*
  * FIPS 140-2 continuous self test for the noise source
@@ -1214,7 +1216,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;
@@ -1235,12 +1237,13 @@ static inline void drbg_dealloc_state(struct drbg_state 
*drbg)
drbg->fips_primed = false;
}
 }
+EXPORT_SYMBOL(drbg_dealloc_state);
 
 /*
  * 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;
@@ -1321,6 +1324,7 @@ static inline int drbg_alloc_state(struct drbg_state 
*drbg)
drbg_dealloc_state(drbg);
return ret;
 }
+EXPORT_SYMBOL(drbg_alloc_state);
 
 /*
  * DRBG interface functions
@@ -1890,8 +1894,7 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
  *
  * 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;
@@ -1918,6 +1921,7 @@ static inline void drbg_convert_tfm_core(const char 
*cra_driver_name,
}
}
 }
+EXPORT_SYMBOL(drbg_convert_tfm_core);
 
 static int drbg_kcapi_init(struct crypto_tfm *tfm)
 {
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index c4165126937e..71d53e028e6d 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -278,4 +278,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 const struct drbg_core drbg_cores[];
+extern unsigned short drbg_sec_strength(drbg_flag_t flags);
+
 #endif /* _DRBG_H */
-- 
2.26.2






[PATCH v35 08/13] LRNG - add kernel crypto API PRNG extension

2020-09-18 Thread Stephan Müller
Add runtime-pluggable support for all PRNGs that are accessible via
the kernel crypto API, including hardware PRNGs. The PRNG is selected
with the module parameter drng_name where the name must be one that the
kernel crypto API can resolve into an RNG.

This allows using of the kernel crypto API PRNG implementations that
provide an interface to hardware PRNGs. Using this extension,
the LRNG uses the hardware PRNGs to generate random numbers. An
example is the S390 CPACF support providing such a PRNG.

The hash is provided by a kernel crypto API SHASH whose digest size
complies with the seedsize of the PRNG.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig  |  13 ++
 drivers/char/lrng/Makefile |   1 +
 drivers/char/lrng/lrng_kcapi.c | 228 +
 3 files changed, 242 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_kcapi.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index a3c4cd153f35..af487b3391e0 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -91,6 +91,19 @@ config LRNG_DRBG
  Enable the SP800-90A DRBG support for the LRNG. Once the
  module is loaded, output from /dev/random, /dev/urandom,
  getrandom(2), or get_random_bytes_full is provided by a DRBG.
+
+config LRNG_KCAPI
+   tristate "Kernel Crypto API support for the LRNG"
+   depends on CRYPTO
+   depends on !LRNG_DRBG
+   select CRYPTO_RNG
+   select LRNG_KCAPI_HASH
+   help
+ Enable the support for generic pseudo-random number
+ generators offered by the kernel crypto API with the
+ LRNG. Once the module is loaded, output from /dev/random,
+ /dev/urandom, getrandom(2), or get_random_bytes is
+ provided by the selected kernel crypto API RNG.
 endif # LRNG_DRNG_SWITCH
 
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 6ebd252db12f..97d2b13d3227 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_SYSCTL)  += lrng_proc.o
 obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
 obj-$(CONFIG_LRNG_KCAPI_HASH)  += lrng_kcapi_hash.o
 obj-$(CONFIG_LRNG_DRBG)+= lrng_drbg.o
+obj-$(CONFIG_LRNG_KCAPI)   += lrng_kcapi.o
diff --git a/drivers/char/lrng/lrng_kcapi.c b/drivers/char/lrng/lrng_kcapi.c
new file mode 100644
index ..197dc84552e9
--- /dev/null
+++ b/drivers/char/lrng/lrng_kcapi.c
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Backend for the LRNG providing the cryptographic primitives using the
+ * kernel crypto API.
+ *
+ * Copyright (C) 2018 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "lrng_kcapi_hash.h"
+
+static char *drng_name = NULL;
+module_param(drng_name, charp, 0444);
+MODULE_PARM_DESC(drng_name, "Kernel crypto API name of DRNG");
+
+static char *pool_hash = "sha512";
+module_param(pool_hash, charp, 0444);
+MODULE_PARM_DESC(pool_hash,
+"Kernel crypto API name of hash or keyed message digest to 
read the entropy pool");
+
+static char *seed_hash = NULL;
+module_param(seed_hash, charp, 0444);
+MODULE_PARM_DESC(seed_hash,
+"Kernel crypto API name of hash with output size equal to 
seedsize of DRNG to bring seed string to the size required by the DRNG");
+
+struct lrng_drng_info {
+   struct crypto_rng *kcapi_rng;
+   void *lrng_hash;
+};
+
+static void *lrng_kcapi_drng_hash_alloc(void)
+{
+   return lrng_kcapi_hash_alloc(pool_hash);
+}
+
+static int lrng_kcapi_drng_seed_helper(void *drng, const u8 *inbuf,
+  u32 inbuflen)
+{
+   SHASH_DESC_ON_STACK(shash, NULL);
+   struct lrng_drng_info *lrng_drng_info = (struct lrng_drng_info *)drng;
+   struct crypto_rng *kcapi_rng = lrng_drng_info->kcapi_rng;
+   void *hash = lrng_drng_info->lrng_hash;
+   u32 digestsize = lrng_kcapi_hash_digestsize(hash);
+   u8 digest[64] __aligned(8);
+   int ret;
+
+   if (!hash)
+   return crypto_rng_reset(kcapi_rng, inbuf, inbuflen);
+
+   BUG_ON(digestsize > sizeof(digest));
+
+   ret = lrng_kcapi_hash_init(shash, hash) ?:
+ lrng_kcapi_hash_update(shash, inbuf, inbuflen) ?:
+ lrng_kcapi_hash_final(shash, digest);
+   if (ret)
+   return ret;
+
+   ret = 

[PATCH v35 07/13] LRNG - add SP800-90A DRBG extension

2020-09-18 Thread Stephan Müller
Using the LRNG switchable DRNG support, the SP800-90A DRBG extension is
implemented.

The DRBG uses the kernel crypto API DRBG implementation. In addition, it
uses the kernel crypto API SHASH support to provide the hashing
operation.

The DRBG supports the choice of either a CTR DRBG using AES-256, HMAC
DRBG with SHA-512 core or Hash DRBG with SHA-512 core. The used core can
be selected with the module parameter lrng_drbg_type. The default is the
CTR DRBG.

When compiling the DRBG extension statically, the DRBG is loaded at
late_initcall stage which implies that with the start of user space, the
user space interfaces of getrandom(2), /dev/random and /dev/urandom
provide random data produced by an SP800-90A DRBG.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig |  10 ++
 drivers/char/lrng/Makefile|   1 +
 drivers/char/lrng/lrng_drbg.c | 197 ++
 3 files changed, 208 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_drbg.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index daa2057248ac..a3c4cd153f35 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -81,6 +81,16 @@ if LRNG_DRNG_SWITCH
 config LRNG_KCAPI_HASH
bool
 
+config LRNG_DRBG
+   tristate "SP800-90A support for the LRNG"
+   depends on CRYPTO
+   select CRYPTO_DRBG_MENU
+   select CRYPTO_SHA512
+   select LRNG_KCAPI_HASH
+   help
+ Enable the SP800-90A DRBG support for the LRNG. Once the
+ module is loaded, output from /dev/random, /dev/urandom,
+ getrandom(2), or get_random_bytes_full is provided by a DRBG.
 endif # LRNG_DRNG_SWITCH
 
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 40f8826edeeb..6ebd252db12f 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_NUMA)+= lrng_numa.o
 obj-$(CONFIG_SYSCTL)   += lrng_proc.o
 obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
 obj-$(CONFIG_LRNG_KCAPI_HASH)  += lrng_kcapi_hash.o
+obj-$(CONFIG_LRNG_DRBG)+= lrng_drbg.o
diff --git a/drivers/char/lrng/lrng_drbg.c b/drivers/char/lrng/lrng_drbg.c
new file mode 100644
index ..c428d41af64d
--- /dev/null
+++ b/drivers/char/lrng/lrng_drbg.c
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Backend for the LRNG providing the cryptographic primitives using the
+ * kernel crypto API and its DRBG.
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+
+#include "lrng_kcapi_hash.h"
+
+/*
+ * Define a DRBG plus a hash / MAC used to extract data from the entropy pool.
+ * For LRNG_HASH_NAME you can use a hash or a MAC (HMAC or CMAC) of your choice
+ * (Note, you should use the suggested selections below -- using SHA-1 or MD5
+ * is not wise). The idea is that the used cipher primitive can be selected to
+ * be the same as used for the DRBG. I.e. the LRNG only uses one cipher
+ * primitive using the same cipher implementation with the options offered in
+ * the following. This means, if the CTR DRBG is selected and AES-NI is 
present,
+ * both the CTR DRBG and the selected cmac(aes) use AES-NI.
+ *
+ * The security strengths of the DRBGs are all 256 bits according to
+ * SP800-57 section 5.6.1.
+ *
+ * This definition is allowed to be changed.
+ */
+#ifdef CONFIG_CRYPTO_DRBG_CTR
+static unsigned int lrng_drbg_type = 0;
+#elif defined CONFIG_CRYPTO_DRBG_HMAC
+static unsigned int lrng_drbg_type = 1;
+#elif defined CONFIG_CRYPTO_DRBG_HASH
+static unsigned int lrng_drbg_type = 2;
+#else
+#error "Unknown DRBG in use"
+#endif
+
+/* The parameter must be r/o in sysfs as otherwise races appear. */
+module_param(lrng_drbg_type, uint, 0444);
+MODULE_PARM_DESC(lrng_drbg_type, "DRBG type used for LRNG (0->CTR_DRBG, 
1->HMAC_DRBG, 2->Hash_DRBG)");
+
+struct lrng_drbg {
+   const char *hash_name;
+   const char *drbg_core;
+};
+
+static const struct lrng_drbg lrng_drbg_types[] = {
+   {   /* CTR_DRBG with AES-256 using derivation function */
+   .hash_name = "sha512",
+   .drbg_core = "drbg_nopr_ctr_aes256",
+   }, {/* HMAC_DRBG with SHA-512 */
+   .hash_name = "sha512",
+   .drbg_core = "drbg_nopr_hmac_sha512",
+   }, {/* Hash_DRBG with SHA-512 using derivation function */
+   .hash_name = "sha512",
+   .drbg_core = 

[PATCH v35 13/13] LRNG - add power-on and runtime self-tests

2020-09-18 Thread Stephan Müller
Parts of the LRNG are already covered by self-tests, including:

* Self-test of SP800-90A DRBG provided by the Linux kernel crypto API.

* Self-test of the PRNG provided by the Linux kernel crypto API.

* Raw noise source data testing including SP800-90B compliant
  tests when enabling CONFIG_LRNG_HEALTH_TESTS

This patch adds the self-tests for the remaining critical functions of
the LRNG that are essential to maintain entropy and provide
cryptographic strong random numbers. The following self-tests are
implemented:

* Self-test of the time array maintenance. This test verifies whether
the time stamp array management to store multiple values in one integer
implements a concatenation of the data.

* Self-test of the software hash implementation ensures that this
function operates compliant to the FIPS 180-4 specification. The
self-test performs a hash operation of a zeroized per-CPU data array.

* Self-test of the ChaCha20 DRNG is based on the self-tests that are
already present and implemented with the stand-alone user space
ChaCha20 DRNG implementation available at [1]. The self-tests cover
different use cases of the DRNG seeded with known seed data.

The status of the LRNG self-tests is provided with the selftest_status
SysFS file. If the file contains a zero, the self-tests passed. The
value 0x means that the self-tests were not executed. Any other
value indicates a self-test failure.

The self-test may be compiled to panic the system if the self-test
fails.

All self-tests operate on private state data structures. This implies
that none of the self-tests have any impact on the regular LRNG
operations. This allows the self-tests to be repeated at runtime by
writing anything into the selftest_status SysFS file.

[1] https://www.chronox.de/chacha20.html

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
CC: Marcelo Henrique Cerri 
CC: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig |  26 +++
 drivers/char/lrng/Makefile|   1 +
 drivers/char/lrng/lrng_selftest.c | 344 ++
 3 files changed, 371 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_selftest.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index bb785bc61abb..6f180641a5da 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -324,4 +324,30 @@ config LRNG_TESTING
 
 endif #LRNG_TESTING_MENU
 
+config LRNG_SELFTEST
+   bool "Enable power-on and on-demand self-tests"
+   help
+ The power-on self-tests are executed during boot time
+ covering the ChaCha20 DRNG, the hash operation used for
+ processing the entropy pools and the auxiliary pool, and
+ the time stamp management of the LRNG.
+
+ The on-demand self-tests are triggered by writing any
+ value into the SysFS file selftest_status. At the same
+ time, when reading this file, the test status is
+ returned. A zero indicates that all tests were executed
+ successfully.
+
+ If unsure, say Y.
+
+if LRNG_SELFTEST
+
+config LRNG_SELFTEST_PANIC
+   bool "Panic the kernel upon self-test failure"
+   help
+ If the option is enabled, the kernel is terminated if an
+ LRNG power-on self-test failure is detected.
+
+endif # LRNG_SELFTEST
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 532501b38a00..a633638af991 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_LRNG_KCAPI)  += lrng_kcapi.o
 obj-$(CONFIG_LRNG_JENT)+= lrng_jent.o
 obj-$(CONFIG_LRNG_HEALTH_TESTS)+= lrng_health.o
 obj-$(CONFIG_LRNG_TESTING) += lrng_testing.o
+obj-$(CONFIG_LRNG_SELFTEST)+= lrng_selftest.o
diff --git a/drivers/char/lrng/lrng_selftest.c 
b/drivers/char/lrng/lrng_selftest.c
new file mode 100644
index ..4c7d124d24a4
--- /dev/null
+++ b/drivers/char/lrng/lrng_selftest.c
@@ -0,0 +1,344 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG power-on and on-demand self-test
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+/*
+ * In addition to the self-tests below, the following LRNG components
+ * are covered with self-tests during regular operation:
+ *
+ * * power-on self-test: SP800-90A DRBG provided by the Linux kernel crypto API
+ * * power-on self-test: PRNG provided by the Linux kernel crypto API
+ * * runtime test: Raw noise source data testing including SP800-90B compliant
+ *tests when enabling CONFIG_LRNG_HEALTH_TESTS
+ *
+ * Additional developer tests present with LRNG code:
+ * * SP800-90B APT and RCT test enforcement validation 

[PATCH v35 09/13] crypto: provide access to a static Jitter RNG state

2020-09-18 Thread Stephan Müller
To support the LRNG operation which uses the Jitter RNG separately
from the kernel crypto API, at a time where potentially the regular
memory management is not yet initialized, the Jitter RNG needs to
provide a state whose memory is defined at compile time. As only once
instance will ever be needed by the LRNG, define once static memory
block which is solely to be used by the LRNG.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 crypto/jitterentropy-kcapi.c  |  3 +-
 crypto/jitterentropy.c| 31 ++-
 .../crypto/internal}/jitterentropy.h  |  3 ++
 3 files changed, 34 insertions(+), 3 deletions(-)
 rename {crypto => include/crypto/internal}/jitterentropy.h (84%)

diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c
index eb7d1dd506bf..25a192f5984e 100644
--- a/crypto/jitterentropy-kcapi.c
+++ b/crypto/jitterentropy-kcapi.c
@@ -43,8 +43,7 @@
 #include 
 #include 
 #include 
-
-#include "jitterentropy.h"
+#include 
 
 /***
  * Helper function
diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c
index 6e147c43fc18..fa1459f09b01 100644
--- a/crypto/jitterentropy.c
+++ b/crypto/jitterentropy.c
@@ -117,7 +117,7 @@ struct rand_data {
 #define JENT_EHEALTH   9 /* Health test failed during initialization */
 #define JENT_ERCT  10 /* RCT failed during initialization */
 
-#include "jitterentropy.h"
+#include 
 
 /***
  * Adaptive Proportion Test
@@ -854,3 +854,32 @@ int jent_entropy_init(void)
 
return 0;
 }
+
+struct rand_data *jent_lrng_entropy_collector(void)
+{
+   static unsigned char lrng_jent_mem[JENT_MEMORY_SIZE];
+   static struct rand_data lrng_jent_state = {
+   .data   = 0,
+   .old_data   = 0,
+   .prev_time  = 0,
+   .last_delta = 0,
+   .last_delta2= 0,
+   .osr= 1,
+   .mem= lrng_jent_mem,
+   .memlocation= 0,
+   .memblocks  = JENT_MEMORY_BLOCKSIZE,
+   .memblocksize   = JENT_MEMORY_BLOCKS,
+   .memaccessloops = JENT_MEMORY_ACCESSLOOPS,
+   .rct_count  = 0,
+   .apt_observations = 0,
+   .apt_count  = 0,
+   .apt_base   = 0,
+   .apt_base_set   = 0,
+   .health_failure = 0
+   };
+
+   if (jent_entropy_init())
+   return NULL;
+
+   return _jent_state;
+}
diff --git a/crypto/jitterentropy.h b/include/crypto/internal/jitterentropy.h
similarity index 84%
rename from crypto/jitterentropy.h
rename to include/crypto/internal/jitterentropy.h
index c83fff32d130..6e07d86eac82 100644
--- a/crypto/jitterentropy.h
+++ b/include/crypto/internal/jitterentropy.h
@@ -15,3 +15,6 @@ extern int jent_read_entropy(struct rand_data *ec, unsigned 
char *data,
 extern struct rand_data *jent_entropy_collector_alloc(unsigned int osr,
  unsigned int flags);
 extern void jent_entropy_collector_free(struct rand_data *entropy_collector);
+
+/* Access to statically allocated Jitter RNG instance */
+extern struct rand_data *jent_lrng_entropy_collector(void);
-- 
2.26.2






[PATCH v34 08/12] crypto: provide access to a static Jitter RNG state

2020-08-25 Thread Stephan Müller
To support the LRNG operation which uses the Jitter RNG separately
from the kernel crypto API, at a time where potentially the regular
memory management is not yet initialized, the Jitter RNG needs to
provide a state whose memory is defined at compile time. As only once
instance will ever be needed by the LRNG, define once static memory
block which is solely to be used by the LRNG.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 crypto/jitterentropy-kcapi.c  |  3 +-
 crypto/jitterentropy.c| 31 ++-
 .../crypto/internal}/jitterentropy.h  |  3 ++
 3 files changed, 34 insertions(+), 3 deletions(-)
 rename {crypto => include/crypto/internal}/jitterentropy.h (84%)

diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c
index eb7d1dd506bf..25a192f5984e 100644
--- a/crypto/jitterentropy-kcapi.c
+++ b/crypto/jitterentropy-kcapi.c
@@ -43,8 +43,7 @@
 #include 
 #include 
 #include 
-
-#include "jitterentropy.h"
+#include 
 
 /***
  * Helper function
diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c
index 6e147c43fc18..fa1459f09b01 100644
--- a/crypto/jitterentropy.c
+++ b/crypto/jitterentropy.c
@@ -117,7 +117,7 @@ struct rand_data {
 #define JENT_EHEALTH   9 /* Health test failed during initialization */
 #define JENT_ERCT  10 /* RCT failed during initialization */
 
-#include "jitterentropy.h"
+#include 
 
 /***
  * Adaptive Proportion Test
@@ -854,3 +854,32 @@ int jent_entropy_init(void)
 
return 0;
 }
+
+struct rand_data *jent_lrng_entropy_collector(void)
+{
+   static unsigned char lrng_jent_mem[JENT_MEMORY_SIZE];
+   static struct rand_data lrng_jent_state = {
+   .data   = 0,
+   .old_data   = 0,
+   .prev_time  = 0,
+   .last_delta = 0,
+   .last_delta2= 0,
+   .osr= 1,
+   .mem= lrng_jent_mem,
+   .memlocation= 0,
+   .memblocks  = JENT_MEMORY_BLOCKSIZE,
+   .memblocksize   = JENT_MEMORY_BLOCKS,
+   .memaccessloops = JENT_MEMORY_ACCESSLOOPS,
+   .rct_count  = 0,
+   .apt_observations = 0,
+   .apt_count  = 0,
+   .apt_base   = 0,
+   .apt_base_set   = 0,
+   .health_failure = 0
+   };
+
+   if (jent_entropy_init())
+   return NULL;
+
+   return _jent_state;
+}
diff --git a/crypto/jitterentropy.h b/include/crypto/internal/jitterentropy.h
similarity index 84%
rename from crypto/jitterentropy.h
rename to include/crypto/internal/jitterentropy.h
index c83fff32d130..6e07d86eac82 100644
--- a/crypto/jitterentropy.h
+++ b/include/crypto/internal/jitterentropy.h
@@ -15,3 +15,6 @@ extern int jent_read_entropy(struct rand_data *ec, unsigned 
char *data,
 extern struct rand_data *jent_entropy_collector_alloc(unsigned int osr,
  unsigned int flags);
 extern void jent_entropy_collector_free(struct rand_data *entropy_collector);
+
+/* Access to statically allocated Jitter RNG instance */
+extern struct rand_data *jent_lrng_entropy_collector(void);
-- 
2.26.2






[PATCH v34 09/12] LRNG - add Jitter RNG fast noise source

2020-08-25 Thread Stephan Müller
The Jitter RNG fast noise source implemented as part of the kernel
crypto API is queried for 256 bits of entropy at the time the seed
buffer managed by the LRNG is about to be filled.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig | 12 +
 drivers/char/lrng/Makefile|  1 +
 drivers/char/lrng/lrng_jent.c | 88 +++
 3 files changed, 101 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_jent.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index c89de14d173a..377593fc1985 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -96,4 +96,16 @@ config LRNG_KCAPI
  provided by the selected kernel crypto API RNG.
 endif # LRNG_DRNG_SWITCH
 
+config LRNG_JENT
+   bool "Enable Jitter RNG as LRNG Seed Source"
+   depends on CRYPTO
+   select CRYPTO_JITTERENTROPY
+   help
+ The Linux RNG may use the Jitter RNG as noise source. Enabling
+ this option enables the use of the Jitter RNG. Its default
+ entropy level is 16 bits of entropy per 256 data bits delivered
+ by the Jitter RNG. This entropy level can be changed at boot
+ time or at runtime with the lrng_base.jitterrng configuration
+ variable.
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 94b2dfb2dfdb..4f5b6f38f0c4 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_SYSCTL)  += lrng_proc.o
 obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
 obj-$(CONFIG_LRNG_DRBG)+= lrng_drbg.o
 obj-$(CONFIG_LRNG_KCAPI)   += lrng_kcapi.o
+obj-$(CONFIG_LRNG_JENT)+= lrng_jent.o
diff --git a/drivers/char/lrng/lrng_jent.c b/drivers/char/lrng/lrng_jent.c
new file mode 100644
index ..225505271fcb
--- /dev/null
+++ b/drivers/char/lrng/lrng_jent.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG Fast Noise Source: Jitter RNG
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+
+#include "lrng_internal.h"
+
+/*
+ * Estimated entropy of data is a 16th of LRNG_DRNG_SECURITY_STRENGTH_BITS.
+ * Albeit a full entropy assessment is provided for the noise source indicating
+ * that it provides high entropy rates and considering that it deactivates
+ * when it detects insufficient hardware, the chosen under estimation of
+ * entropy is considered to be acceptable to all reviewers.
+ */
+static u32 jitterrng = LRNG_DRNG_SECURITY_STRENGTH_BITS>>4;
+module_param(jitterrng, uint, 0644);
+MODULE_PARM_DESC(jitterrng, "Entropy in bits of 256 data bits from Jitter RNG 
noise source");
+
+/**
+ * lrng_get_jent() - Get Jitter RNG entropy
+ *
+ * @outbuf: buffer to store entropy
+ * @outbuflen: length of buffer
+ *
+ * Return:
+ * * > 0 on success where value provides the added entropy in bits
+ * * 0 if no fast source was available
+ */
+static struct rand_data *lrng_jent_state;
+
+u32 lrng_get_jent(u8 *outbuf, unsigned int outbuflen)
+{
+   int ret;
+   u32 ent_bits = jitterrng;
+   unsigned long flags;
+   static DEFINE_SPINLOCK(lrng_jent_lock);
+   static int lrng_jent_initialized = 0;
+
+   spin_lock_irqsave(_jent_lock, flags);
+
+   if (!ent_bits || (lrng_jent_initialized == -1)) {
+   spin_unlock_irqrestore(_jent_lock, flags);
+   return 0;
+   }
+
+   if (!lrng_jent_initialized) {
+   lrng_jent_state = jent_lrng_entropy_collector();
+   if (!lrng_jent_state) {
+   jitterrng = 0;
+   lrng_jent_initialized = -1;
+   spin_unlock_irqrestore(_jent_lock, flags);
+   pr_info("Jitter RNG unusable on current system\n");
+   return 0;
+   }
+   lrng_jent_initialized = 1;
+   pr_debug("Jitter RNG working on current system\n");
+   }
+   ret = jent_read_entropy(lrng_jent_state, outbuf, outbuflen);
+   spin_unlock_irqrestore(_jent_lock, flags);
+
+   if (ret) {
+   pr_debug("Jitter RNG failed with %d\n", ret);
+   return 0;
+   }
+
+   /* Obtain entropy statement */
+   if (outbuflen != LRNG_DRNG_SECURITY_STRENGTH_BYTES)
+   ent_bits = (ent_bits * outbuflen<<3) /
+  LRNG_DRNG_SECURITY_STRENGTH_BITS;

[PATCH v34 12/12] LRNG - add power-on and runtime self-tests

2020-08-25 Thread Stephan Müller
Parts of the LRNG are already covered by self-tests, including:

* Self-test of SP800-90A DRBG provided by the Linux kernel crypto API.

* Self-test of the PRNG provided by the Linux kernel crypto API.

* Raw noise source data testing including SP800-90B compliant
  tests when enabling CONFIG_LRNG_HEALTH_TESTS

This patch adds the self-tests for the remaining critical functions of
the LRNG that are essential to maintain entropy and provide
cryptographic strong random numbers. The following self-tests are
implemented:

* Self-test of the time array maintenance. This test verifies whether
the time stamp array management to store multiple values in one integer
implements a concatenation of the data.

* Self-test of the LFSR operation. This test injects a monotonic
increasing counter into the LFSR. After completion of the injection of
the counter, 3 pool words are compared with known good values. The known
good values are calculated with the newly-developed tool
lfsr_testvector_generation provided as part of the LRNG test tool set at
[1].

* Self-test of the Hash_DF operation ensures that this function operates
compliant to the specification. The self-test performs a Hash_DF
operation of a zeroized entropy pool state. The test vectors are
generated using the newly-developed tool hash_df_testvector_generation
provided as part of the LRNG test tool set at [1].

* Self-test of the ChaCha20 DRNG is based on the self-tests that are
already present and implemented with the stand-alone user space
ChaCha20 DRNG implementation available at [2]. The self-tests cover
different use cases of the DRNG seeded with known seed data.

The status of the LRNG self-tests is provided with the selftest_status
SysFS file. If the file contains a zero, the self-tests passed. The
value 0x means that the self-tests were not executed. Any other
value indicates a self-test failure.

The self-test may be compiled to panic the system if the self-test
fails.

All self-tests operate on private state data structures. This implies
that none of the self-tests have any impact on the regular LRNG
operations. This allows the self-tests to be repeated at runtime by
writing anything into the selftest_status SysFS file.

[1] https://www.chronox.de/lrng.html
[2] https://www.chronox.de/chacha20.html

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
CC: Marcelo Henrique Cerri 
CC: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig |  25 ++
 drivers/char/lrng/Makefile|   1 +
 drivers/char/lrng/lrng_selftest.c | 506 ++
 3 files changed, 532 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_selftest.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index de20f189e297..b75d809bed50 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -288,4 +288,29 @@ config LRNG_TESTING
 
 endif #LRNG_TESTING_MENU
 
+config LRNG_SELFTEST
+   bool "Enable power-on and on-demand self-tests"
+   help
+ The power-on self-tests are executed during boot time
+ covering the ChaCha20 DRNG, the LFSR processing and the
+ time stamp management of the LRNG.
+
+ The on-demand self-tests are triggered by writing any
+ value into the SysFS file selftest_status. At the same
+ time, when reading this file, the test status is
+ returned. A zero indicates that all tests were executed
+ successfully.
+
+ If unsure, say Y.
+
+if LRNG_SELFTEST
+
+config LRNG_SELFTEST_PANIC
+   bool "Panic the kernel upon self-test failure"
+   help
+ If the option is enabled, the kernel is terminated if an
+ LRNG power-on self-test failure is detected.
+
+endif # LRNG_SELFTEST
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index b2ce1979dc4b..92219c565f66 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_LRNG_KCAPI)  += lrng_kcapi.o
 obj-$(CONFIG_LRNG_JENT)+= lrng_jent.o
 obj-$(CONFIG_LRNG_HEALTH_TESTS)+= lrng_health.o
 obj-$(CONFIG_LRNG_TESTING) += lrng_testing.o
+obj-$(CONFIG_LRNG_SELFTEST)+= lrng_selftest.o
diff --git a/drivers/char/lrng/lrng_selftest.c 
b/drivers/char/lrng/lrng_selftest.c
new file mode 100644
index ..74a529b15fa5
--- /dev/null
+++ b/drivers/char/lrng/lrng_selftest.c
@@ -0,0 +1,506 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG power-on and on-demand self-test
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+/*
+ * In addition to the self-tests below, the following LRNG components
+ * are covered with self-tests during 

[PATCH v34 02/12] LRNG - allocate one DRNG instance per NUMA node

2020-08-25 Thread Stephan Müller
In order to improve NUMA-locality when serving getrandom(2) requests,
allocate one DRNG instance per node.

The DRNG instance that is present right from the start of the kernel is
reused as the first per-NUMA-node DRNG. For all remaining online NUMA
nodes a new DRNG instance is allocated.

During boot time, the multiple DRNG instances are seeded sequentially.
With this, the first DRNG instance (referenced as the initial DRNG
in the code) is completely seeded with 256 bits of entropy before the
next DRNG instance is completely seeded.

When random numbers are requested, the NUMA-node-local DRNG is checked
whether it has been already fully seeded. If this is not the case, the
initial DRNG is used to serve the request.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Makefile|   2 +
 drivers/char/lrng/lrng_internal.h |   5 ++
 drivers/char/lrng/lrng_numa.c | 101 ++
 3 files changed, 108 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_numa.c

diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 1d2a0211973d..0a32f22c2c1a 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -7,3 +7,5 @@ obj-y   += lrng_pool.o lrng_aux.o \
   lrng_sw_noise.o lrng_archrandom.o \
   lrng_drng.o lrng_chacha20.o \
   lrng_interfaces.o \
+
+obj-$(CONFIG_NUMA) += lrng_numa.o
diff --git a/drivers/char/lrng/lrng_internal.h 
b/drivers/char/lrng/lrng_internal.h
index f86afe8d2612..de034260c323 100644
--- a/drivers/char/lrng/lrng_internal.h
+++ b/drivers/char/lrng/lrng_internal.h
@@ -256,8 +256,13 @@ int lrng_drng_get_sleep(u8 *outbuf, u32 outbuflen);
 void lrng_drng_force_reseed(void);
 void lrng_drng_seed_work(struct work_struct *dummy);
 
+#ifdef CONFIG_NUMA
+struct lrng_drng **lrng_drng_instances(void);
+void lrng_drngs_numa_alloc(void);
+#else  /* CONFIG_NUMA */
 static inline struct lrng_drng **lrng_drng_instances(void) { return NULL; }
 static inline void lrng_drngs_numa_alloc(void) { return; }
+#endif /* CONFIG_NUMA */
 
 /** Health Test linking code 
**/
 
diff --git a/drivers/char/lrng/lrng_numa.c b/drivers/char/lrng/lrng_numa.c
new file mode 100644
index ..947c5b3ed517
--- /dev/null
+++ b/drivers/char/lrng/lrng_numa.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG NUMA support
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+
+#include "lrng_internal.h"
+
+static struct lrng_drng **lrng_drng __read_mostly = NULL;
+
+struct lrng_drng **lrng_drng_instances(void)
+{
+   return lrng_drng;
+}
+
+/* Allocate the data structures for the per-NUMA node DRNGs */
+static void _lrng_drngs_numa_alloc(struct work_struct *work)
+{
+   struct lrng_drng **drngs;
+   struct lrng_drng *lrng_drng_init = lrng_drng_init_instance();
+   u32 node;
+   bool init_drng_used = false;
+
+   mutex_lock(_crypto_cb_update);
+
+   /* per-NUMA-node DRNGs are already present */
+   if (lrng_drng)
+   goto unlock;
+
+   drngs = kcalloc(nr_node_ids, sizeof(void *), GFP_KERNEL|__GFP_NOFAIL);
+   for_each_online_node(node) {
+   struct lrng_drng *drng;
+
+   if (!init_drng_used) {
+   drngs[node] = lrng_drng_init;
+   init_drng_used = true;
+   continue;
+   }
+
+   drng = kmalloc_node(sizeof(struct lrng_drng),
+GFP_KERNEL|__GFP_NOFAIL, node);
+   memset(drng, 0, sizeof(lrng_drng));
+
+   drng->crypto_cb = lrng_drng_init->crypto_cb;
+   drng->drng = drng->crypto_cb->lrng_drng_alloc(
+   LRNG_DRNG_SECURITY_STRENGTH_BYTES);
+   if (IS_ERR(drng->drng)) {
+   kfree(drng);
+   goto err;
+   }
+
+   mutex_init(>lock);
+   spin_lock_init(>spin_lock);
+
+   /*
+* No reseeding of NUMA DRNGs from previous DRNGs as this
+* would complicate the code. Let it simply reseed.
+*/
+   lrng_drng_reset(drng);
+   drngs[node] = drng;
+
+   

[PATCH v34 05/12] crypto: DRBG - externalize DRBG functions for LRNG

2020-08-25 Thread Stephan Müller
This patch allows several DRBG functions to be called by the LRNG kernel
code paths outside the drbg.c file.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 crypto/drbg.c | 16 ++--
 include/crypto/drbg.h |  7 +++
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index e99fe34cfa00..3644e954785a 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[] = {
+const struct drbg_core drbg_cores[] = {
 #ifdef CONFIG_CRYPTO_DRBG_CTR
{
.flags = DRBG_CTR | DRBG_STRENGTH128,
@@ -190,6 +190,7 @@ static const struct drbg_core drbg_cores[] = {
},
 #endif /* CONFIG_CRYPTO_DRBG_HMAC */
 };
+EXPORT_SYMBOL(drbg_cores);
 
 static int drbg_uninstantiate(struct drbg_state *drbg);
 
@@ -205,7 +206,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:
@@ -218,6 +219,7 @@ static inline unsigned short drbg_sec_strength(drbg_flag_t 
flags)
return 32;
}
 }
+EXPORT_SYMBOL(drbg_sec_strength);
 
 /*
  * FIPS 140-2 continuous self test for the noise source
@@ -1214,7 +1216,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;
@@ -1235,12 +1237,13 @@ static inline void drbg_dealloc_state(struct drbg_state 
*drbg)
drbg->fips_primed = false;
}
 }
+EXPORT_SYMBOL(drbg_dealloc_state);
 
 /*
  * 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;
@@ -1321,6 +1324,7 @@ static inline int drbg_alloc_state(struct drbg_state 
*drbg)
drbg_dealloc_state(drbg);
return ret;
 }
+EXPORT_SYMBOL(drbg_alloc_state);
 
 /*
  * DRBG interface functions
@@ -1890,8 +1894,7 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
  *
  * 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;
@@ -1918,6 +1921,7 @@ static inline void drbg_convert_tfm_core(const char 
*cra_driver_name,
}
}
 }
+EXPORT_SYMBOL(drbg_convert_tfm_core);
 
 static int drbg_kcapi_init(struct crypto_tfm *tfm)
 {
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index c4165126937e..71d53e028e6d 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -278,4 +278,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 const struct drbg_core drbg_cores[];
+extern unsigned short drbg_sec_strength(drbg_flag_t flags);
+
 #endif /* _DRBG_H */
-- 
2.26.2






[PATCH v34 01/12] Linux Random Number Generator

2020-08-25 Thread Stephan Müller
In an effort to provide a flexible implementation for a random number
generator that also delivers entropy during early boot time, allows
replacement of the deterministic random number generation mechanism,
implement the various components in separate code for easier
maintenance, and provide compliance to SP800-90[A|B|C], introduce
the Linux Random Number Generator (LRNG) framework.

The general design is as follows. Additional implementation details
are given in [1]. The LRNG consists of the following components:

1. The LRNG implements a DRNG. The DRNG always generates the
requested amount of output. When using the SP800-90A terminology
it operates without prediction resistance. The secondary DRNG
maintains a counter of how many bytes were generated since last
re-seed and a timer of the elapsed time since last re-seed. If either
the counter or the timer reaches a threshold, the secondary DRNG is
seeded from the entropy pool.

In case the Linux kernel detects a NUMA system, one secondary DRNG
instance per NUMA node is maintained.

2. The DRNG is seeded by concatenating the data from the
following sources:

(a) the output of the entropy pool,

(b) the Jitter RNG if available and enabled, and

(c) the CPU-based noise source such as Intel RDRAND if available and
enabled.

The entropy estimate of the data of all noise sources are added to
form the entropy estimate of the data used to seed the DRNG with.
The LRNG ensures, however, that the DRNG after seeding is at
maximum the security strength of the DRNG.

The LRNG is designed such that none of these noise sources can dominate
the other noise sources to provide seed data to the DRNG during due to
the following:

(a) During boot time, the amount of received interrupts are the trigger
points to (re)seed the DRNG.

(b) At runtime, the available entropy from the slow noise source is
concatenated with a pre-defined amount of data from the fast noise
sources. In addition, each DRNG reseed operation triggers external
noise source providers to deliver one block of data.

3. The entropy pool accumulates entropy obtained from certain events,
which will henceforth be collectively called "slow noise sources".
The entropy pool collects noise data from slow noise sources. Any data
received by the LRNG from the slow noise sources is inserted into the
entropy pool using an LFSR with a primitive and irreducible polynomial.
The following sources of entropy are used:

 (a) When an interrupt occurs, the high-resolution time stamp is mixed
into the LFSR. This time stamp is credited with heuristically implied
entropy.

 (b) HID event data like the key stroke or the mouse coordinates are
mixed into the LFSR. This data is not credited with entropy by the LRNG.

 (c) Device drivers may provide data that is mixed into the LFSR. This
data is not credited with entropy by the LRNG.

 (d) After the entropy pool is ``read'' by the DRNG, the data
used to seed the DRNG is mixed back into the entropy pool to
stir the pool. This data is not credited with entropy by the LRNG.

Any data provided from user space by either writing to /dev/random,
/dev/urandom or the IOCTL of RNDADDENTROPY on both device files
are always injected into the entropy pool.

In addition, when a hardware random number generator covered by the
Linux kernel HW generator framework wants to deliver random numbers,
it is injected into the entropy pool as well. HW generator noise source
is handled separately from the other noise source due to the fact that
the HW generator framework may decide by itself when to deliver data
whereas the other noise sources always requested for data driven by the
LRNG operation. Similarly any user space provided data is inserted into
the entropy pool.

When the DRNG requires data from the entropy pool, the entire
entropy pool is processed with an SP800-90A section 10.3.1 compliant
hash_df function to generate random numbers.

To speed up the interrupt handling code of the LRNG, the time stamp
collected for an interrupt event is truncated to the 8 least
significant bits. 64 truncated time stamps are concatenated and then
jointly inserted into the LFSR. During boot time, until the fully seeded
stage is reached, each time stamp with its 32 least significant bits is
inserted into the LFSR at the time of arrival.

The LRNG allows the DRNG mechanism to be changed at runtime. Per default,
a ChaCha20-based DRNG is used. The ChaCha20-DRNG implemented for the
LRNG is also provided as a stand-alone user space deterministic random
number generator. The LRNG also offers an SP800-90A DRBG based on the
Linux kernel crypto API DRBG implementation.

The processing of entropic data from the noise source before injecting
them into the DRNG is performed with the following mathematical
operations:

1. LFSR: The 8 least significant bits of the time stamp data received
from the interrupts are processed with an LFSR. That LFSR is implemented
identically to the LSFR used in the existing /dev/random implementation

[PATCH v34 03/12] LRNG - sysctls and /proc interface

2020-08-25 Thread Stephan Müller
The LRNG sysctl interface provides the same controls as the existing
/dev/random implementation. These sysctls behave identically and are
implemented identically. The goal is to allow a possible merge of the
existing /dev/random implementation with this implementation which
implies that this patch tries have a very close similarity. Yet, all
sysctls are documented at [1].

In addition, it provides the file lrng_type which provides details about
the LRNG:

- the name of the DRNG that produces the random numbers for /dev/random,
/dev/urandom, getrandom(2)

- the hash used to produce random numbers from the entropy pool

- the number of secondary DRNG instances

- indicator whether the LRNG operates SP800-90B compliant

- indicator whether a high-resolution timer is identified - only with a
high-resolution timer the interrupt noise source will deliver sufficient
entropy

- indicator whether the LRNG has been minimally seeded (i.e. is the
secondary DRNG seeded with at least 128 bits of of entropy)

- indicator whether the LRNG has been fully seeded (i.e. is the
secondary DRNG seeded with at least 256 bits of entropy)

[1] https://www.chronox.de/lrng.html

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Makefile  |   1 +
 drivers/char/lrng/lrng_interfaces.c |   1 -
 drivers/char/lrng/lrng_internal.h   |   4 +
 drivers/char/lrng/lrng_proc.c   | 163 
 4 files changed, 168 insertions(+), 1 deletion(-)
 create mode 100644 drivers/char/lrng/lrng_proc.c

diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 0a32f22c2c1a..e69c176f0161 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -9,3 +9,4 @@ obj-y   += lrng_pool.o lrng_aux.o \
   lrng_interfaces.o \
 
 obj-$(CONFIG_NUMA) += lrng_numa.o
+obj-$(CONFIG_SYSCTL)   += lrng_proc.o
diff --git a/drivers/char/lrng/lrng_interfaces.c 
b/drivers/char/lrng/lrng_interfaces.c
index ff8b73e4c936..78ebbfd20f0c 100644
--- a/drivers/char/lrng/lrng_interfaces.c
+++ b/drivers/char/lrng/lrng_interfaces.c
@@ -38,7 +38,6 @@ static DECLARE_WAIT_QUEUE_HEAD(lrng_write_wait);
 static DECLARE_WAIT_QUEUE_HEAD(lrng_init_wait);
 static struct fasync_struct *fasync;
 
-struct ctl_table random_table[];
 /** Helper ***/
 
 /* Is the DRNG seed level too low? */
diff --git a/drivers/char/lrng/lrng_internal.h 
b/drivers/char/lrng/lrng_internal.h
index de034260c323..4ccfe53e6ce9 100644
--- a/drivers/char/lrng/lrng_internal.h
+++ b/drivers/char/lrng/lrng_internal.h
@@ -117,7 +117,11 @@ void lrng_cc20_init_state_boot(struct chacha20_state 
*state);
 
 /** /proc 
*/
 
+#ifdef CONFIG_SYSCTL
+void lrng_pool_inc_numa_node(void);
+#else
 static inline void lrng_pool_inc_numa_node(void) { }
+#endif
 
 /** LRNG interfaces 
***/
 
diff --git a/drivers/char/lrng/lrng_proc.c b/drivers/char/lrng/lrng_proc.c
new file mode 100644
index ..e5aba75968c1
--- /dev/null
+++ b/drivers/char/lrng/lrng_proc.c
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG proc and sysctl interfaces
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "lrng_internal.h"
+
+/*
+ * This function is used to return both the bootid UUID, and random
+ * UUID.  The difference is in whether table->data is NULL; if it is,
+ * then a new UUID is generated and returned to the user.
+ *
+ * If the user accesses this via the proc interface, the UUID will be
+ * returned as an ASCII string in the standard UUID format; if via the
+ * sysctl system call, as 16 bytes of binary data.
+ */
+static int lrng_proc_do_uuid(struct ctl_table *table, int write,
+void *buffer, size_t *lenp, loff_t *ppos)
+{
+   struct ctl_table fake_table;
+   unsigned char buf[64], tmp_uuid[16], *uuid;
+
+   uuid = table->data;
+   if (!uuid) {
+   uuid = tmp_uuid;
+   generate_random_uuid(uuid);
+   } else {
+   static DEFINE_SPINLOCK(bootid_spinlock);
+
+   spin_lock(_spinlock);
+   if (!uuid[8])
+   generate_random_uuid(uuid);
+   spin_unlock(_spinlock);
+   }
+
+   sprintf(buf, "%pU", 

[PATCH v34 11/12] LRNG - add interface for gathering of raw entropy

2020-08-25 Thread Stephan Müller
The test interface allows a privileged process to capture the raw
unconditioned noise that is collected by the LRNG for statistical
analysis. Such testing allows the analysis how much entropy
the interrupt noise source provides on a given platform.
Extracted noise data is not used to seed the LRNG. This
is a test interface and not appropriate for production systems.
Yet, the interface is considered to be sufficiently secured for
production systems.

Access to the data is given through the lrng_raw debugfs file. The
data buffer should be multiples of sizeof(u32) to fill the entire
buffer. Using the option lrng_testing.boot_test=1 the raw noise of
the first 1000 entropy events since boot can be sampled.

This test interface allows generating the data required for
analysis whether the LRNG is in compliance with SP800-90B
sections 3.1.3 and 3.1.4.

In addition, the test interface allows gathering of the conatenated raw
entropy data to verify that the concatenation works appropriately.
This includes sampling of the following raw data:

* high-resolution time stamp

* Jiffies

* IRQ number

* IRQ flags

* return instruction pointer

* array logic batching the high-resolution time stamp

Finally, the execution duration for processing a time stamp can be
obtained with the LRNG raw entropy interface.

If a test interface is not compiled, its code is a noop which has no
impact on the performance.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig| 124 +++
 drivers/char/lrng/Makefile   |   1 +
 drivers/char/lrng/lrng_testing.c | 575 +++
 3 files changed, 700 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_testing.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index 452ee4adb577..de20f189e297 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -164,4 +164,128 @@ config LRNG_APT_CUTOFF
default 325 if !LRNG_APT_BROKEN
default 32 if LRNG_APT_BROKEN
 
+menuconfig LRNG_TESTING_MENU
+   bool "LRNG testing interfaces"
+   depends on DEBUG_FS
+   help
+ Enable one or more of the following test interfaces.
+
+ If unsure, say N.
+
+if LRNG_TESTING_MENU
+
+config LRNG_RAW_HIRES_ENTROPY
+   bool "Enable entropy test interface to hires timer noise source"
+   default y
+   help
+ The test interface allows a privileged process to capture
+ the raw unconditioned high resolution time stamp noise that
+ is collected by the LRNG for statistical analysis. Extracted
+ noise data is not used to seed the LRNG.
+
+ The raw noise data can be obtained using the lrng_raw_hires
+ debugfs file. Using the option lrng_testing.boot_raw_hires_test=1
+ the raw noise of the first 1000 entropy events since boot
+ can be sampled.
+
+config LRNG_RAW_JIFFIES_ENTROPY
+   bool "Enable entropy test interface to Jiffies noise source"
+   help
+ The test interface allows a privileged process to capture
+ the raw unconditioned Jiffies that is collected by
+ the LRNG for statistical analysis. This data is used for
+ seeding the LRNG if a high-resolution time stamp is not
+ available. If a high-resolution time stamp is detected,
+ the Jiffies value is not collected by the LRNG and no
+ data is provided via the test interface. Extracted noise
+ data is not used to seed the random number generator.
+
+ The raw noise data can be obtained using the lrng_raw_jiffies
+ debugfs file. Using the option lrng_testing.boot_raw_jiffies_test=1
+ the raw noise of the first 1000 entropy events since boot
+ can be sampled.
+
+config LRNG_RAW_IRQ_ENTROPY
+   bool "Enable entropy test interface to IRQ number noise source"
+   help
+ The test interface allows a privileged process to capture
+ the raw unconditioned interrupt number that is collected by
+ the LRNG for statistical analysis. This data is used for
+ seeding the random32 PRNG external to the LRNG if a
+ high-resolution time stamp is available or it will be used to
+ seed the LRNG otherwise. Extracted noise data is not used to
+ seed the random number generator.
+
+ The raw noise data can be obtained using the lrng_raw_irq
+ debugfs file. Using the option lrng_testing.boot_raw_irq_test=1
+ the raw noise of the first 1000 entropy events since boot
+ can be 

[PATCH v34 04/12] LRNG - add switchable DRNG support

2020-08-25 Thread Stephan Müller
The DRNG switch support allows replacing the DRNG mechanism of the
LRNG. The switching support rests on the interface definition of
include/linux/lrng.h. A new DRNG is implemented by filling in the
interface defined in this header file.

In addition to the DRNG, the extension also has to provide a hash
implementation that is used to hash the entropy pool for random number
extraction.

Note: It is permissible to implement a DRNG whose operations may sleep.
However, the hash function must not sleep.

The switchable DRNG support allows replacing the DRNG at runtime.
However, only one DRNG extension is allowed to be loaded at any given
time. Before replacing it with another DRNG implementation, the possibly
existing DRNG extension must be unloaded.

The switchable DRNG extension activates the new DRNG during load time.
It is expected, however, that such a DRNG switch would be done only once
by an administrator to load the intended DRNG implementation.

It is permissible to compile DRNG extensions either as kernel modules or
statically. The initialization of the DRNG extension should be performed
with a late_initcall to ensure the extension is available when user
space starts but after all other initialization completed.
The initialization is performed by registering the function call data
structure with the lrng_set_drng_cb function. In order to unload the
DRNG extension, lrng_set_drng_cb must be invoked with the NULL
parameter.

The DRNG extension should always provide a security strength that is at
least as strong as LRNG_DRNG_SECURITY_STRENGTH_BITS.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig   |   7 ++
 drivers/char/lrng/Makefile  |   1 +
 drivers/char/lrng/lrng_switch.c | 193 
 3 files changed, 201 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_switch.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index 059b21d9728c..d3138458fd8b 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -65,4 +65,11 @@ config LRNG_POOL_SIZE
default 7 if LRNG_POOL_SIZE_65536
default 8 if LRNG_POOL_SIZE_131072
 
+menuconfig LRNG_DRNG_SWITCH
+   bool "Support DRNG runtime switching"
+   help
+ The Linux RNG per default uses a ChaCha20 DRNG that is
+ accessible via the external interfaces. With this configuration
+ option other DRNGs can be selected and loaded at runtime.
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index e69c176f0161..31cfe87c999e 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -10,3 +10,4 @@ obj-y += lrng_pool.o lrng_aux.o \
 
 obj-$(CONFIG_NUMA) += lrng_numa.o
 obj-$(CONFIG_SYSCTL)   += lrng_proc.o
+obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
diff --git a/drivers/char/lrng/lrng_switch.c b/drivers/char/lrng/lrng_switch.c
new file mode 100644
index ..9b40671c6375
--- /dev/null
+++ b/drivers/char/lrng/lrng_switch.c
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG DRNG switching support
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+
+#include "lrng_internal.h"
+
+static int lrng_drng_switch(struct lrng_drng *drng_store,
+   const struct lrng_crypto_cb *cb, int node)
+{
+   const struct lrng_crypto_cb *old_cb;
+   unsigned long flags = 0;
+   int ret;
+   u8 seed[LRNG_DRNG_SECURITY_STRENGTH_BYTES] __latent_entropy;
+   void *new_drng = cb->lrng_drng_alloc(LRNG_DRNG_SECURITY_STRENGTH_BYTES);
+   void *old_drng, *new_hash, *old_hash;
+   bool sl = false, reset_drng = !lrng_get_available();
+
+   if (IS_ERR(new_drng)) {
+   pr_warn("could not allocate new DRNG for NUMA node %d (%ld)\n",
+   node, PTR_ERR(new_drng));
+   return PTR_ERR(new_drng);
+   }
+
+   /*
+* The seed potentially used as MAC key is undefined to add some
+* variation. Yet, the security of the MAC does not rely on the key
+* being secret. The key is only there to turn a MAC into a hash.
+* The intention is to allow the specification of CMAC(AES) as "hash"
+* to limit the dependency to AES when using the CTR DRBG.
+*/
+   new_hash = cb->lrng_hash_alloc(seed, sizeof(seed));
+   if (IS_ERR(new_hash)) {
+   

[PATCH v34 10/12] LRNG - add SP800-90B compliant health tests

2020-08-25 Thread Stephan Müller
Implement health tests for LRNG's slow noise sources as mandated by
SP-800-90B The file contains the following health tests:

- stuck test: The stuck test calculates the first, second and third
  discrete derivative of the time stamp to be processed by the LFSR.
  Only if all three values are non-zero, the received time delta is
  considered to be non-stuck.

- SP800-90B Repetition Count Test (RCT): The LRNG uses an enhanced
  version of the RCT specified in SP800-90B section 4.4.1. Instead of
  counting identical back-to-back values, the input to the RCT is the
  counting of the stuck values during the processing of received
  interrupt events. The RCT is applied with alpha=2^-30 compliant to
  the recommendation of FIPS 140-2 IG 9.8. During the counting operation,
  the LRNG always calculates the RCT cut-off value of C. If that value
  exceeds the allowed cut-off value, the LRNG will trigger the health
  test failure discussed below. An error is logged to the kernel log
  that such RCT failure occurred. This test is only applied and
  enforced in FIPS mode, i.e. when the kernel compiled with
  CONFIG_CONFIG_FIPS is started with fips=1.

- SP800-90B Adaptive Proportion Test (APT): The LRNG implements the
  APT as defined in SP800-90B section 4.4.2. The applied significance
  level again is alpha=2^-30 compliant to the recommendation of FIPS
  140-2 IG 9.8.

The aforementioned health tests are applied to the first 1,024 time stamps
obtained from interrupt events. In case one error is identified for either
the RCT, or the APT, the collected entropy is invalidated and the
SP800-90B startup health test is restarted.

As long as the SP800-90B startup health test is not completed, all LRNG
random number output interfaces that may block will block and not generate
any data. This implies that only those potentially blocking interfaces are
defined to provide random numbers that are seeded with the interrupt noise
source being SP800-90B compliant. All other output interfaces will not be
affected by the SP800-90B startup test and thus are not considered
SP800-90B compliant.

At runtime, the SP800-90B APT and RCT are applied to each time stamp
generated for a received interrupt. When either the APT and RCT indicates
a noise source failure, the LRNG is reset to a state it has immediately
after boot:

- all entropy counters are set to zero

- the SP800-90B startup tests are re-performed which implies that
getrandom(2) would block again until new entropy was collected

To summarize, the following rules apply:

• SP800-90B compliant output interfaces

  - /dev/random

  - getrandom(2) system call

  -  get_random_bytes kernel-internal interface when being triggered by
 the callback registered with add_random_ready_callback

• SP800-90B non-compliant output interfaces

  - /dev/urandom

  - get_random_bytes kernel-internal interface called directly

  - randomize_page kernel-internal interface

  - get_random_u32 and get_random_u64 kernel-internal interfaces

  - get_random_u32_wait, get_random_u64_wait, get_random_int_wait, and
get_random_long_wait kernel-internal interfaces

If either the RCT, or the APT health test fails irrespective whether
during initialization or runtime, the following actions occur:

  1. The entropy of the entire entropy pool is invalidated.

  2. All DRNGs are reset which imply that they are treated as being
 not seeded and require a reseed during next invocation.

  3. The SP800-90B startup health test are initiated with all
 implications of the startup tests. That implies that from that point
 on, new events must be observed and its entropy must be inserted into
 the entropy pool before random numbers are calculated from the
 entropy pool.

Further details on the SP800-90B compliance and the availability of all
test tools required to perform all tests mandated by SP800-90B are
provided at [1].

The entire health testing code is compile-time configurable.

The patch provides a CONFIG_BROKEN configuration of the APT / RCT cutoff
values which have a high likelihood to trigger the health test failure.
The BROKEN APT cutoff is set to the exact mean of the expected value if
the time stamps are equally distributed (512 time stamps divided by 16
possible values due to using the 4 LSB of the time stamp). The BROKEN
RCT cutoff value is set to 1 which is likely to be triggered during
regular operation.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig   |  56 +
 drivers/char/lrng/Makefile  |   1 +
 

[PATCH v34 06/12] LRNG - add SP800-90A DRBG extension

2020-08-25 Thread Stephan Müller
Using the LRNG switchable DRNG support, the SP800-90A DRBG extension is
implemented.

The DRBG uses the kernel crypto API DRBG implementation. In addition, it
uses the kernel crypto API SHASH support to provide the hashing
operation.

The DRBG supports the choice of either a CTR DRBG using AES-256, HMAC
DRBG with SHA-512 core or Hash DRBG with SHA-512 core. The used core can
be selected with the module parameter lrng_drbg_type. The default is the
CTR DRBG.

When compiling the DRBG extension statically, the DRBG is loaded at
late_initcall stage which implies that with the start of user space, the
user space interfaces of getrandom(2), /dev/random and /dev/urandom
provide random data produced by an SP800-90A DRBG.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig |  12 ++
 drivers/char/lrng/Makefile|   1 +
 drivers/char/lrng/lrng_drbg.c | 259 ++
 3 files changed, 272 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_drbg.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index d3138458fd8b..4f2b757a8962 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -72,4 +72,16 @@ menuconfig LRNG_DRNG_SWITCH
  accessible via the external interfaces. With this configuration
  option other DRNGs can be selected and loaded at runtime.
 
+if LRNG_DRNG_SWITCH
+config LRNG_DRBG
+   tristate "SP800-90A support for the LRNG"
+   depends on CRYPTO
+   select CRYPTO_DRBG_MENU
+   select CRYPTO_SHA512
+   help
+ Enable the SP800-90A DRBG support for the LRNG. Once the
+ module is loaded, output from /dev/random, /dev/urandom,
+ getrandom(2), or get_random_bytes_full is provided by a DRBG.
+endif # LRNG_DRNG_SWITCH
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 31cfe87c999e..0d320fcb7b9e 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -11,3 +11,4 @@ obj-y += lrng_pool.o lrng_aux.o \
 obj-$(CONFIG_NUMA) += lrng_numa.o
 obj-$(CONFIG_SYSCTL)   += lrng_proc.o
 obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
+obj-$(CONFIG_LRNG_DRBG)+= lrng_drbg.o
diff --git a/drivers/char/lrng/lrng_drbg.c b/drivers/char/lrng/lrng_drbg.c
new file mode 100644
index ..e6fbb5a82ff0
--- /dev/null
+++ b/drivers/char/lrng/lrng_drbg.c
@@ -0,0 +1,259 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Backend for the LRNG providing the cryptographic primitives using the
+ * kernel crypto API and its DRBG.
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Define a DRBG plus a hash / MAC used to extract data from the entropy pool.
+ * For LRNG_HASH_NAME you can use a hash or a MAC (HMAC or CMAC) of your choice
+ * (Note, you should use the suggested selections below -- using SHA-1 or MD5
+ * is not wise). The idea is that the used cipher primitive can be selected to
+ * be the same as used for the DRBG. I.e. the LRNG only uses one cipher
+ * primitive using the same cipher implementation with the options offered in
+ * the following. This means, if the CTR DRBG is selected and AES-NI is 
present,
+ * both the CTR DRBG and the selected cmac(aes) use AES-NI.
+ *
+ * The security strengths of the DRBGs are all 256 bits according to
+ * SP800-57 section 5.6.1.
+ *
+ * This definition is allowed to be changed.
+ */
+#ifdef CONFIG_CRYPTO_DRBG_CTR
+static unsigned int lrng_drbg_type = 0;
+#elif defined CONFIG_CRYPTO_DRBG_HMAC
+static unsigned int lrng_drbg_type = 1;
+#elif defined CONFIG_CRYPTO_DRBG_HASH
+static unsigned int lrng_drbg_type = 2;
+#else
+#error "Unknown DRBG in use"
+#endif
+
+/* The parameter must be r/o in sysfs as otherwise races appear. */
+module_param(lrng_drbg_type, uint, 0444);
+MODULE_PARM_DESC(lrng_drbg_type, "DRBG type used for LRNG (0->CTR_DRBG, 
1->HMAC_DRBG, 2->Hash_DRBG)");
+
+struct lrng_drbg {
+   const char *hash_name;
+   const char *drbg_core;
+};
+
+static const struct lrng_drbg lrng_drbg_types[] = {
+   {   /* CTR_DRBG with AES-256 using derivation function */
+   .hash_name = "sha512",
+   .drbg_core = "drbg_nopr_ctr_aes256",
+   }, {/* HMAC_DRBG with SHA-512 */
+   .hash_name = "sha512",
+   .drbg_core = "drbg_nopr_hmac_sha512",
+   }, {/* Hash_DRBG with SHA-512 using derivation function 

[PATCH v34 07/12] LRNG - add kernel crypto API PRNG extension

2020-08-25 Thread Stephan Müller
Add runtime-pluggable support for all PRNGs that are accessible via
the kernel crypto API, including hardware PRNGs. The PRNG is selected
with the module parameter drng_name where the name must be one that the
kernel crypto API can resolve into an RNG.

This allows using of the kernel crypto API PRNG implementations that
provide an interface to hardware PRNGs. Using this extension,
the LRNG uses the hardware PRNGs to generate random numbers. An
example is the S390 CPACF support providing such a PRNG.

The hash is provided by a kernel crypto API SHASH whose digest size
complies with the seedsize of the PRNG.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig  |  12 ++
 drivers/char/lrng/Makefile |   1 +
 drivers/char/lrng/lrng_kcapi.c | 321 +
 3 files changed, 334 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_kcapi.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index 4f2b757a8962..c89de14d173a 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -82,6 +82,18 @@ config LRNG_DRBG
  Enable the SP800-90A DRBG support for the LRNG. Once the
  module is loaded, output from /dev/random, /dev/urandom,
  getrandom(2), or get_random_bytes_full is provided by a DRBG.
+
+config LRNG_KCAPI
+   tristate "Kernel Crypto API support for the LRNG"
+   depends on CRYPTO
+   depends on !LRNG_DRBG
+   select CRYPTO_RNG
+   help
+ Enable the support for generic pseudo-random number
+ generators offered by the kernel crypto API with the
+ LRNG. Once the module is loaded, output from /dev/random,
+ /dev/urandom, getrandom(2), or get_random_bytes is
+ provided by the selected kernel crypto API RNG.
 endif # LRNG_DRNG_SWITCH
 
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 0d320fcb7b9e..94b2dfb2dfdb 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_NUMA)+= lrng_numa.o
 obj-$(CONFIG_SYSCTL)   += lrng_proc.o
 obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
 obj-$(CONFIG_LRNG_DRBG)+= lrng_drbg.o
+obj-$(CONFIG_LRNG_KCAPI)   += lrng_kcapi.o
diff --git a/drivers/char/lrng/lrng_kcapi.c b/drivers/char/lrng/lrng_kcapi.c
new file mode 100644
index ..b71092605e6b
--- /dev/null
+++ b/drivers/char/lrng/lrng_kcapi.c
@@ -0,0 +1,321 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Backend for the LRNG providing the cryptographic primitives using the
+ * kernel crypto API.
+ *
+ * Copyright (C) 2018 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static char *drng_name = NULL;
+module_param(drng_name, charp, 0444);
+MODULE_PARM_DESC(drng_name, "Kernel crypto API name of DRNG");
+
+static char *pool_hash = "sha512";
+module_param(pool_hash, charp, 0444);
+MODULE_PARM_DESC(pool_hash,
+"Kernel crypto API name of hash or keyed message digest to 
read the entropy pool");
+
+static char *seed_hash = NULL;
+module_param(seed_hash, charp, 0444);
+MODULE_PARM_DESC(seed_hash,
+"Kernel crypto API name of hash with output size equal to 
seedsize of DRNG to bring seed string to the size required by the DRNG");
+
+struct lrng_hash_info {
+   struct shash_desc shash;
+   char ctx[];
+};
+
+struct lrng_drng_info {
+   struct crypto_rng *kcapi_rng;
+   struct lrng_hash_info *lrng_hash;
+};
+
+static struct lrng_hash_info *_lrng_kcapi_hash_alloc(const char *name)
+{
+   struct lrng_hash_info *lrng_hash;
+   struct crypto_shash *tfm;
+   int size;
+
+   if (!name) {
+   pr_err("Hash name missing\n");
+   return ERR_PTR(-EINVAL);
+   }
+
+   tfm = crypto_alloc_shash(name, 0, 0);
+   if (IS_ERR(tfm)) {
+   pr_err("could not allocate hash %s\n", name);
+   return ERR_CAST(tfm);
+   }
+
+   size = sizeof(struct lrng_hash_info) + crypto_shash_descsize(tfm);
+   lrng_hash = kmalloc(size, GFP_KERNEL);
+   if (!lrng_hash) {
+   crypto_free_shash(tfm);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   lrng_hash->shash.tfm = tfm;
+
+   return lrng_hash;
+}
+
+static inline u32 _lrng_kcapi_hash_digestsize(struct lrng_hash_info *lrng_hash)
+{
+   struct shash_desc *shash = _hash->shash;
+   

[PATCH v34 00/12] /dev/random - a new approach with full SP800-90B compliance

2020-08-25 Thread Stephan Müller
Hi,

The following patch set provides a different approach to /dev/random which is
called Linux Random Number Generator (LRNG) to collect entropy within the Linux
kernel. The main improvements compared to the existing /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.

The LRNG patch set allows a user to select use of the existing /dev/random or
the LRNG during compile time. As the LRNG provides API and ABI compatible
interfaces to the existing /dev/random implementation, the user can freely chose
the RNG implementation without affecting kernel or user space operations.

This patch set provides early boot-time entropy which implies that no
additional flags to the getrandom(2) system call discussed recently on
the LKML is considered to be necessary. Yet, if additional flags are
introduced to cover special hardware, the LRNG implementation will also
provide them to be fully ABI and API compliant as already discussed on
LKML.

The LRNG is fully compliant to SP800-90B requirements and is shipped with a
full SP800-90B assessment and all required test tools. The existing /dev/random
implementation on the other hand has architectural limitations which
does not easily allow to bring the implementation in compliance with
SP800-90B. The key statement that causes concern is SP800-90B section
3.1.6. This section denies crediting entropy to multiple similar noise
sources. This section explicitly references different noise sources resting
on the timing of events and their derivatives (i.e. it is a direct complaint
to the existing existing /dev/random implementation). Therefore, SP800-90B
now denies the very issue mentioned in [1] with the existing /dev/random
implementation for a long time: crediting entropy to interrupts as well as
crediting entropy to derivatives of interrupts (HID and disk events). This is
not permissible with SP800-90B.

SP800-90B specifies various requirements for the noise source(s) that seed any
DRNG including SP800-90A DRBGs. In about a year from now, SP800-90B will be
mandated for all noise sources that provide entropy to DRBGs as part of a FIPS
140-[2|3] validation or other evaluation types. That means, if we there are no
solutions to comply with the requirements of SP800-90B found till one year
from now, any random number generation and ciphers based on random numbers
on Linux will be considered and treated as not applicable and delivering
no entropy! As /dev/urandom, getrandom(2) and /dev/random are the most
common and prevalent noise sources for DRNGs, all these DRNGs are affected.
This applies across the board for all validations of cryptography executing on
Linux (kernel and user space modules).

For users that are not interested in SP800-90B, the entire code for the
compliance as well as test interfaces can be deselected at compile time.

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

The LRNG provides a complete separation of the noise source maintenance
and the collection of entropy into an entropy pool from the post-processing
using a pseudo-random number generator. Different DRNGs are supported,
including:

* The LRNG can be compile-time enabled to replace the existing /dev/random
  implementation. When not selecting the LRNG at compile time (default), the
  existing /dev/random implementation is built.

* Built-in ChaCha20 DRNG which has no dependency to other kernel
  frameworks.

* SP800-90A DRBG using the kernel crypto API including its accelerated
  raw cipher implementations. This implies that the output of /dev/random,
  getrandom(2), /dev/urandom or get_random_bytes is fully compliant to
  SP800-90A.

* Arbitrary DRNGs registered with the kernel crypto API

* Full compliance with SP800-90B which covers the startup and runtime health
  tests mandated by SP800-90B as well as providing the test tools and test
  interfaces to obtain raw noise data securely. The test tools are provided at
  [1].

Booting the patch with the kernel command line option
"dyndbg=file drivers/char/lrng/* +p" generates logs indicating the operation
of the LRNG. Each log is pre-pended with "lrng".

The LRNG has a flexible design by allowing an easy replacement of the
deterministic random number generator component.

Compared to the existing /dev/random implementation, the compiled binary
is smaller when the LRNG is compiled with all options equal to the
existing /dev/random (i.e. only CONFIG_LRNG is set): random.o is 52.5 kBytes
whereas all LRNG object files are in 49 kBytes in size. The fully

Re: [PATCH v33 01/12] Linux Random Number Generator

2020-08-21 Thread Stephan Müller
Am Freitag, 21. August 2020, 21:42:17 CEST schrieb kernel test robot:

Hi,
> 
>hppa-linux-ld: lib/random32.o: in function `prandom_u32':
> >> (.text+0x318): undefined reference to `__tracepoint_prandom_u32'
> >> hppa-linux-ld: (.text+0x31c): undefined reference to
> >> `__tracepoint_prandom_u32' hppa-linux-ld:
> >> lib/random32.o:(__jump_table+0x8): undefined reference to
> >> `__tracepoint_prandom_u32'

This is caused by the fact that the LRNG code does not include trace/events/
random.h. However, a patch to lib/random32.c now requires this file to be 
included and creating a tracepoint. I.e. lib/random32.c code now relies on 
some other code to create the necessary hook.

I have added the include and will provide it with the next release although I 
am not sure lib/random32.c should rely on some other code to create its 
dependencies.

Ciao
Stephan




[PATCH v33 00/12] /dev/random - a new approach with full SP800-90B compliance

2020-08-21 Thread Stephan Müller
Hi,

The following patch set provides a different approach to /dev/random which is
called Linux Random Number Generator (LRNG) to collect entropy within the Linux
kernel. The main improvements compared to the existing /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.

The LRNG patch set allows a user to select use of the existing /dev/random or
the LRNG during compile time. As the LRNG provides API and ABI compatible
interfaces to the existing /dev/random implementation, the user can freely chose
the RNG implementation without affecting kernel or user space operations.

This patch set provides early boot-time entropy which implies that no
additional flags to the getrandom(2) system call discussed recently on
the LKML is considered to be necessary. Yet, if additional flags are
introduced to cover special hardware, the LRNG implementation will also
provide them to be fully ABI and API compliant as already discussed on
LKML.

The LRNG is fully compliant to SP800-90B requirements and is shipped with a
full SP800-90B assessment and all required test tools. The existing /dev/random
implementation on the other hand has architectural limitations which
does not easily allow to bring the implementation in compliance with
SP800-90B. The key statement that causes concern is SP800-90B section
3.1.6. This section denies crediting entropy to multiple similar noise
sources. This section explicitly references different noise sources resting
on the timing of events and their derivatives (i.e. it is a direct complaint
to the existing existing /dev/random implementation). Therefore, SP800-90B
now denies the very issue mentioned in [1] with the existing /dev/random
implementation for a long time: crediting entropy to interrupts as well as
crediting entropy to derivatives of interrupts (HID and disk events). This is
not permissible with SP800-90B.

SP800-90B specifies various requirements for the noise source(s) that seed any
DRNG including SP800-90A DRBGs. In about a year from now, SP800-90B will be
mandated for all noise sources that provide entropy to DRBGs as part of a FIPS
140-[2|3] validation or other evaluation types. That means, if we there are no
solutions to comply with the requirements of SP800-90B found till one year
from now, any random number generation and ciphers based on random numbers
on Linux will be considered and treated as not applicable and delivering
no entropy! As /dev/urandom, getrandom(2) and /dev/random are the most
common and prevalent noise sources for DRNGs, all these DRNGs are affected.
This applies across the board for all validations of cryptography executing on
Linux (kernel and user space modules).

For users that are not interested in SP800-90B, the entire code for the
compliance as well as test interfaces can be deselected at compile time.

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

The LRNG provides a complete separation of the noise source maintenance
and the collection of entropy into an entropy pool from the post-processing
using a pseudo-random number generator. Different DRNGs are supported,
including:

* The LRNG can be compile-time enabled to replace the existing /dev/random
  implementation. When not selecting the LRNG at compile time (default), the
  existing /dev/random implementation is built.

* Built-in ChaCha20 DRNG which has no dependency to other kernel
  frameworks.

* SP800-90A DRBG using the kernel crypto API including its accelerated
  raw cipher implementations. This implies that the output of /dev/random,
  getrandom(2), /dev/urandom or get_random_bytes is fully compliant to
  SP800-90A.

* Arbitrary DRNGs registered with the kernel crypto API

* Full compliance with SP800-90B which covers the startup and runtime health
  tests mandated by SP800-90B as well as providing the test tools and test
  interfaces to obtain raw noise data securely. The test tools are provided at
  [1].

Booting the patch with the kernel command line option
"dyndbg=file drivers/char/lrng/* +p" generates logs indicating the operation
of the LRNG. Each log is pre-pended with "lrng".

The LRNG has a flexible design by allowing an easy replacement of the
deterministic random number generator component.

Compared to the existing /dev/random implementation, the compiled binary
is smaller when the LRNG is compiled with all options equal to the
existing /dev/random (i.e. only CONFIG_LRNG is set): random.o is 52.5 kBytes
whereas all LRNG object files are in 49 kBytes in size. The fully

[PATCH v33 02/12] LRNG - allocate one DRNG instance per NUMA node

2020-08-21 Thread Stephan Müller
In order to improve NUMA-locality when serving getrandom(2) requests,
allocate one DRNG instance per node.

The DRNG instance that is present right from the start of the kernel is
reused as the first per-NUMA-node DRNG. For all remaining online NUMA
nodes a new DRNG instance is allocated.

During boot time, the multiple DRNG instances are seeded sequentially.
With this, the first DRNG instance (referenced as the initial DRNG
in the code) is completely seeded with 256 bits of entropy before the
next DRNG instance is completely seeded.

When random numbers are requested, the NUMA-node-local DRNG is checked
whether it has been already fully seeded. If this is not the case, the
initial DRNG is used to serve the request.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Makefile|   2 +
 drivers/char/lrng/lrng_internal.h |   5 ++
 drivers/char/lrng/lrng_numa.c | 101 ++
 3 files changed, 108 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_numa.c

diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 1d2a0211973d..0a32f22c2c1a 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -7,3 +7,5 @@ obj-y   += lrng_pool.o lrng_aux.o \
   lrng_sw_noise.o lrng_archrandom.o \
   lrng_drng.o lrng_chacha20.o \
   lrng_interfaces.o \
+
+obj-$(CONFIG_NUMA) += lrng_numa.o
diff --git a/drivers/char/lrng/lrng_internal.h 
b/drivers/char/lrng/lrng_internal.h
index 53c267115721..5587be09f495 100644
--- a/drivers/char/lrng/lrng_internal.h
+++ b/drivers/char/lrng/lrng_internal.h
@@ -250,8 +250,13 @@ int lrng_drng_get_sleep(u8 *outbuf, u32 outbuflen);
 void lrng_drng_force_reseed(void);
 void lrng_drng_seed_work(struct work_struct *dummy);
 
+#ifdef CONFIG_NUMA
+struct lrng_drng **lrng_drng_instances(void);
+void lrng_drngs_numa_alloc(void);
+#else  /* CONFIG_NUMA */
 static inline struct lrng_drng **lrng_drng_instances(void) { return NULL; }
 static inline void lrng_drngs_numa_alloc(void) { return; }
+#endif /* CONFIG_NUMA */
 
 /** Health Test linking code 
**/
 
diff --git a/drivers/char/lrng/lrng_numa.c b/drivers/char/lrng/lrng_numa.c
new file mode 100644
index ..947c5b3ed517
--- /dev/null
+++ b/drivers/char/lrng/lrng_numa.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG NUMA support
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+
+#include "lrng_internal.h"
+
+static struct lrng_drng **lrng_drng __read_mostly = NULL;
+
+struct lrng_drng **lrng_drng_instances(void)
+{
+   return lrng_drng;
+}
+
+/* Allocate the data structures for the per-NUMA node DRNGs */
+static void _lrng_drngs_numa_alloc(struct work_struct *work)
+{
+   struct lrng_drng **drngs;
+   struct lrng_drng *lrng_drng_init = lrng_drng_init_instance();
+   u32 node;
+   bool init_drng_used = false;
+
+   mutex_lock(_crypto_cb_update);
+
+   /* per-NUMA-node DRNGs are already present */
+   if (lrng_drng)
+   goto unlock;
+
+   drngs = kcalloc(nr_node_ids, sizeof(void *), GFP_KERNEL|__GFP_NOFAIL);
+   for_each_online_node(node) {
+   struct lrng_drng *drng;
+
+   if (!init_drng_used) {
+   drngs[node] = lrng_drng_init;
+   init_drng_used = true;
+   continue;
+   }
+
+   drng = kmalloc_node(sizeof(struct lrng_drng),
+GFP_KERNEL|__GFP_NOFAIL, node);
+   memset(drng, 0, sizeof(lrng_drng));
+
+   drng->crypto_cb = lrng_drng_init->crypto_cb;
+   drng->drng = drng->crypto_cb->lrng_drng_alloc(
+   LRNG_DRNG_SECURITY_STRENGTH_BYTES);
+   if (IS_ERR(drng->drng)) {
+   kfree(drng);
+   goto err;
+   }
+
+   mutex_init(>lock);
+   spin_lock_init(>spin_lock);
+
+   /*
+* No reseeding of NUMA DRNGs from previous DRNGs as this
+* would complicate the code. Let it simply reseed.
+*/
+   lrng_drng_reset(drng);
+   drngs[node] = drng;
+
+   

[PATCH v33 03/12] LRNG - sysctls and /proc interface

2020-08-21 Thread Stephan Müller
The LRNG sysctl interface provides the same controls as the existing
/dev/random implementation. These sysctls behave identically and are
implemented identically. The goal is to allow a possible merge of the
existing /dev/random implementation with this implementation which
implies that this patch tries have a very close similarity. Yet, all
sysctls are documented at [1].

In addition, it provides the file lrng_type which provides details about
the LRNG:

- the name of the DRNG that produces the random numbers for /dev/random,
/dev/urandom, getrandom(2)

- the hash used to produce random numbers from the entropy pool

- the number of secondary DRNG instances

- indicator whether the LRNG operates SP800-90B compliant

- indicator whether a high-resolution timer is identified - only with a
high-resolution timer the interrupt noise source will deliver sufficient
entropy

- indicator whether the LRNG has been minimally seeded (i.e. is the
secondary DRNG seeded with at least 128 bits of of entropy)

- indicator whether the LRNG has been fully seeded (i.e. is the
secondary DRNG seeded with at least 256 bits of entropy)

[1] https://www.chronox.de/lrng.html

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Makefile  |   1 +
 drivers/char/lrng/lrng_interfaces.c |   1 -
 drivers/char/lrng/lrng_internal.h   |   4 +
 drivers/char/lrng/lrng_proc.c   | 163 
 4 files changed, 168 insertions(+), 1 deletion(-)
 create mode 100644 drivers/char/lrng/lrng_proc.c

diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 0a32f22c2c1a..e69c176f0161 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -9,3 +9,4 @@ obj-y   += lrng_pool.o lrng_aux.o \
   lrng_interfaces.o \
 
 obj-$(CONFIG_NUMA) += lrng_numa.o
+obj-$(CONFIG_SYSCTL)   += lrng_proc.o
diff --git a/drivers/char/lrng/lrng_interfaces.c 
b/drivers/char/lrng/lrng_interfaces.c
index d9c68679136d..95ee99c82592 100644
--- a/drivers/char/lrng/lrng_interfaces.c
+++ b/drivers/char/lrng/lrng_interfaces.c
@@ -35,7 +35,6 @@ static DECLARE_WAIT_QUEUE_HEAD(lrng_write_wait);
 static DECLARE_WAIT_QUEUE_HEAD(lrng_init_wait);
 static struct fasync_struct *fasync;
 
-struct ctl_table random_table[];
 /** Helper ***/
 
 /* Is the DRNG seed level too low? */
diff --git a/drivers/char/lrng/lrng_internal.h 
b/drivers/char/lrng/lrng_internal.h
index 5587be09f495..8aea41a2f43f 100644
--- a/drivers/char/lrng/lrng_internal.h
+++ b/drivers/char/lrng/lrng_internal.h
@@ -117,7 +117,11 @@ void lrng_cc20_init_state_boot(struct chacha20_state 
*state);
 
 /** /proc 
*/
 
+#ifdef CONFIG_SYSCTL
+void lrng_pool_inc_numa_node(void);
+#else
 static inline void lrng_pool_inc_numa_node(void) { }
+#endif
 
 /** LRNG interfaces 
***/
 
diff --git a/drivers/char/lrng/lrng_proc.c b/drivers/char/lrng/lrng_proc.c
new file mode 100644
index ..c569a269b07a
--- /dev/null
+++ b/drivers/char/lrng/lrng_proc.c
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG proc and sysctl interfaces
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "lrng_internal.h"
+
+/*
+ * This function is used to return both the bootid UUID, and random
+ * UUID.  The difference is in whether table->data is NULL; if it is,
+ * then a new UUID is generated and returned to the user.
+ *
+ * If the user accesses this via the proc interface, the UUID will be
+ * returned as an ASCII string in the standard UUID format; if via the
+ * sysctl system call, as 16 bytes of binary data.
+ */
+static int lrng_proc_do_uuid(struct ctl_table *table, int write,
+void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+   struct ctl_table fake_table;
+   unsigned char buf[64], tmp_uuid[16], *uuid;
+
+   uuid = table->data;
+   if (!uuid) {
+   uuid = tmp_uuid;
+   generate_random_uuid(uuid);
+   } else {
+   static DEFINE_SPINLOCK(bootid_spinlock);
+
+   spin_lock(_spinlock);
+   if (!uuid[8])
+   generate_random_uuid(uuid);
+   spin_unlock(_spinlock);
+   }
+
+   sprintf(buf, 

[PATCH v33 06/12] LRNG - add SP800-90A DRBG extension

2020-08-21 Thread Stephan Müller
Using the LRNG switchable DRNG support, the SP800-90A DRBG extension is
implemented.

The DRBG uses the kernel crypto API DRBG implementation. In addition, it
uses the kernel crypto API SHASH support to provide the hashing
operation.

The DRBG supports the choice of either a CTR DRBG using AES-256, HMAC
DRBG with SHA-512 core or Hash DRBG with SHA-512 core. The used core can
be selected with the module parameter lrng_drbg_type. The default is the
CTR DRBG.

When compiling the DRBG extension statically, the DRBG is loaded at
late_initcall stage which implies that with the start of user space, the
user space interfaces of getrandom(2), /dev/random and /dev/urandom
provide random data produced by an SP800-90A DRBG.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig |  12 ++
 drivers/char/lrng/Makefile|   1 +
 drivers/char/lrng/lrng_drbg.c | 259 ++
 3 files changed, 272 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_drbg.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index d3138458fd8b..4ad26fdfbe7e 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -72,4 +72,16 @@ menuconfig LRNG_DRNG_SWITCH
  accessible via the external interfaces. With this configuration
  option other DRNGs can be selected and loaded at runtime.
 
+if LRNG_DRNG_SWITCH
+config LRNG_DRBG
+   tristate "SP800-90A support for the LRNG"
+   depends on CRYPTO
+   select CRYPTO_DRBG_MENU
+   select CRYPTO_SHA512
+   help
+ Enable the SP800-90A DRBG support for the LRNG. Once the
+ module is loaded, output from /dev/random, /dev/urandom,
+ getrandom(2), or get_random_bytes is provided by a DRBG.
+endif # LRNG_DRNG_SWITCH
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 31cfe87c999e..0d320fcb7b9e 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -11,3 +11,4 @@ obj-y += lrng_pool.o lrng_aux.o \
 obj-$(CONFIG_NUMA) += lrng_numa.o
 obj-$(CONFIG_SYSCTL)   += lrng_proc.o
 obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
+obj-$(CONFIG_LRNG_DRBG)+= lrng_drbg.o
diff --git a/drivers/char/lrng/lrng_drbg.c b/drivers/char/lrng/lrng_drbg.c
new file mode 100644
index ..e6fbb5a82ff0
--- /dev/null
+++ b/drivers/char/lrng/lrng_drbg.c
@@ -0,0 +1,259 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Backend for the LRNG providing the cryptographic primitives using the
+ * kernel crypto API and its DRBG.
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Define a DRBG plus a hash / MAC used to extract data from the entropy pool.
+ * For LRNG_HASH_NAME you can use a hash or a MAC (HMAC or CMAC) of your choice
+ * (Note, you should use the suggested selections below -- using SHA-1 or MD5
+ * is not wise). The idea is that the used cipher primitive can be selected to
+ * be the same as used for the DRBG. I.e. the LRNG only uses one cipher
+ * primitive using the same cipher implementation with the options offered in
+ * the following. This means, if the CTR DRBG is selected and AES-NI is 
present,
+ * both the CTR DRBG and the selected cmac(aes) use AES-NI.
+ *
+ * The security strengths of the DRBGs are all 256 bits according to
+ * SP800-57 section 5.6.1.
+ *
+ * This definition is allowed to be changed.
+ */
+#ifdef CONFIG_CRYPTO_DRBG_CTR
+static unsigned int lrng_drbg_type = 0;
+#elif defined CONFIG_CRYPTO_DRBG_HMAC
+static unsigned int lrng_drbg_type = 1;
+#elif defined CONFIG_CRYPTO_DRBG_HASH
+static unsigned int lrng_drbg_type = 2;
+#else
+#error "Unknown DRBG in use"
+#endif
+
+/* The parameter must be r/o in sysfs as otherwise races appear. */
+module_param(lrng_drbg_type, uint, 0444);
+MODULE_PARM_DESC(lrng_drbg_type, "DRBG type used for LRNG (0->CTR_DRBG, 
1->HMAC_DRBG, 2->Hash_DRBG)");
+
+struct lrng_drbg {
+   const char *hash_name;
+   const char *drbg_core;
+};
+
+static const struct lrng_drbg lrng_drbg_types[] = {
+   {   /* CTR_DRBG with AES-256 using derivation function */
+   .hash_name = "sha512",
+   .drbg_core = "drbg_nopr_ctr_aes256",
+   }, {/* HMAC_DRBG with SHA-512 */
+   .hash_name = "sha512",
+   .drbg_core = "drbg_nopr_hmac_sha512",
+   }, {/* Hash_DRBG with SHA-512 using derivation function */
+  

[PATCH v33 04/12] LRNG - add switchable DRNG support

2020-08-21 Thread Stephan Müller
The DRNG switch support allows replacing the DRNG mechanism of the
LRNG. The switching support rests on the interface definition of
include/linux/lrng.h. A new DRNG is implemented by filling in the
interface defined in this header file.

In addition to the DRNG, the extension also has to provide a hash
implementation that is used to hash the entropy pool for random number
extraction.

Note: It is permissible to implement a DRNG whose operations may sleep.
However, the hash function must not sleep.

The switchable DRNG support allows replacing the DRNG at runtime.
However, only one DRNG extension is allowed to be loaded at any given
time. Before replacing it with another DRNG implementation, the possibly
existing DRNG extension must be unloaded.

The switchable DRNG extension activates the new DRNG during load time.
It is expected, however, that such a DRNG switch would be done only once
by an administrator to load the intended DRNG implementation.

It is permissible to compile DRNG extensions either as kernel modules or
statically. The initialization of the DRNG extension should be performed
with a late_initcall to ensure the extension is available when user
space starts but after all other initialization completed.
The initialization is performed by registering the function call data
structure with the lrng_set_drng_cb function. In order to unload the
DRNG extension, lrng_set_drng_cb must be invoked with the NULL
parameter.

The DRNG extension should always provide a security strength that is at
least as strong as LRNG_DRNG_SECURITY_STRENGTH_BITS.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig   |   7 ++
 drivers/char/lrng/Makefile  |   1 +
 drivers/char/lrng/lrng_switch.c | 189 
 3 files changed, 197 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_switch.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index 059b21d9728c..d3138458fd8b 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -65,4 +65,11 @@ config LRNG_POOL_SIZE
default 7 if LRNG_POOL_SIZE_65536
default 8 if LRNG_POOL_SIZE_131072
 
+menuconfig LRNG_DRNG_SWITCH
+   bool "Support DRNG runtime switching"
+   help
+ The Linux RNG per default uses a ChaCha20 DRNG that is
+ accessible via the external interfaces. With this configuration
+ option other DRNGs can be selected and loaded at runtime.
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index e69c176f0161..31cfe87c999e 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -10,3 +10,4 @@ obj-y += lrng_pool.o lrng_aux.o \
 
 obj-$(CONFIG_NUMA) += lrng_numa.o
 obj-$(CONFIG_SYSCTL)   += lrng_proc.o
+obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
diff --git a/drivers/char/lrng/lrng_switch.c b/drivers/char/lrng/lrng_switch.c
new file mode 100644
index ..67eebb3c119f
--- /dev/null
+++ b/drivers/char/lrng/lrng_switch.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG DRNG switching support
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+
+#include "lrng_internal.h"
+
+static int lrng_drng_switch(struct lrng_drng *drng_store,
+   const struct lrng_crypto_cb *cb, int node)
+{
+   const struct lrng_crypto_cb *old_cb;
+   unsigned long flags = 0;
+   int ret;
+   u8 seed[LRNG_DRNG_SECURITY_STRENGTH_BYTES] __latent_entropy;
+   void *new_drng = cb->lrng_drng_alloc(LRNG_DRNG_SECURITY_STRENGTH_BYTES);
+   void *old_drng, *new_hash, *old_hash;
+   bool sl = false, reset_drng = !lrng_get_available();
+
+   if (IS_ERR(new_drng)) {
+   pr_warn("could not allocate new DRNG for NUMA node %d (%ld)\n",
+   node, PTR_ERR(new_drng));
+   return PTR_ERR(new_drng);
+   }
+
+   /*
+* The seed potentially used as MAC key is undefined to add some
+* variation. Yet, the security of the MAC does not rely on the key
+* being secret. The key is only there to turn a MAC into a hash.
+* The intention is to allow the specification of CMAC(AES) as "hash"
+* to limit the dependency to AES when using the CTR DRBG.
+*/
+   new_hash = cb->lrng_hash_alloc(seed, sizeof(seed));
+   if (IS_ERR(new_hash)) {
+   

[PATCH v33 05/12] crypto: DRBG - externalize DRBG functions for LRNG

2020-08-21 Thread Stephan Müller
This patch allows several DRBG functions to be called by the LRNG kernel
code paths outside the drbg.c file.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 crypto/drbg.c | 16 ++--
 include/crypto/drbg.h |  7 +++
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index e99fe34cfa00..3644e954785a 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[] = {
+const struct drbg_core drbg_cores[] = {
 #ifdef CONFIG_CRYPTO_DRBG_CTR
{
.flags = DRBG_CTR | DRBG_STRENGTH128,
@@ -190,6 +190,7 @@ static const struct drbg_core drbg_cores[] = {
},
 #endif /* CONFIG_CRYPTO_DRBG_HMAC */
 };
+EXPORT_SYMBOL(drbg_cores);
 
 static int drbg_uninstantiate(struct drbg_state *drbg);
 
@@ -205,7 +206,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:
@@ -218,6 +219,7 @@ static inline unsigned short drbg_sec_strength(drbg_flag_t 
flags)
return 32;
}
 }
+EXPORT_SYMBOL(drbg_sec_strength);
 
 /*
  * FIPS 140-2 continuous self test for the noise source
@@ -1214,7 +1216,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;
@@ -1235,12 +1237,13 @@ static inline void drbg_dealloc_state(struct drbg_state 
*drbg)
drbg->fips_primed = false;
}
 }
+EXPORT_SYMBOL(drbg_dealloc_state);
 
 /*
  * 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;
@@ -1321,6 +1324,7 @@ static inline int drbg_alloc_state(struct drbg_state 
*drbg)
drbg_dealloc_state(drbg);
return ret;
 }
+EXPORT_SYMBOL(drbg_alloc_state);
 
 /*
  * DRBG interface functions
@@ -1890,8 +1894,7 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
  *
  * 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;
@@ -1918,6 +1921,7 @@ static inline void drbg_convert_tfm_core(const char 
*cra_driver_name,
}
}
 }
+EXPORT_SYMBOL(drbg_convert_tfm_core);
 
 static int drbg_kcapi_init(struct crypto_tfm *tfm)
 {
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index c4165126937e..71d53e028e6d 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -278,4 +278,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 const struct drbg_core drbg_cores[];
+extern unsigned short drbg_sec_strength(drbg_flag_t flags);
+
 #endif /* _DRBG_H */
-- 
2.26.2






[PATCH v33 09/12] LRNG - add Jitter RNG fast noise source

2020-08-21 Thread Stephan Müller
From 4a94cf2db12d5d1f8fd3354ea0da2c5726f96ac7 Mon Sep 17 00:00:00 2001
From: Stephan Mueller 
Date: Sun, 19 Jan 2020 21:23:17 +0100
Subject: 
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The Jitter RNG fast noise source implemented as part of the kernel
crypto API is queried for 256 bits of entropy at the time the seed
buffer managed by the LRNG is about to be filled.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig | 12 +
 drivers/char/lrng/Makefile|  1 +
 drivers/char/lrng/lrng_jent.c | 88 +++
 3 files changed, 101 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_jent.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index ba3d84cd0676..66a775a8f912 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -95,4 +95,16 @@ config LRNG_KCAPI
  provided by the selected kernel crypto API RNG.
 endif # LRNG_DRNG_SWITCH
 
+config LRNG_JENT
+   bool "Enable Jitter RNG as LRNG Seed Source"
+   depends on CRYPTO
+   select CRYPTO_JITTERENTROPY
+   help
+ The Linux RNG may use the Jitter RNG as noise source. Enabling
+ this option enables the use of the Jitter RNG. Its default
+ entropy level is 16 bits of entropy per 256 data bits delivered
+ by the Jitter RNG. This entropy level can be changed at boot
+ time or at runtime with the lrng_base.jitterrng configuration
+ variable.
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 94b2dfb2dfdb..4f5b6f38f0c4 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_SYSCTL)  += lrng_proc.o
 obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
 obj-$(CONFIG_LRNG_DRBG)+= lrng_drbg.o
 obj-$(CONFIG_LRNG_KCAPI)   += lrng_kcapi.o
+obj-$(CONFIG_LRNG_JENT)+= lrng_jent.o
diff --git a/drivers/char/lrng/lrng_jent.c b/drivers/char/lrng/lrng_jent.c
new file mode 100644
index ..225505271fcb
--- /dev/null
+++ b/drivers/char/lrng/lrng_jent.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG Fast Noise Source: Jitter RNG
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+
+#include "lrng_internal.h"
+
+/*
+ * Estimated entropy of data is a 16th of LRNG_DRNG_SECURITY_STRENGTH_BITS.
+ * Albeit a full entropy assessment is provided for the noise source indicating
+ * that it provides high entropy rates and considering that it deactivates
+ * when it detects insufficient hardware, the chosen under estimation of
+ * entropy is considered to be acceptable to all reviewers.
+ */
+static u32 jitterrng = LRNG_DRNG_SECURITY_STRENGTH_BITS>>4;
+module_param(jitterrng, uint, 0644);
+MODULE_PARM_DESC(jitterrng, "Entropy in bits of 256 data bits from Jitter RNG 
noise source");
+
+/**
+ * lrng_get_jent() - Get Jitter RNG entropy
+ *
+ * @outbuf: buffer to store entropy
+ * @outbuflen: length of buffer
+ *
+ * Return:
+ * * > 0 on success where value provides the added entropy in bits
+ * * 0 if no fast source was available
+ */
+static struct rand_data *lrng_jent_state;
+
+u32 lrng_get_jent(u8 *outbuf, unsigned int outbuflen)
+{
+   int ret;
+   u32 ent_bits = jitterrng;
+   unsigned long flags;
+   static DEFINE_SPINLOCK(lrng_jent_lock);
+   static int lrng_jent_initialized = 0;
+
+   spin_lock_irqsave(_jent_lock, flags);
+
+   if (!ent_bits || (lrng_jent_initialized == -1)) {
+   spin_unlock_irqrestore(_jent_lock, flags);
+   return 0;
+   }
+
+   if (!lrng_jent_initialized) {
+   lrng_jent_state = jent_lrng_entropy_collector();
+   if (!lrng_jent_state) {
+   jitterrng = 0;
+   lrng_jent_initialized = -1;
+   spin_unlock_irqrestore(_jent_lock, flags);
+   pr_info("Jitter RNG unusable on current system\n");
+   return 0;
+   }
+   lrng_jent_initialized = 1;
+   pr_debug("Jitter RNG working on current system\n");
+   }
+   ret = jent_read_entropy(lrng_jent_state, outbuf, outbuflen);
+   spin_unlock_irqrestore(_jent_lock, flags);
+
+   if (ret) {
+   pr_debug("Jitter RNG failed with %d\n", ret);
+   

[PATCH v33 01/12] Linux Random Number Generator

2020-08-21 Thread Stephan Müller
In an effort to provide a flexible implementation for a random number
generator that also delivers entropy during early boot time, allows
replacement of the deterministic random number generation mechanism,
implement the various components in separate code for easier
maintenance, and provide compliance to SP800-90[A|B|C], introduce
the Linux Random Number Generator (LRNG) framework.

The general design is as follows. Additional implementation details
are given in [1]. The LRNG consists of the following components:

1. The LRNG implements a DRNG. The DRNG always generates the
requested amount of output. When using the SP800-90A terminology
it operates without prediction resistance. The secondary DRNG
maintains a counter of how many bytes were generated since last
re-seed and a timer of the elapsed time since last re-seed. If either
the counter or the timer reaches a threshold, the secondary DRNG is
seeded from the entropy pool.

In case the Linux kernel detects a NUMA system, one secondary DRNG
instance per NUMA node is maintained.

2. The DRNG is seeded by concatenating the data from the
following sources:

(a) the output of the entropy pool,

(b) the Jitter RNG if available and enabled, and

(c) the CPU-based noise source such as Intel RDRAND if available and
enabled.

The entropy estimate of the data of all noise sources are added to
form the entropy estimate of the data used to seed the DRNG with.
The LRNG ensures, however, that the DRNG after seeding is at
maximum the security strength of the DRNG.

The LRNG is designed such that none of these noise sources can dominate
the other noise sources to provide seed data to the DRNG during due to
the following:

(a) During boot time, the amount of received interrupts are the trigger
points to (re)seed the DRNG.

(b) At runtime, the available entropy from the slow noise source is
concatenated with a pre-defined amount of data from the fast noise
sources. In addition, each DRNG reseed operation triggers external
noise source providers to deliver one block of data.

3. The entropy pool accumulates entropy obtained from certain events,
which will henceforth be collectively called "slow noise sources".
The entropy pool collects noise data from slow noise sources. Any data
received by the LRNG from the slow noise sources is inserted into the
entropy pool using an LFSR with a primitive and irreducible polynomial.
The following sources of entropy are used:

 (a) When an interrupt occurs, the high-resolution time stamp is mixed
into the LFSR. This time stamp is credited with heuristically implied
entropy.

 (b) HID event data like the key stroke or the mouse coordinates are
mixed into the LFSR. This data is not credited with entropy by the LRNG.

 (c) Device drivers may provide data that is mixed into the LFSR. This
data is not credited with entropy by the LRNG.

 (d) After the entropy pool is ``read'' by the DRNG, the data
used to seed the DRNG is mixed back into the entropy pool to
stir the pool. This data is not credited with entropy by the LRNG.

Any data provided from user space by either writing to /dev/random,
/dev/urandom or the IOCTL of RNDADDENTROPY on both device files
are always injected into the entropy pool.

In addition, when a hardware random number generator covered by the
Linux kernel HW generator framework wants to deliver random numbers,
it is injected into the entropy pool as well. HW generator noise source
is handled separately from the other noise source due to the fact that
the HW generator framework may decide by itself when to deliver data
whereas the other noise sources always requested for data driven by the
LRNG operation. Similarly any user space provided data is inserted into
the entropy pool.

When the DRNG requires data from the entropy pool, the entire
entropy pool is processed with an SP800-90A section 10.3.1 compliant
hash_df function to generate random numbers.

To speed up the interrupt handling code of the LRNG, the time stamp
collected for an interrupt event is truncated to the 8 least
significant bits. 64 truncated time stamps are concatenated and then
jointly inserted into the LFSR. During boot time, until the fully seeded
stage is reached, each time stamp with its 32 least significant bits is
inserted into the LFSR at the time of arrival.

The LRNG allows the DRNG mechanism to be changed at runtime. Per default,
a ChaCha20-based DRNG is used. The ChaCha20-DRNG implemented for the
LRNG is also provided as a stand-alone user space deterministic random
number generator. The LRNG also offers an SP800-90A DRBG based on the
Linux kernel crypto API DRBG implementation.

The processing of entropic data from the noise source before injecting
them into the DRNG is performed with the following mathematical
operations:

1. LFSR: The 8 least significant bits of the time stamp data received
from the interrupts are processed with an LFSR. That LFSR is implemented
identically to the LSFR used in the existing /dev/random implementation

[PATCH v33 10/12] LRNG - add SP800-90B compliant health tests

2020-08-21 Thread Stephan Müller
Implement health tests for LRNG's slow noise sources as mandated by
SP-800-90B The file contains the following health tests:

- stuck test: The stuck test calculates the first, second and third
  discrete derivative of the time stamp to be processed by the LFSR.
  Only if all three values are non-zero, the received time delta is
  considered to be non-stuck.

- SP800-90B Repetition Count Test (RCT): The LRNG uses an enhanced
  version of the RCT specified in SP800-90B section 4.4.1. Instead of
  counting identical back-to-back values, the input to the RCT is the
  counting of the stuck values during the processing of received
  interrupt events. The RCT is applied with alpha=2^-30 compliant to
  the recommendation of FIPS 140-2 IG 9.8. During the counting operation,
  the LRNG always calculates the RCT cut-off value of C. If that value
  exceeds the allowed cut-off value, the LRNG will trigger the health
  test failure discussed below. An error is logged to the kernel log
  that such RCT failure occurred. This test is only applied and
  enforced in FIPS mode, i.e. when the kernel compiled with
  CONFIG_CONFIG_FIPS is started with fips=1.

- SP800-90B Adaptive Proportion Test (APT): The LRNG implements the
  APT as defined in SP800-90B section 4.4.2. The applied significance
  level again is alpha=2^-30 compliant to the recommendation of FIPS
  140-2 IG 9.8.

The aforementioned health tests are applied to the first 1,024 time stamps
obtained from interrupt events. In case one error is identified for either
the RCT, or the APT, the collected entropy is invalidated and the
SP800-90B startup health test is restarted.

As long as the SP800-90B startup health test is not completed, all LRNG
random number output interfaces that may block will block and not generate
any data. This implies that only those potentially blocking interfaces are
defined to provide random numbers that are seeded with the interrupt noise
source being SP800-90B compliant. All other output interfaces will not be
affected by the SP800-90B startup test and thus are not considered
SP800-90B compliant.

At runtime, the SP800-90B APT and RCT are applied to each time stamp
generated for a received interrupt. When either the APT and RCT indicates
a noise source failure, the LRNG is reset to a state it has immediately
after boot:

- all entropy counters are set to zero

- the SP800-90B startup tests are re-performed which implies that
getrandom(2) would block again until new entropy was collected

To summarize, the following rules apply:

• SP800-90B compliant output interfaces

  - /dev/random

  - getrandom(2) system call

  -  get_random_bytes kernel-internal interface when being triggered by
 the callback registered with add_random_ready_callback

• SP800-90B non-compliant output interfaces

  - /dev/urandom

  - get_random_bytes kernel-internal interface called directly

  - randomize_page kernel-internal interface

  - get_random_u32 and get_random_u64 kernel-internal interfaces

  - get_random_u32_wait, get_random_u64_wait, get_random_int_wait, and
get_random_long_wait kernel-internal interfaces

If either the RCT, or the APT health test fails irrespective whether
during initialization or runtime, the following actions occur:

  1. The entropy of the entire entropy pool is invalidated.

  2. All DRNGs are reset which imply that they are treated as being
 not seeded and require a reseed during next invocation.

  3. The SP800-90B startup health test are initiated with all
 implications of the startup tests. That implies that from that point
 on, new events must be observed and its entropy must be inserted into
 the entropy pool before random numbers are calculated from the
 entropy pool.

Further details on the SP800-90B compliance and the availability of all
test tools required to perform all tests mandated by SP800-90B are
provided at [1].

The entire health testing code is compile-time configurable.

The patch provides a CONFIG_BROKEN configuration of the APT / RCT cutoff
values which have a high likelihood to trigger the health test failure.
The BROKEN APT cutoff is set to the exact mean of the expected value if
the time stamps are equally distributed (512 time stamps divided by 16
possible values due to using the 4 LSB of the time stamp). The BROKEN
RCT cutoff value is set to 1 which is likely to be triggered during
regular operation.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig   |  56 +
 drivers/char/lrng/Makefile  |   1 +
 

[PATCH v33 12/12] LRNG - add power-on and runtime self-tests

2020-08-21 Thread Stephan Müller
Parts of the LRNG are already covered by self-tests, including:

* Self-test of SP800-90A DRBG provided by the Linux kernel crypto API.

* Self-test of the PRNG provided by the Linux kernel crypto API.

* Raw noise source data testing including SP800-90B compliant
  tests when enabling CONFIG_LRNG_HEALTH_TESTS

This patch adds the self-tests for the remaining critical functions of
the LRNG that are essential to maintain entropy and provide
cryptographic strong random numbers. The following self-tests are
implemented:

* Self-test of the time array maintenance. This test verifies whether
the time stamp array management to store multiple values in one integer
implements a concatenation of the data.

* Self-test of the LFSR operation. This test injects a monotonic
increasing counter into the LFSR. After completion of the injection of
the counter, 3 pool words are compared with known good values. The known
good values are calculated with the newly-developed tool
lfsr_testvector_generation provided as part of the LRNG test tool set at
[1].

* Self-test of the Hash_DF operation ensures that this function operates
compliant to the specification. The self-test performs a Hash_DF
operation of a zeroized entropy pool state. The test vectors are
generated using the newly-developed tool hash_df_testvector_generation
provided as part of the LRNG test tool set at [1].

* Self-test of the ChaCha20 DRNG is based on the self-tests that are
already present and implemented with the stand-alone user space
ChaCha20 DRNG implementation available at [2]. The self-tests cover
different use cases of the DRNG seeded with known seed data.

The status of the LRNG self-tests is provided with the selftest_status
SysFS file. If the file contains a zero, the self-tests passed. The
value 0x means that the self-tests were not executed. Any other
value indicates a self-test failure.

The self-test may be compiled to panic the system if the self-test
fails.

All self-tests operate on private state data structures. This implies
that none of the self-tests have any impact on the regular LRNG
operations. This allows the self-tests to be repeated at runtime by
writing anything into the selftest_status SysFS file.

[1] https://www.chronox.de/lrng.html
[2] https://www.chronox.de/chacha20.html

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
CC: Marcelo Henrique Cerri 
CC: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig |  25 ++
 drivers/char/lrng/Makefile|   1 +
 drivers/char/lrng/lrng_selftest.c | 504 ++
 3 files changed, 530 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_selftest.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index 4feabb0a20c2..e8b7e9620123 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -287,4 +287,29 @@ config LRNG_TESTING
 
 endif #LRNG_TESTING_MENU
 
+config LRNG_SELFTEST
+   bool "Enable power-on and on-demand self-tests"
+   help
+ The power-on self-tests are executed during boot time
+ covering the ChaCha20 DRNG, the LFSR processing and the
+ time stamp management of the LRNG.
+
+ The on-demand self-tests are triggered by writing any
+ value into the SysFS file selftest_status. At the same
+ time, when reading this file, the test status is
+ returned. A zero indicates that all tests were executed
+ successfully.
+
+ If unsure, say Y.
+
+if LRNG_SELFTEST
+
+config LRNG_SELFTEST_PANIC
+   bool "Panic the kernel upon self-test failure"
+   help
+ If the option is enabled, the kernel is terminated if an
+ LRNG power-on self-test failure is detected.
+
+endif # LRNG_SELFTEST
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index b2ce1979dc4b..92219c565f66 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_LRNG_KCAPI)  += lrng_kcapi.o
 obj-$(CONFIG_LRNG_JENT)+= lrng_jent.o
 obj-$(CONFIG_LRNG_HEALTH_TESTS)+= lrng_health.o
 obj-$(CONFIG_LRNG_TESTING) += lrng_testing.o
+obj-$(CONFIG_LRNG_SELFTEST)+= lrng_selftest.o
diff --git a/drivers/char/lrng/lrng_selftest.c 
b/drivers/char/lrng/lrng_selftest.c
new file mode 100644
index ..fc4871148f95
--- /dev/null
+++ b/drivers/char/lrng/lrng_selftest.c
@@ -0,0 +1,504 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG power-on and on-demand self-test
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+/*
+ * In addition to the self-tests below, the following LRNG components
+ * are covered with self-tests during 

[PATCH v33 07/12] LRNG - add kernel crypto API PRNG extension

2020-08-21 Thread Stephan Müller
Add runtime-pluggable support for all PRNGs that are accessible via
the kernel crypto API, including hardware PRNGs. The PRNG is selected
with the module parameter drng_name where the name must be one that the
kernel crypto API can resolve into an RNG.

This allows using of the kernel crypto API PRNG implementations that
provide an interface to hardware PRNGs. Using this extension,
the LRNG uses the hardware PRNGs to generate random numbers. An
example is the S390 CPACF support providing such a PRNG.

The hash is provided by a kernel crypto API SHASH whose digest size
complies with the seedsize of the PRNG.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig  |  11 ++
 drivers/char/lrng/Makefile |   1 +
 drivers/char/lrng/lrng_kcapi.c | 321 +
 3 files changed, 333 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_kcapi.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index 4ad26fdfbe7e..ba3d84cd0676 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -82,6 +82,17 @@ config LRNG_DRBG
  Enable the SP800-90A DRBG support for the LRNG. Once the
  module is loaded, output from /dev/random, /dev/urandom,
  getrandom(2), or get_random_bytes is provided by a DRBG.
+
+config LRNG_KCAPI
+   tristate "Kernel Crypto API support for the LRNG"
+   depends on CRYPTO
+   select CRYPTO_RNG
+   help
+ Enable the support for generic pseudo-random number
+ generators offered by the kernel crypto API with the
+ LRNG. Once the module is loaded, output from /dev/random,
+ /dev/urandom, getrandom(2), or get_random_bytes is
+ provided by the selected kernel crypto API RNG.
 endif # LRNG_DRNG_SWITCH
 
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 0d320fcb7b9e..94b2dfb2dfdb 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_NUMA)+= lrng_numa.o
 obj-$(CONFIG_SYSCTL)   += lrng_proc.o
 obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
 obj-$(CONFIG_LRNG_DRBG)+= lrng_drbg.o
+obj-$(CONFIG_LRNG_KCAPI)   += lrng_kcapi.o
diff --git a/drivers/char/lrng/lrng_kcapi.c b/drivers/char/lrng/lrng_kcapi.c
new file mode 100644
index ..b71092605e6b
--- /dev/null
+++ b/drivers/char/lrng/lrng_kcapi.c
@@ -0,0 +1,321 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Backend for the LRNG providing the cryptographic primitives using the
+ * kernel crypto API.
+ *
+ * Copyright (C) 2018 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static char *drng_name = NULL;
+module_param(drng_name, charp, 0444);
+MODULE_PARM_DESC(drng_name, "Kernel crypto API name of DRNG");
+
+static char *pool_hash = "sha512";
+module_param(pool_hash, charp, 0444);
+MODULE_PARM_DESC(pool_hash,
+"Kernel crypto API name of hash or keyed message digest to 
read the entropy pool");
+
+static char *seed_hash = NULL;
+module_param(seed_hash, charp, 0444);
+MODULE_PARM_DESC(seed_hash,
+"Kernel crypto API name of hash with output size equal to 
seedsize of DRNG to bring seed string to the size required by the DRNG");
+
+struct lrng_hash_info {
+   struct shash_desc shash;
+   char ctx[];
+};
+
+struct lrng_drng_info {
+   struct crypto_rng *kcapi_rng;
+   struct lrng_hash_info *lrng_hash;
+};
+
+static struct lrng_hash_info *_lrng_kcapi_hash_alloc(const char *name)
+{
+   struct lrng_hash_info *lrng_hash;
+   struct crypto_shash *tfm;
+   int size;
+
+   if (!name) {
+   pr_err("Hash name missing\n");
+   return ERR_PTR(-EINVAL);
+   }
+
+   tfm = crypto_alloc_shash(name, 0, 0);
+   if (IS_ERR(tfm)) {
+   pr_err("could not allocate hash %s\n", name);
+   return ERR_CAST(tfm);
+   }
+
+   size = sizeof(struct lrng_hash_info) + crypto_shash_descsize(tfm);
+   lrng_hash = kmalloc(size, GFP_KERNEL);
+   if (!lrng_hash) {
+   crypto_free_shash(tfm);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   lrng_hash->shash.tfm = tfm;
+
+   return lrng_hash;
+}
+
+static inline u32 _lrng_kcapi_hash_digestsize(struct lrng_hash_info *lrng_hash)
+{
+   struct shash_desc *shash = _hash->shash;
+   struct crypto_shash *tfm = 

[PATCH v33 08/12] crypto: provide access to a static Jitter RNG state

2020-08-21 Thread Stephan Müller
To support the LRNG operation which uses the Jitter RNG separately
from the kernel crypto API, at a time where potentially the regular
memory management is not yet initialized, the Jitter RNG needs to
provide a state whose memory is defined at compile time. As only once
instance will ever be needed by the LRNG, define once static memory
block which is solely to be used by the LRNG.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 crypto/jitterentropy-kcapi.c  |  3 +-
 crypto/jitterentropy.c| 31 ++-
 .../crypto/internal}/jitterentropy.h  |  3 ++
 3 files changed, 34 insertions(+), 3 deletions(-)
 rename {crypto => include/crypto/internal}/jitterentropy.h (84%)

diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c
index eb7d1dd506bf..25a192f5984e 100644
--- a/crypto/jitterentropy-kcapi.c
+++ b/crypto/jitterentropy-kcapi.c
@@ -43,8 +43,7 @@
 #include 
 #include 
 #include 
-
-#include "jitterentropy.h"
+#include 
 
 /***
  * Helper function
diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c
index 6e147c43fc18..fa1459f09b01 100644
--- a/crypto/jitterentropy.c
+++ b/crypto/jitterentropy.c
@@ -117,7 +117,7 @@ struct rand_data {
 #define JENT_EHEALTH   9 /* Health test failed during initialization */
 #define JENT_ERCT  10 /* RCT failed during initialization */
 
-#include "jitterentropy.h"
+#include 
 
 /***
  * Adaptive Proportion Test
@@ -854,3 +854,32 @@ int jent_entropy_init(void)
 
return 0;
 }
+
+struct rand_data *jent_lrng_entropy_collector(void)
+{
+   static unsigned char lrng_jent_mem[JENT_MEMORY_SIZE];
+   static struct rand_data lrng_jent_state = {
+   .data   = 0,
+   .old_data   = 0,
+   .prev_time  = 0,
+   .last_delta = 0,
+   .last_delta2= 0,
+   .osr= 1,
+   .mem= lrng_jent_mem,
+   .memlocation= 0,
+   .memblocks  = JENT_MEMORY_BLOCKSIZE,
+   .memblocksize   = JENT_MEMORY_BLOCKS,
+   .memaccessloops = JENT_MEMORY_ACCESSLOOPS,
+   .rct_count  = 0,
+   .apt_observations = 0,
+   .apt_count  = 0,
+   .apt_base   = 0,
+   .apt_base_set   = 0,
+   .health_failure = 0
+   };
+
+   if (jent_entropy_init())
+   return NULL;
+
+   return _jent_state;
+}
diff --git a/crypto/jitterentropy.h b/include/crypto/internal/jitterentropy.h
similarity index 84%
rename from crypto/jitterentropy.h
rename to include/crypto/internal/jitterentropy.h
index c83fff32d130..6e07d86eac82 100644
--- a/crypto/jitterentropy.h
+++ b/include/crypto/internal/jitterentropy.h
@@ -15,3 +15,6 @@ extern int jent_read_entropy(struct rand_data *ec, unsigned 
char *data,
 extern struct rand_data *jent_entropy_collector_alloc(unsigned int osr,
  unsigned int flags);
 extern void jent_entropy_collector_free(struct rand_data *entropy_collector);
+
+/* Access to statically allocated Jitter RNG instance */
+extern struct rand_data *jent_lrng_entropy_collector(void);
-- 
2.26.2






[PATCH v33 11/12] LRNG - add interface for gathering of raw entropy

2020-08-21 Thread Stephan Müller
The test interface allows a privileged process to capture the raw
unconditioned noise that is collected by the LRNG for statistical
analysis. Such testing allows the analysis how much entropy
the interrupt noise source provides on a given platform.
Extracted noise data is not used to seed the LRNG. This
is a test interface and not appropriate for production systems.
Yet, the interface is considered to be sufficiently secured for
production systems.

Access to the data is given through the lrng_raw debugfs file. The
data buffer should be multiples of sizeof(u32) to fill the entire
buffer. Using the option lrng_testing.boot_test=1 the raw noise of
the first 1000 entropy events since boot can be sampled.

This test interface allows generating the data required for
analysis whether the LRNG is in compliance with SP800-90B
sections 3.1.3 and 3.1.4.

In addition, the test interface allows gathering of the conatenated raw
entropy data to verify that the concatenation works appropriately.
This includes sampling of the following raw data:

* high-resolution time stamp

* Jiffies

* IRQ number

* IRQ flags

* return instruction pointer

* array logic batching the high-resolution time stamp

Finally, the execution duration for processing a time stamp can be
obtained with the LRNG raw entropy interface.

If a test interface is not compiled, its code is a noop which has no
impact on the performance.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig| 124 +++
 drivers/char/lrng/Makefile   |   1 +
 drivers/char/lrng/lrng_testing.c | 575 +++
 3 files changed, 700 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_testing.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index 70eee0f43d8c..4feabb0a20c2 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -163,4 +163,128 @@ config LRNG_APT_CUTOFF
default 325 if !LRNG_APT_BROKEN
default 32 if LRNG_APT_BROKEN
 
+menuconfig LRNG_TESTING_MENU
+   bool "LRNG testing interfaces"
+   depends on DEBUG_FS
+   help
+ Enable one or more of the following test interfaces.
+
+ If unsure, say N.
+
+if LRNG_TESTING_MENU
+
+config LRNG_RAW_HIRES_ENTROPY
+   bool "Enable entropy test interface to hires timer noise source"
+   default y
+   help
+ The test interface allows a privileged process to capture
+ the raw unconditioned high resolution time stamp noise that
+ is collected by the LRNG for statistical analysis. Extracted
+ noise data is not used to seed the LRNG.
+
+ The raw noise data can be obtained using the lrng_raw_hires
+ debugfs file. Using the option lrng_testing.boot_raw_hires_test=1
+ the raw noise of the first 1000 entropy events since boot
+ can be sampled.
+
+config LRNG_RAW_JIFFIES_ENTROPY
+   bool "Enable entropy test interface to Jiffies noise source"
+   help
+ The test interface allows a privileged process to capture
+ the raw unconditioned Jiffies that is collected by
+ the LRNG for statistical analysis. This data is used for
+ seeding the LRNG if a high-resolution time stamp is not
+ available. If a high-resolution time stamp is detected,
+ the Jiffies value is not collected by the LRNG and no
+ data is provided via the test interface. Extracted noise
+ data is not used to seed the random number generator.
+
+ The raw noise data can be obtained using the lrng_raw_jiffies
+ debugfs file. Using the option lrng_testing.boot_raw_jiffies_test=1
+ the raw noise of the first 1000 entropy events since boot
+ can be sampled.
+
+config LRNG_RAW_IRQ_ENTROPY
+   bool "Enable entropy test interface to IRQ number noise source"
+   help
+ The test interface allows a privileged process to capture
+ the raw unconditioned interrupt number that is collected by
+ the LRNG for statistical analysis. This data is used for
+ seeding the random32 PRNG external to the LRNG if a
+ high-resolution time stamp is available or it will be used to
+ seed the LRNG otherwise. Extracted noise data is not used to
+ seed the random number generator.
+
+ The raw noise data can be obtained using the lrng_raw_irq
+ debugfs file. Using the option lrng_testing.boot_raw_irq_test=1
+ the raw noise of the first 1000 entropy events since boot
+ can be 

Re: [PATCH v32 01/12] Linux Random Number Generator

2020-08-20 Thread Stephan Müller
Am Donnerstag, 20. August 2020, 13:46:49 CEST schrieb kernel test robot:

Hi,

> All warnings (new ones prefixed by >>):
> >> drivers/char/lrng/lrng_interfaces.c:120:6: warning: no previous prototype
> >> for 'add_hwgenerator_randomness' [-Wmissing-prototypes]
>  120 | void add_hwgenerator_randomness(const char *buffer, size_t count,
>  |  ^~

Thank you, added 
> >> 
> >> drivers/char/lrng/lrng_interfaces.c:297:6: warning: no previous prototype
> >> for 'get_random_bytes_full' [-Wmissing-prototypes]
>  297 | void get_random_bytes_full(void *buf, int nbytes)
> 
>  |  ^
> 
Thanks, added prototype to header file.

Ciao
Stephan




Re: [PATCH v32 06/12] LRNG - add SP800-90A DRBG extension

2020-08-20 Thread Stephan Müller
Am Donnerstag, 20. August 2020, 14:07:40 CEST schrieb kernel test robot:

Hi,

> 
> All warnings (new ones prefixed by >>):
> >> drivers/char/lrng/lrng_drbg.c:226:1: warning: 'static' is not at
> >> beginning of declaration [-Wold-style-declaration]
>  226 | const static struct lrng_crypto_cb lrng_drbg_crypto_cb = {
> 
>  | ^

Thanks, I will provide a new patch set with the two keywords switched.

Ciao
Stephan




[PATCH v32 03/12] LRNG - sysctls and /proc interface

2020-08-20 Thread Stephan Müller
The LRNG sysctl interface provides the same controls as the existing
/dev/random implementation. These sysctls behave identically and are
implemented identically. The goal is to allow a possible merge of the
existing /dev/random implementation with this implementation which
implies that this patch tries have a very close similarity. Yet, all
sysctls are documented at [1].

In addition, it provides the file lrng_type which provides details about
the LRNG:

- the name of the DRNG that produces the random numbers for /dev/random,
/dev/urandom, getrandom(2)

- the hash used to produce random numbers from the entropy pool

- the number of secondary DRNG instances

- indicator whether the LRNG operates SP800-90B compliant

- indicator whether a high-resolution timer is identified - only with a
high-resolution timer the interrupt noise source will deliver sufficient
entropy

- indicator whether the LRNG has been minimally seeded (i.e. is the
secondary DRNG seeded with at least 128 bits of of entropy)

- indicator whether the LRNG has been fully seeded (i.e. is the
secondary DRNG seeded with at least 256 bits of entropy)

[1] https://www.chronox.de/lrng.html

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Makefile  |   1 +
 drivers/char/lrng/lrng_interfaces.c |   1 -
 drivers/char/lrng/lrng_internal.h   |   4 +
 drivers/char/lrng/lrng_proc.c   | 163 
 4 files changed, 168 insertions(+), 1 deletion(-)
 create mode 100644 drivers/char/lrng/lrng_proc.c

diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 0a32f22c2c1a..e69c176f0161 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -9,3 +9,4 @@ obj-y   += lrng_pool.o lrng_aux.o \
   lrng_interfaces.o \
 
 obj-$(CONFIG_NUMA) += lrng_numa.o
+obj-$(CONFIG_SYSCTL)   += lrng_proc.o
diff --git a/drivers/char/lrng/lrng_interfaces.c 
b/drivers/char/lrng/lrng_interfaces.c
index 7fc04e54d834..184108b6e1cb 100644
--- a/drivers/char/lrng/lrng_interfaces.c
+++ b/drivers/char/lrng/lrng_interfaces.c
@@ -34,7 +34,6 @@ static DECLARE_WAIT_QUEUE_HEAD(lrng_write_wait);
 static DECLARE_WAIT_QUEUE_HEAD(lrng_init_wait);
 static struct fasync_struct *fasync;
 
-struct ctl_table random_table[];
 /** Helper ***/
 
 /* Is the DRNG seed level too low? */
diff --git a/drivers/char/lrng/lrng_internal.h 
b/drivers/char/lrng/lrng_internal.h
index 495e00ae5ee1..a52c4cf367e2 100644
--- a/drivers/char/lrng/lrng_internal.h
+++ b/drivers/char/lrng/lrng_internal.h
@@ -117,7 +117,11 @@ void lrng_cc20_init_state_boot(struct chacha20_state 
*state);
 
 /** /proc 
*/
 
+#ifdef CONFIG_SYSCTL
+void lrng_pool_inc_numa_node(void);
+#else
 static inline void lrng_pool_inc_numa_node(void) { }
+#endif
 
 /** LRNG interfaces 
***/
 
diff --git a/drivers/char/lrng/lrng_proc.c b/drivers/char/lrng/lrng_proc.c
new file mode 100644
index ..c569a269b07a
--- /dev/null
+++ b/drivers/char/lrng/lrng_proc.c
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG proc and sysctl interfaces
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "lrng_internal.h"
+
+/*
+ * This function is used to return both the bootid UUID, and random
+ * UUID.  The difference is in whether table->data is NULL; if it is,
+ * then a new UUID is generated and returned to the user.
+ *
+ * If the user accesses this via the proc interface, the UUID will be
+ * returned as an ASCII string in the standard UUID format; if via the
+ * sysctl system call, as 16 bytes of binary data.
+ */
+static int lrng_proc_do_uuid(struct ctl_table *table, int write,
+void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+   struct ctl_table fake_table;
+   unsigned char buf[64], tmp_uuid[16], *uuid;
+
+   uuid = table->data;
+   if (!uuid) {
+   uuid = tmp_uuid;
+   generate_random_uuid(uuid);
+   } else {
+   static DEFINE_SPINLOCK(bootid_spinlock);
+
+   spin_lock(_spinlock);
+   if (!uuid[8])
+   generate_random_uuid(uuid);
+   spin_unlock(_spinlock);
+   }
+
+   sprintf(buf, 

[PATCH v32 10/12] LRNG - add SP800-90B compliant health tests

2020-08-20 Thread Stephan Müller
Implement health tests for LRNG's slow noise sources as mandated by
SP-800-90B The file contains the following health tests:

- stuck test: The stuck test calculates the first, second and third
  discrete derivative of the time stamp to be processed by the LFSR.
  Only if all three values are non-zero, the received time delta is
  considered to be non-stuck.

- SP800-90B Repetition Count Test (RCT): The LRNG uses an enhanced
  version of the RCT specified in SP800-90B section 4.4.1. Instead of
  counting identical back-to-back values, the input to the RCT is the
  counting of the stuck values during the processing of received
  interrupt events. The RCT is applied with alpha=2^-30 compliant to
  the recommendation of FIPS 140-2 IG 9.8. During the counting operation,
  the LRNG always calculates the RCT cut-off value of C. If that value
  exceeds the allowed cut-off value, the LRNG will trigger the health
  test failure discussed below. An error is logged to the kernel log
  that such RCT failure occurred. This test is only applied and
  enforced in FIPS mode, i.e. when the kernel compiled with
  CONFIG_CONFIG_FIPS is started with fips=1.

- SP800-90B Adaptive Proportion Test (APT): The LRNG implements the
  APT as defined in SP800-90B section 4.4.2. The applied significance
  level again is alpha=2^-30 compliant to the recommendation of FIPS
  140-2 IG 9.8.

The aforementioned health tests are applied to the first 1,024 time stamps
obtained from interrupt events. In case one error is identified for either
the RCT, or the APT, the collected entropy is invalidated and the
SP800-90B startup health test is restarted.

As long as the SP800-90B startup health test is not completed, all LRNG
random number output interfaces that may block will block and not generate
any data. This implies that only those potentially blocking interfaces are
defined to provide random numbers that are seeded with the interrupt noise
source being SP800-90B compliant. All other output interfaces will not be
affected by the SP800-90B startup test and thus are not considered
SP800-90B compliant.

At runtime, the SP800-90B APT and RCT are applied to each time stamp
generated for a received interrupt. When either the APT and RCT indicates
a noise source failure, the LRNG is reset to a state it has immediately
after boot:

- all entropy counters are set to zero

- the SP800-90B startup tests are re-performed which implies that
getrandom(2) would block again until new entropy was collected

To summarize, the following rules apply:

• SP800-90B compliant output interfaces

  - /dev/random

  - getrandom(2) system call

  -  get_random_bytes kernel-internal interface when being triggered by
 the callback registered with add_random_ready_callback

• SP800-90B non-compliant output interfaces

  - /dev/urandom

  - get_random_bytes kernel-internal interface called directly

  - randomize_page kernel-internal interface

  - get_random_u32 and get_random_u64 kernel-internal interfaces

  - get_random_u32_wait, get_random_u64_wait, get_random_int_wait, and
get_random_long_wait kernel-internal interfaces

If either the RCT, or the APT health test fails irrespective whether
during initialization or runtime, the following actions occur:

  1. The entropy of the entire entropy pool is invalidated.

  2. All DRNGs are reset which imply that they are treated as being
 not seeded and require a reseed during next invocation.

  3. The SP800-90B startup health test are initiated with all
 implications of the startup tests. That implies that from that point
 on, new events must be observed and its entropy must be inserted into
 the entropy pool before random numbers are calculated from the
 entropy pool.

Further details on the SP800-90B compliance and the availability of all
test tools required to perform all tests mandated by SP800-90B are
provided at [1].

The entire health testing code is compile-time configurable.

The patch provides a CONFIG_BROKEN configuration of the APT / RCT cutoff
values which have a high likelihood to trigger the health test failure.
The BROKEN APT cutoff is set to the exact mean of the expected value if
the time stamps are equally distributed (512 time stamps divided by 16
possible values due to using the 4 LSB of the time stamp). The BROKEN
RCT cutoff value is set to 1 which is likely to be triggered during
regular operation.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig   |  56 +
 drivers/char/lrng/Makefile  |   1 +
 

[PATCH v32 06/12] LRNG - add SP800-90A DRBG extension

2020-08-20 Thread Stephan Müller
Using the LRNG switchable DRNG support, the SP800-90A DRBG extension is
implemented.

The DRBG uses the kernel crypto API DRBG implementation. In addition, it
uses the kernel crypto API SHASH support to provide the hashing
operation.

The DRBG supports the choice of either a CTR DRBG using AES-256, HMAC
DRBG with SHA-512 core or Hash DRBG with SHA-512 core. The used core can
be selected with the module parameter lrng_drbg_type. The default is the
CTR DRBG.

When compiling the DRBG extension statically, the DRBG is loaded at
late_initcall stage which implies that with the start of user space, the
user space interfaces of getrandom(2), /dev/random and /dev/urandom
provide random data produced by an SP800-90A DRBG.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig |  12 ++
 drivers/char/lrng/Makefile|   1 +
 drivers/char/lrng/lrng_drbg.c | 259 ++
 3 files changed, 272 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_drbg.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index d3138458fd8b..4ad26fdfbe7e 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -72,4 +72,16 @@ menuconfig LRNG_DRNG_SWITCH
  accessible via the external interfaces. With this configuration
  option other DRNGs can be selected and loaded at runtime.
 
+if LRNG_DRNG_SWITCH
+config LRNG_DRBG
+   tristate "SP800-90A support for the LRNG"
+   depends on CRYPTO
+   select CRYPTO_DRBG_MENU
+   select CRYPTO_SHA512
+   help
+ Enable the SP800-90A DRBG support for the LRNG. Once the
+ module is loaded, output from /dev/random, /dev/urandom,
+ getrandom(2), or get_random_bytes is provided by a DRBG.
+endif # LRNG_DRNG_SWITCH
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 31cfe87c999e..0d320fcb7b9e 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -11,3 +11,4 @@ obj-y += lrng_pool.o lrng_aux.o \
 obj-$(CONFIG_NUMA) += lrng_numa.o
 obj-$(CONFIG_SYSCTL)   += lrng_proc.o
 obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
+obj-$(CONFIG_LRNG_DRBG)+= lrng_drbg.o
diff --git a/drivers/char/lrng/lrng_drbg.c b/drivers/char/lrng/lrng_drbg.c
new file mode 100644
index ..06590438f88f
--- /dev/null
+++ b/drivers/char/lrng/lrng_drbg.c
@@ -0,0 +1,259 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Backend for the LRNG providing the cryptographic primitives using the
+ * kernel crypto API and its DRBG.
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Define a DRBG plus a hash / MAC used to extract data from the entropy pool.
+ * For LRNG_HASH_NAME you can use a hash or a MAC (HMAC or CMAC) of your choice
+ * (Note, you should use the suggested selections below -- using SHA-1 or MD5
+ * is not wise). The idea is that the used cipher primitive can be selected to
+ * be the same as used for the DRBG. I.e. the LRNG only uses one cipher
+ * primitive using the same cipher implementation with the options offered in
+ * the following. This means, if the CTR DRBG is selected and AES-NI is 
present,
+ * both the CTR DRBG and the selected cmac(aes) use AES-NI.
+ *
+ * The security strengths of the DRBGs are all 256 bits according to
+ * SP800-57 section 5.6.1.
+ *
+ * This definition is allowed to be changed.
+ */
+#ifdef CONFIG_CRYPTO_DRBG_CTR
+static unsigned int lrng_drbg_type = 0;
+#elif defined CONFIG_CRYPTO_DRBG_HMAC
+static unsigned int lrng_drbg_type = 1;
+#elif defined CONFIG_CRYPTO_DRBG_HASH
+static unsigned int lrng_drbg_type = 2;
+#else
+#error "Unknown DRBG in use"
+#endif
+
+/* The parameter must be r/o in sysfs as otherwise races appear. */
+module_param(lrng_drbg_type, uint, 0444);
+MODULE_PARM_DESC(lrng_drbg_type, "DRBG type used for LRNG (0->CTR_DRBG, 
1->HMAC_DRBG, 2->Hash_DRBG)");
+
+struct lrng_drbg {
+   const char *hash_name;
+   const char *drbg_core;
+};
+
+static const struct lrng_drbg lrng_drbg_types[] = {
+   {   /* CTR_DRBG with AES-256 using derivation function */
+   .hash_name = "sha512",
+   .drbg_core = "drbg_nopr_ctr_aes256",
+   }, {/* HMAC_DRBG with SHA-512 */
+   .hash_name = "sha512",
+   .drbg_core = "drbg_nopr_hmac_sha512",
+   }, {/* Hash_DRBG with SHA-512 using derivation function */
+  

[PATCH v32 04/12] LRNG - add switchable DRNG support

2020-08-20 Thread Stephan Müller
The DRNG switch support allows replacing the DRNG mechanism of the
LRNG. The switching support rests on the interface definition of
include/linux/lrng.h. A new DRNG is implemented by filling in the
interface defined in this header file.

In addition to the DRNG, the extension also has to provide a hash
implementation that is used to hash the entropy pool for random number
extraction.

Note: It is permissible to implement a DRNG whose operations may sleep.
However, the hash function must not sleep.

The switchable DRNG support allows replacing the DRNG at runtime.
However, only one DRNG extension is allowed to be loaded at any given
time. Before replacing it with another DRNG implementation, the possibly
existing DRNG extension must be unloaded.

The switchable DRNG extension activates the new DRNG during load time.
It is expected, however, that such a DRNG switch would be done only once
by an administrator to load the intended DRNG implementation.

It is permissible to compile DRNG extensions either as kernel modules or
statically. The initialization of the DRNG extension should be performed
with a late_initcall to ensure the extension is available when user
space starts but after all other initialization completed.
The initialization is performed by registering the function call data
structure with the lrng_set_drng_cb function. In order to unload the
DRNG extension, lrng_set_drng_cb must be invoked with the NULL
parameter.

The DRNG extension should always provide a security strength that is at
least as strong as LRNG_DRNG_SECURITY_STRENGTH_BITS.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig   |   7 ++
 drivers/char/lrng/Makefile  |   1 +
 drivers/char/lrng/lrng_switch.c | 189 
 3 files changed, 197 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_switch.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index 059b21d9728c..d3138458fd8b 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -65,4 +65,11 @@ config LRNG_POOL_SIZE
default 7 if LRNG_POOL_SIZE_65536
default 8 if LRNG_POOL_SIZE_131072
 
+menuconfig LRNG_DRNG_SWITCH
+   bool "Support DRNG runtime switching"
+   help
+ The Linux RNG per default uses a ChaCha20 DRNG that is
+ accessible via the external interfaces. With this configuration
+ option other DRNGs can be selected and loaded at runtime.
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index e69c176f0161..31cfe87c999e 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -10,3 +10,4 @@ obj-y += lrng_pool.o lrng_aux.o \
 
 obj-$(CONFIG_NUMA) += lrng_numa.o
 obj-$(CONFIG_SYSCTL)   += lrng_proc.o
+obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
diff --git a/drivers/char/lrng/lrng_switch.c b/drivers/char/lrng/lrng_switch.c
new file mode 100644
index ..67eebb3c119f
--- /dev/null
+++ b/drivers/char/lrng/lrng_switch.c
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG DRNG switching support
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+
+#include "lrng_internal.h"
+
+static int lrng_drng_switch(struct lrng_drng *drng_store,
+   const struct lrng_crypto_cb *cb, int node)
+{
+   const struct lrng_crypto_cb *old_cb;
+   unsigned long flags = 0;
+   int ret;
+   u8 seed[LRNG_DRNG_SECURITY_STRENGTH_BYTES] __latent_entropy;
+   void *new_drng = cb->lrng_drng_alloc(LRNG_DRNG_SECURITY_STRENGTH_BYTES);
+   void *old_drng, *new_hash, *old_hash;
+   bool sl = false, reset_drng = !lrng_get_available();
+
+   if (IS_ERR(new_drng)) {
+   pr_warn("could not allocate new DRNG for NUMA node %d (%ld)\n",
+   node, PTR_ERR(new_drng));
+   return PTR_ERR(new_drng);
+   }
+
+   /*
+* The seed potentially used as MAC key is undefined to add some
+* variation. Yet, the security of the MAC does not rely on the key
+* being secret. The key is only there to turn a MAC into a hash.
+* The intention is to allow the specification of CMAC(AES) as "hash"
+* to limit the dependency to AES when using the CTR DRBG.
+*/
+   new_hash = cb->lrng_hash_alloc(seed, sizeof(seed));
+   if (IS_ERR(new_hash)) {
+   

[PATCH v32 01/12] Linux Random Number Generator

2020-08-20 Thread Stephan Müller
In an effort to provide a flexible implementation for a random number
generator that also delivers entropy during early boot time, allows
replacement of the deterministic random number generation mechanism,
implement the various components in separate code for easier
maintenance, and provide compliance to SP800-90[A|B|C], introduce
the Linux Random Number Generator (LRNG) framework.

The general design is as follows. Additional implementation details
are given in [1]. The LRNG consists of the following components:

1. The LRNG implements a DRNG. The DRNG always generates the
requested amount of output. When using the SP800-90A terminology
it operates without prediction resistance. The secondary DRNG
maintains a counter of how many bytes were generated since last
re-seed and a timer of the elapsed time since last re-seed. If either
the counter or the timer reaches a threshold, the secondary DRNG is
seeded from the entropy pool.

In case the Linux kernel detects a NUMA system, one secondary DRNG
instance per NUMA node is maintained.

2. The DRNG is seeded by concatenating the data from the
following sources:

(a) the output of the entropy pool,

(b) the Jitter RNG if available and enabled, and

(c) the CPU-based noise source such as Intel RDRAND if available and
enabled.

The entropy estimate of the data of all noise sources are added to
form the entropy estimate of the data used to seed the DRNG with.
The LRNG ensures, however, that the DRNG after seeding is at
maximum the security strength of the DRNG.

The LRNG is designed such that none of these noise sources can dominate
the other noise sources to provide seed data to the DRNG during due to
the following:

(a) During boot time, the amount of received interrupts are the trigger
points to (re)seed the DRNG.

(b) At runtime, the available entropy from the slow noise source is
concatenated with a pre-defined amount of data from the fast noise
sources. In addition, each DRNG reseed operation triggers external
noise source providers to deliver one block of data.

3. The entropy pool accumulates entropy obtained from certain events,
which will henceforth be collectively called "slow noise sources".
The entropy pool collects noise data from slow noise sources. Any data
received by the LRNG from the slow noise sources is inserted into the
entropy pool using an LFSR with a primitive and irreducible polynomial.
The following sources of entropy are used:

 (a) When an interrupt occurs, the high-resolution time stamp is mixed
into the LFSR. This time stamp is credited with heuristically implied
entropy.

 (b) HID event data like the key stroke or the mouse coordinates are
mixed into the LFSR. This data is not credited with entropy by the LRNG.

 (c) Device drivers may provide data that is mixed into the LFSR. This
data is not credited with entropy by the LRNG.

 (d) After the entropy pool is ``read'' by the DRNG, the data
used to seed the DRNG is mixed back into the entropy pool to
stir the pool. This data is not credited with entropy by the LRNG.

Any data provided from user space by either writing to /dev/random,
/dev/urandom or the IOCTL of RNDADDENTROPY on both device files
are always injected into the entropy pool.

In addition, when a hardware random number generator covered by the
Linux kernel HW generator framework wants to deliver random numbers,
it is injected into the entropy pool as well. HW generator noise source
is handled separately from the other noise source due to the fact that
the HW generator framework may decide by itself when to deliver data
whereas the other noise sources always requested for data driven by the
LRNG operation. Similarly any user space provided data is inserted into
the entropy pool.

When the DRNG requires data from the entropy pool, the entire
entropy pool is processed with an SP800-90A section 10.3.1 compliant
hash_df function to generate random numbers.

To speed up the interrupt handling code of the LRNG, the time stamp
collected for an interrupt event is truncated to the 8 least
significant bits. 64 truncated time stamps are concatenated and then
jointly inserted into the LFSR. During boot time, until the fully seeded
stage is reached, each time stamp with its 32 least significant bits is
inserted into the LFSR at the time of arrival.

The LRNG allows the DRNG mechanism to be changed at runtime. Per default,
a ChaCha20-based DRNG is used. The ChaCha20-DRNG implemented for the
LRNG is also provided as a stand-alone user space deterministic random
number generator. The LRNG also offers an SP800-90A DRBG based on the
Linux kernel crypto API DRBG implementation.

The processing of entropic data from the noise source before injecting
them into the DRNG is performed with the following mathematical
operations:

1. LFSR: The 8 least significant bits of the time stamp data received
from the interrupts are processed with an LFSR. That LFSR is implemented
identically to the LSFR used in the existing /dev/random implementation

[PATCH v32 00/12] /dev/random - a new approach with full SP800-90B compliance

2020-08-20 Thread Stephan Müller
Hi,

The following patch set provides a different approach to /dev/random which is
called Linux Random Number Generator (LRNG) to collect entropy within the Linux
kernel. The main improvements compared to the existing /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.

The LRNG patch set allows a user to select use of the existing /dev/random or
the LRNG during compile time. As the LRNG provides API and ABI compatible
interfaces to the existing /dev/random implementation, the user can freely chose
the RNG implementation without affecting kernel or user space operations.

This patch set provides early boot-time entropy which implies that no
additional flags to the getrandom(2) system call discussed recently on
the LKML is considered to be necessary. Yet, if additional flags are
introduced to cover special hardware, the LRNG implementation will also
provide them to be fully ABI and API compliant as already discussed on
LKML.

The LRNG is fully compliant to SP800-90B requirements and is shipped with a
full SP800-90B assessment and all required test tools. The existing /dev/random
implementation on the other hand has architectural limitations which
does not easily allow to bring the implementation in compliance with
SP800-90B. The key statement that causes concern is SP800-90B section
3.1.6. This section denies crediting entropy to multiple similar noise
sources. This section explicitly references different noise sources resting
on the timing of events and their derivatives (i.e. it is a direct complaint
to the existing existing /dev/random implementation). Therefore, SP800-90B
now denies the very issue mentioned in [1] with the existing /dev/random
implementation for a long time: crediting entropy to interrupts as well as
crediting entropy to derivatives of interrupts (HID and disk events). This is
not permissible with SP800-90B.

SP800-90B specifies various requirements for the noise source(s) that seed any
DRNG including SP800-90A DRBGs. In about a year from now, SP800-90B will be
mandated for all noise sources that provide entropy to DRBGs as part of a FIPS
140-[2|3] validation or other evaluation types. That means, if we there are no
solutions to comply with the requirements of SP800-90B found till one year
from now, any random number generation and ciphers based on random numbers
on Linux will be considered and treated as not applicable and delivering
no entropy! As /dev/urandom, getrandom(2) and /dev/random are the most
common and prevalent noise sources for DRNGs, all these DRNGs are affected.
This applies across the board for all validations of cryptography executing on
Linux (kernel and user space modules).

For users that are not interested in SP800-90B, the entire code for the
compliance as well as test interfaces can be deselected at compile time.

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

The LRNG provides a complete separation of the noise source maintenance
and the collection of entropy into an entropy pool from the post-processing
using a pseudo-random number generator. Different DRNGs are supported,
including:

* The LRNG can be compile-time enabled to replace the existing /dev/random
  implementation. When not selecting the LRNG at compile time (default), the
  existing /dev/random implementation is built.

* Built-in ChaCha20 DRNG which has no dependency to other kernel
  frameworks.

* SP800-90A DRBG using the kernel crypto API including its accelerated
  raw cipher implementations. This implies that the output of /dev/random,
  getrandom(2), /dev/urandom or get_random_bytes is fully compliant to
  SP800-90A.

* Arbitrary DRNGs registered with the kernel crypto API

* Full compliance with SP800-90B which covers the startup and runtime health
  tests mandated by SP800-90B as well as providing the test tools and test
  interfaces to obtain raw noise data securely. The test tools are provided at
  [1].

Booting the patch with the kernel command line option
"dyndbg=file drivers/char/lrng/* +p" generates logs indicating the operation
of the LRNG. Each log is pre-pended with "lrng".

The LRNG has a flexible design by allowing an easy replacement of the
deterministic random number generator component.

Compared to the existing /dev/random implementation, the compiled binary
is smaller when the LRNG is compiled with all options equal to the
existing /dev/random (i.e. only CONFIG_LRNG is set): random.o is 52.5 kBytes
whereas all LRNG object files are in 49 kBytes in size. The fully

[PATCH v32 02/12] LRNG - allocate one DRNG instance per NUMA node

2020-08-20 Thread Stephan Müller
In order to improve NUMA-locality when serving getrandom(2) requests,
allocate one DRNG instance per node.

The DRNG instance that is present right from the start of the kernel is
reused as the first per-NUMA-node DRNG. For all remaining online NUMA
nodes a new DRNG instance is allocated.

During boot time, the multiple DRNG instances are seeded sequentially.
With this, the first DRNG instance (referenced as the initial DRNG
in the code) is completely seeded with 256 bits of entropy before the
next DRNG instance is completely seeded.

When random numbers are requested, the NUMA-node-local DRNG is checked
whether it has been already fully seeded. If this is not the case, the
initial DRNG is used to serve the request.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Makefile|   2 +
 drivers/char/lrng/lrng_internal.h |   5 ++
 drivers/char/lrng/lrng_numa.c | 101 ++
 3 files changed, 108 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_numa.c

diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 1d2a0211973d..0a32f22c2c1a 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -7,3 +7,5 @@ obj-y   += lrng_pool.o lrng_aux.o \
   lrng_sw_noise.o lrng_archrandom.o \
   lrng_drng.o lrng_chacha20.o \
   lrng_interfaces.o \
+
+obj-$(CONFIG_NUMA) += lrng_numa.o
diff --git a/drivers/char/lrng/lrng_internal.h 
b/drivers/char/lrng/lrng_internal.h
index f6a5f0d960c1..495e00ae5ee1 100644
--- a/drivers/char/lrng/lrng_internal.h
+++ b/drivers/char/lrng/lrng_internal.h
@@ -247,8 +247,13 @@ int lrng_drng_get_sleep(u8 *outbuf, u32 outbuflen);
 void lrng_drng_force_reseed(void);
 void lrng_drng_seed_work(struct work_struct *dummy);
 
+#ifdef CONFIG_NUMA
+struct lrng_drng **lrng_drng_instances(void);
+void lrng_drngs_numa_alloc(void);
+#else  /* CONFIG_NUMA */
 static inline struct lrng_drng **lrng_drng_instances(void) { return NULL; }
 static inline void lrng_drngs_numa_alloc(void) { return; }
+#endif /* CONFIG_NUMA */
 
 /** Health Test linking code 
**/
 
diff --git a/drivers/char/lrng/lrng_numa.c b/drivers/char/lrng/lrng_numa.c
new file mode 100644
index ..947c5b3ed517
--- /dev/null
+++ b/drivers/char/lrng/lrng_numa.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG NUMA support
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+
+#include "lrng_internal.h"
+
+static struct lrng_drng **lrng_drng __read_mostly = NULL;
+
+struct lrng_drng **lrng_drng_instances(void)
+{
+   return lrng_drng;
+}
+
+/* Allocate the data structures for the per-NUMA node DRNGs */
+static void _lrng_drngs_numa_alloc(struct work_struct *work)
+{
+   struct lrng_drng **drngs;
+   struct lrng_drng *lrng_drng_init = lrng_drng_init_instance();
+   u32 node;
+   bool init_drng_used = false;
+
+   mutex_lock(_crypto_cb_update);
+
+   /* per-NUMA-node DRNGs are already present */
+   if (lrng_drng)
+   goto unlock;
+
+   drngs = kcalloc(nr_node_ids, sizeof(void *), GFP_KERNEL|__GFP_NOFAIL);
+   for_each_online_node(node) {
+   struct lrng_drng *drng;
+
+   if (!init_drng_used) {
+   drngs[node] = lrng_drng_init;
+   init_drng_used = true;
+   continue;
+   }
+
+   drng = kmalloc_node(sizeof(struct lrng_drng),
+GFP_KERNEL|__GFP_NOFAIL, node);
+   memset(drng, 0, sizeof(lrng_drng));
+
+   drng->crypto_cb = lrng_drng_init->crypto_cb;
+   drng->drng = drng->crypto_cb->lrng_drng_alloc(
+   LRNG_DRNG_SECURITY_STRENGTH_BYTES);
+   if (IS_ERR(drng->drng)) {
+   kfree(drng);
+   goto err;
+   }
+
+   mutex_init(>lock);
+   spin_lock_init(>spin_lock);
+
+   /*
+* No reseeding of NUMA DRNGs from previous DRNGs as this
+* would complicate the code. Let it simply reseed.
+*/
+   lrng_drng_reset(drng);
+   drngs[node] = drng;
+
+   

[PATCH v32 11/12] LRNG - add interface for gathering of raw entropy

2020-08-20 Thread Stephan Müller
The test interface allows a privileged process to capture the raw
unconditioned noise that is collected by the LRNG for statistical
analysis. Such testing allows the analysis how much entropy
the interrupt noise source provides on a given platform.
Extracted noise data is not used to seed the LRNG. This
is a test interface and not appropriate for production systems.
Yet, the interface is considered to be sufficiently secured for
production systems.

Access to the data is given through the lrng_raw debugfs file. The
data buffer should be multiples of sizeof(u32) to fill the entire
buffer. Using the option lrng_testing.boot_test=1 the raw noise of
the first 1000 entropy events since boot can be sampled.

This test interface allows generating the data required for
analysis whether the LRNG is in compliance with SP800-90B
sections 3.1.3 and 3.1.4.

In addition, the test interface allows gathering of the conatenated raw
entropy data to verify that the concatenation works appropriately.
This includes sampling of the following raw data:

* high-resolution time stamp

* Jiffies

* IRQ number

* IRQ flags

* return instruction pointer

* array logic batching the high-resolution time stamp

Finally, the execution duration for processing a time stamp can be
obtained with the LRNG raw entropy interface.

If a test interface is not compiled, its code is a noop which has no
impact on the performance.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig| 124 +++
 drivers/char/lrng/Makefile   |   1 +
 drivers/char/lrng/lrng_testing.c | 575 +++
 3 files changed, 700 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_testing.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index 70eee0f43d8c..5d2f44d07581 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -163,4 +163,128 @@ config LRNG_APT_CUTOFF
default 325 if !LRNG_APT_BROKEN
default 32 if LRNG_APT_BROKEN
 
+menuconfig LRNG_TESTING_MENU
+   bool "LRNG testing interfaces"
+   depends on DEBUG_FS
+   help
+ Enable one or more of the following test interfaces.
+
+ If unsure, say N.
+
+if LRNG_TESTING_MENU
+
+config LRNG_RAW_HIRES_ENTROPY
+   bool "Enable entropy test interface to hires timer noise source"
+   default y
+   help
+ The test interface allows a privileged process to capture
+ the raw unconditioned high resolution time stamp noise that
+ is collected by the LRNG for statistical analysis. Extracted
+ noise data is not used to seed the LRNG.
+
+ The raw noise data can be obtained using the lrng_raw_hires
+ debugfs file. Using the option lrng_testing.boot_raw_hires_test=1
+ the raw noise of the first 1000 entropy events since boot
+ can be sampled.
+
+config LRNG_RAW_JIFFIES_ENTROPY
+   bool "Enable entropy test interface to Jiffies noise source"
+   help
+ The test interface allows a privileged process to capture
+ the raw unconditioned Jiffies that is collected by
+ the LRNG for statistical analysis. This data is used for
+ seeding the LRNG if a high-resolution time stamp is not
+ available. If a high-resolution time stamp is detected,
+ the Jiffies value is not collected by the LRNG and no
+ data is provided via the test interface. Extracted noise
+ data is not used to seed the random number generator.
+
+ The raw noise data can be obtained using the lrng_raw_jiffies
+ debugfs file. Using the option lrng_testing.boot_raw_jiffies_test=1
+ the raw noise of the first 1000 entropy events since boot
+ can be sampled.
+
+config LRNG_RAW_IRQ_ENTROPY
+   bool "Enable entropy test interface to IRQ number noise source"
+   help
+ The test interface allows a privileged process to capture
+ the raw unconditioned interrupt number that is collected by
+ the LRNG for statistical analysis. This data is used for
+ seeding the random32 PRNG external to the LRNG if a
+ high-resolution time stamp is available or it will be used to
+ seed the LRNG otherwise. Extracted noise data is not used to
+ seed the random number generator.
+
+ The raw noise data can be obtained using the lrng_raw_irq
+ debugfs file. Using the option lrng_testing.boot_raw_irq_test=1
+ the raw noise of the first 1000 entropy events since boot
+ can be 

[PATCH v32 09/12] LRNG - add Jitter RNG fast noise source

2020-08-20 Thread Stephan Müller
The Jitter RNG fast noise source implemented as part of the kernel
crypto API is queried for 256 bits of entropy at the time the seed
buffer managed by the LRNG is about to be filled.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Marcelo Henrique Cerri 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 drivers/char/lrng/Kconfig | 12 +
 drivers/char/lrng/Makefile|  1 +
 drivers/char/lrng/lrng_jent.c | 88 +++
 3 files changed, 101 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_jent.c

diff --git a/drivers/char/lrng/Kconfig b/drivers/char/lrng/Kconfig
index ba3d84cd0676..66a775a8f912 100644
--- a/drivers/char/lrng/Kconfig
+++ b/drivers/char/lrng/Kconfig
@@ -95,4 +95,16 @@ config LRNG_KCAPI
  provided by the selected kernel crypto API RNG.
 endif # LRNG_DRNG_SWITCH
 
+config LRNG_JENT
+   bool "Enable Jitter RNG as LRNG Seed Source"
+   depends on CRYPTO
+   select CRYPTO_JITTERENTROPY
+   help
+ The Linux RNG may use the Jitter RNG as noise source. Enabling
+ this option enables the use of the Jitter RNG. Its default
+ entropy level is 16 bits of entropy per 256 data bits delivered
+ by the Jitter RNG. This entropy level can be changed at boot
+ time or at runtime with the lrng_base.jitterrng configuration
+ variable.
+
 endif # LRNG
diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 94b2dfb2dfdb..4f5b6f38f0c4 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_SYSCTL)  += lrng_proc.o
 obj-$(CONFIG_LRNG_DRNG_SWITCH) += lrng_switch.o
 obj-$(CONFIG_LRNG_DRBG)+= lrng_drbg.o
 obj-$(CONFIG_LRNG_KCAPI)   += lrng_kcapi.o
+obj-$(CONFIG_LRNG_JENT)+= lrng_jent.o
diff --git a/drivers/char/lrng/lrng_jent.c b/drivers/char/lrng/lrng_jent.c
new file mode 100644
index ..225505271fcb
--- /dev/null
+++ b/drivers/char/lrng/lrng_jent.c
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG Fast Noise Source: Jitter RNG
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller 
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+
+#include "lrng_internal.h"
+
+/*
+ * Estimated entropy of data is a 16th of LRNG_DRNG_SECURITY_STRENGTH_BITS.
+ * Albeit a full entropy assessment is provided for the noise source indicating
+ * that it provides high entropy rates and considering that it deactivates
+ * when it detects insufficient hardware, the chosen under estimation of
+ * entropy is considered to be acceptable to all reviewers.
+ */
+static u32 jitterrng = LRNG_DRNG_SECURITY_STRENGTH_BITS>>4;
+module_param(jitterrng, uint, 0644);
+MODULE_PARM_DESC(jitterrng, "Entropy in bits of 256 data bits from Jitter RNG 
noise source");
+
+/**
+ * lrng_get_jent() - Get Jitter RNG entropy
+ *
+ * @outbuf: buffer to store entropy
+ * @outbuflen: length of buffer
+ *
+ * Return:
+ * * > 0 on success where value provides the added entropy in bits
+ * * 0 if no fast source was available
+ */
+static struct rand_data *lrng_jent_state;
+
+u32 lrng_get_jent(u8 *outbuf, unsigned int outbuflen)
+{
+   int ret;
+   u32 ent_bits = jitterrng;
+   unsigned long flags;
+   static DEFINE_SPINLOCK(lrng_jent_lock);
+   static int lrng_jent_initialized = 0;
+
+   spin_lock_irqsave(_jent_lock, flags);
+
+   if (!ent_bits || (lrng_jent_initialized == -1)) {
+   spin_unlock_irqrestore(_jent_lock, flags);
+   return 0;
+   }
+
+   if (!lrng_jent_initialized) {
+   lrng_jent_state = jent_lrng_entropy_collector();
+   if (!lrng_jent_state) {
+   jitterrng = 0;
+   lrng_jent_initialized = -1;
+   spin_unlock_irqrestore(_jent_lock, flags);
+   pr_info("Jitter RNG unusable on current system\n");
+   return 0;
+   }
+   lrng_jent_initialized = 1;
+   pr_debug("Jitter RNG working on current system\n");
+   }
+   ret = jent_read_entropy(lrng_jent_state, outbuf, outbuflen);
+   spin_unlock_irqrestore(_jent_lock, flags);
+
+   if (ret) {
+   pr_debug("Jitter RNG failed with %d\n", ret);
+   return 0;
+   }
+
+   /* Obtain entropy statement */
+   if (outbuflen != LRNG_DRNG_SECURITY_STRENGTH_BYTES)
+   ent_bits = (ent_bits * outbuflen<<3) /
+  LRNG_DRNG_SECURITY_STRENGTH_BITS;

[PATCH v32 08/12] crypto: provide access to a static Jitter RNG state

2020-08-20 Thread Stephan Müller
To support the LRNG operation which uses the Jitter RNG separately
from the kernel crypto API, at a time where potentially the regular
memory management is not yet initialized, the Jitter RNG needs to
provide a state whose memory is defined at compile time. As only once
instance will ever be needed by the LRNG, define once static memory
block which is solely to be used by the LRNG.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 crypto/jitterentropy-kcapi.c  |  3 +-
 crypto/jitterentropy.c| 31 ++-
 .../crypto/internal}/jitterentropy.h  |  3 ++
 3 files changed, 34 insertions(+), 3 deletions(-)
 rename {crypto => include/crypto/internal}/jitterentropy.h (84%)

diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c
index eb7d1dd506bf..25a192f5984e 100644
--- a/crypto/jitterentropy-kcapi.c
+++ b/crypto/jitterentropy-kcapi.c
@@ -43,8 +43,7 @@
 #include 
 #include 
 #include 
-
-#include "jitterentropy.h"
+#include 
 
 /***
  * Helper function
diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c
index 6e147c43fc18..fa1459f09b01 100644
--- a/crypto/jitterentropy.c
+++ b/crypto/jitterentropy.c
@@ -117,7 +117,7 @@ struct rand_data {
 #define JENT_EHEALTH   9 /* Health test failed during initialization */
 #define JENT_ERCT  10 /* RCT failed during initialization */
 
-#include "jitterentropy.h"
+#include 
 
 /***
  * Adaptive Proportion Test
@@ -854,3 +854,32 @@ int jent_entropy_init(void)
 
return 0;
 }
+
+struct rand_data *jent_lrng_entropy_collector(void)
+{
+   static unsigned char lrng_jent_mem[JENT_MEMORY_SIZE];
+   static struct rand_data lrng_jent_state = {
+   .data   = 0,
+   .old_data   = 0,
+   .prev_time  = 0,
+   .last_delta = 0,
+   .last_delta2= 0,
+   .osr= 1,
+   .mem= lrng_jent_mem,
+   .memlocation= 0,
+   .memblocks  = JENT_MEMORY_BLOCKSIZE,
+   .memblocksize   = JENT_MEMORY_BLOCKS,
+   .memaccessloops = JENT_MEMORY_ACCESSLOOPS,
+   .rct_count  = 0,
+   .apt_observations = 0,
+   .apt_count  = 0,
+   .apt_base   = 0,
+   .apt_base_set   = 0,
+   .health_failure = 0
+   };
+
+   if (jent_entropy_init())
+   return NULL;
+
+   return _jent_state;
+}
diff --git a/crypto/jitterentropy.h b/include/crypto/internal/jitterentropy.h
similarity index 84%
rename from crypto/jitterentropy.h
rename to include/crypto/internal/jitterentropy.h
index c83fff32d130..6e07d86eac82 100644
--- a/crypto/jitterentropy.h
+++ b/include/crypto/internal/jitterentropy.h
@@ -15,3 +15,6 @@ extern int jent_read_entropy(struct rand_data *ec, unsigned 
char *data,
 extern struct rand_data *jent_entropy_collector_alloc(unsigned int osr,
  unsigned int flags);
 extern void jent_entropy_collector_free(struct rand_data *entropy_collector);
+
+/* Access to statically allocated Jitter RNG instance */
+extern struct rand_data *jent_lrng_entropy_collector(void);
-- 
2.26.2






[PATCH v32 05/12] crypto: DRBG - externalize DRBG functions for LRNG

2020-08-20 Thread Stephan Müller
This patch allows several DRBG functions to be called by the LRNG kernel
code paths outside the drbg.c file.

CC: "Eric W. Biederman" 
CC: "Alexander E. Patrakov" 
CC: "Ahmed S. Darwish" 
CC: "Theodore Y. Ts'o" 
CC: Willy Tarreau 
CC: Matthew Garrett 
CC: Vito Caputo 
CC: Andreas Dilger 
CC: Jan Kara 
CC: Ray Strode 
CC: William Jon McCann 
CC: zhangjs 
CC: Andy Lutomirski 
CC: Florian Weimer 
CC: Lennart Poettering 
CC: Nicolai Stange 
Reviewed-by: Roman Drahtmueller 
Tested-by: Roman Drahtmüller 
Tested-by: Marcelo Henrique Cerri 
Tested-by: Neil Horman 
Signed-off-by: Stephan Mueller 
---
 crypto/drbg.c | 16 ++--
 include/crypto/drbg.h |  7 +++
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/crypto/drbg.c b/crypto/drbg.c
index e99fe34cfa00..3644e954785a 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[] = {
+const struct drbg_core drbg_cores[] = {
 #ifdef CONFIG_CRYPTO_DRBG_CTR
{
.flags = DRBG_CTR | DRBG_STRENGTH128,
@@ -190,6 +190,7 @@ static const struct drbg_core drbg_cores[] = {
},
 #endif /* CONFIG_CRYPTO_DRBG_HMAC */
 };
+EXPORT_SYMBOL(drbg_cores);
 
 static int drbg_uninstantiate(struct drbg_state *drbg);
 
@@ -205,7 +206,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:
@@ -218,6 +219,7 @@ static inline unsigned short drbg_sec_strength(drbg_flag_t 
flags)
return 32;
}
 }
+EXPORT_SYMBOL(drbg_sec_strength);
 
 /*
  * FIPS 140-2 continuous self test for the noise source
@@ -1214,7 +1216,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;
@@ -1235,12 +1237,13 @@ static inline void drbg_dealloc_state(struct drbg_state 
*drbg)
drbg->fips_primed = false;
}
 }
+EXPORT_SYMBOL(drbg_dealloc_state);
 
 /*
  * 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;
@@ -1321,6 +1324,7 @@ static inline int drbg_alloc_state(struct drbg_state 
*drbg)
drbg_dealloc_state(drbg);
return ret;
 }
+EXPORT_SYMBOL(drbg_alloc_state);
 
 /*
  * DRBG interface functions
@@ -1890,8 +1894,7 @@ static int drbg_kcapi_sym_ctr(struct drbg_state *drbg,
  *
  * 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;
@@ -1918,6 +1921,7 @@ static inline void drbg_convert_tfm_core(const char 
*cra_driver_name,
}
}
 }
+EXPORT_SYMBOL(drbg_convert_tfm_core);
 
 static int drbg_kcapi_init(struct crypto_tfm *tfm)
 {
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index c4165126937e..71d53e028e6d 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -278,4 +278,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 const struct drbg_core drbg_cores[];
+extern unsigned short drbg_sec_strength(drbg_flag_t flags);
+
 #endif /* _DRBG_H */
-- 
2.26.2






  1   2   3   4   >