2022-12-07 17:14:49

by Eric Snowberg

[permalink] [raw]
Subject: [PATCH v2 00/10] Add CA enforcement keyring restrictions

Prior to the introduction of the machine keyring, most distros simply
allowed all keys contained within the platform keyring to be used
for both kernel and module verification. This was done by an out of
tree patch. Some distros took it even further and loaded all these keys
into the secondary trusted keyring. This also allowed the system owner
to add their own key for IMA usage.

Each distro contains similar documentation on how to sign kernel modules
and enroll the key into the MOK. The process is fairly straightforward.
With the introduction of the machine keyring, the process remains
basically the same, without the need for any out of tree patches.

The machine keyring allowed distros to eliminate the out of tree patches
for kernel module signing. However, it falls short in allowing the end
user to add their own keys for IMA. Currently the machine keyring can not
be used as another trust anchor for adding keys to the ima keyring, since
CA enforcement does not currently exist. This would expand the current
integrity gap. The IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
Kconfig states that keys may be added to the ima keyrings if the key is
validly signed by a CA cert in the system built-in or secondary trusted
keyring. Currently there is not code that enforces the "validly signed"
CA cert. Any key in the builtin or secondary keyring can be used. Also,
the definition of "validly signed" has never been stated, leaving this up
to multiple interpretations.

To allow IMA to be enabled with the machine keyring, this series introduces
enforcement of key usage in the certificate. This series also defines a
"validly signed" CA cert and applies the same definition across all
kernel keyrings.

The machine keyring shares similarities with both the builtin and
secondary keyrings. Similar to the builtin, no keys may be added to the
machine keyring following boot. The secondary keyring allows user
provided keys to be added following boot; however, a previously enrolled
kernel key must vouch for the key before it may be included. The system
owner may include their own keys into the machine keyring prior to boot.
If the end-user is not the system owner, they may not add their own keys
to the machine keyring.

The machine keyring is only populated when Secure Boot is enabled. A
system owner has the ability to control the entire Secure Boot keychain
(PK, KEK, DB, and DBX). The system owner can also turn Secure Boot off.
With this control, they may use insert-sys-cert to include their own key
and re-sign their kernel and have it boot. The system owner also has
control to include or exclude MOK keys. This series does not try to
interpret how a system owner has configured their machine. If the system
owner has taken the steps to add their own MOK keys, they will be
included in the machine keyring and used for verification, exactly
the same way as keys contained in the builtin and secondary keyrings.
Since the system owner has the ability to add keys before booting to
either the machine or builtin keyrings, it is viewed as inconsequential
if the key originated from one or the other.

This series introduces two different ways to configure the machine keyring.
By default, nothing changes and all MOK keys are loaded into it. Whenever
a "validly signed" key is found within the machine, builtin, or
secondary, a flag indicating this is stored in the public key struct.
The other option is if the new Kconfig INTEGRITY_CA_MACHINE_KEYRING is
enabled, only "validly signed" CA certs will be loaded into the machine
keyring. All remaining MOK keys will be loaded into the platform keyring.

A "validly signed" CA cert shall be defined as any X509 certificate that
is self signed, contains the keyCertSign key usage and has the CA bit
set to true.

With this series applied, "validly signed" CA enforcement is in place
whenever IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY is enabled.
Meaning, before any key can be included into the ima keyring, it must be
vouched for by a "validly signed" CA key contained within the builtin,
secondary, or machine keyrings.

IMA allows userspace applications to be signed. The enduser may sign
their own application, however they may also want to use an application
provided by a 3rd party. The entity building the kernel, may not be the
same entity building the userspace program. The system owner may also
be a third entity. If the system owner trusts the entity building the
userspace program, they will include their public key within the MOK.
This key would be used to sign the key added to the ima keyring. Not all
3rd party userspace providers have the capability to properly manage a
root CA. Some may outsource to a different code signing provider. Many
code signing providers use Intermediate CA certificates. Therefore, this
series also includes support for Intermediate CA certificates. If a
"validly signed" CA can vouch for an Intermediate CA, and it contains
the keyCertSign key usage, it will also be flagged as being a "validly
signed" CA. The Intermediate CA certificates could be loaded into the
secondary keyring following boot. Afterwards, CA enforcement is
maintained for any key added to the ima keyring.

This series could be broken up into 3 different parts. The first two
patches could be taken now. They solve current issues that will be
triggered by the build robots. Patches 3-8 add CA enforcement for the
ima keyring. Patches 9-10 restrict the machine keyring to only load CA
certs into it. Patches 9-10 require all the previous patches since
Intermediate CA enforcement is required.

Eric Snowberg (10):
KEYS: Create static version of public_key_verify_signature
KEYS: Add missing function documentation
KEYS: X.509: Parse Basic Constraints for CA
KEYS: X.509: Parse Key Usage
KEYS: Introduce a CA endorsed flag
KEYS: Introduce keyring restriction that validates ca trust
KEYS: X.509: Flag Intermediate CA certs as endorsed
integrity: Use root of trust signature restriction
KEYS: CA link restriction
integrity: restrict INTEGRITY_KEYRING_MACHINE to restrict_link_by_ca

certs/system_keyring.c | 30 ++++++++-
crypto/asymmetric_keys/restrict.c | 81 +++++++++++++++++++++++
crypto/asymmetric_keys/x509_cert_parser.c | 31 +++++++++
crypto/asymmetric_keys/x509_parser.h | 2 +
crypto/asymmetric_keys/x509_public_key.c | 16 +++++
include/crypto/public_key.h | 30 +++++++++
include/keys/system_keyring.h | 12 +++-
include/linux/ima.h | 11 +++
include/linux/key-type.h | 3 +
include/linux/key.h | 2 +
security/integrity/Kconfig | 11 ++-
security/integrity/digsig.c | 12 ++--
security/integrity/ima/Kconfig | 6 +-
security/keys/key.c | 13 ++++
14 files changed, 249 insertions(+), 11 deletions(-)


base-commit: 76dcd734eca23168cb008912c0f69ff408905235
--
2.27.0


2022-12-07 17:15:07

by Eric Snowberg

[permalink] [raw]
Subject: [PATCH v2 10/10] integrity: restrict INTEGRITY_KEYRING_MACHINE to restrict_link_by_ca

Set the restriction check for INTEGRITY_KEYRING_MACHINE keys to
restrict_link_by_ca. This will only allow CA keys into the machine
keyring.

Signed-off-by: Eric Snowberg <[email protected]>
---
security/integrity/Kconfig | 10 ++++++++++
security/integrity/digsig.c | 8 ++++++--
2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index 14cc3c767270..3357883fa5a8 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -74,6 +74,16 @@ config INTEGRITY_MACHINE_KEYRING
in the platform keyring, keys contained in the .machine keyring will
be trusted within the kernel.

+config INTEGRITY_CA_MACHINE_KEYRING
+ bool "Only allow CA keys into the Machine Keyring"
+ depends on INTEGRITY_MACHINE_KEYRING
+ help
+ If set, only Machine Owner Keys (MOK) that are Certificate
+ Authority (CA) keys will be added to the .machine keyring. All
+ other MOK keys will be added to the .platform keyring. After
+ booting, any other key signed by the CA key can be added to the
+ secondary_trusted_keys keyring.
+
config LOAD_UEFI_KEYS
depends on INTEGRITY_PLATFORM_KEYRING
depends on EFI
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index 1fe8d1ed6e0b..b0ec615745e3 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -131,7 +131,8 @@ int __init integrity_init_keyring(const unsigned int id)
| KEY_USR_READ | KEY_USR_SEARCH;

if (id == INTEGRITY_KEYRING_PLATFORM ||
- id == INTEGRITY_KEYRING_MACHINE) {
+ (id == INTEGRITY_KEYRING_MACHINE &&
+ !IS_ENABLED(CONFIG_INTEGRITY_CA_MACHINE_KEYRING))) {
restriction = NULL;
goto out;
}
@@ -143,7 +144,10 @@ int __init integrity_init_keyring(const unsigned int id)
if (!restriction)
return -ENOMEM;

- restriction->check = restrict_link_to_ima;
+ if (id == INTEGRITY_KEYRING_MACHINE)
+ restriction->check = restrict_link_by_ca;
+ else
+ restriction->check = restrict_link_to_ima;

