mbox series

[RFC,00/12] Enroll kernel keys thru MOK

Message ID 20210707024403.1083977-1-eric.snowberg@oracle.com (mailing list archive)
Headers show
Series Enroll kernel keys thru MOK | expand

Message

Eric Snowberg July 7, 2021, 2:43 a.m. UTC
This is a follow up to the "Add additional MOK vars" [1] series I 
previously sent.  This series incorporates the feedback given 
both publicly on the mailing list and privately from Mimi. This 
series just focuses on getting end-user keys into the kernel trust 
boundary.

Currently, pre-boot keys are not trusted within the Linux boundary [2].
Pre-boot keys include UEFI Secure Boot DB keys and MOKList keys. These
keys are loaded into the platform keyring and can only be used for kexec.
If an end-user wants to use their own key within the Linux trust
boundary, they must either compile it into the kernel themselves or use
the insert-sys-cert script. Both options present a problem. Many
end-users do not want to compile their own kernels. With the
insert-sys-cert option, there are missing upstream changes [3].  Also,
with the insert-sys-cert option, the end-user must re-sign their kernel
again with their own key, and then insert that key into the MOK db.
Another problem with insert-sys-cert is that only a single key can be
inserted into a compressed kernel.

Having the ability to insert a key into the Linux trust boundary opens
up various possibilities.  The end-user can use a pre-built kernel and
sign their own kernel modules.  It also opens up the ability for an
end-user to more easily use digital signature based IMA-appraisal.  To
get a key into the ima keyring, it must be signed by a key within the
Linux trust boundary.

Downstream Linux distros try to have a single signed kernel for each
architecture.  Each end-user may use this kernel in entirely different
ways.  Some downstream kernels have chosen to always trust platform keys
within the Linux trust boundary for kernel module signing.  These
kernels have no way of using digital signature base IMA appraisal. 

This series adds a new MOK variable to shim.  This variable allows the
end-user to decide if they want to trust keys enrolled in the MOK within
the Linux trust boundary.  By default, nothing changes; MOK keys are
not trusted within the Linux kernel.  They are only trusted after the 
end-user makes the decision themselves.  The end-user would set this
through mokutil using a new --trust-mok option [4]. This would work
similar to how the kernel uses MOK variable to enable/disable signature
validation as well as use/ignore the db.

When shim boots, it mirrors the new MokTML Boot Services variable to a new
MokListTrustedRT Runtime Services variable and extends PCR14. 
MokListTrustedRT is written without EFI_VARIABLE_NON_VOLATILE set,
preventing an end-user from setting it after booting and doing a kexec.

When the kernel boots, if MokListTrustedRT is set and
EFI_VARIABLE_NON_VOLATILE is not set, the MokListRT is loaded into the
secondary trusted keyring instead of the platform keyring. Mimi has
suggested that only CA keys or keys that can be vouched for by other
kernel keys be loaded. All other certs will load into the platform
keyring instead.

This is done by introducing a new .mok keyring.  This keyring is only
used during boot.  After booting it is destroyed and not visible to the
end-user after booting completes.  This keyring contains a new keyring
permission that only allows CA keys to be loaded. If the permission
fails, the key is later loaded into the platform keyring.  After keys
are added into the .mok keyring, they are moved into the secondary
trusted keyring.

Secure Boot keys will never be trusted.  They will always be loaded
into the platform keyring.  If an end-user wanted to trust one, they
would need to enroll it into the MOK.

I have included links to both the mokutil [3] and shim [4] changes I
have made to support this new functionality.

Thank you and looking forward to hearing your reviews.

[1] https://lore.kernel.org/linux-integrity/20210517225714.498032-1-eric.snowberg@oracle.com/
[2] https://lore.kernel.org/lkml/1556221605.24945.3.camel@HansenPartnership.com/
[3] https://lore.kernel.org/patchwork/cover/902768/
[4] https://github.com/esnowberg/mokutil/tree/0.3.0-mokvars-v2
[5] https://github.com/esnowberg/shim/tree/mokvars-v2

Eric Snowberg (12):
  KEYS: Add KEY_ALLOC_BYPASS_RESTRICTION option to key_move
  KEYS: Allow unrestricted keys to be moved to the secondary keyring
  KEYS: CA link restriction
  integrity: add integrity_destroy_keyring
  integrity: Introduce mok keyring
  integrity: Trust mok keys if MokListTrustedRT found
  integrity: add add_to_mok_keyring
  integrity: restrict INTEGRITY_KEYRING_MOK to
    restrict_link_by_secondary_trusted_or_ca
  integrity: accessor function to get trust_moklist
  integrity: add new keyring handler
  integrity: move keys from the mok keyring into the secondary keyring
  integrity: Suppress error message for keys added to the mok keyring

 certs/system_keyring.c                        | 43 +++++++++
 crypto/asymmetric_keys/restrict.c             | 60 +++++++++++++
 include/crypto/public_key.h                   |  5 ++
 include/keys/system_keyring.h                 | 21 +++++
 security/integrity/Makefile                   |  3 +-
 security/integrity/digsig.c                   | 26 +++++-
 security/integrity/integrity.h                | 21 ++++-
 .../platform_certs/keyring_handler.c          | 17 +++-
 .../platform_certs/keyring_handler.h          |  5 ++
 security/integrity/platform_certs/load_uefi.c |  5 +-
 .../integrity/platform_certs/mok_keyring.c    | 90 +++++++++++++++++++
 security/keys/keyring.c                       | 10 ++-
 12 files changed, 294 insertions(+), 12 deletions(-)
 create mode 100644 security/integrity/platform_certs/mok_keyring.c


base-commit: 13311e74253fe64329390df80bed3f07314ddd61

Comments

Christoph Hellwig July 7, 2021, 6:46 a.m. UTC | #1
On Tue, Jul 06, 2021 at 10:43:51PM -0400, Eric Snowberg wrote:
> This is a follow up to the "Add additional MOK vars" [1] series I 
> previously sent.  This series incorporates the feedback given 
> both publicly on the mailing list and privately from Mimi. This 
> series just focuses on getting end-user keys into the kernel trust 
> boundary.

