mbox series

[0/6,RFC] Add EFI secure key to key retention service

Message ID 20180805032119.20485-1-jlee@suse.com (mailing list archive)
Headers show
Series Add EFI secure key to key retention service | expand

Message

Chun-Yi Lee Aug. 5, 2018, 3:21 a.m. UTC
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

Comments

Ard Biesheuvel Aug. 5, 2018, 7:25 a.m. UTC | #1
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
>
joeyli Aug. 5, 2018, 4:31 p.m. UTC | #2
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
James Bottomley Aug. 5, 2018, 5:47 p.m. UTC | #3
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
Ard Biesheuvel Aug. 5, 2018, 7 p.m. UTC | #4
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
joeyli Aug. 6, 2018, 6 a.m. UTC | #5
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