Skip to contentSkip to conversation

/dev/random - a new approach with full SP800-90B compliance

PATCH Superseded Stephan Müller 2 participants 72 messages Aug 20, 2020 – Sep 20, 2020

Subsystems (3)

v32 of 43 Superseded Latest is v43 →

lore
Share & tools
lore
#0 lore raw

v32 cover /dev/random - a new approach with full SP800-90B compliance

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 SP800-90A/SP800-90B compliant binary code (CONFIG_LRNG, CONFIG_LRNG_DRNG_SWITCH, CONFIG_LRNG_DRBG, CONFIG_LRNG_HEALTH_TESTS) uses some 61 kBytes. In addition, the LRNG is about 50% faster in the performance critical interrupt handler code path compared to the existing /dev/random implementation.

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 MIPS embedded device

[1] https://www.chronox.de/lrng.html - If the patch is accepted, I would be volunteering to convert the documentation into RST format and contribute it to the Linux kernel documentation directory.

[2] https://www.chronox.de/lrng/doc/lrng.pdf

Changes (compared to the previous patch set):

* Use of SHA-256 for hashing the entropy pool per default to ensure the LRNG can be claimed to manage 256 bits of entropy pursuant to SP800-90B (note, the required CONFIG_CRYPTO_LIB_SHA256 current depends on CONFIG_CRYPTO due to artificial Kconfig settings - technically CONFIG_CRYPTO_LIB_SHA256 could be compiled without CONFIG_CRYPTO)

* When using CTR DRBG, use SHA-256 for hashing entropy pool instead of CMAC AES to fully comply with SP800-90B to the letter of the law

* Correctly use CONFIG_BASE_SMALL in C code

* speed up add_interrupt_randomness if high-resolution time stamp is not available

* integrate patch a2541dcb51127dc31934ab93bc99ae7df458e41b

* integrate patch f227e3ec3b5cad859ad15666874405e8c1bbc1d4 and ensure that its associated design concerns documented in [2] section 2.2.5 are addressed

* add test interfaces for Jiffies, interrupt numbers, interrupt flags, and return instruction pointer supporting integration of patch f227e3ec3b5cad859ad15666874405e8c1bbc1d4 and systems with a missing high-resolution timer

As a side node: With the switchable DRNG support offered in this patch set, the following areas could be removed. As the existing /dev/random has no support for switchable DRNGs, however, this is not yet feasible though.

* remove lrng_ready_list and all code around it in lrng_interfaces.c

* remove the kernel crypto API RNG API to avoid having two random number providing APIs - this would imply that all RNGs developed for this API would be converted to the LRNG interface

CC "Eric W. Biederman" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>

Stephan Mueller (12):
Linux Random Number Generator
LRNG - allocate one DRNG instance per NUMA node LRNG - sysctls and /proc interface
LRNG - add switchable DRNG support
crypto: DRBG - externalize DRBG functions for LRNG LRNG - add SP800-90A DRBG extension
LRNG - add kernel crypto API PRNG extension
crypto: provide access to a static Jitter RNG state LRNG - add Jitter RNG fast noise source LRNG - add SP800-90B compliant health tests LRNG - add interface for gathering of raw entropy LRNG - add power-on and runtime self-tests

 MAINTAINERS                                   |   7 +
 crypto/drbg.c                                 |  16 +-
 crypto/jitterentropy-kcapi.c                  |   3 +-
 crypto/jitterentropy.c                        |  31 +-
 drivers/char/Kconfig                          |   2 +
 drivers/char/Makefile                         |   9 +-
 drivers/char/lrng/Kconfig                     | 315 +++++++++
 drivers/char/lrng/Makefile                    |  19 +
 drivers/char/lrng/lrng_archrandom.c           |  93 +++
 drivers/char/lrng/lrng_aux.c                  | 136 ++++
 drivers/char/lrng/lrng_chacha20.c             | 320 +++++++++
 drivers/char/lrng/lrng_chacha20.h             |  29 +
 drivers/char/lrng/lrng_drbg.c                 | 259 +++++++
 drivers/char/lrng/lrng_drng.c                 | 409 +++++++++++
 drivers/char/lrng/lrng_health.c               | 407 +++++++++++
 drivers/char/lrng/lrng_interfaces.c           | 647 ++++++++++++++++++
 drivers/char/lrng/lrng_internal.h             | 342 +++++++++
 drivers/char/lrng/lrng_jent.c                 |  88 +++
 drivers/char/lrng/lrng_kcapi.c                | 321 +++++++++
 drivers/char/lrng/lrng_lfsr.h                 | 152 ++++
 drivers/char/lrng/lrng_numa.c                 | 101 +++
 drivers/char/lrng/lrng_pool.c                 | 589 ++++++++++++++++
 drivers/char/lrng/lrng_proc.c                 | 163 +++++
 drivers/char/lrng/lrng_selftest.c             | 504 ++++++++++++++
 drivers/char/lrng/lrng_sw_noise.c             | 155 +++++
 drivers/char/lrng/lrng_sw_noise.h             |  57 ++
 drivers/char/lrng/lrng_switch.c               | 189 +++++
 drivers/char/lrng/lrng_testing.c              | 575 ++++++++++++++++
 include/crypto/drbg.h                         |   7 +
 .../crypto/internal}/jitterentropy.h          |   3 +
 include/linux/lrng.h                          |  63 ++
 31 files changed, 6001 insertions(+), 10 deletions(-)
 create mode 100644 drivers/char/lrng/Kconfig
 create mode 100644 drivers/char/lrng/Makefile
 create mode 100644 drivers/char/lrng/lrng_archrandom.c
 create mode 100644 drivers/char/lrng/lrng_aux.c
 create mode 100644 drivers/char/lrng/lrng_chacha20.c
 create mode 100644 drivers/char/lrng/lrng_chacha20.h
 create mode 100644 drivers/char/lrng/lrng_drbg.c
 create mode 100644 drivers/char/lrng/lrng_drng.c
 create mode 100644 drivers/char/lrng/lrng_health.c
 create mode 100644 drivers/char/lrng/lrng_interfaces.c
 create mode 100644 drivers/char/lrng/lrng_internal.h
 create mode 100644 drivers/char/lrng/lrng_jent.c
 create mode 100644 drivers/char/lrng/lrng_kcapi.c
 create mode 100644 drivers/char/lrng/lrng_lfsr.h
 create mode 100644 drivers/char/lrng/lrng_numa.c
 create mode 100644 drivers/char/lrng/lrng_pool.c
 create mode 100644 drivers/char/lrng/lrng_proc.c
 create mode 100644 drivers/char/lrng/lrng_selftest.c
 create mode 100644 drivers/char/lrng/lrng_sw_noise.c
 create mode 100644 drivers/char/lrng/lrng_sw_noise.h
 create mode 100644 drivers/char/lrng/lrng_switch.c
 create mode 100644 drivers/char/lrng/lrng_testing.c
 rename {crypto => include/crypto/internal}/jitterentropy.h (84%)
 create mode 100644 include/linux/lrng.h
Signature · 1 line
2.26.2
#1 lore raw

PATCH v32 1/12 Linux Random Number Generator

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 except that it is capable of processing an entire word and that a different polynomial is used. The reason for the different polynomial is performance in a performance sensitive code section, the interrupt handler. The chosen polynomials have 4 taps. Also, this LFSR-approach is used in the OpenBSD /dev/random equivalent.

2. Concatenation: The temporary seed buffer used to seed the DRNG is a concatenation of parts of the entropy pool data, and the CPU noise source output.

The DRNG always tries to seed itself with 256 bits of entropy, except during boot. In any case, if the noise sources cannot deliver that amount, the available entropy is used and the DRNG keeps track on how much entropy it was seeded with. The entropy implied by the LRNG available in the entropy pool may be too conservative. To ensure that during boot time all available entropy from the entropy pool is transferred to the DRNG, the hash_df function always generates 256 data bits during boot to seed the DRNG. During boot, the DRNG is seeded as follows:

1. The DRNG is reseeded from the entropy pool and potentially the fast noise sources if the entropy pool has collected at least 32 bits of entropy from the interrupt noise source. The goal of this step is to ensure that the DRNG receives some initial entropy as early as possible. In addition it receives the entropy available from the fast noise sources.

2. The DRNG is reseeded from the entropy pool and potentially the fast noise sources if all noise sources collectively can provide at least 128 bits of entropy.

3. The DRNG is reseeded from the entropy pool and potentially the fast noise sources if all noise sources collectivel can provide at least 256 bits.

At the time of the reseeding steps, the DRNG requests as much entropy as is available in order to skip certain steps and reach the seeding level of 256 bits. This may imply that one or more of the aforementioned steps are skipped.

In all listed steps, the DRNG is (re)seeded with a number of random bytes from the entropy pool that is at most the amount of entropy present in the entropy pool. This means that when the entropy pool contains 128 or 256 bits of entropy, the DRNG is seeded with that amount of entropy as well.

Before the DRNG is seeded with 256 bits of entropy in step 3, requests of random data from /dev/random are not processed.

The hash_df operation providing random data from the entropy pool will always require that all entropy sources collectively can deliver at least 129 entropy bits as configured with (128 bits of entropy for seeding plus one bit of entropy that is lost with the post processing as defined in SP800-90B).

The DRNG operates as deterministic random number generator with the following properties:

* The maximum number of random bytes that can be generated with one DRNG generate operation is limited to 4096 bytes. When longer random numbers are requested, multiple DRNG generate operations are performed. The ChaCha20 DRNG as well as the SP800-90A DRBGs implement an update of their state after completing a generate request for backtracking resistance.

* The secondary DRNG is reseeded with whatever entropy is available – in the worst case where no additional entropy can be provided by the noise sources, the DRNG is not re-seeded and continues its operation to try to reseed again after again the expiry of one of these thresholds:

- If the last reseeding of the secondary DRNG is more than 600 seconds ago, or

- 2^20 DRNG generate operations are performed, whatever comes first, or

- the secondary DRNG is forced to reseed before the next generation of random numbers if data has been injected into the LRNG by writing data into /dev/random or /dev/urandom.

The chosen values prevent high-volume requests from user space to cause frequent reseeding operations which drag down the performance of the DRNG.

With the automatic reseeding after 600 seconds, the LRNG is triggered to reseed itself before the first request after a suspend that put the hardware to sleep for longer than 600 seconds.

The LRNG uses the following runtime memory using the currently smallest configuration:

* 576 bytes (512 bytes for the entropy pool and 64 for the entropy pool meta data) for the entropy pool management

* 64 bytes per CPU for the time stamp array

To support smaller devices including IoT environments, this patch allows reducing the runtime memory footprint of the LRNG at compile time by selecting smaller entropy pool sizes.

The entropy pool has support for sizes of 256, 128 and 64 bytes supported by primitive and irreducible polynomials.

The time stamp array is reduced to one atomic_t variable per CPU, i.e. 4 bytes when CONFIG_BASE_SMALL is selected during kernel configuration. This implies that after the receipt of 4 interrupts on one CPU, the data is injected into the LFSR. Depending on the behavior of the CPU caches, this may imply that the average interrupt handler execution time increases a bit, since instead of injecting 8 atomic_t values at one given time into the LFSR, only one is processed which may incur cache misses.

When selecting the compilation of a kernel for a small environment, prevent the allocation of a buffer up to 4096 bytes to serve user space requests. In this case, the stack variable of 64 bytes is used to serve all user space requests.

The LRNG has the following properties:

* internal noise source: interrupts timing with fast boot time seeding

* high performance of interrupt handling code: The LRNG impact on the interrupt handling has been reduced to a minimum. On one example system, the LRNG interrupt handling code executes within an average of 65 cycles whereas the existing /dev/random on the same device takes about 97 cycles when measuring the execution time of add_interrupt_randomness().

* lockless LFSR to collect raw entropy supporing concurrency-free use of massive parallel systems

* use of standalone ChaCha20 based RNG with the option to use a different DRNG selectable at compile time

* "atomic" seeding of secondary DRBG to ensure full entropy transport

* instantiate one DRNG per NUMA node

* support for runtime switchable output DRNGs

* use of only well-defined entropy-preserving operations to collect, compress and forward entropy: concatenation, LFSR, SP800-90A hash_df function

* compile-time selectable entropy pool size: the choice also uses the applicable LFSR polynomial to maintain the entropy pool size

* support of small systems by allowing the reduction of the runtime memory needs

Further details including the rationale for the design choices and properties of the LRNG together with testing is provided at [1]. In addition, the documentation explains the conducted regression tests to verify that the LRNG is API and ABI compatible with the existing /dev/random implementation.

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

CC: "Eric W. Biederman" <[email protected]>
CC: "Alexander E. Patrakov" <[email protected]>
CC: "Ahmed S. Darwish" <[email protected]>
CC: "Theodore Y. Ts'o" <[email protected]>
CC: Willy Tarreau <[email protected]>
CC: Matthew Garrett <[email protected]>
CC: Vito Caputo <[email protected]>
CC: Andreas Dilger <[email protected]>
CC: Jan Kara <[email protected]>
CC: Ray Strode <[email protected]>
CC: William Jon McCann <[email protected]>
CC: zhangjs <[email protected]>
CC: Andy Lutomirski <[email protected]>
CC: Florian Weimer <[email protected]>
CC: Lennart Poettering <[email protected]>
CC: Nicolai Stange <[email protected]>
Mathematical aspects Reviewed-by: "Peter, Matthias" <[email protected]>

---
 MAINTAINERS                         |   7 +
 drivers/char/Kconfig                |   2 +
 drivers/char/Makefile               |   9 +-
 drivers/char/lrng/Kconfig           |  68 +++
 drivers/char/lrng/Makefile          |   9 +
 drivers/char/lrng/lrng_archrandom.c |  93 ++++
 drivers/char/lrng/lrng_aux.c        | 136 ++++++
 drivers/char/lrng/lrng_chacha20.c   | 320 ++++++++++++++
 drivers/char/lrng/lrng_chacha20.h   |  29 ++
 drivers/char/lrng/lrng_drng.c       | 409 ++++++++++++++++++
 drivers/char/lrng/lrng_interfaces.c | 648 ++++++++++++++++++++++++++++
 drivers/char/lrng/lrng_internal.h   | 333 ++++++++++++++
 drivers/char/lrng/lrng_lfsr.h       | 152 +++++++
 drivers/char/lrng/lrng_pool.c       | 589 +++++++++++++++++++++++++
 drivers/char/lrng/lrng_sw_noise.c   | 155 +++++++
 drivers/char/lrng/lrng_sw_noise.h   |  57 +++
 include/linux/lrng.h                |  63 +++
 17 files changed, 3078 insertions(+), 1 deletion(-)
 create mode 100644 drivers/char/lrng/Kconfig
 create mode 100644 drivers/char/lrng/Makefile
 create mode 100644 drivers/char/lrng/lrng_archrandom.c
 create mode 100644 drivers/char/lrng/lrng_aux.c
 create mode 100644 drivers/char/lrng/lrng_chacha20.c
 create mode 100644 drivers/char/lrng/lrng_chacha20.h
 create mode 100644 drivers/char/lrng/lrng_drng.c
 create mode 100644 drivers/char/lrng/lrng_interfaces.c
 create mode 100644 drivers/char/lrng/lrng_internal.h
 create mode 100644 drivers/char/lrng/lrng_lfsr.h
 create mode 100644 drivers/char/lrng/lrng_pool.c
 create mode 100644 drivers/char/lrng/lrng_sw_noise.c
 create mode 100644 drivers/char/lrng/lrng_sw_noise.h
 create mode 100644 include/linux/lrng.h
MAINTAINERS +7 -0
index deaafb617361..74f6fd1ba1ec 100644
@@ -10084,6 +10084,13 @@ F:	Documentation/litmus-tests/
 F:	Documentation/memory-barriers.txt
 F:	tools/memory-model/
 
+LINUX RANDOM NUMBER GENERATOR (LRNG) DRIVER
+M:	Stephan Mueller <[email protected]>
+S:	Maintained
+W:	https://www.chronox.de/lrng.html
+F:	drivers/char/lrng/*
+F:	include/linux/lrng.h
+
 LIS3LV02D ACCELEROMETER DRIVER
 M:	Eric Piel <[email protected]>
 S:	Maintained
drivers/char/Kconfig +2 -0
index b1bd336761b1..8a5b8a2db2c7 100644
@@ -470,6 +470,8 @@ config ADI
 	  and SSM (Silicon Secured Memory).  Intended consumers of this
 	  driver include crash and makedumpfile.
 
+source "drivers/char/lrng/Kconfig"
+
 endmenu
 
 config RANDOM_TRUST_CPU
drivers/char/Makefile +8 -1
index ffce287ef415..2110d3e28cf2 100644
@@ -3,7 +3,14 @@
 # Makefile for the kernel character device drivers.
 #
 
-obj-y				+= mem.o random.o
+obj-y				+= mem.o
+
+ifeq ($(CONFIG_LRNG),y)
+  obj-y				+= lrng/
+else
+  obj-y				+= random.o
+endif
+
 obj-$(CONFIG_TTY_PRINTK)	+= ttyprintk.o
 obj-y				+= misc.o
 obj-$(CONFIG_ATARI_DSP56K)	+= dsp56k.o
drivers/char/lrng/Kconfig new file +68 -0

68 lines not on this page · raw message

drivers/char/lrng/Makefile new file +9 -0
new file mode 100644
index 000000000000..1d2a0211973d
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the Linux Random Number Generator.
+#
+
+obj-y				+= lrng_pool.o lrng_aux.o \
+				   lrng_sw_noise.o lrng_archrandom.o \
+				   lrng_drng.o lrng_chacha20.o \
+				   lrng_interfaces.o \
drivers/char/lrng/lrng_archrandom.c new file +93 -0

93 lines not on this page · raw message

drivers/char/lrng/lrng_aux.c new file +136 -0

136 lines not on this page · raw message

drivers/char/lrng/lrng_chacha20.c new file +320 -0

320 lines not on this page · raw message

drivers/char/lrng/lrng_chacha20.h new file +29 -0
new file mode 100644
index 000000000000..1533b2490964
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
+/*
+ * LRNG ChaCha20 definitions
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller <[email protected]>
+ */
+
+#include <crypto/chacha.h>
+
+/* State according to RFC 7539 section 2.3 */
+struct chacha20_block {
+	u32 constants[4];
+	union {
+#define CHACHA_KEY_SIZE_WORDS (CHACHA_KEY_SIZE / sizeof(u32))
+		u32 u[CHACHA_KEY_SIZE_WORDS];
+		u8  b[CHACHA_KEY_SIZE];
+	} key __latent_entropy;
+	u32 counter;
+	u32 nonce[3] __latent_entropy;
+};
+
+static inline void lrng_cc20_init_rfc7539(struct chacha20_block *chacha20)
+{
+	/* String "expand 32-byte k" */
+	chacha20->constants[0] = 0x61707865;
+	chacha20->constants[1] = 0x3320646e;
+	chacha20->constants[2] = 0x79622d32;
+	chacha20->constants[3] = 0x6b206574;
+}
drivers/char/lrng/lrng_drng.c new file +409 -0

409 lines not on this page · raw message

drivers/char/lrng/lrng_interfaces.c new file +648 -0

648 lines not on this page · raw message

drivers/char/lrng/lrng_internal.h new file +333 -0

333 lines not on this page · raw message

drivers/char/lrng/lrng_lfsr.h new file +152 -0

152 lines not on this page · raw message

drivers/char/lrng/lrng_pool.c new file +589 -0

589 lines not on this page · raw message

drivers/char/lrng/lrng_sw_noise.c new file +155 -0

155 lines not on this page · raw message

drivers/char/lrng/lrng_sw_noise.h new file +57 -0

23 lines not on this page · raw message

include/linux/lrng.h new file +63 -0

63 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.26.2

Part of the diff is not shown here. View the raw message.

#2 lore raw

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

Thank you for the patch! Perhaps something to improve:

Hi "Stephan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on char-misc/char-misc-testing]
[also build test WARNING on cryptodev/master crypto/master v5.9-rc1 next-20200820] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200820-165712
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git d162219c655c8cf8003128a13840d6c1e183fb80
config: nios2-allyesconfig (attached as .config)
compiler: nios2-linux-gcc (GCC) 9.3.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=nios2

If you fix the issue, kindly add following tag as appropriate

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,
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~~
>> 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)
         |      ^~~~~~~~~~~~~~~~~~~~~
   drivers/char/lrng/lrng_interfaces.c:37:18: warning: array 'random_table' assumed to have one element
      37 | struct ctl_table random_table[];
         |                  ^~~~~~~~~~~~

# https://github.com/0day-ci/linux/commit/866aae82856f1fba6af5c4b19a3905800cab4563
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200820-165712 git checkout 866aae82856f1fba6af5c4b19a3905800cab4563
vim +/add_hwgenerator_randomness +120 drivers/char/lrng/lrng_interfaces.c

