Merge pull request #9125 from douzzer/20250819-linuxkm-fips-v5-wc_GenerateSeed_IntelRD

20250819-linuxkm-fips-v5-wc_GenerateSeed_IntelRD
This commit is contained in:
Sean Parkinson
2025-08-25 21:37:35 +10:00
committed by GitHub
13 changed files with 160 additions and 32 deletions

View File

@@ -44,7 +44,7 @@ void wolfssl_test(void)
test_func_args args = {0};
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
wc_SetSeed_Cb(WC_GENERATE_SEED_DEFAULT);
#endif
printf("Run wolfCrypt Test:\n");

View File

@@ -4082,7 +4082,7 @@ exit:
#endif
wolfSSL_Init();
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
wc_SetSeed_Cb(WC_GENERATE_SEED_DEFAULT);
#endif
ChangeToWolfRoot();

View File

@@ -161,10 +161,17 @@
#ifndef WOLFSSL_LINUXKM_USE_SAVE_VECTOR_REGISTERS
#define WOLFSSL_LINUXKM_USE_SAVE_VECTOR_REGISTERS
#endif
#else
#ifndef WOLFSSL_NO_ASM
#define WOLFSSL_NO_ASM
#endif
#endif
#if defined(HAVE_HASHDRBG) && defined(HAVE_FIPS) && FIPS_VERSION3_LT(6, 0, 0) && \
(defined(HAVE_INTEL_RDSEED) || defined(HAVE_AMD_RDSEED)) && \
!defined(WC_LINUXKM_RDSEED_IN_GLUE_LAYER)
#define WC_LINUXKM_RDSEED_IN_GLUE_LAYER
#endif
#ifdef WC_LINUXKM_RDSEED_IN_GLUE_LAYER
struct OS_Seed;
extern int wc_linuxkm_GenerateSeed_IntelRD(struct OS_Seed* os, unsigned char* output, unsigned int sz);
#define WC_GENERATE_SEED_DEFAULT wc_linuxkm_GenerateSeed_IntelRD
#endif
#ifdef BUILDING_WOLFSSL

View File

@@ -1292,7 +1292,7 @@ static int wc_linuxkm_drbg_loaded = 0;
#ifdef LINUXKM_DRBG_GET_RANDOM_BYTES
#if !(defined(HAVE_ENTROPY_MEMUSE) || defined(HAVE_INTEL_RDSEED) || \
defined(HAVE_AMD_RDSEED))
defined(HAVE_AMD_RDSEED) || defined(WC_LINUXKM_RDSEED_IN_GLUE_LAYER))
#error LINUXKM_DRBG_GET_RANDOM_BYTES requires a native or intrinsic entropy source.
#endif

View File

