summaryrefslogtreecommitdiffstats
path: root/crypto/rand
diff options
context:
space:
mode:
authorDr. Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>2018-08-16 21:34:37 +0200
committerDr. Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>2018-08-19 12:44:05 +0200
commitcca996217802077fe74711310356124a492756a8 (patch)
tree7a03cf074af64e9820c10475b0711dde9a166554 /crypto/rand
parent630ce41e836a756423c7d834fa2b4a0f8efec871 (diff)
rand_unix.c: don't discard entropy bytes from /dev/*random
Don't discard partial reads from /dev/*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/rand')
-rw-r--r--crypto/rand/rand_unix.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c
index e63d778900..9c62a04ebf 100644
--- a/crypto/rand/rand_unix.c
+++ b/crypto/rand/rand_unix.c
@@ -493,22 +493,27 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
size_t i;
for (i = 0; bytes_needed > 0 && i < OSSL_NELEM(random_device_paths); i++) {
+ ssize_t bytes = 0;
+ /* Maximum allowed number of consecutive unsuccessful attempts */
+ int attempts = 3;
const int fd = get_random_device(i);
if (fd == -1)
continue;
- buffer = rand_pool_add_begin(pool, bytes_needed);
- if (buffer != NULL) {
- const ssize_t n = read(fd, buffer, bytes_needed);
- if (n <= 0) {
- close_random_device(i);
- continue;
- }
+ while (bytes_needed != 0 && attempts-- > 0) {
+ buffer = rand_pool_add_begin(pool, bytes_needed);
+ bytes = read(fd, buffer, bytes_needed);
- rand_pool_add_end(pool, n, 8 * n);
+ 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;
+ }
}
- if (!keep_random_devices_open)
+ if (bytes < 0 || !keep_random_devices_open)
close_random_device(i);
bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);