107
108 /**
109 * add_hwgenerator_randomness() - Interface for in-kernel drivers of true
110 * hardware RNGs.
111 *
112 * Those devices may produce endless random bits and will be throttled
113 * when our pool is full.
114 *
115 * @buffer: buffer holding the entropic data from HW noise sources to be used to
116 * insert into entropy pool.
117 * @count: length of buffer
118 * @entropy_bits: amount of entropy in buffer (value is in bits)
119 */

 > 120	void add_hwgenerator_randomness(const char *buffer, size_t count,
   121					size_t entropy_bits)
   122	{
   123		/*
   124		 * Suspend writing if we are fully loaded with entropy.
   125		 * We'll be woken up again once below lrng_write_wakeup_thresh,
   126		 * or when the calling thread is about to terminate.
   127		 */
   128		wait_event_interruptible(lrng_write_wait,
   129					lrng_need_entropy() ||
   130					lrng_state_exseed_allow(lrng_noise_source_hw) ||
   131					kthread_should_stop());
   132		lrng_state_exseed_set(lrng_noise_source_hw, false);
   133		lrng_pool_lfsr_nonaligned(buffer, count);
   134		lrng_pool_add_entropy(entropy_bits);
   135	}
   136	EXPORT_SYMBOL_GPL(add_hwgenerator_randomness);
   137	
   138	/**
   139	 * add_bootloader_randomness() - Handle random seed passed by bootloader.
   140	 *
   141	 * If the seed is trustworthy, it would be regarded as hardware RNGs. Otherwise
   142	 * it would be regarded as device data.
   143	 * The decision is controlled by CONFIG_RANDOM_TRUST_BOOTLOADER.
   144	 *
   145	 * @buf: buffer holding the entropic data from HW noise sources to be used to
   146	 *	 insert into entropy pool.
   147	 * @size: length of buffer
   148	 */
   149	void add_bootloader_randomness(const void *buf, unsigned int size)
   150	{
   151		if (IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER))
   152			add_hwgenerator_randomness(buf, size, size * 8);
   153		else
   154			add_device_randomness(buf, size);
   155	}
   156	EXPORT_SYMBOL_GPL(add_bootloader_randomness);
   157	
   158	/*
   159	 * Callback for HID layer -- use the HID event values to stir the entropy pool
   160	 */
   161	void add_input_randomness(unsigned int type, unsigned int code,
   162				  unsigned int value)
   163	{
   164		static unsigned char last_value;
   165	
   166		/* ignore autorepeat and the like */
   167		if (value == last_value)
   168			return;
   169	
   170		last_value = value;
   171	
   172		lrng_pool_lfsr_u32((type << 4) ^ code ^ (code >> 4) ^ value);
   173	}
   174	EXPORT_SYMBOL_GPL(add_input_randomness);
   175	
   176	/**
   177	 * add_device_randomness() - Add device- or boot-specific data to the entropy
   178	 * pool to help initialize it.
   179	 *
   180	 * None of this adds any entropy; it is meant to avoid the problem of
   181	 * the entropy pool having similar initial state across largely
   182	 * identical devices.
   183	 *
   184	 * @buf: buffer holding the entropic data from HW noise sources to be used to
   185	 *	 insert into entropy pool.
   186	 * @size: length of buffer
   187	 */
   188	void add_device_randomness(const void *buf, unsigned int size)
   189	{
   190		lrng_pool_lfsr_nonaligned((u8 *)buf, size);
   191		lrng_pool_lfsr_u32(random_get_entropy());
   192		lrng_pool_lfsr_u32(jiffies);
   193	}
   194	EXPORT_SYMBOL(add_device_randomness);
   195	
   196	#ifdef CONFIG_BLOCK
   197	void rand_initialize_disk(struct gendisk *disk) { }
   198	void add_disk_randomness(struct gendisk *disk) { }
   199	EXPORT_SYMBOL(add_disk_randomness);
   200	#endif
   201	
   202	/**
   203	 * del_random_ready_callback() - Delete a previously registered readiness
   204	 * callback function.
   205	 *
   206	 * @rdy: callback definition that was registered initially
   207	 */
   208	void del_random_ready_callback(struct random_ready_callback *rdy)
   209	{
   210		unsigned long flags;
   211		struct module *owner = NULL;
   212	
   213		spin_lock_irqsave(&lrng_ready_list_lock, flags);
   214		if (!list_empty(&rdy->list)) {
   215			list_del_init(&rdy->list);
   216			owner = rdy->owner;
   217		}
   218		spin_unlock_irqrestore(&lrng_ready_list_lock, flags);
   219	
   220		module_put(owner);
   221	}
   222	EXPORT_SYMBOL(del_random_ready_callback);
   223	
   224	/**
   225	 * add_random_ready_callback() - Add a callback function that will be invoked
   226	 * when the DRNG is mimimally seeded.
   227	 *
   228	 * @rdy: callback definition to be invoked when the LRNG is seeded
   229	 *
   230	 * Return:
   231	 * * 0 if callback is successfully added
   232	 * * -EALREADY if pool is already initialised (callback not called)
   233	 * * -ENOENT if module for callback is not alive
   234	 */
   235	int add_random_ready_callback(struct random_ready_callback *rdy)
   236	{
   237		struct module *owner;
   238		unsigned long flags;
   239		int err = -EALREADY;
   240	
   241		if (likely(lrng_state_min_seeded()))
   242			return err;
   243	
   244		owner = rdy->owner;
   245		if (!try_module_get(owner))
   246			return -ENOENT;
   247	
   248		spin_lock_irqsave(&lrng_ready_list_lock, flags);
   249		if (lrng_state_min_seeded())
   250			goto out;
   251	
   252		owner = NULL;
   253	
   254		list_add(&rdy->list, &lrng_ready_list);
   255		err = 0;
   256	
   257	out:
   258		spin_unlock_irqrestore(&lrng_ready_list_lock, flags);
   259	
   260		module_put(owner);
   261	
   262		return err;
   263	}
   264	EXPORT_SYMBOL(add_random_ready_callback);
   265	
   266	/*********************** LRNG kernel output interfaces ************************/
   267	
   268	/**
   269	 * get_random_bytes() - Provider of cryptographic strong random numbers for
   270	 * kernel-internal usage.
   271	 *
   272	 * This function is appropriate for all in-kernel use cases. However,
   273	 * it will always use the ChaCha20 DRNG.
   274	 *
   275	 * @buf: buffer to store the random bytes
   276	 * @nbytes: size of the buffer
   277	 */
   278	void get_random_bytes(void *buf, int nbytes)
   279	{
   280		lrng_drng_get_atomic((u8 *)buf, (u32)nbytes);
   281		lrng_debug_report_seedlevel("get_random_bytes");
   282	}
   283	EXPORT_SYMBOL(get_random_bytes);
   284	
   285	/**
   286	 * get_random_bytes_full() - Provider of cryptographic strong random numbers
   287	 * for kernel-internal usage.
   288	 *
   289	 * This function is appropriate only for non-atomic use cases as this
   290	 * function may sleep. Though, it provides access to the full functionality
   291	 * of LRNG including the switchable DRNG support, that may support other
   292	 * DRNGs such as the SP800-90A DRBG.
   293	 *
   294	 * @buf: buffer to store the random bytes
   295	 * @nbytes: size of the buffer
   296	 */
 > 297	void get_random_bytes_full(void *buf, int nbytes)

298 {
299 lrng_drng_get_sleep((u8 *)buf, (u32)nbytes);
300 lrng_debug_report_seedlevel("get_random_bytes_full");
301 }
302 EXPORT_SYMBOL(get_random_bytes_full);
303

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#3 lore raw

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

Am Donnerstag, 20. August 2020, 13:46:49 CEST schrieb kernel test robot:

Hi,

Quoted 5 lines

All warnings (new ones prefixed by >>):

Quoted 2 lines
Quoted 2 lines

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 <linux/hw_random.h>

Quoted 7 lines
Quoted 3 lines
Quoted 3 lines

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

#4 lore raw

PATCH v32 2/12 LRNG - allocate one DRNG instance per NUMA node

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Makefile +2 -0
index 1d2a0211973d..0a32f22c2c1a 100644
@@ -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
drivers/char/lrng/lrng_internal.h +5 -0
index f6a5f0d960c1..495e00ae5ee1 100644
@@ -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 **************************/
 
drivers/char/lrng/lrng_numa.c new file +101 -0

101 lines not on this page · raw message

Signature · 1 line
2.26.2
#5 lore raw

PATCH v32 3/12 LRNG - sysctls and /proc interface

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Makefile +1 -0
index 0a32f22c2c1a..e69c176f0161 100644
@@ -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
drivers/char/lrng/lrng_interfaces.c +0 -1
index 7fc04e54d834..184108b6e1cb 100644
@@ -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? */
drivers/char/lrng/lrng_internal.h +4 -0
index 495e00ae5ee1..a52c4cf367e2 100644
@@ -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 *******************************/
 
drivers/char/lrng/lrng_proc.c new file +163 -0

163 lines not on this page · raw message

Signature · 1 line
2.26.2
#6 lore raw

PATCH v32 4/12 LRNG - add switchable DRNG support

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +7 -0
index 059b21d9728c..d3138458fd8b 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index e69c176f0161..31cfe87c999e 100644
@@ -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
drivers/char/lrng/lrng_switch.c new file +189 -0

189 lines not on this page · raw message

Signature · 1 line
2.26.2
#7 lore raw

PATCH v32 5/12 crypto: DRBG - externalize DRBG functions for LRNG

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 crypto/drbg.c         | 16 ++++++++++------
 include/crypto/drbg.h |  7 +++++++
 2 files changed, 17 insertions(+), 6 deletions(-)
