diff options
| author | Michael Biebl <biebl@debian.org> | 2020-10-05 22:27:18 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2020-10-05 22:27:18 +0200 |
| commit | aafc1dbe4712c86189bbc1d4d54ad8cb4c69be7e (patch) | |
| tree | a2a9bb4d007339a0b1304540388230ccedac32bd /shared/nm-glib-aux/nm-random-utils.c | |
| parent | e7b44ef4c80907346ec7492a09c45277459924fc (diff) | |
New upstream version 1.27.90 upstream/1.27.90
Diffstat (limited to 'shared/nm-glib-aux/nm-random-utils.c')
| -rw-r--r-- | shared/nm-glib-aux/nm-random-utils.c | 201 |
1 files changed, 100 insertions, 101 deletions
diff --git a/shared/nm-glib-aux/nm-random-utils.c b/shared/nm-glib-aux/nm-random-utils.c index 95063c94..0c8b2758 100644 --- a/shared/nm-glib-aux/nm-random-utils.c +++ b/shared/nm-glib-aux/nm-random-utils.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: LGPL-2.1+ +/* SPDX-License-Identifier: LGPL-2.1+ */ /* * Copyright (C) 2017 Red Hat, Inc. */ @@ -10,9 +10,9 @@ #include <fcntl.h> #if USE_SYS_RANDOM_H -#include <sys/random.h> + #include <sys/random.h> #else -#include <linux/random.h> + #include <linux/random.h> #endif #include "nm-shared-utils.h" @@ -41,109 +41,108 @@ * a warning. */ gboolean -nm_utils_random_bytes (void *p, size_t n) +nm_utils_random_bytes(void *p, size_t n) { - int fd; - int r; - gboolean has_high_quality = TRUE; - gboolean urandom_success; - guint8 *buf = p; - gboolean avoid_urandom = FALSE; + int fd; + int r; + gboolean has_high_quality = TRUE; + gboolean urandom_success; + guint8 * buf = p; + gboolean avoid_urandom = FALSE; - g_return_val_if_fail (p, FALSE); - g_return_val_if_fail (n > 0, FALSE); + g_return_val_if_fail(p, FALSE); + g_return_val_if_fail(n > 0, FALSE); #if HAVE_GETRANDOM - { - static gboolean have_syscall = TRUE; - - if (have_syscall) { - r = getrandom (buf, n, GRND_NONBLOCK); - if (r > 0) { - if ((size_t) r == n) - return TRUE; - - /* no or partial read. There is not enough entropy. - * Fill the rest reading from urandom, and remember that - * some bits are not high quality. */ - nm_assert (r < n); - buf += r; - n -= r; - has_high_quality = FALSE; - - /* At this point, we don't want to read /dev/urandom, because - * the entropy pool is low (early boot?), and asking for more - * entropy causes kernel messages to be logged. - * - * We use our fallback via GRand. Note that g_rand_new() also - * tries to seed itself with data from /dev/urandom, but since - * we reuse the instance, it shouldn't matter. */ - avoid_urandom = TRUE; - } else { - if (errno == ENOSYS) { - /* no support for getrandom(). We don't know whether - * we urandom will give us good quality. Assume yes. */ - have_syscall = FALSE; - } else { - /* unknown error. We'll read urandom below, but we don't have - * high-quality randomness. */ - has_high_quality = FALSE; - } - } - } - } + { + static gboolean have_syscall = TRUE; + + if (have_syscall) { + r = getrandom(buf, n, GRND_NONBLOCK); + if (r > 0) { + if ((size_t) r == n) + return TRUE; + + /* no or partial read. There is not enough entropy. + * Fill the rest reading from urandom, and remember that + * some bits are not high quality. */ + nm_assert(r < n); + buf += r; + n -= r; + has_high_quality = FALSE; + + /* At this point, we don't want to read /dev/urandom, because + * the entropy pool is low (early boot?), and asking for more + * entropy causes kernel messages to be logged. + * + * We use our fallback via GRand. Note that g_rand_new() also + * tries to seed itself with data from /dev/urandom, but since + * we reuse the instance, it shouldn't matter. */ + avoid_urandom = TRUE; + } else { + if (errno == ENOSYS) { + /* no support for getrandom(). We don't know whether + * we urandom will give us good quality. Assume yes. */ + have_syscall = FALSE; + } else { + /* unknown error. We'll read urandom below, but we don't have + * high-quality randomness. */ + has_high_quality = FALSE; + } + } + } + } #endif - urandom_success = FALSE; - if (!avoid_urandom) { + urandom_success = FALSE; + if (!avoid_urandom) { fd_open: - fd = open ("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOCTTY); - if (fd < 0) { - r = errno; - if (r == EINTR) - goto fd_open; - } else { - r = nm_utils_fd_read_loop_exact (fd, buf, n, TRUE); - nm_close (fd); - if (r >= 0) - urandom_success = TRUE; - } - } - - if (!urandom_success) { - static _nm_thread_local GRand *rand = NULL; - gsize i; - int j; - - /* we failed to fill the bytes reading from urandom. - * Fill the bits using GRand pseudo random numbers. - * - * We don't have good quality. - */ - has_high_quality = FALSE; - - if (G_UNLIKELY (!rand)) - rand = g_rand_new (); - - nm_assert (n > 0); - i = 0; - for (;;) { - const union { - guint32 v32; - guint8 v8[4]; - } v = { - .v32 = g_rand_int (rand), - }; - - for (j = 0; j < 4; ) { - buf[i++] = v.v8[j++]; - if (i >= n) - goto done; - } - } -done: - ; - } - - return has_high_quality; + fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOCTTY); + if (fd < 0) { + r = errno; + if (r == EINTR) + goto fd_open; + } else { + r = nm_utils_fd_read_loop_exact(fd, buf, n, TRUE); + nm_close(fd); + if (r >= 0) + urandom_success = TRUE; + } + } + + if (!urandom_success) { + static _nm_thread_local GRand *rand = NULL; + gsize i; + int j; + + /* we failed to fill the bytes reading from urandom. + * Fill the bits using GRand pseudo random numbers. + * + * We don't have good quality. + */ + has_high_quality = FALSE; + + if (G_UNLIKELY(!rand)) + rand = g_rand_new(); + + nm_assert(n > 0); + i = 0; + for (;;) { + const union { + guint32 v32; + guint8 v8[4]; + } v = { + .v32 = g_rand_int(rand), + }; + + for (j = 0; j < 4;) { + buf[i++] = v.v8[j++]; + if (i >= n) + goto done; + } + } +done:; + } + + return has_high_quality; } |