Fixes and cleanups for the openssl compatibility layer RAND_ functions. For opensslextra=x509small don't include the RAND method code. Removed abandonded "ENABLED_SMALL" option in configure.ac.

This commit is contained in:
David Garske
2021-03-17 15:51:52 -07:00
parent 1477af9a22
commit 7760dcb43b
4 changed files with 178 additions and 267 deletions

View File

@ -949,16 +949,12 @@ then
AM_CFLAGS="-DHAVE_EXT_CACHE $AM_CFLAGS"
fi
if test "$ENABLED_OPENSSLEXTRA" = "yes" && test "$ENABLED_SMALL" = "yes"
then
AC_MSG_ERROR([cannot enable small and opensslextra, only one or the other.])
fi
if test "$ENABLED_OPENSSLEXTRA" = "x509small"
then
AC_MSG_NOTICE([Enabling only a subset of X509 opensslextra])
AM_CFLAGS="-DOPENSSL_EXTRA_X509_SMALL $AM_CFLAGS"
AM_CFLAGS="-DWOLFSSL_EKU_OID -DWOLFSSL_MULTI_ATTRIB $AM_CFLAGS"
AM_CFLAGS="-DWOLFSSL_NO_OPENSSL_RAND_CB $AM_CFLAGS"
fi
# One Error Queue per Thread
@ -5194,11 +5190,6 @@ if test "$ENABLED_SP_NONBLOCK" = "yes"; then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_NONBLOCK"
AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_NONBLOCK"
fi
if test "$ENABLED_SMALL" = "yes"; then
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_SMALL"
AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_SMALL"
fi
if test "$ENABLED_SP_MATH" = "yes"; then
if test "$ENABLED_SP" = "no"; then

370
src/ssl.c
View File