crypto/drbg.c +10 -6
index e99fe34cfa00..3644e954785a 100644
@@ -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)
 {
include/crypto/drbg.h +7 -0
index c4165126937e..71d53e028e6d 100644
@@ -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 */
Signature · 1 line
2.26.2
#8 lore raw

PATCH v32 6/12 LRNG - add SP800-90A DRBG extension

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +12 -0
index d3138458fd8b..4ad26fdfbe7e 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index 31cfe87c999e..0d320fcb7b9e 100644
@@ -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
drivers/char/lrng/lrng_drbg.c new file +259 -0

259 lines not on this page · raw message

Signature · 1 line
2.26.2
#9 lore raw

Re: [PATCH v32 06/12] LRNG - add SP800-90A DRBG extension

Thank you for the patch! Perhaps something to improve:

Hi "Stephan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on char-misc/char-misc-testing]
[also build test WARNING on cryptodev/master crypto/master v5.9-rc1 next-20200820] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200820-165712
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git d162219c655c8cf8003128a13840d6c1e183fb80
config: nios2-allyesconfig (attached as .config)
compiler: nios2-linux-gcc (GCC) 9.3.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=nios2

If you fix the issue, kindly add following tag as appropriate

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 = {
         | ^~~~~

# https://github.com/0day-ci/linux/commit/9f9f02aa6db0f17774ad2e8646faf738097260e8
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200820-165712 git checkout 9f9f02aa6db0f17774ad2e8646faf738097260e8
vim +/static +226 drivers/char/lrng/lrng_drbg.c

225

 > 226	const static struct lrng_crypto_cb lrng_drbg_crypto_cb = {

227 .lrng_drng_name = lrng_drbg_name,
228 .lrng_hash_name = lrng_hash_name,
229 .lrng_drng_alloc = lrng_drbg_drng_alloc,
230 .lrng_drng_dealloc = lrng_drbg_drng_dealloc,
231 .lrng_drng_seed_helper = lrng_drbg_drng_seed_helper,
232 .lrng_drng_generate_helper = lrng_drbg_drng_generate_helper,
233 .lrng_hash_alloc = lrng_drbg_hash_alloc,
234 .lrng_hash_dealloc = lrng_drbg_hash_dealloc,
235 .lrng_hash_digestsize = lrng_drbg_hash_digestsize,
236 .lrng_hash_buffer = lrng_drbg_hash_buffer,
237 };
238

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#10 lore raw

Re: [PATCH v32 06/12] LRNG - add SP800-90A DRBG extension

Am Donnerstag, 20. August 2020, 14:07:40 CEST schrieb kernel test robot:

Hi,

Quoted 7 lines

All warnings (new ones prefixed by >>):

Quoted 2 lines
Quoted 2 lines

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

#11 lore raw

PATCH v32 7/12 LRNG - add kernel crypto API PRNG extension

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +11 -0
index 4ad26fdfbe7e..ba3d84cd0676 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index 0d320fcb7b9e..94b2dfb2dfdb 100644
@@ -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
drivers/char/lrng/lrng_kcapi.c new file +321 -0

321 lines not on this page · raw message

Signature · 1 line
2.26.2
#12 lore raw

Re: [PATCH v32 07/12] LRNG - add kernel crypto API PRNG extension

Thank you for the patch! Perhaps something to improve:

Hi "Stephan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on char-misc/char-misc-testing]
[also build test WARNING on cryptodev/master crypto/master v5.9-rc1 next-20200820] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200820-165712
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git d162219c655c8cf8003128a13840d6c1e183fb80
config: nios2-allyesconfig (attached as .config)
compiler: nios2-linux-gcc (GCC) 9.3.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=nios2

If you fix the issue, kindly add following tag as appropriate

All warnings (new ones prefixed by >>):

>> drivers/char/lrng/lrng_kcapi.c:295:1: warning: 'static' is not at beginning of declaration [-Wold-style-declaration]
     295 | const static struct lrng_crypto_cb lrng_kcapi_crypto_cb = {
         | ^~~~~

# https://github.com/0day-ci/linux/commit/808fe83c881534a108058461be3f9a0706d0c423
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200820-165712 git checkout 808fe83c881534a108058461be3f9a0706d0c423
vim +/static +295 drivers/char/lrng/lrng_kcapi.c

294

 > 295	const static struct lrng_crypto_cb lrng_kcapi_crypto_cb = {

296 .lrng_drng_name = lrng_kcapi_drng_name,
297 .lrng_hash_name = lrng_kcapi_pool_hash,
298 .lrng_drng_alloc = lrng_kcapi_drng_alloc,
299 .lrng_drng_dealloc = lrng_kcapi_drng_dealloc,
300 .lrng_drng_seed_helper = lrng_kcapi_drng_seed_helper,
301 .lrng_drng_generate_helper = lrng_kcapi_drng_generate_helper,
302 .lrng_hash_alloc = lrng_kcapi_hash_alloc,
303 .lrng_hash_dealloc = lrng_kcapi_hash_dealloc,
304 .lrng_hash_digestsize = lrng_kcapi_hash_digestsize,
305 .lrng_hash_buffer = lrng_kcapi_hash_buffer,
306 };
307

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#13 lore raw

PATCH v32 8/12 crypto: provide access to a static Jitter RNG state

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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%)
crypto/jitterentropy-kcapi.c +1 -2
index eb7d1dd506bf..25a192f5984e 100644
@@ -43,8 +43,7 @@
 #include <linux/time.h>
 #include <linux/crypto.h>
 #include <crypto/internal/rng.h>
-
-#include "jitterentropy.h"
+#include <crypto/internal/jitterentropy.h>
 
 /***************************************************************************
  * Helper function
crypto/jitterentropy.c +30 -1
index 6e147c43fc18..fa1459f09b01 100644
@@ -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 <crypto/internal/jitterentropy.h>
 
 /***************************************************************************
  * 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 &lrng_jent_state;
+}
include/crypto/internal/jitterentropy.h renamed from crypto/jitterentropy.h +3 -0
similarity index 84%
rename from crypto/jitterentropy.h
rename to include/crypto/internal/jitterentropy.h
index c83fff32d130..6e07d86eac82 100644
@@ -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);
Signature · 1 line
2.26.2
#14 lore raw

PATCH v32 9/12 LRNG - add Jitter RNG fast noise source

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +12 -0
index ba3d84cd0676..66a775a8f912 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index 94b2dfb2dfdb..4f5b6f38f0c4 100644
@@ -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
drivers/char/lrng/lrng_jent.c new file +88 -0

88 lines not on this page · raw message

Signature · 1 line
2.26.2
#15 lore raw

PATCH v32 10/12 LRNG - add SP800-90B compliant health tests

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 drivers/char/lrng/Kconfig       |  56 +++++
 drivers/char/lrng/Makefile      |   1 +
 drivers/char/lrng/lrng_health.c | 407 ++++++++++++++++++++++++++++++++
 3 files changed, 464 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_health.c
drivers/char/lrng/Kconfig +56 -0
index 66a775a8f912..70eee0f43d8c 100644
@@ -107,4 +107,60 @@ config LRNG_JENT
 	  time or at runtime with the lrng_base.jitterrng configuration
 	  variable.
 
+config LRNG_HEALTH_TESTS
+	bool "Enable noise source online health tests"
+	help
+	  The online health tests validate the noise source at
+	  runtime for fatal errors. These tests include SP800-90B
+	  compliant tests which are invoked if the system is booted
+	  with fips=1. In case of fatal errors during active
+	  SP800-90B tests, the issue is logged and the noise
+	  data is discarded. These tests are required for full
+	  compliance with SP800-90B.
+
+	  If unsure, say Y.
+
+config LRNG_RCT_BROKEN
+	bool "SP800-90B RCT with dangerous low cutoff value"
+	depends on LRNG_HEALTH_TESTS
+	depends on BROKEN
+	default n
+	help
+	  This option enables a dangerously low SP800-90B repetitive
+	  count test (RCT) cutoff value which makes it very likely
+	  that the RCT is triggered to raise a self test failure.
+
+	  This option is ONLY intended for developers wanting to
+	  test the effectiveness of the SP800-90B RCT health test.
+
+	  If unsure, say N.
+
+config LRNG_APT_BROKEN
+	bool "SP800-90B APT with dangerous low cutoff value"
+	depends on LRNG_HEALTH_TESTS
+	depends on BROKEN
+	default n
+	help
+	  This option enables a dangerously low SP800-90B adaptive
+	  proportion test (APT) cutoff value which makes it very
+	  likely that the RCT is triggered to raise a self test
+	  failure.
+
+	  This option is ONLY intended for developers wanting to
+	  test the effectiveness of the SP800-90B APT health test.
+
+	  If unsure, say N.
+
+# Default taken from SP800-90B sec 4.4.1 - significance level 2^-30
+config LRNG_RCT_CUTOFF
+	int
+	default 31 if !LRNG_RCT_BROKEN
+	default 1 if LRNG_RCT_BROKEN
+
+# Default taken from SP800-90B sec 4.4.2 - significance level 2^-30
+config LRNG_APT_CUTOFF
+	int
+	default 325 if !LRNG_APT_BROKEN
+	default 32 if LRNG_APT_BROKEN
+
 endif # LRNG
drivers/char/lrng/Makefile +1 -0
index 4f5b6f38f0c4..c3008763dd14 100644
@@ -14,3 +14,4 @@ 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
+obj-$(CONFIG_LRNG_HEALTH_TESTS)	+= lrng_health.o
drivers/char/lrng/lrng_health.c new file +407 -0

407 lines not on this page · raw message

Signature · 1 line
2.26.2
#16 lore raw

PATCH v32 11/12 LRNG - add interface for gathering of raw entropy

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +124 -0
index 70eee0f43d8c..5d2f44d07581 100644
@@ -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 sampled.
+
+config LRNG_RAW_IRQFLAGS_ENTROPY
+	bool "Enable entropy test interface to IRQ flags noise source"
+	help
+	  The test interface allows a privileged process to capture
+	  the raw unconditioned interrupt flags 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_irqflags
+	  debugfs file. Using the option lrng_testing.boot_raw_irqflags_test=1
+	  the raw noise of the first 1000 entropy events since boot
+	  can be sampled.
+
+config LRNG_RAW_RETIP_ENTROPY
+	bool "Enable entropy test interface to RETIP value noise source"
+	help
+	  The test interface allows a privileged process to capture
+	  the raw unconditioned return instruction pointer value
+	  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_retip
+	  debugfs file. Using the option lrng_testing.boot_raw_retip_test=1
+	  the raw noise of the first 1000 entropy events since boot
+	  can be sampled.
+
+config LRNG_RAW_ARRAY
+	bool "Enable test interface to LRNG raw entropy storage array"
+	help
+	  The test interface allows a privileged process to capture
+	  the raw noise data that is collected by the LRNG
+	  in the per-CPU array for statistical analysis. The purpose
+	  of this interface is to verify that the array handling code
+	  truly only concatenates data and provides the same entropy
+	  rate as the raw unconditioned noise source when assessing
+	  the collected data byte-wise.
+
+	  The data can be obtained using the lrng_raw_array debugfs
+	  file. Using the option lrng_testing.boot_raw_array=1
+	  the raw noise of the first 1000 entropy events since boot
+	  can be sampled.
+
+config LRNG_IRQ_PERF
+	bool "Enable LRNG interrupt performance monitor"
+	help
+	  With this option, the performance monitor of the LRNG
+	  interrupt handling code is enabled. The file provides
+	  the execution time of the interrupt handler in
+	  cycles.
+
+	  The interrupt performance data can be obtained using
+	  the lrng_irq_perf debugfs file. Using the option
+	  lrng_testing.boot_irq_perf=1 the performance data of
+	  the first 1000 entropy events since boot can be sampled.
+
+config LRNG_TESTING
+	bool
+	default y if (LRNG_RAW_ENTROPY || LRNG_RAW_ARRAY || LRNG_IRQ_PERF)
+
+endif #LRNG_TESTING_MENU
+
 endif # LRNG
drivers/char/lrng/Makefile +1 -0
index c3008763dd14..b2ce1979dc4b 100644
@@ -15,3 +15,4 @@ obj-$(CONFIG_LRNG_DRBG)		+= lrng_drbg.o
 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
drivers/char/lrng/lrng_testing.c new file +575 -0

575 lines not on this page · raw message

Signature · 1 line
2.26.2
#17 lore raw

Re: [PATCH v32 11/12] LRNG - add interface for gathering of raw entropy

Thank you for the patch! Perhaps something to improve:

Hi "Stephan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on char-misc/char-misc-testing]
[also build test WARNING on cryptodev/master crypto/master v5.9-rc1 next-20200820] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200820-165712
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git d162219c655c8cf8003128a13840d6c1e183fb80
config: nios2-allyesconfig (attached as .config)
compiler: nios2-linux-gcc (GCC) 9.3.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=nios2

If you fix the issue, kindly add following tag as appropriate

All warnings (new ones prefixed by >>):

>> drivers/char/lrng/lrng_testing.c:255:15: warning: initialized field overwritten [-Woverride-init]
     255 |  .rb_reader = 0,
         |               ^
   drivers/char/lrng/lrng_testing.c:255:15: note: (near initialization for 'lrng_raw_hires.rb_reader')
   drivers/char/lrng/lrng_testing.c:295:15: warning: initialized field overwritten [-Woverride-init]
     295 |  .rb_reader = 0,
         |               ^
   drivers/char/lrng/lrng_testing.c:295:15: note: (near initialization for 'lrng_raw_jiffies.rb_reader')
   drivers/char/lrng/lrng_testing.c:336:15: warning: initialized field overwritten [-Woverride-init]
     336 |  .rb_reader = 0,
         |               ^
   drivers/char/lrng/lrng_testing.c:336:15: note: (near initialization for 'lrng_raw_irq.rb_reader')
   drivers/char/lrng/lrng_testing.c:376:15: warning: initialized field overwritten [-Woverride-init]
     376 |  .rb_reader = 0,
         |               ^
   drivers/char/lrng/lrng_testing.c:376:15: note: (near initialization for 'lrng_raw_irqflags.rb_reader')
   drivers/char/lrng/lrng_testing.c:417:15: warning: initialized field overwritten [-Woverride-init]
     417 |  .rb_reader = 0,
         |               ^
   drivers/char/lrng/lrng_testing.c:417:15: note: (near initialization for 'lrng_raw_retip.rb_reader')
   drivers/char/lrng/lrng_testing.c:457:15: warning: initialized field overwritten [-Woverride-init]
     457 |  .rb_reader = 0,
         |               ^
   drivers/char/lrng/lrng_testing.c:457:15: note: (near initialization for 'lrng_raw_array.rb_reader')
   drivers/char/lrng/lrng_testing.c:497:15: warning: initialized field overwritten [-Woverride-init]
     497 |  .rb_reader = 0,
         |               ^

drivers/char/lrng/lrng_testing.c:497:15: note: (near initialization for 'lrng_irq_perf.rb_reader')

# https://github.com/0day-ci/linux/commit/89b15c614286cea77d633ade2a9045060a492149
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200820-165712 git checkout 89b15c614286cea77d633ade2a9045060a492149
vim +255 drivers/char/lrng/lrng_testing.c

252
253 static struct lrng_testing lrng_raw_hires = {
254 .rb_reader = 0,

 > 255		.rb_reader = 0,

256 .lock = __SPIN_LOCK_UNLOCKED(lrng_raw_hires.lock),
257 .read_wait = __WAIT_QUEUE_HEAD_INITIALIZER(lrng_raw_hires.read_wait)
258 };
259

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#18 lore raw

PATCH v32 12/12 LRNG - add power-on and runtime self-tests

In reply to 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 0xffffffff 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
CC Marcelo Henrique Cerri <[email protected]>
CC Neil Horman <[email protected]>
---
 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
drivers/char/lrng/Kconfig +25 -0
index 5d2f44d07581..6930dddb5347 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index b2ce1979dc4b..92219c565f66 100644
@@ -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
drivers/char/lrng/lrng_selftest.c new file +504 -0

504 lines not on this page · raw message

Signature · 1 line
2.26.2
#19 lore raw

v33 cover /dev/random - a new approach with full SP800-90B compliance

In reply to 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 SP800-90A/SP800-90B compliant binary code (CONFIG_LRNG, CONFIG_LRNG_DRNG_SWITCH, CONFIG_LRNG_DRBG, CONFIG_LRNG_HEALTH_TESTS) uses some 61 kBytes. In addition, the LRNG is about 50% faster in the performance critical interrupt handler code path compared to the existing /dev/random implementation.

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 MIPS embedded device

[1] https://www.chronox.de/lrng.html - If the patch is accepted, I would be volunteering to convert the documentation into RST format and contribute it to the Linux kernel documentation directory.

[2] https://www.chronox.de/lrng/doc/lrng.pdf

Changes (compared to the previous patch set):

* fix const static -> static const as indicated by kernel test robot

* fix double initialization as indicated by kernel test robot

* add hw_random.h header file and add get_random_bytes_full prototypes as indicated by kernel test robot

* if -> ifdef for CONFIG_CRYPTO_LIB_SHA256 in lrng_selftest.c

* Note, the warning on random_table is expected as it is there to ensure patch 0001 can be compiled. This symbol is "fixed" with patch 0003.

As a side node: With the switchable DRNG support offered in this patch set, the following areas could be removed. As the existing /dev/random has no support for switchable DRNGs, however, this is not yet feasible though.

* remove lrng_ready_list and all code around it in lrng_interfaces.c

* remove the kernel crypto API RNG API to avoid having two random number providing APIs - this would imply that all RNGs developed for this API would be converted to the LRNG interface

CC "Eric W. Biederman" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>

Stephan Mueller (12):
Linux Random Number Generator
LRNG - allocate one DRNG instance per NUMA node LRNG - sysctls and /proc interface
LRNG - add switchable DRNG support
crypto: DRBG - externalize DRBG functions for LRNG LRNG - add SP800-90A DRBG extension
LRNG - add kernel crypto API PRNG extension
crypto: provide access to a static Jitter RNG state LRNG - add Jitter RNG fast noise source LRNG - add SP800-90B compliant health tests LRNG - add interface for gathering of raw entropy LRNG - add power-on and runtime self-tests

 MAINTAINERS                                   |   7 +
 crypto/drbg.c                                 |  16 +-
 crypto/jitterentropy-kcapi.c                  |   3 +-
 crypto/jitterentropy.c                        |  31 +-
 drivers/char/Kconfig                          |   2 +
 drivers/char/Makefile                         |   9 +-
 drivers/char/lrng/Kconfig                     | 315 +++++++++
 drivers/char/lrng/Makefile                    |  19 +
 drivers/char/lrng/lrng_archrandom.c           |  93 +++
 drivers/char/lrng/lrng_aux.c                  | 136 ++++
 drivers/char/lrng/lrng_chacha20.c             | 320 +++++++++
 drivers/char/lrng/lrng_chacha20.h             |  29 +
 drivers/char/lrng/lrng_drbg.c                 | 259 +++++++
 drivers/char/lrng/lrng_drng.c                 | 409 +++++++++++
 drivers/char/lrng/lrng_health.c               | 407 +++++++++++
 drivers/char/lrng/lrng_interfaces.c           | 648 ++++++++++++++++++
 drivers/char/lrng/lrng_internal.h             | 345 ++++++++++
 drivers/char/lrng/lrng_jent.c                 |  88 +++
 drivers/char/lrng/lrng_kcapi.c                | 321 +++++++++
 drivers/char/lrng/lrng_lfsr.h                 | 152 ++++
 drivers/char/lrng/lrng_numa.c                 | 101 +++
 drivers/char/lrng/lrng_pool.c                 | 589 ++++++++++++++++
 drivers/char/lrng/lrng_proc.c                 | 163 +++++
 drivers/char/lrng/lrng_selftest.c             | 504 ++++++++++++++
 drivers/char/lrng/lrng_sw_noise.c             | 155 +++++
 drivers/char/lrng/lrng_sw_noise.h             |  57 ++
 drivers/char/lrng/lrng_switch.c               | 189 +++++
 drivers/char/lrng/lrng_testing.c              | 575 ++++++++++++++++
 include/crypto/drbg.h                         |   7 +
 .../crypto/internal}/jitterentropy.h          |   3 +
 include/linux/lrng.h                          |  63 ++
 31 files changed, 6005 insertions(+), 10 deletions(-)
 create mode 100644 drivers/char/lrng/Kconfig
 create mode 100644 drivers/char/lrng/Makefile
 create mode 100644 drivers/char/lrng/lrng_archrandom.c
 create mode 100644 drivers/char/lrng/lrng_aux.c
 create mode 100644 drivers/char/lrng/lrng_chacha20.c
 create mode 100644 drivers/char/lrng/lrng_chacha20.h
 create mode 100644 drivers/char/lrng/lrng_drbg.c
 create mode 100644 drivers/char/lrng/lrng_drng.c
 create mode 100644 drivers/char/lrng/lrng_health.c
 create mode 100644 drivers/char/lrng/lrng_interfaces.c
 create mode 100644 drivers/char/lrng/lrng_internal.h
 create mode 100644 drivers/char/lrng/lrng_jent.c
 create mode 100644 drivers/char/lrng/lrng_kcapi.c
 create mode 100644 drivers/char/lrng/lrng_lfsr.h
 create mode 100644 drivers/char/lrng/lrng_numa.c
 create mode 100644 drivers/char/lrng/lrng_pool.c
 create mode 100644 drivers/char/lrng/lrng_proc.c
 create mode 100644 drivers/char/lrng/lrng_selftest.c
 create mode 100644 drivers/char/lrng/lrng_sw_noise.c
 create mode 100644 drivers/char/lrng/lrng_sw_noise.h
 create mode 100644 drivers/char/lrng/lrng_switch.c
 create mode 100644 drivers/char/lrng/lrng_testing.c
 rename {crypto => include/crypto/internal}/jitterentropy.h (84%)
 create mode 100644 include/linux/lrng.h
Signature · 1 line
2.26.2
#20 lore raw

PATCH v33 1/12 Linux Random Number Generator

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 except that it is capable of processing an entire word and that a different polynomial is used. The reason for the different polynomial is performance in a performance sensitive code section, the interrupt handler. The chosen polynomials have 4 taps. Also, this LFSR-approach is used in the OpenBSD /dev/random equivalent.

2. Concatenation: The temporary seed buffer used to seed the DRNG is a concatenation of parts of the entropy pool data, and the CPU noise source output.

The DRNG always tries to seed itself with 256 bits of entropy, except during boot. In any case, if the noise sources cannot deliver that amount, the available entropy is used and the DRNG keeps track on how much entropy it was seeded with. The entropy implied by the LRNG available in the entropy pool may be too conservative. To ensure that during boot time all available entropy from the entropy pool is transferred to the DRNG, the hash_df function always generates 256 data bits during boot to seed the DRNG. During boot, the DRNG is seeded as follows:

1. The DRNG is reseeded from the entropy pool and potentially the fast noise sources if the entropy pool has collected at least 32 bits of entropy from the interrupt noise source. The goal of this step is to ensure that the DRNG receives some initial entropy as early as possible. In addition it receives the entropy available from the fast noise sources.

2. The DRNG is reseeded from the entropy pool and potentially the fast noise sources if all noise sources collectively can provide at least 128 bits of entropy.

3. The DRNG is reseeded from the entropy pool and potentially the fast noise sources if all noise sources collectivel can provide at least 256 bits.

At the time of the reseeding steps, the DRNG requests as much entropy as is available in order to skip certain steps and reach the seeding level of 256 bits. This may imply that one or more of the aforementioned steps are skipped.

In all listed steps, the DRNG is (re)seeded with a number of random bytes from the entropy pool that is at most the amount of entropy present in the entropy pool. This means that when the entropy pool contains 128 or 256 bits of entropy, the DRNG is seeded with that amount of entropy as well.

Before the DRNG is seeded with 256 bits of entropy in step 3, requests of random data from /dev/random are not processed.

The hash_df operation providing random data from the entropy pool will always require that all entropy sources collectively can deliver at least 129 entropy bits as configured with (128 bits of entropy for seeding plus one bit of entropy that is lost with the post processing as defined in SP800-90B).

The DRNG operates as deterministic random number generator with the following properties:

* The maximum number of random bytes that can be generated with one DRNG generate operation is limited to 4096 bytes. When longer random numbers are requested, multiple DRNG generate operations are performed. The ChaCha20 DRNG as well as the SP800-90A DRBGs implement an update of their state after completing a generate request for backtracking resistance.

* The secondary DRNG is reseeded with whatever entropy is available – in the worst case where no additional entropy can be provided by the noise sources, the DRNG is not re-seeded and continues its operation to try to reseed again after again the expiry of one of these thresholds:

- If the last reseeding of the secondary DRNG is more than 600 seconds ago, or

- 2^20 DRNG generate operations are performed, whatever comes first, or

- the secondary DRNG is forced to reseed before the next generation of random numbers if data has been injected into the LRNG by writing data into /dev/random or /dev/urandom.

The chosen values prevent high-volume requests from user space to cause frequent reseeding operations which drag down the performance of the DRNG.

With the automatic reseeding after 600 seconds, the LRNG is triggered to reseed itself before the first request after a suspend that put the hardware to sleep for longer than 600 seconds.

The LRNG uses the following runtime memory using the currently smallest configuration:

* 576 bytes (512 bytes for the entropy pool and 64 for the entropy pool meta data) for the entropy pool management

* 64 bytes per CPU for the time stamp array

To support smaller devices including IoT environments, this patch allows reducing the runtime memory footprint of the LRNG at compile time by selecting smaller entropy pool sizes.

The entropy pool has support for sizes of 256, 128 and 64 bytes supported by primitive and irreducible polynomials.

The time stamp array is reduced to one atomic_t variable per CPU, i.e. 4 bytes when CONFIG_BASE_SMALL is selected during kernel configuration. This implies that after the receipt of 4 interrupts on one CPU, the data is injected into the LFSR. Depending on the behavior of the CPU caches, this may imply that the average interrupt handler execution time increases a bit, since instead of injecting 8 atomic_t values at one given time into the LFSR, only one is processed which may incur cache misses.

When selecting the compilation of a kernel for a small environment, prevent the allocation of a buffer up to 4096 bytes to serve user space requests. In this case, the stack variable of 64 bytes is used to serve all user space requests.

The LRNG has the following properties:

* internal noise source: interrupts timing with fast boot time seeding

* high performance of interrupt handling code: The LRNG impact on the interrupt handling has been reduced to a minimum. On one example system, the LRNG interrupt handling code executes within an average of 65 cycles whereas the existing /dev/random on the same device takes about 97 cycles when measuring the execution time of add_interrupt_randomness().

* lockless LFSR to collect raw entropy supporing concurrency-free use of massive parallel systems

* use of standalone ChaCha20 based RNG with the option to use a different DRNG selectable at compile time

* "atomic" seeding of secondary DRBG to ensure full entropy transport

* instantiate one DRNG per NUMA node

* support for runtime switchable output DRNGs

* use of only well-defined entropy-preserving operations to collect, compress and forward entropy: concatenation, LFSR, SP800-90A hash_df function

* compile-time selectable entropy pool size: the choice also uses the applicable LFSR polynomial to maintain the entropy pool size

* support of small systems by allowing the reduction of the runtime memory needs

Further details including the rationale for the design choices and properties of the LRNG together with testing is provided at [1]. In addition, the documentation explains the conducted regression tests to verify that the LRNG is API and ABI compatible with the existing /dev/random implementation.

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

CC: "Eric W. Biederman" <[email protected]>
CC: "Alexander E. Patrakov" <[email protected]>
CC: "Ahmed S. Darwish" <[email protected]>
CC: "Theodore Y. Ts'o" <[email protected]>
CC: Willy Tarreau <[email protected]>
CC: Matthew Garrett <[email protected]>
CC: Vito Caputo <[email protected]>
CC: Andreas Dilger <[email protected]>
CC: Jan Kara <[email protected]>
CC: Ray Strode <[email protected]>
CC: William Jon McCann <[email protected]>
CC: zhangjs <[email protected]>
CC: Andy Lutomirski <[email protected]>
CC: Florian Weimer <[email protected]>
CC: Lennart Poettering <[email protected]>
CC: Nicolai Stange <[email protected]>
Mathematical aspects Reviewed-by: "Peter, Matthias" <[email protected]>

---
 MAINTAINERS                         |   7 +
 drivers/char/Kconfig                |   2 +
 drivers/char/Makefile               |   9 +-
 drivers/char/lrng/Kconfig           |  68 +++
 drivers/char/lrng/Makefile          |   9 +
 drivers/char/lrng/lrng_archrandom.c |  93 ++++
 drivers/char/lrng/lrng_aux.c        | 136 ++++++
 drivers/char/lrng/lrng_chacha20.c   | 320 ++++++++++++++
 drivers/char/lrng/lrng_chacha20.h   |  29 ++
 drivers/char/lrng/lrng_drng.c       | 409 ++++++++++++++++++
 drivers/char/lrng/lrng_interfaces.c | 649 ++++++++++++++++++++++++++++
 drivers/char/lrng/lrng_internal.h   | 336 ++++++++++++++
 drivers/char/lrng/lrng_lfsr.h       | 152 +++++++
 drivers/char/lrng/lrng_pool.c       | 589 +++++++++++++++++++++++++
 drivers/char/lrng/lrng_sw_noise.c   | 155 +++++++
 drivers/char/lrng/lrng_sw_noise.h   |  57 +++
 include/linux/lrng.h                |  63 +++
 17 files changed, 3082 insertions(+), 1 deletion(-)
 create mode 100644 drivers/char/lrng/Kconfig
 create mode 100644 drivers/char/lrng/Makefile
 create mode 100644 drivers/char/lrng/lrng_archrandom.c
 create mode 100644 drivers/char/lrng/lrng_aux.c
 create mode 100644 drivers/char/lrng/lrng_chacha20.c
 create mode 100644 drivers/char/lrng/lrng_chacha20.h
 create mode 100644 drivers/char/lrng/lrng_drng.c
 create mode 100644 drivers/char/lrng/lrng_interfaces.c
 create mode 100644 drivers/char/lrng/lrng_internal.h
 create mode 100644 drivers/char/lrng/lrng_lfsr.h
 create mode 100644 drivers/char/lrng/lrng_pool.c
 create mode 100644 drivers/char/lrng/lrng_sw_noise.c
 create mode 100644 drivers/char/lrng/lrng_sw_noise.h
 create mode 100644 include/linux/lrng.h
MAINTAINERS +7 -0
index deaafb617361..74f6fd1ba1ec 100644
@@ -10084,6 +10084,13 @@ F:	Documentation/litmus-tests/
 F:	Documentation/memory-barriers.txt
 F:	tools/memory-model/
 
+LINUX RANDOM NUMBER GENERATOR (LRNG) DRIVER
+M:	Stephan Mueller <[email protected]>
+S:	Maintained
+W:	https://www.chronox.de/lrng.html
+F:	drivers/char/lrng/*
+F:	include/linux/lrng.h
+
 LIS3LV02D ACCELEROMETER DRIVER
 M:	Eric Piel <[email protected]>
 S:	Maintained
drivers/char/Kconfig +2 -0
index b1bd336761b1..8a5b8a2db2c7 100644
@@ -470,6 +470,8 @@ config ADI
 	  and SSM (Silicon Secured Memory).  Intended consumers of this
 	  driver include crash and makedumpfile.
 
+source "drivers/char/lrng/Kconfig"
+
 endmenu
 
 config RANDOM_TRUST_CPU
drivers/char/Makefile +8 -1
index ffce287ef415..2110d3e28cf2 100644
@@ -3,7 +3,14 @@
 # Makefile for the kernel character device drivers.
 #
 
-obj-y				+= mem.o random.o
+obj-y				+= mem.o
+
+ifeq ($(CONFIG_LRNG),y)
+  obj-y				+= lrng/
+else
+  obj-y				+= random.o
+endif
+
 obj-$(CONFIG_TTY_PRINTK)	+= ttyprintk.o
 obj-y				+= misc.o
 obj-$(CONFIG_ATARI_DSP56K)	+= dsp56k.o
drivers/char/lrng/Kconfig new file +68 -0

68 lines not on this page · raw message

drivers/char/lrng/Makefile new file +9 -0
new file mode 100644
index 000000000000..1d2a0211973d
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the Linux Random Number Generator.
+#
+
+obj-y				+= lrng_pool.o lrng_aux.o \
+				   lrng_sw_noise.o lrng_archrandom.o \
+				   lrng_drng.o lrng_chacha20.o \
+				   lrng_interfaces.o \
drivers/char/lrng/lrng_archrandom.c new file +93 -0

93 lines not on this page · raw message

drivers/char/lrng/lrng_aux.c new file +136 -0

136 lines not on this page · raw message

drivers/char/lrng/lrng_chacha20.c new file +320 -0

320 lines not on this page · raw message

drivers/char/lrng/lrng_chacha20.h new file +29 -0
new file mode 100644
index 000000000000..1533b2490964
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
+/*
+ * LRNG ChaCha20 definitions
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller <[email protected]>
+ */
+
+#include <crypto/chacha.h>
+
+/* State according to RFC 7539 section 2.3 */
+struct chacha20_block {
+	u32 constants[4];
+	union {
+#define CHACHA_KEY_SIZE_WORDS (CHACHA_KEY_SIZE / sizeof(u32))
+		u32 u[CHACHA_KEY_SIZE_WORDS];
+		u8  b[CHACHA_KEY_SIZE];
+	} key __latent_entropy;
+	u32 counter;
+	u32 nonce[3] __latent_entropy;
+};
+
+static inline void lrng_cc20_init_rfc7539(struct chacha20_block *chacha20)
+{
+	/* String "expand 32-byte k" */
+	chacha20->constants[0] = 0x61707865;
+	chacha20->constants[1] = 0x3320646e;
+	chacha20->constants[2] = 0x79622d32;
+	chacha20->constants[3] = 0x6b206574;
+}
drivers/char/lrng/lrng_drng.c new file +409 -0

409 lines not on this page · raw message

drivers/char/lrng/lrng_interfaces.c new file +649 -0

649 lines not on this page · raw message

drivers/char/lrng/lrng_internal.h new file +336 -0

336 lines not on this page · raw message

drivers/char/lrng/lrng_lfsr.h new file +152 -0

152 lines not on this page · raw message

drivers/char/lrng/lrng_pool.c new file +589 -0

589 lines not on this page · raw message

drivers/char/lrng/lrng_sw_noise.c new file +155 -0

155 lines not on this page · raw message

drivers/char/lrng/lrng_sw_noise.h new file +57 -0

19 lines not on this page · raw message

include/linux/lrng.h new file +63 -0

63 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.26.2

Part of the diff is not shown here. View the raw message.

#21 lore raw

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

Thank you for the patch! Yet something to improve:

Hi "Stephan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on char-misc/char-misc-testing]
[also build test ERROR on cryptodev/master crypto/master v5.9-rc1 next-20200821] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200821-140523
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git d162219c655c8cf8003128a13840d6c1e183fb80
config: parisc-allyesconfig (attached as .config)
compiler: hppa-linux-gcc (GCC) 9.3.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=parisc

If you fix the issue, kindly add following tag as appropriate

All errors (new ones prefixed by >>):

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'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#22 lore raw

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

Am Freitag, 21. August 2020, 21:42:17 CEST schrieb kernel test robot:

Hi,

Quoted 7 lines

hppa-linux-ld: lib/random32.o: in function `prandom_u32':

Quoted 5 lines
Quoted 5 lines

(.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

#23 lore raw

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

In reply to Stephan Müller
Thank you for the patch! Yet something to improve:

Hi "Stephan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on char-misc/char-misc-testing]
[also build test ERROR on cryptodev/master crypto/master v5.9-rc1 next-20200821] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200821-140523
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git d162219c655c8cf8003128a13840d6c1e183fb80
config: i386-allyesconfig (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce (this is a W=1 build):
        # save the attached .config to linux build tree
        make W=1 ARCH=i386 

If you fix the issue, kindly add following tag as appropriate

All errors (new ones prefixed by >>):

ld: lib/random32.o: in function `prandom_u32':

>> random32.c:(.text+0x234): undefined reference to `__tracepoint_prandom_u32'
>> ld: random32.c:(.text+0x268): undefined reference to `__tracepoint_prandom_u32'
>> ld: lib/random32.o:(__jump_table+0x8): undefined reference to `__tracepoint_prandom_u32'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#24 lore raw

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

In reply to Stephan Müller
Thank you for the patch! Perhaps something to improve:

Hi "Stephan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on char-misc/char-misc-testing]
[also build test WARNING on cryptodev/master crypto/master v5.9-rc1 next-20200821] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200821-140523
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git d162219c655c8cf8003128a13840d6c1e183fb80

:::::: branch date: 2 days ago
:::::: commit date: 2 days ago
config: arm64-randconfig-s031-20200821 (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.2-191-g10164920-dirty
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=arm64

If you fix the issue, kindly add following tag as appropriate

sparse warnings: (new ones prefixed by >>)

drivers/char/lrng/lrng_drng.c:381:6: sparse: sparse: symbol 'lrng_reset' was not declared. Should it be static?
--

>> drivers/char/lrng/lrng_chacha20.c:54:47: sparse: sparse: cast to restricted __le32
   drivers/char/lrng/lrng_chacha20.c:58:47: sparse: sparse: cast to restricted __le32
--
>> drivers/char/lrng/lrng_interfaces.c:482:16: sparse: sparse: incorrect type in return expression (different base types) @@     expected unsigned int @@     got restricted __poll_t [assigned] [usertype] mask @@
>> drivers/char/lrng/lrng_interfaces.c:482:16: sparse:     expected unsigned int
>> drivers/char/lrng/lrng_interfaces.c:482:16: sparse:     got restricted __poll_t [assigned] [usertype] mask
>> drivers/char/lrng/lrng_interfaces.c:612:18: sparse: sparse: incorrect type in initializer (different base types) @@     expected restricted __poll_t ( *poll )( ... ) @@     got unsigned int ( * )( ... ) @@
>> drivers/char/lrng/lrng_interfaces.c:612:18: sparse:     expected restricted __poll_t ( *poll )( ... )
>> drivers/char/lrng/lrng_interfaces.c:612:18: sparse:     got unsigned int ( * )( ... )

# https://github.com/0day-ci/linux/commit/95481f9aadd4408e56c65cd95e47b929224fbc28
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200821-140523 git checkout 95481f9aadd4408e56c65cd95e47b929224fbc28
vim +/lrng_drngs_init_cc20 +81 drivers/char/lrng/lrng_drng.c

95481f9aadd440 Stephan Müller 2020-08-21 79

95481f9aadd440 Stephan Müller 2020-08-21   80  /* Initialize the default DRNG during boot */
95481f9aadd440 Stephan Müller 2020-08-21  @81  static void lrng_drngs_init_cc20(void)
95481f9aadd440 Stephan Müller 2020-08-21   82  {
95481f9aadd440 Stephan Müller 2020-08-21   83  	unsigned long flags = 0;
95481f9aadd440 Stephan Müller 2020-08-21   84  
95481f9aadd440 Stephan Müller 2020-08-21   85  	if (lrng_get_available())
95481f9aadd440 Stephan Müller 2020-08-21   86  		return;
95481f9aadd440 Stephan Müller 2020-08-21   87  
95481f9aadd440 Stephan Müller 2020-08-21   88  	lrng_drng_lock(&lrng_drng_init, &flags);
95481f9aadd440 Stephan Müller 2020-08-21   89  	if (lrng_get_available()) {
95481f9aadd440 Stephan Müller 2020-08-21   90  		lrng_drng_unlock(&lrng_drng_init, &flags);
95481f9aadd440 Stephan Müller 2020-08-21   91  		return;
95481f9aadd440 Stephan Müller 2020-08-21   92  	}
95481f9aadd440 Stephan Müller 2020-08-21   93  
95481f9aadd440 Stephan Müller 2020-08-21   94  	lrng_drng_reset(&lrng_drng_init);
95481f9aadd440 Stephan Müller 2020-08-21   95  	lrng_cc20_init_state(&chacha20);
95481f9aadd440 Stephan Müller 2020-08-21   96  	lrng_state_init_seed_work();
95481f9aadd440 Stephan Müller 2020-08-21   97  	lrng_drng_unlock(&lrng_drng_init, &flags);
95481f9aadd440 Stephan Müller 2020-08-21   98  
95481f9aadd440 Stephan Müller 2020-08-21   99  	lrng_drng_lock(&lrng_drng_atomic, &flags);
95481f9aadd440 Stephan Müller 2020-08-21  100  	lrng_drng_reset(&lrng_drng_atomic);
95481f9aadd440 Stephan Müller 2020-08-21  101  	/*
95481f9aadd440 Stephan Müller 2020-08-21  102  	 * We do not initialize the state of the atomic DRNG as it is identical
95481f9aadd440 Stephan Müller 2020-08-21  103  	 * to the DRNG at this point.
95481f9aadd440 Stephan Müller 2020-08-21  104  	 */
95481f9aadd440 Stephan Müller 2020-08-21  105  	lrng_drng_unlock(&lrng_drng_atomic, &flags);
95481f9aadd440 Stephan Müller 2020-08-21  106  
95481f9aadd440 Stephan Müller 2020-08-21  107  	lrng_set_available();
95481f9aadd440 Stephan Müller 2020-08-21  108  }
95481f9aadd440 Stephan Müller 2020-08-21  109  
95481f9aadd440 Stephan Müller 2020-08-21  110  /************************* Random Number Generation ***************************/
95481f9aadd440 Stephan Müller 2020-08-21  111  
95481f9aadd440 Stephan Müller 2020-08-21  112  /* Inject a data buffer into the DRNG */
95481f9aadd440 Stephan Müller 2020-08-21 @113  static void lrng_drng_inject(struct lrng_drng *drng,
95481f9aadd440 Stephan Müller 2020-08-21  114  			     const u8 *inbuf, u32 inbuflen)
95481f9aadd440 Stephan Müller 2020-08-21  115  {
95481f9aadd440 Stephan Müller 2020-08-21  116  	const char *drng_type = unlikely(drng == &lrng_drng_atomic) ?
95481f9aadd440 Stephan Müller 2020-08-21  117  				"atomic" : "regular";
95481f9aadd440 Stephan Müller 2020-08-21  118  	unsigned long flags = 0;
95481f9aadd440 Stephan Müller 2020-08-21  119  
95481f9aadd440 Stephan Müller 2020-08-21  120  	BUILD_BUG_ON(LRNG_DRNG_RESEED_THRESH > INT_MAX);
95481f9aadd440 Stephan Müller 2020-08-21  121  	pr_debug("seeding %s DRNG with %u bytes\n", drng_type, inbuflen);
95481f9aadd440 Stephan Müller 2020-08-21  122  	lrng_drng_lock(drng, &flags);
95481f9aadd440 Stephan Müller 2020-08-21  123  	if (drng->crypto_cb->lrng_drng_seed_helper(drng->drng,
95481f9aadd440 Stephan Müller 2020-08-21  124  						    inbuf, inbuflen) < 0) {
95481f9aadd440 Stephan Müller 2020-08-21  125  		pr_warn("seeding of %s DRNG failed\n", drng_type);
95481f9aadd440 Stephan Müller 2020-08-21  126  		atomic_set(&drng->requests, 1);
95481f9aadd440 Stephan Müller 2020-08-21  127  	} else {
95481f9aadd440 Stephan Müller 2020-08-21  128  		pr_debug("%s DRNG stats since last seeding: %lu secs; generate calls: %d\n",
95481f9aadd440 Stephan Müller 2020-08-21  129  			 drng_type,
95481f9aadd440 Stephan Müller 2020-08-21  130  			 (time_after(jiffies, drng->last_seeded) ?
95481f9aadd440 Stephan Müller 2020-08-21  131  			  (jiffies - drng->last_seeded) : 0) / HZ,
95481f9aadd440 Stephan Müller 2020-08-21  132  			 (LRNG_DRNG_RESEED_THRESH -
95481f9aadd440 Stephan Müller 2020-08-21  133  			  atomic_read(&drng->requests)));
95481f9aadd440 Stephan Müller 2020-08-21  134  		drng->last_seeded = jiffies;
95481f9aadd440 Stephan Müller 2020-08-21  135  		atomic_set(&drng->requests, LRNG_DRNG_RESEED_THRESH);
95481f9aadd440 Stephan Müller 2020-08-21  136  		drng->force_reseed = false;
95481f9aadd440 Stephan Müller 2020-08-21  137  
95481f9aadd440 Stephan Müller 2020-08-21  138  		if (drng->drng == lrng_drng_atomic.drng) {
95481f9aadd440 Stephan Müller 2020-08-21  139  			lrng_drng_atomic.last_seeded = jiffies;
95481f9aadd440 Stephan Müller 2020-08-21  140  			atomic_set(&lrng_drng_atomic.requests,
95481f9aadd440 Stephan Müller 2020-08-21  141  				   LRNG_DRNG_RESEED_THRESH);
95481f9aadd440 Stephan Müller 2020-08-21  142  			lrng_drng_atomic.force_reseed = false;
95481f9aadd440 Stephan Müller 2020-08-21  143  		}
95481f9aadd440 Stephan Müller 2020-08-21  144  	}
95481f9aadd440 Stephan Müller 2020-08-21  145  	lrng_drng_unlock(drng, &flags);
95481f9aadd440 Stephan Müller 2020-08-21  146  }
95481f9aadd440 Stephan Müller 2020-08-21  147  
95481f9aadd440 Stephan Müller 2020-08-21  148  /*
95481f9aadd440 Stephan Müller 2020-08-21  149   * Perform the seeding of the DRNG with data from noise source
95481f9aadd440 Stephan Müller 2020-08-21  150   */
95481f9aadd440 Stephan Müller 2020-08-21  151  static inline int _lrng_drng_seed(struct lrng_drng *drng)
95481f9aadd440 Stephan Müller 2020-08-21  152  {
95481f9aadd440 Stephan Müller 2020-08-21  153  	struct entropy_buf seedbuf __aligned(LRNG_KCAPI_ALIGN);
95481f9aadd440 Stephan Müller 2020-08-21  154  	unsigned long flags = 0;
95481f9aadd440 Stephan Müller 2020-08-21  155  	u32 total_entropy_bits;
95481f9aadd440 Stephan Müller 2020-08-21  156  	int ret;
95481f9aadd440 Stephan Müller 2020-08-21  157  
95481f9aadd440 Stephan Müller 2020-08-21  158  	lrng_drng_lock(drng, &flags);
95481f9aadd440 Stephan Müller 2020-08-21  159  	total_entropy_bits = lrng_fill_seed_buffer(drng->crypto_cb, drng->hash,
95481f9aadd440 Stephan Müller 2020-08-21  160  						   &seedbuf, 0);
95481f9aadd440 Stephan Müller 2020-08-21 @161  	lrng_drng_unlock(drng, &flags);
95481f9aadd440 Stephan Müller 2020-08-21  162  
95481f9aadd440 Stephan Müller 2020-08-21  163  	/* Allow the seeding operation to be called again */
95481f9aadd440 Stephan Müller 2020-08-21  164  	lrng_pool_unlock();
95481f9aadd440 Stephan Müller 2020-08-21  165  	lrng_init_ops(total_entropy_bits);
95481f9aadd440 Stephan Müller 2020-08-21  166  	ret = total_entropy_bits >> 3;
95481f9aadd440 Stephan Müller 2020-08-21  167  
95481f9aadd440 Stephan Müller 2020-08-21  168  	lrng_drng_inject(drng, (u8 *)&seedbuf, sizeof(seedbuf));
95481f9aadd440 Stephan Müller 2020-08-21  169  	memzero_explicit(&seedbuf, sizeof(seedbuf));
95481f9aadd440 Stephan Müller 2020-08-21  170  
95481f9aadd440 Stephan Müller 2020-08-21  171  	return ret;
95481f9aadd440 Stephan Müller 2020-08-21  172  }
95481f9aadd440 Stephan Müller 2020-08-21  173  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]

#25 lore raw

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

Am Mittwoch, 26. August 2020, 16:27:42 CEST schrieb kernel test robot:

Hi,

Quoted 4 lines
Quoted 2 lines
Quoted 2 lines

drivers/char/lrng/lrng_chacha20.c:54:47: sparse: sparse: cast to restricted __le32

drivers/char/lrng/lrng_chacha20.c:58:47: sparse: sparse: cast to
restricted __le32 --

Thanks for the reports. Both, the __poll_t and the __le32 issues are fixed in v34.

Ciao
Stephan

#26 lore raw

PATCH v33 2/12 LRNG - allocate one DRNG instance per NUMA node

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Makefile +2 -0
index 1d2a0211973d..0a32f22c2c1a 100644
@@ -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
drivers/char/lrng/lrng_internal.h +5 -0
index 53c267115721..5587be09f495 100644
@@ -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 **************************/
 
drivers/char/lrng/lrng_numa.c new file +101 -0

101 lines not on this page · raw message

Signature · 1 line
2.26.2
#27 lore raw

PATCH v33 3/12 LRNG - sysctls and /proc interface

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Makefile +1 -0
index 0a32f22c2c1a..e69c176f0161 100644
@@ -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
drivers/char/lrng/lrng_interfaces.c +0 -1
index d9c68679136d..95ee99c82592 100644
@@ -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? */
drivers/char/lrng/lrng_internal.h +4 -0
index 5587be09f495..8aea41a2f43f 100644
@@ -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 *******************************/
 
drivers/char/lrng/lrng_proc.c new file +163 -0

163 lines not on this page · raw message

Signature · 1 line
2.26.2
#28 lore raw

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

Thank you for the patch! Perhaps something to improve:

Hi "Stephan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on char-misc/char-misc-testing]
[also build test WARNING on cryptodev/master crypto/master v5.9-rc1 next-20200821] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200821-140523
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git d162219c655c8cf8003128a13840d6c1e183fb80
config: arm64-randconfig-s031-20200821 (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0

reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.2-191-g10164920-dirty
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=arm64

If you fix the issue, kindly add following tag as appropriate

sparse warnings: (new ones prefixed by >>)

>> drivers/char/lrng/lrng_proc.c:49:50: sparse: sparse: incorrect type in argument 3 (different address spaces) @@     expected void * @@     got void [noderef] __user *buffer @@
>> drivers/char/lrng/lrng_proc.c:49:50: sparse:     expected void *
>> drivers/char/lrng/lrng_proc.c:49:50: sparse:     got void [noderef] __user *buffer
>> drivers/char/lrng/lrng_proc.c:100:35: sparse: sparse: incorrect type in initializer (incompatible argument 3 (different address spaces)) @@     expected int ( [usertype] *proc_handler )( ... ) @@     got int ( * )( ... ) @@
>> drivers/char/lrng/lrng_proc.c:100:35: sparse:     expected int ( [usertype] *proc_handler )( ... )
>> drivers/char/lrng/lrng_proc.c:100:35: sparse:     got int ( * )( ... )
   drivers/char/lrng/lrng_proc.c:106:35: sparse: sparse: incorrect type in initializer (incompatible argument 3 (different address spaces)) @@     expected int ( [usertype] *proc_handler )( ... ) @@     got int ( * )( ... ) @@
   drivers/char/lrng/lrng_proc.c:106:35: sparse:     expected int ( [usertype] *proc_handler )( ... )
   drivers/char/lrng/lrng_proc.c:106:35: sparse:     got int ( * )( ... )
>> drivers/char/lrng/lrng_proc.c:150:25: sparse: sparse: context imbalance in 'lrng_proc_type_show' - different lock contexts for basic block

# https://github.com/0day-ci/linux/commit/902758205b535f162d904f8209936aed9d6ae6d3
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200821-140523 git checkout 902758205b535f162d904f8209936aed9d6ae6d3
vim +49 drivers/char/lrng/lrng_proc.c

    15	
    16	/*
    17	 * This function is used to return both the bootid UUID, and random
    18	 * UUID.  The difference is in whether table->data is NULL; if it is,
    19	 * then a new UUID is generated and returned to the user.
    20	 *
    21	 * If the user accesses this via the proc interface, the UUID will be
    22	 * returned as an ASCII string in the standard UUID format; if via the
    23	 * sysctl system call, as 16 bytes of binary data.
    24	 */
    25	static int lrng_proc_do_uuid(struct ctl_table *table, int write,
    26				     void __user *buffer, size_t *lenp, loff_t *ppos)
    27	{
    28		struct ctl_table fake_table;
    29		unsigned char buf[64], tmp_uuid[16], *uuid;
    30	
    31		uuid = table->data;
    32		if (!uuid) {
    33			uuid = tmp_uuid;
    34			generate_random_uuid(uuid);
    35		} else {
    36			static DEFINE_SPINLOCK(bootid_spinlock);
    37	
    38			spin_lock(&bootid_spinlock);
    39			if (!uuid[8])
    40				generate_random_uuid(uuid);
    41			spin_unlock(&bootid_spinlock);
    42		}
    43	
    44		sprintf(buf, "%pU", uuid);
    45	
    46		fake_table.data = buf;
    47		fake_table.maxlen = sizeof(buf);
    48	
  > 49		return proc_dostring(&fake_table, write, buffer, lenp, ppos);
    50	}
    51	
    52	static int lrng_proc_do_entropy(struct ctl_table *table, int write,
    53					void *buffer, size_t *lenp, loff_t *ppos)
    54	{
    55		struct ctl_table fake_table;
    56		int entropy_count;
    57	
    58		entropy_count = lrng_avail_entropy();
    59	
    60		fake_table.data = &entropy_count;
    61		fake_table.maxlen = sizeof(entropy_count);
    62	
    63		return proc_dointvec(&fake_table, write, buffer, lenp, ppos);
    64	}
    65	
    66	static int lrng_sysctl_poolsize = LRNG_POOL_SIZE_BITS;
    67	static int lrng_min_write_thresh;
    68	static int lrng_max_write_thresh = LRNG_POOL_SIZE_BITS;
    69	static char lrng_sysctl_bootid[16];
    70	static int lrng_drng_reseed_max_min;
    71	
    72	struct ctl_table random_table[] = {
    73		{
    74			.procname	= "poolsize",
    75			.data		= &lrng_sysctl_poolsize,
    76			.maxlen		= sizeof(int),
    77			.mode		= 0444,
    78			.proc_handler	= proc_dointvec,
    79		},
    80		{
    81			.procname	= "entropy_avail",
    82			.maxlen		= sizeof(int),
    83			.mode		= 0444,
    84			.proc_handler	= lrng_proc_do_entropy,
    85		},
    86		{
    87			.procname	= "write_wakeup_threshold",
    88			.data		= &lrng_write_wakeup_bits,
    89			.maxlen		= sizeof(int),
    90			.mode		= 0644,
    91			.proc_handler	= proc_dointvec_minmax,
    92			.extra1		= &lrng_min_write_thresh,
    93			.extra2		= &lrng_max_write_thresh,
    94		},
    95		{
    96			.procname	= "boot_id",
    97			.data		= &lrng_sysctl_bootid,
    98			.maxlen		= 16,
    99			.mode		= 0444,
 > 100			.proc_handler	= lrng_proc_do_uuid,
   101		},
   102		{
   103			.procname	= "uuid",
   104			.maxlen		= 16,
   105			.mode		= 0444,
   106			.proc_handler	= lrng_proc_do_uuid,
   107		},
   108		{
   109			.procname       = "urandom_min_reseed_secs",
   110			.data           = &lrng_drng_reseed_max_time,
   111			.maxlen         = sizeof(int),
   112			.mode           = 0644,
   113			.proc_handler   = proc_dointvec,
   114			.extra1		= &lrng_drng_reseed_max_min,
   115		},
   116		{ }
   117	};
   118	
   119	/* Number of online DRNGs */
   120	static u32 numa_drngs = 1;
   121	
   122	void lrng_pool_inc_numa_node(void)
   123	{
   124		numa_drngs++;
   125	}
   126	
   127	static int lrng_proc_type_show(struct seq_file *m, void *v)
   128	{
   129		struct lrng_drng *lrng_drng_init = lrng_drng_init_instance();
   130		unsigned long flags = 0;
   131		unsigned char buf[300];
   132	
   133		lrng_drng_lock(lrng_drng_init, &flags);
   134		snprintf(buf, sizeof(buf),
   135			 "DRNG name: %s\n"
   136			 "Hash for reading entropy pool: %s\n"
   137			 "DRNG security strength: %d bits\n"
   138			 "number of DRNG instances: %u\n"
   139			 "SP800-90B compliance: %s\n"
   140			 "High-resolution timer: %s\n"
   141			 "LRNG minimally seeded: %s\n"
   142			 "LRNG fully seeded: %s\n",
   143			 lrng_drng_init->crypto_cb->lrng_drng_name(),
   144			 lrng_drng_init->crypto_cb->lrng_hash_name(),
   145			 LRNG_DRNG_SECURITY_STRENGTH_BITS, numa_drngs,
   146			 lrng_sp80090b_compliant() ? "true" : "false",
   147			 lrng_pool_highres_timer() ? "true" : "false",
   148			 lrng_state_min_seeded() ? "true" : "false",
   149			 lrng_state_fully_seeded() ? "true" : "false");
 > 150		lrng_drng_unlock(lrng_drng_init, &flags);

151
152 seq_write(m, buf, strlen(buf));
153
154 return 0;
155 }
156

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#29 lore raw

PATCH v33 4/12 LRNG - add switchable DRNG support

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +7 -0
index 059b21d9728c..d3138458fd8b 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index e69c176f0161..31cfe87c999e 100644
@@ -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
drivers/char/lrng/lrng_switch.c new file +189 -0

189 lines not on this page · raw message

Signature · 1 line
2.26.2
#30 lore raw

PATCH v33 5/12 crypto: DRBG - externalize DRBG functions for LRNG

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 crypto/drbg.c         | 16 ++++++++++------
 include/crypto/drbg.h |  7 +++++++
 2 files changed, 17 insertions(+), 6 deletions(-)
crypto/drbg.c +10 -6
index e99fe34cfa00..3644e954785a 100644
@@ -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)
 {
include/crypto/drbg.h +7 -0
index c4165126937e..71d53e028e6d 100644
@@ -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 */
Signature · 1 line
2.26.2
#31 lore raw

PATCH v33 6/12 LRNG - add SP800-90A DRBG extension

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +12 -0
index d3138458fd8b..4ad26fdfbe7e 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index 31cfe87c999e..0d320fcb7b9e 100644
@@ -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
drivers/char/lrng/lrng_drbg.c new file +259 -0

259 lines not on this page · raw message

Signature · 1 line
2.26.2
#32 lore raw

PATCH v33 7/12 LRNG - add kernel crypto API PRNG extension

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +11 -0
index 4ad26fdfbe7e..ba3d84cd0676 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index 0d320fcb7b9e..94b2dfb2dfdb 100644
@@ -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
drivers/char/lrng/lrng_kcapi.c new file +321 -0

321 lines not on this page · raw message

Signature · 1 line
2.26.2
#33 lore raw

PATCH v33 8/12 crypto: provide access to a static Jitter RNG state

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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%)
crypto/jitterentropy-kcapi.c +1 -2
index eb7d1dd506bf..25a192f5984e 100644
@@ -43,8 +43,7 @@
 #include <linux/time.h>
 #include <linux/crypto.h>
 #include <crypto/internal/rng.h>
-
-#include "jitterentropy.h"
+#include <crypto/internal/jitterentropy.h>
 
 /***************************************************************************
  * Helper function
crypto/jitterentropy.c +30 -1
index 6e147c43fc18..fa1459f09b01 100644
@@ -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 <crypto/internal/jitterentropy.h>
 
 /***************************************************************************
  * 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 &lrng_jent_state;
+}
include/crypto/internal/jitterentropy.h renamed from crypto/jitterentropy.h +3 -0
similarity index 84%
rename from crypto/jitterentropy.h
rename to include/crypto/internal/jitterentropy.h
index c83fff32d130..6e07d86eac82 100644
@@ -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);
Signature · 1 line
2.26.2
#34 lore raw

PATCH v33 9/12 LRNG - add Jitter RNG fast noise source

In reply to Stephan Müller

From 4a94cf2db12d5d1f8fd3354ea0da2c5726f96ac7 Mon Sep 17 00:00:00 2001
From: Stephan Mueller <[email protected]>
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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +12 -0
index ba3d84cd0676..66a775a8f912 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index 94b2dfb2dfdb..4f5b6f38f0c4 100644
@@ -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
drivers/char/lrng/lrng_jent.c new file +88 -0

88 lines not on this page · raw message

Signature · 1 line
2.26.2
#35 lore raw

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

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 drivers/char/lrng/Kconfig       |  56 +++++
 drivers/char/lrng/Makefile      |   1 +
 drivers/char/lrng/lrng_health.c | 407 ++++++++++++++++++++++++++++++++
 3 files changed, 464 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_health.c
drivers/char/lrng/Kconfig +56 -0
index 66a775a8f912..70eee0f43d8c 100644
@@ -107,4 +107,60 @@ config LRNG_JENT
 	  time or at runtime with the lrng_base.jitterrng configuration
 	  variable.
 
+config LRNG_HEALTH_TESTS
+	bool "Enable noise source online health tests"
+	help
+	  The online health tests validate the noise source at
+	  runtime for fatal errors. These tests include SP800-90B
+	  compliant tests which are invoked if the system is booted
+	  with fips=1. In case of fatal errors during active
+	  SP800-90B tests, the issue is logged and the noise
+	  data is discarded. These tests are required for full
+	  compliance with SP800-90B.
+
+	  If unsure, say Y.
+
+config LRNG_RCT_BROKEN
+	bool "SP800-90B RCT with dangerous low cutoff value"
+	depends on LRNG_HEALTH_TESTS
+	depends on BROKEN
+	default n
+	help
+	  This option enables a dangerously low SP800-90B repetitive
+	  count test (RCT) cutoff value which makes it very likely
+	  that the RCT is triggered to raise a self test failure.
+
+	  This option is ONLY intended for developers wanting to
+	  test the effectiveness of the SP800-90B RCT health test.
+
+	  If unsure, say N.
+
+config LRNG_APT_BROKEN
+	bool "SP800-90B APT with dangerous low cutoff value"
+	depends on LRNG_HEALTH_TESTS
+	depends on BROKEN
+	default n
+	help
+	  This option enables a dangerously low SP800-90B adaptive
+	  proportion test (APT) cutoff value which makes it very
+	  likely that the RCT is triggered to raise a self test
+	  failure.
+
+	  This option is ONLY intended for developers wanting to
+	  test the effectiveness of the SP800-90B APT health test.
+
+	  If unsure, say N.
+
+# Default taken from SP800-90B sec 4.4.1 - significance level 2^-30
+config LRNG_RCT_CUTOFF
+	int
+	default 31 if !LRNG_RCT_BROKEN
+	default 1 if LRNG_RCT_BROKEN
+
+# Default taken from SP800-90B sec 4.4.2 - significance level 2^-30
+config LRNG_APT_CUTOFF
+	int
+	default 325 if !LRNG_APT_BROKEN
+	default 32 if LRNG_APT_BROKEN
+
 endif # LRNG
drivers/char/lrng/Makefile +1 -0
index 4f5b6f38f0c4..c3008763dd14 100644
@@ -14,3 +14,4 @@ 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
+obj-$(CONFIG_LRNG_HEALTH_TESTS)	+= lrng_health.o
drivers/char/lrng/lrng_health.c new file +407 -0

407 lines not on this page · raw message

Signature · 1 line
2.26.2
#36 lore raw

PATCH v33 11/12 LRNG - add interface for gathering of raw entropy

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +124 -0
index 70eee0f43d8c..4feabb0a20c2 100644
@@ -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 sampled.
+
+config LRNG_RAW_IRQFLAGS_ENTROPY
+	bool "Enable entropy test interface to IRQ flags noise source"
+	help
+	  The test interface allows a privileged process to capture
+	  the raw unconditioned interrupt flags 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_irqflags
+	  debugfs file. Using the option lrng_testing.boot_raw_irqflags_test=1
+	  the raw noise of the first 1000 entropy events since boot
+	  can be sampled.
+
+config LRNG_RAW_RETIP_ENTROPY
+	bool "Enable entropy test interface to RETIP value noise source"
+	help
+	  The test interface allows a privileged process to capture
+	  the raw unconditioned return instruction pointer value
+	  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_retip
+	  debugfs file. Using the option lrng_testing.boot_raw_retip_test=1
+	  the raw noise of the first 1000 entropy events since boot
+	  can be sampled.
+
+config LRNG_RAW_ARRAY
+	bool "Enable test interface to LRNG raw entropy storage array"
+	help
+	  The test interface allows a privileged process to capture
+	  the raw noise data that is collected by the LRNG
+	  in the per-CPU array for statistical analysis. The purpose
+	  of this interface is to verify that the array handling code
+	  truly only concatenates data and provides the same entropy
+	  rate as the raw unconditioned noise source when assessing
+	  the collected data byte-wise.
+
+	  The data can be obtained using the lrng_raw_array debugfs
+	  file. Using the option lrng_testing.boot_raw_array=1
+	  the raw noise of the first 1000 entropy events since boot
+	  can be sampled.
+
+config LRNG_IRQ_PERF
+	bool "Enable LRNG interrupt performance monitor"
+	help
+	  With this option, the performance monitor of the LRNG
+	  interrupt handling code is enabled. The file provides
+	  the execution time of the interrupt handler in
+	  cycles.
+
+	  The interrupt performance data can be obtained using
+	  the lrng_irq_perf debugfs file. Using the option
+	  lrng_testing.boot_irq_perf=1 the performance data of
+	  the first 1000 entropy events since boot can be sampled.
+
+config LRNG_TESTING
+	bool
+	default y if (LRNG_RAW_ENTROPY || LRNG_RAW_ARRAY || LRNG_IRQ_PERF)
+
+endif #LRNG_TESTING_MENU
+
 endif # LRNG
drivers/char/lrng/Makefile +1 -0
index c3008763dd14..b2ce1979dc4b 100644
@@ -15,3 +15,4 @@ obj-$(CONFIG_LRNG_DRBG)		+= lrng_drbg.o
 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
drivers/char/lrng/lrng_testing.c new file +575 -0

575 lines not on this page · raw message

Signature · 1 line
2.26.2
#37 lore raw

PATCH v33 12/12 LRNG - add power-on and runtime self-tests

In reply to 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 0xffffffff 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
CC Marcelo Henrique Cerri <[email protected]>
CC Neil Horman <[email protected]>
---
 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
drivers/char/lrng/Kconfig +25 -0
index 4feabb0a20c2..e8b7e9620123 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index b2ce1979dc4b..92219c565f66 100644
@@ -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
drivers/char/lrng/lrng_selftest.c new file +504 -0

504 lines not on this page · raw message

Signature · 1 line
2.26.2
#38 lore raw

Re: [PATCH v33 12/12] LRNG - add power-on and runtime self-tests

Thank you for the patch! Yet something to improve:

Hi "Stephan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on char-misc/char-misc-testing]
[also build test ERROR on cryptodev/master crypto/master v5.9-rc1 next-20200821] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200821-140523
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git d162219c655c8cf8003128a13840d6c1e183fb80
config: arm64-randconfig-s031-20200821 (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0

reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.2-191-g10164920-dirty
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=arm64

If you fix the issue, kindly add following tag as appropriate

All errors (new ones prefixed by >>):

aarch64-linux-ld: drivers/char/lrng/lrng_sw_noise.o: in function `add_interrupt_randomness':

>> drivers/char/lrng/lrng_sw_noise.c:113: undefined reference to `lrng_raw_irqflags_entropy_store'
   drivers/char/lrng/lrng_sw_noise.c:113:(.text+0x280): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `lrng_raw_irqflags_entropy_store'
>> aarch64-linux-ld: drivers/char/lrng/lrng_sw_noise.c:115: undefined reference to `lrng_raw_retip_entropy_store'
   drivers/char/lrng/lrng_sw_noise.c:115:(.text+0x2b4): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `lrng_raw_retip_entropy_store'
   aarch64-linux-ld: drivers/char/lrng/lrng_sw_noise.c:131: undefined reference to `lrng_raw_retip_entropy_store'
   drivers/char/lrng/lrng_sw_noise.c:131:(.text+0x368): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `lrng_raw_retip_entropy_store'
>> aarch64-linux-ld: drivers/char/lrng/lrng_sw_noise.c:146: undefined reference to `lrng_raw_jiffies_entropy_store'
   drivers/char/lrng/lrng_sw_noise.c:146:(.text+0x3d4): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `lrng_raw_jiffies_entropy_store'
>> aarch64-linux-ld: drivers/char/lrng/lrng_sw_noise.c:149: undefined reference to `lrng_raw_irqflags_entropy_store'

drivers/char/lrng/lrng_sw_noise.c:149:(.text+0x3f0): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `lrng_raw_irqflags_entropy_store'
aarch64-linux-ld: drivers/char/lrng/lrng_sw_noise.c:152: undefined reference to lrng_raw_retip_entropy_store' drivers/char/lrng/lrng_sw_noise.c:152:(.text+0x40c): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol lrng_raw_retip_entropy_store'

sparse warnings: (new ones prefixed by >>)

>> drivers/char/lrng/lrng_selftest.c:53:22: sparse: sparse: incorrect type in assignment (different base types) @@     expected unsigned int [usertype] @@     got restricted __le32 [usertype] @@
>> drivers/char/lrng/lrng_selftest.c:53:22: sparse:     expected unsigned int [usertype]
>> drivers/char/lrng/lrng_selftest.c:53:22: sparse:     got restricted __le32 [usertype]
>> drivers/char/lrng/lrng_selftest.c:53:22: sparse: sparse: incorrect type in assignment (different base types) @@     expected unsigned int [usertype] @@     got restricted __le32 [usertype] @@
>> drivers/char/lrng/lrng_selftest.c:53:22: sparse:     expected unsigned int [usertype]
>> drivers/char/lrng/lrng_selftest.c:53:22: sparse:     got restricted __le32 [usertype]

# https://github.com/0day-ci/linux/commit/04c2864db01edca77a5a59da7b074dc191a30dd8
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200821-140523 git checkout 04c2864db01edca77a5a59da7b074dc191a30dd8
vim +53 drivers/char/lrng/lrng_selftest.c

    46	
    47	static inline void lrng_selftest_bswap32(u32 *ptr, u32 words)
    48	{
    49		u32 i;
    50	
    51		/* Byte-swap data which is an LE representation */
    52		for (i = 0; i < words; i++) {
  > 53			*ptr = cpu_to_le32(*ptr);
    54			ptr++;
    55		}
    56	}
    57	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#39 lore raw

v34 cover /dev/random - a new approach with full SP800-90B compliance

In reply to 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 SP800-90A/SP800-90B compliant binary code (CONFIG_LRNG, CONFIG_LRNG_DRNG_SWITCH, CONFIG_LRNG_DRBG, CONFIG_LRNG_HEALTH_TESTS) uses some 61 kBytes. In addition, the LRNG is about 50% faster in the performance critical interrupt handler code path compared to the existing /dev/random implementation.

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 MIPS embedded device

[1] https://www.chronox.de/lrng.html - If the patch is accepted, I would be volunteering to convert the documentation into RST format and contribute it to the Linux kernel documentation directory.

[2] https://www.chronox.de/lrng/doc/lrng.pdf

Changes (compared to the previous patch set):

* fix all sparse warnings, partially reported by kernel test robot <[email protected]>

* ensure that DRBG or KCAPI backend can only be exclusively compiled if it is selected for static compilation - suggested by
Andy Lavr <[email protected]>

* fix Kconfig to enable compilation of lrng_testing.c in all possible configurations reported by kernel test robot <[email protected]>

* include trace/events/random.h to make lib/random32.c happy (even though the LRNG does not need this header file) reported by kernel test robot <[email protected]>

As a side node: With the switchable DRNG support offered in this patch set, the following areas could be removed. As the existing /dev/random has no support for switchable DRNGs, however, this is not yet feasible though.

* remove lrng_ready_list and all code around it in lrng_interfaces.c

* remove the kernel crypto API RNG API to avoid having two random number providing APIs - this would imply that all RNGs developed for this API would be converted to the LRNG interface

CC "Eric W. Biederman" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>

Stephan Mueller (12):
Linux Random Number Generator
LRNG - allocate one DRNG instance per NUMA node LRNG - sysctls and /proc interface
LRNG - add switchable DRNG support
crypto: DRBG - externalize DRBG functions for LRNG LRNG - add SP800-90A DRBG extension
LRNG - add kernel crypto API PRNG extension
crypto: provide access to a static Jitter RNG state LRNG - add Jitter RNG fast noise source LRNG - add SP800-90B compliant health tests LRNG - add interface for gathering of raw entropy LRNG - add power-on and runtime self-tests

 MAINTAINERS                                   |   7 +
 crypto/drbg.c                                 |  16 +-
 crypto/jitterentropy-kcapi.c                  |   3 +-
 crypto/jitterentropy.c                        |  31 +-
 drivers/char/Kconfig                          |   2 +
 drivers/char/Makefile                         |   9 +-
 drivers/char/lrng/Kconfig                     | 316 +++++++++
 drivers/char/lrng/Makefile                    |  19 +
 drivers/char/lrng/lrng_archrandom.c           |  93 +++
 drivers/char/lrng/lrng_aux.c                  | 136 ++++
 drivers/char/lrng/lrng_chacha20.c             | 321 +++++++++
 drivers/char/lrng/lrng_chacha20.h             |  29 +
 drivers/char/lrng/lrng_drbg.c                 | 259 +++++++
 drivers/char/lrng/lrng_drng.c                 | 409 +++++++++++
 drivers/char/lrng/lrng_health.c               | 407 +++++++++++
 drivers/char/lrng/lrng_interfaces.c           | 651 ++++++++++++++++++
 drivers/char/lrng/lrng_internal.h             | 351 ++++++++++
 drivers/char/lrng/lrng_jent.c                 |  88 +++
 drivers/char/lrng/lrng_kcapi.c                | 321 +++++++++
 drivers/char/lrng/lrng_lfsr.h                 | 152 ++++
 drivers/char/lrng/lrng_numa.c                 | 101 +++
 drivers/char/lrng/lrng_pool.c                 | 589 ++++++++++++++++
 drivers/char/lrng/lrng_proc.c                 | 163 +++++
 drivers/char/lrng/lrng_selftest.c             | 506 ++++++++++++++
 drivers/char/lrng/lrng_sw_noise.c             | 155 +++++
 drivers/char/lrng/lrng_sw_noise.h             |  57 ++
 drivers/char/lrng/lrng_switch.c               | 193 ++++++
 drivers/char/lrng/lrng_testing.c              | 575 ++++++++++++++++
 include/crypto/drbg.h                         |   7 +
 .../crypto/internal}/jitterentropy.h          |   3 +
 include/linux/lrng.h                          |  63 ++
 31 files changed, 6022 insertions(+), 10 deletions(-)
 create mode 100644 drivers/char/lrng/Kconfig
 create mode 100644 drivers/char/lrng/Makefile
 create mode 100644 drivers/char/lrng/lrng_archrandom.c
 create mode 100644 drivers/char/lrng/lrng_aux.c
 create mode 100644 drivers/char/lrng/lrng_chacha20.c
 create mode 100644 drivers/char/lrng/lrng_chacha20.h
 create mode 100644 drivers/char/lrng/lrng_drbg.c
 create mode 100644 drivers/char/lrng/lrng_drng.c
 create mode 100644 drivers/char/lrng/lrng_health.c
 create mode 100644 drivers/char/lrng/lrng_interfaces.c
 create mode 100644 drivers/char/lrng/lrng_internal.h
 create mode 100644 drivers/char/lrng/lrng_jent.c
 create mode 100644 drivers/char/lrng/lrng_kcapi.c
 create mode 100644 drivers/char/lrng/lrng_lfsr.h
 create mode 100644 drivers/char/lrng/lrng_numa.c
 create mode 100644 drivers/char/lrng/lrng_pool.c
 create mode 100644 drivers/char/lrng/lrng_proc.c
 create mode 100644 drivers/char/lrng/lrng_selftest.c
 create mode 100644 drivers/char/lrng/lrng_sw_noise.c
 create mode 100644 drivers/char/lrng/lrng_sw_noise.h
 create mode 100644 drivers/char/lrng/lrng_switch.c
 create mode 100644 drivers/char/lrng/lrng_testing.c
 rename {crypto => include/crypto/internal}/jitterentropy.h (84%)
 create mode 100644 include/linux/lrng.h
Signature · 1 line
2.26.2
#40 lore raw

PATCH v34 1/12 Linux Random Number Generator

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 except that it is capable of processing an entire word and that a different polynomial is used. The reason for the different polynomial is performance in a performance sensitive code section, the interrupt handler. The chosen polynomials have 4 taps. Also, this LFSR-approach is used in the OpenBSD /dev/random equivalent.

2. Concatenation: The temporary seed buffer used to seed the DRNG is a concatenation of parts of the entropy pool data, and the CPU noise source output.

The DRNG always tries to seed itself with 256 bits of entropy, except during boot. In any case, if the noise sources cannot deliver that amount, the available entropy is used and the DRNG keeps track on how much entropy it was seeded with. The entropy implied by the LRNG available in the entropy pool may be too conservative. To ensure that during boot time all available entropy from the entropy pool is transferred to the DRNG, the hash_df function always generates 256 data bits during boot to seed the DRNG. During boot, the DRNG is seeded as follows:

1. The DRNG is reseeded from the entropy pool and potentially the fast noise sources if the entropy pool has collected at least 32 bits of entropy from the interrupt noise source. The goal of this step is to ensure that the DRNG receives some initial entropy as early as possible. In addition it receives the entropy available from the fast noise sources.

2. The DRNG is reseeded from the entropy pool and potentially the fast noise sources if all noise sources collectively can provide at least 128 bits of entropy.

3. The DRNG is reseeded from the entropy pool and potentially the fast noise sources if all noise sources collectivel can provide at least 256 bits.

At the time of the reseeding steps, the DRNG requests as much entropy as is available in order to skip certain steps and reach the seeding level of 256 bits. This may imply that one or more of the aforementioned steps are skipped.

In all listed steps, the DRNG is (re)seeded with a number of random bytes from the entropy pool that is at most the amount of entropy present in the entropy pool. This means that when the entropy pool contains 128 or 256 bits of entropy, the DRNG is seeded with that amount of entropy as well.

Before the DRNG is seeded with 256 bits of entropy in step 3, requests of random data from /dev/random are not processed.

The hash_df operation providing random data from the entropy pool will always require that all entropy sources collectively can deliver at least 129 entropy bits as configured with (128 bits of entropy for seeding plus one bit of entropy that is lost with the post processing as defined in SP800-90B).

The DRNG operates as deterministic random number generator with the following properties:

* The maximum number of random bytes that can be generated with one DRNG generate operation is limited to 4096 bytes. When longer random numbers are requested, multiple DRNG generate operations are performed. The ChaCha20 DRNG as well as the SP800-90A DRBGs implement an update of their state after completing a generate request for backtracking resistance.

* The secondary DRNG is reseeded with whatever entropy is available – in the worst case where no additional entropy can be provided by the noise sources, the DRNG is not re-seeded and continues its operation to try to reseed again after again the expiry of one of these thresholds:

- If the last reseeding of the secondary DRNG is more than 600 seconds ago, or

- 2^20 DRNG generate operations are performed, whatever comes first, or

- the secondary DRNG is forced to reseed before the next generation of random numbers if data has been injected into the LRNG by writing data into /dev/random or /dev/urandom.

The chosen values prevent high-volume requests from user space to cause frequent reseeding operations which drag down the performance of the DRNG.

With the automatic reseeding after 600 seconds, the LRNG is triggered to reseed itself before the first request after a suspend that put the hardware to sleep for longer than 600 seconds.

The LRNG uses the following runtime memory using the currently smallest configuration:

* 576 bytes (512 bytes for the entropy pool and 64 for the entropy pool meta data) for the entropy pool management

* 64 bytes per CPU for the time stamp array

To support smaller devices including IoT environments, this patch allows reducing the runtime memory footprint of the LRNG at compile time by selecting smaller entropy pool sizes.

The entropy pool has support for sizes of 256, 128 and 64 bytes supported by primitive and irreducible polynomials.

The time stamp array is reduced to one atomic_t variable per CPU, i.e. 4 bytes when CONFIG_BASE_SMALL is selected during kernel configuration. This implies that after the receipt of 4 interrupts on one CPU, the data is injected into the LFSR. Depending on the behavior of the CPU caches, this may imply that the average interrupt handler execution time increases a bit, since instead of injecting 8 atomic_t values at one given time into the LFSR, only one is processed which may incur cache misses.

When selecting the compilation of a kernel for a small environment, prevent the allocation of a buffer up to 4096 bytes to serve user space requests. In this case, the stack variable of 64 bytes is used to serve all user space requests.

The LRNG has the following properties:

* internal noise source: interrupts timing with fast boot time seeding

* high performance of interrupt handling code: The LRNG impact on the interrupt handling has been reduced to a minimum. On one example system, the LRNG interrupt handling code executes within an average of 65 cycles whereas the existing /dev/random on the same device takes about 97 cycles when measuring the execution time of add_interrupt_randomness().

* lockless LFSR to collect raw entropy supporing concurrency-free use of massive parallel systems

* use of standalone ChaCha20 based RNG with the option to use a different DRNG selectable at compile time

* "atomic" seeding of secondary DRBG to ensure full entropy transport

* instantiate one DRNG per NUMA node

* support for runtime switchable output DRNGs

* use of only well-defined entropy-preserving operations to collect, compress and forward entropy: concatenation, LFSR, SP800-90A hash_df function

* compile-time selectable entropy pool size: the choice also uses the applicable LFSR polynomial to maintain the entropy pool size

* support of small systems by allowing the reduction of the runtime memory needs

Further details including the rationale for the design choices and properties of the LRNG together with testing is provided at [1]. In addition, the documentation explains the conducted regression tests to verify that the LRNG is API and ABI compatible with the existing /dev/random implementation.

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

CC: "Eric W. Biederman" <[email protected]>
CC: "Alexander E. Patrakov" <[email protected]>
CC: "Ahmed S. Darwish" <[email protected]>
CC: "Theodore Y. Ts'o" <[email protected]>
CC: Willy Tarreau <[email protected]>
CC: Matthew Garrett <[email protected]>
CC: Vito Caputo <[email protected]>
CC: Andreas Dilger <[email protected]>
CC: Jan Kara <[email protected]>
CC: Ray Strode <[email protected]>
CC: William Jon McCann <[email protected]>
CC: zhangjs <[email protected]>
CC: Andy Lutomirski <[email protected]>
CC: Florian Weimer <[email protected]>
CC: Lennart Poettering <[email protected]>
CC: Nicolai Stange <[email protected]>
Mathematical aspects Reviewed-by: "Peter, Matthias" <[email protected]>

---
 MAINTAINERS                         |   7 +
 drivers/char/Kconfig                |   2 +
 drivers/char/Makefile               |   9 +-
 drivers/char/lrng/Kconfig           |  68 +++
 drivers/char/lrng/Makefile          |   9 +
 drivers/char/lrng/lrng_archrandom.c |  93 ++++
 drivers/char/lrng/lrng_aux.c        | 136 ++++++
 drivers/char/lrng/lrng_chacha20.c   | 321 ++++++++++++++
 drivers/char/lrng/lrng_chacha20.h   |  29 ++
 drivers/char/lrng/lrng_drng.c       | 409 +++++++++++++++++
 drivers/char/lrng/lrng_interfaces.c | 652 ++++++++++++++++++++++++++++
 drivers/char/lrng/lrng_internal.h   | 342 +++++++++++++++
 drivers/char/lrng/lrng_lfsr.h       | 152 +++++++
 drivers/char/lrng/lrng_pool.c       | 589 +++++++++++++++++++++++++
 drivers/char/lrng/lrng_sw_noise.c   | 155 +++++++
 drivers/char/lrng/lrng_sw_noise.h   |  57 +++
 include/linux/lrng.h                |  63 +++
 17 files changed, 3092 insertions(+), 1 deletion(-)
 create mode 100644 drivers/char/lrng/Kconfig
 create mode 100644 drivers/char/lrng/Makefile
 create mode 100644 drivers/char/lrng/lrng_archrandom.c
 create mode 100644 drivers/char/lrng/lrng_aux.c
 create mode 100644 drivers/char/lrng/lrng_chacha20.c
 create mode 100644 drivers/char/lrng/lrng_chacha20.h
 create mode 100644 drivers/char/lrng/lrng_drng.c
 create mode 100644 drivers/char/lrng/lrng_interfaces.c
 create mode 100644 drivers/char/lrng/lrng_internal.h
 create mode 100644 drivers/char/lrng/lrng_lfsr.h
 create mode 100644 drivers/char/lrng/lrng_pool.c
 create mode 100644 drivers/char/lrng/lrng_sw_noise.c
 create mode 100644 drivers/char/lrng/lrng_sw_noise.h
 create mode 100644 include/linux/lrng.h
MAINTAINERS +7 -0
index deaafb617361..74f6fd1ba1ec 100644
@@ -10084,6 +10084,13 @@ F:	Documentation/litmus-tests/
 F:	Documentation/memory-barriers.txt
 F:	tools/memory-model/
 
+LINUX RANDOM NUMBER GENERATOR (LRNG) DRIVER
+M:	Stephan Mueller <[email protected]>
+S:	Maintained
+W:	https://www.chronox.de/lrng.html
+F:	drivers/char/lrng/*
+F:	include/linux/lrng.h
+
 LIS3LV02D ACCELEROMETER DRIVER
 M:	Eric Piel <[email protected]>
 S:	Maintained
drivers/char/Kconfig +2 -0
index b1bd336761b1..8a5b8a2db2c7 100644
@@ -470,6 +470,8 @@ config ADI
 	  and SSM (Silicon Secured Memory).  Intended consumers of this
 	  driver include crash and makedumpfile.
 
+source "drivers/char/lrng/Kconfig"
+
 endmenu
 
 config RANDOM_TRUST_CPU
drivers/char/Makefile +8 -1
index ffce287ef415..2110d3e28cf2 100644
@@ -3,7 +3,14 @@
 # Makefile for the kernel character device drivers.
 #
 
-obj-y				+= mem.o random.o
+obj-y				+= mem.o
+
+ifeq ($(CONFIG_LRNG),y)
+  obj-y				+= lrng/
+else
+  obj-y				+= random.o
+endif
+
 obj-$(CONFIG_TTY_PRINTK)	+= ttyprintk.o
 obj-y				+= misc.o
 obj-$(CONFIG_ATARI_DSP56K)	+= dsp56k.o
drivers/char/lrng/Kconfig new file +68 -0

68 lines not on this page · raw message

drivers/char/lrng/Makefile new file +9 -0
new file mode 100644
index 000000000000..1d2a0211973d
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the Linux Random Number Generator.
+#
+
+obj-y				+= lrng_pool.o lrng_aux.o \
+				   lrng_sw_noise.o lrng_archrandom.o \
+				   lrng_drng.o lrng_chacha20.o \
+				   lrng_interfaces.o \
drivers/char/lrng/lrng_archrandom.c new file +93 -0

93 lines not on this page · raw message

drivers/char/lrng/lrng_aux.c new file +136 -0

136 lines not on this page · raw message

drivers/char/lrng/lrng_chacha20.c new file +321 -0

321 lines not on this page · raw message

drivers/char/lrng/lrng_chacha20.h new file +29 -0
new file mode 100644
index 000000000000..1533b2490964
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
+/*
+ * LRNG ChaCha20 definitions
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller <[email protected]>
+ */
+
+#include <crypto/chacha.h>
+
+/* State according to RFC 7539 section 2.3 */
+struct chacha20_block {
+	u32 constants[4];
+	union {
+#define CHACHA_KEY_SIZE_WORDS (CHACHA_KEY_SIZE / sizeof(u32))
+		u32 u[CHACHA_KEY_SIZE_WORDS];
+		u8  b[CHACHA_KEY_SIZE];
+	} key __latent_entropy;
+	u32 counter;
+	u32 nonce[3] __latent_entropy;
+};
+
+static inline void lrng_cc20_init_rfc7539(struct chacha20_block *chacha20)
+{
+	/* String "expand 32-byte k" */
+	chacha20->constants[0] = 0x61707865;
+	chacha20->constants[1] = 0x3320646e;
+	chacha20->constants[2] = 0x79622d32;
+	chacha20->constants[3] = 0x6b206574;
+}
drivers/char/lrng/lrng_drng.c new file +409 -0

409 lines not on this page · raw message

drivers/char/lrng/lrng_interfaces.c new file +652 -0

652 lines not on this page · raw message

drivers/char/lrng/lrng_internal.h new file +342 -0

342 lines not on this page · raw message

drivers/char/lrng/lrng_lfsr.h new file +152 -0

152 lines not on this page · raw message

drivers/char/lrng/lrng_pool.c new file +589 -0

589 lines not on this page · raw message

drivers/char/lrng/lrng_sw_noise.c new file +155 -0

155 lines not on this page · raw message

drivers/char/lrng/lrng_sw_noise.h new file +57 -0

9 lines not on this page · raw message

include/linux/lrng.h new file +63 -0

63 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.26.2

Part of the diff is not shown here. View the raw message.

#41 lore raw

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

Thank you for the patch! Perhaps something to improve:

Hi "Stephan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on char-misc/char-misc-testing]
[also build test WARNING on cryptodev/master crypto/master v5.9-rc2 next-20200825] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200825-153914
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git d162219c655c8cf8003128a13840d6c1e183fb80
config: microblaze-randconfig-r023-20200825 (attached as .config)
compiler: microblaze-linux-gcc (GCC) 9.3.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=microblaze

If you fix the issue, kindly add following tag as appropriate

All warnings (new ones prefixed by >>):

>> drivers/char/lrng/lrng_drng.c:381:6: warning: no previous prototype for 'lrng_reset' [-Wmissing-prototypes]
     381 | void lrng_reset(void)
         |      ^~~~~~~~~~

# https://github.com/0day-ci/linux/commit/b5cc1c486b8491ab0a3817a48964bfd4797484c8
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200825-153914 git checkout b5cc1c486b8491ab0a3817a48964bfd4797484c8
vim +/lrng_reset +381 drivers/char/lrng/lrng_drng.c

380

 > 381	void lrng_reset(void)

382 {
383 schedule_work(&lrng_reset_work);
384 }
385

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#42 lore raw

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

Am Dienstag, 25. August 2020, 13:28:53 CEST schrieb kernel test robot:

Hi,

Quoted 6 lines

All warnings (new ones prefixed by >>):

Quoted 2 lines
Quoted 2 lines

drivers/char/lrng/lrng_drng.c:381:6: warning: no previous prototype for 'lrng_reset' [-Wmissing-prototypes]

     381 | void lrng_reset(void)

         |      ^~~~~~~~~~

The prototype is covered in an ifdef in lrng_internal.h as it is only needed for a specific configuration. I have moved the prototype out of that configuration conditional now.

Thanks.

Ciao
Stephan

#43 lore raw

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

In reply to Stephan Müller
Thank you for the patch! Yet something to improve:

Hi "Stephan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on char-misc/char-misc-testing]
[also build test ERROR on cryptodev/master crypto/master v5.9-rc3 next-20200828] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200825-153914
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git d162219c655c8cf8003128a13840d6c1e183fb80
config: riscv-allmodconfig (attached as .config)
compiler: riscv64-linux-gcc (GCC) 9.3.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=riscv

If you fix the issue, kindly add following tag as appropriate

All errors (new ones prefixed by >>):

In file included from drivers/char/lrng/lrng_pool.c:18:

>> drivers/char/lrng/lrng_lfsr.h:44:4: error: 'latent_entropy' attribute only applies to functions and variables
      44 |    atomic_t pool[LRNG_POOL_SIZE] __latent_entropy;
         |    ^~~~~~~~
--
   In file included from drivers/char/lrng/lrng_chacha20.c:17:
>> drivers/char/lrng/lrng_chacha20.h:17:2: error: 'latent_entropy' attribute only applies to functions and variables
      17 |  } key __latent_entropy;
         |  ^
   drivers/char/lrng/lrng_chacha20.h:19:2: error: 'latent_entropy' attribute only applies to functions and variables
      19 |  u32 nonce[3] __latent_entropy;
         |  ^~~

