wolfcrypt/src/random.c and wolfssl/wolfcrypt/random.h: refactor DRBG_internal.reseedCtr as a word64 if WORD64_AVAILABLE, to accommodate max reseed count per NIST SP 800-90A Rev. 1;

wolfssl/wolfcrypt/settings.h: if WOLFSSL_LINUXKM && LINUXKM_LKCAPI_REGISTER && WORD64_AVAILABLE, set default WC_RESEED_INTERVAL to max allowed (2^48);

linuxkm/lkcapi_sha_glue.c: handle NO_LINUXKM_DRBG_GET_RANDOM_BYTES, for build-time override control of LINUXKM_DRBG_GET_RANDOM_BYTES, and handle WOLFSSL_LINUXKM_USE_GET_RANDOM_USER_KRETPROBE, for separate opt-in control of the buggy wc_get_random_bytes_user_kretprobe_enter().
This commit is contained in:
Daniel Pouzzner
2025-07-01 19:52:54 -05:00
parent 3a43109208
commit dc05c4c01b
5 changed files with 44 additions and 8 deletions

View File

@@ -369,6 +369,7 @@ NO_HANDSHAKE_DONE_CB
NO_IMX6_CAAM_AES
NO_IMX6_CAAM_HASH
NO_KEEP_PEER_CERT
NO_LINUXKM_DRBG_GET_RANDOM_BYTES
NO_OLD_NAMES
NO_OLD_POLY1305
NO_OLD_TIMEVAL_NAME
@@ -719,6 +720,7 @@ WOLFSSL_KYBER_NO_ENCAPSULATE
WOLFSSL_KYBER_NO_MAKE_KEY
WOLFSSL_LIB
WOLFSSL_LINUXKM_USE_GET_RANDOM_KPROBES
WOLFSSL_LINUXKM_USE_GET_RANDOM_USER_KRETPROBE
WOLFSSL_LINUXKM_USE_MUTEXES
WOLFSSL_LMS_CACHE_BITS
WOLFSSL_LMS_FULL_HASH

View File

