From 0160af0a0d0fbfd014b647118cdf56f60068e0c7 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 2 Jul 2025 14:24:17 -0500 Subject: [PATCH] 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. --- linuxkm/lkcapi_sha_glue.c | 21 +-- ...KM_HAVE_GET_RANDOM_CALLBACKS-5v10v17.patch | 118 ++++++++++++--- ...M_HAVE_GET_RANDOM_CALLBACKS-5v10v236.patch | 112 ++++++++++++--- ...NUXKM_HAVE_GET_RANDOM_CALLBACKS-5v15.patch | 116 ++++++++++++--- ...NUXKM_HAVE_GET_RANDOM_CALLBACKS-5v17.patch | 112 ++++++++++++--- ...XKM_HAVE_GET_RANDOM_CALLBACKS-6v1v73.patch | 125 +++++++++++++--- ...NUXKM_HAVE_GET_RANDOM_CALLBACKS-6v12.patch | 136 +++++++++++++++--- ...NUXKM_HAVE_GET_RANDOM_CALLBACKS-6v15.patch | 136 +++++++++++++++--- linuxkm/patches/regen-patches.sh | 5 + wolfssl/wolfcrypt/settings.h | 2 +- 10 files changed, 735 insertions(+), 148 deletions(-) diff --git a/linuxkm/lkcapi_sha_glue.c b/linuxkm/lkcapi_sha_glue.c index 43117421c..dee6d0131 100644 --- a/linuxkm/lkcapi_sha_glue.c +++ b/linuxkm/lkcapi_sha_glue.c @@ -1101,9 +1101,12 @@ retry: pr_warn("WARNING: reinitialized DRBG #%d after RNG_FAILURE_E.", raw_smp_processor_id()); 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; + } } - - if (ret != 0) { + else if (ret != 0) { pr_warn_once("WARNING: wc_RNG_GenerateBlock returned %d\n",ret); ret = -EINVAL; } @@ -1748,7 +1751,7 @@ static int wc_linuxkm_drbg_startup(void) crypto_put_default_rng(); wc_linuxkm_drbg_default_instance_registered = 1; 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 { 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) { 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 { 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); if (ret == 0) { 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 { 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); if (ret == 0) { 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 { 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); 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; } @@ -1852,14 +1855,14 @@ static int wc_linuxkm_drbg_cleanup(void) { wc_get_random_bytes_kprobe_installed = 0; barrier(); 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 if (wc_get_random_bytes_user_kretprobe_installed) { wc_get_random_bytes_user_kretprobe_installed = 0; barrier(); 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 */ diff --git a/linuxkm/patches/5.10.17/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v17.patch b/linuxkm/patches/5.10.17/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v17.patch index 0a6a6bfd8..a6bc78749 100644 --- a/linuxkm/patches/5.10.17/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v17.patch +++ b/linuxkm/patches/5.10.17/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v17.patch @@ -1,5 +1,5 @@ --- ./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 @@ #include #include @@ -261,22 +261,30 @@ #define CREATE_TRACE_POINTS #include -@@ -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). */ 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 -+ #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 -+ #define crng_ready() (likely(crng_init > 1)) ++ #define crng_ready_maybe_cb() crng_ready() +#endif + static int crng_init_cnt = 0; static unsigned long crng_global_init_time = 0; #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; @@ -288,7 +296,7 @@ trace_mix_pool_bytes(r->name, nbytes, _RET_IP_); spin_lock_irqsave(&r->lock, flags); _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; int nfrac = nbits << ENTROPY_SHIFT; @@ -299,19 +307,7 @@ if (!nbits) return; -@@ -954,6 +1223,11 @@ static void crng_reseed(struct crng_stat - __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 __ +@@ -1069,6 +1347,18 @@ static ssize_t extract_crng_user(void __ __u8 tmp[CHACHA_BLOCK_SIZE] __aligned(4); int large_request = (nbytes > 256); @@ -330,7 +326,16 @@ while (nbytes) { if (large_request && need_resched()) { 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_); @@ -345,6 +350,77 @@ while (nbytes >= CHACHA_BLOCK_SIZE) { extract_crng(buf); 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 2025-06-30 12:05:59.106440700 -0500 @@ -158,4 +158,37 @@ static inline bool __init arch_get_rando diff --git a/linuxkm/patches/5.10.236/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v236.patch b/linuxkm/patches/5.10.236/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v236.patch index 8f088bf9e..6c84902b7 100644 --- a/linuxkm/patches/5.10.236/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v236.patch +++ b/linuxkm/patches/5.10.236/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v10v236.patch @@ -1,5 +1,5 @@ --- ./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 @@ #include #include @@ -261,34 +261,55 @@ /********************************************************************* * * 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_READY = 2 /* Fully initialized with POOL_READY_BITS collected */ } 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 -+ #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 -+ #define crng_ready() (likely(crng_init >= CRNG_READY)) ++ #define crng_ready_maybe_cb() crng_ready() +#endif + /* Various types of waiters for crng_init->CRNG_READY transition. */ static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait); static struct fasync_struct *fasync; -@@ -247,6 +507,11 @@ static void crng_reseed(void) - unsigned long next_gen; - u8 key[CHACHA_KEY_SIZE]; +@@ -105,7 +367,7 @@ MODULE_PARM_DESC(ratelimit_disable, "Dis + */ + 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 -+ (void)call_crng_reseed_cb(); -+ /* fall through to reseed native crng too. */ -+#endif -+ - extract_entropy(key, sizeof(key)); +@@ -124,11 +386,11 @@ static void try_to_generate_entropy(void + */ + int wait_for_random_bytes(void) + { +- while (!crng_ready()) { ++ while (!crng_ready_maybe_cb()) { + int ret; - /* -@@ -401,6 +666,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; + } +@@ -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) return; @@ -303,7 +324,7 @@ first_block_len = min_t(size_t, 32, len); crng_make_state(chacha_state, buf, 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))) return 0; @@ -322,7 +343,16 @@ /* * Immediately overwrite the ChaCha key at index 4 with random * 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; @@ -334,7 +364,7 @@ spin_lock_irqsave(&input_pool.lock, flags); _mix_pool_bytes(buf, len); 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)); } @@ -346,6 +376,50 @@ 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 2025-06-30 12:03:15.263141842 -0500 @@ -138,4 +138,37 @@ int random_online_cpu(unsigned int cpu); diff --git a/linuxkm/patches/5.15/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v15.patch b/linuxkm/patches/5.15/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v15.patch index 2f6afad3c..efafb4357 100644 --- a/linuxkm/patches/5.15/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v15.patch +++ b/linuxkm/patches/5.15/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v15.patch @@ -1,5 +1,5 @@ --- ./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 @@ #include #include @@ -261,22 +261,30 @@ #define CREATE_TRACE_POINTS #include -@@ -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). */ 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 -+ #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 -+ #define crng_ready() (likely(crng_init > 1)) ++ #define crng_ready_maybe_cb() crng_ready() +#endif + static int crng_init_cnt = 0; static unsigned long crng_global_init_time = 0; #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; trace_mix_pool_bytes(r->name, nbytes, _RET_IP_); @@ -289,19 +297,7 @@ spin_lock_irqsave(&r->lock, flags); _mix_pool_bytes(r, in, nbytes); spin_unlock_irqrestore(&r->lock, flags); -@@ -944,6 +1210,11 @@ static void crng_reseed(struct crng_stat - __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 __ +@@ -1059,6 +1334,18 @@ static ssize_t extract_crng_user(void __ __u8 tmp[CHACHA_BLOCK_SIZE] __aligned(4); int large_request = (nbytes > 256); @@ -320,7 +316,16 @@ while (nbytes) { if (large_request && need_resched()) { 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_); @@ -335,6 +340,77 @@ while (nbytes >= CHACHA_BLOCK_SIZE) { extract_crng(buf); 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 2025-06-28 13:09:13.392547118 -0500 @@ -158,4 +158,37 @@ static inline bool __init arch_get_rando diff --git a/linuxkm/patches/5.17/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v17.patch b/linuxkm/patches/5.17/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v17.patch index 19340769f..c10745c3b 100644 --- a/linuxkm/patches/5.17/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v17.patch +++ b/linuxkm/patches/5.17/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-5v17.patch @@ -1,5 +1,5 @@ --- ./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 @@ #include #include @@ -261,34 +261,55 @@ /********************************************************************* * * 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_init __read_mostly = CRNG_EMPTY; 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 -+ #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 -+ #define crng_ready() (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY) ++ #define crng_ready_maybe_cb() crng_ready() +#endif + /* Various types of waiters for crng_init->CRNG_READY transition. */ static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait); static struct fasync_struct *fasync; -@@ -253,6 +513,11 @@ static void crng_reseed(void) - unsigned long next_gen; - u8 key[CHACHA_KEY_SIZE]; +@@ -106,7 +368,7 @@ MODULE_PARM_DESC(ratelimit_disable, "Dis + */ + 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 -+ (void)call_crng_reseed_cb(); -+ /* fall through to reseed native crng too. */ -+#endif -+ - extract_entropy(key, sizeof(key)); +@@ -130,11 +392,11 @@ static void try_to_generate_entropy(void + */ + int wait_for_random_bytes(void) + { +- while (!crng_ready()) { ++ while (!crng_ready_maybe_cb()) { + int ret; - /* -@@ -407,6 +672,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; + } +@@ -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) return; @@ -303,7 +324,7 @@ first_block_len = min_t(size_t, 32, len); crng_make_state(chacha_state, buf, 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))) return 0; @@ -322,7 +343,16 @@ /* * Immediately overwrite the ChaCha key at index 4 with random * 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; @@ -334,7 +364,7 @@ spin_lock_irqsave(&input_pool.lock, flags); _mix_pool_bytes(buf, len); 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)); } @@ -346,6 +376,50 @@ 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 2025-06-30 12:06:15.219731761 -0500 @@ -138,4 +138,37 @@ int random_online_cpu(unsigned int cpu); diff --git a/linuxkm/patches/6.1.73/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v1v73.patch b/linuxkm/patches/6.1.73/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v1v73.patch index 6269e9a2c..7d90e7726 100644 --- a/linuxkm/patches/6.1.73/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v1v73.patch +++ b/linuxkm/patches/6.1.73/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v1v73.patch @@ -1,5 +1,5 @@ --- ./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 @@ #include #include @@ -261,34 +261,55 @@ /********************************************************************* * * 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_init __read_mostly = CRNG_EMPTY; 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 -+ #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 -+ #define crng_ready() (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY) ++ #define crng_ready_maybe_cb() crng_ready() +#endif + /* Various types of waiters for crng_init->CRNG_READY transition. */ static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait); static struct fasync_struct *fasync; -@@ -210,6 +470,11 @@ static void crng_reseed(void) - unsigned long next_gen; - u8 key[CHACHA_KEY_SIZE]; +@@ -104,7 +366,7 @@ MODULE_PARM_DESC(ratelimit_disable, "Dis + */ + 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 -+ (void)call_crng_reseed_cb(); -+ /* fall through to reseed native crng too. */ -+#endif -+ - extract_entropy(key, sizeof(key)); +@@ -128,11 +390,11 @@ static void try_to_generate_entropy(void + */ + int wait_for_random_bytes(void) + { +- while (!crng_ready()) { ++ while (!crng_ready_maybe_cb()) { + int ret; - /* -@@ -362,6 +627,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; + } +@@ -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) return; @@ -303,7 +324,7 @@ first_block_len = min_t(size_t, 32, len); crng_make_state(chacha_state, buf, 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))) return 0; @@ -322,7 +343,16 @@ /* * Immediately overwrite the ChaCha key at index 4 with random * 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; @@ -334,7 +364,7 @@ spin_lock_irqsave(&input_pool.lock, flags); _mix_pool_bytes(buf, len); 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)); } @@ -346,6 +376,63 @@ 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 2025-06-30 12:38:54.353341542 -0500 @@ -202,4 +202,37 @@ int random_online_cpu(unsigned int cpu); diff --git a/linuxkm/patches/6.12/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v12.patch b/linuxkm/patches/6.12/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v12.patch index f333e419c..3e2c7f770 100644 --- a/linuxkm/patches/6.12/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v12.patch +++ b/linuxkm/patches/6.12/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v12.patch @@ -1,5 +1,5 @@ --- ./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 @@ #include #include @@ -261,34 +261,64 @@ /********************************************************************* * * 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_init __read_mostly = CRNG_EMPTY; 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 -+ #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 -+ #define crng_ready() (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY) ++ #define crng_ready_maybe_cb() crng_ready() +#endif + /* Various types of waiters for crng_init->CRNG_READY transition. */ static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait); static struct fasync_struct *fasync; -@@ -258,6 +518,11 @@ static void crng_reseed(struct work_stru - unsigned long next_gen; - u8 key[CHACHA_KEY_SIZE]; +@@ -112,7 +374,7 @@ MODULE_PARM_DESC(ratelimit_disable, "Dis + */ + 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 -+ (void)call_crng_reseed_cb(); -+ /* fall through to reseed native crng too. */ -+#endif -+ - /* Immediately schedule the next reseeding, so that it fires sooner rather than later. */ - if (likely(system_unbound_wq)) - queue_delayed_work(system_unbound_wq, &next_reseed, crng_reseed_interval()); -@@ -402,6 +667,14 @@ static void _get_random_bytes(void *buf, +@@ -136,11 +398,11 @@ static void try_to_generate_entropy(void + */ + int wait_for_random_bytes(void) + { +- while (!crng_ready()) { ++ while (!crng_ready_maybe_cb()) { + int ret; + + 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) return; @@ -303,7 +333,7 @@ first_block_len = min_t(size_t, 32, len); crng_make_state(chacha_state, buf, 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))) return 0; @@ -322,7 +352,16 @@ /* * Immediately overwrite the ChaCha key at index 4 with random * 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; @@ -334,7 +373,7 @@ spin_lock_irqsave(&input_pool.lock, flags); _mix_pool_bytes(buf, len); 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)); } @@ -346,6 +385,63 @@ 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 2025-06-30 12:04:32.801676104 -0500 @@ -161,4 +161,37 @@ int random_online_cpu(unsigned int cpu); diff --git a/linuxkm/patches/6.15/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v15.patch b/linuxkm/patches/6.15/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v15.patch index ce62a15c0..e21b76226 100644 --- a/linuxkm/patches/6.15/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v15.patch +++ b/linuxkm/patches/6.15/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-6v15.patch @@ -1,5 +1,5 @@ --- ./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 @@ #include #include @@ -261,34 +261,64 @@ /********************************************************************* * * 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_init __read_mostly = CRNG_EMPTY; 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 -+ #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 -+ #define crng_ready() (static_branch_likely(&crng_is_ready) || crng_init >= CRNG_READY) ++ #define crng_ready_maybe_cb() crng_ready() +#endif + /* Various types of waiters for crng_init->CRNG_READY transition. */ static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait); static struct fasync_struct *fasync; -@@ -258,6 +518,11 @@ static void crng_reseed(struct work_stru - unsigned long next_gen; - u8 key[CHACHA_KEY_SIZE]; +@@ -112,7 +374,7 @@ MODULE_PARM_DESC(ratelimit_disable, "Dis + */ + 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 -+ (void)call_crng_reseed_cb(); -+ /* fall through to reseed native crng too. */ -+#endif -+ - /* Immediately schedule the next reseeding, so that it fires sooner rather than later. */ - if (likely(system_unbound_wq)) - queue_delayed_work(system_unbound_wq, &next_reseed, crng_reseed_interval()); -@@ -402,6 +667,14 @@ static void _get_random_bytes(void *buf, +@@ -136,11 +398,11 @@ static void try_to_generate_entropy(void + */ + int wait_for_random_bytes(void) + { +- while (!crng_ready()) { ++ while (!crng_ready_maybe_cb()) { + int ret; + + 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) return; @@ -303,7 +333,7 @@ first_block_len = min_t(size_t, 32, len); crng_make_state(chacha_state, buf, 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))) return 0; @@ -322,7 +352,16 @@ /* * Immediately overwrite the ChaCha key at index 4 with random * 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; @@ -334,7 +373,7 @@ spin_lock_irqsave(&input_pool.lock, flags); _mix_pool_bytes(buf, len); 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)); } @@ -346,6 +385,63 @@ 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 2025-06-30 12:04:12.032296708 -0500 @@ -154,4 +154,37 @@ int random_online_cpu(unsigned int cpu); diff --git a/linuxkm/patches/regen-patches.sh b/linuxkm/patches/regen-patches.sh index c6cb57f08..cd6349541 100755 --- a/linuxkm/patches/regen-patches.sh +++ b/linuxkm/patches/regen-patches.sh @@ -1,4 +1,9 @@ #!/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 echo "6.15 not found -- wrong working dir?" >&2 exit 1 diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 1a4371b27..fb09637c5 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -3737,7 +3737,7 @@ extern void uITRON4_free(void *p) ; * NIST SP 800-90A Rev. 1, to avoid unnecessary delays in DRBG * generation. */ - #define WC_RESEED_INTERVAL (1UL<<48UL) + #define WC_RESEED_INTERVAL (((word64)1UL)<<48UL) #endif #endif