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 initrd 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>
-
- <para>See <ulink url="https://systemd.io/RANDOM_SEEDS">Random Seeds</ulink> for
- further information.</para></listitem>
- </varlistentry>
-
<varlistentry>
<term><varname>LoaderSystemToken</varname></term>
<filename>/etc/kernel/tries</filename> when a boot loader entry is first created.</para>
</refsect1>
+ <refsect1>
+ <title>Using systemd-boot in virtual machines.</title>
+
+ <para>When using qemu with OVMF (UEFI Firmware for virtual machines) the <option>-kernel</option> switch
+ works not only for linux kernels, but for any EFI binary, including sd-boot and unified linux
+ kernels. Example command line for loading sd-boot on x64:</para>
+
+ <para>
+ <command>qemu-system-x86_64 <replaceable>[ ... ]</replaceable>
+ -kernel /usr/lib/systemd/boot/efi/systemd-bootx64.efi</command>
+ </para>
+
+ <para>systemd-boot will detect that it was started directly instead of being loaded from ESP and will
+ search for the ESP in that case, taking into account boot order information from the hypervisor (if
+ available).</para>
+ </refsect1>
+
<refsect1>
<title>See Also</title>
<para>
r = efi_get_boot_option(id, &title, &partition, &path, &active);
if (r < 0)
- return log_error_errno(r, "Failed to read boot option %u: %m", id);
+ return log_debug_errno(r, "Failed to read boot option 0x%04X: %m", id);
/* print only configured entries with partition information */
if (!path || sd_id128_is_null(partition)) {
- log_debug("Ignoring boot entry %u without partition information.", id);
+ log_debug("Ignoring boot entry 0x%04X without partition information.", id);
return 0;
}
printf("\n");
printf("%sRandom Seed:%s\n", ansi_underline(), ansi_normal());
- have = access(EFIVAR_PATH(EFI_LOADER_VARIABLE(LoaderRandomSeed)), F_OK) >= 0;
- printf(" Passed to OS: %s\n", yes_no(have));
have = access(EFIVAR_PATH(EFI_LOADER_VARIABLE(LoaderSystemToken)), F_OK) >= 0;
printf(" System Token: %s\n", have ? "set" : "not set");
static int install_random_seed(const char *esp) {
_cleanup_(unlink_and_freep) char *tmp = NULL;
- _cleanup_free_ void *buffer = NULL;
+ unsigned char buffer[RANDOM_EFI_SEED_SIZE];
_cleanup_free_ char *path = NULL;
_cleanup_close_ int fd = -1;
- size_t sz, token_size;
+ size_t token_size;
ssize_t n;
int r;
if (!path)
return log_oom();
- sz = random_pool_size();
-
- buffer = malloc(sz);
- if (!buffer)
- return log_oom();
-
- r = crypto_random_bytes(buffer, sz);
+ r = crypto_random_bytes(buffer, sizeof(buffer));
if (r < 0)
return log_error_errno(r, "Failed to acquire random seed: %m");
return log_error_errno(fd, "Failed to open random seed file for writing: %m");
}
- n = write(fd, buffer, sz);
+ n = write(fd, buffer, sizeof(buffer));
if (n < 0)
return log_error_errno(errno, "Failed to write random seed file: %m");
- if ((size_t) n != sz)
+ if ((size_t) n != sizeof(buffer))
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Short write while writing random seed file.");
if (rename(tmp, path) < 0)
tmp = mfree(tmp);
- log_info("Random seed file %s successfully written (%zu bytes).", path, sz);
+ log_info("Random seed file %s successfully written (%zu bytes).", path, sizeof(buffer));
if (!arg_touch_variables)
return 0;
if (r != -ENOENT)
return log_error_errno(r, "Failed to test system token validity: %m");
} else {
- if (token_size >= sz) {
+ if (token_size >= sizeof(buffer)) {
/* Let's avoid writes if we can, and initialize this only once. */
log_debug("System token already written, not updating.");
return 0;
}
- log_debug("Existing system token size (%zu) does not match our expectations (%zu), replacing.", token_size, sz);
+ log_debug("Existing system token size (%zu) does not match our expectations (%zu), replacing.", token_size, sizeof(buffer));
}
- r = crypto_random_bytes(buffer, sz);
+ r = crypto_random_bytes(buffer, sizeof(buffer));
if (r < 0)
return log_error_errno(r, "Failed to acquire random seed: %m");
* and possibly get identification information or too much insight into the kernel's entropy pool
* state. */
RUN_WITH_UMASK(0077) {
- r = efi_set_variable(EFI_LOADER_VARIABLE(LoaderSystemToken), buffer, sz);
+ r = efi_set_variable(EFI_LOADER_VARIABLE(LoaderSystemToken), buffer, sizeof(buffer));
if (r < 0) {
if (!arg_graceful)
return log_error_errno(r, "Failed to write 'LoaderSystemToken' EFI variable: %m");
else
log_warning_errno(r, "Unable to write 'LoaderSystemToken' EFI variable, ignoring: %m");
} else
- log_info("Successfully initialized system token in EFI variable with %zu bytes.", sz);
+ log_info("Successfully initialized system token in EFI variable with %zu bytes.", sizeof(buffer));
}
return 0;