diff mbox series

[v4,6/6] integrity: PowerVM support for loading third party code signing keys

Message ID 20230815112722.1591829-7-nayna@linux.ibm.com (mailing list archive)
State Handled Elsewhere
Headers show
Series Enable loading local and third party keys on PowerVM guest | expand

Commit Message

Nayna Jain Aug. 15, 2023, 11:27 a.m. UTC
On secure boot enabled PowerVM LPAR, third party code signing keys are
needed during early boot to verify signed third party modules. These
third party keys are stored in moduledb object in the Platform
KeyStore (PKS).

Load third party code signing keys onto .secondary_trusted_keys keyring.

Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
---
 certs/system_keyring.c                        | 30 +++++++++++++++++++
 include/keys/system_keyring.h                 |  4 +++
 .../platform_certs/keyring_handler.c          |  8 +++++
 .../platform_certs/keyring_handler.h          |  5 ++++
 .../integrity/platform_certs/load_powerpc.c   | 17 +++++++++++
 5 files changed, 64 insertions(+)

Comments

Mimi Zohar Aug. 15, 2023, 8:30 p.m. UTC | #1
On Tue, 2023-08-15 at 07:27 -0400, Nayna Jain wrote:
> On secure boot enabled PowerVM LPAR, third party code signing keys are
> needed during early boot to verify signed third party modules. These
> third party keys are stored in moduledb object in the Platform
> KeyStore (PKS).
> 
> Load third party code signing keys onto .secondary_trusted_keys keyring.
> 
> Signed-off-by: Nayna Jain <nayna@linux.ibm.com>

Reviewed-and-tested-by: Mimi Zohar <zohar@linux.ibm.com>
R Nageswara Sastry Aug. 16, 2023, 2:42 p.m. UTC | #2
On 15/08/23 4:57 pm, Nayna Jain wrote:
> On secure boot enabled PowerVM LPAR, third party code signing keys are
> needed during early boot to verify signed third party modules. These
> third party keys are stored in moduledb object in the Platform
> KeyStore (PKS).
> 
> Load third party code signing keys onto .secondary_trusted_keys keyring.
> 
> Signed-off-by: Nayna Jain <nayna@linux.ibm.com>


Tested with trustedcadb, moduledb scenarios
Tested-by: Nageswara R Sastry <rnsastry@linux.ibm.com>

