2020 */
2121
2222#include <wolfengine/we_internal.h>
23+ #ifndef _WIN32
24+ #include <sys/time.h>
25+ #endif /* !_WIN32 */
2326
2427#ifdef WE_HAVE_RANDOM
2528
2629#ifdef WE_STATIC_WOLFSSL
2730extern int wc_RNG_DRBG_Reseed (WC_RNG * rng , const byte * seed , word32 seedSz );
28- #if OPENSSL_VERSION_NUMBER < 0x10100000L
29- extern int wc_GenerateSeed (OS_Seed * os , byte * seed , int sz );
30- #endif
3131#else
3232/* Hash of all the seed so far. */
3333unsigned char we_seed [WC_SHA256_DIGEST_SIZE ] = {0 ,};
@@ -45,7 +45,7 @@ int haveSeed = 0;
4545 * @param num [in] Number of random bytes.
4646 * @param seed [in] Buffer holding seed data.
4747 * @param seedLen [in] Number of seed bytes.
48- * @returns 1 when successful and 0 on fauilure .
48+ * @returns 1 when successful and 0 on failure .
4949 */
5050static int we_rand_mix_seed (unsigned char * buf , int num ,
5151 const unsigned char * seed , int seedLen )
@@ -203,72 +203,6 @@ static int we_rand_seed(const void *buf, int num)
203203#endif
204204}
205205
206- /* Note: from OpensSL 1.1.0 onwards RAND_bytes no longer gets true entropy.
207- * There are public and private randoms that are each seeded from entropy.
208- * No way to tell when RAND_priv_rand() is called with methods.
209- * Use pseudo-bytes implementation when RAND_bytes(), RAND_priv_bytes() and
210- * RAND_pseudo_bytes() are called.
211- */
212- #if OPENSSL_VERSION_NUMBER < 0x10100000L
213- /**
214- * Generate true random.
215- *
216- * @param buf [out] Buffer to hold random.
217- * @param num [in] Number of bytes to generate.
218- * @returns 1 when data generated and 0 on failure.
219- */
220- static int we_rand_bytes (unsigned char * buf , int num )
221- {
222- int ret = 1 ;
223- int rc ;
224- #ifdef WE_STATIC_WOLFSSL
225- OS_Seed os ;
226- #else
227- WC_RNG rng ;
228- #endif
229-
230- WOLFENGINE_ENTER (WE_LOG_RNG , "we_rand_bytes" );
231- WOLFENGINE_MSG_VERBOSE (WE_LOG_RNG , "ARGS [buf = %p, num = %d]" , buf , num );
232-
233- #ifdef WE_STATIC_WOLFSSL
234- /* Generate true random using internal API. */
235- rc = wc_GenerateSeed (& os , buf , num );
236- if (rc != 0 ) {
237- WOLFENGINE_ERROR_FUNC (WE_LOG_RNG , "wc_GenerateSeed" , rc );
238- ret = 0 ;
239- }
240-
241- #else
242- /* Create a new random number generator that is seeded with true random. */
243- rc = wc_InitRng (& rng );
244- if (rc != 0 ) {
245- WOLFENGINE_ERROR_FUNC (WE_LOG_RNG , "wc_InitRng" , rc );
246- ret = 0 ;
247- }
248- else {
249- /* Generate true random. */
250- rc = wc_RNG_GenerateBlock (& rng , buf , num );
251- if (rc != 0 ) {
252- WOLFENGINE_ERROR_FUNC (WE_LOG_RNG , "wc_RNG_GenerateBlock" , rc );
253- ret = 0 ;
254- }
255-
256- /* Dispose of random number generator. */
257- rc = wc_FreeRng (& rng );
258- if (rc != 0 ) {
259- WOLFENGINE_ERROR_FUNC (WE_LOG_RNG , "wc_FreeRng" , rc );
260- ret = 0 ;
261- }
262- }
263-
264- #endif
265-
266- WOLFENGINE_LEAVE (WE_LOG_RNG , "we_rand_bytes" , ret );
267-
268- return ret ;
269- }
270- #endif
271-
272206static void we_rand_cleanup (void )
273207{
274208 /* Global random cleanup done in internal.c: we_final_random(). */
@@ -312,19 +246,115 @@ static int we_rand_add(const void *buf, int num, double entropy)
312246#endif
313247}
314248
249+ #ifndef WE_STATIC_WOLFSSL
250+ /**
251+ * Add weak entropy to the input buffer. Used by we_rand_bytes to add entropy
252+ * for RNG. Uses thread ID, a timer value, and PID.
253+ *
254+ * @param buf [in] Input buffer to mix with generated entropy.
255+ * @param num [in] Length of input buffer.
256+ * @returns 1 on success, 0 on failure.
257+ */
258+ static int we_rand_add_weak_entropy (unsigned char * buf , int num )
259+ {
260+ int ret = 1 ;
261+ unsigned char * idx ;
262+ #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
263+ CRYPTO_THREAD_ID threadId ;
264+ #else
265+ CRYPTO_THREADID threadId ;
266+ unsigned long threadIdHash ;
267+ #endif /* OPENSSL_VERSION_NUMBER >= 0x1010000fL */
268+ #ifndef _WIN32
269+ struct timeval tv ;
270+ unsigned long timer ;
271+ pid_t pid ;
272+ #else
273+ LARGE_INTEGER timer ;
274+ DWORD pid ;
275+ #endif /* !_WIN32 */
276+
277+ #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
278+ threadId = CRYPTO_THREAD_get_current_id ();
279+ unsigned char addEntropy [sizeof (threadId ) + sizeof (timer ) + sizeof (pid )];
280+ #else
281+ CRYPTO_THREADID_current (& threadId );
282+ threadIdHash = CRYPTO_THREADID_hash (& threadId );
283+ unsigned char addEntropy [sizeof (threadIdHash ) + sizeof (timer ) +
284+ sizeof (pid )];
285+ #endif /* OPENSSL_VERSION_NUMBER >= 0x1010000fL */
286+ const size_t addEntropySz = sizeof (addEntropy );
287+
288+ WOLFENGINE_ENTER (WE_LOG_RNG , "we_rand_add_weak_entropy" );
289+ WOLFENGINE_MSG_VERBOSE (WE_LOG_RNG , "ARGS [buf = %p, num = %d]" , buf , num );
290+
291+ if (buf == NULL || num <= 0 ) {
292+ WOLFENGINE_ERROR_MSG (WE_LOG_RNG , "Bad argument." );
293+ ret = 0 ;
294+ }
295+
296+ if (ret == 1 ) {
297+ #ifndef _WIN32
298+ if (gettimeofday (& tv , NULL ) != 0 ) {
299+ WOLFENGINE_ERROR_MSG (WE_LOG_RNG , "gettimeofday for additional "
300+ "entropy failed" );
301+ ret = 0 ;
302+ }
303+ else {
304+ timer = 1000000 * tv .tv_sec + tv .tv_usec ; /* time in us */
305+ pid = getpid ();
306+ }
307+ #else
308+ ret = QueryPerformanceCounter (& timer );
309+ if (ret == 0 ) {
310+ WOLFENGINE_ERROR_MSG (WE_LOG_RNG , "QueryPerformanceCounter for "
311+ "additional entropy failed" );
312+ }
313+ else {
314+ pid = GetCurrentProcessId ();
315+ }
316+ #endif /* !_WIN32 */
317+ }
318+
319+ if (ret == 1 ) {
320+ idx = addEntropy ;
321+ #if OPENSSL_VERSION_NUMBER >= 0x1010000fL
322+ XMEMCPY (idx , (unsigned char * )& threadId , sizeof (threadId ));
323+ idx += sizeof (threadId );
324+ #else
325+ XMEMCPY (idx , (unsigned char * )& threadIdHash , sizeof (threadIdHash ));
326+ idx += sizeof (threadIdHash );
327+ #endif /* OPENSSL_VERSION_NUMBER >= 0x1010000fL */
328+ XMEMCPY (idx , (unsigned char * )& timer , sizeof (timer ));
329+ idx += sizeof (timer );
330+ XMEMCPY (idx , (unsigned char * )& pid , sizeof (pid ));
331+
332+ ret = we_rand_mix_seed (buf , num , addEntropy , addEntropySz );
333+ if (ret != 1 ) {
334+ WOLFENGINE_ERROR_MSG (WE_LOG_RNG , "we_rand_mix_seed with weak "
335+ "entropy failed" );
336+ }
337+ }
338+
339+ WOLFENGINE_LEAVE (WE_LOG_RNG , "we_rand_add_weak_entropy" , ret );
340+
341+ return ret ;
342+ }
343+ #endif /* WE_STATIC_WOLFSSL */
344+
315345/**
316346 * Generate pseudo-random data.
317347 *
318348 * @param buf [out] Buffer to fill with random.
319349 * @param num [in] Number of bytes to generate.
320350 * @returns 1 when data generated and 0 on failure.
321351 */
322- static int we_rand_pseudorand (unsigned char * buf , int num )
352+ static int we_rand_bytes (unsigned char * buf , int num )
323353{
324354 int ret = 1 ;
325355 int rc ;
326356
327- WOLFENGINE_ENTER (WE_LOG_RNG , "we_rand_pseudorand " );
357+ WOLFENGINE_ENTER (WE_LOG_RNG , "we_rand_bytes " );
328358 WOLFENGINE_MSG_VERBOSE (WE_LOG_RNG , "ARGS [buf = %p, num = %d]" ,
329359 buf , num );
330360
@@ -346,14 +376,27 @@ static int we_rand_pseudorand(unsigned char *buf, int num)
346376 /* Mix global seed if RAND_add() or RAND_seed() has been called. */
347377 if (haveSeed ) {
348378 ret = we_rand_mix_seed (buf , num , we_seed , sizeof (we_seed ));
379+ if (ret != 1 ) {
380+ WOLFENGINE_ERROR_MSG (WE_LOG_RNG , "we_rand_mix_seed with global "
381+ "seed failed" );
382+ }
349383 }
350- #endif
384+ /* Mix in weak entropy. */
385+ if (ret == 1 ) {
386+ ret = we_rand_add_weak_entropy (buf , num );
387+ if (ret != 1 ) {
388+ WOLFENGINE_ERROR_MSG (WE_LOG_RNG , "we_rand_mix_seed with "
389+ "weak entropy failed" );
390+ }
391+ }
392+ #endif /* !WE_STATIC_WOLFSSL */
393+
351394 #ifndef WE_SINGLE_THREADED
352395 wc_UnLockMutex (we_rng_mutex );
353396 #endif
354397 }
355398
356- WOLFENGINE_LEAVE (WE_LOG_RNG , "we_rand_pseudorand " , ret );
399+ WOLFENGINE_LEAVE (WE_LOG_RNG , "we_rand_bytes " , ret );
357400
358401 return ret ;
359402}
@@ -377,15 +420,10 @@ static int we_rand_status(void)
377420 */
378421RAND_METHOD we_rand_method = {
379422 we_rand_seed ,
380- #if OPENSSL_VERSION_NUMBER < 0x10100000L
381423 we_rand_bytes ,
382- #else
383- /* See note above we_rand_bytes. */
384- we_rand_pseudorand ,
385- #endif
386424 we_rand_cleanup ,
387425 we_rand_add ,
388- we_rand_pseudorand ,
426+ we_rand_bytes ,
389427 we_rand_status ,
390428};
391429
0 commit comments