WTF is MOK?
Mimi Zohar July 7, 2021, 12:39 p.m. UTC | #2
On Tue, 2021-07-06 at 22:43 -0400, Eric Snowberg wrote:
> This is a follow up to the "Add additional MOK vars" [1] series I 
> previously sent.  This series incorporates the feedback given 
> both publicly on the mailing list and privately from Mimi. This 
> series just focuses on getting end-user keys into the kernel trust 
> boundary.
> 
> Currently, pre-boot keys are not trusted within the Linux boundary [2].
> Pre-boot keys include UEFI Secure Boot DB keys and MOKList keys. These
> keys are loaded into the platform keyring and can only be used for kexec.
> If an end-user wants to use their own key within the Linux trust
> boundary, they must either compile it into the kernel themselves or use
> the insert-sys-cert script. Both options present a problem. Many
> end-users do not want to compile their own kernels. With the
> insert-sys-cert option, there are missing upstream changes [3].  Also,
> with the insert-sys-cert option, the end-user must re-sign their kernel
> again with their own key, and then insert that key into the MOK db.
> Another problem with insert-sys-cert is that only a single key can be
> inserted into a compressed kernel.
> 
> Having the ability to insert a key into the Linux trust boundary opens
> up various possibilities.  The end-user can use a pre-built kernel and
> sign their own kernel modules.  It also opens up the ability for an
> end-user to more easily use digital signature based IMA-appraisal.  To
> get a key into the ima keyring, it must be signed by a key within the
> Linux trust boundary.
> 
> Downstream Linux distros try to have a single signed kernel for each
> architecture.  Each end-user may use this kernel in entirely different
> ways.  Some downstream kernels have chosen to always trust platform keys
> within the Linux trust boundary for kernel module signing.  These
> kernels have no way of using digital signature base IMA appraisal. 
> 
> This series adds a new MOK variable to shim.  This variable allows the
> end-user to decide if they want to trust keys enrolled in the MOK within
> the Linux trust boundary.  By default, nothing changes; MOK keys are
> not trusted within the Linux kernel.  They are only trusted after the 
> end-user makes the decision themselves.  The end-user would set this
> through mokutil using a new --trust-mok option [4]. This would work
> similar to how the kernel uses MOK variable to enable/disable signature
> validation as well as use/ignore the db.
> 
> When shim boots, it mirrors the new MokTML Boot Services variable to a new
> MokListTrustedRT Runtime Services variable and extends PCR14. 
> MokListTrustedRT is written without EFI_VARIABLE_NON_VOLATILE set,
> preventing an end-user from setting it after booting and doing a kexec.
> 
> When the kernel boots, if MokListTrustedRT is set and
> EFI_VARIABLE_NON_VOLATILE is not set, the MokListRT is loaded into the
> secondary trusted keyring instead of the platform keyring. Mimi has
> suggested that only CA keys or keys that can be vouched for by other
> kernel keys be loaded. All other certs will load into the platform
> keyring instead.

Loading MOK CA keys onto the "secondary" keyring would need to be an
exception.   Once CA keys are loaded onto the "secondary" keyring,  any
certificates signed by those CA keys may be loaded normally, without
needing an exception, onto the "secondary" keyring.  The kernel MAY
load those keys onto the "secondary" keyring, but really doesn't need
to be involved.

Loading ALL of the MOK db keys onto either the "secondary" or
"platform" keyrings makes the code a lot more complicated.  Is it
really necessary?

thanks,

Mimi

> 
> This is done by introducing a new .mok keyring.  This keyring is only
> used during boot.  After booting it is destroyed and not visible to the
> end-user after booting completes.  This keyring contains a new keyring
> permission that only allows CA keys to be loaded. If the permission
> fails, the key is later loaded into the platform keyring.  After keys
> are added into the .mok keyring, they are moved into the secondary
> trusted keyring.
> 
> Secure Boot keys will never be trusted.  They will always be loaded
> into the platform keyring.  If an end-user wanted to trust one, they
> would need to enroll it into the MOK.
> 
> I have included links to both the mokutil [3] and shim [4] changes I
> have made to support this new functionality.
> 
> Thank you and looking forward to hearing your reviews.
> 
> [1] https://lore.kernel.org/linux-integrity/20210517225714.498032-1-eric.snowberg@oracle.com/
> [2] https://lore.kernel.org/lkml/1556221605.24945.3.camel@HansenPartnership.com/
> [3] https://lore.kernel.org/patchwork/cover/902768/
> [4] https://github.com/esnowberg/mokutil/tree/0.3.0-mokvars-v2
> [5] https://github.com/esnowberg/shim/tree/mokvars-v2
> 
> Eric Snowberg (12):
>   KEYS: Add KEY_ALLOC_BYPASS_RESTRICTION option to key_move
>   KEYS: Allow unrestricted keys to be moved to the secondary keyring
>   KEYS: CA link restriction
>   integrity: add integrity_destroy_keyring
>   integrity: Introduce mok keyring
>   integrity: Trust mok keys if MokListTrustedRT found
>   integrity: add add_to_mok_keyring
>   integrity: restrict INTEGRITY_KEYRING_MOK to
>     restrict_link_by_secondary_trusted_or_ca
>   integrity: accessor function to get trust_moklist
>   integrity: add new keyring handler
>   integrity: move keys from the mok keyring into the secondary keyring
>   integrity: Suppress error message for keys added to the mok keyring
> 
>  certs/system_keyring.c                        | 43 +++++++++
>  crypto/asymmetric_keys/restrict.c             | 60 +++++++++++++
>  include/crypto/public_key.h                   |  5 ++
>  include/keys/system_keyring.h                 | 21 +++++
>  security/integrity/Makefile                   |  3 +-
>  security/integrity/digsig.c                   | 26 +++++-
>  security/integrity/integrity.h                | 21 ++++-
>  .../platform_certs/keyring_handler.c          | 17 +++-
>  .../platform_certs/keyring_handler.h          |  5 ++
>  security/integrity/platform_certs/load_uefi.c |  5 +-
>  .../integrity/platform_certs/mok_keyring.c    | 90 +++++++++++++++++++
>  security/keys/keyring.c                       | 10 ++-
>  12 files changed, 294 insertions(+), 12 deletions(-)
>  create mode 100644 security/integrity/platform_certs/mok_keyring.c
> 
> 
> base-commit: 13311e74253fe64329390df80bed3f07314ddd61
Eric Snowberg July 7, 2021, 4:23 p.m. UTC | #3
> On Jul 7, 2021, at 12:46 AM, Christoph Hellwig <hch@infradead.org> wrote:
> 
> On Tue, Jul 06, 2021 at 10:43:51PM -0400, Eric Snowberg wrote:
>> This is a follow up to the "Add additional MOK vars" [1] series I 
>> previously sent.  This series incorporates the feedback given 
>> both publicly on the mailing list and privately from Mimi. This 
>> series just focuses on getting end-user keys into the kernel trust 
>> boundary.
> 
> WTF is MOK?