> ---
>   certs/system_keyring.c                        | 30 +++++++++++++++++++
>   include/keys/system_keyring.h                 |  4 +++
>   .../platform_certs/keyring_handler.c          |  8 +++++
>   .../platform_certs/keyring_handler.h          |  5 ++++
>   .../integrity/platform_certs/load_powerpc.c   | 17 +++++++++++
>   5 files changed, 64 insertions(+)
> 
> diff --git a/certs/system_keyring.c b/certs/system_keyring.c
> index b348e0898d34..33841c91f12c 100644
> --- a/certs/system_keyring.c
> +++ b/certs/system_keyring.c
> @@ -152,6 +152,36 @@ static __init struct key_restriction *get_builtin_and_secondary_restriction(void
>   
>   	return restriction;
>   }
> +
> +/**
> + * add_to_secondary_keyring - Add to secondary keyring.
> + * @source: Source of key
> + * @data: The blob holding the key
> + * @len: The length of the data blob
> + *
> + * Add a key to the secondary keyring. The key must be vouched for by a key in the builtin,
> + * machine or secondary keyring itself.
> + */
> +void __init add_to_secondary_keyring(const char *source, const void *data, size_t len)
> +{
> +	key_ref_t key;
> +	key_perm_t perm;
> +
> +	perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW;
> +
> +	key = key_create_or_update(make_key_ref(secondary_trusted_keys, 1),
> +				   "asymmetric",
> +				   NULL, data, len, perm,
> +				   KEY_ALLOC_NOT_IN_QUOTA);
> +	if (IS_ERR(key)) {
> +		pr_err("Problem loading X.509 certificate from %s to secondary keyring %ld\n",
> +		       source, PTR_ERR(key));
> +		return;
> +	}
> +
> +	pr_notice("Loaded X.509 cert '%s'\n", key_ref_to_ptr(key)->description);
> +	key_ref_put(key);
> +}
>   #endif
>   #ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
>   void __init set_machine_trusted_keys(struct key *keyring)
> diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
> index 7e2583208820..8365adf842ef 100644
> --- a/include/keys/system_keyring.h
> +++ b/include/keys/system_keyring.h
> @@ -50,9 +50,13 @@ int restrict_link_by_digsig_builtin_and_secondary(struct key *keyring,
>   						  const struct key_type *type,
>   						  const union key_payload *payload,
>   						  struct key *restriction_key);
> +void __init add_to_secondary_keyring(const char *source, const void *data, size_t len);
>   #else
>   #define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted
>   #define restrict_link_by_digsig_builtin_and_secondary restrict_link_by_digsig_builtin
> +static inline void __init add_to_secondary_keyring(const char *source, const void *data, size_t len)
> +{
> +}
>   #endif
>   
>   #ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
> diff --git a/security/integrity/platform_certs/keyring_handler.c b/security/integrity/platform_certs/keyring_handler.c
> index 586027b9a3f5..13ea17207902 100644
> --- a/security/integrity/platform_certs/keyring_handler.c
> +++ b/security/integrity/platform_certs/keyring_handler.c
> @@ -78,6 +78,14 @@ __init efi_element_handler_t get_handler_for_ca_keys(const efi_guid_t *sig_type)
>   	return NULL;
>   }
>   
> +__init efi_element_handler_t get_handler_for_code_signing_keys(const efi_guid_t *sig_type)
> +{
> +	if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0)
> +		return add_to_secondary_keyring;
> +
> +	return NULL;
> +}
> +
>   /*
>    * Return the appropriate handler for particular signature list types found in
>    * the UEFI dbx and MokListXRT tables.
> diff --git a/security/integrity/platform_certs/keyring_handler.h b/security/integrity/platform_certs/keyring_handler.h
> index 6f15bb4cc8dc..f92895cc50f6 100644
> --- a/security/integrity/platform_certs/keyring_handler.h
> +++ b/security/integrity/platform_certs/keyring_handler.h
> @@ -34,6 +34,11 @@ efi_element_handler_t get_handler_for_mok(const efi_guid_t *sig_type);
>    */
>   efi_element_handler_t get_handler_for_ca_keys(const efi_guid_t *sig_type);
>   
> +/*
> + * Return the handler for particular signature list types for code signing keys.
> + */
> +efi_element_handler_t get_handler_for_code_signing_keys(const efi_guid_t *sig_type);
> +
>   /*
>    * Return the handler for particular signature list types found in the dbx.
>    */
> diff --git a/security/integrity/platform_certs/load_powerpc.c b/security/integrity/platform_certs/load_powerpc.c
> index 339053d9726d..c85febca3343 100644
> --- a/security/integrity/platform_certs/load_powerpc.c
> +++ b/security/integrity/platform_certs/load_powerpc.c
> @@ -60,6 +60,7 @@ static int __init load_powerpc_certs(void)
>   {
>   	void *db = NULL, *dbx = NULL, *data = NULL;
>   	void *trustedca;
> +	void *moduledb;
>   	u64 dsize = 0;
>   	u64 offset = 0;
>   	int rc = 0;
> @@ -137,6 +138,22 @@ static int __init load_powerpc_certs(void)
>   		kfree(data);
>   	}
>   
> +	data = get_cert_list("moduledb", 9,  &dsize);
> +	if (!data) {
> +		pr_info("Couldn't get moduledb list from firmware\n");
> +	} else if (IS_ERR(data)) {
> +		rc = PTR_ERR(data);
> +		pr_err("Error reading moduledb from firmware: %d\n", rc);
> +	} else {
> +		extract_esl(moduledb, data, dsize, offset);
> +
> +		rc = parse_efi_signature_list("powerpc:moduledb", moduledb, dsize,
> +					      get_handler_for_code_signing_keys);
> +		if (rc)
> +			pr_err("Couldn't parse moduledb signatures: %d\n", rc);
> +		kfree(data);
> +	}
> +
>   	return rc;
>   }
>   late_initcall(load_powerpc_certs);
Jarkko Sakkinen Aug. 16, 2023, 8:36 p.m. UTC | #3
On Tue Aug 15, 2023 at 2:27 PM EEST, Nayna Jain wrote:
> On secure boot enabled PowerVM LPAR, third party code signing keys are
> needed during early boot to verify signed third party modules. These
> third party keys are stored in moduledb object in the Platform
> KeyStore (PKS).
>
> Load third party code signing keys onto .secondary_trusted_keys keyring.
>
> Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
> ---
>  certs/system_keyring.c                        | 30 +++++++++++++++++++
>  include/keys/system_keyring.h                 |  4 +++
>  .../platform_certs/keyring_handler.c          |  8 +++++
>  .../platform_certs/keyring_handler.h          |  5 ++++
>  .../integrity/platform_certs/load_powerpc.c   | 17 +++++++++++
>  5 files changed, 64 insertions(+)
>
> diff --git a/certs/system_keyring.c b/certs/system_keyring.c
> index b348e0898d34..33841c91f12c 100644
> --- a/certs/system_keyring.c
> +++ b/certs/system_keyring.c
> @@ -152,6 +152,36 @@ static __init struct key_restriction *get_builtin_and_secondary_restriction(void
>  
>  	return restriction;
>  }
> +
> +/**
> + * add_to_secondary_keyring - Add to secondary keyring.
> + * @source: Source of key
> + * @data: The blob holding the key
> + * @len: The length of the data blob
> + *
> + * Add a key to the secondary keyring. The key must be vouched for by a key in the builtin,
> + * machine or secondary keyring itself.
> + */
> +void __init add_to_secondary_keyring(const char *source, const void *data, size_t len)
> +{
> +	key_ref_t key;
> +	key_perm_t perm;
> +
> +	perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW;
> +
> +	key = key_create_or_update(make_key_ref(secondary_trusted_keys, 1),
> +				   "asymmetric",
> +				   NULL, data, len, perm,
> +				   KEY_ALLOC_NOT_IN_QUOTA);
> +	if (IS_ERR(key)) {
> +		pr_err("Problem loading X.509 certificate from %s to secondary keyring %ld\n",
> +		       source, PTR_ERR(key));
> +		return;
> +	}
> +
> +	pr_notice("Loaded X.509 cert '%s'\n", key_ref_to_ptr(key)->description);
> +	key_ref_put(key);
> +}
>  #endif
>  #ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
>  void __init set_machine_trusted_keys(struct key *keyring)
> diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
> index 7e2583208820..8365adf842ef 100644
> --- a/include/keys/system_keyring.h
> +++ b/include/keys/system_keyring.h
> @@ -50,9 +50,13 @@ int restrict_link_by_digsig_builtin_and_secondary(struct key *keyring,
>  						  const struct key_type *type,
>  						  const union key_payload *payload,
>  						  struct key *restriction_key);
> +void __init add_to_secondary_keyring(const char *source, const void *data, size_t len);
>  #else
>  #define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted
>  #define restrict_link_by_digsig_builtin_and_secondary restrict_link_by_digsig_builtin
> +static inline void __init add_to_secondary_keyring(const char *source, const void *data, size_t len)
> +{
> +}
>  #endif
>  
>  #ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
> diff --git a/security/integrity/platform_certs/keyring_handler.c b/security/integrity/platform_certs/keyring_handler.c
> index 586027b9a3f5..13ea17207902 100644
> --- a/security/integrity/platform_certs/keyring_handler.c
> +++ b/security/integrity/platform_certs/keyring_handler.c
> @@ -78,6 +78,14 @@ __init efi_element_handler_t get_handler_for_ca_keys(const efi_guid_t *sig_type)
>  	return NULL;
>  }
>  
> +__init efi_element_handler_t get_handler_for_code_signing_keys(const efi_guid_t *sig_type)
> +{
> +	if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0)
> +		return add_to_secondary_keyring;
> +
> +	return NULL;
> +}
> +
>  /*
>   * Return the appropriate handler for particular signature list types found in
>   * the UEFI dbx and MokListXRT tables.
> diff --git a/security/integrity/platform_certs/keyring_handler.h b/security/integrity/platform_certs/keyring_handler.h
> index 6f15bb4cc8dc..f92895cc50f6 100644
> --- a/security/integrity/platform_certs/keyring_handler.h
> +++ b/security/integrity/platform_certs/keyring_handler.h
> @@ -34,6 +34,11 @@ efi_element_handler_t get_handler_for_mok(const efi_guid_t *sig_type);
>   */
>  efi_element_handler_t get_handler_for_ca_keys(const efi_guid_t *sig_type);
>  
> +/*
> + * Return the handler for particular signature list types for code signing keys.
> + */
> +efi_element_handler_t get_handler_for_code_signing_keys(const efi_guid_t *sig_type);
> +
>  /*
>   * Return the handler for particular signature list types found in the dbx.
>   */
> diff --git a/security/integrity/platform_certs/load_powerpc.c b/security/integrity/platform_certs/load_powerpc.c
> index 339053d9726d..c85febca3343 100644
> --- a/security/integrity/platform_certs/load_powerpc.c
> +++ b/security/integrity/platform_certs/load_powerpc.c
> @@ -60,6 +60,7 @@ static int __init load_powerpc_certs(void)
>  {
>  	void *db = NULL, *dbx = NULL, *data = NULL;
>  	void *trustedca;
> +	void *moduledb;
>  	u64 dsize = 0;
>  	u64 offset = 0;
>  	int rc = 0;
> @@ -137,6 +138,22 @@ static int __init load_powerpc_certs(void)
>  		kfree(data);
>  	}
>  
> +	data = get_cert_list("moduledb", 9,  &dsize);
> +	if (!data) {
> +		pr_info("Couldn't get moduledb list from firmware\n");
> +	} else if (IS_ERR(data)) {
> +		rc = PTR_ERR(data);
> +		pr_err("Error reading moduledb from firmware: %d\n", rc);
> +	} else {
> +		extract_esl(moduledb, data, dsize, offset);
> +
> +		rc = parse_efi_signature_list("powerpc:moduledb", moduledb, dsize,
> +					      get_handler_for_code_signing_keys);
> +		if (rc)
> +			pr_err("Couldn't parse moduledb signatures: %d\n", rc);
> +		kfree(data);
> +	}
> +
>  	return rc;
>  }
>  late_initcall(load_powerpc_certs);
> -- 
> 2.31.1

Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>

I can pick this. My last PR did not went too great partly because of
mess with tpm_tis but now things are calmer.

BR, Jarkko
Mimi Zohar Aug. 16, 2023, 9:06 p.m. UTC | #4
On Wed, 2023-08-16 at 23:36 +0300, Jarkko Sakkinen wrote:
> On Tue Aug 15, 2023 at 2:27 PM EEST, Nayna Jain wrote:
> > On secure boot enabled PowerVM LPAR, third party code signing keys are
> > needed during early boot to verify signed third party modules. These
> > third party keys are stored in moduledb object in the Platform
> > KeyStore (PKS).
> >
> > Load third party code signing keys onto .secondary_trusted_keys keyring.
> >
> > Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
> > ---
> >  certs/system_keyring.c                        | 30 +++++++++++++++++++
> >  include/keys/system_keyring.h                 |  4 +++
> >  .../platform_certs/keyring_handler.c          |  8 +++++
> >  .../platform_certs/keyring_handler.h          |  5 ++++
> >  .../integrity/platform_certs/load_powerpc.c   | 17 +++++++++++
> >  5 files changed, 64 insertions(+)
> >
> > diff --git a/certs/system_keyring.c b/certs/system_keyring.c
> > index b348e0898d34..33841c91f12c 100644
> > --- a/certs/system_keyring.c
> > +++ b/certs/system_keyring.c
> > @@ -152,6 +152,36 @@ static __init struct key_restriction *get_builtin_and_secondary_restriction(void
> >  
> >  	return restriction;
> >  }
> > +
> > +/**
> > + * add_to_secondary_keyring - Add to secondary keyring.
> > + * @source: Source of key
> > + * @data: The blob holding the key
> > + * @len: The length of the data blob
> > + *
> > + * Add a key to the secondary keyring. The key must be vouched for by a key in the builtin,
> > + * machine or secondary keyring itself.
> > + */
> > +void __init add_to_secondary_keyring(const char *source, const void *data, size_t len)
> > +{
> > +	key_ref_t key;
> > +	key_perm_t perm;
> > +
> > +	perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW;
> > +
> > +	key = key_create_or_update(make_key_ref(secondary_trusted_keys, 1),
> > +				   "asymmetric",
> > +				   NULL, data, len, perm,
> > +				   KEY_ALLOC_NOT_IN_QUOTA);
> > +	if (IS_ERR(key)) {
> > +		pr_err("Problem loading X.509 certificate from %s to secondary keyring %ld\n",
> > +		       source, PTR_ERR(key));
> > +		return;
> > +	}
> > +
> > +	pr_notice("Loaded X.509 cert '%s'\n", key_ref_to_ptr(key)->description);
> > +	key_ref_put(key);
> > +}
> >  #endif
> >  #ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
> >  void __init set_machine_trusted_keys(struct key *keyring)
> > diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
> > index 7e2583208820..8365adf842ef 100644
> > --- a/include/keys/system_keyring.h
> > +++ b/include/keys/system_keyring.h
> > @@ -50,9 +50,13 @@ int restrict_link_by_digsig_builtin_and_secondary(struct key *keyring,
> >  						  const struct key_type *type,
> >  						  const union key_payload *payload,
> >  						  struct key *restriction_key);
> > +void __init add_to_secondary_keyring(const char *source, const void *data, size_t len);
> >  #else
> >  #define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted
> >  #define restrict_link_by_digsig_builtin_and_secondary restrict_link_by_digsig_builtin
> > +static inline void __init add_to_secondary_keyring(const char *source, const void *data, size_t len)
> > +{
> > +}
> >  #endif
> >  
> >  #ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
> > diff --git a/security/integrity/platform_certs/keyring_handler.c b/security/integrity/platform_certs/keyring_handler.c
> > index 586027b9a3f5..13ea17207902 100644
> > --- a/security/integrity/platform_certs/keyring_handler.c
> > +++ b/security/integrity/platform_certs/keyring_handler.c
> > @@ -78,6 +78,14 @@ __init efi_element_handler_t get_handler_for_ca_keys(const efi_guid_t *sig_type)
> >  	return NULL;
> >  }
> >  
> > +__init efi_element_handler_t get_handler_for_code_signing_keys(const efi_guid_t *sig_type)
> > +{
> > +	if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0)
> > +		return add_to_secondary_keyring;
> > +
> > +	return NULL;
> > +}
> > +
> >  /*
> >   * Return the appropriate handler for particular signature list types found in
> >   * the UEFI dbx and MokListXRT tables.
> > diff --git a/security/integrity/platform_certs/keyring_handler.h b/security/integrity/platform_certs/keyring_handler.h
> > index 6f15bb4cc8dc..f92895cc50f6 100644
> > --- a/security/integrity/platform_certs/keyring_handler.h
> > +++ b/security/integrity/platform_certs/keyring_handler.h
> > @@ -34,6 +34,11 @@ efi_element_handler_t get_handler_for_mok(const efi_guid_t *sig_type);
> >   */
> >  efi_element_handler_t get_handler_for_ca_keys(const efi_guid_t *sig_type);
> >  
> > +/*
> > + * Return the handler for particular signature list types for code signing keys.
> > + */
> > +efi_element_handler_t get_handler_for_code_signing_keys(const efi_guid_t *sig_type);
> > +
> >  /*
> >   * Return the handler for particular signature list types found in the dbx.
> >   */
> > diff --git a/security/integrity/platform_certs/load_powerpc.c b/security/integrity/platform_certs/load_powerpc.c
> > index 339053d9726d..c85febca3343 100644
> > --- a/security/integrity/platform_certs/load_powerpc.c
> > +++ b/security/integrity/platform_certs/load_powerpc.c
> > @@ -60,6 +60,7 @@ static int __init load_powerpc_certs(void)
> >  {
> >  	void *db = NULL, *dbx = NULL, *data = NULL;
> >  	void *trustedca;
> > +	void *moduledb;
> >  	u64 dsize = 0;
> >  	u64 offset = 0;
> >  	int rc = 0;
> > @@ -137,6 +138,22 @@ static int __init load_powerpc_certs(void)
> >  		kfree(data);
> >  	}
> >  
> > +	data = get_cert_list("moduledb", 9,  &dsize);
> > +	if (!data) {
> > +		pr_info("Couldn't get moduledb list from firmware\n");
> > +	} else if (IS_ERR(data)) {
> > +		rc = PTR_ERR(data);
> > +		pr_err("Error reading moduledb from firmware: %d\n", rc);
> > +	} else {
> > +		extract_esl(moduledb, data, dsize, offset);
> > +
> > +		rc = parse_efi_signature_list("powerpc:moduledb", moduledb, dsize,
> > +					      get_handler_for_code_signing_keys);
> > +		if (rc)
> > +			pr_err("Couldn't parse moduledb signatures: %d\n", rc);
> > +		kfree(data);
> > +	}
> > +
> >  	return rc;
> >  }
> >  late_initcall(load_powerpc_certs);
> > -- 
> > 2.31.1
> 
> Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
> 
> I can pick this. My last PR did not went too great partly because of
> mess with tpm_tis but now things are calmer.

Glad things have settled down.  Whatever you prefer is fine.   This
patch set needs to make it into linux-next as soon as possible.  Please
don't forget to add Nageswara's "Tested-by" and fix mine on 4/6.
Jarkko Sakkinen Aug. 16, 2023, 9:11 p.m. UTC | #5
On Thu Aug 17, 2023 at 12:06 AM EEST, Mimi Zohar wrote:
> On Wed, 2023-08-16 at 23:36 +0300, Jarkko Sakkinen wrote:
> > On Tue Aug 15, 2023 at 2:27 PM EEST, Nayna Jain wrote:
> > > On secure boot enabled PowerVM LPAR, third party code signing keys are
> > > needed during early boot to verify signed third party modules. These
> > > third party keys are stored in moduledb object in the Platform
> > > KeyStore (PKS).
> > >
> > > Load third party code signing keys onto .secondary_trusted_keys keyring.
> > >
> > > Signed-off-by: Nayna Jain <nayna@linux.ibm.com>
> > > ---
> > >  certs/system_keyring.c                        | 30 +++++++++++++++++++
> > >  include/keys/system_keyring.h                 |  4 +++
> > >  .../platform_certs/keyring_handler.c          |  8 +++++
> > >  .../platform_certs/keyring_handler.h          |  5 ++++
> > >  .../integrity/platform_certs/load_powerpc.c   | 17 +++++++++++
> > >  5 files changed, 64 insertions(+)
> > >
> > > diff --git a/certs/system_keyring.c b/certs/system_keyring.c
> > > index b348e0898d34..33841c91f12c 100644
> > > --- a/certs/system_keyring.c
> > > +++ b/certs/system_keyring.c
> > > @@ -152,6 +152,36 @@ static __init struct key_restriction *get_builtin_and_secondary_restriction(void
> > >  
> > >  	return restriction;
> > >  }
> > > +
> > > +/**
> > > + * add_to_secondary_keyring - Add to secondary keyring.
> > > + * @source: Source of key
> > > + * @data: The blob holding the key
> > > + * @len: The length of the data blob
> > > + *
> > > + * Add a key to the secondary keyring. The key must be vouched for by a key in the builtin,
> > > + * machine or secondary keyring itself.
> > > + */
> > > +void __init add_to_secondary_keyring(const char *source, const void *data, size_t len)
> > > +{
> > > +	key_ref_t key;
> > > +	key_perm_t perm;
> > > +
> > > +	perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW;
> > > +
> > > +	key = key_create_or_update(make_key_ref(secondary_trusted_keys, 1),
> > > +				   "asymmetric",
> > > +				   NULL, data, len, perm,
> > > +				   KEY_ALLOC_NOT_IN_QUOTA);
> > > +	if (IS_ERR(key)) {
> > > +		pr_err("Problem loading X.509 certificate from %s to secondary keyring %ld\n",
> > > +		       source, PTR_ERR(key));
> > > +		return;
> > > +	}
> > > +
> > > +	pr_notice("Loaded X.509 cert '%s'\n", key_ref_to_ptr(key)->description);
> > > +	key_ref_put(key);
> > > +}
> > >  #endif
> > >  #ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
> > >  void __init set_machine_trusted_keys(struct key *keyring)
> > > diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
> > > index 7e2583208820..8365adf842ef 100644
> > > --- a/include/keys/system_keyring.h
> > > +++ b/include/keys/system_keyring.h
> > > @@ -50,9 +50,13 @@ int restrict_link_by_digsig_builtin_and_secondary(struct key *keyring,
> > >  						  const struct key_type *type,
> > >  						  const union key_payload *payload,
> > >  						  struct key *restriction_key);
> > > +void __init add_to_secondary_keyring(const char *source, const void *data, size_t len);
> > >  #else
> > >  #define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted
> > >  #define restrict_link_by_digsig_builtin_and_secondary restrict_link_by_digsig_builtin
> > > +static inline void __init add_to_secondary_keyring(const char *source, const void *data, size_t len)
> > > +{
> > > +}
> > >  #endif
> > >  
> > >  #ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
> > > diff --git a/security/integrity/platform_certs/keyring_handler.c b/security/integrity/platform_certs/keyring_handler.c
> > > index 586027b9a3f5..13ea17207902 100644
> > > --- a/security/integrity/platform_certs/keyring_handler.c
> > > +++ b/security/integrity/platform_certs/keyring_handler.c
> > > @@ -78,6 +78,14 @@ __init efi_element_handler_t get_handler_for_ca_keys(const efi_guid_t *sig_type)
> > >  	return NULL;
> > >  }
> > >  
> > > +__init efi_element_handler_t get_handler_for_code_signing_keys(const efi_guid_t *sig_type)
> > > +{
> > > +	if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0)
> > > +		return add_to_secondary_keyring;
> > > +
> > > +	return NULL;
> > > +}
> > > +
> > >  /*
> > >   * Return the appropriate handler for particular signature list types found in
> > >   * the UEFI dbx and MokListXRT tables.
> > > diff --git a/security/integrity/platform_certs/keyring_handler.h b/security/integrity/platform_certs/keyring_handler.h
> > > index 6f15bb4cc8dc..f92895cc50f6 100644
> > > --- a/security/integrity/platform_certs/keyring_handler.h
> > > +++ b/security/integrity/platform_certs/keyring_handler.h
> > > @@ -34,6 +34,11 @@ efi_element_handler_t get_handler_for_mok(const efi_guid_t *sig_type);
> > >   */
> > >  efi_element_handler_t get_handler_for_ca_keys(const efi_guid_t *sig_type);
> > >  
> > > +/*
> > > + * Return the handler for particular signature list types for code signing keys.
> > > + */
> > > +efi_element_handler_t get_handler_for_code_signing_keys(const efi_guid_t *sig_type);
> > > +
> > >  /*
> > >   * Return the handler for particular signature list types found in the dbx.
> > >   */
> > > diff --git a/security/integrity/platform_certs/load_powerpc.c b/security/integrity/platform_certs/load_powerpc.c
> > > index 339053d9726d..c85febca3343 100644
> > > --- a/security/integrity/platform_certs/load_powerpc.c
> > > +++ b/security/integrity/platform_certs/load_powerpc.c
> > > @@ -60,6 +60,7 @@ static int __init load_powerpc_certs(void)
> > >  {
> > >  	void *db = NULL, *dbx = NULL, *data = NULL;
> > >  	void *trustedca;
> > > +	void *moduledb;
> > >  	u64 dsize = 0;
> > >  	u64 offset = 0;
> > >  	int rc = 0;
> > > @@ -137,6 +138,22 @@ static int __init load_powerpc_certs(void)
> > >  		kfree(data);
> > >  	}
> > >  
> > > +	data = get_cert_list("moduledb", 9,  &dsize);
> > > +	if (!data) {
> > > +		pr_info("Couldn't get moduledb list from firmware\n");
> > > +	} else if (IS_ERR(data)) {
> > > +		rc = PTR_ERR(data);
> > > +		pr_err("Error reading moduledb from firmware: %d\n", rc);
> > > +	} else {
> > > +		extract_esl(moduledb, data, dsize, offset);
> > > +
> > > +		rc = parse_efi_signature_list("powerpc:moduledb", moduledb, dsize,
> > > +					      get_handler_for_code_signing_keys);
> > > +		if (rc)
> > > +			pr_err("Couldn't parse moduledb signatures: %d\n", rc);
> > > +		kfree(data);
> > > +	}
> > > +
> > >  	return rc;
> > >  }
> > >  late_initcall(load_powerpc_certs);
> > > -- 
> > > 2.31.1
> > 
> > Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
> > 
> > I can pick this. My last PR did not went too great partly because of
> > mess with tpm_tis but now things are calmer.
>
> Glad things have settled down.  Whatever you prefer is fine.   This
> patch set needs to make it into linux-next as soon as possible.  Please
> don't forget to add Nageswara's "Tested-by" and fix mine on 4/6.
>
> -- 
> thanks,
>
> Mimi

