From patchwork Thu Aug 18 14:30:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Joyce X-Patchwork-Id: 12947218 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 11234C32793 for ; Thu, 18 Aug 2022 14:31:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245418AbiHRObK (ORCPT ); Thu, 18 Aug 2022 10:31:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53260 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245296AbiHRObH (ORCPT ); Thu, 18 Aug 2022 10:31:07 -0400 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0763CB9FAD; Thu, 18 Aug 2022 07:31:05 -0700 (PDT) Received: from pps.filterd (m0187473.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27IEMRiC011807; Thu, 18 Aug 2022 14:30:53 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=q+xuCAT8Dq2xaBP3fkQXIIwvZvm8PlLRevWJ8ZGNlhU=; b=YSw3eVUV2zGsknzQVm6j3m1EOBW3g0I1pYbtvyiUcaXbKVk64IwOj2dhhBNkWB/hNabs JI6mhM24Ja6+FSofiNltD9nWBMsjmukrQeBcgs4y5SyHgmrxw988qJji6CmrcaRZdzra 4N6xL6Ze6xpV+agY6e9s/PMhqztJ2nqOwJMIG5gHOIoQS4ktHISBsBXY4dbDmzVp5Skp olrHdB9qXvpsoCvXXDikrLbD5gzrttRb6SWHFOLmIqe4yZyjlwytp0pdFhTB1p/IaBH0 b2uuyBUyuHNrElX01JXRDaHt1/kKAFOdOLAbAfMuRtucWuLXPXm3Q3cUu/k3DawwVmNU 8Q== Received: from ppma02wdc.us.ibm.com (aa.5b.37a9.ip4.static.sl-reverse.com [169.55.91.170]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3j1q4e08mm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 18 Aug 2022 14:30:52 +0000 Received: from pps.filterd (ppma02wdc.us.ibm.com [127.0.0.1]) by ppma02wdc.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 27IEK2og030461; Thu, 18 Aug 2022 14:30:51 GMT Received: from b03cxnp08027.gho.boulder.ibm.com (b03cxnp08027.gho.boulder.ibm.com [9.17.130.19]) by ppma02wdc.us.ibm.com with ESMTP id 3hx3ka79p7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 18 Aug 2022 14:30:51 +0000 Received: from b03ledav004.gho.boulder.ibm.com (b03ledav004.gho.boulder.ibm.com [9.17.130.235]) by b03cxnp08027.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 27IEUoTf34013680 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 18 Aug 2022 14:30:50 GMT Received: from b03ledav004.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 8EA0D7805C; Thu, 18 Aug 2022 14:30:50 +0000 (GMT) Received: from b03ledav004.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 648877805E; Thu, 18 Aug 2022 14:30:49 +0000 (GMT) Received: from rhel-laptop.ibm.com.com (unknown [9.160.121.241]) by b03ledav004.gho.boulder.ibm.com (Postfix) with ESMTP; Thu, 18 Aug 2022 14:30:49 +0000 (GMT) From: gjoyce@linux.vnet.ibm.com To: linux-block@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org, jonathan.derrick@linux.dev, brking@linux.vnet.ibm.com, msuchanek@suse.de, mpe@ellerman.id.au, nayna@linux.ibm.com, axboe@kernel.dk, akpm@linux-foundation.org, gjoyce@linux.vnet.ibm.com, linux-efi@vger.kernel.org, keyrings@vger.kernel.org Subject: [PATCH v2 1/3 RESEND] block: sed-opal: Implement IOC_OPAL_DISCOVERY Date: Thu, 18 Aug 2022 09:30:43 -0500 Message-Id: <20220818143045.680972-2-gjoyce@linux.vnet.ibm.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220818143045.680972-1-gjoyce@linux.vnet.ibm.com> References: <20220818143045.680972-1-gjoyce@linux.vnet.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: meLidihwLuwr4vO9zvPF2C_7j2Jkg1sB X-Proofpoint-ORIG-GUID: meLidihwLuwr4vO9zvPF2C_7j2Jkg1sB X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-08-18_12,2022-08-18_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 spamscore=0 clxscore=1015 suspectscore=0 priorityscore=1501 mlxscore=0 adultscore=0 malwarescore=0 phishscore=0 bulkscore=0 mlxlogscore=999 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2207270000 definitions=main-2208180050 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org From: Greg Joyce Add IOC_OPAL_DISCOVERY ioctl to return raw discovery data to a SED Opal application. This allows the application to display drive capabilities and state. Signed-off-by: Greg Joyce Reviewed-by: Jonathan Derrick --- block/sed-opal.c | 38 ++++++++++++++++++++++++++++++++--- include/linux/sed-opal.h | 1 + include/uapi/linux/sed-opal.h | 6 ++++++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/block/sed-opal.c b/block/sed-opal.c index 9700197000f2..e4d8fbdc9dad 100644 --- a/block/sed-opal.c +++ b/block/sed-opal.c @@ -426,8 +426,12 @@ static int execute_steps(struct opal_dev *dev, return error; } -static int opal_discovery0_end(struct opal_dev *dev) +static int opal_discovery0_end(struct opal_dev *dev, void *data) { + struct opal_discovery *discv_out = data; /* may be NULL */ + u8 __user *buf_out; + u64 len_out; + bool found_com_id = false, supported = true, single_user = false; const struct d0_header *hdr = (struct d0_header *)dev->resp; const u8 *epos = dev->resp, *cpos = dev->resp; @@ -443,6 +447,15 @@ static int opal_discovery0_end(struct opal_dev *dev) return -EFAULT; } + if (discv_out) { + buf_out = (u8 __user *)(uintptr_t)discv_out->data; + len_out = min_t(u64, discv_out->size, hlen); + if (buf_out && copy_to_user(buf_out, dev->resp, len_out)) + return -EFAULT; + + discv_out->size = hlen; /* actual size of data */ + } + epos += hlen; /* end of buffer */ cpos += sizeof(*hdr); /* current position on buffer */ @@ -517,13 +530,13 @@ static int opal_discovery0(struct opal_dev *dev, void *data) if (ret) return ret; - return opal_discovery0_end(dev); + return opal_discovery0_end(dev, data); } static int opal_discovery0_step(struct opal_dev *dev) { const struct opal_step discovery0_step = { - opal_discovery0, + opal_discovery0, NULL }; return execute_step(dev, &discovery0_step, 0); @@ -2179,6 +2192,22 @@ static int opal_secure_erase_locking_range(struct opal_dev *dev, return ret; } +static int opal_get_discv(struct opal_dev *dev, struct opal_discovery *discv) +{ + const struct opal_step discovery0_step = { + opal_discovery0, discv + }; + int ret = 0; + + mutex_lock(&dev->dev_lock); + setup_opal_dev(dev); + ret = execute_step(dev, &discovery0_step, 0); + mutex_unlock(&dev->dev_lock); + if (ret) + return ret; + return discv->size; /* modified to actual length of data */ +} + static int opal_erase_locking_range(struct opal_dev *dev, struct opal_session_info *opal_session) { @@ -2685,6 +2714,9 @@ int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg) case IOC_OPAL_GENERIC_TABLE_RW: ret = opal_generic_read_write_table(dev, p); break; + case IOC_OPAL_DISCOVERY: + ret = opal_get_discv(dev, p); + break; default: break; } diff --git a/include/linux/sed-opal.h b/include/linux/sed-opal.h index 1ac0d712a9c3..9197b7a628f2 100644 --- a/include/linux/sed-opal.h +++ b/include/linux/sed-opal.h @@ -43,6 +43,7 @@ static inline bool is_sed_ioctl(unsigned int cmd) case IOC_OPAL_MBR_DONE: case IOC_OPAL_WRITE_SHADOW_MBR: case IOC_OPAL_GENERIC_TABLE_RW: + case IOC_OPAL_DISCOVERY: return true; } return false; diff --git a/include/uapi/linux/sed-opal.h b/include/uapi/linux/sed-opal.h index 6f5af1a84213..89dd108b426f 100644 --- a/include/uapi/linux/sed-opal.h +++ b/include/uapi/linux/sed-opal.h @@ -132,6 +132,11 @@ struct opal_read_write_table { __u64 priv; }; +struct opal_discovery { + __u64 data; + __u64 size; +}; + #define IOC_OPAL_SAVE _IOW('p', 220, struct opal_lock_unlock) #define IOC_OPAL_LOCK_UNLOCK _IOW('p', 221, struct opal_lock_unlock) #define IOC_OPAL_TAKE_OWNERSHIP _IOW('p', 222, struct opal_key) @@ -148,5 +153,6 @@ struct opal_read_write_table { #define IOC_OPAL_MBR_DONE _IOW('p', 233, struct opal_mbr_done) #define IOC_OPAL_WRITE_SHADOW_MBR _IOW('p', 234, struct opal_shadow_mbr) #define IOC_OPAL_GENERIC_TABLE_RW _IOW('p', 235, struct opal_read_write_table) +#define IOC_OPAL_DISCOVERY _IOW('p', 236, struct opal_discovery) #endif /* _UAPI_SED_OPAL_H */ From patchwork Thu Aug 18 14:30:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Joyce X-Patchwork-Id: 12947219 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AAA8DC32792 for ; Thu, 18 Aug 2022 14:31:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245468AbiHRObJ (ORCPT ); Thu, 18 Aug 2022 10:31:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53258 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245243AbiHRObH (ORCPT ); Thu, 18 Aug 2022 10:31:07 -0400 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 48DC0B9F9D; Thu, 18 Aug 2022 07:31:05 -0700 (PDT) Received: from pps.filterd (m0098421.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27IEEY1V014225; Thu, 18 Aug 2022 14:30:54 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=kuf2QCWXrsl52T7eFPd0nJPt3gRfgPQ0AbooXYG3RPk=; b=lyQU7G2KwvWsvJj7n8o54APQm9nio/W6eJjwJDj4AemVvSpMT7tMAxYmxF/rqJKwav/k hOH6hZ4okNX5LOuLDc7wZsZYH9yrs+tj6ylJ5LUJtjripWqTpWGqHB/s0PX0K3/bzNho 26C6SSOJZgE4V3Up9xNDQ7yQLweB/Fg+/ILfHrwBX/ar08G5sTYx2jbkOxj63dLkGFOv 9delB+STnjh11U4h1Lf10vYqkwJHhesbNkqTaxkUSBwrduxyqyXcGPFuxWrA9/DL4Ufj vXDQEUIT3oxqOHs/kbc1/57y44URSgDPMM4KaX1dfkK3SPhfJRJwamEmdNHfyjzlZn3+ hg== Received: from ppma03dal.us.ibm.com (b.bd.3ea9.ip4.static.sl-reverse.com [169.62.189.11]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3j1q0w0js1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 18 Aug 2022 14:30:54 +0000 Received: from pps.filterd (ppma03dal.us.ibm.com [127.0.0.1]) by ppma03dal.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 27IELhwd024218; Thu, 18 Aug 2022 14:30:53 GMT Received: from b03cxnp08028.gho.boulder.ibm.com (b03cxnp08028.gho.boulder.ibm.com [9.17.130.20]) by ppma03dal.us.ibm.com with ESMTP id 3hx3kaeyyj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 18 Aug 2022 14:30:53 +0000 Received: from b03ledav004.gho.boulder.ibm.com (b03ledav004.gho.boulder.ibm.com [9.17.130.235]) by b03cxnp08028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 27IEUpqn34865470 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 18 Aug 2022 14:30:52 GMT Received: from b03ledav004.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E00437805E; Thu, 18 Aug 2022 14:30:51 +0000 (GMT) Received: from b03ledav004.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id B62FF7805C; Thu, 18 Aug 2022 14:30:50 +0000 (GMT) Received: from rhel-laptop.ibm.com.com (unknown [9.160.121.241]) by b03ledav004.gho.boulder.ibm.com (Postfix) with ESMTP; Thu, 18 Aug 2022 14:30:50 +0000 (GMT) From: gjoyce@linux.vnet.ibm.com To: linux-block@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org, jonathan.derrick@linux.dev, brking@linux.vnet.ibm.com, msuchanek@suse.de, mpe@ellerman.id.au, nayna@linux.ibm.com, axboe@kernel.dk, akpm@linux-foundation.org, gjoyce@linux.vnet.ibm.com, linux-efi@vger.kernel.org, keyrings@vger.kernel.org Subject: [PATCH v2 2/3 RESEND] block: sed-opal: Implement IOC_OPAL_REVERT_LSP Date: Thu, 18 Aug 2022 09:30:44 -0500 Message-Id: <20220818143045.680972-3-gjoyce@linux.vnet.ibm.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220818143045.680972-1-gjoyce@linux.vnet.ibm.com> References: <20220818143045.680972-1-gjoyce@linux.vnet.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: v3fji98D0YIfuxmIrRD8kwfzYaiD1tkL X-Proofpoint-GUID: v3fji98D0YIfuxmIrRD8kwfzYaiD1tkL X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-08-18_12,2022-08-18_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=999 mlxscore=0 priorityscore=1501 impostorscore=0 lowpriorityscore=0 bulkscore=0 suspectscore=0 adultscore=0 malwarescore=0 phishscore=0 clxscore=1015 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2207270000 definitions=main-2208180050 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org From: Greg Joyce This is used in conjunction with IOC_OPAL_REVERT_TPR to return a drive to Original Factory State without erasing the data. If IOC_OPAL_REVERT_LSP is called with opal_revert_lsp.options bit OPAL_PRESERVE set prior to calling IOC_OPAL_REVERT_TPR, the drive global locking range will not be erased. Signed-off-by: Greg Joyce Reviewed-by: Jonathan Derrick --- block/opal_proto.h | 4 ++++ block/sed-opal.c | 40 +++++++++++++++++++++++++++++++++++ include/linux/sed-opal.h | 1 + include/uapi/linux/sed-opal.h | 11 ++++++++++ 4 files changed, 56 insertions(+) diff --git a/block/opal_proto.h b/block/opal_proto.h index b486b3ec7dc4..6127c08267f8 100644 --- a/block/opal_proto.h +++ b/block/opal_proto.h @@ -210,6 +210,10 @@ enum opal_parameter { OPAL_SUM_SET_LIST = 0x060000, }; +enum opal_revertlsp { + OPAL_KEEP_GLOBAL_RANGE_KEY = 0x060000, +}; + /* Packets derived from: * TCG_Storage_Architecture_Core_Spec_v2.01_r1.00 * Secion: 3.2.3 ComPackets, Packets & Subpackets diff --git a/block/sed-opal.c b/block/sed-opal.c index e4d8fbdc9dad..2916b9539b84 100644 --- a/block/sed-opal.c +++ b/block/sed-opal.c @@ -1593,6 +1593,26 @@ static int internal_activate_user(struct opal_dev *dev, void *data) return finalize_and_send(dev, parse_and_check_status); } +static int revert_lsp(struct opal_dev *dev, void *data) +{ + struct opal_revert_lsp *rev = data; + int err; + + err = cmd_start(dev, opaluid[OPAL_THISSP_UID], + opalmethod[OPAL_REVERTSP]); + add_token_u8(&err, dev, OPAL_STARTNAME); + add_token_u64(&err, dev, OPAL_KEEP_GLOBAL_RANGE_KEY); + add_token_u8(&err, dev, (rev->options & OPAL_PRESERVE) ? + OPAL_TRUE : OPAL_FALSE); + add_token_u8(&err, dev, OPAL_ENDNAME); + if (err) { + pr_debug("Error building REVERT SP command.\n"); + return err; + } + + return finalize_and_send(dev, parse_and_check_status); +} + static int erase_locking_range(struct opal_dev *dev, void *data) { struct opal_session_info *session = data; @@ -2208,6 +2228,23 @@ static int opal_get_discv(struct opal_dev *dev, struct opal_discovery *discv) return discv->size; /* modified to actual length of data */ } +static int opal_revertlsp(struct opal_dev *dev, struct opal_revert_lsp *rev) +{ + /* controller will terminate session */ + const struct opal_step steps[] = { + { start_admin1LSP_opal_session, &rev->key }, + { revert_lsp, rev } + }; + int ret; + + mutex_lock(&dev->dev_lock); + setup_opal_dev(dev); + ret = execute_steps(dev, steps, ARRAY_SIZE(steps)); + mutex_unlock(&dev->dev_lock); + + return ret; +} + static int opal_erase_locking_range(struct opal_dev *dev, struct opal_session_info *opal_session) { @@ -2714,6 +2751,9 @@ int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg) case IOC_OPAL_GENERIC_TABLE_RW: ret = opal_generic_read_write_table(dev, p); break; + case IOC_OPAL_REVERT_LSP: + ret = opal_revertlsp(dev, p); + break; case IOC_OPAL_DISCOVERY: ret = opal_get_discv(dev, p); break; diff --git a/include/linux/sed-opal.h b/include/linux/sed-opal.h index 9197b7a628f2..3a6082ff97e7 100644 --- a/include/linux/sed-opal.h +++ b/include/linux/sed-opal.h @@ -43,6 +43,7 @@ static inline bool is_sed_ioctl(unsigned int cmd) case IOC_OPAL_MBR_DONE: case IOC_OPAL_WRITE_SHADOW_MBR: case IOC_OPAL_GENERIC_TABLE_RW: + case IOC_OPAL_REVERT_LSP: case IOC_OPAL_DISCOVERY: return true; } diff --git a/include/uapi/linux/sed-opal.h b/include/uapi/linux/sed-opal.h index 89dd108b426f..bc91987a6328 100644 --- a/include/uapi/linux/sed-opal.h +++ b/include/uapi/linux/sed-opal.h @@ -51,6 +51,10 @@ struct opal_key { __u8 key[OPAL_KEY_MAX]; }; +enum opal_revert_lsp_opts { + OPAL_PRESERVE = 0x01, +}; + struct opal_lr_act { struct opal_key key; __u32 sum; @@ -137,6 +141,12 @@ struct opal_discovery { __u64 size; }; +struct opal_revert_lsp { + struct opal_key key; + __u32 options; + __u32 __pad; +}; + #define IOC_OPAL_SAVE _IOW('p', 220, struct opal_lock_unlock) #define IOC_OPAL_LOCK_UNLOCK _IOW('p', 221, struct opal_lock_unlock) #define IOC_OPAL_TAKE_OWNERSHIP _IOW('p', 222, struct opal_key) @@ -154,5 +164,6 @@ struct opal_discovery { #define IOC_OPAL_WRITE_SHADOW_MBR _IOW('p', 234, struct opal_shadow_mbr) #define IOC_OPAL_GENERIC_TABLE_RW _IOW('p', 235, struct opal_read_write_table) #define IOC_OPAL_DISCOVERY _IOW('p', 236, struct opal_discovery) +#define IOC_OPAL_REVERT_LSP _IOW('p', 237, struct opal_revert_lsp) #endif /* _UAPI_SED_OPAL_H */ From patchwork Thu Aug 18 14:30:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Joyce X-Patchwork-Id: 12947220 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 966EAC38147 for ; Thu, 18 Aug 2022 14:31:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245598AbiHRObK (ORCPT ); Thu, 18 Aug 2022 10:31:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53264 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245192AbiHRObI (ORCPT ); Thu, 18 Aug 2022 10:31:08 -0400 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A3E34B99C6; Thu, 18 Aug 2022 07:31:06 -0700 (PDT) Received: from pps.filterd (m0098399.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27IDfr0D003963; Thu, 18 Aug 2022 14:30:55 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=TAzDUvqbXfCA2IACO9YAMYkxmNEIQAorzKNDitphQK8=; b=kZ6jvQY9DQFNkpzY/D8MKWDSTN3RkGr2iLYrOhV6Ofo4L5PH2B/EtWHxo/tgXfAKDEHE n2yUdL32oFJiVViAgm0TzlLCqvw7joZm4f42Z5n+oJO7m0WDGLJ3e6+itqvEGfL6R75x FwCaDwi5+ihSceCg0/R4mL89THHaUPrNcvxkItiwOsaC1AiWz50vymgIIXvN7/MzAmMJ ap+DDxiNjPJvhopBWNkgd/HeY3tHF1lBvOKVdnnVhvo7PhyYGRQDJR4iCsOpu2ZGM+r+ BG7rDZM762/NXrmlDRlT1gIX3GFB8ubG8CtNR2vgFJUQsUbARFw0TgY+W0un9+r4Qdq8 xQ== Received: from ppma04dal.us.ibm.com (7a.29.35a9.ip4.static.sl-reverse.com [169.53.41.122]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3j1phjssdh-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 18 Aug 2022 14:30:55 +0000 Received: from pps.filterd (ppma04dal.us.ibm.com [127.0.0.1]) by ppma04dal.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 27IEKplq005867; Thu, 18 Aug 2022 14:30:54 GMT Received: from b03cxnp07029.gho.boulder.ibm.com (b03cxnp07029.gho.boulder.ibm.com [9.17.130.16]) by ppma04dal.us.ibm.com with ESMTP id 3hx3kaexvy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 18 Aug 2022 14:30:54 +0000 Received: from b03ledav004.gho.boulder.ibm.com (b03ledav004.gho.boulder.ibm.com [9.17.130.235]) by b03cxnp07029.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 27IEUrbZ49414504 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 18 Aug 2022 14:30:53 GMT Received: from b03ledav004.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3E77678060; Thu, 18 Aug 2022 14:30:53 +0000 (GMT) Received: from b03ledav004.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1444D7805C; Thu, 18 Aug 2022 14:30:52 +0000 (GMT) Received: from rhel-laptop.ibm.com.com (unknown [9.160.121.241]) by b03ledav004.gho.boulder.ibm.com (Postfix) with ESMTP; Thu, 18 Aug 2022 14:30:51 +0000 (GMT) From: gjoyce@linux.vnet.ibm.com To: linux-block@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org, jonathan.derrick@linux.dev, brking@linux.vnet.ibm.com, msuchanek@suse.de, mpe@ellerman.id.au, nayna@linux.ibm.com, axboe@kernel.dk, akpm@linux-foundation.org, gjoyce@linux.vnet.ibm.com, linux-efi@vger.kernel.org, keyrings@vger.kernel.org Subject: [PATCH v2 3/3 RESEND] block: sed-opal: keyring support for SED keys Date: Thu, 18 Aug 2022 09:30:45 -0500 Message-Id: <20220818143045.680972-4-gjoyce@linux.vnet.ibm.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220818143045.680972-1-gjoyce@linux.vnet.ibm.com> References: <20220818143045.680972-1-gjoyce@linux.vnet.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: CxbsJ-H76uriqGu_LFzHKhe37EJw7hW4 X-Proofpoint-ORIG-GUID: CxbsJ-H76uriqGu_LFzHKhe37EJw7hW4 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-08-18_12,2022-08-18_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 phishscore=0 mlxscore=0 malwarescore=0 clxscore=1015 adultscore=0 spamscore=0 priorityscore=1501 impostorscore=0 lowpriorityscore=0 bulkscore=0 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2207270000 definitions=main-2208180050 Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org From: Greg Joyce Extend the SED block driver so it can alternatively obtain a key from a sed-opal kernel keyring. The SED ioctls will indicate the source of the key, either directly in the ioctl data or from the keyring. This allows the use of SED commands in scripts such as udev scripts so that drives may be automatically unlocked as they become available. Signed-off-by: Greg Joyce Reviewed-by: Jonathan Derrick --- block/Kconfig | 1 + block/sed-opal.c | 174 +++++++++++++++++++++++++++++++++- include/linux/sed-opal.h | 3 + include/uapi/linux/sed-opal.h | 8 +- 4 files changed, 183 insertions(+), 3 deletions(-) diff --git a/block/Kconfig b/block/Kconfig index 50b17e260fa2..f65169e9356b 100644 --- a/block/Kconfig +++ b/block/Kconfig @@ -182,6 +182,7 @@ config BLK_DEBUG_FS_ZONED config BLK_SED_OPAL bool "Logic for interfacing with Opal enabled SEDs" + depends on KEYS help Builds Logic for interfacing with Opal enabled controllers. Enabling this option enables users to setup/unlock/lock diff --git a/block/sed-opal.c b/block/sed-opal.c index 2916b9539b84..3bdb31cf3e7c 100644 --- a/block/sed-opal.c +++ b/block/sed-opal.c @@ -20,6 +20,9 @@ #include #include #include +#include +#include +#include #include "opal_proto.h" @@ -29,6 +32,8 @@ /* Number of bytes needed by cmd_finalize. */ #define CMD_FINALIZE_BYTES_NEEDED 7 +static struct key *sed_opal_keyring; + struct opal_step { int (*fn)(struct opal_dev *dev, void *data); void *data; @@ -266,6 +271,101 @@ static void print_buffer(const u8 *ptr, u32 length) #endif } +/* + * Allocate/update a SED Opal key and add it to the SED Opal keyring. + */ +static int update_sed_opal_key(const char *desc, u_char *key_data, int keylen) +{ + key_ref_t kr; + + if (!sed_opal_keyring) + return -ENOKEY; + + kr = key_create_or_update(make_key_ref(sed_opal_keyring, true), "user", + desc, (const void *)key_data, keylen, + KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_WRITE, + KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_BUILT_IN | + KEY_ALLOC_BYPASS_RESTRICTION); + if (IS_ERR(kr)) { + pr_err("Error adding SED key (%ld)\n", PTR_ERR(kr)); + return PTR_ERR(kr); + } + + return 0; +} + +/* + * Read a SED Opal key from the SED Opal keyring. + */ +static int read_sed_opal_key(const char *key_name, u_char *buffer, int buflen) +{ + int ret; + key_ref_t kref; + struct key *key; + + if (!sed_opal_keyring) + return -ENOKEY; + + kref = keyring_search(make_key_ref(sed_opal_keyring, true), + &key_type_user, key_name, true); + + if (IS_ERR(kref)) + ret = PTR_ERR(kref); + + key = key_ref_to_ptr(kref); + down_read(&key->sem); + ret = key_validate(key); + if (ret == 0) { + if (buflen > key->datalen) + buflen = key->datalen; + + ret = key->type->read(key, (char *)buffer, buflen); + } + up_read(&key->sem); + + key_ref_put(kref); + + return ret; +} + +static int opal_get_key(struct opal_dev *dev, struct opal_key *key) +{ + int ret = 0; + + switch (key->key_type) { + case OPAL_INCLUDED: + /* the key is ready to use */ + break; + case OPAL_KEYRING: + /* the key is in the keyring */ + ret = read_sed_opal_key(OPAL_AUTH_KEY, key->key, OPAL_KEY_MAX); + if (ret > 0) { + if (ret > 255) { + ret = -ENOSPC; + goto error; + } + key->key_len = ret; + key->key_type = OPAL_INCLUDED; + } + break; + default: + ret = -EINVAL; + break; + } + if (ret < 0) + goto error; + + /* must have a PEK by now or it's an error */ + if (key->key_type != OPAL_INCLUDED || key->key_len == 0) { + ret = -EINVAL; + goto error; + } + return 0; +error: + pr_debug("Error getting password: %d\n", ret); + return ret; +} + static bool check_tper(const void *data) { const struct d0_tper_features *tper = data; @@ -2204,6 +2304,9 @@ static int opal_secure_erase_locking_range(struct opal_dev *dev, }; int ret; + ret = opal_get_key(dev, &opal_session->opal_key); + if (ret) + return ret; mutex_lock(&dev->dev_lock); setup_opal_dev(dev); ret = execute_steps(dev, erase_steps, ARRAY_SIZE(erase_steps)); @@ -2237,6 +2340,9 @@ static int opal_revertlsp(struct opal_dev *dev, struct opal_revert_lsp *rev) }; int ret; + ret = opal_get_key(dev, &rev->key); + if (ret) + return ret; mutex_lock(&dev->dev_lock); setup_opal_dev(dev); ret = execute_steps(dev, steps, ARRAY_SIZE(steps)); @@ -2255,6 +2361,9 @@ static int opal_erase_locking_range(struct opal_dev *dev, }; int ret; + ret = opal_get_key(dev, &opal_session->opal_key); + if (ret) + return ret; mutex_lock(&dev->dev_lock); setup_opal_dev(dev); ret = execute_steps(dev, erase_steps, ARRAY_SIZE(erase_steps)); @@ -2283,6 +2392,9 @@ static int opal_enable_disable_shadow_mbr(struct opal_dev *dev, opal_mbr->enable_disable != OPAL_MBR_DISABLE) return -EINVAL; + ret = opal_get_key(dev, &opal_mbr->key); + if (ret) + return ret; mutex_lock(&dev->dev_lock); setup_opal_dev(dev); ret = execute_steps(dev, mbr_steps, ARRAY_SIZE(mbr_steps)); @@ -2308,6 +2420,9 @@ static int opal_set_mbr_done(struct opal_dev *dev, mbr_done->done_flag != OPAL_MBR_NOT_DONE) return -EINVAL; + ret = opal_get_key(dev, &mbr_done->key); + if (ret) + return ret; mutex_lock(&dev->dev_lock); setup_opal_dev(dev); ret = execute_steps(dev, mbr_steps, ARRAY_SIZE(mbr_steps)); @@ -2329,6 +2444,9 @@ static int opal_write_shadow_mbr(struct opal_dev *dev, if (info->size == 0) return 0; + ret = opal_get_key(dev, &info->key); + if (ret) + return ret; mutex_lock(&dev->dev_lock); setup_opal_dev(dev); ret = execute_steps(dev, mbr_steps, ARRAY_SIZE(mbr_steps)); @@ -2385,6 +2503,9 @@ static int opal_add_user_to_lr(struct opal_dev *dev, return -EINVAL; } + ret = opal_get_key(dev, &lk_unlk->session.opal_key); + if (ret) + return ret; mutex_lock(&dev->dev_lock); setup_opal_dev(dev); ret = execute_steps(dev, steps, ARRAY_SIZE(steps)); @@ -2407,6 +2528,10 @@ static int opal_reverttper(struct opal_dev *dev, struct opal_key *opal, bool psi int ret; + ret = opal_get_key(dev, opal); + + if (ret) + return ret; mutex_lock(&dev->dev_lock); setup_opal_dev(dev); if (psid) @@ -2469,6 +2594,9 @@ static int opal_lock_unlock(struct opal_dev *dev, if (lk_unlk->session.who > OPAL_USER9) return -EINVAL; + ret = opal_get_key(dev, &lk_unlk->session.opal_key); + if (ret) + return ret; mutex_lock(&dev->dev_lock); ret = __opal_lock_unlock(dev, lk_unlk); mutex_unlock(&dev->dev_lock); @@ -2491,6 +2619,9 @@ static int opal_take_ownership(struct opal_dev *dev, struct opal_key *opal) if (!dev) return -ENODEV; + ret = opal_get_key(dev, opal); + if (ret) + return ret; mutex_lock(&dev->dev_lock); setup_opal_dev(dev); ret = execute_steps(dev, owner_steps, ARRAY_SIZE(owner_steps)); @@ -2513,6 +2644,9 @@ static int opal_activate_lsp(struct opal_dev *dev, if (!opal_lr_act->num_lrs || opal_lr_act->num_lrs > OPAL_MAX_LRS) return -EINVAL; + ret = opal_get_key(dev, &opal_lr_act->key); + if (ret) + return ret; mutex_lock(&dev->dev_lock); setup_opal_dev(dev); ret = execute_steps(dev, active_steps, ARRAY_SIZE(active_steps)); @@ -2531,6 +2665,9 @@ static int opal_setup_locking_range(struct opal_dev *dev, }; int ret; + ret = opal_get_key(dev, &opal_lrs->session.opal_key); + if (ret) + return ret; mutex_lock(&dev->dev_lock); setup_opal_dev(dev); ret = execute_steps(dev, lr_steps, ARRAY_SIZE(lr_steps)); @@ -2557,6 +2694,14 @@ static int opal_set_new_pw(struct opal_dev *dev, struct opal_new_pw *opal_pw) ret = execute_steps(dev, pw_steps, ARRAY_SIZE(pw_steps)); mutex_unlock(&dev->dev_lock); + if (ret) + return ret; + + /* update keyring with new password */ + ret = update_sed_opal_key(OPAL_AUTH_KEY, + opal_pw->new_user_pw.opal_key.key, + opal_pw->new_user_pw.opal_key.key_len); + return ret; } @@ -2577,6 +2722,9 @@ static int opal_activate_user(struct opal_dev *dev, return -EINVAL; } + ret = opal_get_key(dev, &opal_session->opal_key); + if (ret) + return ret; mutex_lock(&dev->dev_lock); setup_opal_dev(dev); ret = execute_steps(dev, act_steps, ARRAY_SIZE(act_steps)); @@ -2663,6 +2811,9 @@ static int opal_generic_read_write_table(struct opal_dev *dev, { int ret, bit_set; + ret = opal_get_key(dev, &rw_tbl->key); + if (ret) + return ret; mutex_lock(&dev->dev_lock); setup_opal_dev(dev); @@ -2694,9 +2845,9 @@ int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg) if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (!dev) - return -ENOTSUPP; + return -EOPNOTSUPP; if (!dev->supported) - return -ENOTSUPP; + return -EOPNOTSUPP; p = memdup_user(arg, _IOC_SIZE(cmd)); if (IS_ERR(p)) @@ -2765,3 +2916,22 @@ int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *arg) return ret; } EXPORT_SYMBOL_GPL(sed_ioctl); + +static int __init sed_opal_init(void) +{ + struct key *kr; + + kr = keyring_alloc(".sed_opal", + GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(), + (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | + KEY_USR_READ | KEY_USR_SEARCH | KEY_USR_WRITE, + KEY_ALLOC_NOT_IN_QUOTA, + NULL, NULL); + if (IS_ERR(kr)) + return PTR_ERR(kr); + + sed_opal_keyring = kr; + + return 0; +} +late_initcall(sed_opal_init); diff --git a/include/linux/sed-opal.h b/include/linux/sed-opal.h index 3a6082ff97e7..ed21e47bf773 100644 --- a/include/linux/sed-opal.h +++ b/include/linux/sed-opal.h @@ -24,6 +24,9 @@ bool opal_unlock_from_suspend(struct opal_dev *dev); struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv); int sed_ioctl(struct opal_dev *dev, unsigned int cmd, void __user *ioctl_ptr); +#define OPAL_AUTH_KEY "opal-boot-pin" +#define OPAL_AUTH_KEY_PREV "opal-boot-pin-prev" + static inline bool is_sed_ioctl(unsigned int cmd) { switch (cmd) { diff --git a/include/uapi/linux/sed-opal.h b/include/uapi/linux/sed-opal.h index bc91987a6328..852d3098ec00 100644 --- a/include/uapi/linux/sed-opal.h +++ b/include/uapi/linux/sed-opal.h @@ -44,10 +44,16 @@ enum opal_lock_state { OPAL_LK = 0x04, /* 0100 */ }; +enum opal_key_type { + OPAL_INCLUDED = 0, /* key[] is the key */ + OPAL_KEYRING, /* key is in keyring */ +}; + struct opal_key { __u8 lr; __u8 key_len; - __u8 __align[6]; + __u8 key_type; + __u8 __align[5]; __u8 key[OPAL_KEY_MAX]; };