linuxkm/patches/: update patches to reseed the wolfCrypt DRBG array only on explicit RNDRESEEDCRNG ioctl;

linuxkm/lkcapi_sha_glue.c: add error msg in wc_linuxkm_drbg_generate() if wc_InitRng() fails, and add "libwolfssl: " prefixes in pr_info() messages.
This commit is contained in:
Daniel Pouzzner
2025-07-02 14:24:17 -05:00
parent d2083db6de
commit 0160af0a0d
10 changed files with 735 additions and 148 deletions

View File

@@ -1101,9 +1101,12 @@ retry:
pr_warn("WARNING: reinitialized DRBG #%d after RNG_FAILURE_E.", raw_smp_processor_id()); pr_warn("WARNING: reinitialized DRBG #%d after RNG_FAILURE_E.", raw_smp_processor_id());
goto retry; goto retry;
} }
else {
pr_warn_once("ERROR: reinitialization of DRBG #%d after RNG_FAILURE_E failed with ret %d.", raw_smp_processor_id(), ret);
ret = -EINVAL;
}
} }
else if (ret != 0) {
if (ret != 0) {
pr_warn_once("WARNING: wc_RNG_GenerateBlock returned %d\n",ret); pr_warn_once("WARNING: wc_RNG_GenerateBlock returned %d\n",ret);
ret = -EINVAL; ret = -EINVAL;
} }
@@ -1748,7 +1751,7 @@ static int wc_linuxkm_drbg_startup(void)
crypto_put_default_rng(); crypto_put_default_rng();
wc_linuxkm_drbg_default_instance_registered = 1; wc_linuxkm_drbg_default_instance_registered = 1;
pr_info("%s registered as systemwide default stdrng.", wc_linuxkm_drbg.base.cra_driver_name); pr_info("%s registered as systemwide default stdrng.", wc_linuxkm_drbg.base.cra_driver_name);
pr_info("to unload module, first echo 1 > /sys/module/libwolfssl/deinstall_algs"); pr_info("libwolfssl: to unload module, first echo 1 > /sys/module/libwolfssl/deinstall_algs");
} }
else { else {
pr_err("ERROR: %s NOT registered as systemwide default stdrng -- found \"%s\".", wc_linuxkm_drbg.base.cra_driver_name, crypto_tfm_alg_driver_name(&crypto_default_rng->base)); pr_err("ERROR: %s NOT registered as systemwide default stdrng -- found \"%s\".", wc_linuxkm_drbg.base.cra_driver_name, crypto_tfm_alg_driver_name(&crypto_default_rng->base));
@@ -1766,7 +1769,7 @@ static int wc_linuxkm_drbg_startup(void)
if (ret == 0) { if (ret == 0) {
wc_get_random_bytes_callbacks_installed = 1; wc_get_random_bytes_callbacks_installed = 1;
pr_info("Kernel global random_bytes handlers installed."); pr_info("libwolfssl: kernel global random_bytes handlers installed.");
} }
else { else {
pr_err("ERROR: wolfssl_linuxkm_register_random_bytes_handlers() failed: %d\n", ret); pr_err("ERROR: wolfssl_linuxkm_register_random_bytes_handlers() failed: %d\n", ret);
@@ -1777,7 +1780,7 @@ static int wc_linuxkm_drbg_startup(void)
ret = register_kprobe(&wc_get_random_bytes_kprobe); ret = register_kprobe(&wc_get_random_bytes_kprobe);
if (ret == 0) { if (ret == 0) {
wc_get_random_bytes_kprobe_installed = 1; wc_get_random_bytes_kprobe_installed = 1;
pr_info("wc_get_random_bytes_kprobe installed\n"); pr_info("libwolfssl: wc_get_random_bytes_kprobe installed\n");
} }
else { else {
pr_err("ERROR: wc_get_random_bytes_kprobe installation failed: %d\n", ret); pr_err("ERROR: wc_get_random_bytes_kprobe installation failed: %d\n", ret);
@@ -1787,7 +1790,7 @@ static int wc_linuxkm_drbg_startup(void)
ret = register_kretprobe(&wc_get_random_bytes_user_kretprobe); ret = register_kretprobe(&wc_get_random_bytes_user_kretprobe);
if (ret == 0) { if (ret == 0) {
wc_get_random_bytes_user_kretprobe_installed = 1; wc_get_random_bytes_user_kretprobe_installed = 1;
pr_info("wc_get_random_bytes_user_kretprobe installed\n"); pr_info("libwolfssl: wc_get_random_bytes_user_kretprobe installed\n");
} }
else { else {
pr_err("ERROR: wc_get_random_bytes_user_kprobe installation failed: %d\n", ret); pr_err("ERROR: wc_get_random_bytes_user_kprobe installation failed: %d\n", ret);
@@ -1842,7 +1845,7 @@ static int wc_linuxkm_drbg_cleanup(void) {
pr_err("ERROR: wolfssl_linuxkm_unregister_random_bytes_handlers returned %d", ret); pr_err("ERROR: wolfssl_linuxkm_unregister_random_bytes_handlers returned %d", ret);
return ret; return ret;
} }
pr_info("wc_get_random_bytes handlers uninstalled\n"); pr_info("libwolfssl: kernel global random_bytes handlers uninstalled\n");
wc_get_random_bytes_callbacks_installed = 0; wc_get_random_bytes_callbacks_installed = 0;
} }
@@ -1852,14 +1855,14 @@ static int wc_linuxkm_drbg_cleanup(void) {
wc_get_random_bytes_kprobe_installed = 0; wc_get_random_bytes_kprobe_installed = 0;
barrier(); barrier();
unregister_kprobe(&wc_get_random_bytes_kprobe); unregister_kprobe(&wc_get_random_bytes_kprobe);
pr_info("wc_get_random_bytes_kprobe uninstalled\n"); pr_info("libwolfssl: wc_get_random_bytes_kprobe uninstalled\n");
} }
#ifdef WOLFSSL_LINUXKM_USE_GET_RANDOM_USER_KRETPROBE #ifdef WOLFSSL_LINUXKM_USE_GET_RANDOM_USER_KRETPROBE
if (wc_get_random_bytes_user_kretprobe_installed) { if (wc_get_random_bytes_user_kretprobe_installed) {
wc_get_random_bytes_user_kretprobe_installed = 0; wc_get_random_bytes_user_kretprobe_installed = 0;
barrier(); barrier();
unregister_kretprobe(&wc_get_random_bytes_user_kretprobe); unregister_kretprobe(&wc_get_random_bytes_user_kretprobe);
pr_info("wc_get_random_bytes_user_kretprobe uninstalled\n"); pr_info("libwolfssl: wc_get_random_bytes_user_kretprobe uninstalled\n");
} }
#endif /* WOLFSSL_LINUXKM_USE_GET_RANDOM_USER_KRETPROBE */ #endif /* WOLFSSL_LINUXKM_USE_GET_RANDOM_USER_KRETPROBE */

View File

@@ -1,5 +1,5 @@
--- ./drivers/char/random.c.dist 2020-12-13 16:41:30.000000000 -0600 --- ./drivers/char/random.c.dist 2020-12-13 16:41:30.000000000 -0600
+++ ./drivers/char/random.c 2025-06-28 10:11:47.329492006 -0500 +++ ./drivers/char/random.c 2025-07-02 11:59:07.220250957 -0500
@@ -344,6 +344,260 @@ @@ -344,6 +344,260 @@
#include <asm/irq_regs.h> #include <asm/irq_regs.h>
#include <asm/io.h> #include <asm/io.h>
@@ -261,22 +261,30 @@
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include <trace/events/random.h> #include <trace/events/random.h>
@@ -461,7 +715,13 @@ static struct crng_state primary_crng = @@ -461,7 +715,22 @@ static struct crng_state primary_crng =
* its value (from 0->1->2). * its value (from 0->1->2).
*/ */
static int crng_init = 0; static int crng_init = 0;
-#define crng_ready() (likely(crng_init > 1)) +
#define crng_ready() (likely(crng_init > 1))
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ #define crng_ready_by_cb() (atomic_read(&random_bytes_cb_refcnt) && call_crng_ready_cb())
+ #define crng_ready_maybe_cb() (atomic_read(&random_bytes_cb_refcnt) ? (call_crng_ready_cb() || crng_ready()) : crng_ready())
+#else
+ #define crng_ready_maybe_cb() crng_ready()
+#endif
+ +
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS +#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ #define crng_ready() (atomic_read(&random_bytes_cb_refcnt) ? call_crng_ready_cb() : (likely(crng_init > 1))) + #define crng_ready_by_cb() (atomic_read(&random_bytes_cb_refcnt) && call_crng_ready_cb())
+ #define crng_ready_maybe_cb() (atomic_read(&random_bytes_cb_refcnt) ? (call_crng_ready_cb() || crng_ready()) : crng_ready())
+#else +#else
+ #define crng_ready() (likely(crng_init > 1)) + #define crng_ready_maybe_cb() crng_ready()
+#endif +#endif
+ +
static int crng_init_cnt = 0; static int crng_init_cnt = 0;
static unsigned long crng_global_init_time = 0; static unsigned long crng_global_init_time = 0;
#define CRNG_INIT_CNT_THRESH (2*CHACHA_KEY_SIZE) #define CRNG_INIT_CNT_THRESH (2*CHACHA_KEY_SIZE)
@@ -593,6 +853,11 @@ static void mix_pool_bytes(struct entrop @@ -593,6 +862,11 @@ static void mix_pool_bytes(struct entrop
{ {
unsigned long flags; unsigned long flags;
@@ -288,7 +296,7 @@
trace_mix_pool_bytes(r->name, nbytes, _RET_IP_); trace_mix_pool_bytes(r->name, nbytes, _RET_IP_);
spin_lock_irqsave(&r->lock, flags); spin_lock_irqsave(&r->lock, flags);
_mix_pool_bytes(r, in, nbytes); _mix_pool_bytes(r, in, nbytes);
@@ -664,6 +929,10 @@ static void credit_entropy_bits(struct e @@ -664,6 +938,10 @@ static void credit_entropy_bits(struct e
const int pool_size = r->poolinfo->poolfracbits; const int pool_size = r->poolinfo->poolfracbits;
int nfrac = nbits << ENTROPY_SHIFT; int nfrac = nbits << ENTROPY_SHIFT;
@@ -299,19 +307,7 @@
if (!nbits) if (!nbits)
return; return;
@@ -954,6 +1223,11 @@ static void crng_reseed(struct crng_stat @@ -1069,6 +1347,18 @@ static ssize_t extract_crng_user(void __
__u32 key[8];
} buf;
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ (void)call_crng_reseed_cb();
+ /* fall through to reseed native crng too. */
+#endif
+
if (r) {
num = extract_entropy(r, &buf, 32, 16, 0);
if (num == 0)
@@ -1069,6 +1343,18 @@ static ssize_t extract_crng_user(void __
__u8 tmp[CHACHA_BLOCK_SIZE] __aligned(4); __u8 tmp[CHACHA_BLOCK_SIZE] __aligned(4);
int large_request = (nbytes > 256); int large_request = (nbytes > 256);
@@ -330,7 +326,16 @@
while (nbytes) { while (nbytes) {
if (large_request && need_resched()) { if (large_request && need_resched()) {
if (signal_pending(current)) { if (signal_pending(current)) {
@@ -1552,6 +1838,14 @@ static void _get_random_bytes(void *buf, @@ -1523,7 +1813,7 @@ static void _warn_unseeded_randomness(co
#endif
if (print_once ||
- crng_ready() ||
+ crng_ready_maybe_cb() ||
(previous && (caller == READ_ONCE(*previous))))
return;
WRITE_ONCE(*previous, caller);
@@ -1552,6 +1842,14 @@ static void _get_random_bytes(void *buf,
trace_get_random_bytes(nbytes, _RET_IP_); trace_get_random_bytes(nbytes, _RET_IP_);
@@ -345,6 +350,77 @@
while (nbytes >= CHACHA_BLOCK_SIZE) { while (nbytes >= CHACHA_BLOCK_SIZE) {
extract_crng(buf); extract_crng(buf);
buf += CHACHA_BLOCK_SIZE; buf += CHACHA_BLOCK_SIZE;
@@ -1638,12 +1936,12 @@ static void try_to_generate_entropy(void
*/
int wait_for_random_bytes(void)
{
- if (likely(crng_ready()))
+ if (likely(crng_ready_maybe_cb()))
return 0;
do {
int ret;
- ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ);
+ ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready_maybe_cb(), HZ);
if (ret)
return ret > 0 ? 0 : ret;
@@ -1665,7 +1963,7 @@ EXPORT_SYMBOL(wait_for_random_bytes);
*/
bool rng_is_initialized(void)
{
- return crng_ready();
+ return crng_ready_maybe_cb();
}
EXPORT_SYMBOL(rng_is_initialized);
@@ -1843,7 +2141,7 @@ urandom_read(struct file *file, char __u
unsigned long flags;
static int maxwarn = 10;
- if (!crng_ready() && maxwarn > 0) {
+ if (!crng_ready_maybe_cb() && maxwarn > 0) {
maxwarn--;
if (__ratelimit(&urandom_warning))
pr_notice("%s: uninitialized urandom read (%zd bytes read)\n",
@@ -1872,6 +2170,11 @@ random_poll(struct file *file, poll_tabl
{
__poll_t mask;
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ if (crng_ready_by_cb())
+ return EPOLLIN | EPOLLRDNORM;
+#endif
+
poll_wait(file, &crng_init_wait, wait);
poll_wait(file, &random_write_wait, wait);
mask = 0;
@@ -1970,6 +2273,16 @@ static long random_ioctl(struct file *f,
case RNDRESEEDCRNG:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ /* fall through to reseed native crng too. */
+ if (call_crng_reseed_cb() == 0) {
+ if (crng_init >= 2) {
+ crng_reseed(&primary_crng, &input_pool);
+ crng_global_init_time = jiffies - 1;
+ }
+ return 0;
+ }
+#endif
if (crng_init < 2)
return -ENODATA;
crng_reseed(&primary_crng, NULL);
@@ -2022,7 +2335,7 @@ SYSCALL_DEFINE3(getrandom, char __user *
if (count > INT_MAX)
count = INT_MAX;
- if (!(flags & GRND_INSECURE) && !crng_ready()) {
+ if (!(flags & GRND_INSECURE) && !crng_ready_maybe_cb()) {
if (flags & GRND_NONBLOCK)
return -EAGAIN;
ret = wait_for_random_bytes();
--- ./include/linux/random.h.dist 2020-12-13 16:41:30.000000000 -0600 --- ./include/linux/random.h.dist 2020-12-13 16:41:30.000000000 -0600
+++ ./include/linux/random.h 2025-06-30 12:05:59.106440700 -0500 +++ ./include/linux/random.h 2025-06-30 12:05:59.106440700 -0500
@@ -158,4 +158,37 @@ static inline bool __init arch_get_rando @@ -158,4 +158,37 @@ static inline bool __init arch_get_rando

View File

@@ -1,5 +1,5 @@
--- ./drivers/char/random.c.dist 2025-04-29 18:54:03.390121890 -0500 --- ./drivers/char/random.c.dist 2025-04-29 18:54:03.390121890 -0500
+++ ./drivers/char/random.c 2025-06-28 11:49:00.005493589 -0500 +++ ./drivers/char/random.c 2025-07-02 11:57:40.176497765 -0500
@@ -60,6 +60,260 @@ @@ -60,6 +60,260 @@
#include <asm/irq_regs.h> #include <asm/irq_regs.h>
#include <asm/io.h> #include <asm/io.h>
@@ -261,34 +261,55 @@
/********************************************************************* /*********************************************************************
* *
* Initialization and readiness waiting. * Initialization and readiness waiting.
@@ -79,7 +333,13 @@ static enum { @@ -79,7 +333,15 @@ static enum {
CRNG_EARLY = 1, /* At least POOL_EARLY_BITS collected */ CRNG_EARLY = 1, /* At least POOL_EARLY_BITS collected */
CRNG_READY = 2 /* Fully initialized with POOL_READY_BITS collected */ CRNG_READY = 2 /* Fully initialized with POOL_READY_BITS collected */
} crng_init __read_mostly = CRNG_EMPTY; } crng_init __read_mostly = CRNG_EMPTY;
-#define crng_ready() (likely(crng_init >= CRNG_READY))
+ +
#define crng_ready() (likely(crng_init >= CRNG_READY))
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS +#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ #define crng_ready() (atomic_read(&random_bytes_cb_refcnt) ? call_crng_ready_cb() : (likely(crng_init >= CRNG_READY))) + #define crng_ready_by_cb() (atomic_read(&random_bytes_cb_refcnt) && call_crng_ready_cb())
+ #define crng_ready_maybe_cb() (atomic_read(&random_bytes_cb_refcnt) ? (call_crng_ready_cb() || crng_ready()) : crng_ready())
+#else +#else
+ #define crng_ready() (likely(crng_init >= CRNG_READY)) + #define crng_ready_maybe_cb() crng_ready()
+#endif +#endif
+ +
/* Various types of waiters for crng_init->CRNG_READY transition. */ /* Various types of waiters for crng_init->CRNG_READY transition. */
static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait); static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);
static struct fasync_struct *fasync; static struct fasync_struct *fasync;
@@ -247,6 +507,11 @@ static void crng_reseed(void) @@ -105,7 +367,7 @@ MODULE_PARM_DESC(ratelimit_disable, "Dis
unsigned long next_gen; */
u8 key[CHACHA_KEY_SIZE]; bool rng_is_initialized(void)
{
- return crng_ready();
+ return crng_ready_maybe_cb();
}
EXPORT_SYMBOL(rng_is_initialized);
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS @@ -124,11 +386,11 @@ static void try_to_generate_entropy(void
+ (void)call_crng_reseed_cb(); */
+ /* fall through to reseed native crng too. */ int wait_for_random_bytes(void)
+#endif {
+ - while (!crng_ready()) {
extract_entropy(key, sizeof(key)); + while (!crng_ready_maybe_cb()) {
int ret;
/* try_to_generate_entropy();
@@ -401,6 +666,14 @@ static void _get_random_bytes(void *buf, - ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ);
+ ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready_maybe_cb(), HZ);
if (ret)
return ret > 0 ? 0 : ret;
}
@@ -182,7 +444,7 @@ static void __cold process_random_ready_
}
#define warn_unseeded_randomness() \
- if (IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM) && !crng_ready()) \
+ if (IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM) && !crng_ready_maybe_cb()) \
printk_deferred(KERN_NOTICE "random: %s called from %pS with crng_init=%d\n", \
__func__, (void *)_RET_IP_, crng_init)
@@ -401,6 +663,14 @@ static void _get_random_bytes(void *buf,
if (!len) if (!len)
return; return;
@@ -303,7 +324,7 @@
first_block_len = min_t(size_t, 32, len); first_block_len = min_t(size_t, 32, len);
crng_make_state(chacha_state, buf, first_block_len); crng_make_state(chacha_state, buf, first_block_len);
len -= first_block_len; len -= first_block_len;
@@ -450,6 +723,18 @@ static ssize_t get_random_bytes_user(str @@ -450,6 +720,18 @@ static ssize_t get_random_bytes_user(str
if (unlikely(!iov_iter_count(iter))) if (unlikely(!iov_iter_count(iter)))
return 0; return 0;
@@ -322,7 +343,16 @@
/* /*
* Immediately overwrite the ChaCha key at index 4 with random * Immediately overwrite the ChaCha key at index 4 with random
* bytes, in case userspace causes copy_to_iter() below to sleep * bytes, in case userspace causes copy_to_iter() below to sleep
@@ -650,6 +935,11 @@ static void mix_pool_bytes(const void *b @@ -526,7 +808,7 @@ type get_random_ ##type(void) \
\
warn_unseeded_randomness(); \
\
- if (!crng_ready()) { \
+ if (!crng_ready_maybe_cb()) { \
_get_random_bytes(&ret, sizeof(ret)); \
return ret; \
} \
@@ -650,6 +932,11 @@ static void mix_pool_bytes(const void *b
{ {
unsigned long flags; unsigned long flags;
@@ -334,7 +364,7 @@
spin_lock_irqsave(&input_pool.lock, flags); spin_lock_irqsave(&input_pool.lock, flags);
_mix_pool_bytes(buf, len); _mix_pool_bytes(buf, len);
spin_unlock_irqrestore(&input_pool.lock, flags); spin_unlock_irqrestore(&input_pool.lock, flags);
@@ -701,7 +991,11 @@ static void extract_entropy(void *buf, s @@ -701,7 +988,11 @@ static void extract_entropy(void *buf, s
memzero_explicit(&block, sizeof(block)); memzero_explicit(&block, sizeof(block));
} }
@@ -346,6 +376,50 @@
static void __cold _credit_init_bits(size_t bits) static void __cold _credit_init_bits(size_t bits)
{ {
@@ -1229,7 +1520,7 @@ SYSCALL_DEFINE3(getrandom, char __user *
if ((flags & (GRND_INSECURE | GRND_RANDOM)) == (GRND_INSECURE | GRND_RANDOM))
return -EINVAL;
- if (!crng_ready() && !(flags & GRND_INSECURE)) {
+ if (!crng_ready_maybe_cb() && !(flags & GRND_INSECURE)) {
if (flags & GRND_NONBLOCK)
return -EAGAIN;
ret = wait_for_random_bytes();
@@ -1245,6 +1536,10 @@ SYSCALL_DEFINE3(getrandom, char __user *
static __poll_t random_poll(struct file *file, poll_table *wait)
{
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ if (crng_ready_by_cb())
+ return EPOLLIN | EPOLLRDNORM;
+#endif
poll_wait(file, &crng_init_wait, wait);
return crng_ready() ? EPOLLIN | EPOLLRDNORM : EPOLLOUT | EPOLLWRNORM;
}
@@ -1286,7 +1581,7 @@ static ssize_t urandom_read_iter(struct
{
static int maxwarn = 10;
- if (!crng_ready()) {
+ if (!crng_ready_maybe_cb()) {
if (!ratelimit_disable && maxwarn <= 0)
++urandom_warning.missed;
else if (ratelimit_disable || __ratelimit(&urandom_warning)) {
@@ -1369,6 +1664,14 @@ static long random_ioctl(struct file *f,
case RNDRESEEDCRNG:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ /* fall through to reseed native crng too. */
+ if (call_crng_reseed_cb() == 0) {
+ if (crng_ready())
+ crng_reseed();
+ return 0;
+ }
+#endif
if (!crng_ready())
return -ENODATA;
crng_reseed();
--- ./include/linux/random.h.dist 2025-04-29 18:54:07.595202807 -0500 --- ./include/linux/random.h.dist 2025-04-29 18:54:07.595202807 -0500
+++ ./include/linux/random.h 2025-06-30 12:03:15.263141842 -0500 +++ ./include/linux/random.h 2025-06-30 12:03:15.263141842 -0500
@@ -138,4 +138,37 @@ int random_online_cpu(unsigned int cpu); @@ -138,4 +138,37 @@ int random_online_cpu(unsigned int cpu);

View File

@@ -1,5 +1,5 @@
--- ./drivers/char/random.c.dist 2021-10-31 15:53:10.000000000 -0500 --- ./drivers/char/random.c.dist 2021-10-31 15:53:10.000000000 -0500
+++ ./drivers/char/random.c 2025-06-28 13:16:25.528404270 -0500 +++ ./drivers/char/random.c 2025-07-02 11:49:13.836320539 -0500
@@ -344,6 +344,260 @@ @@ -344,6 +344,260 @@
#include <asm/irq_regs.h> #include <asm/irq_regs.h>
#include <asm/io.h> #include <asm/io.h>
@@ -261,22 +261,30 @@
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include <trace/events/random.h> #include <trace/events/random.h>
@@ -461,7 +715,13 @@ static struct crng_state primary_crng = @@ -461,7 +715,22 @@ static struct crng_state primary_crng =
* its value (from 0->1->2). * its value (from 0->1->2).
*/ */
static int crng_init = 0; static int crng_init = 0;
-#define crng_ready() (likely(crng_init > 1)) +
#define crng_ready() (likely(crng_init > 1))
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ #define crng_ready_by_cb() (atomic_read(&random_bytes_cb_refcnt) && call_crng_ready_cb())
+ #define crng_ready_maybe_cb() (atomic_read(&random_bytes_cb_refcnt) ? (call_crng_ready_cb() || crng_ready()) : crng_ready())
+#else
+ #define crng_ready_maybe_cb() crng_ready()
+#endif
+ +
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS +#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ #define crng_ready() (atomic_read(&random_bytes_cb_refcnt) ? call_crng_ready_cb() : (likely(crng_init > 1))) + #define crng_ready_by_cb() (atomic_read(&random_bytes_cb_refcnt) && call_crng_ready_cb())
+ #define crng_ready_maybe_cb() (atomic_read(&random_bytes_cb_refcnt) ? (call_crng_ready_cb() || crng_ready()) : crng_ready())
+#else +#else
+ #define crng_ready() (likely(crng_init > 1)) + #define crng_ready_maybe_cb() crng_ready()
+#endif +#endif
+ +
static int crng_init_cnt = 0; static int crng_init_cnt = 0;
static unsigned long crng_global_init_time = 0; static unsigned long crng_global_init_time = 0;
#define CRNG_INIT_CNT_THRESH (2*CHACHA_KEY_SIZE) #define CRNG_INIT_CNT_THRESH (2*CHACHA_KEY_SIZE)
@@ -593,6 +853,12 @@ static void mix_pool_bytes(struct entrop @@ -593,6 +862,12 @@ static void mix_pool_bytes(struct entrop
unsigned long flags; unsigned long flags;
trace_mix_pool_bytes(r->name, nbytes, _RET_IP_); trace_mix_pool_bytes(r->name, nbytes, _RET_IP_);
@@ -289,19 +297,7 @@
spin_lock_irqsave(&r->lock, flags); spin_lock_irqsave(&r->lock, flags);
_mix_pool_bytes(r, in, nbytes); _mix_pool_bytes(r, in, nbytes);
spin_unlock_irqrestore(&r->lock, flags); spin_unlock_irqrestore(&r->lock, flags);
@@ -944,6 +1210,11 @@ static void crng_reseed(struct crng_stat @@ -1059,6 +1334,18 @@ static ssize_t extract_crng_user(void __
__u32 key[8];
} buf;
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ (void)call_crng_reseed_cb();
+ /* fall through to reseed native crng too. */
+#endif
+
if (r) {
num = extract_entropy(r, &buf, 32, 16, 0);
if (num == 0)
@@ -1059,6 +1330,18 @@ static ssize_t extract_crng_user(void __
__u8 tmp[CHACHA_BLOCK_SIZE] __aligned(4); __u8 tmp[CHACHA_BLOCK_SIZE] __aligned(4);
int large_request = (nbytes > 256); int large_request = (nbytes > 256);
@@ -320,7 +316,16 @@
while (nbytes) { while (nbytes) {
if (large_request && need_resched()) { if (large_request && need_resched()) {
if (signal_pending(current)) { if (signal_pending(current)) {
@@ -1528,6 +1811,14 @@ static void _get_random_bytes(void *buf, @@ -1499,7 +1786,7 @@ static void _warn_unseeded_randomness(co
#endif
if (print_once ||
- crng_ready() ||
+ crng_ready_maybe_cb() ||
(previous && (caller == READ_ONCE(*previous))))
return;
WRITE_ONCE(*previous, caller);
@@ -1528,6 +1815,14 @@ static void _get_random_bytes(void *buf,
trace_get_random_bytes(nbytes, _RET_IP_); trace_get_random_bytes(nbytes, _RET_IP_);
@@ -335,6 +340,77 @@
while (nbytes >= CHACHA_BLOCK_SIZE) { while (nbytes >= CHACHA_BLOCK_SIZE) {
extract_crng(buf); extract_crng(buf);
buf += CHACHA_BLOCK_SIZE; buf += CHACHA_BLOCK_SIZE;
@@ -1614,12 +1909,12 @@ static void try_to_generate_entropy(void
*/
int wait_for_random_bytes(void)
{
- if (likely(crng_ready()))
+ if (likely(crng_ready_maybe_cb()))
return 0;
do {
int ret;
- ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ);
+ ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready_maybe_cb(), HZ);
if (ret)
return ret > 0 ? 0 : ret;
@@ -1641,7 +1936,7 @@ EXPORT_SYMBOL(wait_for_random_bytes);
*/
bool rng_is_initialized(void)
{
- return crng_ready();
+ return crng_ready_maybe_cb();
}
EXPORT_SYMBOL(rng_is_initialized);
@@ -1819,7 +2114,7 @@ urandom_read(struct file *file, char __u
unsigned long flags;
static int maxwarn = 10;
- if (!crng_ready() && maxwarn > 0) {
+ if (!crng_ready_maybe_cb() && maxwarn > 0) {
maxwarn--;
if (__ratelimit(&urandom_warning))
pr_notice("%s: uninitialized urandom read (%zd bytes read)\n",
@@ -1848,6 +2143,11 @@ random_poll(struct file *file, poll_tabl
{
__poll_t mask;
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ if (crng_ready_by_cb())
+ return EPOLLIN | EPOLLRDNORM;
+#endif
+
poll_wait(file, &crng_init_wait, wait);
poll_wait(file, &random_write_wait, wait);
mask = 0;
@@ -1946,6 +2246,16 @@ static long random_ioctl(struct file *f,
case RNDRESEEDCRNG:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ /* fall through to reseed native crng too. */
+ if (call_crng_reseed_cb() == 0) {
+ if (crng_init >= 2) {
+ crng_reseed(&primary_crng, &input_pool);
+ crng_global_init_time = jiffies - 1;
+ }
+ return 0;
+ }
+#endif
if (crng_init < 2)
return -ENODATA;
crng_reseed(&primary_crng, &input_pool);
@@ -1998,7 +2308,7 @@ SYSCALL_DEFINE3(getrandom, char __user *
if (count > INT_MAX)
count = INT_MAX;
- if (!(flags & GRND_INSECURE) && !crng_ready()) {
+ if (!(flags & GRND_INSECURE) && !crng_ready_maybe_cb()) {
if (flags & GRND_NONBLOCK)
return -EAGAIN;
ret = wait_for_random_bytes();
--- ./include/linux/random.h.dist 2021-10-31 15:53:10.000000000 -0500 --- ./include/linux/random.h.dist 2021-10-31 15:53:10.000000000 -0500
+++ ./include/linux/random.h 2025-06-28 13:09:13.392547118 -0500 +++ ./include/linux/random.h 2025-06-28 13:09:13.392547118 -0500
@@ -158,4 +158,37 @@ static inline bool __init arch_get_rando @@ -158,4 +158,37 @@ static inline bool __init arch_get_rando

View File

@@ -1,5 +1,5 @@
--- ./drivers/char/random.c.dist 2022-05-31 08:33:43.006547419 -0500 --- ./drivers/char/random.c.dist 2022-05-31 08:33:43.006547419 -0500
+++ ./drivers/char/random.c 2025-06-28 14:03:07.062703841 -0500 +++ ./drivers/char/random.c 2025-07-02 11:42:10.098166804 -0500
@@ -60,6 +60,260 @@ @@ -60,6 +60,260 @@
#include <asm/irq_regs.h> #include <asm/irq_regs.h>
#include <asm/io.h> #include <asm/io.h>
@@ -261,34 +261,55 @@
/********************************************************************* /*********************************************************************
* *
* Initialization and readiness waiting. * Initialization and readiness waiting.
@@ -80,7 +334,13 @@ static enum { @@ -80,7 +334,15 @@ static enum {
CRNG_READY = 2 /* Fully initialized with POOL_READY_BITS collected */ CRNG_READY = 2 /* Fully initialized with POOL_READY_BITS collected */
} crng_init __read_mostly = CRNG_EMPTY; } crng_init __read_mostly = CRNG_EMPTY;
static DEFINE_STATIC_KEY_FALSE(crng_is_ready); static DEFINE_STATIC_KEY_FALSE(crng_is_ready);
-#define crng_ready() (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY)
+ +
#define crng_ready() (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY)
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS +#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ #define crng_ready() (atomic_read(&random_bytes_cb_refcnt) ? call_crng_ready_cb() : (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY)) + #define crng_ready_by_cb() (atomic_read(&random_bytes_cb_refcnt) && call_crng_ready_cb())
+ #define crng_ready_maybe_cb() (atomic_read(&random_bytes_cb_refcnt) ? (call_crng_ready_cb() || crng_ready()) : crng_ready())
+#else +#else
+ #define crng_ready() (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY) + #define crng_ready_maybe_cb() crng_ready()
+#endif +#endif
+ +
/* Various types of waiters for crng_init->CRNG_READY transition. */ /* Various types of waiters for crng_init->CRNG_READY transition. */
static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait); static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);
static struct fasync_struct *fasync; static struct fasync_struct *fasync;
@@ -253,6 +513,11 @@ static void crng_reseed(void) @@ -106,7 +368,7 @@ MODULE_PARM_DESC(ratelimit_disable, "Dis
unsigned long next_gen; */
u8 key[CHACHA_KEY_SIZE]; bool rng_is_initialized(void)
{
- return crng_ready();
+ return crng_ready_maybe_cb();
}
EXPORT_SYMBOL(rng_is_initialized);
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS @@ -130,11 +392,11 @@ static void try_to_generate_entropy(void
+ (void)call_crng_reseed_cb(); */
+ /* fall through to reseed native crng too. */ int wait_for_random_bytes(void)
+#endif {
+ - while (!crng_ready()) {
extract_entropy(key, sizeof(key)); + while (!crng_ready_maybe_cb()) {
int ret;
/* try_to_generate_entropy();
@@ -407,6 +672,14 @@ static void _get_random_bytes(void *buf, - ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ);
+ ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready_maybe_cb(), HZ);
if (ret)
return ret > 0 ? 0 : ret;
}
@@ -188,7 +450,7 @@ static void __cold process_random_ready_
}
#define warn_unseeded_randomness() \
- if (IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM) && !crng_ready()) \
+ if (IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM) && !crng_ready_maybe_cb()) \
printk_deferred(KERN_NOTICE "random: %s called from %pS with crng_init=%d\n", \
__func__, (void *)_RET_IP_, crng_init)
@@ -407,6 +669,14 @@ static void _get_random_bytes(void *buf,
if (!len) if (!len)
return; return;
@@ -303,7 +324,7 @@
first_block_len = min_t(size_t, 32, len); first_block_len = min_t(size_t, 32, len);
crng_make_state(chacha_state, buf, first_block_len); crng_make_state(chacha_state, buf, first_block_len);
len -= first_block_len; len -= first_block_len;
@@ -456,6 +729,18 @@ static ssize_t get_random_bytes_user(str @@ -456,6 +726,18 @@ static ssize_t get_random_bytes_user(str
if (unlikely(!iov_iter_count(iter))) if (unlikely(!iov_iter_count(iter)))
return 0; return 0;
@@ -322,7 +343,16 @@
/* /*
* Immediately overwrite the ChaCha key at index 4 with random * Immediately overwrite the ChaCha key at index 4 with random
* bytes, in case userspace causes copy_to_user() below to sleep * bytes, in case userspace causes copy_to_user() below to sleep
@@ -656,6 +941,11 @@ static void mix_pool_bytes(const void *b @@ -532,7 +814,7 @@ type get_random_ ##type(void) \
\
warn_unseeded_randomness(); \
\
- if (!crng_ready()) { \
+ if (!crng_ready_maybe_cb()) { \
_get_random_bytes(&ret, sizeof(ret)); \
return ret; \
} \
@@ -656,6 +938,11 @@ static void mix_pool_bytes(const void *b
{ {
unsigned long flags; unsigned long flags;
@@ -334,7 +364,7 @@
spin_lock_irqsave(&input_pool.lock, flags); spin_lock_irqsave(&input_pool.lock, flags);
_mix_pool_bytes(buf, len); _mix_pool_bytes(buf, len);
spin_unlock_irqrestore(&input_pool.lock, flags); spin_unlock_irqrestore(&input_pool.lock, flags);
@@ -707,7 +997,11 @@ static void extract_entropy(void *buf, s @@ -707,7 +994,11 @@ static void extract_entropy(void *buf, s
memzero_explicit(&block, sizeof(block)); memzero_explicit(&block, sizeof(block));
} }
@@ -346,6 +376,50 @@
static void __cold _credit_init_bits(size_t bits) static void __cold _credit_init_bits(size_t bits)
{ {
@@ -1233,7 +1524,7 @@ SYSCALL_DEFINE3(getrandom, char __user *
if ((flags & (GRND_INSECURE | GRND_RANDOM)) == (GRND_INSECURE | GRND_RANDOM))
return -EINVAL;
- if (!crng_ready() && !(flags & GRND_INSECURE)) {
+ if (!crng_ready_maybe_cb() && !(flags & GRND_INSECURE)) {
if (flags & GRND_NONBLOCK)
return -EAGAIN;
ret = wait_for_random_bytes();
@@ -1249,6 +1540,10 @@ SYSCALL_DEFINE3(getrandom, char __user *
static __poll_t random_poll(struct file *file, poll_table *wait)
{
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ if (crng_ready_by_cb())
+ return EPOLLIN | EPOLLRDNORM;
+#endif
poll_wait(file, &crng_init_wait, wait);
return crng_ready() ? EPOLLIN | EPOLLRDNORM : EPOLLOUT | EPOLLWRNORM;
}
@@ -1290,7 +1585,7 @@ static ssize_t urandom_read_iter(struct
{
static int maxwarn = 10;
- if (!crng_ready()) {
+ if (!crng_ready_maybe_cb()) {
if (!ratelimit_disable && maxwarn <= 0)
++urandom_warning.missed;
else if (ratelimit_disable || __ratelimit(&urandom_warning)) {
@@ -1368,6 +1663,14 @@ static long random_ioctl(struct file *f,
case RNDRESEEDCRNG:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ /* fall through to reseed native crng too. */
+ if (call_crng_reseed_cb() == 0) {
+ if (crng_ready())
+ crng_reseed();
+ return 0;
+ }
+#endif
if (!crng_ready())
return -ENODATA;
crng_reseed();
--- ./include/linux/random.h.dist 2022-05-31 08:33:43.007547457 -0500 --- ./include/linux/random.h.dist 2022-05-31 08:33:43.007547457 -0500
+++ ./include/linux/random.h 2025-06-30 12:06:15.219731761 -0500 +++ ./include/linux/random.h 2025-06-30 12:06:15.219731761 -0500
@@ -138,4 +138,37 @@ int random_online_cpu(unsigned int cpu); @@ -138,4 +138,37 @@ int random_online_cpu(unsigned int cpu);

View File

@@ -1,5 +1,5 @@
--- ./drivers/char/random.c.dist 2024-01-19 16:25:03.754138321 -0600 --- ./drivers/char/random.c.dist 2024-01-19 16:25:03.754138321 -0600
+++ ./drivers/char/random.c 2025-06-30 12:39:40.400450784 -0500 +++ ./drivers/char/random.c 2025-07-02 10:45:31.769041473 -0500
@@ -60,6 +60,260 @@ @@ -60,6 +60,260 @@
#include <asm/irq_regs.h> #include <asm/irq_regs.h>
#include <asm/io.h> #include <asm/io.h>
@@ -261,34 +261,55 @@
/********************************************************************* /*********************************************************************
* *
* Initialization and readiness waiting. * Initialization and readiness waiting.
@@ -80,7 +334,13 @@ static enum { @@ -80,7 +334,15 @@ static enum {
CRNG_READY = 2 /* Fully initialized with POOL_READY_BITS collected */ CRNG_READY = 2 /* Fully initialized with POOL_READY_BITS collected */
} crng_init __read_mostly = CRNG_EMPTY; } crng_init __read_mostly = CRNG_EMPTY;
static DEFINE_STATIC_KEY_FALSE(crng_is_ready); static DEFINE_STATIC_KEY_FALSE(crng_is_ready);
-#define crng_ready() (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY)
+ +
#define crng_ready() (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY)
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS +#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ #define crng_ready() (atomic_read(&random_bytes_cb_refcnt) ? call_crng_ready_cb() : (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY)) + #define crng_ready_by_cb() (atomic_read(&random_bytes_cb_refcnt) && call_crng_ready_cb())
+ #define crng_ready_maybe_cb() (atomic_read(&random_bytes_cb_refcnt) ? (call_crng_ready_cb() || crng_ready()) : crng_ready())
+#else +#else
+ #define crng_ready() (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY) + #define crng_ready_maybe_cb() crng_ready()
+#endif +#endif
+ +
/* Various types of waiters for crng_init->CRNG_READY transition. */ /* Various types of waiters for crng_init->CRNG_READY transition. */
static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait); static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);
static struct fasync_struct *fasync; static struct fasync_struct *fasync;
@@ -210,6 +470,11 @@ static void crng_reseed(void) @@ -104,7 +366,7 @@ MODULE_PARM_DESC(ratelimit_disable, "Dis
unsigned long next_gen; */
u8 key[CHACHA_KEY_SIZE]; bool rng_is_initialized(void)
{
- return crng_ready();
+ return crng_ready_maybe_cb();
}
EXPORT_SYMBOL(rng_is_initialized);
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS @@ -128,11 +390,11 @@ static void try_to_generate_entropy(void
+ (void)call_crng_reseed_cb(); */
+ /* fall through to reseed native crng too. */ int wait_for_random_bytes(void)
+#endif {
+ - while (!crng_ready()) {
extract_entropy(key, sizeof(key)); + while (!crng_ready_maybe_cb()) {
int ret;
/* try_to_generate_entropy();
@@ -362,6 +627,14 @@ static void _get_random_bytes(void *buf, - ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ);
+ ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready_maybe_cb(), HZ);
if (ret)
return ret > 0 ? 0 : ret;
}
@@ -141,7 +403,7 @@ int wait_for_random_bytes(void)
EXPORT_SYMBOL(wait_for_random_bytes);
#define warn_unseeded_randomness() \
- if (IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM) && !crng_ready()) \
+ if (IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM) && !crng_ready_maybe_cb()) \
printk_deferred(KERN_NOTICE "random: %s called from %pS with crng_init=%d\n", \
__func__, (void *)_RET_IP_, crng_init)
@@ -362,6 +624,14 @@ static void _get_random_bytes(void *buf,
if (!len) if (!len)
return; return;
@@ -303,7 +324,7 @@
first_block_len = min_t(size_t, 32, len); first_block_len = min_t(size_t, 32, len);
crng_make_state(chacha_state, buf, first_block_len); crng_make_state(chacha_state, buf, first_block_len);
len -= first_block_len; len -= first_block_len;
@@ -408,6 +681,18 @@ static ssize_t get_random_bytes_user(str @@ -408,6 +678,18 @@ static ssize_t get_random_bytes_user(str
if (unlikely(!iov_iter_count(iter))) if (unlikely(!iov_iter_count(iter)))
return 0; return 0;
@@ -322,7 +343,16 @@
/* /*
* Immediately overwrite the ChaCha key at index 4 with random * Immediately overwrite the ChaCha key at index 4 with random
* bytes, in case userspace causes copy_to_iter() below to sleep * bytes, in case userspace causes copy_to_iter() below to sleep
@@ -620,6 +905,11 @@ static void mix_pool_bytes(const void *b @@ -484,7 +766,7 @@ type get_random_ ##type(void) \
\
warn_unseeded_randomness(); \
\
- if (!crng_ready()) { \
+ if (!crng_ready_maybe_cb()) { \
_get_random_bytes(&ret, sizeof(ret)); \
return ret; \
} \
@@ -620,6 +902,11 @@ static void mix_pool_bytes(const void *b
{ {
unsigned long flags; unsigned long flags;
@@ -334,7 +364,7 @@
spin_lock_irqsave(&input_pool.lock, flags); spin_lock_irqsave(&input_pool.lock, flags);
_mix_pool_bytes(buf, len); _mix_pool_bytes(buf, len);
spin_unlock_irqrestore(&input_pool.lock, flags); spin_unlock_irqrestore(&input_pool.lock, flags);
@@ -679,7 +969,11 @@ static void extract_entropy(void *buf, s @@ -679,7 +966,11 @@ static void extract_entropy(void *buf, s
memzero_explicit(&block, sizeof(block)); memzero_explicit(&block, sizeof(block));
} }
@@ -346,6 +376,63 @@
static void __cold _credit_init_bits(size_t bits) static void __cold _credit_init_bits(size_t bits)
{ {
@@ -1321,7 +1612,7 @@ SYSCALL_DEFINE3(getrandom, char __user *
if ((flags & (GRND_INSECURE | GRND_RANDOM)) == (GRND_INSECURE | GRND_RANDOM))
return -EINVAL;
- if (!crng_ready() && !(flags & GRND_INSECURE)) {
+ if (!crng_ready_maybe_cb() && !(flags & GRND_INSECURE)) {
if (flags & GRND_NONBLOCK)
return -EAGAIN;
ret = wait_for_random_bytes();
@@ -1337,6 +1628,10 @@ SYSCALL_DEFINE3(getrandom, char __user *
static __poll_t random_poll(struct file *file, poll_table *wait)
{
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ if (crng_ready_by_cb())
+ return EPOLLIN | EPOLLRDNORM;
+#endif
poll_wait(file, &crng_init_wait, wait);
return crng_ready() ? EPOLLIN | EPOLLRDNORM : EPOLLOUT | EPOLLWRNORM;
}
@@ -1382,10 +1677,10 @@ static ssize_t urandom_read_iter(struct
* Opportunistically attempt to initialize the RNG on platforms that
* have fast cycle counters, but don't (for now) require it to succeed.
*/
- if (!crng_ready())
+ if (!crng_ready_maybe_cb())
try_to_generate_entropy();
- if (!crng_ready()) {
+ if (!crng_ready_maybe_cb()) {
if (!ratelimit_disable && maxwarn <= 0)
++urandom_warning.missed;
else if (ratelimit_disable || __ratelimit(&urandom_warning)) {
@@ -1402,7 +1697,7 @@ static ssize_t random_read_iter(struct k
{
int ret;
- if (!crng_ready() &&
+ if (!crng_ready_by_cb() &&
((kiocb->ki_flags & (IOCB_NOWAIT | IOCB_NOIO)) ||
(kiocb->ki_filp->f_flags & O_NONBLOCK)))
return -EAGAIN;
@@ -1468,6 +1763,14 @@ static long random_ioctl(struct file *f,
case RNDRESEEDCRNG:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ /* fall through to reseed native crng too. */
+ if (call_crng_reseed_cb() == 0) {
+ if (crng_ready())
+ crng_reseed(NULL);
+ return 0;
+ }
+#endif
if (!crng_ready())
return -ENODATA;
crng_reseed();
--- ./include/linux/random.h.dist 2024-01-19 16:25:07.891223702 -0600 --- ./include/linux/random.h.dist 2024-01-19 16:25:07.891223702 -0600
+++ ./include/linux/random.h 2025-06-30 12:38:54.353341542 -0500 +++ ./include/linux/random.h 2025-06-30 12:38:54.353341542 -0500
@@ -202,4 +202,37 @@ int random_online_cpu(unsigned int cpu); @@ -202,4 +202,37 @@ int random_online_cpu(unsigned int cpu);

View File

@@ -1,5 +1,5 @@
--- ./drivers/char/random.c.dist 2025-01-19 19:03:47.877152701 -0600 --- ./drivers/char/random.c.dist 2025-01-19 19:03:47.877152701 -0600
+++ ./drivers/char/random.c 2025-06-30 11:36:08.594481563 -0500 +++ ./drivers/char/random.c 2025-07-02 10:40:21.994303997 -0500
@@ -67,6 +67,260 @@ @@ -67,6 +67,260 @@
#include <asm/irq_regs.h> #include <asm/irq_regs.h>
#include <asm/io.h> #include <asm/io.h>
@@ -261,34 +261,64 @@
/********************************************************************* /*********************************************************************
* *
* Initialization and readiness waiting. * Initialization and readiness waiting.
@@ -87,7 +341,13 @@ static enum { @@ -87,7 +341,15 @@ static enum {
CRNG_READY = 2 /* Fully initialized with POOL_READY_BITS collected */ CRNG_READY = 2 /* Fully initialized with POOL_READY_BITS collected */
} crng_init __read_mostly = CRNG_EMPTY; } crng_init __read_mostly = CRNG_EMPTY;
static DEFINE_STATIC_KEY_FALSE(crng_is_ready); static DEFINE_STATIC_KEY_FALSE(crng_is_ready);
-#define crng_ready() (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY)
+ +
#define crng_ready() (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY)
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS +#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ #define crng_ready() (atomic_read(&random_bytes_cb_refcnt) ? call_crng_ready_cb() : (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY)) + #define crng_ready_by_cb() (atomic_read(&random_bytes_cb_refcnt) && call_crng_ready_cb())
+ #define crng_ready_maybe_cb() (atomic_read(&random_bytes_cb_refcnt) ? (call_crng_ready_cb() || crng_ready()) : crng_ready())
+#else +#else
+ #define crng_ready() (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY) + #define crng_ready_maybe_cb() crng_ready()
+#endif +#endif
+ +
/* Various types of waiters for crng_init->CRNG_READY transition. */ /* Various types of waiters for crng_init->CRNG_READY transition. */
static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait); static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);
static struct fasync_struct *fasync; static struct fasync_struct *fasync;
@@ -258,6 +518,11 @@ static void crng_reseed(struct work_stru @@ -112,7 +374,7 @@ MODULE_PARM_DESC(ratelimit_disable, "Dis
unsigned long next_gen; */
u8 key[CHACHA_KEY_SIZE]; bool rng_is_initialized(void)
{
- return crng_ready();
+ return crng_ready_maybe_cb();
}
EXPORT_SYMBOL(rng_is_initialized);
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS @@ -136,11 +398,11 @@ static void try_to_generate_entropy(void
+ (void)call_crng_reseed_cb(); */
+ /* fall through to reseed native crng too. */ int wait_for_random_bytes(void)
+#endif {
+ - while (!crng_ready()) {
/* Immediately schedule the next reseeding, so that it fires sooner rather than later. */ + while (!crng_ready_maybe_cb()) {
if (likely(system_unbound_wq)) int ret;
queue_delayed_work(system_unbound_wq, &next_reseed, crng_reseed_interval());
@@ -402,6 +667,14 @@ static void _get_random_bytes(void *buf, try_to_generate_entropy();
- ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ);
+ ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready_maybe_cb(), HZ);
if (ret)
return ret > 0 ? 0 : ret;
}
@@ -160,7 +422,7 @@ int __cold execute_with_initialized_rng(
int ret = 0;
spin_lock_irqsave(&random_ready_notifier.lock, flags);
- if (crng_ready())
+ if (crng_ready_maybe_cb())
nb->notifier_call(nb, 0, NULL);
else
ret = raw_notifier_chain_register((struct raw_notifier_head *)&random_ready_notifier.head, nb);
@@ -169,7 +431,7 @@ int __cold execute_with_initialized_rng(
}
#define warn_unseeded_randomness() \
- if (IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM) && !crng_ready()) \
+ if (IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM) && !crng_ready_maybe_cb()) \
printk_deferred(KERN_NOTICE "random: %s called from %pS with crng_init=%d\n", \
__func__, (void *)_RET_IP_, crng_init)
@@ -402,6 +664,14 @@ static void _get_random_bytes(void *buf,
if (!len) if (!len)
return; return;
@@ -303,7 +333,7 @@
first_block_len = min_t(size_t, 32, len); first_block_len = min_t(size_t, 32, len);
crng_make_state(chacha_state, buf, first_block_len); crng_make_state(chacha_state, buf, first_block_len);
len -= first_block_len; len -= first_block_len;
@@ -448,6 +721,18 @@ static ssize_t get_random_bytes_user(str @@ -448,6 +718,18 @@ static ssize_t get_random_bytes_user(str
if (unlikely(!iov_iter_count(iter))) if (unlikely(!iov_iter_count(iter)))
return 0; return 0;
@@ -322,7 +352,16 @@
/* /*
* Immediately overwrite the ChaCha key at index 4 with random * Immediately overwrite the ChaCha key at index 4 with random
* bytes, in case userspace causes copy_to_iter() below to sleep * bytes, in case userspace causes copy_to_iter() below to sleep
@@ -660,6 +945,11 @@ static void mix_pool_bytes(const void *b @@ -524,7 +806,7 @@ type get_random_ ##type(void) \
\
warn_unseeded_randomness(); \
\
- if (!crng_ready()) { \
+ if (!crng_ready_maybe_cb()) { \
_get_random_bytes(&ret, sizeof(ret)); \
return ret; \
} \
@@ -660,6 +942,11 @@ static void mix_pool_bytes(const void *b
{ {
unsigned long flags; unsigned long flags;
@@ -334,7 +373,7 @@
spin_lock_irqsave(&input_pool.lock, flags); spin_lock_irqsave(&input_pool.lock, flags);
_mix_pool_bytes(buf, len); _mix_pool_bytes(buf, len);
spin_unlock_irqrestore(&input_pool.lock, flags); spin_unlock_irqrestore(&input_pool.lock, flags);
@@ -719,7 +1009,11 @@ static void extract_entropy(void *buf, s @@ -719,7 +1006,11 @@ static void extract_entropy(void *buf, s
memzero_explicit(&block, sizeof(block)); memzero_explicit(&block, sizeof(block));
} }
@@ -346,6 +385,63 @@
static void __cold _credit_init_bits(size_t bits) static void __cold _credit_init_bits(size_t bits)
{ {
@@ -1400,7 +1691,7 @@ SYSCALL_DEFINE3(getrandom, char __user *
if ((flags & (GRND_INSECURE | GRND_RANDOM)) == (GRND_INSECURE | GRND_RANDOM))
return -EINVAL;
- if (!crng_ready() && !(flags & GRND_INSECURE)) {
+ if (!crng_ready_maybe_cb() && !(flags & GRND_INSECURE)) {
if (flags & GRND_NONBLOCK)
return -EAGAIN;
ret = wait_for_random_bytes();
@@ -1416,6 +1707,10 @@ SYSCALL_DEFINE3(getrandom, char __user *
static __poll_t random_poll(struct file *file, poll_table *wait)
{
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ if (crng_ready_by_cb())
+ return EPOLLIN | EPOLLRDNORM;
+#endif
poll_wait(file, &crng_init_wait, wait);
return crng_ready() ? EPOLLIN | EPOLLRDNORM : EPOLLOUT | EPOLLWRNORM;
}
@@ -1461,10 +1756,10 @@ static ssize_t urandom_read_iter(struct
* Opportunistically attempt to initialize the RNG on platforms that
* have fast cycle counters, but don't (for now) require it to succeed.
*/
- if (!crng_ready())
+ if (!crng_ready_maybe_cb())
try_to_generate_entropy();
- if (!crng_ready()) {
+ if (!crng_ready_maybe_cb()) {
if (!ratelimit_disable && maxwarn <= 0)
++urandom_warning.missed;
else if (ratelimit_disable || __ratelimit(&urandom_warning)) {
@@ -1481,7 +1776,7 @@ static ssize_t random_read_iter(struct k
{
int ret;
- if (!crng_ready() &&
+ if (!crng_ready_by_cb() &&
((kiocb->ki_flags & (IOCB_NOWAIT | IOCB_NOIO)) ||
(kiocb->ki_filp->f_flags & O_NONBLOCK)))
return -EAGAIN;
@@ -1546,6 +1841,14 @@ static long random_ioctl(struct file *f,
case RNDRESEEDCRNG:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ /* fall through to reseed native crng too. */
+ if (call_crng_reseed_cb() == 0) {
+ if (crng_ready())
+ crng_reseed(NULL);
+ return 0;
+ }
+#endif
if (!crng_ready())
return -ENODATA;
crng_reseed(NULL);
--- ./include/linux/random.h.dist 2025-01-19 19:03:57.524328914 -0600 --- ./include/linux/random.h.dist 2025-01-19 19:03:57.524328914 -0600
+++ ./include/linux/random.h 2025-06-30 12:04:32.801676104 -0500 +++ ./include/linux/random.h 2025-06-30 12:04:32.801676104 -0500
@@ -161,4 +161,37 @@ int random_online_cpu(unsigned int cpu); @@ -161,4 +161,37 @@ int random_online_cpu(unsigned int cpu);

View File

@@ -1,5 +1,5 @@
--- ./drivers/char/random.c.dist 2025-05-27 15:19:59.167827834 -0500 --- ./drivers/char/random.c.dist 2025-05-27 15:19:59.167827834 -0500
+++ ./drivers/char/random.c 2025-06-28 10:10:59.552488658 -0500 +++ ./drivers/char/random.c 2025-07-02 09:34:56.197972526 -0500
@@ -67,6 +67,260 @@ @@ -67,6 +67,260 @@
#include <asm/irq_regs.h> #include <asm/irq_regs.h>
#include <asm/io.h> #include <asm/io.h>
@@ -261,34 +261,64 @@
/********************************************************************* /*********************************************************************
* *
* Initialization and readiness waiting. * Initialization and readiness waiting.
@@ -87,7 +341,13 @@ static enum { @@ -87,7 +341,15 @@ static enum {
CRNG_READY = 2 /* Fully initialized with POOL_READY_BITS collected */ CRNG_READY = 2 /* Fully initialized with POOL_READY_BITS collected */
} crng_init __read_mostly = CRNG_EMPTY; } crng_init __read_mostly = CRNG_EMPTY;
static DEFINE_STATIC_KEY_FALSE(crng_is_ready); static DEFINE_STATIC_KEY_FALSE(crng_is_ready);
-#define crng_ready() (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY)
+ +
#define crng_ready() (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY)
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS +#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ #define crng_ready() (atomic_read(&random_bytes_cb_refcnt) ? call_crng_ready_cb() : (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY)) + #define crng_ready_by_cb() (atomic_read(&random_bytes_cb_refcnt) && call_crng_ready_cb())
+ #define crng_ready_maybe_cb() (atomic_read(&random_bytes_cb_refcnt) ? (call_crng_ready_cb() || crng_ready()) : crng_ready())
+#else +#else
+ #define crng_ready() (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY) + #define crng_ready_maybe_cb() crng_ready()
+#endif +#endif
+ +
/* Various types of waiters for crng_init->CRNG_READY transition. */ /* Various types of waiters for crng_init->CRNG_READY transition. */
static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait); static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait);
static struct fasync_struct *fasync; static struct fasync_struct *fasync;
@@ -258,6 +518,11 @@ static void crng_reseed(struct work_stru @@ -112,7 +374,7 @@ MODULE_PARM_DESC(ratelimit_disable, "Dis
unsigned long next_gen; */
u8 key[CHACHA_KEY_SIZE]; bool rng_is_initialized(void)
{
- return crng_ready();
+ return crng_ready_maybe_cb();
}
EXPORT_SYMBOL(rng_is_initialized);
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS @@ -136,11 +398,11 @@ static void try_to_generate_entropy(void
+ (void)call_crng_reseed_cb(); */
+ /* fall through to reseed native crng too. */ int wait_for_random_bytes(void)
+#endif {
+ - while (!crng_ready()) {
/* Immediately schedule the next reseeding, so that it fires sooner rather than later. */ + while (!crng_ready_maybe_cb()) {
if (likely(system_unbound_wq)) int ret;
queue_delayed_work(system_unbound_wq, &next_reseed, crng_reseed_interval());
@@ -402,6 +667,14 @@ static void _get_random_bytes(void *buf, try_to_generate_entropy();
- ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ);
+ ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready_maybe_cb(), HZ);
if (ret)
return ret > 0 ? 0 : ret;
}
@@ -160,7 +422,7 @@ int __cold execute_with_initialized_rng(
int ret = 0;
spin_lock_irqsave(&random_ready_notifier.lock, flags);
- if (crng_ready())
+ if (crng_ready_maybe_cb())
nb->notifier_call(nb, 0, NULL);
else
ret = raw_notifier_chain_register((struct raw_notifier_head *)&random_ready_notifier.head, nb);
@@ -169,7 +431,7 @@ int __cold execute_with_initialized_rng(
}
#define warn_unseeded_randomness() \
- if (IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM) && !crng_ready()) \
+ if (IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM) && !crng_ready_maybe_cb()) \
printk_deferred(KERN_NOTICE "random: %s called from %pS with crng_init=%d\n", \
__func__, (void *)_RET_IP_, crng_init)
@@ -402,6 +664,14 @@ static void _get_random_bytes(void *buf,
if (!len) if (!len)
return; return;
@@ -303,7 +333,7 @@
first_block_len = min_t(size_t, 32, len); first_block_len = min_t(size_t, 32, len);
crng_make_state(chacha_state, buf, first_block_len); crng_make_state(chacha_state, buf, first_block_len);
len -= first_block_len; len -= first_block_len;
@@ -448,6 +721,18 @@ static ssize_t get_random_bytes_user(str @@ -448,6 +718,18 @@ static ssize_t get_random_bytes_user(str
if (unlikely(!iov_iter_count(iter))) if (unlikely(!iov_iter_count(iter)))
return 0; return 0;
@@ -322,7 +352,16 @@
/* /*
* Immediately overwrite the ChaCha key at index 4 with random * Immediately overwrite the ChaCha key at index 4 with random
* bytes, in case userspace causes copy_to_iter() below to sleep * bytes, in case userspace causes copy_to_iter() below to sleep
@@ -660,6 +945,11 @@ static void mix_pool_bytes(const void *b @@ -524,7 +806,7 @@ type get_random_ ##type(void) \
\
warn_unseeded_randomness(); \
\
- if (!crng_ready()) { \
+ if (!crng_ready_maybe_cb()) { \
_get_random_bytes(&ret, sizeof(ret)); \
return ret; \
} \
@@ -660,6 +942,11 @@ static void mix_pool_bytes(const void *b
{ {
unsigned long flags; unsigned long flags;
@@ -334,7 +373,7 @@
spin_lock_irqsave(&input_pool.lock, flags); spin_lock_irqsave(&input_pool.lock, flags);
_mix_pool_bytes(buf, len); _mix_pool_bytes(buf, len);
spin_unlock_irqrestore(&input_pool.lock, flags); spin_unlock_irqrestore(&input_pool.lock, flags);
@@ -719,7 +1009,11 @@ static void extract_entropy(void *buf, s @@ -719,7 +1006,11 @@ static void extract_entropy(void *buf, s
memzero_explicit(&block, sizeof(block)); memzero_explicit(&block, sizeof(block));
} }
@@ -346,6 +385,63 @@
static void __cold _credit_init_bits(size_t bits) static void __cold _credit_init_bits(size_t bits)
{ {
@@ -1400,7 +1691,7 @@ SYSCALL_DEFINE3(getrandom, char __user *
if ((flags & (GRND_INSECURE | GRND_RANDOM)) == (GRND_INSECURE | GRND_RANDOM))
return -EINVAL;
- if (!crng_ready() && !(flags & GRND_INSECURE)) {
+ if (!crng_ready_maybe_cb() && !(flags & GRND_INSECURE)) {
if (flags & GRND_NONBLOCK)
return -EAGAIN;
ret = wait_for_random_bytes();
@@ -1416,6 +1707,10 @@ SYSCALL_DEFINE3(getrandom, char __user *
static __poll_t random_poll(struct file *file, poll_table *wait)
{
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ if (crng_ready_by_cb())
+ return EPOLLIN | EPOLLRDNORM;
+#endif
poll_wait(file, &crng_init_wait, wait);
return crng_ready() ? EPOLLIN | EPOLLRDNORM : EPOLLOUT | EPOLLWRNORM;
}
@@ -1461,10 +1756,10 @@ static ssize_t urandom_read_iter(struct
* Opportunistically attempt to initialize the RNG on platforms that
* have fast cycle counters, but don't (for now) require it to succeed.
*/
- if (!crng_ready())
+ if (!crng_ready_maybe_cb())
try_to_generate_entropy();
- if (!crng_ready()) {
+ if (!crng_ready_maybe_cb()) {
if (!ratelimit_disable && maxwarn <= 0)
++urandom_warning.missed;
else if (ratelimit_disable || __ratelimit(&urandom_warning)) {
@@ -1481,7 +1776,7 @@ static ssize_t random_read_iter(struct k
{
int ret;
- if (!crng_ready() &&
+ if (!crng_ready_by_cb() &&
((kiocb->ki_flags & (IOCB_NOWAIT | IOCB_NOIO)) ||
(kiocb->ki_filp->f_flags & O_NONBLOCK)))
return -EAGAIN;
@@ -1546,6 +1841,14 @@ static long random_ioctl(struct file *f,
case RNDRESEEDCRNG:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
+#ifdef WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS
+ /* fall through to reseed native crng too. */
+ if (call_crng_reseed_cb() == 0) {
+ if (crng_ready())
+ crng_reseed(NULL);
+ return 0;
+ }
+#endif
if (!crng_ready())
return -ENODATA;
crng_reseed(NULL);
--- ./include/linux/random.h.dist 2025-05-27 15:20:04.394946820 -0500 --- ./include/linux/random.h.dist 2025-05-27 15:20:04.394946820 -0500
+++ ./include/linux/random.h 2025-06-30 12:04:12.032296708 -0500 +++ ./include/linux/random.h 2025-06-30 12:04:12.032296708 -0500
@@ -154,4 +154,37 @@ int random_online_cpu(unsigned int cpu); @@ -154,4 +154,37 @@ int random_online_cpu(unsigned int cpu);

View File

@@ -1,4 +1,9 @@
#!/bin/bash #!/bin/bash
# This script is an internal tool that regenerates kernel patches for
# WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS, using full kernel sources staged
# for development.
if [[ ! -d 6.15 ]]; then if [[ ! -d 6.15 ]]; then
echo "6.15 not found -- wrong working dir?" >&2 echo "6.15 not found -- wrong working dir?" >&2
exit 1 exit 1

View File

@@ -3737,7 +3737,7 @@ extern void uITRON4_free(void *p) ;
* NIST SP 800-90A Rev. 1, to avoid unnecessary delays in DRBG * NIST SP 800-90A Rev. 1, to avoid unnecessary delays in DRBG
* generation. * generation.
*/ */
#define WC_RESEED_INTERVAL (1UL<<48UL) #define WC_RESEED_INTERVAL (((word64)1UL)<<48UL)
#endif #endif
#endif #endif