1
0
mirror of https://github.com/systemd/systemd synced 2025-10-06 00:13:24 +02:00

boot: add support for overriding key enrollement timeout

Currently, a 15-second timeout is hardcoded for the key enrollment
process while waiting for user confirmation. Make this value configurable
to allow the option of disabling user input, such as during automatic key
provisioning at the factory.

Signed-off-by: Igor Opaniuk <igor.opaniuk@foundries.io>
This commit is contained in:
Igor Opaniuk
2025-09-18 17:49:32 +02:00
committed by Lennart Poettering
parent e216876fc6
commit 64376936c7
4 changed files with 60 additions and 23 deletions

View File

@@ -421,6 +421,17 @@ sbvarsign --attr "${attr}" --key KEK.key --cert KEK.pem --output db.auth db db.e
</listitem>
</varlistentry>
<varlistentry>
<term>secure-boot-enroll-timeout-sec</term>
<listitem>
<para>How long the warning should be shown in seconds before the key enrollment process starts.</para>
<para>If set to <literal>hidden</literal> or <literal>0</literal>, no warning is shown and the keys
will be enrolled immediately. The default timeout (if not set explicitly) is 15 seconds.</para>
<para>This option is only relevant if <literal>secure-boot-enroll</literal> is enabled.</para>
<xi:include href="version-info.xml" xpointer="v259"/>
</listitem>
</varlistentry>
<varlistentry>
<term>reboot-for-bitlocker</term>

View File

