Message ID | 20180805032119.20485-1-jlee@suse.com (mailing list archive) |
---|---|
Headers | show |
Series | Add EFI secure key to key retention service | expand |
Hello Chun,yi, On 5 August 2018 at 05:21, Lee, Chun-Yi <joeyli.kernel@gmail.com> wrote: > When secure boot is enabled, only signed EFI binary can access > EFI boot service variable before ExitBootService. Which means that > the EFI boot service variable is secure. > No it, isn't, and this is a very dangerous assumption to make. 'Secure' means different things to different people. 'Secure boot' is a misnomer, since it is too vague: it should be called 'authenticated boot', and the catch is that authentication using public-key crypto does not involve secrets at all. The UEFI variable store was not designed with confidentiality in mind, and assuming [given the reputation of EFI on the implementation side] that you can use it to keep secrets is rather unwise imho. > This patch set add functions to EFI boot stub to generate a 512-bit > random number that it can be used as a root key for encryption and > authentication. This root key will be kept in EFI boot service variable. > EFI boot stub will read and transfer ERK (efi root key) to kernel. > > At runtime, the ERK can be used to encrypted/authentication other > random number to generate EFI secure key. The EFI secure key can be > a new master key type for encrypted key. It's useful for hibernation > or evm. > > Here is the proof of concept for using EFI secure key in hibernation: > https://github.com/joeyli/linux-s4sign/commit/6311e97038974bc5de8121769fb4d34470009566 > > Cc: Kees Cook <keescook@chromium.org> > Cc: Thomas Gleixner <tglx@linutronix.de> > Cc: Ingo Molnar <mingo@redhat.com> > Cc: "H. Peter Anvin" <hpa@zytor.com> > Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> > Cc: Pavel Machek <pavel@ucw.cz> > Cc: Chen Yu <yu.c.chen@intel.com> > Cc: Oliver Neukum <oneukum@suse.com> > Cc: Ryan Chen <yu.chen.surf@gmail.com> > Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> > Cc: David Howells <dhowells@redhat.com> > Cc: Mimi Zohar <zohar@linux.vnet.ibm.com> > Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com> > > Lee, Chun-Yi (6): > x86/KASLR: make getting random long number function public > efi: the function transfers status to string > efi: generate efi root key in EFI boot stub > key: add EFI secure key type > key: add EFI secure key as a master key type > key: enforce the secure boot checking when loading efi root key > > Documentation/admin-guide/kernel-parameters.txt | 6 + > arch/x86/boot/compressed/Makefile | 1 + > arch/x86/boot/compressed/cpuflags.c | 2 +- > arch/x86/boot/compressed/eboot.c | 2 + > arch/x86/boot/compressed/efi_root_key.c | 212 +++++++ > arch/x86/boot/compressed/kaslr.c | 21 - > arch/x86/boot/compressed/misc.c | 17 + > arch/x86/boot/compressed/misc.h | 12 +- > arch/x86/include/asm/efi.h | 13 + > arch/x86/include/uapi/asm/bootparam.h | 1 + > arch/x86/kernel/setup.c | 3 + > arch/x86/lib/kaslr.c | 61 +- > arch/x86/lib/random.c | 68 +++ > drivers/firmware/efi/Kconfig | 31 + > drivers/firmware/efi/Makefile | 1 + > drivers/firmware/efi/efi-secure-key.c | 748 ++++++++++++++++++++++++ > include/keys/efi-type.h | 57 ++ > include/linux/efi.h | 40 ++ > include/linux/kernel.h | 3 +- > kernel/panic.c | 1 + > security/keys/encrypted-keys/encrypted.c | 10 + > 21 files changed, 1226 insertions(+), 84 deletions(-) > create mode 100644 arch/x86/boot/compressed/efi_root_key.c > create mode 100644 arch/x86/lib/random.c > create mode 100644 drivers/firmware/efi/efi-secure-key.c > create mode 100644 include/keys/efi-type.h > > -- > 2.13.6 >
On Sun, Aug 05, 2018 at 09:25:56AM +0200, Ard Biesheuvel wrote: > Hello Chun,yi, > > On 5 August 2018 at 05:21, Lee, Chun-Yi <joeyli.kernel@gmail.com> wrote: > > When secure boot is enabled, only signed EFI binary can access > > EFI boot service variable before ExitBootService. Which means that > > the EFI boot service variable is secure. > > > > No it, isn't, and this is a very dangerous assumption to make. > > 'Secure' means different things to different people. 'Secure boot' is > a misnomer, since it is too vague: it should be called 'authenticated > boot', and the catch is that authentication using public-key crypto > does not involve secrets at all. The UEFI variable store was not > designed with confidentiality in mind, and assuming [given the > reputation of EFI on the implementation side] that you can use it to > keep secrets is rather unwise imho. > I agreed with you. Especially I can't refute the part of EFI implementation, manufacturers can not be fully trusted. I am thinking a case... Some machines provide setup mode. If user earses all manufacturer's reloaded keys and only enrolls their own key. Which means that user fully controls the authentication environment. Then the EFI boot service varible can be trusted by the user. But this case is too strict for normal user. Thanks for your review and comments. I will think more about your suggestions. Joey Lee
On Sun, 2018-08-05 at 09:25 +0200, Ard Biesheuvel wrote: > Hello Chun,yi, > > On 5 August 2018 at 05:21, Lee, Chun-Yi <joeyli.kernel@gmail.com> > wrote: > > When secure boot is enabled, only signed EFI binary can access > > EFI boot service variable before ExitBootService. Which means that > > the EFI boot service variable is secure. > > > > No it, isn't, and this is a very dangerous assumption to make. > > 'Secure' means different things to different people. 'Secure boot' is > a misnomer, since it is too vague: it should be called 'authenticated > boot', and the catch is that authentication using public-key crypto > does not involve secrets at all. Hang on, let's not throw the baby out with the bathwater here. The design of "secure boot" is to create a boot time environment where only trusted code may execute. We rely on this trust guarantee when we pivot from the EFI to the MoK root of trust in shim. The reason we in Linux trust this guarantee is that it pertains to the boot environment only, so any violation would allow Windows boot to be compromised as well and we trust Microsoft's Business interests in securing windows far enough to think this would be dealt with very severely and it's an outcome the ODMs (who also add secure boot keys) are worried enough about to be very careful. The rub (and this is where I'm agreeing with Ard) is that any use case we come up with where a violation wouldn't cause a problem in windows is a use case where we cannot rely on the guarantee because Microsoft no longer has a strong business interest in policing it. This, for instance, is why we don't populate the Linux trusted keyrings with the secure boot keys (we may trust them in the boot environment where compromise would be shared with windows but we can't trust them in the Linux OS environment where it wouldn't). So this means we have to be very careful coming up with uses for secure boot that aren't strictly rooted in the guarantee as enforced by the business interests of Microsoft and the ODMs. > The UEFI variable store was not designed with confidentiality in > mind, and assuming [given the reputation of EFI on the implementation > side] that you can use it to keep secrets is rather unwise imho. Agree completely here: Microsoft doesn't use UEFI variables for confidentiality, so we shouldn't either. If you want confidentiality, use a TPM (like Microsoft does for the bitlocker key). James
On 5 August 2018 at 18:31, joeyli <jlee@suse.com> wrote: > On Sun, Aug 05, 2018 at 09:25:56AM +0200, Ard Biesheuvel wrote: >> Hello Chun,yi, >> >> On 5 August 2018 at 05:21, Lee, Chun-Yi <joeyli.kernel@gmail.com> wrote: >> > When secure boot is enabled, only signed EFI binary can access >> > EFI boot service variable before ExitBootService. Which means that >> > the EFI boot service variable is secure. >> > >> >> No it, isn't, and this is a very dangerous assumption to make. >> >> 'Secure' means different things to different people. 'Secure boot' is >> a misnomer, since it is too vague: it should be called 'authenticated >> boot', and the catch is that authentication using public-key crypto >> does not involve secrets at all. The UEFI variable store was not >> designed with confidentiality in mind, and assuming [given the >> reputation of EFI on the implementation side] that you can use it to >> keep secrets is rather unwise imho. >> > > I agreed with you. Especially I can't refute the part of EFI > implementation, manufacturers can not be fully trusted. > > I am thinking a case... Some machines provide setup mode. If user > earses all manufacturer's reloaded keys and only enrolls their own > key. Which means that user fully controls the authentication > environment. Then the EFI boot service varible can be trusted by > the user. This has nothing to do with trust but everything to do with confidentiality. *Nothing* in the UEFI variable store stack has been designed or implemented with confidentiality in mind. The contents of EFI variables are readable in the clear from the SPI flash. Code that handles variable store reads may leave unsanitized buffers behind. We have efivarfs that needs to be modified to hide 'secret' variables, but also, to kzfree() every allocation that is used in handling varstore access etc etc. > But this case is too strict for normal user. > > Thanks for your review and comments. I will think more about your > suggestions. > > Joey Lee
Hi James, On Sun, Aug 05, 2018 at 10:47:26AM -0700, James Bottomley wrote: > On Sun, 2018-08-05 at 09:25 +0200, Ard Biesheuvel wrote: > > Hello Chun,yi, > > > > On 5 August 2018 at 05:21, Lee, Chun-Yi <joeyli.kernel@gmail.com> > > wrote: > > > When secure boot is enabled, only signed EFI binary can access > > > EFI boot service variable before ExitBootService. Which means that > > > the EFI boot service variable is secure. > > > > > > > No it, isn't, and this is a very dangerous assumption to make. > > > > 'Secure' means different things to different people. 'Secure boot' is > > a misnomer, since it is too vague: it should be called 'authenticated > > boot', and the catch is that authentication using public-key crypto > > does not involve secrets at all. > > Hang on, let's not throw the baby out with the bathwater here. > > The design of "secure boot" is to create a boot time environment where > only trusted code may execute. We rely on this trust guarantee when we > pivot from the EFI to the MoK root of trust in shim. > > The reason we in Linux trust this guarantee is that it pertains to the > boot environment only, so any violation would allow Windows boot to be > compromised as well and we trust Microsoft's Business interests in > securing windows far enough to think this would be dealt with very > severely and it's an outcome the ODMs (who also add secure boot keys) > are worried enough about to be very careful. > > The rub (and this is where I'm agreeing with Ard) is that any use case > we come up with where a violation wouldn't cause a problem in windows > is a use case where we cannot rely on the guarantee because Microsoft > no longer has a strong business interest in policing it. This, for > instance, is why we don't populate the Linux trusted keyrings with the > secure boot keys (we may trust them in the boot environment where > compromise would be shared with windows but we can't trust them in the > Linux OS environment where it wouldn't). So this means we have to be > very careful coming up with uses for secure boot that aren't strictly > rooted in the guarantee as enforced by the business interests of > Microsoft and the ODMs. > Thank you for providing the view point from Microsoft bussiness ineterests. I agreed with you. Honestly I didn't think this point before. > > The UEFI variable store was not designed with confidentiality in > > mind, and assuming [given the reputation of EFI on the implementation > > side] that you can use it to keep secrets is rather unwise imho. > > Agree completely here: Microsoft doesn't use UEFI variables for > confidentiality, so we shouldn't either. If you want confidentiality, > use a TPM (like Microsoft does for the bitlocker key). > OK~~ Then I will use TPM trusted key + encrypted key in hibernation encryption/authentication. Thanks for James and Ard's comments. Joey Lee
When secure boot is enabled, only signed EFI binary can access EFI boot service variable before ExitBootService. Which means that the EFI boot service variable is secure. This patch set add functions to EFI boot stub to generate a 512-bit random number that it can be used as a root key for encryption and authentication. This root key will be kept in EFI boot service variable. EFI boot stub will read and transfer ERK (efi root key) to kernel. At runtime, the ERK can be used to encrypted/authentication other random number to generate EFI secure key. The EFI secure key can be a new master key type for encrypted key. It's useful for hibernation or evm. Here is the proof of concept for using EFI secure key in hibernation: https://github.com/joeyli/linux-s4sign/commit/6311e97038974bc5de8121769fb4d34470009566 Cc: Kees Cook <keescook@chromium.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> Cc: Pavel Machek <pavel@ucw.cz> Cc: Chen Yu <yu.c.chen@intel.com> Cc: Oliver Neukum <oneukum@suse.com> Cc: Ryan Chen <yu.chen.surf@gmail.com> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: David Howells <dhowells@redhat.com> Cc: Mimi Zohar <zohar@linux.vnet.ibm.com> Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com> Lee, Chun-Yi (6): x86/KASLR: make getting random long number function public efi: the function transfers status to string efi: generate efi root key in EFI boot stub key: add EFI secure key type key: add EFI secure key as a master key type key: enforce the secure boot checking when loading efi root key Documentation/admin-guide/kernel-parameters.txt | 6 + arch/x86/boot/compressed/Makefile | 1 + arch/x86/boot/compressed/cpuflags.c | 2 +- arch/x86/boot/compressed/eboot.c | 2 + arch/x86/boot/compressed/efi_root_key.c | 212 +++++++ arch/x86/boot/compressed/kaslr.c | 21 - arch/x86/boot/compressed/misc.c | 17 + arch/x86/boot/compressed/misc.h | 12 +- arch/x86/include/asm/efi.h | 13 + arch/x86/include/uapi/asm/bootparam.h | 1 + arch/x86/kernel/setup.c | 3 + arch/x86/lib/kaslr.c | 61 +- arch/x86/lib/random.c | 68 +++ drivers/firmware/efi/Kconfig | 31 + drivers/firmware/efi/Makefile | 1 + drivers/firmware/efi/efi-secure-key.c | 748 ++++++++++++++++++++++++ include/keys/efi-type.h | 57 ++ include/linux/efi.h | 40 ++ include/linux/kernel.h | 3 +- kernel/panic.c | 1 + security/keys/encrypted-keys/encrypted.c | 10 + 21 files changed, 1226 insertions(+), 84 deletions(-) create mode 100644 arch/x86/boot/compressed/efi_root_key.c create mode 100644 arch/x86/lib/random.c create mode 100644 drivers/firmware/efi/efi-secure-key.c create mode 100644 include/keys/efi-type.h