# https://github.com/0day-ci/linux/commit/b5cc1c486b8491ab0a3817a48964bfd4797484c8
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200825-153914 git checkout b5cc1c486b8491ab0a3817a48964bfd4797484c8
vim +/latent_entropy +44 drivers/char/lrng/lrng_lfsr.h

    16	
    17	/*
    18	 * This is the entropy pool used by the slow noise source. Its size should
    19	 * be at least as large as LRNG_DRNG_SECURITY_STRENGTH_BITS.
    20	 *
    21	 * The pool array is aligned to 8 bytes to comfort the kernel crypto API cipher
    22	 * implementations of the hash functions used to read the pool: for some
    23	 * accelerated implementations, we need an alignment to avoid a realignment
    24	 * which involves memcpy(). The alignment to 8 bytes should satisfy all crypto
    25	 * implementations.
    26	 *
    27	 * LRNG_POOL_SIZE is allowed to be changed only if the taps of the polynomial
    28	 * used for the LFSR are changed as well. The size must be in powers of 2 due
    29	 * to the mask handling in lrng_pool_lfsr_u32 which uses AND instead of modulo.
    30	 */
    31	struct lrng_pool {
    32		union {
    33			struct {
    34				/*
    35				 * hash_df implementation: counter, requested_bits and
    36				 * pool form a linear buffer that is used in the
    37				 * hash_df function specified in SP800-90A section
    38				 * 10.3.1
    39				 */
    40				unsigned char counter;
    41				__be32 requested_bits;
    42	
    43				/* Pool */
  > 44				atomic_t pool[LRNG_POOL_SIZE] __latent_entropy;
    45				/* Ptr into pool for next IRQ word injection */
    46				atomic_t pool_ptr;
    47				/* rotate for LFSR */
    48				atomic_t input_rotate;
    49				/* All NUMA DRNGs seeded? */
    50				bool all_online_numa_node_seeded;
    51				/* IRQ noise source status info */
    52				struct lrng_irq_info irq_info;
    53				/* Serialize read of entropy pool */
    54				spinlock_t lock;
    55			};
    56			/*
    57			 * Static SHA-1 implementation in lrng_cc20_hash_buffer
    58			 * processes data 64-byte-wise. Hence, ensure proper size
    59			 * of LRNG entropy pool data structure.
    60			 */
    61			u8 hash_input_buf[LRNG_POOL_SIZE_BYTES + 64];
    62		};
    63	};
    64	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#44 lore raw

