diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index a05b91dd2..c755a6d5a 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -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 diff --git a/linuxkm/lkcapi_sha_glue.c b/linuxkm/lkcapi_sha_glue.c index b82b0d358..43117421c 100644 --- a/linuxkm/lkcapi_sha_glue.c +++ b/linuxkm/lkcapi_sha_glue.c @@ -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 */ diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 2ccea5c0d..6e44ff6e8 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -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)); diff --git a/wolfssl/wolfcrypt/random.h b/wolfssl/wolfcrypt/random.h index a566956f1..4a863be2a 100644 --- a/wolfssl/wolfcrypt/random.h +++ b/wolfssl/wolfcrypt/random.h @@ -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; diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index feedf7856..9f29221a1 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -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 #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