Skip to content

Commit

Permalink
char/lrng: add Jitter RNG fast noise source
Browse files Browse the repository at this point in the history
The Jitter RNG fast noise source implemented as part of the kernel
crypto API is queried for 256 bits of entropy at the time the seed
buffer managed by the LRNG is about to be filled.

CC: Torsten Duwe <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>
CC: Alexander Lobakin <alobakin@mailbox.org>
Reviewed-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
Tested-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
Tested-by: Neil Horman <nhorman@redhat.com>
Signed-off-by: Stephan Mueller <smueller@chronox.de>
  • Loading branch information
smuellerDD authored and xanmod committed Jul 19, 2021
1 parent 3c1b9ec commit 5a544a2
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 0 deletions.
27 changes: 27 additions & 0 deletions drivers/char/lrng/Kconfig
Expand Up @@ -182,6 +182,33 @@ config LRNG_IRQ_ENTROPY_RATE
interrupt entropy source will still deliver data but without
being credited with entropy.

comment "Jitter RNG Entropy Source"

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.

config LRNG_JENT_ENTROPY_RATE
int "Jitter RNG Entropy Source Entropy Rate"
range 0 256
default 16
help
The option defines the amount of entropy the LRNG applies to 256
bits of data obtained from the Jitter RNG entropy source. The
LRNG enforces the limit that this value must be in the range
between 0 and 256.

In order to disable the Jitter RNG entropy source, the option
has to be set to 0.

comment "CPU Entropy Source"

config LRNG_CPU_ENTROPY_RATE
Expand Down
1 change: 1 addition & 0 deletions drivers/char/lrng/Makefile
Expand Up @@ -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
90 changes: 90 additions & 0 deletions drivers/char/lrng/lrng_jent.c
@@ -0,0 +1,90 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
/*
* LRNG Fast Entropy Source: Jitter RNG
*
* Copyright (C) 2016 - 2021, Stephan Mueller <smueller@chronox.de>
*/

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/types.h>
#include <crypto/internal/jitterentropy.h>

#include "lrng_internal.h"

/*
* Estimated entropy of data is a 16th of LRNG_DRNG_SECURITY_STRENGTH_BITS.
* Albeit a full entropy assessment is provided for the noise source indicating
* that it provides high entropy rates and considering that it deactivates
* when it detects insufficient hardware, the chosen under estimation of
* entropy is considered to be acceptable to all reviewers.
*/
static u32 jitterrng = CONFIG_LRNG_JENT_ENTROPY_RATE;
#ifdef CONFIG_LRNG_RUNTIME_ES_CONFIG
module_param(jitterrng, uint, 0644);
MODULE_PARM_DESC(jitterrng, "Entropy in bits of 256 data bits from Jitter RNG noise source");
#endif

static bool lrng_jent_initialized = false;
static struct rand_data *lrng_jent_state;

static int __init lrng_jent_initialize(void)
{
/* Initialize the Jitter RNG after the clocksources are initialized. */
lrng_jent_state = jent_lrng_entropy_collector();
if (!lrng_jent_state) {
jitterrng = 0;
pr_info("Jitter RNG unusable on current system\n");
return 0;
}
lrng_jent_initialized = true;
lrng_pool_add_entropy();
pr_debug("Jitter RNG working on current system\n");

return 0;
}
device_initcall(lrng_jent_initialize);

/**
* lrng_get_jent() - Get Jitter RNG entropy
*
* @outbuf: buffer to store entropy
* @outbuflen: length of buffer
*
* Return:
* * > 0 on success where value provides the added entropy in bits
* * 0 if no fast source was available
*/
u32 lrng_get_jent(u8 *outbuf, u32 requested_bits)
{
int ret;
u32 ent_bits = lrng_jent_entropylevel(requested_bits);
unsigned long flags;
static DEFINE_SPINLOCK(lrng_jent_lock);

spin_lock_irqsave(&lrng_jent_lock, flags);

if (!ent_bits || !lrng_jent_initialized) {
spin_unlock_irqrestore(&lrng_jent_lock, flags);
return 0;
}

ret = jent_read_entropy(lrng_jent_state, outbuf, requested_bits >> 3);
spin_unlock_irqrestore(&lrng_jent_lock, flags);

if (ret) {
pr_debug("Jitter RNG failed with %d\n", ret);
return 0;
}

pr_debug("obtained %u bits of entropy from Jitter RNG noise source\n",
ent_bits);

return ent_bits;
}

u32 lrng_jent_entropylevel(u32 requested_bits)
{
return lrng_fast_noise_entropylevel((lrng_jent_initialized) ?
jitterrng : 0, requested_bits);
}

0 comments on commit 5a544a2

Please sign in to comment.