PATCH v34 2/12 LRNG - allocate one DRNG instance per NUMA node

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Makefile +2 -0
index 1d2a0211973d..0a32f22c2c1a 100644
@@ -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
drivers/char/lrng/lrng_internal.h +5 -0
index f86afe8d2612..de034260c323 100644
@@ -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 **************************/
 
drivers/char/lrng/lrng_numa.c new file +101 -0

101 lines not on this page · raw message

Signature · 1 line
2.26.2
#45 lore raw

PATCH v34 3/12 LRNG - sysctls and /proc interface

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Makefile +1 -0
index 0a32f22c2c1a..e69c176f0161 100644
@@ -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
drivers/char/lrng/lrng_interfaces.c +0 -1
index ff8b73e4c936..78ebbfd20f0c 100644
@@ -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? */
drivers/char/lrng/lrng_internal.h +4 -0
index de034260c323..4ccfe53e6ce9 100644
@@ -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 *******************************/
 
drivers/char/lrng/lrng_proc.c new file +163 -0

163 lines not on this page · raw message

Signature · 1 line
2.26.2
#46 lore raw

PATCH v34 4/12 LRNG - add switchable DRNG support

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +7 -0
index 059b21d9728c..d3138458fd8b 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index e69c176f0161..31cfe87c999e 100644
@@ -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
drivers/char/lrng/lrng_switch.c new file +193 -0

