diff --git a/packages/system/systemd/001-add_poweroff_autoenroll.diff b/packages/system/systemd/001-add_poweroff_autoenroll.diff new file mode 100644 index 0000000..17c8c99 --- /dev/null +++ b/packages/system/systemd/001-add_poweroff_autoenroll.diff @@ -0,0 +1,123 @@ +Enable the use of power off instead of reboot for secure boot enrollment + +For systemd v256 only +Allows setting the secure-boot-enroll-poweroff option in the loader.conf to a bool value to enable the +use of power off instead of reboot after a successful secure boot enrollment. + +diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c +index 5e6f142dd7..b2ef269682 100644 +--- a/src/boot/efi/boot.c ++++ b/src/boot/efi/boot.c +@@ -92,6 +92,7 @@ typedef struct { + bool auto_reboot; + bool reboot_for_bitlocker; + secure_boot_enroll secure_boot_enroll; ++ bool secure_boot_enroll_poweroff; + bool force_menu; + bool use_saved_entry; + bool use_saved_entry_efivar; +@@ -539,12 +540,15 @@ static void print_status(Config *config, char16_t *loaded_image_path) { + break; + case ENROLL_MANUAL: + printf(" secure-boot-enroll: manual\n"); ++ printf(" secure-boot-enroll-poweroff: %ls\n", yes_no(config->secure_boot_enroll_poweroff)); + break; + case ENROLL_IF_SAFE: + printf(" secure-boot-enroll: if-safe\n"); ++ printf(" secure-boot-enroll-poweroff: %ls\n", yes_no(config->secure_boot_enroll_poweroff)); + break; + case ENROLL_FORCE: + printf(" secure-boot-enroll: force\n"); ++ printf(" secure-boot-enroll-poweroff: %ls\n", yes_no(config->secure_boot_enroll_poweroff)); + break; + default: + assert_not_reached(); +@@ -1270,7 +1274,9 @@ static void config_defaults_load_from_file(Config *config, char *content) { + else + log_error("Error parsing 'secure-boot-enroll' config option, ignoring: %s", + value); +- ++ } else if (streq8(key, "secure-boot-enroll-poweroff")) { ++ if (!parse_boolean(value, &config->secure_boot_enroll_poweroff)) ++ log_error("Error parsing 'secure-boot-enroll-poweroff' config option, ignoring: %s", value); + } else if (streq8(key, "console-mode")) { + if (streq8(value, "auto")) + config->console_mode = CONSOLE_MODE_AUTO; +@@ -1566,6 +1572,7 @@ static void config_load_defaults(Config *config, EFI_FILE *root_dir) { + .auto_entries = true, + .auto_firmware = true, + .secure_boot_enroll = ENROLL_IF_SAFE, ++ .secure_boot_enroll_poweroff = false, + .idx_default_efivar = IDX_INVALID, + .console_mode = CONSOLE_MODE_KEEP, + .console_mode_efivar = CONSOLE_MODE_KEEP, +@@ -2560,7 +2567,7 @@ 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->path, config->secure_boot_enroll == ENROLL_FORCE); ++ secure_boot_enroll_at(root_dir, entry->path, config->secure_boot_enroll == ENROLL_FORCE, config->secure_boot_enroll_poweroff); + } + + return EFI_SUCCESS; +@@ -2771,7 +2778,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, /*force=*/ true); ++ err = secure_boot_enroll_at(root_dir, entry->path, /*force=*/ true, config.secure_boot_enroll_poweroff); + if (err != EFI_SUCCESS) + return err; + continue; +diff --git a/src/boot/efi/secure-boot.c b/src/boot/efi/secure-boot.c +index 2400324fc5..c4a13fdf8f 100644 +--- a/src/boot/efi/secure-boot.c ++++ b/src/boot/efi/secure-boot.c +@@ -67,7 +67,7 @@ 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) { ++EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path, bool force, bool poweroff) { + assert(root_dir); + assert(path); + +@@ -184,11 +184,21 @@ EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path, bool + } + } + +- printf("Custom Secure Boot keys successfully enrolled, rebooting the system now!\n"); + /* The system should be in secure boot mode now and we could continue a regular boot. But at least +- * TPM PCR7 measurements should change on next boot. Reboot now so that any OS we load does not end +- * up relying on the old PCR state. */ +- RT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); ++ * TPM PCR7 measurements should change on next boot. Reboot/poweroff now so that any OS we load ++ * does not end up relying on the old PCR state. ++ */ ++ ++ uint64_t dummy_key; ++ if (poweroff == 1) { ++ printf("Custom Secure Boot keys successfully enrolled, powering of the system now!\n"); ++ console_key_read(&dummy_key , 2 * 1000 * 1000); /* wait a bit so user can see the message */ ++ RT->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL); ++ } else { ++ printf("Custom Secure Boot keys successfully enrolled, rebooting the system now!\n"); ++ console_key_read(&dummy_key, 2 * 1000 * 1000); /* wait a bit so user can see the message */ ++ RT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL); ++ } + assert_not_reached(); + + out_deallocate: +diff --git a/src/boot/efi/secure-boot.h b/src/boot/efi/secure-boot.h +index 347113135f..3eb9eef006 100644 +--- a/src/boot/efi/secure-boot.h ++++ b/src/boot/efi/secure-boot.h +@@ -14,7 +14,7 @@ typedef enum { + 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); ++EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path, bool force, bool poweroff); + + typedef bool (*security_validator_t)( + const void *ctx, diff --git a/packages/system/systemd/build.yaml b/packages/system/systemd/build.yaml index f243808..4b12020 100644 --- a/packages/system/systemd/build.yaml +++ b/packages/system/systemd/build.yaml @@ -7,6 +7,10 @@ prelude: - PACKAGE_VERSION=${PACKAGE_VERSION%\-*} && git clone --branch v${PACKAGE_VERSION} https://github.com/systemd/systemd.git steps: + # check if version matches 256* + {{ if regexMatch "256.*" .Values.version }} + - cd systemd && patch -p1 < ../001-add_poweroff_autoenroll.diff + {{ end }} # Minimal systemd build, remove almost everything, we only interested in the efi boot files - cd systemd && meson setup build -Dmode=release -Dbootloader=enabled -Defi=true -Dukify=disabled -Dblkid=disabled -Dopenssl=disabled -Dsbat-distro="Kairos" -Dsbat-distro-url="kairos.io" -Dsbat-distro-summary="Kairos" -Dsbat-distro-version="kairos-${PACKAGE_VERSION}" -Ddns-servers='' -Dsysvinit-path= -Dsysvrcnd-path= -Dtpm=true -Dinstall-tests=false -Dnss-resolve=disabled -Dlogind=false -Dcoredump=false -Dhomed=disabled -Dfirstboot=false -Dhostnamed=false -Dhibernate=false -Dinitrd=false -Dimportd=disabled -Dkernel-install=false -Dlocaled=false -Dmachined=false -Dnetworkd=false -Dnss-myhostname=false -Dnss-mymachines=disabled -Dnss-systemd=false -Doomd=false -Dportabled=false -Dhwdb=false -Dpstore=false -Dquotacheck=false -Drandomseed=false -Drepart=disabled -Dresolve=false -Drfkill=false -Dsysext=false -Danalyze=false -Dsysupdate=disabled -Dsysusers=false -Dstoragetm=false -Dtimedated=false -Dtimesyncd=false -Dtmpfiles=false -Duserdb=false -Dvconsole=false -Dxdg-autostart=false -Didn=false -Dpolkit=disabled -Dnscd=false -Dkmod=disabled -Ddbus=disabled -Dglib=disabled -Dbacklight=false -Dldconfig=false -Dgshadow=false -Dwheel-group=false -Dadm-group=false -Dxkbcommon=disabled -Dzstd=disabled -Dlz4=disabled -Dutmp=false -Dlink-udev-shared=false -Dlink-systemctl-shared=false -Dlink-networkd-shared=false -Dlink-timesyncd-shared=false -Dlink-journalctl-shared=false -Dlink-boot-shared=false -Dlink-portabled-shared=false -Denvironment-d=false -Dqrencode=disabled -Dpwquality=disabled -Dlibcurl=disabled -Dfdisk=disabled -Dlibidn2=disabled -Dlibiptc=disabled -Ddns-over-tls=false -Didn=false -Dgnutls=disabled -Dp11kit=disabled -Dlibidn=disabled -Dlibidn2=disabled -Dgcrypt=disabled -Dxz=disabled -Dzlib=disabled -Dbzip2=disabled - cd systemd && ninja -C build