MOK stands for Machine Owner Key.   The MOK facility can be used to 
import keys that you use to sign your own development kernel build, 
so that it is able to boot with UEFI Secure Boot enabled. Many Linux 
distributions have implemented UEFI Secure Boot using these keys 
as well as the ones Secure Boot provides.  It allows the end-user 
a choice, instead of locking them into only being able to use keys 
their hardware manufacture provided, or forcing them to enroll keys 
through their BIOS.
Eric Snowberg July 7, 2021, 4:28 p.m. UTC | #4
> On Jul 7, 2021, at 6:39 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> 
> On Tue, 2021-07-06 at 22:43 -0400, Eric Snowberg wrote:
>> This is a follow up to the "Add additional MOK vars" [1] series I 
>> previously sent.  This series incorporates the feedback given 
>> both publicly on the mailing list and privately from Mimi. This 
>> series just focuses on getting end-user keys into the kernel trust 
>> boundary.
>> 
>> Currently, pre-boot keys are not trusted within the Linux boundary [2].
>> Pre-boot keys include UEFI Secure Boot DB keys and MOKList keys. These
>> keys are loaded into the platform keyring and can only be used for kexec.
>> If an end-user wants to use their own key within the Linux trust
>> boundary, they must either compile it into the kernel themselves or use
>> the insert-sys-cert script. Both options present a problem. Many
>> end-users do not want to compile their own kernels. With the
>> insert-sys-cert option, there are missing upstream changes [3].  Also,
>> with the insert-sys-cert option, the end-user must re-sign their kernel
>> again with their own key, and then insert that key into the MOK db.
>> Another problem with insert-sys-cert is that only a single key can be
>> inserted into a compressed kernel.
>> 
>> Having the ability to insert a key into the Linux trust boundary opens
>> up various possibilities.  The end-user can use a pre-built kernel and
>> sign their own kernel modules.  It also opens up the ability for an
>> end-user to more easily use digital signature based IMA-appraisal.  To
>> get a key into the ima keyring, it must be signed by a key within the
>> Linux trust boundary.
>> 
>> Downstream Linux distros try to have a single signed kernel for each
>> architecture.  Each end-user may use this kernel in entirely different
>> ways.  Some downstream kernels have chosen to always trust platform keys
>> within the Linux trust boundary for kernel module signing.  These
>> kernels have no way of using digital signature base IMA appraisal. 
>> 
>> This series adds a new MOK variable to shim.  This variable allows the
>> end-user to decide if they want to trust keys enrolled in the MOK within
>> the Linux trust boundary.  By default, nothing changes; MOK keys are
>> not trusted within the Linux kernel.  They are only trusted after the 
>> end-user makes the decision themselves.  The end-user would set this
>> through mokutil using a new --trust-mok option [4]. This would work
>> similar to how the kernel uses MOK variable to enable/disable signature
>> validation as well as use/ignore the db.
>> 
>> When shim boots, it mirrors the new MokTML Boot Services variable to a new
>> MokListTrustedRT Runtime Services variable and extends PCR14. 
>> MokListTrustedRT is written without EFI_VARIABLE_NON_VOLATILE set,
>> preventing an end-user from setting it after booting and doing a kexec.
>> 
>> When the kernel boots, if MokListTrustedRT is set and
>> EFI_VARIABLE_NON_VOLATILE is not set, the MokListRT is loaded into the
>> secondary trusted keyring instead of the platform keyring. Mimi has
>> suggested that only CA keys or keys that can be vouched for by other
>> kernel keys be loaded. All other certs will load into the platform
>> keyring instead.
> 
> Loading MOK CA keys onto the "secondary" keyring would need to be an
> exception.   Once CA keys are loaded onto the "secondary" keyring,  any
> certificates signed by those CA keys may be loaded normally, without
> needing an exception, onto the "secondary" keyring.  The kernel MAY
> load those keys onto the "secondary" keyring, but really doesn't need
> to be involved.
> 
> Loading ALL of the MOK db keys onto either the "secondary" or
> "platform" keyrings makes the code a lot more complicated.  Is it
> really necessary?

Today all keys are loaded into the platform keyring. For kexec_file_load, 
the platform and secondary keys are trusted the same.  If this series were 
not to load them all into either keyring, it would be a kexec_file_load 
regression, since keys that previously loaded into the platform keyring 
could be missing.  The complexity arises from the CA key restriction.  
If that requirement was removed, this series would be much smaller.
Christoph Hellwig July 7, 2021, 4:28 p.m. UTC | #5
On Wed, Jul 07, 2021 at 10:23:04AM -0600, Eric Snowberg wrote:
> 
> > On Jul 7, 2021, at 12:46 AM, Christoph Hellwig <hch@infradead.org> wrote:
> > 
> > On Tue, Jul 06, 2021 at 10:43:51PM -0400, Eric Snowberg wrote:
> >> This is a follow up to the "Add additional MOK vars" [1] series I 
> >> previously sent.  This series incorporates the feedback given 
> >> both publicly on the mailing list and privately from Mimi. This 
> >> series just focuses on getting end-user keys into the kernel trust 
> >> boundary.
> > 
> > WTF is MOK?
> 
> MOK stands for Machine Owner Key.   The MOK facility can be used to 
> import keys that you use to sign your own development kernel build, 
> so that it is able to boot with UEFI Secure Boot enabled. Many Linux 
> distributions have implemented UEFI Secure Boot using these keys 
> as well as the ones Secure Boot provides.  It allows the end-user 
> a choice, instead of locking them into only being able to use keys 
> their hardware manufacture provided, or forcing them to enroll keys 
> through their BIOS.

Please spell this out in your cover letters and commit logs.
Eric Snowberg July 7, 2021, 4:45 p.m. UTC | #6
> On Jul 7, 2021, at 10:28 AM, Christoph Hellwig <hch@infradead.org> wrote:
> 
> On Wed, Jul 07, 2021 at 10:23:04AM -0600, Eric Snowberg wrote:
>> 
>>> On Jul 7, 2021, at 12:46 AM, Christoph Hellwig <hch@infradead.org> wrote:
>>> 
>>> On Tue, Jul 06, 2021 at 10:43:51PM -0400, Eric Snowberg wrote:
>>>> This is a follow up to the "Add additional MOK vars" [1] series I 
>>>> previously sent.  This series incorporates the feedback given 
>>>> both publicly on the mailing list and privately from Mimi. This 
>>>> series just focuses on getting end-user keys into the kernel trust 
>>>> boundary.
>>> 
>>> WTF is MOK?
>> 
>> MOK stands for Machine Owner Key.   The MOK facility can be used to 
>> import keys that you use to sign your own development kernel build, 
>> so that it is able to boot with UEFI Secure Boot enabled. Many Linux 
>> distributions have implemented UEFI Secure Boot using these keys 
>> as well as the ones Secure Boot provides.  It allows the end-user 
>> a choice, instead of locking them into only being able to use keys 
>> their hardware manufacture provided, or forcing them to enroll keys 
>> through their BIOS.
> 
> Please spell this out in your cover letters and commit logs.

