/* Full initialization of this module. */ static void initialize(void) { /* Although the basic initialization should have happened already, we call it here to make sure that all prerequisites are met. */ initialize_basics (); /* Now we can look the pool and complete the initialization if necessary. */ lock_pool (); if (!rndpool) { /* The data buffer is allocated somewhat larger, so that we can use this extra space (which is allocated in secure memory) as a temporary hash buffer */ rndpool = (secure_alloc ? xcalloc_secure (1, POOLSIZE + BLOCKLEN) : xcalloc (1, POOLSIZE + BLOCKLEN)); keypool = (secure_alloc ? xcalloc_secure (1, POOLSIZE + BLOCKLEN) : xcalloc (1, POOLSIZE + BLOCKLEN)); /* Setup the slow entropy gathering function. The code requires that this function exists. */ slow_gather_fnc = getfnc_gather_random (); /* Setup the fast entropy gathering function. */ fast_gather_fnc = getfnc_fast_random_poll (); } unlock_pool (); }
static void do_fast_random_poll (void) { static void (*fnc)( void (*)(const void*, size_t, int), int) = NULL; static int initialized = 0; assert (pool_is_locked); rndstats.fastpolls++; if (!initialized ) { if (!is_initialized ) initialize(); initialized = 1; fnc = getfnc_fast_random_poll (); } if (fnc) (*fnc)( add_randomness, 1 ); /* Continue with the generic functions. */ #if HAVE_GETHRTIME { hrtime_t tv; tv = gethrtime(); add_randomness( &tv, sizeof(tv), 1 ); } #elif HAVE_GETTIMEOFDAY { struct timeval tv; if( gettimeofday( &tv, NULL ) ) BUG(); add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 ); add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), 1 ); } #elif HAVE_CLOCK_GETTIME { struct timespec tv; if( clock_gettime( CLOCK_REALTIME, &tv ) == -1 ) BUG(); add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 ); add_randomness( &tv.tv_nsec, sizeof(tv.tv_nsec), 1 ); } #else /* use times */ # ifndef HAVE_DOSISH_SYSTEM { struct tms buf; times( &buf ); add_randomness( &buf, sizeof buf, 1 ); } # endif #endif #ifdef HAVE_GETRUSAGE # ifdef RUSAGE_SELF { struct rusage buf; /* QNX/Neutrino does return ENOSYS - so we just ignore it and * add whatever is in buf. In a chroot environment it might not * work at all (i.e. because /proc/ is not accessible), so we better * ugnore all error codes and hope for the best */ getrusage (RUSAGE_SELF, &buf ); add_randomness( &buf, sizeof buf, 1 ); memset( &buf, 0, sizeof buf ); } # else /*!RUSAGE_SELF*/ # ifdef __GCC__ # warning There is no RUSAGE_SELF on this system # endif # endif /*!RUSAGE_SELF*/ #endif /*HAVE_GETRUSAGE*/ /* time and clock are availabe on all systems - so we better do it just in case one of the above functions didn't work */ { time_t x = time(NULL); add_randomness( &x, sizeof(x), 1 ); } { clock_t x = clock(); add_randomness( &x, sizeof(x), 1 ); } }
void fast_random_poll() { static void (*fnc)( void (*)(const void*, size_t, int), int) = NULL; static int initialized = 0; rndstats.fastpolls++; if( !initialized ) { if( !is_initialized ) initialize(); initialized = 1; fnc = getfnc_fast_random_poll(); } if( fnc ) { (*fnc)( add_randomness, 1 ); return; } /* fall back to the generic function */ #if defined(HAVE_GETHRTIME) && !defined(HAVE_BROKEN_GETHRTIME) { hrtime_t tv; /* On some Solaris and HPUX system gethrtime raises an SIGILL, but we * checked this with configure */ tv = gethrtime(); add_randomness( &tv, sizeof(tv), 1 ); } #elif defined (HAVE_GETTIMEOFDAY) { struct timeval tv; if( gettimeofday( &tv, NULL ) ) BUG(); add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 ); add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), 1 ); } #elif defined (HAVE_CLOCK_GETTIME) { struct timespec tv; if( clock_gettime( CLOCK_REALTIME, &tv ) == -1 ) BUG(); add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 ); add_randomness( &tv.tv_nsec, sizeof(tv.tv_nsec), 1 ); } #else /* use times */ #ifndef HAVE_DOSISH_SYSTEM { struct tms buf; times( &buf ); add_randomness( &buf, sizeof buf, 1 ); } #endif #endif #ifdef HAVE_GETRUSAGE #ifndef RUSAGE_SELF #ifdef __GCC__ #warning There is no RUSAGE_SELF on this system #endif #else { struct rusage buf; /* QNX/Neutrino does return ENOSYS - so we just ignore it and * add whatever is in buf. In a chroot environment it might not * work at all (i.e. because /proc/ is not accessible), so we better * ignore all error codes and hope for the best */ getrusage( RUSAGE_SELF, &buf ); add_randomness( &buf, sizeof buf, 1 ); memset( &buf, 0, sizeof buf ); } #endif #endif /* time and clock are available on all systems - so * we better do it just in case one of the above functions * didn't work */ { time_t x = time(NULL); add_randomness( &x, sizeof(x), 1 ); } { clock_t x = clock(); add_randomness( &x, sizeof(x), 1 ); } }