Linux Security Modules development
 help / color / mirror / Atom feed
From: R Nageswara Sastry <rnsastry@linux.ibm.com>
To: Srish Srinivasan <ssrish@linux.ibm.com>,
	linux-integrity@vger.kernel.org, keyrings@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org
Cc: maddy@linux.ibm.com, mpe@ellerman.id.au, npiggin@gmail.com,
	christophe.leroy@csgroup.eu,
	James.Bottomley@HansenPartnership.com, jarkko@kernel.org,
	zohar@linux.ibm.com, linux-kernel@vger.kernel.org,
	linux-security-module@vger.kernel.org, nayna@linux.ibm.com
Subject: Re: [PATCH v2 09/10] keys/trusted_keys: enable PKWM wrapping key selection by label
Date: Fri, 4 Sep 2026 11:47:33 +0530	[thread overview]
Message-ID: <805f4e2c-f48e-4ace-ad16-18fd99aa4270@linux.ibm.com> (raw)
In-Reply-To: <20260831111738.334857-10-ssrish@linux.ibm.com>


On 31.08.2026 4:47 PM, Srish Srinivasan wrote:
> The PKWM trusted source currently uses the default wrapping key for all
> seal and unseal operations. However, PKWM supports multiple wrapping keys,
> enabling better isolation between trusted keys.
>
> Allow users to provide an active wrapping key of their choice created
> through sysfs when sealing trusted keys through a new wrapping_key=<label>
> option. If no label is specified, the default wrapping key is used for
> sealing.
>
> Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
Tested-by: R Nageswara Sastry <rnsastry@linux.ibm.com>

Tested on ppc64le PowerVM LPARs on firmware with wrap/unwrap support,
with and without Secure Boot enabled.

Verified that:
   - Trusted key creation without specifying wrapping_key= continues to work
     (default wrapping key used).
   - Trusted key creation with wrapping_key=<label> works correctly.
   - A label longer than 239 characters is rejected.
   - wrap_flags=0x01 and wrap_flags=0x02 behave as expected with the
     wrapping_key= option under each Secure Boot mode.