@@ -144,6 +144,7 @@ typedef struct {
RebootOnError reboot_on_error;
secure_boot_enroll secure_boot_enroll;
secure_boot_enroll_action secure_boot_enroll_action;
uint64_t secure_boot_enroll_timeout_sec;
bool force_menu;
bool use_saved_entry;
bool use_saved_entry_efivar;
@@ -332,36 +333,37 @@ static void print_status(Config *config, char16_t *loaded_image_path) {
printf(" sysfail: %ls\n", config->entry_sysfail);
if (config->entry_saved)
printf(" saved entry: %ls\n", config->entry_saved);
printf(" editor: %ls\n", yes_no(config->editor));
printf(" auto-entries: %ls\n", yes_no(config->auto_entries));
printf(" auto-firmware: %ls\n", yes_no(config->auto_firmware));
printf(" auto-poweroff: %ls\n", yes_no(config->auto_poweroff));
printf(" auto-reboot: %ls\n", yes_no(config->auto_reboot));
printf(" beep: %ls\n", yes_no(config->beep));
printf(" reboot-for-bitlocker: %ls\n", yes_no(config->reboot_for_bitlocker));
printf(" reboot-on-error: %s\n", reboot_on_error_to_string(config->reboot_on_error));
printf(" secure-boot-enroll: %s\n", secure_boot_enroll_to_string(config->secure_boot_enroll));
printf("secure-boot-enroll-action: %s\n", secure_boot_enroll_action_to_string(config->secure_boot_enroll_action));
printf(" editor: %ls\n", yes_no(config->editor));
printf(" auto-entries: %ls\n", yes_no(config->auto_entries));
printf(" auto-firmware: %ls\n", yes_no(config->auto_firmware));
printf(" auto-poweroff: %ls\n", yes_no(config->auto_poweroff));
printf(" auto-reboot: %ls\n", yes_no(config->auto_reboot));
printf(" beep: %ls\n", yes_no(config->beep));
printf(" reboot-for-bitlocker: %ls\n", yes_no(config->reboot_for_bitlocker));
printf(" reboot-on-error: %s\n", reboot_on_error_to_string(config->reboot_on_error));
printf(" secure-boot-enroll: %s\n", secure_boot_enroll_to_string(config->secure_boot_enroll));
printf(" secure-boot-enroll-action: %s\n", secure_boot_enroll_action_to_string(config->secure_boot_enroll_action));
printf("secure-boot-enroll-timeout-sec: %" PRIu64 "\n", config->secure_boot_enroll_timeout_sec);
switch (config->console_mode) {
case CONSOLE_MODE_AUTO:
printf(" console-mode (config): auto\n");
printf(" console-mode (config): auto\n");
break;
case CONSOLE_MODE_KEEP:
printf(" console-mode (config): keep\n");
printf(" console-mode (config): keep\n");
break;
case CONSOLE_MODE_FIRMWARE_MAX:
printf(" console-mode (config): max\n");
printf(" console-mode (config): max\n");
break;
default:
printf(" console-mode (config): %" PRIi64 "\n", config->console_mode);
printf(" console-mode (config): %" PRIi64 "\n", config->console_mode);
}
/* EFI var console mode is always a concrete value or unset. */
if (config->console_mode_efivar != CONSOLE_MODE_KEEP)
printf(" console-mode (EFI var): %" PRIi64 "\n", config->console_mode_efivar);
printf(" console-mode (EFI var): %" PRIi64 "\n", config->console_mode_efivar);
printf(" log-level: %s\n", log_level_to_string(log_get_max_level()));
printf(" log-level: %s\n", log_level_to_string(log_get_max_level()));
if (!ps_continue())
return;
@@ -1097,6 +1099,18 @@ static void config_defaults_load_from_file(Config *config, char *content) {
else
log_error("Error parsing 'secure-boot-enroll-action' config option, ignoring: %s",
value);
} else if (streq8(key, "secure-boot-enroll-timeout-sec")) {
if (streq8(value, "hidden"))
config->secure_boot_enroll_timeout_sec = ENROLL_TIMEOUT_HIDDEN;
else {
uint64_t u;
if (!parse_number8(value, &u, NULL) || u > ENROLL_TIMEOUT_TYPE_MAX) {
log_error("Error parsing 'secure-boot-enroll-timeout-sec' config option, ignoring: %s",
value);
continue;
}
config->secure_boot_enroll_timeout_sec = u;
}
} else if (streq8(key, "console-mode")) {
if (streq8(value, "auto"))
config->console_mode = CONSOLE_MODE_AUTO;
@@ -1463,6 +1477,7 @@ static void config_load_defaults(Config *config, EFI_FILE *root_dir) {
.reboot_on_error = REBOOT_AUTO,
.secure_boot_enroll = ENROLL_IF_SAFE,
.secure_boot_enroll_action = ENROLL_ACTION_REBOOT,
.secure_boot_enroll_timeout_sec = ENROLL_TIMEOUT_DEFAULT,
.idx_default_efivar = IDX_INVALID,
.console_mode = CONSOLE_MODE_KEEP,
.console_mode_efivar = CONSOLE_MODE_KEEP,
@@ -2781,7 +2796,8 @@ static void save_selected_entry(const Config *config, const BootEntry *entry) {
static EFI_STATUS call_secure_boot_enroll(const BootEntry *entry, EFI_FILE *root_dir, EFI_HANDLE parent_image) {
assert(entry);
return secure_boot_enroll_at(root_dir, entry->directory, /* force= */ true, /* action= */ ENROLL_ACTION_REBOOT);
return secure_boot_enroll_at(root_dir, entry->directory, /* force= */ true, /* action= */ ENROLL_ACTION_REBOOT,
ENROLL_TIMEOUT_DEFAULT);
}
static EFI_STATUS secure_boot_discover_keys(Config *config, EFI_FILE *root_dir) {
@@ -2832,7 +2848,8 @@ static EFI_STATUS secure_boot_discover_keys(Config *config, EFI_FILE *root_dir)
strcaseeq16(dirent->FileName, u"auto"))
/* If we auto enroll successfully this call does not return.
* If it fails we still want to add other potential entries to the menu. */
secure_boot_enroll_at(root_dir, entry->directory, config->secure_boot_enroll == ENROLL_FORCE, config->secure_boot_enroll_action);
secure_boot_enroll_at(root_dir, entry->directory, config->secure_boot_enroll == ENROLL_FORCE,
config->secure_boot_enroll_action, config->secure_boot_enroll_timeout_sec);
}
return EFI_SUCCESS;

View File

@@ -3,6 +3,7 @@
#include "console.h"
#include "efi-efivars.h"
#include "efi-log.h"
#include "efi-string.h"
#include "efi-string-table.h"
#include "proto/security-arch.h"
#include "secure-boot.h"
@@ -70,7 +71,8 @@ static EFI_STATUS set_custom_mode(bool enable) {
attr, sizeof(mode), &mode);
}
EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path, bool force, secure_boot_enroll_action action) {
EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path, bool force,
secure_boot_enroll_action action, uint64_t timeout_sec) {
assert(root_dir);
assert(path);
@@ -88,12 +90,11 @@ EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path, bool
printf("Enrolling secure boot keys from directory: %ls\n", path);
if (!is_safe) {
if (!is_safe && timeout_sec != ENROLL_TIMEOUT_HIDDEN) {
printf("Warning: Enrolling custom Secure Boot keys might soft-brick your machine!\n");
unsigned timeout_sec = 15;
for (;;) {
printf("\rEnrolling in %2u s, press any key to abort.", timeout_sec);
printf("\rEnrolling in %" PRIu64 " s, press any key to abort.", timeout_sec);
err = console_key_read(/* ret_key= */ NULL, /* timeout_usec= */ 1000 * 1000);
if (err == EFI_NOT_READY)

View File

@@ -18,10 +18,18 @@ typedef enum {
_SECURE_BOOT_ENROLL_ACTION_MAX,
} secure_boot_enroll_action;
enum {
ENROLL_TIMEOUT_HIDDEN = 0,
ENROLL_TIMEOUT_MIN = 1,
ENROLL_TIMEOUT_DEFAULT = 15,
ENROLL_TIMEOUT_TYPE_MAX = UINT32_MAX,
};
bool secure_boot_enabled(void);
SecureBootMode secure_boot_mode(void);
EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path, bool force, secure_boot_enroll_action action);
EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path, bool force,
secure_boot_enroll_action action, uint64_t timeout_sec);
typedef bool (*security_validator_t)(
const void *ctx,