Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

beef up random seed logic, add boot loader entropy privisioning, improve docs about it #13137

Merged
merged 26 commits into from Jul 26, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
63d59b8
fs-util: add fsync_full() helper
poettering Jul 22, 2019
5373172
xattr-util: document that we NUL suffix
poettering Jul 22, 2019
1aaabb1
efi: modernize file_read() a bit
poettering Jul 18, 2019
b19fa81
efi: add log_oom() helper
poettering Jul 18, 2019
c242a08
efivars: modernize efi_get_variable() a bit
poettering Jul 19, 2019
5509f91
bootctl: use the fact that startswith() returns the suffix
poettering Jul 19, 2019
b461576
bootctl: drop const from non-pointer function argument
poettering Jul 19, 2019
7c122df
bootctl: shortcut configuration file parsing
poettering Jul 19, 2019
22c5ff5
bootctl: add new feature flag for indicating random seed management s…
poettering Jul 18, 2019
073220b
efi: steal glibc sha256 implementation
poettering Jul 19, 2019
e4dcf7a
sd-boot: read random seed from ESP and pass it to OS
poettering Jul 18, 2019
c18ecf0
core: take random seed from boot loader and credit it to kernel entro…
poettering Jul 19, 2019
3e155eb
random-seed: move pool size determination to random-util.[ch]
poettering Jul 19, 2019
e44c322
bootctl: add new verb for initializing a random seed in the ESP
poettering Jul 19, 2019
d6e9a34
bootctl: show random seed state
poettering Jul 19, 2019
d985064
units: automatically initialize the system token if that makes sense
poettering Jul 19, 2019
15d961b
random-seed: reduce scope of variable
poettering Jul 22, 2019
c6127c3
random-seed: drop falling back to O_WRONLY if O_RDWR on /dev/urandom …
poettering Jul 22, 2019
26ded55
random-seed: rework systemd-random-seed.service substantially
poettering Jul 22, 2019
c7bb4df
docs: document new random seed EFI vars as part of the boot loader in…
poettering Jul 22, 2019
39867bb
man: document the systemd-random-seed rework
poettering Jul 22, 2019
a2aa605
bootctl: add is-installed verb
poettering Jul 22, 2019
7fb0c61
man: extend on the --print-boot-path description a bit
poettering Jul 22, 2019
93f5910
docs: add longer document about systemd and random number seeds
poettering Jul 22, 2019
341fd87
TODO: remove apparently fixed issue from TODO
poettering Jul 22, 2019
312dc15
update TODO
poettering Jul 22, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 18 additions & 4 deletions man/bootctl.xml
Expand Up @@ -45,15 +45,15 @@
<varlistentry>
<term><option>--esp-path=</option></term>
<listitem><para>Path to the EFI System Partition (ESP). If not specified, <filename>/efi/</filename>,
<filename>/boot/</filename>, and <filename>/boot/efi</filename> are checked in turn. It is recommended to mount
the ESP to <filename>/efi/</filename>, if possible.</para></listitem>
<filename>/boot/</filename>, and <filename>/boot/efi/</filename> are checked in turn. It is
recommended to mount the ESP to <filename>/efi/</filename>, if possible.</para></listitem>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if the time has come to relax this, and accept that everybody mounts it on /boot/efi...

</varlistentry>

<varlistentry>
<term><option>--boot-path=</option></term>
<listitem><para>Path to the Extended Boot Loader partition, as defined in the <ulink
url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot Loader Specification</ulink>. If not
specified, <filename>/boot/</filename> are checked. It is recommended to mount the Extended Boot
specified, <filename>/boot/</filename> is checked. It is recommended to mount the Extended Boot
Loader partition to <filename>/boot/</filename>, if possible.</para></listitem>
</varlistentry>

Expand Down Expand Up @@ -124,6 +124,19 @@
and the firmware's boot loader list.</para></listitem>
</varlistentry>

<varlistentry>
<term><option>random-seed</option></term>

