Don't use assert for catching randomness failures

This commit is contained in:
Pieter Wuille 2016-04-23 18:07:35 +02:00
parent fa2637a3be
commit 628cf1440a

View file

@ -15,6 +15,7 @@
#include "util.h" // for LogPrint() #include "util.h" // for LogPrint()
#include "utilstrencodings.h" // for GetTime() #include "utilstrencodings.h" // for GetTime()
#include <stdlib.h>
#include <limits> #include <limits>
#ifndef WIN32 #ifndef WIN32
@ -24,6 +25,12 @@
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/rand.h> #include <openssl/rand.h>
static void RandFailure()
{
LogPrintf("Failed to read randomness, aborting\n");
abort();
}
static inline int64_t GetPerformanceCounter() static inline int64_t GetPerformanceCounter()
{ {
int64_t nCounter = 0; int64_t nCounter = 0;
@ -91,17 +98,25 @@ static void GetOSRand(unsigned char *ent32)
#ifdef WIN32 #ifdef WIN32
HCRYPTPROV hProvider; HCRYPTPROV hProvider;
int ret = CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); int ret = CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
assert(ret); if (!ret) {
RandFailure();
}
ret = CryptGenRandom(hProvider, 32, ent32); ret = CryptGenRandom(hProvider, 32, ent32);
assert(ret); if (!ret) {
RandFailure();
}
CryptReleaseContext(hProvider, 0); CryptReleaseContext(hProvider, 0);
#else #else
int f = open("/dev/urandom", O_RDONLY); int f = open("/dev/urandom", O_RDONLY);
assert(f != -1); if (f == -1) {
RandFailure();
}
int have = 0; int have = 0;
do { do {
ssize_t n = read(f, ent32 + have, 32 - have); ssize_t n = read(f, ent32 + have, 32 - have);
assert(n > 0 && n <= 32 - have); if (n <= 0 || n + have > 32) {
RandFailure();
}
have += n; have += n;
} while (have < 32); } while (have < 32);
close(f); close(f);
@ -111,8 +126,7 @@ static void GetOSRand(unsigned char *ent32)
void GetRandBytes(unsigned char* buf, int num) void GetRandBytes(unsigned char* buf, int num)
{ {
if (RAND_bytes(buf, num) != 1) { if (RAND_bytes(buf, num) != 1) {
LogPrintf("%s: OpenSSL RAND_bytes() failed with error: %s\n", __func__, ERR_error_string(ERR_get_error(), NULL)); RandFailure();
assert(false);
} }
} }