mirror of
https://github.com/ntop/n2n.git
synced 2024-09-20 00:51:10 +02:00
Merge pull request #331 from Logan007/rndSeedLoop
retrying syscall and calls to hardware random number generators
This commit is contained in:
commit
f02a5c91c6
|
@ -16,8 +16,16 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifdef SYS_getrandom
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "n2n.h"
|
||||
|
||||
// syscall and inquiring random number from hardware generators might fail, so we will retry
|
||||
#define RND_RETRIES 1000
|
||||
|
||||
|
||||
/* The following code offers an alterate pseudo random number generator
|
||||
namely XORSHIFT128+ to use instead of C's rand(). Its performance is
|
||||
on par with C's rand().
|
||||
|
@ -93,24 +101,62 @@ uint64_t n2n_rand () {
|
|||
state yet, a call to n2n_srand ( n2n_seed() ) would do. */
|
||||
uint64_t n2n_seed (void) {
|
||||
|
||||
uint64_t seed = 0;
|
||||
uint64_t ret = 0;
|
||||
uint64_t seed;
|
||||
uint64_t ret;
|
||||
size_t i;
|
||||
|
||||
#ifdef SYS_getrandom
|
||||
syscall (SYS_getrandom, &seed, sizeof(seed), GRND_NONBLOCK);
|
||||
ret += seed;
|
||||
int rc = -1;
|
||||
for(i = 0; (i < RND_RETRIES) && (rc != sizeof(seed)); i++) {
|
||||
rc = syscall (SYS_getrandom, &seed, sizeof(seed), GRND_NONBLOCK);
|
||||
// if successful, rc should contain the requested number of random bytes
|
||||
if(rc != sizeof(seed)) {
|
||||
if (errno != EAGAIN) {
|
||||
traceEvent(TRACE_ERROR, "n2n_seed faced error errno=%u from getrandom syscall.", errno);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if we still see an EAGAIN error here, we must have run out of retries
|
||||
if(errno == EAGAIN) {
|
||||
traceEvent(TRACE_ERROR, "n2n_seed saw getrandom syscall indicate not being able to provide enough entropy yet.");
|
||||
}
|
||||
#endif
|
||||
|
||||
// as we want randomness, it does no harm to add up even uninitialized values or
|
||||
// erroneously arbitrary values returned from the syscall for the first time
|
||||
ret += seed;
|
||||
|
||||
// __RDRND__ is set only if architecturual feature is set, e.g. compile with -march=native
|
||||
#ifdef __RDRND__
|
||||
_rdrand64_step ((unsigned long long*)&seed);
|
||||
ret += seed;
|
||||
for(i = 0; i < RND_RETRIES; i++) {
|
||||
if(_rdrand64_step ((unsigned long long*)&seed)) {
|
||||
// success!
|
||||
// from now on, we keep this inside the loop because in case of failure
|
||||
// and with unchanged values, we do not want to double the previous value
|
||||
ret += seed;
|
||||
break;
|
||||
}
|
||||
// continue loop to try again otherwise
|
||||
}
|
||||
if(i == RND_RETRIES){
|
||||
traceEvent(TRACE_ERROR, "n2n_seed was not able to get a hardware generated random number from RDRND.");
|
||||
}
|
||||
#endif
|
||||
|
||||
// __RDSEED__ ist set only if architecturual feature is set, e.g. compile with -march=native
|
||||
#ifdef __RDSEED__
|
||||
_rdseed64_step((unsigned long long*)&seed);
|
||||
ret += seed;
|
||||
for(i = 0; i < RND_RETRIES; i++) {
|
||||
if(_rdseed64_step((unsigned long long*)&seed)) {
|
||||
// success!
|
||||
ret += seed;
|
||||
break;
|
||||
}
|
||||
// continue loop to try again otherwise
|
||||
}
|
||||
if(i == RND_RETRIES){
|
||||
traceEvent(TRACE_ERROR, "n2n_seed was not able to get a hardware generated random number from RDSEED.");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The WIN32 code is still untested and thus commented
|
||||
|
@ -126,7 +172,7 @@ uint64_t n2n_seed (void) {
|
|||
seed = time(NULL); /* UTC in seconds */
|
||||
ret += seed;
|
||||
|
||||
seed = clock() * 8996146197; /* clock() = ticks since program start */
|
||||
seed = clock() * 18444244737; /* clock() = ticks since program start */
|
||||
ret += seed;
|
||||
|
||||
return ret;
|
||||
|
|
Loading…
Reference in New Issue
Block a user