I will add it in the future, thanks.
Mimi Zohar July 7, 2021, 5 p.m. UTC | #7
On Wed, 2021-07-07 at 10:28 -0600, Eric Snowberg wrote:
> > On Jul 7, 2021, at 6:39 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> > 
> > On Tue, 2021-07-06 at 22:43 -0400, Eric Snowberg wrote:
> >> This is a follow up to the "Add additional MOK vars" [1] series I 
> >> previously sent.  This series incorporates the feedback given 
> >> both publicly on the mailing list and privately from Mimi. This 
> >> series just focuses on getting end-user keys into the kernel trust 
> >> boundary.
> >> 
> >> Currently, pre-boot keys are not trusted within the Linux boundary [2].
> >> Pre-boot keys include UEFI Secure Boot DB keys and MOKList keys. These
> >> keys are loaded into the platform keyring and can only be used for kexec.
> >> If an end-user wants to use their own key within the Linux trust
> >> boundary, they must either compile it into the kernel themselves or use
> >> the insert-sys-cert script. Both options present a problem. Many
> >> end-users do not want to compile their own kernels. With the
> >> insert-sys-cert option, there are missing upstream changes [3].  Also,
> >> with the insert-sys-cert option, the end-user must re-sign their kernel
> >> again with their own key, and then insert that key into the MOK db.
> >> Another problem with insert-sys-cert is that only a single key can be
> >> inserted into a compressed kernel.
> >> 
> >> Having the ability to insert a key into the Linux trust boundary opens
> >> up various possibilities.  The end-user can use a pre-built kernel and
> >> sign their own kernel modules.  It also opens up the ability for an
> >> end-user to more easily use digital signature based IMA-appraisal.  To
> >> get a key into the ima keyring, it must be signed by a key within the
> >> Linux trust boundary.
> >> 
> >> Downstream Linux distros try to have a single signed kernel for each
> >> architecture.  Each end-user may use this kernel in entirely different
> >> ways.  Some downstream kernels have chosen to always trust platform keys
> >> within the Linux trust boundary for kernel module signing.  These
> >> kernels have no way of using digital signature base IMA appraisal. 
> >> 
> >> This series adds a new MOK variable to shim.  This variable allows the
> >> end-user to decide if they want to trust keys enrolled in the MOK within
> >> the Linux trust boundary.  By default, nothing changes; MOK keys are
> >> not trusted within the Linux kernel.  They are only trusted after the 
> >> end-user makes the decision themselves.  The end-user would set this
> >> through mokutil using a new --trust-mok option [4]. This would work
> >> similar to how the kernel uses MOK variable to enable/disable signature
> >> validation as well as use/ignore the db.
> >> 
> >> When shim boots, it mirrors the new MokTML Boot Services variable to a new
> >> MokListTrustedRT Runtime Services variable and extends PCR14. 
> >> MokListTrustedRT is written without EFI_VARIABLE_NON_VOLATILE set,
> >> preventing an end-user from setting it after booting and doing a kexec.
> >> 
> >> When the kernel boots, if MokListTrustedRT is set and
> >> EFI_VARIABLE_NON_VOLATILE is not set, the MokListRT is loaded into the
> >> secondary trusted keyring instead of the platform keyring. Mimi has
> >> suggested that only CA keys or keys that can be vouched for by other
> >> kernel keys be loaded. All other certs will load into the platform
> >> keyring instead.
> > 
> > Loading MOK CA keys onto the "secondary" keyring would need to be an
> > exception.   Once CA keys are loaded onto the "secondary" keyring,  any
> > certificates signed by those CA keys may be loaded normally, without
> > needing an exception, onto the "secondary" keyring.  The kernel MAY
> > load those keys onto the "secondary" keyring, but really doesn't need
> > to be involved.
> > 
> > Loading ALL of the MOK db keys onto either the "secondary" or
> > "platform" keyrings makes the code a lot more complicated.  Is it
> > really necessary?
> 
> Today all keys are loaded into the platform keyring. For kexec_file_load, 
> the platform and secondary keys are trusted the same.  If this series were 
> not to load them all into either keyring, it would be a kexec_file_load 
> regression, since keys that previously loaded into the platform keyring 
> could be missing. The complexity arises from the CA key restriction.  
> If that requirement was removed, this series would be much smaller.

To prevent the regression, allow the the existing firmware/UEFI keys to
continue to be loaded on the platform keyring, as it is currently being
done.  The new code would load just the MOK db CA keys onto the
secondary keyring, based on the new UEFI variable.  This is the only
code that would require a
"restrict_link_by_builtin_and_secondary_trusted" exemption.  The code
duplication would be minimal in comparison to the complexity being
introduced.

thanks,

Mimi
Eric Snowberg July 7, 2021, 10:10 p.m. UTC | #8
> On Jul 7, 2021, at 11:00 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> 
> On Wed, 2021-07-07 at 10:28 -0600, Eric Snowberg wrote:
>>> On Jul 7, 2021, at 6:39 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
>>> 
>>> On Tue, 2021-07-06 at 22:43 -0400, Eric Snowberg wrote:
>>>> This is a follow up to the "Add additional MOK vars" [1] series I 
>>>> previously sent.  This series incorporates the feedback given 
>>>> both publicly on the mailing list and privately from Mimi. This 
>>>> series just focuses on getting end-user keys into the kernel trust 
>>>> boundary.
>>>> 
>>>> Currently, pre-boot keys are not trusted within the Linux boundary [2].
>>>> Pre-boot keys include UEFI Secure Boot DB keys and MOKList keys. These
>>>> keys are loaded into the platform keyring and can only be used for kexec.
>>>> If an end-user wants to use their own key within the Linux trust
>>>> boundary, they must either compile it into the kernel themselves or use
>>>> the insert-sys-cert script. Both options present a problem. Many
>>>> end-users do not want to compile their own kernels. With the
>>>> insert-sys-cert option, there are missing upstream changes [3].  Also,
>>>> with the insert-sys-cert option, the end-user must re-sign their kernel
>>>> again with their own key, and then insert that key into the MOK db.
>>>> Another problem with insert-sys-cert is that only a single key can be
>>>> inserted into a compressed kernel.
>>>> 
>>>> Having the ability to insert a key into the Linux trust boundary opens
>>>> up various possibilities.  The end-user can use a pre-built kernel and
>>>> sign their own kernel modules.  It also opens up the ability for an
>>>> end-user to more easily use digital signature based IMA-appraisal.  To
>>>> get a key into the ima keyring, it must be signed by a key within the
>>>> Linux trust boundary.
>>>> 
>>>> Downstream Linux distros try to have a single signed kernel for each
>>>> architecture.  Each end-user may use this kernel in entirely different
>>>> ways.  Some downstream kernels have chosen to always trust platform keys
>>>> within the Linux trust boundary for kernel module signing.  These
>>>> kernels have no way of using digital signature base IMA appraisal. 
>>>> 
>>>> This series adds a new MOK variable to shim.  This variable allows the
>>>> end-user to decide if they want to trust keys enrolled in the MOK within
>>>> the Linux trust boundary.  By default, nothing changes; MOK keys are
>>>> not trusted within the Linux kernel.  They are only trusted after the 
>>>> end-user makes the decision themselves.  The end-user would set this
>>>> through mokutil using a new --trust-mok option [4]. This would work
>>>> similar to how the kernel uses MOK variable to enable/disable signature
>>>> validation as well as use/ignore the db.
>>>> 
>>>> When shim boots, it mirrors the new MokTML Boot Services variable to a new
>>>> MokListTrustedRT Runtime Services variable and extends PCR14. 
>>>> MokListTrustedRT is written without EFI_VARIABLE_NON_VOLATILE set,
>>>> preventing an end-user from setting it after booting and doing a kexec.
>>>> 
>>>> When the kernel boots, if MokListTrustedRT is set and
>>>> EFI_VARIABLE_NON_VOLATILE is not set, the MokListRT is loaded into the
>>>> secondary trusted keyring instead of the platform keyring. Mimi has
>>>> suggested that only CA keys or keys that can be vouched for by other
>>>> kernel keys be loaded. All other certs will load into the platform
>>>> keyring instead.
>>> 
>>> Loading MOK CA keys onto the "secondary" keyring would need to be an
>>> exception.   Once CA keys are loaded onto the "secondary" keyring,  any
>>> certificates signed by those CA keys may be loaded normally, without
>>> needing an exception, onto the "secondary" keyring.  The kernel MAY
>>> load those keys onto the "secondary" keyring, but really doesn't need
>>> to be involved.
>>> 
>>> Loading ALL of the MOK db keys onto either the "secondary" or
>>> "platform" keyrings makes the code a lot more complicated.  Is it
>>> really necessary?
>> 
>> Today all keys are loaded into the platform keyring. For kexec_file_load, 
>> the platform and secondary keys are trusted the same.  If this series were 
>> not to load them all into either keyring, it would be a kexec_file_load 
>> regression, since keys that previously loaded into the platform keyring 
>> could be missing. The complexity arises from the CA key restriction.  
>> If that requirement was removed, this series would be much smaller.
> 
> To prevent the regression, allow the the existing firmware/UEFI keys to
> continue to be loaded on the platform keyring, as it is currently being
> done.  The new code would load just the MOK db CA keys onto the
> secondary keyring, based on the new UEFI variable.  This is the only
> code that would require a
> "restrict_link_by_builtin_and_secondary_trusted" exemption.  The code
> duplication would be minimal in comparison to the complexity being
> introduced.

