From c353052e54c2101d3d0629a62602f62af270ea6d Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 30 Jul 2025 22:15:05 -0500 Subject: [PATCH] linuxkm/linuxkm_wc_port.h: * move enum wc_svr_flags out of BUILDING_WOLFSSL guard; * add DISABLE_VECTOR_REGISTERS() and REENABLE_VECTOR_REGISTERS() definitions for !BUILDING_WOLFSSL; * add #include to !WOLFSSL_LINUXKM_USE_MUTEXES implementation to fix compilation (and add usability) to caller code; linuxkm/lkcapi_sha_glue.c: in wc_linuxkm_drbg_ctx_clear(), fix error-path deallocation of locked object; wolfcrypt/benchmark/benchmark.c: * in FIPS v6+ builds, and FIPS linuxkm v5+, check retval from wc_AesEncryptDirect() and wc_AesDecryptDirect(); * add WC_RELAX_LONG_LOOP() in bench_stats_sym_finish() and bench_stats_asym_finish_ex(); wolfcrypt/test/test.c: fix rng_seed_test() with correct test vectors for the relevant combinations of features, and gate the test out if there are user override defines for ENTROPY_SCALE_FACTOR or SEED_BLOCK_SZ. --- linuxkm/linuxkm_wc_port.h | 36 ++++++++++++-- linuxkm/lkcapi_sha_glue.c | 3 ++ wolfcrypt/benchmark/benchmark.c | 16 ++++++ wolfcrypt/test/test.c | 87 +++++++++++++++++++++++++++++---- 4 files changed, 128 insertions(+), 14 deletions(-) diff --git a/linuxkm/linuxkm_wc_port.h b/linuxkm/linuxkm_wc_port.h index 78dbdb84d..f70b63103 100644 --- a/linuxkm/linuxkm_wc_port.h +++ b/linuxkm/linuxkm_wc_port.h @@ -135,6 +135,10 @@ #endif extern void wc_linuxkm_relax_long_loop(void); + enum wc_svr_flags { + WC_SVR_FLAG_INHIBIT = 1, + }; + #ifdef BUILDING_WOLFSSL #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0)) || \ @@ -453,10 +457,6 @@ #if defined(WOLFSSL_LINUXKM_USE_SAVE_VECTOR_REGISTERS) && \ defined(CONFIG_X86) - enum wc_svr_flags { - WC_SVR_FLAG_INHIBIT = 1, - }; - extern __must_check int allocate_wolfcrypt_linuxkm_fpu_states(void); extern void free_wolfcrypt_linuxkm_fpu_states(void); extern __must_check int can_save_vector_registers_x86(void); @@ -1179,6 +1179,28 @@ #endif /* BUILDING_WOLFSSL */ + #if !defined(BUILDING_WOLFSSL) + /* some caller code needs these. */ + #if defined(WOLFSSL_LINUXKM_USE_SAVE_VECTOR_REGISTERS) + #ifdef CONFIG_X86 + extern __must_check int save_vector_registers_x86(enum wc_svr_flags flags); + #ifndef DISABLE_VECTOR_REGISTERS + #define DISABLE_VECTOR_REGISTERS() save_vector_registers_x86(WC_SVR_FLAG_INHIBIT) + #endif + #ifndef REENABLE_VECTOR_REGISTERS + #define REENABLE_VECTOR_REGISTERS() restore_vector_registers_x86() + #endif + #endif /* CONFIG_X86 */ + #else /* !WOLFSSL_LINUXKM_USE_SAVE_VECTOR_REGISTERS */ + #ifndef DISABLE_VECTOR_REGISTERS + #define DISABLE_VECTOR_REGISTERS() NOT_COMPILED_IN + #endif + #ifndef REENABLE_VECTOR_REGISTERS + #define REENABLE_VECTOR_REGISTERS() WC_DO_NOTHING + #endif + #endif + #endif /* !BUILDING_WOLFSSL */ + /* Copied from wc_port.h: For FIPS keep the function names the same */ #ifdef HAVE_FIPS #define wc_InitMutex InitMutex @@ -1232,6 +1254,12 @@ return 0; } #else + /* if BUILDING_WOLFSSL, spinlock.h will have already been included + * recursively above, with the bevy of warnings suppressed, and the + * below include will be a redundant no-op. + */ + #include + typedef struct wolfSSL_Mutex { spinlock_t lock; unsigned long irq_flags; diff --git a/linuxkm/lkcapi_sha_glue.c b/linuxkm/lkcapi_sha_glue.c index f2c754861..0ba8a6c1e 100644 --- a/linuxkm/lkcapi_sha_glue.c +++ b/linuxkm/lkcapi_sha_glue.c @@ -980,6 +980,9 @@ static inline void wc_linuxkm_drbg_ctx_clear(struct wc_linuxkm_drbg_ctx * ctx) if (ctx->rngs[i].lock != 0) { /* better to leak than to crash. */ pr_err("BUG: wc_linuxkm_drbg_ctx_clear called with DRBG #%d still locked.", i); + ctx->rngs = NULL; + ctx->n_rngs = 0; + return; } else wc_FreeRng(&ctx->rngs[i].rng); diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index d248acbf9..4bc47bb24 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -2543,6 +2543,8 @@ static void bench_stats_sym_finish(const char* desc, int useDeviceID, total = current_time(0) - start; + WC_RELAX_LONG_LOOP(); + #if defined(WOLFSSL_ESPIDF) && defined(DEBUG_WOLFSSL_BENCHMARK_TIMING) ESP_LOGI(TAG, "%s total_cycles = %llu", desc, total_cycles); #endif @@ -2773,6 +2775,8 @@ static void bench_stats_asym_finish_ex(const char* algo, int strength, total = current_time(0) - start; + WC_RELAX_LONG_LOOP(); + #ifdef LINUX_RUSAGE_UTIME check_for_excessive_stime(algo, strength, desc, desc_extra); #endif @@ -5010,7 +5014,13 @@ static void bench_aesecb_internal(int useDeviceID, if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(enc[i]), 0, ×, outer_loop_limit, &pending)) { #ifdef HAVE_FIPS + #if defined(WOLFSSL_LINUXKM) || FIPS_VERSION_GE(6, 0) + ret = wc_AesEncryptDirect(enc[i], bench_cipher, bench_plain); + if (ret != 0) + goto exit_aes_enc; + #else wc_AesEncryptDirect(enc[i], bench_cipher, bench_plain); + #endif #else wc_AesEcbEncrypt(enc[i], bench_cipher, bench_plain, benchSz); @@ -5061,7 +5071,13 @@ exit_aes_enc: if (bench_async_check(&ret, BENCH_ASYNC_GET_DEV(enc[i]), 0, ×, outer_loop_limit, &pending)) { #ifdef HAVE_FIPS + #if defined(WOLFSSL_LINUXKM) || FIPS_VERSION_GE(6, 0) + ret = wc_AesDecryptDirect(enc[i], bench_plain, bench_cipher); + if (ret != 0) + goto exit_aes_dec; + #else wc_AesDecryptDirect(enc[i], bench_plain, bench_cipher); + #endif #else wc_AesEcbDecrypt(enc[i], bench_plain, bench_cipher, benchSz); diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index b86ac6f56..9b162b417 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -18352,7 +18352,8 @@ static wc_test_ret_t random_rng_test(void) #if defined(HAVE_HASHDRBG) && !defined(CUSTOM_RAND_GENERATE_BLOCK) -#ifdef WC_RNG_SEED_CB +#if defined(WC_RNG_SEED_CB) && \ + !(defined(ENTROPY_SCALE_FACTOR) || defined(SEED_BLOCK_SZ)) static int seed_cb(OS_Seed* os, byte* output, word32 sz) { word32 i; @@ -18365,16 +18366,73 @@ static int seed_cb(OS_Seed* os, byte* output, word32 sz) static wc_test_ret_t rng_seed_test(void) { -#ifndef HAVE_FIPS + /* The expected PRNG block depends on ENTROPY_SCALE_FACTOR and + * SEED_BLOCK_SZ, which depend on which seed back end is configured. + */ +#if defined(HAVE_ENTROPY_MEMUSE) && defined(HAVE_AMD_RDSEED) + #ifdef HAVE_FIPS WOLFSSL_SMALL_STACK_STATIC const byte check[] = { - 0x83, 0x46, 0x65, 0x2f, 0x5c, 0x44, 0x16, 0x5f, - 0xb3, 0x89, 0x26, 0xde, 0x0b, 0x6b, 0xa2, 0x06, - 0x7e, 0xa7, 0x9a, 0x55, 0x22, 0x01, 0xb0, 0x22, - 0xf4, 0x7e, 0xa2, 0x66, 0xc4, 0x08, 0x6f, 0xba + 0x35, 0x1e, 0xf9, 0xe8, 0x6b, 0x19, 0xe0, 0xe5, + 0x32, 0xb3, 0x41, 0xe5, 0xc1, 0x35, 0x18, 0x35, + 0x84, 0x2a, 0x3f, 0x84, 0x16, 0xc4, 0xf3, 0x50, + 0xdd, 0x4b, 0xeb, 0xe4, 0xcd, 0xbe, 0x94, 0x84 }; -#else - /* FIPS uses a longer seed, so different check value. */ + #else + WOLFSSL_SMALL_STACK_STATIC const byte check[] = + { + 0xb8, 0x3e, 0x23, 0xad, 0x34, 0xb6, 0x1e, 0xc7, + 0x0f, 0xa6, 0x4a, 0x45, 0x12, 0x66, 0xfd, 0x4d, + 0x97, 0xb2, 0x3d, 0xb3, 0xda, 0xcc, 0xed, 0x50, + 0x2e, 0xe0, 0x51, 0x38, 0x1d, 0x0f, 0x81, 0x35 + }; + #endif +#elif defined(HAVE_ENTROPY_MEMUSE) && \ + (defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND)) + #ifdef HAVE_FIPS + WOLFSSL_SMALL_STACK_STATIC const byte check[] = + { + 0xba, 0xc3, 0x2f, 0xcf, 0xd2, 0x0e, 0xe1, 0x16, + 0x45, 0xdc, 0xc2, 0x87, 0x0d, 0x70, 0xde, 0x5e, + 0x2e, 0x2f, 0x0c, 0x7a, 0x1d, 0x04, 0x89, 0x0d, + 0x0b, 0x9a, 0x51, 0x00, 0x4f, 0x7e, 0xce, 0xd6 + }; + #else + WOLFSSL_SMALL_STACK_STATIC const byte check[] = + { + 0xa6, 0xfa, 0x3e, 0xb7, 0x66, 0x85, 0x96, 0x79, + 0xef, 0x91, 0x26, 0xa1, 0xe8, 0x71, 0xa7, 0x13, + 0x03, 0xea, 0xe5, 0x7b, 0x36, 0x52, 0x02, 0x39, + 0x83, 0xbf, 0x41, 0xd1, 0x3e, 0x8f, 0xc0, 0x45 + }; + #endif +#elif defined(HAVE_AMD_RDSEED) + WOLFSSL_SMALL_STACK_STATIC const byte check[] = + { + 0x2c, 0xd4, 0x9b, 0x1e, 0x1e, 0xe7, 0xb0, 0xb0, + 0xf9, 0xa0, 0xa9, 0xd5, 0x8d, 0xf9, 0x6d, 0x10, + 0xf4, 0x77, 0xaf, 0xac, 0x3d, 0x2f, 0x6b, 0x1f, + 0xa2, 0xe7, 0xe5, 0x90, 0x6d, 0x1f, 0x88, 0x98 + }; +#elif defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND) + #ifdef HAVE_FIPS + WOLFSSL_SMALL_STACK_STATIC const byte check[] = + { + 0x27, 0xdd, 0xff, 0x5b, 0x21, 0x26, 0x0a, 0x48, + 0xb3, 0x6b, 0xd8, 0x14, 0x00, 0x55, 0xe8, 0x39, + 0x6d, 0x31, 0xf3, 0x6e, 0xe7, 0xbf, 0xce, 0x08, + 0x1f, 0x61, 0x73, 0xe6, 0x3c, 0xb9, 0x12, 0xea + }; + #else + WOLFSSL_SMALL_STACK_STATIC const byte check[] = + { + 0x3b, 0x9d, 0x0d, 0xc8, 0x0e, 0xb4, 0x33, 0x0b, + 0x50, 0x5f, 0x3a, 0xee, 0xc8, 0x68, 0x8d, 0x9f, + 0xdf, 0x39, 0x06, 0x78, 0xf8, 0x6a, 0xd6, 0xc6, + 0xd7, 0x63, 0x57, 0xe8, 0x6d, 0xf7, 0xc8, 0x6b + }; + #endif +#elif defined(HAVE_FIPS) WOLFSSL_SMALL_STACK_STATIC const byte check[] = { 0xaf, 0x31, 0xcc, 0xef, 0xa9, 0x29, 0x4c, 0x24, @@ -18382,6 +18440,14 @@ static wc_test_ret_t rng_seed_test(void) 0x1e, 0xd4, 0x52, 0x3b, 0x9a, 0x96, 0x06, 0x20, 0xc0, 0x5f, 0x44, 0x06, 0x1f, 0x80, 0xdf, 0xe0 }; +#else + WOLFSSL_SMALL_STACK_STATIC const byte check[] = + { + 0x83, 0x46, 0x65, 0x2f, 0x5c, 0x44, 0x16, 0x5f, + 0xb3, 0x89, 0x26, 0xde, 0x0b, 0x6b, 0xa2, 0x06, + 0x7e, 0xa7, 0x9a, 0x55, 0x22, 0x01, 0xb0, 0x22, + 0xf4, 0x7e, 0xa2, 0x66, 0xc4, 0x08, 0x6f, 0xba + }; #endif byte output[WC_SHA256_DIGEST_SIZE]; WC_RNG rng; @@ -18415,7 +18481,7 @@ static wc_test_ret_t rng_seed_test(void) out: return ret; } -#endif +#endif /* WC_RNG_SEED_CB) && !(ENTROPY_SCALE_FACTOR || SEED_BLOCK_SZ) */ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_test(void) @@ -18526,7 +18592,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_test(void) #endif /* Test the seed callback. */ -#ifdef WC_RNG_SEED_CB +#if defined(WC_RNG_SEED_CB) && \ + !(defined(ENTROPY_SCALE_FACTOR) || defined(SEED_BLOCK_SZ)) if ((ret = rng_seed_test()) != 0) return ret; #endif