From nobody Sun Jul 12 00:33:30 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=1783697537; cv=none; d=zohomail.com; s=zohoarc; b=IAPSVXWaw5U30f1rPjlRtXqkwDg1D8okuEpIf/5467K9IZ1M8Rf0p0IVlZY3RRcupD9Kluhq8sC+HSmiQwBFM95zt2F5U0GrllsATNmswQuXeJnlnuJG7VPLJruICiPSyJw/fLF+4GjJNpgyG4FGZ4Jchks0wpumOt1dZiXIK0Y= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783697537; 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=dBmI6CYlJnmsEC7FzUHIrAnuhDT9i6Q7utX2BB4b4AnK8VoEhEUZDcdUtq1dHVV9XFs53HRu7pX/O/ocyX8mnpRmFEd+IULltOJzAe3r9tUGzfdV2PshHtdil4KXpfgad8zB5n4Mnhwtkn0qZY1jlAALu9TkAMq8EF6giWvG3Ko= 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 1783697537041731.9553540611032; Fri, 10 Jul 2026 08:32:17 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiDAK-0001sg-7d; Fri, 10 Jul 2026 11:29:24 -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 1wiDAI-0001qv-DF; Fri, 10 Jul 2026 11:29:22 -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 1wiDAF-0004Ei-U4; Fri, 10 Jul 2026 11:29:22 -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 66AEmkME765860; Fri, 10 Jul 2026 15:29:12 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 4f6rke7kmu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:12 +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 66AFJiZH015261; Fri, 10 Jul 2026 15:29:11 GMT Received: from smtprelay07.fra02v.mail.ibm.com ([9.218.2.229]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 4f7f6yj8y6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:11 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay07.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 66AFT7tk49480144 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jul 2026 15:29:07 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9680A20040; Fri, 10 Jul 2026 15:29:07 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 64F242004D; Fri, 10 Jul 2026 15:29:07 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.196.135]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 10 Jul 2026 15:29:07 +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=V8y/Mx+f9IqruFhYUtPY5zQ7o68Sg6AI7 VY8OWTKQDR3/Wt8oZPbl3dYkn9T33smV7Ie54Szq1WL603lP9w4yRXhq4okUf0PZ cImBYkT0kwXsRu4gtt1/jQdj1n+7zYKKMjdim82qb37ugZi2vp1Smwg2zpY2sl1q D+igJIFdeyQcrwbmSVt3iqFoMMeC3KVn56j+MZiu8Cqm0ERDd24rMtr/lAmpXSRa ur5bE3VOSSvtmAhRdRkR3ikMsMd89BI7phO4NaPls8F7NrT1m3FN9FZQZ/zJGjEj 4tuaVBOdv0c7kWtkW8lJpvxb4X+Sp/8OGX9yF7UYD8XwrcJPY473g== 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 v12 01/17] target/s390x: Rework s390 cpacf implementations Date: Fri, 10 Jul 2026 17:28:47 +0200 Message-ID: <20260710152906.80207-2-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260710152906.80207-1-freude@linux.ibm.com> References: <20260710152906.80207-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=M7J97Sws c=1 sm=1 tr=0 ts=6a510fc8 cx=c_pps a=aDMHemPKRhS1OARIsFnwRA==:117 a=aDMHemPKRhS1OARIsFnwRA==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=V8glGbnc2Ofi9Qvn3v5h:22 a=VnNF1IyMAAAA:8 a=4KKJp7DvKucWb6I3c-QA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfXw3gL2hBl8lq7 9EXLapOpJkjSVmyISfqrgIVZ/2Zoqg3LoWrjNlU2gzi0zWHNd3Q4caa5JdVcmj8oXnKGY0EYuVz Gth+pbvOV3zYWZSCnZB/U4aUCMFdnWrcMXZ8KWINoP7nSkNjE8rjcmqrFGAW7yXDv9RfmAcPJlh XTAgwksOQdudlzjs1mBTdzD2a6PeBJzxPVMzrlYqj6hHIF59Hwof3NvqFO1+ZQ1ZAS6SBzZJQeB 7lkZFg5vbiCxYil3tT91pmfiPsUDi2/PO4lSd+GQPC3t8j708GgP8XnvMc21tBnDsQsQq3QK29d d48xxRwHCyp5akEWp/HOZTClCkD+9IjUfHOAA+UyJO6oX88ci3A8iF9+TyT844q4yMuZRPCLwwq 6YjRdNxbB0N5Tyvgc8840XfgNIecjUnKXzb7Xws05BaLna+FmamK3WO9E72ja0ZLeJ590BFH/0u qOI9ESDtZA+82YPphGQ== X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX59PQfQo/DsfH s3AsgRq47TcN9OySA15WhV9yTgL57qp29JJ9zfUWbvHg0WFTgfC/GP1L3bUPhIU7Qt1bZyD2m+q rL5XuE9GJxFeQ/LeTcNiyIkIAjDZ+aI= X-Proofpoint-GUID: MKE9TkSQH-pbiG92-n35W0BEDRK_Gvul X-Proofpoint-ORIG-GUID: MKE9TkSQH-pbiG92-n35W0BEDRK_Gvul X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_04,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 lowpriorityscore=0 malwarescore=0 clxscore=1015 adultscore=0 priorityscore=1501 bulkscore=0 spamscore=0 impostorscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100153 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.001, RCVD_IN_MSPIKE_WL=0.001, 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: 1783697538042158500 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 Sun Jul 12 00:33:30 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=1783697558; cv=none; d=zohomail.com; s=zohoarc; b=FK82g/kfuJvFDg9NsLweABH+9wYYu7BWi92fwp4JEoKwNiCsfNiuYtcPGvgcgRAnOF7Mw1Ozqt4iZHgZoj2zcVhVUp1X09ZjPWvkJ9oYEdoQQTiAuajaYYw1rqo0ASwLkAz0a0aSrXIbH7prhPcuOI6DgjoDAYJ3lrnLGm8UGp0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783697558; 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=aRP6++3n2QtNv4XcTSuSBOh1bhhP5NAlE3yrkjLx7YSXiN3ysbK/htR5nNPjQm3elCu47mcWofharDcjixRXYsHK7sEFYQZsRqzhW3/3WYnm0a2ngxVan2QmKZZu0N8TlMApC/vg6gCgiW5W9kDs9/CzHNMsCZKWA8whcK2ON9o= 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 1783697558661784.8662359511438; Fri, 10 Jul 2026 08:32:38 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiDAK-0001tp-Uq; Fri, 10 Jul 2026 11:29:24 -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 1wiDAI-0001r0-H5; Fri, 10 Jul 2026 11:29:22 -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 1wiDAF-0004DT-7v; Fri, 10 Jul 2026 11:29:22 -0400 Received: from pps.filterd (m0360083.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66AEmWTJ1406500; Fri, 10 Jul 2026 15:29:13 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 4fafh0cprb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:12 +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 66AFJqGO015771; Fri, 10 Jul 2026 15:29:11 GMT Received: from smtprelay07.fra02v.mail.ibm.com ([9.218.2.229]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 4f7cgqjt1y-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:11 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay07.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 66AFT7u635652082 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jul 2026 15:29:08 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D488B20040; Fri, 10 Jul 2026 15:29:07 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9AF8E2004B; Fri, 10 Jul 2026 15:29:07 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.196.135]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 10 Jul 2026 15:29:07 +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=T7HlRPdZ7vbphOIKmt68xQeyUrqnQ9137 xKX/QrAHWB4Kx/mbyQmmk2KxZBpgZMJ59ij4z4EJgpqMsM463yTvl7hheof1X1hf YxpS78hVIs4N2Bs6NtyArXP96KETdGZtQkmk3kKpSlg+t8gq2nrLVSAfpOrCfv0k B3dlXkXGTk16oEH3VoWCpLHh4QVjLN1DjvQQMoBtGal3kshQBL/QP9sYqCzmQp9T Wh7QO2c9+ZebRm4HjjD0yZC9bIFATLRbE2QGUDdQxfTFadMO+rYI971NNUK0Mpxm J5xvGGf+yEKwfxNQrq6Gob619d6JFp/xvH3+kEJN8EZi0KV7tomIw== 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 v12 02/17] target/s390x: Move cpacf sha512 code into a new file Date: Fri, 10 Jul 2026 17:28:48 +0200 Message-ID: <20260710152906.80207-3-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260710152906.80207-1-freude@linux.ibm.com> References: <20260710152906.80207-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=VebH+lp9 c=1 sm=1 tr=0 ts=6a510fc8 cx=c_pps a=bLidbwmWQ0KltjZqbj+ezA==:117 a=bLidbwmWQ0KltjZqbj+ezA==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=iQ6ETzBq9ecOQQE5vZCe:22 a=VnNF1IyMAAAA:8 a=UGG5zPGqAAAA:8 a=yMKeI-deMsSePwiaAVEA:9 a=17ibUXfGiVyGqR_YBevW:22 X-Proofpoint-GUID: NX58Zetrk4ajr6b10USUmsIpQhN2hEWF X-Proofpoint-ORIG-GUID: NX58Zetrk4ajr6b10USUmsIpQhN2hEWF X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX1XJT6G2PAjsL u/WMpQHCDkvdAe9ErLWUmcBPxe1hz8eQ5Qp0iYR+sxllDg+0Yd4DwMY0oXPO8q8OHSzHIgpCcYS hoMK6TJ9dyVTehGndnawhpYWUEdQdP8= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfXxkrrEOy8dE3O vVQ+FStkGN1oOCm5aAK2EyTbKd2Bym0dYzVjtGmnWbV8i1baxnP/wgKv+4LIFvq2tElF8lM+vgb SsPpz+ITjzu4jLa52nhNmAsYYQsKeEauMPUM6rnG4QcXrOmPAsvF8p+Isra1bj9EtdsU5li3zSa dPAQzcZFiiw8VfsQgHdBQw9IOePwhLNZCClx83LLqAEcevfUew1kLgdzuRSDpFxbbFd2WdjoNew Oq0e0Le4EgkbHgjJIE4j4X0p29Fe7kpl5qsHWhonstUTZ4XWw38rcfR6VrwDR3y/BzWLlLaDmrU S8qkuuO62OcV3nv3ZBR6BS/EPSsZTeahaaeDg7Zlvllreaq1U0M78LMbzXAK9f1uXc1yD8wjyw2 l+aBupA95OB3TYymu6j3phsZ3EPzutCVyUGzMGqWvBNturNGfv+iZB/EDqd3mzve2CN5jsOYn// ah3gp3oPI1ZfEISrifA== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_04,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 suspectscore=0 clxscore=1015 malwarescore=0 impostorscore=0 phishscore=0 lowpriorityscore=0 adultscore=0 spamscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100153 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.001, RCVD_IN_MSPIKE_WL=0.001, 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: 1783697559945158500 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 Sun Jul 12 00:33:30 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=1783697395; cv=none; d=zohomail.com; s=zohoarc; b=j+/gwbV2tnBa/cSyt3Exg/K6LrhimkWPNqd83X6QwzfLTAjCjYzx/FlqmbRsSlXwBLpUC6xTnIxO8rxbx94L4tN/yxDJ00fOq6e5GW+GqPKMiGpW3/fKzQPlSw4hoE1RPGggcETxr7qUcxKQ1ijOIJ2i2ZzgKmUaDll9Iy5ohO8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783697395; 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=fKO7VqDqwcIV1DU3B9c/B+I8YniDj9giIDTO7WukIx94FW4tfBYdAK9sLtYwTXHaXyhGQR8Jkrpd4Hru5W4zbOuuwd6rpT+Mmp/gJsq7Oh2IZb4Ml9sj0jTBZk2WFM7fsH3DEKyKnLITkUAkz2LggFk9mN+sF8DNTD6WJPN16a0= 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 178369739550719.20296863216572; Fri, 10 Jul 2026 08:29:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiDAP-0001yE-DM; Fri, 10 Jul 2026 11:29: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 1wiDAL-0001ul-Ub; Fri, 10 Jul 2026 11:29:25 -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 1wiDAH-0004Fq-Hc; Fri, 10 Jul 2026 11:29:25 -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 66AEmjkM1545548; Fri, 10 Jul 2026 15:29:13 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 4f6qknxqbf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:12 +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 66AFJsvK021018; Fri, 10 Jul 2026 15:29:12 GMT Received: from smtprelay01.fra02v.mail.ibm.com ([9.218.2.227]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7dgkjkyh-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:12 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay01.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 66AFT89t54264186 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jul 2026 15:29:08 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 155A520040; Fri, 10 Jul 2026 15:29:08 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D8FEF20043; Fri, 10 Jul 2026 15:29:07 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.196.135]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 10 Jul 2026 15:29:07 +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=TfZb01Q5X8Qt4uqNMGPOycg+1pBRD6Mgk yHZdwMPTUYPXuSFkXVfooN96VXluFrIq/NXOwTkqUWII+JRA0rm/iypEzm8YZHFq 8kIKXfaYA8NRzswL1oEoqroIkQ66783go1lpiqu+pVpSv/6scMNye4r4mNqztIqR 5JYITQDP79rUfadrmWYxuPi2jI8CYIDMUvKrQcv+w65z87dAX6BR53gYBoO7L6XF a6qkhUM78ixfBEAIDgl3L5mQ0PrbHatO199Qi58HFdR6hr3ykF/87m2u54PC3EkW PcobU47N8hERrjYj4FYu3t+qktVamrqAHX9Ai2yFHhOZDPyxlre/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 v12 03/17] target/s390x: Support cpacf sha256 Date: Fri, 10 Jul 2026 17:28:49 +0200 Message-ID: <20260710152906.80207-4-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260710152906.80207-1-freude@linux.ibm.com> References: <20260710152906.80207-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=Q/XiJY2a c=1 sm=1 tr=0 ts=6a510fc8 cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=Y2IxJ9c9Rs8Kov3niI8_:22 a=VnNF1IyMAAAA:8 a=Oku5TADFz1XGWIWXx1gA:9 X-Proofpoint-GUID: yRky9sjAvvtO17fn4PHc95ObjrVT7Yvw X-Proofpoint-ORIG-GUID: yRky9sjAvvtO17fn4PHc95ObjrVT7Yvw X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX0OE788qJRbX5 xXOjM8m7Bc7bJn+m4E8QYq7pzSJrmfxElzuBuk3S7ahcQ37hIbA3VKGrmAaA3jhbwneWpoOXzBh HqxAsQJVEp7S9R1DmQiUrtmBPv94Xis= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX6yfB0EFa9to/ YUWK2LMZ2DZfeuUF4bU8DwxRBxhL4Xw6z4nV66s4O4nSka0M58fDzQaDasudalDsqEIFyAa5+Qo ccgLtDHhmnd/SZYJLJqOawtsElllBmuLUswfcMVZ4qycB+8FGl5Zkv9yUFzFzmAU2/zEQMltxAs 4xrH+8RayY36tO9YOWGR0FmmXJWseVNhdrtJgJZaS1CG1SRSmxY3tzLDUVQ/hkg6oF8k1N16uM1 eXKYIK9ZFuGC1OmeN03EXQ1zAprpRmfi6KroYdpVM+MyElPpfinRHkQW3bBCPmV6NnNejeFavcC vp4+7X+53MXb5n4H/fh1Goc2HYP76Iu42y0DO3+3J3x6rtrxHYkRqAFNwQaC0oYNd060pZ+gLgB L3LOUSOuPKYAycjDfHsV813hF2EPFXD446UhnmJg8QOSxOm2X4fjdBw+ohVyH+04r/dQ3H47UiO 04oQh6zilxwvtV10hwg== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_04,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 impostorscore=0 spamscore=0 phishscore=0 priorityscore=1501 bulkscore=0 clxscore=1015 lowpriorityscore=0 suspectscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100153 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.001, RCVD_IN_MSPIKE_WL=0.001, 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: 1783697396695158500 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 Sun Jul 12 00:33:30 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=1783697558; cv=none; d=zohomail.com; s=zohoarc; b=bog2Kn1op4DxJMJPHmvMRgWxRQPv772HeWrQ7wD9S90GtiJhjqQGXmRA42XhOpMbozTptEU3ZqYYieCC5iD3E7lKlfnaOMXHO8M5ZRvheN4FZope0V6C5vRbU0icEJPlpRd18WPARKTilzpjWpYOeu5g5+GmWm1deNWTjgUuHM8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783697558; 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=cu6HPnEOKo40lGZU96y22CBYEdDjsoCox7hngywxAvc=; b=OfUc13+Gff2P3Cg68M9i56DC0xpCpQRERWXdOG8VVwOmN8yBBngS7LNKFJVh0rwIbGQzt7jchXcJR4VuP0x5Rllnjj6k9H1+HNrpzleAa+gPBfR7tUK2UVGVsnWtUEyMte1ZWRluTgVWGvpBWWTLcnrGHeOMKkFvGfpMRuSmPcE= 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 1783697558661422.4430174061531; Fri, 10 Jul 2026 08:32:38 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiDAM-0001v5-AU; Fri, 10 Jul 2026 11:29:26 -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 1wiDAK-0001sM-2c; Fri, 10 Jul 2026 11:29:24 -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 1wiDAG-0004Ev-LG; Fri, 10 Jul 2026 11:29:23 -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 66AEmj8a765843; Fri, 10 Jul 2026 15:29:13 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 4f6rke7kmw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:12 +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 66AFJeI8011436; Fri, 10 Jul 2026 15:29:12 GMT Received: from smtprelay01.fra02v.mail.ibm.com ([9.218.2.227]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4f7eqgjd1m-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:11 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay01.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 66AFT8xl54264188 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jul 2026 15:29:08 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4A52D20040; Fri, 10 Jul 2026 15:29:08 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 19C4A2004B; Fri, 10 Jul 2026 15:29:08 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.196.135]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 10 Jul 2026 15:29:08 +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=cu6HPn EOKo40lGZU96y22CBYEdDjsoCox7hngywxAvc=; b=qTED2d+uP9EI+8tW0RSckn l0uM/F9MRH9ENh9nKd7WzZM2aiWbaKha+CNjQaRz2amlR+QZtT1nMJa6PXQ0Q4W6 MPLL+xWS1cwHGusRh1uooY9iMnufYnIiIHlwG360vj5WSc+J0qmiNJpeLGHpRQMB 8ydfgtVOg6xDb8jdOQ46jnYGdA6i9mkmfoP2zpI2JtOrOsJJf0Ay6k95dKbpVL+S mfK/b2tF3e33l8+yGQ80VID1m88wnox/Na+x1/9Xrixoc5/p0ALTx3likKuQqN0B +c85zTKbRKIogCKUBVWrnoUrtiAEChxx0iT3NnaF9tX2oqdB1rxADfCkJu9bsj6Q == 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 v12 04/17] crypto: Add aes-helpers file to support some AES modes Date: Fri, 10 Jul 2026 17:28:50 +0200 Message-ID: <20260710152906.80207-5-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260710152906.80207-1-freude@linux.ibm.com> References: <20260710152906.80207-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-Authority-Analysis: v=2.4 cv=M7J97Sws c=1 sm=1 tr=0 ts=6a510fc8 cx=c_pps a=AfN7/Ok6k8XGzOShvHwTGQ==:117 a=AfN7/Ok6k8XGzOShvHwTGQ==:17 a=IkcTkHD0fZMA:10 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=V8glGbnc2Ofi9Qvn3v5h:22 a=VnNF1IyMAAAA:8 a=zkwM-tl61wuaHISZUgYA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX7sYVPE9VMcXO ciyE7Ehes3cBCssoQpBAyS+lGpTuF/o//jMW2ybiMTRQ1H5TOO1g6LU3W1s57JPDpYs13/VWuNZ QOOmqs6AUpC2ajw866JxrGydCvsZ8QDBq07q06LzNLq3KOzeVmWwX6qkqix8D13FA9caUcVboYA znBNAtQp/BL5E2Xv+MrMqA6BCAFiTGAzIy2YMvlsr76xTyuvAqsBtbU7dpn+Q+BnvuAg0XaA57r V5iRh0/cuJvV0l3GM0YKJRO1TihxGg9LwVCnLZ+bqJSvVGe+r3F65ZbQiMUAHgJsA0akhAmAgFX ILp491e+EVXtPTcmYb7+F/AByiy/64O+0GlMPlkBn5vC8owSJV7zM3n4O1aWLo6RswjLaAwHouK ODgLoaaIcXiS3w61Eq3SgTFm83NBr303ya4/s3UqXkesAS29gfSg/WmKW62Bhy+tfnTtCNDD5h8 EJE0s9q8f5KDrSPedxw== X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX2lFPQzD0Akch RDNrJHpDz0DYjtXSmfczvqKNI3x6eDRl7Uw58C6ssy5luiVX9V9x2+ApJZhP5K01+DZo5QeBeD9 /zJ2mbsPetcN3ZLYYsiIIMhW10zmgro= X-Proofpoint-GUID: _08aBMQTkXnsHcUqkRs2eUyDkywd1FlM X-Proofpoint-ORIG-GUID: _08aBMQTkXnsHcUqkRs2eUyDkywd1FlM X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_04,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 lowpriorityscore=0 malwarescore=0 clxscore=1015 adultscore=0 priorityscore=1501 bulkscore=0 spamscore=0 impostorscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100153 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.001, RCVD_IN_MSPIKE_WL=0.001, 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: 1783697560038158500 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 --- crypto/aes-helpers.c | 106 ++++++++++++++++++++++++++++++++ crypto/meson.build | 1 + include/crypto/aes-helpers.h | 116 +++++++++++++++++++++++++++++++++++ 3 files changed, 223 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..ff4aa0a385 --- /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 litte 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 b51597a879..675f27311c 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..c1552b0e8f --- /dev/null +++ b/include/crypto/aes-helpers.h @@ -0,0 +1,116 @@ +/* + * 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: + * + * Bitwise XOR operation between two AES blocks. + * + * @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 + */ +void AES_xor(const unsigned char *src1, const unsigned char *src2, + unsigned char *dst); + +/** + * AES_cbc_encrypt: + * + * 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. + * + * @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 + */ +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + unsigned char *iv, const AES_KEY *key); + +/** + * AES_cbc_decrypt: + * + * 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. + * + * @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 + */ +void AES_cbc_decrypt(const unsigned char *in, unsigned char *out, + unsigned char *iv, const AES_KEY *key); + +/** + * AES_ctr_encrypt: + * + * 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. + * + * @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 + */ +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 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. + * + * @tweak: pointer to tweak value to be updated (16 bytes buffer + * containing a 128 bit little endian integer) + */ +void AES_xts_prep_next_tweak(unsigned char *tweak); + +/** + * AES_xts_encrypt: + * + * 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. + * + * @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 + */ +void AES_xts_encrypt(const unsigned char *in, unsigned char *out, + const unsigned char *tweak, const AES_KEY *key); + +/** + * AES_xts_decrypt: + * + * 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. + * + * @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 + */ +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 Sun Jul 12 00:33:30 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=1783697395; cv=none; d=zohomail.com; s=zohoarc; b=YfE1JBG1boMOA85gtQiUT8HfTZ6YgRfQqyv4zxvPWNiSLZbQ9wz6zXCoPg0eImuWA9eVl7mZtfNfRMNx5GgjZC+mDRsu7P2a+TXNVrCp0TFjhEo/huaFZW33fYkJUOS8hW4TVvVUFSzFXjHOdST9aHrLIEUQNFF5H8HZeF+yJyo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783697395; 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=17EASr86680uF9dCCr32CSPhpnjy+PR4I5qmOE9ircU=; b=CfBxlhBVPQ8QjFGKSfuwv097DPl+SB9WuMNsfy3X8kIhSIdhbkb0da8FcU3FQXIt7eBETjDEr0aYLEXvxf1zuhDd493RuXcLbfVsTPc09iHDpdH7Pq9LBG9xtdOWtkBY1X0aONPe8VuLHbrmhO1LuPo0JVo1YdnrVct6tf4cEh0= 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 1783697395825172.51480104514178; Fri, 10 Jul 2026 08:29:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiDAP-0001yY-Mz; Fri, 10 Jul 2026 11:29: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 1wiDAM-0001w5-UF; Fri, 10 Jul 2026 11:29:26 -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 1wiDAI-0004GL-Ll; Fri, 10 Jul 2026 11:29:26 -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 66AEmbQX1907303; Fri, 10 Jul 2026 15:29:13 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 4f6sur75sj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:13 +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 66AFJeaP015235; Fri, 10 Jul 2026 15:29:12 GMT Received: from smtprelay01.fra02v.mail.ibm.com ([9.218.2.227]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 4f7f6yj8y8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:12 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay01.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 66AFT8mY54264190 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jul 2026 15:29:08 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 80C7C20040; Fri, 10 Jul 2026 15:29:08 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4FB1820043; Fri, 10 Jul 2026 15:29:08 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.196.135]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 10 Jul 2026 15:29:08 +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=17EASr86680uF9dCC r32CSPhpnjy+PR4I5qmOE9ircU=; b=E09JtmbY0KdzpsOwui9LD3J8dhV4UlixT SuYpDICokiK18QVecbXHvrk/BWNzdGiqXlSl5cAS8t4c95O9tKhH+mrEDyA2PrVj EY3pvlVvDDH2p/82TRIaHPnj+a5Qxpw65V/X9GzZwlAwcfdAvGyGlnF1M/Jel4Y7 Bu8+a+9w2Cg0OivcDiI4nV1b7WcejPhMo29v6Q6ExEB5ZcSdxfz+MEPz0ilq7mRS Y3MVbDbM80gQw1ofQqWPqMOwKSKnjOad3GyvDGpS1ow/G0cmvfj/N9Ghj74O0JEj VQlQtqAKYxyH7oPIPm3AexV/TLw4m9VECZm0oVWpfugBeasnG6VJQ== 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 v12 05/17] target/s390x: Support AES ECB for cpacf km instruction Date: Fri, 10 Jul 2026 17:28:51 +0200 Message-ID: <20260710152906.80207-6-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260710152906.80207-1-freude@linux.ibm.com> References: <20260710152906.80207-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX+FX32/dxuTeR dhzfobgfCwXXegIyYW7Jx/91hEqpIJSG4uqKwg/nX6jjLvHSA9CNtItrNya8DGEdBsvO9I/Kb4H MnBWxfXLi7TmDAAt2tGhtCWsCIMb0LY= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX33jtz1cla+jN zxirYKeyWbzFKZEJ0rEA9qTWYmMHcCpRt7UFpC55oMADhc0T+8BTM7yhXXLJXiFNidJLqUxjZpa WSp4VPNE+GISfVDUSB5BbV1EqzDBhbS8Uqu1SF4g9wXucT9hs7Oet1SQHK2e6HnRMQOu/UaR81d 9ZEwPZC+j+tnB4p9o7Jich3as1li4eN+RWi9OsETCVsaR9ab3Idyuq5bHX90+0sie9O/xqn6vUr Z62F+6qNDApBKBZXpig2/CoFGmcmOVLcxYzSX7YjRSGozRiLuSe/cVo2pnkVyjMbOg1kWVFuNDv qxCEtNWQ/9XwSB8h4C9mFfOHG4OKcmxg6v40sQ5Cknpa/17BSsg2HORF95pmWmUS4b29XAC3gSk Ww04tggw5TIjkXRrVKTx0r6klxPGVEQMF4ECWqB04IjfMr1iXKwGVx74GFoP8Ias48WWh0s3Ay8 10EqsGlZQ69Dtvrq4Sg== X-Proofpoint-GUID: ThmU4TCApWNhZY3jERPgM0zcFGN7Z2-K X-Authority-Analysis: v=2.4 cv=Oot/DS/t c=1 sm=1 tr=0 ts=6a510fc9 cx=c_pps a=aDMHemPKRhS1OARIsFnwRA==:117 a=aDMHemPKRhS1OARIsFnwRA==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=uAbxVGIbfxUO_5tXvNgY:22 a=VnNF1IyMAAAA:8 a=5Vg_AgGwEONL64qEDWAA:9 X-Proofpoint-ORIG-GUID: ThmU4TCApWNhZY3jERPgM0zcFGN7Z2-K X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_04,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 lowpriorityscore=0 clxscore=1015 impostorscore=0 phishscore=0 malwarescore=0 suspectscore=0 spamscore=0 adultscore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100153 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.001, RCVD_IN_MSPIKE_WL=0.001, 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: 1783697396803158500 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 | 136 +++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 24 ++++++ target/s390x/tcg/meson.build | 1 + 5 files changed, 170 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..5357d099c4 --- /dev/null +++ b/target/s390x/tcg/cpacf_aes.c @@ -0,0 +1,136 @@ +/* + * 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" + +/* + * helper function to copy some memory from guest to a local buffer + */ +static inline void copy_from_guest_wrap(CPUS390XState *env, const int mmu_= idx, + const uintptr_t ra, uint64_t guest= _addr, + 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 copy from a local buffer to guest memory + */ +static inline void copy_to_guest_wrap(CPUS390XState *env, const int mmu_id= x, + const uintptr_t ra, uint64_t guest_a= ddr, + 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); + } +} + +/* + * 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) +{ + copy_from_guest_wrap(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) +{ + copy_to_guest_wrap(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 */ + copy_from_guest_wrap(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 6c296f6731..3907b9748c 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -89,6 +89,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) { @@ -153,6 +174,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 Sun Jul 12 00:33:30 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=1783697431; cv=none; d=zohomail.com; s=zohoarc; b=brrvFiY55y6i8K+fCaLzznmeJpSEhBsqn8XQYA/Ul4mkNWSqosYPf9cZtXL+jPfItMlunFNC9eOL0/v1FvqVdhYZWL8umqAWsSQykm4mXPw0Emhf+tpBVoRsR9T+2frluZ7IAfe9FLXU77msLMHc1ufvSOLp3Q58gn+eNLx8BR0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783697431; 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=sP0b6T9Lp3+v/32fZE0ohP+wSeF69bFIAev892OrkZo=; b=NWmWn/tdcYtwQHZRaleQkXDHK7YbE6xG7tu0nQIMe+ggWCBOZ8bOJ024USuSyd0D1v4gTmnijUnIS77tfniTl2CeDgDbgn+P+WfiEUDSemY3L0NzEh8tG6PicmMdMzbnvCcdXEpFE3wD1ghho1YVs9j7cBxmrf1+N7pfNJQxrQI= 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 1783697431863795.4619666732076; Fri, 10 Jul 2026 08:30:31 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiDAQ-0001z1-BK; Fri, 10 Jul 2026 11:29:30 -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 1wiDAL-0001uD-KT; Fri, 10 Jul 2026 11:29:25 -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 1wiDAH-0004FQ-Cn; Fri, 10 Jul 2026 11:29:25 -0400 Received: from pps.filterd (m0360083.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66AEmSoI1406411; Fri, 10 Jul 2026 15:29:13 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 4fafh0cpre-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:13 +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 66AFJeh6015716; Fri, 10 Jul 2026 15:29:12 GMT Received: from smtprelay01.fra02v.mail.ibm.com ([9.218.2.227]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 4f7cgqjt20-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:12 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay01.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 66AFT8eH54264192 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jul 2026 15:29:08 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id AB00A20043; Fri, 10 Jul 2026 15:29:08 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 84FEB2004B; Fri, 10 Jul 2026 15:29:08 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.196.135]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 10 Jul 2026 15:29:08 +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=sP0b6T9Lp3+v/32fZ E0ohP+wSeF69bFIAev892OrkZo=; b=c3eMHQvH5LxHOhkRhkTGjY++XhOVv8mjj vdRcx7LSy4YwDLxuT/6oOCnYLkob0snfBQfjucM+xa96r+rnpO+8bQivN/g31E6d 3mtrlxHU1ijmk930vu9AHJHhW+4sqekYXLhO45Qc3P1WWwJp7HfEdxJ3pqk5ciJt PpZ1hrpONH30nbx5Ci1GUZozIbaDxmB6mpxyVo4dF1tRC8Wn5LEjTRLEzYY+fR6+ HAHf4+WNCELDXtyEudcbAbASpv/z2iEFP/9hYtzD3o1stYu9VH2K4HEsDhxT++Ms p52924c07FSslLGC3eh8su3qMaVLkJ2KtC1Cuhcv+Hr9HZsVP1Llg== 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 v12 06/17] target/s390x: Support AES CBC for cpacf kmc instruction Date: Fri, 10 Jul 2026 17:28:52 +0200 Message-ID: <20260710152906.80207-7-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260710152906.80207-1-freude@linux.ibm.com> References: <20260710152906.80207-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=VebH+lp9 c=1 sm=1 tr=0 ts=6a510fc9 cx=c_pps a=bLidbwmWQ0KltjZqbj+ezA==:117 a=bLidbwmWQ0KltjZqbj+ezA==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=iQ6ETzBq9ecOQQE5vZCe:22 a=VnNF1IyMAAAA:8 a=4s_zGP7M7QCs5o7xjogA:9 X-Proofpoint-GUID: pUVsW527je6WaaKhdx9tusLuffB54Svp X-Proofpoint-ORIG-GUID: pUVsW527je6WaaKhdx9tusLuffB54Svp X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX+PhfKbSb2IEf hNNUempMk92ICMTLigVctio/4t5l+9l5qG01BWl5DbD0+SFPABSdRW9qxeYYpMVDOG0LR78CX/+ bfgmrJNGHgCN+PwH5V/Iy36nVyqy2VM= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfXyMsRUxivXZ5n L5ko6W5zARqDvqoCcAo20+E++Gu2zqmxupg15Mg0PBLCqY93Me0gJh5/FNN0D7adEW325k8BiWg sL0Hxk7FuxrO+4NYAcskNi6viX+X4tRif+G3ku58Mz6kOk0FuyCvRlKfYOcUkbLQhmkcfSJI8pz oiLgHW7bYmtvrE1xIsA4d6cRsFEUQDLrwPtjlRh5wIkMCvylNTvI2y1/6ShntoEFikWgTRV29fJ vDv0cQobXYWoXgiry7ujL8eTLqSeL3MaODrL4eTTyx4IoJeSB8JjydQtH7ELRY93ZSno86hCcD4 S3KK0q49PJLdnpAp0MpUv4gfxyfjgldJlTnmwTTRcfcDwQo3/Z5iZEypMIrzMiuP3GIPiWzDHG5 Y3FQDJbJiftI9JS9jaXXeklFAufGtGRWsNdNSvxHtvXD1WLQzkwGg8gP5YEk/io2Vr64/XLdUGF EbE65rAuVhdcKoS9yJg== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_04,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 suspectscore=0 clxscore=1015 malwarescore=0 impostorscore=0 phishscore=0 lowpriorityscore=0 adultscore=0 spamscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100153 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.001, RCVD_IN_MSPIKE_WL=0.001, 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: 1783697432828158501 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 5357d099c4..7b6d133bec 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -134,3 +134,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 */ + copy_from_guest_wrap(env, mmu_idx, ra, param_addr, iv, AES_BLOCK_SIZE); + + /* fetch key from param block */ + copy_from_guest_wrap(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 */ + copy_to_guest_wrap(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 3907b9748c..1fe1d7157b 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -110,6 +110,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) { @@ -177,6 +198,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 Sun Jul 12 00:33:30 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=1783697504; cv=none; d=zohomail.com; s=zohoarc; b=R2erFHobtYqbc0RL4yR2a+4HV1vqQcSrbSn4gvXXDRsYw+9G5RavRpDpXjZ20MtV328zuvxLbupy7xw/ojAKsXtG3FhsrzyI2pNBwFnkx/HQjF7OuhIUzZN3gcvl8rxopNujhoT89Ifo7K0IiGvPtxAMAafxo2KpgvKJZH3eRw4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783697504; 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=VlFMWtJDmOSkrtggsJ5bwp/xaXy5pGmU/zp/zjQDk+Q=; b=CbS1dneaBKMnFrOkcHUCvhymA41v4aQhx8USKPeXQTwCBnlVKD74nW9qd1rsJt22AnU/yRi521SijQpCOzQK5LTvE7tq/7u5DJFP1WxoFTuehrsSR5vjqSZcpZ1Nt6WH/Qx8Kh0NHgIFUymp2sxh21zJUVxmsvvRMFx8DD/HqJs= 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 1783697504948835.3108161784982; Fri, 10 Jul 2026 08:31:44 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiDAM-0001vC-Ca; Fri, 10 Jul 2026 11:29:26 -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 1wiDAK-0001sZ-5R; Fri, 10 Jul 2026 11:29:24 -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 1wiDAG-0004Es-St; Fri, 10 Jul 2026 11:29:23 -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 66AEmjJW1165009; Fri, 10 Jul 2026 15:29:14 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 4f6sw57f6d-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:14 +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 66AFJdKI003153; Fri, 10 Jul 2026 15:29:12 GMT Received: from smtprelay01.fra02v.mail.ibm.com ([9.218.2.227]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7cvwjt2e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:12 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay01.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 66AFT87659048422 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jul 2026 15:29:09 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D5EE720040; Fri, 10 Jul 2026 15:29:08 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id AF2DD2004D; Fri, 10 Jul 2026 15:29:08 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.196.135]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 10 Jul 2026 15:29:08 +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=VlFMWtJDmOSkrtggs J5bwp/xaXy5pGmU/zp/zjQDk+Q=; b=S1rTJShiTJ7Ngt0TBK3yoj2vMJ0nPtswT /SO+SfboM6xpcS1sodBIs/Dwf1HqD/QtQexggEM0CASzjdgdHVAkYImY16jH/q9p KUymZW+xM2/zu8m9MOstu+sVruPQjTS2k84hNEXSBHV1pulwXJvMLHu8PdR7nxbS 1wj+s1a8kPPnimksXfqFzlI9WO7TWj8OBE3EVTPVR4HFYBH14iIwK2j8yaCqS1oa FHbh2Jl/hpth1nZnYnI0/Y9QYQlz1ZVec9avA/nlPYGsqepo4zjkE0Y8qy5uB+C7 CYuIEeI4XN/ugqBLUfGvoxzVOTchNX2O2VU0a11khG68ChvheMcoQ== 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 v12 07/17] target/s390x: Support AES CTR for cpacf kmctr instruction Date: Fri, 10 Jul 2026 17:28:53 +0200 Message-ID: <20260710152906.80207-8-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260710152906.80207-1-freude@linux.ibm.com> References: <20260710152906.80207-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: 3ATEQ3fmkWyaOnupf3i4dzAYIhj53tkj X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX5FqCWiunAgit XzBxrjk86Yhbki45hB9p1sk+MXf2EnzQkPsuN2gpLIGaAXf4ZVdsy7u1lI7JHQhnRrK1KJThmdQ wCX7n1COqsUjLaI2v6dKvCmAykRFpFKTET00T8f6WC60WWgHxjYg9n6mVoOTUe6BLkkuxLFspRa lNPEpult/ax6yjmCrCGnhDDBX0gAwlu27tkEwZrZN5FXsuOh7278EcXkToyiLhI3hExAfX8D2Xl VeHCbLzRx8l2KmrNH6zoQG4y76aD5igxiytyhvljEZNLOOtl0wYFjXX0tZEmNAHRzIhpT7tcxhP zhpqHNHUExgwXRg0C7V8Td9kBzy28quR+sSuMb71p3yoPUFYceY8vNbFN1m04x6X8pfATSYzsWs 7pZTP7O96rfQLYguXp+4eYnnGH4NWQws1j+7fw58ze/v87az7bkcZMQTjHH2PaFJhnAslOvFV+b HbwPrdmxewY3kanRZbg== X-Proofpoint-ORIG-GUID: 3ATEQ3fmkWyaOnupf3i4dzAYIhj53tkj X-Authority-Analysis: v=2.4 cv=FqQ1OWrq c=1 sm=1 tr=0 ts=6a510fca cx=c_pps a=5BHTudwdYE3Te8bg5FgnPg==:117 a=5BHTudwdYE3Te8bg5FgnPg==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=LQnWXxm1RwZjr7XDrSkA:9 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfXzeiTNTF2SUFK 4wZm1OJedRcMWqZYzu76aJLbHN7AHYjADkCYerH9bGBC7tZ0E8IU/Zl+Ws0ehzl8UMfScfl1Qdj XrX/3UlGaKSDKcV9id1K/CCSq3JMTEg= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_04,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 impostorscore=0 clxscore=1015 malwarescore=0 lowpriorityscore=0 priorityscore=1501 bulkscore=0 suspectscore=0 spamscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100153 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.001, RCVD_IN_MSPIKE_WL=0.001, 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: 1783697505541158500 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 7b6d133bec..7deb1a3fd2 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -213,3 +213,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 */ + copy_from_guest_wrap(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 1fe1d7157b..9be8a14a80 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -131,6 +131,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) { @@ -201,6 +222,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 Sun Jul 12 00:33:30 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=1783697446; cv=none; d=zohomail.com; s=zohoarc; b=bC6JM2d0gsdfxp4NsIB/tRPaR9b0t9ZTl1p7mUF+FoeZa1c//5tQhDenXZZATcfz6AmOuSQewVgV38ne3pQJTGPN8OoQzB/MDSxmvFymzuH1wS7AWkrwuhNILJ8O/n6BqngLpLOuCc3XDvz81Lvyhk5iwqBybHSyf7ERpf4W8XQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783697446; 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=IF9TW55XEtxMsH/zIq0l47zFW3oV5V4H8owPWhsqZjQ=; b=FS76Oankp+UDBnWWADc5RIW7a6qIneNdkbOOTYx96DKlaFgMIEdAcoMHGv/d+8z7E0MieV7gz1obw6XydAQz2K+nRMjWOdbL6W9xe3w4jFar1yWCJCVEunwyUwvv7pbw8Gz/LJz3i4s0eWfWSFjIu9m23oQB8isdOlOGLpGOGkI= 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 1783697446671880.9453476772458; Fri, 10 Jul 2026 08:30:46 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiDAL-0001tt-BZ; Fri, 10 Jul 2026 11:29:25 -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 1wiDAJ-0001ri-Mm; Fri, 10 Jul 2026 11:29:23 -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 1wiDAG-0004Eg-E5; Fri, 10 Jul 2026 11:29:23 -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 66AEmM7q1164399; Fri, 10 Jul 2026 15:29:14 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 4f6sw57f6c-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:13 +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 66AFJeaQ015235; Fri, 10 Jul 2026 15:29:12 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 4f7f6yj8yb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:12 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 66AFT9eg23069364 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jul 2026 15:29:09 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 0C5082004B; Fri, 10 Jul 2026 15:29:09 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DA69F20043; Fri, 10 Jul 2026 15:29:08 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.196.135]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 10 Jul 2026 15:29:08 +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=IF9TW55XEtxMsH/zI q0l47zFW3oV5V4H8owPWhsqZjQ=; b=IWy+Wm6dRCYpAp5cnvPsCoYNet0gmuRCN QhrL+tm3o0NNtdB55AKZed25TdVgBToNfXB/hFmlteLasUrhZF7rRFpAbcENtyTe UoBCtObCztxfvpNYGHQFePZ+VIBX0WvR9CHEJcLSO+/5NAjjUySfM+GnTaGoAFqo M/PuTNFfWnTMFu8qt+WLi3eTVOOJZEQHS59+/DYsJKmj/xCg330wg91ksuzFR7FD s6+nQRNaBpgrXuLH8QafuztqW/C26Eje8M1Tu2wKBd/Q7LYx8c7hgygqmHQ7zY/W dsmZB87wYWYeJPuDhGx6uaL3aYnFbzU5sqqqujcFn2n5w9nMUbbnQ== 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 v12 08/17] target/s390x: Minimal AES XTS support for cpacf pcc instruction Date: Fri, 10 Jul 2026 17:28:54 +0200 Message-ID: <20260710152906.80207-9-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260710152906.80207-1-freude@linux.ibm.com> References: <20260710152906.80207-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: TrPr0sofbaxLbfvS7rnfCAOt_qgtsIup X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfXxr06OYUxpbtS onXoDHaieZyYQ7lAnLFJTXZh6ui84GsTg6z1WfznHuvWHoNqY+T1dhQOAEE1CYjXDBu1KXCN8xe O0hfkFJbBnaJ7XqbCTUv1xNISebyFhxcfqpWNLu5IH5mNfe5NIb2uTx9WKAicnymDS9md8bVtW9 5syXnD79Pf/ojZMp4H42fcKll7DbHDJixA8/O7lQxdayBOdkmdNnJS4zAtaoUN9x2mEIf79b5c1 ZbYlD2qVrIeMaJvm0iHmEzZygYkaw8nn4tvdqp6LHMqpn6w6nuAvaU0AkRfHIhiCcfkzfO0WxiZ iWf3g101I0u7xENqeFrS52YuY7ogLym6O16vbyAEazN39fOmDMmd75da4IeAIMBdkY/jsd4NRGD e3dw0osrW3Uxdm+mNzgh4tzo16W5vMr0uH7fDK9LYrwCBzlXZRqxs4uOBrVHDh1CGDVMKzWUPYb dA43nan7iPoFNMKDKrQ== X-Proofpoint-ORIG-GUID: TrPr0sofbaxLbfvS7rnfCAOt_qgtsIup X-Authority-Analysis: v=2.4 cv=FqQ1OWrq c=1 sm=1 tr=0 ts=6a510fc9 cx=c_pps a=aDMHemPKRhS1OARIsFnwRA==:117 a=aDMHemPKRhS1OARIsFnwRA==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=WW2E3BMAMqXElFb4OSsA:9 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX8SxOgSfRbNsZ CqzfYINZflur/kdH8QP8ErpJ53l3UcqgV6r9o7BdNX+9n9VAlN01AU9d16RS/4Apg4q2crkw9P5 WOu63/GHxz9lDDbdG5AgahJk83qT0Wk= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_04,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 impostorscore=0 clxscore=1015 malwarescore=0 lowpriorityscore=0 priorityscore=1501 bulkscore=0 suspectscore=0 spamscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100153 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.001, RCVD_IN_MSPIKE_WL=0.001, 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: 1783697447004158500 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 7deb1a3fd2..e15230d5e3 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -283,3 +283,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 */ + copy_from_guest_wrap(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 */ + copy_from_guest_wrap(env, mmu_idx, ra, param_addr, key, keysize); + + /* fetch tweak from param block into tweak */ + copy_from_guest_wrap(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 */ + copy_to_guest_wrap(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 9be8a14a80..1d447cef30 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -169,6 +169,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) { @@ -225,6 +242,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 Sun Jul 12 00:33:30 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=1783697396; cv=none; d=zohomail.com; s=zohoarc; b=WL9n0Ah1fxFTq85/cfXNW3sEFR3SFOrUhe3BOXir5PjW7wUBlvMXCkXfq3YYFrvbSDjYbVji/DTX2+yrEBYwbfpQy4qQXgjgjeCmjekhHKPRzNPMc5/qm7AExzHX//OxDrtpAeoLsywxlktyBa21gXmcQUbwsaP6KpIggV2LL2k= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783697396; 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=2419BazIBPWgTDLVmoiNJgKSDjfV/oHOK66ZrUHy/GA=; b=J31ShmrKc+DfzjClHXsO4x7boo40D0l1YoM7jKlejdWYqo+r6TfPDgUD4smmqRFbyUSOajVjre0xv56JbbbeBHDhv/7OpfGjzpZWNYa5mEinRP/7D2tIJSesrKJRxksB+biEOU43JieyxpqvIv7W7glkcmdYXkk6YMmuUJ2VtSo= 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 1783697396098308.0670636383802; Fri, 10 Jul 2026 08:29:56 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiDAL-0001uT-Si; Fri, 10 Jul 2026 11:29:25 -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 1wiDAJ-0001ro-RR; Fri, 10 Jul 2026 11:29:23 -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 1wiDAG-0004F2-Ll; Fri, 10 Jul 2026 11:29:23 -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 66AEn89c491586; Fri, 10 Jul 2026 15:29:14 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 4f6stt7hs7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:14 +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 66AFJdKJ003153; Fri, 10 Jul 2026 15:29:13 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7cvwjt2f-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:13 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 66AFT9Aq14877164 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jul 2026 15:29:09 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 36CBF20040; Fri, 10 Jul 2026 15:29:09 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 108C82004D; Fri, 10 Jul 2026 15:29:09 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.196.135]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 10 Jul 2026 15:29:09 +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=2419BazIBPWgTDLVm oiNJgKSDjfV/oHOK66ZrUHy/GA=; b=ATI2ON3zJU8WZr2WnxxJS0CPAPzBa+iXI 2fh2HtwRXFGDJ+jaf2oa7t+ldz4wweTT+L4PEN1D9wv04llNbTb1pc3cvE4MCGKP lPJoUgYLt20lX7UrwdKto7zaKC3QV/MCTJ4kixwNBnLOMUMr4YvxWqADxhjn3E/U maqSm0o+ZaYOin4olPuPa3zj/KA4PAxG13k9LNScqfsmQEeJ8e7L1w/xg6Tmg+/m V1yiQCsPV4kVhFBhyR+RjK6R/2rEPZpOdwQoSODQrFhVUHaotUaFsUor+Dv1YDyF 3wA1WK21NZnJFpndK7qOIYOCoYBsZG7Clf34Td031KVOkWXb3YnDg== 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 v12 09/17] target/s390x: Support AES XTS for cpacf km instruction Date: Fri, 10 Jul 2026 17:28:55 +0200 Message-ID: <20260710152906.80207-10-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260710152906.80207-1-freude@linux.ibm.com> References: <20260710152906.80207-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: eP09DKiujcH9CoM-fHGOPN4hCWKxmZcb X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfXyARiKDLJggFT bq2GP0yVnV7l97/HUzb1ddngzbxBNTRs3mUcVfMWpQ6PkH/8tnqYLWcwv2ldRyMzuvicUBkVjNQ Pc8ZWa8xlLIwPGg1tnWoyGRUS2ZZi4Q= X-Authority-Analysis: v=2.4 cv=DKW/JSNb c=1 sm=1 tr=0 ts=6a510fca cx=c_pps a=5BHTudwdYE3Te8bg5FgnPg==:117 a=5BHTudwdYE3Te8bg5FgnPg==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=RzCfie-kr_QcCd8fBx8p:22 a=VnNF1IyMAAAA:8 a=NfUx3EYS-SKBlRlFgzgA:9 X-Proofpoint-GUID: eP09DKiujcH9CoM-fHGOPN4hCWKxmZcb X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX+QXzrjeWtIZY qK1gRA5R3MSXlo9U/aY27aMfQRyVpQdd16N4612uhLxBL5uxRnLfwd6VmxiAHlLor/OYMJa5kBb Fx5lNJyRnxKWzWLSxtR5wKfip0249bzOjZVQPpOi0hiGpk1KkLKl6eVebNCcubSi78eCB/fE5Ro bMdiyHRaJ7N33n2+mPffoDTJrruapG2ru9XJ4vl7s7sANrZh17uW2cj/vZgxB6z4juOQn/PffCA 7U06zCXE1L/gxEmU1M63FyWIX4OTS8MLHsyloF+hItBtQWUuFwkWHT2++hQ1V861nU27kZEzr11 1ZrHbEBTLkdnye7p1hXsFqBsHXMjjaHaPvphZe7abNpdEnO7sv6tck1pQUj8PCsmfa/bZMZ08GY a3nBxYs3aitX8BQFupaZRPDJ32ILT7B1Fug+PRL5/q10bWLtjq7s6gFI6DByht0sEP0fkelhy1z s6ORxuIeElYp/t7PjCg== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_04,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 bulkscore=0 clxscore=1015 phishscore=0 impostorscore=0 priorityscore=1501 adultscore=0 lowpriorityscore=0 suspectscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100153 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.001, RCVD_IN_MSPIKE_WL=0.001, 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: 1783697396776158500 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 e15230d5e3..13d5cdff42 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -337,3 +337,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 */ + copy_from_guest_wrap(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 */ + copy_from_guest_wrap(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 */ + copy_to_guest_wrap(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 1d447cef30..564f7fa243 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -103,6 +103,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 Sun Jul 12 00:33:30 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=1783697426; cv=none; d=zohomail.com; s=zohoarc; b=Pj3/4DDk9N90iViVMA9M1ESIL460igm9EWlcWil8xdwh839ey4h7tcRViVNar91ndZNFdZIOXoJerV4kauYXqjiEm3q5UpFB8E52pjGQh6W4GCajdoODjcBFNSz/pstfuiIt6Up/eRO1cDPvTnxUqi8aBRVXjW9Jk57FmcZ/zPA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783697426; 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=Jk5moPdrXc9aQmeghF2zfNWd4aiJcnkAJzlqEsomAdU=; b=aHHpnRipRJnuwQay6Tuzw8ZaGDMW/yuVGEX+C74MTYLoWVBRsZ3mH+qVqWssBztT8gR+k+oGtKgQUjM7KFLj+ijdNbCQ3/1bzbEZ45aXm/vyU0vU4wnZz1xsJw3oXqjsQPlfGskijMzd/FrC8U7eAgVOKSbFiooedJ2V7WrpU7o= 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 178369742644827.209401662537516; Fri, 10 Jul 2026 08:30:26 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiDAP-0001yc-Si; Fri, 10 Jul 2026 11:29: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 1wiDAM-0001vz-QL; Fri, 10 Jul 2026 11:29:26 -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 1wiDAH-0004FT-I5; Fri, 10 Jul 2026 11:29:26 -0400 Received: from pps.filterd (m0360083.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66AEmTdI1406446; Fri, 10 Jul 2026 15:29:14 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 4fafh0cprg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:14 +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 66AFJh7q015250; Fri, 10 Jul 2026 15:29:13 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 4f7f6yj8yc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:13 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 66AFT90623069372 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jul 2026 15:29:09 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6A8AD20040; Fri, 10 Jul 2026 15:29:09 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3B2E220043; Fri, 10 Jul 2026 15:29:09 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.196.135]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 10 Jul 2026 15:29:09 +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=Jk5moPdrXc9aQmegh F2zfNWd4aiJcnkAJzlqEsomAdU=; b=qwf3SC4JvmUZ0qwhIoCk3wqg7ApkzEYMr QSjOhMrXzCsJTTkDyful5u3a9v3+LUsK6H/7hviiPA8kA9nD14pLlFSzrJ9nuE6K DG7VRqLrWvgvWBu+WPuk8jXYwfefa0il9i4DUscSLG0Adk5efYzG14Jm/FYFtTv0 oOhlb5RiHCvdFKEGSqxwU0fKSJ8nzNSmeJSEQPN/yvVFA16Bpt8ulwaM2EaCtyl4 Ncjb6uuAV2PiyYtIcLyzlrn3ic7KYwe2Xvjzb0kJLKW6D0P23RYx6fmHGDFaamVV 5mhCBZmyTD73K6ojY3QGk7VzYio7v4fHgT5mugk35PdmDynzcSB6w== 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 v12 10/17] target/s390x: Base support for cpacf protected keys and pckmo Date: Fri, 10 Jul 2026 17:28:56 +0200 Message-ID: <20260710152906.80207-11-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260710152906.80207-1-freude@linux.ibm.com> References: <20260710152906.80207-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=VebH+lp9 c=1 sm=1 tr=0 ts=6a510fca cx=c_pps a=aDMHemPKRhS1OARIsFnwRA==:117 a=aDMHemPKRhS1OARIsFnwRA==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=iQ6ETzBq9ecOQQE5vZCe:22 a=VnNF1IyMAAAA:8 a=c7LoGp8Tn7I-ceKYaY8A:9 X-Proofpoint-GUID: gn67LIa9bP0xhWCoscYAil1twQ1Ktvcj X-Proofpoint-ORIG-GUID: gn67LIa9bP0xhWCoscYAil1twQ1Ktvcj X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX6rb7w/vnVvEY XXMRDrp0nkU79qKAxXgW4Svod6Ooo6SFRKD1AJnQQHRcaO2+Lq0R8eEdEZLhIXrc0cWZ4MYewqF 1g87X107MeV5s6ie5mq7fWjwlagwTdM= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX6YcU24N+CJzw Q8JXIlULgKeeIF4vd9WVsiKcfsBR1I1oJxOKqH+8xnp50xpPMMj/KGb73YXVzR0pXjwsVb+dZi6 GnzaToByEIIxRkkzE1w7pIwraJ5Ir7JKn+t0qql14SPkRnm3OKL+8YSPTI2NCpKUvz00knWuc6E 7vShrEMxQqNYTv85oY0qqgVyvVNCE4EMlo2GBWYZWjGLpT7w6FM9kOGlifChue7w2mxarPMpTNV QhjtaZlAFJBQtoiK1H19MJDphOCeU+jWbFetM1F6VOx3hZMUcsHCJz4Oqs7sLjJcdZuxwWudgo/ aYtElqkikoBmIJUMOZHqsTRCpJnP8JtAfQi+eVylXlMnffl5D4L6qj++3Ibbis3hMkE0/rILw4b lNPyVz/uTzPES2x8hBdxsEq6yYMyme40cTdNLpchuYMJbUYSYIQioxrWC+AEcy+CDQkm/eBttSf wdHcRff2l0Gsbb3QDyg== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_04,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 suspectscore=0 clxscore=1015 malwarescore=0 impostorscore=0 phishscore=0 lowpriorityscore=0 adultscore=0 spamscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100153 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.001, RCVD_IN_MSPIKE_WL=0.001, 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: 1783697426790158500 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 13d5cdff42..bc92884ff9 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -418,3 +418,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 */ + copy_from_guest_wrap(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 */ + copy_to_guest_wrap(env, mmu_idx, ra, param_addr, key, keysize); + /* followed by the fake wkvp */ + copy_to_guest_wrap(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 564f7fa243..08151e916f 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -192,6 +192,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) { @@ -251,6 +269,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 Sun Jul 12 00:33:30 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=1783697453; cv=none; d=zohomail.com; s=zohoarc; b=fp7z28Mv85kxassnMxAo/DDA0rVg7uHKpHzads7T35AzGjCDAx80iwMHy5U74ZSyNy3FSkCLRUhbA7iAOV86JSwrgof93FPatUv+LFT5FcXcBNeK8z0ASIxd/Eq5mN+J73Ls/DdmhZGJc0wAKzYCBuBG35dN3qaezKpEyJDUQKM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783697453; 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=ueqtySTOiep3/VPxKzaZoB8dIjfhZCYHQfpKYNFVDdM=; b=DU/IRH7zMBc/DmF8MPchfZUdnXENRuek0qio1v9q2S5a3+i1cov1Z8PBNVYGUNv4kSLHtPlDWBmIpIX5+0ROfPgBx4J9bS0ufXfqWAALjn3u3/+lOlJoK3RCPA8GfGHe1783js3ZuujjMvPcGWkmbXAoq1A+CTNtJ92/bAfQDks= 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 178369745357223.65440834079743; Fri, 10 Jul 2026 08:30:53 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiDAK-0001sY-5h; Fri, 10 Jul 2026 11:29:24 -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 1wiDAI-0001qh-6h; Fri, 10 Jul 2026 11:29:22 -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 1wiDAG-0004Ep-At; Fri, 10 Jul 2026 11:29:21 -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 66AEnA6e766570; Fri, 10 Jul 2026 15:29:14 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 4f6rke7kn0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:14 +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 66AFJbWh015708; Fri, 10 Jul 2026 15:29:13 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 4f7cgqjt22-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:13 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 66AFT9UY16384330 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jul 2026 15:29:09 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 95C1E20043; Fri, 10 Jul 2026 15:29:09 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6F80D2004B; Fri, 10 Jul 2026 15:29:09 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.196.135]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 10 Jul 2026 15:29:09 +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=ueqtySTOiep3/VPxK zaZoB8dIjfhZCYHQfpKYNFVDdM=; b=grgh2vBju+BjWFf3WfDXKPIfQok6KLSCh fFGATtmeP0zgYU9CTKgmIDEbNE5mJLuyBsqeaD7DgdGITP9s492eUZhtZtbpp34n 4GJrYBglzF6oJA/oJ+JKVFz/0Y8C0kT3Vql6CjS+QBOv/fKpXMjithBJ+B4b2G0q ghFDI7j+iUxpepj2bdZXsIGFSlBN8Uqw8U263o6aK3CUhjWCKhAuLfPVaZ5zxGca p+Y81EAwmgYDba0HtV8PgHPklgrbeUmkQ1ge5V/P+NUDtxoWO249ZLyMvq8Dx2OV LnXsM280aXHghQFEJC4bk0ZyEJk2XGCGMsvenz+dJWg8DwoLITJeA== 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 v12 11/17] target/s390x: Support protected key AES ECB for cpacf km instruction Date: Fri, 10 Jul 2026 17:28:57 +0200 Message-ID: <20260710152906.80207-12-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260710152906.80207-1-freude@linux.ibm.com> References: <20260710152906.80207-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=M7J97Sws c=1 sm=1 tr=0 ts=6a510fca cx=c_pps a=bLidbwmWQ0KltjZqbj+ezA==:117 a=bLidbwmWQ0KltjZqbj+ezA==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=V8glGbnc2Ofi9Qvn3v5h:22 a=VnNF1IyMAAAA:8 a=WpPIafo2g3WOFiBud6QA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfXz8Txt32oICrq ccVyT9PddxUUt6t7b3MUa0q5PP3jiQ9E0yC945G2m/t9GSJiu4NJDWCb8iscFwE9GybOmTn1QPu zb/1uJcTbURGjtciimOPGhoCS/GrbBY9jOijAN9TTxrMGGzJqR/njtE4WmlIxaFvFQO60kBab0P BBEKpAdEQ7H7U7FHYdZ9do6J188CXRoyQ4zyM/On5wgIj4Q18D/yWHRdGxNHvA9yeVQhhSDbZlL xFAJ6uOQnLEz69L6ZucmMJFSSb4ifFguVcmY8S+bhrwfSALuU9mX1offOG8rH3RqNpP9fZj38P4 gYNw0n1Tn6sRTmZBcYygbcJvD2pM2+b3Roe9Bgwci6aYaCAqWyAGpXLJbFVmMAezxIkcIm+5Hm/ CcXvMcdzmpmsfHBuJ/NMvM9IkrnLyEwtzFm2Pl9qW9i7dg4qftkNlvaIedUMF6QxS8GpxEV70X/ QpHxrjUuQC3AzqRtgeQ== X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX2UIDysiYooiq E5gZCUk8b0sfoTnPxw7iSq3tik1iaE8MBai9UYSEDmujFhvKW3k8FQvzPaxM45pTEpHYOBID90I c83uGiaR7J8hiNiN6HV9O2QRBtA6y+M= X-Proofpoint-GUID: VEuz2yPuF-7Yy-h0KU_afNVrrzyC5q6n X-Proofpoint-ORIG-GUID: VEuz2yPuF-7Yy-h0KU_afNVrrzyC5q6n X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_04,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 lowpriorityscore=0 malwarescore=0 clxscore=1015 adultscore=0 priorityscore=1501 bulkscore=0 spamscore=0 impostorscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100153 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.001, RCVD_IN_MSPIKE_WL=0.001, 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: 1783697455036158500 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 bc92884ff9..a5507d87d5 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -447,6 +447,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) { @@ -482,3 +493,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 */ + copy_from_guest_wrap(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 */ + copy_from_guest_wrap(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 08151e916f..b00351d8c1 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -103,6 +103,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 Sun Jul 12 00:33:30 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=1783697396; cv=none; d=zohomail.com; s=zohoarc; b=NCLyODWd6u49HIYAbBXwoMOzjrJMMVhkElqmOI38hJ+gf4tc1SLSgah835/9Uu18QLe0xtqcWCkrWcL9AF2DgL5Ftce5akyvvTZSPlWPIhwnEsErErUTI/JOxNe4pIcXRk8DpWflMr8KB4e3aj1cTZgRZIoTSNDEkOLquwkLJNs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783697396; 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=Za5AI10BWqKyRRYKPSMr1uatQyzW26DPLuTbUpWswps=; b=Z0rJjZPLUB5AjW6xRM6Mtgu3iPYUPMn8G9XgEKy331WLvHDS0FJj/XLJvORGFhVwV99gQOZE0Aq7SX1VTA8377SBSoFMvaCISneRqBtXbAXhg1FDE2yV61oTSBDXIxERyaL4uzHE2s9cxpy78W218eQgX5UnHWKxRLtNjogK9S0= 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 1783697396119577.5216139487536; Fri, 10 Jul 2026 08:29:56 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiDAM-0001vi-KX; Fri, 10 Jul 2026 11:29:26 -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 1wiDAL-0001tr-9o; Fri, 10 Jul 2026 11:29:25 -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 1wiDAH-0004FX-7J; Fri, 10 Jul 2026 11:29:25 -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 66AEml8N1545582; Fri, 10 Jul 2026 15:29:14 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 4f6qknxqbg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:14 +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 66AFJfaL020974; Fri, 10 Jul 2026 15:29:13 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7dgkjkyk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:13 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 66AFT9Ct31130364 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jul 2026 15:29:09 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C0B9D20043; Fri, 10 Jul 2026 15:29:09 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 99FDA20040; Fri, 10 Jul 2026 15:29:09 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.196.135]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 10 Jul 2026 15:29:09 +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=Za5AI10BWqKyRRYKP SMr1uatQyzW26DPLuTbUpWswps=; b=Rye05ZcLByoCiEi2DkPuZwB4cElr6NiEt GfVqt2fV4b930Q/QDM7MJMI60D8u3Q2Z1hxiN1su6OlGBD9D0OzzIGMfbmCjdnbY 1P6QeQ7Grgb7XVqSJG59LIxn96rhUsag+Q2uxrzd/alL1qge3aTpCjJ9TMXEZV0m pyxuCh61PY4Dz16D+Mn4SG9V3bijpwkMpw/OKxOAPEY42tGsZvcJ/L6ufV/zRIX4 /TrW38RR6/88vHQesejDPED4Ttu3bSgE/VDSm3CWQw+vSfUdZBWcgJkHmcuxmUNp F1Vu70B+UmPZV+o03pKZgqSd6mK4rhConoUaYCLIy5u+mqiyyLgrA== 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 v12 12/17] target/s390x: Support protected key AES CBC for cpacf kmc instruction Date: Fri, 10 Jul 2026 17:28:58 +0200 Message-ID: <20260710152906.80207-13-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260710152906.80207-1-freude@linux.ibm.com> References: <20260710152906.80207-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=Q/XiJY2a c=1 sm=1 tr=0 ts=6a510fca cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=Y2IxJ9c9Rs8Kov3niI8_:22 a=VnNF1IyMAAAA:8 a=8AYr_lYigW3ys9mEaM0A:9 X-Proofpoint-GUID: uXICQb5_qYBlusYkMNVcYCMf6pR0BKGh X-Proofpoint-ORIG-GUID: uXICQb5_qYBlusYkMNVcYCMf6pR0BKGh X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX02DSxJOONPOW JYSMgIgGtCYYKZZ215Fz2i6iFPmqF7ZawZmI985OYT7I/74+ykGw9AnVvlf5f4b9gY2+J+rSwvr SDf7Oz9JoEoXsFZ1NHGvJIstXuQrvXs= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfXw9HeWlNpdWss 2iIzG9JvcDzz8vZgpnGNi7qJOrq0P+awyPtMXWlqK/qUI40w3wj+22ULgo6Dfz3NU6h6T5M8psM WyR5nDduqLJWgNo3dgmsVxfY90WNxIuFdizX4qf5kaHatxJZu7qu/q0fgPBKJMsJJ1Hp8UcQvZa ulBaJb4cO3MCts5cyEevGD0VPKcd9LAtinTATHD1QpMPqkM0RKYyRTZXK//td+8GatjiB0O9noo Dgr0XoXF073yRtyYTTezEuliVhYcHoywP4iAUmxtOtTbLD5ds5o12TsXzhHAgJ9Gs1sOP7sDXbu HhAN02G3VzPdgKvpL9QnstasrajhLtrPiA2HjStJUL6ozQEzQ6zGtnRPp0ErjvP6t7KWQyw7IXh Fx0wYtEED08YxR0ZJa/Rzp1iCa35FBIfM1CgegR4dCzvOj+ZJshrO2CrdFbKjzgelMLAM0TkCJh ML84/pDUdzEV8Rg1ISw== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_04,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 impostorscore=0 spamscore=0 phishscore=0 priorityscore=1501 bulkscore=0 clxscore=1015 lowpriorityscore=0 suspectscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100153 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.001, RCVD_IN_MSPIKE_WL=0.001, 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: 1783697396769158500 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 a5507d87d5..b207ebc954 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -573,3 +573,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 */ + copy_from_guest_wrap(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 */ + copy_from_guest_wrap(env, mmu_idx, ra, param_addr, iv, AES_BLOCK_SIZE); + + /* fetch protected key from param block */ + copy_from_guest_wrap(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 */ + copy_to_guest_wrap(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 b00351d8c1..237ce744b7 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -137,6 +137,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 Sun Jul 12 00:33:30 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=1783697393; cv=none; d=zohomail.com; s=zohoarc; b=gjVYipEvebxZd/HDxOiZqnwdmPH/KiWp7azXeplUTuOxytGDMHYS9y6U7TNgDBtFK17TwT3q5rHqJBPeNLBmUR28eb8YjSSKo1auEWcKsGRyi4YcnJlOIHovzdau7PPY3F0GFGnpM34LPLyGMsWvCPlekbt+ejQxZqJhgExmemA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783697393; 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=QInrnpVNGRAgYpEnMuWrFy7oWjtbqTsnUxXhRdGgCu8=; b=Faktp1wa5x4TADm/NDpBSgVLos7TrwgwzsB8MuFI4YC+gDj9inlL6/AuMS+PG2vVEt8qA7tddJDERgPtFrnDAMDfxXY7FeLzA2r+akZyLbXKZCPtPJaBeA+j9rsIajq3He8yG3zIlsBhaednYFqFE1plgrPbYSYVyTvTh0AJpEY= 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 1783697393640335.6728355526267; Fri, 10 Jul 2026 08:29:53 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiDAQ-0001zi-Pr; Fri, 10 Jul 2026 11:29:30 -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 1wiDAN-0001wJ-0R; Fri, 10 Jul 2026 11:29:27 -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 1wiDAJ-0004GV-3Z; Fri, 10 Jul 2026 11:29:26 -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 66AEmdAJ1164860; Fri, 10 Jul 2026 15:29:14 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 4f6sw57f6g-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:14 +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 66AFJiZI015261; Fri, 10 Jul 2026 15:29:13 GMT Received: from smtprelay05.fra02v.mail.ibm.com ([9.218.2.225]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 4f7f6yj8yd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:13 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay05.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 66AFTAuQ48824658 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jul 2026 15:29:10 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id EAB9820040; Fri, 10 Jul 2026 15:29:09 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C4F2E2004B; Fri, 10 Jul 2026 15:29:09 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.196.135]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 10 Jul 2026 15:29:09 +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=QInrnpVNGRAgYpEnM uWrFy7oWjtbqTsnUxXhRdGgCu8=; b=I0SMXp9hCPcvj5QiJWRyttwMbWlb8BSNh SiFs2kNCkARIbL3007/4YCeaQRmaxZT5ChwEJCdGi9UaHExvTgdSqU9H2FyIFnnD dy+MgOJWiKMzIeDKvfhe4GbAIMkUnKlNuhjit30ZCznbj977QYXtFcVKT8lMYGrM V6AY33sIQsgxHzYJsrV4/OAzX565qZJnNZ+z2zgOQthEHske2WIlbQUsXhh3HydA UKYFgoo1OfQmNCdok4xyBGv27gqz7ZpksWWQ1UgUeZy0osoPJN690VUKXNh21s26 tiexcLjBDral9lHAZ4NYiTyJisb+lTo5XisTuEsYLF6+LgXiNhseg== 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 v12 13/17] target/s390x: Support protected key AES CTR for cpacf kmctr instruction Date: Fri, 10 Jul 2026 17:28:59 +0200 Message-ID: <20260710152906.80207-14-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260710152906.80207-1-freude@linux.ibm.com> References: <20260710152906.80207-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: vPRV6FiHJfUDioWURdvBlP6Vp-rVjrfg X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfXztP9L/IIdueU 3JarSJj3GDziKNfHMz81e0cUoOfAFGMA2SUjevYVPEn2euZlYKODeSjrs0IL3fDYRydmTc/sHjf GTKe+8fNlkeCis2Bxcjr0Ireew5yuYZUjgwDDWRuhW6XRWZT1rr3sUbXAAc5/wZuSzYB+YRkxz8 cDoDqVb/Hg+CwGx71905wFwVrOtyXc0Ox8/a4rDot8jdfj4+A5DQQf59qLLbPABPfoijgsR9x3i 9enrzHVeXghFZDNce8M9l1DVQil2tzUyjLBuC/xXJ80mpLiQW6RIlD5o+Ns49S9Ja5ffAMK0PrU dVdkk/8uqyvpUmhj3+VexKByaY5Js2Nam/Ndl7qsSuXoLUPuB/fQCwreaDpkfdA/mteCzEhGW3e 57y7Rpj9vn110/h0Nc9Uh88W8dp662xDBoUTZRZ5EzRSEsSyTAA+GvpQj7ZZsTun2hBjtVYVvyx 8Z5CFuMRZYZLMMT5IlQ== X-Proofpoint-ORIG-GUID: vPRV6FiHJfUDioWURdvBlP6Vp-rVjrfg X-Authority-Analysis: v=2.4 cv=FqQ1OWrq c=1 sm=1 tr=0 ts=6a510fca cx=c_pps a=aDMHemPKRhS1OARIsFnwRA==:117 a=aDMHemPKRhS1OARIsFnwRA==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=Ff2AzlR8v_7kNCG2J78A:9 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX0JyBHm9kCg0A cHzim0emkFnUwsfOrKpIIb6hG9Ni6NPMEJJ9P79G+kJ4kzhHQkLM3/jtzMyxEsLgNoHvj4jtKCf wFiFKnVR2JkR9IvWr76hteQXuKDq6oY= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_04,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 impostorscore=0 clxscore=1015 malwarescore=0 lowpriorityscore=0 priorityscore=1501 bulkscore=0 suspectscore=0 spamscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100153 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.001, RCVD_IN_MSPIKE_WL=0.001, 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: 1783697394591158500 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 b207ebc954..a38f4cdbd4 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -663,3 +663,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 */ + copy_from_guest_wrap(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 */ + copy_from_guest_wrap(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 237ce744b7..73b2a6557c 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -165,6 +165,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 Sun Jul 12 00:33:30 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=1783697406; cv=none; d=zohomail.com; s=zohoarc; b=IuI7H3oAFRZuvNE2DOPel2fi8gijE2cyQ+QO3U10oOyh0CdBEgoa6h0BTJn6vQsUE4Obfca+OvxJlLqwhn5z7CRmC2IHsqOw2Z4s5X7OK3G1oHwcXQWv/hQKy2QBzWwNjzbJaNiqSxzw0V1Pd+BVHsUcs3phvB5WUUKs0tl6TEw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783697406; 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=+rMdj29e1ietHOKLbCemF84CKWW/oW5k3rSAHcQxyjA=; b=aGSFTQ2/J9JAma1LadRggXummy+5iEcuadT9PGi5Wiy8hDgby0rXFwB1RCkNuE/Iiy23g4FAzWa26tR5GH0CW+b46jiWe7OItxSevqbd1lK5SZDm7GW0qoKtV5SN//PYNG1ZRZVlbNytQiNAN05s3BtISi8zmfPVDs/GBwBi5jM= 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 1783697406595461.99274344290166; Fri, 10 Jul 2026 08:30:06 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiDAL-0001ud-To; Fri, 10 Jul 2026 11:29:25 -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 1wiDAJ-0001s8-Ut; Fri, 10 Jul 2026 11:29:23 -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 1wiDAH-0004FE-1n; Fri, 10 Jul 2026 11:29:23 -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 66AEmm9N1545586; Fri, 10 Jul 2026 15:29:15 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 4f6qknxqbh-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:14 +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 66AFJb5B020515; Fri, 10 Jul 2026 15:29:14 GMT Received: from smtprelay05.fra02v.mail.ibm.com ([9.218.2.225]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7dgkjkym-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:13 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay05.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 66AFTAHS48824660 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jul 2026 15:29:10 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2094920043; Fri, 10 Jul 2026 15:29:10 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id EEF1B2004D; Fri, 10 Jul 2026 15:29:09 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.196.135]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 10 Jul 2026 15:29:09 +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=+rMdj29e1ietHOKLb CemF84CKWW/oW5k3rSAHcQxyjA=; b=nJJhhZ+rn82fVNKGM2YZ1r5pEsxlejLX/ crE7+HJpZ+6AVTqle5kXuul/XE0AwOfpFmFd4AZ84kOF4u3DWQp6cReAwizUUCFk gHPqqSAoB8YAsCLyT0EvfTisGlQVQWoFudlCLXLPnvHDoJk+5p00lahqNY5udey8 R7yb8mMtJk/B2p9KR3RPBICEHCKDTCosK91JWf1otXJSuOvReO115qZD4H4cYRe6 8+MiR/biKsfxJA3/BZDhcicIRWXOc6DRpUh3BKfU0Mybbpc/EZaol7d7cPMbH+hC uSl+1Vu2PsbDN0A8NysiBbumx5hU0yV+L2dKDgbqKP3S9XgvfYwjQ== 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 v12 14/17] target/s390x: Minimal protected key AES XTS support for cpacf pcc instruction Date: Fri, 10 Jul 2026 17:29:00 +0200 Message-ID: <20260710152906.80207-15-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260710152906.80207-1-freude@linux.ibm.com> References: <20260710152906.80207-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=Q/XiJY2a c=1 sm=1 tr=0 ts=6a510fca cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=Y2IxJ9c9Rs8Kov3niI8_:22 a=VnNF1IyMAAAA:8 a=tkYQr5ag8MGam-WK_qUA:9 X-Proofpoint-GUID: kQn0QZcMMZ0Bu-tnXK90Ug1XxGw2CWZm X-Proofpoint-ORIG-GUID: kQn0QZcMMZ0Bu-tnXK90Ug1XxGw2CWZm X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfXy3E/kjC3tomD dqfBDdYbBAzPsvSTdeRDmqgBKX9PRHchskPVh9eQcNR08lu+Jeb1AuNiaRksArK+vO1QLC/KJN6 Po260DV4Q9d2/DDfmg/f1ElwH7tqVmM= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX7Gh7cOc2hQYy OprsR3XufzL5u8dvbVjsIP54OFsDHx8zC1fIiia6/Vxn5qVDFAuYKWwVZI3vZWcG1S7vJGrgp8k pxmTKuJy3w+TOm/FY4DLMYmdrdwWw7dIe8ukrsLZo/7wFcg/fzYSxLba0f10FLE/BLsyDa8txv+ Up+VBdbZhfoHRW4pRZzy6qZseHCqYdDBGqH7Wd3uJh9FCinDkKZTu7KfOJ0ufYfshW+i2BAM8Pl H7dzC6xm/7e/Fy6PX0puaZJkc3V6zchmFes1XctzFgg3i0uHHnaFqFfZjzlij+YpxkIl2qDGnak U/3mcJk6jsZ4yEa1ZApzGex0hUMyU7rNOw5Xt1BxlNDH8ulpclzEw+BNmv1ibnCj6U+FoibNDA1 uiA8eHSIsolgsnQxB3HwVPUBUVEXO4SjlvBIshr4mRW/LZv5B0p60Jvbps0zUN9KcTwTf33bb7z A5tO2q1YJTVF3DdlLbw== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_04,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 impostorscore=0 spamscore=0 phishscore=0 priorityscore=1501 bulkscore=0 clxscore=1015 lowpriorityscore=0 suspectscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100153 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.001, RCVD_IN_MSPIKE_WL=0.001, 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: 1783697408723158500 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 a38f4cdbd4..a53c59d488 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -743,3 +743,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 */ + copy_from_guest_wrap(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 */ + copy_from_guest_wrap(env, mmu_idx, ra, + param_addr + keysize + sizeof(wkvp) + AES_BLOCK_S= IZE, + 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 */ + copy_from_guest_wrap(env, mmu_idx, ra, param_addr, key, keysize); + /* decrypt the protected key */ + decrypt_protkey(key, keysize); + + /* fetch tweak from param block into tweak */ + copy_from_guest_wrap(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 */ + copy_to_guest_wrap(env, mmu_idx, ra, + param_addr + keysize + sizeof(wkvp) + 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 73b2a6557c..5e924b78f5 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -206,6 +206,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 Sun Jul 12 00:33:30 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=1783697559; cv=none; d=zohomail.com; s=zohoarc; b=O59c4uyk1QI5hiiPQ+gdTwDLkgEmIQIKEeiBXY97oUsrpCxy22U+4NajtJZhHc/8uMFBoaa+NffHh9Za/DENFQ1fH7H6GHFG8u7GyYF4XmXPVwv9fRk8ySPssKpLtVbNT7t0NvYGqZAwX0sSxmBkTc7pheqOVtIFBsOPWEzW0iU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783697559; 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=irWtw/zx0j1a+Ojopf/0It0+i3iGzSr+JCkBUCuqt9I=; b=BtLHep+wUGuubLrgSzmZncj5TA/gyeE6u7fZ5HgPiU+oVr5YRBjy8aFgOz40p6gzOtozMqGQFxTBtfJ2ld8MghLrwPEjbFLC5FHcpXuOxi6gx8QQRfCK0ouCWaAeTDSjTCH6cRXrf1WMR6LQBTnA5RLbxouDdUUIhLXXGFaw+u8= 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 1783697559954383.0173451288473; Fri, 10 Jul 2026 08:32:39 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiDAO-0001x6-3E; Fri, 10 Jul 2026 11:29:28 -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 1wiDAL-0001tq-6n; Fri, 10 Jul 2026 11:29:25 -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 1wiDAH-0004Ey-2H; Fri, 10 Jul 2026 11:29:24 -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 66AEmTDm1164607; Fri, 10 Jul 2026 15:29:15 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 4f6sw57f6j-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:15 +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 66AFJjmZ003178; Fri, 10 Jul 2026 15:29:14 GMT Received: from smtprelay05.fra02v.mail.ibm.com ([9.218.2.225]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7cvwjt2g-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:14 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay05.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 66AFTAt348824662 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jul 2026 15:29:10 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4B8FF20043; Fri, 10 Jul 2026 15:29:10 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 24FED20040; Fri, 10 Jul 2026 15:29:10 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.196.135]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 10 Jul 2026 15:29:10 +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=irWtw/zx0j1a+Ojop f/0It0+i3iGzSr+JCkBUCuqt9I=; b=Mz4Aej3GoBZyy54tOKPymGxFb4pi/jKUg LIBYgqK5ZW8brGO+o1e9YYRQ/Dmd2gMcBgowZBxLvTjIrPf6VCyv00c3WmlrmESl Ipzzl2XOLUs8yrVXv6Z1VSCKB6z3Amy0frq69ZR4dp6siEsqgP7RGYXO5ffJdBj0 aZnuW1R8p3wpkxfXf4I0I19r9hcHYMiuHgJ5rhGQl3BHMOVNbk4otY7o+W4ny8Lx CPyew7p895/oL9AzaRwpzFqqaXql0AaDaX74nx4bGNYMkjshiDAQXv4bhryMUovK js22lcUxN9SEsB1TQ7Unbyuic9JoXTovJWwiNcNBH2nU8aj/gwMvg== 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 v12 15/17] target/s390x: Support protected key AES XTS for cpacf km instruction Date: Fri, 10 Jul 2026 17:29:01 +0200 Message-ID: <20260710152906.80207-16-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260710152906.80207-1-freude@linux.ibm.com> References: <20260710152906.80207-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: ku-3G40n5Sgv-S7iIr9sSiVfBOdFMgil X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX6jKXr+ipzgxH rK6YfEq/Dg0hp7y2fAKutcFjbIdeP7mQP8igDTypQz8zw/PX4uBBfZ7w8A9r2KYMZE1+lAYKPvd 7J+1yZMj/JaG1gWqoE0lxZzEiVKZUX10ih9+/pK4LxiVuPgUMgUEML5sutcWEU5kLF2ruUzP475 gfYeQCPFevwmTKMobimOOl8Pm9BUyAk8z2aMxKMirQ7azq2DT0sF3XRrrG/saVo7PRa245ljFfa xH8tovwSBBQTjWbNeIDG8CobyL2TkqjHmssJywAi1AxsQaavRoouARgRFaTX/tEEvxglRANaWOB AS+uDcwyOKhwgS7k+O3lLOTQ2aZfkEQe5zW/vYsD7AXMISOh+eS47ckLwPXdXmFSV2ge+QSNlwo 9MwI7bJwiwFB3YgLgMZJVhGNEBLxqEgoUZfRGcm2RHVx32UMmGR0SxASt+HfEt3e9zj/vHRAuG7 L/LFzCo2ATJusCexdnw== X-Proofpoint-ORIG-GUID: ku-3G40n5Sgv-S7iIr9sSiVfBOdFMgil X-Authority-Analysis: v=2.4 cv=FqQ1OWrq c=1 sm=1 tr=0 ts=6a510fcb cx=c_pps a=5BHTudwdYE3Te8bg5FgnPg==:117 a=5BHTudwdYE3Te8bg5FgnPg==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=D0XGIOQStSI5JxgU9CcA:9 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX5tJEO9iIDKTB fQ3I5re6HP0TZKUQgNtErsPGsimKekrJCkZs8hvLGqLIEwjqABB/6ExsjxI1jyG04pW65h2GNzt AoTyuy+maZC32hmgcL4XQy+JLQZrLPk= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_04,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 impostorscore=0 clxscore=1015 malwarescore=0 lowpriorityscore=0 priorityscore=1501 bulkscore=0 suspectscore=0 spamscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100153 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.001, RCVD_IN_MSPIKE_WL=0.001, 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: 1783697561989158500 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 a53c59d488..173e5f1b61 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -808,3 +808,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 */ + copy_from_guest_wrap(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 */ + copy_from_guest_wrap(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 */ + copy_from_guest_wrap(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 */ + copy_to_guest_wrap(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 5e924b78f5..6172012979 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -116,6 +116,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 Sun Jul 12 00:33:30 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=1783697533; cv=none; d=zohomail.com; s=zohoarc; b=OZ0fCJ2lNiSt2N35Kj+3INgOimRAB2f/umT1H7YqUrATp1ubmnI4tMR/CmvzujL2nHQSFJwdDQthy0cWT12JQjbX1LeQ2jMCullXc8fogggLUUHQ3jYfEICn4JYH5l4kMPnSnwd6WaZkNh23eCsEuFS6u5bwBXemwh3TkjKuFmM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783697533; 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=JX52dDCOJedeCYe6dEedwFwkxEmkUNBwOksMcAyM74M=; b=j7nNPq2mt6+J75dhpN8LNvyYTQWpb3MUgy8u3RTjCcpGU5epksDzzIMVtyQRCzqjU03WNgCoLLhzu3OK3P8F30TGigNpU/+J4LhRPeEnq9LxQYY5gnOQJnEm2g4Bfha/3ni5haoxUiZSam0XJfYtr7Jlhe75R908ZFxl3Ikb4hY= 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 1783697533734784.7280710550417; Fri, 10 Jul 2026 08:32:13 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiDAO-0001xL-IA; Fri, 10 Jul 2026 11:29:28 -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 1wiDAL-0001uE-LJ; Fri, 10 Jul 2026 11:29:25 -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 1wiDAH-0004F9-AL; Fri, 10 Jul 2026 11:29:25 -0400 Received: from pps.filterd (m0360083.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 66AEmMrl1406288; Fri, 10 Jul 2026 15:29:15 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 4fafh0cprm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:15 +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 66AFK4la012079; Fri, 10 Jul 2026 15:29:14 GMT Received: from smtprelay05.fra02v.mail.ibm.com ([9.218.2.225]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4f7eqgjd1n-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:14 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay05.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 66AFTAcJ48824664 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jul 2026 15:29:10 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7836D20040; Fri, 10 Jul 2026 15:29:10 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 500492004B; Fri, 10 Jul 2026 15:29:10 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.196.135]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 10 Jul 2026 15:29:10 +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=JX52dDCOJedeCYe6d EedwFwkxEmkUNBwOksMcAyM74M=; b=McwHAbsLMbBEHJzytjK/6DLsr+1WU39Vn oRpAU8CHh2QSW0xawW0dIA4zFdl7sfKtKgzqEA9zTk2PfQvfjfDcPaiOgpISv3/b Nxx+FFnwyhXspg0evC1DSAF1F2XnLxB88hlhtUIN9d6F9oAvnHSa+6843bjP2EDM 1QbfOzDT04Ja7dpD3ugyEMykvo9q+mb22VcWTTvpqgvQ8D7KuEUK2cwCCRCWw62D lExz/0qiTPN7AWy0wIKpfcG99ST8TURi8ZLOHtkwXdFEebRHawHjjC0OHmNJYq5h jfjH+YSmTfWSKsMkT51E3HAQiIHXY2au4/CxsaGpXkO4v0TJxhSpQ== 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 v12 16/17] docs/s390: Document CPACF instructions support Date: Fri, 10 Jul 2026 17:29:02 +0200 Message-ID: <20260710152906.80207-17-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260710152906.80207-1-freude@linux.ibm.com> References: <20260710152906.80207-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=VebH+lp9 c=1 sm=1 tr=0 ts=6a510fcb cx=c_pps a=AfN7/Ok6k8XGzOShvHwTGQ==:117 a=AfN7/Ok6k8XGzOShvHwTGQ==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=iQ6ETzBq9ecOQQE5vZCe:22 a=VnNF1IyMAAAA:8 a=IlYB4z8HrC9mJJy16gAA:9 a=5wi_FRADO1KgGG3s:21 a=O8hF6Hzn-FEA:10 X-Proofpoint-GUID: TVwGE350OMm74t0NgDykXCLNWKlfTrz- X-Proofpoint-ORIG-GUID: TVwGE350OMm74t0NgDykXCLNWKlfTrz- X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX1WqJ9ddci7jS 85U95Hy/MhXiRe8hn7rBd/cZV2a1oZyud0TxtX1Nr6OdFnZphUUIwvl4FtE1u8pBXOLUbfVcPO5 klpdg85l1AhjmdFZMql782lN3sYstSo= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX9qkGN1s3VTKD vrnWKnW446yDN36nnB4z4nnPRVsbC1a/K0ZFiY9OEH4a6MEBHQbd8VJhc0KcjdrW2R2RMDoM3pG 0gWy+yE6H2bjUnFDOzV6d0P2u/Y563LtMS+cjnsefmYExAkUXH360X9kUNol5vVdvq/glg/1sSK qdvNM7JmRr/ittdGckvg3v4HiWfBMg7vOKX+DSHSKKjgOnqcGn8es3wB4rGQmBxgAWToWBZZl7+ 1cmmb9NIpmUjFSpXJlGCVMw99ej0XTmkYNoF+8s7y24pLcnnEDOLQAhZLPuJQGvAJU6HrD+1yzo ba/8DRqU6fnKJPhK/c2Nx3ni7Eya0ABBoD6onySCJkeGP1sRu90lvlohGYYinmvrJxgwob0FFyQ mVbPTk6oHkBicSamntHYywcXW0LxJ5jpPxt94Dbe2YWPjY3701XuxmeWDkkwub3JVU8xj0MglOq nk7zlDwWWwpFcoIAL1Q== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_04,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 suspectscore=0 clxscore=1015 malwarescore=0 impostorscore=0 phishscore=0 lowpriorityscore=0 adultscore=0 spamscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100153 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.001, RCVD_IN_MSPIKE_WL=0.001, 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: 1783697535731158501 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 --- 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 Sun Jul 12 00:33:30 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=1783697404; cv=none; d=zohomail.com; s=zohoarc; b=Bddww5f8yBPhM5NCU4MygpBMZVZ6wDsGPCE1EElmzZ+FOgN6zHE5aHtrXbtqDDs7uYU7uen6ZRkPH9fCz7hUVwmv6x/X6Vhn9AYt12cEZ4hQqKL65/SVDxwDT22Fu/h/Nd9Z2hRe20m1Ye+73dRyUkTG+SlqByIKC1+CYaEgUrI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783697404; 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=Vu6EgR44CusjNgI3ODdMh0Fstw6fGfYwALXVRC7HGXE=; b=k6IjYLYVXpuBIB9kZB/KD1jtwkhw6Q8SJkdDs8XkigeXAljlguxfRTdZrehykpQEYKYztK0W1BvHvexxnb8g31HYcaDU/czBZ/h46EiO6v7BUUUDIrFGLPqPmgk6/8qBjKqM9u1gXghXCw2UShcyo50QZA8k/RA65jsH1xn089E= 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 178369740438397.22885064103855; Fri, 10 Jul 2026 08:30:04 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wiDAk-00029e-LF; Fri, 10 Jul 2026 11:29:50 -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 1wiDAi-00029D-R0; Fri, 10 Jul 2026 11:29: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 1wiDAd-0004Gk-E8; Fri, 10 Jul 2026 11:29:48 -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 66AEmHFP1906959; Fri, 10 Jul 2026 15:29:17 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 4f6sur75sq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:17 +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 66AFJdKK003153; Fri, 10 Jul 2026 15:29:16 GMT Received: from smtprelay05.fra02v.mail.ibm.com ([9.218.2.225]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7cvwjt2h-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 10 Jul 2026 15:29:15 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay05.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 66AFTAwD48824666 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 10 Jul 2026 15:29:11 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id BB99820040; Fri, 10 Jul 2026 15:29:10 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7DADE20043; Fri, 10 Jul 2026 15:29:10 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.196.135]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Fri, 10 Jul 2026 15:29:10 +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=Vu6EgR44CusjNgI3O DdMh0Fstw6fGfYwALXVRC7HGXE=; b=GMWHm1lbFiVqBz+h4pESEqDyXvFUNywr4 v4l7DnpWwViRaoiTXKFshbG83CR7Tc+q56nCrrjlyx4q+bq2UM0wCUASh3BTfmo6 a5SOOwkeYOb/SH4ABHmanRyMpFqCja8TIISaHBhAWNoG+hlfDWumALJOasDCNL/2 Nktiex1oIYXiXfeyHxaN4xREMlz+vZCfbQuAWb6mgzcgWW7DxjKAn/Gq/+wDkCZW 42snY++fZJKmJdXvTR7Kz/gjTZTz5NFTYMn5dXvTqZVtAmFN2ndKkXh0+jTV6jSy Pi4dZJQpkINNzJ5EYFIjJgTrLPlf7xdVAcy0eThmi9rojHG0WDYbg== 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 v12 17/17] tests/tcg/s390x: Add tests for CPACF instructions Date: Fri, 10 Jul 2026 17:29:03 +0200 Message-ID: <20260710152906.80207-18-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260710152906.80207-1-freude@linux.ibm.com> References: <20260710152906.80207-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX7b9mjQwBOU1j VRmhRguXAuOn5luX9VJ55i5VUjltrhQjCy1PQmLiRRzqcw0m8IZbjicSCvqW/+73BHAaXGPN7Hq 9NciZIkCueRv/UYtvxYItIwF99rCFZo= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzEwMDE1MyBTYWx0ZWRfX6Azet0WWZ5zY KScBJYKL4RPgwOYmVjGqVdrcRRo49A62XIrAKzgIhcpfVt73uLBurlxJy2qicK6nDuTwdEZrB6f dw7uaGsC38YL9I0OArvZIGIUbTQDSVVlMun4qJp7ETuMyvJkPX3BNby1cZoajRplrT9u80Umgcg BGJdUWbS6aF8VKqwNZNg5YiWJQPwaVAEe3O7QYKO4F0RgUBUJkyeTEUy1b0wKOM37Uay2UHQNP2 8oeX5Vfo+VPERD6XJXQ8kshc87f+HpuaWvDDf/5BPwO5ZcxtlRY3IC438gw4s8dFGoE/j1rHt3Q j2fOCoW+NS6jhzZHVfgvaMBGkKIcxah3NL8TQjh9W09FThaeS1dwneReayXou26gBxXqLumaVEY jJ+ZEqG4ffFxeZrEVKErCAwIeV7T4Wps2YgYs1jkkhXiDPwSebHZxAvsPQrLkh4kqk4jlY7drGm S1jpuk7gj1KQTGTqUrQ== X-Proofpoint-GUID: phG2rJ06fB4BWAkzuTzX6synS-QmsJPK X-Authority-Analysis: v=2.4 cv=Oot/DS/t c=1 sm=1 tr=0 ts=6a510fcd cx=c_pps a=5BHTudwdYE3Te8bg5FgnPg==:117 a=5BHTudwdYE3Te8bg5FgnPg==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=uAbxVGIbfxUO_5tXvNgY:22 a=VnNF1IyMAAAA:8 a=uTGXcgEPX-vUjW6082YA:9 a=9gp5PUktWgSiYFtD:21 X-Proofpoint-ORIG-GUID: phG2rJ06fB4BWAkzuTzX6synS-QmsJPK X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-10_04,2026-07-10_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 lowpriorityscore=0 clxscore=1015 impostorscore=0 phishscore=0 malwarescore=0 suspectscore=0 spamscore=0 adultscore=0 priorityscore=1501 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607100153 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.001, RCVD_IN_MSPIKE_WL=0.001, 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: 1783697404591158501 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..328f588a76 --- /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] !=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..51517de2da --- /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] !=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..16c43b4e5d --- /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] !=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..a69f9ded6f --- /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] !=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..27f369acbb --- /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] !=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..8f1e8038e6 --- /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] !=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..c98fe833b2 --- /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] !=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..eb202e99fa --- /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] !=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..0478568a9b --- /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] !=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