193 lines not on this page · raw message

Signature · 1 line
2.26.2
#47 lore raw

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

Thank you for the patch! Yet something to improve:

Hi "Stephan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on char-misc/char-misc-testing]
[also build test ERROR on cryptodev/master crypto/master v5.9-rc3 next-20200828] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200825-153914
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git d162219c655c8cf8003128a13840d6c1e183fb80
config: riscv-allmodconfig (attached as .config)
compiler: riscv64-linux-gcc (GCC) 9.3.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=riscv

If you fix the issue, kindly add following tag as appropriate

All errors (new ones prefixed by >>):

drivers/char/lrng/lrng_switch.c: In function 'lrng_drng_switch':

>> drivers/char/lrng/lrng_switch.c:20:2: error: variable 'seed' with 'latent_entropy' attribute must not be local
      20 |  u8 seed[LRNG_DRNG_SECURITY_STRENGTH_BYTES] __latent_entropy;
         |  ^~

# https://github.com/0day-ci/linux/commit/b4a65336bab63ba2d7b4be76a1acad8eb6b63daf
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Stephan-M-ller/dev-random-a-new-approach-with-full-SP800-90B-compliance/20200825-153914 git checkout b4a65336bab63ba2d7b4be76a1acad8eb6b63daf
vim +20 drivers/char/lrng/lrng_switch.c

    13	
    14	static int lrng_drng_switch(struct lrng_drng *drng_store,
    15				    const struct lrng_crypto_cb *cb, int node)
    16	{
    17		const struct lrng_crypto_cb *old_cb;
    18		unsigned long flags = 0;
    19		int ret;
  > 20		u8 seed[LRNG_DRNG_SECURITY_STRENGTH_BYTES] __latent_entropy;
    21		void *new_drng = cb->lrng_drng_alloc(LRNG_DRNG_SECURITY_STRENGTH_BYTES);
    22		void *old_drng, *new_hash, *old_hash;
    23		bool sl = false, reset_drng = !lrng_get_available();
    24	
    25		if (IS_ERR(new_drng)) {
    26			pr_warn("could not allocate new DRNG for NUMA node %d (%ld)\n",
    27				node, PTR_ERR(new_drng));
    28			return PTR_ERR(new_drng);
    29		}
    30	
    31		/*
    32		 * The seed potentially used as MAC key is undefined to add some
    33		 * variation. Yet, the security of the MAC does not rely on the key
    34		 * being secret. The key is only there to turn a MAC into a hash.
    35		 * The intention is to allow the specification of CMAC(AES) as "hash"
    36		 * to limit the dependency to AES when using the CTR DRBG.
    37		 */
    38		new_hash = cb->lrng_hash_alloc(seed, sizeof(seed));
    39		if (IS_ERR(new_hash)) {
    40			pr_warn("could not allocate new LRNG pool hash (%ld)\n",
    41				PTR_ERR(new_hash));
    42			cb->lrng_drng_dealloc(new_drng);
    43			return PTR_ERR(new_hash);
    44		}
    45	
    46		lrng_drng_lock(drng_store, &flags);
    47	
    48		/*
    49		 * Pull from existing DRNG to seed new DRNG regardless of seed status
    50		 * of old DRNG -- the entropy state for the DRNG is left unchanged which
    51		 * implies that als the new DRNG is reseeded when deemed necessary. This
    52		 * seeding of the new DRNG shall only ensure that the new DRNG has the
    53		 * same entropy as the old DRNG.
    54		 */
    55		ret = drng_store->crypto_cb->lrng_drng_generate_helper(
    56					drng_store->drng, seed, sizeof(seed));
    57		lrng_drng_unlock(drng_store, &flags);
    58	
    59		if (ret < 0) {
    60			reset_drng = true;
    61			pr_warn("getting random data from DRNG failed for NUMA node %d (%d)\n",
    62				node, ret);
    63		} else {
    64			/* seed new DRNG with data */
    65			ret = cb->lrng_drng_seed_helper(new_drng, seed, ret);
    66			if (ret < 0) {
    67				reset_drng = true;
    68				pr_warn("seeding of new DRNG failed for NUMA node %d (%d)\n",
    69					node, ret);
    70			} else {
    71				pr_debug("seeded new DRNG of NUMA node %d instance from old DRNG instance\n",
    72					 node);
    73			}
    74		}
    75	
    76		mutex_lock(&drng_store->lock);
    77		/*
    78		 * If we switch the DRNG from the initial ChaCha20 DRNG to something
    79		 * else, there is a lock transition from spin lock to mutex (see
    80		 * lrng_drng_is_atomic and how the lock is taken in lrng_drng_lock).
    81		 * Thus, we need to take both locks during the transition phase.
    82		 */
    83		if (lrng_drng_is_atomic(drng_store)) {
    84			spin_lock_irqsave(&drng_store->spin_lock, flags);
    85			sl = true;
    86		} else {
    87			__acquire(&drng_store->spin_lock);
    88		}
    89	
    90		if (reset_drng)
    91			lrng_drng_reset(drng_store);
    92	
    93		old_drng = drng_store->drng;
    94		old_cb = drng_store->crypto_cb;
    95		drng_store->drng = new_drng;
    96		drng_store->crypto_cb = cb;
    97	
    98		old_hash = drng_store->hash;
    99		drng_store->hash = new_hash;

100 pr_info("Entropy pool read-hash allocated for DRNG for NUMA node %d\n",
101 node);
102
103 if (sl)
104 spin_unlock_irqrestore(&drng_store->spin_lock, flags);
105 else
106 __release(&drng_store->spin_lock);
107 mutex_unlock(&drng_store->lock);
108
109 /* ChaCha20 serves as atomic instance left untouched. */
110 if (old_drng != &chacha20) {
111 old_cb->lrng_drng_dealloc(old_drng);
112 old_cb->lrng_hash_dealloc(old_hash);
113 }
114
115 pr_info("DRNG of NUMA node %d switched\n", node);
116
117 return 0;
118 }
119

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#48 lore raw

PATCH v34 5/12 crypto: DRBG - externalize DRBG functions for LRNG

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 crypto/drbg.c         | 16 ++++++++++------
 include/crypto/drbg.h |  7 +++++++
 2 files changed, 17 insertions(+), 6 deletions(-)
crypto/drbg.c +10 -6
index e99fe34cfa00..3644e954785a 100644
@@ -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)
 {
include/crypto/drbg.h +7 -0
index c4165126937e..71d53e028e6d 100644
@@ -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 */
Signature · 1 line
2.26.2
#49 lore raw

PATCH v34 6/12 LRNG - add SP800-90A DRBG extension

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +12 -0
index d3138458fd8b..4f2b757a8962 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index 31cfe87c999e..0d320fcb7b9e 100644
@@ -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
drivers/char/lrng/lrng_drbg.c new file +259 -0

259 lines not on this page · raw message

Signature · 1 line
2.26.2
#50 lore raw

PATCH v34 7/12 LRNG - add kernel crypto API PRNG extension

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +12 -0
index 4f2b757a8962..c89de14d173a 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index 0d320fcb7b9e..94b2dfb2dfdb 100644
@@ -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
drivers/char/lrng/lrng_kcapi.c new file +321 -0

321 lines not on this page · raw message

Signature · 1 line
2.26.2
#51 lore raw

PATCH v34 8/12 crypto: provide access to a static Jitter RNG state

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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%)
crypto/jitterentropy-kcapi.c +1 -2
index eb7d1dd506bf..25a192f5984e 100644
@@ -43,8 +43,7 @@
 #include <linux/time.h>
 #include <linux/crypto.h>
 #include <crypto/internal/rng.h>
