]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
random-util: introduce RANDOM_DONT_DRAIN
authorLennart Poettering <lennart@poettering.net>
Wed, 7 Nov 2018 18:31:39 +0000 (19:31 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 8 Nov 2018 08:44:27 +0000 (09:44 +0100)
Originally, the high_quality_required boolean argument controlled two
things: whether to extend any random data we successfully read with
pseudo-random data, and whether to return -ENODATA if we couldn't read
any data at all.

The boolean got replaced by RANDOM_EXTEND_WITH_PSEUDO, but this name
doesn't really cover the second part nicely. Moreover hiding both
changes of behaviour under a single flag is confusing. Hence, let's
split this part off under a new flag, and use it from random_bytes().

src/basic/random-util.c
src/basic/random-util.h

index 922b5a57b0f2d8d3f7d964679efb4485d2265597..6b08f72fc2f47f78c92611e4ff2a2cae3de462d2 100644 (file)
@@ -72,9 +72,9 @@ int genuine_random_bytes(void *p, size_t n, RandomFlags flags) {
         int r;
 
         /* Gathers some randomness from the kernel. This call won't block, unless the RANDOM_BLOCK flag is set. If
-         * RANDOM_EXTEND_WITH_PSEUDO is unset, it will always return some data from the kernel, regardless of whether
-         * the random pool is fully initialized or not.  Otherwise, it will return success if at least some random
-         * bytes were successfully acquired, and an error if the kernel has no entropy whatsover for us. */
+         * RANDOM_DONT_DRAIN is set, an error is returned if the random pool is not initialized. Otherwise it will
+         * always return some data from the kernel, regardless of whether the random pool is fully initialized or
+         * not. */
 
         if (n == 0)
                 return 0;
@@ -117,16 +117,17 @@ int genuine_random_bytes(void *p, size_t n, RandomFlags flags) {
                                 break;
 
                         } else if (errno == EAGAIN) {
-                                /* The kernel has no entropy whatsoever. Let's remember to
-                                 * use the syscall the next time again though.
+                                /* The kernel has no entropy whatsoever. Let's remember to use the syscall the next
+                                 * time again though.
                                  *
-                                 * If high_quality_required is false, return an error so that
-                                 * random_bytes() can produce some pseudorandom
-                                 * bytes. Otherwise, fall back to /dev/urandom, which we know
-                                 * is empty, but the kernel will produce some bytes for us on
-                                 * a best-effort basis. */
+                                 * If RANDOM_DONT_DRAIN is set, return an error so that random_bytes() can produce some
+                                 * pseudo-random bytes instead. Otherwise, fall back to /dev/urandom, which we know is empty,
+                                 * but the kernel will produce some bytes for us on a best-effort basis. */
                                 have_syscall = true;
 
+                                if (FLAGS_SET(flags, RANDOM_DONT_DRAIN))
+                                        return -ENODATA;
+
                                 if (FLAGS_SET(flags, RANDOM_EXTEND_WITH_PSEUDO)) {
                                         uint64_t u;
                                         size_t k;
@@ -228,7 +229,7 @@ void pseudo_random_bytes(void *p, size_t n) {
 
 void random_bytes(void *p, size_t n) {
 
-        if (genuine_random_bytes(p, n, RANDOM_EXTEND_WITH_PSEUDO) >= 0)
+        if (genuine_random_bytes(p, n, RANDOM_EXTEND_WITH_PSEUDO|RANDOM_DONT_DRAIN) >= 0)
                 return;
 
         /* If for some reason some user made /dev/urandom unavailable to us, or the kernel has no entropy, use a PRNG instead. */
index 0813314a0557d6829f83ab562f01c044aa79e82f..487f20e0ab959fd0e2123241d50761bd50d7bae9 100644 (file)
@@ -8,6 +8,7 @@
 typedef enum RandomFlags {
         RANDOM_EXTEND_WITH_PSEUDO = 1 << 0, /* If we can't get enough genuine randomness, but some, fill up the rest with pseudo-randomness */
         RANDOM_BLOCK              = 1 << 1, /* Rather block than return crap randomness (only if the kernel supports that) */
+        RANDOM_DONT_DRAIN         = 1 << 2, /* If we can't get any randomness at all, return early with -EAGAIN */
 } RandomFlags;
 
 int genuine_random_bytes(void *p, size_t n, RandomFlags flags); /* returns "genuine" randomness, optionally filled upwith pseudo random, if not enough is available */