Linux – Why is the random seed only saved to disk on boot and shutdown

linuxrandom

On my system, there's /var/lib/systemd/random-seed. On boot, it's loaded it into the entropy pool and replaced with a new one. On shutdown, entropy is saved to it. I didn't find anything changing it in between.

If there is a computer that only shuts down in power losses, then the entropy it gathers will not be written to disk. Thus it will take time to gather entropy when recovering from power loss.

Why isn't entropy saved to disk during normal operation, like once a day?

Best Answer

It helps to stop thinking about this as "entropy". This isn't anything to do with entropy, and mistakenly thinking about pseudo-random number generation in terms of entropy is the root of many misconceptions about this subject. So stop thinking about "entropy".

This is, as the name states, a seed value for a pseudo-random number generator.

The thing to remember about PRNGs is that they are not random. They are entirely deterministic. If one knows the initial input values and the particular PRNG algorithm, one can determine every single future "random" output value.

In this case, the algorithm is well known. It is after all, published as part of an open source kernel. So the key to randomness is the seed. The level of "randomness" that is provided is unpredictability, from one output to the next. Knowing the algorithm and the previous outputs but not the seed, it is unfeasibly hard to predict what the next random output will be. (This is not a formal nor a complete definition of what it means for a PRNG to be cryptographically secure; but will do as a limited approximation for the purposes of this answer.)

This is the basic reason for the widely-discussed problems with Linux's /dev/urandom, which I am just going to gloss over here. At bootstrap, the seed is also well known. The random outputs are all entirely predictable until the PRNG is re-seeded, i.e. supplied with a fresh seed that is unique (or as near as one can get) to that run of that operating system installation, for the first time.

And that's what /var/lib/systemd/random-seed (on systemd operating systems), /var/lib/urandom/random-seed (on non-systemd Linux operating systems), and /var/db/entropy-file (on FreeBSD/TrueOS) are all about: holding a re-seed value that can be applied, as that first re-seed value, as soon as possible after the next bootstrap.

The important thing is that once it has been used at bootstrap, it is immediately replaced with another, different, seed value. This is, as you surmise, so that if the system is not shut down cleanly, it does not re-boot with the same seed value as at the preceding bootstrap.

As such, changing it between bootstrap and shutdown is fairly pointless. It has to be changed immediately after it has been read and used, and the replacement kept secret during the lifetime of this run of the operating system. But there's no point in updating it repeatedly in the meantime, unless its value has been exposed somehow.

The seed value is not some sort of accrued "entropy". It is a secret. It is the seed value for the next run of the PRNG. It should not be exposed outwith the Trusted Computing Base, and it should be hard to predict. Ironically, because it only need be unpredictable it can actually be the output of the PRNG itself, and that is in fact the case with tools like systemd-random-seed, which take output from the re-seeded PRNG to use as the next seed value at the next bootstrap.

So the rationale for changing it at shutdown is that if the next seed value has been exposed somehow during the runtime of the operating system, replacing it at shutdown makes it a little harder for an attacker to learn what the PRNG is next going to be seeded with.

And that includes being exposed because it is predictable. In theory, if you know that each seed is taken from immediately running the PRNG against the previous seed, then knowing any seed allows you to determine all subsequent seeds. Fortunately, the PRNG is also periodically further re-seeded as the operating system runs, from other seed sources, so the next seed value that is taken from the PRNG output and stored at shutdown is not predictable even if one knows the previous seed that was used at bootstrap for the current run of the operating system.

This secrecy extends to not duplicating it when you "clone" systems from central common images.

So, to recap: The next seed value is not "entropy". It does not accrue in any meaningful sense, and so does not need building up, in some fashion, or "refreshing" at runtime. It needs to be replaced immediately upon use, and in order to make the sequence of seeds themselves an unpredictable sequence, as otherwise the next seed is the entirely predictable output of the PRNG and the last seed, it also should be updated from the PRNG output, once, at some point after the PRNG has been re-seeded a second time, for which shutdown time is a good (but not perfect) approximation, given that sometime between startup and shutdown the operating system will do its own re-seeding.

Further reading