This series was written with the following three requirements in mind:

1. Only CA keys that were originally bound for the platform keyring 
can enter the secondary keyring.

2. No key in the UEFI Secure Boot DB, CA or not, may enter the 
secondary keyring, only MOKList keys may be trusted.

3. A new MOK variable is added to signify the user wants to trust 
MOKList keys.

Given these requirements, I started down the path I think you are 
suggesting.  However I found it to be more complex.  If we load all 
keys into the platform keyring first and later try to load only CA keys, 
we don’t have a way of knowing where the platform key came from.  
Platform keys can originate from the UEFI Secure Boot DB or the MOKList. 
This would violate the second requirement. This caused me to need to 
create a new keyring handler. [PATCH RFC 10/12] integrity: add new 
keyring handler.  

To satisfy the first requirement a new restriction is required.  This 
is contained in [PATCH RFC 03/12] KEYS: CA link restriction.

To satisfy the third requirement, we must read the new MOK var.  This 
is contained in [PATCH RFC 06/12] integrity: Trust mok keys if 
MokListTrustedRT found.

The patches above make up a majority of the new code.  

The remaining code of creating a new .mok keyring was done with code 
reuse in mind. Many of the required functions necessary to add this 
capability is already contained in integrity_ functions.  If the 
operation was done directly on the secondary keyring, similar code 
would need to be added to certs/system_keyring.c. Just like how the 
platform keyring is created within integrity code, the mok keyring 
is created in the same fashion.  When the platform keyring has 
completed initialization and loaded all its keys, the keyring is set 
into system_keyring code using set_platform_trusted_keys.  Instead of 
setting the mok keyring, I’m moving the keys directly into the secondary 
keyring, while bypassing the current restriction placed on this keyring.
Basically I'm trying to follow the same design pattern. 

If requirements #1, #2 or both (#1 and #2) could be dropped, most of 
this series would not be necessary.
Mimi Zohar July 8, 2021, 1:56 p.m. UTC | #9
On Wed, 2021-07-07 at 16:10 -0600, Eric Snowberg wrote:
> > On Jul 7, 2021, at 11:00 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> > 
> > On Wed, 2021-07-07 at 10:28 -0600, Eric Snowberg wrote:
> >>> On Jul 7, 2021, at 6:39 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> >>> 
> >>> On Tue, 2021-07-06 at 22:43 -0400, Eric Snowberg wrote:
> >>>> This is a follow up to the "Add additional MOK vars" [1] series I 
> >>>> previously sent.  This series incorporates the feedback given 
> >>>> both publicly on the mailing list and privately from Mimi. This 
> >>>> series just focuses on getting end-user keys into the kernel trust 
> >>>> boundary.
> >>>> 
> >>>> Currently, pre-boot keys are not trusted within the Linux boundary [2].
> >>>> Pre-boot keys include UEFI Secure Boot DB keys and MOKList keys. These
> >>>> keys are loaded into the platform keyring and can only be used for kexec.
> >>>> If an end-user wants to use their own key within the Linux trust
> >>>> boundary, they must either compile it into the kernel themselves or use
> >>>> the insert-sys-cert script. Both options present a problem. Many
> >>>> end-users do not want to compile their own kernels. With the
> >>>> insert-sys-cert option, there are missing upstream changes [3].  Also,
> >>>> with the insert-sys-cert option, the end-user must re-sign their kernel
> >>>> again with their own key, and then insert that key into the MOK db.
> >>>> Another problem with insert-sys-cert is that only a single key can be
> >>>> inserted into a compressed kernel.
> >>>> 
> >>>> Having the ability to insert a key into the Linux trust boundary opens
> >>>> up various possibilities.  The end-user can use a pre-built kernel and
> >>>> sign their own kernel modules.  It also opens up the ability for an
> >>>> end-user to more easily use digital signature based IMA-appraisal.  To
> >>>> get a key into the ima keyring, it must be signed by a key within the
> >>>> Linux trust boundary.
> >>>> 
> >>>> Downstream Linux distros try to have a single signed kernel for each
> >>>> architecture.  Each end-user may use this kernel in entirely different
> >>>> ways.  Some downstream kernels have chosen to always trust platform keys
> >>>> within the Linux trust boundary for kernel module signing.  These
> >>>> kernels have no way of using digital signature base IMA appraisal. 
> >>>> 
> >>>> This series adds a new MOK variable to shim.  This variable allows the
> >>>> end-user to decide if they want to trust keys enrolled in the MOK within
> >>>> the Linux trust boundary.  By default, nothing changes; MOK keys are
> >>>> not trusted within the Linux kernel.  They are only trusted after the 
> >>>> end-user makes the decision themselves.  The end-user would set this
> >>>> through mokutil using a new --trust-mok option [4]. This would work
> >>>> similar to how the kernel uses MOK variable to enable/disable signature
> >>>> validation as well as use/ignore the db.
> >>>> 
> >>>> When shim boots, it mirrors the new MokTML Boot Services variable to a new
> >>>> MokListTrustedRT Runtime Services variable and extends PCR14. 
> >>>> MokListTrustedRT is written without EFI_VARIABLE_NON_VOLATILE set,
> >>>> preventing an end-user from setting it after booting and doing a kexec.
> >>>> 
> >>>> When the kernel boots, if MokListTrustedRT is set and
> >>>> EFI_VARIABLE_NON_VOLATILE is not set, the MokListRT is loaded into the
> >>>> secondary trusted keyring instead of the platform keyring. Mimi has
> >>>> suggested that only CA keys or keys that can be vouched for by other
> >>>> kernel keys be loaded. All other certs will load into the platform
> >>>> keyring instead.
> >>> 
> >>> Loading MOK CA keys onto the "secondary" keyring would need to be an
> >>> exception.   Once CA keys are loaded onto the "secondary" keyring,  any
> >>> certificates signed by those CA keys may be loaded normally, without
> >>> needing an exception, onto the "secondary" keyring.  The kernel MAY
> >>> load those keys onto the "secondary" keyring, but really doesn't need
> >>> to be involved.
> >>> 
> >>> Loading ALL of the MOK db keys onto either the "secondary" or
> >>> "platform" keyrings makes the code a lot more complicated.  Is it
> >>> really necessary?
> >> 
> >> Today all keys are loaded into the platform keyring. For kexec_file_load, 
> >> the platform and secondary keys are trusted the same.  If this series were 
> >> not to load them all into either keyring, it would be a kexec_file_load 
> >> regression, since keys that previously loaded into the platform keyring 
> >> could be missing. The complexity arises from the CA key restriction.  
> >> If that requirement was removed, this series would be much smaller.
> > 
> > To prevent the regression, allow the the existing firmware/UEFI keys to
> > continue to be loaded on the platform keyring, as it is currently being
> > done.  The new code would load just the MOK db CA keys onto the
> > secondary keyring, based on the new UEFI variable.  This is the only
> > code that would require a
> > "restrict_link_by_builtin_and_secondary_trusted" exemption.  The code
> > duplication would be minimal in comparison to the complexity being
> > introduced.
> 
> This series was written with the following three requirements in mind:
> 
> 1. Only CA keys that were originally bound for the platform keyring 
> can enter the secondary keyring.
> 
> 2. No key in the UEFI Secure Boot DB, CA or not, may enter the 
> secondary keyring, only MOKList keys may be trusted.
> 
> 3. A new MOK variable is added to signify the user wants to trust 
> MOKList keys.

Sounds good!

> 
> Given these requirements, I started down the path I think you are 
> suggesting.  However I found it to be more complex.  If we load all 
> keys into the platform keyring first and later try to load only CA keys, 
> we don’t have a way of knowing where the platform key came from.  
> Platform keys can originate from the UEFI Secure Boot DB or the MOKList. 
> This would violate the second requirement. This caused me to need to 
> create a new keyring handler. [PATCH RFC 10/12] integrity: add new 
> keyring handler.

To prevent the regression you mentioned, I was suggesting reading the
MOK DB twice.  One time loading all the keys onto the platform keyring.
The other time loading only the CA keys onto the secondary keyring.

> 
> To satisfy the first requirement a new restriction is required.  This 
> is contained in [PATCH RFC 03/12] KEYS: CA link restriction.
> 
> To satisfy the third requirement, we must read the new MOK var.  This 
> is contained in [PATCH RFC 06/12] integrity: Trust mok keys if 
> MokListTrustedRT found.
> 
> The patches above make up a majority of the new code.  
> 
> The remaining code of creating a new .mok keyring was done with code 
> reuse in mind. Many of the required functions necessary to add this 
> capability is already contained in integrity_ functions.  If the 
> operation was done directly on the secondary keyring, similar code 
> would need to be added to certs/system_keyring.c. Just like how the 
> platform keyring is created within integrity code, the mok keyring 
> is created in the same fashion.  When the platform keyring has 
> completed initialization and loaded all its keys, the keyring is set 
> into system_keyring code using set_platform_trusted_keys.  Instead of 
> setting the mok keyring, I’m moving the keys directly into the secondary 
> keyring, while bypassing the current restriction placed on this keyring.
> Basically I'm trying to follow the same design pattern. 
> 
> If requirements #1, #2 or both (#1 and #2) could be dropped, most of 
> this series would not be necessary.

But without these requirements, the source of trust is unclear.

Is there a reason why the MOK keyring is temporary?   Asumming a
function similar to "restrict_link_by_builtin_and_secondary_trusted" is
defined to include the MOK keyring, the CA keys in the MOK db would be
loaded onto the MOK keyring, the other keys that meet the secondary
keyring restriction would be loaded directly onto the secondary
keyring[1], and as you currently have, the remaining keys onto the
platform keyring.

This eliminates the exemption needed for loading keys onto the
secondary keyring.  The MOK keyring, containing just CA keys, becomes a
new trust source.

thanks,

Mimi

