From nobody Mon Sep 28 01:12:31 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1785773652; cv=none; d=zohomail.com; s=zohoarc; b=P5bNjSRdL/x0h85iMmLE5QKJ+9Juw4YJY+PXwvzzBG9HtTtSZ0Czzd9pu8day5X26RJBlKnUrNzj0TJ/lpvS3rRgaQwR/jkmz+tzoerDZLawC7rqMxB1BnAeH/98sK9SH13CKgsYTgXB5mw2C8FXEWnPi7TXL7svia5XpCfk0s8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785773652; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=s7XbP3NXFrOl+6effIgLJ+MIGqKsuVCxmppm7IMXE1Y=; b=B/cxnzzveqTXPoyoy6VFDABEFfYidwBGrfTfk8VLMyCfih8Ue5oHZHjlIpmjxg61qi5pS2FJ4kGrQX+vAfDsUZG4jra3Bh05cWcHvID8XZ7JPRcoYam8NJpzB9BiW3nSKSPHqL9N5BMhtrKHPLQ8CKKiyZA7R2l/6j4zWsqFE6o= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 178577365288747.69832721764658; Mon, 3 Aug 2026 09:14:12 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wqvHv-0006Pv-BC; Mon, 03 Aug 2026 12:13:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHW-00066G-5T; Mon, 03 Aug 2026 12:12:50 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHS-00036Y-0z; Mon, 03 Aug 2026 12:12:49 -0400 Received: from pps.filterd (m0353729.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 673EHYhQ413703; Mon, 3 Aug 2026 16:12:37 GMT Received: from ppma21.wdc07v.mail.ibm.com (5b.69.3da9.ip4.static.sl-reverse.com [169.61.105.91]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs8fqhpnt-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:36 +0000 (GMT) Received: from pps.filterd (ppma21.wdc07v.mail.ibm.com [127.0.0.1]) by ppma21.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 673GBFxo011972; Mon, 3 Aug 2026 16:12:34 GMT Received: from smtprelay05.fra02v.mail.ibm.com ([9.218.2.225]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4fsv4jx6ab-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:34 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay05.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 673GCUIe50987342 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 16:12:30 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 95D2D20040; Mon, 3 Aug 2026 16:12:30 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 60AF22004B; Mon, 3 Aug 2026 16:12:30 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 16:12:30 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=s7XbP3NXFrOl+6eff IgLJ+MIGqKsuVCxmppm7IMXE1Y=; b=N8kK2IrlAwT6Xgs30ukIT+KaWEqnZ6JgP nWj1A3L8kAats1VfFl2Eq5Cgqr3Kut1eVlcdOvzw3jK7vncHpV1a2kE9/Fl8zcBa aKTtZwpq4onwS47pFhzI2PjtV+yyftMWQQDSwigCAdsfb0LBnvHGl0+CUMyJUfqh DCOupzjxvlgxeKegQLLFpUuqj04gm/ZqLKln/wi6RiMpz/83y0R0MLRTy0vBQNC8 wQLSNn5Fy6Qy4DgBCdHLZc+ipFZKUhSycRMeID7RpfFXfvLwRHzdi47upaMaBFKW l6WeAEcDRFPlCwEdNAb5lr8abbyIRdAUfEjLmmu6pUrkg2IMop++Q== From: Harald Freudenberger To: richard.henderson@linaro.org, iii@linux.ibm.com, david@kernel.org, thuth@redhat.com, berrange@redhat.com Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org, linux-s390@vger.kernel.org, dengler@linux.ibm.com, borntraeger@linux.ibm.com, fcallies@linux.ibm.com, cohuck@redhat.com Subject: [PATCH v13 01/18] target/s390x: Rework s390 cpacf implementations Date: Mon, 3 Aug 2026 18:12:18 +0200 Message-ID: <20260803161235.228704-2-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803161235.228704-1-freude@linux.ibm.com> References: <20260803161235.228704-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: E6UwKGLAku7sYe7YYZ1tXLom1r2tb3eD X-Proofpoint-ORIG-GUID: E6UwKGLAku7sYe7YYZ1tXLom1r2tb3eD X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX4LTdyTz70Z/j Hdn/WpD9rnOzux+32D05j9kzMpXtSfIuqxmIO4qDWHGgMiFdcgn/jc9jbjstHNHpuDRsn0KT+1L aCufYhxCuzbMfzVkRcKxV616PJCYQPw= X-Authority-Analysis: v=2.4 cv=K8cS2SWI c=1 sm=1 tr=0 ts=6a70bdf4 cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=uAbxVGIbfxUO_5tXvNgY:22 a=VnNF1IyMAAAA:8 a=4KKJp7DvKucWb6I3c-QA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX22Z4pzYKvg0I reCay0BNDCK/5wlG/9g3EMYIS0dBRfmnJDLDlKORTcg5XikHSECtMS1c50uIAZfMVsG9GqNVWcx Nv7QCUpD+5ruWdS8WPbcyyPHjPM7w5xjqdgGXi0eo310jawtLkFH/16UVTqYY5r+BTPBDrf6Kmv RZkgud/sQlq77IFNRf3s98em1ipLNngpzV89VrA1yTrmI8XHeI8xLn6evydz0FPJnOIpTkbm0fO e4iXVPEFJQ9WLvGaWquDXjDTU3kSqgwpAV/hrM0PCAPPHzaQlrmXQ9OBFuoJB4UxAa2UU43O+LU Iqgp1w2Q9/WCqxVClxtgLRcGbNrNW1t73AA5QMtkJ84bgrXjkWdovcmX/2LtTawj5IKVoRZFA1n LGIna/yqnPHuRnvEDhR0FJj3VeyI2asdptuO3dU+mWb4Uu0FeDqsKnmmIhNQA9G6eHB3IRmf4fW 5g0fqstfEUitaQB1FVw== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-03_03,2026-08-03_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 spamscore=0 impostorscore=0 bulkscore=0 priorityscore=1501 lowpriorityscore=0 malwarescore=0 phishscore=0 suspectscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030141 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=148.163.156.1; envelope-from=freude@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1785773654142158501 Content-Type: text/plain; charset="utf-8" Fix missing parts for MSA 9 kdsa and rework the cpacf handling code so that further extensions can be made in a clean and structured way. Introduce a new header file to hold defines, structs and function prototypes around s390 cpacf. Use the cpcaf function defines in the existing code. Reviewed-by: Holger Dengler Tested-by: Holger Dengler Reviewed-by: Ilya Leoshkevich Signed-off-by: Harald Freudenberger --- target/s390x/tcg/cpacf.h | 226 +++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 90 ++++++++++-- target/s390x/tcg/insn-data.h.inc | 1 + target/s390x/tcg/translate.c | 2 + 4 files changed, 306 insertions(+), 13 deletions(-) create mode 100644 target/s390x/tcg/cpacf.h diff --git a/target/s390x/tcg/cpacf.h b/target/s390x/tcg/cpacf.h new file mode 100644 index 0000000000..49496d39ed --- /dev/null +++ b/target/s390x/tcg/cpacf.h @@ -0,0 +1,226 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * s390x cpacf + * + */ + +#ifndef S390X_CPACF_H +#define S390X_CPACF_H + +/* + * Function codes for the KM instruction + */ +#define CPACF_KM_QUERY 0x00 +#define CPACF_KM_DEA 0x01 +#define CPACF_KM_TDEA_128 0x02 +#define CPACF_KM_TDEA_192 0x03 +#define CPACF_KM_AES_128 0x12 +#define CPACF_KM_AES_192 0x13 +#define CPACF_KM_AES_256 0x14 +#define CPACF_KM_PAES_128 0x1a +#define CPACF_KM_PAES_192 0x1b +#define CPACF_KM_PAES_256 0x1c +#define CPACF_KM_XTS_128 0x32 +#define CPACF_KM_XTS_256 0x34 +#define CPACF_KM_PXTS_128 0x3a +#define CPACF_KM_PXTS_256 0x3c +#define CPACF_KM_FULL_XTS_128 0x52 +#define CPACF_KM_FULL_XTS_256 0x54 +#define CPACF_KM_FULL_PXTS_128 0x5a +#define CPACF_KM_FULL_PXTS_256 0x5c + +/* + * Function codes for the KMC instruction + */ +#define CPACF_KMC_QUERY 0x00 +#define CPACF_KMC_DEA 0x01 +#define CPACF_KMC_TDEA_128 0x02 +#define CPACF_KMC_TDEA_192 0x03 +#define CPACF_KMC_AES_128 0x12 +#define CPACF_KMC_AES_192 0x13 +#define CPACF_KMC_AES_256 0x14 +#define CPACF_KMC_PAES_128 0x1a +#define CPACF_KMC_PAES_192 0x1b +#define CPACF_KMC_PAES_256 0x1c +#define CPACF_KMC_PRNG 0x43 + +/* + * Function codes for the KMCTR instruction + */ +#define CPACF_KMCTR_QUERY 0x00 +#define CPACF_KMCTR_DEA 0x01 +#define CPACF_KMCTR_TDEA_128 0x02 +#define CPACF_KMCTR_TDEA_192 0x03 +#define CPACF_KMCTR_AES_128 0x12 +#define CPACF_KMCTR_AES_192 0x13 +#define CPACF_KMCTR_AES_256 0x14 +#define CPACF_KMCTR_PAES_128 0x1a +#define CPACF_KMCTR_PAES_192 0x1b +#define CPACF_KMCTR_PAES_256 0x1c + +/* + * Function codes for the KIMD instruction + */ +#define CPACF_KIMD_QUERY 0x00 +#define CPACF_KIMD_SHA_1 0x01 +#define CPACF_KIMD_SHA_256 0x02 +#define CPACF_KIMD_SHA_512 0x03 +#define CPACF_KIMD_SHA3_224 0x20 +#define CPACF_KIMD_SHA3_256 0x21 +#define CPACF_KIMD_SHA3_384 0x22 +#define CPACF_KIMD_SHA3_512 0x23 +#define CPACF_KIMD_SHAKE_128 0x24 +#define CPACF_KIMD_SHAKE_256 0x25 +#define CPACF_KIMD_GHASH 0x41 + +/* + * Function codes for the KLMD instruction + */ +#define CPACF_KLMD_QUERY 0x00 +#define CPACF_KLMD_SHA_1 0x01 +#define CPACF_KLMD_SHA_256 0x02 +#define CPACF_KLMD_SHA_512 0x03 +#define CPACF_KLMD_SHA3_224 0x20 +#define CPACF_KLMD_SHA3_256 0x21 +#define CPACF_KLMD_SHA3_384 0x22 +#define CPACF_KLMD_SHA3_512 0x23 +#define CPACF_KLMD_SHAKE_128 0x24 +#define CPACF_KLMD_SHAKE_256 0x25 + +/* + * function codes for the KMAC instruction + */ +#define CPACF_KMAC_QUERY 0x00 +#define CPACF_KMAC_DEA 0x01 +#define CPACF_KMAC_TDEA_128 0x02 +#define CPACF_KMAC_TDEA_192 0x03 +#define CPACF_KMAC_AES_128 0x12 +#define CPACF_KMAC_AES_192 0x13 +#define CPACF_KMAC_AES_256 0x14 +#define CPACF_KMAC_PAES_128 0x1A +#define CPACF_KMAC_PAES_192 0x1B +#define CPACF_KMAC_PAES_256 0x1C +#define CPACF_KMAC_HMAC_SHA_224 0x70 +#define CPACF_KMAC_HMAC_SHA_256 0x71 +#define CPACF_KMAC_HMAC_SHA_384 0x72 +#define CPACF_KMAC_HMAC_SHA_512 0x73 +#define CPACF_KMAC_PHMAC_SHA_224 0x78 +#define CPACF_KMAC_PHMAC_SHA_256 0x79 +#define CPACF_KMAC_PHMAC_SHA_384 0x7a +#define CPACF_KMAC_PHMAC_SHA_512 0x7b + +/* + * Function codes for the PCKMO instruction + */ +#define CPACF_PCKMO_QUERY 0x00 +#define CPACF_PCKMO_ENC_DES_KEY 0x01 +#define CPACF_PCKMO_ENC_TDES_128_KEY 0x02 +#define CPACF_PCKMO_ENC_TDES_192_KEY 0x03 +#define CPACF_PCKMO_ENC_AES_128_KEY 0x12 +#define CPACF_PCKMO_ENC_AES_192_KEY 0x13 +#define CPACF_PCKMO_ENC_AES_256_KEY 0x14 +#define CPACF_PCKMO_ENC_AES_XTS_128_DOUBLE_KEY 0x14 +#define CPACF_PCKMO_ENC_AES_XTS_256_DOUBLE_KEY 0x16 +#define CPACF_PCKMO_ENC_ECC_P256_KEY 0x20 +#define CPACF_PCKMO_ENC_ECC_P384_KEY 0x21 +#define CPACF_PCKMO_ENC_ECC_P521_KEY 0x22 +#define CPACF_PCKMO_ENC_ECC_ED25519_KEY 0x28 +#define CPACF_PCKMO_ENC_ECC_ED448_KEY 0x29 +#define CPACF_PCKMO_ENC_HMAC_512_KEY 0x76 +#define CPACF_PCKMO_ENC_HMAC_1024_KEY 0x7a + +/* + * Function codes for the PRNO instruction + */ +#define CPACF_PRNO_QUERY 0x00 +#define CPACF_PRNO_SHA512_DRNG_GEN 0x03 +#define CPACF_PRNO_SHA512_DRNG_SEED 0x83 +#define CPACF_PRNO_TRNG_Q_R2C_RATIO 0x70 +#define CPACF_PRNO_TRNG 0x72 + +/* + * Function codes for the KMA instruction + */ +#define CPACF_KMA_QUERY 0x00 +#define CPACF_KMA_GCM_AES_128 0x12 +#define CPACF_KMA_GCM_AES_192 0x13 +#define CPACF_KMA_GCM_AES_256 0x14 +#define CPACF_KMA_GCM_PAES_128 0x1A +#define CPACF_KMA_GCM_PAES_192 0x1B +#define CPACF_KMA_GCM_PAES_256 0x1C + +/* + * Function codes for the KMF instruction + */ +#define CPACF_KMF_QUERY 0 +#define CPACF_KMF_DEA 1 +#define CPACF_KMF_TDEA_128 2 +#define CPACF_KMF_TDEA_192 3 +#define CPACF_KMF_AES_128 18 +#define CPACF_KMF_AES_192 19 +#define CPACF_KMF_AES_256 20 +#define CPACF_KMF_PAES_128 26 +#define CPACF_KMF_PAES_192 27 +#define CPACF_KMF_PAES_256 28 + +/* + * Function codes for the KMO instruction + */ +#define CPACF_KMO_QUERY 0 +#define CPACF_KMO_DEA 1 +#define CPACF_KMO_TDEA_128 2 +#define CPACF_KMO_TDEA_192 3 +#define CPACF_KMO_AES_128 18 +#define CPACF_KMO_AES_192 19 +#define CPACF_KMO_AES_256 20 +#define CPACF_KMO_PAES_128 26 +#define CPACF_KMO_PAES_192 27 +#define CPACF_KMO_PAES_256 28 + +/* + * Function codes for the PCC instruction + */ +#define CPACF_PCC_QUERY 0 +#define CPACF_PCC_CMAC_DEA 1 +#define CPACF_PCC_CMAC_TDEA_128 2 +#define CPACF_PCC_CMAC_TDEA_192 3 +#define CPACF_PCC_CMAC_AES_128 18 +#define CPACF_PCC_CMAC_AES_192 19 +#define CPACF_PCC_CMAC_AES_256 20 +#define CPACF_PCC_CMAC_PAES_128 26 +#define CPACF_PCC_CMAC_PAES_192 27 +#define CPACF_PCC_CMAC_PAES_256 28 +#define CPACF_PCC_XTS_AES_128 50 +#define CPACF_PCC_XTS_AES_256 52 +#define CPACF_PCC_XTS_PAES_128 58 +#define CPACF_PCC_XTS_PAES_256 60 +#define CPACF_PCC_SM_P256 64 +#define CPACF_PCC_SM_P384 65 +#define CPACF_PCC_SM_P521 66 +#define CPACF_PCC_SM_ED25519 72 +#define CPACF_PCC_SM_ED448 73 +#define CPACF_PCC_SM_X25519 80 +#define CPACF_PCC_SM_X448 81 + +/* + * Function codes for the KDSA instruction + */ +#define CPACF_KDSA_QUERY 0 +#define CPACF_KDSA_VERIFY_P256 1 +#define CPACF_KDSA_VERIFY_P384 2 +#define CPACF_KDSA_VERIFY_P521 3 +#define CPACF_KDSA_SIGN_P256 9 +#define CPACF_KDSA_SIGN_P384 10 +#define CPACF_KDSA_SIGN_P521 11 +#define CPACF_KDSA_PSIGN_P256 17 +#define CPACF_KDSA_PSIGN_P384 18 +#define CPACF_KDSA_PSIGN_P521 19 +#define CPACF_KDSA_VERIFY_ED25519 32 +#define CPACF_KDSA_VERIFY_ED448 36 +#define CPACF_KDSA_SIGN_ED25519 40 +#define CPACF_KDSA_SIGN_ED448 44 +#define CPACF_KDSA_PSIGN_ED25519 48 +#define CPACF_KDSA_PSIGN_ED448 52 + +#endif /* S390X_CPACF_H */ diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_hel= per.c index 8fe0a22219..987bc72ae9 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -19,6 +19,7 @@ #include "exec/helper-proto.h" #include "accel/tcg/cpu-ldst-common.h" #include "accel/tcg/cpu-mmu-index.h" +#include "target/s390x/tcg/cpacf.h" =20 static uint64_t R(uint64_t x, int c) { @@ -268,6 +269,57 @@ static void fill_buf_random(CPUS390XState *env, const = int mmu_idx, uintptr_t ra, } } =20 +static int cpacf_kimd(CPUS390XState *env, const int mmu_idx, const uintptr= _t ra, + uint32_t r1, uint32_t r2, uint32_t r3, uint8_t fc) +{ + int rc =3D 0; + + switch (fc) { + case CPACF_KIMD_SHA_512: + rc =3D cpacf_sha512(env, mmu_idx, ra, env->regs[1], &env->regs[r2], + &env->regs[r2 + 1], S390_FEAT_TYPE_KIMD); + break; + default: + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } + + return rc; +} + +static int cpacf_klmd(CPUS390XState *env, const int mmu_idx, const uintptr= _t ra, + uint32_t r1, uint32_t r2, uint32_t r3, uint8_t fc) +{ + int rc =3D 0; + + switch (fc) { + case CPACF_KLMD_SHA_512: + rc =3D cpacf_sha512(env, mmu_idx, ra, env->regs[1], &env->regs[r2], + &env->regs[r2 + 1], S390_FEAT_TYPE_KLMD); + break; + default: + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } + + return rc; +} + +static int cpacf_ppno(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint32_t r1, uint32_t r2, uint32_t r3, uint8_t fc) +{ + int rc =3D 0; + + switch (fc) { + case CPACF_PRNO_TRNG: + fill_buf_random(env, mmu_idx, ra, &env->regs[r1], &env->regs[r1 + = 1]); + fill_buf_random(env, mmu_idx, ra, &env->regs[r2], &env->regs[r2 + = 1]); + break; + default: + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } + + return rc; +} + uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_= t r3, uint32_t type) { @@ -278,13 +330,15 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1,= uint32_t r2, uint32_t r3, uint8_t subfunc[16] =3D { 0 }; uint64_t param_addr; MemOpIdx oi; + int rc =3D 0; =20 switch (type) { - case S390_FEAT_TYPE_KMAC: + case S390_FEAT_TYPE_KDSA: case S390_FEAT_TYPE_KIMD: case S390_FEAT_TYPE_KLMD: - case S390_FEAT_TYPE_PCKMO: + case S390_FEAT_TYPE_KMAC: case S390_FEAT_TYPE_PCC: + case S390_FEAT_TYPE_PCKMO: if (mod) { tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); } @@ -296,25 +350,35 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1,= uint32_t r2, uint32_t r3, tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); } =20 - switch (fc) { - case 0: /* query subfunction */ + /* handle query subfunction */ + if (fc =3D=3D 0) { oi =3D make_memop_idx(MO_8, mmu_idx); - for (int i =3D 0; i < 16; i++) { + for (int i =3D 0; i < sizeof(subfunc); i++) { param_addr =3D wrap_address(env, env->regs[1] + i); cpu_stb_mmu(env, param_addr, subfunc[i], oi, ra); } + goto out; + } + + switch (type) { + case S390_FEAT_TYPE_KIMD: + rc =3D cpacf_kimd(env, mmu_idx, ra, r1, r2, r3, fc); break; - case 3: /* CPACF_*_SHA_512 */ - return cpacf_sha512(env, mmu_idx, ra, env->regs[1], &env->regs[r2], - &env->regs[r2 + 1], type); - case 114: /* CPACF_PRNO_TRNG */ - fill_buf_random(env, mmu_idx, ra, &env->regs[r1], &env->regs[r1 + = 1]); - fill_buf_random(env, mmu_idx, ra, &env->regs[r2], &env->regs[r2 + = 1]); + case S390_FEAT_TYPE_KLMD: + rc =3D cpacf_klmd(env, mmu_idx, ra, r1, r2, r3, fc); + break; + case S390_FEAT_TYPE_PPNO: + rc =3D cpacf_ppno(env, mmu_idx, ra, r1, r2, r3, fc); + break; + case S390_FEAT_TYPE_KDSA: + case S390_FEAT_TYPE_KMAC: + /* subfunctions (other than query) are not implemented yet */ + tcg_s390_program_interrupt(env, PGM_OPERATION, ra); break; default: - /* we don't implement any other subfunction yet */ g_assert_not_reached(); } =20 - return 0; +out: + return rc; } diff --git a/target/s390x/tcg/insn-data.h.inc b/target/s390x/tcg/insn-data.= h.inc index 0d5392eac5..6a0a7aacda 100644 --- a/target/s390x/tcg/insn-data.h.inc +++ b/target/s390x/tcg/insn-data.h.inc @@ -1015,6 +1015,7 @@ D(0xb92e, KM, RRE, MSA, 0, 0, 0, 0, msa, 0, S390_FEAT_TYPE_KM) D(0xb92f, KMC, RRE, MSA, 0, 0, 0, 0, msa, 0, S390_FEAT_TYPE_KMC) D(0xb929, KMA, RRF_b, MSA8, 0, 0, 0, 0, msa, 0, S390_FEAT_TYPE_KMA) + D(0xb93a, KDSA, RRE, MSA9, 0, 0, 0, 0, msa, 0, S390_FEAT_TYPE_KDS= A) E(0xb93c, PPNO, RRE, MSA5, 0, 0, 0, 0, msa, 0, S390_FEAT_TYPE_PPN= O, IF_IO) D(0xb93e, KIMD, RRE, MSA, 0, 0, 0, 0, msa, 0, S390_FEAT_TYPE_KIM= D) D(0xb93f, KLMD, RRE, MSA, 0, 0, 0, 0, msa, 0, S390_FEAT_TYPE_KLM= D) diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c index 82165ac1ec..cef1b55149 100644 --- a/target/s390x/tcg/translate.c +++ b/target/s390x/tcg/translate.c @@ -2592,6 +2592,7 @@ static DisasJumpType op_msa(DisasContext *s, DisasOps= *o) /* FALL THROUGH */ case S390_FEAT_TYPE_PCKMO: case S390_FEAT_TYPE_PCC: + case S390_FEAT_TYPE_KDSA: break; default: g_assert_not_reached(); @@ -6046,6 +6047,7 @@ enum DisasInsnEnum { #define FAC_MSA4 S390_FEAT_MSA_EXT_4 /* msa-extension-4 facility */ #define FAC_MSA5 S390_FEAT_MSA_EXT_5 /* msa-extension-5 facility */ #define FAC_MSA8 S390_FEAT_MSA_EXT_8 /* msa-extension-8 facility */ +#define FAC_MSA9 S390_FEAT_MSA_EXT_9 /* msa-extension-9 facility */ #define FAC_ECT S390_FEAT_EXTRACT_CPU_TIME #define FAC_PCI S390_FEAT_ZPCI /* z/PCI facility */ #define FAC_AIS S390_FEAT_ADAPTER_INT_SUPPRESSION --=20 2.43.0 From nobody Mon Sep 28 01:12:31 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1785773705; cv=none; d=zohomail.com; s=zohoarc; b=OT9d4xUY+hgPf/QWiQaMvN1cNp90E8fquLiACjsCHo6t1stU0iAz8fOWsbfC7/6O/Jysi3gQciSsKQP6Ek3EdQMoWjYsbHkkDuwsHyjB1KQ26Zfs9dlt4FPpG0eljYv3hIt0oiEworXVp6HZ+eG3UonDMV1wPQKYaMQEceaS25c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785773705; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=eb25SZPwZNi2FSM5vWIidIdiqEslosb0SmqiUcMFblc=; b=RWsOKvYYLteqzQ2d5CLL4Cp74nLdGs/u9hSVngPC5cxkxPqGYJlQDy+sDizICwyUk8JvTHvpYJFtwNUQ6CM9KqdoaoVu/ElLx5MmGZr3NqehGwISxRmKtb0XC62wf2zjuRlIzMpKLA68KvcStDHCdioPIBfzg1z/7s9UtC8Poqw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785773705869499.0133714658542; Mon, 3 Aug 2026 09:15:05 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wqvHt-0006I3-0B; Mon, 03 Aug 2026 12:13:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHQ-00060w-Hg; Mon, 03 Aug 2026 12:12:44 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHN-00034i-LX; Mon, 03 Aug 2026 12:12:44 -0400 Received: from pps.filterd (m0356516.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 673EI5cs2202716; Mon, 3 Aug 2026 16:12:36 GMT Received: from ppma22.wdc07v.mail.ibm.com (5c.69.3da9.ip4.static.sl-reverse.com [169.61.105.92]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs67hhp3m-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:35 +0000 (GMT) Received: from pps.filterd (ppma22.wdc07v.mail.ibm.com [127.0.0.1]) by ppma22.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 673GBJrw020100; Mon, 3 Aug 2026 16:12:35 GMT Received: from smtprelay05.fra02v.mail.ibm.com ([9.218.2.225]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4fsugvx8y0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:34 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay05.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 673GCVwV50987344 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 16:12:31 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DC52720040; Mon, 3 Aug 2026 16:12:30 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9BFC420043; Mon, 3 Aug 2026 16:12:30 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 16:12:30 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=eb25SZPwZNi2FSM5v WIidIdiqEslosb0SmqiUcMFblc=; b=U38r+d2L00lr048sCoALf0+QD1+rvZdp4 hXVkIWasVPOXkG2YSd4fnRhlV0TnpwEBpvswDJJVqwXedFrGsRrcuKHFJEA+5u7u CZMce8MCWFGqW+lImyT9i0djOi+nfNbf5NSmTfEv5B+eXFtFmerDPWGP5TKZBdFR ZMo5mNt2C56fOpIn0GMkbgowE+BV5wTwdMwmTMXh68munEfug9P2xmQ55ekF3paP 3DmD70kjkGr/SfkETywc9PENnE1x73FqBDaXF0veCtDgo8TAhOWofM5lNvftKszV ToaY3xwh/07UGctLM2bCD5fUxd2bWvnfDPVYvDvr+VComa4zWFzOg== From: Harald Freudenberger To: richard.henderson@linaro.org, iii@linux.ibm.com, david@kernel.org, thuth@redhat.com, berrange@redhat.com Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org, linux-s390@vger.kernel.org, dengler@linux.ibm.com, borntraeger@linux.ibm.com, fcallies@linux.ibm.com, cohuck@redhat.com Subject: [PATCH v13 02/18] target/s390x: Move cpacf sha512 code into a new file Date: Mon, 3 Aug 2026 18:12:19 +0200 Message-ID: <20260803161235.228704-3-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803161235.228704-1-freude@linux.ibm.com> References: <20260803161235.228704-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX1SjIZBTcqbsY EcIeuC/5hh8rIYywjIrAJj4cOawzqtumicOXVSiNLwhkzTuuA0BlSl1Y1lPpqFIZG8sGheCWXG6 ZpBNl/AX7lcnub4tBGTHYQkKSReCm38= X-Authority-Analysis: v=2.4 cv=I7VVgtgg c=1 sm=1 tr=0 ts=6a70bdf3 cx=c_pps a=5BHTudwdYE3Te8bg5FgnPg==:117 a=5BHTudwdYE3Te8bg5FgnPg==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=Y2IxJ9c9Rs8Kov3niI8_:22 a=VnNF1IyMAAAA:8 a=UGG5zPGqAAAA:8 a=yMKeI-deMsSePwiaAVEA:9 a=17ibUXfGiVyGqR_YBevW:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX1PMf5NUhZDDQ D+xqHiYyn0cBlILY4+StRJVR/FrIBKQpKrpBB6LbUwqzqyJ7Kc8FR5MHfziNmTztnQqUJnCIaCj lp93bOM+bi5y2xBstB8sTvvMuxIB4Iu07On0bwhIfELAr2k3oCITDOBnAHf9eUHbskPLvfbVUe6 EBqHpB653tLv7HgaWsieMG2C5fjYQjdS+rC8TtUUltPpRztzyjmo771PGpyhqP33PQsvF1pK4MU LHJNjgYsvQyveZU/mAgGecqM01y/rfiultYZQ02YL7ft6ePdQWqu6JWOCbQ/9HTBForExZVAH7n fw/qpJsihesHSLQ1znwU0wX9Dok/dMip2vRp+zy7pxDFmMgxRXya5l1i9xVMiaZe3VHPUHFtZJR bB2ZtLlXr9FMEHw1Yqswq8ksrwjftSYibbD5PFPCm63i3J4XYnY0slxPPeG4AhuIP48fBOfyBZg WOoLwpcFSYzxYwKALBA== X-Proofpoint-ORIG-GUID: 2f_FRaOLgACTaTkjPaVWS5qTWwd_1F_i X-Proofpoint-GUID: 2f_FRaOLgACTaTkjPaVWS5qTWwd_1F_i X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-03_03,2026-08-03_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 impostorscore=0 clxscore=1015 priorityscore=1501 suspectscore=0 malwarescore=0 adultscore=0 lowpriorityscore=0 phishscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030141 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=148.163.158.5; envelope-from=freude@linux.ibm.com; helo=mx0b-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1785773706294158500 Content-Type: text/plain; charset="utf-8" Move the cpacf sha512 implementation into a new file cpacf_sha512.c. Add this new file to the build and use the cpacf.h header file storing function the prototypes. Signed-off-by: Harald Freudenberger Tested-by: Holger Dengler Reviewed-by: Finn Callies Reviewed-by: Ilya Leoshkevich Reviewed-by: Holger Dengler --- target/s390x/tcg/cpacf.h | 5 + target/s390x/tcg/cpacf_sha512.c | 241 +++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 222 ---------------------------- target/s390x/tcg/meson.build | 1 + 4 files changed, 247 insertions(+), 222 deletions(-) create mode 100644 target/s390x/tcg/cpacf_sha512.c diff --git a/target/s390x/tcg/cpacf.h b/target/s390x/tcg/cpacf.h index 49496d39ed..3b89bc5cd7 100644 --- a/target/s390x/tcg/cpacf.h +++ b/target/s390x/tcg/cpacf.h @@ -223,4 +223,9 @@ #define CPACF_KDSA_PSIGN_ED25519 48 #define CPACF_KDSA_PSIGN_ED448 52 =20 +/* from cpacf_sha512.c */ +int cpacf_sha512(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *message_reg, uint64_t *len= _reg, + uint32_t type); + #endif /* S390X_CPACF_H */ diff --git a/target/s390x/tcg/cpacf_sha512.c b/target/s390x/tcg/cpacf_sha51= 2.c new file mode 100644 index 0000000000..ebfecc70f7 --- /dev/null +++ b/target/s390x/tcg/cpacf_sha512.c @@ -0,0 +1,241 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * s390 cpacf sha512 + * + * Copyright (C) 2022 Jason A. Donenfeld . + * All Rights Reserved. + * + * Authors: + * Jason A. Donenfeld + */ + +#include "qemu/osdep.h" +#include "s390x-internal.h" +#include "tcg_s390x.h" +#include "exec/helper-proto.h" +#include "accel/tcg/cpu-ldst-common.h" +#include "accel/tcg/cpu-mmu-index.h" +#include "target/s390x/tcg/cpacf.h" + +static uint64_t R(uint64_t x, int c) +{ + return (x >> c) | (x << (64 - c)); +} +static uint64_t Ch(uint64_t x, uint64_t y, uint64_t z) +{ + return (x & y) ^ (~x & z); +} +static uint64_t Maj(uint64_t x, uint64_t y, uint64_t z) +{ + return (x & y) ^ (x & z) ^ (y & z); +} +static uint64_t Sigma0(uint64_t x) +{ + return R(x, 28) ^ R(x, 34) ^ R(x, 39); +} +static uint64_t Sigma1(uint64_t x) +{ + return R(x, 14) ^ R(x, 18) ^ R(x, 41); +} +static uint64_t sigma0(uint64_t x) +{ + return R(x, 1) ^ R(x, 8) ^ (x >> 7); +} +static uint64_t sigma1(uint64_t x) +{ + return R(x, 19) ^ R(x, 61) ^ (x >> 6); +} + +static const uint64_t K[80] =3D { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, + 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, + 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, + 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, + 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, + 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, + 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, + 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, + 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, + 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, + 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, + 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, + 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, + 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, + 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, + 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, + 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, + 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, + 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, + 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, + 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; + +/* a is icv/ocv, w is a single message block. w will get reused internally= . */ +static void sha512_bda(uint64_t a[8], uint64_t w[16]) +{ + uint64_t t, z[8], b[8]; + int i, j; + + memcpy(z, a, sizeof(z)); + for (i =3D 0; i < 80; i++) { + memcpy(b, a, sizeof(b)); + + t =3D a[7] + Sigma1(a[4]) + Ch(a[4], a[5], a[6]) + K[i] + w[i % 16= ]; + b[7] =3D t + Sigma0(a[0]) + Maj(a[0], a[1], a[2]); + b[3] +=3D t; + for (j =3D 0; j < 8; ++j) { + a[(j + 1) % 8] =3D b[j]; + } + if (i % 16 =3D=3D 15) { + for (j =3D 0; j < 16; ++j) { + w[j] +=3D w[(j + 9) % 16] + sigma0(w[(j + 1) % 16]) + + sigma1(w[(j + 14) % 16]); + } + } + } + + for (i =3D 0; i < 8; i++) { + a[i] +=3D z[i]; + } +} + +/* a is icv/ocv, w is a single message block that needs be64 conversion. */ +static void sha512_bda_be64(uint64_t a[8], uint64_t w[16]) +{ + uint64_t t[16]; + int i; + + for (i =3D 0; i < 16; i++) { + t[i] =3D be64_to_cpu(w[i]); + } + sha512_bda(a, t); +} + +static void sha512_read_icv(CPUS390XState *env, const int mmu_idx, + uint64_t addr, uint64_t a[8], uintptr_t ra) +{ + const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_64 | MO_UNALN, mmu_idx= ); + + for (int i =3D 0; i < 8; i++, addr +=3D 8) { + a[i] =3D cpu_ldq_mmu(env, wrap_address(env, addr), oi, ra); + } +} + +static void sha512_write_ocv(CPUS390XState *env, const int mmu_idx, + uint64_t addr, uint64_t a[8], uintptr_t ra) +{ + const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_64 | MO_UNALN, mmu_idx= ); + + for (int i =3D 0; i < 8; i++, addr +=3D 8) { + cpu_stq_mmu(env, wrap_address(env, addr), a[i], oi, ra); + } +} + +static void sha512_read_block(CPUS390XState *env, const int mmu_idx, + uint64_t addr, uint64_t a[16], uintptr_t ra) +{ + const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_64 | MO_UNALN, mmu_idx= ); + + for (int i =3D 0; i < 16; i++, addr +=3D 8) { + a[i] =3D cpu_ldq_mmu(env, wrap_address(env, addr), oi, ra); + } +} + +static void sha512_read_mbl_be64(CPUS390XState *env, const int mmu_idx, + uint64_t addr, uint8_t a[16], uintptr_t r= a) +{ + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + + for (int i =3D 0; i < 16; i++, addr +=3D 1) { + a[i] =3D cpu_ldb_mmu(env, wrap_address(env, addr), oi, ra); + } +} + +int cpacf_sha512(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *message_reg, uint64_t *len= _reg, + uint32_t type) +{ + enum { MAX_BLOCKS_PER_RUN =3D 64 }; /* Arbitrary: keep interactivity. = */ + uint64_t len =3D *len_reg, a[8], processed =3D 0; + int i, message_reg_len =3D 64; + + g_assert(type =3D=3D S390_FEAT_TYPE_KIMD || type =3D=3D S390_FEAT_TYPE= _KLMD); + + if (!(env->psw.mask & PSW_MASK_64)) { + len =3D (uint32_t)len; + message_reg_len =3D (env->psw.mask & PSW_MASK_32) ? 32 : 24; + } + + /* KIMD: length has to be properly aligned. */ + if (type =3D=3D S390_FEAT_TYPE_KIMD && !QEMU_IS_ALIGNED(len, 128)) { + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } + + sha512_read_icv(env, mmu_idx, param_addr, a, ra); + + /* Process full blocks first. */ + for (; len >=3D 128; len -=3D 128, processed +=3D 128) { + uint64_t w[16]; + + if (processed >=3D MAX_BLOCKS_PER_RUN * 128) { + break; + } + + sha512_read_block(env, mmu_idx, *message_reg + processed, w, ra); + sha512_bda(a, w); + } + + /* KLMD: Process partial/empty block last. */ + if (type =3D=3D S390_FEAT_TYPE_KLMD && len < 128) { + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + uint8_t x[128]; + + /* Read the remainder of the message byte-per-byte. */ + for (i =3D 0; i < len; i++) { + uint64_t addr =3D wrap_address(env, *message_reg + processed += i); + + x[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + /* Pad the remainder with zero and set the top bit. */ + memset(x + len, 0, 128 - len); + x[len] =3D 128; + + /* + * Place the MBL either into this block (if there is space left), + * or use an additional one. + */ + if (len < 112) { + sha512_read_mbl_be64(env, mmu_idx, param_addr + 64, x + 112, r= a); + } + sha512_bda_be64(a, (uint64_t *)x); + + if (len >=3D 112) { + memset(x, 0, 112); + sha512_read_mbl_be64(env, mmu_idx, param_addr + 64, x + 112, r= a); + sha512_bda_be64(a, (uint64_t *)x); + } + + processed +=3D len; + len =3D 0; + } + + /* + * Modify memory after we read all inputs and modify registers only af= ter + * writing memory succeeded. + * + * TODO: if writing fails halfway through (e.g., when crossing page + * boundaries), we're in trouble. We'd need something like access_prep= are(). + */ + sha512_write_ocv(env, mmu_idx, param_addr, a, ra); + *message_reg =3D deposit64(*message_reg, 0, message_reg_len, + *message_reg + processed); + *len_reg -=3D processed; + return !len ? 0 : 3; +} diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_hel= per.c index 987bc72ae9..dba46baa0d 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -21,228 +21,6 @@ #include "accel/tcg/cpu-mmu-index.h" #include "target/s390x/tcg/cpacf.h" =20 -static uint64_t R(uint64_t x, int c) -{ - return (x >> c) | (x << (64 - c)); -} -static uint64_t Ch(uint64_t x, uint64_t y, uint64_t z) -{ - return (x & y) ^ (~x & z); -} -static uint64_t Maj(uint64_t x, uint64_t y, uint64_t z) -{ - return (x & y) ^ (x & z) ^ (y & z); -} -static uint64_t Sigma0(uint64_t x) -{ - return R(x, 28) ^ R(x, 34) ^ R(x, 39); -} -static uint64_t Sigma1(uint64_t x) -{ - return R(x, 14) ^ R(x, 18) ^ R(x, 41); -} -static uint64_t sigma0(uint64_t x) -{ - return R(x, 1) ^ R(x, 8) ^ (x >> 7); -} -static uint64_t sigma1(uint64_t x) -{ - return R(x, 19) ^ R(x, 61) ^ (x >> 6); -} - -static const uint64_t K[80] =3D { - 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, - 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, - 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, - 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, - 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, - 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, - 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, - 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, - 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, - 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, - 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, - 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, - 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, - 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, - 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, - 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, - 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, - 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, - 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, - 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, - 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, - 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, - 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, - 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, - 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, - 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, - 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL -}; - -/* a is icv/ocv, w is a single message block. w will get reused internally= . */ -static void sha512_bda(uint64_t a[8], uint64_t w[16]) -{ - uint64_t t, z[8], b[8]; - int i, j; - - memcpy(z, a, sizeof(z)); - for (i =3D 0; i < 80; i++) { - memcpy(b, a, sizeof(b)); - - t =3D a[7] + Sigma1(a[4]) + Ch(a[4], a[5], a[6]) + K[i] + w[i % 16= ]; - b[7] =3D t + Sigma0(a[0]) + Maj(a[0], a[1], a[2]); - b[3] +=3D t; - for (j =3D 0; j < 8; ++j) { - a[(j + 1) % 8] =3D b[j]; - } - if (i % 16 =3D=3D 15) { - for (j =3D 0; j < 16; ++j) { - w[j] +=3D w[(j + 9) % 16] + sigma0(w[(j + 1) % 16]) + - sigma1(w[(j + 14) % 16]); - } - } - } - - for (i =3D 0; i < 8; i++) { - a[i] +=3D z[i]; - } -} - -/* a is icv/ocv, w is a single message block that needs be64 conversion. */ -static void sha512_bda_be64(uint64_t a[8], uint64_t w[16]) -{ - uint64_t t[16]; - int i; - - for (i =3D 0; i < 16; i++) { - t[i] =3D be64_to_cpu(w[i]); - } - sha512_bda(a, t); -} - -static void sha512_read_icv(CPUS390XState *env, const int mmu_idx, - uint64_t addr, uint64_t a[8], uintptr_t ra) -{ - const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_64 | MO_UNALN, mmu_idx= ); - - for (int i =3D 0; i < 8; i++, addr +=3D 8) { - a[i] =3D cpu_ldq_mmu(env, wrap_address(env, addr), oi, ra); - } -} - -static void sha512_write_ocv(CPUS390XState *env, const int mmu_idx, - uint64_t addr, uint64_t a[8], uintptr_t ra) -{ - const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_64 | MO_UNALN, mmu_idx= ); - - for (int i =3D 0; i < 8; i++, addr +=3D 8) { - cpu_stq_mmu(env, wrap_address(env, addr), a[i], oi, ra); - } -} - -static void sha512_read_block(CPUS390XState *env, const int mmu_idx, - uint64_t addr, uint64_t a[16], uintptr_t ra) -{ - const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_64 | MO_UNALN, mmu_idx= ); - - for (int i =3D 0; i < 16; i++, addr +=3D 8) { - a[i] =3D cpu_ldq_mmu(env, wrap_address(env, addr), oi, ra); - } -} - -static void sha512_read_mbl_be64(CPUS390XState *env, const int mmu_idx, - uint64_t addr, uint8_t a[16], uintptr_t r= a) -{ - const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); - - for (int i =3D 0; i < 16; i++, addr +=3D 1) { - a[i] =3D cpu_ldb_mmu(env, wrap_address(env, addr), oi, ra); - } -} - -static int cpacf_sha512(CPUS390XState *env, const int mmu_idx, uintptr_t r= a, - uint64_t param_addr, uint64_t *message_reg, - uint64_t *len_reg, uint32_t type) -{ - enum { MAX_BLOCKS_PER_RUN =3D 64 }; /* Arbitrary: keep interactivity. = */ - uint64_t len =3D *len_reg, a[8], processed =3D 0; - int i, message_reg_len =3D 64; - - g_assert(type =3D=3D S390_FEAT_TYPE_KIMD || type =3D=3D S390_FEAT_TYPE= _KLMD); - - if (!(env->psw.mask & PSW_MASK_64)) { - len =3D (uint32_t)len; - message_reg_len =3D (env->psw.mask & PSW_MASK_32) ? 32 : 24; - } - - /* KIMD: length has to be properly aligned. */ - if (type =3D=3D S390_FEAT_TYPE_KIMD && !QEMU_IS_ALIGNED(len, 128)) { - tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); - } - - sha512_read_icv(env, mmu_idx, param_addr, a, ra); - - /* Process full blocks first. */ - for (; len >=3D 128; len -=3D 128, processed +=3D 128) { - uint64_t w[16]; - - if (processed >=3D MAX_BLOCKS_PER_RUN * 128) { - break; - } - - sha512_read_block(env, mmu_idx, *message_reg + processed, w, ra); - sha512_bda(a, w); - } - - /* KLMD: Process partial/empty block last. */ - if (type =3D=3D S390_FEAT_TYPE_KLMD && len < 128) { - const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); - uint8_t x[128]; - - /* Read the remainder of the message byte-per-byte. */ - for (i =3D 0; i < len; i++) { - uint64_t addr =3D wrap_address(env, *message_reg + processed += i); - - x[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } - /* Pad the remainder with zero and set the top bit. */ - memset(x + len, 0, 128 - len); - x[len] =3D 128; - - /* - * Place the MBL either into this block (if there is space left), - * or use an additional one. - */ - if (len < 112) { - sha512_read_mbl_be64(env, mmu_idx, param_addr + 64, x + 112, r= a); - } - sha512_bda_be64(a, (uint64_t *)x); - - if (len >=3D 112) { - memset(x, 0, 112); - sha512_read_mbl_be64(env, mmu_idx, param_addr + 64, x + 112, r= a); - sha512_bda_be64(a, (uint64_t *)x); - } - - processed +=3D len; - len =3D 0; - } - - /* - * Modify memory after we read all inputs and modify registers only af= ter - * writing memory succeeded. - * - * TODO: if writing fails halfway through (e.g., when crossing page - * boundaries), we're in trouble. We'd need something like access_prep= are(). - */ - sha512_write_ocv(env, mmu_idx, param_addr, a, ra); - *message_reg =3D deposit64(*message_reg, 0, message_reg_len, - *message_reg + processed); - *len_reg -=3D processed; - return !len ? 0 : 3; -} - static void fill_buf_random(CPUS390XState *env, const int mmu_idx, uintptr= _t ra, uint64_t *buf_reg, uint64_t *len_reg) { diff --git a/target/s390x/tcg/meson.build b/target/s390x/tcg/meson.build index 36cb0e079e..54a87393a3 100644 --- a/target/s390x/tcg/meson.build +++ b/target/s390x/tcg/meson.build @@ -5,6 +5,7 @@ s390x_ss.add(when: 'CONFIG_TCG', if_true: files( )) s390x_common_ss.add(when: 'CONFIG_TCG', if_true: files( 'cc_helper.c', + 'cpacf_sha512.c', 'crypto_helper.c', 'excp_helper.c', 'fpu_helper.c', --=20 2.43.0 From nobody Mon Sep 28 01:12:31 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1785773625; cv=none; d=zohomail.com; s=zohoarc; b=Or3aDubYPhBfJTQK4Vtgeq+wYq8fRMpyP58fVkG3SRfSgYasiigBLYW44J7LnneWjpshnGM6CArlgVxRlUDegGybSsEx6AF0wTu7ZYgB40/TnjBoLQM08lN14NsW1MOR40hyVof2kaVdCrhon4eETMgsztFRjoz6y9PVAOBZLes= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785773625; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=gF/fP+cgAZpgFRTvskZ7voOM3S0do/ZvOq5fCTXHGz0=; b=FvsiUa29Qk7OCXk7RTgJquuia8aGVSmLc/242n3udsKBXKkSQM8Ym3pby7CHq1ik1gYDs00hOwuEp3XHOahw03OX39snXy2gGP3pfHbZc3JVqIN/5lAGvJGZ1cQL679H9a6pRv+VtoU94DI383TmaEhAcRaP5ofWZ3UTgZGBxzo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785773625839374.99670589008656; Mon, 3 Aug 2026 09:13:45 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wqvHv-0006RL-W6; Mon, 03 Aug 2026 12:13:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHT-00064J-Vc; Mon, 03 Aug 2026 12:12:48 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHQ-00035Q-EJ; Mon, 03 Aug 2026 12:12:47 -0400 Received: from pps.filterd (m0353729.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 673EHksQ413967; Mon, 3 Aug 2026 16:12:37 GMT Received: from ppma21.wdc07v.mail.ibm.com (5b.69.3da9.ip4.static.sl-reverse.com [169.61.105.91]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs8fqhpnv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:36 +0000 (GMT) Received: from pps.filterd (ppma21.wdc07v.mail.ibm.com [127.0.0.1]) by ppma21.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 673GBFxp011972; Mon, 3 Aug 2026 16:12:35 GMT Received: from smtprelay06.fra02v.mail.ibm.com ([9.218.2.230]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4fsv4jx6ae-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:35 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay06.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 673GCVsB29688098 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 16:12:31 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2377420040; Mon, 3 Aug 2026 16:12:31 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E1B0A2004B; Mon, 3 Aug 2026 16:12:30 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 16:12:30 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=gF/fP+cgAZpgFRTvs kZ7voOM3S0do/ZvOq5fCTXHGz0=; b=qsTHxKkaB+/v/2sPzu8uojYyUy7VGwgj4 XIwVkDQieGBBLK5+KXd0udD7ZDVBKwnjFRUEkQ90szhxZyzT1Rf5Y3h74OvDjB+X 1TsoyiCpkodfCfOrC3veAVhgHgoyyQEG/v/IgSUW1N9JD+NlrTfJ1VznM3jNuxP9 0tyPRuZv2Gx6q8kVRLMqOT7yVfe1CiT+7fMBq1MzUgAA1Jun/Ai6stBWxndtVxG/ 13e6V95qBLCvh82ApadXDqdUIKOoQKoVT/avHjTLO76KTch32s404Mi4a0kFMfRa 0yFHJ8XK7lRubYTAwXFtLCUsCpqgzs9lDnpgKPbekLQEwT5psxrkQ== From: Harald Freudenberger To: richard.henderson@linaro.org, iii@linux.ibm.com, david@kernel.org, thuth@redhat.com, berrange@redhat.com Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org, linux-s390@vger.kernel.org, dengler@linux.ibm.com, borntraeger@linux.ibm.com, fcallies@linux.ibm.com, cohuck@redhat.com Subject: [PATCH v13 03/18] target/s390x: Support cpacf sha256 Date: Mon, 3 Aug 2026 18:12:20 +0200 Message-ID: <20260803161235.228704-4-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803161235.228704-1-freude@linux.ibm.com> References: <20260803161235.228704-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: cRqFAvR-V6mHH6YaFVlWxSU3eda1wWEq X-Proofpoint-ORIG-GUID: cRqFAvR-V6mHH6YaFVlWxSU3eda1wWEq X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX8mNaRxnEuQk3 j/uqLBJReuFUPdZ7a01KtTLa99MU23MYH4z/MvZKgjAhpkUqtXLRuhpiR6zXBU9v+0/e27l+ivW DGOj1HgWQ1n9ebZ356rVDrWwe6B0+9k= X-Authority-Analysis: v=2.4 cv=K8cS2SWI c=1 sm=1 tr=0 ts=6a70bdf4 cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=uAbxVGIbfxUO_5tXvNgY:22 a=VnNF1IyMAAAA:8 a=Oku5TADFz1XGWIWXx1gA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX2OHtO7Vg2YsL VdSnT9J+gnLhf+43BmMfCo9Hr7ePVaex+RT4cuIJ0Ek12bOFfIh3T1wahYHx2JzgHfVVA5HOi05 DjlGtgLMBKLwGKX7/yiyuO1wohO4T60xeRTjBfAe+GvzrP2ilAJOpBeeF4Lzk7BUYOJp3ROQ1a0 BQndVUCnSvqLb8sg6qaNwjO+QOZ9YGCzkpgyhGFiYNsww9Mp04GmaWqW2HXCeiX47KEtRodSOkM /iDN5k59PJ3uj9ip+fJrBD1xXULDILVipNkbtNauSe7CjJVvAXPUorqczejqUnOOVROLXs/dLtv OZJAkDJcb1ZSRL6Scm6KiFkuUAt8ie+GbzjKGJr1VhWfqtaz3/dzBf62B5TVB/siivOYbSgUj1U nz6hlaPcKZou9TODTDaUswWME+wIYf5tp9BYdK9AZOIVrCQH241lDx99Z7753/+9D3g7rqOUVjL 4hpWAFJ9YA8Nq4o8B8Q== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-03_03,2026-08-03_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 spamscore=0 impostorscore=0 bulkscore=0 priorityscore=1501 lowpriorityscore=0 malwarescore=0 phishscore=0 suspectscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030141 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=148.163.156.1; envelope-from=freude@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1785773628224158500 Content-Type: text/plain; charset="utf-8" Add a new file cpacf_sha256.c which implements sha256. Add support for the sha256 subfuction for CPACF kimd and klmd. Tested-by: Holger Dengler Reviewed-by: Finn Callies Reviewed-by: Ilya Leoshkevich Signed-off-by: Harald Freudenberger --- target/s390x/gen-features.c | 2 + target/s390x/tcg/cpacf.h | 5 + target/s390x/tcg/cpacf_sha256.c | 227 +++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 8 ++ target/s390x/tcg/meson.build | 1 + 5 files changed, 243 insertions(+) create mode 100644 target/s390x/tcg/cpacf_sha256.c diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index a309dc2c09..78f71c6c7b 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -917,7 +917,9 @@ static uint16_t qemu_V7_1[] =3D { */ static uint16_t qemu_MAX[] =3D { S390_FEAT_MSA_EXT_5, + S390_FEAT_KIMD_SHA_256, S390_FEAT_KIMD_SHA_512, + S390_FEAT_KLMD_SHA_256, S390_FEAT_KLMD_SHA_512, S390_FEAT_PRNO_TRNG, }; diff --git a/target/s390x/tcg/cpacf.h b/target/s390x/tcg/cpacf.h index 3b89bc5cd7..94e9de5b23 100644 --- a/target/s390x/tcg/cpacf.h +++ b/target/s390x/tcg/cpacf.h @@ -223,6 +223,11 @@ #define CPACF_KDSA_PSIGN_ED25519 48 #define CPACF_KDSA_PSIGN_ED448 52 =20 +/* from cpacf_sha256.c */ +int cpacf_sha256(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *message_reg, uint64_t *len= _reg, + uint32_t type); + /* from cpacf_sha512.c */ int cpacf_sha512(CPUS390XState *env, const int mmu_idx, uintptr_t ra, uint64_t param_addr, uint64_t *message_reg, uint64_t *len= _reg, diff --git a/target/s390x/tcg/cpacf_sha256.c b/target/s390x/tcg/cpacf_sha25= 6.c new file mode 100644 index 0000000000..7e57e497a3 --- /dev/null +++ b/target/s390x/tcg/cpacf_sha256.c @@ -0,0 +1,227 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * s390 cpacf sha256 + * + * Authors: + * Harald Freudenberger + * + * The sha256 implementation here is more or less a copy-and-paste + * from Jason A. Donenfeld's implementation of sha 512 with adaptions + * for sha 256. + */ + +#include "qemu/osdep.h" +#include "s390x-internal.h" +#include "tcg_s390x.h" +#include "exec/helper-proto.h" +#include "accel/tcg/cpu-ldst-common.h" +#include "accel/tcg/cpu-mmu-index.h" +#include "target/s390x/tcg/cpacf.h" + +static uint32_t R(uint32_t x, int c) +{ + return (x >> c) | (x << (32 - c)); +} +static uint32_t Ch(uint32_t x, uint32_t y, uint32_t z) +{ + return (x & y) ^ (~x & z); +} +static uint32_t Maj(uint32_t x, uint32_t y, uint32_t z) +{ + return (x & y) ^ (x & z) ^ (y & z); +} +static uint32_t Sigma0(uint32_t x) +{ + return R(x, 2) ^ R(x, 13) ^ R(x, 22); +} +static uint32_t Sigma1(uint32_t x) +{ + return R(x, 6) ^ R(x, 11) ^ R(x, 25); +} +static uint32_t sigma0(uint32_t x) +{ + return R(x, 7) ^ R(x, 18) ^ (x >> 3); +} +static uint32_t sigma1(uint32_t x) +{ + return R(x, 17) ^ R(x, 19) ^ (x >> 10); +} + +static const uint32_t K[64] =3D { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, + 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, + 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, + 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, + 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, + 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, +}; + +/* a is icv/ocv, w is a single message block. w will get reused internally= . */ +static void sha256_bda(uint32_t a[8], uint32_t w[16]) +{ + uint32_t t, z[8], b[8]; + int i, j; + + memcpy(z, a, sizeof(z)); + for (i =3D 0; i < 64; i++) { + memcpy(b, a, sizeof(b)); + + t =3D a[7] + Sigma1(a[4]) + Ch(a[4], a[5], a[6]) + K[i] + w[i % 16= ]; + b[7] =3D t + Sigma0(a[0]) + Maj(a[0], a[1], a[2]); + b[3] +=3D t; + for (j =3D 0; j < 8; ++j) { + a[(j + 1) % 8] =3D b[j]; + } + if (i % 16 =3D=3D 15) { + for (j =3D 0; j < 16; ++j) { + w[j] +=3D w[(j + 9) % 16] + sigma0(w[(j + 1) % 16]) + + sigma1(w[(j + 14) % 16]); + } + } + } + + for (i =3D 0; i < 8; i++) { + a[i] +=3D z[i]; + } +} + +/* a is icv/ocv, w is a single message block that needs be32 conversion. */ +static void sha256_bda_be32(uint32_t a[8], uint32_t w[16]) +{ + uint32_t t[16]; + int i; + + for (i =3D 0; i < 16; i++) { + t[i] =3D be32_to_cpu(w[i]); + } + sha256_bda(a, t); +} + +static void sha256_read_icv(CPUS390XState *env, const int mmu_idx, + uint64_t addr, uint32_t a[8], uintptr_t ra) +{ + const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_32 | MO_UNALN, mmu_idx= ); + + for (int i =3D 0; i < 8; i++, addr +=3D 4) { + a[i] =3D cpu_ldl_mmu(env, wrap_address(env, addr), oi, ra); + } +} + +static void sha256_write_ocv(CPUS390XState *env, const int mmu_idx, + uint64_t addr, uint32_t a[8], uintptr_t ra) +{ + const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_32 | MO_UNALN, mmu_idx= ); + + for (int i =3D 0; i < 8; i++, addr +=3D 4) { + cpu_stl_mmu(env, wrap_address(env, addr), a[i], oi, ra); + } +} + +static void sha256_read_block(CPUS390XState *env, const int mmu_idx, + uint64_t addr, uint32_t a[16], uintptr_t ra) +{ + const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_32 | MO_UNALN, mmu_idx= ); + + for (int i =3D 0; i < 16; i++, addr +=3D 4) { + a[i] =3D cpu_ldl_mmu(env, wrap_address(env, addr), oi, ra); + } +} + +static void sha256_read_mbl_be32(CPUS390XState *env, const int mmu_idx, + uint64_t addr, uint8_t a[8], uintptr_t ra) +{ + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + + for (int i =3D 0; i < 8; i++, addr +=3D 1) { + a[i] =3D cpu_ldb_mmu(env, wrap_address(env, addr), oi, ra); + } +} + +int cpacf_sha256(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *message_reg, uint64_t *len= _reg, + uint32_t type) +{ + enum { MAX_BLOCKS_PER_RUN =3D 128 }; /* 128 * 64 =3D 8K */ + uint64_t len =3D *len_reg, processed =3D 0; + int i, message_reg_len =3D 64; + uint32_t a[8]; + + g_assert(type =3D=3D S390_FEAT_TYPE_KIMD || type =3D=3D S390_FEAT_TYPE= _KLMD); + + if (!(env->psw.mask & PSW_MASK_64)) { + len =3D (uint32_t)len; + message_reg_len =3D (env->psw.mask & PSW_MASK_32) ? 32 : 24; + } + + /* KIMD: length has to be properly aligned. */ + if (type =3D=3D S390_FEAT_TYPE_KIMD && !QEMU_IS_ALIGNED(len, 64)) { + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } + + sha256_read_icv(env, mmu_idx, param_addr, a, ra); + + /* Process full blocks first. */ + for (; len >=3D 64; len -=3D 64, processed +=3D 64) { + uint32_t w[16]; + + if (processed >=3D MAX_BLOCKS_PER_RUN * 64) { + break; + } + + sha256_read_block(env, mmu_idx, *message_reg + processed, w, ra); + sha256_bda(a, w); + } + + /* KLMD: Process partial/empty block last. */ + if (type =3D=3D S390_FEAT_TYPE_KLMD && len < 64) { + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + uint8_t x[64]; + + /* Read the remainder of the message byte-per-byte. */ + for (i =3D 0; i < len; i++) { + uint64_t addr =3D wrap_address(env, *message_reg + processed += i); + + x[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + /* Pad the remainder with zero and set the top bit. */ + memset(x + len, 0, 64 - len); + x[len] =3D 0x80; + + /* + * Place the MBL either into this block (if there is space left), + * or use an additional one. + */ + if (len < 56) { + sha256_read_mbl_be32(env, mmu_idx, param_addr + 32, x + 56, ra= ); + } + sha256_bda_be32(a, (uint32_t *)x); + + if (len >=3D 56) { + memset(x, 0, 56); + sha256_read_mbl_be32(env, mmu_idx, param_addr + 32, x + 56, ra= ); + sha256_bda_be32(a, (uint32_t *)x); + } + + processed +=3D len; + len =3D 0; + } + + /* + * Modify memory after we read all inputs and modify registers only af= ter + * writing memory succeeded. + * + * TODO: if writing fails halfway through (e.g., when crossing page + * boundaries), we're in trouble. We'd need something like access_prep= are(). + */ + sha256_write_ocv(env, mmu_idx, param_addr, a, ra); + *message_reg =3D deposit64(*message_reg, 0, message_reg_len, + *message_reg + processed); + *len_reg -=3D processed; + return !len ? 0 : 3; +} diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_hel= per.c index dba46baa0d..6c296f6731 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -53,6 +53,10 @@ static int cpacf_kimd(CPUS390XState *env, const int mmu_= idx, const uintptr_t ra, int rc =3D 0; =20 switch (fc) { + case CPACF_KIMD_SHA_256: + rc =3D cpacf_sha256(env, mmu_idx, ra, env->regs[1], &env->regs[r2], + &env->regs[r2 + 1], S390_FEAT_TYPE_KIMD); + break; case CPACF_KIMD_SHA_512: rc =3D cpacf_sha512(env, mmu_idx, ra, env->regs[1], &env->regs[r2], &env->regs[r2 + 1], S390_FEAT_TYPE_KIMD); @@ -70,6 +74,10 @@ static int cpacf_klmd(CPUS390XState *env, const int mmu_= idx, const uintptr_t ra, int rc =3D 0; =20 switch (fc) { + case CPACF_KLMD_SHA_256: + rc =3D cpacf_sha256(env, mmu_idx, ra, env->regs[1], &env->regs[r2], + &env->regs[r2 + 1], S390_FEAT_TYPE_KLMD); + break; case CPACF_KLMD_SHA_512: rc =3D cpacf_sha512(env, mmu_idx, ra, env->regs[1], &env->regs[r2], &env->regs[r2 + 1], S390_FEAT_TYPE_KLMD); diff --git a/target/s390x/tcg/meson.build b/target/s390x/tcg/meson.build index 54a87393a3..8ae8da9708 100644 --- a/target/s390x/tcg/meson.build +++ b/target/s390x/tcg/meson.build @@ -5,6 +5,7 @@ s390x_ss.add(when: 'CONFIG_TCG', if_true: files( )) s390x_common_ss.add(when: 'CONFIG_TCG', if_true: files( 'cc_helper.c', + 'cpacf_sha256.c', 'cpacf_sha512.c', 'crypto_helper.c', 'excp_helper.c', --=20 2.43.0 From nobody Mon Sep 28 01:12:31 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1785773596; cv=none; d=zohomail.com; s=zohoarc; b=csW+TjYRjW9pKSAAbKks2g0VxfoXtFN+BH4eoyVNPbLeh/XK8neOo9ykAJSX11Pm3JzVpqrmeTDlGdo6qzksP1kPNdEJ1kJIQk6cIymO/QeyYrtWsGldh0L+gh2KKHibfa42IgqpLK6XpNITa3pSc5mj+BSdhsgzhc7iR8GM344= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785773596; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Xv3I5qm5EaQWZ77Nm2gBe5qnWzKcgVMENuy8PMzAUCc=; b=E9YorUgy9/4PSnfcr04tToBHD5sB4WduLYf92ZXKyzDU+dMV1WRmEsbG9Nji2M+HwFY5kiO8MlRB3nTbEtfWNzsi1zXMBNVkHNn3HzVjqjwBEc+X4faguBILlbr5pvZgOBZROdbpTbJMqOs3nQcZkq64iw2YUdgUBDbwbM8HeMI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785773596984279.2614999598097; Mon, 3 Aug 2026 09:13:16 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wqvHa-000671-9V; Mon, 03 Aug 2026 12:12:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHP-00060W-8v; Mon, 03 Aug 2026 12:12:44 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHM-00034W-CO; Mon, 03 Aug 2026 12:12:42 -0400 Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 673EHhTP2282695; Mon, 3 Aug 2026 16:12:36 GMT Received: from ppma13.dal12v.mail.ibm.com (dd.9e.1632.ip4.static.sl-reverse.com [50.22.158.221]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs8h4squy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:36 +0000 (GMT) Received: from pps.filterd (ppma13.dal12v.mail.ibm.com [127.0.0.1]) by ppma13.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 673GBIWN008958; Mon, 3 Aug 2026 16:12:35 GMT Received: from smtprelay06.fra02v.mail.ibm.com ([9.218.2.230]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4fswbg5yac-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:35 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay06.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 673GCVqT29688100 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 16:12:31 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 69DAD20040; Mon, 3 Aug 2026 16:12:31 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2A27020043; Mon, 3 Aug 2026 16:12:31 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 16:12:31 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=Xv3I5qm5EaQWZ77Nm 2gBe5qnWzKcgVMENuy8PMzAUCc=; b=D3FBz/4flDreU+MaLvq593jpgvBURSmaV e6r5t6JwyYuqOJ76ut2Ciw1VeoKpgX+YT0/xmqlanUydx6tlmZEJGoq+yPi9hEy2 7Yq2sBTpHzMn+wGzeA3rFd7a49+n19sMb/zPFCNuVrJDeQlvN4mVqPvm3o6e0gzJ VpEsHPQL9/vJPd/O4T1rgPza9859ei1ma9D/Q9ZQZSneMw4GYqgbcJHeWoGai5ox 4S39BKW7jxeQDaqnpLXvGReiE+5Q0XSD7zDGvH/38OE8sRsTBBx1Uqxthu/QBBuq wy1CL2hDmMU4RslKHCqm354zTrdege0abRsFhOZBVaI9tHWilyxbQ== From: Harald Freudenberger To: richard.henderson@linaro.org, iii@linux.ibm.com, david@kernel.org, thuth@redhat.com, berrange@redhat.com Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org, linux-s390@vger.kernel.org, dengler@linux.ibm.com, borntraeger@linux.ibm.com, fcallies@linux.ibm.com, cohuck@redhat.com Subject: [PATCH v13 04/18] target/s390x: Add helper functions for copy memory to and from guest Date: Mon, 3 Aug 2026 18:12:21 +0200 Message-ID: <20260803161235.228704-5-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803161235.228704-1-freude@linux.ibm.com> References: <20260803161235.228704-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX+exY1og2kk90 iQAdqvD7fK5Fq7qAeHLYbhP5dMMHZsQwoiidAnxQZUb1t+3+j1+DE2OnmLn35vT+fHfA0EAZ2IK NZV7ygE5rd6ZvhAz89ckgkc5l8QUbx4= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX3d/biHmRWUx1 FjjQ+txdsQ0XpJdv9jYfKsF9HQIKGOEFXo1xMQnQRGciRGzJh3VwmdYSzTemQZtQ76OcQxzQcmy 1i9zw4DL8Vh0i0VULxStqcoqGTJ7EX8+EGjc6VJ6xJpM88AUAKyibkHVfP9sEab5/jJW5ovCoXJ 4vVklIXHS86j3UTtvgaUFrPw1a5Zt2oY2Ka50xqUDtbBBvn1W3UBHoyatvEWPCvR2es4xgiMujg KziUF6RRiJSGjyTDZhwzzKl3XtsZ7fHe2fG+o6wRMzCpMfZSvQN7H6ahuSUg3XE7r9McWKKSVT8 68pHaCW5uD0P5vZU/zPwbXlX0J+mNH02VEu/b6iEbdwQtR1A5eqwGc+wdcCPiYaXKQUCLKRhg35 kNimC6f8JxdUYWO36EeCzL6hlTekR92lAUoTXqc2NIMndE5b0eGTaXDrRFwebE6O3mVnTg1AHKj C/D2aW0NbBAjjIqhT9Q== X-Authority-Analysis: v=2.4 cv=SI1ykuvH c=1 sm=1 tr=0 ts=6a70bdf4 cx=c_pps a=AfN7/Ok6k8XGzOShvHwTGQ==:117 a=AfN7/Ok6k8XGzOShvHwTGQ==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=FyORFv3Am_Wt7j1hYGwA:9 X-Proofpoint-ORIG-GUID: iRCsIyUVQkC1CGtlan4wHvteoTDUMxgC X-Proofpoint-GUID: iRCsIyUVQkC1CGtlan4wHvteoTDUMxgC X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-03_03,2026-08-03_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 bulkscore=0 suspectscore=0 impostorscore=0 spamscore=0 phishscore=0 priorityscore=1501 lowpriorityscore=0 adultscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030141 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=148.163.156.1; envelope-from=freude@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1785773598065158500 Content-Type: text/plain; charset="utf-8" Add some simple helper functions to copy memory from guest to a local buffer and the other way around: - read_guest_wrap_u8() - write_guest_wrap_u8() - read_guest_wrap_u32() - write_guest_wrap_u32() - read_guest_wrap_u64() - write_guest_wrap_u64() The reader functions read from guest memory into an array of u8/u32/u64 with BE conversion. Similar the writer functions write an array of u8/u32/u64 into guest memory with BE conversion. All these functions are intended to be used for the crypto implementations thus are located in crypto_helper.h. Rework and simplify the sha 256 and sha 512 implementations to use these helper functions. Signed-off-by: Harald Freudenberger Reviewed-by: Ilya Leoshkevich --- target/s390x/tcg/cpacf_sha256.c | 63 ++++--------------- target/s390x/tcg/cpacf_sha512.c | 63 ++++--------------- target/s390x/tcg/crypto_helper.c | 1 + target/s390x/tcg/crypto_helper.h | 100 +++++++++++++++++++++++++++++++ 4 files changed, 123 insertions(+), 104 deletions(-) create mode 100644 target/s390x/tcg/crypto_helper.h diff --git a/target/s390x/tcg/cpacf_sha256.c b/target/s390x/tcg/cpacf_sha25= 6.c index 7e57e497a3..f895f9e20c 100644 --- a/target/s390x/tcg/cpacf_sha256.c +++ b/target/s390x/tcg/cpacf_sha256.c @@ -18,6 +18,7 @@ #include "accel/tcg/cpu-ldst-common.h" #include "accel/tcg/cpu-mmu-index.h" #include "target/s390x/tcg/cpacf.h" +#include "target/s390x/tcg/crypto_helper.h" =20 static uint32_t R(uint32_t x, int c) { @@ -103,53 +104,13 @@ static void sha256_bda_be32(uint32_t a[8], uint32_t w= [16]) sha256_bda(a, t); } =20 -static void sha256_read_icv(CPUS390XState *env, const int mmu_idx, - uint64_t addr, uint32_t a[8], uintptr_t ra) -{ - const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_32 | MO_UNALN, mmu_idx= ); - - for (int i =3D 0; i < 8; i++, addr +=3D 4) { - a[i] =3D cpu_ldl_mmu(env, wrap_address(env, addr), oi, ra); - } -} - -static void sha256_write_ocv(CPUS390XState *env, const int mmu_idx, - uint64_t addr, uint32_t a[8], uintptr_t ra) -{ - const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_32 | MO_UNALN, mmu_idx= ); - - for (int i =3D 0; i < 8; i++, addr +=3D 4) { - cpu_stl_mmu(env, wrap_address(env, addr), a[i], oi, ra); - } -} - -static void sha256_read_block(CPUS390XState *env, const int mmu_idx, - uint64_t addr, uint32_t a[16], uintptr_t ra) -{ - const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_32 | MO_UNALN, mmu_idx= ); - - for (int i =3D 0; i < 16; i++, addr +=3D 4) { - a[i] =3D cpu_ldl_mmu(env, wrap_address(env, addr), oi, ra); - } -} - -static void sha256_read_mbl_be32(CPUS390XState *env, const int mmu_idx, - uint64_t addr, uint8_t a[8], uintptr_t ra) -{ - const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); - - for (int i =3D 0; i < 8; i++, addr +=3D 1) { - a[i] =3D cpu_ldb_mmu(env, wrap_address(env, addr), oi, ra); - } -} - int cpacf_sha256(CPUS390XState *env, const int mmu_idx, uintptr_t ra, uint64_t param_addr, uint64_t *message_reg, uint64_t *len= _reg, uint32_t type) { enum { MAX_BLOCKS_PER_RUN =3D 128 }; /* 128 * 64 =3D 8K */ uint64_t len =3D *len_reg, processed =3D 0; - int i, message_reg_len =3D 64; + int message_reg_len =3D 64; uint32_t a[8]; =20 g_assert(type =3D=3D S390_FEAT_TYPE_KIMD || type =3D=3D S390_FEAT_TYPE= _KLMD); @@ -164,7 +125,8 @@ int cpacf_sha256(CPUS390XState *env, const int mmu_idx,= uintptr_t ra, tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); } =20 - sha256_read_icv(env, mmu_idx, param_addr, a, ra); + /* read icv (8 * u32) */ + read_guest_wrap_u32(env, mmu_idx, ra, param_addr, a, 8); =20 /* Process full blocks first. */ for (; len >=3D 64; len -=3D 64, processed +=3D 64) { @@ -174,21 +136,18 @@ int cpacf_sha256(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, break; } =20 - sha256_read_block(env, mmu_idx, *message_reg + processed, w, ra); + /* read sha256 block (16 * u32) */ + read_guest_wrap_u32(env, mmu_idx, ra, *message_reg + processed, w,= 16); sha256_bda(a, w); } =20 /* KLMD: Process partial/empty block last. */ if (type =3D=3D S390_FEAT_TYPE_KLMD && len < 64) { - const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); uint8_t x[64]; =20 - /* Read the remainder of the message byte-per-byte. */ - for (i =3D 0; i < len; i++) { - uint64_t addr =3D wrap_address(env, *message_reg + processed += i); + /* Read the remainder of the message. */ + read_guest_wrap_u8(env, mmu_idx, ra, *message_reg + processed, x, = len); =20 - x[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } /* Pad the remainder with zero and set the top bit. */ memset(x + len, 0, 64 - len); x[len] =3D 0x80; @@ -198,13 +157,13 @@ int cpacf_sha256(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, * or use an additional one. */ if (len < 56) { - sha256_read_mbl_be32(env, mmu_idx, param_addr + 32, x + 56, ra= ); + read_guest_wrap_u8(env, mmu_idx, ra, param_addr + 32, x + 56, = 8); } sha256_bda_be32(a, (uint32_t *)x); =20 if (len >=3D 56) { memset(x, 0, 56); - sha256_read_mbl_be32(env, mmu_idx, param_addr + 32, x + 56, ra= ); + read_guest_wrap_u8(env, mmu_idx, ra, param_addr + 32, x + 56, = 8); sha256_bda_be32(a, (uint32_t *)x); } =20 @@ -219,7 +178,7 @@ int cpacf_sha256(CPUS390XState *env, const int mmu_idx,= uintptr_t ra, * TODO: if writing fails halfway through (e.g., when crossing page * boundaries), we're in trouble. We'd need something like access_prep= are(). */ - sha256_write_ocv(env, mmu_idx, param_addr, a, ra); + write_guest_wrap_u32(env, mmu_idx, ra, param_addr, a, 8); *message_reg =3D deposit64(*message_reg, 0, message_reg_len, *message_reg + processed); *len_reg -=3D processed; diff --git a/target/s390x/tcg/cpacf_sha512.c b/target/s390x/tcg/cpacf_sha51= 2.c index ebfecc70f7..fa42eff336 100644 --- a/target/s390x/tcg/cpacf_sha512.c +++ b/target/s390x/tcg/cpacf_sha512.c @@ -17,6 +17,7 @@ #include "accel/tcg/cpu-ldst-common.h" #include "accel/tcg/cpu-mmu-index.h" #include "target/s390x/tcg/cpacf.h" +#include "target/s390x/tcg/crypto_helper.h" =20 static uint64_t R(uint64_t x, int c) { @@ -118,53 +119,13 @@ static void sha512_bda_be64(uint64_t a[8], uint64_t w= [16]) sha512_bda(a, t); } =20 -static void sha512_read_icv(CPUS390XState *env, const int mmu_idx, - uint64_t addr, uint64_t a[8], uintptr_t ra) -{ - const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_64 | MO_UNALN, mmu_idx= ); - - for (int i =3D 0; i < 8; i++, addr +=3D 8) { - a[i] =3D cpu_ldq_mmu(env, wrap_address(env, addr), oi, ra); - } -} - -static void sha512_write_ocv(CPUS390XState *env, const int mmu_idx, - uint64_t addr, uint64_t a[8], uintptr_t ra) -{ - const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_64 | MO_UNALN, mmu_idx= ); - - for (int i =3D 0; i < 8; i++, addr +=3D 8) { - cpu_stq_mmu(env, wrap_address(env, addr), a[i], oi, ra); - } -} - -static void sha512_read_block(CPUS390XState *env, const int mmu_idx, - uint64_t addr, uint64_t a[16], uintptr_t ra) -{ - const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_64 | MO_UNALN, mmu_idx= ); - - for (int i =3D 0; i < 16; i++, addr +=3D 8) { - a[i] =3D cpu_ldq_mmu(env, wrap_address(env, addr), oi, ra); - } -} - -static void sha512_read_mbl_be64(CPUS390XState *env, const int mmu_idx, - uint64_t addr, uint8_t a[16], uintptr_t r= a) -{ - const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); - - for (int i =3D 0; i < 16; i++, addr +=3D 1) { - a[i] =3D cpu_ldb_mmu(env, wrap_address(env, addr), oi, ra); - } -} - int cpacf_sha512(CPUS390XState *env, const int mmu_idx, uintptr_t ra, uint64_t param_addr, uint64_t *message_reg, uint64_t *len= _reg, uint32_t type) { enum { MAX_BLOCKS_PER_RUN =3D 64 }; /* Arbitrary: keep interactivity. = */ uint64_t len =3D *len_reg, a[8], processed =3D 0; - int i, message_reg_len =3D 64; + int message_reg_len =3D 64; =20 g_assert(type =3D=3D S390_FEAT_TYPE_KIMD || type =3D=3D S390_FEAT_TYPE= _KLMD); =20 @@ -178,7 +139,8 @@ int cpacf_sha512(CPUS390XState *env, const int mmu_idx,= uintptr_t ra, tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); } =20 - sha512_read_icv(env, mmu_idx, param_addr, a, ra); + /* read icv (8 * u64) */ + read_guest_wrap_u64(env, mmu_idx, ra, param_addr, a, 8); =20 /* Process full blocks first. */ for (; len >=3D 128; len -=3D 128, processed +=3D 128) { @@ -188,21 +150,18 @@ int cpacf_sha512(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, break; } =20 - sha512_read_block(env, mmu_idx, *message_reg + processed, w, ra); + /* read sha512 block (16 * u64) */ + read_guest_wrap_u64(env, mmu_idx, ra, *message_reg + processed, w,= 16); sha512_bda(a, w); } =20 /* KLMD: Process partial/empty block last. */ if (type =3D=3D S390_FEAT_TYPE_KLMD && len < 128) { - const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); uint8_t x[128]; =20 - /* Read the remainder of the message byte-per-byte. */ - for (i =3D 0; i < len; i++) { - uint64_t addr =3D wrap_address(env, *message_reg + processed += i); + /* Read the remainder of the message. */ + read_guest_wrap_u8(env, mmu_idx, ra, *message_reg + processed, x, = len); =20 - x[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } /* Pad the remainder with zero and set the top bit. */ memset(x + len, 0, 128 - len); x[len] =3D 128; @@ -212,13 +171,13 @@ int cpacf_sha512(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, * or use an additional one. */ if (len < 112) { - sha512_read_mbl_be64(env, mmu_idx, param_addr + 64, x + 112, r= a); + read_guest_wrap_u8(env, mmu_idx, ra, param_addr + 64, x + 112,= 16); } sha512_bda_be64(a, (uint64_t *)x); =20 if (len >=3D 112) { memset(x, 0, 112); - sha512_read_mbl_be64(env, mmu_idx, param_addr + 64, x + 112, r= a); + read_guest_wrap_u8(env, mmu_idx, ra, param_addr + 64, x + 112,= 16); sha512_bda_be64(a, (uint64_t *)x); } =20 @@ -233,7 +192,7 @@ int cpacf_sha512(CPUS390XState *env, const int mmu_idx,= uintptr_t ra, * TODO: if writing fails halfway through (e.g., when crossing page * boundaries), we're in trouble. We'd need something like access_prep= are(). */ - sha512_write_ocv(env, mmu_idx, param_addr, a, ra); + write_guest_wrap_u64(env, mmu_idx, ra, param_addr, a, 8); *message_reg =3D deposit64(*message_reg, 0, message_reg_len, *message_reg + processed); *len_reg -=3D processed; diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_hel= per.c index 6c296f6731..d996caf56a 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -20,6 +20,7 @@ #include "accel/tcg/cpu-ldst-common.h" #include "accel/tcg/cpu-mmu-index.h" #include "target/s390x/tcg/cpacf.h" +#include "target/s390x/tcg/crypto_helper.h" =20 static void fill_buf_random(CPUS390XState *env, const int mmu_idx, uintptr= _t ra, uint64_t *buf_reg, uint64_t *len_reg) diff --git a/target/s390x/tcg/crypto_helper.h b/target/s390x/tcg/crypto_hel= per.h new file mode 100644 index 0000000000..2364e46029 --- /dev/null +++ b/target/s390x/tcg/crypto_helper.h @@ -0,0 +1,100 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Crypto helper functions + */ + +#ifndef TARGET_S390_CRYPTO_HELPER_H +#define TARGET_S390_CRYPTO_HELPER_H + +/* + * helper function to read len * u8 from guest to local buffer + */ +static inline void read_guest_wrap_u8(CPUS390XState *env, const int mmu_id= x, + const uintptr_t ra, uint64_t guest_a= ddr, + uint8_t *dest, size_t len) +{ + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + + for (size_t i =3D 0; i < len; i++, guest_addr++) { + uint64_t waddr =3D wrap_address(env, guest_addr); + dest[i] =3D cpu_ldb_mmu(env, waddr, oi, ra); + } +} + +/* + * helper function to write len * u8 from local buffer to guest + */ +static inline void write_guest_wrap_u8(CPUS390XState *env, const int mmu_i= dx, + const uintptr_t ra, uint64_t guest_= addr, + const uint8_t *src, size_t len) +{ + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + + for (size_t i =3D 0; i < len; i++, guest_addr++) { + uint64_t waddr =3D wrap_address(env, guest_addr); + cpu_stb_mmu(env, waddr, src[i], oi, ra); + } +} + +/* + * helper function to read len * u32 from guest to local buffer + */ +static inline void read_guest_wrap_u32(CPUS390XState *env, const int mmu_i= dx, + const uintptr_t ra, uint64_t guest_a= ddr, + uint32_t *dest, size_t len) +{ + const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_32 | MO_UNALN, mmu_idx= ); + + for (size_t i =3D 0; i < len; i++, guest_addr +=3D 4) { + uint64_t waddr =3D wrap_address(env, guest_addr); + dest[i] =3D cpu_ldl_mmu(env, waddr, oi, ra); + } +} + +/* + * helper function to write len * u32 from local buffer to guest + */ +static inline void write_guest_wrap_u32(CPUS390XState *env, const int mmu_= idx, + const uintptr_t ra, uint64_t guest= _addr, + const uint32_t *src, size_t len) +{ + const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_32 | MO_UNALN, mmu_idx= ); + + for (size_t i =3D 0; i < len; i++, guest_addr +=3D 4) { + uint64_t waddr =3D wrap_address(env, guest_addr); + cpu_stl_mmu(env, waddr, src[i], oi, ra); + } +} + +/* + * helper function to read len * u64 from guest to local buffer + */ +static inline void read_guest_wrap_u64(CPUS390XState *env, const int mmu_i= dx, + const uintptr_t ra, uint64_t guest_a= ddr, + uint64_t *dest, size_t len) +{ + const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_64 | MO_UNALN, mmu_idx= ); + + for (size_t i =3D 0; i < len; i++, guest_addr +=3D 8) { + uint64_t waddr =3D wrap_address(env, guest_addr); + dest[i] =3D cpu_ldq_mmu(env, waddr, oi, ra); + } +} + +/* + * helper function to write len * u64 from local buffer to guest + */ +static inline void write_guest_wrap_u64(CPUS390XState *env, const int mmu_= idx, + const uintptr_t ra, uint64_t guest= _addr, + const uint64_t *src, size_t len) +{ + const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_64 | MO_UNALN, mmu_idx= ); + + for (size_t i =3D 0; i < len; i++, guest_addr +=3D 8) { + uint64_t waddr =3D wrap_address(env, guest_addr); + cpu_stq_mmu(env, waddr, src[i], oi, ra); + } +} + +#endif /* TARGET_S390_CRYPTO_HELPER_H */ --=20 2.43.0 From nobody Mon Sep 28 01:12:31 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1785773603; cv=none; d=zohomail.com; s=zohoarc; b=ZrtyKT3O3vs9L6yGxhM9tfMZhMdAWr/7eqfOGu+wEycMtAWwN4kD9lNNzVUUOGIMy25kk6l9lhn+U4hA71S7RyFlHDz5s/oQqzmKx3s/J0RCL27Wvmxa8n3psmVmwy4gV59hxaAjOCRhREpJzrsZQnjN+Vwwo2h1I5RledsJ/Cw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785773603; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=B/SybmQ/FJyrxZ7FxX4k3LSF1+CDBp2yE9MObY673j0=; b=AG3YUvcA43Cl7X2fwmmKQJZgnHJilug6zjbvf1b4BklbqUED/11KJqX8oYHsphzOIYksGvi6qAXtaDl1/JbpKLBS477cMCaeJglrvXVftF0UxNoSDjP15PJ9bk+gNlF9j7sTDUWKCrXBrUKo344PCTqKCy5FcUD2426/2kZupuA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785773603116942.4549665341236; Mon, 3 Aug 2026 09:13:23 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wqvHw-0006WP-Q6; Mon, 03 Aug 2026 12:13:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHS-000640-JK; Mon, 03 Aug 2026 12:12:47 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHP-00035F-T4; Mon, 03 Aug 2026 12:12:46 -0400 Received: from pps.filterd (m0353725.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 673EHkc52206230; Mon, 3 Aug 2026 16:12:36 GMT Received: from ppma11.dal12v.mail.ibm.com (db.9e.1632.ip4.static.sl-reverse.com [50.22.158.219]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs77g1hub-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:36 +0000 (GMT) Received: from pps.filterd (ppma11.dal12v.mail.ibm.com [127.0.0.1]) by ppma11.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 673GBEqq012378; Mon, 3 Aug 2026 16:12:35 GMT Received: from smtprelay06.fra02v.mail.ibm.com ([9.218.2.230]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 4fswtydx9u-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:35 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay06.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 673GCVxa29688102 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 16:12:31 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A2B0320040; Mon, 3 Aug 2026 16:12:31 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6F9DF2004B; Mon, 3 Aug 2026 16:12:31 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 16:12:31 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=pp1; bh=B/Sybm Q/FJyrxZ7FxX4k3LSF1+CDBp2yE9MObY673j0=; b=cJVhFDFhJyPD+2o2lh+I68 c4vbkqlZIPqfmeomlm0m1U+UDRhcU7pRLBm3KGNgO24F9X7VHc4c7Db3OrLkqos6 Oj/OvrwWYu9cIzpjlFC1uFDmkUzOcmaGq6dkAKJNHUyTkpkKgg458d4vfC8Ilskq psb0+u7lrQ7Ojv/oEffHb+fXUo2dhYoYItuP9WNb3Hbkn8+GbKWXryF4C7Dv8jw6 LJ95Y5VVuAwljZ/i9kNgJ233V2GdqRoFkygDoV2iBGtVSiGN13cMVognyef8K6++ 8d20nq7JLFHmP7U9XTUWrGopYj789f7sh2+uHzDLyPaAun8z86aSILI0bsdEAJIg == From: Harald Freudenberger To: richard.henderson@linaro.org, iii@linux.ibm.com, david@kernel.org, thuth@redhat.com, berrange@redhat.com Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org, linux-s390@vger.kernel.org, dengler@linux.ibm.com, borntraeger@linux.ibm.com, fcallies@linux.ibm.com, cohuck@redhat.com Subject: [PATCH v13 05/18] crypto: Add aes-helpers file to support some AES modes Date: Mon, 3 Aug 2026 18:12:22 +0200 Message-ID: <20260803161235.228704-6-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803161235.228704-1-freude@linux.ibm.com> References: <20260803161235.228704-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX8UUenXErdppX uYqI4ZFaTj2Zhgq7tjJ2rGRGnNE808JjKjtdEq/tWmNUzV7zxWIKGhvv8e43fijNmsnTp2pSi3X DSzkLCMPKyBOkGX8da2II6mvBsdLb1PwbIVqb7AMMnW9e/qXHBm6RLdbWTpbmr6s48OoKOqls7U aF5ymt5NvVP2iIwMXNL/Xldkal301Z/rG4Wdz5lCdJFpNHjoqeIDMoTsX3VCnnTPEQMZZqRAlX4 lVejvjzr+XUNU4lW/DvlinWWE5yWQrC4sZS+/InT/nad7YWO37dCSTQxj688rXMaUq3jhEZpek1 cay0xYvIGS1YvqZcfXiYn6ccswCzpXGh6FAshVWnFGkBMgRQc2p0qNk8rnCl6nM2uhV4/mhH2CG oHgwYB9QMAEEwU0LjOafYXkfLZ6I9uRiXSXz0yv8ajTiX/JBgvTKLX/hRt5LP5uAKF2sK2KCjW9 iPLiuiin6Du9U9aJZPg== X-Authority-Analysis: v=2.4 cv=WIFPmHsR c=1 sm=1 tr=0 ts=6a70bdf4 cx=c_pps a=aDMHemPKRhS1OARIsFnwRA==:117 a=aDMHemPKRhS1OARIsFnwRA==:17 a=IkcTkHD0fZMA:10 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=V8glGbnc2Ofi9Qvn3v5h:22 a=VnNF1IyMAAAA:8 a=20KFwNOVAAAA:8 a=zkwM-tl61wuaHISZUgYA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 X-Proofpoint-GUID: NLqqqmUTUJeL2PXT1b_bR9c47yMsz2sF X-Proofpoint-ORIG-GUID: NLqqqmUTUJeL2PXT1b_bR9c47yMsz2sF X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX9KNhgaKz80CS yuaJz12RZXxg2Pa6pTTFZ0Gn2ESGQfHFYz6EEf44oC7XMvXwh1R6ufGJcMEpcy/hWyvQVrKzpHP xw54bwnF/9hQPi/BgE0Tb6PZfAoBoNI= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-03_03,2026-08-03_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 lowpriorityscore=0 priorityscore=1501 phishscore=0 malwarescore=0 suspectscore=0 clxscore=1015 impostorscore=0 bulkscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030141 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=148.163.158.5; envelope-from=freude@linux.ibm.com; helo=mx0b-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1785773604093158500 Add a new file crypto/aes-helpers.c with simple functions to support some AES modes: - AES cbc: AES_cbc_encrypt() AES_cbc_decrypt() - AES ctr: AES_ctr_encrypt() - AES xts: AES_xts_encrypt() AES_xts_decrypt() and some AES related helpers: - AES_xor() - AES_xts_prep_next_tweak() Add header file include/crypto/aes-helpers.h for these functions Signed-off-by: Harald Freudenberger Reviewed-by: Finn Callies Reviewed-by: Ilya Leoshkevich Reviewed-by: Daniel P. Berrang=C3=A9 Acked-by: Daniel P. Berrang=C3=A9 --- crypto/aes-helpers.c | 106 ++++++++++++++++++++++++++++++++++ crypto/meson.build | 1 + include/crypto/aes-helpers.h | 109 +++++++++++++++++++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 crypto/aes-helpers.c create mode 100644 include/crypto/aes-helpers.h diff --git a/crypto/aes-helpers.c b/crypto/aes-helpers.c new file mode 100644 index 0000000000..68d848683c --- /dev/null +++ b/crypto/aes-helpers.c @@ -0,0 +1,106 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * AES helper functions and mode implementations + * + * Authors: + * Harald Freudenberger + */ + +#include "qemu/osdep.h" +#include "crypto/aes.h" +#include "crypto/aes-helpers.h" + +void AES_xor(const unsigned char *src1, const unsigned char *src2, + unsigned char *dst) +{ + int i; + + for (i =3D 0; i < AES_BLOCK_SIZE; i++) { + dst[i] =3D src1[i] ^ src2[i]; + } +} + +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + unsigned char *iv, const AES_KEY *key) +{ + unsigned char buf[AES_BLOCK_SIZE]; + + /* in xor iv =3D> buf */ + AES_xor(in, iv, buf); + /* encrypt buf =3D> out */ + AES_encrypt(buf, out, key); + /* prep iv for next round */ + memcpy(iv, out, AES_BLOCK_SIZE); +} + +void AES_cbc_decrypt(const unsigned char *in, unsigned char *out, + unsigned char *iv, const AES_KEY *key) +{ + unsigned char buf[AES_BLOCK_SIZE]; + + /* decrypt in =3D> buf */ + AES_decrypt(in, buf, key); + /* buf xor iv =3D> out */ + AES_xor(buf, iv, out); + /* prep iv for next round */ + memcpy(iv, in, AES_BLOCK_SIZE); +} + +void AES_ctr_encrypt(const unsigned char *in, unsigned char *out, + const unsigned char *ctr, const AES_KEY *key) +{ + unsigned char buf[AES_BLOCK_SIZE]; + + /* encrypt ctr =3D> buf */ + AES_encrypt(ctr, buf, key); + /* exor input data with encrypted ctr =3D> out */ + AES_xor(in, buf, out); +} + +/* + * Tweak calculation for AES XTS. + * Multiply tweak by =CE=B1 (x) in GF(2^128) per IEEE 1619-2007. The tweak + * is a 128-bit little-endian integer (tweak[0]=3DLSB, tweak[15]=3DMSB). + * This implementation has been verified on little and big endian. + */ +void AES_xts_prep_next_tweak(unsigned char *tweak) +{ + unsigned char carry; + int i; + + carry =3D tweak[AES_BLOCK_SIZE - 1] >> 7; + + for (i =3D AES_BLOCK_SIZE - 1; i > 0; i--) { + tweak[i] =3D (unsigned char)((tweak[i] << 1) | (tweak[i - 1] >> 7)= ); + } + + tweak[i] =3D (unsigned char)(tweak[i] << 1); + tweak[i] ^=3D (unsigned char)(0x87 & (unsigned char)(-(unsigned char)c= arry)); +} + +void AES_xts_encrypt(const unsigned char *in, unsigned char *out, + const unsigned char *tweak, const AES_KEY *key) +{ + unsigned char buf1[AES_BLOCK_SIZE], buf2[AES_BLOCK_SIZE]; + + /* in xor tweak =3D> buf1 */ + AES_xor(in, tweak, buf1); + /* encrypt buf1 =3D> buf2 */ + AES_encrypt(buf1, buf2, key); + /* buf2 xor tweak =3D> out */ + AES_xor(buf2, tweak, out); +} + +void AES_xts_decrypt(const unsigned char *in, unsigned char *out, + const unsigned char *tweak, const AES_KEY *key) +{ + unsigned char buf1[AES_BLOCK_SIZE], buf2[AES_BLOCK_SIZE]; + + /* in xor tweak =3D> buf1 */ + AES_xor(in, tweak, buf1); + /* encrypt buf1 =3D> buf2 */ + AES_decrypt(buf1, buf2, key); + /* buf2 xor tweak =3D> out */ + AES_xor(buf2, tweak, out); +} diff --git a/crypto/meson.build b/crypto/meson.build index 6ac83857aa..534b995c9b 100644 --- a/crypto/meson.build +++ b/crypto/meson.build @@ -55,6 +55,7 @@ system_ss.add(when: gnutls, if_true: files('tls-cipher-su= ites.c')) =20 util_ss.add(files( 'aes.c', + 'aes-helpers.c', 'clmul.c', 'init.c', 'sm4.c', diff --git a/include/crypto/aes-helpers.h b/include/crypto/aes-helpers.h new file mode 100644 index 0000000000..9a94c48d86 --- /dev/null +++ b/include/crypto/aes-helpers.h @@ -0,0 +1,109 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * AES helper functions and modes + */ + +#ifndef QEMU_AES_HELPERS_H +#define QEMU_AES_HELPERS_H + +/** + * AES_xor: + * @src1: first source buffer of AES_BLOCK_SIZE bytes + * @src2: second source buffer of AES_BLOCK_SIZE bytes + * @dst: destination buffer of AES_BLOCK_SIZE bytes + * + * Bitwise XOR operation between two AES blocks. + */ +void AES_xor(const unsigned char *src1, const unsigned char *src2, + unsigned char *dst); + +/** + * AES_cbc_encrypt: + * @in: input plaintext block of AES_BLOCK_SIZE bytes + * @out: output ciphertext block of AES_BLOCK_SIZE bytes + * @iv: IV, updated after processing for chaining + * @key: AES key + * + * Single block AES encrypt in CBC (Cipher Block Chaining) mode. + * The input block is XORed with the IV, then encrypted with AES. + * IV is updated at the end and is prepared for the next invocation. + */ +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + unsigned char *iv, const AES_KEY *key); + +/** + * AES_cbc_decrypt: + * @in: input ciphertext block of AES_BLOCK_SIZE bytes + * @out: output plaintext block of AES_BLOCK_SIZE bytes + * @iv: initialization vector, updated to input block for chaining + * @key: AES key + * + * Single block AES decrypt in CBC (Cipher Block Chaining) mode. + * The input block is decrypted, then XORed with the IV. + * IV is updated at the end and is prepared for the next invocation. + */ +void AES_cbc_decrypt(const unsigned char *in, unsigned char *out, + unsigned char *iv, const AES_KEY *key); + +/** + * AES_ctr_encrypt: + * @in: input data block of AES_BLOCK_SIZE bytes + * @out: output data block of AES_BLOCK_SIZE bytes + * @ctr: counter value of AES_BLOCK_SIZE bytes + * @key: AES key + * + * Single block AES encrypt/decrypt in CTR (Counter) mode. + * The counter block is encrypted, then XORed with the + * input data block. + * In CTR mode encrypt and decrypt are identical operations. + * Note that the caller is responsible for incrementing the + * counter block. + */ +void AES_ctr_encrypt(const unsigned char *in, unsigned char *out, + const unsigned char *ctr, const AES_KEY *key); + +/** + * AES_xts_prep_next_tweak: + * @tweak: pointer to tweak value to be updated (16 bytes buffer + * containing a 128 bit little endian integer) + * + * Tweak calculation for AES XTS. + * Prepares the next tweak value for AES-XTS mode by multiplying + * the current tweak by =CE=B1 (x) in GF(2^128) according to IEEE 1619-200= 7. + */ +void AES_xts_prep_next_tweak(unsigned char *tweak); + +/** + * AES_xts_encrypt: + * @in: input plaintext block of AES_BLOCK_SIZE bytes + * @out: output ciphertext block of AES_BLOCK_SIZE bytes + * @tweak: tweak value (16 bytes) + * @key: AES key + * + * Single block AES encrypt in XTS mode. + * The input is XORed with the tweak, encrypted, then XORed with + * the tweak again to produce the output. + * Note that the caller is responsible for managing the tweak value. + * Use AES_xts_prep_next_tweak() to advance the tweak for the next block. + */ +void AES_xts_encrypt(const unsigned char *in, unsigned char *out, + const unsigned char *tweak, const AES_KEY *key); + +/** + * AES_xts_decrypt: + * @in: input ciphertext block of AES_BLOCK_SIZE bytes + * @out: output plaintext block of AES_BLOCK_SIZE bytes + * @tweak: tweak value (16 bytes) + * @key: AES key + * + * Single block AES decrypt in XTS mode. + * The input is XORed with the tweak, decrypted, then XORed with + * the tweak again to produce the output. + * Note that the caller is responsible for managing the tweak value. + * Use AES_xts_prep_next_tweak() to advance the tweak for the next block. + */ +void AES_xts_decrypt(const unsigned char *in, unsigned char *out, + const unsigned char *tweak, const AES_KEY *key); + +#endif --=20 2.43.0 From nobody Mon Sep 28 01:12:31 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1785773685; cv=none; d=zohomail.com; s=zohoarc; b=koc+YGph2q4ZjrAV3fwUdWlToavc3IIyJcnWjhzbxkyoHnRGv0ki04tjM16pri+nYVPQPCGLxw8Zr1vzsG+aaUmpxmev8/RwdWYpNTNlTUHybG+QkuH9SLXu59ha55PZrJ1zfBXpUB06ptRrzIJcAfhAi6MvjS/xx/ftpNFfAVM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785773685; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=hmMmEVX2PyKREt0Eqc9ijRYqocMKqA/X/bK25X2bK4U=; b=O6D4SFXoqgVWcBC4zzbGn/em7FtOayNg6Zilir9YNBc9SgPs0bQbR8y29fWqF9qDgDlUqhjxtAzBufuEpqxY+XGQn6nL+vnN2s8TIQtC4uN1NVZMfmXsirDm1/yGDCdDPKLf11lupylAWjFEHJ04vjUkZJQU0fd41BaXu770QoQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785773685568450.4808541309063; Mon, 3 Aug 2026 09:14:45 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wqvHw-0006SC-1G; Mon, 03 Aug 2026 12:13:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHV-00065h-7G; Mon, 03 Aug 2026 12:12:50 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHR-00036K-BL; Mon, 03 Aug 2026 12:12:48 -0400 Received: from pps.filterd (m0360072.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 673EHnqu2341358; Mon, 3 Aug 2026 16:12:36 GMT Received: from ppma23.wdc07v.mail.ibm.com (5d.69.3da9.ip4.static.sl-reverse.com [169.61.105.93]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs8euhbvb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:36 +0000 (GMT) Received: from pps.filterd (ppma23.wdc07v.mail.ibm.com [127.0.0.1]) by ppma23.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 673FuIZu006964; Mon, 3 Aug 2026 16:12:36 GMT Received: from smtprelay06.fra02v.mail.ibm.com ([9.218.2.230]) by ppma23.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4fsvmh6464-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:35 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay06.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 673GCVrm29688104 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 16:12:32 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DC16820040; Mon, 3 Aug 2026 16:12:31 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A871820043; Mon, 3 Aug 2026 16:12:31 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 16:12:31 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=hmMmEVX2PyKREt0Eq c9ijRYqocMKqA/X/bK25X2bK4U=; b=pT+5W2nlaj9DAQ1n/icWir4Jju4Taflny tIQzzzwLtBDJyC5eSNHy1iksy8Y1RxJVgQPqR9aadLjngSMPsZ36Ovtf+rBQQK5O ZBThecyMCLwQcS9Drj2W0O5b2kenkqm8oR6RGv3Bbu29TdQ+1CAzf9SN4mJ7UFtp 4yaJV6vgyOlkar6IcSlto3rxZvIp375Yd9v2SkDaXeWC76BNuFe5SL/HZJxrP2E+ I+WS7BDtotmrk9VZ+TizmYoFiHVmtJIBJXUkipz6oYogcNK1d1Con1XzDCIflQP3 5gcgSsODShAFSGUYZb14DuYdGOH8/gFQ90Fr2xGLCuxEFXt04/0hA== From: Harald Freudenberger To: richard.henderson@linaro.org, iii@linux.ibm.com, david@kernel.org, thuth@redhat.com, berrange@redhat.com Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org, linux-s390@vger.kernel.org, dengler@linux.ibm.com, borntraeger@linux.ibm.com, fcallies@linux.ibm.com, cohuck@redhat.com Subject: [PATCH v13 06/18] target/s390x: Support AES ECB for cpacf km instruction Date: Mon, 3 Aug 2026 18:12:23 +0200 Message-ID: <20260803161235.228704-7-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803161235.228704-1-freude@linux.ibm.com> References: <20260803161235.228704-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: xiO-PvtAX-mnd_182ZCCPGH83paVwKyg X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX8WVpa+ecuY3C JtkulmhlWkvGMMNlXynSS93u8QXx9ioH+bQIj47PSBZCGGUB4j6dCs9E9KwRNK78BPPtJA38pOW seznFch4H+fB8/XD3/4qxBULv8k+dlw= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfXxQqEX+Hhierc JfIfG89Vp0VlLCX7Fep7zYdIL/Dobrw9Qt6fd9yoNZVPrub9Fqa/QCH6Pz8ZbKKW8nNDSR0G2dW edU5++VK74sTXRM0PPTmajRRoBoGXtUpuySCCneDq5JUr3oI1oHMKKh6+UvmCwoPCzFnMvwcAw/ QRHecafVneomoLoXkJY5r2xrANfXEFe4W+shaV7MtQ0/k7xm21tInrr+225+naR04fm5bI6rAPW qjigyI1nJr6Waww8Dc3ZB89Ps63U2VE+XwkFDnDwP5HOxRkzzV6I2ANfN/sjXOPZjoDXGBHNpdk sZ28e40d0LCUUyfMonTg2NHMLuXGuExnbxG1JYIuetlDVc2Y5YCyrGRtxIsNbOpS7QSVS+XnmrG v17VyS1ADfQJG1Wf9nT0SBWYnoy72LQ9LR5e/u/DJSKezQg4zxUMamDXMN+3a9S58Yr2V+47Hg0 jvVPOosV9bsyyXCCnVg== X-Proofpoint-GUID: xiO-PvtAX-mnd_182ZCCPGH83paVwKyg X-Authority-Analysis: v=2.4 cv=KfzidwYD c=1 sm=1 tr=0 ts=6a70bdf4 cx=c_pps a=3Bg1Hr4SwmMryq2xdFQyZA==:117 a=3Bg1Hr4SwmMryq2xdFQyZA==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=RzCfie-kr_QcCd8fBx8p:22 a=VnNF1IyMAAAA:8 a=UeJqcyLMtA2A8E2_xXgA:9 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-03_03,2026-08-03_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 bulkscore=0 impostorscore=0 suspectscore=0 malwarescore=0 adultscore=0 clxscore=1015 priorityscore=1501 phishscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030141 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=148.163.158.5; envelope-from=freude@linux.ibm.com; helo=mx0b-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1785773686426158500 Content-Type: text/plain; charset="utf-8" Support the subfunctions CPACF_KM_AES_128, CPACF_KM_AES_192 and CPACF_KM_AES_256 for the cpacf km instruction. Tested-by: Holger Dengler Reviewed-by: Finn Callies Signed-off-by: Harald Freudenberger --- target/s390x/gen-features.c | 3 + target/s390x/tcg/cpacf.h | 6 ++ target/s390x/tcg/cpacf_aes.c | 107 +++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 24 +++++++ target/s390x/tcg/meson.build | 1 + 5 files changed, 141 insertions(+) create mode 100644 target/s390x/tcg/cpacf_aes.c diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index 78f71c6c7b..c8ba5107d7 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -922,6 +922,9 @@ static uint16_t qemu_MAX[] =3D { S390_FEAT_KLMD_SHA_256, S390_FEAT_KLMD_SHA_512, S390_FEAT_PRNO_TRNG, + S390_FEAT_KM_AES_128, + S390_FEAT_KM_AES_192, + S390_FEAT_KM_AES_256, }; =20 /****** END FEATURE DEFS ******/ diff --git a/target/s390x/tcg/cpacf.h b/target/s390x/tcg/cpacf.h index 94e9de5b23..cee393cdc0 100644 --- a/target/s390x/tcg/cpacf.h +++ b/target/s390x/tcg/cpacf.h @@ -233,4 +233,10 @@ int cpacf_sha512(CPUS390XState *env, const int mmu_idx= , uintptr_t ra, uint64_t param_addr, uint64_t *message_reg, uint64_t *len= _reg, uint32_t type); =20 +/* from cpacf_aes.c */ +int cpacf_aes_ecb(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *dst_ptr_reg, + uint64_t *src_ptr_reg, uint64_t *src_len_reg, + uint32_t type, uint8_t fc, uint8_t mod); + #endif /* S390X_CPACF_H */ diff --git a/target/s390x/tcg/cpacf_aes.c b/target/s390x/tcg/cpacf_aes.c new file mode 100644 index 0000000000..0dee9d3ec8 --- /dev/null +++ b/target/s390x/tcg/cpacf_aes.c @@ -0,0 +1,107 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * s390 cpacf aes + * + * Authors: + * Harald Freudenberger + */ + +#include "qemu/osdep.h" +#include "s390x-internal.h" +#include "tcg_s390x.h" +#include "accel/tcg/cpu-ldst-common.h" +#include "accel/tcg/cpu-mmu-index.h" +#include "crypto/aes.h" +#include "crypto/aes-helpers.h" +#include "target/s390x/tcg/cpacf.h" +#include "target/s390x/tcg/crypto_helper.h" + +/* + * read exactly one AES block from guest memory into a local buffer + */ +static inline void aes_read_block(CPUS390XState *env, const int mmu_idx, + const uintptr_t ra, uint64_t guest_addr, + uint8_t *buf) +{ + read_guest_wrap_u8(env, mmu_idx, ra, guest_addr, buf, AES_BLOCK_SIZE); +} + +/* + * write exactly one AES block from local buffer to guest memory + */ +static void aes_write_block(CPUS390XState *env, const int mmu_idx, + const uintptr_t ra, uint64_t guest_addr, + uint8_t *buf) +{ + write_guest_wrap_u8(env, mmu_idx, ra, guest_addr, buf, AES_BLOCK_SIZE); +} + +int cpacf_aes_ecb(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *dst_ptr_reg, + uint64_t *src_ptr_reg, uint64_t *src_len_reg, + uint32_t type, uint8_t fc, uint8_t mod) +{ + enum { MAX_BLOCKS_PER_RUN =3D 8192 / AES_BLOCK_SIZE }; + uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; + uint64_t len =3D *src_len_reg, done =3D 0; + int i, keysize, addr_reg_size =3D 64; + uint8_t key[32]; + AES_KEY exkey; + + g_assert(type =3D=3D S390_FEAT_TYPE_KM); + switch (fc) { + case CPACF_KM_AES_128: + keysize =3D 16; + break; + case CPACF_KM_AES_192: + keysize =3D 24; + break; + case CPACF_KM_AES_256: + keysize =3D 32; + break; + default: + g_assert_not_reached(); + } + + if (!(env->psw.mask & PSW_MASK_64)) { + len =3D (uint32_t)len; + addr_reg_size =3D (env->psw.mask & PSW_MASK_32) ? 32 : 24; + } + + /* length has to be properly aligned. */ + if (!QEMU_IS_ALIGNED(len, AES_BLOCK_SIZE)) { + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } + + /* fetch key from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, param_addr, key, keysize); + + /* expand key */ + if (mod) { + AES_set_decrypt_key(key, keysize * 8, &exkey); + } else { + AES_set_encrypt_key(key, keysize * 8, &exkey); + } + + /* process up to MAX_BLOCKS_PER_RUN aes blocks */ + for (i =3D 0; i < MAX_BLOCKS_PER_RUN && len >=3D AES_BLOCK_SIZE; i++) { + aes_read_block(env, mmu_idx, ra, *src_ptr_reg + done, in); + if (mod) { + AES_decrypt(in, out, &exkey); + } else { + AES_encrypt(in, out, &exkey); + } + aes_write_block(env, mmu_idx, ra, *dst_ptr_reg + done, out); + len -=3D AES_BLOCK_SIZE; + done +=3D AES_BLOCK_SIZE; + } + + *src_ptr_reg =3D deposit64(*src_ptr_reg, 0, addr_reg_size, + *src_ptr_reg + done); + *dst_ptr_reg =3D deposit64(*dst_ptr_reg, 0, addr_reg_size, + *dst_ptr_reg + done); + *src_len_reg -=3D done; + + return !len ? 0 : 3; +} diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_hel= per.c index d996caf56a..80403cafbb 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -90,6 +90,27 @@ static int cpacf_klmd(CPUS390XState *env, const int mmu_= idx, const uintptr_t ra, return rc; } =20 +static int cpacf_km(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint32_t r1, uint32_t r2, uint32_t r3, + uint8_t fc, uint8_t mod) +{ + int rc =3D 0; + + switch (fc) { + case CPACF_KM_AES_128: + case CPACF_KM_AES_192: + case CPACF_KM_AES_256: + rc =3D cpacf_aes_ecb(env, mmu_idx, ra, env->regs[1], + &env->regs[r1], &env->regs[r2], &env->regs[r2 += 1], + S390_FEAT_TYPE_KM, fc, mod); + break; + default: + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } + + return rc; +} + static int cpacf_ppno(CPUS390XState *env, const int mmu_idx, uintptr_t ra, uint32_t r1, uint32_t r2, uint32_t r3, uint8_t fc) { @@ -154,6 +175,9 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, u= int32_t r2, uint32_t r3, case S390_FEAT_TYPE_KLMD: rc =3D cpacf_klmd(env, mmu_idx, ra, r1, r2, r3, fc); break; + case S390_FEAT_TYPE_KM: + rc =3D cpacf_km(env, mmu_idx, ra, r1, r2, r3, fc, mod); + break; case S390_FEAT_TYPE_PPNO: rc =3D cpacf_ppno(env, mmu_idx, ra, r1, r2, r3, fc); break; diff --git a/target/s390x/tcg/meson.build b/target/s390x/tcg/meson.build index 8ae8da9708..6f2e75764b 100644 --- a/target/s390x/tcg/meson.build +++ b/target/s390x/tcg/meson.build @@ -5,6 +5,7 @@ s390x_ss.add(when: 'CONFIG_TCG', if_true: files( )) s390x_common_ss.add(when: 'CONFIG_TCG', if_true: files( 'cc_helper.c', + 'cpacf_aes.c', 'cpacf_sha256.c', 'cpacf_sha512.c', 'crypto_helper.c', --=20 2.43.0 From nobody Mon Sep 28 01:12:31 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1785773687; cv=none; d=zohomail.com; s=zohoarc; b=Or7DOduT29ABPejFnTHrQbcrVlyJDH0lkDdgTokBuGkBesO8Bt69xltFZY6GmjZ082bFxZcWUOtAmZtIj5tYzIH7ZAbM/MGfqg0sUlu1+/5/+MTxcnKJy63+jYi0BFsXLIfkV3mMeEMU6mLXdObqdMzrDIcrP2H+0rdFC34YVrY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785773687; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=bDNwl77WIcVCGtvkFS2DvsrQjGnrI3UHFNs1eKD0yZU=; b=E8qMeqt4slSaGW/5WgQ/PfM4Fimrg71WDHBcUqhKWnFc9uY+gpS9mSSLl25iDHDEsYQcHAn9PcCV9DxBjyPkJ7fASKIIbOAvj7dlbsxr5+2ua73f5W0AgkGylL4wxkk5glBrFuOUmYy95lxLlnJZL7UUegpCk05b0Ty9bpw4KO4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785773687273890.7513121506698; Mon, 3 Aug 2026 09:14:47 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wqvI7-0006df-Sf; Mon, 03 Aug 2026 12:13:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHU-00064U-5X; Mon, 03 Aug 2026 12:12:48 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHR-00036I-AN; Mon, 03 Aug 2026 12:12:47 -0400 Received: from pps.filterd (m0356516.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 673EIqXh2203944; Mon, 3 Aug 2026 16:12:37 GMT Received: from ppma21.wdc07v.mail.ibm.com (5b.69.3da9.ip4.static.sl-reverse.com [169.61.105.91]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs67hhp3q-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:36 +0000 (GMT) Received: from pps.filterd (ppma21.wdc07v.mail.ibm.com [127.0.0.1]) by ppma21.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 673GBI3P011999; Mon, 3 Aug 2026 16:12:36 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4fsv4jx6ag-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:36 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 673GCW0732178564 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 16:12:32 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1981320043; Mon, 3 Aug 2026 16:12:32 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E1CA82004B; Mon, 3 Aug 2026 16:12:31 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 16:12:31 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=bDNwl77WIcVCGtvkF S2DvsrQjGnrI3UHFNs1eKD0yZU=; b=jDyu1+K6XXLqIv2ErkJvFrOPtnLJN217/ lykyObidEKxG8nBeVdf8aElxndnGBX7lZXLWKlI0clegq0D6XMeDtE8CmMajzrZh n73YaiCQFkkjCtEjb4W/iv2NrKhE25j5nW7BqEY3ocG0dpWcX/z828tJ5IkncP0+ k7vGC1ByhDwH4ehUnwSnYE5xlSLMxXIZFuAR0czXIO6R8FDU6ZAbUR9HahuhiPxY 59en2GvJEEtJO1mg5Ag+I8z9RwfGCxwqphQeGwPi7irlC7mG1EiDxIRa6WeoOEV0 IhhmCUYhRJ/bfCAv0qGaUAQ4yVsYHkXQvLGWbgNVxtAv+Zdu/qorw== From: Harald Freudenberger To: richard.henderson@linaro.org, iii@linux.ibm.com, david@kernel.org, thuth@redhat.com, berrange@redhat.com Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org, linux-s390@vger.kernel.org, dengler@linux.ibm.com, borntraeger@linux.ibm.com, fcallies@linux.ibm.com, cohuck@redhat.com Subject: [PATCH v13 07/18] target/s390x: Support AES CBC for cpacf kmc instruction Date: Mon, 3 Aug 2026 18:12:24 +0200 Message-ID: <20260803161235.228704-8-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803161235.228704-1-freude@linux.ibm.com> References: <20260803161235.228704-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX8YWDXBM4hQRo 5xvBfsrGTyBNoCsVNdFkOO3tza7LmE3DieCQastKToM3wgrWzI8sH0YdRGtiFyXratPwNBC4njS P3F+kfkIe3uwhPJgxzm30GhFWstUtsA= X-Authority-Analysis: v=2.4 cv=I7VVgtgg c=1 sm=1 tr=0 ts=6a70bdf4 cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=Y2IxJ9c9Rs8Kov3niI8_:22 a=VnNF1IyMAAAA:8 a=4s_zGP7M7QCs5o7xjogA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfXwc7ewJ5H+jEt quFbmpGmXa0Y5U3e/8zw6oXWoTQ5nN6Erqgt3+JC9YHMx12nuCxzn9Dg90aTwml/6vi43hra0rj Cw3uW4/iKZnq9iZOMwmqGtr/43Jbf1hDibu22L1O7z/tqkzX4Bm45GO3+roqlE9ljnczXrn17Ep VZzhPOehRgS6/PauDnGqJn/X4xUY/kTpYYcT+aLLQ508Nyj6wd6cVDM3aP5CLKRg2BWVP5BVg6p oVMPrxLM3cahwmCwdca2mzB6gZf9JNi+t9XoZjQSeag5Z4N1ISEbFkGhe4zvTI8Igw0oivZfAmu rTauNB7wfU0JMfoSGpXM9cZ1qDVYnWI21hDkc93HBNz5nG+ZgtlvGD9nGcjJhkSbRtqciEiYBXc 937qX1Li5BWUvQqxhk3HH56V7QsmOJs1png+bj+Tm9kaW7mee/JI7o4a2FdhqamAnnw1BHIn9+F 6ep1IgN3S0SrLj223vQ== X-Proofpoint-ORIG-GUID: mbnRbOSaQ4y46Nkn7mZLy2ocf4EkePQi X-Proofpoint-GUID: mbnRbOSaQ4y46Nkn7mZLy2ocf4EkePQi X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-03_03,2026-08-03_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 impostorscore=0 clxscore=1015 priorityscore=1501 suspectscore=0 malwarescore=0 adultscore=0 lowpriorityscore=0 phishscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030141 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=148.163.158.5; envelope-from=freude@linux.ibm.com; helo=mx0b-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1785773688186158500 Content-Type: text/plain; charset="utf-8" Support the subfunctions CPACF_KMC_AES_128, CPACF_KMC_AES_192 and CPACF_KMC_AES_256 for the cpacf kmc instruction. Tested-by: Holger Dengler Reviewed-by: Finn Callies Reviewed-by: Ilya Leoshkevich Signed-off-by: Harald Freudenberger --- target/s390x/gen-features.c | 3 ++ target/s390x/tcg/cpacf.h | 4 ++ target/s390x/tcg/cpacf_aes.c | 79 ++++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 24 ++++++++++ 4 files changed, 110 insertions(+) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index c8ba5107d7..2dacc65995 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -925,6 +925,9 @@ static uint16_t qemu_MAX[] =3D { S390_FEAT_KM_AES_128, S390_FEAT_KM_AES_192, S390_FEAT_KM_AES_256, + S390_FEAT_KMC_AES_128, + S390_FEAT_KMC_AES_192, + S390_FEAT_KMC_AES_256, }; =20 /****** END FEATURE DEFS ******/ diff --git a/target/s390x/tcg/cpacf.h b/target/s390x/tcg/cpacf.h index cee393cdc0..df6e3262d3 100644 --- a/target/s390x/tcg/cpacf.h +++ b/target/s390x/tcg/cpacf.h @@ -238,5 +238,9 @@ int cpacf_aes_ecb(CPUS390XState *env, const int mmu_idx= , uintptr_t ra, uint64_t param_addr, uint64_t *dst_ptr_reg, uint64_t *src_ptr_reg, uint64_t *src_len_reg, uint32_t type, uint8_t fc, uint8_t mod); +int cpacf_aes_cbc(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *dst_ptr_reg, + uint64_t *src_ptr_reg, uint64_t *src_len_reg, + uint32_t type, uint8_t fc, uint8_t mod); =20 #endif /* S390X_CPACF_H */ diff --git a/target/s390x/tcg/cpacf_aes.c b/target/s390x/tcg/cpacf_aes.c index 0dee9d3ec8..fa30fad1d4 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -105,3 +105,82 @@ int cpacf_aes_ecb(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, =20 return !len ? 0 : 3; } + +int cpacf_aes_cbc(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *dst_ptr_reg, + uint64_t *src_ptr_reg, uint64_t *src_len_reg, + uint32_t type, uint8_t fc, uint8_t mod) +{ + enum { MAX_BLOCKS_PER_RUN =3D 8192 / AES_BLOCK_SIZE }; + uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; + uint64_t len =3D *src_len_reg, done =3D 0; + int i, keysize, addr_reg_size =3D 64; + uint8_t key[32], iv[AES_BLOCK_SIZE]; + AES_KEY exkey; + + g_assert(type =3D=3D S390_FEAT_TYPE_KMC); + + switch (fc) { + case CPACF_KMC_AES_128: + keysize =3D 16; + break; + case CPACF_KMC_AES_192: + keysize =3D 24; + break; + case CPACF_KMC_AES_256: + keysize =3D 32; + break; + default: + g_assert_not_reached(); + } + + if (!(env->psw.mask & PSW_MASK_64)) { + len =3D (uint32_t)len; + addr_reg_size =3D (env->psw.mask & PSW_MASK_32) ? 32 : 24; + } + + /* length has to be properly aligned. */ + if (!QEMU_IS_ALIGNED(len, AES_BLOCK_SIZE)) { + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } + + /* fetch iv from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, param_addr, iv, AES_BLOCK_SIZE); + + /* fetch key from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, + param_addr + AES_BLOCK_SIZE, key, keysize); + + /* expand key */ + if (mod) { + AES_set_decrypt_key(key, keysize * 8, &exkey); + } else { + AES_set_encrypt_key(key, keysize * 8, &exkey); + } + + /* process up to MAX_BLOCKS_PER_RUN aes blocks */ + for (i =3D 0; i < MAX_BLOCKS_PER_RUN && len >=3D AES_BLOCK_SIZE; i++) { + aes_read_block(env, mmu_idx, ra, *src_ptr_reg + done, in); + if (mod) { + /* decrypt in =3D> out */ + AES_cbc_decrypt(in, out, iv, &exkey); + } else { + /* encrypt in =3D> out */ + AES_cbc_encrypt(in, out, iv, &exkey); + } + aes_write_block(env, mmu_idx, ra, *dst_ptr_reg + done, out); + len -=3D AES_BLOCK_SIZE; + done +=3D AES_BLOCK_SIZE; + } + + /* update iv in param block */ + write_guest_wrap_u8(env, mmu_idx, ra, param_addr, iv, AES_BLOCK_SIZE); + + *src_ptr_reg =3D deposit64(*src_ptr_reg, 0, addr_reg_size, + *src_ptr_reg + done); + *dst_ptr_reg =3D deposit64(*dst_ptr_reg, 0, addr_reg_size, + *dst_ptr_reg + done); + *src_len_reg -=3D done; + + return !len ? 0 : 3; +} diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_hel= per.c index 80403cafbb..695e3fef7e 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -111,6 +111,27 @@ static int cpacf_km(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, return rc; } =20 +static int cpacf_kmc(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint32_t r1, uint32_t r2, uint32_t r3, + uint8_t fc, uint8_t mod) +{ + int rc =3D 0; + + switch (fc) { + case CPACF_KMC_AES_128: + case CPACF_KMC_AES_192: + case CPACF_KMC_AES_256: + rc =3D cpacf_aes_cbc(env, mmu_idx, ra, env->regs[1], + &env->regs[r1], &env->regs[r2], &env->regs[r2 += 1], + S390_FEAT_TYPE_KMC, fc, mod); + break; + default: + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } + + return rc; +} + static int cpacf_ppno(CPUS390XState *env, const int mmu_idx, uintptr_t ra, uint32_t r1, uint32_t r2, uint32_t r3, uint8_t fc) { @@ -178,6 +199,9 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, u= int32_t r2, uint32_t r3, case S390_FEAT_TYPE_KM: rc =3D cpacf_km(env, mmu_idx, ra, r1, r2, r3, fc, mod); break; + case S390_FEAT_TYPE_KMC: + rc =3D cpacf_kmc(env, mmu_idx, ra, r1, r2, r3, fc, mod); + break; case S390_FEAT_TYPE_PPNO: rc =3D cpacf_ppno(env, mmu_idx, ra, r1, r2, r3, fc); break; --=20 2.43.0 From nobody Mon Sep 28 01:12:31 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1785773716; cv=none; d=zohomail.com; s=zohoarc; b=ByP5EJN15h2jH7Z9hx/KHh4v5KZXaKUNnyNcnOnxBa0YCqM7OWBtoz5n4lqGRo9AswLCJF6duA3O7XDE0nO8C1//YHOYoKIzjS51NsRCKZ7pEPt3mFZj6Iugsph9lqvg8sS8Z7hBOSawlcuaKFiN3ostejBs2ZNVxpiuf0JjGbw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785773716; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=WN6+UdiluCJxd9Sj/bvGQTwfIcMhHuvZjR1XnTQDbuE=; b=IJqTOTlE19v63R1B8adorB5u6i0IZAVzETPYJtfkSNrtAncV9ZxgFq/DxFuk2N15hMwYV01x64rzbqFyNIbWEhBCn54Szp02ysPnXX0s7VzKNJnU5bp3UB3IqY6hc8krI7tfJ3oAAyF99vZx9XUbGjJmZrkIduH9aXsZeiF6Hyw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785773716805154.12469566622167; Mon, 3 Aug 2026 09:15:16 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wqvHt-0006KH-Hs; Mon, 03 Aug 2026 12:13:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHQ-000619-Rj; Mon, 03 Aug 2026 12:12:45 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHO-00034u-R1; Mon, 03 Aug 2026 12:12:44 -0400 Received: from pps.filterd (m0356516.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 673EHpM92202026; Mon, 3 Aug 2026 16:12:37 GMT Received: from ppma11.dal12v.mail.ibm.com (db.9e.1632.ip4.static.sl-reverse.com [50.22.158.219]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs67hhp3p-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:36 +0000 (GMT) Received: from pps.filterd (ppma11.dal12v.mail.ibm.com [127.0.0.1]) by ppma11.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 673GBEJK012381; Mon, 3 Aug 2026 16:12:36 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 4fswtydx9v-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:36 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 673GCWNO32178566 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 16:12:32 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 48D8D20040; Mon, 3 Aug 2026 16:12:32 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1F4A12004D; Mon, 3 Aug 2026 16:12:32 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 16:12:32 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=WN6+UdiluCJxd9Sj/ bvGQTwfIcMhHuvZjR1XnTQDbuE=; b=fJ+hfMsI9gTi697jJgNP15stKDBB4tpnD U0onwdC2oTUCHGb8OBf9vIDE982ChmTnBluItizaZeXRh+fBOKsbe3CglCdrIwEs CxL5bJmm1mcEYhFkxkKEpDgz29RX83oY5CfsUgj5VDZNQV6B6201ZwfCxF1XiDTs AnHAUNcf5HSYQW8VIk/+EvE8llDfjVT3h/SlGM0W9/Ki3zH3Vj0P/d6hClqy5ODE zb5p9rhnBI4eC3ZGfGcQMIvcHB8CpRMxhj0A8sI75y/+gNSxDFctiTKu8WBK73x5 wAFwNu4emdG1IdHjYzmX1EGdmDuN/HOd5aJGeHEYbim+gbE7dX+pg== From: Harald Freudenberger To: richard.henderson@linaro.org, iii@linux.ibm.com, david@kernel.org, thuth@redhat.com, berrange@redhat.com Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org, linux-s390@vger.kernel.org, dengler@linux.ibm.com, borntraeger@linux.ibm.com, fcallies@linux.ibm.com, cohuck@redhat.com Subject: [PATCH v13 08/18] target/s390x: Support AES CTR for cpacf kmctr instruction Date: Mon, 3 Aug 2026 18:12:25 +0200 Message-ID: <20260803161235.228704-9-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803161235.228704-1-freude@linux.ibm.com> References: <20260803161235.228704-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX2lfdfkOfWlAW CwrTVLAxSTtCttY8ue1IQc0If/j/4/Nw1J+/c0c502Y4wv+sXykR5GR5gY6TpX2XXS/L1h1U26t 03c8IQBQj7uxjPQvVIU0shsI/9PBxjM= X-Authority-Analysis: v=2.4 cv=I7VVgtgg c=1 sm=1 tr=0 ts=6a70bdf5 cx=c_pps a=aDMHemPKRhS1OARIsFnwRA==:117 a=aDMHemPKRhS1OARIsFnwRA==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=Y2IxJ9c9Rs8Kov3niI8_:22 a=VnNF1IyMAAAA:8 a=LQnWXxm1RwZjr7XDrSkA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX3GEY3dQL+KcX 9suxRXoZUZUAgL5qreLQwIKFlZfkWi6drNIGmI10ERIlvZooC2w6A8Gi/bbZ/1bDqD+CvIF2deM RfwNvEdjNjaudY9X7QmZfoG29d9LOHuN/IVISQgDCVg3n81LTkNb9hxPf21Jxu4j4lf4vWnArCS RF3BIvmVT3kP50ZnRB9/o+KfDFkOF+y1HriIi6H+fGkdC4Y9M9UvL4J3LvAZcQSrhYzIdMjxqza 3adymDBLj79Zv/wz7EB+4IHmN+khToTNA8Q104jCOjZK+JUghN7wUVNVWJL+miYncE91mpPnoNN 7uU4Y8Q9Aw6ZwsnVfTgzgIva72LZlg8bfPmeLRz7zwuA7bfo3Skmw0HnvIZUN/okYLABvni2cdl wKp34jQzatf81TSfsqdwZZvRY/6o+kCkUyxLEMM8pk2hUqBkLT4L6WmQMQRsC3wA1RqGYdVq5/E 8SO94edrH/YhTgSaDoQ== X-Proofpoint-ORIG-GUID: oUsnVYxOIFsqeGhoQtS3VqEHm5easiRh X-Proofpoint-GUID: oUsnVYxOIFsqeGhoQtS3VqEHm5easiRh X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-03_03,2026-08-03_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 impostorscore=0 clxscore=1015 priorityscore=1501 suspectscore=0 malwarescore=0 adultscore=0 lowpriorityscore=0 phishscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030141 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=148.163.158.5; envelope-from=freude@linux.ibm.com; helo=mx0b-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1785773718422158500 Content-Type: text/plain; charset="utf-8" Support the subfunctions CPACF_KMCTR_AES_128, CPACF_KMCTR_AES_192 and CPACF_KMCTR_AES_256 for the cpacf kmctr instruction. Reviewed-by: Finn Callies Reviewed-by: Ilya Leoshkevich Signed-off-by: Harald Freudenberger --- target/s390x/gen-features.c | 3 ++ target/s390x/tcg/cpacf.h | 5 +++ target/s390x/tcg/cpacf_aes.c | 70 ++++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 24 +++++++++++ 4 files changed, 102 insertions(+) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index 2dacc65995..3281037958 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -928,6 +928,9 @@ static uint16_t qemu_MAX[] =3D { S390_FEAT_KMC_AES_128, S390_FEAT_KMC_AES_192, S390_FEAT_KMC_AES_256, + S390_FEAT_KMCTR_AES_128, + S390_FEAT_KMCTR_AES_192, + S390_FEAT_KMCTR_AES_256, }; =20 /****** END FEATURE DEFS ******/ diff --git a/target/s390x/tcg/cpacf.h b/target/s390x/tcg/cpacf.h index df6e3262d3..4af7bc753c 100644 --- a/target/s390x/tcg/cpacf.h +++ b/target/s390x/tcg/cpacf.h @@ -242,5 +242,10 @@ int cpacf_aes_cbc(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, uint64_t param_addr, uint64_t *dst_ptr_reg, uint64_t *src_ptr_reg, uint64_t *src_len_reg, uint32_t type, uint8_t fc, uint8_t mod); +int cpacf_aes_ctr(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *dst_ptr_reg, + uint64_t *src_ptr_reg, uint64_t *src_len_reg, + uint64_t *ctr_ptr_reg, uint32_t type, + uint8_t fc, uint8_t mod); =20 #endif /* S390X_CPACF_H */ diff --git a/target/s390x/tcg/cpacf_aes.c b/target/s390x/tcg/cpacf_aes.c index fa30fad1d4..a94c5e74e1 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -184,3 +184,73 @@ int cpacf_aes_cbc(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, =20 return !len ? 0 : 3; } + +int cpacf_aes_ctr(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *dst_ptr_reg, + uint64_t *src_ptr_reg, uint64_t *src_len_reg, + uint64_t *ctr_ptr_reg, uint32_t type, + uint8_t fc, uint8_t mod) +{ + enum { MAX_BLOCKS_PER_RUN =3D 8192 / AES_BLOCK_SIZE }; + uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; + uint64_t len =3D *src_len_reg, done =3D 0; + uint8_t ctr[AES_BLOCK_SIZE], key[32]; + int i, keysize, addr_reg_size =3D 64; + AES_KEY exkey; + + g_assert(type =3D=3D S390_FEAT_TYPE_KMCTR); + + switch (fc) { + case CPACF_KMCTR_AES_128: + keysize =3D 16; + break; + case CPACF_KMCTR_AES_192: + keysize =3D 24; + break; + case CPACF_KMCTR_AES_256: + keysize =3D 32; + break; + default: + g_assert_not_reached(); + } + + if (!(env->psw.mask & PSW_MASK_64)) { + len =3D (uint32_t)len; + addr_reg_size =3D (env->psw.mask & PSW_MASK_32) ? 32 : 24; + } + + /* length has to be properly aligned. */ + if (!QEMU_IS_ALIGNED(len, AES_BLOCK_SIZE)) { + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } + + /* fetch key from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, param_addr, key, keysize); + + /* expand key */ + AES_set_encrypt_key(key, keysize * 8, &exkey); + + /* process up to MAX_BLOCKS_PER_RUN aes blocks */ + for (i =3D 0; i < MAX_BLOCKS_PER_RUN && len >=3D AES_BLOCK_SIZE; i++) { + /* read in nonce/ctr =3D> ctr */ + aes_read_block(env, mmu_idx, ra, *ctr_ptr_reg + done, ctr); + /* read in one block of input data =3D> in */ + aes_read_block(env, mmu_idx, ra, *src_ptr_reg + done, in); + /* encrypt ctr and xor with in =3D> out */ + AES_ctr_encrypt(in, out, ctr, &exkey); + /* write out the processed block */ + aes_write_block(env, mmu_idx, ra, *dst_ptr_reg + done, out); + len -=3D AES_BLOCK_SIZE; + done +=3D AES_BLOCK_SIZE; + } + + *src_ptr_reg =3D deposit64(*src_ptr_reg, 0, addr_reg_size, + *src_ptr_reg + done); + *dst_ptr_reg =3D deposit64(*dst_ptr_reg, 0, addr_reg_size, + *dst_ptr_reg + done); + *ctr_ptr_reg =3D deposit64(*ctr_ptr_reg, 0, addr_reg_size, + *ctr_ptr_reg + done); + *src_len_reg -=3D done; + + return !len ? 0 : 3; +} diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_hel= per.c index 695e3fef7e..7dd6ae4ed4 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -132,6 +132,27 @@ static int cpacf_kmc(CPUS390XState *env, const int mmu= _idx, uintptr_t ra, return rc; } =20 +static int cpacf_kmctr(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint32_t r1, uint32_t r2, uint32_t r3, + uint8_t fc, uint8_t mod) +{ + int rc =3D 0; + + switch (fc) { + case CPACF_KMCTR_AES_128: + case CPACF_KMCTR_AES_192: + case CPACF_KMCTR_AES_256: + rc =3D cpacf_aes_ctr(env, mmu_idx, ra, env->regs[1], + &env->regs[r1], &env->regs[r2], &env->regs[r2 += 1], + &env->regs[r3], S390_FEAT_TYPE_KMCTR, fc, mod); + break; + default: + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } + + return rc; +} + static int cpacf_ppno(CPUS390XState *env, const int mmu_idx, uintptr_t ra, uint32_t r1, uint32_t r2, uint32_t r3, uint8_t fc) { @@ -202,6 +223,9 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, u= int32_t r2, uint32_t r3, case S390_FEAT_TYPE_KMC: rc =3D cpacf_kmc(env, mmu_idx, ra, r1, r2, r3, fc, mod); break; + case S390_FEAT_TYPE_KMCTR: + rc =3D cpacf_kmctr(env, mmu_idx, ra, r1, r2, r3, fc, mod); + break; case S390_FEAT_TYPE_PPNO: rc =3D cpacf_ppno(env, mmu_idx, ra, r1, r2, r3, fc); break; --=20 2.43.0 From nobody Mon Sep 28 01:12:31 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1785773780; cv=none; d=zohomail.com; s=zohoarc; b=ZsPRLnfVqpFzI8b2A3IBBK6TBvR0pAGm9QzqGDphO97vr7721zNOs3ccnh4r2oqpEMyMseNdqPrU9FDmzBOyjKDFc+4Iz+x7wbQOMMhw3J1bxMpvmr/uUcomjNHcM+/BMWV32vRm2BpfkJ1vvVvQ4Wk8zKyYMsZuMs/RjERB9IY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785773780; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=gVJ5/l9qbSpOyFbwIpE11qxzJWNwUiLc0YoLgR2jK1g=; b=knjjFsgs1a7r8PtiTne0YdxvCWmcCIqfBHSMQc4ogVfJD0PXYzdJl9VhWEbm19UUrLFvvrhCkGICbU2QipuCJTGo71zAy/dAOrJ/gMAH6QVjIfBLdVetTAQ/6vlRmCQE6PJ426aVXrGtqm9gyV1nb+/DsczTFof8ioSgkGElJZs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785773780653278.21941577300686; Mon, 3 Aug 2026 09:16:20 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wqvHt-0006I6-0V; Mon, 03 Aug 2026 12:13:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHS-00061K-0b; Mon, 03 Aug 2026 12:12:46 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHP-00034r-As; Mon, 03 Aug 2026 12:12:45 -0400 Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 673EHoYe2282779; Mon, 3 Aug 2026 16:12:37 GMT Received: from ppma12.dal12v.mail.ibm.com (dc.9e.1632.ip4.static.sl-reverse.com [50.22.158.220]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs8h4sqv5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:37 +0000 (GMT) Received: from pps.filterd (ppma12.dal12v.mail.ibm.com [127.0.0.1]) by ppma12.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 673GBFbd013151; Mon, 3 Aug 2026 16:12:36 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 4fsu4qeb5y-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:36 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 673GCW0Z32178568 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 16:12:32 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7750720040; Mon, 3 Aug 2026 16:12:32 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4E0CF2004B; Mon, 3 Aug 2026 16:12:32 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 16:12:32 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=gVJ5/l9qbSpOyFbwI pE11qxzJWNwUiLc0YoLgR2jK1g=; b=HSyqdM0iiuwwHdSJRFxwt96osoJ5sBTfa qNBCYLnvt+m3FgOEP1oSmf/cXXj0sgTdTqMX7Kpl3rjBI/9etRaKOY0qa+71caB9 SxTwqnv43xYro5uzfAUK4nmll8FRh378vBfb46oc2RGCP7mfYYGTvyt+JSXx1jcD MEwPW2w8mRUEUXSwCG+e1IM+N3eKWdgMoPcKZGjUj+6TQFaL4D5KF/2bn+8LWIgu yy8OikAIwjgGyhlp6W+gb39ely16iApAH6UPq5ggBoCpOpWizflZEYE3uoXdbG7f ENyTTRmZiydseLQFFE6ekgP9Fo4TTx0IhCbSn7shlhXOc2FUwUVSw== From: Harald Freudenberger To: richard.henderson@linaro.org, iii@linux.ibm.com, david@kernel.org, thuth@redhat.com, berrange@redhat.com Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org, linux-s390@vger.kernel.org, dengler@linux.ibm.com, borntraeger@linux.ibm.com, fcallies@linux.ibm.com, cohuck@redhat.com Subject: [PATCH v13 09/18] target/s390x: Minimal AES XTS support for cpacf pcc instruction Date: Mon, 3 Aug 2026 18:12:26 +0200 Message-ID: <20260803161235.228704-10-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803161235.228704-1-freude@linux.ibm.com> References: <20260803161235.228704-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX2m/7FZ3GS2Y0 9Isy+OAhkJwVuymupmh8U6oeM4Rr9ZyoiHMdNEib7A+GxOhvg8pJBe1V1TnXiAfw60hGsr84zFq oeUyPyYPaXjz2iKr6tu3HJGxD8D1EvM= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfXzuVWQafEZddC jgSi4wp16oSFqWrT7n3uP5zRDBIrr/Pf/VrcSqzXFCjJAMRgxss4941wdrrhn6tjg0en7f46Fu8 esDLx7rejihAHsDGy7s/s7w9VlPFwMybbcSqNKxiuTpBVm67fu34CBjgyiNVgqnWj659dwhANQz gM/pJSxQ3NlDKIcXXWDPy8GX0ZCm3bNWIsH3ho/l3eSMc3HU9VFh5Pg6CnpASG1B7dHbnS12FQ7 puaeyezeoLUMFD9UrI75tIPJrRXnn5azBfSK4jyMB2QLF415JUjuJej9vU3LKVVkozgal+Vauji ohhevxd4tAJCZHflryQ20qke3by7x9YpojIlepSPD0afaA81DO2Hms9N0cAaz1OrC+ZCzULbOfW txbnw5SGJacmnsnA2OPxBJEOSN9P1XqO0tDeuxgAtYMw3hofs8Q8IvUCvQjuU9quwtDgWtFDBHz Hd1eufkF+W9X7u2pp4g== X-Authority-Analysis: v=2.4 cv=SI1ykuvH c=1 sm=1 tr=0 ts=6a70bdf5 cx=c_pps a=bLidbwmWQ0KltjZqbj+ezA==:117 a=bLidbwmWQ0KltjZqbj+ezA==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=WW2E3BMAMqXElFb4OSsA:9 X-Proofpoint-ORIG-GUID: csNIZQpdOZdanx2kRpW-2UtWIGIdZxkQ X-Proofpoint-GUID: csNIZQpdOZdanx2kRpW-2UtWIGIdZxkQ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-03_03,2026-08-03_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 bulkscore=0 suspectscore=0 impostorscore=0 spamscore=0 phishscore=0 priorityscore=1501 lowpriorityscore=0 adultscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030141 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=148.163.156.1; envelope-from=freude@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1785773782725158500 Content-Type: text/plain; charset="utf-8" Support CPACF pcc subfunctions PCC-Compute-XTS-Parameter-AES-128 and PCC-Compute-XTS-Parameter-AES-245 but only for the special case block sequential number is 0. However, this covers the s390 AES XTS implementation in the Linux kernel and Libica and thus also Opencryptoki clear key via Libica. Tested-by: Holger Dengler Signed-off-by: Harald Freudenberger Reviewed-by: Holger Dengler --- target/s390x/gen-features.c | 2 ++ target/s390x/tcg/cpacf.h | 2 ++ target/s390x/tcg/cpacf_aes.c | 54 ++++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 20 ++++++++++++ 4 files changed, 78 insertions(+) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index 3281037958..4132d7b932 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -931,6 +931,8 @@ static uint16_t qemu_MAX[] =3D { S390_FEAT_KMCTR_AES_128, S390_FEAT_KMCTR_AES_192, S390_FEAT_KMCTR_AES_256, + S390_FEAT_PCC_XTS_AES_128, + S390_FEAT_PCC_XTS_AES_256, }; =20 /****** END FEATURE DEFS ******/ diff --git a/target/s390x/tcg/cpacf.h b/target/s390x/tcg/cpacf.h index 4af7bc753c..cbb6090b44 100644 --- a/target/s390x/tcg/cpacf.h +++ b/target/s390x/tcg/cpacf.h @@ -247,5 +247,7 @@ int cpacf_aes_ctr(CPUS390XState *env, const int mmu_idx= , uintptr_t ra, uint64_t *src_ptr_reg, uint64_t *src_len_reg, uint64_t *ctr_ptr_reg, uint32_t type, uint8_t fc, uint8_t mod); +int cpacf_aes_pcc(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint8_t fc); =20 #endif /* S390X_CPACF_H */ diff --git a/target/s390x/tcg/cpacf_aes.c b/target/s390x/tcg/cpacf_aes.c index a94c5e74e1..1127452f28 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -254,3 +254,57 @@ int cpacf_aes_ctr(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, =20 return !len ? 0 : 3; } + +int cpacf_aes_pcc(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint8_t fc) +{ + uint8_t key[32], tweak[AES_BLOCK_SIZE], buf[AES_BLOCK_SIZE]; + int keysize, i; + AES_KEY exkey; + + switch (fc) { + case CPACF_PCC_XTS_AES_128: + keysize =3D 16; + break; + case CPACF_PCC_XTS_AES_256: + keysize =3D 32; + break; + default: + g_assert_not_reached(); + } + + /* fetch block sequence nr from param block into buf */ + read_guest_wrap_u8(env, mmu_idx, ra, + param_addr + keysize + AES_BLOCK_SIZE, + buf, AES_BLOCK_SIZE); + + /* is the block sequence nr 0 ? */ + for (i =3D 0; i < AES_BLOCK_SIZE && !buf[i]; i++) { + ; + } + if (i < AES_BLOCK_SIZE) { + /* no, sorry handling of non zero block sequence is not implemente= d */ + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + return 1; + } + + /* fetch key from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, param_addr, key, keysize); + + /* fetch tweak from param block into tweak */ + read_guest_wrap_u8(env, mmu_idx, ra, + param_addr + keysize, tweak, AES_BLOCK_SIZE); + + /* expand key */ + AES_set_encrypt_key(key, keysize * 8, &exkey); + + /* encrypt tweak */ + AES_encrypt(tweak, buf, &exkey); + + /* store encrypted tweak into xts parameter field of the param block */ + write_guest_wrap_u8(env, mmu_idx, ra, + param_addr + keysize + 3 * AES_BLOCK_SIZE, + buf, AES_BLOCK_SIZE); + + return 0; +} diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_hel= per.c index 7dd6ae4ed4..9f4408f1c5 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -170,6 +170,23 @@ static int cpacf_ppno(CPUS390XState *env, const int mm= u_idx, uintptr_t ra, return rc; } =20 +static int cpacf_pcc(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint8_t fc) +{ + int rc =3D 0; + + switch (fc) { + case CPACF_PCC_XTS_AES_128: + case CPACF_PCC_XTS_AES_256: + rc =3D cpacf_aes_pcc(env, mmu_idx, ra, env->regs[1], fc); + break; + default: + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } + + return rc; +} + uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_= t r3, uint32_t type) { @@ -226,6 +243,9 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, u= int32_t r2, uint32_t r3, case S390_FEAT_TYPE_KMCTR: rc =3D cpacf_kmctr(env, mmu_idx, ra, r1, r2, r3, fc, mod); break; + case S390_FEAT_TYPE_PCC: + rc =3D cpacf_pcc(env, mmu_idx, ra, fc); + break; case S390_FEAT_TYPE_PPNO: rc =3D cpacf_ppno(env, mmu_idx, ra, r1, r2, r3, fc); break; --=20 2.43.0 From nobody Mon Sep 28 01:12:31 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1785773705; cv=none; d=zohomail.com; s=zohoarc; b=WiCNo7vEISPIRCyQNL2/Sg78+m43x/WjekJXy8bZKN2I84e3xK4LalkWEJHFKq8Whoa4fUwtmWj9XA1zeF6chEISqIPIO+qPwwiznrokFxaUNpZHj8C9wbcAKGWPDHwVjZk1u61Dc0gfycbWU+6NTf/A2mrsSOQKc/39w3rUHgY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785773705; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=qsodicJO2X68ujhIGG2ufJWH6f2uIpaV0GLUyF++k2E=; b=VINOMhzcMBCRP+UnGx1PtzhyyeMCtXdxon+hR7iWAq7f9vQOBsO2P4a0D7Os9yYlZvl3m1HejRctfVOaQGLsR7wsVu+oz7+DZqpfc/6oqIcrDVgTSZp2t0s026suA9qhF09hSPHXxPFm5U04nNO33YKWvsytHZaq/X+0Wv75pnE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785773705038780.866724863907; Mon, 3 Aug 2026 09:15:05 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wqvHv-0006PT-7r; Mon, 03 Aug 2026 12:13:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHR-00061J-7Z; Mon, 03 Aug 2026 12:12:45 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHP-000351-Aj; Mon, 03 Aug 2026 12:12:44 -0400 Received: from pps.filterd (m0360072.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 673EHrBR2341591; Mon, 3 Aug 2026 16:12:37 GMT Received: from ppma23.wdc07v.mail.ibm.com (5d.69.3da9.ip4.static.sl-reverse.com [169.61.105.93]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs8euhbvc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:37 +0000 (GMT) Received: from pps.filterd (ppma23.wdc07v.mail.ibm.com [127.0.0.1]) by ppma23.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 673FuPeF007006; Mon, 3 Aug 2026 16:12:36 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma23.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4fsvmh6466-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:36 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 673GCWaw27656456 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 16:12:32 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A7A0620040; Mon, 3 Aug 2026 16:12:32 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7CC3420043; Mon, 3 Aug 2026 16:12:32 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 16:12:32 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=qsodicJO2X68ujhIG G2ufJWH6f2uIpaV0GLUyF++k2E=; b=R/lgm9FRTGWBjJgjNcs/fjOLAL/I+asms AEos6HFeeACBb5uDDPRWMsPHXIWAgGFNspwDqD9akvu/cco7tunVzjPbojXwucJo ZG2xvgImQ25X4wPVYK8dYmdVlJgy2mYQFXoSDP1ZqYrFBk67Lo6QjTefGTty7JG1 7JPkXBfHOsrfpdyx1fgVVgfTbb9z/tBmc2LmbE/i2kHNyv37nmxiRY7iA+hZjUDa eh276+ms+yxN1OLopvjl9YVm8vXpyjMCxlpfFVAlGQTHtIGbkAtzsXBhv4MzS8Ay kiH+wT1cB+FKgnrXaqe1p8uMU9kHcqBXA2uF6O91wRr5T8H+76jaQ== From: Harald Freudenberger To: richard.henderson@linaro.org, iii@linux.ibm.com, david@kernel.org, thuth@redhat.com, berrange@redhat.com Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org, linux-s390@vger.kernel.org, dengler@linux.ibm.com, borntraeger@linux.ibm.com, fcallies@linux.ibm.com, cohuck@redhat.com Subject: [PATCH v13 10/18] target/s390x: Support AES XTS for cpacf km instruction Date: Mon, 3 Aug 2026 18:12:27 +0200 Message-ID: <20260803161235.228704-11-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803161235.228704-1-freude@linux.ibm.com> References: <20260803161235.228704-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: lDqhIK9RGwiuA70o3vLgZ-esdakBdTq0 X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfXx8KNAqLlzAiL SxMSF8etqz3Etoo4InW2adxdnTMSP+Df1ll6PjaPpwkt6DY0JQ1omBqoVhmKTF4u+svYVAdetQH pgI9pNjugHdv+KegRmfEWJVMAPpLfaw= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfXzIs/LT6x+ZT/ LC+bySUcu36EnZ5OpbdkThNcMzCz9NtuUNcwOeJnShjBlfG7tkpWLkBsMiAOY4k8ZfuqsdFcDnl Wxew8zjiR4VH8xAB1235N4StKk3V5rhGRkhkvbC0hFbZUZn32beqWTmYGLIoMupGQwHUVYuqWQL nVHFWlJOEXu0fTP9UocZ14UScFb/oftXVaW6FRKAfihWKmzByamefUqp4gKRvNtq41ytFRVjBrd V6wwDh2PEy5QsCA85VpaklVfQ9SHlmpD03skIJgfVUxjLipe9qieHfTAFaliAtkZ46wlEzDXNcM 9F3MdewBTXnr0SbaLcZPQaAosETUnmeR00UX/twhQdQMYzQzUndNAKjI/A/7qd7BYtdfQQfh9ur GcR4kgEf0uQjrkcsQmeVRIBbVdd2NERGPjqKwmbmedu+uYT1rEh9Ttj7UerPxkqCms/ypoYquty prhfeCwuNiJyahs7ygg== X-Proofpoint-GUID: lDqhIK9RGwiuA70o3vLgZ-esdakBdTq0 X-Authority-Analysis: v=2.4 cv=KfzidwYD c=1 sm=1 tr=0 ts=6a70bdf5 cx=c_pps a=3Bg1Hr4SwmMryq2xdFQyZA==:117 a=3Bg1Hr4SwmMryq2xdFQyZA==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=RzCfie-kr_QcCd8fBx8p:22 a=VnNF1IyMAAAA:8 a=NfUx3EYS-SKBlRlFgzgA:9 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-03_03,2026-08-03_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 bulkscore=0 impostorscore=0 suspectscore=0 malwarescore=0 adultscore=0 clxscore=1015 priorityscore=1501 phishscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030141 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=148.163.158.5; envelope-from=freude@linux.ibm.com; helo=mx0b-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1785773706361158500 Content-Type: text/plain; charset="utf-8" Support the subfunctions XTS-AES-128 and XTS-AES-256 for the cpacf km instruction. Signed-off-by: Harald Freudenberger Tested-by: Holger Dengler Reviewed-by: Holger Dengler --- target/s390x/gen-features.c | 2 + target/s390x/tcg/cpacf.h | 4 ++ target/s390x/tcg/cpacf_aes.c | 81 ++++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 6 +++ 4 files changed, 93 insertions(+) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index 4132d7b932..078aeddb36 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -925,6 +925,8 @@ static uint16_t qemu_MAX[] =3D { S390_FEAT_KM_AES_128, S390_FEAT_KM_AES_192, S390_FEAT_KM_AES_256, + S390_FEAT_KM_XTS_AES_128, + S390_FEAT_KM_XTS_AES_256, S390_FEAT_KMC_AES_128, S390_FEAT_KMC_AES_192, S390_FEAT_KMC_AES_256, diff --git a/target/s390x/tcg/cpacf.h b/target/s390x/tcg/cpacf.h index cbb6090b44..61ce71476b 100644 --- a/target/s390x/tcg/cpacf.h +++ b/target/s390x/tcg/cpacf.h @@ -249,5 +249,9 @@ int cpacf_aes_ctr(CPUS390XState *env, const int mmu_idx= , uintptr_t ra, uint8_t fc, uint8_t mod); int cpacf_aes_pcc(CPUS390XState *env, const int mmu_idx, uintptr_t ra, uint64_t param_addr, uint8_t fc); +int cpacf_aes_xts(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *dst_ptr_reg, + uint64_t *src_ptr_reg, uint64_t *src_len_reg, + uint32_t type, uint8_t fc, uint8_t mod); =20 #endif /* S390X_CPACF_H */ diff --git a/target/s390x/tcg/cpacf_aes.c b/target/s390x/tcg/cpacf_aes.c index 1127452f28..0ffb514a84 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -308,3 +308,84 @@ int cpacf_aes_pcc(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, =20 return 0; } + +int cpacf_aes_xts(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *dst_ptr_reg, + uint64_t *src_ptr_reg, uint64_t *src_len_reg, + uint32_t type, uint8_t fc, uint8_t mod) +{ + enum { MAX_BLOCKS_PER_RUN =3D 8192 / AES_BLOCK_SIZE }; + uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; + uint64_t len =3D *src_len_reg, done =3D 0; + uint8_t key[32], tweak[AES_BLOCK_SIZE]; + int i, keysize, addr_reg_size =3D 64; + AES_KEY exkey; + + g_assert(type =3D=3D S390_FEAT_TYPE_KM); + + switch (fc) { + case CPACF_KM_XTS_128: + keysize =3D 16; + break; + case CPACF_KM_XTS_256: + keysize =3D 32; + break; + default: + g_assert_not_reached(); + } + + if (!(env->psw.mask & PSW_MASK_64)) { + len =3D (uint32_t)len; + addr_reg_size =3D (env->psw.mask & PSW_MASK_32) ? 32 : 24; + } + + /* length has to be properly aligned. */ + if (!QEMU_IS_ALIGNED(len, AES_BLOCK_SIZE)) { + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } + + /* fetch key from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, param_addr, key, keysize); + + /* expand key */ + if (mod) { + AES_set_decrypt_key(key, keysize * 8, &exkey); + } else { + AES_set_encrypt_key(key, keysize * 8, &exkey); + } + + /* fetch tweak from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, + param_addr + keysize, tweak, AES_BLOCK_SIZE); + + /* process up to MAX_BLOCKS_PER_RUN aes blocks */ + for (i =3D 0; i < MAX_BLOCKS_PER_RUN && len >=3D AES_BLOCK_SIZE; i++) { + /* fetch one AES block into in */ + aes_read_block(env, mmu_idx, ra, *src_ptr_reg + done, in); + if (mod) { + /* decrypt in =3D> out */ + AES_xts_decrypt(in, out, tweak, &exkey); + } else { + /* encrypt in =3D> out */ + AES_xts_encrypt(in, out, tweak, &exkey); + } + /* prep tweak for next round */ + AES_xts_prep_next_tweak(tweak); + /* write out this processed block from out */ + aes_write_block(env, mmu_idx, ra, *dst_ptr_reg + done, out); + len -=3D AES_BLOCK_SIZE; + done +=3D AES_BLOCK_SIZE; + } + + /* update tweak in param block */ + write_guest_wrap_u8(env, mmu_idx, ra, + param_addr + keysize, tweak, AES_BLOCK_SIZE); + + *src_ptr_reg =3D deposit64(*src_ptr_reg, 0, addr_reg_size, + *src_ptr_reg + done); + *dst_ptr_reg =3D deposit64(*dst_ptr_reg, 0, addr_reg_size, + *dst_ptr_reg + done); + *src_len_reg -=3D done; + + return !len ? 0 : 3; +} diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_hel= per.c index 9f4408f1c5..4fdb0d7c7d 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -104,6 +104,12 @@ static int cpacf_km(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, &env->regs[r1], &env->regs[r2], &env->regs[r2 += 1], S390_FEAT_TYPE_KM, fc, mod); break; + case CPACF_KM_XTS_128: + case CPACF_KM_XTS_256: + rc =3D cpacf_aes_xts(env, mmu_idx, ra, env->regs[1], + &env->regs[r1], &env->regs[r2], &env->regs[r2 += 1], + S390_FEAT_TYPE_KM, fc, mod); + break; default: tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); } --=20 2.43.0 From nobody Mon Sep 28 01:12:31 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1785773655; cv=none; d=zohomail.com; s=zohoarc; b=UmXIZTY8OPaWc3rYEk4gnGmxeGjhsCKOK4uxbsSpfTU7nlBcXRYOkSb2f5QSjp9dVXJaHSoE3GcLhlFzm22HbH9b6UJn+EVLn6o7LBoMEMXoQXTpvYUqAFjBT7mDFUzieCDEnNyiCPRWIMxURqoiHvoLjsE1WiBCgNiITIkkv4o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785773655; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=kbG70sko5MjTOTBwEPiFt6z0BOgUCwkodIZnAKzhJtQ=; b=AV9BWGMG5HbKn64K/QBd1bu1lybgMmZNWnQgQ3i9p9A1dahyALvHERet6K7QoZF0G+R4MCc86H6OPiwFYF4O9xOOWhxjHNVQMj37kJGwQfztIUeChdl46s3YM15j9sTx7nHKJKglTHSmk2ijOML2EoRmFMTlLN+ZwwackIisvMU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785773655002760.8172124388288; Mon, 3 Aug 2026 09:14:15 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wqvI1-0006bh-QI; Mon, 03 Aug 2026 12:13:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHS-000644-Lz; Mon, 03 Aug 2026 12:12:48 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHQ-00035T-7W; Mon, 03 Aug 2026 12:12:46 -0400 Received: from pps.filterd (m0360072.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 673EHnqv2341358; Mon, 3 Aug 2026 16:12:38 GMT Received: from ppma21.wdc07v.mail.ibm.com (5b.69.3da9.ip4.static.sl-reverse.com [169.61.105.91]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs8euhbvd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:37 +0000 (GMT) Received: from pps.filterd (ppma21.wdc07v.mail.ibm.com [127.0.0.1]) by ppma21.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 673GBQ8I012078; Mon, 3 Aug 2026 16:12:37 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4fsv4jx6aj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:36 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 673GCX1e8782096 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 16:12:33 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E2EC120040; Mon, 3 Aug 2026 16:12:32 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id ADE8E2004B; Mon, 3 Aug 2026 16:12:32 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 16:12:32 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=kbG70sko5MjTOTBwE PiFt6z0BOgUCwkodIZnAKzhJtQ=; b=deTzTg9TsklPCWVtMnhDSn8lyXsTONqvw YUhCIHJyP/MR3dcTboomKVQ9dVMqmKuqhwv2Uzchxl1C2e16SWLSJW6mberyc92z vW7JQvm0eFUj1BsMEj32dQXhYUtUaGgUnmW6Wx/n8y+D26TCBiEflRllKP8h+Qrt /JxxbxigOaspMCxoVo4fAteRGD3KdYOH3kpvHqjb6re28xgG2etcB9P40Ae0IVc4 lpx484Ok1BoimDsKhALF+2ut9YpMk9iYouBBIoq2n/ClXfG9AtqffvlR8SELANVa fqp4/mfVbUDaBUD2t1RiM43cALG8ViKcTmUz+9XJ7+qbyimx6MdgA== From: Harald Freudenberger To: richard.henderson@linaro.org, iii@linux.ibm.com, david@kernel.org, thuth@redhat.com, berrange@redhat.com Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org, linux-s390@vger.kernel.org, dengler@linux.ibm.com, borntraeger@linux.ibm.com, fcallies@linux.ibm.com, cohuck@redhat.com Subject: [PATCH v13 11/18] target/s390x: Base support for cpacf protected keys and pckmo Date: Mon, 3 Aug 2026 18:12:28 +0200 Message-ID: <20260803161235.228704-12-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803161235.228704-1-freude@linux.ibm.com> References: <20260803161235.228704-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: tYTCBoQZZF0C0tx7CM8sKnsUoC9kpr-B X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX5DXuFAViCK/A AMVFzuW3PgNhphdROAvB5C4M97wxfiIg5ip8CD8mjE0UKJ3RUtNp3Nr05NkGtINRsFjvdUTW0nZ kKwTLio8V9I92PbfXoUG0GwMD7HUOqg= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX6y37RGsY+Hbs YV74RBCB5x7iEE+4fIh9MCenpdL1et2hY5OctXH8MfMh/oaTf2Xr3PmCH8JmSrThqoNE9BzyV/s 4ntjG9PZYzfL30vWxUOM3eZQI0XyNyFXpaOMF/AE0EddSTJHGOsyCmkV3QzY4a6B0ZkRvKJetfs Vd18Uoo1LO24ISJJ00nitePm5m/+0+wfBqmZxVhs4/1gcuBS+a2J44dty1+bPSu1eXmagaguVLu p79JtT96cAlciKyZVTUwtZNjYgFzfHvBP9aktVTazcAgjCQn8hQpPzX2tVMOI+sYD6Iytb2NqA4 pes3JpNl9Z0Evv+xzkaiZRYx9woccrC3qGKxOrQHborOXHlqiQD6DST/9+6Z421cMpD52I0DnDV T8PV7MCmlAsNOijV5ZuBRmUSlhMud/SmWCNRWR178hOJNH0FcY7Ltow9IGZMkxN093lhbPfoLUI ZyA/lcKH/378xSITJow== X-Proofpoint-GUID: tYTCBoQZZF0C0tx7CM8sKnsUoC9kpr-B X-Authority-Analysis: v=2.4 cv=KfzidwYD c=1 sm=1 tr=0 ts=6a70bdf5 cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=RzCfie-kr_QcCd8fBx8p:22 a=VnNF1IyMAAAA:8 a=c7LoGp8Tn7I-ceKYaY8A:9 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-03_03,2026-08-03_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 bulkscore=0 impostorscore=0 suspectscore=0 malwarescore=0 adultscore=0 clxscore=1015 priorityscore=1501 phishscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030141 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=148.163.158.5; envelope-from=freude@linux.ibm.com; helo=mx0b-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1785773658153158500 Content-Type: text/plain; charset="utf-8" Add base support for cpacf protected key handling. Add support for the pckmo subfunctions PCKMO-Encrypt-AES-128-Key, PCKMO-Encrypt-AES-192-Key and PCKMO-Encrypt-AES-256-Key which deal with protected keys. These pckmo subfunctions derive a protected key from an AES clear key by encrypting it with an internal AES wrapping key. More details about protected keys can be found in the "z/Architecture Prinziples of Operation" document. The qemu version provided here is only a fake intended to make protected key available for developing and testing purpose: * The protected key is 'derived' from the clear key by xoring the fixed pattern 0xAAAA... onto the key value. * The AES Wrapping Key Verification Pattern is a fixed value of 32 bytes 0xFACEFACE... Add preprocessor defines for the xor pattern and wkvp used to construct ('encrypt') a protected key from a clear key value with this implementation. Also add some static functions to 'encrypt' from clear key to protected key and 'decrypt' back to cpacf_aes.c. The preprocessor defines shall be used later in testcases to construct and decode protected keys. Signed-off-by: Harald Freudenberger Tested-by: Holger Dengler --- target/s390x/gen-features.c | 3 ++ target/s390x/tcg/cpacf.h | 29 +++++++++++++++ target/s390x/tcg/cpacf_aes.c | 64 ++++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 21 +++++++++++ target/s390x/tcg/translate.c | 9 ++++- 5 files changed, 124 insertions(+), 2 deletions(-) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index 078aeddb36..c5fd578d92 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -935,6 +935,9 @@ static uint16_t qemu_MAX[] =3D { S390_FEAT_KMCTR_AES_256, S390_FEAT_PCC_XTS_AES_128, S390_FEAT_PCC_XTS_AES_256, + S390_FEAT_PCKMO_AES_128, + S390_FEAT_PCKMO_AES_192, + S390_FEAT_PCKMO_AES_256, }; =20 /****** END FEATURE DEFS ******/ diff --git a/target/s390x/tcg/cpacf.h b/target/s390x/tcg/cpacf.h index 61ce71476b..1d7d9baf0c 100644 --- a/target/s390x/tcg/cpacf.h +++ b/target/s390x/tcg/cpacf.h @@ -254,4 +254,33 @@ int cpacf_aes_xts(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, uint64_t *src_ptr_reg, uint64_t *src_len_reg, uint32_t type, uint8_t fc, uint8_t mod); =20 +/* + * Support for protected key cpacf functions. Note that this is + * a fake implementation intended for debugging and development. + * Do not use for production load ! + */ + +/* + * Hard coded pattern xored with the AES clear key + * to 'produce' the protected key. + */ +#define PROTKEY_XOR_PATTERN { \ + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, \ + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, \ + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, \ + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA } + +/* + * Hard coded wkvp ("Wrapping Key Verification Pattern") + */ +#define PROTKEY_WKVP { \ + 0x0F, 0x0A, 0x0C, 0x0E, 0x0F, 0x0A, 0x0C, 0x0E, \ + 0x0F, 0x0A, 0x0C, 0x0E, 0x0F, 0x0A, 0x0C, 0x0E, \ + 0x0F, 0x0A, 0x0C, 0x0E, 0x0F, 0x0A, 0x0C, 0x0E, \ + 0x0F, 0x0A, 0x0C, 0x0E, 0x0F, 0x0A, 0x0C, 0x0E } + +/* from cpacf_aes.c */ +int cpacf_aes_pckmo(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint8_t fc); + #endif /* S390X_CPACF_H */ diff --git a/target/s390x/tcg/cpacf_aes.c b/target/s390x/tcg/cpacf_aes.c index 0ffb514a84..4f0b243f53 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -389,3 +389,67 @@ int cpacf_aes_xts(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, =20 return !len ? 0 : 3; } + +/* + * Support for protected key cpacf functions. Note that this is + * a fake implementation intended for debugging and development. + * Do not use for production load ! + */ + +/* + * Hard coded pattern xored with the AES clear key + * to 'produce' the protected key. + */ +static const uint8_t protkey_xor_pattern[32] =3D PROTKEY_XOR_PATTERN; + +/* + * Hard coded wkvp ("Wrapping Key Verification Pattern") + */ +static const uint8_t protkey_wkvp[32] =3D PROTKEY_WKVP; + +/* + * 'encrypt' the clear key value into a protected key + * by xor-ing the protkey_xor_pattern onto it. + */ +static void encrypt_clrkey(uint8_t *key, int keysize) +{ + for (int i =3D 0; i < keysize; i++) { + key[i] ^=3D protkey_xor_pattern[i]; + } +} + +int cpacf_aes_pckmo(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint8_t fc) +{ + uint8_t key[32]; + int keysize; + + switch (fc) { + case CPACF_PCKMO_ENC_AES_128_KEY: + keysize =3D 16; + break; + case CPACF_PCKMO_ENC_AES_192_KEY: + keysize =3D 24; + break; + case CPACF_PCKMO_ENC_AES_256_KEY: + keysize =3D 32; + break; + default: + g_assert_not_reached(); + } + + /* fetch key from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, param_addr, key, keysize); + + /* 'derive' the protected key from the clear key */ + encrypt_clrkey(key, keysize); + + /* store the protected key into param block */ + write_guest_wrap_u8(env, mmu_idx, ra, param_addr, key, keysize); + /* followed by the fake wkvp */ + write_guest_wrap_u8(env, mmu_idx, ra, + param_addr + keysize, + protkey_wkvp, sizeof(protkey_wkvp)); + + return 0; +} diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_hel= per.c index 4fdb0d7c7d..f1ebac1e41 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -193,6 +193,24 @@ static int cpacf_pcc(CPUS390XState *env, const int mmu= _idx, uintptr_t ra, return rc; } =20 +static int cpacf_pckmo(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint8_t fc) +{ + int rc =3D 0; + + switch (fc) { + case CPACF_PCKMO_ENC_AES_128_KEY: + case CPACF_PCKMO_ENC_AES_192_KEY: + case CPACF_PCKMO_ENC_AES_256_KEY: + rc =3D cpacf_aes_pckmo(env, mmu_idx, ra, env->regs[1], fc); + break; + default: + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } + + return rc; +} + uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_= t r3, uint32_t type) { @@ -252,6 +270,9 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, u= int32_t r2, uint32_t r3, case S390_FEAT_TYPE_PCC: rc =3D cpacf_pcc(env, mmu_idx, ra, fc); break; + case S390_FEAT_TYPE_PCKMO: + rc =3D cpacf_pckmo(env, mmu_idx, ra, fc); + break; case S390_FEAT_TYPE_PPNO: rc =3D cpacf_ppno(env, mmu_idx, ra, r1, r2, r3, fc); break; diff --git a/target/s390x/tcg/translate.c b/target/s390x/tcg/translate.c index cef1b55149..d7a99e6c1e 100644 --- a/target/s390x/tcg/translate.c +++ b/target/s390x/tcg/translate.c @@ -2558,6 +2558,7 @@ static DisasJumpType op_msa(DisasContext *s, DisasOps= *o) int r2 =3D have_field(s, r2) ? get_field(s, r2) : 0; int r3 =3D have_field(s, r3) ? get_field(s, r3) : 0; TCGv_i32 t_r1, t_r2, t_r3, type; + bool update_cc =3D true; =20 switch (s->insn->data) { case S390_FEAT_TYPE_KMA: @@ -2589,8 +2590,10 @@ static DisasJumpType op_msa(DisasContext *s, DisasOp= s *o) gen_program_exception(s, PGM_SPECIFICATION); return DISAS_NORETURN; } - /* FALL THROUGH */ + break; case S390_FEAT_TYPE_PCKMO: + update_cc =3D false; + /* FALL THROUGH */ case S390_FEAT_TYPE_PCC: case S390_FEAT_TYPE_KDSA: break; @@ -2603,7 +2606,9 @@ static DisasJumpType op_msa(DisasContext *s, DisasOps= *o) t_r3 =3D tcg_constant_i32(r3); type =3D tcg_constant_i32(s->insn->data); gen_helper_msa(cc_op, tcg_env, t_r1, t_r2, t_r3, type); - set_cc_static(s); + if (update_cc) { + set_cc_static(s); + } return DISAS_NEXT; } =20 --=20 2.43.0 From nobody Mon Sep 28 01:12:31 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1785773701; cv=none; d=zohomail.com; s=zohoarc; b=Ij3oNLd+Y6j+Jf4MeFw36KxJluVLWohic17A32QImDfkyQUd8xnw1ctHMhwYxvYbKew+U9UcurXEg4iUcrURCYaLdZQRTtbE1cCf0ZviXYdi7/HPbJhppmAJFUwLaDn8MWbCXjIGJTi/ppQtZwVYagKs7M0KLtdPAtiWEdLKDCg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785773701; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=85Xl4iIBNE+HMCyN8DitBfsap7WNumLnHcHA3z0V3bE=; b=jdiXZ2+z+B8xL31yQhFyr0XcF0OkpTMdP0vb0WpD9CTus/1TcceXY7LzmLjABiVibLgo9wjV/bDEvvUv1RlMdzRKLh/8ecCA98gDoIrevkkbzGaJBlYP2GZZ1yqtupIK2C/yt8hKsOvRFG9tO4ZoIaivaVgTbbxptfaQDj0G6Bw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 178577370141793.9956534300843; Mon, 3 Aug 2026 09:15:01 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wqvI7-0006dI-S1; Mon, 03 Aug 2026 12:13:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHV-00065i-B2; Mon, 03 Aug 2026 12:12:50 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHR-000366-Ea; Mon, 03 Aug 2026 12:12:49 -0400 Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 673EHVJ62282331; Mon, 3 Aug 2026 16:12:38 GMT Received: from ppma13.dal12v.mail.ibm.com (dd.9e.1632.ip4.static.sl-reverse.com [50.22.158.221]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs8h4sqv6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:37 +0000 (GMT) Received: from pps.filterd (ppma13.dal12v.mail.ibm.com [127.0.0.1]) by ppma13.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 673GBEWb008934; Mon, 3 Aug 2026 16:12:36 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4fswbg5yap-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:36 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 673GCXq88782098 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 16:12:33 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1DA082004B; Mon, 3 Aug 2026 16:12:33 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E811F20043; Mon, 3 Aug 2026 16:12:32 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 16:12:32 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=85Xl4iIBNE+HMCyN8 DitBfsap7WNumLnHcHA3z0V3bE=; b=D/Y6ioxvtkJCe0c5uP2QELt8+V5gOmEtg MXIsHDQDR4iIB7Ml3aCyLI2Uk+Ya9l+l8UB1lGHk3lJgKxsvH11xXZEOqidtUxoG ND6cr+hz0ZUdlwEah1/EFP5t2H26pqN4YzgrtV6zQAWKe1WwBBPslTNYKxjqakjy v/CfDm44mhKarAHvzSOtWF3sdLn080MqnHLIcQ2WQ6W7lOEhVP01hVlLIXTtXAbg WtVArBJ/49xfG6SsOj2cbnQI8qBB1WqJkGx8NnKc0L8SlaJ30MIoQ+RbvuAhxyd8 dc2kcdNLqzQKgy5j9g3zj+5KGs2YLK7YPajBjKVh6x373A/JkW+Xg== From: Harald Freudenberger To: richard.henderson@linaro.org, iii@linux.ibm.com, david@kernel.org, thuth@redhat.com, berrange@redhat.com Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org, linux-s390@vger.kernel.org, dengler@linux.ibm.com, borntraeger@linux.ibm.com, fcallies@linux.ibm.com, cohuck@redhat.com Subject: [PATCH v13 12/18] target/s390x: Support protected key AES ECB for cpacf km instruction Date: Mon, 3 Aug 2026 18:12:29 +0200 Message-ID: <20260803161235.228704-13-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803161235.228704-1-freude@linux.ibm.com> References: <20260803161235.228704-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX6j26amdOsZQo UpBhRSGjqwtY5lClQBgzNfa9ZsZI4lEBZyXvf5fGFLhO4LBvZY2hqAx4MkvrjjNeYWXbO98rB6N GQp2649MD7sG5vndn4yLV10JfMuS/e0= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX63p+gevBAOF4 PX9dGlLGVYlEISJYxiqXixm8Nw1ZwjgpFYwBKIXqRIZAzlyZbbD3QK/5RZy08CYM5+ZXKWSgwny Ii2qnPNpHYbUgwaws6jju4xEewDPKnuM6jOsJAE0LUDg1Wa+uOoKKaYU6sah/RnLl2N2hF1M+QN TNTdMkwh41OoBNTExwNTAC/hVDcg43WIwq5gRgKqgFKFhMGvdX+lsKckcX+Zwue2gJlh99UQE/0 u8ynREl/CjprteQfK4p+Bx4xXt2uIgxqSwZi6Pp+y2VGjEQ+byCCdpYQLDH728K+v1lz5leANHR QokUQEXNMjcMHlbQgSOuOeAkB1g/SgopcU4XrJl/S0mdQSheirtSE4MT2ikX/G2h9WTu7laGJtp bac5/0zKGxgsDhyJnIu0fQ18w3GAo14HyEG63CGlg5fKL4fJB8Azant7SGS1Jx9S5dmdlIEonMV S3ZPfhxoAGKWF90AXfw== X-Authority-Analysis: v=2.4 cv=SI1ykuvH c=1 sm=1 tr=0 ts=6a70bdf5 cx=c_pps a=AfN7/Ok6k8XGzOShvHwTGQ==:117 a=AfN7/Ok6k8XGzOShvHwTGQ==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=WpPIafo2g3WOFiBud6QA:9 X-Proofpoint-ORIG-GUID: KP9HGM5uA4CPASeZCPle3FUQFwCKxHyb X-Proofpoint-GUID: KP9HGM5uA4CPASeZCPle3FUQFwCKxHyb X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-03_03,2026-08-03_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 bulkscore=0 suspectscore=0 impostorscore=0 spamscore=0 phishscore=0 priorityscore=1501 lowpriorityscore=0 adultscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030141 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=148.163.156.1; envelope-from=freude@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1785773702483158500 Content-Type: text/plain; charset="utf-8" Support the subfunctions CPACF_KM_PAES_128, CPACF_KM_PAES_192 and CPACF_KM_PAES_256 for the cpacf km instruction. Tested-by: Holger Dengler Reviewed-by: Finn Callies Signed-off-by: Harald Freudenberger --- target/s390x/gen-features.c | 3 ++ target/s390x/tcg/cpacf.h | 4 ++ target/s390x/tcg/cpacf_aes.c | 91 ++++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 7 +++ 4 files changed, 105 insertions(+) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index c5fd578d92..17de37f183 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -925,6 +925,9 @@ static uint16_t qemu_MAX[] =3D { S390_FEAT_KM_AES_128, S390_FEAT_KM_AES_192, S390_FEAT_KM_AES_256, + S390_FEAT_KM_EAES_128, + S390_FEAT_KM_EAES_192, + S390_FEAT_KM_EAES_256, S390_FEAT_KM_XTS_AES_128, S390_FEAT_KM_XTS_AES_256, S390_FEAT_KMC_AES_128, diff --git a/target/s390x/tcg/cpacf.h b/target/s390x/tcg/cpacf.h index 1d7d9baf0c..9820ec293b 100644 --- a/target/s390x/tcg/cpacf.h +++ b/target/s390x/tcg/cpacf.h @@ -282,5 +282,9 @@ int cpacf_aes_xts(CPUS390XState *env, const int mmu_idx= , uintptr_t ra, /* from cpacf_aes.c */ int cpacf_aes_pckmo(CPUS390XState *env, const int mmu_idx, uintptr_t ra, uint64_t param_addr, uint8_t fc); +int cpacf_paes_ecb(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *dst_ptr_reg, + uint64_t *src_ptr_reg, uint64_t *src_len_reg, + uint32_t type, uint8_t fc, uint8_t mod); =20 #endif /* S390X_CPACF_H */ diff --git a/target/s390x/tcg/cpacf_aes.c b/target/s390x/tcg/cpacf_aes.c index 4f0b243f53..a6d3efb383 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -418,6 +418,17 @@ static void encrypt_clrkey(uint8_t *key, int keysize) } } =20 +/* + * 'decrypt' the protected key by reverting the xor + * of the protkey_xor_pattern onto the clear key value. + */ +static void decrypt_protkey(uint8_t *key, int keysize) +{ + for (int i =3D 0; i < keysize; i++) { + key[i] ^=3D protkey_xor_pattern[i]; + } +} + int cpacf_aes_pckmo(CPUS390XState *env, const int mmu_idx, uintptr_t ra, uint64_t param_addr, uint8_t fc) { @@ -453,3 +464,83 @@ int cpacf_aes_pckmo(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, =20 return 0; } + +int cpacf_paes_ecb(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *dst_ptr_reg, + uint64_t *src_ptr_reg, uint64_t *src_len_reg, + uint32_t type, uint8_t fc, uint8_t mod) +{ + enum { MAX_BLOCKS_PER_RUN =3D 8192 / AES_BLOCK_SIZE }; + uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; + uint64_t len =3D *src_len_reg, done =3D 0; + int i, keysize, addr_reg_size =3D 64; + uint8_t key[32], wkvp[32]; + AES_KEY exkey; + + g_assert(type =3D=3D S390_FEAT_TYPE_KM); + + switch (fc) { + case CPACF_KM_PAES_128: + keysize =3D 16; + break; + case CPACF_KM_PAES_192: + keysize =3D 24; + break; + case CPACF_KM_PAES_256: + keysize =3D 32; + break; + default: + g_assert_not_reached(); + } + + if (!(env->psw.mask & PSW_MASK_64)) { + len =3D (uint32_t)len; + addr_reg_size =3D (env->psw.mask & PSW_MASK_32) ? 32 : 24; + } + + /* length has to be properly aligned. */ + if (!QEMU_IS_ALIGNED(len, AES_BLOCK_SIZE)) { + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } + + /* fetch and check wkvp from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, + param_addr + keysize, wkvp, sizeof(wkvp)); + if (memcmp(wkvp, protkey_wkvp, sizeof(wkvp))) { + /* wkvp mismatch -> return with cc 1 */ + return 1; + } + + /* fetch protected key from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, param_addr, key, keysize); + /* decrypt the protected key */ + decrypt_protkey(key, keysize); + + /* expand key */ + if (mod) { + AES_set_decrypt_key(key, keysize * 8, &exkey); + } else { + AES_set_encrypt_key(key, keysize * 8, &exkey); + } + + /* process up to MAX_BLOCKS_PER_RUN aes blocks */ + for (i =3D 0; i < MAX_BLOCKS_PER_RUN && len >=3D AES_BLOCK_SIZE; i++) { + aes_read_block(env, mmu_idx, ra, *src_ptr_reg + done, in); + if (mod) { + AES_decrypt(in, out, &exkey); + } else { + AES_encrypt(in, out, &exkey); + } + aes_write_block(env, mmu_idx, ra, *dst_ptr_reg + done, out); + len -=3D AES_BLOCK_SIZE; + done +=3D AES_BLOCK_SIZE; + } + + *src_ptr_reg =3D deposit64(*src_ptr_reg, 0, addr_reg_size, + *src_ptr_reg + done); + *dst_ptr_reg =3D deposit64(*dst_ptr_reg, 0, addr_reg_size, + *dst_ptr_reg + done); + *src_len_reg -=3D done; + + return !len ? 0 : 3; +} diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_hel= per.c index f1ebac1e41..b4e9407d60 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -104,6 +104,13 @@ static int cpacf_km(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, &env->regs[r1], &env->regs[r2], &env->regs[r2 += 1], S390_FEAT_TYPE_KM, fc, mod); break; + case CPACF_KM_PAES_128: + case CPACF_KM_PAES_192: + case CPACF_KM_PAES_256: + rc =3D cpacf_paes_ecb(env, mmu_idx, ra, env->regs[1], + &env->regs[r1], &env->regs[r2], &env->regs[r2 = + 1], + S390_FEAT_TYPE_KM, fc, mod); + break; case CPACF_KM_XTS_128: case CPACF_KM_XTS_256: rc =3D cpacf_aes_xts(env, mmu_idx, ra, env->regs[1], --=20 2.43.0 From nobody Mon Sep 28 01:12:31 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1785773643; cv=none; d=zohomail.com; s=zohoarc; b=GW+4SHSE3opg91bWORyqM/Z2v2XRVYjffKKSCMB5mnOC2tIpYc3Y4zc7H67DVi3VDZCHDBe6ELaUNfyEAwhgCftfto1WTfPNQgXbXUMNY1i9AkfCut+8zWBnLwO/zNDHvIwI2rD0iVKiHUwe1MBL5gWVFmgDmuZXp33dKf4fonM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785773643; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=BG+Tv8UfDnUQ7yFcwdJGpeL0oUU6GyvvrnQJ8tPooIk=; b=kU8Adw/3lqsyZw86+auJnp/zupdQxev2X1v4eJ0z/BDbV7uhWVtbiJnMH6wcJ/xg5mwBRMWNVedIcGQZb/OY7BOIPCypGlAUaP0ViWk3y/dJVyl9FM3iLGd8P0SQUqpQQBQZz+dyoafIG4Zo7ro40q5Uj+5s8j348NbmyTJdwoo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785773643486402.1824361379952; Mon, 3 Aug 2026 09:14:03 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wqvHx-0006Z0-M9; Mon, 03 Aug 2026 12:13:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHU-00064T-4a; Mon, 03 Aug 2026 12:12:48 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHR-00035u-0H; Mon, 03 Aug 2026 12:12:47 -0400 Received: from pps.filterd (m0360072.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 673EI0G02341761; Mon, 3 Aug 2026 16:12:38 GMT Received: from ppma21.wdc07v.mail.ibm.com (5b.69.3da9.ip4.static.sl-reverse.com [169.61.105.91]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs8euhbve-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:38 +0000 (GMT) Received: from pps.filterd (ppma21.wdc07v.mail.ibm.com [127.0.0.1]) by ppma21.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 673GBGG5011978; Mon, 3 Aug 2026 16:12:37 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4fsv4jx6ak-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:37 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 673GCXTK8782100 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 16:12:33 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4D3E920040; Mon, 3 Aug 2026 16:12:33 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2393F2004D; Mon, 3 Aug 2026 16:12:33 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 16:12:33 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=BG+Tv8UfDnUQ7yFcw dJGpeL0oUU6GyvvrnQJ8tPooIk=; b=HHEBYX7TTyLD2oVmxbysvv8iCYlGNk4SL qK/lru8om5AJ6Z7DEiNqvU1dE2Stqnx6xL7WVSsOCgDQhnD+Qj4zxfqjOg27FEH9 5E4AAk+X5C9AfySNB7VHegoqp1OI+NU6qXsTbmUydtnKUDxP72gLfE/H6vTrYjLb FjMfqts/1gaPJmn246a4oCL7uwwa53zy98a3cwEE85RHmQsT3G53sGojCu+W5cEa 09c0DOE8XNdRurmmozgHaIHTxVxab7JcRpogg0a0tLBtIb9NjuU0jp7ne8xU0rYH 1D6Jsfjxxgk9F3LTB8pDhRUOQNziUiLV7z5G3gAbFSGG5lv6BMVBg== From: Harald Freudenberger To: richard.henderson@linaro.org, iii@linux.ibm.com, david@kernel.org, thuth@redhat.com, berrange@redhat.com Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org, linux-s390@vger.kernel.org, dengler@linux.ibm.com, borntraeger@linux.ibm.com, fcallies@linux.ibm.com, cohuck@redhat.com Subject: [PATCH v13 13/18] target/s390x: Support protected key AES CBC for cpacf kmc instruction Date: Mon, 3 Aug 2026 18:12:30 +0200 Message-ID: <20260803161235.228704-14-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803161235.228704-1-freude@linux.ibm.com> References: <20260803161235.228704-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: nBsKc0b6pJmFIoN65ERHcbb7B4YDhWPa X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX0TwA+Mu6+O2o kRyZbBrI7LbvbUi5mKvejU+o8xSZ7z698G4y5l6yTpRfS8faAzzGoLn11H8U2IUiGZk2Nk1LRXB KcZ2WDQr73E47BYz5edJwPveCA6TMbo= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX07uSFfiW6uwY 15VC82j/sLs2pyE9vu1bNp0UGJUVem9qWaIcUB/XhLL2fdAatTk6mn667hHssUkqc6PR1OHjLIi djO7ngGNcavqj3qvq+Nyk19CVHk9yzRf+O3OyY6nj15Ly/fi9rFxOQudsqyAM0mUODY8y9n7w+y aN65qwuYRN1pYhUBgeZlYhPc1UOO6Wlf7JxF8dm/map5LV4L4KfmGta2fh1p3YFwVYNb4k9qX9z YcGx4RvJFdsnf8rpgh82/cgViR3n+1BD5RakpGs1uTpWA4WzUuXqsgljt4QH7KFYP2I1bp9xfot DTyPgAFT5EoAjBmZpqDJTlTas4FXcrWIofhQQberE2QJuh41I7TwlCnUzRcLcdps4B8Y96dZ4+V rj7oqYsqieGx7dyMUORWnZSvD7ol3o+JAUq8uwgn9PqXwSfG+peuSux+Jch5hhZOSR9+SPLO1uW L2Phbyz5SBxPYmjA/Tg== X-Proofpoint-GUID: nBsKc0b6pJmFIoN65ERHcbb7B4YDhWPa X-Authority-Analysis: v=2.4 cv=KfzidwYD c=1 sm=1 tr=0 ts=6a70bdf6 cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=RzCfie-kr_QcCd8fBx8p:22 a=VnNF1IyMAAAA:8 a=8AYr_lYigW3ys9mEaM0A:9 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-03_03,2026-08-03_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 bulkscore=0 impostorscore=0 suspectscore=0 malwarescore=0 adultscore=0 clxscore=1015 priorityscore=1501 phishscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030141 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=148.163.158.5; envelope-from=freude@linux.ibm.com; helo=mx0b-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1785773643988158500 Content-Type: text/plain; charset="utf-8" Support the subfunctions CPACF_KMC_PAES_128, CPACF_KMC_PAES_192 and CPACF_KMC_PAES_256 for the cpacf kmc instruction. Tested-by: Holger Dengler Reviewed-by: Finn Callies Signed-off-by: Harald Freudenberger --- target/s390x/gen-features.c | 3 ++ target/s390x/tcg/cpacf.h | 4 ++ target/s390x/tcg/cpacf_aes.c | 90 ++++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 7 +++ 4 files changed, 104 insertions(+) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index 17de37f183..d1fce9e00c 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -933,6 +933,9 @@ static uint16_t qemu_MAX[] =3D { S390_FEAT_KMC_AES_128, S390_FEAT_KMC_AES_192, S390_FEAT_KMC_AES_256, + S390_FEAT_KMC_EAES_128, + S390_FEAT_KMC_EAES_192, + S390_FEAT_KMC_EAES_256, S390_FEAT_KMCTR_AES_128, S390_FEAT_KMCTR_AES_192, S390_FEAT_KMCTR_AES_256, diff --git a/target/s390x/tcg/cpacf.h b/target/s390x/tcg/cpacf.h index 9820ec293b..8987f8fbc7 100644 --- a/target/s390x/tcg/cpacf.h +++ b/target/s390x/tcg/cpacf.h @@ -286,5 +286,9 @@ int cpacf_paes_ecb(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, uint64_t param_addr, uint64_t *dst_ptr_reg, uint64_t *src_ptr_reg, uint64_t *src_len_reg, uint32_t type, uint8_t fc, uint8_t mod); +int cpacf_paes_cbc(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *dst_ptr_reg, + uint64_t *src_ptr_reg, uint64_t *src_len_reg, + uint32_t type, uint8_t fc, uint8_t mod); =20 #endif /* S390X_CPACF_H */ diff --git a/target/s390x/tcg/cpacf_aes.c b/target/s390x/tcg/cpacf_aes.c index a6d3efb383..7373609ced 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -544,3 +544,93 @@ int cpacf_paes_ecb(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, =20 return !len ? 0 : 3; } + +int cpacf_paes_cbc(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *dst_ptr_reg, + uint64_t *src_ptr_reg, uint64_t *src_len_reg, + uint32_t type, uint8_t fc, uint8_t mod) +{ + enum { MAX_BLOCKS_PER_RUN =3D 8192 / AES_BLOCK_SIZE }; + uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; + uint8_t key[32], wkvp[32], iv[AES_BLOCK_SIZE]; + uint64_t len =3D *src_len_reg, done =3D 0; + int i, keysize, addr_reg_size =3D 64; + AES_KEY exkey; + + g_assert(type =3D=3D S390_FEAT_TYPE_KMC); + + switch (fc) { + case CPACF_KMC_PAES_128: + keysize =3D 16; + break; + case CPACF_KMC_PAES_192: + keysize =3D 24; + break; + case CPACF_KMC_PAES_256: + keysize =3D 32; + break; + default: + g_assert_not_reached(); + } + + if (!(env->psw.mask & PSW_MASK_64)) { + len =3D (uint32_t)len; + addr_reg_size =3D (env->psw.mask & PSW_MASK_32) ? 32 : 24; + } + + /* length has to be properly aligned. */ + if (!QEMU_IS_ALIGNED(len, AES_BLOCK_SIZE)) { + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } + + /* fetch and check wkvp from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, + param_addr + AES_BLOCK_SIZE + keysize, + wkvp, sizeof(wkvp)); + if (memcmp(wkvp, protkey_wkvp, sizeof(wkvp))) { + /* wkvp mismatch -> return with cc 1 */ + return 1; + } + + /* fetch iv from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, param_addr, iv, AES_BLOCK_SIZE); + + /* fetch protected key from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, + param_addr + AES_BLOCK_SIZE, key, keysize); + /* decrypt the protected key */ + decrypt_protkey(key, keysize); + + /* expand key */ + if (mod) { + AES_set_decrypt_key(key, keysize * 8, &exkey); + } else { + AES_set_encrypt_key(key, keysize * 8, &exkey); + } + + /* process up to MAX_BLOCKS_PER_RUN aes blocks */ + for (i =3D 0; i < MAX_BLOCKS_PER_RUN && len >=3D AES_BLOCK_SIZE; i++) { + aes_read_block(env, mmu_idx, ra, *src_ptr_reg + done, in); + if (mod) { + /* decrypt in =3D> out */ + AES_cbc_decrypt(in, out, iv, &exkey); + } else { + /* encrypt in =3D> out */ + AES_cbc_encrypt(in, out, iv, &exkey); + } + aes_write_block(env, mmu_idx, ra, *dst_ptr_reg + done, out); + len -=3D AES_BLOCK_SIZE; + done +=3D AES_BLOCK_SIZE; + } + + /* update iv in param block */ + write_guest_wrap_u8(env, mmu_idx, ra, param_addr, iv, AES_BLOCK_SIZE); + + *src_ptr_reg =3D deposit64(*src_ptr_reg, 0, addr_reg_size, + *src_ptr_reg + done); + *dst_ptr_reg =3D deposit64(*dst_ptr_reg, 0, addr_reg_size, + *dst_ptr_reg + done); + *src_len_reg -=3D done; + + return !len ? 0 : 3; +} diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_hel= per.c index b4e9407d60..3c6dd74c70 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -138,6 +138,13 @@ static int cpacf_kmc(CPUS390XState *env, const int mmu= _idx, uintptr_t ra, &env->regs[r1], &env->regs[r2], &env->regs[r2 += 1], S390_FEAT_TYPE_KMC, fc, mod); break; + case CPACF_KMC_PAES_128: + case CPACF_KMC_PAES_192: + case CPACF_KMC_PAES_256: + rc =3D cpacf_paes_cbc(env, mmu_idx, ra, env->regs[1], + &env->regs[r1], &env->regs[r2], &env->regs[r2 = + 1], + S390_FEAT_TYPE_KMC, fc, mod); + break; default: tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); } --=20 2.43.0 From nobody Mon Sep 28 01:12:31 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1785773644; cv=none; d=zohomail.com; s=zohoarc; b=VMiL8Ze1DllmfQ+OhE7aCyPh/J9wOF127s8v2ILV5aiQ/WJto6Vt29QAqxhLnVSdaXHY/hkV2lEpnP+kSgqpfQlgDAaFkLIpReIBzymfXoqwEzgFLratkvS9aQwXQEPrJLLyPBTIS94/uThggEFe9eVFqE2zoUtN/JuJTjkh4Kk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785773644; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=1vHOxJRCXuWEVR1Um3LvcPKeIfNHrtFsFS1tX08le5w=; b=ihH8GtYj+tm6O3v4XcFmebcVdkcAJxgr3CKmYg6fUhf2p+EQdgsd48DqQr0cIrrKir2kjwslHuRXM74WgEYQJT+BY+LPIzf6g1Y6b5BeaSaHc1oDIfXCiNU0kJVY1F32tdlE4TbcJHUzSMoiNmWKx4PXRrgIS6+de245MUQwCOk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785773644880473.53357721735676; Mon, 3 Aug 2026 09:14:04 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wqvI8-0006eY-00; Mon, 03 Aug 2026 12:13:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHT-00064I-U0; Mon, 03 Aug 2026 12:12:48 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHQ-00035b-KR; Mon, 03 Aug 2026 12:12:47 -0400 Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 673EHXEu2282544; Mon, 3 Aug 2026 16:12:38 GMT Received: from ppma13.dal12v.mail.ibm.com (dd.9e.1632.ip4.static.sl-reverse.com [50.22.158.221]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs8h4sqv7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:38 +0000 (GMT) Received: from pps.filterd (ppma13.dal12v.mail.ibm.com [127.0.0.1]) by ppma13.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 673GBIHd008965; Mon, 3 Aug 2026 16:12:37 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4fswbg5yar-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:37 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 673GCXqg31785576 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 16:12:33 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7EDB32004D; Mon, 3 Aug 2026 16:12:33 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 532DD20043; Mon, 3 Aug 2026 16:12:33 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 16:12:33 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=1vHOxJRCXuWEVR1Um 3LvcPKeIfNHrtFsFS1tX08le5w=; b=kMY+804tm8xbtV5qzieX+N0dwF5lBXqzH vAkS63Uxgee726jJf+sQBUedVUYC+TbMEksqsHu+6fgSe0oo4XkzfUcCTRfHfvgf qN4R2Z9kBjGb4PMzm7YgmpgC9gozjLZhuRq7i9UYpu2OFXsZFcuWpzaiaVNJ6uB+ Yv0bYhUshBxav/75mQKaAdX01qAU1BhvPPa5oYwJUVnTT3IKpSo2+W9M3y/y7CuA 8HC0bq3gm2NP7PDnvSmIK2T0TnAuPjQU3dhN+gVEEtMkIHXZT4W06LOEs8shIsYL ypPjXMt2MBA4tsTW9XU1Elw70l2GTSZu/d73inyP9HMSu65TnrnSg== From: Harald Freudenberger To: richard.henderson@linaro.org, iii@linux.ibm.com, david@kernel.org, thuth@redhat.com, berrange@redhat.com Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org, linux-s390@vger.kernel.org, dengler@linux.ibm.com, borntraeger@linux.ibm.com, fcallies@linux.ibm.com, cohuck@redhat.com Subject: [PATCH v13 14/18] target/s390x: Support protected key AES CTR for cpacf kmctr instruction Date: Mon, 3 Aug 2026 18:12:31 +0200 Message-ID: <20260803161235.228704-15-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803161235.228704-1-freude@linux.ibm.com> References: <20260803161235.228704-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX+fiRNqB9zVeK w2fno3Zezjj66wXpVlRDbPQxj9mYG2bl6USbk0x5Sam2tJaWaChJRaTGad9yjsmDr184NT6S/W/ fao2V2Dj6mlnisXzGHmQJHfD0dBI8Eo= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX88w9t06WjK03 w8268jlct5yX5/MRk8KuQLsK5h7djzhWAeHbaZ6H32JtebYndozPygAPdayeEQsKNl23c6BWFxZ 07ac1e1cIqmqIGz9de13dvzbvOeP40ztWFLQDozWlPMhSYDy/+0vvQPu0kzwROmCxXNDcrJeXdp 5n6FKKYLBZYTNZxFMl2ipSkFfjtJ8Tycar0qxEJgxYBS8mr6jum4YPyRQskUnD2T85X9QZ9mUTL VdtIEGUHelMRqeD/SuKPNRfLhh2fY9NVuupXjOuS52t+QDJyPpNVS2n3Wjot4BP96FMxKuOntZc IbAGnxqPMgc0F4vgZz60j58PQWaKZJmu8sVaw8qifpc5OY9VsJo9u5wJ8A3hgBpMi/Y+NlTQy8m TN9d6aADNh1z6p+5E1iliP/1JZyVkTqTB//K5Z0KqeBMctSKCjK4A9eYlMn2UJ/t5W8t06vL50f EiLuqWBoFB9BEnNB80w== X-Authority-Analysis: v=2.4 cv=SI1ykuvH c=1 sm=1 tr=0 ts=6a70bdf6 cx=c_pps a=AfN7/Ok6k8XGzOShvHwTGQ==:117 a=AfN7/Ok6k8XGzOShvHwTGQ==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=Ff2AzlR8v_7kNCG2J78A:9 X-Proofpoint-ORIG-GUID: zR2RMMCzpun-WT0Y8-Of_lYZ_tfFnnMc X-Proofpoint-GUID: zR2RMMCzpun-WT0Y8-Of_lYZ_tfFnnMc X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-03_03,2026-08-03_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 bulkscore=0 suspectscore=0 impostorscore=0 spamscore=0 phishscore=0 priorityscore=1501 lowpriorityscore=0 adultscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030141 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=148.163.156.1; envelope-from=freude@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1785773646025158500 Content-Type: text/plain; charset="utf-8" Support the subfunctions CPACF_KMCTR_PAES_128, CPACF_KMCTR_PAES_192 and CPACF_KMCTR_PAES_256 for the cpacf kmctr instruction. Signed-off-by: Harald Freudenberger --- target/s390x/gen-features.c | 3 ++ target/s390x/tcg/cpacf.h | 5 ++ target/s390x/tcg/cpacf_aes.c | 80 ++++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 7 +++ 4 files changed, 95 insertions(+) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index d1fce9e00c..9898f880a6 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -939,6 +939,9 @@ static uint16_t qemu_MAX[] =3D { S390_FEAT_KMCTR_AES_128, S390_FEAT_KMCTR_AES_192, S390_FEAT_KMCTR_AES_256, + S390_FEAT_KMCTR_EAES_128, + S390_FEAT_KMCTR_EAES_192, + S390_FEAT_KMCTR_EAES_256, S390_FEAT_PCC_XTS_AES_128, S390_FEAT_PCC_XTS_AES_256, S390_FEAT_PCKMO_AES_128, diff --git a/target/s390x/tcg/cpacf.h b/target/s390x/tcg/cpacf.h index 8987f8fbc7..71a2c6b914 100644 --- a/target/s390x/tcg/cpacf.h +++ b/target/s390x/tcg/cpacf.h @@ -290,5 +290,10 @@ int cpacf_paes_cbc(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, uint64_t param_addr, uint64_t *dst_ptr_reg, uint64_t *src_ptr_reg, uint64_t *src_len_reg, uint32_t type, uint8_t fc, uint8_t mod); +int cpacf_paes_ctr(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *dst_ptr_reg, + uint64_t *src_ptr_reg, uint64_t *src_len_reg, + uint64_t *ctr_ptr_reg, uint32_t type, + uint8_t fc, uint8_t mod); =20 #endif /* S390X_CPACF_H */ diff --git a/target/s390x/tcg/cpacf_aes.c b/target/s390x/tcg/cpacf_aes.c index 7373609ced..18d8e2299b 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -634,3 +634,83 @@ int cpacf_paes_cbc(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, =20 return !len ? 0 : 3; } + +int cpacf_paes_ctr(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *dst_ptr_reg, + uint64_t *src_ptr_reg, uint64_t *src_len_reg, + uint64_t *ctr_ptr_reg, uint32_t type, + uint8_t fc, uint8_t mod) +{ + enum { MAX_BLOCKS_PER_RUN =3D 8192 / AES_BLOCK_SIZE }; + uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; + uint8_t ctr[AES_BLOCK_SIZE], key[32], wkvp[32]; + uint64_t len =3D *src_len_reg, done =3D 0; + int i, keysize, addr_reg_size =3D 64; + AES_KEY exkey; + + g_assert(type =3D=3D S390_FEAT_TYPE_KMCTR); + + switch (fc) { + case CPACF_KMCTR_PAES_128: + keysize =3D 16; + break; + case CPACF_KMCTR_PAES_192: + keysize =3D 24; + break; + case CPACF_KMCTR_PAES_256: + keysize =3D 32; + break; + default: + g_assert_not_reached(); + } + + if (!(env->psw.mask & PSW_MASK_64)) { + len =3D (uint32_t)len; + addr_reg_size =3D (env->psw.mask & PSW_MASK_32) ? 32 : 24; + } + + /* length has to be properly aligned. */ + if (!QEMU_IS_ALIGNED(len, AES_BLOCK_SIZE)) { + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } + + /* fetch and check wkvp from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, + param_addr + keysize, wkvp, sizeof(wkvp)); + if (memcmp(wkvp, protkey_wkvp, sizeof(wkvp))) { + /* wkvp mismatch -> return with cc 1 */ + return 1; + } + + /* fetch protected key from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, param_addr, key, keysize); + /* decrypt the protected key */ + decrypt_protkey(key, keysize); + + /* expand key */ + AES_set_encrypt_key(key, keysize * 8, &exkey); + + /* process up to MAX_BLOCKS_PER_RUN aes blocks */ + for (i =3D 0; i < MAX_BLOCKS_PER_RUN && len >=3D AES_BLOCK_SIZE; i++) { + /* read in nonce/ctr =3D> ctr */ + aes_read_block(env, mmu_idx, ra, *ctr_ptr_reg + done, ctr); + /* read in one block of input data =3D> in */ + aes_read_block(env, mmu_idx, ra, *src_ptr_reg + done, in); + /* encrypt ctr and xor with in =3D> out */ + AES_ctr_encrypt(in, out, ctr, &exkey); + /* write out the processed block */ + aes_write_block(env, mmu_idx, ra, *dst_ptr_reg + done, out); + len -=3D AES_BLOCK_SIZE; + done +=3D AES_BLOCK_SIZE; + } + + *src_ptr_reg =3D deposit64(*src_ptr_reg, 0, addr_reg_size, + *src_ptr_reg + done); + *dst_ptr_reg =3D deposit64(*dst_ptr_reg, 0, addr_reg_size, + *dst_ptr_reg + done); + *ctr_ptr_reg =3D deposit64(*ctr_ptr_reg, 0, addr_reg_size, + *ctr_ptr_reg + done); + *src_len_reg -=3D done; + + return !len ? 0 : 3; +} diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_hel= per.c index 3c6dd74c70..155c06ee4c 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -166,6 +166,13 @@ static int cpacf_kmctr(CPUS390XState *env, const int m= mu_idx, uintptr_t ra, &env->regs[r1], &env->regs[r2], &env->regs[r2 += 1], &env->regs[r3], S390_FEAT_TYPE_KMCTR, fc, mod); break; + case CPACF_KMCTR_PAES_128: + case CPACF_KMCTR_PAES_192: + case CPACF_KMCTR_PAES_256: + rc =3D cpacf_paes_ctr(env, mmu_idx, ra, env->regs[1], + &env->regs[r1], &env->regs[r2], &env->regs[r2 = + 1], + &env->regs[r3], S390_FEAT_TYPE_KMCTR, fc, mod); + break; default: tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); } --=20 2.43.0 From nobody Mon Sep 28 01:12:31 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1785773702; cv=none; d=zohomail.com; s=zohoarc; b=WUURmUsellyTb23wv1ys5Dx8IQTyJuC9PyE2/p4U7McvdcfO5yKEdNq2lLgF6VrZI7ofA014kyijcSGAYBcPd/hmy4E4Rf+XMkU3N73BcLntTzUuN7MTX0Z5FqP+ooiyKf1HR+lAEcEOYG9MNIpgfXvRH5yzXuCWSvaR7BJUIKo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785773702; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=xmtUOuir1wK9KwGxE8LbYVIlgP621HqP3y7rRVPlQZw=; b=OWAFgoSL/dDgLOLRcZfPL6tQ/y4yv9/M1pohEugUJdHkWM07E99lROpwyU3byw4wGlhoIhrpRReDcNnJLDfsTSRmW5ayOol4TZ++mXCSe1jE+KDymthmuZiPk1fd8cB8/fg68JvOYeABYQg9zUd72wIrUNI5hNUTdtYCowAwnqM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785773702617346.02694739822687; Mon, 3 Aug 2026 09:15:02 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wqvHu-0006Mt-44; Mon, 03 Aug 2026 12:13:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHS-00061X-3X; Mon, 03 Aug 2026 12:12:46 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHQ-00035M-65; Mon, 03 Aug 2026 12:12:45 -0400 Received: from pps.filterd (m0360072.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 673EHnIi2341470; Mon, 3 Aug 2026 16:12:38 GMT Received: from ppma21.wdc07v.mail.ibm.com (5b.69.3da9.ip4.static.sl-reverse.com [169.61.105.91]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs8euhbvg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:38 +0000 (GMT) Received: from pps.filterd (ppma21.wdc07v.mail.ibm.com [127.0.0.1]) by ppma21.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 673GBSRT012089; Mon, 3 Aug 2026 16:12:37 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4fsv4jx6am-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:37 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 673GCX7U19858058 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 16:12:33 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id AEF9F20043; Mon, 3 Aug 2026 16:12:33 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 849D02004E; Mon, 3 Aug 2026 16:12:33 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 16:12:33 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=xmtUOuir1wK9KwGxE 8LbYVIlgP621HqP3y7rRVPlQZw=; b=At33l9QS8UPR9AzOhIUpzUZzhJoB1uP9t qa8wPVl8kgwNPqFe0p6HgwMQrGCx+BULM9QYcR8EoO21eTy/XxSRtgyaQcIoGHNt 6rg/we7wLG/EUTtaMNX2tTtLsve8G/oTteG63vKg38dYTXmvXltsB/gIPfXH9EQy fW6MobhXftHNL2UlUEwrC9Bm0h7hsXbzWComWweF64S64MOB1bv5PLTj78mMgylI 1HsuR7eykC94AajKb6gYrpS2AGkzR293xLyS/Mo0zUVnkE6N7Gr8KiqkLqsMsCca torLby9S8Ap+JkInHSJbnik5Tg5wrfB8pa5ORRuM/9W87+Xo/+rVw== From: Harald Freudenberger To: richard.henderson@linaro.org, iii@linux.ibm.com, david@kernel.org, thuth@redhat.com, berrange@redhat.com Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org, linux-s390@vger.kernel.org, dengler@linux.ibm.com, borntraeger@linux.ibm.com, fcallies@linux.ibm.com, cohuck@redhat.com Subject: [PATCH v13 15/18] target/s390x: Minimal protected key AES XTS support for cpacf pcc instruction Date: Mon, 3 Aug 2026 18:12:32 +0200 Message-ID: <20260803161235.228704-16-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803161235.228704-1-freude@linux.ibm.com> References: <20260803161235.228704-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: C7DaaF6rF6_jyRdHqTZQar9szG10hh4b X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX3YmWVzdaUf97 d3JmWgHl5IAG+Qgg8u1BK/kBWMJJZsKYr6LdKwyLyV+eE8/xzZWK1nnnODH0r0RLCcoI6YKoNns DqCwdkhumBrlJ/nAAhrTMjO0DCHNHV4= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX2svY07E7HKtb yDyFjIrRUefZJfzOYBPHjiOhtGgRL6IFML8Ppb/iqFtqXb0lXCXf9s6GYM9+PA5qsFzyGymRVtM ttFiVqsbiGXanPFzR920rKcH0lBA0lt6GMbB5MhhPv3BjxS3b/ed3lQZgO7cqU3chjcYMWdCJmr mtSPHzZEr8g/QKTssogxYJwXaJhxA3yQMu6PmcAaORIwCXV7ZLWgtJZNrPZdJm8CX0fGSCOVm8a 7FwzZW9TPwPgaCFO7KQj+3zu/Vo3iZvJ73wXam0CA2SAFbe+oK/pPFEWuIrnBfZiMz19iMS8pAk 8bs6jbSs1xQ/W0Lx/0OAxz5hZFUbtpsHWACBTwpj3cYk3g5LdQOnevCtNkUKV+dgcORkq/HeFCp TUKQhrZCKzl8Re4JDSvp8jVYFfva8F598fOotVBIxERP78aFE7XQdFjlWJs5UsI/wokT+pKkwSa pIlfQNjCxhQgHyRc6bQ== X-Proofpoint-GUID: C7DaaF6rF6_jyRdHqTZQar9szG10hh4b X-Authority-Analysis: v=2.4 cv=KfzidwYD c=1 sm=1 tr=0 ts=6a70bdf6 cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=RzCfie-kr_QcCd8fBx8p:22 a=VnNF1IyMAAAA:8 a=tkYQr5ag8MGam-WK_qUA:9 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-03_03,2026-08-03_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 bulkscore=0 impostorscore=0 suspectscore=0 malwarescore=0 adultscore=0 clxscore=1015 priorityscore=1501 phishscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030141 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=148.163.158.5; envelope-from=freude@linux.ibm.com; helo=mx0b-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1785773704335158500 Content-Type: text/plain; charset="utf-8" Support CPACF pcc subfunctions PCC-Compute-XTS-Parameter-Encrypted-AES-128 and PCC-Compute-XTS-Parameter-Encrypted-AES-128 but only for the special case block sequential number is 0. However, this covers the s390 PAES XTS implementation in the Linux kernel. Signed-off-by: Harald Freudenberger Tested-by: Holger Dengler --- target/s390x/gen-features.c | 2 + target/s390x/tcg/cpacf.h | 2 + target/s390x/tcg/cpacf_aes.c | 65 ++++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 4 ++ 4 files changed, 73 insertions(+) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index 9898f880a6..6b206cee83 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -944,6 +944,8 @@ static uint16_t qemu_MAX[] =3D { S390_FEAT_KMCTR_EAES_256, S390_FEAT_PCC_XTS_AES_128, S390_FEAT_PCC_XTS_AES_256, + S390_FEAT_PCC_XTS_EAES_128, + S390_FEAT_PCC_XTS_EAES_256, S390_FEAT_PCKMO_AES_128, S390_FEAT_PCKMO_AES_192, S390_FEAT_PCKMO_AES_256, diff --git a/target/s390x/tcg/cpacf.h b/target/s390x/tcg/cpacf.h index 71a2c6b914..1786a21f83 100644 --- a/target/s390x/tcg/cpacf.h +++ b/target/s390x/tcg/cpacf.h @@ -295,5 +295,7 @@ int cpacf_paes_ctr(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, uint64_t *src_ptr_reg, uint64_t *src_len_reg, uint64_t *ctr_ptr_reg, uint32_t type, uint8_t fc, uint8_t mod); +int cpacf_paes_pcc(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint8_t fc); =20 #endif /* S390X_CPACF_H */ diff --git a/target/s390x/tcg/cpacf_aes.c b/target/s390x/tcg/cpacf_aes.c index 18d8e2299b..d1f3b44a15 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -714,3 +714,68 @@ int cpacf_paes_ctr(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, =20 return !len ? 0 : 3; } + +int cpacf_paes_pcc(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint8_t fc) +{ + uint8_t key[32], wkvp[32], tweak[AES_BLOCK_SIZE], buf[AES_BLOCK_SIZE]; + int keysize, i; + AES_KEY exkey; + + switch (fc) { + case CPACF_PCC_XTS_PAES_128: + keysize =3D 16; + break; + case CPACF_PCC_XTS_PAES_256: + keysize =3D 32; + break; + default: + g_assert_not_reached(); + } + + /* fetch and check wkvp from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, + param_addr + keysize, wkvp, sizeof(wkvp)); + if (memcmp(wkvp, protkey_wkvp, sizeof(wkvp))) { + /* wkvp mismatch -> return with cc 1 */ + return 1; + } + + /* fetch block sequence nr from param block into buf */ + read_guest_wrap_u8(env, mmu_idx, ra, + param_addr + keysize + sizeof(wkvp) + AES_BLOCK_SIZ= E, + buf, AES_BLOCK_SIZE); + + /* is the block sequence nr 0 ? */ + for (i =3D 0; i < AES_BLOCK_SIZE && !buf[i]; i++) { + ; + } + if (i < AES_BLOCK_SIZE) { + /* no, sorry handling of non zero block sequence is not implemente= d */ + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + return 1; + } + + /* fetch protected key from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, param_addr, key, keysize); + /* decrypt the protected key */ + decrypt_protkey(key, keysize); + + /* fetch tweak from param block into tweak */ + read_guest_wrap_u8(env, mmu_idx, ra, + param_addr + keysize + sizeof(wkvp), + tweak, AES_BLOCK_SIZE); + + /* expand key */ + AES_set_encrypt_key(key, keysize * 8, &exkey); + + /* encrypt tweak */ + AES_encrypt(tweak, buf, &exkey); + + /* store encrypted tweak into xts parameter field of the param block */ + write_guest_wrap_u8(env, mmu_idx, ra, + param_addr + keysize + sizeof(wkvp) + 3 * AES_BLOC= K_SIZE, + buf, AES_BLOCK_SIZE); + + return 0; +} diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_hel= per.c index 155c06ee4c..aa27889d97 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -207,6 +207,10 @@ static int cpacf_pcc(CPUS390XState *env, const int mmu= _idx, uintptr_t ra, case CPACF_PCC_XTS_AES_256: rc =3D cpacf_aes_pcc(env, mmu_idx, ra, env->regs[1], fc); break; + case CPACF_PCC_XTS_PAES_128: + case CPACF_PCC_XTS_PAES_256: + rc =3D cpacf_paes_pcc(env, mmu_idx, ra, env->regs[1], fc); + break; default: tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); } --=20 2.43.0 From nobody Mon Sep 28 01:12:31 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1785773617; cv=none; d=zohomail.com; s=zohoarc; b=J1KSXOXXLv+ug/umOc5jSuXF7xW+207eFlKNHo7KFplbKbJ2PZqhb3wBJrPdCFlE8dnotdU8n+Q1miM4FQTWOL0F+6En9MWHJ8lC/8evpfEPaj1KAfDsq1Mn90jQfzi2XRKUpWytC8BFLrlrReZh6/CB2R+bC6Ye3YtDjpMBl84= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785773617; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=H4M5B8h1itkJgYltg1tv4u9TB8rC0J+torP0XHYxLrw=; b=cmU+vFz5E9YIGBgmVITVYkunyzYTL5iI4XYPV8MhwimJCcJkDsSypj9w6eYjBxA5XaTMfNJ3U3ieoXUJ3QoGlbMVGfRgovMhCsR3zYftnltDF67hyCIe3GWtsrmQ1PlcGC3LvGgjzktenPTsRLTLoTMG6pLc80BNgKhvIsrehb8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785773617364606.9803517043975; Mon, 3 Aug 2026 09:13:37 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wqvHw-0006Wr-Ui; Mon, 03 Aug 2026 12:13:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHS-000645-N3; Mon, 03 Aug 2026 12:12:48 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHQ-00035D-7O; Mon, 03 Aug 2026 12:12:46 -0400 Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 673EHUbd2282318; Mon, 3 Aug 2026 16:12:38 GMT Received: from ppma13.dal12v.mail.ibm.com (dd.9e.1632.ip4.static.sl-reverse.com [50.22.158.221]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs8h4sqv8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:38 +0000 (GMT) Received: from pps.filterd (ppma13.dal12v.mail.ibm.com [127.0.0.1]) by ppma13.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 673GBEWc008934; Mon, 3 Aug 2026 16:12:37 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4fswbg5yat-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:37 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 673GCYL211272664 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 16:12:34 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DE42A2004E; Mon, 3 Aug 2026 16:12:33 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id B508C2004F; Mon, 3 Aug 2026 16:12:33 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 16:12:33 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=H4M5B8h1itkJgYltg 1tv4u9TB8rC0J+torP0XHYxLrw=; b=pVFiYj28V1KBJ3tSj+GX19kqweYTq/ses xabtnXm1UVfV+UZkbdpP4e2dZKk79EyHpDGL5qbrSUZPHz/1E8BasBVPj5dyKNFe 5aNXZKHZ4LpynGbehev0IQM4whmM5NwBS9wjsjAMFnNpIMqVxxgYDYNovlyj0e0k SCYzQn6SKzHoXLJTqoS4AVoGi46v5qvVAPWAi4nNd4ytp5A0thG8hcBQwMpRZvUk ro36cPosrn4ySqamDuskw2REqk2csaekZOGubeqQUO/oxJ2iO5kYzhySxPHNNM33 XWXBIPTq+GZb9w+xG9yRPiB4ir6eDTLlXoZW2S9WgD6JhI5ZnRUgg== From: Harald Freudenberger To: richard.henderson@linaro.org, iii@linux.ibm.com, david@kernel.org, thuth@redhat.com, berrange@redhat.com Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org, linux-s390@vger.kernel.org, dengler@linux.ibm.com, borntraeger@linux.ibm.com, fcallies@linux.ibm.com, cohuck@redhat.com Subject: [PATCH v13 16/18] target/s390x: Support protected key AES XTS for cpacf km instruction Date: Mon, 3 Aug 2026 18:12:33 +0200 Message-ID: <20260803161235.228704-17-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803161235.228704-1-freude@linux.ibm.com> References: <20260803161235.228704-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfXyjk1LcQ6u0kB kaV1YcXDVxwB6Ki/RjhPz0VmSaZjWnoQIeddInoNNgm2CFXmDCL03SbiJtL3alwo6lYnkCjRgZz 4u5dg0FF0H9+TiUxo3PQe0p4DGo5qKk= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX3MADY0Pv98AK pX9MEau8T0tsVT+lYmCiXXNvRSN2z0jAWc+uZwoQ7poj59cGObOKPE11wZ4ee3ircjyywXrQfoB QjB9n0P+4V+0EVs2/cI2xPehsIF4s7TtDe2ITYdsihoH6Gz7U5afCtRVbIEIH1KKbIrz0Ag3cPx lhV8jSnZdPsp6QSyhPf6rQypeRbIAmTEvGgoE0auamqxb83afwcchCutjLDJE01lz+6jjI0wKwp vWXiOhVqP0m9I8sMmiIRFaBh0OH0E4NRqD44Iev/m9/+aAhUAkUvddF7nY896LOYq3B+POFer1p m1vHnGxNjG1eAL0B4TCNt4x7myThi9RlL5oOM7NGD6qA/CeTzZXRECjaI/qmWgCRhtwPdIuggSS mqw1rS9BSiRJQrXgu0GOuJbp9Hja60Z8oQqIuQaCH/zsRvaZRxLQcQspXBufSioEiCN/WW5+zrv i5LN9u30PT+sIasJVxQ== X-Authority-Analysis: v=2.4 cv=SI1ykuvH c=1 sm=1 tr=0 ts=6a70bdf6 cx=c_pps a=AfN7/Ok6k8XGzOShvHwTGQ==:117 a=AfN7/Ok6k8XGzOShvHwTGQ==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=D0XGIOQStSI5JxgU9CcA:9 X-Proofpoint-ORIG-GUID: PhXIZejCWbIlVFdBDoGyW2EhUQj_eSII X-Proofpoint-GUID: PhXIZejCWbIlVFdBDoGyW2EhUQj_eSII X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-03_03,2026-08-03_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 bulkscore=0 suspectscore=0 impostorscore=0 spamscore=0 phishscore=0 priorityscore=1501 lowpriorityscore=0 adultscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030141 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=148.163.156.1; envelope-from=freude@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1785773617978158500 Content-Type: text/plain; charset="utf-8" Support the subfunctions CPACF_KM_PXTS_128 and CPACF_KM_PXTS_256 for the cpacf km instruction. Tested-by: Holger Dengler Signed-off-by: Harald Freudenberger --- target/s390x/gen-features.c | 2 + target/s390x/tcg/cpacf.h | 4 ++ target/s390x/tcg/cpacf_aes.c | 93 ++++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 6 +++ 4 files changed, 105 insertions(+) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index 6b206cee83..0afea9fdd0 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -930,6 +930,8 @@ static uint16_t qemu_MAX[] =3D { S390_FEAT_KM_EAES_256, S390_FEAT_KM_XTS_AES_128, S390_FEAT_KM_XTS_AES_256, + S390_FEAT_KM_XTS_EAES_128, + S390_FEAT_KM_XTS_EAES_256, S390_FEAT_KMC_AES_128, S390_FEAT_KMC_AES_192, S390_FEAT_KMC_AES_256, diff --git a/target/s390x/tcg/cpacf.h b/target/s390x/tcg/cpacf.h index 1786a21f83..d86d3b58f9 100644 --- a/target/s390x/tcg/cpacf.h +++ b/target/s390x/tcg/cpacf.h @@ -297,5 +297,9 @@ int cpacf_paes_ctr(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, uint8_t fc, uint8_t mod); int cpacf_paes_pcc(CPUS390XState *env, const int mmu_idx, uintptr_t ra, uint64_t param_addr, uint8_t fc); +int cpacf_paes_xts(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *dst_ptr_reg, + uint64_t *src_ptr_reg, uint64_t *src_len_reg, + uint32_t type, uint8_t fc, uint8_t mod); =20 #endif /* S390X_CPACF_H */ diff --git a/target/s390x/tcg/cpacf_aes.c b/target/s390x/tcg/cpacf_aes.c index d1f3b44a15..1de80a7a7f 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -779,3 +779,96 @@ int cpacf_paes_pcc(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, =20 return 0; } + +int cpacf_paes_xts(CPUS390XState *env, const int mmu_idx, uintptr_t ra, + uint64_t param_addr, uint64_t *dst_ptr_reg, + uint64_t *src_ptr_reg, uint64_t *src_len_reg, + uint32_t type, uint8_t fc, uint8_t mod) +{ + enum { MAX_BLOCKS_PER_RUN =3D 8192 / AES_BLOCK_SIZE }; + uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; + uint8_t key[32], wkvp[32], tweak[AES_BLOCK_SIZE]; + uint64_t len =3D *src_len_reg, done =3D 0; + int i, keysize, addr_reg_size =3D 64; + AES_KEY exkey; + + g_assert(type =3D=3D S390_FEAT_TYPE_KM); + + switch (fc) { + case CPACF_KM_PXTS_128: + keysize =3D 16; + break; + case CPACF_KM_PXTS_256: + keysize =3D 32; + break; + default: + g_assert_not_reached(); + } + + if (!(env->psw.mask & PSW_MASK_64)) { + len =3D (uint32_t)len; + addr_reg_size =3D (env->psw.mask & PSW_MASK_32) ? 32 : 24; + } + + /* length has to be properly aligned. */ + if (!QEMU_IS_ALIGNED(len, AES_BLOCK_SIZE)) { + tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); + } + + /* fetch and check wkvp from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, + param_addr + keysize, wkvp, sizeof(wkvp)); + if (memcmp(wkvp, protkey_wkvp, sizeof(wkvp))) { + /* wkvp mismatch -> return with cc 1 */ + return 1; + } + + /* fetch protected key from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, param_addr, key, keysize); + /* decrypt the protected key */ + decrypt_protkey(key, keysize); + + /* expand key */ + if (mod) { + AES_set_decrypt_key(key, keysize * 8, &exkey); + } else { + AES_set_encrypt_key(key, keysize * 8, &exkey); + } + + /* fetch tweak from param block */ + read_guest_wrap_u8(env, mmu_idx, ra, + param_addr + keysize + sizeof(wkvp), + tweak, AES_BLOCK_SIZE); + + /* process up to MAX_BLOCKS_PER_RUN aes blocks */ + for (i =3D 0; i < MAX_BLOCKS_PER_RUN && len >=3D AES_BLOCK_SIZE; i++) { + /* fetch one AES block into in */ + aes_read_block(env, mmu_idx, ra, *src_ptr_reg + done, in); + if (mod) { + /* decrypt in =3D> out */ + AES_xts_decrypt(in, out, tweak, &exkey); + } else { + /* encrypt in =3D> out */ + AES_xts_encrypt(in, out, tweak, &exkey); + } + /* prep tweak for next round */ + AES_xts_prep_next_tweak(tweak); + /* write out this processed block from out */ + aes_write_block(env, mmu_idx, ra, *dst_ptr_reg + done, out); + len -=3D AES_BLOCK_SIZE; + done +=3D AES_BLOCK_SIZE; + } + + /* update tweak in param block */ + write_guest_wrap_u8(env, mmu_idx, ra, + param_addr + keysize + sizeof(wkvp), + tweak, AES_BLOCK_SIZE); + + *src_ptr_reg =3D deposit64(*src_ptr_reg, 0, addr_reg_size, + *src_ptr_reg + done); + *dst_ptr_reg =3D deposit64(*dst_ptr_reg, 0, addr_reg_size, + *dst_ptr_reg + done); + *src_len_reg -=3D done; + + return !len ? 0 : 3; +} diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_hel= per.c index aa27889d97..47176c78be 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -117,6 +117,12 @@ static int cpacf_km(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, &env->regs[r1], &env->regs[r2], &env->regs[r2 += 1], S390_FEAT_TYPE_KM, fc, mod); break; + case CPACF_KM_PXTS_128: + case CPACF_KM_PXTS_256: + rc =3D cpacf_paes_xts(env, mmu_idx, ra, env->regs[1], + &env->regs[r1], &env->regs[r2], &env->regs[r2 = + 1], + S390_FEAT_TYPE_KM, fc, mod); + break; default: tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra); } --=20 2.43.0 From nobody Mon Sep 28 01:12:31 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1785773665; cv=none; d=zohomail.com; s=zohoarc; b=RyKWXlBEt9PVRcxCBq/CBJ0o9AfT8eoosuzSh1iEm3cAbwHxzMhf2B9WgRePaUeMxAWeaDCcVtwEo8nQktdloVtqjWeIVqR1+IhakCL65ZwA/2WMcKr6aSHvFng7oKj4BgOg3WBU7pmEtvgWAKo8c2PNgDEFmxEWa3frbyH1XTc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785773665; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=QHws/HGyPCBEZzV43fOKgIcCUZPefUjWYFD1n6swBRI=; b=d+5dy/QFk9CF7Y5S/Ydk3b4V6TdesIMCkp1SM5hJTLYBwWgyBhGc5BmyarIxuce+s/Zji0yCTbI0NRrErdzACdw1XxxNdBcuh6KLrk4s3tK+6gz0RxSyXPk8dabW+AjNR6einguFbekrNvGUoRd3EX8MqJQPZ03KFqbniVulKXg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785773665463475.553037905182; Mon, 3 Aug 2026 09:14:25 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wqvI1-0006bW-NE; Mon, 03 Aug 2026 12:13:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHT-00064H-Kk; Mon, 03 Aug 2026 12:12:48 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHQ-00035W-BF; Mon, 03 Aug 2026 12:12:47 -0400 Received: from pps.filterd (m0353725.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 673EHgTe2206102; Mon, 3 Aug 2026 16:12:39 GMT Received: from ppma11.dal12v.mail.ibm.com (db.9e.1632.ip4.static.sl-reverse.com [50.22.158.219]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs77g1huj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:38 +0000 (GMT) Received: from pps.filterd (ppma11.dal12v.mail.ibm.com [127.0.0.1]) by ppma11.dal12v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 673GBGDW012401; Mon, 3 Aug 2026 16:12:37 GMT Received: from smtprelay07.fra02v.mail.ibm.com ([9.218.2.229]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 4fswtydxa0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:37 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay07.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 673GCYQB45416886 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 16:12:34 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 19F3E2004B; Mon, 3 Aug 2026 16:12:34 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E3F9320043; Mon, 3 Aug 2026 16:12:33 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 16:12:33 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=QHws/HGyPCBEZzV43 fOKgIcCUZPefUjWYFD1n6swBRI=; b=H9WXjO/SmhopDBO+lVLhsfIJJewpBrJ/2 kZDJsvd58m2SG2hLFdxIkqN7jrUdpFVg/r/4ZWEqTnL/bnTPHPvuT5b5M6HjlxjF 6JgfplF7jZLE6RIEv42LWorMWTBRWm6nTU/PGyaybulC0EYwMB/uMopL5Oa2jNTa QbC3XQVqd+PKIm/gRn3UU0xJDjbI/D/yV80esj6R4lVrWAQ4AFGWRLFoTA8YvjS9 YBpXQw9tpQXQGTOuPNMW0fZQD007zCDnAYcZ7ZWD9+/eRlSGq/0/24SkOhsgrJB7 0XzsmPrL16NBEVvi4/cSmtxtpQxFULTPZBkWhRrd2BLEalDcpJwWw== From: Harald Freudenberger To: richard.henderson@linaro.org, iii@linux.ibm.com, david@kernel.org, thuth@redhat.com, berrange@redhat.com Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org, linux-s390@vger.kernel.org, dengler@linux.ibm.com, borntraeger@linux.ibm.com, fcallies@linux.ibm.com, cohuck@redhat.com Subject: [PATCH v13 17/18] docs/s390: Document CPACF instructions support Date: Mon, 3 Aug 2026 18:12:34 +0200 Message-ID: <20260803161235.228704-18-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803161235.228704-1-freude@linux.ibm.com> References: <20260803161235.228704-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX1gfSDWiBqzIz pYHuer/hccpbhr0WRXgYQlJgO2hCH8w7JvzMKOoch5CvJiCkniu7MwDjnds5qSgy2krGKcPXmsT 89qs3UqBwEr20lmviLFb1JUKD8Em/L7Yj+ZFXjB3Yz26alHEJtL80paxhL/0DNEWRFfDCv2EDQB +K0OUyhgziLnCuVY9bh11GyYIHxr/CXaU/rJJm9jJOEMLSen3pZWj2cGh8Q63QjuX47Y4RZErkL paiJlA8GPdZFjtCsmLwUvils5yciOJVU/AYwelRKGpRhkVplRLiPKZZoIhisSqIv1E7MAJutmKx lNe4e0H/STsULtuym2dDZZlXzRGTm/oISYXg1UQIWeCBcVn2A1OkOuAuaLLMhEPZY2LgiroQQ/o 95P6CXMdstrVBWGbzK/lkMia1SvWU4IJhbLBtkfL/TYm3hHMm7nf6sfMz6QZgHrgOUt9c483zDX lMNOxiGTNJa6E2nzLQQ== X-Authority-Analysis: v=2.4 cv=WIFPmHsR c=1 sm=1 tr=0 ts=6a70bdf6 cx=c_pps a=aDMHemPKRhS1OARIsFnwRA==:117 a=aDMHemPKRhS1OARIsFnwRA==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=V8glGbnc2Ofi9Qvn3v5h:22 a=VnNF1IyMAAAA:8 a=IlYB4z8HrC9mJJy16gAA:9 a=5wi_FRADO1KgGG3s:21 a=O8hF6Hzn-FEA:10 X-Proofpoint-GUID: gEN4jmj6ZW5VxxbqrTTLLYpYTd2TW5ON X-Proofpoint-ORIG-GUID: gEN4jmj6ZW5VxxbqrTTLLYpYTd2TW5ON X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX0QT2upEGDgeq +bjfHEv0pYlKy5YR9YXP84uK+17Tf/FAuLsjLL2DUAscww2fIdADLgZ+Xtz0D5akGHyUZbTLjnV 5bMISweRd27xDD/bBDKs1jkXNzfjszw= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-03_03,2026-08-03_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 lowpriorityscore=0 priorityscore=1501 phishscore=0 malwarescore=0 suspectscore=0 clxscore=1015 impostorscore=0 bulkscore=0 adultscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030141 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=148.163.158.5; envelope-from=freude@linux.ibm.com; helo=mx0b-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1785773666225158500 Content-Type: text/plain; charset="utf-8" Add a first document covering the Qemu s390 CPACF instructions and functions supported. Signed-off-by: Harald Freudenberger Reviewed-by: Finn Callies Reviewed-by: Ilya Leoshkevich --- docs/system/s390x/cpacf.rst | 146 +++++++++++++++++++++++++++++++++++ docs/system/target-s390x.rst | 1 + 2 files changed, 147 insertions(+) create mode 100644 docs/system/s390x/cpacf.rst diff --git a/docs/system/s390x/cpacf.rst b/docs/system/s390x/cpacf.rst new file mode 100644 index 0000000000..4b77146a98 --- /dev/null +++ b/docs/system/s390x/cpacf.rst @@ -0,0 +1,146 @@ +.. SPDX-License-Identifier: GPL-2.0-or-later + +CPACF Support +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +CPACF +----- + +CP Assist for Cryptographic Function (CPACF) is a hardware-integrated +coprocessor feature built into every processor core of IBM Z and +LinuxONE mainframes (s390x architecture). It provides high-speed, +hardware-accelerated encryption and hashing directly on the CPU. + +CPACF provides a set of z/Architecture instructions (known as Message +Security Assist or MSA) that execute cryptographic operations +synchronously with the main processor. + +- Symmetric Encryption: Support for AES (128, 192, 256-bit), DES, and + Triple-DES (TDES). +- Hashing: Acceleration for SHA-1, SHA-2 (up to SHA-512), SHA-3 and + SHAKE. +- Random Number Generation: Pseudo Random Number Generator (PRNG) and + a hardware-based True Random Number Generator (TRNG). +- Asymmetric Support: Elliptic Curve Cryptography (ECC) primitives + P-256, P-384, P-521, Montgomery/Edwards curves (e.g., Ed25519). + +Documentation about CPACF instructions is publicly available and +can be found in the "z/Architecture Principles of Operation" +accessible at the IBM documentation hub https://www.ibm.com/docs/en. +For example the latest version as a pdf is available here: +https://www.ibm.com/support/pages/zvm/library/other/22783214.pdf + + +CPACF instructions +------------------ + +Here is a list of implemented CPACF instructions and the supported +functions for each instruction: + +KDSA (COMPUTE DIGITAL SIGNATURE AUTHENTICATION) +- Function code 0x00 - Function Query + +KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) +- Function code 0x00 - Function Query +- Function code 0x02 - CPACF_KIMD_SHA_256 +- Function code 0x03 - CPACF_KIMD_SHA_512 + +KLMD (COMPUTE LAST MESSAGE DIGEST) +- Function code 0x00 - Function Query +- Function code 0x02 - CPACF_KLMD_SHA_256 +- Function code 0x03 - CPACF_KLMD_SHA_512 + +KM (CIPHER MESSAGE) +- Function code 0x00 - Function Query +- Function code 0x12 - CPACF_KM_AES_128 +- Function code 0x13 - CPACF_KM_AES_192 +- Function code 0x14 - CPACF_KM_AES_256 +- Function code 0x1a - CPACF_KM_PAES_128 +- Function code 0x1b - CPACF_KM_PAES_192 +- Function code 0x1c - CPACF_KM_PAES_256 +- Function code 0x32 - CPACF_KM_XTS_128 +- Function code 0x34 - CPACF_KM_XTS_256 +- Function code 0x3a - CPACF_KM_PXTS_128 +- Function code 0x3c - CPACF_KM_PXTS_256 + +KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) +- Function code 0x00 - Function Query + +KMC (CIPHER MESSAGE WITH CHAINING) +- Function code 0x00 - Function Query +- Function code 0x12 - CPACF_KMC_AES_128 +- Function code 0x13 - CPACF_KMC_AES_192 +- Function code 0x14 - CPACF_KMC_AES_256 +- Function code 0x1a - CPACF_KMC_PAES_128 +- Function code 0x1b - CPACF_KMC_PAES_192 +- Function code 0x1c - CPACF_KMC_PAES_256 + +KMCTR (CIPHER MESSAGE WITH COUNTER) +- Function code 0x00 - Function Query +- Function code 0x12 - CPACF_KMCTR_AES_128 +- Function code 0x13 - CPACF_KMCTR_AES_192 +- Function code 0x14 - CPACF_KMCTR_AES_256 +- Function code 0x1a - CPACF_KMCTR_PAES_128 +- Function code 0x1b - CPACF_KMCTR_PAES_192 +- Function code 0x1c - CPACF_KMCTR_PAES_256 + +KMF (CIPHER MESSAGE WITH CIPHER FEEDBACK) +- not supported + +KMO (CIPHER MESSAGE WITH OUTPUT FEEDBACK) +- not supported + +PCC (PERFORM CRYPTOGRAPHIC COMPUTATION) +- Function code 0x00 - Function Query +- Function code 0x32 - compute XTS param AES-128 +- Function code 0x34 - compute XTS param AES-256 +- Function code 0x3a - compute XTS param Encrypted AES-128 +- Function code 0x3c - compute XTS param Encrypted AES-256 + +PCKMO (PERFORM CRYPTOGRAPHIC KEY MANAGEMENT OPERATION) +- Function code 0x00 - Function Query +- Function code 0x12 - CPACF_PCKMO_ENC_AES_128_KEY +- Function code 0x13 - CPACF_PCKMO_ENC_AES_192_KEY +- Function code 0x14 - CPACF_PCKMO_ENC_AES_256_KEY + +PRNO (PERFORM RANDOM NUMBER OPERATION) +- Function code 0x00 - Function Query +- Function code 0x72 - CPACF_PRNO_TRNG + +Note that the use of a not supported CPACF instruction (KMF and KMO) +or invocation of a not listed function will result in a Specification +Exception. + +Not listed CPACF instructions (KMA, KMF, KMO) cause an Operation +Exception when used. Not listed functions cause a Specification +Exception when called. If only the query function is listed (KDSA), +then the query function will return a function status word with all +but the query function bit set to 0. + + +Protected key support +--------------------- + +The qemu version for protected key support is only a fake provided +here for developing and testing purpose: + +- The protected key is _derived_ from the clear key by xoring the + fixed pattern 0xAAAA... onto the key value. +- The AES Wrapping Key Verification Pattern is a fixed value of 32 + bytes 0xFACEFACE... + +The PCKMO instruction implementation does exactly this - _derive_ a +_protected_ key from the clear key given by xor 0xAAAA... and writing +the fixed value for the WKVP of 0xFACEFACE into the blob. +The other subfunctions of the CPACF instructions dealing with +protected key treat the protected key blob by first checking for the +WKVP (against the fixed value of 0xFACEFACE...) and second +_decrypting_ the key value by xoring 0xAAAA... and then execute the +clear key operation with the decrypted key value. +This is suitable for testing purpose but such keys are not for real +production load and would open up a huge security breach! + +For more details about protected keys see the "z/Architecture +Principles of Operation" document chapter "General Instructions" +sub-chapter "Protection of Cryptographic Keys" and again the +implementation here does NOT implement what is explained there. diff --git a/docs/system/target-s390x.rst b/docs/system/target-s390x.rst index 94c981e732..49159826eb 100644 --- a/docs/system/target-s390x.rst +++ b/docs/system/target-s390x.rst @@ -35,3 +35,4 @@ Architectural features s390x/bootdevices s390x/protvirt s390x/cpu-topology + s390x/cpacf --=20 2.43.0 From nobody Mon Sep 28 01:12:31 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=linux.ibm.com ARC-Seal: i=1; a=rsa-sha256; t=1785773690; cv=none; d=zohomail.com; s=zohoarc; b=h1RNXFT9aHBvdnGVy+ChGI/C0ONd2KrLcQpnTad1WlxBHZ/0eClmO9xeiGGIbm55RlKZSOdfLVG8JgEtnKph1UuiZs3CVE8M4S6kMxr4QUIsjp3R3dx8s7DmIprWiRMFFe+UisAyXYcGp+7mWskYyHiMcF667RDTxeaJJsejTAQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1785773690; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=gjlqvz016wu7GARZVYqq0Jdf9bJH3IR+4mMhnAJTPHc=; b=b3Nb7xZO12ydKmLMZE58pQIltjPsaoEUKf5FG8aIZ11YzVu4tRvTRvo2iMXYFn4yZAlE3rymWPRJtWd41JI19CWZ2NfO3rUQIxbfYhtZY9V3Z2J9pccoJJLRdKdNapxRfshdO1cKWz2zohO7gofDcNtL+j+A3PXm586L8Upf1nM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1785773690060742.856083045878; Mon, 3 Aug 2026 09:14:50 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wqvHw-0006Sz-5G; Mon, 03 Aug 2026 12:13:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHr-0006GG-Jh; Mon, 03 Aug 2026 12:13:12 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wqvHm-00036m-0l; Mon, 03 Aug 2026 12:13:11 -0400 Received: from pps.filterd (m0356516.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 673EICnO2202861; Mon, 3 Aug 2026 16:12:40 GMT Received: from ppma21.wdc07v.mail.ibm.com (5b.69.3da9.ip4.static.sl-reverse.com [169.61.105.91]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fs67hhp3w-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:40 +0000 (GMT) Received: from pps.filterd (ppma21.wdc07v.mail.ibm.com [127.0.0.1]) by ppma21.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 673GBFxr011972; Mon, 3 Aug 2026 16:12:39 GMT Received: from smtprelay07.fra02v.mail.ibm.com ([9.218.2.229]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4fsv4jx6as-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 03 Aug 2026 16:12:39 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (smtpav01.fra02v.mail.ibm.com [10.20.54.100]) by smtprelay07.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 673GCYxO48103812 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 3 Aug 2026 16:12:34 GMT Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6668620040; Mon, 3 Aug 2026 16:12:34 +0000 (GMT) Received: from smtpav01.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 211E82004E; Mon, 3 Aug 2026 16:12:34 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.207.251]) by smtpav01.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 3 Aug 2026 16:12:34 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=gjlqvz016wu7GARZV Yqq0Jdf9bJH3IR+4mMhnAJTPHc=; b=e2h2PdGPFbqOXxxKyysJT7R3+wSZcr98k Bz85bz2g7F+zVBmVn82tJUZTGIEvHCL5wn+okWr48M+iRKyTaMxjA/1DoVHv/iUo g6qQNbnFUQX2YgHQ1kj+woJIavSZEOGLsU1Wlj7GEi+sx5uwkyPzxdBloQ6u2qqn jVz1XIKTqoLNkuSW1Fs+q3AWKuJsvc8MTs/Gpz9N6S8DUf8hdi2cdyYqmex7mUwO /tllMu32cnQGJfWbBTVs6+WGRiRgS7QHxJ4q19X+1kuCb/p5W+Egwy+5Iq04BRF3 rCjUCVkK99ueBoROZ4sncnPYN6gNJoqBm9aT/cXjp8mRHOpzP4UUA== From: Harald Freudenberger To: richard.henderson@linaro.org, iii@linux.ibm.com, david@kernel.org, thuth@redhat.com, berrange@redhat.com Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org, linux-s390@vger.kernel.org, dengler@linux.ibm.com, borntraeger@linux.ibm.com, fcallies@linux.ibm.com, cohuck@redhat.com Subject: [PATCH v13 18/18] tests/tcg/s390x: Add tests for CPACF instructions Date: Mon, 3 Aug 2026 18:12:35 +0200 Message-ID: <20260803161235.228704-19-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260803161235.228704-1-freude@linux.ibm.com> References: <20260803161235.228704-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX9BFUc2ndoz0x x/zcT6eliTzcNPpDRG74brViZCtBB2yhwas151XvsNf/8FZCpcE3V1kHGdkkOBsghS6au7bPKbs sLvWZNzoqsbK6pMcb60zuLsoUOTCj3I= X-Authority-Analysis: v=2.4 cv=I7VVgtgg c=1 sm=1 tr=0 ts=6a70bdf8 cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=Y2IxJ9c9Rs8Kov3niI8_:22 a=VnNF1IyMAAAA:8 a=uTGXcgEPX-vUjW6082YA:9 a=9gp5PUktWgSiYFtD:21 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODAzMDE0MSBTYWx0ZWRfX1+VaeLDXEsKS 7huAF/gORMxmCg6lfbWwuGEnmcV8RnNzU/EYmVv+ZjWjjob7gqqaeRjCXPOJWPc1N7MmyEg8/R9 OHw6LnndWCJCcN/2JQHC9rEicYgxwoeDLLuw4c8MCdh3rjmDC1cN0Smti2Hn27G2244ARYq3XxV HhtUjpYb/M89fiUWkIiT1DOYOavHIsojhT2tLEolIJHBVLlEg2JVTd+GLuNkOUKE7p8K9VmE9UI EnWFuycwk1ibXlDyRpfQrLeeyoWp4ZEf73ZVlMHYN/m3HZp4klb4n0vCPr9t33ZkpcV3xtmqFsR Jle3RwVIBzTL23SfIPzygvbWsVPnW9dsTemU2XgxTjLAIuHIq8QvTU6FupkXCmF98ILMZU5IcM1 9NiliyqIJVtc+m/Oxffm6DYYjBtW87FjugDkwEcmiFXNU6rOPyobMsLZ6t0AXuRqtotvzunI8ag g5Vp/MaU/FopzEmDhZQ== X-Proofpoint-ORIG-GUID: 52XtKWylipmoWjDASDE_0UT1J-WwxrJp X-Proofpoint-GUID: 52XtKWylipmoWjDASDE_0UT1J-WwxrJp X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-03_03,2026-08-03_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 impostorscore=0 clxscore=1015 priorityscore=1501 suspectscore=0 malwarescore=0 adultscore=0 lowpriorityscore=0 phishscore=0 spamscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608030141 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=148.163.158.5; envelope-from=freude@linux.ibm.com; helo=mx0b-001b2d01.pphosted.com X-Spam_score_int: -26 X-Spam_score: -2.7 X-Spam_bar: -- X-Spam_report: (-2.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ibm.com) X-ZM-MESSAGEID: 1785773692345158500 Content-Type: text/plain; charset="utf-8" Add simple tests for the CPACF instructions implemented: - kdsa - minimal as only query is implemented - kimd - query, sha256, sha512 - klmd - query, sha256, sha512 - km - query, aes 128, 192, 256 with clear and prot key - kmac - minimal as only query is implemented - kmc - query, aes 128, 192, 256 with clear and prot key - kmctr - query, aes 128, 192, 256 with clear and prot key - pcc - query, xts aes 128, 256 and prot key xts aes 128, 256 - prno - query, trng No test for pckmo as this is a privileged instruction. No test for kma, kmf, kmo as these instructions are currently not implemented at all. Signed-off-by: Harald Freudenberger --- target/s390x/tcg/cpacf.h | 7 + tests/tcg/s390x/Makefile.target | 9 + tests/tcg/s390x/cpacf-kdsa.c | 58 ++++ tests/tcg/s390x/cpacf-kimd.c | 166 +++++++++ tests/tcg/s390x/cpacf-klmd.c | 206 +++++++++++ tests/tcg/s390x/cpacf-km.c | 590 ++++++++++++++++++++++++++++++++ tests/tcg/s390x/cpacf-kmac.c | 58 ++++ tests/tcg/s390x/cpacf-kmc.c | 351 +++++++++++++++++++ tests/tcg/s390x/cpacf-kmctr.c | 360 +++++++++++++++++++ tests/tcg/s390x/cpacf-pcc.c | 245 +++++++++++++ tests/tcg/s390x/cpacf-prno.c | 131 +++++++ tests/tcg/s390x/cpacf.h | 571 +++++++++++++++++++++++++++++++ 12 files changed, 2752 insertions(+) create mode 100644 tests/tcg/s390x/cpacf-kdsa.c create mode 100644 tests/tcg/s390x/cpacf-kimd.c create mode 100644 tests/tcg/s390x/cpacf-klmd.c create mode 100644 tests/tcg/s390x/cpacf-km.c create mode 100644 tests/tcg/s390x/cpacf-kmac.c create mode 100644 tests/tcg/s390x/cpacf-kmc.c create mode 100644 tests/tcg/s390x/cpacf-kmctr.c create mode 100644 tests/tcg/s390x/cpacf-pcc.c create mode 100644 tests/tcg/s390x/cpacf-prno.c create mode 100644 tests/tcg/s390x/cpacf.h diff --git a/target/s390x/tcg/cpacf.h b/target/s390x/tcg/cpacf.h index d86d3b58f9..b2c4e7a838 100644 --- a/target/s390x/tcg/cpacf.h +++ b/target/s390x/tcg/cpacf.h @@ -223,6 +223,8 @@ #define CPACF_KDSA_PSIGN_ED25519 48 #define CPACF_KDSA_PSIGN_ED448 52 =20 +#ifndef CPACF_H_INCLUDE_FOR_TESTS + /* from cpacf_sha256.c */ int cpacf_sha256(CPUS390XState *env, const int mmu_idx, uintptr_t ra, uint64_t param_addr, uint64_t *message_reg, uint64_t *len= _reg, @@ -254,6 +256,8 @@ int cpacf_aes_xts(CPUS390XState *env, const int mmu_idx= , uintptr_t ra, uint64_t *src_ptr_reg, uint64_t *src_len_reg, uint32_t type, uint8_t fc, uint8_t mod); =20 +#endif /* CPACF_H_INCLUDE_FOR_TESTS */ + /* * Support for protected key cpacf functions. Note that this is * a fake implementation intended for debugging and development. @@ -279,6 +283,8 @@ int cpacf_aes_xts(CPUS390XState *env, const int mmu_idx= , uintptr_t ra, 0x0F, 0x0A, 0x0C, 0x0E, 0x0F, 0x0A, 0x0C, 0x0E, \ 0x0F, 0x0A, 0x0C, 0x0E, 0x0F, 0x0A, 0x0C, 0x0E } =20 +#ifndef CPACF_H_INCLUDE_FOR_TESTS + /* from cpacf_aes.c */ int cpacf_aes_pckmo(CPUS390XState *env, const int mmu_idx, uintptr_t ra, uint64_t param_addr, uint8_t fc); @@ -302,4 +308,5 @@ int cpacf_paes_xts(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, uint64_t *src_ptr_reg, uint64_t *src_len_reg, uint32_t type, uint8_t fc, uint8_t mod); =20 +#endif /* CPACF_H_INCLUDE_FOR_TESTS */ #endif /* S390X_CPACF_H */ diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.tar= get index 0ca030ded0..68e6a1816d 100644 --- a/tests/tcg/s390x/Makefile.target +++ b/tests/tcg/s390x/Makefile.target @@ -50,6 +50,15 @@ TESTS+=3Dcvb TESTS+=3Dts TESTS+=3Dex-smc TESTS+=3Ddivide-to-integer +TESTS+=3Dcpacf-kdsa +TESTS+=3Dcpacf-kimd +TESTS+=3Dcpacf-klmd +TESTS+=3Dcpacf-km +TESTS+=3Dcpacf-kmac +TESTS+=3Dcpacf-kmc +TESTS+=3Dcpacf-kmctr +TESTS+=3Dcpacf-pcc +TESTS+=3Dcpacf-prno =20 cdsg: CFLAGS+=3D-pthread cdsg: LDFLAGS+=3D-pthread diff --git a/tests/tcg/s390x/cpacf-kdsa.c b/tests/tcg/s390x/cpacf-kdsa.c new file mode 100644 index 0000000000..cc06e60f11 --- /dev/null +++ b/tests/tcg/s390x/cpacf-kdsa.c @@ -0,0 +1,58 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Simple test for the CPACF KDSA instruction + */ + +#include +#include +#include +#include +#include "cpacf.h" + +#define QUERY_BLOCK_SIZE 16 + +/* expected kdsa query block */ +static uint8_t exp_query_block[QUERY_BLOCK_SIZE] =3D { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static int test_kdsa_query(void) +{ + uint8_t query_block[QUERY_BLOCK_SIZE] =3D {0}; + unsigned long cc =3D 0; + int i, rc =3D 0; + + cpacf_kdsa(CPACF_KDSA_QUERY, query_block, NULL, 0, &cc); + + /* compare with expected query block */ + for (i =3D 0; i < QUERY_BLOCK_SIZE; i++) { + if ((query_block[i] & exp_query_block[i]) !=3D exp_query_block[i])= { + rc++; + break; + } + } + + if (rc) { + printf("%s failed\n", __func__); + } + + return rc; +} + +int main(void) +{ + int rc; + + /* Test query function */ + rc =3D test_kdsa_query(); + + /* As of now only KDSA query is implemented */ + + if (rc) { + printf("cpacf-kdsa: %d failures\n", rc); + } + + return rc ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/tests/tcg/s390x/cpacf-kimd.c b/tests/tcg/s390x/cpacf-kimd.c new file mode 100644 index 0000000000..61c5268ccb --- /dev/null +++ b/tests/tcg/s390x/cpacf-kimd.c @@ -0,0 +1,166 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Simple test for CPACF KIMD instruction + */ + +#include +#include +#include +#include +#include "cpacf.h" + +#define QUERY_BLOCK_SIZE 16 + +/* expected kimd query block */ +static uint8_t exp_query_block[QUERY_BLOCK_SIZE] =3D { + 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +/* SHA-256 test data */ +static const uint8_t sha256in[] =3D { + 0x5a, 0x86, 0xb7, 0x37, 0xea, 0xea, 0x8e, 0xe9, + 0x76, 0xa0, 0xa2, 0x4d, 0xa6, 0x3e, 0x7e, 0xd7, + 0xee, 0xfa, 0xd1, 0x8a, 0x10, 0x1c, 0x12, 0x11, + 0xe2, 0xb3, 0x65, 0x0c, 0x51, 0x87, 0xc2, 0xa8, + 0xa6, 0x50, 0x54, 0x72, 0x08, 0x25, 0x1f, 0x6d, + 0x42, 0x37, 0xe6, 0x61, 0xc7, 0xbf, 0x4c, 0x77, + 0xf3, 0x35, 0x39, 0x03, 0x94, 0xc3, 0x7f, 0xa1, + 0xa9, 0xf9, 0xbe, 0x83, 0x6a, 0xc2, 0x85, 0x09 +}; + +/* SHA-512 test data */ +static const uint8_t sha512in[] =3D { + 0xfd, 0x22, 0x03, 0xe4, 0x67, 0x57, 0x4e, 0x83, + 0x4a, 0xb0, 0x7c, 0x90, 0x97, 0xae, 0x16, 0x45, + 0x32, 0xf2, 0x4b, 0xe1, 0xeb, 0x5d, 0x88, 0xf1, + 0xaf, 0x77, 0x48, 0xce, 0xff, 0x0d, 0x2c, 0x67, + 0xa2, 0x1f, 0x4e, 0x40, 0x97, 0xf9, 0xd3, 0xbb, + 0x4e, 0x9f, 0xbf, 0x97, 0x18, 0x6e, 0x0d, 0xb6, + 0xdb, 0x01, 0x00, 0x23, 0x0a, 0x52, 0xb4, 0x53, + 0xd4, 0x21, 0xf8, 0xab, 0x9c, 0x9a, 0x60, 0x43, + 0xaa, 0x32, 0x95, 0xea, 0x20, 0xd2, 0xf0, 0x6a, + 0x2f, 0x37, 0x47, 0x0d, 0x8a, 0x99, 0x07, 0x5f, + 0x1b, 0x8a, 0x83, 0x36, 0xf6, 0x22, 0x8c, 0xf0, + 0x8b, 0x59, 0x42, 0xfc, 0x1f, 0xb4, 0x29, 0x9c, + 0x7d, 0x24, 0x80, 0xe8, 0xe8, 0x2b, 0xce, 0x17, + 0x55, 0x40, 0xbd, 0xfa, 0xd7, 0x75, 0x2b, 0xc9, + 0x5b, 0x57, 0x7f, 0x22, 0x95, 0x15, 0x39, 0x4f, + 0x3a, 0xe5, 0xce, 0xc8, 0x70, 0xa4, 0xb2, 0xf8 +}; + +/* + * Query test for kimd + * returns > 0 on failure, otherwise 0 + */ +static int test_kimd_query(void) +{ + uint8_t query_block[QUERY_BLOCK_SIZE] =3D {0}; + unsigned long cc =3D 0; + int i, rc =3D 0; + + cpacf_kimd(CPACF_KIMD_QUERY, query_block, NULL, 0, &cc); + + /* compare with expected query block */ + for (i =3D 0; i < QUERY_BLOCK_SIZE; i++) { + if ((query_block[i] & exp_query_block[i]) !=3D exp_query_block[i])= { + rc++; + break; + } + } + + if (rc) { + printf("%s failed\n", __func__); + } + + return rc; +} + +/* + * Subfunction CPACF_KIMD_SHA_256 test for kimd + * returns > 0 on failure, otherwise 0 + */ +static int test_kimd_sha256(void) +{ + uint32_t param[8]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Initialize SHA-256 hash values */ + param[0] =3D 0x6a09e667u; + param[1] =3D 0xbb67ae85u; + param[2] =3D 0x3c6ef372u; + param[3] =3D 0xa54ff53au; + param[4] =3D 0x510e527fu; + param[5] =3D 0x9b05688cu; + param[6] =3D 0x1f83d9abu; + param[7] =3D 0x5be0cd19u; + + /* Process input data */ + cpacf_kimd(CPACF_KIMD_SHA_256, param, sha256in, sizeof(sha256in), &cc); + + /* No check of the result in param block as this is an intermediate va= lue */ + + /* Check for correct condition code (should be 0 on success) */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KIMD_SHA_512 test for kimd + * returns > 0 on failure, otherwise 0 + */ +static int test_kimd_sha512(void) +{ + uint64_t param[8]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Initialize SHA-512 hash values */ + param[0] =3D 0x6a09e667f3bcc908lu; + param[1] =3D 0xbb67ae8584caa73blu; + param[2] =3D 0x3c6ef372fe94f82blu; + param[3] =3D 0xa54ff53a5f1d36f1lu; + param[4] =3D 0x510e527fade682d1lu; + param[5] =3D 0x9b05688c2b3e6c1flu; + param[6] =3D 0x1f83d9abfb41bd6blu; + param[7] =3D 0x5be0cd19137e2179lu; + + /* Process input data */ + cpacf_kimd(CPACF_KIMD_SHA_512, param, sha512in, sizeof(sha512in), &cc); + + /* No check of the result in param block as this is an intermediate va= lue */ + + /* Check for correct condition code (should be 0 on success) */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + return rc; +} + +int main(void) +{ + int rc =3D 0; + + /* Test query function */ + rc +=3D test_kimd_query(); + + /* Test SHA-256 */ + rc +=3D test_kimd_sha256(); + + /* Test SHA-512 */ + rc +=3D test_kimd_sha512(); + + if (rc) { + printf("cpacf-kimd: %d failures\n", rc); + } + + return rc ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/tests/tcg/s390x/cpacf-klmd.c b/tests/tcg/s390x/cpacf-klmd.c new file mode 100644 index 0000000000..1761bb64f9 --- /dev/null +++ b/tests/tcg/s390x/cpacf-klmd.c @@ -0,0 +1,206 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Simple test for CPACF KLMD instruction + */ + +#include +#include +#include +#include +#include "cpacf.h" + +#define QUERY_BLOCK_SIZE 16 + +/* expected klmd query block */ +static uint8_t exp_query_block[QUERY_BLOCK_SIZE] =3D { + 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +/* SHA-256 test data */ +static const uint8_t sha256in[] =3D { + 0x5a, 0x86, 0xb7, 0x37, 0xea, 0xea, 0x8e, 0xe9, + 0x76, 0xa0, 0xa2, 0x4d, 0xa6, 0x3e, 0x7e, 0xd7, + 0xee, 0xfa, 0xd1, 0x8a, 0x10, 0x1c, 0x12, 0x11, + 0xe2, 0xb3, 0x65, 0x0c, 0x51, 0x87, 0xc2, 0xa8, + 0xa6, 0x50, 0x54, 0x72, 0x08, 0x25, 0x1f, 0x6d, + 0x42, 0x37, 0xe6, 0x61, 0xc7, 0xbf, 0x4c, 0x77, + 0xf3, 0x35, 0x39, 0x03, 0x94, 0xc3, 0x7f, 0xa1, + 0xa9, 0xf9, 0xbe, 0x83, 0x6a, 0xc2, 0x85, 0x09 +}; + +static const uint8_t sha256md[] =3D { + 0x42, 0xe6, 0x1e, 0x17, 0x4f, 0xbb, 0x38, 0x97, + 0xd6, 0xdd, 0x6c, 0xef, 0x3d, 0xd2, 0x80, 0x2f, + 0xe6, 0x7b, 0x33, 0x19, 0x53, 0xb0, 0x61, 0x14, + 0xa6, 0x5c, 0x77, 0x28, 0x59, 0xdf, 0xc1, 0xaa +}; + +/* SHA-512 test data */ +static const uint8_t sha512in[] =3D { + 0xfd, 0x22, 0x03, 0xe4, 0x67, 0x57, 0x4e, 0x83, + 0x4a, 0xb0, 0x7c, 0x90, 0x97, 0xae, 0x16, 0x45, + 0x32, 0xf2, 0x4b, 0xe1, 0xeb, 0x5d, 0x88, 0xf1, + 0xaf, 0x77, 0x48, 0xce, 0xff, 0x0d, 0x2c, 0x67, + 0xa2, 0x1f, 0x4e, 0x40, 0x97, 0xf9, 0xd3, 0xbb, + 0x4e, 0x9f, 0xbf, 0x97, 0x18, 0x6e, 0x0d, 0xb6, + 0xdb, 0x01, 0x00, 0x23, 0x0a, 0x52, 0xb4, 0x53, + 0xd4, 0x21, 0xf8, 0xab, 0x9c, 0x9a, 0x60, 0x43, + 0xaa, 0x32, 0x95, 0xea, 0x20, 0xd2, 0xf0, 0x6a, + 0x2f, 0x37, 0x47, 0x0d, 0x8a, 0x99, 0x07, 0x5f, + 0x1b, 0x8a, 0x83, 0x36, 0xf6, 0x22, 0x8c, 0xf0, + 0x8b, 0x59, 0x42, 0xfc, 0x1f, 0xb4, 0x29, 0x9c, + 0x7d, 0x24, 0x80, 0xe8, 0xe8, 0x2b, 0xce, 0x17, + 0x55, 0x40, 0xbd, 0xfa, 0xd7, 0x75, 0x2b, 0xc9, + 0x5b, 0x57, 0x7f, 0x22, 0x95, 0x15, 0x39, 0x4f, + 0x3a, 0xe5, 0xce, 0xc8, 0x70, 0xa4, 0xb2, 0xf8 +}; + +static const uint8_t sha512md[] =3D { + 0xa2, 0x1b, 0x10, 0x77, 0xd5, 0x2b, 0x27, 0xac, + 0x54, 0x5a, 0xf6, 0x3b, 0x32, 0x74, 0x6c, 0x6e, + 0x3c, 0x51, 0xcb, 0x0c, 0xb9, 0xf2, 0x81, 0xeb, + 0x9f, 0x35, 0x80, 0xa6, 0xd4, 0x99, 0x6d, 0x5c, + 0x99, 0x17, 0xd2, 0xa6, 0xe4, 0x84, 0x62, 0x7a, + 0x9d, 0x5a, 0x06, 0xfa, 0x1b, 0x25, 0x32, 0x7a, + 0x9d, 0x71, 0x0e, 0x02, 0x73, 0x87, 0xfc, 0x3e, + 0x07, 0xd7, 0xc4, 0xd1, 0x4c, 0x60, 0x86, 0xcc +}; + +/* + * Query test for klmd + * returns > 0 on failure, otherwise 0 + */ +static int test_klmd_query(void) +{ + uint8_t query_block[QUERY_BLOCK_SIZE] =3D {0}; + unsigned long cc =3D 0; + int i, rc =3D 0; + + cpacf_klmd(CPACF_KLMD_QUERY, query_block, NULL, 0, NULL, 0, &cc); + + /* compare with expected query block */ + for (i =3D 0; i < QUERY_BLOCK_SIZE; i++) { + if ((query_block[i] & exp_query_block[i]) !=3D exp_query_block[i])= { + rc++; + break; + } + } + + if (rc) { + printf("%s failed\n", __func__); + } + + return rc; +} + +/* + * Subfunction CPACF_KLMD_SHA_256 test for klmd + * returns > 0 on failure, otherwise 0 + */ +static int test_klmd_sha256(void) +{ + uint8_t param[40]; /* 32 bytes hash + 8 bytes message bit length */ + uint32_t *hash =3D (uint32_t *)param; + uint64_t *mbl =3D (uint64_t *)(param + 32); + unsigned long cc =3D 0; + int rc =3D 0; + + /* Initialize SHA-256 hash values (H0-H7) */ + hash[0] =3D 0x6a09e667u; + hash[1] =3D 0xbb67ae85u; + hash[2] =3D 0x3c6ef372u; + hash[3] =3D 0xa54ff53au; + hash[4] =3D 0x510e527fu; + hash[5] =3D 0x9b05688cu; + hash[6] =3D 0x1f83d9abu; + hash[7] =3D 0x5be0cd19u; + + /* Set message bit length for KLMD */ + *mbl =3D sizeof(sha256in) * 8; + + /* Process input data with KLMD (finalize hash) */ + cpacf_klmd(CPACF_KLMD_SHA_256, param, sha256in, + sizeof(sha256in), NULL, 0, &cc); + + /* Check for correct condition code (should be 0 on success) */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare hash result in param with expected message digest */ + if (memcmp(param, sha256md, sizeof(sha256md))) { + printf("%s failed: hash mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KLMD_SHA_512 test for klmd + * returns > 0 on failure, otherwise 0 + */ +static int test_klmd_sha512(void) +{ + uint8_t param[80]; /* 64 bytes hash + 16 bytes message bit length */ + uint64_t *hash =3D (uint64_t *)param; + uint64_t *mbl_high =3D (uint64_t *)(param + 64); + uint64_t *mbl_low =3D (uint64_t *)(param + 72); + unsigned long cc =3D 0; + int rc =3D 0; + + /* Initialize SHA-512 hash values (H0-H7) */ + hash[0] =3D 0x6a09e667f3bcc908lu; + hash[1] =3D 0xbb67ae8584caa73blu; + hash[2] =3D 0x3c6ef372fe94f82blu; + hash[3] =3D 0xa54ff53a5f1d36f1lu; + hash[4] =3D 0x510e527fade682d1lu; + hash[5] =3D 0x9b05688c2b3e6c1flu; + hash[6] =3D 0x1f83d9abfb41bd6blu; + hash[7] =3D 0x5be0cd19137e2179lu; + + /* Set message bit length for KLMD (128-bit, high and low) */ + *mbl_high =3D 0; + *mbl_low =3D sizeof(sha512in) * 8; + + /* Process input data with KLMD (finalize hash) */ + cpacf_klmd(CPACF_KLMD_SHA_512, param, sha512in, + sizeof(sha512in), NULL, 0, &cc); + + /* Check for correct condition code (should be 0 on success) */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare hash result in param with expected message digest */ + if (memcmp(param, sha512md, sizeof(sha512md))) { + printf("%s failed: hash mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +int main(void) +{ + int rc =3D 0; + + /* Test query function */ + rc +=3D test_klmd_query(); + + /* Test SHA-256 */ + rc +=3D test_klmd_sha256(); + + /* Test SHA-512 */ + rc +=3D test_klmd_sha512(); + + if (rc) { + printf("cpacf-klmd: %d failures\n", rc); + } + + return rc ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/tests/tcg/s390x/cpacf-km.c b/tests/tcg/s390x/cpacf-km.c new file mode 100644 index 0000000000..35a5ecbfef --- /dev/null +++ b/tests/tcg/s390x/cpacf-km.c @@ -0,0 +1,590 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Simple test for CPACF KM instruction + */ + +#include +#include +#include +#include +#include "cpacf.h" + +#define QUERY_BLOCK_SIZE 16 + +/* expected km query block */ +static uint8_t exp_query_block[QUERY_BLOCK_SIZE] =3D { + 0x80, 0x00, 0x38, 0x38, 0x00, 0x00, 0x28, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +/* KM AES-128 test data */ +static const uint8_t kmaes128key[] =3D { + 0xed, 0xfd, 0xb2, 0x57, 0xcb, 0x37, 0xcd, 0xf1, + 0x82, 0xc5, 0x45, 0x5b, 0x0c, 0x0e, 0xfe, 0xbb +}; +static const uint8_t kmaes128plain[] =3D { + 0x16, 0x95, 0xfe, 0x47, 0x54, 0x21, 0xca, 0xce, + 0x35, 0x57, 0xda, 0xca, 0x01, 0xf4, 0x45, 0xff +}; +static const uint8_t kmaes128cipher[] =3D { + 0x78, 0x88, 0xbe, 0xae, 0x6e, 0x7a, 0x42, 0x63, + 0x32, 0xa7, 0xea, 0xa2, 0xf8, 0x08, 0xe6, 0x37 +}; + +/* KM AES-192 test data */ +static const uint8_t kmaes192key[] =3D { + 0x61, 0x39, 0x6c, 0x53, 0x0c, 0xc1, 0x74, 0x9a, + 0x5b, 0xab, 0x6f, 0xbc, 0xf9, 0x06, 0xfe, 0x67, + 0x2d, 0x0c, 0x4a, 0xb2, 0x01, 0xaf, 0x45, 0x54 +}; +static const uint8_t kmaes192plain[] =3D { + 0x60, 0xbc, 0xdb, 0x94, 0x16, 0xba, 0xc0, 0x8d, + 0x7f, 0xd0, 0xd7, 0x80, 0x35, 0x37, 0x40, 0xa5 +}; +static const uint8_t kmaes192cipher[] =3D { + 0x24, 0xf4, 0x0c, 0x4e, 0xec, 0xd9, 0xc4, 0x98, + 0x25, 0x00, 0x0f, 0xcb, 0x49, 0x72, 0x64, 0x7a +}; + +/* KM AES-256 test data */ +static const uint8_t kmaes256key[] =3D { + 0xcc, 0x22, 0xda, 0x78, 0x7f, 0x37, 0x57, 0x11, + 0xc7, 0x63, 0x02, 0xbe, 0xf0, 0x97, 0x9d, 0x8e, + 0xdd, 0xf8, 0x42, 0x82, 0x9c, 0x2b, 0x99, 0xef, + 0x3d, 0xd0, 0x4e, 0x23, 0xe5, 0x4c, 0xc2, 0x4b +}; +static const uint8_t kmaes256plain[] =3D { + 0xcc, 0xc6, 0x2c, 0x6b, 0x0a, 0x09, 0xa6, 0x71, + 0xd6, 0x44, 0x56, 0x81, 0x8d, 0xb2, 0x9a, 0x4d +}; +static const uint8_t kmaes256cipher[] =3D { + 0xdf, 0x86, 0x34, 0xca, 0x02, 0xb1, 0x3a, 0x12, + 0x5b, 0x78, 0x6e, 0x1d, 0xce, 0x90, 0x65, 0x8b +}; + +/* KM AES XTS-128 test data */ +static const uint8_t kmaesxts128key1[] =3D { + 0xa1, 0xb9, 0x0c, 0xba, 0x3f, 0x06, 0xac, 0x35, + 0x3b, 0x2c, 0x34, 0x38, 0x76, 0x08, 0x17, 0x62 +}; +static const uint8_t kmaesxts128key2[] =3D { + 0x09, 0x09, 0x23, 0x02, 0x6e, 0x91, 0x77, 0x18, + 0x15, 0xf2, 0x9d, 0xab, 0x01, 0x93, 0x2f, 0x2f +}; +static const uint8_t kmaesxts128sect[] =3D { + 0x4f, 0xae, 0xf7, 0x11, 0x7c, 0xda, 0x59, 0xc6, + 0x6e, 0x4b, 0x92, 0x01, 0x3e, 0x76, 0x8a, 0xd5 +}; +static const uint8_t kmaesxts128plain[] =3D { + 0xeb, 0xab, 0xce, 0x95, 0xb1, 0x4d, 0x3c, 0x8d, + 0x6f, 0xb3, 0x50, 0x39, 0x07, 0x90, 0x31, 0x1c +}; +static const uint8_t kmaesxts128cipher[] =3D { + 0x77, 0x8a, 0xe8, 0xb4, 0x3c, 0xb9, 0x8d, 0x5a, + 0x82, 0x50, 0x81, 0xd5, 0xbe, 0x47, 0x1c, 0x63 +}; + +/* KM AES XTS-256 test data */ +static const uint8_t kmaesxts256key1[] =3D { + 0x1e, 0xa6, 0x61, 0xc5, 0x8d, 0x94, 0x3a, 0x0e, + 0x48, 0x01, 0xe4, 0x2f, 0x4b, 0x09, 0x47, 0x14, + 0x9e, 0x7f, 0x9f, 0x8e, 0x3e, 0x68, 0xd0, 0xc7, + 0x50, 0x52, 0x10, 0xbd, 0x31, 0x1a, 0x0e, 0x7c +}; +static const uint8_t kmaesxts256key2[] =3D { + 0xd6, 0xe1, 0x3f, 0xfd, 0xf2, 0x41, 0x8d, 0x8d, + 0x19, 0x11, 0xc0, 0x04, 0xcd, 0xa5, 0x8d, 0xa3, + 0xd6, 0x19, 0xb7, 0xe2, 0xb9, 0x14, 0x1e, 0x58, + 0x31, 0x8e, 0xea, 0x39, 0x2c, 0xf4, 0x1b, 0x08 +}; +static const uint8_t kmaesxts256sect[] =3D { + 0xad, 0xf8, 0xd9, 0x26, 0x27, 0x46, 0x4a, 0xd2, + 0xf0, 0x42, 0x8e, 0x84, 0xa9, 0xf8, 0x75, 0x64 +}; +static const uint8_t kmaesxts256plain[] =3D { + 0x2e, 0xed, 0xea, 0x52, 0xcd, 0x82, 0x15, 0xe1, + 0xac, 0xc6, 0x47, 0xe8, 0x10, 0xbb, 0xc3, 0x64, + 0x2e, 0x87, 0x28, 0x7f, 0x8d, 0x2e, 0x57, 0xe3, + 0x6c, 0x0a, 0x24, 0xfb, 0xc1, 0x2a, 0x20, 0x2e +}; +static const uint8_t kmaesxts256cipher[] =3D { + 0xcb, 0xaa, 0xd0, 0xe2, 0xf6, 0xce, 0xa3, 0xf5, + 0x0b, 0x37, 0xf9, 0x34, 0xd4, 0x6a, 0x9b, 0x13, + 0x0b, 0x9d, 0x54, 0xf0, 0x7e, 0x34, 0xf3, 0x6a, + 0xf7, 0x93, 0xe8, 0x6f, 0x73, 0xc6, 0xd7, 0xdb +}; + +/* static byte array containing the WKVP */ +static const uint8_t protkey_wkvp[32] =3D PROTKEY_WKVP; + +/* + * Query test for km + * returns > 0 on failure, otherwise 0 + */ +static int test_km_query(void) +{ + uint8_t query_block[QUERY_BLOCK_SIZE] =3D {0}; + unsigned long cc =3D 0; + int i, rc =3D 0; + + cpacf_km(CPACF_KM_QUERY, query_block, NULL, NULL, 0, &cc); + + /* compare with expected query block */ + for (i =3D 0; i < QUERY_BLOCK_SIZE; i++) { + if ((query_block[i] & exp_query_block[i]) !=3D exp_query_block[i])= { + rc++; + break; + } + } + + if (rc) { + printf("%s failed\n", __func__); + } + + return rc; +} + +/* + * Subfunction CPACF_KM_AES_128 test for km + * returns > 0 on failure, otherwise 0 + */ +static int test_km_aes_128(void) +{ + uint8_t param[16]; /* key only, no IV for ECB mode */ + uint8_t output[16]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: key only */ + memcpy(param, kmaes128key, sizeof(kmaes128key)); + + /* Encrypt */ + cpacf_km(CPACF_KM_AES_128, param, output, kmaes128plain, + sizeof(kmaes128plain), &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmaes128cipher, sizeof(kmaes128cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KM_AES_192 test for km + * returns > 0 on failure, otherwise 0 + */ +static int test_km_aes_192(void) +{ + uint8_t param[24]; /* key only, no IV for ECB mode */ + uint8_t output[16]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: key only */ + memcpy(param, kmaes192key, sizeof(kmaes192key)); + + /* Encrypt */ + cpacf_km(CPACF_KM_AES_192, param, output, kmaes192plain, + sizeof(kmaes192plain), &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmaes192cipher, sizeof(kmaes192cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KM_AES_256 test for km + * returns > 0 on failure, otherwise 0 + */ +static int test_km_aes_256(void) +{ + uint8_t param[32]; /* key only, no IV for ECB mode */ + uint8_t output[16]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: key only */ + memcpy(param, kmaes256key, sizeof(kmaes256key)); + + /* Encrypt */ + cpacf_km(CPACF_KM_AES_256, param, output, kmaes256plain, + sizeof(kmaes256plain), &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmaes256cipher, sizeof(kmaes256cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KM_PAES_128 test for km + * returns > 0 on failure, otherwise 0 + */ +static int test_km_paes_128(void) +{ + uint8_t param[16 + 32]; /* protected key + wkvp */ + uint8_t output[16]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: protected key + wkvp */ + memcpy(param, kmaes128key, sizeof(kmaes128key)); + encrypt_clrkey(param, sizeof(kmaes128key)); + memcpy(param + sizeof(kmaes128key), protkey_wkvp, sizeof(protkey_wkvp)= ); + + /* Encrypt */ + cpacf_km(CPACF_KM_PAES_128, param, output, kmaes128plain, + sizeof(kmaes128plain), &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmaes128cipher, sizeof(kmaes128cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KM_PAES_192 test for km + * returns > 0 on failure, otherwise 0 + */ +static int test_km_paes_192(void) +{ + uint8_t param[24 + 32]; /* protected key + wkvp */ + uint8_t output[16]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: protected key + wkvp */ + memcpy(param, kmaes192key, sizeof(kmaes192key)); + encrypt_clrkey(param, sizeof(kmaes192key)); + memcpy(param + sizeof(kmaes192key), protkey_wkvp, sizeof(protkey_wkvp)= ); + + /* Encrypt */ + cpacf_km(CPACF_KM_PAES_192, param, output, kmaes192plain, + sizeof(kmaes192plain), &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmaes192cipher, sizeof(kmaes192cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KM_PAES_256 test for km + * returns > 0 on failure, otherwise 0 + */ +static int test_km_paes_256(void) +{ + uint8_t param[32 + 32]; /* protected key + wkvp */ + uint8_t output[16]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: protected key + wkvp */ + memcpy(param, kmaes256key, sizeof(kmaes256key)); + encrypt_clrkey(param, sizeof(kmaes256key)); + memcpy(param + sizeof(kmaes256key), protkey_wkvp, sizeof(protkey_wkvp)= ); + + /* Encrypt */ + cpacf_km(CPACF_KM_PAES_256, param, output, kmaes256plain, + sizeof(kmaes256plain), &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmaes256cipher, sizeof(kmaes256cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KM_XTS_128 test for km + * returns > 0 on failure, otherwise 0 + */ +static int test_km_xts_128(void) +{ + uint8_t param[16 + 16]; /* key + initial XTS value */ + uint8_t output[16]; + uint8_t init_xts[16]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* First compute initial XTS value using key2 and sector */ + memcpy(param, kmaesxts128key2, sizeof(kmaesxts128key2)); + cpacf_km(CPACF_KM_AES_128, param, init_xts, kmaesxts128sect, + sizeof(kmaesxts128sect), &cc); + + if (cc !=3D 0) { + printf("%s failed: initial XTS computation cc=3D%lu\n", __func__, = cc); + return 1; + } + + /* Setup parameter block: key1 + initial XTS value */ + memcpy(param, kmaesxts128key1, sizeof(kmaesxts128key1)); + memcpy(param + 16, init_xts, sizeof(init_xts)); + + /* Encrypt */ + cpacf_km(CPACF_KM_XTS_128, param, output, kmaesxts128plain, + sizeof(kmaesxts128plain), &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmaesxts128cipher, sizeof(kmaesxts128cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KM_XTS_256 test for km + * returns > 0 on failure, otherwise 0 + */ +static int test_km_xts_256(void) +{ + uint8_t param[32 + 16]; /* key + initial XTS value */ + uint8_t output[32]; + uint8_t init_xts[16]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* First compute initial XTS value using key2 and sector */ + memcpy(param, kmaesxts256key2, sizeof(kmaesxts256key2)); + cpacf_km(CPACF_KM_AES_256, param, init_xts, kmaesxts256sect, + sizeof(kmaesxts256sect), &cc); + + if (cc !=3D 0) { + printf("%s failed: initial XTS computation cc=3D%lu\n", __func__, = cc); + return 1; + } + + /* Setup parameter block: key1 + initial XTS value */ + memcpy(param, kmaesxts256key1, sizeof(kmaesxts256key1)); + memcpy(param + 32, init_xts, sizeof(init_xts)); + + /* Encrypt */ + cpacf_km(CPACF_KM_XTS_256, param, output, kmaesxts256plain, + sizeof(kmaesxts256plain), &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmaesxts256cipher, sizeof(kmaesxts256cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KM_PXTS_128 test for km + * returns > 0 on failure, otherwise 0 + */ +static int test_km_pxts_128(void) +{ + uint8_t param[16 + 32 + 16]; /* protected key + wkvp + initial XTS val= ue */ + uint8_t output[16]; + uint8_t init_xts[16]; + uint8_t key2_param[16 + 32]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* First compute initial XTS value using protected key2 and sector */ + memcpy(key2_param, kmaesxts128key2, sizeof(kmaesxts128key2)); + encrypt_clrkey(key2_param, sizeof(kmaesxts128key2)); + memcpy(key2_param + sizeof(kmaesxts128key2), + protkey_wkvp, sizeof(protkey_wkvp)); + + cpacf_km(CPACF_KM_PAES_128, key2_param, init_xts, kmaesxts128sect, + sizeof(kmaesxts128sect), &cc); + + if (cc !=3D 0) { + printf("%s failed: initial XTS computation cc=3D%lu\n", __func__, = cc); + return 1; + } + + /* Setup parameter block: protected key1 + wkvp + initial XTS value */ + memcpy(param, kmaesxts128key1, sizeof(kmaesxts128key1)); + encrypt_clrkey(param, sizeof(kmaesxts128key1)); + memcpy(param + sizeof(kmaesxts128key1), protkey_wkvp, sizeof(protkey_w= kvp)); + memcpy(param + sizeof(kmaesxts128key1) + sizeof(protkey_wkvp), + init_xts, sizeof(init_xts)); + + /* Encrypt */ + cpacf_km(CPACF_KM_PXTS_128, param, output, kmaesxts128plain, + sizeof(kmaesxts128plain), &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmaesxts128cipher, sizeof(kmaesxts128cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KM_PXTS_256 test for km + * returns > 0 on failure, otherwise 0 + */ +static int test_km_pxts_256(void) +{ + uint8_t param[32 + 32 + 16]; /* protected key + wkvp + initial XTS val= ue */ + uint8_t output[32]; + uint8_t init_xts[16]; + uint8_t key2_param[32 + 32]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* First compute initial XTS value using protected key2 and sector */ + memcpy(key2_param, kmaesxts256key2, sizeof(kmaesxts256key2)); + encrypt_clrkey(key2_param, sizeof(kmaesxts256key2)); + memcpy(key2_param + sizeof(kmaesxts256key2), + protkey_wkvp, sizeof(protkey_wkvp)); + + cpacf_km(CPACF_KM_PAES_256, key2_param, init_xts, kmaesxts256sect, + sizeof(kmaesxts256sect), &cc); + + if (cc !=3D 0) { + printf("%s failed: initial XTS computation cc=3D%lu\n", __func__, = cc); + return 1; + } + + /* Setup parameter block: protected key1 + wkvp + initial XTS value */ + memcpy(param, kmaesxts256key1, sizeof(kmaesxts256key1)); + encrypt_clrkey(param, sizeof(kmaesxts256key1)); + memcpy(param + sizeof(kmaesxts256key1), protkey_wkvp, sizeof(protkey_w= kvp)); + memcpy(param + sizeof(kmaesxts256key1) + sizeof(protkey_wkvp), + init_xts, sizeof(init_xts)); + + /* Encrypt */ + cpacf_km(CPACF_KM_PXTS_256, param, output, kmaesxts256plain, + sizeof(kmaesxts256plain), &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmaesxts256cipher, sizeof(kmaesxts256cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +int main(void) +{ + int rc =3D 0; + + /* Test query function */ + rc +=3D test_km_query(); + + /* Test AES-128 */ + rc +=3D test_km_aes_128(); + + /* Test AES-192 */ + rc +=3D test_km_aes_192(); + + /* Test AES-256 */ + rc +=3D test_km_aes_256(); + + /* Test PAES-128 */ + rc +=3D test_km_paes_128(); + + /* Test PAES-192 */ + rc +=3D test_km_paes_192(); + + /* Test PAES-256 */ + rc +=3D test_km_paes_256(); + + /* Test XTS-128 */ + rc +=3D test_km_xts_128(); + + /* Test XTS-256 */ + rc +=3D test_km_xts_256(); + + /* Test PXTS-128 */ + rc +=3D test_km_pxts_128(); + + /* Test PXTS-256 */ + rc +=3D test_km_pxts_256(); + + if (rc) { + printf("cpacf-km: %d failures\n", rc); + } + + return rc ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/tests/tcg/s390x/cpacf-kmac.c b/tests/tcg/s390x/cpacf-kmac.c new file mode 100644 index 0000000000..c9ef847110 --- /dev/null +++ b/tests/tcg/s390x/cpacf-kmac.c @@ -0,0 +1,58 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Simple test for the CPACF KMAC instruction + */ + +#include +#include +#include +#include +#include "cpacf.h" + +#define QUERY_BLOCK_SIZE 16 + +/* expected kmac query block */ +static uint8_t exp_query_block[QUERY_BLOCK_SIZE] =3D { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static int test_kmac_query(void) +{ + uint8_t query_block[QUERY_BLOCK_SIZE] =3D {0}; + unsigned long cc =3D 0; + int i, rc =3D 0; + + cpacf_kmac(CPACF_KMAC_QUERY, query_block, NULL, 0, &cc); + + /* compare with expected query block */ + for (i =3D 0; i < QUERY_BLOCK_SIZE; i++) { + if ((query_block[i] & exp_query_block[i]) !=3D exp_query_block[i])= { + rc++; + break; + } + } + + if (rc) { + printf("%s failed\n", __func__); + } + + return rc; +} + +int main(void) +{ + int rc; + + /* Test query function */ + rc =3D test_kmac_query(); + + /* As of now only KMAC query is implemented */ + + if (rc) { + printf("cpacf-kmac: %d failures\n", rc); + } + + return rc ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/tests/tcg/s390x/cpacf-kmc.c b/tests/tcg/s390x/cpacf-kmc.c new file mode 100644 index 0000000000..671a8f3171 --- /dev/null +++ b/tests/tcg/s390x/cpacf-kmc.c @@ -0,0 +1,351 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Simple test for CPACF KMC instruction + */ + +#include +#include +#include +#include +#include "cpacf.h" + +#define QUERY_BLOCK_SIZE 16 + +/* expected kmc query block */ +static uint8_t exp_query_block[QUERY_BLOCK_SIZE] =3D { + 0x80, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +/* KMC AES-128 test data */ +static const uint8_t kmcaes128key[] =3D { + 0x1f, 0x8e, 0x49, 0x73, 0x95, 0x3f, 0x3f, 0xb0, + 0xbd, 0x6b, 0x16, 0x66, 0x2e, 0x9a, 0x3c, 0x17 +}; +static const uint8_t kmcaes128iv[] =3D { + 0x2f, 0xe2, 0xb3, 0x33, 0xce, 0xda, 0x8f, 0x98, + 0xf4, 0xa9, 0x9b, 0x40, 0xd2, 0xcd, 0x34, 0xa8 +}; +static const uint8_t kmcaes128plain[] =3D { + 0x45, 0xcf, 0x12, 0x96, 0x4f, 0xc8, 0x24, 0xab, + 0x76, 0x61, 0x6a, 0xe2, 0xf4, 0xbf, 0x08, 0x22 +}; +static const uint8_t kmcaes128cipher[] =3D { + 0x0f, 0x61, 0xc4, 0xd4, 0x4c, 0x51, 0x47, 0xc0, + 0x3c, 0x19, 0x5a, 0xd7, 0xe2, 0xcc, 0x12, 0xb2 +}; + +/* KMC AES-192 test data */ +static const uint8_t kmcaes192key[] =3D { + 0xba, 0x75, 0xf4, 0xd1, 0xd9, 0xd7, 0xcf, 0x7f, + 0x55, 0x14, 0x45, 0xd5, 0x6c, 0xc1, 0xa8, 0xab, + 0x2a, 0x07, 0x8e, 0x15, 0xe0, 0x49, 0xdc, 0x2c +}; +static const uint8_t kmcaes192iv[] =3D { + 0x53, 0x1c, 0xe7, 0x81, 0x76, 0x40, 0x16, 0x66, + 0xaa, 0x30, 0xdb, 0x94, 0xec, 0x4a, 0x30, 0xeb +}; +static const uint8_t kmcaes192plain[] =3D { + 0xc5, 0x1f, 0xc2, 0x76, 0x77, 0x4d, 0xad, 0x94, + 0xbc, 0xdc, 0x1d, 0x28, 0x91, 0xec, 0x86, 0x68 +}; +static const uint8_t kmcaes192cipher[] =3D { + 0x70, 0xdd, 0x95, 0xa1, 0x4e, 0xe9, 0x75, 0xe2, + 0x39, 0xdf, 0x36, 0xff, 0x4a, 0xee, 0x1d, 0x5d +}; + +/* KMC AES-256 test data */ +static const uint8_t kmcaes256key[] =3D { + 0x6e, 0xd7, 0x6d, 0x2d, 0x97, 0xc6, 0x9f, 0xd1, + 0x33, 0x95, 0x89, 0x52, 0x39, 0x31, 0xf2, 0xa6, + 0xcf, 0xf5, 0x54, 0xb1, 0x5f, 0x73, 0x8f, 0x21, + 0xec, 0x72, 0xdd, 0x97, 0xa7, 0x33, 0x09, 0x07 +}; +static const uint8_t kmcaes256iv[] =3D { + 0x85, 0x1e, 0x87, 0x64, 0x77, 0x6e, 0x67, 0x96, + 0xaa, 0xb7, 0x22, 0xdb, 0xb6, 0x44, 0xac, 0xe8 +}; +static const uint8_t kmcaes256plain[] =3D { + 0x62, 0x82, 0xb8, 0xc0, 0x5c, 0x5c, 0x15, 0x30, + 0xb9, 0x7d, 0x48, 0x16, 0xca, 0x43, 0x47, 0x62 +}; +static const uint8_t kmcaes256cipher[] =3D { + 0x6a, 0xcc, 0x04, 0x14, 0x2e, 0x10, 0x0a, 0x65, + 0xf5, 0x1b, 0x97, 0xad, 0xf5, 0x17, 0x2c, 0x41 +}; + +/* static byte array containing the WKVP */ +static const uint8_t protkey_wkvp[32] =3D PROTKEY_WKVP; + +/* + * Query test for kmc + * returns > 0 on failure, otherwise 0 + */ +static int test_kmc_query(void) +{ + uint8_t query_block[QUERY_BLOCK_SIZE] =3D {0}; + unsigned long cc =3D 0; + int i, rc =3D 0; + + cpacf_kmc(CPACF_KMC_QUERY, query_block, NULL, NULL, 0, &cc); + + /* compare with expected query block */ + for (i =3D 0; i < QUERY_BLOCK_SIZE; i++) { + if ((query_block[i] & exp_query_block[i]) !=3D exp_query_block[i])= { + rc++; + break; + } + } + + if (rc) { + printf("%s failed\n", __func__); + } + + return rc; +} + +/* + * Subfunction CPACF_KMC_AES_128 test for kmc + * returns > 0 on failure, otherwise 0 + */ +static int test_kmc_aes_128(void) +{ + uint8_t param[16 + 16]; /* IV + key */ + uint8_t output[16]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: IV followed by key */ + memcpy(param, kmcaes128iv, sizeof(kmcaes128iv)); + memcpy(param + sizeof(kmcaes128iv), kmcaes128key, sizeof(kmcaes128key)= ); + + /* Encrypt */ + cpacf_kmc(CPACF_KMC_AES_128, param, output, kmcaes128plain, + sizeof(kmcaes128plain), &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmcaes128cipher, sizeof(kmcaes128cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KMC_AES_192 test for kmc + * returns > 0 on failure, otherwise 0 + */ +static int test_kmc_aes_192(void) +{ + uint8_t param[16 + 24]; /* IV + key */ + uint8_t output[16]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: IV followed by key */ + memcpy(param, kmcaes192iv, sizeof(kmcaes192iv)); + memcpy(param + sizeof(kmcaes192iv), kmcaes192key, sizeof(kmcaes192key)= ); + + /* Encrypt */ + cpacf_kmc(CPACF_KMC_AES_192, param, output, kmcaes192plain, + sizeof(kmcaes192plain), &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmcaes192cipher, sizeof(kmcaes192cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KMC_AES_256 test for kmc + * returns > 0 on failure, otherwise 0 + */ +static int test_kmc_aes_256(void) +{ + uint8_t param[16 + 32]; /* IV + key */ + uint8_t output[16]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: IV followed by key */ + memcpy(param, kmcaes256iv, sizeof(kmcaes256iv)); + memcpy(param + sizeof(kmcaes256iv), kmcaes256key, sizeof(kmcaes256key)= ); + + /* Encrypt */ + cpacf_kmc(CPACF_KMC_AES_256, param, output, kmcaes256plain, + sizeof(kmcaes256plain), &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmcaes256cipher, sizeof(kmcaes256cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KMC_PAES_128 test for kmc + * returns > 0 on failure, otherwise 0 + */ +static int test_kmc_paes_128(void) +{ + uint8_t param[16 + 16 + 32]; /* IV + protected key + wkvp */ + uint8_t output[16]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: IV + protected key + wkvp */ + memcpy(param, kmcaes128iv, sizeof(kmcaes128iv)); + memcpy(param + sizeof(kmcaes128iv), kmcaes128key, sizeof(kmcaes128key)= ); + encrypt_clrkey(param + sizeof(kmcaes128iv), sizeof(kmcaes128key)); + memcpy(param + sizeof(kmcaes128iv) + sizeof(kmcaes128key), + protkey_wkvp, sizeof(protkey_wkvp)); + + /* Encrypt */ + cpacf_kmc(CPACF_KMC_PAES_128, param, output, kmcaes128plain, + sizeof(kmcaes128plain), &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmcaes128cipher, sizeof(kmcaes128cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KMC_PAES_192 test for kmc + * returns > 0 on failure, otherwise 0 + */ +static int test_kmc_paes_192(void) +{ + uint8_t param[16 + 24 + 32]; /* IV + protected key + wkvp */ + uint8_t output[16]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: IV + protected key + wkvp */ + memcpy(param, kmcaes192iv, sizeof(kmcaes192iv)); + memcpy(param + sizeof(kmcaes192iv), kmcaes192key, sizeof(kmcaes192key)= ); + encrypt_clrkey(param + sizeof(kmcaes192iv), sizeof(kmcaes192key)); + memcpy(param + sizeof(kmcaes192iv) + sizeof(kmcaes192key), + protkey_wkvp, sizeof(protkey_wkvp)); + + /* Encrypt */ + cpacf_kmc(CPACF_KMC_PAES_192, param, output, kmcaes192plain, + sizeof(kmcaes192plain), &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmcaes192cipher, sizeof(kmcaes192cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KMC_PAES_256 test for kmc + * returns > 0 on failure, otherwise 0 + */ +static int test_kmc_paes_256(void) +{ + uint8_t param[16 + 32 + 32]; /* IV + protected key + wkvp */ + uint8_t output[16]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: IV + protected key + wkvp */ + memcpy(param, kmcaes256iv, sizeof(kmcaes256iv)); + memcpy(param + sizeof(kmcaes256iv), kmcaes256key, sizeof(kmcaes256key)= ); + encrypt_clrkey(param + sizeof(kmcaes256iv), sizeof(kmcaes256key)); + memcpy(param + sizeof(kmcaes256iv) + sizeof(kmcaes256key), + protkey_wkvp, sizeof(protkey_wkvp)); + + /* Encrypt */ + cpacf_kmc(CPACF_KMC_PAES_256, param, output, kmcaes256plain, + sizeof(kmcaes256plain), &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmcaes256cipher, sizeof(kmcaes256cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +int main(void) +{ + int rc =3D 0; + + /* Test query function */ + rc +=3D test_kmc_query(); + + /* Test AES-128 */ + rc +=3D test_kmc_aes_128(); + + /* Test AES-192 */ + rc +=3D test_kmc_aes_192(); + + /* Test AES-256 */ + rc +=3D test_kmc_aes_256(); + + /* Test PAES-128 */ + rc +=3D test_kmc_paes_128(); + + /* Test PAES-192 */ + rc +=3D test_kmc_paes_192(); + + /* Test PAES-256 */ + rc +=3D test_kmc_paes_256(); + + if (rc) { + printf("cpacf-kmc: %d failures\n", rc); + } + + return rc ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/tests/tcg/s390x/cpacf-kmctr.c b/tests/tcg/s390x/cpacf-kmctr.c new file mode 100644 index 0000000000..515f94038b --- /dev/null +++ b/tests/tcg/s390x/cpacf-kmctr.c @@ -0,0 +1,360 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Simple test for CPACF KMCTR instruction + */ + +#include +#include +#include +#include +#include "cpacf.h" + +#define QUERY_BLOCK_SIZE 16 + +/* expected kmctr query block */ +static uint8_t exp_query_block[QUERY_BLOCK_SIZE] =3D { + 0x80, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +/* KMCTR AES-128 test data */ +static const uint8_t kmctraes128key[] =3D { + 0xed, 0xfd, 0xb2, 0x57, 0xcb, 0x37, 0xcd, 0xf1, + 0x82, 0xc5, 0x45, 0x5b, 0x0c, 0x0e, 0xfe, 0xbb +}; +static const uint8_t kmctraes128plain[] =3D { + 0x16, 0x95, 0xfe, 0x47, 0x54, 0x21, 0xca, 0xce, + 0x35, 0x57, 0xda, 0xca, 0x01, 0xf4, 0x45, 0xff +}; +static const uint8_t kmctraes128cipher[] =3D { + 0x78, 0x88, 0xbe, 0xae, 0x6e, 0x7a, 0x42, 0x63, + 0x32, 0xa7, 0xea, 0xa2, 0xf8, 0x08, 0xe6, 0x37 +}; + +/* KMCTR AES-192 test data */ +static const uint8_t kmctraes192key[] =3D { + 0x61, 0x39, 0x6c, 0x53, 0x0c, 0xc1, 0x74, 0x9a, + 0x5b, 0xab, 0x6f, 0xbc, 0xf9, 0x06, 0xfe, 0x67, + 0x2d, 0x0c, 0x4a, 0xb2, 0x01, 0xaf, 0x45, 0x54 +}; +static const uint8_t kmctraes192plain[] =3D { + 0x60, 0xbc, 0xdb, 0x94, 0x16, 0xba, 0xc0, 0x8d, + 0x7f, 0xd0, 0xd7, 0x80, 0x35, 0x37, 0x40, 0xa5 +}; +static const uint8_t kmctraes192cipher[] =3D { + 0x24, 0xf4, 0x0c, 0x4e, 0xec, 0xd9, 0xc4, 0x98, + 0x25, 0x00, 0x0f, 0xcb, 0x49, 0x72, 0x64, 0x7a +}; + +/* KMCTR AES-256 test data */ +static const uint8_t kmctraes256key[] =3D { + 0xcc, 0x22, 0xda, 0x78, 0x7f, 0x37, 0x57, 0x11, + 0xc7, 0x63, 0x02, 0xbe, 0xf0, 0x97, 0x9d, 0x8e, + 0xdd, 0xf8, 0x42, 0x82, 0x9c, 0x2b, 0x99, 0xef, + 0x3d, 0xd0, 0x4e, 0x23, 0xe5, 0x4c, 0xc2, 0x4b +}; +static const uint8_t kmctraes256plain[] =3D { + 0xcc, 0xc6, 0x2c, 0x6b, 0x0a, 0x09, 0xa6, 0x71, + 0xd6, 0x44, 0x56, 0x81, 0x8d, 0xb2, 0x9a, 0x4d +}; +static const uint8_t kmctraes256cipher[] =3D { + 0xdf, 0x86, 0x34, 0xca, 0x02, 0xb1, 0x3a, 0x12, + 0x5b, 0x78, 0x6e, 0x1d, 0xce, 0x90, 0x65, 0x8b +}; + +/* static byte array containing the WKVP */ +static const uint8_t protkey_wkvp[32] =3D PROTKEY_WKVP; + +/* + * Query test for kmctr + * returns > 0 on failure, otherwise 0 + */ +static int test_kmctr_query(void) +{ + uint8_t query_block[QUERY_BLOCK_SIZE] =3D {0}; + unsigned long cc =3D 0; + int i, rc =3D 0; + + cpacf_kmctr(CPACF_KMCTR_QUERY, query_block, NULL, NULL, 0, NULL, &cc); + + /* compare with expected query block */ + for (i =3D 0; i < QUERY_BLOCK_SIZE; i++) { + if ((query_block[i] & exp_query_block[i]) !=3D exp_query_block[i])= { + rc++; + break; + } + } + + if (rc) { + printf("%s failed\n", __func__); + } + + return rc; +} + +/* + * Subfunction CPACF_KMCTR_AES_128 test for kmctr + * returns > 0 on failure, otherwise 0 + */ +static int test_kmctr_aes_128(void) +{ + uint8_t param[16]; /* Parameter block: AES-128 key */ + uint8_t src[16] =3D {0}; /* Source data (zeros for this test) */ + uint8_t counter[16]; /* Counter value */ + uint8_t output[16]; /* Output buffer */ + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: key only */ + memcpy(param, kmctraes128key, sizeof(kmctraes128key)); + + /* Setup counter buffer */ + memcpy(counter, kmctraes128plain, sizeof(kmctraes128plain)); + + /* En/Decrypt src with given counter, note that src is all zero */ + cpacf_kmctr(CPACF_KMCTR_AES_128, param, output, src, + sizeof(src), counter, &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmctraes128cipher, sizeof(kmctraes128cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KMCTR_AES_192 test for kmctr + * returns > 0 on failure, otherwise 0 + */ +static int test_kmctr_aes_192(void) +{ + uint8_t param[24]; /* Parameter block: AES-192 key */ + uint8_t src[16] =3D {0}; /* Source data (zeros for this test) */ + uint8_t counter[16]; /* Counter value */ + uint8_t output[16]; /* Output buffer */ + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: key only */ + memcpy(param, kmctraes192key, sizeof(kmctraes192key)); + + /* Setup counter buffer */ + memcpy(counter, kmctraes192plain, sizeof(kmctraes192plain)); + + /* En/Decrypt src with given counter, note that src is all zero */ + cpacf_kmctr(CPACF_KMCTR_AES_192, param, output, src, + sizeof(src), counter, &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmctraes192cipher, sizeof(kmctraes192cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KMCTR_AES_256 test for kmctr + * returns > 0 on failure, otherwise 0 + */ +static int test_kmctr_aes_256(void) +{ + uint8_t param[32]; /* Parameter block: AES-256 key */ + uint8_t src[16] =3D {0}; /* Source data (zeros for this test) */ + uint8_t counter[16]; /* Counter value */ + uint8_t output[16]; /* Output buffer */ + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: key only */ + memcpy(param, kmctraes256key, sizeof(kmctraes256key)); + + /* Setup counter buffer */ + memcpy(counter, kmctraes256plain, sizeof(kmctraes256plain)); + + /* En/Decrypt src with given counter, note that src is all zero */ + cpacf_kmctr(CPACF_KMCTR_AES_256, param, output, src, + sizeof(src), counter, &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmctraes256cipher, sizeof(kmctraes256cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KMCTR_PAES_128 test for kmctr + * returns > 0 on failure, otherwise 0 + */ +static int test_kmctr_paes_128(void) +{ + uint8_t param[16 + 32]; /* Parameter block: protected key + wkvp */ + uint8_t src[16] =3D {0}; /* Source data (zeros for this test) */ + uint8_t counter[16]; /* Counter value */ + uint8_t output[16]; /* Output buffer */ + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: protected key + wkvp */ + memcpy(param, kmctraes128key, sizeof(kmctraes128key)); + encrypt_clrkey(param, sizeof(kmctraes128key)); + memcpy(param + sizeof(kmctraes128key), protkey_wkvp, sizeof(protkey_wk= vp)); + + /* Setup counter buffer */ + memcpy(counter, kmctraes128plain, sizeof(kmctraes128plain)); + + /* En/Decrypt src with given counter, note that src is all zero */ + cpacf_kmctr(CPACF_KMCTR_PAES_128, param, output, src, + sizeof(src), counter, &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmctraes128cipher, sizeof(kmctraes128cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KMCTR_PAES_192 test for kmctr + * returns > 0 on failure, otherwise 0 + */ +static int test_kmctr_paes_192(void) +{ + uint8_t param[24 + 32]; /* Parameter block: protected key + wkvp */ + uint8_t src[16] =3D {0}; /* Source data (zeros for this test) */ + uint8_t counter[16]; /* Counter value */ + uint8_t output[16]; /* Output buffer */ + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: protected key + wkvp */ + memcpy(param, kmctraes192key, sizeof(kmctraes192key)); + encrypt_clrkey(param, sizeof(kmctraes192key)); + memcpy(param + sizeof(kmctraes192key), protkey_wkvp, sizeof(protkey_wk= vp)); + + /* Setup counter buffer */ + memcpy(counter, kmctraes192plain, sizeof(kmctraes192plain)); + + /* En/Decrypt src with given counter, note that src is all zero */ + cpacf_kmctr(CPACF_KMCTR_PAES_192, param, output, src, + sizeof(src), counter, &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmctraes192cipher, sizeof(kmctraes192cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_KMCTR_PAES_256 test for kmctr + * returns > 0 on failure, otherwise 0 + */ +static int test_kmctr_paes_256(void) +{ + uint8_t param[32 + 32]; /* Parameter block: protected key + wkvp */ + uint8_t src[16] =3D {0}; /* Source data (zeros for this test) */ + uint8_t counter[16]; /* Counter value */ + uint8_t output[16]; /* Output buffer */ + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: protected key + wkvp */ + memcpy(param, kmctraes256key, sizeof(kmctraes256key)); + encrypt_clrkey(param, sizeof(kmctraes256key)); + memcpy(param + sizeof(kmctraes256key), protkey_wkvp, sizeof(protkey_wk= vp)); + + /* Setup counter buffer */ + memcpy(counter, kmctraes256plain, sizeof(kmctraes256plain)); + + /* En/Decrypt src with given counter, note that src is all zero */ + cpacf_kmctr(CPACF_KMCTR_PAES_256, param, output, src, + sizeof(src), counter, &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare result with expected ciphertext */ + if (memcmp(output, kmctraes256cipher, sizeof(kmctraes256cipher))) { + printf("%s failed: output mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +int main(void) +{ + int rc =3D 0; + + /* Test query function */ + rc +=3D test_kmctr_query(); + + /* Test AES-128 */ + rc +=3D test_kmctr_aes_128(); + + /* Test AES-192 */ + rc +=3D test_kmctr_aes_192(); + + /* Test AES-256 */ + rc +=3D test_kmctr_aes_256(); + + /* Test PAES-128 */ + rc +=3D test_kmctr_paes_128(); + + /* Test PAES-192 */ + rc +=3D test_kmctr_paes_192(); + + /* Test PAES-256 */ + rc +=3D test_kmctr_paes_256(); + + if (rc) { + printf("cpacf-kmctr: %d failures\n", rc); + } + + return rc ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/tests/tcg/s390x/cpacf-pcc.c b/tests/tcg/s390x/cpacf-pcc.c new file mode 100644 index 0000000000..e61672f98b --- /dev/null +++ b/tests/tcg/s390x/cpacf-pcc.c @@ -0,0 +1,245 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Simple test for CPACF PCC instruction + */ + +#include +#include +#include +#include +#include "cpacf.h" + +#define QUERY_BLOCK_SIZE 16 + +/* expected pcc query block */ +static uint8_t exp_query_block[QUERY_BLOCK_SIZE] =3D { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +/* PCC XTS AES-128 test data */ +static const uint8_t kmaes128key[] =3D { + 0xed, 0xfd, 0xb2, 0x57, 0xcb, 0x37, 0xcd, 0xf1, + 0x82, 0xc5, 0x45, 0x5b, 0x0c, 0x0e, 0xfe, 0xbb +}; +static const uint8_t kmaes128plain[] =3D { + 0x16, 0x95, 0xfe, 0x47, 0x54, 0x21, 0xca, 0xce, + 0x35, 0x57, 0xda, 0xca, 0x01, 0xf4, 0x45, 0xff +}; +static const uint8_t kmaes128cipher[] =3D { + 0x78, 0x88, 0xbe, 0xae, 0x6e, 0x7a, 0x42, 0x63, + 0x32, 0xa7, 0xea, 0xa2, 0xf8, 0x08, 0xe6, 0x37 +}; + +/* PCC XTS AES-256 test data */ +static const uint8_t kmaes256key[] =3D { + 0xcc, 0x22, 0xda, 0x78, 0x7f, 0x37, 0x57, 0x11, + 0xc7, 0x63, 0x02, 0xbe, 0xf0, 0x97, 0x9d, 0x8e, + 0xdd, 0xf8, 0x42, 0x82, 0x9c, 0x2b, 0x99, 0xef, + 0x3d, 0xd0, 0x4e, 0x23, 0xe5, 0x4c, 0xc2, 0x4b +}; +static const uint8_t kmaes256plain[] =3D { + 0xcc, 0xc6, 0x2c, 0x6b, 0x0a, 0x09, 0xa6, 0x71, + 0xd6, 0x44, 0x56, 0x81, 0x8d, 0xb2, 0x9a, 0x4d +}; +static const uint8_t kmaes256cipher[] =3D { + 0xdf, 0x86, 0x34, 0xca, 0x02, 0xb1, 0x3a, 0x12, + 0x5b, 0x78, 0x6e, 0x1d, 0xce, 0x90, 0x65, 0x8b +}; + +/* static byte array containing the WKVP */ +static const uint8_t protkey_wkvp[32] =3D PROTKEY_WKVP; + +/* + * Query test for pcc + * returns > 0 on failure, otherwise 0 + */ +static int test_pcc_query(void) +{ + uint8_t query_block[QUERY_BLOCK_SIZE] =3D {0}; + unsigned long cc =3D 0; + int i, rc =3D 0; + + cpacf_pcc(CPACF_PCC_QUERY, query_block, &cc); + + /* compare with expected query block */ + for (i =3D 0; i < QUERY_BLOCK_SIZE; i++) { + if ((query_block[i] & exp_query_block[i]) !=3D exp_query_block[i])= { + rc++; + break; + } + } + + if (rc) { + printf("%s failed\n", __func__); + } + + return rc; +} + +/* + * Subfunction CPACF_PCC_XTS_AES_128 test for pcc + * returns > 0 on failure, otherwise 0 + */ +static int test_pcc_xts_aes_128(void) +{ + uint8_t param[80]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: key + plaintext + zeros */ + memcpy(param, kmaes128key, sizeof(kmaes128key)); + memcpy(param + 16, kmaes128plain, sizeof(kmaes128plain)); + /* Clear Block Sequential Nr, Intermediate Bit Index, and XTS Paramete= r */ + memset(param + 32, 0, 48); + + /* Execute PCC to compute XTS parameter */ + cpacf_pcc(CPACF_PCC_XTS_AES_128, param, &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare computed XTS parameter (at offset 64) with expected cipher = */ + if (memcmp(param + 64, kmaes128cipher, sizeof(kmaes128cipher))) { + printf("%s failed: XTS parameter mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_PCC_XTS_AES_256 test for pcc + * returns > 0 on failure, otherwise 0 + */ +static int test_pcc_xts_aes_256(void) +{ + uint8_t param[96]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: key + plaintext + zeros */ + memcpy(param, kmaes256key, sizeof(kmaes256key)); + memcpy(param + 32, kmaes256plain, sizeof(kmaes256plain)); + /* Clear Block Sequential Nr, Intermediate Bit Index, and XTS Paramete= r */ + memset(param + 48, 0, 48); + + /* Execute PCC to compute XTS parameter */ + cpacf_pcc(CPACF_PCC_XTS_AES_256, param, &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare computed XTS parameter (at offset 80) with expected cipher = */ + if (memcmp(param + 80, kmaes256cipher, sizeof(kmaes256cipher))) { + printf("%s failed: XTS parameter mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_PCC_XTS_PAES_128 test for pcc + * returns > 0 on failure, otherwise 0 + */ +static int test_pcc_xts_paes_128(void) +{ + uint8_t param[112]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: protected key + wkvp + plaintext + zeros */ + memcpy(param, kmaes128key, sizeof(kmaes128key)); + encrypt_clrkey(param, sizeof(kmaes128key)); + memcpy(param + 16, protkey_wkvp, sizeof(protkey_wkvp)); + memcpy(param + 48, kmaes128plain, sizeof(kmaes128plain)); + /* Clear Block Sequential Nr, Intermediate Bit Index, and XTS Paramete= r */ + memset(param + 64, 0, 48); + + /* Execute PCC to compute XTS parameter */ + cpacf_pcc(CPACF_PCC_XTS_PAES_128, param, &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare computed XTS parameter (at offset 96) with expected cipher = */ + if (memcmp(param + 96, kmaes128cipher, sizeof(kmaes128cipher))) { + printf("%s failed: XTS parameter mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +/* + * Subfunction CPACF_PCC_XTS_PAES_256 test for pcc + * returns > 0 on failure, otherwise 0 + */ +static int test_pcc_xts_paes_256(void) +{ + uint8_t param[128]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Setup parameter block: protected key + wkvp + plaintext + zeros */ + memcpy(param, kmaes256key, sizeof(kmaes256key)); + encrypt_clrkey(param, sizeof(kmaes256key)); + memcpy(param + 32, protkey_wkvp, sizeof(protkey_wkvp)); + memcpy(param + 64, kmaes256plain, sizeof(kmaes256plain)); + /* Clear Block Sequential Nr, Intermediate Bit Index, and XTS Paramete= r */ + memset(param + 80, 0, 48); + + /* Execute PCC to compute XTS parameter */ + cpacf_pcc(CPACF_PCC_XTS_PAES_256, param, &cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu\n", __func__, cc); + rc =3D 1; + } + + /* Compare computed XTS parameter (at offset 112) with expected cipher= */ + if (memcmp(param + 112, kmaes256cipher, sizeof(kmaes256cipher))) { + printf("%s failed: XTS parameter mismatch\n", __func__); + rc =3D 1; + } + + return rc; +} + +int main(void) +{ + int rc =3D 0; + + /* Test query function */ + rc +=3D test_pcc_query(); + + /* Test XTS-AES-128 */ + rc +=3D test_pcc_xts_aes_128(); + + /* Test XTS-AES-256 */ + rc +=3D test_pcc_xts_aes_256(); + + /* Test XTS-PAES-128 */ + rc +=3D test_pcc_xts_paes_128(); + + /* Test XTS-PAES-256 */ + rc +=3D test_pcc_xts_paes_256(); + + if (rc) { + printf("cpacf-pcc: %d failures\n", rc); + } + + return rc ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/tests/tcg/s390x/cpacf-prno.c b/tests/tcg/s390x/cpacf-prno.c new file mode 100644 index 0000000000..1081a9e970 --- /dev/null +++ b/tests/tcg/s390x/cpacf-prno.c @@ -0,0 +1,131 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Simple test for CPACF PRNO instruction + */ + +#include +#include +#include +#include +#include +#include "cpacf.h" + +#define QUERY_BLOCK_SIZE 16 +#define TRNG_OUTPUT_SIZE 32 + +/* expected prno query block */ +static uint8_t exp_query_block[QUERY_BLOCK_SIZE] =3D { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, +}; + +/* + * Query test for prno + * returns > 0 on failure, otherwise 0 + */ +static int test_prno_query(void) +{ + uint8_t query_block[QUERY_BLOCK_SIZE] =3D {0}; + unsigned long cc =3D 0; + int i, rc =3D 0; + + cpacf_prno(CPACF_PRNO_QUERY, query_block, NULL, 0, NULL, 0, &cc); + + /* compare with expected query block */ + for (i =3D 0; i < QUERY_BLOCK_SIZE; i++) { + if ((query_block[i] & exp_query_block[i]) !=3D exp_query_block[i])= { + rc++; + break; + } + } + + if (rc) { + printf("%s failed\n", __func__); + } + + return rc; +} + +/* check for buffer is all zero */ +static bool is_all_zeros(const uint8_t *buf, size_t len) +{ + size_t i; + + for (i =3D 0; i < len; i++) { + if (buf[i] !=3D 0) { + return false; + } + } + + return true; +} + +/* + * Subfunction CPACF_PRNO_TRNG test for prno + * returns > 0 on failure, otherwise 0 + */ +static int test_prno_trng(void) +{ + uint8_t output1[TRNG_OUTPUT_SIZE]; + uint8_t output2[TRNG_OUTPUT_SIZE]; + unsigned long cc =3D 0; + int rc =3D 0; + + /* Initialize outputs to detect if they get filled */ + memset(output1, 0, sizeof(output1)); + memset(output2, 0, sizeof(output2)); + + /* First TRNG call */ + cpacf_prno(CPACF_PRNO_TRNG, NULL, output1, sizeof(output1), NULL, 0, &= cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu on first call\n", __func__,= cc); + rc =3D 1; + } + /* Verify output is not all zeros */ + if (is_all_zeros(output1, TRNG_OUTPUT_SIZE)) { + printf("%s failed: output1 is all zeros\n", __func__); + rc =3D 1; + } + + /* Second TRNG call */ + cpacf_prno(CPACF_PRNO_TRNG, NULL, output2, sizeof(output2), NULL, 0, &= cc); + + /* Check for correct condition code */ + if (cc !=3D 0) { + printf("%s failed: unexpected cc=3D%lu on second call\n", __func__= , cc); + rc =3D 1; + } + /* Verify output is not all zeros */ + if (is_all_zeros(output2, TRNG_OUTPUT_SIZE)) { + printf("%s failed: output2 is all zeros\n", __func__); + rc =3D 1; + } + + /* Verify the two outputs are different */ + if (memcmp(output1, output2, TRNG_OUTPUT_SIZE) =3D=3D 0) { + printf("%s failed: two TRNG calls produced same output\n", __func_= _); + rc =3D 1; + } + + return rc; +} + +int main(void) +{ + int rc =3D 0; + + /* Test query function */ + rc +=3D test_prno_query(); + + /* Test TRNG */ + rc +=3D test_prno_trng(); + + if (rc) { + printf("cpacf-prno: %d failures\n", rc); + } + + return rc ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/tests/tcg/s390x/cpacf.h b/tests/tcg/s390x/cpacf.h new file mode 100644 index 0000000000..76b02866b0 --- /dev/null +++ b/tests/tcg/s390x/cpacf.h @@ -0,0 +1,571 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Defines and inline functions around testing CPACF instructions + * + */ + +#ifndef _S390_CPACF_H_ +#define _S390_CPACF_H_ + +#define CPACF_H_INCLUDE_FOR_TESTS +#include "../../../target/s390x/tcg/cpacf.h" + +union register_pair { + unsigned __int128 pair; + struct { + unsigned long even; + unsigned long odd; + }; +}; + +/* + * Instruction opcodes for the CPACF instructions + */ +#define CPACF_KMAC 0xb91e /* MSA */ +#define CPACF_KM 0xb92e /* MSA */ +#define CPACF_KMC 0xb92f /* MSA */ +#define CPACF_KIMD 0xb93e /* MSA */ +#define CPACF_KLMD 0xb93f /* MSA */ +#define CPACF_PCKMO 0xb928 /* MSA3 */ +#define CPACF_KMF 0xb92a /* MSA4 */ +#define CPACF_KMO 0xb92b /* MSA4 */ +#define CPACF_PCC 0xb92c /* MSA4 */ +#define CPACF_KMCTR 0xb92d /* MSA4 */ +#define CPACF_PRNO 0xb93c /* MSA5 */ +#define CPACF_KMA 0xb929 /* MSA8 */ +#define CPACF_KDSA 0xb93a /* MSA9 */ + +/* + * 'encrypt' the clear key value into a protected key + * by xor-ing the protkey_xor_pattern onto it. + */ +static inline void encrypt_clrkey(uint8_t *key, int keysize) +{ + const uint8_t protkey_xor_pattern[32] =3D PROTKEY_XOR_PATTERN; + + for (int i =3D 0; i < keysize; i++) { + key[i] ^=3D protkey_xor_pattern[i]; + } +} + +/** + * cpacf_km() - executes the KM instruction + * @func: the function code passed to KM; see CPACF_KM_xxx defines + * @param: address of parameter block; see POP for details on each func + * @dest: address of destination memory area + * @src: address of source memory area + * @src_len: length of src operand in bytes + * + * Returns 0 for the query func, number of processed bytes for + * encryption/decryption funcs + */ +static inline int cpacf_km(unsigned long func, void *param, + uint8_t *dest, const uint8_t *src, long src_len, + unsigned long *cc) +{ + union register_pair d, s; + + *cc =3D 0; + d.even =3D (unsigned long)dest; + s.even =3D (unsigned long)src; + s.odd =3D (unsigned long)src_len; + asm volatile( + " lgr 0,%[fc]\n" + " lgr 1,%[pba]\n" + "0: .insn rre,%[opc] << 16,%[dst],%[src]\n" + " brc 1,0b\n" /* handle partial completion */ + " brc 8,2f\n" + " brc 4,1f\n" + " agsi %[__cc],1\n" + "1: agsi %[__cc],1\n" + "2:\n" + : [src] "+&d" (s.pair), [dst] "+&d" (d.pair), [__cc] "+Q"= (*cc) + : [fc] "d" (func), [pba] "d" ((unsigned long)param), + [opc] "i" (CPACF_KM) + : "cc", "memory", "0", "1"); + + return src_len - s.odd; +} + +/** + * cpacf_kmc() - executes the KMC instruction + * @func: the function code passed to KM; see CPACF_KMC_xxx defines + * @param: address of parameter block; see POP for details on each func + * @dest: address of destination memory area + * @src: address of source memory area + * @src_len: length of src operand in bytes + * + * Returns 0 for the query func, number of processed bytes for + * encryption/decryption funcs + */ +static inline int cpacf_kmc(unsigned long func, void *param, + uint8_t *dest, const uint8_t *src, long src_le= n, + unsigned long *cc) +{ + union register_pair d, s; + + *cc =3D 0; + d.even =3D (unsigned long)dest; + s.even =3D (unsigned long)src; + s.odd =3D (unsigned long)src_len; + asm volatile( + " lgr 0,%[fc]\n" + " lgr 1,%[pba]\n" + "0: .insn rre,%[opc] << 16,%[dst],%[src]\n" + " brc 1,0b\n" /* handle partial completion */ + " brc 8,2f\n" + " brc 4,1f\n" + " agsi %[__cc],1\n" + "1: agsi %[__cc],1\n" + "2:\n" + : [src] "+&d" (s.pair), [dst] "+&d" (d.pair), [__cc] "+Q"= (*cc) + : [fc] "d" (func), [pba] "d" ((unsigned long)param), + [opc] "i" (CPACF_KMC) + : "cc", "memory", "0", "1"); + + return src_len - s.odd; +} + +/** + * cpacf_kimd() - executes the KIMD instruction + * @func: the function code passed to KM; see CPACF_KIMD_xxx defines + * @param: address of parameter block; see POP for details on each func + * @src: address of source memory area + * @src_len: length of src operand in bytes + */ +static inline void cpacf_kimd(unsigned long func, void *param, + const uint8_t *src, long src_len, + unsigned long *cc) +{ + union register_pair s; + + *cc =3D 0; + s.even =3D (unsigned long)src; + s.odd =3D (unsigned long)src_len; + asm volatile( + " lgr 0,%[fc]\n" + " lgr 1,%[pba]\n" + "0: .insn rre,%[opc] << 16,0,%[src]\n" + " brc 1,0b\n" /* handle partial completion */ + " brc 8,2f\n" + " brc 4,1f\n" + " agsi %[__cc],1\n" + "1: agsi %[__cc],1\n" + "2:\n" + : [src] "+&d" (s.pair), [__cc] "+Q" (*cc) + : [fc] "d" (func), [pba] "d" ((unsigned long)(param)), + [opc] "i" (CPACF_KIMD) + : "cc", "memory", "0", "1"); +} + +/** + * cpacf_klmd() - executes the KLMD instruction + * @func: the function code passed to KM; see CPACF_KLMD_xxx defines + * @param: address of parameter block; see POP for details on each func + * @src: address of source memory area + * @src_len: length of src operand in bytes + */ +static inline void cpacf_klmd(unsigned long func, void *param, + const uint8_t *src, long src_len, + uint8_t *dest, long dest_len, + unsigned long *cc) +{ + union register_pair s, d; + + *cc =3D 0; + s.even =3D (unsigned long)src; + s.odd =3D (unsigned long)src_len; + d.even =3D (unsigned long)dest; + d.odd =3D (unsigned long)dest_len; + asm volatile( + " lgr 0,%[fc]\n" + " lgr 1,%[pba]\n" + "0: .insn rre,%[opc] << 16,%[dst],%[src]\n" + " brc 1,0b\n" /* handle partial completion */ + " brc 8,2f\n" + " brc 4,1f\n" + " agsi %[__cc],1\n" + "1: agsi %[__cc],1\n" + "2:\n" + : [src] "+&d" (s.pair), [dst] "+&d" (d.pair), [__cc] "+Q"= (*cc) + : [fc] "d" (func), [pba] "d" ((unsigned long)param), + [opc] "i" (CPACF_KLMD) + : "cc", "memory", "0", "1"); +} + +/** + * cpacf_kmac() - executes the KMAC instruction + * @func: the function code passed to KM; see CPACF_KMAC_xxx defines + * @param: address of parameter block; see POP for details on each func + * @src: address of source memory area + * @src_len: length of src operand in bytes + * + * Returns 0 for the query func, number of processed bytes for digest funcs + */ +static inline int cpacf_kmac(unsigned long func, void *param, + const uint8_t *src, long src_len, + unsigned long *cc) +{ + union register_pair s; + + *cc =3D 0; + s.even =3D (unsigned long)src; + s.odd =3D (unsigned long)src_len; + asm volatile( + " lgr 0,%[fc]\n" + " lgr 1,%[pba]\n" + "0: .insn rre,%[opc] << 16,0,%[src]\n" + " brc 1,0b\n" /* handle partial completion */ + " brc 8,2f\n" + " brc 4,1f\n" + " agsi %[__cc],1\n" + "1: agsi %[__cc],1\n" + "2:\n" + : [src] "+&d" (s.pair), [__cc] "+Q" (*cc) + : [fc] "d" (func), [pba] "d" ((unsigned long)param), + [opc] "i" (CPACF_KMAC) + : "cc", "memory", "0", "1"); + + return src_len - s.odd; +} + +static inline int cpacf_kmac_x(unsigned long *func, void *param, + const uint8_t *src, long src_len, + unsigned long *cc) +{ + union register_pair s; + unsigned long fc =3D *func; + + *cc =3D 0; + s.even =3D (unsigned long)src; + s.odd =3D (unsigned long)src_len; + asm volatile( + " lgr 0,%[fc]\n" + " lgr 1,%[pba]\n" + "0: .insn rre,%[opc] << 16,0,%[src]\n" + " brc 1,0b\n" /* handle partial completion */ + " brc 8,2f\n" + " brc 4,1f\n" + " agsi %[__cc],1\n" + "1: agsi %[__cc],1\n" + "2: lgr %[fc],0\n" + : [fc] "+d" (fc), [src] "+&d" (s.pair), [__cc] "+Q" (*cc) + : [pba] "d" ((unsigned long)param), + [opc] "i" (CPACF_KMAC) + : "cc", "memory", "0", "1"); + + *func =3D fc; + + return src_len - s.odd; +} + +/** + * cpacf_kmctr() - executes the KMCTR instruction + * @func: the function code passed to KMCTR; see CPACF_KMCTR_xxx defines + * @param: address of parameter block; see POP for details on each func + * @dest: address of destination memory area + * @src: address of source memory area + * @src_len: length of src operand in bytes + * @counter: address of counter value + * + * Returns 0 for the query func, number of processed bytes for + * encryption/decryption funcs + */ +static inline int cpacf_kmctr(unsigned long func, void *param, uint8_t *de= st, + const uint8_t *src, long src_len, + uint8_t *counter, unsigned long *cc) +{ + union register_pair d, s, c; + + *cc =3D 0; + d.even =3D (unsigned long)dest; + s.even =3D (unsigned long)src; + s.odd =3D (unsigned long)src_len; + c.even =3D (unsigned long)counter; + asm volatile( + " lgr 0,%[fc]\n" + " lgr 1,%[pba]\n" + "0: .insn rrf,%[opc] << 16,%[dst],%[src],%[ctr],0\n" + " brc 1,0b\n" /* handle partial completion */ + " brc 8,2f\n" + " brc 4,1f\n" + " agsi %[__cc],1\n" + "1: agsi %[__cc],1\n" + "2:\n" + : [src] "+&d" (s.pair), [dst] "+&d" (d.pair), + [ctr] "+&d" (c.pair), [__cc] "+Q" (*cc) + : [fc] "d" (func), [pba] "d" ((unsigned long)param), + [opc] "i" (CPACF_KMCTR) + : "cc", "memory", "0", "1"); + + return src_len - s.odd; +} + +/** + * cpacf_prno() - executes the PRNO instruction + * @func: the function code passed to PRNO; see CPACF_PRNO_xxx defines + * @param: address of parameter block; see POP for details on each func + * @dest: address of destination memory area + * @dest_len: size of destination memory area in bytes + * @seed: address of seed data + * @seed_len: size of seed data in bytes + */ +static inline void cpacf_prno(unsigned long func, void *param, + uint8_t *dest, unsigned long dest_len, + const uint8_t *seed, unsigned long seed_len, + unsigned long *cc) +{ + union register_pair d, s; + + *cc =3D 0; + d.even =3D (unsigned long)dest; + d.odd =3D (unsigned long)dest_len; + s.even =3D (unsigned long)seed; + s.odd =3D (unsigned long)seed_len; + asm volatile ( + " lgr 0,%[fc]\n" + " lgr 1,%[pba]\n" + "0: .insn rre,%[opc] << 16,%[dst],%[seed]\n" + " brc 1,0b\n" /* handle partial complet= ion */ + " brc 8,2f\n" + " brc 4,1f\n" + " agsi %[__cc],1\n" + "1: agsi %[__cc],1\n" + "2:\n" + : [dst] "+&d" (d.pair), [__cc] "+Q" (*cc) + : [fc] "d" (func), [pba] "d" ((unsigned long)param), + [seed] "d" (s.pair), [opc] "i" (CPACF_PRNO) + : "cc", "memory", "0", "1"); +} + +/** + * cpacf_trng() - executes the TRNG subfunction of the PRNO instruction + * @ucbuf: buffer for unconditioned data + * @ucbuf_len: amount of unconditioned data to fetch in bytes + * @cbuf: buffer for conditioned data + * @cbuf_len: amount of conditioned data to fetch in bytes + */ +static inline void cpacf_trng(uint8_t *ucbuf, unsigned long ucbuf_len, + uint8_t *cbuf, unsigned long cbuf_len, + unsigned long *cc) +{ + union register_pair u, c; + + *cc =3D 0; + u.even =3D (unsigned long)ucbuf; + u.odd =3D (unsigned long)ucbuf_len; + c.even =3D (unsigned long)cbuf; + c.odd =3D (unsigned long)cbuf_len; + asm volatile ( + " lghi 0,%[fc]\n" + "0: .insn rre,%[opc] << 16,%[ucbuf],%[cbuf]\n" + " brc 1,0b\n" /* handle partial complet= ion */ + " brc 8,2f\n" + " brc 4,1f\n" + " agsi %[__cc],1\n" + "1: agsi %[__cc],1\n" + "2:\n" + : [ucbuf] "+&d" (u.pair), [cbuf] "+&d" (c.pair), + [__cc] "+Q" (*cc) + : [fc] "K" (CPACF_PRNO_TRNG), [opc] "i" (CPACF_PRNO) + : "cc", "memory", "0"); +} + +/** + * cpacf_pcc() - executes the PCC instruction + * @func: the function code passed to PCC; see CPACF_KM_xxx defines + * @param: address of parameter block; see POP for details on each func + */ +static inline void cpacf_pcc(unsigned long func, void *param, unsigned lon= g *cc) +{ + *cc =3D 0; + asm volatile( + " lgr 0,%[fc]\n" + " lgr 1,%[pba]\n" + "0: .insn rre,%[opc] << 16,0,0\n" /* PCC opcode */ + " brc 1,0b\n" /* handle partial completion */ + " brc 8,2f\n" + " brc 4,1f\n" + " agsi %[__cc],1\n" + "1: agsi %[__cc],1\n" + "2:\n" + : [__cc] "+Q" (*cc) + : [fc] "d" (func), [pba] "d" ((unsigned long)param), + [opc] "i" (CPACF_PCC) + : "cc", "memory", "0", "1"); +} + +/** + * cpacf_pckmo() - executes the PCKMO instruction + * @func: the function code passed to PCKMO; see CPACF_PCKMO_xxx defines + * @param: address of parameter block; see POP for details on each func + */ +static inline void cpacf_pckmo(long func, void *param) +{ + asm volatile( + " lgr 0,%[fc]\n" + " lgr 1,%[pba]\n" + " .insn rre,%[opc] << 16,0,0\n" /* PCKMO opcode */ + : + : [fc] "d" (func), [pba] "d" ((unsigned long)param), + [opc] "i" (CPACF_PCKMO) + : "cc", "memory", "0", "1"); +} + +/** + * cpacf_kma() - executes the KMA instruction + * @func: the function code passed to KMA; see CPACF_KMA_xxx defines + * @param: address of parameter block; see POP for details on each func + * @dest: address of destination memory area + * @src: address of source memory area + * @src_len: length of src operand in bytes + * @aad: address of additional authenticated data memory area + * @aad_len: length of aad operand in bytes + */ +static inline void cpacf_kma(unsigned long func, void *param, uint8_t *des= t, + const uint8_t *src, unsigned long src_len, + const uint8_t *aad, unsigned long aad_len, + unsigned long *cc) +{ + union register_pair d, s, a; + + *cc =3D 0; + d.even =3D (unsigned long)dest; + s.even =3D (unsigned long)src; + s.odd =3D (unsigned long)src_len; + a.even =3D (unsigned long)aad; + a.odd =3D (unsigned long)aad_len; + asm volatile( + " lgr 0,%[fc]\n" + " lgr 1,%[pba]\n" + "0: .insn rrf,%[opc] << 16,%[dst],%[src],%[aad],0\n" + " brc 1,0b\n" /* handle partial completi= on */ + " brc 8,2f\n" + " brc 4,1f\n" + " agsi %[__cc],1\n" + "1: agsi %[__cc],1\n" + "2:\n" + : [dst] "+&d" (d.pair), [src] "+&d" (s.pair), + [aad] "+&d" (a.pair), [__cc] "+Q" (*cc) + : [fc] "d" (func), [pba] "d" ((unsigned long)param), + [opc] "i" (CPACF_KMA) + : "cc", "memory", "0", "1"); +} + +/** + * cpacf_kmf() - executes the KMF instruction + * @func: the function code passed to KMF; see CPACF_KMF_xxx defines + * @param: address of parameter block; see POP for details on each func + * @dest: address of destination memory area + * @src: address of source memory area + * @src_len: length of src operand in bytes + * + * Returns 0 for the query func, number of processed bytes for + * encryption/decryption funcs + */ +static inline int cpacf_kmf(unsigned long func, void *param, + uint8_t *dest, const uint8_t *src, long src_le= n, + unsigned long *cc) +{ + union register_pair d, s; + + *cc =3D 0; + d.even =3D (unsigned long)dest; + s.even =3D (unsigned long)src; + s.odd =3D (unsigned long)src_len; + asm volatile( + " lgr 0,%[fc]\n" + " lgr 1,%[pba]\n" + "0: .insn rre,%[opc] << 16,%[dst],%[src]\n" + " brc 1,0b\n" /* handle partial completion */ + " brc 8,2f\n" + " brc 4,1f\n" + " agsi %[__cc],1\n" + "1: agsi %[__cc],1\n" + "2:\n" + : [src] "+&d" (s.pair), [dst] "+&d" (d.pair), [__cc] "+Q"= (*cc) + : [fc] "d" (func), [pba] "d" ((unsigned long)param), + [opc] "i" (CPACF_KMF) + : "cc", "memory", "0", "1"); + + return src_len - s.odd; +} + +/** + * cpacf_kmo() - executes the KMO instruction + * @func: the function code passed to KMO; see CPACF_KMO_xxx defines + * @param: address of parameter block; see POP for details on each func + * @dest: address of destination memory area + * @src: address of source memory area + * @src_len: length of src operand in bytes + * + * Returns 0 for the query func, number of processed bytes for + * encryption/decryption funcs + */ +static inline int cpacf_kmo(unsigned long func, void *param, + uint8_t *dest, const uint8_t *src, long src_le= n, + unsigned long *cc) +{ + union register_pair d, s; + + *cc =3D 0; + d.even =3D (unsigned long)dest; + s.even =3D (unsigned long)src; + s.odd =3D (unsigned long)src_len; + asm volatile( + " lgr 0,%[fc]\n" + " lgr 1,%[pba]\n" + "0: .insn rre,%[opc] << 16,%[dst],%[src]\n" + " brc 1,0b\n" /* handle partial completion */ + " brc 8,2f\n" + " brc 4,1f\n" + " agsi %[__cc],1\n" + "1: agsi %[__cc],1\n" + "2:\n" + : [src] "+&d" (s.pair), [dst] "+&d" (d.pair), [__cc] "+Q"= (*cc) + : [fc] "d" (func), [pba] "d" ((unsigned long)param), + [opc] "i" (CPACF_KMO) + : "cc", "memory", "0", "1"); + + return src_len - s.odd; +} + +/** + * cpacf_kdsa() - executes the KDSA instruction + * @func: the function code passed to KDSA; see CPACF_KDSA_xxx defines + * @param: address of parameter block; see POP for details on each func + * @src: address of source memory area + * @src_len: length of src operand in bytes + * + * Returns 0 for the query func, otherwise the condition code is checked + * and 0 returned on cc 0, otherwise a value !=3D 0 to indicate failure. + */ +static inline int cpacf_kdsa(unsigned long func, void *param, + const uint8_t *src, long src_len, + unsigned long *cc) +{ + union register_pair s; + + *cc =3D 0; + s.even =3D (unsigned long)src; + s.odd =3D (unsigned long)src_len; + asm volatile( + " lgr 0,%[fc]\n" + " lgr 1,%[pba]\n" + "0: .insn rre,%[opc] << 16,0,%[src]\n" + " brc 1,0b\n" /* handle partial completion */ + " brc 8,2f\n" + " brc 4,1f\n" + " agsi %[__cc],1\n" + "1: agsi %[__cc],1\n" + "2:\n" + : [src] "+&d" (s.pair), [__cc] "+Q" (*cc) + : [fc] "d" (func), [pba] "d" ((unsigned long)param), + [opc] "i" (CPACF_KDSA) + : "cc", "memory", "0", "1"); + + return (int)(*cc !=3D 0); +} + +#endif /* _S390_CPACF_H_ */ --=20 2.43.0