diff options
-rw-r--r-- | src/basic/random-util.c | 35 | ||||
-rw-r--r-- | src/basic/random-util.h | 2 | ||||
-rw-r--r-- | src/core/efi-random.c | 20 | ||||
-rw-r--r-- | src/random-seed/random-seed.c | 22 |
4 files changed, 44 insertions, 35 deletions
diff --git a/src/basic/random-util.c b/src/basic/random-util.c index 73cc7272db..4a30c4d359 100644 --- a/src/basic/random-util.c +++ b/src/basic/random-util.c @@ -7,11 +7,13 @@ #include <elf.h> #include <errno.h> #include <fcntl.h> +#include <linux/random.h> #include <pthread.h> #include <stdbool.h> #include <stdint.h> #include <stdlib.h> #include <string.h> +#include <sys/ioctl.h> #include <sys/time.h> #if HAVE_SYS_AUXV_H @@ -438,3 +440,36 @@ size_t random_pool_size(void) { /* Use the minimum as default, if we can't retrieve the correct value */ return RANDOM_POOL_SIZE_MIN; } + +int random_write_entropy(int fd, const void *seed, size_t size, bool credit) { + int r; + + assert(fd >= 0); + assert(seed && size > 0); + + if (credit) { + _cleanup_free_ struct rand_pool_info *info = NULL; + + /* The kernel API only accepts "int" as entropy count (which is in bits), let's avoid any + * chance for confusion here. */ + if (size > INT_MAX / 8) + return -EOVERFLOW; + + info = malloc(offsetof(struct rand_pool_info, buf) + size); + if (!info) + return -ENOMEM; + + info->entropy_count = size * 8; + info->buf_size = size; + memcpy(info->buf, seed, size); + + if (ioctl(fd, RNDADDENTROPY, info) < 0) + return -errno; + } else { + r = loop_write(fd, seed, size, false); + if (r < 0) + return r; + } + + return 0; +} diff --git a/src/basic/random-util.h b/src/basic/random-util.h index d8e067d96e..7824ffaceb 100644 --- a/src/basic/random-util.h +++ b/src/basic/random-util.h @@ -38,3 +38,5 @@ int rdrand(unsigned long *ret); #define RANDOM_POOL_SIZE_MAX (10U*1024U*1024U) size_t random_pool_size(void); + +int random_write_entropy(int fd, const void *seed, size_t size, bool credit); diff --git a/src/core/efi-random.c b/src/core/efi-random.c index c4d25d68e4..b6609e63e5 100644 --- a/src/core/efi-random.c +++ b/src/core/efi-random.c @@ -1,8 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #include <fcntl.h> -#include <linux/random.h> -#include <sys/ioctl.h> #include <unistd.h> #include "alloc-util.h" @@ -11,6 +9,7 @@ #include "efivars.h" #include "fd-util.h" #include "fs-util.h" +#include "random-util.h" #include "strv.h" /* If a random seed was passed by the boot loader in the LoaderRandomSeed EFI variable, let's credit it to @@ -43,7 +42,6 @@ static void lock_down_efi_variables(void) { } int efi_take_random_seed(void) { - _cleanup_free_ struct rand_pool_info *info = NULL; _cleanup_free_ void *value = NULL; _cleanup_close_ int random_fd = -1; size_t size; @@ -79,11 +77,6 @@ int efi_take_random_seed(void) { if (size == 0) return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Random seed passed from boot loader has zero size? Ignoring."); - /* The kernel API only accepts "int" as entropy count (which is in bits), let's avoid any chance for - * confusion here. */ - if (size > INT_MAX / 8) - size = INT_MAX / 8; - random_fd = open("/dev/urandom", O_WRONLY|O_CLOEXEC|O_NOCTTY); if (random_fd < 0) return log_warning_errno(errno, "Failed to open /dev/urandom for writing, ignoring: %m"); @@ -94,15 +87,8 @@ int efi_take_random_seed(void) { if (r < 0) return log_warning_errno(r, "Unable to mark EFI random seed as used, not using it: %m"); - info = malloc(offsetof(struct rand_pool_info, buf) + size); - if (!info) - return log_oom(); - - info->entropy_count = size * 8; - info->buf_size = size; - memcpy(info->buf, value, size); - - if (ioctl(random_fd, RNDADDENTROPY, info) < 0) + r = random_write_entropy(random_fd, value, size, true); + if (r < 0) return log_warning_errno(errno, "Failed to credit entropy, ignoring: %m"); log_info("Successfully credited entropy passed from boot loader."); diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c index 89452c8e15..63ad977514 100644 --- a/src/random-seed/random-seed.c +++ b/src/random-seed/random-seed.c @@ -236,24 +236,10 @@ static int run(int argc, char *argv[]) { } } - if (IN_SET(lets_credit, CREDIT_ENTROPY_YES_PLEASE, CREDIT_ENTROPY_YES_FORCED)) { - _cleanup_free_ struct rand_pool_info *info = NULL; - - info = malloc(offsetof(struct rand_pool_info, buf) + k); - if (!info) - return log_oom(); - - info->entropy_count = k * 8; - info->buf_size = k; - memcpy(info->buf, buf, k); - - if (ioctl(random_fd, RNDADDENTROPY, info) < 0) - return log_warning_errno(errno, "Failed to credit entropy, ignoring: %m"); - } else { - r = loop_write(random_fd, buf, (size_t) k, false); - if (r < 0) - log_error_errno(r, "Failed to write seed to /dev/urandom: %m"); - } + r = random_write_entropy(random_fd, buf, k, + IN_SET(lets_credit, CREDIT_ENTROPY_YES_PLEASE, CREDIT_ENTROPY_YES_FORCED)); + if (r < 0) + log_error_errno(r, "Failed to write seed to /dev/urandom: %m"); } } |