]> git.ipfire.org Git - thirdparty/systemd.git/blame - docs/RANDOM_SEEDS.md
docs: fix grammar a bit
[thirdparty/systemd.git] / docs / RANDOM_SEEDS.md
CommitLineData
93f59100
LP
1---
2title: Random Seeds
4cdca0af 3category: Concepts
b41a3f66 4layout: default
0aff7b75 5SPDX-License-Identifier: LGPL-2.1-or-later
93f59100
LP
6---
7
8# Random Seeds
9
10systemd can help in a number of ways with providing reliable, high quality
11random numbers from early boot on.
12
13## Linux Kernel Entropy Pool
14
15Today's computer systems require random number generators for numerous
16cryptographic and other purposes. On Linux systems, the kernel's entropy pool
17is typically used as high-quality source of random numbers. The kernel's
18entropy pool combines various entropy inputs together, mixes them and provides
19an API to userspace as well as to internal kernel subsystems to retrieve
20it. This entropy pool needs to be initialized with a minimal level of entropy
21before it can provide high quality, cryptographic random numbers to
22applications. Until the entropy pool is fully initialized application requests
23for high-quality random numbers cannot be fulfilled.
24
25The Linux kernel provides three relevant userspace APIs to request random data
26from the kernel's entropy pool:
27
e2285c57 28* The [`getrandom()`](https://man7.org/linux/man-pages/man2/getrandom.2.html)
e347d53a 29 system call with its `flags` parameter set to 0. If invoked, the calling
93f59100
LP
30 program will synchronously block until the random pool is fully initialized
31 and the requested bytes can be provided.
32
33* The `getrandom()` system call with its `flags` parameter set to
e347d53a 34 `GRND_NONBLOCK`. If invoked, the request for random bytes will fail if the
93f59100
LP
35 pool is not initialized yet.
36
37* Reading from the
e2285c57 38 [`/dev/urandom`](https://man7.org/linux/man-pages/man4/urandom.4.html)
93f59100
LP
39 pseudo-device will always return random bytes immediately, even if the pool
40 is not initialized. The provided random bytes will be of low quality in this
e347d53a 41 case however. Moreover, the kernel will log about all programs using this
93f59100
LP
42 interface in this state, and which thus potentially rely on an uninitialized
43 entropy pool.
44
e347d53a 45(Strictly speaking, there are more APIs, for example `/dev/random`, but these
93f59100
LP
46should not be used by almost any application and hence aren't mentioned here.)
47
48Note that the time it takes to initialize the random pool may differ between
49systems. If local hardware random number generators are available,
50initialization is likely quick, but particularly in embedded and virtualized
51environments available entropy is small and thus random pool initialization
52might take a long time (up to tens of minutes!).
53
54Modern hardware tends to come with a number of hardware random number
55generators (hwrng), that may be used to relatively quickly fill up the entropy
56pool. Specifically:
57
58* All recent Intel and AMD CPUs provide the CPU opcode
59 [RDRAND](https://en.wikipedia.org/wiki/RdRand) to acquire random bytes. Linux
60 includes random bytes generated this way in its entropy pool, but didn't use
61 to credit entropy for it (i.e. data from this source wasn't considered good
62 enough to consider the entropy pool properly filled even though it was
63 used). This has changed recently however, and most big distributions have
64 turned on the `CONFIG_RANDOM_TRUST_CPU=y` kernel compile time option. This
65 means systems with CPUs supporting this opcode will be able to very quickly
66 reach the "pool filled" state.
67
68* The TPM security chip that is available on all modern desktop systems has a
69 hwrng. It is also fed into the entropy pool, but generally not credited
70 entropy. You may use `rng_core.default_quality=1000` on the kernel command
71 line to change that, but note that this is a global setting affect all
72 hwrngs. (Yeah, that's weird.)
73
74* Many Intel and AMD chipsets have hwrng chips. Their Linux drivers usually
75 don't credit entropy. (But there's `rng_core.default_quality=1000`, see
76 above.)
77
78* Various embedded boards have hwrng chips. Some drivers automatically credit
79 entropy, others do not. Some WiFi chips appear to have hwrng sources too, and
80 they usually do not credit entropy for them.
81
82* `virtio-rng` is used in virtualized environments and retrieves random data
83 from the VM host. It credits full entropy.
84
85* The EFI firmware typically provides a RNG API. When transitioning from UEFI
86 to kernel mode Linux will query some random data through it, and feed it into
87 the pool, but not credit entropy to it. What kind of random source is behind
88 the EFI RNG API is often not entirely clear, but it hopefully is some kind of
89 hardware source.
90
91If neither of these are available (in fact, even if they are), Linux generates
92entropy from various non-hwrng sources in various subsystems, all of which
93ultimately are rooted in IRQ noise, a very "slow" source of entropy, in
94particular in virtualized environments.
95
96## `systemd`'s Use of Random Numbers
97
98systemd is responsible for bringing up the OS. It generally runs as the first
99userspace process the kernel invokes. Because of that it runs at a time where
100the entropy pool is typically not yet initialized, and thus requests to acquire
101random bytes will either be delayed, will fail or result in a noisy kernel log
102message (see above).
103
104Various other components run during early boot that require random bytes. For
55c041b4
LP
105example, initrds nowadays communicate with encrypted networks or access
106encrypted storage which might need random numbers. systemd itself requires
107random numbers as well, including for the following uses:
93f59100
LP
108
109* systemd assigns 'invocation' UUIDs to all services it invokes that uniquely
e347d53a 110 identify each invocation. This is useful to retain a global handle on a specific
93f59100
LP
111 service invocation and relate it to other data. For example, log data
112 collected by the journal usually includes the invocation UUID and thus the
113 runtime context the service manager maintains can be neatly matched up with
114 the log data a specific service invocation generated. systemd also
115 initializes `/etc/machine-id` with a randomized UUID. (systemd also makes use
116 of the randomized "boot id" the kernel exposes in
117 `/proc/sys/kernel/random/boot_id`). These UUIDs are exclusively Type 4 UUIDs,
118 i.e. randomly generated ones.
119
120* systemd maintains various hash tables internally. In order to harden them
121 against [collision
21385e63 122 attacks](https://www.cs.auckland.ac.nz/~mcw/Teaching/refs/misc/denial-of-service.pdf)
93f59100
LP
123 they are seeded with random numbers.
124
125* At various places systemd needs random bytes for temporary file name
126 generation, UID allocation randomization, and similar.
127
128* systemd-resolved and systemd-networkd use random number generators to harden
129 the protocols they implement against packet forgery.
130
131* systemd-udevd and systemd-nspawn can generate randomized MAC addresses for
132 network devices.
133
134Note that these cases generally do not require a cryptographic-grade random
135number generator, as most of these utilize random numbers to minimize risk of
136collision and not to generate secret key material. However, they usually do
137require "medium-grade" random data. For example: systemd's hash-maps are
138reseeded if they grow beyond certain thresholds (and thus collisions are more
139likely). This means they are generally fine with low-quality (even constant)
140random numbers initially as long as they get better with time, so that
141collision attacks are eventually thwarted as better, non-guessable seeds are
142acquired.
143
144## Keeping `systemd'`s Demand on the Kernel Entropy Pool Minimal
145
146Since most of systemd's own use of random numbers do not require
ffa047a0
JD
147cryptographic-grade RNGs, it tries to avoid blocking reads to the kernel's RNG,
148opting instead for using `getrandom(GRND_INSECURE)`. After the pool is
149initialized, this is identical to `getrandom(0)`, returning cryptographically
150secure random numbers, but before it's initialized it has the nice effect of
151not blocking system boot.
93f59100
LP
152
153## `systemd`'s Support for Filling the Kernel Entropy Pool
154
155systemd has various provisions to ensure the kernel entropy is filled during
156boot, in order to ensure the entropy pool is filled up quickly.
157
1581. When systemd's PID 1 detects it runs in a virtualized environment providing
159 the `virtio-rng` interface it will load the necessary kernel modules to make
160 use of it during earliest boot, if possible — much earlier than regular
161 kernel module loading done by `systemd-udevd.service`. This should ensure
162 that in VM environments the entropy pool is quickly filled, even before
163 systemd invokes the first service process — as long as the VM environment
164 provides virtualized RNG hardware (and VM environments really should!).
165
1662. The
167 [`systemd-random-seed.service`](https://www.freedesktop.org/software/systemd/man/systemd-random-seed.service.html)
168 system service will load a random seed from `/var/lib/systemd/random-seed`
169 into the kernel entropy pool. By default it does not credit entropy for it
170 though, since the seed is — more often than not — not reset when 'golden'
171 master images of an OS are created, and thus replicated into every
172 installation. If OS image builders carefully reset the random seed file
173 before generating the image it should be safe to credit entropy, which can
d35c7741
LP
174 be enabled by setting the `$SYSTEMD_RANDOM_SEED_CREDIT` environment variable
175 for the service to `1` (or even `force`, see man page). Note however, that
176 this service typically runs relatively late during early boot: long after
55c041b4
LP
177 the initrd completed, and after the `/var/` file system became
178 writable. This is usually too late for many applications, it is hence not
179 advised to rely exclusively on this functionality to seed the kernel's
93f59100
LP
180 entropy pool. Also note that this service synchronously waits until the
181 kernel's entropy pool is initialized before completing start-up. It may thus
182 be used by other services as synchronization point to order against, if they
183 require an initialized entropy pool to operate correctly.
184
1853. The
186 [`systemd-boot`](https://www.freedesktop.org/software/systemd/man/systemd-boot.html)
187 EFI boot loader included in systemd is able to maintain and provide a random
188 seed stored in the EFI System Partition (ESP) to the booted OS, which allows
189 booting up with a fully initialized entropy pool from earliest boot
190 on. During installation of the boot loader (or when invoking [`bootctl
191 random-seed`](https://www.freedesktop.org/software/systemd/man/bootctl.html#random-seed))
192 a seed file with an initial seed is placed in a file `/loader/random-seed`
193 in the ESP. In addition, an identically sized randomized EFI variable called
37b22b3b
ZJS
194 the 'system token' is set, which is written to the machine's firmware NVRAM.
195 During boot, when `systemd-boot` finds both the random seed file and the
196 system token they are combined and hashed with SHA256 (in counter mode, to
197 generate sufficient data), to generate a new random seed file to store in
93f59100
LP
198 the ESP as well as a random seed to pass to the OS kernel. The new random
199 seed file for the ESP is then written to the ESP, ensuring this is completed
0be72218
JD
200 before the OS is invoked.
201
202 The kernel then reads the random seed that the boot loader passes to it, via
203 the EFI configuration table entry, `LINUX_EFI_RANDOM_SEED_TABLE_GUID`
204 (1ce1e5bc-7ceb-42f2-81e5-8aadf180f57b), which is allocated with pool memory
205 of type `EfiACPIReclaimMemory`. Its contents have the form:
206 ```
207 struct linux_efi_random_seed {
208 u32 size; // of the 'seed' array in bytes
209 u8 seed[];
210 };
211 ```
212 The size field is generally set to 32 bytes, and the seed field includes a
213 hashed representation of any prior seed in `LINUX_EFI_RANDOM_SEED_TABLE_GUID`
214 together with the new seed.
215
216 This mechanism is able to safely provide an initialized entropy pool before
217 userspace even starts and guarantees that different seeds are passed from
218 the boot loader to the OS on every boot (in a way that does not allow
219 regeneration of an old seed file from a new seed file). Moreover, when an OS
220 image is replicated between multiple images and the random seed is not
221 reset, this will still result in different random seeds being passed to the
222 OS, as the per-machine 'system token' is specific to the physical host, and
223 not included in OS disk images. If the 'system token' is properly
224 initialized and kept sufficiently secret it should not be possible to
225 regenerate the entropy pool of different machines, even if this seed is the
226 only source of entropy.
93f59100
LP
227
228 Note that the writes to the ESP needed to maintain the random seed should be
0be72218
JD
229 minimal. Because the size of the random seed file is generally set to 32 bytes,
230 updating the random seed in the ESP should be doable safely with a single
231 sector write (since hard-disk sectors typically happen to be 512 bytes long,
232 too), which should be safe even with FAT file system drivers built into
93f59100
LP
233 low-quality EFI firmwares.
234
18d9cee0
LP
2354. A kernel command line option `systemd.random_seed=` may be used to pass in a
236 base64 encoded seed to initialize the kernel's entropy pool from during
237 early service manager initialization. This option is only safe in testing
238 environments, as the random seed passed this way is accessible to
239 unprivileged programs via `/proc/cmdline`. Using this option outside of
240 testing environments is a security problem since cryptographic key material
241 derived from the entropy pool initialized with a seed accessible to
242 unprivileged programs should not be considered secret.
243
244With the four mechanisms described above it should be possible to provide
93f59100
LP
245early-boot entropy in most cases. Specifically:
246
2471. On EFI systems, `systemd-boot`'s random seed logic should make sure good
248 entropy is available during earliest boot — as long as `systemd-boot` is
249 used as boot loader, and outside of virtualized environments.
250
2512. On virtualized systems, the early `virtio-rng` hookup should ensure entropy
252 is available early on — as long as the VM environment provides virtualized
253 RNG devices, which they really should all do in 2019. Complain to your
18d9cee0
LP
254 hosting provider if they don't. For VMs used in testing environments,
255 `systemd.random_seed=` may be used as an alternative to a virtualized RNG.
93f59100 256
ffa047a0
JD
2573. In general, systemd's own reliance on the kernel entropy pool is minimal
258 (due to the use of `GRND_INSECURE`).
93f59100
LP
259
2604. In all other cases, `systemd-random-seed.service` will help a bit, but — as
261 mentioned — is too late to help with early boot.
262
263This primarily leaves two kind of systems in the cold:
264
2651. Some embedded systems. Many embedded chipsets have hwrng functionality these
266 days. Consider using them while crediting
267 entropy. (i.e. `rng_core.default_quality=1000` on the kernel command line is
268 your friend). Or accept that the system might take a bit longer to
269 boot. Alternatively, consider implementing a solution similar to
270 systemd-boot's random seed concept in your platform's boot loader.
271
18d9cee0
LP
2722. Virtualized environments that lack both virtio-rng and RDRAND, outside of
273 test environments. Tough luck. Talk to your hosting provider, and ask them
274 to fix this.
93f59100
LP
275
2763. Also note: if you deploy an image without any random seed and/or without
277 installing any 'system token' in an EFI variable, as described above, this
278 means that on the first boot no seed can be passed to the OS
279 either. However, as the boot completes (with entropy acquired elsewhere),
280 systemd will automatically install both a random seed in the GPT and a
281 'system token' in the EFI variable space, so that any future boots will have
282 entropy from earliest boot on — all provided `systemd-boot` is used.
283
284## Frequently Asked Questions
285
2861. *Why don't you just use getrandom()? That's all you need!*
287
288 Did you read any of the above? getrandom() is hooked to the kernel entropy
289 pool, and during early boot it's not going to be filled yet, very likely. We
290 do use it in many cases, but not in all. Please read the above again!
291
2922. *Why don't you use
e2285c57 293 [getentropy()](https://man7.org/linux/man-pages/man3/getentropy.3.html)? That's
93f59100
LP
294 all you need!*
295
296 Same story. That call is just a different name for `getrandom()` with
297 `flags` set to zero, and some additional limitations, and thus it also needs
298 the kernel's entropy pool to be initialized, which is the whole problem we
299 are trying to address here.
300
3013. *Why don't you generate your UUIDs with
e2285c57 302 [`uuidd`](https://man7.org/linux/man-pages/man8/uuidd.8.html)? That's all you
93f59100
LP
303 need!*
304
305 First of all, that's a system service, i.e. something that runs as "payload"
306 of systemd, long after systemd is already up and hence can't provide us
307 UUIDs during earliest boot yet. Don't forget: to assign the invocation UUID
308 for the `uuidd.service` start we already need a UUID that the service is
309 supposed to provide us. More importantly though, `uuidd` needs state/a random
310 seed/a MAC address/host ID to operate, all of which are not available during
311 early boot.
312
3134. *Why don't you generate your UUIDs with `/proc/sys/kernel/random/uuid`?
314 That's all you need!*
315
316 This is just a different, more limited interface to `/dev/urandom`. It gains
317 us nothing.
318
3195. *Why don't you use [`rngd`](https://github.com/nhorman/rng-tools),
320 [`haveged`](http://www.issihosts.com/haveged/),
321 [`egd`](http://egd.sourceforge.net/)? That's all you need!*
322
323 Like `uuidd` above these are system services, hence come too late for our
324 use-case. In addition much of what `rngd` provides appears to be equivalent
325 to `CONFIG_RANDOM_TRUST_CPU=y` or `rng_core.default_quality=1000`, except
326 being more complex and involving userspace. These services partly measure
327 system behavior (such as scheduling effects) which the kernel either
328 already feeds into its pool anyway (and thus shouldn't be fed into it a
329 second time, crediting entropy for it a second time) or is at least
330 something the kernel could much better do on its own. Hence, if what these
331 daemons do is still desirable today, this would be much better implemented
332 in kernel (which would be very welcome of course, but wouldn't really help
333 us here in our specific problem, see above).
334
3356. *Why don't you use [`arc4random()`](https://man.openbsd.org/arc4random.3)?
336 That's all you need!*
337
338 This doesn't solve the issue, since it requires a nonce to start from, and
339 it gets that from `getrandom()`, and thus we have to wait for random pool
340 initialization the same way as calling `getrandom()`
341 directly. `arc4random()` is nothing more than optimization, in fact it
342 implements similar algorithms that the kernel entropy pool implements
343 anyway, hence besides being able to provide random bytes with higher
344 throughput there's little it gets us over just using `getrandom()`. Also,
345 it's not supported by glibc. And as long as that's the case we are not keen
346 on using it, as we'd have to maintain that on our own, and we don't want to
347 maintain our own cryptographic primitives if we don't have to. Since
348 systemd's uses are not performance relevant (besides the pool initialization
349 delay, which this doesn't solve), there's hence little benefit for us to
350 call these functions. That said, if glibc learns these APIs one day, we'll
351 certainly make use of them where appropriate.
352
3537. *This is boring: NetBSD had [boot loader entropy seed
354 support](https://netbsd.gw.com/cgi-bin/man-cgi?boot+8) since ages!*
355
356 Yes, NetBSD has that, and the above is inspired by that (note though: this
357 article is about a lot more than that). NetBSD's support is not really safe,
358 since it neither updates the random seed before using it, nor has any
359 safeguards against replicating the same disk image with its random seed on
360 multiple machines (which the 'system token' mentioned above is supposed to
361 address). This means reuse of the same random seed by the boot loader is
362 much more likely.
363
3648. *Why does PID 1 upload the boot loader provided random seed into kernel
365 instead of kernel doing that on its own?*
366
367 That's a good question. Ideally the kernel would do that on its own, and we
368 wouldn't have to involve userspace in this.
369
3709. *What about non-EFI?*
371
372 The boot loader random seed logic described above uses EFI variables to pass
373 the seed from the boot loader to the OS. Other systems might have similar
374 functionality though, and it shouldn't be too hard to implement something
375 similar for them. Ideally, we'd have an official way to pass such a seed as
376 part of the `struct boot_params` from the boot loader to the kernel, but
377 this is currently not available.
378
37910. *I use a different boot loader than `systemd-boot`, I'd like to use boot
380 loader random seeds too!*
381
382 Well, consider just switching to `systemd-boot`, it's worth it. See
383 [systemd-boot(7)](https://www.freedesktop.org/software/systemd/man/systemd-boot.html)
384 for an introduction why. That said, any boot loader can re-implement the
385 logic described above, and can pass a random seed that systemd as PID 1
5c90c67a
BF
386 will then upload into the kernel's entropy pool. For details see the
387 [Boot Loader Interface](BOOT_LOADER_INTERFACE.md) documentation.
93f59100
LP
388
38911. *Why not pass the boot loader random seed via kernel command line instead
390 of as EFI variable?*
391
392 The kernel command line is accessible to unprivileged processes via
393 `/proc/cmdline`. It's not desirable if unprivileged processes can use this
394 information to possibly gain too much information about the current state
395 of the kernel's entropy pool.
396
18d9cee0
LP
397 That said, we actually do implement this with the `systemd.random_seed=`
398 kernel command line option. Don't use this outside of testing environments,
399 however, for the aforementioned reasons.
400
93f59100
LP
40112. *Why doesn't `systemd-boot` rewrite the 'system token' too each time
402 when updating the random seed file stored in the ESP?*
403
404 The system token is stored as persistent EFI variable, i.e. in some form of
405 NVRAM. These memory chips tend be of low quality in many machines, and
406 hence we shouldn't write them too often. Writing them once during
407 installation should generally be OK, but rewriting them on every single
408 boot would probably wear the chip out too much, and we shouldn't risk that.