forked from lthn/blockchain
Merge branch 'random_refactoring' into develop
This commit is contained in:
commit
c36355d489
2 changed files with 69 additions and 33 deletions
|
|
@ -115,13 +115,17 @@ else()
|
|||
set_source_files_properties("crypto/chacha8_stream.c" PROPERTIES COMPILE_FLAGS "-Wno-sign-compare -Wno-strict-prototypes")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(BCRYPT_LIB bcrypt)
|
||||
endif()
|
||||
|
||||
add_library(crypto ${CRYPTO})
|
||||
if(USE_BITCOIN_SECP256K1_FOR_ECDSA)
|
||||
add_dependencies(crypto secp256k1)
|
||||
target_link_libraries(crypto secp256k1)
|
||||
target_link_libraries(crypto secp256k1 ${BCRYPT_LIB})
|
||||
else()
|
||||
add_dependencies(crypto OpenSSL::Crypto)
|
||||
target_link_libraries(crypto OpenSSL::Crypto)
|
||||
target_link_libraries(crypto OpenSSL::Crypto ${BCRYPT_LIB})
|
||||
endif()
|
||||
|
||||
add_library(currency_core ${CURRENCY_CORE})
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "hash-ops.h"
|
||||
#include "random.h"
|
||||
|
|
@ -15,19 +17,29 @@ static_assert(RANDOM_STATE_SIZE >= HASH_DATA_AREA, "Invalid RANDOM_STATE_SIZE");
|
|||
#if defined(_WIN32)
|
||||
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
#include <bcrypt.h>
|
||||
|
||||
void generate_system_random_bytes_no_lock(size_t n, void *result) {
|
||||
HCRYPTPROV prov;
|
||||
#define must_succeed(x) do if (!(x)) assert(0); while (0)
|
||||
if(!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
|
||||
// thread-safe version
|
||||
bool generate_system_random_bytes(size_t n, void *result)
|
||||
{
|
||||
if (n == 0)
|
||||
return true;
|
||||
|
||||
if (result == NULL)
|
||||
return false;
|
||||
|
||||
NTSTATUS status = BCryptGenRandom(NULL, (PUCHAR)result, (ULONG)n, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
|
||||
return BCRYPT_SUCCESS(status);
|
||||
}
|
||||
|
||||
void generate_system_random_bytes_or_die(size_t n, void *result)
|
||||
{
|
||||
if (!generate_system_random_bytes(n, result))
|
||||
{
|
||||
int err = GetLastError();
|
||||
assert(0);
|
||||
fprintf(stderr, "Error: generate_system_random_bytes failed and this is fatal\n\n");
|
||||
fflush(stderr);
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
must_succeed(CryptGenRandom(prov, (DWORD)n, result));
|
||||
must_succeed(CryptReleaseContext(prov, 0));
|
||||
#undef must_succeed
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
@ -40,28 +52,49 @@ void generate_system_random_bytes_no_lock(size_t n, void *result) {
|
|||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void generate_system_random_bytes_no_lock(size_t n, void *result) {
|
||||
bool generate_system_random_bytes(size_t n, void *result)
|
||||
{
|
||||
int fd;
|
||||
if ((fd = open("/dev/urandom", O_RDONLY | O_NOCTTY | O_CLOEXEC)) < 0) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (;;) {
|
||||
ssize_t res = read(fd, result, n);
|
||||
if ((size_t) res == n) {
|
||||
break;
|
||||
}
|
||||
if (res < 0) {
|
||||
if (errno != EINTR) {
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return false;
|
||||
|
||||
size_t bytes_read = 0;
|
||||
while (bytes_read < n)
|
||||
{
|
||||
ssize_t res = read(fd, (char*)result + bytes_read, n - bytes_read);
|
||||
if (res < 0)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
{
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
} else if (res == 0) {
|
||||
exit(EXIT_FAILURE);
|
||||
} else {
|
||||
result = padd(result, (size_t) res);
|
||||
n -= (size_t) res;
|
||||
// EINTR - interrupted by signal, continue reading
|
||||
}
|
||||
else if (res == 0)
|
||||
{
|
||||
// EOF - should not happen with /dev/urandom
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_read += res;
|
||||
}
|
||||
}
|
||||
if (close(fd) < 0) {
|
||||
|
||||
close(fd); // don't check, 'cuz failing to close /dev/urandom is not truly fatal, the OS will clean up
|
||||
return true;
|
||||
}
|
||||
|
||||
void generate_system_random_bytes_or_die(size_t n, void *result)
|
||||
{
|
||||
if (!generate_system_random_bytes(n, result))
|
||||
{
|
||||
fprintf(stderr, "FATAL: Failed to generate %zu random bytes: %s\n\n", n, strerror(errno));
|
||||
fflush(stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
|
@ -85,11 +118,10 @@ FINALIZER(deinit_random) {
|
|||
}
|
||||
*/
|
||||
|
||||
//INITIALIZER(init_random) {
|
||||
void init_random(void)
|
||||
{
|
||||
generate_system_random_bytes_no_lock(RANDOM_STATE_SIZE, &state);
|
||||
//REGISTER_FINA\LIZER(deinit_random);
|
||||
generate_system_random_bytes_or_die(HASH_DATA_AREA, &state);
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
assert(curstate == 0);
|
||||
curstate = 1;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue