1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
|
/*
* Copyright (C) 2014- The University of Notre Dame
* This software is distributed under the GNU General Public License.
* See the file COPYING for details.
*/
#include "full_io.h"
#include "random.h"
#include "twister.h"
#include "debug.h"
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
void random_init (void)
{
static int random_initialized = 0;
if (random_initialized) return;
int fd = open("/dev/urandom", O_RDONLY);
if (fd == -1) {
fd = open("/dev/random", O_RDONLY);
}
if (fd >= 0) {
uint64_t seed[8];
if (full_read(fd, seed, sizeof(seed)) < (int64_t)sizeof(seed))
goto nasty_fallback;
srand(seed[0]);
twister_init_by_array64(seed, sizeof(seed)/sizeof(seed[0]));
} else {
uint64_t seed;
nasty_fallback:
debug(D_NOTICE, "warning: falling back to low-quality entropy");
seed = (uint64_t)getpid() ^ (uint64_t)time(NULL);
seed |= (((uint64_t)(uintptr_t)&seed) << 32); /* using ASLR */
srand(seed);
twister_init_genrand64(seed);
}
close(fd);
random_initialized = 1;
return;
}
int64_t random_int64 (void)
{
return twister_genrand64_int64();
}
double random_double (void)
{
return twister_genrand64_real3();
}
void random_array (void *dest, size_t len)
{
size_t i;
uint8_t *out = dest;
for (i = 0; i < len; i += sizeof(int64_t)) {
int64_t r = twister_genrand64_int64();
size_t count = len > sizeof(int64_t) ? sizeof(int64_t) : len;
memcpy(out+i, &r, count);
}
}
void random_hex (char *str, size_t len)
{
int64_t r;
size_t i = 0;
do {
r = twister_genrand64_int64();
snprintf(str+i, len-i, "%016" PRIx64, r);
i += sizeof(r)*2;
} while (i < len);
}
/* vim: set noexpandtab tabstop=4: */
|