@@ -1184,7 +1184,9 @@ static struct rng_alg wc_linuxkm_drbg = {
};
static int wc_linuxkm_drbg_loaded = 0;
#if defined(LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT) && \
#ifdef NO_LINUXKM_DRBG_GET_RANDOM_BYTES
#undef LINUXKM_DRBG_GET_RANDOM_BYTES
#elif defined(LINUXKM_LKCAPI_REGISTER_HASH_DRBG_DEFAULT) && \
(defined(WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS) || defined(WOLFSSL_LINUXKM_USE_GET_RANDOM_KPROBES))
#ifndef LINUXKM_DRBG_GET_RANDOM_BYTES
#define LINUXKM_DRBG_GET_RANDOM_BYTES
@@ -1475,9 +1477,7 @@ static int wc_get_random_bytes_kprobe_installed = 0;
/* note, we can't kprobe _get_random_bytes() because it's inlined. */
struct wc_get_random_bytes_user_kretprobe_ctx {
unsigned long retval;
};
#ifdef WOLFSSL_LINUXKM_USE_GET_RANDOM_USER_KRETPROBE
#warning Interception of /dev/random, /dev/urandom, and getrandom() using \
wc_get_random_bytes_user_kretprobe_enter() is known to destabilize large \
@@ -1486,6 +1486,10 @@ struct wc_get_random_bytes_user_kretprobe_ctx {
/dev/urandom reads. When in doubt, patch your kernel, activating \
WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS.
struct wc_get_random_bytes_user_kretprobe_ctx {
unsigned long retval;
};
static int wc_get_random_bytes_user_kretprobe_enter(struct kretprobe_instance *p, struct pt_regs *regs)
{
struct iov_iter *iter = (struct iov_iter *)regs->di;
@@ -1586,6 +1590,8 @@ static struct kretprobe wc_get_random_bytes_user_kretprobe = {
};
static int wc_get_random_bytes_user_kretprobe_installed = 0;
#endif /* WOLFSSL_LINUXKM_USE_GET_RANDOM_USER_KRETPROBE */
#else /* !WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS && !(CONFIG_KPROBES && CONFIG_X86) */
#error LINUXKM_DRBG_GET_RANDOM_BYTES implementation missing for target architecture/configuration.
#endif
@@ -1777,6 +1783,7 @@ static int wc_linuxkm_drbg_startup(void)
pr_err("ERROR: wc_get_random_bytes_kprobe installation failed: %d\n", ret);
}
#ifdef WOLFSSL_LINUXKM_USE_GET_RANDOM_USER_KRETPROBE
ret = register_kretprobe(&wc_get_random_bytes_user_kretprobe);
if (ret == 0) {
wc_get_random_bytes_user_kretprobe_installed = 1;
@@ -1785,6 +1792,7 @@ static int wc_linuxkm_drbg_startup(void)
else {
pr_err("ERROR: wc_get_random_bytes_user_kprobe installation failed: %d\n", ret);
}
#endif /* WOLFSSL_LINUXKM_USE_GET_RANDOM_USER_KRETPROBE */
#else
#error LINUXKM_DRBG_GET_RANDOM_BYTES missing installation calls.
@@ -1846,15 +1854,17 @@ static int wc_linuxkm_drbg_cleanup(void) {
unregister_kprobe(&wc_get_random_bytes_kprobe);
pr_info("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");
}
#endif /* WOLFSSL_LINUXKM_USE_GET_RANDOM_USER_KRETPROBE */
#else
#error LINUXKM_DRBG_GET_RANDOM_BYTES missing installation calls.
#error LINUXKM_DRBG_GET_RANDOM_BYTES missing deinstallation calls.
#endif
#endif /* LINUXKM_DRBG_GET_RANDOM_BYTES */

View File

@@ -642,7 +642,11 @@ static int Hash_DRBG_Generate(DRBG_internal* drbg, byte* out, word32 outSz)
wc_Sha256 sha[1];
#endif
byte type;
#ifdef WORD64_AVAILABLE
word64 reseedCtr;
#else
word32 reseedCtr;
#endif
if (drbg == NULL) {
return DRBG_FAILURE;
@@ -692,7 +696,11 @@ static int Hash_DRBG_Generate(DRBG_internal* drbg, byte* out, word32 outSz)
array_add(drbg->V, sizeof(drbg->V), digest, WC_SHA256_DIGEST_SIZE);
array_add(drbg->V, sizeof(drbg->V), drbg->C, sizeof(drbg->C));
#ifdef LITTLE_ENDIAN_ORDER
#ifdef WORD64_AVAILABLE
reseedCtr = ByteReverseWord64(reseedCtr);
#else
reseedCtr = ByteReverseWord32(reseedCtr);
#endif
#endif
array_add(drbg->V, sizeof(drbg->V),
(byte*)&reseedCtr, sizeof(reseedCtr));

View File

@@ -164,7 +164,11 @@ struct OS_Seed {
#ifdef HAVE_HASHDRBG
struct DRBG_internal {
#ifdef WORD64_AVAILABLE
word64 reseedCtr;
#else
word32 reseedCtr;
#endif
byte V[DRBG_SEED_LEN];
byte C[DRBG_SEED_LEN];
void* heap;

View File

@@ -3625,9 +3625,6 @@ extern void uITRON4_free(void *p) ;
/* Linux Kernel Module */
#ifdef WOLFSSL_LINUXKM
#ifndef WOLFSSL_NO_GETPID
#define WOLFSSL_NO_GETPID
#endif /* WOLFSSL_NO_GETPID */
#ifdef HAVE_CONFIG_H
#include <config.h>
#undef HAVE_CONFIG_H
@@ -3681,6 +3678,9 @@ extern void uITRON4_free(void *p) ;
#undef WOLFSSL_HAVE_MAX
#undef WOLFSSL_HAVE_ASSERT_H
#define WOLFSSL_NO_ASSERT_H
#ifndef WOLFSSL_NO_GETPID
#define WOLFSSL_NO_GETPID
#endif /* WOLFSSL_NO_GETPID */
#ifndef SIZEOF_LONG
#define SIZEOF_LONG 8
#endif
@@ -3731,6 +3731,18 @@ extern void uITRON4_free(void *p) ;
#define WC_SANITIZE_ENABLE() kasan_enable_current()
#endif
#endif
#if !defined(WC_RESEED_INTERVAL) && defined(LINUXKM_LKCAPI_REGISTER)
/* If installing handlers, use the maximum reseed interval allowed by
* NIST SP 800-90A Rev. 1, to avoid unnecessary delays in DRBG
* generation.
*/
#ifdef WORD64_AVAILABLE
#define WC_RESEED_INTERVAL (1UL<<48UL)
#else
#define WC_RESEED_INTERVAL 0xffffffffU
#endif
#endif
#endif