diff --git a/man/loader.conf.xml b/man/loader.conf.xml index 8808461ceb1..22f4644d9e8 100644 --- a/man/loader.conf.xml +++ b/man/loader.conf.xml @@ -227,12 +227,33 @@ Danger: this feature might soft-brick your device if used improperly. - Takes one of off, manual or force. - Controls the enrollment of Secure Boot keys. If set to off, no action whatsoever - is taken. If set to manual (the default) and the UEFI firmware is in setup-mode - then entries to manually enroll Secure Boot variables are created in the boot menu. If set to - force, in addition, if a directory named /loader/keys/auto/ - exists on the ESP then the keys in that directory are enrolled automatically. + Controls enrollment of secure boot keys found on the ESP if the system is in setup mode: + + + + No action is taken. + + + + + Boot entries for found secure boot keys are created that allow manual + enrollment. + + + + + Same behavior as , but will try to automatically + enroll the key auto if it is considered to be safe. Currently, this is only + the case if the system is running inside a virtual machine. + + + + + Always enroll the auto key if found. Note that a warning + message with a timeout will still be shown if this operation is unknown to be safe. + + + The different sets of variables can be set up under /loader/keys/NAME where diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index bb318c4e7e6..03fe022ef64 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -526,6 +526,9 @@ static void print_status(Config *config, char16_t *loaded_image_path) { case ENROLL_MANUAL: printf(" secure-boot-enroll: manual\n"); break; + case ENROLL_IF_SAFE: + printf(" secure-boot-enroll: if-safe\n"); + break; case ENROLL_FORCE: printf(" secure-boot-enroll: force\n"); break; @@ -1259,6 +1262,8 @@ static void config_defaults_load_from_file(Config *config, char *content) { config->secure_boot_enroll = ENROLL_MANUAL; else if (streq8(value, "force")) config->secure_boot_enroll = ENROLL_FORCE; + else if (streq8(value, "if-safe")) + config->secure_boot_enroll = ENROLL_IF_SAFE; else if (streq8(value, "off")) config->secure_boot_enroll = ENROLL_OFF; else @@ -1572,7 +1577,7 @@ static void config_load_defaults(Config *config, EFI_FILE *root_dir) { .auto_entries = true, .auto_firmware = true, .reboot_for_bitlocker = false, - .secure_boot_enroll = ENROLL_MANUAL, + .secure_boot_enroll = ENROLL_IF_SAFE, .idx_default_efivar = IDX_INVALID, .console_mode = CONSOLE_MODE_KEEP, .console_mode_efivar = CONSOLE_MODE_KEEP, @@ -2511,10 +2516,11 @@ static EFI_STATUS secure_boot_discover_keys(Config *config, EFI_FILE *root_dir) }; config_add_entry(config, entry); - if (config->secure_boot_enroll == ENROLL_FORCE && strcaseeq16(dirent->FileName, u"auto")) + if (IN_SET(config->secure_boot_enroll, ENROLL_IF_SAFE, ENROLL_FORCE) && + 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->path); + secure_boot_enroll_at(root_dir, entry->path, config->secure_boot_enroll == ENROLL_FORCE); } return EFI_SUCCESS; @@ -2700,7 +2706,7 @@ static EFI_STATUS run(EFI_HANDLE image) { /* if auto enrollment is activated, we try to load keys for the given entry. */ if (entry->type == LOADER_SECURE_BOOT_KEYS && config.secure_boot_enroll != ENROLL_OFF) { - err = secure_boot_enroll_at(root_dir, entry->path); + err = secure_boot_enroll_at(root_dir, entry->path, /*force=*/ true); if (err != EFI_SUCCESS) return err; continue; diff --git a/src/boot/efi/secure-boot.c b/src/boot/efi/secure-boot.c index c8a3957b1e1..8b796db65f9 100644 --- a/src/boot/efi/secure-boot.c +++ b/src/boot/efi/secure-boot.c @@ -36,7 +36,7 @@ SecureBootMode secure_boot_mode(void) { static const char sbat[] _used_ _section_(".sbat") = SBAT_SECTION_TEXT; #endif -EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path) { +EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path, bool force) { assert(root_dir); assert(path); @@ -44,11 +44,16 @@ EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path) { clear_screen(COLOR_NORMAL); - printf("Enrolling secure boot keys from directory: %ls\n", path); - /* Enrolling secure boot keys is safe to do in virtualized environments as there is nothing * we can brick there. */ - if (!in_hypervisor()) { + bool is_safe = in_hypervisor(); + + if (!is_safe && !force) + return EFI_SUCCESS; + + printf("Enrolling secure boot keys from directory: %ls\n", path); + + if (!is_safe) { printf("Warning: Enrolling custom Secure Boot keys might soft-brick your machine!\n"); unsigned timeout_sec = 15; diff --git a/src/boot/efi/secure-boot.h b/src/boot/efi/secure-boot.h index e98de81c2a5..bdc34150da6 100644 --- a/src/boot/efi/secure-boot.h +++ b/src/boot/efi/secure-boot.h @@ -9,13 +9,14 @@ typedef enum { ENROLL_OFF, /* no Secure Boot key enrollment whatsoever, even manual entries are not generated */ ENROLL_MANUAL, /* Secure Boot key enrollment is strictly manual: manual entries are generated and need to be selected by the user */ + ENROLL_IF_SAFE, /* Automatically enroll if it is safe (if we are running inside a VM, for example). */ ENROLL_FORCE, /* Secure Boot key enrollment may be automatic if it is available but might not be safe */ } secure_boot_enroll; bool secure_boot_enabled(void); SecureBootMode secure_boot_mode(void); -EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path); +EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path, bool force); typedef bool (*security_validator_t)( const void *ctx,