mirror of
https://github.com/systemd/systemd.git
synced 2025-01-24 06:04:05 +03:00
sd-boot: add support for custom mode.
Custom mode allows to write updates to db, dbx, KEK and PK without signature. See the comment block for a more detailed description. In case the PK update has no signature try to enable custom mode.
This commit is contained in:
parent
3037616d8e
commit
102138a12e
@ -140,6 +140,8 @@ typedef struct {
|
||||
GUID_DEF(0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c)
|
||||
#define EFI_IMAGE_SECURITY_DATABASE_GUID \
|
||||
GUID_DEF(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f)
|
||||
#define EFI_CUSTOM_MODE_ENABLE_GUID \
|
||||
GUID_DEF(0xc076ec0c, 0x7028, 0x4399, 0xa0, 0x72, 0x71, 0xee, 0x5c, 0x44, 0x8b, 0x9f)
|
||||
|
||||
#define EVT_TIMER 0x80000000U
|
||||
#define EVT_RUNTIME 0x40000000U
|
||||
|
@ -32,10 +32,46 @@ SecureBootMode secure_boot_mode(void) {
|
||||
return decode_secure_boot_mode(secure, audit, deployed, setup);
|
||||
}
|
||||
|
||||
/*
|
||||
* Custom mode allows to change secure boot certificate databases db, dbx, KEK and PK without the variable
|
||||
* updates being signed. When enrolling certificates to an unconfigured system (no PK present yet) writing
|
||||
* db, dbx and KEK updates without signature works fine even in standard mode. Writing PK updates without
|
||||
* signature requires custom mode in any case.
|
||||
*
|
||||
* Enabling custom mode works only if a user is physically present. Note that OVMF has a dummy
|
||||
* implementation for the user presence check (there is no useful way to implement a presence check for a
|
||||
* virtual machine).
|
||||
*
|
||||
* FYI: Your firmware setup utility might offers the option to enroll certificates from *.crt files
|
||||
* (DER-encoded x509 certificates) on the ESP; that uses custom mode too. Your firmware setup might also
|
||||
* offer the option to switch the system into custom mode for the next boot.
|
||||
*/
|
||||
static bool custom_mode_enabled(void) {
|
||||
bool enabled = false;
|
||||
|
||||
(void) efivar_get_boolean_u8(MAKE_GUID_PTR(EFI_CUSTOM_MODE_ENABLE),
|
||||
u"CustomMode", &enabled);
|
||||
return enabled;
|
||||
}
|
||||
|
||||
static EFI_STATUS set_custom_mode(bool enable) {
|
||||
static char16_t name[] = u"CustomMode";
|
||||
static uint32_t attr =
|
||||
EFI_VARIABLE_NON_VOLATILE |
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS;
|
||||
uint8_t mode = enable
|
||||
? 1 /* CUSTOM_SECURE_BOOT_MODE */
|
||||
: 0; /* STANDARD_SECURE_BOOT_MODE */
|
||||
|
||||
return RT->SetVariable(name, MAKE_GUID_PTR(EFI_CUSTOM_MODE_ENABLE),
|
||||
attr, sizeof(mode), &mode);
|
||||
}
|
||||
|
||||
EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path, bool force) {
|
||||
assert(root_dir);
|
||||
assert(path);
|
||||
|
||||
bool need_custom_mode = false;
|
||||
EFI_STATUS err;
|
||||
|
||||
clear_screen(COLOR_NORMAL);
|
||||
@ -103,6 +139,30 @@ EFI_STATUS secure_boot_enroll_at(EFI_FILE *root_dir, const char16_t *path, bool
|
||||
log_error_status(err, "Failed reading file %ls\\%ls: %m", path, sb_vars[i].filename);
|
||||
goto out_deallocate;
|
||||
}
|
||||
if (streq16(sb_vars[i].name, u"PK") && sb_vars[i].size > 20) {
|
||||
assert(sb_vars[i].buffer);
|
||||
/*
|
||||
* The buffer should be EFI_TIME (16 bytes), followed by
|
||||
* EFI_VARIABLE_AUTHENTICATION_2 header. First header field is the size. If the
|
||||
* size covers only the header itself (8 bytes) plus the signature type guid (16
|
||||
* bytes), leaving no space for an actual signature, we can conclude that no
|
||||
* signature is present.
|
||||
*/
|
||||
uint32_t *sigsize = (uint32_t*)(sb_vars[i].buffer + 16);
|
||||
if (*sigsize <= 24) {
|
||||
printf("PK is not signed (need custom mode).\n");
|
||||
need_custom_mode = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (need_custom_mode && !custom_mode_enabled()) {
|
||||
err = set_custom_mode(/* enable */ true);
|
||||
if (err != EFI_SUCCESS) {
|
||||
log_error_status(err, "Failed to enable custom mode: %m");
|
||||
goto out_deallocate;
|
||||
}
|
||||
printf("Custom mode enabled.\n");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ELEMENTSOF(sb_vars); i++) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user