-
-#include "jitterentropy.h"
+#include <crypto/internal/jitterentropy.h>
 
 /***************************************************************************
  * Helper function
crypto/jitterentropy.c +30 -1
index 6e147c43fc18..fa1459f09b01 100644
@@ -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 <crypto/internal/jitterentropy.h>
 
 /***************************************************************************
  * 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 &lrng_jent_state;
+}
include/crypto/internal/jitterentropy.h renamed from crypto/jitterentropy.h +3 -0
similarity index 84%
rename from crypto/jitterentropy.h
rename to include/crypto/internal/jitterentropy.h
index c83fff32d130..6e07d86eac82 100644
@@ -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);
Signature · 1 line
2.26.2
#52 lore raw

PATCH v34 9/12 LRNG - add Jitter RNG fast noise source

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +12 -0
index c89de14d173a..377593fc1985 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index 94b2dfb2dfdb..4f5b6f38f0c4 100644
@@ -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
drivers/char/lrng/lrng_jent.c new file +88 -0

88 lines not on this page · raw message

Signature · 1 line
2.26.2
#53 lore raw

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

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 drivers/char/lrng/Kconfig       |  56 +++++
 drivers/char/lrng/Makefile      |   1 +
 drivers/char/lrng/lrng_health.c | 407 ++++++++++++++++++++++++++++++++
 3 files changed, 464 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_health.c
drivers/char/lrng/Kconfig +56 -0
index 377593fc1985..452ee4adb577 100644
@@ -108,4 +108,60 @@ config LRNG_JENT
 	  time or at runtime with the lrng_base.jitterrng configuration
 	  variable.
 
+config LRNG_HEALTH_TESTS
+	bool "Enable noise source online health tests"
+	help
+	  The online health tests validate the noise source at
+	  runtime for fatal errors. These tests include SP800-90B
+	  compliant tests which are invoked if the system is booted
+	  with fips=1. In case of fatal errors during active
+	  SP800-90B tests, the issue is logged and the noise
+	  data is discarded. These tests are required for full
+	  compliance with SP800-90B.
+
+	  If unsure, say Y.
+
+config LRNG_RCT_BROKEN
+	bool "SP800-90B RCT with dangerous low cutoff value"
+	depends on LRNG_HEALTH_TESTS
+	depends on BROKEN
+	default n
+	help
+	  This option enables a dangerously low SP800-90B repetitive
+	  count test (RCT) cutoff value which makes it very likely
+	  that the RCT is triggered to raise a self test failure.
+
+	  This option is ONLY intended for developers wanting to
+	  test the effectiveness of the SP800-90B RCT health test.
+
+	  If unsure, say N.
+
+config LRNG_APT_BROKEN
+	bool "SP800-90B APT with dangerous low cutoff value"
+	depends on LRNG_HEALTH_TESTS
+	depends on BROKEN
+	default n
+	help
+	  This option enables a dangerously low SP800-90B adaptive
+	  proportion test (APT) cutoff value which makes it very
+	  likely that the RCT is triggered to raise a self test
+	  failure.
+
+	  This option is ONLY intended for developers wanting to
+	  test the effectiveness of the SP800-90B APT health test.
+
+	  If unsure, say N.
+
+# Default taken from SP800-90B sec 4.4.1 - significance level 2^-30
+config LRNG_RCT_CUTOFF
+	int
+	default 31 if !LRNG_RCT_BROKEN
+	default 1 if LRNG_RCT_BROKEN
+
+# Default taken from SP800-90B sec 4.4.2 - significance level 2^-30
+config LRNG_APT_CUTOFF
+	int
+	default 325 if !LRNG_APT_BROKEN
+	default 32 if LRNG_APT_BROKEN
+
 endif # LRNG
drivers/char/lrng/Makefile +1 -0
index 4f5b6f38f0c4..c3008763dd14 100644
@@ -14,3 +14,4 @@ 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
+obj-$(CONFIG_LRNG_HEALTH_TESTS)	+= lrng_health.o
drivers/char/lrng/lrng_health.c new file +407 -0

407 lines not on this page · raw message

Signature · 1 line
2.26.2
#54 lore raw

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

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +124 -0
index 452ee4adb577..de20f189e297 100644
@@ -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 sampled.
+
+config LRNG_RAW_IRQFLAGS_ENTROPY
+	bool "Enable entropy test interface to IRQ flags noise source"
+	help
+	  The test interface allows a privileged process to capture
+	  the raw unconditioned interrupt flags 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_irqflags
+	  debugfs file. Using the option lrng_testing.boot_raw_irqflags_test=1
+	  the raw noise of the first 1000 entropy events since boot
+	  can be sampled.
+
+config LRNG_RAW_RETIP_ENTROPY
+	bool "Enable entropy test interface to RETIP value noise source"
+	help
+	  The test interface allows a privileged process to capture
+	  the raw unconditioned return instruction pointer value
+	  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_retip
+	  debugfs file. Using the option lrng_testing.boot_raw_retip_test=1
+	  the raw noise of the first 1000 entropy events since boot
+	  can be sampled.
+
+config LRNG_RAW_ARRAY
+	bool "Enable test interface to LRNG raw entropy storage array"
+	help
+	  The test interface allows a privileged process to capture
+	  the raw noise data that is collected by the LRNG
+	  in the per-CPU array for statistical analysis. The purpose
+	  of this interface is to verify that the array handling code
+	  truly only concatenates data and provides the same entropy
+	  rate as the raw unconditioned noise source when assessing
+	  the collected data byte-wise.
+
+	  The data can be obtained using the lrng_raw_array debugfs
+	  file. Using the option lrng_testing.boot_raw_array=1
+	  the raw noise of the first 1000 entropy events since boot
+	  can be sampled.
+
+config LRNG_IRQ_PERF
+	bool "Enable LRNG interrupt performance monitor"
+	help
+	  With this option, the performance monitor of the LRNG
+	  interrupt handling code is enabled. The file provides
+	  the execution time of the interrupt handler in
+	  cycles.
+
+	  The interrupt performance data can be obtained using
+	  the lrng_irq_perf debugfs file. Using the option
+	  lrng_testing.boot_irq_perf=1 the performance data of
+	  the first 1000 entropy events since boot can be sampled.
+
+config LRNG_TESTING
+	bool
+	default y if (LRNG_RAW_HIRES_ENTROPY || LRNG_RAW_JIFFIES_ENTROPY ||LRNG_RAW_IRQ_ENTROPY || LRNG_RAW_IRQFLAGS_ENTROPY || LRNG_RAW_RETIP_ENTROPY || LRNG_RAW_ARRAY || LRNG_IRQ_PERF)
+
+endif #LRNG_TESTING_MENU
+
 endif # LRNG
drivers/char/lrng/Makefile +1 -0
index c3008763dd14..b2ce1979dc4b 100644
@@ -15,3 +15,4 @@ obj-$(CONFIG_LRNG_DRBG)		+= lrng_drbg.o
 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
drivers/char/lrng/lrng_testing.c new file +575 -0

575 lines not on this page · raw message

Signature · 1 line
2.26.2
#55 lore raw

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

In reply to 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 0xffffffff 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
CC Marcelo Henrique Cerri <[email protected]>
CC Neil Horman <[email protected]>
---
 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
drivers/char/lrng/Kconfig +25 -0
index de20f189e297..b75d809bed50 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index b2ce1979dc4b..92219c565f66 100644
@@ -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
drivers/char/lrng/lrng_selftest.c new file +506 -0

506 lines not on this page · raw message

Signature · 1 line
2.26.2
#56 lore raw

v35 cover /dev/random - a new approach

In reply to 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 MIPS embedded device

* testing with GCC and Clang

[1] https://www.chronox.de/lrng.html - If the patch is accepted, I would be volunteering to convert the documentation into RST format and contribute it to the Linux kernel documentation directory.

[2] https://www.chronox.de/lrng/doc/lrng.pdf

[3] https://www.chronox.de/chacha20_drng.html

Changes (compared to the previous patch set):

* replace hash_df operation with simple hash to make code leaner without affecting entropy statements

* replace central LFSR with per-CPU entropy pools which implies that LRNG only uses a hash for conditioning - this makes data processing much cleaner (see [2] section 2.2) entropy assessment significantly easier (see [2] section 3.2.6)

* add aux_pool to process data received from user space and add_hwgenerator_randomness with a cryptographic hash compliant to SP800-90B section 3.1.6 to allow data from those sources and stay SP800-90B compliant

* remove duplicated code - add lrng_kcapi_hash.c to consolidate hash handling code from lrng_drbg.c and lrng_kcapi.c

* ensure that the NUMA pool allocation also allocates the hash instance as a precaution in case the DRNG switching code is executed before the NUMA allocation

* Make invocation of SHA-1 compliant to FIPS 180-4

* Addition of test interface for interrupt registers noise data - with that interface, all data potentially delivering entropy can be sampled.

* Addition of ACVT interface to validate correct invocation of SHA by LRNG (for test definition, see https://github.com/usnistgov/ACVP) - interface was used for successful testing of the SHA-256 and SHA-1 handling of the LRNG.

* remove superfluous backslash from Makefile reported by Andy Lavr <[email protected]>

* move prototype of lrng_reset() to a spot in lrng_internal.h that is compiled unconditional as requested by kernel test robot <[email protected]>

* correctly advance *ppos in DebugFS read function for testing interfaces preventing successive read operations

* fix __latent_entropy usage as reported by kernel test robot <[email protected]>

* use compxch_release / smp_load_acquire to set NUMA pool as suggested by Eric Biggers

CC "Eric W. Biederman" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
CC Eric Biggers <[email protected]>

Stephan Mueller (13):
Linux Random Number Generator
LRNG - allocate one DRNG instance per NUMA node LRNG - sysctls and /proc interface
LRNG - add switchable DRNG support
LRNG - add common generic hash support
crypto: DRBG - externalize DRBG functions for LRNG LRNG - add SP800-90A DRBG extension
LRNG - add kernel crypto API PRNG extension
crypto: provide access to a static Jitter RNG state LRNG - add Jitter RNG fast noise source LRNG - add SP800-90B compliant health tests LRNG - add interface for gathering of raw entropy LRNG - add power-on and runtime self-tests

 MAINTAINERS                                   |   7 +
 crypto/drbg.c                                 |  16 +-
 crypto/jitterentropy-kcapi.c                  |   3 +-
 crypto/jitterentropy.c                        |  31 +-
 drivers/char/Kconfig                          |   2 +
 drivers/char/Makefile                         |   9 +-
 drivers/char/lrng/Kconfig                     | 353 +++++++++
 drivers/char/lrng/Makefile                    |  20 +
 drivers/char/lrng/lrng_archrandom.c           |  93 +++
 drivers/char/lrng/lrng_aux.c                  | 136 ++++
 drivers/char/lrng/lrng_chacha20.c             | 352 +++++++++
 drivers/char/lrng/lrng_chacha20.h             |  29 +
 drivers/char/lrng/lrng_drbg.c                 | 197 +++++
 drivers/char/lrng/lrng_drng.c                 | 406 +++++++++++
 drivers/char/lrng/lrng_health.c               | 407 +++++++++++
 drivers/char/lrng/lrng_interfaces.c           | 649 +++++++++++++++++
 drivers/char/lrng/lrng_internal.h             | 426 +++++++++++
 drivers/char/lrng/lrng_jent.c                 |  88 +++
 drivers/char/lrng/lrng_kcapi.c                | 228 ++++++
 drivers/char/lrng/lrng_kcapi_hash.c           |  97 +++
 drivers/char/lrng/lrng_kcapi_hash.h           |  19 +
 drivers/char/lrng/lrng_numa.c                 | 108 +++
 drivers/char/lrng/lrng_pool.c                 | 478 ++++++++++++
 drivers/char/lrng/lrng_proc.c                 | 181 +++++
 drivers/char/lrng/lrng_selftest.c             | 344 +++++++++
 drivers/char/lrng/lrng_sw_noise.c             | 461 ++++++++++++
 drivers/char/lrng/lrng_sw_noise.h             |  56 ++
 drivers/char/lrng/lrng_switch.c               | 203 ++++++
 drivers/char/lrng/lrng_testing.c              | 687 ++++++++++++++++++
 include/crypto/drbg.h                         |   7 +
 .../crypto/internal}/jitterentropy.h          |   3 +
 include/linux/lrng.h                          |  79 ++
 32 files changed, 6165 insertions(+), 10 deletions(-)
 create mode 100644 drivers/char/lrng/Kconfig
 create mode 100644 drivers/char/lrng/Makefile
 create mode 100644 drivers/char/lrng/lrng_archrandom.c
 create mode 100644 drivers/char/lrng/lrng_aux.c
 create mode 100644 drivers/char/lrng/lrng_chacha20.c
 create mode 100644 drivers/char/lrng/lrng_chacha20.h
 create mode 100644 drivers/char/lrng/lrng_drbg.c
 create mode 100644 drivers/char/lrng/lrng_drng.c
 create mode 100644 drivers/char/lrng/lrng_health.c
 create mode 100644 drivers/char/lrng/lrng_interfaces.c
 create mode 100644 drivers/char/lrng/lrng_internal.h
 create mode 100644 drivers/char/lrng/lrng_jent.c
 create mode 100644 drivers/char/lrng/lrng_kcapi.c
 create mode 100644 drivers/char/lrng/lrng_kcapi_hash.c
 create mode 100644 drivers/char/lrng/lrng_kcapi_hash.h
 create mode 100644 drivers/char/lrng/lrng_numa.c
 create mode 100644 drivers/char/lrng/lrng_pool.c
 create mode 100644 drivers/char/lrng/lrng_proc.c
 create mode 100644 drivers/char/lrng/lrng_selftest.c
 create mode 100644 drivers/char/lrng/lrng_sw_noise.c
 create mode 100644 drivers/char/lrng/lrng_sw_noise.h
 create mode 100644 drivers/char/lrng/lrng_switch.c
 create mode 100644 drivers/char/lrng/lrng_testing.c
 rename {crypto => include/crypto/internal}/jitterentropy.h (84%)
 create mode 100644 include/linux/lrng.h
Signature · 1 line
2.26.2
#57 lore raw

PATCH v35 1/13 Linux Random Number Generator

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 as well as auxiliary 32 bit words are concatenated to fill the per-CPU data array that is capable of holding 64 8-bit words.

3. Hashing: A set of concatenated time stamp data received from the interrupts are hashed together with the current existing per-CPU entropy pool state. The resulting message digest is the new per-CPU entropy pool state.

4. Hashing: When new data is added to the auxiliary pool, the data is hashed together with the auxiliary pool to form a new auxiliary pool state.

5. Hashing: A message digest of all per-CPU entropy pools and the auxiliary pool is calculated which forms the new auxiliary pool state. At the same time, this message digest is used to fill the slow noise source output buffer discussed in the following.

6. Truncation: The most-significant bits (MSB) defined by the requested number of bits (commonly equal to the security strength of the DRBG) or the entropy available transported with the buffer (which is the minimum of the message digest size and the available entropy in all entropy pools and the auxiliary pool), whatever is smaller, are obtained from the slow noise source output buffer.

7. Concatenation: The temporary seed buffer used to seed the DRNG is a concatenation of the slow noise source buffer, the Jitter RNG output, the CPU noise source output, and the current time.

The DRNG always tries to seed itself with 256 bits of entropy, except during boot. In any case, if the noise sources cannot deliver that amount, the available entropy is used and the DRNG keeps track on how much entropy it was seeded with. The entropy implied by the LRNG available in the entropy pool may be too conservative. To ensure that during boot time all available entropy from the entropy pool is transferred to the DRNG, the hash_df function always generates 256 data bits during boot to seed the DRNG. During boot, the DRNG is seeded as follows:

1. The DRNG is reseeded from the entropy pool and potentially the fast noise sources if the entropy pool has collected at least 32 bits of entropy from the interrupt noise source. The goal of this step is to ensure that the DRNG receives some initial entropy as early as possible. In addition it receives the entropy available from the fast noise sources.

2. The DRNG is reseeded from the entropy pool and potentially the fast noise sources if all noise sources collectively can provide at least 128 bits of entropy.

3. The DRNG is reseeded from the entropy pool and potentially the fast noise sources if all noise sources collectivel can provide at least 256 bits.

At the time of the reseeding steps, the DRNG requests as much entropy as is available in order to skip certain steps and reach the seeding level of 256 bits. This may imply that one or more of the aforementioned steps are skipped.

In all listed steps, the DRNG is (re)seeded with a number of random bytes from the entropy pool that is at most the amount of entropy present in the entropy pool. This means that when the entropy pool contains 128 or 256 bits of entropy, the DRNG is seeded with that amount of entropy as well.

Before the DRNG is seeded with 256 bits of entropy in step 3, requests of random data from /dev/random and the getrandom system call are not processed.

The hash operation providing random data from the entropy pools will always require that all entropy sources collectively can deliver at least 128 entropy bits.

The DRNG operates as deterministic random number generator with the following properties:

* The maximum number of random bytes that can be generated with one DRNG generate operation is limited to 4096 bytes. When longer random numbers are requested, multiple DRNG generate operations are performed. The ChaCha20 DRNG as well as the SP800-90A DRBGs implement an update of their state after completing a generate request for backtracking resistance.

* The secondary DRNG is reseeded with whatever entropy is available – in the worst case where no additional entropy can be provided by the noise sources, the DRNG is not re-seeded and continues its operation to try to reseed again after again the expiry of one of these thresholds:

- If the last reseeding of the secondary DRNG is more than 600 seconds ago, or

- 2^20 DRNG generate operations are performed, whatever comes first, or

- the secondary DRNG is forced to reseed before the next generation of random numbers if data has been injected into the LRNG by writing data into /dev/random or /dev/urandom.

The chosen values prevent high-volume requests from user space to cause frequent reseeding operations which drag down the performance of the DRNG.

With the automatic reseeding after 600 seconds, the LRNG is triggered to reseed itself before the first request after a suspend that put the hardware to sleep for longer than 600 seconds.

To support smaller devices including IoT environments, this patch allows reducing the runtime memory footprint of the LRNG at compile time by selecting smaller collection data sizes.

When selecting the compilation of a kernel for a small environment, prevent the allocation of a buffer up to 4096 bytes to serve user space requests. In this case, the stack variable of 64 bytes is used to serve all user space requests.

The LRNG has the following properties:

* internal noise source: interrupts timing with fast boot time seeding

* high performance of interrupt handling code: The LRNG impact on the interrupt handling has been reduced to a minimum. On one example system, the LRNG interrupt handling code in its fastest configuration executes within an average 55 cycles whereas the existing /dev/random on the same device takes about 97 cycles when measuring the execution time of add_interrupt_randomness().

* use of almost never contended lock for hashing operation to collect raw entropy supporting concurrency-free use of massive parallel systems - worst case rate of contention is the number of DRNG reseeds, usually: number of NUMA nodes contentions per 5 minutes.

* use of standalone ChaCha20 based RNG with the option to use a different DRNG selectable at compile time

* instantiate one DRNG per NUMA node

* support for runtime switchable output DRNGs

* use of runtime-switchable hash for conditioning implementation following widely accepted approach

* compile-time selectable collection size

* support of small systems by allowing the reduction of the runtime memory needs

Further details including the rationale for the design choices and properties of the LRNG together with testing is provided at [1]. In addition, the documentation explains the conducted regression tests to verify that the LRNG is API and ABI compatible with the existing /dev/random implementation.

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

CC: "Eric W. Biederman" <[email protected]>
CC: "Alexander E. Patrakov" <[email protected]>
CC: "Ahmed S. Darwish" <[email protected]>
CC: "Theodore Y. Ts'o" <[email protected]>
CC: Willy Tarreau <[email protected]>
CC: Matthew Garrett <[email protected]>
CC: Vito Caputo <[email protected]>
CC: Andreas Dilger <[email protected]>
CC: Jan Kara <[email protected]>
CC: Ray Strode <[email protected]>
CC: William Jon McCann <[email protected]>
CC: zhangjs <[email protected]>
CC: Andy Lutomirski <[email protected]>
CC: Florian Weimer <[email protected]>
CC: Lennart Poettering <[email protected]>
CC: Nicolai Stange <[email protected]>
Mathematical aspects Reviewed-by: "Peter, Matthias" <[email protected]>

---
 MAINTAINERS                         |   7 +
 drivers/char/Kconfig                |   2 +
 drivers/char/Makefile               |   9 +-
 drivers/char/lrng/Kconfig           |  72 +++
 drivers/char/lrng/Makefile          |   9 +
 drivers/char/lrng/lrng_archrandom.c |  93 ++++
 drivers/char/lrng/lrng_aux.c        | 136 ++++++
 drivers/char/lrng/lrng_chacha20.c   | 352 +++++++++++++++
 drivers/char/lrng/lrng_chacha20.h   |  29 ++
 drivers/char/lrng/lrng_drng.c       | 406 +++++++++++++++++
 drivers/char/lrng/lrng_interfaces.c | 651 ++++++++++++++++++++++++++++
 drivers/char/lrng/lrng_internal.h   | 417 ++++++++++++++++++
 drivers/char/lrng/lrng_pool.c       | 478 ++++++++++++++++++++
 drivers/char/lrng/lrng_sw_noise.c   | 461 ++++++++++++++++++++
 drivers/char/lrng/lrng_sw_noise.h   |  56 +++
 include/linux/lrng.h                |  79 ++++
 16 files changed, 3256 insertions(+), 1 deletion(-)
 create mode 100644 drivers/char/lrng/Kconfig
 create mode 100644 drivers/char/lrng/Makefile
 create mode 100644 drivers/char/lrng/lrng_archrandom.c
 create mode 100644 drivers/char/lrng/lrng_aux.c
 create mode 100644 drivers/char/lrng/lrng_chacha20.c
 create mode 100644 drivers/char/lrng/lrng_chacha20.h
 create mode 100644 drivers/char/lrng/lrng_drng.c
 create mode 100644 drivers/char/lrng/lrng_interfaces.c
 create mode 100644 drivers/char/lrng/lrng_internal.h
 create mode 100644 drivers/char/lrng/lrng_pool.c
 create mode 100644 drivers/char/lrng/lrng_sw_noise.c
 create mode 100644 drivers/char/lrng/lrng_sw_noise.h
 create mode 100644 include/linux/lrng.h
MAINTAINERS +7 -0
index 0d0862b19ce5..006ff84ee874 100644
@@ -10109,6 +10109,13 @@ F:	Documentation/litmus-tests/
 F:	Documentation/memory-barriers.txt
 F:	tools/memory-model/
 
+LINUX RANDOM NUMBER GENERATOR (LRNG) DRIVER
+M:	Stephan Mueller <[email protected]>
+S:	Maintained
+W:	https://www.chronox.de/lrng.html
+F:	drivers/char/lrng/*
+F:	include/linux/lrng.h
+
 LIS3LV02D ACCELEROMETER DRIVER
 M:	Eric Piel <[email protected]>
 S:	Maintained
drivers/char/Kconfig +2 -0
index b1bd336761b1..8a5b8a2db2c7 100644
@@ -470,6 +470,8 @@ config ADI
 	  and SSM (Silicon Secured Memory).  Intended consumers of this
 	  driver include crash and makedumpfile.
 
+source "drivers/char/lrng/Kconfig"
+
 endmenu
 
 config RANDOM_TRUST_CPU
drivers/char/Makefile +8 -1
index ffce287ef415..2110d3e28cf2 100644
@@ -3,7 +3,14 @@
 # Makefile for the kernel character device drivers.
 #
 
-obj-y				+= mem.o random.o
+obj-y				+= mem.o
+
+ifeq ($(CONFIG_LRNG),y)
+  obj-y				+= lrng/
+else
+  obj-y				+= random.o
+endif
+
 obj-$(CONFIG_TTY_PRINTK)	+= ttyprintk.o
 obj-y				+= misc.o
 obj-$(CONFIG_ATARI_DSP56K)	+= dsp56k.o
drivers/char/lrng/Kconfig new file +72 -0

72 lines not on this page · raw message

drivers/char/lrng/Makefile new file +9 -0
new file mode 100644
index 000000000000..e72e01c15bb9
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the Linux Random Number Generator.
+#
+
+obj-y				+= lrng_pool.o lrng_aux.o \
+				   lrng_sw_noise.o lrng_archrandom.o \
+				   lrng_drng.o lrng_chacha20.o \
+				   lrng_interfaces.o
drivers/char/lrng/lrng_archrandom.c new file +93 -0

93 lines not on this page · raw message

drivers/char/lrng/lrng_aux.c new file +136 -0

136 lines not on this page · raw message

drivers/char/lrng/lrng_chacha20.c new file +352 -0

352 lines not on this page · raw message

drivers/char/lrng/lrng_chacha20.h new file +29 -0
new file mode 100644
index 000000000000..2340b12a56a4
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
+/*
+ * LRNG ChaCha20 definitions
+ *
+ * Copyright (C) 2016 - 2020, Stephan Mueller <[email protected]>
+ */
+
+#include <crypto/chacha.h>
+
+/* State according to RFC 7539 section 2.3 */
+struct chacha20_block {
+	u32 constants[4];
+	union {
+#define CHACHA_KEY_SIZE_WORDS (CHACHA_KEY_SIZE / sizeof(u32))
+		u32 u[CHACHA_KEY_SIZE_WORDS];
+		u8  b[CHACHA_KEY_SIZE];
+	} key;
+	u32 counter;
+	u32 nonce[3];
+};
+
+static inline void lrng_cc20_init_rfc7539(struct chacha20_block *chacha20)
+{
+	/* String "expand 32-byte k" */
+	chacha20->constants[0] = 0x61707865;
+	chacha20->constants[1] = 0x3320646e;
+	chacha20->constants[2] = 0x79622d32;
+	chacha20->constants[3] = 0x6b206574;
+}
drivers/char/lrng/lrng_drng.c new file +406 -0

