diff --git a/man/loader.conf.xml b/man/loader.conf.xml
index 0d12b1e874..ef358f7e68 100644
--- a/man/loader.conf.xml
+++ b/man/loader.conf.xml
@@ -421,6 +421,17 @@ sbvarsign --attr "${attr}" --key KEK.key --cert KEK.pem --output db.auth db db.e
+
+ secure-boot-enroll-timeout-sec
+
+ How long the warning should be shown in seconds before the key enrollment process starts.
+ If set to hidden or 0, no warning is shown and the keys
+ will be enrolled immediately. The default timeout (if not set explicitly) is 15 seconds.
+ This option is only relevant if secure-boot-enroll is enabled.
+
+
+
+
reboot-for-bitlocker
diff --git a/src/boot/boot.c b/src/boot/boot.c
index abf7693a36..0c88b05a41 100644
--- a/src/boot/boot.c
+++ b/src/boot/boot.c
@@ -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;
diff --git a/src/boot/secure-boot.c b/src/boot/secure-boot.c
index dd3757aa5c..a7bac8bf08 100644
--- a/src/boot/secure-boot.c
+++ b/src/boot/secure-boot.c
@@ -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)
diff --git a/src/boot/secure-boot.h b/src/boot/secure-boot.h
index 12f764c8a4..02683a61dc 100644
--- a/src/boot/secure-boot.h
+++ b/src/boot/secure-boot.h
@@ -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,