I'll apply the full (v4) patch set tomorrow after I wake up.

BR, Jarkko
diff mbox series

Patch

diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index b348e0898d34..33841c91f12c 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -152,6 +152,36 @@  static __init struct key_restriction *get_builtin_and_secondary_restriction(void
 
 	return restriction;
 }
+
+/**
+ * add_to_secondary_keyring - Add to secondary keyring.
+ * @source: Source of key
+ * @data: The blob holding the key
+ * @len: The length of the data blob
+ *
+ * Add a key to the secondary keyring. The key must be vouched for by a key in the builtin,
+ * machine or secondary keyring itself.
+ */
+void __init add_to_secondary_keyring(const char *source, const void *data, size_t len)
+{
+	key_ref_t key;
+	key_perm_t perm;
+
+	perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW;
+
+	key = key_create_or_update(make_key_ref(secondary_trusted_keys, 1),
+				   "asymmetric",
+				   NULL, data, len, perm,
+				   KEY_ALLOC_NOT_IN_QUOTA);
+	if (IS_ERR(key)) {
+		pr_err("Problem loading X.509 certificate from %s to secondary keyring %ld\n",
+		       source, PTR_ERR(key));
+		return;
+	}
+
+	pr_notice("Loaded X.509 cert '%s'\n", key_ref_to_ptr(key)->description);
+	key_ref_put(key);
+}
 #endif
 #ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
 void __init set_machine_trusted_keys(struct key *keyring)
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
index 7e2583208820..8365adf842ef 100644
--- a/include/keys/system_keyring.h
+++ b/include/keys/system_keyring.h
@@ -50,9 +50,13 @@  int restrict_link_by_digsig_builtin_and_secondary(struct key *keyring,
 						  const struct key_type *type,
 						  const union key_payload *payload,
 						  struct key *restriction_key);
+void __init add_to_secondary_keyring(const char *source, const void *data, size_t len);
 #else
 #define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted
 #define restrict_link_by_digsig_builtin_and_secondary restrict_link_by_digsig_builtin
+static inline void __init add_to_secondary_keyring(const char *source, const void *data, size_t len)
+{
+}
 #endif
 
 #ifdef CONFIG_INTEGRITY_MACHINE_KEYRING
diff --git a/security/integrity/platform_certs/keyring_handler.c b/security/integrity/platform_certs/keyring_handler.c
index 586027b9a3f5..13ea17207902 100644
--- a/security/integrity/platform_certs/keyring_handler.c
+++ b/security/integrity/platform_certs/keyring_handler.c
@@ -78,6 +78,14 @@  __init efi_element_handler_t get_handler_for_ca_keys(const efi_guid_t *sig_type)
 	return NULL;
 }
 
+__init efi_element_handler_t get_handler_for_code_signing_keys(const efi_guid_t *sig_type)
+{
+	if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0)
+		return add_to_secondary_keyring;
+
+	return NULL;
+}
+
 /*
  * Return the appropriate handler for particular signature list types found in
  * the UEFI dbx and MokListXRT tables.
diff --git a/security/integrity/platform_certs/keyring_handler.h b/security/integrity/platform_certs/keyring_handler.h
index 6f15bb4cc8dc..f92895cc50f6 100644
--- a/security/integrity/platform_certs/keyring_handler.h
+++ b/security/integrity/platform_certs/keyring_handler.h
@@ -34,6 +34,11 @@  efi_element_handler_t get_handler_for_mok(const efi_guid_t *sig_type);
  */
 efi_element_handler_t get_handler_for_ca_keys(const efi_guid_t *sig_type);
 
