diff options
author | Dr. Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com> | 2018-08-16 21:05:47 +0200 |
---|---|---|
committer | Dr. Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com> | 2018-08-19 12:44:05 +0200 |
commit | 630ce41e836a756423c7d834fa2b4a0f8efec871 (patch) | |
tree | b13928ba107439b462acf57b75be530f6bde114c /crypto | |
parent | rand_unix.c: assimilate syscall_random() with getrandom(2) (diff) | |
download | openssl-630ce41e836a756423c7d834fa2b4a0f8efec871.tar.xz openssl-630ce41e836a756423c7d834fa2b4a0f8efec871.zip |
rand_unix.c: don't discard entropy bytes from syscall_random()
Fixes #6978
Don't discard partial reads from syscall_random() and retry instead.
Reviewed-by: Andy Polyakov <appro@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Tim Hudson <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6990)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/rand/rand_unix.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c index 74cc9e146f..e63d778900 100644 --- a/crypto/rand/rand_unix.c +++ b/crypto/rand/rand_unix.c @@ -458,17 +458,25 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool) unsigned char *buffer; # ifdef OPENSSL_RAND_SEED_GETRANDOM - bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); - buffer = rand_pool_add_begin(pool, bytes_needed); - if (buffer != NULL) { - size_t bytes = 0; - - if (syscall_random(buffer, bytes_needed) == (int)bytes_needed) - bytes = bytes_needed; + { + ssize_t bytes; + /* Maximum allowed number of consecutive unsuccessful attempts */ + int attempts = 3; - rand_pool_add_end(pool, bytes, 8 * bytes); - entropy_available = rand_pool_entropy_available(pool); + bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/); + while (bytes_needed != 0 && attempts-- > 0) { + buffer = rand_pool_add_begin(pool, bytes_needed); + bytes = syscall_random(buffer, bytes_needed); + if (bytes > 0) { + rand_pool_add_end(pool, bytes, 8 * bytes); + bytes_needed -= bytes; + attempts = 3; /* reset counter after successful attempt */ + } else if (bytes < 0 && errno != EINTR) { + break; + } + } } + entropy_available = rand_pool_entropy_available(pool); if (entropy_available > 0) return entropy_available; # endif |