<listitem><para>Generates a random seed and stores it in the EFI System Partition, for use by the
<command>systemd-boot</command> boot loader. Also, generates a random 'system token' and stores it
persistently as an EFI variable, if one has not been set before. If the boot loader finds the random
seed in the ESP and the system token in the EFI variable it will derive a random seed to pass to the
OS and a new seed to store in the ESP from the combination of both. The random seed passed to the OS
is credited to the kernel's entropy pool by the system manager during early boot, and permits
userspace to boot up with an entropy pool fully initialized very early on. Also see
<citerefentry><refentrytitle>systemd-boot-system-token.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para></listitem>
</varlistentry>

<varlistentry>
<term><option>list</option></term>

Expand Down Expand Up @@ -165,7 +178,8 @@
<para>
<citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<ulink url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot Loader Specification</ulink>,
<ulink url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink>
<ulink url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink>,
<citerefentry><refentrytitle>systemd-boot-system-token.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>
16 changes: 16 additions & 0 deletions man/loader.conf.xml
Expand Up @@ -153,6 +153,22 @@
<listitem><para>Takes a boolean argument. Enable (the default) or disable
the "Reboot into firmware" entry.</para></listitem>
</varlistentry>

<varlistentry>
<term>random-seed-mode</term>

<listitem><para>Takes one of <literal>off</literal>, <literal>with-system-token</literal> and
<literal>always</literal>. If <literal>off</literal> no random seed data is read off the ESP, nor
passed to the OS. If <literal>with-system-token</literal> (the default)
<command>systemd-boot</command> will read a random seed from the ESP (from the file
<filename>/loader/random-seed</filename>) only if the <varname>LoaderSystemToken</varname> EFI
variable is set, and then derive the random seed to pass to the OS from the combination. If
<literal>always</literal> the boot loader will do so even if <varname>LoaderSystemToken</varname> is
not set. This mode is useful in environments where protection against OS image reuse is not a
concern, and the random seed shall be used even with no further setup in place. User <command>bootctl
random-seed</command> to initialize both the random seed file in the ESP and the system token EFI
variable.</para></listitem>
</varlistentry>
</variablelist>
</refsect1>

