diff --git a/configure.ac b/configure.ac index fff71cfe7..109ad83d0 100644 --- a/configure.ac +++ b/configure.ac @@ -3373,7 +3373,7 @@ AS_CASE([$FIPS_VERSION], AS_IF([test "x$ENABLED_AESGCM" = "xno"], [ENABLED_AESGCM="yes"; AM_CFLAGS="$AM_CFLAGS -DHAVE_AESGCM"]) AS_IF([test "x$ENABLED_MD5" = "xyes"],[ENABLED_MD5="no"; ENABLED_OLD_TLS="no"; AM_CFLAGS="$AM_CFLAGS -DNO_MD5 -DNO_OLD_TLS"]) - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ECDSA_SET_K" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ECDSA_SET_K -DWC_RNG_SEED_CB" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_VALIDATE_FFC_IMPORT -DHAVE_FFDHE_Q" AM_CFLAGS="$AM_CFLAGS -DHAVE_FFDHE_3072 -DHAVE_FFDHE_4096 -DHAVE_FFDHE_6144 -DHAVE_FFDHE_8192 -DFP_MAX_BITS=16384" ], diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index df8a2a736..3dbd4d251 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -289,6 +289,19 @@ int wc_RNG_GenerateByte(WC_RNG* rng, byte* b) #define MAX_SEED_SZ (SEED_SZ + SEED_SZ/2 + SEED_BLOCK_SZ) +#ifdef WC_RNG_SEED_CB + +static wc_RngSeed_Cb seedCb = NULL; + +int wc_SetSeed_Cb(wc_RngSeed_Cb cb) +{ + seedCb = cb; + return 0; +} + +#endif + + /* Internal return codes */ #define DRBG_SUCCESS 0 #define DRBG_FAILURE 1 @@ -806,7 +819,18 @@ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz, rng->drbg = (struct DRBG*)&rng->drbg_data; #endif if (ret == 0) { - ret = wc_GenerateSeed(&rng->seed, seed, seedSz); + ret = -1; + +#ifdef WC_RNG_SEED_CB + if (seedCb != NULL) { + ret = seedCb(seed, seedSz); + } +#endif + + if (ret < 0) { + ret = wc_GenerateSeed(&rng->seed, seed, seedSz); + } + if (ret == 0) ret = wc_RNG_TestSeed(seed, seedSz); else { diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 12f9a561f..a9dd419b8 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -11666,6 +11666,76 @@ static int random_rng_test(void) #if defined(HAVE_HASHDRBG) && !defined(CUSTOM_RAND_GENERATE_BLOCK) +#ifdef WC_RNG_SEED_CB +static int seed_cb(byte* output, word32 sz) +{ + word32 i; + /* Known answer test. Set the seed to the same value every time. */ + for (i = 0; i < sz; i++) + output[i] = (byte)i; + return 0; +} + +static int rng_seed_test(void) +{ +#ifndef 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 + }; +#else + /* FIPS uses a longer seed, so different check value. */ + WOLFSSL_SMALL_STACK_STATIC const byte check[] = + { + 0xaf, 0x31, 0xcc, 0xef, 0xa9, 0x29, 0x4c, 0x24, + 0xbd, 0xa5, 0xa3, 0x52, 0x69, 0xf3, 0xb9, 0xb2, + 0x1e, 0xd4, 0x52, 0x3b, 0x9a, 0x96, 0x06, 0x20, + 0xc0, 0x5f, 0x44, 0x06, 0x1f, 0x80, 0xdf, 0xe0 + }; +#endif + byte output[WC_SHA256_DIGEST_SIZE]; + WC_RNG rng; + int ret; + + ret = wc_SetSeed_Cb(seed_cb); + if (ret != 0) { + ret = -7007; + goto exit; + } + ret = wc_InitRng(&rng); + if (ret != 0) { + ret = -7008; + goto exit; + } + ret = wc_RNG_GenerateBlock(&rng, output, sizeof(output)); + if (ret != 0) { + ret = -7009; + goto exit; + } + ret = XMEMCMP(output, check, sizeof(output)); + if (ret != 0) { + ret = -7010; + goto exit; + } + ret = wc_FreeRng(&rng); + if (ret != 0) { + ret = -7011; + goto exit; + } + ret = wc_SetSeed_Cb(NULL); + if (ret != 0) { + ret = -7012; + } + +exit: + return ret; +} +#endif + + WOLFSSL_TEST_SUBROUTINE int random_test(void) { WOLFSSL_SMALL_STACK_STATIC const byte test1Entropy[] = @@ -11771,6 +11841,13 @@ WOLFSSL_TEST_SUBROUTINE int random_test(void) return -7006; } #endif + + /* Test the seed callback. */ +#ifdef WC_RNG_SEED_CB + if ((ret = rng_seed_test()) != 0) + return ret; +#endif + return 0; } diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index a3ac0e108..3450dfcd0 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -65,6 +65,9 @@ This library defines the interface APIs for X509 certificates. #endif #ifndef WC_RNG_TYPE_DEFINED typedef struct WC_RNG WC_RNG; + #ifdef WC_RNG_SEED_CB + typedef int (*wc_RngSeed_Cb)(byte* seed, word32 sz); + #endif #define WC_RNG_TYPE_DEFINED #endif #ifndef WC_DH_TYPE_DEFINED diff --git a/wolfssl/wolfcrypt/random.h b/wolfssl/wolfcrypt/random.h index 066eaff49..69cfd4867 100644 --- a/wolfssl/wolfcrypt/random.h +++ b/wolfssl/wolfcrypt/random.h @@ -235,7 +235,10 @@ WOLFSSL_API int wc_FreeRng(WC_RNG*); #define wc_FreeRng(rng) (void)NOT_COMPILED_IN #endif - +#ifdef WC_RNG_SEED_CB + typedef int (*wc_RngSeed_Cb)(byte* seed, word32 sz); + WOLFSSL_API int wc_SetSeed_Cb(wc_RngSeed_Cb cb); +#endif #ifdef HAVE_HASHDRBG WOLFSSL_LOCAL int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* entropy,