@ -151,13 +151,17 @@
#ifndef WOLFCRYPT_ONLY
#ifdef OPENSSL_EXTRA
/* Global pointer to constant BN on */
static WOLFSSL_BIGNUM* bn_one = NULL;
/* Global pointer to constant BN on */
static WOLFSSL_BIGNUM* bn_one = NULL;
static const WOLFSSL_RAND_METHOD* rand_methods = NULL;
static int initRandMethMutex = 0;
static wolfSSL_Mutex rand_methods_mutex;
#endif
/* WOLFSSL_NO_OPENSSL_RAND_CB: Allows way to reduce code size for
* OPENSSL_EXTRA where RAND callbacks are not used */
#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
static const WOLFSSL_RAND_METHOD* gRandMethods = NULL;
static int gRandMethodsInit = 0;
static wolfSSL_Mutex gRandMethodMutex;
#endif /* !WOLFSSL_NO_OPENSSL_RAND_CB */
#endif /* OPENSSL_EXTRA */
#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC)
const WOLF_EC_NIST_NAME kNistCurves[] = {
@ -4931,9 +4935,25 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
#if defined(OPENSSL_EXTRA) || \
(defined(OPENSSL_EXTRA_X509_SMALL) && !defined(NO_RSA))
static WC_RNG globalRNG;
static int initGlobalRNG = 0;
static wolfSSL_Mutex globalRNGMutex;
#define HAVE_GLOBAL_RNG /* consolidate flags for using globalRNG */
static WC_RNG globalRNG;
static int initGlobalRNG = 0;
static wolfSSL_Mutex globalRNGMutex;
#endif
#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_OPENSSL_RAND_CB)
static int wolfSSL_RAND_InitMutex(void)
{
if (gRandMethodsInit == 0) {
if (wc_InitMutex(&gRandMethodMutex) != 0) {
WOLFSSL_MSG("Bad Init Mutex rand methods");
return BAD_MUTEX_E;
}
gRandMethodsInit = 1;
}
return 0;
}
#endif
WOLFSSL_ABI
@ -4948,8 +4968,7 @@ int wolfSSL_Init(void)
return WC_INIT_E;
}
#if defined(OPENSSL_EXTRA) || \
(defined(OPENSSL_EXTRA_X509_SMALL) && !defined(NO_RSA))
#ifdef HAVE_GLOBAL_RNG
if (wc_InitMutex(&globalRNGMutex) != 0) {
WOLFSSL_MSG("Bad Init Mutex rng");
return BAD_MUTEX_E;
@ -4957,18 +4976,12 @@ int wolfSSL_Init(void)
#endif
#ifdef OPENSSL_EXTRA
if (wc_InitMutex(&rand_methods_mutex) != 0) {
WOLFSSL_MSG("Bad Init Mutex rand methods");
#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
if (wolfSSL_RAND_InitMutex() != 0) {
return BAD_MUTEX_E;
}
else {
initRandMethMutex = 1;
}
if (wolfSSL_RAND_seed(NULL, 0) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("wolfSSL_RAND_Seed failed");
return WC_INIT_E;
}
#endif
wolfSSL_RAND_seed(NULL, 0);
#endif
#ifndef NO_SESSION_CACHE
@ -13231,18 +13244,6 @@ int wolfSSL_Cleanup(void)
#ifdef OPENSSL_EXTRA
wolfSSL_RAND_Cleanup();
if (wc_LockMutex(&rand_methods_mutex) != 0) {
WOLFSSL_MSG("Bad Lock Mutex rand methods");
return BAD_MUTEX_E;
}
rand_methods = NULL;
wc_UnLockMutex(&rand_methods_mutex);
if (wc_FreeMutex(&rand_methods_mutex) != 0)
ret = BAD_MUTEX_E;
else
initRandMethMutex = 0;
#endif
if (wolfCrypt_Cleanup() != 0) {
@ -17838,123 +17839,50 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
Returns WOLFSSL_SUCCESS on success, WOLFSSL_FAILURE on failure. */
int wolfSSL_RAND_set_rand_method(const WOLFSSL_RAND_METHOD *methods)
{
int ret = WOLFSSL_FAILURE;
if (initRandMethMutex == 0) {
if (wc_InitMutex(&rand_methods_mutex) != 0) {
WOLFSSL_MSG("Bad Init Mutex rand methods");
ret = BAD_MUTEX_E;
}
else {
initRandMethMutex = 1;
}
#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
gRandMethods = methods;
wc_UnLockMutex(&gRandMethodMutex);
}
if (initRandMethMutex != 0) {
if (wc_LockMutex(&rand_methods_mutex) != 0) {
WOLFSSL_MSG("Lock rand methods mutex failed");
ret = BAD_MUTEX_E;
}
else {
rand_methods = methods;
wc_UnLockMutex(&rand_methods_mutex);
ret = WOLFSSL_SUCCESS;
}
}
return ret;
}
/* Sets func_ptr to a pointer to the given function func if it was set
by RAND_set_rand_method, or NULL if either it was not set,
or there was an error retreiving it.
Returns WOLFSSL_SUCCESS on success, otherwise returns an error code. */
static int GetRandFunction(RandFunction func, void** func_ptr)
{
int ret = WOLFSSL_FAILURE;
if (func_ptr == NULL) {
return WOLFSSL_FAILURE;
}
*func_ptr = NULL;
if (initRandMethMutex == 0) {
if (wc_InitMutex(&rand_methods_mutex) != 0) {
WOLFSSL_MSG("Bad Init Mutex rand methods");
ret = BAD_MUTEX_E;
}
else {
initRandMethMutex = 1;
}
}
if (initRandMethMutex != 0) {
if (wc_LockMutex(&rand_methods_mutex) != 0) {
WOLFSSL_MSG("Lock rand methods mutex failed");
ret = BAD_MUTEX_E;
}
else {
if (rand_methods != NULL && rand_methods->status != NULL) {
if (func == RAND_SEED) {
*func_ptr = rand_methods->seed;
}
else if (func == RAND_BYTES) {
*func_ptr = rand_methods->bytes;
}
else if (func == RAND_CLEANUP) {
*func_ptr = rand_methods->cleanup;
}
else if (func == RAND_ADD) {
*func_ptr = rand_methods->add;
}
else if (func == RAND_PSEUDORAND) {
*func_ptr = rand_methods->pseudorand;
}
else if (func == RAND_STATUS) {
*func_ptr = rand_methods->status;
}
}
wc_UnLockMutex(&rand_methods_mutex);
ret = WOLFSSL_SUCCESS;
}
}
return ret;
#else
(void)methods;
#endif
return WOLFSSL_SUCCESS;
}
/* Returns WOLFSSL_SUCCESS if the RNG has been seeded with enough data */
int wolfSSL_RAND_status(void)
{
RandStatusMethod* randFunc = NULL;
if (GetRandFunction(RAND_STATUS, (void**)&randFunc)
!= WOLFSSL_SUCCESS) {
return WOLFSSL_FAILURE;
int ret = WOLFSSL_SUCCESS;
#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
if (gRandMethods && gRandMethods->status)
ret = gRandMethods->status();
wc_UnLockMutex(&gRandMethodMutex);
}
else if (randFunc != NULL) {
return randFunc();
}
return WOLFSSL_SUCCESS; /* wolfCrypt provides enough seed internally */
#else
/* wolfCrypt provides enough seed internally, so return success */
#endif
return ret;
}
void wolfSSL_RAND_add(const void* add, int len, double entropy)
{
RandAddMethod* randFunc = NULL;
if (GetRandFunction(RAND_ADD, (void**)&randFunc)
!= WOLFSSL_SUCCESS) {
return;
#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
if (gRandMethods && gRandMethods->add) {
/* callback has return code, but RAND_add does not */
(void)gRandMethods->add(add, len, entropy);
}
wc_UnLockMutex(&gRandMethodMutex);
}
else if (randFunc != NULL) {
randFunc(add, len, entropy);
}
#else
/* wolfSSL seeds/adds internally, use explicit RNG if you want
to take control */
return;
(void)add;
(void)len;
(void)entropy;
#endif
}
#ifndef NO_DES3
@ -31622,40 +31550,41 @@ WC_RNG* WOLFSSL_RSA_GetRNG(WOLFSSL_RSA *rsa, WC_RNG **tmpRNG, int *initTmpRng)
*/
static int wolfSSL_RAND_Init(void)
{
if (wc_LockMutex(&globalRNGMutex) != 0) {
WOLFSSL_MSG("Bad Lock Mutex rng");
return 0;
}
if (initGlobalRNG == 0) {
if (wc_InitRng(&globalRNG) < 0) {
WOLFSSL_MSG("wolfSSL Init Global RNG failed");
wc_UnLockMutex(&globalRNGMutex);
return 0;
int ret = WOLFSSL_FAILURE;
#ifdef HAVE_GLOBAL_RNG
if (wc_LockMutex(&globalRNGMutex) == 0) {
if (initGlobalRNG == 0) {
ret = wc_InitRng(&globalRNG);
if (ret == 0) {
initGlobalRNG = 1;
ret = WOLFSSL_SUCCESS;
}
}
initGlobalRNG = 1;
wc_UnLockMutex(&globalRNGMutex);
}
wc_UnLockMutex(&globalRNGMutex);
return WOLFSSL_SUCCESS;
#endif
return ret;
}
/* WOLFSSL_SUCCESS on ok */
int wolfSSL_RAND_seed(const void* seed, int len)
void wolfSSL_RAND_seed(const void* seed, int len)
{
RandSeedMethod* randFunc = NULL;
WOLFSSL_MSG("wolfSSL_RAND_seed");
if (GetRandFunction(RAND_SEED, (void**)&randFunc)
!= WOLFSSL_SUCCESS) {
return WOLFSSL_FAILURE;
}
else if (randFunc != NULL) {
return randFunc(seed, len);
#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
if (gRandMethods && gRandMethods->seed) {
/* seed callback has return code, but function RAND_seed does not */
(void)gRandMethods->seed(seed, len);
}
wc_UnLockMutex(&gRandMethodMutex);
}
#else
(void)seed;
(void)len;
#endif
return wolfSSL_RAND_Init();
/* Make sure global shared RNG (globalRNG) is initialized */
(void)wolfSSL_RAND_Init();
}
@ -31958,75 +31887,72 @@ int wolfSSL_RAND_egd(const char* nm)
void wolfSSL_RAND_Cleanup(void)
{
RandCleanupMethod* randFunc = NULL;
WOLFSSL_ENTER("wolfSSL_RAND_Cleanup()");
if (GetRandFunction(RAND_CLEANUP, (void**)&randFunc)
== WOLFSSL_SUCCESS && randFunc != NULL) {
randFunc();
#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
if (gRandMethods && gRandMethods->cleanup)
gRandMethods->cleanup();
wc_UnLockMutex(&gRandMethodMutex);
}
if (wc_LockMutex(&globalRNGMutex) != 0) {
WOLFSSL_MSG("Bad Lock Mutex rng");
#endif
#ifdef HAVE_GLOBAL_RNG
if (wc_LockMutex(&globalRNGMutex) == 0) {
if (initGlobalRNG) {
wc_FreeRng(&globalRNG);
initGlobalRNG = 0;
}
wc_UnLockMutex(&globalRNGMutex);
}
else if (initGlobalRNG != 0) {
wc_FreeRng(&globalRNG);
initGlobalRNG = 0;
}
wc_UnLockMutex(&globalRNGMutex);
return;
#endif
}
/* returns WOLFSSL_SUCCESS if the bytes generated are valid otherwise WOLFSSL_FAILURE */
int wolfSSL_RAND_pseudo_bytes(unsigned char* buf, int num)
{
RandPseudorandMethod* randFunc = NULL;
if (GetRandFunction(RAND_PSEUDORAND, (void**)&randFunc)
!= WOLFSSL_SUCCESS) {
return WOLFSSL_FAILURE;
}
else if (randFunc != NULL) {
return randFunc(buf, num);
#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
if (gRandMethods && gRandMethods->pseudorand) {
int ret = gRandMethods->pseudorand(buf, num);
wc_UnLockMutex(&gRandMethodMutex);
return ret;
}
wc_UnLockMutex(&gRandMethodMutex);
}
#endif
/* fallback to using the global shared RNG */
return wolfSSL_RAND_bytes(buf, num);
}
/* WOLFSSL_SUCCESS on ok */
/* returns WOLFSSL_SUCCESS if the bytes generated are valid otherwise WOLFSSL_FAILURE */
int wolfSSL_RAND_bytes(unsigned char* buf, int num)
{
int ret = 0;
int initTmpRng = 0;
WC_RNG* rng = NULL;
#ifdef WOLFSSL_SMALL_STACK
WC_RNG* tmpRNG;
WC_RNG* tmpRNG = NULL;
#else
WC_RNG tmpRNG[1];
#endif
int used_global = 0;
int initTmpRng = 0;
int blockCount = 0;
RandBytesMethod* randFunc = NULL;
#ifdef HAVE_GLOBAL_RNG
int used_global = 0;
#endif
WOLFSSL_ENTER("wolfSSL_RAND_bytes");
if (GetRandFunction(RAND_BYTES, (void**)&randFunc)
!= WOLFSSL_SUCCESS) {
return WOLFSSL_FAILURE;
/* if a RAND callback has been set try and use it */
#ifndef WOLFSSL_NO_OPENSSL_RAND_CB
if (wolfSSL_RAND_InitMutex() == 0 && wc_LockMutex(&gRandMethodMutex) == 0) {
if (gRandMethods && gRandMethods->bytes) {
ret = gRandMethods->bytes(buf, num);
wc_UnLockMutex(&gRandMethodMutex);
return ret;
}
wc_UnLockMutex(&gRandMethodMutex);
}
else if (randFunc != NULL) {
return randFunc(buf, num);
}
#ifdef WOLFSSL_SMALL_STACK
tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
if (tmpRNG == NULL)
return ret;
#endif
#ifdef HAVE_GLOBAL_RNG
if (initGlobalRNG) {
if (wc_LockMutex(&globalRNGMutex) != 0) {
WOLFSSL_MSG("Bad Lock Mutex rng");
@ -32036,16 +31962,26 @@ int wolfSSL_RAND_bytes(unsigned char* buf, int num)
rng = &globalRNG;
used_global = 1;
}
else if(wc_InitRng(tmpRNG) == 0) {
rng = tmpRNG;
initTmpRng = 1;
else
#endif
{
#ifdef WOLFSSL_SMALL_STACK
tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
if (tmpRNG == NULL)
return ret;
#endif
if (wc_InitRng(tmpRNG) == 0) {
rng = tmpRNG;
initTmpRng = 1;
}
}
if (rng) {
/* handles size grater than RNG_MAX_BLOCK_LEN */
/* handles size greater than RNG_MAX_BLOCK_LEN */
blockCount = num / RNG_MAX_BLOCK_LEN;
while(blockCount--) {
if((ret = wc_RNG_GenerateBlock(rng, buf, RNG_MAX_BLOCK_LEN) != 0)){
while (blockCount--) {
ret = wc_RNG_GenerateBlock(rng, buf, RNG_MAX_BLOCK_LEN);
if (ret != 0) {
WOLFSSL_MSG("Bad wc_RNG_GenerateBlock");
break;
}
@ -32062,15 +31998,15 @@ int wolfSSL_RAND_bytes(unsigned char* buf, int num)
ret = WOLFSSL_SUCCESS;
}
if (used_global == 1) {
#ifdef HAVE_GLOBAL_RNG
if (used_global == 1)
wc_UnLockMutex(&globalRNGMutex);
}
#endif
if (initTmpRng)
wc_FreeRng(tmpRNG);
#ifdef WOLFSSL_SMALL_STACK
XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
if (tmpRNG)
XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
#endif
return ret;

View File

@ -30381,7 +30381,7 @@ static void test_wolfSSL_BUF(void)
#endif /* OPENSSL_EXTRA */
}
#if defined(OPENSSL_EXTRA)
#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_OPENSSL_RAND_CB)
static int stub_rand_seed(const void *buf, int num)
{
(void)buf;
@ -30446,11 +30446,11 @@ static int stub_rand_status(void)
{
return 5432;
}
#endif
#endif /* OPENSSL_EXTRA && !WOLFSSL_NO_OPENSSL_RAND_CB */
static void test_wolfSSL_RAND_set_rand_method(void)
{
#if defined(OPENSSL_EXTRA)
#if defined(OPENSSL_EXTRA) && !defined(WOLFSSL_NO_OPENSSL_RAND_CB)
WOLFSSL_RAND_METHOD rand_methods = {NULL, NULL, NULL, NULL, NULL, NULL};
unsigned char* buf = NULL;
int num = 0;
@ -30473,8 +30473,8 @@ static void test_wolfSSL_RAND_set_rand_method(void)
rand_methods.pseudorand = &stub_rand_pseudo_bytes;
rand_methods.status = &stub_rand_status;
AssertIntEQ(wolfSSL_RAND_set_rand_method(&rand_methods), SSL_SUCCESS);
AssertIntEQ(wolfSSL_RAND_seed(buf, num), 123);
AssertIntEQ(wolfSSL_RAND_set_rand_method(&rand_methods), WOLFSSL_SUCCESS);
wolfSSL_RAND_seed(buf, num);
AssertIntEQ(wolfSSL_RAND_bytes(buf, num), 456);
AssertIntEQ(wolfSSL_RAND_pseudo_bytes(buf, num), 9876);
AssertIntEQ(wolfSSL_RAND_status(), 5432);
@ -30490,14 +30490,14 @@ static void test_wolfSSL_RAND_set_rand_method(void)
*was_cleanup_called = 0;
AssertIntEQ(wolfSSL_RAND_set_rand_method(NULL), SSL_SUCCESS);
AssertIntEQ(wolfSSL_RAND_set_rand_method(NULL), WOLFSSL_SUCCESS);
AssertIntNE(wolfSSL_RAND_status(), 5432);
AssertIntEQ(*was_cleanup_called, 0);
wolfSSL_RAND_Cleanup();
AssertIntEQ(*was_cleanup_called, 0);
printf(resultFmt, passed);
#endif
#endif /* OPENSSL_EXTRA && !WOLFSSL_NO_OPENSSL_RAND_CB */
}
static void test_wolfSSL_RAND_bytes(void)

View File

@ -639,41 +639,25 @@ struct WOLFSSL_X509_STORE_CTX {
typedef char* WOLFSSL_STRING;
/* seed = Data to mix into the random generator.
len = Number of bytes to mix from seed. */
typedef int RandSeedMethod(const void* seed, int len);
/* buf = Buffer to store random bytes in.
len = Number of bytes to store in buf. */
typedef int RandBytesMethod(unsigned char* buf, int len);
typedef void RandCleanupMethod(void);
/* add = Data to mix into the random generator.
len = Number of bytes to mix from add.
entropy = Estimate of randomness contained in seed.
Should be between 0 and len. */
typedef int RandAddMethod(const void* add, int len, double entropy);
/* buf = Buffer to store pseudorandom bytes in.
len = Number of bytes to store in buf. */
typedef int RandPseudorandMethod(unsigned char *buf, int len);
typedef int RandStatusMethod(void);
typedef struct WOLFSSL_RAND_METHOD {
RandSeedMethod* seed;
RandBytesMethod* bytes;
RandCleanupMethod* cleanup;
RandAddMethod* add;
RandPseudorandMethod* pseudorand;
RandStatusMethod* status;
/* seed = Data to mix into the random generator.
* len = Number of bytes to mix from seed. */
int (*seed)(const void* seed, int len);
/* buf = Buffer to store random bytes in.
* len = Number of bytes to store in buf. */
int (*bytes)(unsigned char* buf, int len);
void (*cleanup)(void);
/* add = Data to mix into the random generator.
* len = Number of bytes to mix from add.
* entropy = Estimate of randomness contained in seed.
* Should be between 0 and len. */
int (*add)(const void* add, int len, double entropy);
/* buf = Buffer to store pseudorandom bytes in.
* len = Number of bytes to store in buf. */
int (*pseudorand)(unsigned char *buf, int len);
int (*status)(void);
} WOLFSSL_RAND_METHOD;
typedef enum RandFunction {
RAND_SEED,
RAND_BYTES,
RAND_CLEANUP,
RAND_ADD,
RAND_PSEUDORAND,
RAND_STATUS
} RandFunction;
/* Valid Alert types from page 16/17
* Add alert string to the function wolfSSL_alert_type_string_long in src/ssl.c
*/
@ -1424,7 +1408,7 @@ WOLFSSL_API const char* wolfSSL_RAND_file_name(char*, unsigned long);
WOLFSSL_API int wolfSSL_RAND_write_file(const char*);
WOLFSSL_API int wolfSSL_RAND_load_file(const char*, long);
WOLFSSL_API int wolfSSL_RAND_egd(const char*);
WOLFSSL_API int wolfSSL_RAND_seed(const void*, int);
WOLFSSL_API void wolfSSL_RAND_seed(const void*, int);
WOLFSSL_API void wolfSSL_RAND_Cleanup(void);
WOLFSSL_API void wolfSSL_RAND_add(const void*, int, double);
WOLFSSL_API int wolfSSL_RAND_poll(void);