sanity: Move OS random to sanity check function

Move the OS random test to a sanity check function that is called every
time bitcoind is initialized.

Keep `src/test/random_tests.cpp` for the case that later random tests
are added, and keep a rudimentary test that just calls the sanity check.
This commit is contained in:
Wladimir J. van der Laan 2017-02-22 08:02:50 +01:00
parent aa09ccbb74
commit 7cad849299
4 changed files with 42 additions and 28 deletions

View File

@ -687,9 +687,15 @@ bool InitSanityCheck(void)
InitError("Elliptic curve cryptography sanity check failure. Aborting."); InitError("Elliptic curve cryptography sanity check failure. Aborting.");
return false; return false;
} }
if (!glibc_sanity_test() || !glibcxx_sanity_test()) if (!glibc_sanity_test() || !glibcxx_sanity_test())
return false; return false;
if (!Random_SanityCheck()) {
InitError("OS cryptographic RNG sanity check failure. Aborting.");
return false;
}
return true; return true;
} }

View File

@ -239,3 +239,33 @@ FastRandomContext::FastRandomContext(bool fDeterministic)
} }
} }
bool Random_SanityCheck()
{
/* This does not measure the quality of randomness, but it does test that
* OSRandom() overwrites all 32 bytes of the output given a maximum
* number of tries.
*/
static const ssize_t MAX_TRIES = 1024;
uint8_t data[NUM_OS_RANDOM_BYTES];
bool overwritten[NUM_OS_RANDOM_BYTES] = {}; /* Tracks which bytes have been overwritten at least once */
int num_overwritten;
int tries = 0;
/* Loop until all bytes have been overwritten at least once, or max number tries reached */
do {
memset(data, 0, NUM_OS_RANDOM_BYTES);
GetOSRand(data);
for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
overwritten[x] |= (data[x] != 0);
}
num_overwritten = 0;
for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
if (overwritten[x]) {
num_overwritten += 1;
}
}
tries += 1;
} while (num_overwritten < NUM_OS_RANDOM_BYTES && tries < MAX_TRIES);
return (num_overwritten == NUM_OS_RANDOM_BYTES); /* If this failed, bailed out after too many tries */
}

View File

@ -58,4 +58,9 @@ static const ssize_t NUM_OS_RANDOM_BYTES = 32;
*/ */
void GetOSRand(unsigned char *ent32); void GetOSRand(unsigned char *ent32);
/** Check that OS randomness is available and returning the requested number
* of bytes.
*/
bool Random_SanityCheck();
#endif // BITCOIN_RANDOM_H #endif // BITCOIN_RANDOM_H

View File

@ -10,36 +10,9 @@
BOOST_FIXTURE_TEST_SUITE(random_tests, BasicTestingSetup) BOOST_FIXTURE_TEST_SUITE(random_tests, BasicTestingSetup)
static const ssize_t MAX_TRIES = 1024;
BOOST_AUTO_TEST_CASE(osrandom_tests) BOOST_AUTO_TEST_CASE(osrandom_tests)
{ {
/* This does not measure the quality of randomness, but it does test that BOOST_CHECK(Random_SanityCheck());
* OSRandom() overwrites all 32 bytes of the output given a maximum
* number of tries.
*/
uint8_t data[NUM_OS_RANDOM_BYTES];
bool overwritten[NUM_OS_RANDOM_BYTES] = {}; /* Tracks which bytes have been overwritten at least once */
int num_overwritten;
int tries = 0;
/* Loop until all bytes have been overwritten at least once */
do {
memset(data, 0, NUM_OS_RANDOM_BYTES);
GetOSRand(data);
for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
overwritten[x] |= (data[x] != 0);
}
num_overwritten = 0;
for (int x=0; x < NUM_OS_RANDOM_BYTES; ++x) {
if (overwritten[x]) {
num_overwritten += 1;
}
}
tries += 1;
} while (num_overwritten < NUM_OS_RANDOM_BYTES && tries < MAX_TRIES);
BOOST_CHECK(num_overwritten == NUM_OS_RANDOM_BYTES); /* If this failed, bailed out after too many tries */
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()