Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.0/patches/2175289/?format=api
{ "id": 2175289, "url": "http://patchwork.ozlabs.org/api/1.0/patches/2175289/?format=api", "project": { "id": 2, "url": "http://patchwork.ozlabs.org/api/1.0/projects/2/?format=api", "name": "Linux PPC development", "link_name": "linuxppc-dev", "list_id": "linuxppc-dev.lists.ozlabs.org", "list_email": "linuxppc-dev@lists.ozlabs.org", "web_url": "https://github.com/linuxppc/wiki/wiki", "scm_url": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git", "webscm_url": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/" }, "msgid": "<20251217172505.112398-5-ssrish@linux.ibm.com>", "date": "2025-12-17T17:25:03", "name": "[v2,4/6] pseries/plpks: add HCALLs for PowerVM Key Wrapping Module", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "c607ca7e13ed1e9cbcfd64a7aab92af27fecfc42", "submitter": { "id": 90762, "url": "http://patchwork.ozlabs.org/api/1.0/people/90762/?format=api", "name": "Srish Srinivasan", "email": "ssrish@linux.ibm.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linuxppc-dev/patch/20251217172505.112398-5-ssrish@linux.ibm.com/mbox/", "series": [ { "id": 485734, "url": "http://patchwork.ozlabs.org/api/1.0/series/485734/?format=api", "date": "2025-12-17T17:24:59", "name": "Extend \"trusted\" keys to support a new trust source named the PowerVM Key Wrapping Module (PKWM)", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/485734/mbox/" } ], "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2175289/checks/", "tags": {}, "headers": { "Return-Path": "\n <linuxppc-dev+bounces-14848-incoming=patchwork.ozlabs.org@lists.ozlabs.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "linuxppc-dev@lists.ozlabs.org" ], "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256\n header.s=pp1 header.b=Ylb0Qh8v;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org\n (client-ip=2404:9400:21b9:f100::1; helo=lists.ozlabs.org;\n envelope-from=linuxppc-dev+bounces-14848-incoming=patchwork.ozlabs.org@lists.ozlabs.org;\n receiver=patchwork.ozlabs.org)", "lists.ozlabs.org;\n arc=none smtp.remote-ip=148.163.156.1", "lists.ozlabs.org;\n dmarc=pass (p=none dis=none) header.from=linux.ibm.com", "lists.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256\n header.s=pp1 header.b=Ylb0Qh8v;\n\tdkim-atps=neutral", "lists.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=linux.ibm.com\n (client-ip=148.163.156.1; helo=mx0a-001b2d01.pphosted.com;\n envelope-from=ssrish@linux.ibm.com; receiver=lists.ozlabs.org)" ], "Received": [ "from lists.ozlabs.org (lists.ozlabs.org\n [IPv6:2404:9400:21b9:f100::1])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4dWggW57Szz1y0P\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 18 Dec 2025 04:25:59 +1100 (AEDT)", "from boromir.ozlabs.org (localhost [127.0.0.1])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 4dWggB1Svkz30VM;\n\tThu, 18 Dec 2025 04:25:42 +1100 (AEDT)", "from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com\n [148.163.156.1])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 4dWgg92gNJz30TL\n\tfor <linuxppc-dev@lists.ozlabs.org>; Thu, 18 Dec 2025 04:25:41 +1100 (AEDT)", "from pps.filterd (m0360083.ppops.net [127.0.0.1])\n\tby mx0a-001b2d01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id\n 5BH89Ik7012679;\n\tWed, 17 Dec 2025 17:25:29 GMT", "from pps.reinject (localhost [127.0.0.1])\n\tby mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4b0yn8pdsr-1\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);\n\tWed, 17 Dec 2025 17:25:29 +0000 (GMT)", "from m0360083.ppops.net (m0360083.ppops.net [127.0.0.1])\n\tby pps.reinject (8.18.1.12/8.18.0.8) with ESMTP id 5BHHPSnK012469;\n\tWed, 17 Dec 2025 17:25:28 GMT", "from ppma13.dal12v.mail.ibm.com\n (dd.9e.1632.ip4.static.sl-reverse.com [50.22.158.221])\n\tby mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4b0yn8pdsf-1\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);\n\tWed, 17 Dec 2025 17:25:28 +0000 (GMT)", "from pps.filterd (ppma13.dal12v.mail.ibm.com [127.0.0.1])\n\tby ppma13.dal12v.mail.ibm.com (8.18.1.2/8.18.1.2) with ESMTP id\n 5BHExUCI014337;\n\tWed, 17 Dec 2025 17:25:27 GMT", "from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228])\n\tby ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4b1mpk3aew-1\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT);\n\tWed, 17 Dec 2025 17:25:27 +0000", "from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com\n [10.20.54.100])\n\tby smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id\n 5BHHPNnP15466852\n\t(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK);\n\tWed, 17 Dec 2025 17:25:23 GMT", "from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1])\n\tby IMSVA (Postfix) with ESMTP id 63B0420043;\n\tWed, 17 Dec 2025 17:25:23 +0000 (GMT)", "from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1])\n\tby IMSVA (Postfix) with ESMTP id 5AF1E20040;\n\tWed, 17 Dec 2025 17:25:20 +0000 (GMT)", "from li-fc74f8cc-3279-11b2-a85c-ef5828687581.ibm.com.com (unknown\n [9.124.211.226])\n\tby smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP;\n\tWed, 17 Dec 2025 17:25:20 +0000 (GMT)" ], "ARC-Seal": "i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707; t=1765992342;\n\tcv=none;\n b=UcrY9e5KAGgCFVERkAudBZ8nNQvr9UbUR0Yy3NEhoiqfyFGU4i0Ml6l8b325JVlG91kFQ1PgOcddrVJJvsSxFayGhUjbn6epJ48sKdSmJ2Hb77UkIw1K8eF4x04O74p2SE6Lq/gTDcuAeAnSKb44W/5HBJZXLM030WM8nYGG/h9mw5AkI++TaSt/v1zKeaPdhU5dlWZzz3BruSzfNbYTo301I0+86rRweN9ah8j0hQrowU82LGrJsYI4DNbRq+bEdCivIFQdqKXHqs6j8VbcHnwqxBGmq7GtcJAx2VOkxmSE3IPxWKK1z+pmhQXcJuj6aKOELQhyQ2VvnDDrV3M9+A==", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707;\n\tt=1765992342; c=relaxed/relaxed;\n\tbh=nFPrYCraD//jynpErWr/f59XvOgzbV5kfqIFM5do+3c=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=REs8cffnP9vmxGmd13dvnJJnIqcowBZp0ywLwwtwniD5PcWkTgLKfdntO3J1iwWuLVM0GX2OBcs+b344ydsTcRT6A+DoI7RNlRYyf7aL1maFGle6cbJpDC8IG11ZjIrYqI3rvfkfjAXwia9fNgNGrcOiFhvpadU5bWD3DhxJGElnvuNQWK5pFozZs1SsJYTqXhUQmcmeTeodtTvPqShMHmCexIwp6TOkalBqPopC3eJF+8BJuSCjzrqEtU6iGcsEQG/jFtrQ26ExQZlwE/VXZqb99bU+ARJP5LAoOn7BJ3UTHfItTiAG1XwccXnRu62NiNk+Sz8+4eRsDCZxcWm2Tg==", "ARC-Authentication-Results": "i=1; lists.ozlabs.org;\n dmarc=pass (p=none dis=none) header.from=linux.ibm.com;\n dkim=pass (2048-bit key;\n unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256\n header.s=pp1 header.b=Ylb0Qh8v; dkim-atps=neutral;\n spf=pass (client-ip=148.163.156.1; helo=mx0a-001b2d01.pphosted.com;\n envelope-from=ssrish@linux.ibm.com;\n receiver=lists.ozlabs.org) smtp.mailfrom=linux.ibm.com", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc\n\t:content-transfer-encoding:date:from:in-reply-to:message-id\n\t:mime-version:references:subject:to; s=pp1; bh=nFPrYCraD//jynpEr\n\tWr/f59XvOgzbV5kfqIFM5do+3c=; b=Ylb0Qh8vVyGhYAO3yCheuuSIoHf5PvXwh\n\tD4a9k6o4R+Gda6DFKk7uskOgqJRMy7FpKUnywIGgcOGIbOpP/6u6AhLzUGftt4Si\n\tTxWLpumzZsdOmb8mnLiHouZnwSBxOxioV8i0V49noPJG05IWJEVRpfa8iZQmYT7T\n\tS1B2KHsbeVmdoEuTjrAy5Tyy+dea+xzxrvXqi1d52n4d5HBb6cHQFsgQbcuPrkgH\n\tbe1aSuZ4tRtw1r47TUe3FpldCDZ58Lm+GSCu9GI50/WEVwtNtGvIoj6wMTpg8J0P\n\teo1RTX1sc3N2AT5lboCMwchgKF/Y8I10yOmub+vEElD6wiUk8PK0A==", "From": "Srish Srinivasan <ssrish@linux.ibm.com>", "To": "linux-integrity@vger.kernel.org, keyrings@vger.kernel.org,\n linuxppc-dev@lists.ozlabs.org", "Cc": "maddy@linux.ibm.com, mpe@ellerman.id.au, npiggin@gmail.com,\n christophe.leroy@csgroup.eu, James.Bottomley@HansenPartnership.com,\n jarkko@kernel.org, zohar@linux.ibm.com, nayna@linux.ibm.com,\n rnsastry@linux.ibm.com, linux-kernel@vger.kernel.org,\n linux-security-module@vger.kernel.org, ssrish@linux.ibm.com", "Subject": "[PATCH v2 4/6] pseries/plpks: add HCALLs for PowerVM Key Wrapping\n Module", "Date": "Wed, 17 Dec 2025 22:55:03 +0530", "Message-ID": "<20251217172505.112398-5-ssrish@linux.ibm.com>", "X-Mailer": "git-send-email 2.52.0", "In-Reply-To": "<20251217172505.112398-1-ssrish@linux.ibm.com>", "References": "<20251217172505.112398-1-ssrish@linux.ibm.com>", "X-Mailing-List": "linuxppc-dev@lists.ozlabs.org", "List-Id": "<linuxppc-dev.lists.ozlabs.org>", "List-Help": "<mailto:linuxppc-dev+help@lists.ozlabs.org>", "List-Owner": "<mailto:linuxppc-dev+owner@lists.ozlabs.org>", "List-Post": "<mailto:linuxppc-dev@lists.ozlabs.org>", "List-Archive": "<https://lore.kernel.org/linuxppc-dev/>,\n <https://lists.ozlabs.org/pipermail/linuxppc-dev/>", "List-Subscribe": "<mailto:linuxppc-dev+subscribe@lists.ozlabs.org>,\n <mailto:linuxppc-dev+subscribe-digest@lists.ozlabs.org>,\n <mailto:linuxppc-dev+subscribe-nomail@lists.ozlabs.org>", "List-Unsubscribe": "<mailto:linuxppc-dev+unsubscribe@lists.ozlabs.org>", "Precedence": "list", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-TM-AS-GCONF": "00", "X-Proofpoint-Spam-Details-Enc": "AW1haW4tMjUxMjEzMDAxOCBTYWx0ZWRfX+bNMazSfdutm\n mttvqcitDpNPHkkDd8nyGD2sSflOo4xBvwOMEbxjb9+SMQC9Ka+6QGLnwOyVtUPvrYzIu1K3Q1d\n VZMIlqnl3zb+R9EQhoZDCEZC/ds4+8s/qo2nYZ0/v3tvXQtfWH5TSinX2N6XdHA+owyu7yrxNFO\n WZStytzAIanz2kk/naDQC4VDxNoJ07V/wHi5KKEp7cZVylmqqXud0veTcQyjTVfknYNb1d5abxs\n TKg1d9hPN51VplzTxRrjS4az7hff4QWSLTpTcIvsn1pK/EvKZF9f2VKe5mvjzf5MOe4ibOdCRdH\n c3pr9PNQrnLsotOTyezCQW0j271XV/MSdv9QGvIS0qwHO8qFq94HGpdgR/DxgOnzJQFreCGCccp\n jUTBmWCBtRULd4qQesyqXKl4g4N+fg==", "X-Proofpoint-GUID": "yHPmUlFxvPQI96BYcLOniGxumhEAqBqL", "X-Proofpoint-ORIG-GUID": "IVmEhqT1h2QN1A9kZGWp4vspQecipr1G", "X-Authority-Analysis": "v=2.4 cv=LbYxKzfi c=1 sm=1 tr=0 ts=6942e789 cx=c_pps\n a=AfN7/Ok6k8XGzOShvHwTGQ==:117 a=AfN7/Ok6k8XGzOShvHwTGQ==:17\n a=wP3pNCr1ah4A:10 a=VkNPw1HP01LnGYTKEx00:22 a=VnNF1IyMAAAA:8\n a=nO4dFLMeAchwtJrxA4IA:9 a=QtseMjuWhX2mhlOB:21", "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49\n definitions=2025-12-17_03,2025-12-16_05,2025-10-01_01", "X-Proofpoint-Spam-Details": "rule=outbound_notspam policy=outbound score=0\n bulkscore=0 spamscore=0 phishscore=0 clxscore=1015 suspectscore=0\n adultscore=0 malwarescore=0 priorityscore=1501 lowpriorityscore=0\n impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc=\n route=outbound adjust=0 reason=mlx scancount=1 engine=8.19.0-2510240000\n definitions=main-2512130018", "X-Spam-Status": "No, score=-0.7 required=3.0 tests=DKIM_SIGNED,DKIM_VALID,\n\tRCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,\n\tSPF_PASS autolearn=disabled version=4.0.1 OzLabs 8", "X-Spam-Checker-Version": "SpamAssassin 4.0.1 (2024-03-25) on lists.ozlabs.org" }, "content": "The hypervisor generated wrapping key is an AES-GCM-256 symmetric key which\nis stored in a non-volatile, secure, and encrypted storage called the Power\nLPAR Platform KeyStore. It has policy based protections that prevent it\nfrom being read out or exposed to the user.\n\nImplement H_PKS_GEN_KEY, H_PKS_WRAP_OBJECT, and H_PKS_UNWRAP_OBJECT HCALLs\nto enable using the PowerVM Key Wrapping Module (PKWM) as a new trust\nsource for trusted keys. Disallow H_PKS_READ_OBJECT, H_PKS_SIGNED_UPDATE,\nand H_PKS_WRITE_OBJECT for objects with the 'wrapping key' policy set.\nCapture the availability status for the H_PKS_WRAP_OBJECT interface.\n\nSigned-off-by: Srish Srinivasan <ssrish@linux.ibm.com>\n---\n Documentation/arch/powerpc/papr_hcalls.rst | 43 +++\n arch/powerpc/include/asm/plpks.h | 10 +\n arch/powerpc/platforms/pseries/plpks.c | 345 ++++++++++++++++++++-\n 3 files changed, 396 insertions(+), 2 deletions(-)", "diff": "diff --git a/Documentation/arch/powerpc/papr_hcalls.rst b/Documentation/arch/powerpc/papr_hcalls.rst\nindex 805e1cb9bab9..14e39f095a1c 100644\n--- a/Documentation/arch/powerpc/papr_hcalls.rst\n+++ b/Documentation/arch/powerpc/papr_hcalls.rst\n@@ -300,6 +300,49 @@ H_HTM supports setup, configuration, control and dumping of Hardware Trace\n Macro (HTM) function and its data. HTM buffer stores tracing data for functions\n like core instruction, core LLAT and nest.\n \n+**H_PKS_GEN_KEY**\n+\n+| Input: authorization, objectlabel, objectlabellen, policy, out, outlen\n+| Out: *Hypervisor Generated Key, or None when the wrapping key policy is set*\n+| Return Value: *H_SUCCESS, H_Function, H_State, H_R_State, H_Parameter, H_P2,\n+ H_P3, H_P4, H_P5, H_P6, H_Authority, H_Nomem, H_Busy, H_Resource,\n+ H_Aborted*\n+\n+H_PKS_GEN_KEY is used to have the hypervisor generate a new random key.\n+This key is stored as an object in the Power LPAR Platform KeyStore with\n+the provided object label. With the wrapping key policy set the key is only\n+visible to the hypervisor, while the key's label would still be visible to\n+the user. Generation of wrapping keys is supported only for a key size of\n+32 bytes.\n+\n+**H_PKS_WRAP_OBJECT**\n+\n+| Input: authorization, wrapkeylabel, wrapkeylabellen, objectwrapflags, in,\n+| inlen, out, outlen, continue-token\n+| Out: *continue-token, byte size of wrapped object, wrapped object*\n+| Return Value: *H_SUCCESS, H_Function, H_State, H_R_State, H_Parameter, H_P2,\n+ H_P3, H_P4, H_P5, H_P6, H_P7, H_P8, H_P9, H_Authority, H_Invalid_Key,\n+ H_NOT_FOUND, H_Busy, H_LongBusy, H_Aborted*\n+\n+H_PKS_WRAP_OBJECT is used to wrap an object using a wrapping key stored in the\n+Power LPAR Platform KeyStore and return the wrapped object to the caller. The\n+caller provides a label to a wrapping key with the 'wrapping key' policy set,\n+which must have been previously created with H_PKS_GEN_KEY. The provided object\n+is then encrypted with the wrapping key and additional metadata and the result\n+is returned to the caller.\n+\n+\n+**H_PKS_UNWRAP_OBJECT**\n+\n+| Input: authorization, objectwrapflags, in, inlen, out, outlen, continue-token\n+| Out: *continue-token, byte size of unwrapped object, unwrapped object*\n+| Return Value: *H_SUCCESS, H_Function, H_State, H_R_State, H_Parameter, H_P2,\n+ H_P3, H_P4, H_P5, H_P6, H_P7, H_Authority, H_Unsupported, H_Bad_Data,\n+ H_NOT_FOUND, H_Invalid_Key, H_Busy, H_LongBusy, H_Aborted*\n+\n+H_PKS_UNWRAP_OBJECT is used to unwrap an object that was previously warapped with\n+H_PKS_WRAP_OBJECT.\n+\n References\n ==========\n .. [1] \"Power Architecture Platform Reference\"\ndiff --git a/arch/powerpc/include/asm/plpks.h b/arch/powerpc/include/asm/plpks.h\nindex 8f034588fdf7..e87f90e40d4e 100644\n--- a/arch/powerpc/include/asm/plpks.h\n+++ b/arch/powerpc/include/asm/plpks.h\n@@ -113,6 +113,16 @@ void plpks_early_init_devtree(void);\n int plpks_populate_fdt(void *fdt);\n \n int plpks_config_create_softlink(struct kobject *from);\n+\n+bool plpks_wrapping_is_supported(void);\n+\n+int plpks_gen_wrapping_key(void);\n+\n+int plpks_wrap_object(u8 **input_buf, u32 input_len, u16 wrap_flags,\n+\t\t u8 **output_buf, u32 *output_len);\n+\n+int plpks_unwrap_object(u8 **input_buf, u32 input_len,\n+\t\t\tu8 **output_buf, u32 *output_len);\n #else // CONFIG_PSERIES_PLPKS\n static inline bool plpks_is_available(void) { return false; }\n static inline u16 plpks_get_passwordlen(void) { BUILD_BUG(); }\ndiff --git a/arch/powerpc/platforms/pseries/plpks.c b/arch/powerpc/platforms/pseries/plpks.c\nindex 4a08f51537c8..2ec04908b057 100644\n--- a/arch/powerpc/platforms/pseries/plpks.c\n+++ b/arch/powerpc/platforms/pseries/plpks.c\n@@ -9,6 +9,32 @@\n \n #define pr_fmt(fmt) \"plpks: \" fmt\n \n+#define PLPKS_WRAPKEY_COMPONENT\t\"PLPKSWR\"\n+#define PLPKS_WRAPKEY_NAME\t\"default-wrapping-key\"\n+\n+/*\n+ * To 4K align the {input, output} buffers to the {UN}WRAP H_CALLs\n+ */\n+#define PLPKS_WRAPPING_BUF_ALIGN\t4096\n+\n+/*\n+ * To ensure the output buffer's length is at least 1024 bytes greater\n+ * than the input buffer's length during the WRAP H_CALL\n+ */\n+#define PLPKS_WRAPPING_BUF_DIFF\t1024\n+\n+#define PLPKS_WRAP_INTERFACE_BIT\t3\n+#define PLPKS_WRAPPING_KEY_LENGTH\t32\n+\n+#define WRAPFLAG_BE_BIT_SET(be_bit) \\\n+\tBIT_ULL(63 - (be_bit))\n+\n+#define WRAPFLAG_BE_GENMASK(be_bit_hi, be_bit_lo) \\\n+\tGENMASK_ULL(63 - (be_bit_hi), 63 - (be_bit_lo))\n+\n+#define WRAPFLAG_BE_FIELD_PREP(be_bit_hi, be_bit_lo, val) \\\n+\tFIELD_PREP(WRAPFLAG_BE_GENMASK(be_bit_hi, be_bit_lo), (val))\n+\n #include <linux/delay.h>\n #include <linux/errno.h>\n #include <linux/io.h>\n@@ -39,6 +65,7 @@ static u32 supportedpolicies;\n static u32 maxlargeobjectsize;\n static u64 signedupdatealgorithms;\n static u64 wrappingfeatures;\n+static bool wrapsupport;\n \n struct plpks_auth {\n \tu8 version;\n@@ -283,6 +310,7 @@ static int _plpks_get_config(void)\n \tmaxlargeobjectsize = be32_to_cpu(config->maxlargeobjectsize);\n \tsignedupdatealgorithms = be64_to_cpu(config->signedupdatealgorithms);\n \twrappingfeatures = be64_to_cpu(config->wrappingfeatures);\n+\twrapsupport = config->flags & PPC_BIT8(PLPKS_WRAP_INTERFACE_BIT);\n \n \t// Validate that the numbers we get back match the requirements of the spec\n \tif (maxpwsize < 32) {\n@@ -614,6 +642,9 @@ int plpks_signed_update_var(struct plpks_var *var, u64 flags)\n \tif (!(var->policy & PLPKS_SIGNEDUPDATE))\n \t\treturn -EINVAL;\n \n+\tif (var->policy & PLPKS_WRAPPINGKEY)\n+\t\treturn -EINVAL;\n+\n \t// Signed updates need the component to be NULL.\n \tif (var->component)\n \t\treturn -EINVAL;\n@@ -696,6 +727,9 @@ int plpks_write_var(struct plpks_var var)\n \tif (var.policy & PLPKS_SIGNEDUPDATE)\n \t\treturn -EINVAL;\n \n+\tif (var.policy & PLPKS_WRAPPINGKEY)\n+\t\treturn -EINVAL;\n+\n \tauth = construct_auth(PLPKS_OS_OWNER);\n \tif (IS_ERR(auth))\n \t\treturn PTR_ERR(auth);\n@@ -790,6 +824,9 @@ static int plpks_read_var(u8 consumer, struct plpks_var *var)\n \tif (var->namelen > PLPKS_MAX_NAME_SIZE)\n \t\treturn -EINVAL;\n \n+\tif (var->policy & PLPKS_WRAPPINGKEY)\n+\t\treturn -EINVAL;\n+\n \tauth = construct_auth(consumer);\n \tif (IS_ERR(auth))\n \t\treturn PTR_ERR(auth);\n@@ -845,8 +882,312 @@ static int plpks_read_var(u8 consumer, struct plpks_var *var)\n }\n \n /**\n- * plpks_read_os_var() - Fetch the data for the specified variable that is\n- * owned by the OS consumer.\n+ * plpks_wrapping_is_supported() - Get the H_PKS_WRAP_OBJECT interface\n+ * availability status for the LPAR.\n+ *\n+ * Successful execution of the H_PKS_GET_CONFIG HCALL during initialization\n+ * sets bit 3 of the flags variable in the PLPKS config structure if the\n+ * H_PKS_WRAP_OBJECT interface is supported.\n+ *\n+ * Returns: true if the H_PKS_WRAP_OBJECT interface is supported, false if not.\n+ */\n+bool plpks_wrapping_is_supported(void)\n+{\n+\treturn wrapsupport;\n+}\n+\n+/**\n+ * plpks_gen_wrapping_key() - Generate a new random key with the 'wrapping key'\n+ * policy set.\n+ *\n+ * The H_PKS_GEN_KEY HCALL makes the hypervisor generate a new random key and\n+ * store the key in a PLPKS object with the provided object label. With the\n+ * 'wrapping key' policy set, only the label to the newly generated random key\n+ * would be visible to the user.\n+ *\n+ * Possible reasons for the returned errno values:\n+ *\n+ * -ENXIO\tif PLPKS is not supported\n+ * -EIO\t\tif PLPKS access is blocked due to the LPAR's state\n+ *\t\tif PLPKS modification is blocked due to the LPAR's state\n+ *\t\tif an error occurred while processing the request\n+ * -EINVAL\tif invalid authorization parameter\n+ *\t\tif invalid object label parameter\n+ *\t\tif invalid object label len parameter\n+ *\t\tif invalid or unsupported policy declaration\n+ *\t\tif invalid output buffer parameter\n+ *\t\tif invalid output buffer length parameter\n+ * -EPERM\tif access is denied\n+ * -ENOMEM\tif there is inadequate memory to perform this operation\n+ * -EBUSY\tif unable to handle the request\n+ * -EEXIST\tif the object label already exists\n+ *\n+ * Returns: On success 0 is returned, a negative errno if not.\n+ */\n+int plpks_gen_wrapping_key(void)\n+{\n+\tunsigned long retbuf[PLPAR_HCALL_BUFSIZE] = { 0 };\n+\tstruct plpks_auth *auth;\n+\tstruct label *label;\n+\tint rc = 0, pseries_status = 0;\n+\tstruct plpks_var var = {\n+\t\t.name = PLPKS_WRAPKEY_NAME,\n+\t\t.namelen = strlen(var.name),\n+\t\t.policy = PLPKS_WRAPPINGKEY,\n+\t\t.os = PLPKS_VAR_LINUX,\n+\t\t.component = PLPKS_WRAPKEY_COMPONENT\n+\t};\n+\n+\tauth = construct_auth(PLPKS_OS_OWNER);\n+\tif (IS_ERR(auth))\n+\t\treturn PTR_ERR(auth);\n+\n+\tlabel = construct_label(var.component, var.os, var.name, var.namelen);\n+\tif (IS_ERR(label)) {\n+\t\trc = PTR_ERR(label);\n+\t\tgoto out;\n+\t}\n+\n+\trc = plpar_hcall(H_PKS_GEN_KEY, retbuf,\n+\t\t\t virt_to_phys(auth), virt_to_phys(label),\n+\t\t\t label->size, var.policy,\n+\t\t\t NULL, PLPKS_WRAPPING_KEY_LENGTH);\n+\n+\tif (!rc)\n+\t\trc = plpks_confirm_object_flushed(label, auth);\n+\n+\tpseries_status = rc;\n+\trc = pseries_status_to_err(rc);\n+\n+\tif (rc && rc != -EEXIST) {\n+\t\tpr_err(\"H_PKS_GEN_KEY failed.\");\n+\t\tpr_err(\"pseries_status = %d, error code = %d\", pseries_status,\n+\t\t rc);\n+\t} else {\n+\t\trc = 0;\n+\t}\n+\n+\tkfree(label);\n+out:\n+\tkfree(auth);\n+\treturn rc;\n+}\n+EXPORT_SYMBOL_GPL(plpks_gen_wrapping_key);\n+\n+/**\n+ * plpks_wrap_object() - Wrap an object using the default wrapping key stored in\n+ * the PLPKS.\n+ * @input_buf: buffer containing the data to be wrapped\n+ * @input_len: length of the input buffer\n+ * @wrap_flags: object wrapping flags\n+ * @output_buf: buffer to store the wrapped data\n+ * @output_len: length of the output buffer\n+ *\n+ * The H_PKS_WRAP_OBJECT HCALL wraps an object using a wrapping key stored in\n+ * the PLPKS and returns the wrapped object to the caller. The caller provides a\n+ * label to the wrapping key with the 'wrapping key' policy set that must have\n+ * been previously created with the H_PKS_GEN_KEY HCALL. The provided object is\n+ * then encrypted with the wrapping key and additional metadata and the result\n+ * is returned to the user. The metadata includes the wrapping algorithm and the\n+ * wrapping key name so those parameters are not required during unwrap.\n+ *\n+ * Possible reasons for the returned errno values:\n+ *\n+ * -ENXIO\tif PLPKS is not supported\n+ * -EIO\t\tif PLPKS access is blocked due to the LPAR's state\n+ *\t\tif PLPKS modification is blocked due to the LPAR's state\n+ *\t\tif an error occurred while processing the request\n+ * -EINVAL\tif invalid authorization parameter\n+ *\t\tif invalid wraping key label parameter\n+ *\t\tif invalid wrapping key label length parameter\n+ *\t\tif invalid or unsupported object wrapping flags\n+ *\t\tif invalid inut buffer parameter\n+ *\t\tif invalid input buffer length parameter\n+ *\t\tif invalid output buffer parameter\n+ *\t\tif invalid output buffer length parameter\n+ *\t\tif invalid continue token parameter\n+ *\t\tif the wrapping key is not compatible with the wrapping\n+ *\t\talgorithm\n+ * -EPERM\tif access is denied\n+ * -ENOENT\tif the requested wrapping key was not found\n+ * -EBUSY\tif unable to handle the request or long running operation\n+ *\t\tinitiated, retry later.\n+ *\n+ * Returns: On success 0 is returned, a negative errno if not.\n+ */\n+int plpks_wrap_object(u8 **input_buf, u32 input_len, u16 wrap_flags,\n+\t\t u8 **output_buf, u32 *output_len)\n+{\n+\tunsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = { 0 };\n+\tstruct plpks_auth *auth;\n+\tstruct label *label;\n+\tu64 continuetoken = 0;\n+\tu64 objwrapflags = 0;\n+\tint rc = 0, pseries_status = 0;\n+\tbool sb_audit_or_enforce_bit = wrap_flags & BIT(0);\n+\tbool sb_enforce_bit = wrap_flags & BIT(1);\n+\tstruct plpks_var var = {\n+\t\t.name = PLPKS_WRAPKEY_NAME,\n+\t\t.namelen = strlen(var.name),\n+\t\t.os = PLPKS_VAR_LINUX,\n+\t\t.component = PLPKS_WRAPKEY_COMPONENT\n+\t};\n+\n+\tauth = construct_auth(PLPKS_OS_OWNER);\n+\tif (IS_ERR(auth))\n+\t\treturn PTR_ERR(auth);\n+\n+\tlabel = construct_label(var.component, var.os, var.name, var.namelen);\n+\tif (IS_ERR(label)) {\n+\t\trc = PTR_ERR(label);\n+\t\tgoto out;\n+\t}\n+\n+\t/* Set the consumer password requirement bit. A must have. */\n+\tobjwrapflags |= WRAPFLAG_BE_BIT_SET(3);\n+\n+\t/* Set the wrapping algorithm bit. Just one algorithm option for now */\n+\tobjwrapflags |= WRAPFLAG_BE_FIELD_PREP(60, 63, 0x1);\n+\n+\tif (sb_audit_or_enforce_bit & sb_enforce_bit) {\n+\t\tpr_err(\"Cannot set both audit/enforce and enforce bits.\");\n+\t\trc = -EINVAL;\n+\t\tgoto out_free_label;\n+\t} else if (sb_audit_or_enforce_bit) {\n+\t\tobjwrapflags |= WRAPFLAG_BE_BIT_SET(1);\n+\t} else if (sb_enforce_bit) {\n+\t\tobjwrapflags |= WRAPFLAG_BE_BIT_SET(2);\n+\t}\n+\n+\t*output_len = input_len + PLPKS_WRAPPING_BUF_DIFF;\n+\n+\t*output_buf = kzalloc(ALIGN(*output_len, PLPKS_WRAPPING_BUF_ALIGN),\n+\t\t\t GFP_KERNEL);\n+\tif (!(*output_buf)) {\n+\t\tpr_err(\"Output buffer allocation failed. Returning -ENOMEM.\");\n+\t\trc = -ENOMEM;\n+\t\tgoto out_free_label;\n+\t}\n+\n+\tdo {\n+\t\trc = plpar_hcall9(H_PKS_WRAP_OBJECT, retbuf,\n+\t\t\t\t virt_to_phys(auth), virt_to_phys(label),\n+\t\t\t\t label->size, objwrapflags,\n+\t\t\t\t virt_to_phys(*input_buf), input_len,\n+\t\t\t\t virt_to_phys(*output_buf), *output_len,\n+\t\t\t\t continuetoken);\n+\n+\t\tcontinuetoken = retbuf[0];\n+\t\tpseries_status = rc;\n+\t\trc = pseries_status_to_err(rc);\n+\t} while (rc == -EBUSY);\n+\n+\tif (rc) {\n+\t\tpr_err(\"H_PKS_WRAP_OBJECT failed.\");\n+\t\tpr_err(\"pseries_status = %d, return code = %d\", pseries_status,\n+\t\t rc);\n+\t\tkfree(*output_buf);\n+\t\t*output_buf = NULL;\n+\t} else {\n+\t\t*output_len = retbuf[1];\n+\t}\n+\n+out_free_label:\n+\tkfree(label);\n+out:\n+\tkfree(auth);\n+\treturn rc;\n+}\n+EXPORT_SYMBOL_GPL(plpks_wrap_object);\n+\n+/**\n+ * plpks_unwrap_object() - Unwrap an object using the default wrapping key\n+ * stored in the PLPKS.\n+ * @input_buf: buffer containing the data to be unwrapped\n+ * @input_len: length of the input buffer\n+ * @output_buf: buffer to store the unwrapped data\n+ * @output_len: length of the output buffer\n+ *\n+ * The H_PKS_UNWRAP_OBJECT HCALL unwraps an object that was previously wrapped\n+ * using the H_PKS_WRAP_OBJECT HCALL.\n+ *\n+ * Possible reasons for the returned errno values:\n+ *\n+ * -ENXIO\tif PLPKS is not supported\n+ * -EIO\t\tif PLPKS access is blocked due to the LPAR's state\n+ *\t\tif PLPKS modification is blocked due to the LPAR's state\n+ *\t\tif an error occurred while processing the request\n+ * -EINVAL\tif invalid authorization parameter\n+ *\t\tif invalid or unsupported object unwrapping flags\n+ *\t\tif invalid inut buffer parameter\n+ *\t\tif invalid input buffer length parameter\n+ *\t\tif invalid output buffer parameter\n+ *\t\tif invalid output buffer length parameter\n+ *\t\tif invalid continue token parameter\n+ *\t\tif the wrapping key is not compatible with the wrapping\n+ *\t\talgorithm\n+ *\t\tif the wrapped object's format is not supported\n+ *\t\tif the wrapped object is invalid\n+ * -EPERM\tif access is denied\n+ * -ENOENT\tif the wrapping key for the provided object was not found\n+ * -EBUSY\tif unable to handle the request or long running operation\n+ *\t\tinitiated, retry later.\n+ *\n+ * Returns: On success 0 is returned, a negative errno if not.\n+ */\n+int plpks_unwrap_object(u8 **input_buf, u32 input_len, u8 **output_buf,\n+\t\t\tu32 *output_len)\n+{\n+\tunsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = { 0 };\n+\tstruct plpks_auth *auth;\n+\tu64 continuetoken = 0;\n+\tu64 objwrapflags = 0;\n+\tint rc = 0, pseries_status = 0;\n+\n+\tauth = construct_auth(PLPKS_OS_OWNER);\n+\tif (IS_ERR(auth))\n+\t\treturn PTR_ERR(auth);\n+\n+\t*output_len = input_len - PLPKS_WRAPPING_BUF_DIFF;\n+\t*output_buf = kzalloc(ALIGN(*output_len, PLPKS_WRAPPING_BUF_ALIGN),\n+\t\t\t GFP_KERNEL);\n+\tif (!(*output_buf)) {\n+\t\tpr_err(\"Output buffer allocation failed. Returning -ENOMEM.\");\n+\t\trc = -ENOMEM;\n+\t\tgoto out;\n+\t}\n+\n+\tdo {\n+\t\trc = plpar_hcall9(H_PKS_UNWRAP_OBJECT, retbuf,\n+\t\t\t\t virt_to_phys(auth), objwrapflags,\n+\t\t\t\t virt_to_phys(*input_buf), input_len,\n+\t\t\t\t virt_to_phys(*output_buf), *output_len,\n+\t\t\t\t continuetoken);\n+\n+\t\tcontinuetoken = retbuf[0];\n+\t\tpseries_status = rc;\n+\t\trc = pseries_status_to_err(rc);\n+\t} while (rc == -EBUSY);\n+\n+\tif (rc) {\n+\t\tpr_err(\"H_PKS_UNWRAP_OBJECT failed.\");\n+\t\tpr_err(\"pseries_status = %d, return code = %d\", pseries_status,\n+\t\t rc);\n+\t\tkfree(*output_buf);\n+\t\t*output_buf = NULL;\n+\t} else {\n+\t\t*output_len = retbuf[1];\n+\t}\n+\n+out:\n+\tkfree(auth);\n+\treturn rc;\n+}\n+EXPORT_SYMBOL_GPL(plpks_unwrap_object);\n+\n+/**\n+ * plpks_read_os_var() - Fetch the data for the specified variable that is owned\n+ * by the OS consumer.\n * @var: variable to be read from the PLPKS\n *\n * The consumer or the owner of the object is the os kernel. The\n", "prefixes": [ "v2", "4/6" ] }