summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2020-06-11 09:53:29 +0200
committerLennart Poettering <lennart@poettering.net>2020-06-24 15:33:27 +0200
commit4dd055f907eda30b95c9cdd0b822120bbf646ecf (patch)
tree8ca8249ef5b8f4dcfc98a59b2983150d7bf8e59a
parent45250e66cc68fe238acbf8889a7797829fa0e9d4 (diff)
downloadsystemd-4dd055f907eda30b95c9cdd0b822120bbf646ecf.tar.gz
random-util: add common helper random_write_entropy() for crediting entropy to the kernel's pool
-rw-r--r--src/basic/random-util.c35
-rw-r--r--src/basic/random-util.h2
-rw-r--r--src/core/efi-random.c20
-rw-r--r--src/random-seed/random-seed.c22
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");
}
}