Message ID | 20201130145839.31620-1-pc@cjr.nz |
---|---|
State | Rejected, archived |
Delegated to: | Heinrich Schuchardt |
Headers | show |
Series | efi_loader: allow disabling EFI secure boot in User Mode | expand |
On 11/30/20 3:58 PM, Paulo Alcantara wrote: > Introduce a new config option CONFIG_EFI_SECURE_BOOT_VAR_DISABLE to > allow disabling EFI secure boot when the platform is operating in User > Mode and there is an NV+BS EFI variable called "SecureBootDisable". > Otherwise, keep it enabled by default. Hello Paulo, could you, please, explain why this is needed. You can simply delete PK if you want to disable secure boot. Best regards Heinrich > > Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz> > --- > lib/efi_loader/Kconfig | 13 +++++++++ > lib/efi_loader/efi_var_common.c | 48 ++++++++++++++++++++++++++++++++- > 2 files changed, 60 insertions(+), 1 deletion(-) > > diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig > index 29ea14b2ee2a..d453905c7666 100644 > --- a/lib/efi_loader/Kconfig > +++ b/lib/efi_loader/Kconfig > @@ -224,5 +224,18 @@ config EFI_SECURE_BOOT > Once SecureBoot mode is enforced, any EFI binary can run only if > it is signed with a trusted key. To do that, you need to install, > at least, PK, KEK and db. > + Note that SecureBoot mode may no longer be enforced when > + EFI_SECURE_BOOT_VAR_DISABLE option is enabled. > + > +config EFI_SECURE_BOOT_VAR_DISABLE > + bool "Permit to disable EFI secure boot when in User Mode" > + depends on EFI_SECURE_BOOT > + default n > + help > + Select this option to allow disabling EFI secure boot when > + the platform is operating in User Mode (e.g. PK is enrolled) > + and there is an NV+BS EFI variable called > + "SecureBootDisable". A platform reset is also required to > + actually disable it. > > endif > diff --git a/lib/efi_loader/efi_var_common.c b/lib/efi_loader/efi_var_common.c > index 1c7459266a38..89aa944180a4 100644 > --- a/lib/efi_loader/efi_var_common.c > +++ b/lib/efi_loader/efi_var_common.c > @@ -241,6 +241,48 @@ err: > return ret; > } > > + > +#ifdef CONFIG_EFI_SECURE_BOOT_VAR_DISABLE > +/** > + * efi_secure_boot_in_user_mode - check if secure boot enabled in User Mode > + * > + * @enabled: true if enabled, false if disabled > + * > + * Return: status code > + */ > +static efi_status_t efi_secure_boot_in_user_mode(u8 *enabled) > +{ > + efi_status_t ret; > + efi_uintn_t size = 0; > + u32 attributes; > + u32 mask = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS; > + > + ret = efi_get_variable_int(L"SecureBootDisable", > + &efi_global_variable_guid, > + &attributes, &size, NULL, NULL); > + if (ret == EFI_BUFFER_TOO_SMALL) { > + if (attributes ^ mask) { > + log_err("Unable to disable secure boot. Required attributes for SecureBootDisable variable: NV+BS\n"); > + *enabled = 1; > + } else { > + EFI_PRINT("Disabling secure boot due to existing SecureBootDisable variable\n"); > + *enabled = 0; > + } > + ret = EFI_SUCCESS; > + } else if (ret == EFI_NOT_FOUND) { > + *enabled = 1; > + ret = EFI_SUCCESS; > + } > + return ret; > +} > +#else > +static efi_status_t efi_secure_boot_in_user_mode(u8 *enabled) > +{ > + *enabled = 1; > + return EFI_SUCCESS; > +} > +#endif > + > /** > * efi_transfer_secure_state - handle a secure boot state transition > * @mode: new state > @@ -274,7 +316,11 @@ static efi_status_t efi_transfer_secure_state(enum efi_secure_mode mode) > if (ret != EFI_SUCCESS) > goto err; > } else if (mode == EFI_MODE_USER) { > - ret = efi_set_secure_state(1, 0, 0, 0); > + u8 secure_boot; > + ret = efi_secure_boot_in_user_mode(&secure_boot); > + if (ret != EFI_SUCCESS) > + goto err; > + ret = efi_set_secure_state(secure_boot, 0, 0, 0); > if (ret != EFI_SUCCESS) > goto err; > } else if (mode == EFI_MODE_SETUP) { >
Hi Heinrich, Heinrich Schuchardt <xypron.glpk@gmx.de> writes: > On 11/30/20 3:58 PM, Paulo Alcantara wrote: >> Introduce a new config option CONFIG_EFI_SECURE_BOOT_VAR_DISABLE to >> allow disabling EFI secure boot when the platform is operating in User >> Mode and there is an NV+BS EFI variable called "SecureBootDisable". >> Otherwise, keep it enabled by default. > > could you, please, explain why this is needed. I was just looking for an easier way to disable it without having to mess with the secure boot variables and possibly breaking secure boot altogether. Of course, we could do the same by creating such SecureBootDisable variable and forgetting about it. Since we're gonna provide u-boot package with the secure boot keys (PK, KEK, db, dbx) enrolled in (ESP)/ubootefi.var (generated by efivar.py script), and those certificates are only provided at build time, that would be tricky to get it enabled or disabled by removing and inserting the PK, finding the appropriate certificate depending on whether it is openSUSE or SLES. For instance, OVMF does have something like that [1]. [1] https://github.com/tianocore/edk2/blob/master/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c#L682 Thanks.
On 11/30/20 7:22 PM, Paulo Alcantara wrote: > Hi Heinrich, > > Heinrich Schuchardt <xypron.glpk@gmx.de> writes: > >> On 11/30/20 3:58 PM, Paulo Alcantara wrote: >>> Introduce a new config option CONFIG_EFI_SECURE_BOOT_VAR_DISABLE to >>> allow disabling EFI secure boot when the platform is operating in User >>> Mode and there is an NV+BS EFI variable called "SecureBootDisable". >>> Otherwise, keep it enabled by default. >> >> could you, please, explain why this is needed. > > I was just looking for an easier way to disable it without having to > mess with the secure boot variables and possibly breaking secure boot > altogether. Of course, we could do the same by creating such > SecureBootDisable variable and forgetting about it. Since we're gonna > provide u-boot package with the secure boot keys (PK, KEK, db, dbx) > enrolled in (ESP)/ubootefi.var (generated by efivar.py script), and > those certificates are only provided at build time, that would be tricky > to get it enabled or disabled by removing and inserting the PK, finding > the appropriate certificate depending on whether it is openSUSE or SLES. > > For instance, OVMF does have something like that [1]. > > [1] > https://github.com/tianocore/edk2/blob/master/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c#L682 > > Thanks. > Hello Paulo, how would you stop an attacker from disabling secure boot on your device and tempering with it if this configuration were enabled? Best regard Heinrich
Hi Heinrich, Heinrich Schuchardt <xypron.glpk@gmx.de> writes: > On 11/30/20 7:22 PM, Paulo Alcantara wrote: >> Heinrich Schuchardt <xypron.glpk@gmx.de> writes: >> >>> On 11/30/20 3:58 PM, Paulo Alcantara wrote: >>>> Introduce a new config option CONFIG_EFI_SECURE_BOOT_VAR_DISABLE to >>>> allow disabling EFI secure boot when the platform is operating in User >>>> Mode and there is an NV+BS EFI variable called "SecureBootDisable". >>>> Otherwise, keep it enabled by default. >>> >>> could you, please, explain why this is needed. >> >> I was just looking for an easier way to disable it without having to >> mess with the secure boot variables and possibly breaking secure boot >> altogether. Of course, we could do the same by creating such >> SecureBootDisable variable and forgetting about it. Since we're gonna >> provide u-boot package with the secure boot keys (PK, KEK, db, dbx) >> enrolled in (ESP)/ubootefi.var (generated by efivar.py script), and >> those certificates are only provided at build time, that would be tricky >> to get it enabled or disabled by removing and inserting the PK, finding >> the appropriate certificate depending on whether it is openSUSE or SLES. >> >> For instance, OVMF does have something like that [1]. >> >> [1] >> https://github.com/tianocore/edk2/blob/master/OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.c#L682 >> >> Thanks. >> > how would you stop an attacker from disabling secure boot on your device > and tempering with it if this configuration were enabled? Yep. There isn't much we can do, and it is even unauthenticated. Please ignore this patch. Thanks!
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 29ea14b2ee2a..d453905c7666 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -224,5 +224,18 @@ config EFI_SECURE_BOOT Once SecureBoot mode is enforced, any EFI binary can run only if it is signed with a trusted key. To do that, you need to install, at least, PK, KEK and db. + Note that SecureBoot mode may no longer be enforced when + EFI_SECURE_BOOT_VAR_DISABLE option is enabled. + +config EFI_SECURE_BOOT_VAR_DISABLE + bool "Permit to disable EFI secure boot when in User Mode" + depends on EFI_SECURE_BOOT + default n + help + Select this option to allow disabling EFI secure boot when + the platform is operating in User Mode (e.g. PK is enrolled) + and there is an NV+BS EFI variable called + "SecureBootDisable". A platform reset is also required to + actually disable it. endif diff --git a/lib/efi_loader/efi_var_common.c b/lib/efi_loader/efi_var_common.c index 1c7459266a38..89aa944180a4 100644 --- a/lib/efi_loader/efi_var_common.c +++ b/lib/efi_loader/efi_var_common.c @@ -241,6 +241,48 @@ err: return ret; } + +#ifdef CONFIG_EFI_SECURE_BOOT_VAR_DISABLE +/** + * efi_secure_boot_in_user_mode - check if secure boot enabled in User Mode + * + * @enabled: true if enabled, false if disabled + * + * Return: status code + */ +static efi_status_t efi_secure_boot_in_user_mode(u8 *enabled) +{ + efi_status_t ret; + efi_uintn_t size = 0; + u32 attributes; + u32 mask = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS; + + ret = efi_get_variable_int(L"SecureBootDisable", + &efi_global_variable_guid, + &attributes, &size, NULL, NULL); + if (ret == EFI_BUFFER_TOO_SMALL) { + if (attributes ^ mask) { + log_err("Unable to disable secure boot. Required attributes for SecureBootDisable variable: NV+BS\n"); + *enabled = 1; + } else { + EFI_PRINT("Disabling secure boot due to existing SecureBootDisable variable\n"); + *enabled = 0; + } + ret = EFI_SUCCESS; + } else if (ret == EFI_NOT_FOUND) { + *enabled = 1; + ret = EFI_SUCCESS; + } + return ret; +} +#else +static efi_status_t efi_secure_boot_in_user_mode(u8 *enabled) +{ + *enabled = 1; + return EFI_SUCCESS; +} +#endif + /** * efi_transfer_secure_state - handle a secure boot state transition * @mode: new state @@ -274,7 +316,11 @@ static efi_status_t efi_transfer_secure_state(enum efi_secure_mode mode) if (ret != EFI_SUCCESS) goto err; } else if (mode == EFI_MODE_USER) { - ret = efi_set_secure_state(1, 0, 0, 0); + u8 secure_boot; + ret = efi_secure_boot_in_user_mode(&secure_boot); + if (ret != EFI_SUCCESS) + goto err; + ret = efi_set_secure_state(secure_boot, 0, 0, 0); if (ret != EFI_SUCCESS) goto err; } else if (mode == EFI_MODE_SETUP) {
Introduce a new config option CONFIG_EFI_SECURE_BOOT_VAR_DISABLE to allow disabling EFI secure boot when the platform is operating in User Mode and there is an NV+BS EFI variable called "SecureBootDisable". Otherwise, keep it enabled by default. Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz> --- lib/efi_loader/Kconfig | 13 +++++++++ lib/efi_loader/efi_var_common.c | 48 ++++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-)