> ---
>   .../security/keys/trusted-encrypted.rst       |  4 +-
>   arch/powerpc/include/asm/plpks.h              | 10 ++-
>   arch/powerpc/platforms/pseries/plpks.c        | 64 ++++++++++---------
>   include/keys/trusted_pkwm.h                   |  3 +
>   security/keys/trusted-keys/trusted_pkwm.c     | 34 +++++++++-
>   5 files changed, 80 insertions(+), 35 deletions(-)
>
> diff --git a/Documentation/security/keys/trusted-encrypted.rst b/Documentation/security/keys/trusted-encrypted.rst
> index ddff7c7c2582..76fda28fddb1 100644
> --- a/Documentation/security/keys/trusted-encrypted.rst
> +++ b/Documentation/security/keys/trusted-encrypted.rst
> @@ -83,7 +83,7 @@ safe.
>   
>        (5) PKWM (PowerVM Key Wrapping Module: IBM PowerVM + Platform KeyStore)
>   
> -         Rooted to a unique, per-LPAR key, which is derived from a system-wide,
> +         Rooted to unique, per-LPAR keys, which are derived from a system-wide,
>            randomly generated LPAR root key. Both the per-LPAR keys and the LPAR
>            root key are stored in hypervisor-owned secure memory at runtime,
>            and the LPAR root key is additionally persisted in secure locations
> @@ -366,6 +366,8 @@ Usage::
>                          0x01: require secure boot to be in either audit or
>                                enforced mode
>                          0x02: require secure boot to be in enforced mode
> +       wrapping_key= optional wrapping key label as a string. The default
> +                     wrapping key is used when no label is provided.
>   
>   "keyctl print" returns an ASCII hex copy of the sealed key, which is in format
>   specific to PKWM key-blob implementation.  The key length for new keys is
> diff --git a/arch/powerpc/include/asm/plpks.h b/arch/powerpc/include/asm/plpks.h
> index c39d1f07017e..badb07afe749 100644
> --- a/arch/powerpc/include/asm/plpks.h
> +++ b/arch/powerpc/include/asm/plpks.h
> @@ -50,6 +50,12 @@
>   #define PLPKS_MAX_TIMEOUT		(5 * USEC_PER_SEC)
>   #define PLPKS_FLUSH_SLEEP		10000 // usec
>   
> +// Label for the PKWM default wrapping key
> +#define PLPKS_DEFAULT_WRAPKEY_LABEL	"default-wrapping-key"
> +
> +// Component for a PKWM wrapping key
> +#define PLPKS_WRAPKEY_COMPONENT	"PLPKSWR"
> +
>   struct plpks_var {
>   	char *component;
>   	u8 *name;
> @@ -117,10 +123,10 @@ int plpks_config_create_softlink(struct kobject *from);
>   
>   bool plpks_wrapping_is_supported(void);
>   
> -int plpks_gen_wrapping_key(void);
> +int plpks_gen_wrapping_key(struct plpks_var *var);
>   
>   int plpks_wrap_object(u8 **input_buf, u64 input_len, u16 wrap_flags,
> -		      u8 **output_buf, u64 *output_len);
> +		      u8 **output_buf, u64 *output_len, struct plpks_var *var);
>   
>   int plpks_unwrap_object(u8 **input_buf, u64 input_len,
>   			u8 **output_buf, u64 *output_len);
> diff --git a/arch/powerpc/platforms/pseries/plpks.c b/arch/powerpc/platforms/pseries/plpks.c
> index 3b1e6f00b4ae..5cdaabe9de06 100644
> --- a/arch/powerpc/platforms/pseries/plpks.c
> +++ b/arch/powerpc/platforms/pseries/plpks.c
> @@ -9,9 +9,6 @@
>   
>   #define pr_fmt(fmt) "plpks: " fmt
>   
> -#define PLPKS_WRAPKEY_COMPONENT	"PLPKSWR"
> -#define PLPKS_DEFAULT_WRAPKEY_LABEL	"default-wrapping-key"
> -
>   /*
>    * To 4K align the {input, output} buffers to the {UN}WRAP H_CALLs
>    */
> @@ -935,6 +932,7 @@ EXPORT_SYMBOL_GPL(plpks_revoke_is_supported);
>   /**
>    * plpks_gen_wrapping_key() - Generate a new random key with the 'wrapping key'
>    * policy set.
> + * @var: variable representing the wrapping key to be created
>    *
>    * The H_PKS_GEN_KEY HCALL makes the hypervisor generate a new random key and
>    * store the key in a PLPKS object with the provided object label. With the
> @@ -960,25 +958,27 @@ EXPORT_SYMBOL_GPL(plpks_revoke_is_supported);
>    *
>    * Returns: On success 0 is returned, a negative errno if not.
>    */
> -int plpks_gen_wrapping_key(void)
> +int plpks_gen_wrapping_key(struct plpks_var *var)
>   {
>   	unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };
>   	struct plpks_auth *auth;
>   	struct label *label;
>   	int rc = 0, pseries_status = 0;
> -	struct plpks_var var = {
> -		.name = PLPKS_DEFAULT_WRAPKEY_LABEL,
> -		.namelen = sizeof(PLPKS_DEFAULT_WRAPKEY_LABEL) - 1,
> -		.policy = PLPKS_WRAPPINGKEY,
> -		.os = PLPKS_VAR_LINUX,
> -		.component = PLPKS_WRAPKEY_COMPONENT
> -	};
> +
> +	if (!var)
> +		return -EINVAL;
> +
> +	if (!var->name || !*var->name) {
> +		pr_err("key label cannot be NULL/empty\n");
> +		return -EINVAL;
> +	}
>   
>   	auth = construct_auth(PLPKS_OS_OWNER);
>   	if (IS_ERR(auth))
>   		return PTR_ERR(auth);
>   
> -	label = construct_label(var.component, var.os, var.name, var.namelen);
> +	label = construct_label(var->component, var->os, var->name,
> +				var->namelen);
>   	if (IS_ERR(label)) {
>   		rc = PTR_ERR(label);
>   		goto out;
> @@ -986,7 +986,7 @@ int plpks_gen_wrapping_key(void)
>   
>   	rc = plpar_hcall(H_PKS_GEN_KEY, retbuf,
>   			 virt_to_phys(auth), virt_to_phys(label),
> -			 label->size, var.policy,
> +			 label->size, var->policy,
>   			 NULL, PLPKS_WRAPPING_KEY_LENGTH);
>   
>   	if (!rc)
> @@ -995,11 +995,13 @@ int plpks_gen_wrapping_key(void)
>   	pseries_status = rc;
>   	rc = pseries_status_to_err(rc);
>   
> -	if (rc && rc != -EEXIST) {
> -		pr_err("H_PKS_GEN_KEY failed. pseries_status=%d, rc=%d",
> -		       pseries_status, rc);
> -	} else {
> -		rc = 0;
> +	if (rc) {
> +		if (rc == -EEXIST)
> +			pr_info("wrapping key <%s> already exists\n",
> +				(char *)var->name);
> +		else
> +			pr_err("H_PKS_GEN_KEY failed. pseries_status=%d, rc=%d\n",
> +			       pseries_status, rc);
>   	}
>   
>   	kfree(label);
> @@ -1010,13 +1012,14 @@ int plpks_gen_wrapping_key(void)
>   EXPORT_SYMBOL_GPL(plpks_gen_wrapping_key);
>   
>   /**
> - * plpks_wrap_object() - Wrap an object using the default wrapping key stored in
> - * the PLPKS.
> + * plpks_wrap_object() - Wrap an object using the specified wrapping key stored
> + * in the PLPKS.
>    * @input_buf: buffer containing the data to be wrapped
>    * @input_len: length of the input buffer
>    * @wrap_flags: object wrapping flags
>    * @output_buf: buffer to store the wrapped data
>    * @output_len: length of the output buffer
> + * @var: variable representing the wrapping key to be used
>    *
>    * The H_PKS_WRAP_OBJECT HCALL wraps an object using a wrapping key stored in
>    * the PLPKS and returns the wrapped object to the caller. The caller provides a
> @@ -1051,7 +1054,7 @@ EXPORT_SYMBOL_GPL(plpks_gen_wrapping_key);
>    * Returns: On success 0 is returned, a negative errno if not.
>    */
>   int plpks_wrap_object(u8 **input_buf, u64 input_len, u16 wrap_flags,
> -		      u8 **output_buf, u64 *output_len)
> +		      u8 **output_buf, u64 *output_len, struct plpks_var *var)
>   {
>   	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = { 0 };
>   	struct plpks_auth *auth;
> @@ -1061,18 +1064,21 @@ int plpks_wrap_object(u8 **input_buf, u64 input_len, u16 wrap_flags,
>   	int rc = 0, pseries_status = 0;
>   	bool sb_audit_or_enforce_bit = wrap_flags & BIT(0);
>   	bool sb_enforce_bit = wrap_flags & BIT(1);
> -	struct plpks_var var = {
> -		.name = PLPKS_DEFAULT_WRAPKEY_LABEL,
> -		.namelen = sizeof(PLPKS_DEFAULT_WRAPKEY_LABEL) - 1,
> -		.os = PLPKS_VAR_LINUX,
> -		.component = PLPKS_WRAPKEY_COMPONENT
> -	};
> +
> +	if (!var)
> +		return -EINVAL;
> +
> +	if (!var->name || !*var->name) {
> +		pr_err("key label cannot be NULL/empty\n");
> +		return -EINVAL;
> +	}
>   
>   	auth = construct_auth(PLPKS_OS_OWNER);
>   	if (IS_ERR(auth))
>   		return PTR_ERR(auth);
>   
> -	label = construct_label(var.component, var.os, var.name, var.namelen);
> +	label = construct_label(var->component, var->os, var->name,
> +				var->namelen);
>   	if (IS_ERR(label)) {
>   		rc = PTR_ERR(label);
>   		goto out;
> @@ -1135,7 +1141,7 @@ int plpks_wrap_object(u8 **input_buf, u64 input_len, u16 wrap_flags,
>   EXPORT_SYMBOL_GPL(plpks_wrap_object);
>   
>   /**
> - * plpks_unwrap_object() - Unwrap an object using the default wrapping key
> + * plpks_unwrap_object() - Unwrap an object using its associated wrapping key
>    * stored in the PLPKS.
>    * @input_buf: buffer containing the data to be unwrapped
>    * @input_len: length of the input buffer
> diff --git a/include/keys/trusted_pkwm.h b/include/keys/trusted_pkwm.h
> index 4035b9776394..53a5f780edd2 100644
> --- a/include/keys/trusted_pkwm.h
> +++ b/include/keys/trusted_pkwm.h
> @@ -6,10 +6,13 @@
>   #include <linux/bitops.h>
>   #include <linux/printk.h>
>   
> +#define WRAPPING_KEY_LABEL_LEN_MAX	239
> +
>   extern struct trusted_key_ops pkwm_trusted_key_ops;
>   
>   struct trusted_pkwm_options {
>   	u16 wrap_flags;
> +	unsigned char wrapping_key_label[WRAPPING_KEY_LABEL_LEN_MAX + 1];
>   };
>   
>   static inline void dump_options(struct trusted_key_options *o)
> diff --git a/security/keys/trusted-keys/trusted_pkwm.c b/security/keys/trusted-keys/trusted_pkwm.c
> index 633a7674d065..7bfe98d79cd7 100644
> --- a/security/keys/trusted-keys/trusted_pkwm.c
> +++ b/security/keys/trusted-keys/trusted_pkwm.c
> @@ -13,10 +13,12 @@
>   enum {
>   	Opt_err,
>   	Opt_wrap_flags,
> +	Opt_wrapping_key_label,
>   };
>   
>   static const match_table_t key_tokens = {
>   	{Opt_wrap_flags, "wrap_flags=%s"},
> +	{Opt_wrapping_key_label, "wrapping_key=%s"},
>   	{Opt_err, NULL}
>   };
>   
> @@ -50,6 +52,12 @@ static int getoptions(char *datablob, struct trusted_key_options *opt)
>   				return -EINVAL;
>   			pkwm->wrap_flags = wrap_flags;
>   			break;
> +		case Opt_wrapping_key_label:
> +			if (strlen(args[0].from) > WRAPPING_KEY_LABEL_LEN_MAX)
> +				return -EINVAL;
> +			strscpy(pkwm->wrapping_key_label, args[0].from,
> +				sizeof(pkwm->wrapping_key_label));
> +			break;
>   		default:
>   			return -EINVAL;
>   		}
> @@ -82,6 +90,7 @@ static int trusted_pkwm_seal(struct trusted_key_payload *p, char *datablob)
>   {
>   	struct trusted_key_options *options = NULL;
>   	struct trusted_pkwm_options *pkwm = NULL;
> +	struct plpks_var var;
>   	u8 *input_buf, *output_buf;
>   	u64 output_len, input_len;
>   	int rc;
> @@ -108,8 +117,18 @@ static int trusted_pkwm_seal(struct trusted_key_payload *p, char *datablob)
>   
>   	pkwm = options->private;
>   
> +	if (pkwm->wrapping_key_label[0]) {
> +		var.name = (u8 *)pkwm->wrapping_key_label;
> +		var.namelen = strlen(pkwm->wrapping_key_label);
> +	} else {
> +		var.name = (u8 *)PLPKS_DEFAULT_WRAPKEY_LABEL;
> +		var.namelen = strlen(PLPKS_DEFAULT_WRAPKEY_LABEL);
> +	}
> +	var.os = PLPKS_VAR_LINUX;
> +	var.component = PLPKS_WRAPKEY_COMPONENT;
> +
>   	rc = plpks_wrap_object(&input_buf, input_len, pkwm->wrap_flags,
> -			       &output_buf, &output_len);
> +			       &output_buf, &output_len, &var);
>   	if (!rc) {
>   		memcpy(p->blob, output_buf, output_len);
>   		p->blob_len = output_len;
> @@ -161,14 +180,23 @@ static int trusted_pkwm_unseal(struct trusted_key_payload *p, char *datablob)
>   static int trusted_pkwm_init(void)
>   {
>   	int ret;
> +	struct plpks_var var;
>   
>   	if (!plpks_wrapping_is_supported()) {
>   		pr_err("H_PKS_WRAP_OBJECT interface not supported\n");
>   		return -ENODEV;
>   	}
>   
> -	ret = plpks_gen_wrapping_key();
> -	if (ret) {
> +	var = (struct plpks_var) {
> +		.name = (u8 *)PLPKS_DEFAULT_WRAPKEY_LABEL,
> +		.namelen = sizeof(PLPKS_DEFAULT_WRAPKEY_LABEL) - 1,
> +		.policy = PLPKS_WRAPPINGKEY,
> +		.os = PLPKS_VAR_LINUX,
> +		.component = PLPKS_WRAPKEY_COMPONENT
> +	};
> +
> +	ret = plpks_gen_wrapping_key(&var);
> +	if (ret && ret != -EEXIST) {
>   		pr_err("Failed to generate default wrapping key\n");
>   		return ret;
>   	}

-- 
Thanks and Regards
R.Nageswara Sastry


  reply	other threads:[~2026-09-04  6:18 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-31 11:17 [PATCH v2 00/10] Extend PKWM to support user-created wrapping keys Srish Srinivasan
2026-08-31 11:17 ` [PATCH v2 01/10] pseries/plpks: update PKS documentation and maintainer entry Srish Srinivasan
2026-09-04  6:10   ` R Nageswara Sastry
2026-08-31 11:17 ` [PATCH v2 02/10] pseries/plpks: fix error handling in plpks_read_var() Srish Srinivasan
2026-09-04  6:10   ` R Nageswara Sastry
2026-08-31 11:17 ` [PATCH v2 03/10] pseries/plpks: improve type consistency and parameter validation Srish Srinivasan
2026-09-04  6:11   ` R Nageswara Sastry
2026-08-31 11:17 ` [PATCH v2 04/10] keys/trusted_keys: propagate wrapping key generation errors Srish Srinivasan
2026-09-04  6:12   ` R Nageswara Sastry
2026-08-31 11:17 ` [PATCH v2 05/10] pseries/plpks: rename the default wrapping key macro Srish Srinivasan
2026-09-04  6:13   ` R Nageswara Sastry
2026-08-31 11:17 ` [PATCH v2 06/10] pseries/plpks: fix self-reference in plpks_var initializer Srish Srinivasan
2026-09-04  6:14   ` R Nageswara Sastry
2026-08-31 11:17 ` [PATCH v2 07/10] pseries/plpks: hide wrapping_features when unsupported Srish Srinivasan
2026-09-04  6:16   ` R Nageswara Sastry
2026-08-31 11:17 ` [PATCH v2 08/10] pseries/plpks: add HCALLs for PKWM wrapping key life cycle management Srish Srinivasan
2026-09-04  6:16   ` R Nageswara Sastry
2026-08-31 11:17 ` [PATCH v2 09/10] keys/trusted_keys: enable PKWM wrapping key selection by label Srish Srinivasan
2026-09-04  6:17   ` R Nageswara Sastry [this message]
2026-08-31 11:17 ` [PATCH v2 10/10] pseries/plpks/wrapkey: expose PKWM wrapping key management to userspace via sysfs Srish Srinivasan
2026-09-04  6:19   ` R Nageswara Sastry

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=805f4e2c-f48e-4ace-ad16-18fd99aa4270@linux.ibm.com \
    --to=rnsastry@linux.ibm.com \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=christophe.leroy@csgroup.eu \
    --cc=jarkko@kernel.org \
    --cc=keyrings@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=maddy@linux.ibm.com \
    --cc=mpe@ellerman.id.au \
    --cc=nayna@linux.ibm.com \
    --cc=npiggin@gmail.com \
    --cc=ssrish@linux.ibm.com \
    --cc=zohar@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox