1
0
Fork 0
forked from lthn/blockchain

Merge branch 'random_refactoring' into develop

This commit is contained in:
sowle 2025-08-11 00:16:15 +03:00
commit c36355d489
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
2 changed files with 69 additions and 33 deletions

View file

@ -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})

View file

@ -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;