[1] Refer to the comment in
restrict_link_by_builtin_and_secondary_trusted() on linking the builtin
keyring to the secondary keyring.
Eric Snowberg July 8, 2021, 5:59 p.m. UTC | #10
> On Jul 8, 2021, at 7:56 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> 
> On Wed, 2021-07-07 at 16:10 -0600, Eric Snowberg wrote:
>>> On Jul 7, 2021, at 11:00 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
>>> 
>>> On Wed, 2021-07-07 at 10:28 -0600, Eric Snowberg wrote:
>>>>> On Jul 7, 2021, at 6:39 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
>>>>> 
>>>>> On Tue, 2021-07-06 at 22:43 -0400, Eric Snowberg wrote:
>>>>>> This is a follow up to the "Add additional MOK vars" [1] series I 
>>>>>> previously sent.  This series incorporates the feedback given 
>>>>>> both publicly on the mailing list and privately from Mimi. This 
>>>>>> series just focuses on getting end-user keys into the kernel trust 
>>>>>> boundary.
>>>>>> 
>>>>>> Currently, pre-boot keys are not trusted within the Linux boundary [2].
>>>>>> Pre-boot keys include UEFI Secure Boot DB keys and MOKList keys. These
>>>>>> keys are loaded into the platform keyring and can only be used for kexec.
>>>>>> If an end-user wants to use their own key within the Linux trust
>>>>>> boundary, they must either compile it into the kernel themselves or use
>>>>>> the insert-sys-cert script. Both options present a problem. Many
>>>>>> end-users do not want to compile their own kernels. With the
>>>>>> insert-sys-cert option, there are missing upstream changes [3].  Also,
>>>>>> with the insert-sys-cert option, the end-user must re-sign their kernel
>>>>>> again with their own key, and then insert that key into the MOK db.
>>>>>> Another problem with insert-sys-cert is that only a single key can be
>>>>>> inserted into a compressed kernel.
>>>>>> 
>>>>>> Having the ability to insert a key into the Linux trust boundary opens
>>>>>> up various possibilities.  The end-user can use a pre-built kernel and
>>>>>> sign their own kernel modules.  It also opens up the ability for an
>>>>>> end-user to more easily use digital signature based IMA-appraisal.  To
>>>>>> get a key into the ima keyring, it must be signed by a key within the
>>>>>> Linux trust boundary.
>>>>>> 
>>>>>> Downstream Linux distros try to have a single signed kernel for each
>>>>>> architecture.  Each end-user may use this kernel in entirely different
>>>>>> ways.  Some downstream kernels have chosen to always trust platform keys
>>>>>> within the Linux trust boundary for kernel module signing.  These
>>>>>> kernels have no way of using digital signature base IMA appraisal. 
>>>>>> 
>>>>>> This series adds a new MOK variable to shim.  This variable allows the
>>>>>> end-user to decide if they want to trust keys enrolled in the MOK within
>>>>>> the Linux trust boundary.  By default, nothing changes; MOK keys are
>>>>>> not trusted within the Linux kernel.  They are only trusted after the 
>>>>>> end-user makes the decision themselves.  The end-user would set this
>>>>>> through mokutil using a new --trust-mok option [4]. This would work
>>>>>> similar to how the kernel uses MOK variable to enable/disable signature
>>>>>> validation as well as use/ignore the db.
>>>>>> 
>>>>>> When shim boots, it mirrors the new MokTML Boot Services variable to a new
>>>>>> MokListTrustedRT Runtime Services variable and extends PCR14. 
>>>>>> MokListTrustedRT is written without EFI_VARIABLE_NON_VOLATILE set,
>>>>>> preventing an end-user from setting it after booting and doing a kexec.
>>>>>> 
>>>>>> When the kernel boots, if MokListTrustedRT is set and
>>>>>> EFI_VARIABLE_NON_VOLATILE is not set, the MokListRT is loaded into the
>>>>>> secondary trusted keyring instead of the platform keyring. Mimi has
>>>>>> suggested that only CA keys or keys that can be vouched for by other
>>>>>> kernel keys be loaded. All other certs will load into the platform
>>>>>> keyring instead.
>>>>> 
>>>>> Loading MOK CA keys onto the "secondary" keyring would need to be an
>>>>> exception.   Once CA keys are loaded onto the "secondary" keyring,  any
>>>>> certificates signed by those CA keys may be loaded normally, without
>>>>> needing an exception, onto the "secondary" keyring.  The kernel MAY
>>>>> load those keys onto the "secondary" keyring, but really doesn't need
>>>>> to be involved.
>>>>> 
>>>>> Loading ALL of the MOK db keys onto either the "secondary" or
>>>>> "platform" keyrings makes the code a lot more complicated.  Is it
>>>>> really necessary?
>>>> 
>>>> Today all keys are loaded into the platform keyring. For kexec_file_load, 
>>>> the platform and secondary keys are trusted the same.  If this series were 
>>>> not to load them all into either keyring, it would be a kexec_file_load 
>>>> regression, since keys that previously loaded into the platform keyring 
>>>> could be missing. The complexity arises from the CA key restriction.  
>>>> If that requirement was removed, this series would be much smaller.
>>> 
>>> To prevent the regression, allow the the existing firmware/UEFI keys to
>>> continue to be loaded on the platform keyring, as it is currently being
>>> done.  The new code would load just the MOK db CA keys onto the
>>> secondary keyring, based on the new UEFI variable.  This is the only
>>> code that would require a
>>> "restrict_link_by_builtin_and_secondary_trusted" exemption.  The code
>>> duplication would be minimal in comparison to the complexity being
>>> introduced.
>> 
>> This series was written with the following three requirements in mind:
>> 
>> 1. Only CA keys that were originally bound for the platform keyring 
>> can enter the secondary keyring.
>> 
>> 2. No key in the UEFI Secure Boot DB, CA or not, may enter the 
>> secondary keyring, only MOKList keys may be trusted.
>> 
>> 3. A new MOK variable is added to signify the user wants to trust 
>> MOKList keys.
> 
> Sounds good!
> 
>> 
>> Given these requirements, I started down the path I think you are 
>> suggesting.  However I found it to be more complex.  If we load all 
>> keys into the platform keyring first and later try to load only CA keys, 
>> we don’t have a way of knowing where the platform key came from.  
>> Platform keys can originate from the UEFI Secure Boot DB or the MOKList. 
>> This would violate the second requirement. This caused me to need to 
>> create a new keyring handler. [PATCH RFC 10/12] integrity: add new 
>> keyring handler.
> 
> To prevent the regression you mentioned, I was suggesting reading the
> MOK DB twice.  One time loading all the keys onto the platform keyring.
> The other time loading only the CA keys onto the secondary keyring.
> 
>> 
>> To satisfy the first requirement a new restriction is required.  This 
>> is contained in [PATCH RFC 03/12] KEYS: CA link restriction.
>> 
>> To satisfy the third requirement, we must read the new MOK var.  This 
>> is contained in [PATCH RFC 06/12] integrity: Trust mok keys if 
>> MokListTrustedRT found.
>> 
>> The patches above make up a majority of the new code.  
>> 
>> The remaining code of creating a new .mok keyring was done with code 
>> reuse in mind. Many of the required functions necessary to add this 
>> capability is already contained in integrity_ functions.  If the 
>> operation was done directly on the secondary keyring, similar code 
>> would need to be added to certs/system_keyring.c. Just like how the 
>> platform keyring is created within integrity code, the mok keyring 
>> is created in the same fashion.  When the platform keyring has 
>> completed initialization and loaded all its keys, the keyring is set 
>> into system_keyring code using set_platform_trusted_keys.  Instead of 
>> setting the mok keyring, I’m moving the keys directly into the secondary 
>> keyring, while bypassing the current restriction placed on this keyring.
>> Basically I'm trying to follow the same design pattern. 
>> 
>> If requirements #1, #2 or both (#1 and #2) could be dropped, most of 
>> this series would not be necessary.
> 
> But without these requirements, the source of trust is unclear.
> 
> Is there a reason why the MOK keyring is temporary?  

I suppose it doesn't have to be temporary.  I was trying not to introduce
another keyring within system_keyring code.

>  Asumming a
> function similar to "restrict_link_by_builtin_and_secondary_trusted" is
> defined to include the MOK keyring, the CA keys in the MOK db would be
> loaded onto the MOK keyring, the other keys that meet the secondary
> keyring restriction would be loaded directly onto the secondary
> keyring[1], and as you currently have, the remaining keys onto the
> platform keyring.
> 
> This eliminates the exemption needed for loading keys onto the
> secondary keyring.  The MOK keyring, containing just CA keys, becomes a
> new trust source.

