Rename rdrand64 to rdrand, and switch from uint64_t to unsigned long.
This produces code that will compile/assemble on both x86-64 and x86-32.
This could be useful when running a 32-bit copy of systemd on a modern
Intel processor.
RDRAND is inherently arch-specific, so relying on the compiler-defined
'long' type seems reasonable.
We only use this when we don't require the best randomness. The primary
usecase for this is UUID generation, as this means we don't drain
randomness from the kernel pool for them. Since UUIDs are usually not
secrets RDRAND should be goot enough for them to avoid real-life
collisions.
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().
It's more descriptive, since we also have a function random_bytes()
which sounds very similar.
Also rename pseudorandom_bytes() to pseudo_random_bytes(). This way the
two functions are nicely systematic, one returning genuine random bytes
and the other pseudo random ones.
Pretty much all intel cpus have had RDRAND in a long time. While
CPU-internal RNG are widely not trusted, for seeding hash tables it's
perfectly OK to use: we don't high quality entropy in that case, hence
let's use it.
This is only hooked up with 'high_quality_required' is false. If we
require high quality entropy the kernel is the only source we should
use.
These lines are generally out-of-date, incomplete and unnecessary. With
SPDX and git repository much more accurate and fine grained information
about licensing and authorship is available, hence let's drop the
per-file copyright notice. Of course, removing copyright lines of others
is problematic, hence this commit only removes my own lines and leaves
all others untouched. It might be nicer if sooner or later those could
go away too, making git the only and accurate source of authorship
information.
This part of the copyright blurb stems from the GPL use recommendations:
https://www.gnu.org/licenses/gpl-howto.en.html
The concept appears to originate in times where version control was per
file, instead of per tree, and was a way to glue the files together.
Ultimately, we nowadays don't live in that world anymore, and this
information is entirely useless anyway, as people are very welcome to
copy these files into any projects they like, and they shouldn't have to
change bits that are part of our copyright header for that.
hence, let's just get rid of this old cruft, and shorten our codebase a
bit.
Files which are installed as-is (any .service and other unit files, .conf
files, .policy files, etc), are left as is. My assumption is that SPDX
identifiers are not yet that well known, so it's better to retain the
extended header to avoid any doubt.
I also kept any copyright lines. We can probably remove them, but it'd nice to
obtain explicit acks from all involved authors before doing that.
During early boot, we'd call getrandom(), and immediately fall back to
reading from /dev/urandom unless we got the full requested number of bytes.
Those two sources are the same, so the most likely result is /dev/urandom
producing some pseudorandom numbers for us, complaining widely on the way.
Let's change our behaviour to be more conservative:
- if the numbers are only used to initialize a hash table, a short read is OK,
we don't really care if we get the first part of the seed truly random and
then some pseudorandom bytes. So just do that and return "success".
- if getrandom() returns -EAGAIN, fall back to rand() instead of querying
/dev/urandom again.
The idea with those two changes is to avoid generating a warning about
reading from an /dev/urandom when the kernel doesn't have enough entropy.
- only in the cases where we really need to make the best effort possible
(sd_id128_randomize and firstboot password hashing), fall back to
/dev/urandom.
When calling getrandom(), drop the checks whether the argument fits in an int —
getrandom() should do that for us already, and we call it with small arguments
only anyway.
Note that this does not really change the (relatively high) number of random
bytes we request from the kernel. On my laptop, during boot, PID 1 and all
other processes using this code through libsystemd request:
74780 bytes with high_quality_required == false
464 bytes with high_quality_required == true
and it does not eliminate reads from /dev/urandom completely. If the kernel was
short on entropy and getrandom() would fail, we would fall back to /dev/urandom
for those 464 bytes.
When falling back to /dev/urandom, don't lose the short read we already got,
and just read the remaining bytes.
If getrandom() syscall is not available, we fall back to /dev/urandom same
as before.
Fixes#4167 (possibly partially, let's see).
The only implementation that we care about — glibc — provides us
with 31 bits of entropy. Let's use 24 bits of that, instead of throwing
all but 8 away.