From: Srish Srinivasan <ssrish@linux.ibm.com>
To: 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,
rnsastry@linux.ibm.com, ssrish@linux.ibm.com
Subject: [PATCH v2 08/10] pseries/plpks: add HCALLs for PKWM wrapping key life cycle management
Date: Mon, 31 Aug 2026 16:47:36 +0530 [thread overview]
Message-ID: <20260831111738.334857-9-ssrish@linux.ibm.com> (raw)
In-Reply-To: <20260831111738.334857-1-ssrish@linux.ibm.com>
The PKWM trusted source uses a single wrapping key per LPAR, created only
once during trust source initialization. All the wrap and unwrap requests
are bound to this default wrapping key.
Implement H_PKS_REVOKE_OBJECT, H_PKS_UNREVOKE_OBJECT, and
H_PKS_GET_OBJECTLABELS HCALLs to enable support for revoking and unrevoking
PKWM wrapping keys, and for retrieving wrapping key labels. The label
retrieval operation (H_PKS_GET_OBJECTLABELS) applies to all wrapping keys
including the default one, while the life cycle operations
(H_PKS_REVOKE_OBJECT/H_PKS_UNREVOKE_OBJECT) apply only to user-created
wrapping keys.
Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
---
Documentation/arch/powerpc/papr_hcalls.rst | 33 ++
arch/powerpc/include/asm/hvcall.h | 5 +-
arch/powerpc/include/asm/plpks.h | 15 +
arch/powerpc/platforms/pseries/plpks.c | 487 ++++++++++++++++++++-
4 files changed, 536 insertions(+), 4 deletions(-)
diff --git a/Documentation/arch/powerpc/papr_hcalls.rst b/Documentation/arch/powerpc/papr_hcalls.rst
index 44c9c8b32ae3..3455b403a048 100644
--- a/Documentation/arch/powerpc/papr_hcalls.rst
+++ b/Documentation/arch/powerpc/papr_hcalls.rst
@@ -343,6 +343,39 @@ is returned to the caller.
H_PKS_UNWRAP_OBJECT is used to unwrap an object that was previously wrapped with
H_PKS_WRAP_OBJECT.
+**H_PKS_REVOKE_OBJECT**
+
+| Input: authorization, objectlabel, objectlabellen, flags
+| Out: *object policy*
+| Return Value: *H_Success, H_Function, H_State, H_Parameter, H_P2, H_P3, H_P4,
+ H_Authority, H_Not_Found, H_Busy, H_Aborted*
+
+H_PKS_REVOKE_OBJECT is used to revoke an object in Platform Keystore.
+
+
+**H_PKS_UNREVOKE_OBJECT**
+
+| Input: authorization, objectlabel, objectlabellen, flags
+| Out: *object policy*
+| Return Value: *H_Success, H_Function, H_State, H_Parameter, H_P2, H_P3, H_P4,
+ H_Authority, H_Not_Found, H_Busy, H_Aborted*
+
+H_PKS_UNREVOKE_OBJECT is used to unrevoke an object that was previously revoked
+with H_PKS_REVOKE_OBJECT in Platform Keystore.
+
+
+**H_PKS_GET_OBJECTLABELS**
+
+| Input: authorization, continueToken, out, outlen
+| Out: *continue-token, number of object labels in the returned list, object
+ label list*
+| Return Value: *H_Success, H_Function, H_State, H_Parameter, H_P2, H_P3, H_P4,
+ H_Authority, H_Busy, H_Aborted, H_Continue*
+
+H_PKS_GET_OBJECTLABELS is used to retrieve a list of object labels owned by the
+specified consumer.
+
+
References
==========
.. [1] "Power Architecture Platform Reference"
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index dff90a7d7f70..4d4c2ce1dd87 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -340,6 +340,7 @@
#define H_PKS_GET_CONFIG 0x41C
#define H_PKS_SET_PASSWORD 0x420
#define H_PKS_GEN_PASSWORD 0x424
+#define H_PKS_GET_OBJECTLABELS 0x428
#define H_PKS_WRITE_OBJECT 0x42C
#define H_PKS_GEN_KEY 0x430
#define H_PKS_READ_OBJECT 0x434
@@ -362,7 +363,9 @@
#define H_GUEST_DELETE 0x488
#define H_PKS_WRAP_OBJECT 0x490
#define H_PKS_UNWRAP_OBJECT 0x494
-#define MAX_HCALL_OPCODE H_PKS_UNWRAP_OBJECT
+#define H_PKS_REVOKE_OBJECT 0x4AC
+#define H_PKS_UNREVOKE_OBJECT 0x4B0
+#define MAX_HCALL_OPCODE H_PKS_UNREVOKE_OBJECT
/* Scope args for H_SCM_UNBIND_ALL */
#define H_UNBIND_SCOPE_ALL (0x1)
diff --git a/arch/powerpc/include/asm/plpks.h b/arch/powerpc/include/asm/plpks.h
index 8b2ffb27db5a..c39d1f07017e 100644
--- a/arch/powerpc/include/asm/plpks.h
+++ b/arch/powerpc/include/asm/plpks.h
@@ -25,6 +25,7 @@
#define PLPKS_SIGNEDUPDATE PPC_BIT32(7) // Object can only be modified by signed updates
#define PLPKS_WRAPPINGKEY PPC_BIT32(8) // Object contains a wrapping key
#define PLPKS_HVPROVISIONED PPC_BIT32(28) // Hypervisor has provisioned this object
+#define PLPKS_REVOKED PPC_BIT32(30) // Object is revoked
// Signature algorithm flags from signed_update_algorithms
#define PLPKS_ALG_RSA2048 PPC_BIT(0)
@@ -123,6 +124,20 @@ int plpks_wrap_object(u8 **input_buf, u64 input_len, u16 wrap_flags,
int plpks_unwrap_object(u8 **input_buf, u64 input_len,
u8 **output_buf, u64 *output_len);
+
+int plpks_revoke_wrapping_key(struct plpks_var *var);
+
+int plpks_unrevoke_wrapping_key(struct plpks_var *var);
+
+int plpks_del_wrapping_key(struct plpks_var *var);
+
+int plpks_is_wrapping_key_revoked(struct plpks_var *var);
+
+int plpks_get_object_labels(u8 **output_buf, u64 *output_len,
+ char *comp_prefix);
+
+bool plpks_revoke_is_supported(void);
+
#else // CONFIG_PSERIES_PLPKS
static inline bool plpks_is_available(void) { return false; }
static inline u16 plpks_get_passwordlen(void) { BUILD_BUG(); }
diff --git a/arch/powerpc/platforms/pseries/plpks.c b/arch/powerpc/platforms/pseries/plpks.c
index d582c786ccad..3b1e6f00b4ae 100644
--- a/arch/powerpc/platforms/pseries/plpks.c
+++ b/arch/powerpc/platforms/pseries/plpks.c
@@ -23,8 +23,17 @@
*/
#define PLPKS_WRAPPING_BUF_DIFF 1024
+/*
+ * Maximum length for the buffer to store the retrieved object labels
+ */
+#define PLPKS_OBJLABEL_BUF_MAX 2550
+
+#define PLPKS_OBJLABEL_LEN_FIELD_SIZE 2
+#define PLPKS_OBJLABEL_PREFIX_LEN 8
+
#define PLPKS_WRAP_INTERFACE_BIT 3
#define PLPKS_WRAPPING_KEY_LENGTH 32
+#define PLPKS_REVOKE_INTERFACE_BIT 4
#define WRAPFLAG_BE_BIT_SET(be_bit) \
BIT_ULL(63 - (be_bit))
@@ -46,6 +55,7 @@
#include <linux/libfdt.h>
#include <linux/memblock.h>
#include <linux/bitfield.h>
+#include <linux/unaligned.h>
#include <asm/hvcall.h>
#include <asm/machdep.h>
#include <asm/plpks.h>
@@ -67,6 +77,7 @@ static u32 maxlargeobjectsize;
static u64 signedupdatealgorithms;
static u64 wrappingfeatures;
static bool wrapsupport;
+static bool revokesupport;
struct plpks_auth {
u8 version;
@@ -146,6 +157,9 @@ static int pseries_status_to_err(int rc)
case H_ABORTED:
err = -EIO;
break;
+ case H_CONTINUE:
+ err = -EAGAIN;
+ break;
default:
err = -EINVAL;
}
@@ -312,6 +326,7 @@ static int _plpks_get_config(void)
signedupdatealgorithms = be64_to_cpu(config->signedupdatealgorithms);
wrappingfeatures = be64_to_cpu(config->wrappingfeatures);
wrapsupport = config->flags & PPC_BIT8(PLPKS_WRAP_INTERFACE_BIT);
+ revokesupport = config->flags & PPC_BIT8(PLPKS_REVOKE_INTERFACE_BIT);
// Validate that the numbers we get back match the requirements of the spec
if (maxpwsize < 32) {
@@ -831,9 +846,6 @@ static int plpks_read_var(u8 consumer, struct plpks_var *var)
if (var->namelen > PLPKS_MAX_NAME_SIZE)
return -EINVAL;
- if (var->policy & PLPKS_WRAPPINGKEY)
- return -EPERM;
-
auth = construct_auth(consumer);
if (IS_ERR(auth))
return PTR_ERR(auth);
@@ -903,6 +915,23 @@ bool plpks_wrapping_is_supported(void)
}
EXPORT_SYMBOL_GPL(plpks_wrapping_is_supported);
+/**
+ * plpks_revoke_is_supported() - Get the H_PKS_REVOKE_OBJECT and
+ * H_PKS_UNREVOKE_OBJECT interfaces availability status for the LPAR.
+ *
+ * Successful execution of the H_PKS_GET_CONFIG HCALL during initialization
+ * sets bit 4 of the flags variable in the PLPKS config structure if the
+ * H_PKS_REVOKE_OBJECT and H_PKS_UNREVOKE_OBJECT interfaces are supported.
+ *
+ * Returns: true if the H_PKS_REVOKE_OBJECT and H_PKS_UNREVOKE_OBJECT interfaces
+ * are supported, false if not.
+ */
+bool plpks_revoke_is_supported(void)
+{
+ return revokesupport;
+}
+EXPORT_SYMBOL_GPL(plpks_revoke_is_supported);
+
/**
* plpks_gen_wrapping_key() - Generate a new random key with the 'wrapping key'
* policy set.
@@ -1189,6 +1218,458 @@ int plpks_unwrap_object(u8 **input_buf, u64 input_len, u8 **output_buf,
}
EXPORT_SYMBOL_GPL(plpks_unwrap_object);
+/**
+ * plpks_revoke_wrapping_key() - Revoke a wrapping key stored in the PLPKS.
+ * @var: variable representing the wrapping key to be revoked
+ *
+ * The H_PKS_REVOKE_OBJECT HCALL revokes an object stored in the PLPKS.
+ *
+ * Possible reasons for the returned errno values:
+ *
+ * -ENXIO if PLPKS is not supported
+ * -EIO if PLPKS access is blocked due to the LPAR's state
+ * if PLPKS modification is blocked due to the LPAR's state
+ * if an error occurred while processing the request
+ * -EINVAL if invalid authorization parameter
+ * if invalid wrapping key label parameter
+ * if invalid wrapping key label length parameter
+ * if invalid or unsupported wrapping key revoking flags
+ * -EPERM if access is denied
+ * -ENOENT if the requested wrapping key was not found
+ * -EBUSY if unable to handle the request or long running operation
+ * initiated, retry later.
+ *
+ * Returns: On success 0 is returned, a negative errno if not.
+ */
+int plpks_revoke_wrapping_key(struct plpks_var *var)
+{
+ unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };
+ struct plpks_auth *auth = NULL;
+ struct label *label;
+ u64 objrevokeflags = 0;
+ int rc = 0, pseries_status = 0;
+
+ if (!var)
+ return -EINVAL;
+
+ if (!var->name || !*var->name) {
+ pr_err("key label cannot be NULL/empty\n");
+ rc = -EINVAL;
+ goto out;
+ }
+
+ if (!strcmp((char *)var->name, PLPKS_DEFAULT_WRAPKEY_LABEL)) {
+ pr_warn("the default wrapping key must not be revoked!\n");
+ rc = -EPERM;
+ goto out;
+ }
+
+ auth = construct_auth(PLPKS_OS_OWNER);
+ if (IS_ERR(auth)) {
+ rc = PTR_ERR(auth);
+ goto out;
+ }
+
+ label = construct_label(var->component, var->os, var->name,
+ var->namelen);
+ if (IS_ERR(label)) {
+ rc = PTR_ERR(label);
+ goto out;
+ }
+
+ rc = plpar_hcall(H_PKS_REVOKE_OBJECT, retbuf, virt_to_phys(auth),
+ virt_to_phys(label), label->size, objrevokeflags);
+
+ pseries_status = rc;
+ rc = pseries_status_to_err(rc);
+
+ if (rc) {
+ pr_err("H_PKS_REVOKE_OBJECT failed. pseries_status=%d, rc=%d\n",
+ pseries_status, rc);
+ }
+
+ if (!rc || (rc == -EPERM && retbuf[0]))
+ var->policy = (u32)retbuf[0];
+
+ kfree(label);
+out:
+ kfree(auth);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(plpks_revoke_wrapping_key);
+
+/**
+ * plpks_unrevoke_wrapping_key() - Unrevoke a revoked wrapping key in the PLPKS.
+ * @var: variable representing the revoked wrapping key to be unrevoked
+ *
+ * The H_PKS_UNREVOKE_OBJECT HCALL unrevokes a revoked object stored in the
+ * PLPKS.
+ *
+ * Possible reasons for the returned errno values:
+ *
+ * -ENXIO if PLPKS is not supported
+ * -EIO if PLPKS access is blocked due to the LPAR's state
+ * if PLPKS modification is blocked due to the LPAR's state
+ * if an error occurred while processing the request
+ * -EINVAL if invalid authorization parameter
+ * if invalid object label parameter
+ * if invalid object label length parameter
+ * if invalid or unsupported object revoking flags
+ * -EPERM if access is denied
+ * -ENOENT if the requested object was not found
+ * -EBUSY if unable to handle the request or long running operation
+ * initiated, retry later.
+ *
+ * Returns: On success 0 is returned, a negative errno if not.
+ */
+int plpks_unrevoke_wrapping_key(struct plpks_var *var)
+{
+ unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };
+ struct plpks_auth *auth = NULL;
+ struct label *label;
+ u64 objrevokeflags = 0;
+ int rc = 0, pseries_status = 0;
+
+ if (!var)
+ return -EINVAL;
+
+ if (!var->name || !*var->name) {
+ pr_err("key label cannot be NULL/empty\n");
+ rc = -EINVAL;
+ goto out;
+ }
+
+ if (!strcmp((char *)var->name, PLPKS_DEFAULT_WRAPKEY_LABEL)) {
+ pr_warn("unrevoke on the default wrapping key is invalid\n");
+ rc = -EINVAL;
+ goto out;
+ }
+
+ auth = construct_auth(PLPKS_OS_OWNER);
+ if (IS_ERR(auth)) {
+ rc = PTR_ERR(auth);
+ goto out;
+ }
+
+ label = construct_label(var->component, var->os, var->name,
+ var->namelen);
+ if (IS_ERR(label)) {
+ rc = PTR_ERR(label);
+ goto out;
+ }
+
+ rc = plpar_hcall(H_PKS_UNREVOKE_OBJECT, retbuf,
+ virt_to_phys(auth), virt_to_phys(label),
+ label->size, objrevokeflags);
+
+ pseries_status = rc;
+ rc = pseries_status_to_err(rc);
+
+ if (rc)
+ pr_err("H_PKS_UNREVOKE_OBJECT failed. pseries_status=%d, rc=%d\n",
+ pseries_status, rc);
+
+ if (!rc || (rc == -EPERM && retbuf[0]))
+ var->policy = (u32)retbuf[0];
+
+ kfree(label);
+out:
+ kfree(auth);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(plpks_unrevoke_wrapping_key);
+
+/**
+ * plpks_is_wrapping_key_revoked() - Check if a given wrapping key has been
+ * revoked.
+ * @var: variable representing the wrapping key to be checked
+ *
+ * When the H_PKS_READ_OBJECT HCALL tries reads an object that exists but when
+ * the policy is not met, it returns H_AUTHORITY along with the 4-byte object
+ * policy. This policy is inspected to determine if the object has been revoked.
+ *
+ * Possible reasons for the returned errno values:
+ *
+ * -ENXIO if PLPKS is not supported
+ * -EIO if PLPKS access is blocked due to the LPAR's state
+ * if an error occurred while processing the request
+ * -EINVAL if invalid authorization parameter
+ * if invalid object label parameter
+ * if invalid object label len parameter
+ * if invalid output data parameter
+ * if invalid output data len parameter
+ * -EPERM if access is denied
+ * -ENOENT if the requested object was not found
+ * -EFBIG if the requested object couldn't be
+ * stored in the buffer provided
+ * -EBUSY if unable to handle the request
+ *
+ * Returns: 1 is returned if the wrapping key has been revoked. 0 is returned if
+ * the wrapping key has not been revoked. Otherwise, a negative errno
+ * is returned.
+ */
+int plpks_is_wrapping_key_revoked(struct plpks_var *var)
+{
+ int rc;
+
+ if (!var)
+ return -EINVAL;
+
+ if (!var->name || !*var->name) {
+ pr_err("key label cannot be NULL/empty\n");
+ rc = -EINVAL;
+ goto out;
+ }
+
+ rc = plpks_read_var(PLPKS_OS_OWNER, var);
+ if (!rc) {
+ pr_err("unexpected successful read of wrapping key\n");
+ rc = -EIO;
+ } else if (rc == -EPERM) {
+ if (var->policy & PLPKS_WRAPPINGKEY) {
+ if (var->policy & PLPKS_REVOKED)
+ rc = 1;
+ else
+ rc = 0;
+ }
+ }
+
+out:
+ return rc;
+}
+EXPORT_SYMBOL_GPL(plpks_is_wrapping_key_revoked);
+
+/**
+ * plpks_del_wrapping_key() - Delete a wrapping key from the PLPKS.
+ * @var: variable representing the revoked wrapping key to be deleted
+ *
+ * The plpks_remove_var function removes the specified variable and its data
+ * from the PLPKS by invoking the H_PKS_REMOVE_OBJECT HCALL.
+ *
+ * Possible reasons for the returned errno values:
+ *
+ * -ENXIO if PLPKS is not supported
+ * -EIO if PLPKS access is blocked due to the LPAR's state
+ * if PLPKS modification is blocked due to the LPAR's state
+ * if an error occurred while processing the request
+ * -EINVAL if invalid authorization parameter
+ * if invalid object label parameter
+ * if invalid object label len parameter
+ * -EPERM if access is denied
+ * -ENOENT if the requested object was not found
+ * -EBUSY if unable to handle the request
+ *
+ * Returns: On success 0 is returned, a negative errno if not.
+ */
+int plpks_del_wrapping_key(struct plpks_var *var)
+{
+ int rc;
+ struct plpks_var_name vname;
+
+ if (!var)
+ return -EINVAL;
+
+ if (!var->name || !*var->name) {
+ pr_err("key label cannot be NULL/empty\n");
+ rc = -EINVAL;
+ goto out;
+ }
+
+ if (!strcmp((char *)var->name, PLPKS_DEFAULT_WRAPKEY_LABEL)) {
+ pr_warn("the default wrapping key must not be deleted!\n");
+ rc = -EPERM;
+ goto out;
+ }
+
+ rc = plpks_is_wrapping_key_revoked(var);
+ if (rc == 1) {
+ vname = (struct plpks_var_name) {
+ .name = var->name,
+ .namelen = var->namelen
+ };
+
+ rc = plpks_remove_var(PLPKS_WRAPKEY_COMPONENT, var->os,
+ vname);
+ if (rc)
+ pr_err("deletion of <%s> failed. rc=%d\n",
+ (char *)var->name, rc);
+ goto out;
+ } else if (!rc) {
+ pr_err("revoke <%s> before deletion\n", (char *)var->name);
+ rc = -EPERM;
+ goto out;
+ } else {
+ pr_err("revocation status check failed for <%s>. rc = %d\n",
+ (char *)var->name, rc);
+ }
+
+out:
+ return rc;
+}
+EXPORT_SYMBOL_GPL(plpks_del_wrapping_key);
+
+/**
+ * plpks_get_object_labels() - retrieve a list of object labels for the objects
+ * stored in the PLPKS
+ * @output_buf: buffer to store the retrieved object labels
+ * @output_len: number of object labels retrieved
+ * @comp_prefix: component prefix string
+ *
+ * The H_PKS_GET_OBJECTLABELS HCALL retrieves a list of object labels for the
+ * objects with the given component prefix stored in the PLPKS.
+ *
+ * Possible reasons for the returned errno values:
+ *
+ * -ENXIO if PLPKS is not supported
+ * -EIO if PLPKS access is blocked due to the LPAR's state
+ * if PLPKS modification is blocked due to the LPAR's state
+ * if an error occurred while processing the request
+ * -EINVAL if invalid authorization parameter
+ * if invalid output buffer parameter
+ * if invalid output buffer length parameter
+ * if invalid continue token parameter
+ * if the provided component prefix is NULL
+ * -EPERM if access is denied
+ * -EBUSY if unable to handle the request or long running operation
+ * initiated, retry later.
+ *
+ * Returns: On success 0 is returned, a negative errno if not.
+ */
+int plpks_get_object_labels(u8 **output_buf, u64 *output_len,
+ char *comp_prefix)
+{
+ unsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };
+ u8 *labels_buf = NULL;
+ u8 *tmp_buf = NULL;
+ struct plpks_auth *auth = NULL;
+ struct label_attr *metadata = NULL;
+ u16 label_len;
+ u64 labels_count;
+ u64 continuetoken = 0, output_buf_len = 0;
+ int rc = 0, pseries_status = 0;
+ size_t labels_buf_offset = 0, output_buf_offset = 0;
+ size_t obj_label_entry_size, i;
+
+ *output_buf = NULL;
+ *output_len = 0;
+
+ if (!comp_prefix) {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ auth = construct_auth(PLPKS_OS_OWNER);
+ if (IS_ERR(auth)) {
+ rc = PTR_ERR(auth);
+ goto out;
+ }
+
+ do {
+ labels_buf =
+ kzalloc(roundup_pow_of_two(PLPKS_OBJLABEL_BUF_MAX),
+ GFP_KERNEL);
+
+ if (!labels_buf) {
+ pr_err("labels_buf buffer allocation failed\n");
+ rc = -ENOMEM;
+ goto out_free_output_buf;
+ }
+
+ rc = plpar_hcall(H_PKS_GET_OBJECTLABELS, retbuf,
+ virt_to_phys(auth), continuetoken,
+ virt_to_phys(labels_buf),
+ roundup_pow_of_two(PLPKS_OBJLABEL_BUF_MAX));
+
+ pseries_status = rc;
+ rc = pseries_status_to_err(rc);
+
+ if (rc && rc != -EAGAIN) {
+ pr_err("H_PKS_GET_OBJECTLABELS failed. pseries_status=%d rc=%d\n",
+ pseries_status, rc);
+ goto out_free_labels_buf;
+ } else {
+ /*
+ * Setting an incorrect countinuetoken upon
+ * receiving H_CONTINUE would result in H_P2. Since
+ * the continuetoken is being set to the expected
+ * value from the previous call, H_P2 must not be
+ * returned.
+ */
+ continuetoken = retbuf[1];
+
+ labels_count = retbuf[0];
+ if (!labels_count) {
+ kfree(labels_buf);
+ labels_buf = NULL;
+ goto out;
+ }
+
+ /*
+ * Filter out object labels that don't have the provided
+ * component prefix.
+ */
+
+ output_buf_len +=
+ roundup_pow_of_two(PLPKS_OBJLABEL_BUF_MAX);
+
+ tmp_buf = krealloc(*output_buf, output_buf_len,
+ GFP_KERNEL);
+
+ if (!tmp_buf) {
+ pr_err("output buffer re-allocation failed\n");
+ rc = -ENOMEM;
+ goto out_free_labels_buf;
+ }
+
+ *output_buf = tmp_buf;
+
+ for (i = 0; i < labels_count; ++i) {
+ label_len =
+ get_unaligned_be16(labels_buf +
+ labels_buf_offset);
+
+ obj_label_entry_size =
+ PLPKS_OBJLABEL_LEN_FIELD_SIZE +
+ label_len;
+
+ metadata =
+ (struct label_attr *)(labels_buf +
+ labels_buf_offset +
+ PLPKS_OBJLABEL_LEN_FIELD_SIZE);
+
+ if (!memcmp(metadata->prefix, comp_prefix,
+ PLPKS_OBJLABEL_PREFIX_LEN)) {
+ memcpy(*output_buf + output_buf_offset,
+ labels_buf + labels_buf_offset,
+ obj_label_entry_size);
+
+ output_buf_offset +=
+ obj_label_entry_size;
+ (*output_len) += 1;
+ }
+ labels_buf_offset += obj_label_entry_size;
+ }
+ kfree(labels_buf);
+ labels_buf = NULL;
+ labels_buf_offset = 0;
+ }
+ } while (rc == -EAGAIN);
+
+ goto out;
+
+out_free_labels_buf:
+ kfree(labels_buf);
+ labels_buf = NULL;
+out_free_output_buf:
+ kfree(*output_buf);
+ *output_buf = NULL;
+ *output_len = 0;
+out:
+ kfree(auth);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(plpks_get_object_labels);
+
/**
* plpks_read_os_var() - Fetch the data for the specified variable that is owned
* by the OS consumer.
--
2.52.0
next prev parent reply other threads:[~2026-08-31 11: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 ` Srish Srinivasan [this message]
2026-09-04 6:16 ` [PATCH v2 08/10] pseries/plpks: add HCALLs for PKWM wrapping key life cycle management 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
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=20260831111738.334857-9-ssrish@linux.ibm.com \
--to=ssrish@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=rnsastry@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.