mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-01-26 14:22:21 +01:00
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:
@@ -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");
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user