@@ -264,6 +264,104 @@ void wc_linuxkm_relax_long_loop(void) {
#endif
}
/* backported wc_GenerateSeed_IntelRD() for FIPS v5. */
#ifdef WC_LINUXKM_RDSEED_IN_GLUE_LAYER
#include <wolfssl/wolfcrypt/cpuid.h>
#include <wolfssl/wolfcrypt/random.h>
static cpuid_flags_t intel_flags = WC_CPUID_INITIALIZER;
static inline void wc_InitRng_IntelRD(void)
{
cpuid_get_flags_ex(&intel_flags);
}
#define INTELRD_RETRY 32
static WC_INLINE int IntelRDseed64(word64* seed)
{
unsigned char ok;
__asm__ volatile("rdseed %0; setc %1":"=r"(*seed), "=qm"(ok));
return (ok) ? 0 : -1;
}
/* return 0 on success */
static WC_INLINE int IntelRDseed64_r(word64* rnd)
{
int iters, retry_counter;
word64 buf;
#if defined(HAVE_AMD_RDSEED)
/* See "AMD RNG ESV Public Use Document". Version 0.7 of October 24,
* 2024 specifies 0.656 to 1.312 bits of entropy per 128 bit block of
* RDSEED output, depending on CPU family.
*
* FIPS v5 random.c sets ENTROPY_SCALE_FACTOR to 1 for
* HAVE_INTEL_RDSEED.
*/
iters = 128;
#elif defined(HAVE_INTEL_RDSEED)
/* The value of 2 applies to Intel's RDSEED which provides about
* 0.5 bits minimum of entropy per bit. The value of 4 gives a
* conservative margin for FIPS.
*
* FIPS v5 random.c sets ENTROPY_SCALE_FACTOR to 2 for
* HAVE_INTEL_RDSEED.
*/
iters = 2;
#else
#error WC_LINUXKM_RDSEED_IN_GLUE_LAYER requires HAVE_INTEL_RDSEED or HAVE_AMD_RDSEED
#endif
while (--iters >= 0) {
for (retry_counter = 0; retry_counter < INTELRD_RETRY; retry_counter++) {
if (IntelRDseed64(&buf) == 0)
break;
}
if (retry_counter == INTELRD_RETRY)
return -1;
WC_SANITIZE_DISABLE();
*rnd ^= buf; /* deliberately retain any garbage passed in the dest buffer. */
WC_SANITIZE_ENABLE();
}
return 0;
}
/* return 0 on success */
int wc_linuxkm_GenerateSeed_IntelRD(struct OS_Seed* os, byte* output, word32 sz)
{
int ret;
word64 rndTmp;
(void)os;
wc_InitRng_IntelRD();
if (!IS_INTEL_RDSEED(intel_flags))
return -1;
for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64),
output += sizeof(word64)) {
ret = IntelRDseed64_r((word64*)output);
if (ret != 0)
return ret;
}
if (sz == 0)
return 0;
/* handle unaligned remainder */
ret = IntelRDseed64_r(&rndTmp);
if (ret != 0)
return ret;
XMEMCPY(output, &rndTmp, sz);
wc_ForceZero(&rndTmp, sizeof(rndTmp));
return 0;
}
#endif /* WC_LINUXKM_RDSEED_IN_GLUE_LAYER */
#if defined(WOLFSSL_LINUXKM_USE_SAVE_VECTOR_REGISTERS) && defined(CONFIG_X86)
#include "linuxkm/x86_vector_register_glue.c"
#endif
@@ -359,14 +457,15 @@ static int wolfssl_init(void)
#endif /* HAVE_FIPS */
#ifdef WC_RNG_SEED_CB
ret = wc_SetSeed_Cb(wc_GenerateSeed);
ret = wc_SetSeed_Cb(WC_GENERATE_SEED_DEFAULT);
if (ret < 0) {
pr_err("ERROR: wc_SetSeed_Cb() failed with return code %d.\n", ret);
(void)libwolfssl_cleanup();
msleep(10);
return -ECANCELED;
}
#endif
#endif /* WC_RNG_SEED_CB */
#ifdef WOLFCRYPT_ONLY
ret = wolfCrypt_Init();

View File

@@ -6323,7 +6323,7 @@ int wolfSSL_Init(void)
#endif
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
wc_SetSeed_Cb(WC_GENERATE_SEED_DEFAULT);
#endif
#ifdef OPENSSL_EXTRA

View File

@@ -25508,7 +25508,7 @@ static int test_wolfSSL_RAND_poll(void)
ExpectIntNE(XMEMCMP(rand1, rand2, 16), 0);
/* reset the seed function used */
wc_SetSeed_Cb(wc_GenerateSeed);
wc_SetSeed_Cb(WC_GENERATE_SEED_DEFAULT);
#endif
RAND_cleanup();

View File

@@ -89,7 +89,7 @@ int unit_test(int argc, char** argv)
#endif
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
wc_SetSeed_Cb(WC_GENERATE_SEED_DEFAULT);
#endif
#ifdef HAVE_WNR
if (wc_InitNetRandom(wnrConfig, NULL, 5000) != 0)

View File

@@ -4074,7 +4074,7 @@ int benchmark_init(void)
#endif
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
wc_SetSeed_Cb(WC_GENERATE_SEED_DEFAULT);
#endif
bench_stats_init();

View File

@@ -1531,7 +1531,7 @@ wc_test_ret_t wolfcrypt_test(void* args)
#endif
#ifdef WC_RNG_SEED_CB
wc_SetSeed_Cb(wc_GenerateSeed);
wc_SetSeed_Cb(WC_GENERATE_SEED_DEFAULT);
#endif
printf("------------------------------------------------------------------------------\n");
@@ -18423,7 +18423,8 @@ static wc_test_ret_t rng_seed_test(void)
/* 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)
#if defined(HAVE_ENTROPY_MEMUSE) && defined(HAVE_AMD_RDSEED) && \
!(defined(HAVE_FIPS) && FIPS_VERSION_LT(6,0))
#ifdef HAVE_FIPS
WOLFSSL_SMALL_STACK_STATIC const byte check[] =
{
@@ -18460,7 +18461,8 @@ static wc_test_ret_t rng_seed_test(void)
0x83, 0xbf, 0x41, 0xd1, 0x3e, 0x8f, 0xc0, 0x45
};
#endif
#elif defined(HAVE_AMD_RDSEED)
#elif defined(HAVE_AMD_RDSEED) && \
!(defined(HAVE_FIPS) && FIPS_VERSION_LT(6,0))
WOLFSSL_SMALL_STACK_STATIC const byte check[] =
{
0x2c, 0xd4, 0x9b, 0x1e, 0x1e, 0xe7, 0xb0, 0xb0,
@@ -18468,7 +18470,8 @@ static wc_test_ret_t rng_seed_test(void)
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)
#elif (defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND)) && \
!(defined(HAVE_FIPS) && FIPS_VERSION_LT(6,0))
#ifdef HAVE_FIPS
WOLFSSL_SMALL_STACK_STATIC const byte check[] =
{
@@ -18486,6 +18489,15 @@ static wc_test_ret_t rng_seed_test(void)
0xd7, 0x63, 0x57, 0xe8, 0x6d, 0xf7, 0xc8, 0x6b
};
#endif
#elif defined(HAVE_INTEL_RDSEED) && \
defined(HAVE_FIPS) && FIPS_VERSION_LT(6,0)
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
};
#elif defined(HAVE_FIPS)
WOLFSSL_SMALL_STACK_STATIC const byte check[] =
{
@@ -18527,7 +18539,7 @@ static wc_test_ret_t rng_seed_test(void)
if (ret != 0) {
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
}
ret = wc_SetSeed_Cb(wc_GenerateSeed);
ret = wc_SetSeed_Cb(WC_GENERATE_SEED_DEFAULT);
if (ret != 0) {
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
}

View File

@@ -3764,7 +3764,6 @@ extern void uITRON4_free(void *p) ;
#endif
#endif
/* Place any other flags or defines here */
#if defined(WOLFSSL_MYSQL_COMPATIBLE) && defined(_WIN32) \

View File

@@ -1991,21 +1991,28 @@ WOLFSSL_API word32 CheckRunTimeSettings(void);
#define RESTORE_VECTOR_REGISTERS() RESTORE_NO_VECTOR_REGISTERS()
#endif
#ifdef WOLFSSL_NO_ASM
/* We define fallback no-op definitions for these only if asm is disabled,
* otherwise the using code must detect that these macros are undefined and
* provide its own non-vector implementation paths.
*
* Currently these macros are only used in WOLFSSL_LINUXKM code paths, which
* are always compiled either with substantive definitions from
* linuxkm_wc_port.h, or with WOLFSSL_NO_ASM defined.
*/
#ifndef DISABLE_VECTOR_REGISTERS
#if (defined(USE_INTEL_SPEEDUP) || defined(USE_INTEL_SPEEDUP_FOR_AES) || \
defined(WOLFSSL_AESNI) || defined(WOLFSSL_ARMASM) || \
defined(WOLFSSL_SP_ASM)) && !defined(WOLFSSL_NO_ASM)
#define WC_HAVE_VECTOR_SPEEDUPS
#endif
/* DISABLE_VECTOR_REGISTERS() and REENABLE_VECTOR_REGISTERS() are currently only
* used by Linux kernel code. If WC_HAVE_VECTOR_SPEEDUPS, we default
* DISABLE_VECTOR_REGISTERS() to -1, to assure calling code is forced to handle
* the failure. But if the build disables vec regs globally, we can return 0
* harmlessly. The kernel build defines real calls for these in vectorized
* builds, otherwise it uses these fallbacks.
*/
#ifndef DISABLE_VECTOR_REGISTERS
#ifdef WC_HAVE_VECTOR_SPEEDUPS
#define DISABLE_VECTOR_REGISTERS() (-1)
#else
#define DISABLE_VECTOR_REGISTERS() 0
#endif
#ifndef REENABLE_VECTOR_REGISTERS
#define REENABLE_VECTOR_REGISTERS() WC_DO_NOTHING
#endif
#endif
#ifndef REENABLE_VECTOR_REGISTERS
#define REENABLE_VECTOR_REGISTERS() WC_DO_NOTHING
#endif
#ifndef WC_SANITIZE_DISABLE

View File

@@ -1714,6 +1714,10 @@ WOLFSSL_ABI WOLFSSL_API int wolfCrypt_Cleanup(void);
#endif
#endif
#if defined(WC_RNG_SEED_CB) && !defined(WC_GENERATE_SEED_DEFAULT)
#define WC_GENERATE_SEED_DEFAULT wc_GenerateSeed
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif