diff mbox series

[4/7] KEYS: Introduce a builtin root of trust key flag

Message ID 20220406015337.4000739-5-eric.snowberg@oracle.com
State New
Headers show
Series Add CA enforcement keyring restrictions | expand

Commit Message

Eric Snowberg April 6, 2022, 1:53 a.m. UTC
Some subsystems are interested in knowing if keys within a keyring could
be used as a foundation of a root of trust.  Introduce a new builtin root
of trust key flag.

The first type of key to use this is X.509.  When a X.509 certificate
is self signed, has the kernCertSign Key Usage set and contains the
CA bit set this new flag is set.

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
---
 crypto/asymmetric_keys/x509_public_key.c | 2 ++
 include/linux/key-type.h                 | 2 ++
 include/linux/key.h                      | 2 ++
 security/keys/key.c                      | 8 ++++++++
 4 files changed, 14 insertions(+)

Comments

Mimi Zohar April 8, 2022, 2:40 p.m. UTC | #1
On Tue, 2022-04-05 at 21:53 -0400, Eric Snowberg wrote:
> Some subsystems are interested in knowing if keys within a keyring could
> be used as a foundation of a root of trust.  Introduce a new builtin root
> of trust key flag.

Unfortunately a root of trust is not something that can simply be built
into a certificate.  Roots of trust are normally established based on
HW.  The root of trust for the "builtin_trusted_keys" is established
for systems with secure boot enabled by verifying the signature chain
of trust up to and including the kernel image's signature.  Similarly,
the root of trust for keys on the "secondary_trusted_keys" is based on
all certificates being signed by a key on the "builtin_trusted_keys"
keyring or other keys on the "secondary_trusted_keys" keyring.

Defining a new variable claiming that a root-ca with cert signing usage
on any keyring is a root of trust is just wrong.

> 
> The first type of key to use this is X.509.  When a X.509 certificate
> is self signed, has the kernCertSign Key Usage set and contains the
> CA bit set this new flag is set.
> 
> Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>

> 
> diff --git a/include/linux/key.h b/include/linux/key.h
> index 7febc4881363..97f6a1f86a27 100644
> --- a/include/linux/key.h
> +++ b/include/linux/key.h
> @@ -230,6 +230,7 @@ struct key {
>  #define KEY_FLAG_ROOT_CAN_INVAL	7	/* set if key can be invalidated by root without permission */
>  #define KEY_FLAG_KEEP		8	/* set if key should not be removed */
>  #define KEY_FLAG_UID_KEYRING	9	/* set if key is a user or user session keyring */
> +#define KEY_FLAG_BUILTIN_ROT	10	/* set if key is a builtin Root of Trust key */
>  
>  	/* the key type and key description string
>  	 * - the desc is used to match a key against search criteria
> @@ -290,6 +291,7 @@ extern struct key *key_alloc(struct key_type *type,
>  #define KEY_ALLOC_BYPASS_RESTRICTION	0x0008	/* Override the check on restricted keyrings */
>  #define KEY_ALLOC_UID_KEYRING		0x0010	/* allocating a user or user session keyring */
>  #define KEY_ALLOC_SET_KEEP		0x0020	/* Set the KEEP flag on the key/keyring */
> +#define KEY_ALLOC_BUILT_IN_ROT		0x0040  /* Add builtin root of trust key */

Since the concept of root of trust is not generic, but limited to
specific keyrings, the root CA certificate signing keys on the
"machine" keyring need to be identified.  Similar to the
KEY_ALLOC_BUILT_IN/KEY_FLAG_BUILTIN, new flags
KEY_ALLOC_MACHINE/KEY_FLAG_MACHINE should be defined instead.

thanks,

Mimi
Eric Snowberg April 8, 2022, 3:27 p.m. UTC | #2
> On Apr 8, 2022, at 8:40 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> 
> On Tue, 2022-04-05 at 21:53 -0400, Eric Snowberg wrote:
>> 
>> The first type of key to use this is X.509.  When a X.509 certificate
>> is self signed, has the kernCertSign Key Usage set and contains the
>> CA bit set this new flag is set.
>> 
>> Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
>> 
>> diff --git a/include/linux/key.h b/include/linux/key.h
>> index 7febc4881363..97f6a1f86a27 100644
>> --- a/include/linux/key.h
>> +++ b/include/linux/key.h
>> @@ -230,6 +230,7 @@ struct key {
>> #define KEY_FLAG_ROOT_CAN_INVAL	7	/* set if key can be invalidated by root without permission */
>> #define KEY_FLAG_KEEP		8	/* set if key should not be removed */
>> #define KEY_FLAG_UID_KEYRING	9	/* set if key is a user or user session keyring */
>> +#define KEY_FLAG_BUILTIN_ROT	10	/* set if key is a builtin Root of Trust key */
>> 
>> 	/* the key type and key description string
>> 	 * - the desc is used to match a key against search criteria
>> @@ -290,6 +291,7 @@ extern struct key *key_alloc(struct key_type *type,
>> #define KEY_ALLOC_BYPASS_RESTRICTION	0x0008	/* Override the check on restricted keyrings */
>> #define KEY_ALLOC_UID_KEYRING		0x0010	/* allocating a user or user session keyring */
>> #define KEY_ALLOC_SET_KEEP		0x0020	/* Set the KEEP flag on the key/keyring */
>> +#define KEY_ALLOC_BUILT_IN_ROT		0x0040  /* Add builtin root of trust key */
> 
> Since the concept of root of trust is not generic, but limited to
> specific keyrings, the root CA certificate signing keys on the
> "machine" keyring need to be identified.  Similar to the
> KEY_ALLOC_BUILT_IN/KEY_FLAG_BUILTIN, new flags
> KEY_ALLOC_MACHINE/KEY_FLAG_MACHINE should be defined instead.

I’m open to renaming these, however this name change seems confusing to me.  
This flag gets set when the X.509 certificate contains the three CA requirements 
identified above.  The remaining keys in the machine keyring can be used for 
anything else.  Plus this flag can be set for keys loaded into the secondary trusted 
keyring (6th patch in the series).  When an intermediate CA gets loaded into the 
secondary, the flag is set as well.
Mimi Zohar April 8, 2022, 4:55 p.m. UTC | #3
On Fri, 2022-04-08 at 15:27 +0000, Eric Snowberg wrote:
> 
> > On Apr 8, 2022, at 8:40 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> > 
> > On Tue, 2022-04-05 at 21:53 -0400, Eric Snowberg wrote:
> >> 
> >> The first type of key to use this is X.509.  When a X.509 certificate
> >> is self signed, has the kernCertSign Key Usage set and contains the
> >> CA bit set this new flag is set.
> >> 
> >> Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
> >> 
> >> diff --git a/include/linux/key.h b/include/linux/key.h
> >> index 7febc4881363..97f6a1f86a27 100644
> >> --- a/include/linux/key.h
> >> +++ b/include/linux/key.h
> >> @@ -230,6 +230,7 @@ struct key {
> >> #define KEY_FLAG_ROOT_CAN_INVAL	7	/* set if key can be invalidated by root without permission */
> >> #define KEY_FLAG_KEEP		8	/* set if key should not be removed */
> >> #define KEY_FLAG_UID_KEYRING	9	/* set if key is a user or user session keyring */
> >> +#define KEY_FLAG_BUILTIN_ROT	10	/* set if key is a builtin Root of Trust key */
> >> 
> >> 	/* the key type and key description string
> >> 	 * - the desc is used to match a key against search criteria
> >> @@ -290,6 +291,7 @@ extern struct key *key_alloc(struct key_type *type,
> >> #define KEY_ALLOC_BYPASS_RESTRICTION	0x0008	/* Override the check on restricted keyrings */
> >> #define KEY_ALLOC_UID_KEYRING		0x0010	/* allocating a user or user session keyring */
> >> #define KEY_ALLOC_SET_KEEP		0x0020	/* Set the KEEP flag on the key/keyring */
> >> +#define KEY_ALLOC_BUILT_IN_ROT		0x0040  /* Add builtin root of trust key */
> > 
> > Since the concept of root of trust is not generic, but limited to
> > specific keyrings, the root CA certificate signing keys on the
> > "machine" keyring need to be identified.  Similar to the
> > KEY_ALLOC_BUILT_IN/KEY_FLAG_BUILTIN, new flags
> > KEY_ALLOC_MACHINE/KEY_FLAG_MACHINE should be defined instead.
> 
> I’m open to renaming these, however this name change seems confusing to me.  
> This flag gets set when the X.509 certificate contains the three CA requirements 
> identified above.  The remaining keys in the machine keyring can be used for 
> anything else.

Renaming the flag to KEY_ALLOC_MACHINE/KEY_FLAG_MACHINE differentiates
between the "builtin" keys from the "machine" keys.  The trust models
are very different.

> Plus this flag can be set for keys loaded into the secondary trusted 
> keyring (6th patch in the series).  When an intermediate CA gets loaded into the 
> secondary, the flag is set as well.

Please include a full explanation with the motivation in the patch
description as to why support for intermediary CAs is required for the
"end-user" use case.

thanks,

Mimi
Eric Snowberg April 8, 2022, 5:34 p.m. UTC | #4
> On Apr 8, 2022, at 10:55 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> 
> On Fri, 2022-04-08 at 15:27 +0000, Eric Snowberg wrote:
>> 
>>> On Apr 8, 2022, at 8:40 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
>>> 
>>> On Tue, 2022-04-05 at 21:53 -0400, Eric Snowberg wrote:
>>>> 
>>>> The first type of key to use this is X.509.  When a X.509 certificate
>>>> is self signed, has the kernCertSign Key Usage set and contains the
>>>> CA bit set this new flag is set.
>>>> 
>>>> Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
>>>> 
>>>> diff --git a/include/linux/key.h b/include/linux/key.h
>>>> index 7febc4881363..97f6a1f86a27 100644
>>>> --- a/include/linux/key.h
>>>> +++ b/include/linux/key.h
>>>> @@ -230,6 +230,7 @@ struct key {
>>>> #define KEY_FLAG_ROOT_CAN_INVAL	7	/* set if key can be invalidated by root without permission */
>>>> #define KEY_FLAG_KEEP		8	/* set if key should not be removed */
>>>> #define KEY_FLAG_UID_KEYRING	9	/* set if key is a user or user session keyring */
>>>> +#define KEY_FLAG_BUILTIN_ROT	10	/* set if key is a builtin Root of Trust key */
>>>> 
>>>> 	/* the key type and key description string
>>>> 	 * - the desc is used to match a key against search criteria
>>>> @@ -290,6 +291,7 @@ extern struct key *key_alloc(struct key_type *type,
>>>> #define KEY_ALLOC_BYPASS_RESTRICTION	0x0008	/* Override the check on restricted keyrings */
>>>> #define KEY_ALLOC_UID_KEYRING		0x0010	/* allocating a user or user session keyring */
>>>> #define KEY_ALLOC_SET_KEEP		0x0020	/* Set the KEEP flag on the key/keyring */
>>>> +#define KEY_ALLOC_BUILT_IN_ROT		0x0040  /* Add builtin root of trust key */
>>> 
>>> Since the concept of root of trust is not generic, but limited to
>>> specific keyrings, the root CA certificate signing keys on the
>>> "machine" keyring need to be identified.  Similar to the
>>> KEY_ALLOC_BUILT_IN/KEY_FLAG_BUILTIN, new flags
>>> KEY_ALLOC_MACHINE/KEY_FLAG_MACHINE should be defined instead.
>> 
>> I’m open to renaming these, however this name change seems confusing to me.  
>> This flag gets set when the X.509 certificate contains the three CA requirements 
>> identified above.  The remaining keys in the machine keyring can be used for 
>> anything else.
> 
> Renaming the flag to KEY_ALLOC_MACHINE/KEY_FLAG_MACHINE differentiates
> between the "builtin" keys from the "machine" keys.  The trust models
> are very different.

Isn’t the trust model the same for machine and secondary keys?  Both are supplied by 
the end-user. That is why I’m confused by naming something _MACHINE when it applies 
to more than one keyring.

>> Plus this flag can be set for keys loaded into the secondary trusted 
>> keyring (6th patch in the series).  When an intermediate CA gets loaded into the 
>> secondary, the flag is set as well.
> 
> Please include a full explanation with the motivation in the patch
> description as to why support for intermediary CAs is required for the
> "end-user" use case.

Ok, I can add it.  I thought this was an expectation, based on the help section of
IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY:

" Intermediate keys between those the kernel has compiled in and the 
 IMA keys to be added may be added to the system secondary keyring,
 provided they are validly signed by a key already resident in the
 built-in or secondary trusted keyrings."
Mimi Zohar April 8, 2022, 6:49 p.m. UTC | #5
On Fri, 2022-04-08 at 17:34 +0000, Eric Snowberg wrote:
> 
> > On Apr 8, 2022, at 10:55 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> > 
> > On Fri, 2022-04-08 at 15:27 +0000, Eric Snowberg wrote:
> >> 
> >>> On Apr 8, 2022, at 8:40 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> >>> 
> >>> On Tue, 2022-04-05 at 21:53 -0400, Eric Snowberg wrote:
> >>>> 
> >>>> The first type of key to use this is X.509.  When a X.509 certificate
> >>>> is self signed, has the kernCertSign Key Usage set and contains the
> >>>> CA bit set this new flag is set.
> >>>> 
> >>>> Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
> >>>> 
> >>>> diff --git a/include/linux/key.h b/include/linux/key.h
> >>>> index 7febc4881363..97f6a1f86a27 100644
> >>>> --- a/include/linux/key.h
> >>>> +++ b/include/linux/key.h
> >>>> @@ -230,6 +230,7 @@ struct key {
> >>>> #define KEY_FLAG_ROOT_CAN_INVAL	7	/* set if key can be invalidated by root without permission */
> >>>> #define KEY_FLAG_KEEP		8	/* set if key should not be removed */
> >>>> #define KEY_FLAG_UID_KEYRING	9	/* set if key is a user or user session keyring */
> >>>> +#define KEY_FLAG_BUILTIN_ROT	10	/* set if key is a builtin Root of Trust key */
> >>>> 
> >>>> 	/* the key type and key description string
> >>>> 	 * - the desc is used to match a key against search criteria
> >>>> @@ -290,6 +291,7 @@ extern struct key *key_alloc(struct key_type *type,
> >>>> #define KEY_ALLOC_BYPASS_RESTRICTION	0x0008	/* Override the check on restricted keyrings */
> >>>> #define KEY_ALLOC_UID_KEYRING		0x0010	/* allocating a user or user session keyring */
> >>>> #define KEY_ALLOC_SET_KEEP		0x0020	/* Set the KEEP flag on the key/keyring */
> >>>> +#define KEY_ALLOC_BUILT_IN_ROT		0x0040  /* Add builtin root of trust key */
> >>> 
> >>> Since the concept of root of trust is not generic, but limited to
> >>> specific keyrings, the root CA certificate signing keys on the
> >>> "machine" keyring need to be identified.  Similar to the
> >>> KEY_ALLOC_BUILT_IN/KEY_FLAG_BUILTIN, new flags
> >>> KEY_ALLOC_MACHINE/KEY_FLAG_MACHINE should be defined instead.
> >> 
> >> I’m open to renaming these, however this name change seems confusing to me.  
> >> This flag gets set when the X.509 certificate contains the three CA requirements 
> >> identified above.  The remaining keys in the machine keyring can be used for 
> >> anything else.
> > 
> > Renaming the flag to KEY_ALLOC_MACHINE/KEY_FLAG_MACHINE differentiates
> > between the "builtin" keys from the "machine" keys.  The trust models
> > are very different.
> 
> Isn’t the trust model the same for machine and secondary keys?  Both are supplied by 
> the end-user. That is why I’m confused by naming something _MACHINE when it applies 
> to more than one keyring.

True both are supplied by the end-user, but the trust models are
different.  In one case the certificates are coming indirectly from
firmware, while in the other case the certificates would be limited to
certificates signed by the initial firmware certificates.  Loading only
root-CA signing key certificates onto the "machine" keyring highlights
and enforces the different types of trust.

> 
> >> Plus this flag can be set for keys loaded into the secondary trusted 
> >> keyring (6th patch in the series).  When an intermediate CA gets loaded into the 
> >> secondary, the flag is set as well.
> > 
> > Please include a full explanation with the motivation in the patch
> > description as to why support for intermediary CAs is required for the
> > "end-user" use case.
> 
> Ok, I can add it.  I thought this was an expectation, based on the help section of
> IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY:
> 
> " Intermediate keys between those the kernel has compiled in and the 
>  IMA keys to be added may be added to the system secondary keyring,
>  provided they are validly signed by a key already resident in the
>  built-in or secondary trusted keyrings."

This paragraph refers to keys on the "builtin_trusted_keys" keyring. 
The concept would need to be expanded to include keys on the "machine"
keyring.   Since support for intermediary CA keys isn't required for
the simple "end-user" use case, the motivation  needs to be provided.

thanks,

Mimi
Eric Snowberg April 8, 2022, 9:59 p.m. UTC | #6
> On Apr 8, 2022, at 12:49 PM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> 
> On Fri, 2022-04-08 at 17:34 +0000, Eric Snowberg wrote:
>> 
>>> On Apr 8, 2022, at 10:55 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
>>> 
>>> On Fri, 2022-04-08 at 15:27 +0000, Eric Snowberg wrote:
>>>> 
>>>>> On Apr 8, 2022, at 8:40 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
>>>>> 
>>>>> On Tue, 2022-04-05 at 21:53 -0400, Eric Snowberg wrote:
>>>>>> 
>>>>>> The first type of key to use this is X.509.  When a X.509 certificate
>>>>>> is self signed, has the kernCertSign Key Usage set and contains the
>>>>>> CA bit set this new flag is set.
>>>>>> 
>>>>>> Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
>>>>>> 
>>>>>> diff --git a/include/linux/key.h b/include/linux/key.h
>>>>>> index 7febc4881363..97f6a1f86a27 100644
>>>>>> --- a/include/linux/key.h
>>>>>> +++ b/include/linux/key.h
>>>>>> @@ -230,6 +230,7 @@ struct key {
>>>>>> #define KEY_FLAG_ROOT_CAN_INVAL	7	/* set if key can be invalidated by root without permission */
>>>>>> #define KEY_FLAG_KEEP		8	/* set if key should not be removed */
>>>>>> #define KEY_FLAG_UID_KEYRING	9	/* set if key is a user or user session keyring */
>>>>>> +#define KEY_FLAG_BUILTIN_ROT	10	/* set if key is a builtin Root of Trust key */
>>>>>> 
>>>>>> 	/* the key type and key description string
>>>>>> 	 * - the desc is used to match a key against search criteria
>>>>>> @@ -290,6 +291,7 @@ extern struct key *key_alloc(struct key_type *type,
>>>>>> #define KEY_ALLOC_BYPASS_RESTRICTION	0x0008	/* Override the check on restricted keyrings */
>>>>>> #define KEY_ALLOC_UID_KEYRING		0x0010	/* allocating a user or user session keyring */
>>>>>> #define KEY_ALLOC_SET_KEEP		0x0020	/* Set the KEEP flag on the key/keyring */
>>>>>> +#define KEY_ALLOC_BUILT_IN_ROT		0x0040  /* Add builtin root of trust key */
>>>>> 
>>>>> Since the concept of root of trust is not generic, but limited to
>>>>> specific keyrings, the root CA certificate signing keys on the
>>>>> "machine" keyring need to be identified.  Similar to the
>>>>> KEY_ALLOC_BUILT_IN/KEY_FLAG_BUILTIN, new flags
>>>>> KEY_ALLOC_MACHINE/KEY_FLAG_MACHINE should be defined instead.
>>>> 
>>>> I’m open to renaming these, however this name change seems confusing to me.  
>>>> This flag gets set when the X.509 certificate contains the three CA requirements 
>>>> identified above.  The remaining keys in the machine keyring can be used for 
>>>> anything else.
>>> 
>>> Renaming the flag to KEY_ALLOC_MACHINE/KEY_FLAG_MACHINE differentiates
>>> between the "builtin" keys from the "machine" keys.  The trust models
>>> are very different.
>> 
>> Isn’t the trust model the same for machine and secondary keys?  Both are supplied by 
>> the end-user. That is why I’m confused by naming something _MACHINE when it applies 
>> to more than one keyring.
> 
> True both are supplied by the end-user, but the trust models are
> different.

I think I need more information here, I’m not seeing how they are different trust 
models.

>  In one case the certificates are coming indirectly from
> firmware,

Any kernel signed by a cert in the MokList will boot.  The very thing the machine 
keyring contains.

For example, if a user has a cert (CA bit set false, keyCertSign not set, and it isn’t 
self signed), they can use insert-sys-cert to get it into their kernel.  They can then 
sign the kernel with any key in their MokList.  Why would we want to treat this key 
different if it was injected into the kernel verses coming in through the machine 
keyring? 

I can see the desire to have a root of trust all the way back to the root CA.  What 
I can’t see is if we ignore this for certain keyrings.

> while in the other case the certificates would be limited to
> certificates signed by the initial firmware certificates.  Loading only
> root-CA signing key certificates onto the "machine" keyring highlights
> and enforces the different types of trust.

If the root-CA cert must contain keyCertSign, I don’t see the point in loading only 
root-CA certs either. Why would we want to prevent  a code signing cert with the 
CA bit set from loading into the machine keyring?  A code signing cert should be 
allowed to validate a kernel module, but It should not be allowed to validate other
certs.
Mimi Zohar April 11, 2022, 3:30 p.m. UTC | #7
On Fri, 2022-04-08 at 21:59 +0000, Eric Snowberg wrote:
> > On Apr 8, 2022, at 12:49 PM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> > 
> > On Fri, 2022-04-08 at 17:34 +0000, Eric Snowberg wrote:
> >> 
> >>> On Apr 8, 2022, at 10:55 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> >>> 
> >>> On Fri, 2022-04-08 at 15:27 +0000, Eric Snowberg wrote:
> >>>> 
> >>>>> On Apr 8, 2022, at 8:40 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> >>>>> 
> >>>>> On Tue, 2022-04-05 at 21:53 -0400, Eric Snowberg wrote:
> >>>>>> 
> >>>>>> The first type of key to use this is X.509.  When a X.509 certificate
> >>>>>> is self signed, has the kernCertSign Key Usage set and contains the
> >>>>>> CA bit set this new flag is set.
> >>>>>> 
> >>>>>> Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
> >>>>>> 
> >>>>>> diff --git a/include/linux/key.h b/include/linux/key.h
> >>>>>> index 7febc4881363..97f6a1f86a27 100644
> >>>>>> --- a/include/linux/key.h
> >>>>>> +++ b/include/linux/key.h
> >>>>>> @@ -230,6 +230,7 @@ struct key {
> >>>>>> #define KEY_FLAG_ROOT_CAN_INVAL  7       /* set if key can be invalidated by root without permission */
> >>>>>> #define KEY_FLAG_KEEP            8       /* set if key should not be removed */
> >>>>>> #define KEY_FLAG_UID_KEYRING     9       /* set if key is a user or user session keyring */
> >>>>>> +#define KEY_FLAG_BUILTIN_ROT    10      /* set if key is a builtin Root of Trust key */
> >>>>>> 
> >>>>>>  /* the key type and key description string
> >>>>>>   * - the desc is used to match a key against search criteria
> >>>>>> @@ -290,6 +291,7 @@ extern struct key *key_alloc(struct key_type *type,
> >>>>>> #define KEY_ALLOC_BYPASS_RESTRICTION     0x0008  /* Override the check on restricted keyrings */
> >>>>>> #define KEY_ALLOC_UID_KEYRING            0x0010  /* allocating a user or user session keyring */
> >>>>>> #define KEY_ALLOC_SET_KEEP               0x0020  /* Set the KEEP flag on the key/keyring */
> >>>>>> +#define KEY_ALLOC_BUILT_IN_ROT          0x0040  /* Add builtin root of trust key */
> >>>>> 
> >>>>> Since the concept of root of trust is not generic, but limited to
> >>>>> specific keyrings, the root CA certificate signing keys on the
> >>>>> "machine" keyring need to be identified.  Similar to the
> >>>>> KEY_ALLOC_BUILT_IN/KEY_FLAG_BUILTIN, new flags
> >>>>> KEY_ALLOC_MACHINE/KEY_FLAG_MACHINE should be defined instead.
> >>>> 
> >>>> I’m open to renaming these, however this name change seems confusing to me.  
> >>>> This flag gets set when the X.509 certificate contains the three CA requirements 
> >>>> identified above.  The remaining keys in the machine keyring can be used for 
> >>>> anything else.
> >>> 
> >>> Renaming the flag to KEY_ALLOC_MACHINE/KEY_FLAG_MACHINE differentiates
> >>> between the "builtin" keys from the "machine" keys.  The trust models
> >>> are very different.
> >> 
> >> Isn’t the trust model the same for machine and secondary keys?  Both are supplied by 
> >> the end-user. That is why I’m confused by naming something _MACHINE when it applies 
> >> to more than one keyring.
> > 
> > True both are supplied by the end-user, but the trust models are
> > different.
> 
> I think I need more information here, I’m not seeing how they are different trust 
> models.

In order to discuss trust models, we need to understand the different
use-cases that are being discussed here without ever having been
explicitly stated.  Here are a few:
- Allow users to sign their own kernel modules.
- Allow users to selectively authorize 3rd party certificates to verify
kernel modules.
- From an IMA perspective, allow users to sign files within their own
software packages.

Each of the above use-cases needs to be independently configurable,
thoroughly explained, and enforced.

thanks,

Mimi


> 
> >  In one case the certificates are coming indirectly from
> > firmware,
Eric Snowberg April 14, 2022, 4:36 p.m. UTC | #8
> On Apr 11, 2022, at 9:30 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> 
> On Fri, 2022-04-08 at 21:59 +0000, Eric Snowberg wrote:
>>> On Apr 8, 2022, at 12:49 PM, Mimi Zohar <zohar@linux.ibm.com> wrote:
>>> 
>>> On Fri, 2022-04-08 at 17:34 +0000, Eric Snowberg wrote:
>>>> 
>>>>> On Apr 8, 2022, at 10:55 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
>>>>> 
>>>>> On Fri, 2022-04-08 at 15:27 +0000, Eric Snowberg wrote:
>>>>>> 
>>>>>>> On Apr 8, 2022, at 8:40 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
>>>>>>> 
>>>>>>> On Tue, 2022-04-05 at 21:53 -0400, Eric Snowberg wrote:
>>>>>>>> 
>>>>>>>> The first type of key to use this is X.509.  When a X.509 certificate
>>>>>>>> is self signed, has the kernCertSign Key Usage set and contains the
>>>>>>>> CA bit set this new flag is set.
>>>>>>>> 
>>>>>>>> Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
>>>>>>>> 
>>>>>>>> diff --git a/include/linux/key.h b/include/linux/key.h
>>>>>>>> index 7febc4881363..97f6a1f86a27 100644
>>>>>>>> --- a/include/linux/key.h
>>>>>>>> +++ b/include/linux/key.h
>>>>>>>> @@ -230,6 +230,7 @@ struct key {
>>>>>>>> #define KEY_FLAG_ROOT_CAN_INVAL  7       /* set if key can be invalidated by root without permission */
>>>>>>>> #define KEY_FLAG_KEEP            8       /* set if key should not be removed */
>>>>>>>> #define KEY_FLAG_UID_KEYRING     9       /* set if key is a user or user session keyring */
>>>>>>>> +#define KEY_FLAG_BUILTIN_ROT    10      /* set if key is a builtin Root of Trust key */
>>>>>>>> 
>>>>>>>> /* the key type and key description string
>>>>>>>>  * - the desc is used to match a key against search criteria
>>>>>>>> @@ -290,6 +291,7 @@ extern struct key *key_alloc(struct key_type *type,
>>>>>>>> #define KEY_ALLOC_BYPASS_RESTRICTION     0x0008  /* Override the check on restricted keyrings */
>>>>>>>> #define KEY_ALLOC_UID_KEYRING            0x0010  /* allocating a user or user session keyring */
>>>>>>>> #define KEY_ALLOC_SET_KEEP               0x0020  /* Set the KEEP flag on the key/keyring */
>>>>>>>> +#define KEY_ALLOC_BUILT_IN_ROT          0x0040  /* Add builtin root of trust key */
>>>>>>> 
>>>>>>> Since the concept of root of trust is not generic, but limited to
>>>>>>> specific keyrings, the root CA certificate signing keys on the
>>>>>>> "machine" keyring need to be identified.  Similar to the
>>>>>>> KEY_ALLOC_BUILT_IN/KEY_FLAG_BUILTIN, new flags
>>>>>>> KEY_ALLOC_MACHINE/KEY_FLAG_MACHINE should be defined instead.
>>>>>> 
>>>>>> I’m open to renaming these, however this name change seems confusing to me.  
>>>>>> This flag gets set when the X.509 certificate contains the three CA requirements 
>>>>>> identified above.  The remaining keys in the machine keyring can be used for 
>>>>>> anything else.
>>>>> 
>>>>> Renaming the flag to KEY_ALLOC_MACHINE/KEY_FLAG_MACHINE differentiates
>>>>> between the "builtin" keys from the "machine" keys.  The trust models
>>>>> are very different.
>>>> 
>>>> Isn’t the trust model the same for machine and secondary keys?  Both are supplied by 
>>>> the end-user. That is why I’m confused by naming something _MACHINE when it applies 
>>>> to more than one keyring.
>>> 
>>> True both are supplied by the end-user, but the trust models are
>>> different.
>> 
>> I think I need more information here, I’m not seeing how they are different trust 
>> models.
> 
> In order to discuss trust models, we need to understand the different
> use-cases that are being discussed here without ever having been
> explicitly stated.  Here are a few:
> - Allow users to sign their own kernel modules.
> - Allow users to selectively authorize 3rd party certificates to verify
> kernel modules.
> - From an IMA perspective, allow users to sign files within their own
> software packages.
> 
> Each of the above use-cases needs to be independently configurable,
> thoroughly explained, and enforced.

I’m still confused by the request here.  All these use cases can be done 
today with insert-sys-cert.  Take the, " allow user to sign their own kernel 
modules" use case.  Using insert-sys-cert, any type of key can be added 
to the builtin trusted keyring, it doesn’t need to be self signed, there are 
no restrictions on fields in the certificate.  The same approach can be used 
to allow users to ima sign their own files. Any key can be added, it doesn’t 
need to be a CA. The same goes for 3rd party signed modules.

This series doesn’t enable keys to be used for any new purpose than what 
can be done today.  In fact it limits how system keys may be used. It does 
this by adding a new restriction.  The new restriction enforces the CA 
requirements ima expects. This restriction is enforced on all keyrings ima 
references (builtin or secondary).  Since the machine keyring is linked to 
the secondary, it may now be used, since the CA restriction ima expects will 
be enforced.
Mimi Zohar April 15, 2022, 4:14 p.m. UTC | #9
On Thu, 2022-04-14 at 21:59 +0000, Eric Snowberg wrote:
> 
> > On Apr 14, 2022, at 12:09 PM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> > 
> > On Thu, 2022-04-14 at 16:36 +0000, Eric Snowberg wrote:
> >> 
> >>> On Apr 11, 2022, at 9:30 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> >>> 
> >>> On Fri, 2022-04-08 at 21:59 +0000, Eric Snowberg wrote:
> >>>>> On Apr 8, 2022, at 12:49 PM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> >>>>> 
> >>>>> On Fri, 2022-04-08 at 17:34 +0000, Eric Snowberg wrote:
> >>>>>> 
> >>>>>>> On Apr 8, 2022, at 10:55 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> >>>>>>> 
> >>>>>>> On Fri, 2022-04-08 at 15:27 +0000, Eric Snowberg wrote:
> >>>>>>>> 
> >>>>>>>>> On Apr 8, 2022, at 8:40 AM, Mimi Zohar <zohar@linux.ibm.com> wrote:
> >>>>>>>>> 
> >>>>>>>>> On Tue, 2022-04-05 at 21:53 -0400, Eric Snowberg wrote:
> >>>>>>>>>> 
> >>>>>>>>>> The first type of key to use this is X.509.  When a X.509 certificate
> >>>>>>>>>> is self signed, has the kernCertSign Key Usage set and contains the
> >>>>>>>>>> CA bit set this new flag is set.
> >>>>>>>>>> 
> >>>>>>>>>> Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
> >>>>>>>>>> 
> >>>>>>>>>> diff --git a/include/linux/key.h b/include/linux/key.h
> >>>>>>>>>> index 7febc4881363..97f6a1f86a27 100644
> >>>>>>>>>> --- a/include/linux/key.h
> >>>>>>>>>> +++ b/include/linux/key.h
> >>>>>>>>>> @@ -230,6 +230,7 @@ struct key {
> >>>>>>>>>> #define KEY_FLAG_ROOT_CAN_INVAL  7       /* set if key can be invalidated by root without permission */
> >>>>>>>>>> #define KEY_FLAG_KEEP            8       /* set if key should not be removed */
> >>>>>>>>>> #define KEY_FLAG_UID_KEYRING     9       /* set if key is a user or user session keyring */
> >>>>>>>>>> +#define KEY_FLAG_BUILTIN_ROT    10      /* set if key is a builtin Root of Trust key */
> >>>>>>>>>> 
> >>>>>>>>>> /* the key type and key description string
> >>>>>>>>>> * - the desc is used to match a key against search criteria
> >>>>>>>>>> @@ -290,6 +291,7 @@ extern struct key *key_alloc(struct key_type *type,
> >>>>>>>>>> #define KEY_ALLOC_BYPASS_RESTRICTION     0x0008  /* Override the check on restricted keyrings */
> >>>>>>>>>> #define KEY_ALLOC_UID_KEYRING            0x0010  /* allocating a user or user session keyring */
> >>>>>>>>>> #define KEY_ALLOC_SET_KEEP               0x0020  /* Set the KEEP flag on the key/keyring */
> >>>>>>>>>> +#define KEY_ALLOC_BUILT_IN_ROT          0x0040  /* Add builtin root of trust key */
> >>>>>>>>> 
> >>>>>>>>> Since the concept of root of trust is not generic, but limited to
> >>>>>>>>> specific keyrings, the root CA certificate signing keys on the
> >>>>>>>>> "machine" keyring need to be identified.  Similar to the
> >>>>>>>>> KEY_ALLOC_BUILT_IN/KEY_FLAG_BUILTIN, new flags
> >>>>>>>>> KEY_ALLOC_MACHINE/KEY_FLAG_MACHINE should be defined instead.
> >>>>>>>> 
> >>>>>>>> I’m open to renaming these, however this name change seems confusing to me.  
> >>>>>>>> This flag gets set when the X.509 certificate contains the three CA requirements 
> >>>>>>>> identified above.  The remaining keys in the machine keyring can be used for 
> >>>>>>>> anything else.
> >>>>>>> 
> >>>>>>> Renaming the flag to KEY_ALLOC_MACHINE/KEY_FLAG_MACHINE differentiates
> >>>>>>> between the "builtin" keys from the "machine" keys.  The trust models
> >>>>>>> are very different.
> >>>>>> 
> >>>>>> Isn’t the trust model the same for machine and secondary keys?  Both are supplied by 
> >>>>>> the end-user. That is why I’m confused by naming something _MACHINE when it applies 
> >>>>>> to more than one keyring.
> >>>>> 
> >>>>> True both are supplied by the end-user, but the trust models are
> >>>>> different.
> >>>> 
> >>>> I think I need more information here, I’m not seeing how they are different trust 
> >>>> models.
> >>> 
> >>> In order to discuss trust models, we need to understand the different
> >>> use-cases that are being discussed here without ever having been
> >>> explicitly stated.  Here are a few:
> >>> - Allow users to sign their own kernel modules.
> >>> - Allow users to selectively authorize 3rd party certificates to verify
> >>> kernel modules.
> >>> - From an IMA perspective, allow users to sign files within their own
> >>> software packages.
> >>> 
> >>> Each of the above use-cases needs to be independently configurable,
> >>> thoroughly explained, and enforced.
> >> 
> >> I’m still confused by the request here.  All these use cases can be done 
> >> today with insert-sys-cert.  Take the, " allow user to sign their own kernel 
> >> modules" use case.  Using insert-sys-cert, any type of key can be added 
> >> to the builtin trusted keyring, it doesn’t need to be self signed, there are 
> >> no restrictions on fields in the certificate.  The same approach can be used 
> >> to allow users to ima sign their own files. Any key can be added, it doesn’t 
> >> need to be a CA. The same goes for 3rd party signed modules.
> > 
> > The difference is "where" the key is coming from.  In the builtin use-
> > case or the post build insert-sys-cert case, the kernel image is
> > signed, or re-signed, and the kernel image signature is verified.  The
> > root of trust is straight forward - secure boot with a HW root of trust
> > up to and including verifying the kernel image signature, then
> > transition to the builtin keys.
> > 
> > Keys on the "machine" keyring are not part of that signature chain of
> > trust,
> 
> The machine keyring contains all keys in the MokList. On x86 (and other 
> architectures that boot with shim) all keys in the MokList are part of the signature 
> chain of trust. Shim uses MOKList keys to validate the kernel image signature 
> when booting with SecureBoot enabled. Secure Boot DB keys are used to
> validate shim, but rarely used to validate the kernel.

Sure, keys on the "machine" keyring can be used to verify the kexec
kernel image signature.

As all of the above requirements is satisfied by loading a root CA, def
ined as a KeySigning cert, without needing to load all of the MOK keys
onto the "machine" keyring, support both trust models.  Please make
loading all MOK keys configurable, with a thorough explanation.

thanks,

Mimi
diff mbox series

Patch

diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index 91a4ad50dea2..7290e765f46b 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -215,6 +215,8 @@  static int x509_key_preparse(struct key_preparsed_payload *prep)
 	prep->payload.data[asym_auth] = cert->sig;
 	prep->description = desc;
 	prep->quotalen = 100;
+	if (cert->is_kcs_set && cert->self_signed && cert->is_root_ca)
+		prep->payload_flags |= KEY_ALLOC_ROT;
 
 	/* We've finished with the certificate */
 	cert->pub = NULL;
diff --git a/include/linux/key-type.h b/include/linux/key-type.h
index 7d985a1dfe4a..ed0aaad3849b 100644
--- a/include/linux/key-type.h
+++ b/include/linux/key-type.h
@@ -36,6 +36,8 @@  struct key_preparsed_payload {
 	size_t		datalen;	/* Raw datalen */
 	size_t		quotalen;	/* Quota length for proposed payload */
 	time64_t	expiry;		/* Expiry time of key */
+	unsigned int	payload_flags;  /* Proposed payload flags */
+#define KEY_ALLOC_ROT	0x0001		/* Proposed Root of Trust (ROT) key */
 } __randomize_layout;
 
 typedef int (*request_key_actor_t)(struct key *auth_key, void *aux);
diff --git a/include/linux/key.h b/include/linux/key.h
index 7febc4881363..97f6a1f86a27 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -230,6 +230,7 @@  struct key {
 #define KEY_FLAG_ROOT_CAN_INVAL	7	/* set if key can be invalidated by root without permission */
 #define KEY_FLAG_KEEP		8	/* set if key should not be removed */
 #define KEY_FLAG_UID_KEYRING	9	/* set if key is a user or user session keyring */
+#define KEY_FLAG_BUILTIN_ROT	10	/* set if key is a builtin Root of Trust key */
 
 	/* the key type and key description string
 	 * - the desc is used to match a key against search criteria
@@ -290,6 +291,7 @@  extern struct key *key_alloc(struct key_type *type,
 #define KEY_ALLOC_BYPASS_RESTRICTION	0x0008	/* Override the check on restricted keyrings */
 #define KEY_ALLOC_UID_KEYRING		0x0010	/* allocating a user or user session keyring */
 #define KEY_ALLOC_SET_KEEP		0x0020	/* Set the KEEP flag on the key/keyring */
+#define KEY_ALLOC_BUILT_IN_ROT		0x0040  /* Add builtin root of trust key */
 
 extern void key_revoke(struct key *key);
 extern void key_invalidate(struct key *key);
diff --git a/security/keys/key.c b/security/keys/key.c
index c45afdd1dfbb..732bb837fc51 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -305,6 +305,8 @@  struct key *key_alloc(struct key_type *type, const char *desc,
 		key->flags |= 1 << KEY_FLAG_UID_KEYRING;
 	if (flags & KEY_ALLOC_SET_KEEP)
 		key->flags |= 1 << KEY_FLAG_KEEP;
+	if (flags & KEY_ALLOC_BUILT_IN_ROT)
+		key->flags |= 1 << KEY_FLAG_BUILTIN_ROT;
 
 #ifdef KEY_DEBUGGING
 	key->magic = KEY_DEBUG_MAGIC;
@@ -929,6 +931,12 @@  key_ref_t key_create_or_update(key_ref_t keyring_ref,
 			perm |= KEY_POS_WRITE;
 	}
 
+	/* Only allow KEY_ALLOC_BUILT_IN_ROT flag to be set by preparser contents */
+	if (prep.payload_flags & KEY_ALLOC_ROT)
+		flags |= KEY_ALLOC_BUILT_IN_ROT;
+	else
+		flags &= ~KEY_ALLOC_BUILT_IN_ROT;
+
 	/* allocate a new key */
 	key = key_alloc(index_key.type, index_key.description,
 			cred->fsuid, cred->fsgid, cred, perm, flags, NULL);