+/*
+ * Return the handler for particular signature list types for code signing keys.
+ */
+efi_element_handler_t get_handler_for_code_signing_keys(const efi_guid_t *sig_type);
+
 /*
  * Return the handler for particular signature list types found in the dbx.
  */
diff --git a/security/integrity/platform_certs/load_powerpc.c b/security/integrity/platform_certs/load_powerpc.c
index 339053d9726d..c85febca3343 100644
--- a/security/integrity/platform_certs/load_powerpc.c
+++ b/security/integrity/platform_certs/load_powerpc.c
@@ -60,6 +60,7 @@  static int __init load_powerpc_certs(void)
 {
 	void *db = NULL, *dbx = NULL, *data = NULL;
 	void *trustedca;
+	void *moduledb;
 	u64 dsize = 0;
 	u64 offset = 0;
 	int rc = 0;
@@ -137,6 +138,22 @@  static int __init load_powerpc_certs(void)
 		kfree(data);
 	}
 
+	data = get_cert_list("moduledb", 9,  &dsize);
+	if (!data) {
+		pr_info("Couldn't get moduledb list from firmware\n");
+	} else if (IS_ERR(data)) {
+		rc = PTR_ERR(data);
+		pr_err("Error reading moduledb from firmware: %d\n", rc);
+	} else {
+		extract_esl(moduledb, data, dsize, offset);
+
+		rc = parse_efi_signature_list("powerpc:moduledb", moduledb, dsize,
+					      get_handler_for_code_signing_keys);
+		if (rc)
+			pr_err("Couldn't parse moduledb signatures: %d\n", rc);
+		kfree(data);
+	}
+
 	return rc;
 }
 late_initcall(load_powerpc_certs);