3

On embedded systems, read-only filesystems are common. Read-only means that /var/lib/systemd/random-seed cannot be updated on reboot, and is probably a clone of another device's random-seed.

Does this have significant security or other impacts, and if so, how should one mitigate?

Perhaps:

  • Creating a new random-seed per device would be a partial mitigation? Still it could not be updated on reboot
  • Going to great lengths to set up a random-seed file early in boot in a tmpfs? Not sure how to do this
  • Ignoring the problem?
1
  • Another option besides the excellent answers below is to check out haveged ... (but don't do it blindly, read the pros and cons) Commented May 20, 2021 at 1:34

2 Answers 2

4

Bad entropy is a common problem on some classes of embedded devices. It is a serious security risk. Unfortunately there isn't a single solution that works for all devices.

Note: I'm a professional security architect of embedded devices, but usually working with devices that are too small for systemd or even Linux. I don't know much about systemd.

Why do I need entropy?

A lot of security relies on cryptography. A lot of cryptography relies on knowing something that others don't. If you have a device whose state is fully known, for example a newly installed system which is running a deterministic processor, everyone knows the state of your device and so there's no way for the device to know something that an adversary wouldn't know. The device needs to either start out knowing something nobody else knows, or to have a way to generate some information that nobody else knows. That's entropy.

Entropy is needed, for example, to ensure that the data you exchange with a website can't be snooped on, that the data you exchange with a website can't be faked, that your WiFi password can't be snooped on, etc.

As soon as entropy is available on a system, a deterministic random generator (i.e. a software algorithm) can produce an unlimited amount of secret data that nobody else knows. But no deterministic process can produce entropy out of nothing. In principle, deterministic random generation is a solved problem (though implementations can be buggy).

A 2012 study showed that a small but non-negligible proportion of Internet-connected devices were insecure due to a bad random generator. Keep in mind that they just tested a few particular ways in which a bad random generator would be visible. The study missed a lot of other ways a bad RNG could cause problems, but conversely some RNG problems may have been due to software bugs rather than a lack of entropy.

How can I get entropy?

The most robust solution is to have a special-purpose hardware component: a hardware random number generator (HRNG)¹. Most if not all recent PC and smartphone processors have one, some embedded boards have one (as far as I know all Raspberry Pi models have one), but they're less common on lower-end devices (such as home routers). And even when a device has an HRNG, Linux doesn't always have a driver for it.

Without a special-purpose hardware component, it's possible to generate entropy from unpredictable events. The problem is that unpredictable events are hard to quantify, and tend to be rare on embedded devices. For example, spinning hard drives have some unpredictability in their precise response times, but embedded devices usually don't have a spanning hard drive. Complex processors designed for high speeds tend to have unpredictable clock jitter, but cheap or low-power devices don't have much jitter. The timing of user events such as key strokes introduces some unpredictability, but embedded devices tend not to have a physical user. Some devices such as camera sensors and microphones are good at producing entropy from noise, at least if the ambient conditions are right, but not many devices don't have any suitable sensor.

Another way to provide entropy to a device that doesn't have a way to generate it, is to inject it during manufacturing. Run a HRNG on your assembly line, and inject a distinct file with random data onto every device. Then, each time the device boots, it must update this random data. This random data is the random seed you're asking about.

All Linux systems normally have a random seed. It's absolutely necessary on devices that don't have another source of entropy, and nice to have even on devices that do have another source of entropy.

The random seed must not be shared with any other device, and it must not repeat when the device reboots. The way it should work is that the seed is either injected during manufacturing or generated from entropy during the device installation, and then each time the device boots it calculates and saves a new seed.

What can I do if my device was installed without entropy?

If you have command line access to a Linux system, you can inject entropy by writing to /dev/urandom. For example, if you have an SSH connection from a PC to the device:

head -c 99 /dev/urandom | ssh mydevice 'cat >/dev/urandom'

Note that there's a bootstrap problem: as long as the device has no entropy, it cannot securely generate an SSH host key, and it's also vulnerable to replay attacks from networked attackers. So you should do this before the device is exposed to untrusted connections. And if you have any keys that were generated with poor entropy, re-generate them once sufficient entropy is available.

After generating extra entropy, make sure to update the random seed in storage. I think you can do that by restarting the systemd-random-seed service, but I don't know that for sure and I find the documentation of systemd unclear.

What can I do if my device doesn't have a persistent random seed?

If your device has a HRNG, you're fine. Otherwise you're in trouble.

If your device has enough ways to collect entropy from non-dedicated peripherals, you may be fine. The problem is that it's difficult to measure.

/var/lib/systemd/random-seed must be in persistent storage, otherwise it defeats the purpose. “Saving” a random seed on tmpfs would be pointless.

Many embedded devices have a small amount of NVRAM. Saving a random seed at each boot is a good use of this NVRAM, if the maximum write count allows it. I don't know how to configure systemd for that.

If the device is connected to a wired network in a physically secure environment, retrieving entropy from a trusted machine in the same physical location may be an option.

If you have a secret that's unique to your device but can't be rewritten at each boot, you can combine this secret with the time at boot time. But note that this is a last resort.

{ date +%s; cat /path/to/static/seed; } | sha256sum >/dev/urandom

This produces an acceptable seed as long as the date is not repeated. But if your device loses power and forgets the time, i.e. if it reboots “blinking twelve” thinking it's 2000-01-01 at 00:00:00, this produces the same seed over and over, which opens your device to network-based attacks which may be more or less easy depending on what the device does.

¹ Disclaimer: while my employer does not make such devices, it indirectly stands to gain if more embedded devices are equipped with an HRNG. But I'd personally still recommend an HRNG if my employer's main business was a consultancy that stands to gain by helping people recover from attacks.

5
  • This is an excellent answer and basically solves the problem two ways. One: Get random-seed into persistent, rw storage. Alt / two: { date +%s; cat /path/to/static/seed; } | sha256sum >/dev/urandom. Bravo. Commented May 19, 2021 at 22:39
  • Per your server comment, could I (perhaps during boot) reach out to a server that dumps bytes from /dev/urandom into the response? Would it be sufficient to do something like curl my-server.org/random_bytes >> /dev/urandom a few times? And maybe while I'm at it curl my-server.org/random_bytes > /var/lib/systemd/random-seed Commented May 24, 2021 at 18:01
  • Just once is enough, but there's a major caveat: you need to download from a link that is physically protected. Without randomness, the connection would be vulnerable to a man-in-the-middle attack. TLS without randomness protects against a passive adversary, but not against an active adversary (i.e. an adversary who can inject network packets). Commented May 24, 2021 at 19:47
  • Oh interesting. You need a completely isolated wire to a server I didn't think of that. That's strict. So, It's best to ensure you have a HRNG. Commented May 24, 2021 at 22:13
  • I break the rule of "vote and keep silent" :), this is very well written and a joy to read. Commented May 31, 2021 at 21:08
