]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Simplify random number selection
authorJason A. Donenfeld <Jason@zx2c4.com>
Tue, 24 May 2022 13:09:20 +0000 (15:09 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 31 May 2022 07:20:52 +0000 (09:20 +0200)
We currently have a convoluted and complex selection of which random
numbers to use. We can simplify this down to two functions that cover
all of our use cases:

1) Randomness for crypto: this one needs to wait until the RNG is
   initialized. So it uses getrandom(0). If that's not available, it
   polls on /dev/random, and then reads from /dev/urandom. This function
   returns whether or not it was successful, as before.

2) Randomness for other things: this one uses getrandom(GRND_INSECURE).
   If it's not available it uses getrandom(GRND_NONBLOCK). And if that
   would block, then it falls back to /dev/urandom. And if /dev/urandom
   isn't available, it uses the fallback code. It never fails and
   doesn't return a value.

These two cases match all the uses of randomness inside of systemd.

I would prefer to make both of these return void, and get rid of the
fallback code, and simply assert in the incredibly unlikely case that
/dev/urandom doesn't exist. But Luca disagrees, so this commit attempts
to instead keep case (1) returning a return value, which all the callers
already check, and fix the fallback code in (2) to be less bad than
before.

For the less bad fallback code for (2), we now use auxval and some
timestamps, together with various counters representing the invocation,
hash it all together and provide the output. Provided that AT_RANDOM is
secure, this construction is probably okay too, though notably it
doesn't have any forward secrecy. Fortunately, it's only used by
random_bytes() and not by crypto_random_bytes().

20 files changed:
src/basic/random-util.c
src/basic/random-util.h
src/basic/recovery-key.c
src/boot/bootctl.c
src/cryptenroll/cryptenroll-pkcs11.c
src/home/homectl-pkcs11.c
src/home/homework-fscrypt.c
src/home/homework-luks.c
src/journal/journalctl.c
src/libsystemd/sd-id128/sd-id128.c
src/partition/repart.c
src/shared/creds-util.c
src/shared/libcrypt-util.c
src/shared/libfido2-util.c
src/shared/tpm2-util.c
src/test/test-alloc-util.c
src/test/test-firewall-util.c
src/test/test-random-util.c
src/udev/net/link-config.c
src/udev/scsi_id/scsi_serial.c

index a9fe25432ce822448fd06a1e66941b906778d35e..9423a0805dd132b708fbb8e5671550e5c2320e76 100644 (file)
 #include "missing_syscall.h"
 #include "parse-util.h"
 #include "random-util.h"
-#include "siphash24.h"
+#include "sha256.h"
 #include "time-util.h"
 
