#include <stdio.h>
#include <time.h>
#include "cryptlib.h"
#include <openssl/rand.h>
#include "rand_lcl.h"
#ifdef OPENSSL_FIPS
#include <openssl/fips.h>
#include <openssl/fips_rand.h>
#endif
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
static const RAND_METHOD *default_RAND_meth = NULL;
#ifdef OPENSSL_FIPS
static int fips_RAND_set_rand_method(const RAND_METHOD *meth,
const RAND_METHOD **pmeth)
{
*pmeth = meth;
return 1;
}
static const RAND_METHOD *fips_RAND_get_rand_method(const RAND_METHOD **pmeth)
{
if (!*pmeth)
{
if(FIPS_mode())
*pmeth=FIPS_rand_method();
else
*pmeth = RAND_SSLeay();
}
if(FIPS_mode()
&& *pmeth != FIPS_rand_check())
{
RANDerr(RAND_F_FIPS_RAND_GET_RAND_METHOD,RAND_R_NON_FIPS_METHOD);
return 0;
}
return *pmeth;
}
static int (*RAND_set_rand_method_func)(const RAND_METHOD *meth,
const RAND_METHOD **pmeth)
= fips_RAND_set_rand_method;
static const RAND_METHOD *(*RAND_get_rand_method_func)
(const RAND_METHOD **pmeth)
= fips_RAND_get_rand_method;
#ifndef OPENSSL_NO_ENGINE
void int_RAND_set_callbacks(
int (*set_rand_func)(const RAND_METHOD *meth,
const RAND_METHOD **pmeth),
const RAND_METHOD *(*get_rand_func)
(const RAND_METHOD **pmeth))
{
RAND_set_rand_method_func = set_rand_func;
RAND_get_rand_method_func = get_rand_func;
}
#endif
int RAND_set_rand_method(const RAND_METHOD *meth)
{
return RAND_set_rand_method_func(meth, &default_RAND_meth);
}
const RAND_METHOD *RAND_get_rand_method(void)
{
return RAND_get_rand_method_func(&default_RAND_meth);
}
#else
#ifndef OPENSSL_NO_ENGINE
static ENGINE *funct_ref =NULL;
#endif
int RAND_set_rand_method(const RAND_METHOD *meth)
{
#ifndef OPENSSL_NO_ENGINE
if(funct_ref)
{
ENGINE_finish(funct_ref);
funct_ref = NULL;
}
#endif
default_RAND_meth = meth;
return 1;
}
const RAND_METHOD *RAND_get_rand_method(void)
{
if (!default_RAND_meth)
{
#ifndef OPENSSL_NO_ENGINE
ENGINE *e = ENGINE_get_default_RAND();
if(e)
{
default_RAND_meth = ENGINE_get_RAND(e);
if(!default_RAND_meth)
{
ENGINE_finish(e);
e = NULL;
}
}
if(e)
funct_ref = e;
else
#endif
default_RAND_meth = RAND_SSLeay();
}
return default_RAND_meth;
}
#ifndef OPENSSL_NO_ENGINE
int RAND_set_rand_engine(ENGINE *engine)
{
const RAND_METHOD *tmp_meth = NULL;
if(engine)
{
if(!ENGINE_init(engine))
return 0;
tmp_meth = ENGINE_get_RAND(engine);
if(!tmp_meth)
{
ENGINE_finish(engine);
return 0;
}
}
RAND_set_rand_method(tmp_meth);
funct_ref = engine;
return 1;
}
#endif
#endif
void RAND_cleanup(void)
{
const RAND_METHOD *meth = RAND_get_rand_method();
if (meth && meth->cleanup)
meth->cleanup();
RAND_set_rand_method(NULL);
}
void RAND_seed(const void *buf, int num)
{
const RAND_METHOD *meth = RAND_get_rand_method();
if (meth && meth->seed)
meth->seed(buf,num);
}
void RAND_add(const void *buf, int num, double entropy)
{
const RAND_METHOD *meth = RAND_get_rand_method();
if (meth && meth->add)
meth->add(buf,num,entropy);
}
int RAND_bytes(unsigned char *buf, int num)
{
const RAND_METHOD *meth = RAND_get_rand_method();
if (meth && meth->bytes)
return meth->bytes(buf,num);
return(-1);
}
int RAND_pseudo_bytes(unsigned char *buf, int num)
{
const RAND_METHOD *meth = RAND_get_rand_method();
if (meth && meth->pseudorand)
return meth->pseudorand(buf,num);
return(-1);
}
int RAND_status(void)
{
const RAND_METHOD *meth = RAND_get_rand_method();
if (meth && meth->status)
return meth->status();
return 0;
}