diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2022-05-24 15:09:20 +0200 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2022-05-31 09:20:52 +0200 |
commit | 87cb1ab6765d9ad9482b882b26e45a683162a078 (patch) | |
tree | a2af6e58c9044f281828148da47a863f9b91ad0f /src/home | |
parent | fada4bdcaa57137c7245d3031deb08f3bcf7a8cc (diff) | |
download | systemd-87cb1ab6765d9ad9482b882b26e45a683162a078.tar.gz |
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().
Diffstat (limited to 'src/home')
-rw-r--r-- | src/home/homectl-pkcs11.c | 2 | ||||
-rw-r--r-- | src/home/homework-fscrypt.c | 4 | ||||
-rw-r--r-- | src/home/homework-luks.c | 4 |
3 files changed, 5 insertions, 5 deletions
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"); |