Skip to content

Commit

Permalink
char/lrng: add SP800-90B compliant health tests
Browse files Browse the repository at this point in the history
Implement health tests for LRNG's slow noise sources as mandated by
SP-800-90B The file contains the following health tests:

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

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

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

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

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

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

- all entropy counters are set to zero

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

To summarize, the following rules apply:

• SP800-90B compliant output interfaces

  - /dev/random

  - getrandom(2) system call

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

• SP800-90B non-compliant output interfaces

  - /dev/urandom

  - get_random_bytes kernel-internal interface called directly

  - randomize_page kernel-internal interface

  - get_random_u32 and get_random_u64 kernel-internal interfaces

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

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

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

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

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

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

The entire health testing code is compile-time configurable.

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

CC: Torsten Duwe <duwe@lst.de>
CC: "Eric W. Biederman" <ebiederm@xmission.com>
CC: "Alexander E. Patrakov" <patrakov@gmail.com>
CC: "Ahmed S. Darwish" <darwish.07@gmail.com>
CC: "Theodore Y. Ts'o" <tytso@mit.edu>
CC: Willy Tarreau <w@1wt.eu>
CC: Matthew Garrett <mjg59@srcf.ucam.org>
CC: Vito Caputo <vcaputo@pengaru.com>
CC: Andreas Dilger <adilger.kernel@dilger.ca>
CC: Jan Kara <jack@suse.cz>
CC: Ray Strode <rstrode@redhat.com>
CC: William Jon McCann <mccann@jhu.edu>
CC: zhangjs <zachary@baishancloud.com>
CC: Andy Lutomirski <luto@kernel.org>
CC: Florian Weimer <fweimer@redhat.com>
CC: Lennart Poettering <mzxreary@0pointer.de>
CC: Nicolai Stange <nstange@suse.de>
Reviewed-by: Alexander Lobakin <alobakin@pm.me>
Tested-by: Alexander Lobakin <alobakin@pm.me>
Reviewed-by: Roman Drahtmueller <draht@schaltsekun.de>
Tested-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
Tested-by: Neil Horman <nhorman@tuxdriver.com>
Tested-by: Jirka Hladky <jhladky@redhat.com>
Reviewed-by: Jirka Hladky <jhladky@redhat.com>
Signed-off-by: Stephan Mueller <smueller@chronox.de>
  • Loading branch information
smuellerDD authored and xanmod committed Mar 21, 2022
1 parent 86155b3 commit 33b609e
Show file tree
Hide file tree
Showing 3 changed files with 469 additions and 0 deletions.
58 changes: 58 additions & 0 deletions drivers/char/lrng/Kconfig
Expand Up @@ -218,6 +218,64 @@ config LRNG_COLLECTION_SIZE
default 4096 if LRNG_COLLECTION_SIZE_4096
default 8192 if LRNG_COLLECTION_SIZE_8192

config LRNG_HEALTH_TESTS
bool "Enable interrupt entropy source online health tests"
depends on LRNG_IRQ
help
The online health tests applied to the interrupt entropy
source 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 of the
interrupt entropy source 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

config LRNG_IRQ_ENTROPY_RATE
int "Interrupt Entropy Source Entropy Rate"
depends on LRNG_IRQ
Expand Down
1 change: 1 addition & 0 deletions drivers/char/lrng/Makefile
Expand Up @@ -16,3 +16,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_es_jent.o
obj-$(CONFIG_LRNG_HEALTH_TESTS) += lrng_health.o

0 comments on commit 33b609e

Please sign in to comment.