I just want to make sure I understand. If we kept the .mok keyring around, 
we would store it into the system_keyring code, just like the platform 
keyring is stored.  This would allow the move exemption code to be removed.
If the mok keyring is a new trust source, whenever the secondary keyring 
is referenced in verify_ code, the mok keyring will be checked too.  If 
I have this right, let me know and I’ll work on a v2.  Thanks.
Mimi Zohar July 8, 2021, 7:31 p.m. UTC | #11
Hi Eric,

On Thu, 2021-07-08 at 11:59 -0600, Eric Snowberg wrote:
> 
> >  Asumming a
> > function similar to "restrict_link_by_builtin_and_secondary_trusted" is
> > defined to include the MOK keyring, the CA keys in the MOK db would be
> > loaded onto the MOK keyring, the other keys that meet the secondary
> > keyring restriction would be loaded directly onto the secondary
> > keyring[1], and as you currently have, the remaining keys onto the
> > platform keyring.
> > 
> > This eliminates the exemption needed for loading keys onto the
> > secondary keyring.  The MOK keyring, containing just CA keys, becomes a
> > new trust source.
> 
> I just want to make sure I understand. If we kept the .mok keyring around, 
> we would store it into the system_keyring code, just like the platform 
> keyring is stored.  This would allow the move exemption code to be removed.
> If the mok keyring is a new trust source, whenever the secondary keyring 
> is referenced in verify_ code, the mok keyring will be checked too.  If 
> I have this right, let me know and I’ll work on a v2.  Thanks.

All the firmware keys are loaded onto the "platform" keyring, without
any restriction.  Your reference point should be the "builtin" and
"secondary" keyrings, not the "platform" keyring.

Changes:
- defining a new keyring restriction which only allows CA keys to be
loaded onto the MOK keyring.
- defining a new keyring restriction something along the lines of
"restrict_link_by_builtin_mok_and_secondary_trusted()".

In the case of "restrict_link_by_builtin_and_secondary_trusted()", it's
based on a build time option.  In the case of MOK, it might be both a
build time and runtime firmware variable option.  There are quite a few
permutations that will somehow need to be addressed:  secondary keyring
not defined, but MOK keyring defined, and the reverse.

Once all the CA keys in the MOK db are loaded onto the MOK keyring,
there will be no need for moving keys to the secondary keyring.  The
secondary keyring restriction will just work.  The main question is
whether there will need to be two passes.   One pass to first load all
the CA keys onto the MOK keyring.  A second pass to load the keys onto
the secondary keyring, based on the keyring restriction, and the
remaining ones onto the "platform" keyring to avoid the regression.

[Once the CA keys are loaded onto the MOK keyring, userspace will be
able to load certificates, signed by a key on the MOK keyring, onto the
secondary keyring.]

thanks,

Mimi
Eric Snowberg July 8, 2021, 11:17 p.m. UTC | #12
> On Jul 8, 2021, at 1:31 PM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> 
> On Thu, 2021-07-08 at 11:59 -0600, Eric Snowberg wrote:
>> 
>>> Asumming a
>>> function similar to "restrict_link_by_builtin_and_secondary_trusted" is
>>> defined to include the MOK keyring, the CA keys in the MOK db would be
>>> loaded onto the MOK keyring, the other keys that meet the secondary
>>> keyring restriction would be loaded directly onto the secondary
>>> keyring[1], and as you currently have, the remaining keys onto the
>>> platform keyring.
>>> 
>>> This eliminates the exemption needed for loading keys onto the
>>> secondary keyring.  The MOK keyring, containing just CA keys, becomes a
>>> new trust source.
>> 
>> I just want to make sure I understand. If we kept the .mok keyring around, 
>> we would store it into the system_keyring code, just like the platform 
>> keyring is stored.  This would allow the move exemption code to be removed.
>> If the mok keyring is a new trust source, whenever the secondary keyring 
>> is referenced in verify_ code, the mok keyring will be checked too.  If 
>> I have this right, let me know and I’ll work on a v2.  Thanks.
> 
> All the firmware keys are loaded onto the "platform" keyring, without
> any restriction.  Your reference point should be the "builtin" and
> "secondary" keyrings, not the "platform" keyring.
> 
> Changes:
> - defining a new keyring restriction which only allows CA keys to be
> loaded onto the MOK keyring.
> - defining a new keyring restriction something along the lines of
> "restrict_link_by_builtin_mok_and_secondary_trusted()".
> 
> In the case of "restrict_link_by_builtin_and_secondary_trusted()", it's
> based on a build time option.  In the case of MOK, it might be both a
> build time and runtime firmware variable option.  There are quite a few
> permutations that will somehow need to be addressed:  secondary keyring
> not defined, but MOK keyring defined, and the reverse.
> 
> Once all the CA keys in the MOK db are loaded onto the MOK keyring,

To avoid confusion with the new keyring name, would it be more appropriate 
to change what we are calling the .mok keyring to the .trusted_platform 
keyring instead? Or just leave it as .mok?

> there will be no need for moving keys to the secondary keyring.  The
> secondary keyring restriction will just work.  The main question is
> whether there will need to be two passes.   One pass to first load all
> the CA keys onto the MOK keyring.  A second pass to load the keys onto
> the secondary keyring, based on the keyring restriction, and the
> remaining ones onto the "platform" keyring to avoid the regression.
> 
> [Once the CA keys are loaded onto the MOK keyring, userspace will be
> able to load certificates, signed by a key on the MOK keyring, onto the
> secondary keyring.]

Other than that, I think I got it, I’ll start working on a v2.  Thanks.
Mimi Zohar July 9, 2021, 1:10 a.m. UTC | #13
On Thu, 2021-07-08 at 17:17 -0600, Eric Snowberg wrote:
> > Once all the CA keys in the MOK db are loaded onto the MOK keyring,
> 
> To avoid confusion with the new keyring name, would it be more appropriate 
> to change what we are calling the .mok keyring to the .trusted_platform 
> keyring instead? Or just leave it as .mok?

Definitely not ".trusted_platform" keyring, as it would be too
confusing with the existing "trusted" key type [1].  At least for now,
leave it as ".mok".

thanks,

Mimi

[1] Documentation/security/keys/trusted-encrypted.rst
Nayna July 9, 2021, 3:59 p.m. UTC | #14
On 7/8/21 9:10 PM, Mimi Zohar wrote:
> Definitely not ".trusted_platform" keyring, as it would be too
> confusing with the existing "trusted" key type [1].  At least for now,
> leave it as ".mok".

Since this keyring is meant only for "CA" keys, can we name it as ".ca" ?

Thanks & Regards,

     - Nayna