0

Ignore.

While random seeds may be common across systems, they're not the only input to generating "randomness'.

Identical seeds mean that the pseudo-random number generators start their pseudo-random number sequences at the same value.

Over time, data is distilled from system actions, time, etc. and is fed to the pseudo-random number generator. These inputs to pseudo-random number generation differ across systems, so the pseudo-random number sequences quickly diverge.

Pseudo-random number generation is a subfield studied in Math/Computer Science.

6
  • I like ignoring problems. Do you have a link to a method for the build up of entropy, that shows how random-seed fits into that? Commented May 19, 2021 at 18:04
  • 1
    I agree with the answer, The problem might be trying to generate enough random bits for for making HTTPS connection. Try "cat /proc/sys/kernel/random/entropy_avail" on the embedded system. For comparison, on my I5 the number is roughly: 3677 but it drops when I make a SSH or HTTPS connection - to somewhere slighly above 2048. Commented May 19, 2021 at 21:48
  • A PC with a fast processor, a spinning hard drive and a human typing on a keyboard will produce entropy reasonably quickly, though the initial installation could be a problem. An embedded device with none of this won't produce entropy quickly. And the whole point of the question is what to do if the entropy pool is empty each time the device boots. Note that Linux's “available entropy” count is pretty much bogus, it doesn't really say anything about the presence of actual entropy: entropy can't be measured. Cc @CinaedSimson Commented May 19, 2021 at 22:25
  • Pseudo-random number generation is irrelevant here. This question is about seeding the PRNG. Commented May 19, 2021 at 22:25
  • But "PRNG" stands for Pseudo-Random Number Generator. "Anyone who attempts to generate random numbers by deterministic means is, of course, living in a state of sin." —John von Neumann (1951) Commented May 19, 2021 at 23:21

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.