/*
* MOK keys can only be added through a read-only runtime services
--
2.27.0

2022-12-09 10:35:52

by Coiby Xu

[permalink] [raw]
Subject: Re: [PATCH v2 00/10] Add CA enforcement keyring restrictions

Hi Eric,

Thanks for your work! The patch set looks good to me except for the
requirement of an intermediate CA certificate should be vouched for by a
root CA certificate before it can vouch for other certificates. What if
users only want to enroll an intermediate CA certificate into the MOK?
If this requirement could be dropped, the code could be simplified and
some issues could be resolved automatically,

1. "[PATCH v2 03/10] KEYS: X.509: Parse Basic Constraints for CA" added
a root_ca filed to a certificate to indicate the subject of the
certificate is a CA. The name root_ca implies it's also a root CA. But
according to [1], both an intermediate and root CA will have
root_ca=True. For example, the intermediate certificate of
https://www.kernel.org/ has "Certificate Authority=Yes" in the basic
constraints. Btw, a root CA certificate by definition is self-signed,
so the following code in "[PATCH v2 05/10] KEYS: Introduce a CA
endorsed flag" looks a bit strange to me,
if (cert->kcs_set && cert->self_signed && cert->root_ca)
prep->payload_flags |= KEY_ALLOC_PECA;

2. Since an intermediate CA certificate also has root_ca=True,
"[PATCH v2 07/10] KEYS: X.509: Flag Intermediate CA certs as
endorsed" won't work as intended i.e. this following else branch
will never be reached,
else if (!cert->self_signed && !cert->root_ca)
prep->payload_flags |= KEY_MAYBE_PECA;

3. I see nowhere public_key->key_is_ca is set to true for an intermediate
CA certificate after it gains the KEY_ALLOC_PECA flag. So it will fail
restrict_link_by_ca even if the KEY_MAYBE_PECA flag is added.

[1] https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.9

On Wed, Dec 07, 2022 at 12:12:28PM -0500, Eric Snowberg wrote:
>Prior to the introduction of the machine keyring, most distros simply
>allowed all keys contained within the platform keyring to be used
>for both kernel and module verification. This was done by an out of
>tree patch. Some distros took it even further and loaded all these keys
>into the secondary trusted keyring. This also allowed the system owner
>to add their own key for IMA usage.
>
>Each distro contains similar documentation on how to sign kernel modules
>and enroll the key into the MOK. The process is fairly straightforward.
>With the introduction of the machine keyring, the process remains
>basically the same, without the need for any out of tree patches.
>
>The machine keyring allowed distros to eliminate the out of tree patches
>for kernel module signing. However, it falls short in allowing the end
>user to add their own keys for IMA. Currently the machine keyring can not
>be used as another trust anchor for adding keys to the ima keyring, since
>CA enforcement does not currently exist. This would expand the current
>integrity gap. The IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY
>Kconfig states that keys may be added to the ima keyrings if the key is
>validly signed by a CA cert in the system built-in or secondary trusted
>keyring. Currently there is not code that enforces the "validly signed"
>CA cert. Any key in the builtin or secondary keyring can be used. Also,
>the definition of "validly signed" has never been stated, leaving this up
>to multiple interpretations.
>
>To allow IMA to be enabled with the machine keyring, this series introduces
>enforcement of key usage in the certificate. This series also defines a
>"validly signed" CA cert and applies the same definition across all
>kernel keyrings.
>
>The machine keyring shares similarities with both the builtin and
>secondary keyrings. Similar to the builtin, no keys may be added to the
>machine keyring following boot. The secondary keyring allows user
>provided keys to be added following boot; however, a previously enrolled
>kernel key must vouch for the key before it may be included. The system
>owner may include their own keys into the machine keyring prior to boot.
>If the end-user is not the system owner, they may not add their own keys
>to the machine keyring.
>
>The machine keyring is only populated when Secure Boot is enabled. A
>system owner has the ability to control the entire Secure Boot keychain
>(PK, KEK, DB, and DBX). The system owner can also turn Secure Boot off.
>With this control, they may use insert-sys-cert to include their own key
>and re-sign their kernel and have it boot. The system owner also has
>control to include or exclude MOK keys. This series does not try to
>interpret how a system owner has configured their machine. If the system
>owner has taken the steps to add their own MOK keys, they will be
>included in the machine keyring and used for verification, exactly
>the same way as keys contained in the builtin and secondary keyrings.
>Since the system owner has the ability to add keys before booting to
>either the machine or builtin keyrings, it is viewed as inconsequential
>if the key originated from one or the other.
>
>This series introduces two different ways to configure the machine keyring.
>By default, nothing changes and all MOK keys are loaded into it. Whenever
>a "validly signed" key is found within the machine, builtin, or
>secondary, a flag indicating this is stored in the public key struct.
>The other option is if the new Kconfig INTEGRITY_CA_MACHINE_KEYRING is
>enabled, only "validly signed" CA certs will be loaded into the machine
>keyring. All remaining MOK keys will be loaded into the platform keyring.
>
>A "validly signed" CA cert shall be defined as any X509 certificate that
>is self signed, contains the keyCertSign key usage and has the CA bit
>set to true.
>
>With this series applied, "validly signed" CA enforcement is in place
>whenever IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY is enabled.
>Meaning, before any key can be included into the ima keyring, it must be
>vouched for by a "validly signed" CA key contained within the builtin,
>secondary, or machine keyrings.
>
>IMA allows userspace applications to be signed. The enduser may sign
>their own application, however they may also want to use an application
>provided by a 3rd party. The entity building the kernel, may not be the
>same entity building the userspace program. The system owner may also
>be a third entity. If the system owner trusts the entity building the
>userspace program, they will include their public key within the MOK.
>This key would be used to sign the key added to the ima keyring. Not all
>3rd party userspace providers have the capability to properly manage a
>root CA. Some may outsource to a different code signing provider. Many
>code signing providers use Intermediate CA certificates. Therefore, this
>series also includes support for Intermediate CA certificates. If a
>"validly signed" CA can vouch for an Intermediate CA, and it contains
>the keyCertSign key usage, it will also be flagged as being a "validly
>signed" CA. The Intermediate CA certificates could be loaded into the
>secondary keyring following boot. Afterwards, CA enforcement is
>maintained for any key added to the ima keyring.
>
>This series could be broken up into 3 different parts. The first two
>patches could be taken now. They solve current issues that will be
>triggered by the build robots. Patches 3-8 add CA enforcement for the
>ima keyring. Patches 9-10 restrict the machine keyring to only load CA
>certs into it. Patches 9-10 require all the previous patches since
>Intermediate CA enforcement is required.
>
>Eric Snowberg (10):
> KEYS: Create static version of public_key_verify_signature
> KEYS: Add missing function documentation
> KEYS: X.509: Parse Basic Constraints for CA
> KEYS: X.509: Parse Key Usage
> KEYS: Introduce a CA endorsed flag
> KEYS: Introduce keyring restriction that validates ca trust
> KEYS: X.509: Flag Intermediate CA certs as endorsed
> integrity: Use root of trust signature restriction
> KEYS: CA link restriction
> integrity: restrict INTEGRITY_KEYRING_MACHINE to restrict_link_by_ca
>
> certs/system_keyring.c | 30 ++++++++-
> crypto/asymmetric_keys/restrict.c | 81 +++++++++++++++++++++++
> crypto/asymmetric_keys/x509_cert_parser.c | 31 +++++++++
> crypto/asymmetric_keys/x509_parser.h | 2 +
> crypto/asymmetric_keys/x509_public_key.c | 16 +++++
> include/crypto/public_key.h | 30 +++++++++
> include/keys/system_keyring.h | 12 +++-
> include/linux/ima.h | 11 +++
> include/linux/key-type.h | 3 +
> include/linux/key.h | 2 +
> security/integrity/Kconfig | 11 ++-
> security/integrity/digsig.c | 12 ++--
> security/integrity/ima/Kconfig | 6 +-
> security/keys/key.c | 13 ++++
> 14 files changed, 249 insertions(+), 11 deletions(-)
>
>
>base-commit: 76dcd734eca23168cb008912c0f69ff408905235
>--
>2.27.0
>

--
Best regards,
Coiby

2022-12-09 15:50:12

by Eric Snowberg

[permalink] [raw]
Subject: Re: [PATCH v2 00/10] Add CA enforcement keyring restrictions


> On Dec 9, 2022, at 3:26 AM, Coiby Xu <[email protected]> wrote:
>
> Thanks for your work! The patch set looks good to me except for the
> requirement of an intermediate CA certificate should be vouched for by a
> root CA certificate before it can vouch for other certificates. What if
> users only want to enroll an intermediate CA certificate into the MOK?

This question would need to be answered by the maintainers. The intermediate
requirement was based on my understanding of previous discussions requiring
there be a way to validate root of trust all the way back to the root CA.

> If this requirement could be dropped, the code could be simplified and
> some issues could be resolved automatically,

Agreed. I will make sure the issue below is resolved one way or the other,
once we have an agreement on the requirements.

> 1. "[PATCH v2 03/10] KEYS: X.509: Parse Basic Constraints for CA" added
> a root_ca filed to a certificate to indicate the subject of the
> certificate is a CA. The name root_ca implies it's also a root CA. But
> according to [1], both an intermediate and root CA will have
> root_ca=True. For example, the intermediate certificate of
> https://www.kernel.org/ has "Certificate Authority=Yes" in the basic
> constraints. Btw, a root CA certificate by definition is self-signed,
> so the following code in "[PATCH v2 05/10] KEYS: Introduce a CA
> endorsed flag" looks a bit strange to me,
> if (cert->kcs_set && cert->self_signed && cert->root_ca)
> prep->payload_flags |= KEY_ALLOC_PECA;
>
> 2. Since an intermediate CA certificate also has root_ca=True,
> "[PATCH v2 07/10] KEYS: X.509: Flag Intermediate CA certs as
> endorsed" won't work as intended i.e. this following else branch
> will never be reached,
> else if (!cert->self_signed && !cert->root_ca)
> prep->payload_flags |= KEY_MAYBE_PECA;
>
> 3. I see nowhere public_key->key_is_ca is set to true for an intermediate
> CA certificate after it gains the KEY_ALLOC_PECA flag. So it will fail
> restrict_link_by_ca even if the KEY_MAYBE_PECA flag is added.
>
> [1] https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.9

Thanks for reviewing the series.

2022-12-12 21:47:54

by Mimi Zohar

[permalink] [raw]
Subject: Re: [PATCH v2 00/10] Add CA enforcement keyring restrictions

Hi Eric, Coiby,

On Fri, 2022-12-09 at 15:44 +0000, Eric Snowberg wrote:
> > On Dec 9, 2022, at 3:26 AM, Coiby Xu <[email protected]> wrote:
> >
> > Thanks for your work! The patch set looks good to me except for the
> > requirement of an intermediate CA certificate should be vouched for by a
> > root CA certificate before it can vouch for other certificates. What if
> > users only want to enroll an intermediate CA certificate into the MOK?
>
> This question would need to be answered by the maintainers. The intermediate
> requirement was based on my understanding of previous discussions requiring
> there be a way to validate root of trust all the way back to the root CA.

That definitely did not come from me. My requirement all along has
been to support a single self-signed CA certificate for the end
user/customer use case, so that they could create and load their own
public key, signed by that CA, onto the trusted IMA/EVM keyrings.

>
> > If this requirement could be dropped, the code could be simplified and
> > some issues could be resolved automatically,
>
> Agreed. I will make sure the issue below is resolved one way or the other,
> once we have an agreement on the requirements.

I totally agree with Coiby that there is no need for intermediate CA
certificates be vouched for by a root CA certificate. In fact the
closer the CA certificate is to the leaf code signing certificate, the
better. As much as possible we want to limit the CA keys being loaded
onto the machine keyring to those that are absolutely required.

thanks,

Mimi

>
> > 1. "[PATCH v2 03/10] KEYS: X.509: Parse Basic
> > a root_ca filed to a certificate to indicate the subject of the
> > certificate is a CA. The name root_ca implies it's also a root CA. But
> > according to [1], both an intermediate and root CA will have
> > root_ca=True. For example, the intermediate certificate of
> > https://www.kernel.org/ has "Certificate Authority=Yes" in the basic
> > constraints. Btw, a root CA certificate by definition is self-signed,
> > so the following code in "[PATCH v2 05/10] KEYS: Introduce a CA
> > endorsed flag" looks a bit strange to me,
> > if (cert->kcs_set && cert->self_signed && cert->root_ca)
> > prep->payload_flags |= KEY_ALLOC_PECA;
> >
> > 2. Since an intermediate CA certificate also has root_ca=True,
> > "[PATCH v2 07/10] KEYS: X.509: Flag Intermediate CA certs as
> > endorsed" won't work as intended i.e. this following else branch
> > will never be reached,
> > else if (!cert->self_signed && !cert->root_ca)
> > prep->payload_flags |= KEY_MAYBE_PECA;
> >
> > 3. I see nowhere public_key->key_is_ca is set to true for an intermediate
> > CA certificate after it gains the KEY_ALLOC_PECA flag. So it will fail
> > restrict_link_by_ca even if the KEY_MAYBE_PECA flag is added.
> >
> > [1] https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.9
>
> Thanks for reviewing the series.
>