return cache > 0;
}
-bool is_efi_secure_boot_setup_mode(void) {
- static int cache = -1;
+SecureBootMode efi_get_secure_boot_mode(void) {
+ static SecureBootMode cache = _SECURE_BOOT_INVALID;
- if (cache < 0)
- cache = read_flag(EFI_GLOBAL_VARIABLE(SetupMode));
+ if (cache != _SECURE_BOOT_INVALID)
+ return cache;
- return cache > 0;
+ int secure = read_flag(EFI_GLOBAL_VARIABLE(SecureBoot));
+ if (secure < 0) {
+ if (secure != -ENOENT)
+ log_debug_errno(secure, "Error reading SecureBoot EFI variable: %m");
+ return (cache = SECURE_BOOT_UNSUPPORTED);
+ }
+
+ /* We can assume false for all these if they are abscent (AuditMode and
+ * DeployedMode may not exist on older firmware). */
+ int audit = read_flag(EFI_GLOBAL_VARIABLE(AuditMode));
+ int deployed = read_flag(EFI_GLOBAL_VARIABLE(DeployedMode));
+ int setup = read_flag(EFI_GLOBAL_VARIABLE(SetupMode));
+ log_debug("Secure boot variables: SecureBoot=%d AuditMode=%d DeployedMode=%d SetupMode=%d",
+ secure, audit, deployed, setup);
+
+ return (cache = decode_secure_boot_mode(secure, audit > 0, deployed > 0, setup > 0));
}
static int read_efi_options_variable(char **line) {
#include "sd-id128.h"
+#include "efivars-fundamental.h"
#include "time-util.h"
#define EFI_VENDOR_LOADER SD_ID128_MAKE(4a,67,b0,82,0a,4c,41,cf,b6,c7,44,0b,29,bb,8c,4f)
bool is_efi_boot(void);
bool is_efi_secure_boot(void);
-bool is_efi_secure_boot_setup_mode(void);
+SecureBootMode efi_get_secure_boot_mode(void);
int cache_efi_options_variable(void);
int systemd_efi_options_variable(char **line);
return false;
}
-static inline bool is_efi_secure_boot_setup_mode(void) {
- return false;
+static inline SecureBootMode efi_get_secure_boot_mode(void) {
+ return SECURE_BOOT_UNKNOWN;
}
static inline int cache_efi_options_variable(void) {
if (k < 0 && k != -ENOENT)
r = log_warning_errno(k, "Failed to read EFI variable LoaderDevicePartUUID: %m");
+ SecureBootMode secure = efi_get_secure_boot_mode();
printf("System:\n");
printf(" Firmware: %s%s (%s)%s\n", ansi_highlight(), strna(fw_type), strna(fw_info), ansi_normal());
- printf(" Secure Boot: %sd\n", enable_disable(is_efi_secure_boot()));
- printf(" Setup Mode: %s\n", is_efi_secure_boot_setup_mode() ? "setup" : "user");
+ printf(" Secure Boot: %sd (%s)\n",
+ enable_disable(IN_SET(secure, SECURE_BOOT_USER, SECURE_BOOT_DEPLOYED)),
+ secure_boot_mode_to_string(secure));
printf(" TPM2 Support: %s\n", yes_no(efi_has_tpm2()));
k = efi_get_reboot_to_firmware();
#include "devicetree.h"
#include "disk.h"
#include "drivers.h"
-#include "efi-loader-features.h"
+#include "efivars-fundamental.h"
#include "graphics.h"
#include "linux.h"
#include "measure.h"
static void print_status(Config *config, CHAR16 *loaded_image_path) {
UINT64 key;
UINTN x_max, y_max;
- BOOLEAN setup_mode = FALSE;
+ SecureBootMode secure;
_cleanup_freepool_ CHAR16 *device_part_uuid = NULL, *default_efivar = NULL;
assert(config);
clear_screen(COLOR_NORMAL);
console_query_mode(&x_max, &y_max);
+ secure = secure_boot_mode();
(void) efivar_get(LOADER_GUID, L"LoaderDevicePartUUID", &device_part_uuid);
(void) efivar_get(LOADER_GUID, L"LoaderEntryDefault", &default_efivar);
- (void) efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SetupMode", &setup_mode);
/* We employ some unusual indentation here for readability. */
ps_string(L" firmware vendor: %s\n", ST->FirmwareVendor);
Print(L" firmware version: %u.%02u\n", ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff);
Print(L" OS indications: %lu\n", get_os_indications_supported());
- ps_bool(L" secure boot: %s\n", secure_boot_enabled());
- ps_bool(L" setup mode: %s\n", setup_mode);
+ Print(L" secure boot: %s (%s)\n", yes_no(IN_SET(secure, SECURE_BOOT_USER, SECURE_BOOT_DEPLOYED)), secure_boot_mode_to_string(secure));
ps_bool(L" shim: %s\n", shim_loaded());
Print(L" console mode: %d/%d (%lu x %lu)\n", ST->ConOut->Mode->Mode, ST->ConOut->Mode->MaxMode - 1LL, x_max, y_max);
return !EFI_ERROR(err) && secure;
}
+SecureBootMode secure_boot_mode(void) {
+ BOOLEAN secure, audit = FALSE, deployed = FALSE, setup = FALSE;
+ EFI_STATUS err;
+
+ err = efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SecureBoot", &secure);
+ if (EFI_ERROR(err))
+ return SECURE_BOOT_UNSUPPORTED;
+
+ /* We can assume FALSE for all these if they are abscent (AuditMode and
+ * DeployedMode may not exist on older firmware). */
+ (void) efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"AuditMode", &audit);
+ (void) efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"DeployedMode", &deployed);
+ (void) efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SetupMode", &setup);
+
+ return decode_secure_boot_mode(secure, audit, deployed, setup);
+}
+
#ifdef SBAT_DISTRO
static const char sbat[] _used_ _section_ (".sbat") _align_ (512) =
"sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md\n"
#pragma once
#include <efi.h>
+#include "efivars-fundamental.h"
BOOLEAN secure_boot_enabled(void);
+SecureBootMode secure_boot_mode(void);
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "efivars-fundamental.h"
+
+static const sd_char * const table[_SECURE_BOOT_MAX] = {
+ [SECURE_BOOT_UNSUPPORTED] = STR_C("unsupported"),
+ [SECURE_BOOT_UNKNOWN] = STR_C("unknown"),
+ [SECURE_BOOT_AUDIT] = STR_C("audit"),
+ [SECURE_BOOT_DEPLOYED] = STR_C("deployed"),
+ [SECURE_BOOT_SETUP] = STR_C("setup"),
+ [SECURE_BOOT_USER] = STR_C("user"),
+};
+
+const sd_char *secure_boot_mode_to_string(SecureBootMode m) {
+ return (m >= 0 && m < _SECURE_BOOT_MAX) ? table[m] : NULL;
+}
+
+SecureBootMode decode_secure_boot_mode(
+ sd_bool secure,
+ sd_bool audit,
+ sd_bool deployed,
+ sd_bool setup) {
+
+ /* See figure 32-4 Secure Boot Modes from UEFI Specification 2.9 */
+ if (secure && deployed && !audit && !setup)
+ return SECURE_BOOT_DEPLOYED;
+ if (secure && !deployed && !audit && !setup)
+ return SECURE_BOOT_USER;
+ if (!secure && !deployed && audit && setup)
+ return SECURE_BOOT_AUDIT;
+ if (!secure && !deployed && !audit && setup)
+ return SECURE_BOOT_SETUP;
+
+ /* Well, this should not happen. */
+ return SECURE_BOOT_UNKNOWN;
+}
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include <errno.h>
+#include "string-util-fundamental.h"
+
#ifndef UINT64_C
# define UINT64_C(c) (c ## ULL)
#endif
#define EFI_LOADER_FEATURE_XBOOTLDR (UINT64_C(1) << 5)
#define EFI_LOADER_FEATURE_RANDOM_SEED (UINT64_C(1) << 6)
#define EFI_LOADER_FEATURE_LOAD_DRIVER (UINT64_C(1) << 7)
+
+typedef enum SecureBootMode {
+ SECURE_BOOT_UNSUPPORTED,
+ SECURE_BOOT_UNKNOWN,
+ SECURE_BOOT_AUDIT,
+ SECURE_BOOT_DEPLOYED,
+ SECURE_BOOT_SETUP,
+ SECURE_BOOT_USER,
+ _SECURE_BOOT_MAX,
+ _SECURE_BOOT_INVALID = -EINVAL,
+} SecureBootMode;
+
+const sd_char *secure_boot_mode_to_string(SecureBootMode m);
+SecureBootMode decode_secure_boot_mode(
+ sd_bool secure,
+ sd_bool audit,
+ sd_bool deployed,
+ sd_bool setup);
fundamental_path = meson.current_source_dir()
fundamental_headers = files(
- 'efi-loader-features.h',
+ 'efivars-fundamental.h',
'macro-fundamental.h',
'string-util-fundamental.h',
'sha256.h',
'type.h')
sources = '''
+ efivars-fundamental.c
string-util-fundamental.c
sha256.c
'''.split()
#include <sys/stat.h>
-#include "efi-loader-features.h"
+#include "efivars-fundamental.h"
#include "efivars.h"
#if ENABLE_EFI