|  | @@ -33,6 +33,7 @@
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #define CRYPTO_RAND_FAST_PRIVATE
 | 
	
		
			
				|  |  | +#define CRYPTO_PRIVATE
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #include "lib/crypt_ops/crypto_rand.h"
 | 
	
		
			
				|  |  |  #include "lib/crypt_ops/crypto_cipher.h"
 | 
	
	
		
			
				|  | @@ -41,6 +42,7 @@
 | 
	
		
			
				|  |  |  #include "lib/intmath/cmp.h"
 | 
	
		
			
				|  |  |  #include "lib/cc/ctassert.h"
 | 
	
		
			
				|  |  |  #include "lib/malloc/map_anon.h"
 | 
	
		
			
				|  |  | +#include "lib/thread/threads.h"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #include "lib/log/util_bug.h"
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -122,7 +124,8 @@ crypto_fast_rng_new(void)
 | 
	
		
			
				|  |  |   * long.
 | 
	
		
			
				|  |  |   *
 | 
	
		
			
				|  |  |   * Note that this object is NOT thread-safe.  If you need a thread-safe
 | 
	
		
			
				|  |  | - * prng, use crypto_rand(), or wrap this in a mutex.
 | 
	
		
			
				|  |  | + * prng, you should probably look at get_thread_fast_rng().  Alternatively,
 | 
	
		
			
				|  |  | + * use crypto_rand(), wrap this in a mutex.
 | 
	
		
			
				|  |  |   **/
 | 
	
		
			
				|  |  |  crypto_fast_rng_t *
 | 
	
		
			
				|  |  |  crypto_fast_rng_new_from_seed(const uint8_t *seed)
 | 
	
	
		
			
				|  | @@ -261,3 +264,65 @@ crypto_fast_rng_get_bytes_used_per_stream(void)
 | 
	
		
			
				|  |  |    return BUFLEN;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * Thread-local instance for our fast RNG.
 | 
	
		
			
				|  |  | + **/
 | 
	
		
			
				|  |  | +static tor_threadlocal_t thread_rng;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * Return a per-thread fast RNG, initializing it if necessary.
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * You do not need to free this yourself.
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * It is NOT safe to share this value across threads.
 | 
	
		
			
				|  |  | + **/
 | 
	
		
			
				|  |  | +crypto_fast_rng_t *
 | 
	
		
			
				|  |  | +get_thread_fast_rng(void)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  crypto_fast_rng_t *rng = tor_threadlocal_get(&thread_rng);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if (PREDICT_UNLIKELY(rng == NULL)) {
 | 
	
		
			
				|  |  | +    rng = crypto_fast_rng_new();
 | 
	
		
			
				|  |  | +    tor_threadlocal_set(&thread_rng, rng);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  return rng;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * Used when a thread is exiting: free the per-thread fast RNG if needed.
 | 
	
		
			
				|  |  | + * Invoked from the crypto subsystem's thread-cleanup code.
 | 
	
		
			
				|  |  | + **/
 | 
	
		
			
				|  |  | +void
 | 
	
		
			
				|  |  | +destroy_thread_fast_rng(void)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  crypto_fast_rng_t *rng = tor_threadlocal_get(&thread_rng);
 | 
	
		
			
				|  |  | +  if (!rng)
 | 
	
		
			
				|  |  | +    return;
 | 
	
		
			
				|  |  | +  crypto_fast_rng_free(rng);
 | 
	
		
			
				|  |  | +  tor_threadlocal_set(&thread_rng, NULL);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * Initialize the global thread-local key that will be used to keep track
 | 
	
		
			
				|  |  | + * of per-thread fast RNG instances.  Called from the crypto subsystem's
 | 
	
		
			
				|  |  | + * initialization code.
 | 
	
		
			
				|  |  | + **/
 | 
	
		
			
				|  |  | +void
 | 
	
		
			
				|  |  | +crypto_rand_fast_init(void)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  tor_threadlocal_init(&thread_rng);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * Initialize the global thread-local key that will be used to keep track
 | 
	
		
			
				|  |  | + * of per-thread fast RNG instances.  Called from the crypto subsystem's
 | 
	
		
			
				|  |  | + * shutdown code.
 | 
	
		
			
				|  |  | + **/
 | 
	
		
			
				|  |  | +void
 | 
	
		
			
				|  |  | +crypto_rand_fast_shutdown(void)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +  destroy_thread_fast_rng();
 | 
	
		
			
				|  |  | +  tor_threadlocal_destroy(&thread_rng);
 | 
	
		
			
				|  |  | +}
 |