From 87cb1ab6765d9ad9482b882b26e45a683162a078 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 24 May 2022 15:09:20 +0200 Subject: [PATCH] Simplify random number selection 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(). --- src/basic/random-util.c | 269 ++++++++++++--------------- src/basic/random-util.h | 11 +- src/basic/recovery-key.c | 2 +- src/boot/bootctl.c | 4 +- src/cryptenroll/cryptenroll-pkcs11.c | 2 +- src/home/homectl-pkcs11.c | 2 +- src/home/homework-fscrypt.c | 4 +- src/home/homework-luks.c | 4 +- src/journal/journalctl.c | 2 +- src/libsystemd/sd-id128/sd-id128.c | 5 +- src/partition/repart.c | 2 +- src/shared/creds-util.c | 4 +- src/shared/libcrypt-util.c | 2 +- src/shared/libfido2-util.c | 2 +- src/shared/tpm2-util.c | 2 +- src/test/test-alloc-util.c | 2 +- src/test/test-firewall-util.c | 2 +- src/test/test-random-util.c | 15 +- src/udev/net/link-config.c | 5 +- src/udev/scsi_id/scsi_serial.c | 3 +- 20 files changed, 141 insertions(+), 203 deletions(-) diff --git a/src/basic/random-util.c b/src/basic/random-util.c index a9fe25432c..9423a0805d 100644 --- a/src/basic/random-util.c +++ b/src/basic/random-util.c @@ -30,183 +30,142 @@ #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) { diff --git a/src/basic/random-util.h b/src/basic/random-util.h index ccee32792f..2d99807272 100644 --- a/src/basic/random-util.h +++ b/src/basic/random-util.h @@ -5,15 +5,8 @@ #include #include -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; diff --git a/src/basic/recovery-key.c b/src/basic/recovery-key.c index cad639a023..6a2f4d0f98 100644 --- a/src/basic/recovery-key.c +++ b/src/basic/recovery-key.c @@ -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; diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index cebb479e75..814e068158 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -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"); diff --git a/src/cryptenroll/cryptenroll-pkcs11.c b/src/cryptenroll/cryptenroll-pkcs11.c index eb098ce6f0..9f07a2e01d 100644 --- a/src/cryptenroll/cryptenroll-pkcs11.c +++ b/src/cryptenroll/cryptenroll-pkcs11.c @@ -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"); diff --git a/src/home/homectl-pkcs11.c b/src/home/homectl-pkcs11.c index c146c62e58..69c9d97aca 100644 --- a/src/home/homectl-pkcs11.c +++ b/src/home/homectl-pkcs11.c @@ -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"); diff --git a/src/home/homework-fscrypt.c b/src/home/homework-fscrypt.c index afa706a1bf..5106961f38 100644 --- a/src/home/homework-fscrypt.c +++ b/src/home/homework-fscrypt.c @@ -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"); diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c index 17c2f4f4e2..6541cb7ec9 100644 --- a/src/home/homework-luks.c +++ b/src/home/homework-luks.c @@ -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"); diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index cff34fd585..046b48184a 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -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"); diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c index 09c3401ca1..b81cd6ca8b 100644 --- a/src/libsystemd/sd-id128/sd-id128.c +++ b/src/libsystemd/sd-id128/sd-id128.c @@ -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 diff --git a/src/partition/repart.c b/src/partition/repart.c index 051242e836..a164dfefba 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -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"); diff --git a/src/shared/creds-util.c b/src/shared/creds-util.c index 3c89f527b4..72ec992121 100644 --- a/src/shared/creds-util.c +++ b/src/shared/creds-util.c @@ -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"); } diff --git a/src/shared/libcrypt-util.c b/src/shared/libcrypt-util.c index 0d72032f53..81e6f1754c 100644 --- a/src/shared/libcrypt-util.c +++ b/src/shared/libcrypt-util.c @@ -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; diff --git a/src/shared/libfido2-util.c b/src/shared/libfido2-util.c index e70a8c863a..796dc4079e 100644 --- a/src/shared/libfido2-util.c +++ b/src/shared/libfido2-util.c @@ -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"); diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 84120000aa..abcedde8a8 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -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; diff --git a/src/test/test-alloc-util.c b/src/test/test-alloc-util.c index f2064cf2ed..df6139005f 100644 --- a/src/test/test-alloc-util.c +++ b/src/test/test-alloc-util.c @@ -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); diff --git a/src/test/test-firewall-util.c b/src/test/test-firewall-util.c index f22bc3c5bc..3ca3108e36 100644 --- a/src/test/test-firewall-util.c +++ b/src/test/test-firewall-util.c @@ -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); diff --git a/src/test/test-random-util.c b/src/test/test-random-util.c index 8cd457d57d..3128f669b7 100644 --- a/src/test/test-random-util.c +++ b/src/test/test-random-util.c @@ -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); diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index 28c0e633a3..8fdb48f315 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -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; } diff --git a/src/udev/scsi_id/scsi_serial.c b/src/udev/scsi_id/scsi_serial.c index bde2811dd7..cfc13feced 100644 --- a/src/udev/scsi_id/scsi_serial.c +++ b/src/udev/scsi_id/scsi_serial.c @@ -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) -- 2.25.1