Expand Down
1 change: 1 addition & 0 deletions man/rules/meson.build
Expand Up @@ -655,6 +655,7 @@ manpages = [
['systemd-bless-boot-generator', '8', [], 'ENABLE_EFI'],
['systemd-bless-boot.service', '8', [], 'ENABLE_EFI'],
['systemd-boot-check-no-failures.service', '8', [], ''],
['systemd-boot-system-token.service', '8', [], 'ENABLE_EFI'],
['systemd-boot', '7', ['sd-boot'], 'ENABLE_EFI'],
['systemd-cat', '1', [], ''],
['systemd-cgls', '1', [], ''],
Expand Down
76 changes: 76 additions & 0 deletions man/systemd-boot-system-token.service.xml
@@ -0,0 +1,76 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1+ -->

<refentry id="systemd-boot-system-token.service" conditional='ENABLE_EFI'
xmlns:xi="http://www.w3.org/2001/XInclude">

<refentryinfo>
<title>systemd-boot-system-token.service</title>
<productname>systemd</productname>
</refentryinfo>

<refmeta>
<refentrytitle>systemd-boot-system-token.service</refentrytitle>
<manvolnum>8</manvolnum>
</refmeta>

<refnamediv>
<refname>systemd-boot-system-token.service</refname>
<refpurpose>Generate an initial boot loader system token and random seed</refpurpose>
</refnamediv>

<refsynopsisdiv>
<para><filename>systemd-boot-system-token.service</filename></para>
</refsynopsisdiv>

<refsect1>
<title>Description</title>

<para><filename>systemd-boot-system-token.service</filename> is a system service that automatically
generates a 'system token' to store in an EFI variable in the system's NVRAM and a random seed to store
on the EFI System Partition ESP on disk. The boot loader may then combine these two randomized data
fields by cryptographic hashing, and pass it to the OS it boots as initialization seed for its entropy
pool. The random seed stored in the ESP is refreshed on each reboot ensuring that multiple subsequent
boots will boot with different seeds. The 'system token' is generated randomly once, and then
persistently stored in the system's EFI variable storage.</para>

<para>The <filename>systemd-boot-system-token.service</filename> unit invokes the <command>bootctl
random-seed</command> command, which updates the random seed in the ESP, and initializes the 'system
token' if it's not initialized yet. The service is conditionalized so that it is run only when all of the
below apply:</para>

<itemizedlist>
<listitem><para>A boot loader is used that implements the <ulink
url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink> (which defines the 'system
token' concept).</para></listitem>

<listitem><para>Either a 'system token' was not set yet, or the boot loader has not passed the OS a
random seed yet (and thus most likely has been missing the random seed file in the
ESP).</para></listitem>

<listitem><para>The system is not running in a VM environment. This case is explicitly excluded since
on VM environments the ESP backing storage and EFI variable storage is typically not physically
separated and hence booting the same OS image in multiple instances would replicate both, thus reusing
the same random seed and 'system token' among all instances, which defeats its purpose. Note that it's
still possible to use boot loader random seed provisioning in this mode, but the automatic logic
implemented by this service has no effect then, and the user instead has to manually invoke the
<command>bootctl random-seed</command> acknowledging these restrictions.</para></listitem>
</itemizedlist>

<para>For further details see
<citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>, regarding
the command this service invokes.</para>
</refsect1>

<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>
</para>
</refsect1>

</refentry>
102 changes: 84 additions & 18 deletions man/systemd-boot.xml
Expand Up @@ -28,13 +28,14 @@
manager. It provides a graphical menu to select the entry to boot and an editor for the kernel command
line. <command>systemd-boot</command> supports systems with UEFI firmware only.</para>

<para>systemd-boot loads boot entry information from the EFI system partition (ESP), usually mounted at
<filename>/efi/</filename>, <filename>/boot/</filename>, or <filename>/boot/efi/</filename> during OS
runtime, as well as from the Extended Boot Loader partition if it exists (usually mounted to
<filename>/boot/</filename>). Configuration file fragments, kernels, initrds and other EFI images to boot
generally need to reside on the ESP or the Extended Boot Loader partition. Linux kernels must be built
with <option>CONFIG_EFI_STUB</option> to be able to be directly executed as an EFI image. During boot
systemd-boot automatically assembles a list of boot entries from the following sources:</para>
<para><command>systemd-boot</command> loads boot entry information from the EFI system partition (ESP),
usually mounted at <filename>/efi/</filename>, <filename>/boot/</filename>, or
<filename>/boot/efi/</filename> during OS runtime, as well as from the Extended Boot Loader partition if
it exists (usually mounted to <filename>/boot/</filename>). Configuration file fragments, kernels,
initrds and other EFI images to boot generally need to reside on the ESP or the Extended Boot Loader
partition. Linux kernels must be built with <option>CONFIG_EFI_STUB</option> to be able to be directly
executed as an EFI image. During boot <command>systemd-boot</command> automatically assembles a list of
boot entries from the following sources:</para>

<itemizedlist>
<listitem><para>Boot entries defined with <ulink
Expand All @@ -57,17 +58,50 @@
<listitem><para>A reboot into the UEFI firmware setup option, if supported by the firmware</para></listitem>
</itemizedlist>

<para><citerefentry><refentrytitle>kernel-install</refentrytitle><manvolnum>8</manvolnum></citerefentry>
may be used to copy kernel images onto the ESP or the Extended Boot Loader Partition and to generate
description files compliant with the Boot Loader
Specification. <citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
<para><command>systemd-boot</command> supports the following features:</para>

<itemizedlist>
<listitem><para>Basic boot manager configuration changes (such as timeout
configuration, default boot entry selection, …) may be made directly from the boot loader UI at
boot-time, as well as during system runtime with EFI variables.</para></listitem>

<listitem><para>The boot manager integrates with the <command>systemctl</command> command to implement
features such as <command>systemctl reboot --boot-loader-entry=…</command> (for rebooting into a
specific boot menu entry, i.e. "reboot into Windows") and <command>systemctl reboot
--boot-loader-menu=…</command> (for rebooting into the boot loader menu), by implementing the <ulink
url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink>. See
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> for
details.</para></listitem>

<listitem><para>An EFI variable set by the boot loader informs the OS about the ESP partition used
during boot. This is then used to automatically mount the correct ESP partition to
<filename>/efi/</filename> or <filename>/boot/</filename> during OS runtime. See
<citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
for details.</para></listitem>

<listitem><para>The boot manager provides information about the boot time spent in UEFI firmware using
the <ulink url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink>. This
information can be displayed using
<citerefentry><refentrytitle>systemd-analyze</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
</para></listitem>

<listitem><para>The boot manager implements boot counting and automatic fallback to older, working boot
entries on failure. See <ulink url="https://systemd.io/AUTOMATIC_BOOT_ASSESSMENT">Automatic Boot
Assessment</ulink>.</para></listitem>

<listitem><para>The boot manager optionally reads a random seed from the ESP partition, combines it
with a 'system token' stored in a persistant EFI variable and derives a random seed to use by the OS as
entropy pool initializaton, providing a full entropy pool during early boot.</para></listitem>
</itemizedlist>

<para><citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
may be used from a running system to locate the ESP and the Extended Boot Loader Partition, list
available entries, and install <command>systemd-boot</command> itself.</para>

<para>systemd-boot will provide information about the time spent in UEFI firmware using the <ulink
url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink>. This information can be displayed
using <citerefentry><refentrytitle>systemd-analyze</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
</para>
<para><citerefentry><refentrytitle>kernel-install</refentrytitle><manvolnum>8</manvolnum></citerefentry>
may be used to copy kernel images onto the ESP or the Extended Boot Loader Partition and to generate
description files compliant with the Boot Loader
Specification.</para>
</refsect1>

<refsect1>
Expand Down Expand Up @@ -238,7 +272,9 @@
Loader Specification</ulink> are read from <filename>/loader/entries/</filename> on the ESP and the
Extended Boot Loader partition. Unified kernel boot entries following the <ulink
url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot Loader Specification</ulink> are read from
<filename>/EFI/Linux/</filename> on the ESP and the Extended Boot Loader partition.</para>
<filename>/EFI/Linux/</filename> on the ESP and the Extended Boot Loader partition. Optionally, a random
seed for early boot entropy pool provisioning is stored in <filename>/loader/random-seed</filename> in
the ESP.</para>
</refsect1>

<refsect1>
Expand Down Expand Up @@ -346,10 +382,39 @@

<listitem><para>Information about the time spent in various parts of the boot loader. Set by the boot
loader. Use <citerefentry><refentrytitle>systemd-analyze</refentrytitle><manvolnum>1</manvolnum></citerefentry>
to view this data. These variables are defined by the <ulink
url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink>.</para></listitem>
to view this data. </para></listitem>
</varlistentry>

<varlistentry>
<term><varname>LoaderRandomSeed</varname></term>

<listitem><para>A binary random seed <command>systemd-boot</command> may optionally pass to the
OS. This is a volatile EFI variable that is hashed at boot from the combination of a random seed
stored in the ESP (in <filename>/loader/random-seed</filename>) and a "system token" persistently
stored in the EFI variable <varname>LoaderSystemToken</varname> (see below). During early OS boot the
system manager reads this variable and passes it to the OS kernel's random pool, crediting the full
entropy it contains. This is an efficient way to ensure the system starts up with a fully initialized
kernel random pool — as early as the initial RAM disk phase. <command>systemd-boot</command> reads
the random seed from the ESP, combines it with the "system token", and both derives a new random seed
to update in-place the seed stored in the ESP, and the random seed to pass to the OS from it via
SHA256 hashing in counter mode. This ensures that different physical systems that boot the same
"golden" OS image — i.e. containing the same random seed file in the ESP — will still pass a
different random seed to the OS. It is made sure the random seed stored in the ESP is fully
overwritten before the OS is booted, to ensure different random seed data is used between subsequent
boots.</para></listitem>
</varlistentry>

<varlistentry>
<term><varname>LoaderSystemToken</varname></term>

<listitem><para>A binary random data field, that is used for generating the random see to pass to the
OS (see above). Note that this random data is generally only generated once, during OS installation,
and is then never updated again.</para></listitem>
</varlistentry>
</variablelist>

<para>Many of these variables are defined by the <ulink
url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink>.</para>
</refsect1>

<refsect1>
Expand Down Expand Up @@ -413,6 +478,7 @@
<citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>loader.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-bless-boot.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-boot-system-token.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>kernel-install</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<ulink url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot Loader Specification</ulink>,
<ulink url="https://systemd.io/BOOT_LOADER_INTERFACE">Boot Loader Interface</ulink>
Expand Down