]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
random-util: add common helper random_write_entropy() for crediting entropy to the...
authorLennart Poettering <lennart@poettering.net>
Thu, 11 Jun 2020 07:53:29 +0000 (09:53 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 24 Jun 2020 13:33:27 +0000 (15:33 +0200)
src/basic/random-util.c
src/basic/random-util.h
src/core/efi-random.c
src/random-seed/random-seed.c

index 73cc7272db41cfd8c2331da5030043f6e31b8b1c..4a30c4d359c2e34e6e61f27e340f9188bb16ebfa 100644 (file)
@@ -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;
+}
index d8e067d96e877af94aaa00fea1e1454eb6d1ee59..7824ffacebb9255ac81783b5866acc6afb6600e0 100644 (file)
@@ -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);
index c4d25d68e426c5cc2b8425dda2153a818a75936a..b6609e63e548d532c8d1cb6f7433e0371607d7f2 100644 (file)
@@ -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.");
index 89452c8e152109b733dbcd82defb0c8dc0cf1d9e..63ad977514d8eabdeb1dcaa4bcb41766506c439d 100644 (file)
@@ -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");
                 }
         }