1#if defined(HAVE_CONFIG_H)
39#if ( USE_OPENSSL == 1 )
40# include <openssl/opensslv.h>
41#if !defined(LIBRESSL_VERSION_NUMBER)
42# include <openssl/e_os2.h>
44# include <openssl/rand.h>
45# include <openssl/err.h>
49#define RESIPROCATE_SUBSYSTEM Subsystem::SIP
52bool Random::mIsInitialized =
false;
55Random::Initializer Random::mInitializer;
56#ifdef RESIP_RANDOM_WIN32_RTL
57BOOLEAN (APIENTRY *Random::RtlGenRandom)(
void*, ULONG) = 0;
61#ifdef RESIP_RANDOM_THREAD_MUTEX
62struct random_data* Random::sRandomState = 0;
65#ifdef RESIP_RANDOM_THREAD_LOCAL
72 unsigned int sThreadSeedBase = 0;
76#define RANDOM_STATE_SIZE 128
82#if defined(RESIP_RANDOM_WIN32_RTL)
88#if defined(RESIP_RANDOM_THREAD_LOCAL)
89 return "posix_thread_local";
90#elif defined(RESIP_RANDOM_THREAD_MUTEX)
91 return "posix_thread_mutex";
93 return "posix_random";
109 strm << GetTickCount() <<
":";
110 strm << GetCurrentProcessId() <<
":";
111 strm << GetCurrentThreadId();
116#if defined(RESIP_RANDOM_THREAD_LOCAL)
121 return (
unsigned int)buffer.
hash();
131 if ( !Random::mIsInitialized)
134 if (!Random::mIsInitialized)
136 mIsInitialized =
true;
141 if (!Random::mInitializer.isInitialized())
144 if (!Random::mInitializer.isInitialized())
146 Random::mInitializer.setInitialized();
151#ifdef RESIP_RANDOM_WIN32_RTL
160 HMODULE hLib = GetModuleHandle(
"ADVAPI32.DLL");
163 Random::RtlGenRandom =
164 (BOOLEAN(APIENTRY*)(
void*, ULONG))GetProcAddress(hLib,
"SystemFunction036");
165 if (!Random::RtlGenRandom)
167 WarningLog(<<
"Not linked with ADVAPI32.DLL, using srand(..) and rand() for random numbers");
172 mIsInitialized =
true;
180 if ( !Random::mIsInitialized)
183 if (!Random::mIsInitialized)
185 mIsInitialized =
true;
190 int fd = open(
"/dev/urandom", O_RDONLY);
198 unsigned urandomSeed = 0;
199 int s = read( fd,&urandomSeed,
sizeof(urandomSeed) );
201 if ( s ==
sizeof(urandomSeed) )
207 ErrLog( <<
"System is short of randomness" );
212 ErrLog( <<
"Could not open /dev/urandom" );
215#if defined(RESIP_RANDOM_THREAD_LOCAL)
216 sThreadSeedBase = seed;
218#elif defined(RESIP_RANDOM_THREAD_MUTEX)
219 struct random_data *buf;
221 buf = (
struct random_data*) ::malloc(sz);
241 int s = read( fd,&buf,
sizeof(buf) );
243 if ( s !=
sizeof(buf) )
245 ErrLog( <<
"System is short of randomness" );
248 RAND_add(buf,
sizeof(buf),
double(s*8));
269#ifdef RESIP_RANDOM_WIN32_RTL
271 if (Random::RtlGenRandom)
273 unsigned long buff[1];
274 ULONG ulCbBuff =
sizeof(buff);
275 if (Random::RtlGenRandom(buff,ulCbBuff))
278 ret = buff[0] & (~(1<<31));
298#if defined(RESIP_RANDOM_THREAD_LOCAL)
302 buf = (
struct random_data*) ::malloc(sz);
313#elif defined(RESIP_RANDOM_THREAD_MUTEX)
316 Lock statelock(mMutex);
317 random_r(sRandomState, &ret);
336 int e = RAND_bytes( (
unsigned char*)&ret ,
sizeof(ret) );
340 long err = ERR_get_error();
343 ERR_error_string_n(err,buf,
sizeof(buf));
366 for (
unsigned int count=0; count<(len+
sizeof(int)-1)/
sizeof(int); ++count)
370 return Data(cbuf, len);
376 unsigned char* buf =
new unsigned char[len];
438 Data urn (
"urn:uuid:");
445 time_hi_and_version[0] &= 0x0f;
446 time_hi_and_version[0] |= 0x40;
447 urn += time_hi_and_version.
hex();
452 clock_seq_hi_and_reserved[0] &= 0x3f;
453 clock_seq_hi_and_reserved[0] |= 0x40;
454 urn += clock_seq_hi_and_reserved.
hex();
469 int e = RAND_bytes( (
unsigned char*)buf , numBytes );
473 long err = ERR_get_error();
476 ERR_error_string_n(err,buf,
sizeof(buf));
484 memcpy(buf, temp.
data(), numBytes);
489Random::Initializer::Initializer() : mThreadStorage(::TlsAlloc())
494Random::Initializer::~Initializer()
496 ::TlsFree(mThreadStorage);
500Random::Initializer::setInitialized()
502 ::TlsSetValue(mThreadStorage, (LPVOID) TRUE);
506Random::Initializer::isInitialized()
508#pragma warning ( disable:4311)
509#pragma warning ( disable:4302)
511 return (BOOL) ::TlsGetValue(mThreadStorage) == TRUE;
#define WarningLog(args_)
#define RANDOM_STATE_SIZE
#define resip_assert(x)
This file needs to work for both C and C++ code.
Handles cross-platform sockets compatibility.
An iostream that operates on an existing Data.
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
@ Take
The Data instance takes complete ownership of the buffer.
Data base64encode(bool useUrlSafe=false) const
Performs RFC 3548 Base 64 encoding of the contents of this data.
Data hex() const
Returns a hexadecimal representation of the contents of this Data.
size_t hash() const
Creates a 32-bit hash based on the contents of this Data.
const char * data() const noexcept
Returns a pointer to the contents of this Data.
static Data getCryptoRandomBase64(unsigned int numBytes)
static int getRandom()
Returns a postive integer (31 bits) of randomness.
static Data getVersion4UuidUrn()
Returns a version 4 (random) UUID as defined in RFC 4122.
static int getCryptoRandom()
static const char * getImplName()
static Data getCryptoRandomHex(unsigned int numBytes)
static Data getRandomHex(unsigned int numBytes)
static Data getRandomBase64(unsigned int numBytes)
static unsigned getSimpleSeed()
Key goal is to make sure that each thread has distinct seed.
static uint64_t getTimeMicroSec()
Returns the current clock time in microseconds.
static void * tlsGetValue(TlsKey key)
This function follows pthread_getspecific() signature.
static int tlsKeyCreate(TlsKey &key, TlsDestructor *destructor)
This function follows pthread_key_create() signature.
static int tlsSetValue(TlsKey key, const void *val)
This function follows pthread_setspecific() signature.
static void setupTimeOffsets()
dcm! – add UnusedChecking(_enum) below;
std::mutex Mutex
A semaphore that can be locked by only one thread at a time.
std::unique_lock< Mutex > Lock
A convenience class to lock a Lockable (such as a Mutex) on object creation, and unlock on destructio...