random_seed: on error, continue to next method

instead of exiting the process
This commit is contained in:
Pierce Lopez
2020-10-07 01:22:30 -04:00
parent df27756491
commit 0fd3b7d316

View File

@@ -162,15 +162,14 @@ retry:
#include <sys/random.h> #include <sys/random.h>
#endif #endif
static int get_getrandom_seed(void) static int get_getrandom_seed(int *seed)
{ {
DEBUG_SEED("get_getrandom_seed"); DEBUG_SEED("get_getrandom_seed");
int r;
ssize_t ret; ssize_t ret;
do { do {
ret = getrandom(&r, sizeof(r), GRND_NONBLOCK); ret = getrandom(seed, sizeof(*seed), GRND_NONBLOCK);
} while ((ret == -1) && (errno == EINTR)); } while ((ret == -1) && (errno == EINTR));
if (ret == -1) if (ret == -1)
@@ -181,17 +180,17 @@ static int get_getrandom_seed(void)
return -1; return -1;
fprintf(stderr, "error from getrandom(): %s", strerror(errno)); fprintf(stderr, "error from getrandom(): %s", strerror(errno));
exit(1); return -1;
} }
if (ret != sizeof(r)) if (ret != sizeof(*seed))
return -1; return -1;
return r; return 0;
} }
#endif /* defined HAVE_GETRANDOM */ #endif /* defined HAVE_GETRANDOM */
/* has_dev_urandom */ /* get_dev_random_seed */
#if defined(__APPLE__) || defined(__unix__) || defined(__linux__) #if defined(__APPLE__) || defined(__unix__) || defined(__linux__)
@@ -207,39 +206,32 @@ static int get_getrandom_seed(void)
static const char *dev_random_file = "/dev/urandom"; static const char *dev_random_file = "/dev/urandom";
static int has_dev_urandom(void) static int get_dev_random_seed(int *seed)
{
struct stat buf;
if (stat(dev_random_file, &buf))
{
return 0;
}
return ((buf.st_mode & S_IFCHR) != 0);
}
/* get_dev_random_seed */
static int get_dev_random_seed(void)
{ {
DEBUG_SEED("get_dev_random_seed"); DEBUG_SEED("get_dev_random_seed");
struct stat buf;
if (stat(dev_random_file, &buf))
return -1;
if ((buf.st_mode & S_IFCHR) == 0)
return -1;
int fd = open(dev_random_file, O_RDONLY); int fd = open(dev_random_file, O_RDONLY);
if (fd < 0) if (fd < 0)
{ {
fprintf(stderr, "error opening %s: %s", dev_random_file, strerror(errno)); fprintf(stderr, "error opening %s: %s", dev_random_file, strerror(errno));
exit(1); return -1;
} }
int r; ssize_t nread = read(fd, seed, sizeof(*seed));
ssize_t nread = read(fd, &r, sizeof(r)); if (nread != sizeof(*seed))
if (nread != sizeof(r))
{ {
fprintf(stderr, "error short read %s: %s", dev_random_file, strerror(errno)); fprintf(stderr, "error short read %s: %s", dev_random_file, strerror(errno));
exit(1); return -1;
} }
close(fd); close(fd);
return r; return 0;
} }
#endif #endif
@@ -262,9 +254,7 @@ static int get_dev_random_seed(void)
#pragma comment(lib, "advapi32.lib") #pragma comment(lib, "advapi32.lib")
#endif #endif
static int get_time_seed(void); static int get_cryptgenrandom_seed(int *seed)
static int get_cryptgenrandom_seed(void)
{ {
HCRYPTPROV hProvider = 0; HCRYPTPROV hProvider = 0;
DWORD dwFlags = CRYPT_VERIFYCONTEXT; DWORD dwFlags = CRYPT_VERIFYCONTEXT;
@@ -279,20 +269,20 @@ static int get_cryptgenrandom_seed(void)
if (!CryptAcquireContextA(&hProvider, 0, 0, PROV_RSA_FULL, dwFlags)) if (!CryptAcquireContextA(&hProvider, 0, 0, PROV_RSA_FULL, dwFlags))
{ {
fprintf(stderr, "error CryptAcquireContextA 0x%08lx", GetLastError()); fprintf(stderr, "error CryptAcquireContextA 0x%08lx", GetLastError());
r = get_time_seed(); return -1;
} }
else else
{ {
BOOL ret = CryptGenRandom(hProvider, sizeof(r), (BYTE*)&r); BOOL ret = CryptGenRandom(hProvider, sizeof(*seed), (BYTE*)seed);
CryptReleaseContext(hProvider, 0); CryptReleaseContext(hProvider, 0);
if (!ret) if (!ret)
{ {
fprintf(stderr, "error CryptGenRandom 0x%08lx", GetLastError()); fprintf(stderr, "error CryptGenRandom 0x%08lx", GetLastError());
r = get_time_seed(); return -1;
} }
} }
return r; return 0;
} }
#endif #endif
@@ -312,6 +302,7 @@ static int get_time_seed(void)
int json_c_get_random_seed(void) int json_c_get_random_seed(void)
{ {
int seed;
#ifdef OVERRIDE_GET_RANDOM_SEED #ifdef OVERRIDE_GET_RANDOM_SEED
OVERRIDE_GET_RANDOM_SEED; OVERRIDE_GET_RANDOM_SEED;
#endif #endif
@@ -320,18 +311,16 @@ int json_c_get_random_seed(void)
return get_rdrand_seed(); return get_rdrand_seed();
#endif #endif
#ifdef HAVE_GETRANDOM #ifdef HAVE_GETRANDOM
{ if (get_getrandom_seed(&seed) == 0)
int seed = get_getrandom_seed(); return seed;
if (seed != -1)
return seed;
}
#endif #endif
#if defined HAVE_DEV_RANDOM && HAVE_DEV_RANDOM #if defined HAVE_DEV_RANDOM && HAVE_DEV_RANDOM
if (has_dev_urandom()) if (get_dev_random_seed(&seed) == 0)
return get_dev_random_seed(); return seed;
#endif #endif
#if defined HAVE_CRYPTGENRANDOM && HAVE_CRYPTGENRANDOM #if defined HAVE_CRYPTGENRANDOM && HAVE_CRYPTGENRANDOM
return get_cryptgenrandom_seed(); if (get_cryptgenrandom_seed(&seed) == 0)
return seed;
#endif #endif
return get_time_seed(); return get_time_seed();
} }