-static bool srand_called = false;
+/* This is a "best effort" kind of thing, but has no real security value.
+ * So, this should only be used by random_bytes(), which is not meant for
+ * crypto. This could be made better, but we're *not* trying to roll a
+ * userspace prng here, or even have forward secrecy, but rather just do
+ * the shortest thing that is at least better than libc rand(). */
+static void fallback_random_bytes(void *p, size_t n) {
+        static thread_local uint64_t fallback_counter = 0;
+        struct {
+                char label[32];
+                uint64_t call_id, block_id;
+                usec_t stamp_mono, stamp_real;
+                pid_t pid, tid;
+                uint8_t auxval[16];
+        } state = {
+                /* Arbitrary domain separation to prevent other usage of AT_RANDOM from clashing. */
+                .label = "systemd fallback random bytes v1",
+                .call_id = fallback_counter++,
+                .stamp_mono = now(CLOCK_MONOTONIC),
+                .stamp_real = now(CLOCK_REALTIME),
+                .pid = getpid(),
+                .tid = gettid()
+        };
 
-int genuine_random_bytes(void *p, size_t n, RandomFlags flags) {
-        static int have_syscall = -1;
-        _cleanup_close_ int fd = -1;
-
-        /* Gathers some high-quality randomness from the kernel. This call won't block, unless the RANDOM_BLOCK
-         * flag is set. If it doesn't block, it will still always return some data from the kernel, regardless
-         * of whether the random pool is fully initialized or not. When creating cryptographic key material you
-         * should always use RANDOM_BLOCK. */
+#if HAVE_SYS_AUXV_H
+        memcpy(state.auxval, ULONG_TO_PTR(getauxval(AT_RANDOM)), sizeof(state.auxval));
+#endif
 
-        if (n == 0)
-                return 0;
+        while (n > 0) {
+                struct sha256_ctx ctx;
 
-        /* Use the getrandom() syscall unless we know we don't have it. */
-        if (have_syscall != 0 && !HAS_FEATURE_MEMORY_SANITIZER) {
-                for (;;) {
-                        ssize_t l = getrandom(p, n, FLAGS_SET(flags, RANDOM_BLOCK) ? 0 : GRND_INSECURE);
-
-                        if (l > 0) {
-                                have_syscall = true;
-
-                                if ((size_t) l == n)
-                                        return 0; /* Yay, success! */
-
-                                /* We didn't get enough data, so try again */
-                                assert((size_t) l < n);
-                                p = (uint8_t*) p + l;
-                                n -= l;
-                                continue;
-
-                        } else if (l == 0) {
-                                have_syscall = true;
-                                return -EIO;
-
-                        } else if (ERRNO_IS_NOT_SUPPORTED(errno)) {
-                                /* We lack the syscall, continue with reading from /dev/urandom. */
-                                have_syscall = false;
-                                break;
-
-                        } else if (errno == EINVAL) {
-                                /* If we previously passed GRND_INSECURE, and this flag isn't known, then
-                                 * we're likely running an old kernel which has getrandom() but not
-                                 * GRND_INSECURE. In this case, fall back to /dev/urandom. */
-                                if (!FLAGS_SET(flags, RANDOM_BLOCK))
-                                        break;
-
-                                return -errno;
-                        } else
-                                return -errno;
+                sha256_init_ctx(&ctx);
+                sha256_process_bytes(&state, sizeof(state), &ctx);
+                if (n < SHA256_DIGEST_SIZE) {
+                        uint8_t partial[SHA256_DIGEST_SIZE];
+                        sha256_finish_ctx(&ctx, partial);
+                        memcpy(p, partial, n);
+                        break;
                 }
+                sha256_finish_ctx(&ctx, p);
+                p = (uint8_t *) p + SHA256_DIGEST_SIZE;
+                n -= SHA256_DIGEST_SIZE;
+                ++state.block_id;
         }
-
-        fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
-        if (fd < 0)
-                return errno == ENOENT ? -ENOSYS : -errno;
-
-        return loop_read_exact(fd, p, n, true);
 }
 
-static void clear_srand_initialization(void) {
-        srand_called = false;
-}
-
-void initialize_srand(void) {
-        static bool pthread_atfork_registered = false;
-        unsigned x;
+void random_bytes(void *p, size_t n) {
+        static bool have_getrandom = true, have_grndinsecure = true;
+        _cleanup_close_ int fd = -1;
 
-        if (srand_called)
+        if (n == 0)
                 return;
 
-#if HAVE_SYS_AUXV_H
-        /* The kernel provides us with 16 bytes of entropy in auxv, so let's try to make use of that to seed
-         * the pseudo-random generator. It's better than nothing... But let's first hash it to make it harder
-         * to recover the original value by watching any pseudo-random bits we generate. After all the
-         * AT_RANDOM data might be used by other stuff too (in particular: ASLR), and we probably shouldn't
-         * leak the seed for that. */
-
-        const void *auxv = ULONG_TO_PTR(getauxval(AT_RANDOM));
-        if (auxv) {
-                static const uint8_t auxval_hash_key[16] = {
-                        0x92, 0x6e, 0xfe, 0x1b, 0xcf, 0x00, 0x52, 0x9c, 0xcc, 0x42, 0xcf, 0xdc, 0x94, 0x1f, 0x81, 0x0f
-                };
-
-                x = (unsigned) siphash24(auxv, 16, auxval_hash_key);
-        } else
-#endif
-                x = 0;
-
-        x ^= (unsigned) now(CLOCK_REALTIME);
-        x ^= (unsigned) gettid();
-
-        srand(x);
-        srand_called = true;
-
-        if (!pthread_atfork_registered) {
-                (void) pthread_atfork(NULL, NULL, clear_srand_initialization);
-                pthread_atfork_registered = true;
+        for (;;) {
+                ssize_t l;
+
+                if (!have_getrandom)
+                        break;
+
+                l = getrandom(p, n, have_grndinsecure ? GRND_INSECURE : GRND_NONBLOCK);
+                if (l > 0) {
+                        if ((size_t) l == n)
+                                return; /* Done reading, success. */
+                        p = (uint8_t *) p + l;
+                        n -= l;
+                        continue; /* Interrupted by a signal; keep going. */
+                } else if (l == 0)
+                        break; /* Weird, so fallback to /dev/urandom. */
+                else if (ERRNO_IS_NOT_SUPPORTED(errno)) {
+                        have_getrandom = false;
+                        break; /* No syscall, so fallback to /dev/urandom. */
+                } else if (errno == EINVAL && have_grndinsecure) {
+                        have_grndinsecure = false;
+                        continue; /* No GRND_INSECURE; fallback to GRND_NONBLOCK. */
+                } else if (errno == EAGAIN && !have_grndinsecure)
+                        break; /* Will block, but no GRND_INSECURE, so fallback to /dev/urandom. */
+
+                break; /* Unexpected, so just give up and fallback to /dev/urandom. */
         }
-}
 
-/* INT_MAX gives us only 31 bits, so use 24 out of that. */
-#if RAND_MAX >= INT_MAX
-assert_cc(RAND_MAX >= 16777215);
-#  define RAND_STEP 3
-#else
-/* SHORT_INT_MAX or lower gives at most 15 bits, we just use 8 out of that. */
-assert_cc(RAND_MAX >= 255);
-#  define RAND_STEP 1
-#endif
-
-void pseudo_random_bytes(void *p, size_t n) {
-        uint8_t *q;
-
-        /* This returns pseudo-random data using libc's rand() function. You probably never want to call this
-         * directly, because why would you use this if you can get better stuff cheaply? Use random_bytes()
-         * instead, see below: it will fall back to this function if there's nothing better to get, but only
-         * then. */
+        fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+        if (fd >= 0 && loop_read_exact(fd, p, n, false) == 0)
+                return;
 
-        initialize_srand();
+        /* This is a terrible fallback. Oh well. */
+        fallback_random_bytes(p, n);
+}
 
-        for (q = p; q < (uint8_t*) p + n; q += RAND_STEP) {
-                unsigned rr;
+int crypto_random_bytes(void *p, size_t n) {
+        static bool have_getrandom = true, seen_initialized = false;
+        _cleanup_close_ int fd = -1;
 
-                rr = (unsigned) rand();
+        if (n == 0)
+                return 0;
 
-#if RAND_STEP >= 3
-                if ((size_t) (q - (uint8_t*) p + 2) < n)
-                        q[2] = rr >> 16;
-#endif
-#if RAND_STEP >= 2
-                if ((size_t) (q - (uint8_t*) p + 1) < n)
-                        q[1] = rr >> 8;
-#endif
-                q[0] = rr;
+        for (;;) {
+                ssize_t l;
+
+                if (!have_getrandom)
+                        break;
+
+                l = getrandom(p, n, 0);
+                if (l > 0) {
+                        if ((size_t) l == n)
+                                return 0; /* Done reading, success. */
+                        p = (uint8_t *) p + l;
+                        n -= l;
+                        continue; /* Interrupted by a signal; keep going. */
+                } else if (l == 0)
+                        return -EIO; /* Weird, should never happen. */
+                else if (ERRNO_IS_NOT_SUPPORTED(errno)) {
+                        have_getrandom = false;
+                        break; /* No syscall, so fallback to /dev/urandom. */
+                }
+                return -errno;
         }
-}
 
-void random_bytes(void *p, size_t n) {
+        if (!seen_initialized) {
+                _cleanup_close_ int ready_fd = -1;
+                int r;
 
-        /* This returns high quality randomness if we can get it cheaply. If we can't because for some reason
-         * it is not available we'll try some crappy fallbacks.
-         *
-         * What this function will do:
-         *
-         *         • Use getrandom(GRND_INSECURE) or /dev/urandom, to return high-quality random values if
-         *           they are cheaply available, or less high-quality random values if they are not.
-         *
-         *         • This function will return pseudo-random data, generated via libc rand() if nothing
-         *           better is available.
-         *
-         *         • This function will work fine in early boot
-         *
-         *         • This function will always succeed
-         *
-         * What this function won't do:
-         *
-         *         • This function will never fail: it will give you randomness no matter what. It might not
-         *           be high quality, but it will return some, possibly generated via libc's rand() call.
-         *
-         *         • This function will never block: if the only way to get good randomness is a blocking,
-         *           synchronous getrandom() we'll instead provide you with pseudo-random data.
-         *
-         * This function is hence great for things like seeding hash tables, generating random numeric UNIX
-         * user IDs (that are checked for collisions before use) and such.
-         *
-         * This function is hence not useful for generating UUIDs or cryptographic key material.
-         */
-
-        if (genuine_random_bytes(p, n, 0) >= 0)
-                return;
+                ready_fd = open("/dev/random", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+                if (ready_fd < 0)
+                        return -errno;
+                r = fd_wait_for_event(ready_fd, POLLIN, USEC_INFINITY);
+                if (r < 0)
+                        return r;
+                seen_initialized = true;
+        }
 
-        /* If for some reason some user made /dev/urandom unavailable to us, or the kernel has no entropy, use a PRNG instead. */
-        pseudo_random_bytes(p, n);
+        fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+        if (fd < 0)
+                return -errno;
+        return loop_read_exact(fd, p, n, false);
 }
 
 size_t random_pool_size(void) {
index ccee32792f331118d3371c93cba820d9573353fc..2d99807272f3002baa06a0f301093af10a503de6 100644 (file)
@@ -5,15 +5,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-typedef enum RandomFlags {
-        RANDOM_BLOCK              = 1 << 0, /* Rather block than return crap randomness (only if the kernel supports that) */
-} RandomFlags;
-
-int genuine_random_bytes(void *p, size_t n, RandomFlags flags); /* returns "genuine" randomness, optionally filled up with pseudo random, if not enough is available */
-void pseudo_random_bytes(void *p, size_t n);                    /* returns only pseudo-randommess (but possibly seeded from something better) */
-void random_bytes(void *p, size_t n);                           /* returns genuine randomness if cheaply available, and pseudo randomness if not. */
-
-void initialize_srand(void);
+void random_bytes(void *p, size_t n); /* Returns random bytes suitable for most uses, but may be insecure sometimes. */
+int crypto_random_bytes(void *p, size_t n); /* Returns secure random bytes after waiting for the RNG to initialize. */
 
 static inline uint64_t random_u64(void) {
         uint64_t u;
index cad639a023b97fe5098b5968114d7c909a647c98..6a2f4d0f98b974af23238ce089155740741d9a86 100644 (file)
@@ -83,7 +83,7 @@ int make_recovery_key(char **ret) {
         if (!key)
                 return -ENOMEM;
 
-        r = genuine_random_bytes(key, RECOVERY_KEY_MODHEX_RAW_LENGTH, RANDOM_BLOCK);
+        r = crypto_random_bytes(key, RECOVERY_KEY_MODHEX_RAW_LENGTH);
         if (r < 0)
                 return r;
 
index cebb479e75d59a9301b433d9858af8a5d50f104d..814e0681583382e40c733a6def4bf4c1f664b42a 100644 (file)
@@ -1805,7 +1805,7 @@ static int install_random_seed(const char *esp) {
         if (!buffer)
                 return log_oom();
 
-        r = genuine_random_bytes(buffer, sz, RANDOM_BLOCK);
+        r = crypto_random_bytes(buffer, sz);
         if (r < 0)
                 return log_error_errno(r, "Failed to acquire random seed: %m");
 
@@ -1892,7 +1892,7 @@ static int install_random_seed(const char *esp) {
                 log_debug("Existing system token size (%zu) does not match our expectations (%zu), replacing.", token_size, sz);
         }
 
-        r = genuine_random_bytes(buffer, sz, RANDOM_BLOCK);
+        r = crypto_random_bytes(buffer, sz);
         if (r < 0)
                 return log_error_errno(r, "Failed to acquire random seed: %m");
 
index eb098ce6f0b06f4bb28ba3983c0f4f0945bcda43..9f07a2e01d0a55cf575f301d7b1742402bb5b5be 100644 (file)
@@ -50,7 +50,7 @@ int enroll_pkcs11(
         if (!decrypted_key)
                 return log_oom();
 
-        r = genuine_random_bytes(decrypted_key, decrypted_key_size, RANDOM_BLOCK);
+        r = crypto_random_bytes(decrypted_key, decrypted_key_size);
         if (r < 0)
                 return log_error_errno(r, "Failed to generate random key: %m");
 
index c146c62e58bc7f23232cc49e24f9935f6af93632..69c9d97acada63cd9507a88723533ec5f6c3e950 100644 (file)
@@ -184,7 +184,7 @@ int identity_add_pkcs11_key_data(JsonVariant **v, const char *uri) {
         if (!decrypted_key)
                 return log_oom();
 
-        r = genuine_random_bytes(decrypted_key, decrypted_key_size, RANDOM_BLOCK);
+        r = crypto_random_bytes(decrypted_key, decrypted_key_size);
         if (r < 0)
                 return log_error_errno(r, "Failed to generate random key: %m");
 
index afa706a1bf63b8c343305c6b7f35e6270fc28905..5106961f38bdef6ec55b3967699f166c9b99dca7 100644 (file)
@@ -409,7 +409,7 @@ static int fscrypt_slot_set(
         const EVP_CIPHER *cc;
         size_t encrypted_size;
 
-        r = genuine_random_bytes(salt, sizeof(salt), RANDOM_BLOCK);
+        r = crypto_random_bytes(salt, sizeof(salt));
         if (r < 0)
                 return log_error_errno(r, "Failed to generate salt: %m");
 
@@ -540,7 +540,7 @@ int home_create_fscrypt(
         if (!volume_key)
                 return log_oom();
 
-        r = genuine_random_bytes(volume_key, volume_key_size, RANDOM_BLOCK);
+        r = crypto_random_bytes(volume_key, volume_key_size);
         if (r < 0)
                 return log_error_errno(r, "Failed to acquire volume key: %m");
 
index 17c2f4f4e2ce386e56da74a1730c0bedb5e27e1e..6541cb7ec95f548ad460667e1855dfe72f289f2a 100644 (file)
@@ -949,7 +949,7 @@ static int format_luks_token_text(
                 if (!iv)
                         return log_oom();
 
-                r = genuine_random_bytes(iv, iv_size, RANDOM_BLOCK);
+                r = crypto_random_bytes(iv, iv_size);
                 if (r < 0)
                         return log_error_errno(r, "Failed to generate IV: %m");
         }
@@ -1738,7 +1738,7 @@ static int luks_format(
         if (!volume_key)
                 return log_oom();
 
-        r = genuine_random_bytes(volume_key, volume_key_size, RANDOM_BLOCK);
+        r = crypto_random_bytes(volume_key, volume_key_size);
         if (r < 0)
                 return log_error_errno(r, "Failed to generate volume key: %m");
 
index cff34fd585003437a8c994e7cc0bf28e97281626..046b48184a5d85051360aa027e7e995e53fdb765 100644 (file)
@@ -1909,7 +1909,7 @@ static int setup_keys(void) {
         state = alloca_safe(state_size);
 
         log_info("Generating seed...");
-        r = genuine_random_bytes(seed, seed_size, RANDOM_BLOCK);
+        r = crypto_random_bytes(seed, seed_size);
         if (r < 0)
                 return log_error_errno(r, "Failed to acquire random seed: %m");
 
index 09c3401ca10e0958e5ce6780097e7b517175a372..b81cd6ca8b4f88f2f6a5783e6434775b153d0f64 100644 (file)
@@ -272,13 +272,10 @@ _public_ int sd_id128_get_invocation(sd_id128_t *ret) {
 
 _public_ int sd_id128_randomize(sd_id128_t *ret) {
         sd_id128_t t;
-        int r;
 
         assert_return(ret, -EINVAL);
 
-        r = genuine_random_bytes(&t, sizeof(t), 0);
-        if (r < 0)
-                return r;
+        random_bytes(&t, sizeof(t));
 
         /* Turn this into a valid v4 UUID, to be nice. Note that we
          * only guarantee this for newly generated UUIDs, not for
index 051242e836c5e5a575c361b8bf7090371dfcfd91..a164dfefbaf9869f6c9b5ef4639ee6ac63179376 100644 (file)
@@ -2594,7 +2594,7 @@ static int partition_encrypt(
         if (!volume_key)
                 return log_oom();
 
-        r = genuine_random_bytes(volume_key, volume_key_size, RANDOM_BLOCK);
+        r = crypto_random_bytes(volume_key, volume_key_size);
         if (r < 0)
                 return log_error_errno(r, "Failed to generate volume key: %m");
 
index 3c89f527b4000c7e921366225e274150836c52da..72ec992121f67b86c5f8fcfb99b6c6390fa86963 100644 (file)
@@ -158,7 +158,7 @@ static int make_credential_host_secret(
                 .machine_id = machine_id,
         };
 
-        r = genuine_random_bytes(buf.data, sizeof(buf.data), RANDOM_BLOCK);
+        r = crypto_random_bytes(buf.data, sizeof(buf.data));
         if (r < 0)
                 goto finish;
 
@@ -642,7 +642,7 @@ int encrypt_credential_and_warn(
                 if (!iv)
                         return log_oom();
 
-                r = genuine_random_bytes(iv, ivsz, RANDOM_BLOCK);
+                r = crypto_random_bytes(iv, ivsz);
                 if (r < 0)
                         return log_error_errno(r, "Failed to acquired randomized IV: %m");
         }
index 0d72032f53f9a22f6af79e6dc9f7ea98461a150d..81e6f1754c4f8973fb3d5cc99f0a29dbe7d151e6 100644 (file)
@@ -76,7 +76,7 @@ int make_salt(char **ret) {
         log_debug("Generating fallback salt for hash prefix: $6$");
 
         /* Insist on the best randomness by setting RANDOM_BLOCK, this is about keeping passwords secret after all. */
-        r = genuine_random_bytes(raw, sizeof(raw), RANDOM_BLOCK);
+        r = crypto_random_bytes(raw, sizeof(raw));
         if (r < 0)
                 return r;
 
index e70a8c863af4ca8c147cf0b4a780b9d048950b23..796dc4079e54aaef4dfb03c7a22d475ae5ac86c3 100644 (file)
@@ -596,7 +596,7 @@ int fido2_generate_hmac_hash(
         if (!salt)
                 return log_oom();
 
-        r = genuine_random_bytes(salt, FIDO2_SALT_SIZE, RANDOM_BLOCK);
+        r = crypto_random_bytes(salt, FIDO2_SALT_SIZE);
         if (r < 0)
                 return log_error_errno(r, "Failed to generate salt: %m");
 
index 84120000aaec6baf3754361da333abb365aa6153..abcedde8a89d53ab7250e9f585af1d33340f3d2a 100644 (file)
@@ -930,7 +930,7 @@ int tpm2_seal(
 
         log_debug("Generating secret key data.");
 
-        r = genuine_random_bytes(hmac_sensitive.sensitive.data.buffer, hmac_sensitive.sensitive.data.size, RANDOM_BLOCK);
+        r = crypto_random_bytes(hmac_sensitive.sensitive.data.buffer, hmac_sensitive.sensitive.data.size);
         if (r < 0) {
                 log_error_errno(r, "Failed to generate secret key: %m");
                 goto finish;
index f2064cf2ed3edcd47479630e09710546ddd97e84..df6139005f1f5835f29e5bd52912f846e7c6de8a 100644 (file)
@@ -145,7 +145,7 @@ TEST(auto_erase_memory) {
                                              * end of the allocation, since malloc() enforces alignment */
         assert_se(p2 = new(uint8_t, 4703));
 
-        assert_se(genuine_random_bytes(p1, 4703, RANDOM_BLOCK) == 0);
+        assert_se(crypto_random_bytes(p1, 4703) == 0);
 
         /* before we exit the scope, do something with this data, so that the compiler won't optimize this away */
         memcpy(p2, p1, 4703);
index f22bc3c5bcce903877ef187e125334a551190861..3ca3108e365b8b9e0241aa1dc3c32eee6b6287ba 100644 (file)
@@ -25,7 +25,7 @@ static void test_v6(FirewallContext *ctx) {
         assert_se(in_addr_from_string(AF_INET6, "1c3::c01d", &u2) >= 0);
 
         prefixlen = random_u64_range(128 + 1 - 8) + 8;
-        pseudo_random_bytes(&u3, sizeof(u3));
+        random_bytes(&u3, sizeof(u3));
 
         assert_se(fw_add_masquerade(&ctx, true, AF_INET6, &u1, 128) >= 0);
         assert_se(fw_add_masquerade(&ctx, false, AF_INET6, &u1, 128) >= 0);
index 8cd457d57da848c9dc2041c3d37bb44232bcd58f..3128f669b7781c783f2205d74573f7844c6143d0 100644 (file)
@@ -9,13 +9,11 @@
 #include "terminal-util.h"
 #include "tests.h"
 
-static void test_genuine_random_bytes_one(RandomFlags flags) {
+TEST(random_bytes) {
         uint8_t buf[16] = {};
 
-        log_info("/* %s(%d) */", __func__, flags);
-
         for (size_t i = 1; i < sizeof buf; i++) {
-                assert_se(genuine_random_bytes(buf, i, flags) == 0);
+                random_bytes(buf, i);
                 if (i + 1 < sizeof buf)
                         assert_se(buf[i] == 0);
 
@@ -23,16 +21,11 @@ static void test_genuine_random_bytes_one(RandomFlags flags) {
         }
 }
 
-TEST(genuine_random_bytes) {
-        test_genuine_random_bytes_one(0);
-        test_genuine_random_bytes_one(RANDOM_BLOCK);
-}
-
-TEST(pseudo_random_bytes) {
+TEST(crypto_random_bytes) {
         uint8_t buf[16] = {};
 
         for (size_t i = 1; i < sizeof buf; i++) {
-                pseudo_random_bytes(buf, i);
+                assert_se(crypto_random_bytes(buf, i) == 0);
                 if (i + 1 < sizeof buf)
                         assert_se(buf[i] == 0);
 
index 28c0e633a3bc98f652f8ea4d89a11a8c3c72d31b..8fdb48f315b357730e58b3d63469e5563e1111d6 100644 (file)
@@ -623,10 +623,7 @@ static int link_generate_new_hw_addr(Link *link, struct hw_addr_data *ret) {
                 /* We require genuine randomness here, since we want to make sure we won't collide with other
                  * systems booting up at the very same time. */
                 for (;;) {
-                        r = genuine_random_bytes(p, len, 0);
-                        if (r < 0)
-                                return log_link_warning_errno(link, r, "Failed to acquire random data to generate MAC address: %m");
-
+                        random_bytes(p, len);
                         if (hw_addr_is_valid(link, &hw_addr))
                                 break;
                 }
index bde2811dd75bb6f8ca38f0977c09fe4b1aa89f85..cfc13feced84f48c439ffca656f068b9d92e8c91 100644 (file)
@@ -789,7 +789,6 @@ int scsi_get_serial(struct scsi_id_device *dev_scsi, const char *devname,
         int retval;
 
         memzero(dev_scsi->serial, len);
-        initialize_srand();
         for (cnt = 20; cnt > 0; cnt--) {
                 struct timespec duration;
 
@@ -797,7 +796,7 @@ int scsi_get_serial(struct scsi_id_device *dev_scsi, const char *devname,
                 if (fd >= 0 || errno != EBUSY)
                         break;
                 duration.tv_sec = 0;
-                duration.tv_nsec = (200 * 1000 * 1000) + (rand() % 100 * 1000 * 1000);
+                duration.tv_nsec = (200 * 1000 * 1000) + (random_u32() % 100 * 1000 * 1000);
                 nanosleep(&duration, NULL);
         }
         if (fd < 0)