Improve random sources when not using OpenSSL (#976)

* rand.c: request at most 256 bytes per getentropy call

* CMake: Set OQS_HAVE_GETENTROPY

* rand.c: fopen/fread error handling

* rand.c: redundant test to silence warn_unused_result

* CMake: include CheckSymbolExists
This commit is contained in:
John Schanck 2021-04-20 19:48:24 -04:00 committed by GitHub
parent e48bc41c4f
commit a89e3ac581
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 29 deletions

View File

@ -1,5 +1,7 @@
# SPDX-License-Identifier: MIT
include(CheckSymbolExists)
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR
CMAKE_C_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wbad-function-cast)
@ -49,6 +51,13 @@ if(OQS_USE_OPENSSL)
target_include_directories(common PRIVATE ${OPENSSL_INCLUDE_DIR})
endif()
if(NOT OQS_USE_OPENSSL)
check_symbol_exists(getentropy "unistd.h;sys/random.h" CMAKE_HAVE_GETENTROPY)
if(${CMAKE_HAVE_GETENTROPY})
target_compile_definitions(common PRIVATE OQS_HAVE_GETENTROPY)
endif()
endif()
if(NOT OQS_USE_SHA3_OPENSSL) # using XKCP
set(_COMMON_OBJS ${_COMMON_OBJS} ${XKCP_LOW_OBJS})
endif()

View File

@ -60,43 +60,37 @@ OQS_API void OQS_randombytes(uint8_t *random_array, size_t bytes_to_read) {
}
#if !defined(_WIN32)
#if defined(HAVE_GETENTROPY)
#if defined(OQS_HAVE_GETENTROPY)
void OQS_randombytes_system(uint8_t *random_array, size_t bytes_to_read) {
int rc;
do {
rc = getentropy(random_array, bytes_to_read);
} while (rc != 0);
}
#else
static __inline void delay(unsigned int count) {
while (count--) {
while (bytes_to_read > 256) {
if (getentropy(random_array, 256)) {
exit(EXIT_FAILURE);
}
random_array += 256;
bytes_to_read -= 256;
}
if (getentropy(random_array, bytes_to_read)) {
exit(EXIT_FAILURE);
}
}
#else
void OQS_randombytes_system(uint8_t *random_array, size_t bytes_to_read) {
FILE *handle;
do {
handle = fopen("/dev/urandom", "rb");
if (handle == NULL) {
delay(0xFFFFF);
}
} while (handle == NULL);
size_t bytes_read;
size_t bytes_last_read, bytes_total_read, bytes_left_to_read;
bytes_total_read = 0;
bytes_left_to_read = bytes_to_read;
while (bytes_left_to_read > 0) {
do {
bytes_last_read = fread(random_array + bytes_total_read, 1, bytes_left_to_read, handle);
if (bytes_last_read == 0) {
delay(0xFFFF);
}
} while (bytes_last_read == 0);
bytes_total_read += bytes_last_read;
bytes_left_to_read -= bytes_last_read;
handle = fopen("/dev/urandom", "rb");
if (!handle) {
perror("OQS_randombytes");
exit(EXIT_FAILURE);
}
bytes_read = fread(random_array, 1, bytes_to_read, handle);
if (bytes_read < bytes_to_read || ferror(handle)) {
perror("OQS_randombytes");
exit(EXIT_FAILURE);
}
fclose(handle);
}
#endif