Skip to content

Commit

Permalink
backports for LRNG v57
Browse files Browse the repository at this point in the history
Signed-off-by: Stephan Mueller <[email protected]>
  • Loading branch information
smuellerDD committed Sep 28, 2024
1 parent 577f504 commit 7ffd970
Show file tree
Hide file tree
Showing 68 changed files with 2,286 additions and 0 deletions.
13 changes: 13 additions & 0 deletions backports/v57-4.19.322/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Backport Patches for Kernel 4.19

The patches allow applying the LRNG to older kernels. Perform the following
operations:

1. apply all six-digit patches providing necessary code updates to
required before applying the LRNG patches.

2. apply all LRNG patches from upstream - note, some hunks are expected
considering the original code base is written for a different kernel version

3. apply all two-digit patches providing code updates after the LRNG patches
are applied.
13 changes: 13 additions & 0 deletions backports/v57-4.19.322/v57-000001-core.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--- linux-5.8/kernel/sched/core.c.orig 2022-05-17 09:59:33.887522471 +0200
+++ linux-5.8/kernel/sched/core.c 2022-05-17 10:00:18.241509892 +0200
@@ -6,6 +6,10 @@
*
* Copyright (C) 1991-2002 Linus Torvalds
*/
+#include <linux/highmem.h>
+#include <linux/hrtimer_api.h>
+#include <linux/ktime_api.h>
+
#include "sched.h"

#include <linux/nospec.h>
67 changes: 67 additions & 0 deletions backports/v57-4.19.322/v57-000002-jent-backport.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
diff -urNp linux-4.19.orig/crypto/jitterentropy.c linux-4.19/crypto/jitterentropy.c
--- linux-4.19.orig/crypto/jitterentropy.c 2020-08-20 12:33:37.584860610 +0200
+++ linux-4.19/crypto/jitterentropy.c 2020-08-20 12:44:34.654746533 +0200
@@ -110,13 +110,7 @@ struct rand_data {
* Helper functions
***************************************************************************/

-void jent_get_nstime(__u64 *out);
-__u64 jent_rol64(__u64 word, unsigned int shift);
-void *jent_zalloc(unsigned int len);
-void jent_zfree(void *ptr);
-int jent_fips_enabled(void);
-void jent_panic(char *s);
-void jent_memcpy(void *dest, const void *src, unsigned int n);
+#include "jitterentropy.h"

/**
* Update of the loop count used for the next round of
@@ -418,6 +412,7 @@ static __u64 jent_unbiased_bit(struct ra
* Input:
* @entropy_collector Reference to entropy collector
*/
+__u64 jent_rol64(__u64 word, unsigned int shift);
static void jent_stir_pool(struct rand_data *entropy_collector)
{
/*
diff -urNp linux-4.19.orig/crypto/jitterentropy.h linux-4.19/crypto/jitterentropy.h
--- linux-4.19.orig/crypto/jitterentropy.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-4.19/crypto/jitterentropy.h 2020-08-20 12:44:34.654746533 +0200
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+typedef unsigned long long __u64;
+
+extern void *jent_zalloc(unsigned int len);
+extern void jent_zfree(void *ptr);
+extern int jent_fips_enabled(void);
+extern void jent_panic(char *s);
+extern void jent_memcpy(void *dest, const void *src, unsigned int n);
+extern void jent_get_nstime(__u64 *out);
+
+struct rand_data;
+extern int jent_entropy_init(void);
+extern int jent_read_entropy(struct rand_data *ec, unsigned char *data,
+ unsigned int len);
+
+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);
diff -urNp linux-4.19.orig/crypto/jitterentropy-kcapi.c linux-4.19/crypto/jitterentropy-kcapi.c
--- linux-4.19.orig/crypto/jitterentropy-kcapi.c 2020-08-20 12:33:37.583860598 +0200
+++ linux-4.19/crypto/jitterentropy-kcapi.c 2020-08-20 12:44:34.653746522 +0200
@@ -44,13 +44,7 @@
#include <linux/crypto.h>
#include <crypto/internal/rng.h>

-struct rand_data;
-int jent_read_entropy(struct rand_data *ec, unsigned char *data,
- unsigned int len);
-int jent_entropy_init(void);
-struct rand_data *jent_entropy_collector_alloc(unsigned int osr,
- unsigned int flags);
-void jent_entropy_collector_free(struct rand_data *entropy_collector);
+#include "jitterentropy.h"

/***************************************************************************
* Helper function
18 changes: 18 additions & 0 deletions backports/v57-4.19.322/v57-000004-sha1.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--- linux-4.19/include/crypto/sha.h.lrng13 2020-08-13 22:06:20.353827574 -0600
+++ linux-4.19/include/crypto/sha.h 2020-08-13 22:18:18.678469365 -0600
@@ -112,4 +112,15 @@

extern int crypto_sha512_finup(struct shash_desc *desc, const u8 *data,
unsigned int len, u8 *hash);
+
+/*
+ * An implementation of SHA-1's compression function. Don't use in new code!
+ * You shouldn't be using SHA-1, and even if you *have* to use SHA-1, this isn't
+ * the correct way to hash something with SHA-1 (use crypto_shash instead).
+ */
+#define SHA1_DIGEST_WORDS (SHA1_DIGEST_SIZE / 4)
+#define SHA1_WORKSPACE_WORDS 16
+void sha_init(__u32 *buf);
+void sha_transform(__u32 *digest, const char *data, __u32 *W);
+
#endif
12 changes: 12 additions & 0 deletions backports/v57-4.19.322/v57-01-core.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--- linux-5.15/kernel/sched/core.c.orig 2022-05-17 08:10:20.541904807 +0200
+++ linux-5.15/kernel/sched/core.c 2022-05-17 08:10:31.720932544 +0200
@@ -7,9 +7,6 @@
* Copyright (C) 1991-2002 Linus Torvalds
*/
#include <linux/lrng.h>
-#include <linux/highmem.h>
-#include <linux/hrtimer_api.h>
-#include <linux/ktime_api.h>

#define CREATE_TRACE_POINTS
#include <trace/events/sched.h>
68 changes: 68 additions & 0 deletions backports/v57-4.19.322/v57-03-revert-arch_get_random_long.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
diff --git a/drivers/char/lrng/lrng_es_cpu.c b/drivers/char/lrng/lrng_es_cpu.c
index f982cc31df4e..3910108cfd08 100644
--- a/drivers/char/lrng/lrng_es_cpu.c
+++ b/drivers/char/lrng/lrng_es_cpu.c
@@ -65,8 +65,7 @@ static u32 lrng_cpu_poolsize(void)

static u32 lrng_get_cpu_data(u8 *outbuf, u32 requested_bits)
{
- size_t longs = 0;
- u32 i, req = requested_bits >> 3;
+ u32 i;

/* operate on full blocks */
BUILD_BUG_ON(LRNG_DRNG_SECURITY_STRENGTH_BYTES % sizeof(unsigned long));
@@ -74,14 +73,10 @@ static u32 lrng_get_cpu_data(u8 *outbuf, u32 requested_bits)
/* ensure we have aligned buffers */
BUILD_BUG_ON(LRNG_KCAPI_ALIGN % sizeof(unsigned long));

- for (i = 0; i < req; i += longs) {
- longs = arch_get_random_seed_longs(
- (unsigned long *)(outbuf + i), req - i);
- if (longs)
- continue;
- longs = arch_get_random_longs((unsigned long *)(outbuf + i),
- req - i);
- if (!longs) {
+ for (i = 0; i < (requested_bits >> 3);
+ i += sizeof(unsigned long)) {
+ if (!arch_get_random_seed_long((unsigned long *)(outbuf + i)) &&
+ !arch_get_random_long((unsigned long *)(outbuf + i))) {
cpu_entropy = 0;
return 0;
}
@@ -180,7 +175,7 @@ static u32 lrng_cpu_multiplier(void)
if (data_multiplier > 0)
return data_multiplier;

- if (IS_ENABLED(CONFIG_X86) && !arch_get_random_seed_longs(&v, 1)) {
+ if (IS_ENABLED(CONFIG_X86) && !arch_get_random_seed_long(&v)) {
/*
* Intel SPEC: pulling 512 blocks from RDRAND ensures
* one reseed making it logically equivalent to RDSEED.
--- linux-5.15.86/drivers/char/lrng/lrng_es_mgr.c.orig2 2023-01-07 21:18:49.376364123 +0100
+++ linux-5.15.86/drivers/char/lrng/lrng_es_mgr.c 2023-01-07 21:19:44.168291522 +0100
@@ -376,19 +376,12 @@ void __init lrng_rand_initialize_early(v
sizeof(unsigned long))];
struct new_utsname utsname;
} seed __aligned(LRNG_KCAPI_ALIGN);
- size_t longs = 0;
unsigned int i;

- for (i = 0; i < ARRAY_SIZE(seed.data); i += longs) {
- longs = arch_get_random_seed_longs(seed.data + i,
- ARRAY_SIZE(seed.data) - i);
- if (longs)
- continue;
- longs = arch_get_random_longs(seed.data + i,
- ARRAY_SIZE(seed.data) - i);
- if (longs)
- continue;
- longs = 1;
+ for (i = 0; i < ARRAY_SIZE(seed.data); i++) {
+ if (!arch_get_random_seed_long_early(&(seed.data[i])) &&
+ !arch_get_random_long_early(&seed.data[i]))
+ seed.data[i] = random_get_entropy();
}
memcpy(&seed.utsname, init_utsname(), sizeof(*(init_utsname())));

21 changes: 21 additions & 0 deletions backports/v57-4.19.322/v57-05-sysctl.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--- linux-5.15/drivers/char/lrng/lrng_sysctl.c.orig 2022-05-17 08:35:09.958660325 +0200
+++ linux-5.15/drivers/char/lrng/lrng_sysctl.c 2022-05-17 08:36:17.829818950 +0200
@@ -91,7 +91,7 @@ void lrng_sysctl_update_max_write_thresh
mb();
}

-static struct ctl_table random_table[] = {
+struct ctl_table random_table[] = {
{
.procname = "poolsize",
.maxlen = sizeof(int),
@@ -137,9 +137,3 @@ static struct ctl_table random_table[] =
{ }
};

-static int __init random_sysctls_init(void)
-{
- register_sysctl_init("kernel/random", random_table);
- return 0;
-}
-device_initcall(random_sysctls_init);
176 changes: 176 additions & 0 deletions backports/v57-4.19.322/v57-06-add_random_ready_callbacks.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
--- linux-5.18.8/drivers/char/lrng/lrng_es_mgr.c.orig 2022-08-01 09:35:07.227572096 +0200
+++ linux-5.18.8/drivers/char/lrng/lrng_es_mgr.c 2022-08-01 09:31:18.926127936 +0200
@@ -218,6 +218,7 @@ static void lrng_set_operational(void)
*/
if (lrng_state.lrng_fully_seeded) {
lrng_state.lrng_operational = true;
+ lrng_process_ready_list();
lrng_init_wakeup();
pr_info("LRNG fully operational\n");
}
--- linux-5.18.8/drivers/char/lrng/lrng_interface_random_kernel.c.orig 2022-08-01 09:13:51.877910601 +0200
+++ linux-5.18.8/drivers/char/lrng/lrng_interface_random_kernel.c 2022-08-01 09:31:18.926127936 +0200
@@ -19,6 +19,10 @@
#include "lrng_interface_dev_common.h"
#include "lrng_interface_random_kernel.h"

+static RAW_NOTIFIER_HEAD(lrng_ready_chain);
+static DEFINE_SPINLOCK(lrng_ready_chain_lock);
+static unsigned int lrng_ready_chain_used = 0;
+
/********************************** Helper ***********************************/

int __init random_init(const char *command_line)
@@ -29,6 +33,33 @@ int __init random_init(const char *comma
return ret;
}

+bool lrng_ready_chain_has_sleeper(void)
+{
+ return !!lrng_ready_chain_used;
+}
+
+/*
+ * lrng_process_ready_list() - Ping all kernel internal callers waiting until
+ * the DRNG is completely initialized to inform that the DRNG reached that
+ * seed level.
+ *
+ * When the SP800-90B testing is enabled, the ping only happens if the SP800-90B
+ * startup health tests are completed. This implies that kernel internal
+ * callers always have an SP800-90B compliant noise source when being
+ * pinged.
+ */
+void lrng_process_ready_list(void)
+{
+ unsigned long flags;
+
+ if (!lrng_state_operational())
+ return;
+
+ spin_lock_irqsave(&lrng_ready_chain_lock, flags);
+ raw_notifier_call_chain(&lrng_ready_chain, 0, NULL);
+ spin_unlock_irqrestore(&lrng_ready_chain_lock, flags);
+}
+
/************************ LRNG kernel input interfaces ************************/

/*
@@ -125,6 +156,58 @@ void add_interrupt_randomness(int irq) {
EXPORT_SYMBOL(add_interrupt_randomness);
#endif

+/*
+ * unregister_random_ready_notifier() - Delete a previously registered readiness
+ * callback function.
+ *
+ * @nb: callback definition that was registered initially
+ */
+int unregister_random_ready_notifier(struct notifier_block *nb)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&lrng_ready_chain_lock, flags);
+ ret = raw_notifier_chain_unregister(&lrng_ready_chain, nb);
+ spin_unlock_irqrestore(&lrng_ready_chain_lock, flags);
+
+ if (!ret && lrng_ready_chain_used)
+ lrng_ready_chain_used--;
+
+ return ret;
+}
+EXPORT_SYMBOL(unregister_random_ready_notifier);
+
+/*
+ * register_random_ready_notifier() - Add a callback function that will be
+ * invoked when the DRNG is fully initialized and seeded.
+ *
+ * @nb: callback definition to be invoked when the LRNG is seeded
+ *
+ * Return:
+ * * 0 if callback is successfully added
+ * * -EALREADY if pool is already initialised (callback not called)
+ */
+int register_random_ready_notifier(struct notifier_block *nb)
+{
+ unsigned long flags;
+ int err = -EALREADY;
+
+ if (likely(lrng_state_operational()))
+ return err;
+
+ spin_lock_irqsave(&lrng_ready_chain_lock, flags);
+ if (!lrng_state_operational())
+ err = raw_notifier_chain_register(&lrng_ready_chain, nb);
+ spin_unlock_irqrestore(&lrng_ready_chain_lock, flags);
+
+ if (!err)
+ lrng_ready_chain_used++;
+
+ return err;
+}
+EXPORT_SYMBOL(register_random_ready_notifier);
+
#if IS_ENABLED(CONFIG_VMGENID)
static BLOCKING_NOTIFIER_HEAD(lrng_vmfork_chain);

@@ -195,6 +278,43 @@ int wait_for_random_bytes(void)
EXPORT_SYMBOL(wait_for_random_bytes);

/*
+ * get_random_bytes_arch() - This function will use the architecture-specific
+ * hardware random number generator if it is available.
+ *
+ * The arch-specific hw RNG will almost certainly be faster than what we can
+ * do in software, but it is impossible to verify that it is implemented
+ * securely (as opposed, to, say, the AES encryption of a sequence number using
+ * a key known by the NSA). So it's useful if we need the speed, but only if
+ * we're willing to trust the hardware manufacturer not to have put in a back
+ * door.
+ *
+ * @buf: buffer allocated by caller to store the random data in
+ * @nbytes: length of outbuf
+ *
+ * Return: number of bytes filled in.
+ */
+size_t __must_check get_random_bytes_arch(void *buf, size_t nbytes)
+{
+ size_t left = nbytes;
+ u8 *p = buf;
+
+ while (left) {
+ unsigned long v;
+ size_t chunk = min_t(size_t, left, sizeof(unsigned long));
+
+ if (!arch_get_random_long(&v))
+ break;
+
+ memcpy(p, &v, chunk);
+ p += chunk;
+ left -= chunk;
+ }
+
+ return nbytes - left;
+}
+EXPORT_SYMBOL(get_random_bytes_arch);
+
+/*
* Returns whether or not the LRNG has been seeded.
*
* Returns: true if the urandom pool has been seeded.
--- linux-5.15.58/drivers/char/lrng/lrng_interface_random_kernel.h.orig 2022-08-01 10:01:32.939911355 +0200
+++ linux-5.15.58/drivers/char/lrng/lrng_interface_random_kernel.h 2022-08-01 10:01:38.564923636 +0200
@@ -7,9 +7,13 @@
#define _LRNG_INTERFACE_RANDOM_H

#ifdef CONFIG_LRNG_RANDOM_IF
+void lrng_process_ready_list(void);
+bool lrng_ready_chain_has_sleeper(void);
void invalidate_batched_entropy(void);
void lrng_kick_random_ready(void);
#else /* CONFIG_LRNG_RANDOM_IF */
+static inline bool lrng_ready_chain_has_sleeper(void) { return false; }
+static inline void lrng_process_ready_list(void) { }
static inline void invalidate_batched_entropy(void) { }
static inline void lrng_kick_random_ready(void) { }
#endif /* CONFIG_LRNG_RANDOM_IF */
Loading

0 comments on commit 7ffd970

Please sign in to comment.