406 lines not on this page · raw message

drivers/char/lrng/lrng_interfaces.c new file +651 -0

651 lines not on this page · raw message

drivers/char/lrng/lrng_internal.h new file +417 -0

417 lines not on this page · raw message

drivers/char/lrng/lrng_pool.c new file +478 -0

478 lines not on this page · raw message

drivers/char/lrng/lrng_sw_noise.c new file +461 -0

321 lines not on this page · raw message

drivers/char/lrng/lrng_sw_noise.h new file +56 -0

56 lines not on this page · raw message

include/linux/lrng.h new file +79 -0

79 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.26.2

Part of the diff is not shown here. View the raw message.

#58 lore raw

Re: [PATCH v35 01/13] Linux Random Number Generator

Thank you for the patch! Yet something to improve:

Hi "Stephan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on char-misc/char-misc-testing]
[also build test ERROR on cryptodev/master crypto/master v5.9-rc5 next-20200918] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Stephan-M-ller/dev-random-a-new-approach/20200918-181505
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git 8fd0e2a6df262539eaa28b0a2364cca10d1dc662
config: powerpc-allyesconfig (attached as .config)
compiler: powerpc64-linux-gcc (GCC) 9.3.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=powerpc

If you fix the issue, kindly add following tag as appropriate

All errors (new ones prefixed by >>):

>> drivers/char/lrng/lrng_chacha20.c:33:8: error: structure variable 'chacha20' with 'latent_entropy' attribute has a non-integer field 'block'
      33 | struct chacha20_state chacha20 __latent_entropy;
         |        ^~~~~~~~~~~~~~

# https://github.com/0day-ci/linux/commit/ecb964754fd80cca434d6d2ad6db8f28a1592fa1
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Stephan-M-ller/dev-random-a-new-approach/20200918-181505 git checkout ecb964754fd80cca434d6d2ad6db8f28a1592fa1
vim +33 drivers/char/lrng/lrng_chacha20.c

27
28 /*
29 * Have a static memory blocks for the ChaCha20 DRNG instance to avoid calling
30 * kmalloc too early in the boot cycle. For subsequent allocation requests,
31 * such as per-NUMA-node DRNG instances, kmalloc will be used.
32 */

  > 33	struct chacha20_state chacha20 __latent_entropy;
    34	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#59 lore raw

Re: [PATCH v35 01/13] Linux Random Number Generator

Am Freitag, 18. September 2020, 15:02:17 CEST schrieb kernel test robot:

Hi,

Quoted 16 lines

All errors (new ones prefixed by >>):

Quoted 3 lines
Quoted 3 lines

drivers/char/lrng/lrng_chacha20.c:33:8: error: structure variable 'chacha20' with 'latent_entropy' attribute has a non-integer field 'block'

      33 | struct chacha20_state chacha20 __latent_entropy;

         |        ^~~~~~~~~~~~~~

#
https://github.com/0day-ci/linux/commit/ecb964754fd80cca434d6d2ad6db8f28a15
92fa1 git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Stephan-M-ller/dev-random-a-new-approach/20200918-181505 git checkout ecb964754fd80cca434d6d2ad6db8f28a1592fa1
vim +33 drivers/char/lrng/lrng_chacha20.c

Quoted 4 lines
    27
    28	/*
    29	 * Have a static memory blocks for the ChaCha20 DRNG instance to

avoid calling 30 * kmalloc too early in the boot cycle. For

subsequent

Quoted 1 line

allocation requests, 31 * such as per-NUMA-node DRNG instances,

kmalloc

Quoted 3 lines

will be used. 32 */

Quoted 1 line

33 struct chacha20_state chacha20 __latent_entropy;

I do not think this report is valid. The following definitions apply:

struct chacha20_state {
        struct chacha20_block block;
};
struct chacha20_block {
        u32 constants[4];
        union {
#define CHACHA_KEY_SIZE_WORDS (CHACHA_KEY_SIZE / sizeof(u32))
                u32 u[CHACHA_KEY_SIZE_WORDS];
                u8  b[CHACHA_KEY_SIZE];
        } key;
        u32 counter;
        u32 nonce[3];
};

This implies that struct chacha20_state and thus the chacha20 variable is a linear buffer with in total 4 + 8 + 1 + 3 = 16 32-bit integers which are at least aligned on a 32-bit boundary and are designated as u32 integers.

Please let me know if I need to make a tweak to the definitions to convince the code analyzer it is a flat linear buffer consisting of integers and thus to understand the structure correctly.

Thanks a lot.

Ciao
Stephan

#60 lore raw

PATCH v35 2/13 LRNG - allocate one DRNG instance per NUMA node

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
CC Eric Biggers <[email protected]>
---
 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
drivers/char/lrng/Makefile +2 -0
index e72e01c15bb9..29724c65287d 100644
@@ -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
drivers/char/lrng/lrng_internal.h +5 -0
index bf0b32eb9113..c405cbf379d6 100644
@@ -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 ***************************/
 
drivers/char/lrng/lrng_numa.c new file +108 -0

108 lines not on this page · raw message

Signature · 1 line
2.26.2
#61 lore raw

PATCH v35 3/13 LRNG - sysctls and /proc interface

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Makefile +1 -0
index 29724c65287d..ac97f0b11cb7 100644
@@ -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
drivers/char/lrng/lrng_interfaces.c +0 -2
index 19d01d3f7492..b55de97523ad 100644
@@ -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? */
drivers/char/lrng/lrng_internal.h +4 -0
index c405cbf379d6..42014df47028 100644
@@ -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 *******************************/
 
drivers/char/lrng/lrng_proc.c new file +181 -0

181 lines not on this page · raw message

Signature · 1 line
2.26.2
#62 lore raw

PATCH v35 4/13 LRNG - add switchable DRNG support

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +7 -0
index fbbcf2ef43b6..e211fcf5aa8b 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index ac97f0b11cb7..0eb4a6849c88 100644
@@ -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
drivers/char/lrng/lrng_switch.c new file +203 -0

203 lines not on this page · raw message

Signature · 1 line
2.26.2
#63 lore raw

PATCH v35 5/13 LRNG - add common generic hash support

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
CC "Peter, Matthias" <[email protected]>
CC Roman Drahtmueller <[email protected]>
CC Marcelo Henrique Cerri <[email protected]>
CC Neil Horman <[email protected]>
---
 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
drivers/char/lrng/Kconfig +7 -0
index e211fcf5aa8b..daa2057248ac 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index 0eb4a6849c88..40f8826edeeb 100644
@@ -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
drivers/char/lrng/lrng_kcapi_hash.c new file +97 -0

97 lines not on this page · raw message

drivers/char/lrng/lrng_kcapi_hash.h new file +19 -0
new file mode 100644
index 000000000000..5bca7aba197f
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
+/*
+ * Copyright (C) 2020, Stephan Mueller <[email protected]>
+ */
+
+#ifndef _LRNG_KCAPI_HASH_H
+#define _LRNG_KCAPI_HASH_H
+
+#include <linux/module.h>
+
+void *lrng_kcapi_hash_alloc(const char *name);
+u32 lrng_kcapi_hash_digestsize(void *hash);
+void lrng_kcapi_hash_dealloc(void *hash);
+int lrng_kcapi_hash_init(struct shash_desc *shash, void *hash);
+int lrng_kcapi_hash_update(struct shash_desc *shash, const u8 *inbuf,
+			   u32 inbuflen);
+int lrng_kcapi_hash_final(struct shash_desc *shash, u8 *digest);
+
+#endif /* _LRNG_KCAPI_HASH_H */
Signature · 1 line
2.26.2
#64 lore raw

PATCH v35 6/13 crypto: DRBG - externalize DRBG functions for LRNG

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 crypto/drbg.c         | 16 ++++++++++------
 include/crypto/drbg.h |  7 +++++++
 2 files changed, 17 insertions(+), 6 deletions(-)
crypto/drbg.c +10 -6
index 3132967a1749..58b1de903def 100644
@@ -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)
 {
include/crypto/drbg.h +7 -0
index c4165126937e..71d53e028e6d 100644
@@ -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 */
Signature · 1 line
2.26.2
#65 lore raw

PATCH v35 7/13 LRNG - add SP800-90A DRBG extension

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +10 -0
index daa2057248ac..a3c4cd153f35 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index 40f8826edeeb..6ebd252db12f 100644
@@ -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
drivers/char/lrng/lrng_drbg.c new file +197 -0

197 lines not on this page · raw message

Signature · 1 line
2.26.2
#66 lore raw

PATCH v35 8/13 LRNG - add kernel crypto API PRNG extension

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +13 -0
index a3c4cd153f35..af487b3391e0 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index 6ebd252db12f..97d2b13d3227 100644
@@ -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
drivers/char/lrng/lrng_kcapi.c new file +228 -0

228 lines not on this page · raw message

Signature · 1 line
2.26.2
#67 lore raw

PATCH v35 9/13 crypto: provide access to a static Jitter RNG state

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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%)
crypto/jitterentropy-kcapi.c +1 -2
index eb7d1dd506bf..25a192f5984e 100644
@@ -43,8 +43,7 @@
 #include <linux/time.h>
 #include <linux/crypto.h>
 #include <crypto/internal/rng.h>
-
-#include "jitterentropy.h"
+#include <crypto/internal/jitterentropy.h>
 
 /***************************************************************************
  * Helper function
crypto/jitterentropy.c +30 -1
index 6e147c43fc18..fa1459f09b01 100644
@@ -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 <crypto/internal/jitterentropy.h>
 
 /***************************************************************************
  * 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 &lrng_jent_state;
+}
include/crypto/internal/jitterentropy.h renamed from crypto/jitterentropy.h +3 -0
similarity index 84%
rename from crypto/jitterentropy.h
rename to include/crypto/internal/jitterentropy.h
index c83fff32d130..6e07d86eac82 100644
@@ -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);
Signature · 1 line
2.26.2
#68 lore raw

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

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +12 -0
index af487b3391e0..87682f57efb8 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index 97d2b13d3227..6be88156010a 100644
@@ -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
drivers/char/lrng/lrng_jent.c new file +88 -0

88 lines not on this page · raw message

Signature · 1 line
2.26.2
#69 lore raw

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

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 drivers/char/lrng/Kconfig       |  56 +++++
 drivers/char/lrng/Makefile      |   1 +
 drivers/char/lrng/lrng_health.c | 407 ++++++++++++++++++++++++++++++++
 3 files changed, 464 insertions(+)
 create mode 100644 drivers/char/lrng/lrng_health.c
drivers/char/lrng/Kconfig +56 -0
index 87682f57efb8..a059da0b2f5d 100644
@@ -118,4 +118,60 @@ config LRNG_JENT
 	  time or at runtime with the lrng_base.jitterrng configuration
 	  variable.
 
+config LRNG_HEALTH_TESTS
+	bool "Enable noise source online health tests"
+	help
+	  The online health tests validate the noise source at
+	  runtime for fatal errors. These tests include SP800-90B
+	  compliant tests which are invoked if the system is booted
+	  with fips=1. In case of fatal errors during active
+	  SP800-90B tests, the issue is logged and the noise
+	  data is discarded. These tests are required for full
+	  compliance with SP800-90B.
+
+	  If unsure, say Y.
+
+config LRNG_RCT_BROKEN
+	bool "SP800-90B RCT with dangerous low cutoff value"
+	depends on LRNG_HEALTH_TESTS
+	depends on BROKEN
+	default n
+	help
+	  This option enables a dangerously low SP800-90B repetitive
+	  count test (RCT) cutoff value which makes it very likely
+	  that the RCT is triggered to raise a self test failure.
+
+	  This option is ONLY intended for developers wanting to
+	  test the effectiveness of the SP800-90B RCT health test.
+
+	  If unsure, say N.
+
+config LRNG_APT_BROKEN
+	bool "SP800-90B APT with dangerous low cutoff value"
+	depends on LRNG_HEALTH_TESTS
+	depends on BROKEN
+	default n
+	help
+	  This option enables a dangerously low SP800-90B adaptive
+	  proportion test (APT) cutoff value which makes it very
+	  likely that the APT is triggered to raise a self test
+	  failure.
+
+	  This option is ONLY intended for developers wanting to
+	  test the effectiveness of the SP800-90B APT health test.
+
+	  If unsure, say N.
+
+# Default taken from SP800-90B sec 4.4.1 - significance level 2^-30
+config LRNG_RCT_CUTOFF
+	int
+	default 31 if !LRNG_RCT_BROKEN
+	default 1 if LRNG_RCT_BROKEN
+
+# Default taken from SP800-90B sec 4.4.2 - significance level 2^-30
+config LRNG_APT_CUTOFF
+	int
+	default 325 if !LRNG_APT_BROKEN
+	default 32 if LRNG_APT_BROKEN
+
 endif # LRNG
drivers/char/lrng/Makefile +1 -0
index 6be88156010a..3c8637befb42 100644
@@ -15,3 +15,4 @@ 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
+obj-$(CONFIG_LRNG_HEALTH_TESTS)	+= lrng_health.o
drivers/char/lrng/lrng_health.c new file +407 -0

407 lines not on this page · raw message

Signature · 1 line
2.26.2
#70 lore raw

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

In reply to 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
---
 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
drivers/char/lrng/Kconfig +150 -0
index a059da0b2f5d..bb785bc61abb 100644
@@ -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 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 sampled.
+
+config LRNG_RAW_IRQFLAGS_ENTROPY
+	bool "Enable entropy test interface to IRQ flags noise source"
+	help
+	  The test interface allows a privileged process to capture
+	  the raw unconditioned interrupt flags 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_irqflags
+	  debugfs file. Using the option lrng_testing.boot_raw_irqflags_test=1
+	  the raw noise of the first 1000 entropy events since boot
+	  can be sampled.
+
+config LRNG_RAW_RETIP_ENTROPY
+	bool "Enable entropy test interface to RETIP value noise source"
+	help
+	  The test interface allows a privileged process to capture
+	  the raw unconditioned return instruction pointer value
+	  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_retip
+	  debugfs file. Using the option lrng_testing.boot_raw_retip_test=1
+	  the raw noise of the first 1000 entropy events since boot
+	  can be sampled.
+
+config LRNG_RAW_REGS_ENTROPY
+	bool "Enable entropy test interface to IRQ register value noise source"
+	help
+	  The test interface allows a privileged process to capture
+	  the raw unconditioned interrupt register value that is
+	  collected by the LRNG for statistical analysis. Extracted noise
+	  data is not used to seed the random number generator.
+
+	  The raw noise data can be obtained using the lrng_raw_regs
+	  debugfs file. Using the option lrng_testing.boot_raw_regs_test=1
+	  the raw noise of the first 1000 entropy events since boot
+	  can be sampled.
+
+config LRNG_RAW_ARRAY
+	bool "Enable test interface to LRNG raw entropy storage array"
+	help
+	  The test interface allows a privileged process to capture
+	  the raw noise data that is collected by the LRNG
+	  in the per-CPU array for statistical analysis. The purpose
+	  of this interface is to verify that the array handling code
+	  truly only concatenates data and provides the same entropy
+	  rate as the raw unconditioned noise source when assessing
+	  the collected data byte-wise.
+
+	  The data can be obtained using the lrng_raw_array debugfs
+	  file. Using the option lrng_testing.boot_raw_array=1
+	  the raw noise of the first 1000 entropy events since boot
+	  can be sampled.
+
+config LRNG_IRQ_PERF
+	bool "Enable LRNG interrupt performance monitor"
+	help
+	  With this option, the performance monitor of the LRNG
+	  interrupt handling code is enabled. The file provides
+	  the execution time of the interrupt handler in
+	  cycles.
+
+	  The interrupt performance data can be obtained using
+	  the lrng_irq_perf debugfs file. Using the option
+	  lrng_testing.boot_irq_perf=1 the performance data of
+	  the first 1000 entropy events since boot can be sampled.
+
+config LRNG_ACVT_HASH
+	bool "Enable LRNG ACVT Hash interface"
+	help
+	  With this option, the LRNG built-in hash function used for
+	  auxiliary pool management and prior to switching the
+	  cryptographic backends is made available for ACVT. The
+	  interface allows writing of the data to be hashed
+	  into the interface. The read operation triggers the hash
+	  operation to generate message digest.
+
+	  The ACVT interface is available with the lrng_acvt_hash
+	  debugfs file.
+
+config LRNG_TESTING
+	bool
+	default y if (LRNG_RAW_HIRES_ENTROPY || LRNG_RAW_JIFFIES_ENTROPY ||LRNG_RAW_IRQ_ENTROPY || LRNG_RAW_IRQFLAGS_ENTROPY || LRNG_RAW_RETIP_ENTROPY || LRNG_RAW_REGS_ENTROPY || LRNG_RAW_ARRAY || LRNG_IRQ_PERF || LRNG_ACVT_HASH)
+
+endif #LRNG_TESTING_MENU
+
 endif # LRNG
drivers/char/lrng/Makefile +1 -0
index 3c8637befb42..532501b38a00 100644
@@ -16,3 +16,4 @@ obj-$(CONFIG_LRNG_DRBG)		+= lrng_drbg.o
 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
drivers/char/lrng/lrng_testing.c new file +687 -0

687 lines not on this page · raw message

Signature · 1 line
2.26.2
#71 lore raw

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

In reply to 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 0xffffffff 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" <[email protected]>
CC "Alexander E. Patrakov" <[email protected]>
CC "Ahmed S. Darwish" <[email protected]>
CC "Theodore Y. Ts'o" <[email protected]>
CC Willy Tarreau <[email protected]>
CC Matthew Garrett <[email protected]>
CC Vito Caputo <[email protected]>
CC Andreas Dilger <[email protected]>
CC Jan Kara <[email protected]>
CC Ray Strode <[email protected]>
CC William Jon McCann <[email protected]>
CC zhangjs <[email protected]>
CC Andy Lutomirski <[email protected]>
CC Florian Weimer <[email protected]>
CC Lennart Poettering <[email protected]>
CC Nicolai Stange <[email protected]>
CC Marcelo Henrique Cerri <[email protected]>
CC Neil Horman <[email protected]>
---
 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
drivers/char/lrng/Kconfig +26 -0
index bb785bc61abb..6f180641a5da 100644
@@ -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
drivers/char/lrng/Makefile +1 -0
index 532501b38a00..a633638af991 100644
@@ -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
drivers/char/lrng/lrng_selftest.c new file +344 -0

344 lines not on this page · raw message

Signature · 1 line
2.26.2