From nobody Sun Jul 26 10:06:44 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=1783441237; cv=none; d=zohomail.com; s=zohoarc; b=esQBWRaeIwbFucdAWtXW1m9QbF4X4CBJXPRyRow8eRumE7i7lMbWm+f/ATVp2tLDLvKnrICkuAmreynjsSBzz8RGay2jCnl1cQibuK2sSRSEBkfOzH7UzXubCjok3hZLqJBTkt1yjXQcEHakMBwXNa6EyVouanbDi47gzm5mTsQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441237; 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=7HeIz0x3Vg4GqOBlZv/iGgOTB+uhuxBJfASbtqqOY7o=; b=HwgVb9/vQGJnFJXTGJG9HzWQQKH2uDBwd8b/NOjsCdNX7IlUC421SilOu7H4AAm+Ta3XoJFMRGeQsHt0H+xlWi2YBD4cpxtrG2ofk8Bx63IElJUagNwKqKcuqSDCXsPKDSOsjzdDJMC4NP7Pfthc/xuiN0TuNwEVXDdNs+roALU= 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 1783441237367956.5741631460035; Tue, 7 Jul 2026 09:20:37 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8VH-0007Uw-W5; Tue, 07 Jul 2026 12:18:36 -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 1wh8V9-0007T2-Cg; Tue, 07 Jul 2026 12:18: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 1wh8V6-0008AS-Pu; Tue, 07 Jul 2026 12:18: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 667FmH4j309828; Tue, 7 Jul 2026 16:18:19 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 4f6suqqw2m-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:19 +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 667G4cH6023292; Tue, 7 Jul 2026 16:18:18 GMT Received: from smtprelay06.fra02v.mail.ibm.com ([9.218.2.230]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7dgk3n39-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:18 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay06.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 667GIEMq24052110 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:14 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3551F2004D; Tue, 7 Jul 2026 16:18:14 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1082020063; Tue, 7 Jul 2026 16:18:14 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:14 +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=7HeIz0x3Vg4GqOBlZ v/iGgOTB+uhuxBJfASbtqqOY7o=; b=PTZEWYAskIODaNYLKllxr6o+tE6/h4qsW l2LmQrhXpSMNP+unb26NUp7m7TiwvqMbYxlA71FZ2VUjBSvxWTAuM+FB2WzQJMKb CLz3647LlVD5uCNSYUPQktT+/YhZcvlK1vgZ8WH1dLbC+sjmSFcqKEQezcUBtKcl 82dkFP3eO4bTJJF9xzP4AyLbRHE9TTjHyVrlARmh6w8qeYlg0uB3jr4Xu/yN8fPG 6kuNVpO4CaKkhEFDaeFfjulO02MIwND760Q5N8Whh/FcDLKzCdtLOIgMxNHM7jVr YXktFIu57PFZE+BbxUgOsd4djQAGVdZtW1E+UYma958FcFN1OaN8Q== 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 v11 01/21] target/s390x: Fix wrong address handling in address loops Date: Tue, 7 Jul 2026 18:17:48 +0200 Message-ID: <20260707161815.40919-2-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfXyrxFZ3raPmuS 1Od3XEhp13vUj0oFIjUq9hyjttdBBBNVK5wLVDglsQ0wW9WIJyFM0dj68PwMtZzrzNv83xJ8hcy 4SIbeSGZVAcM2y5EwAgxzvLuzTBrYtc= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX/p9mEAbdwV6j tYpLbikDQtJRoj20TyXoUNYdM94FvK77w6uEBukBsL3UMhMuZHkJPBcdcXuxXOAJhati0u2hSqW s+DT97W5RgHrGaqX8p4/Z2issUhP9CsYXkHJ/XIm7okDPYItgJpPee+lrH9UL1JDFlwmNRnrUZT jfhhHst57nbfTKYxHOUmBUzZ1hfOiSPDVUzCPw1MRe3SO/1scZM+3lPFnvZ2V4aV097OMMrd5jy n9HYrxsWWgcuvuoG1UMwPAfM7o/Y8iGq3HKFQlh0mZzE3DXPeKdcuzVq2bZh1H3+MFpiIvq2ojY HoHBmq+316mTVdOByPl3c8zvzRyW95Soc+8cqJI52YbCaRgiO4A9IpZrQZnCtxeBg2t6mYLL0zW PgroIO+zrUXd0n9RVZLh7Hm690HnfSxWUFZXTp1ztFmr+XdaEAijS5Yr0ha9tPH4BubVqSbLANw zj7xqH9ud2sh/lsDfGA== X-Proofpoint-GUID: YzNIBB8JPTppGyj440b-vuxxh5-pt2j3 X-Authority-Analysis: v=2.4 cv=Oot/DS/t c=1 sm=1 tr=0 ts=6a4d26cb cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=uAbxVGIbfxUO_5tXvNgY:22 a=VnNF1IyMAAAA:8 a=JcvBkDReJmzHsdK6FyIA:9 X-Proofpoint-ORIG-GUID: YzNIBB8JPTppGyj440b-vuxxh5-pt2j3 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-07_04,2026-07-06_02,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-2607070160 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: 1783441238798158500 Content-Type: text/plain; charset="utf-8" The loop increments addr by the element stride (+=3D 4) before calling wrap_address, but then overwrites the loop addr with the wrapped value. On the next iteration the stride is applied to the wrapped address of the previous element, not to the original unwrapped address. This results in every element after the first is read from a wrong (wrapped) address. Fixes: 9f17bfdab4 ("target/s390x: support SHA-512 extensions") Signed-off-by: Harald Freudenberger --- target/s390x/tcg/crypto_helper.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/target/s390x/tcg/crypto_helper.c b/target/s390x/tcg/crypto_hel= per.c index ae392bce0e..8fe0a22219 100644 --- a/target/s390x/tcg/crypto_helper.c +++ b/target/s390x/tcg/crypto_helper.c @@ -126,8 +126,7 @@ static void sha512_read_icv(CPUS390XState *env, const i= nt mmu_idx, const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_64 | MO_UNALN, mmu_idx= ); =20 for (int i =3D 0; i < 8; i++, addr +=3D 8) { - addr =3D wrap_address(env, addr); - a[i] =3D cpu_ldq_mmu(env, addr, oi, ra); + a[i] =3D cpu_ldq_mmu(env, wrap_address(env, addr), oi, ra); } } =20 @@ -137,8 +136,7 @@ static void sha512_write_ocv(CPUS390XState *env, const = int mmu_idx, const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_64 | MO_UNALN, mmu_idx= ); =20 for (int i =3D 0; i < 8; i++, addr +=3D 8) { - addr =3D wrap_address(env, addr); - cpu_stq_mmu(env, addr, a[i], oi, ra); + cpu_stq_mmu(env, wrap_address(env, addr), a[i], oi, ra); } } =20 @@ -148,8 +146,7 @@ static void sha512_read_block(CPUS390XState *env, const= int mmu_idx, const MemOpIdx oi =3D make_memop_idx(MO_BE | MO_64 | MO_UNALN, mmu_idx= ); =20 for (int i =3D 0; i < 16; i++, addr +=3D 8) { - addr =3D wrap_address(env, addr); - a[i] =3D cpu_ldq_mmu(env, addr, oi, ra); + a[i] =3D cpu_ldq_mmu(env, wrap_address(env, addr), oi, ra); } } =20 @@ -159,8 +156,7 @@ static void sha512_read_mbl_be64(CPUS390XState *env, co= nst int mmu_idx, const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); =20 for (int i =3D 0; i < 16; i++, addr +=3D 1) { - addr =3D wrap_address(env, addr); - a[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + a[i] =3D cpu_ldb_mmu(env, wrap_address(env, addr), oi, ra); } } =20 --=20 2.43.0 From nobody Sun Jul 26 10:06:44 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=1783441264; cv=none; d=zohomail.com; s=zohoarc; b=jnR9zQTzbbBzNu+kagjKbW0/xhDVORfGMeUZqQoMfVrDBGCkpxjU6d3TG+7lPmXpqAW5za2vW5bKEVtT91onkYgw74glAXTjqu5vTA8EhQvGIZPC9IidQNCRjGMTvfowIYLR2xaSRPkGQGpb3epPlmofhwUUH8hjMbgtNXf000E= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441264; 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=D7FGLJHHebzA+V6/sYfFFdVwwvK+6tZ+zb82i2V8NQ00na0SoSMyKOSBP2+EcisfuvfY5oMfP0xZOhJwNddZCa3uUVH7hV/m23pCeBVcedWGtbjyswzAdjtEU2Xp1fgsteEqRGfYn9eJRTF/SRdg52d3g2Vy7tWIHIJcFzLuIrY= 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 1783441264076372.8305297973751; Tue, 7 Jul 2026 09:21:04 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8VO-0007ZZ-9O; Tue, 07 Jul 2026 12:18:42 -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 1wh8VA-0007TA-Hi; Tue, 07 Jul 2026 12:18:30 -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 1wh8V7-0008AW-1W; Tue, 07 Jul 2026 12:18:27 -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 667FmLNk4084929; Tue, 7 Jul 2026 16:18:20 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 4f6sw4r5pa-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:19 +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 667G4bsu005421; Tue, 7 Jul 2026 16:18:18 GMT Received: from smtprelay06.fra02v.mail.ibm.com ([9.218.2.230]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7cvw3sjm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:18 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay06.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 667GIEe824052114 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:14 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 5D22520040; Tue, 7 Jul 2026 16:18:14 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 392FD2004B; Tue, 7 Jul 2026 16:18:14 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:14 +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=FbToLxGe6C2jBui84zYgXbZb20ndA4wiR VFt4Q8QRC+V6SWR6kB5B86zYBgfFAf62fw5X9bY5EdyyOn//R3xLY5RHR9AY5rHX 3zrJAC7D4CnC+cwt2jsZfVb8kQwCZoHy2NI+rh9e9YQRc9chz31AN5+VhxyrXwmM GDbS5CeQQhhIQFKi7oDBwOEDNZVMB60hD5YcCSq2K7qvW3JxY3J8PusBDJbodKD5 BDOHYQpn3opYHaPQ9sJfPsoZ/SFC54YEbxuJfpqwssqIhtwQtv92Z3JQSwyFll8I KWGYQRpaD4Y2JVgSXaniz5PNWE9wD5WWAmECcP5m5HL1p0n+lTtLA== 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 v11 02/21] target/s390x: Rework s390 cpacf implementations Date: Tue, 7 Jul 2026 18:17:49 +0200 Message-ID: <20260707161815.40919-3-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: Tn-Ho9uNIAU7senPDrQLHIJGG-1z0iod X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX1Z7gI2rwPJ+z qV34SSCOS5bEkKIsNTYeAxUjvl5rfcjlRTzwZHRFYFxh9qt1fUWJDNgwa275hk73rnParK4tamW sZfbbSecySituGyOhleKBaO5dq5rFbssv5wzmzHyZHxV8FBczc+A1b8Ei9DZlK7I49hWeL/+SJX 437rrCoTeW/eLl5eXuF5UN3oYTO1iwAcoWG3y6ktfMIAPnnTBTIr804NKyBjXvgHD6p4Zjn8T1P pOgxllE6/mxgQDByC2ql3x9D/RjGvQ9HbeDapSIz0iws1W2s6U4QZDHB7ZTRWHz2egSTCf3175a ZOeL6Sy9sO+ZgbiphIP9u6Rf+iil17TwI2Zvdz7HXA8tqA5CtyKcF1bdqkM3dFloczWSLm2re6E KIPz2sgTuBnRBJrIWMp5UlSD/X4kv0sF5zh9f7Z354Pw8WhVpuI5jIW2xFRIlLGYCZQ/8GLcrBK ZnZyhKlfsiIHYMbGSYg== X-Proofpoint-ORIG-GUID: Tn-Ho9uNIAU7senPDrQLHIJGG-1z0iod X-Authority-Analysis: v=2.4 cv=FqQ1OWrq c=1 sm=1 tr=0 ts=6a4d26cb 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=4KKJp7DvKucWb6I3c-QA:9 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX3177V7SX1ZCg WlplIz44J7qy8kDlJI+4Kz7mAf9E5UbqGYbCDYNNNt496/gAo5x6x0QG6utrWRHbEZpxUxOm28O oJc90Kuczemp0+j1y2ZwZnSwaot8d6A= 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-07_04,2026-07-06_02,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-2607070160 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: 1783441265268158500 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 26 10:06:44 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=1783441173; cv=none; d=zohomail.com; s=zohoarc; b=QGs/+j2WEIHr+mdMshBx8WHfTSQoar7Grz3JbRnpi4t8IlAAC+b1+ygrvlxHDAes1mG7a/OHaxhx0+eFcy+GbRBhmqXMjlOEosBAUUdAdzRc0jm/r30goii8YKxvLqmTemTbrWAJpbrrfaGAMl7BU1Bai+4Ic3T/WJ31FY6QBrA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441173; 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=RcRojTP2+D61U3KnU+owutMB50JZqxKWbt2nMiWtyDs=; b=gZ4oXxOK0M6WDtv6mWYFMBoqWd1GbRG7q0IZXreT8jJHGCFu/qmJdz/3dK6WlNguy9ZWHkxaFgQRMlQqVzPFtUDwcyBPqG8HmtEKHdVOyyYiFSwFXiw7gytoeaDgdRm/WvNwbFzS1SDTNvj3jAAHoGTTmTmLMW4dFhQ7Hh4hlYA= 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 1783441173347572.7510191405105; Tue, 7 Jul 2026 09:19:33 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8Vc-0007k8-IO; Tue, 07 Jul 2026 12:18:56 -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 1wh8Va-0007iR-R4; Tue, 07 Jul 2026 12:18:54 -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 1wh8VW-0008Bx-NC; Tue, 07 Jul 2026 12:18:54 -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 667FmJgS4186755; Tue, 7 Jul 2026 16:18:20 GMT Received: from ppma23.wdc07v.mail.ibm.com (5d.69.3da9.ip4.static.sl-reverse.com [169.61.105.93]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4f6sp3r809-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:19 +0000 (GMT) Received: from pps.filterd (ppma23.wdc07v.mail.ibm.com [127.0.0.1]) by ppma23.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 667G4cPC003230; Tue, 7 Jul 2026 16:18:18 GMT Received: from smtprelay06.fra02v.mail.ibm.com ([9.218.2.230]) by ppma23.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7e0hbh8r-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:18 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay06.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 667GIE6B24052116 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:14 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A4A4320040; Tue, 7 Jul 2026 16:18:14 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6B50F20043; Tue, 7 Jul 2026 16:18:14 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:14 +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=RcRojTP2+D61U3KnU +owutMB50JZqxKWbt2nMiWtyDs=; b=GszWWHS1W1nzYFndC0k293Dr1b3zB3Qoq rgJVbcO00oJ+VQ9FQbLx7etGH2t7Vf6d/v4L3AbykJX9qv7f+z8MWxCjmb31FlD+ SiDNAfA0JOYBFSoLEONnRxOrB1OjMZQAD9qdB9mj9xeUr7sMjnXz+nbvJeKrOKrB XSUoIVmRMKDqmaI85Vl25FXiwNqokW3pwjCmNHTFzd4WMBuUMKpg71IvUWY6F9ax ZBIaOjTn9dKHsSLRSLah2nuKB1I+Ax/OyfPs52mxwNssTXrqWNUFeuYUZ+D25QPv 5ij6WZG8XkLdnG7UcU2wIki7mTKj34kl01qZj9MqQ6iINl93J8+Og== 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 v11 03/21] target/s390x: Move cpacf sha512 code into a new file Date: Tue, 7 Jul 2026 18:17:50 +0200 Message-ID: <20260707161815.40919-4-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-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=KsJ9H2WN c=1 sm=1 tr=0 ts=6a4d26cc cx=c_pps a=3Bg1Hr4SwmMryq2xdFQyZA==:117 a=3Bg1Hr4SwmMryq2xdFQyZA==: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-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfXycSC/6GWJS7D l1JCjoLv4FeieDI5dVzF3qHSWG+56orD3OpGAXRbwZXQTr0GzhmZBYLTCRTjVp74JJcqoGDYMw6 myezkH141CVSmGdeeCYMK4aDH68cimA= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX/3jkVlqnRBqs vFGXT79YZQxH74VDY9agC38jchWSWk3DdTVw9Q58yvPBHvOk84IEQtV03Ck1kghFuaHHWmBd7Xc sA1XOFPNt+9fJTbbOfKsDr+Wa2KhKha2Jh+yoz9TyfWDu6fjuILwbCIajv3aXaXVI+fFW2HN396 fP5soHKiIs2oiOZ+LDpQQB8W5BABAo1pSYGuQ9Slu0Oy5g0jMKMcsi3d4w9jfQ6NiiENkv9Ksn8 b5m5UOUg2+I5Y3tb0za5kgxhCgdINzUNIKu2wabwVEaTrK/3cbsQY35bN/y8XluIpxq2Fo7dv8w mdpeuGBkq5Ln2r8My+Q8j7QJNiYKdjqLALd2R5c3W/Z5kO7m80pfb1kMJGiJs+mSQl8aMXpUwbH jCTruXdS9RIELRZhjQMgpivYriKlL9DVh7BAMvu+ygHXiNL3QhJ5O4wVNg61xzaeODV8dyNUnUV L6dSTGC9CCTX+7GjNzA== X-Proofpoint-ORIG-GUID: S6hhuj_niadngHHiBpOXvkMfQtEf4y8O X-Proofpoint-GUID: S6hhuj_niadngHHiBpOXvkMfQtEf4y8O 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-07_04,2026-07-06_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 malwarescore=0 spamscore=0 adultscore=0 clxscore=1015 suspectscore=0 lowpriorityscore=0 priorityscore=1501 bulkscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607070160 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: 1783441174417158500 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. Tested-by: Holger Dengler Reviewed-by: Finn Callies Reviewed-by: Ilya Leoshkevich Signed-off-by: Harald Freudenberger 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 26 10:06:44 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=1783441185; cv=none; d=zohomail.com; s=zohoarc; b=D2BoQmOj3tS6uNu3WEslhgAgCM+Lez2SYzSB7aOvZPiTtssJOYBX3x4KZLJYLbDntx9i5FojcpG08qF4Heq7TDbaqkx3id0kYvmJD7sjqqWFmDZplRWgandvYQTI41/xTRQfTQ83KYB99E72QY738bXuntoOpHXRHH+14IFW2tU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441185; 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=oEYiRiAiIEbv8cRpjqCSdGyEYkoorp1ZipG/HNhb/54=; b=oLImbtTBG7UjAdBlojx3zvcHV1bZ5QVCMfvNbIpLxn9B20FfQsyN53kjpGsIFVrUqhmkEYmVgpmqGRY1Z5FrnXdpV7/HheRKns9+b6Th1zV6c3vKq97Bj4nMLQ2izwfbg8eZ0z4JSxyxbGZf6sC1To3nqr92Hnvpp0iuAWGxKU0= 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 1783441185252772.1340161141317; Tue, 7 Jul 2026 09:19:45 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8VS-0007be-Gg; Tue, 07 Jul 2026 12:18:46 -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 1wh8VC-0007Tc-O8; Tue, 07 Jul 2026 12:18:32 -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 1wh8V8-0008Ah-UE; Tue, 07 Jul 2026 12:18:29 -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 667FmmGI670090; Tue, 7 Jul 2026 16:18:20 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 4f6qknfxwu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:19 +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 667G4dNx023303; Tue, 7 Jul 2026 16:18:19 GMT Received: from smtprelay06.fra02v.mail.ibm.com ([9.218.2.230]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7dgk3n3b-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:18 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay06.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 667GIEvP31195458 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:15 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id CF59B2004E; Tue, 7 Jul 2026 16:18:14 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A915F2004B; Tue, 7 Jul 2026 16:18:14 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:14 +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=oEYiRiAiIEbv8cRpj qCSdGyEYkoorp1ZipG/HNhb/54=; b=lv5c+isvddFUj65T9jEoggQ24Tc5fxrEk NfQ4wPJdZnR1txQMK7yicMPvIQCUCa0SQ8APELcHOMXw9pZkEpJ7W5fBdH3KDjKD mudfe77ILxIidGknbiqKtsPLy2qtYTzS0w16T/FcOKIkvqiABylyVjP9sElPFLDE hRlFi9d1JAZUZr0iZbBOE/Sy3ZlQ+ycwn2lqL9gQvaES2xNbOqzi6e/8Fujl+gRe 4q3kP617Rri3VU/AaesIwANoiikBsB5BKy5AxFLiKm6h/bx7A9ufqkxvXRt2TfCx HWfdD/d2gGIRBsafjDXIbJ1kTWKCGurVwGZTmWW0FTiKNvXeecvnQ== 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 v11 04/21] target/s390x: Support cpacf sha256 Date: Tue, 7 Jul 2026 18:17:51 +0200 Message-ID: <20260707161815.40919-5-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-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=6a4d26cb 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: van0Jo21OXk4SW3sVnu_i-P_ZA37p5JG X-Proofpoint-ORIG-GUID: van0Jo21OXk4SW3sVnu_i-P_ZA37p5JG X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX4jyUW0fLTFgf 1QEsx8quHnJ/NOjnrZabB8T/ia+BhInBEDazsepaFrZfuXujx984V7lhMKNU2ubvSQkEtjrHnUq y8YcuJaNuQhJfL/Dg1pxcq1Ubp2/Rbs= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX9c38OgYoFciN 23Zal+7dx/Plv8FbgN1tsZFrxJDpw/u4lb/aRHVPEs6IDHhGzhf6Wh5HYWl8WwNSrsi5SHSyqgP RoahqAioeX8niOYX3xsmQdMGAv390edJtWmcE5nICPtluHoTooGcMQYhLN3mTnYIHQILG0a6V0o Ty/VQFSbUW4z0QV+YqGwpTuNkpFoAkUBu/rDsHvDCwgUoJ02hLUGkIMfrUziqvy6Oe/H5bzE/8P 3eZJv3wz0KNuFtBHP83nQQne+FgZEIo+vVCNz3S5QSjDMy/y5k7cez+ih62nTypqrqCvIDEW+dn XlBVgEVSgZkrmGWMYVGlYsXaee2IV1ZQXS9SNX4xYcj+7RJbikvLDJu0olpSAzXa3vHKYRms73H 3dp4dy+LXIx8FqSrlM+hL6dd/Dm/4WlYqG14Vm8rL0mgFFXF1ctRB/1rpp81CqYlGuOzoIjgtLl MD9tr0ebBp1NbuvZobQ== 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-07_04,2026-07-06_02,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-2607070160 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: 1783441186431158500 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 8218e6470e..5cf5b92c37 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -916,7 +916,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 26 10:06:44 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=1783441271; cv=none; d=zohomail.com; s=zohoarc; b=g8uZ5bIbN/Q4+C2JyrL+RhqbGxRaKPgcyYjQlXYow6Tap987K434URH3XDRjU12xejE7eCPs38WzfegaCjMmcmceyca7pkCoZn0BcPd2Kp2mImmZMJV1kJlb2An+Y2IvAS6Le/0ltugj0EK/Gl0F7XDgVsx1vGC3grJMObFPvyk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441271; 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=Hyp8thwqISc/qrtLtZJll0EHfsSNB2SA9qX493lvmc4=; b=KKdZWf4O8ZD+BhnZ5bCTfauv7R5lTSt+o4s785EBGaDfN7TQKIH7GIcT+8B+jXkyfi9sQH7gFOKw11a4bk+CF2N9N+xjyD25YT4UgBvdMFXUJQB8sX92/dieaeK/ZODRX0n/27+F182AuXZh8d94Olk1rC2PV0WRUog9XL0quW4= 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 1783441271913627.5287023065536; Tue, 7 Jul 2026 09:21:11 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8VO-0007Zp-E3; Tue, 07 Jul 2026 12:18:42 -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 1wh8VA-0007TB-Ho; Tue, 07 Jul 2026 12:18:30 -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 1wh8V7-0008AY-RG; Tue, 07 Jul 2026 12:18:28 -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 667Fmonk4086060; Tue, 7 Jul 2026 16:18:20 GMT Received: from ppma23.wdc07v.mail.ibm.com (5d.69.3da9.ip4.static.sl-reverse.com [169.61.105.93]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4f6sw4r5pe-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:20 +0000 (GMT) Received: from pps.filterd (ppma23.wdc07v.mail.ibm.com [127.0.0.1]) by ppma23.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 667G4doe003243; Tue, 7 Jul 2026 16:18:19 GMT Received: from smtprelay07.fra02v.mail.ibm.com ([9.218.2.229]) by ppma23.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7e0hbh8t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:19 +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 667GIFH644237072 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:15 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 18C2220043; Tue, 7 Jul 2026 16:18:15 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DD50D20040; Tue, 7 Jul 2026 16:18:14 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:14 +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=Hyp8thwqISc/qrtLt ZJll0EHfsSNB2SA9qX493lvmc4=; b=sLIUkeJ4B0kgXoViQGYG4GoUIhZtsQiQE hi4MTa0y+Sx0zJ6td8XyweZdHRfHShwDYsJZWJdvPlusLrLD0/3All6BguPt/pY+ rRrRget6fvaX7eQtRIWA89HSQh7Kp0zlNqgL1L6FDbZ5YHok/IbL2HRNKEs3cDco 6mOBcrtpxSz7iDvrVYrRPrGVfMrellNLWT/M7mWiGtBwFrplRs18pHJdh9ts3bOb I3EC8c9YD+gbEEZFOMjH5pJOmqxuZ8RGut/OuHtI1gvFcVwsSEDb3ZCzh4ZBZQh9 FT3Kg/hXKkehB8lyIxBqkCoGAWo1JJgpSVn1Q7C0gDQMykoX15/mg== 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 v11 05/21] target/s390x: Support AES ECB for cpacf km instruction Date: Tue, 7 Jul 2026 18:17:52 +0200 Message-ID: <20260707161815.40919-6-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: CeuRI7KKi0jU946Gm_QlbIk3zAzc0rfS X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfXxed//M7d9Ccu F8Zvf9uVV41F8DTztnGH0hSQQF6DasPsfiTHjXceEcxoYWinufJtQ72neVii/NX+qWQ/BTDIP80 14GimUQXk9znCI9jq/XcC82ZQfLQ8ih9EqJlcb/EjmDyHmS0QYm6wsXkYzjkEFjTqnEXxI2Cbq0 QkXY+nmQi2OE9faPHu86KXKdHCcZknkYW8RMpu8LGZUL4jpCeA1I96kZxArfi2xCieki5Fhon3e L8ek4scPxvOqykeZ0eOr6ORttZCllqcZfaCNSUDJ5x3Z5PoGCKFd714+IQTge9bfVfvgcBqoprx 8FTuBBibrE7G1UtJQtcLBPMN8zWoJdvOr424Cj0fOAy9GH1wnVtkViiJKb1ZSv90C5z/VtynNOF A23Xj68/WWsAJmhqtHPvaw1cmAi5fPrF6HGtmpc1XUBXsb8movRBvRYeKpIR71wV1pe7rfWLysD JAPcQ9FAj06exqo2Syw== X-Proofpoint-ORIG-GUID: CeuRI7KKi0jU946Gm_QlbIk3zAzc0rfS X-Authority-Analysis: v=2.4 cv=FqQ1OWrq c=1 sm=1 tr=0 ts=6a4d26cc cx=c_pps a=3Bg1Hr4SwmMryq2xdFQyZA==:117 a=3Bg1Hr4SwmMryq2xdFQyZA==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=UeJqcyLMtA2A8E2_xXgA:9 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX/iMq8SK+op2I p5r64cM8+Ci8zYYdYsXXwvdcOfL9cL/91EIEQwAbA4pNlNItT7atcht6fRWwuleo18SVPyzUkv7 n7YWeQ0SouSaNMeT0/2BxDFIjcq1v74= 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-07_04,2026-07-06_02,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-2607070160 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: 1783441273124158500 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 | 111 +++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 24 +++++++ target/s390x/tcg/meson.build | 1 + 5 files changed, 145 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 5cf5b92c37..a35d1fd2f9 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -921,6 +921,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..7a2f555855 --- /dev/null +++ b/target/s390x/tcg/cpacf_aes.c @@ -0,0 +1,111 @@ +/* + * 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 "target/s390x/tcg/cpacf.h" + +static void aes_read_block(CPUS390XState *env, const int mmu_idx, + uint64_t addr, uint8_t *a, uintptr_t ra) +{ + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + + for (int i =3D 0; i < AES_BLOCK_SIZE; i++, addr +=3D 1) { + uint64_t _addr =3D wrap_address(env, addr); + a[i] =3D cpu_ldb_mmu(env, _addr, oi, ra); + } +} + +static void aes_write_block(CPUS390XState *env, const int mmu_idx, + uint64_t addr, uint8_t *a, uintptr_t ra) +{ + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + + for (int i =3D 0; i < AES_BLOCK_SIZE; i++, addr +=3D 1) { + uint64_t _addr =3D wrap_address(env, addr); + cpu_stb_mmu(env, _addr, a[i], oi, ra); + } +} + +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 }; + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; + uint64_t addr, 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 */ + for (i =3D 0; i < keysize; i++) { + addr =3D wrap_address(env, param_addr + i); + key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + + /* 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, *src_ptr_reg + done, in, ra); + if (mod) { + AES_decrypt(in, out, &exkey); + } else { + AES_encrypt(in, out, &exkey); + } + aes_write_block(env, mmu_idx, *dst_ptr_reg + done, out, ra); + 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 26 10:06:44 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=1783441174; cv=none; d=zohomail.com; s=zohoarc; b=NJK4wJWRh4adcYb3kcgEMHQRAk1EIwZZy0RKOvsapD0SHOV2FOi/diHSl8SOlOuduYEMu0Cwl6OUuCzK4dHTTXL95VgOllAGE4i/zTnyE2tybpjS2gOAFSwT0MqcLj1tk2rb7DdBOJAYqxy0NG6kXroh7Dp/2Ffzdy/Ic805YrI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441174; 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=9Jjgs43Kw1MDgkTOo+lI0hsmG1LB/gFo3fZ00JkAHb0=; b=EvbZqXeED5YC8fh6x41cySShRgGEcck+fXjUdXC3GeAlctbgYSxpNTVsTeUziU+/+mSFpckWigqv6vRv/Cu+BP2LwVQMKRT3lxJqhne1/1CDZLrljpTt/4FGuZpk+Lr+vHuyiapsSMj41urR3wgE1fpelldpiD4UAGNmzLd8KjU= 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 1783441174070505.19795872715986; Tue, 7 Jul 2026 09:19:34 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8VK-0007XF-Q8; Tue, 07 Jul 2026 12:18:38 -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 1wh8VC-0007Te-PD; Tue, 07 Jul 2026 12:18:32 -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 1wh8V9-0008Ax-En; Tue, 07 Jul 2026 12:18:29 -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 667FmM3v310140; Tue, 7 Jul 2026 16:18:20 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 4f6suqqw2n-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:19 +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 667G4dkY018739; Tue, 7 Jul 2026 16:18:19 GMT Received: from smtprelay07.fra02v.mail.ibm.com ([9.218.2.229]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4f7eqg3cyx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:18 +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 667GIFoE44237074 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:15 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 41BD420040; Tue, 7 Jul 2026 16:18:15 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1CFDA2004B; Tue, 7 Jul 2026 16:18:15 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:15 +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=9Jjgs43Kw1MDgkTOo +lI0hsmG1LB/gFo3fZ00JkAHb0=; b=K74pT1kMRBY2QGj2wX+/b9vbXAEt2/MRU wGKaebXQIrOQqXlUkRZM7wHeMzNBeGgp3L9HHNmy2/5A/iclQFsD9q/nrgWZOwsE tIVtZp/xLr2v1aMLNYo9xIqIxUm2zNVyVTWny8XU/OR3TKTivkpebhkvJQSOeFRQ XyNTVkm27Bbdck0sgcf6gYXZ8xRJmJgwhsReZ0EqlHCChMelEd2+iaGLL9Uly/6w qa9mMDdz4Fc7yZyDCiVvEb5lBgttKjfopl0FzfLLH7ZqQhamBSLN8KtJqfyyecQX adNYR41MkLhuwUU1oUD+1Xf+scamXym1ZryrdkR2T+9RnS1v5y1Gg== 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 v11 06/21] target/s390x: Support AES CBC for cpacf kmc instruction Date: Tue, 7 Jul 2026 18:17:53 +0200 Message-ID: <20260707161815.40919-7-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX3NHuIWvFnGTV PTYAIuxOGK13xr+zmK9O0Mm3yaWDAiGkwxmAnC0ptTQsH4mqDxSSaqRYQL01krsza5ZTKUP1exI 48zosKH4D/Ntsb3EYoY4L04q/4XPdF8= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX20MsSFCS96Ed QAmyZphiptC0m9d0/tiWOlrYAF5O35ExztbTl+ttNJ9DMraGmV0njHlIysoGqwNmpZP17i+ISlf htBLiLiK3yS5nj2wsQ30dpmpu7SweCRj31Liifds8VDUbO770PV8ByubFJtoT2566oAtSEeSivE mVuQsaGl+a8Ef/6tfnOzvWGX0YshHIjYysrpQcd7pjwIhVuwAxFkIsywVHH79EWknJOzjEYx9hH G0Hv5GssRct6nWc4u4xdxegTZMxcug4oE6YxOPcf1YBxjdIAq/yFBCYUHwoRilHga04Mj7t0FIc E7XPgErZem2e9EbUHL+cZTpsYh5P7DmiI1hZh2HAqojkc5/HDQyWeTDlC9pZsyJ4dAbyBq4oDWt P+StXn1rRoQGOdmSuFP0yeIGuflDvFOhasw6bZ2DCVQGROVQ7Ced+EVgldVj8wN/FeSzwP8lXKu BAlbGjhkrjX+GZcdK/A== X-Proofpoint-GUID: XZ2znX01Lf5o_mQJHAaOBMi-1ooul5PT X-Authority-Analysis: v=2.4 cv=Oot/DS/t c=1 sm=1 tr=0 ts=6a4d26cb cx=c_pps a=AfN7/Ok6k8XGzOShvHwTGQ==:117 a=AfN7/Ok6k8XGzOShvHwTGQ==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=uAbxVGIbfxUO_5tXvNgY:22 a=VnNF1IyMAAAA:8 a=4s_zGP7M7QCs5o7xjogA:9 X-Proofpoint-ORIG-GUID: XZ2znX01Lf5o_mQJHAaOBMi-1ooul5PT 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-07_04,2026-07-06_02,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-2607070160 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: 1783441174414158500 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 | 103 +++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 24 +++++++ 4 files changed, 134 insertions(+) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index a35d1fd2f9..9c0c0b229f 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -924,6 +924,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 7a2f555855..5b4130a19e 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -109,3 +109,106 @@ int cpacf_aes_ecb(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, =20 return !len ? 0 : 3; } + +static void aes_xor(const uint8_t *src1, const uint8_t *src2, uint8_t *dst) +{ + for (int i =3D 0; i < AES_BLOCK_SIZE; i++) { + dst[i] =3D src1[i] ^ src2[i]; + } +} + +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], buf[AES_BLOCK_SIZE]; + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + uint64_t addr, 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 */ + for (i =3D 0; i < AES_BLOCK_SIZE; i++) { + addr =3D wrap_address(env, param_addr + i); + iv[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + + /* fetch key from param block */ + for (i =3D 0; i < keysize; i++) { + addr =3D wrap_address(env, param_addr + AES_BLOCK_SIZE + i); + key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + + /* 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, *src_ptr_reg + done, in, ra); + if (mod) { + /* decrypt in =3D> buf */ + AES_decrypt(in, buf, &exkey); + /* buf xor iv =3D> out */ + aes_xor(buf, iv, out); + /* prep iv for next round */ + memcpy(iv, in, AES_BLOCK_SIZE); + } else { + /* in xor iv =3D> buf */ + aes_xor(in, iv, buf); + /* encrypt buf =3D> out */ + AES_encrypt(buf, out, &exkey); + /* prep iv for next round */ + memcpy(iv, out, AES_BLOCK_SIZE); + } + aes_write_block(env, mmu_idx, *dst_ptr_reg + done, out, ra); + len -=3D AES_BLOCK_SIZE; + done +=3D AES_BLOCK_SIZE; + } + + /* update iv in param block */ + for (i =3D 0; i < AES_BLOCK_SIZE; i++) { + addr =3D wrap_address(env, param_addr + i); + cpu_stb_mmu(env, addr, iv[i], oi, ra); + } + + *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 26 10:06:44 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=1783441209; cv=none; d=zohomail.com; s=zohoarc; b=NMPynxZ1USP0b9OQX1Ud0jUwmWXQR636FZAT+NFf0vHWKYLMRuUmIvquD7l94jC/3tmBxQdL23JnQYM1qS8trVKSvIGS5behZT6iAM0uTtWnzxxgNW6TF12L8VixpkKcw6DyCTu5wQGSLfetjaIj+1WUjdZuqgFg/w/TN4Ytp6E= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441209; 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=ICLd1oaOl2kz0f9bsX0wTQDTaCro87XQ72mLt1FNe1E=; b=Dy7NhvLnbYqryo2X8U9e4yKMKfYb6FHv248HSUh3LTYwTmuteOAip0epKYPhXQLcrRMqQJcWhSEQV42wzUuGj0ISj7imr0VteXy57ap2S2c2/PjyVuyMc1i/KMFUkKbQqTEebl/sYq0EyyJ1Re/6SPG30H9AxPlDe6CS9ErUIcg= 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 1783441209278833.8818067775009; Tue, 7 Jul 2026 09:20:09 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8VW-0007gU-60; Tue, 07 Jul 2026 12:18: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 1wh8VC-0007Tj-UD; Tue, 07 Jul 2026 12:18:32 -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 1wh8V9-0008B1-GL; Tue, 07 Jul 2026 12:18:30 -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 667FmGqR4186714; Tue, 7 Jul 2026 16:18:20 GMT Received: from ppma23.wdc07v.mail.ibm.com (5d.69.3da9.ip4.static.sl-reverse.com [169.61.105.93]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4f6sp3r80d-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:20 +0000 (GMT) Received: from pps.filterd (ppma23.wdc07v.mail.ibm.com [127.0.0.1]) by ppma23.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 667G4mmx003415; Tue, 7 Jul 2026 16:18:19 GMT Received: from smtprelay07.fra02v.mail.ibm.com ([9.218.2.229]) by ppma23.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7e0hbh8u-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:19 +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 667GIFmF44237076 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:15 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6A1AF2004F; Tue, 7 Jul 2026 16:18:15 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 45F6720043; Tue, 7 Jul 2026 16:18:15 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:15 +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=ICLd1oaOl2kz0f9bs X0wTQDTaCro87XQ72mLt1FNe1E=; b=e1+LPFfMFgMQnDa7g1Acx2va8n8GF/aHY QnAdORoxZPmwKR3C5Y+pBSKwKmBCukKcbFS67ae0G3xb4CVjDnwJ24Dsjyg5hlXL ev5s6c9g2dfoEWEjm+z4dEUjHY6Zno1dKjxN+5Cv7WfOgNuyoE88WNH1+5V5g4Z1 bOrdSJgkylfmQfs+LfqSoWjiaU6fx6fxOTJNbOEFIrA0j3cTIBn9WiTn7bro48Bx g9XIXzptI7k4vi2fPhAjmzpz3R7QSFmTGJCI6RGBxmcPDAsyqqs4LFq6/i9EEkc4 mJFQ9n6oVLM86zfnOqlWpZllbLmwYc6N5/+EgCd/FCS4XY1127tkA== 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 v11 07/21] target/s390x: Support AES CTR for cpacf kmctr instruction Date: Tue, 7 Jul 2026 18:17:54 +0200 Message-ID: <20260707161815.40919-8-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-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=KsJ9H2WN c=1 sm=1 tr=0 ts=6a4d26cc cx=c_pps a=3Bg1Hr4SwmMryq2xdFQyZA==:117 a=3Bg1Hr4SwmMryq2xdFQyZA==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=iQ6ETzBq9ecOQQE5vZCe:22 a=VnNF1IyMAAAA:8 a=LQnWXxm1RwZjr7XDrSkA:9 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX25e+mJWs65hc fzK3o1CopyhL3byMoaRjB4WvptWDT+WwS/z4Q8rlufvG8pJvKO0W/rLKa4qdKTT+H6Ucb+U+xyx EWQ8SuTtHL5WGR9tP0MpT0tWvWsRYsQ= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX73kweae3H/u3 khkDvLO6HabblVtD5jLJq58tfKRTWYIuu5f9Eyn52GtZ2yhKfkHy3JUwM4nuDXbVfDA4+yHI3Wj GLK5KZ4whGbot241G+15CpxvbyWMMos+RDIeKMCBgHkSCsof+i4GQTKf9tXovtjudI3s7/SUpK/ AUHyYsj2NALYtTDAyXA102m46VbPvRGzeVS0ex9arFtBDXL+qmQp8funV9KQGMQFiOVqUUNSAoH Jv1CGHy8pKuEQueyDiXZHoMuWKvE1Y1LqrlxBFVQOo0Hll5IQXQcwRm06/LTLqPsqPpl/0B8eUv yiu5D8ZKI/bzjtu7lrFC0qQ+n0jQakR8wda49UXLOWjho3b4fWFJdbvwIYoY65bDVpoquLfBAKw JZli6PtDTRIgEes2swbveLqN4gct2Mz4L3vnpbJ8lfQOnHqJTA2uHRxTarKZWnPppvsQL5621c1 mBcrcTBtRiQIuElcDDg== X-Proofpoint-ORIG-GUID: Be4TQpGn-hkkJiuvz4rX75CKbaAO5sDY X-Proofpoint-GUID: Be4TQpGn-hkkJiuvz4rX75CKbaAO5sDY 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-07_04,2026-07-06_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 malwarescore=0 spamscore=0 adultscore=0 clxscore=1015 suspectscore=0 lowpriorityscore=0 priorityscore=1501 bulkscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607070160 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: 1783441210663158500 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 | 77 ++++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 24 ++++++++++ 4 files changed, 109 insertions(+) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index 9c0c0b229f..59c2a47539 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -927,6 +927,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 5b4130a19e..e0fdf28c67 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -212,3 +212,80 @@ 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 }; + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + uint8_t ctr[AES_BLOCK_SIZE], buf[AES_BLOCK_SIZE]; + uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; + uint64_t addr, 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_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 */ + for (i =3D 0; i < keysize; i++) { + addr =3D wrap_address(env, param_addr + i); + key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + + /* 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, *ctr_ptr_reg + done, ctr, ra); + /* encrypt ctr =3D> buf */ + AES_encrypt(ctr, buf, &exkey); + /* read in one block of input data =3D> in */ + aes_read_block(env, mmu_idx, *src_ptr_reg + done, in, ra); + /* xor input data with encrypted ctr =3D> out */ + aes_xor(in, buf, out); + /* write out the processed block */ + aes_write_block(env, mmu_idx, *dst_ptr_reg + done, out, ra); + 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 26 10:06:44 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=1783441236; cv=none; d=zohomail.com; s=zohoarc; b=oJ1/xImWWEsB7BQxP6YmOXP7H/jA8gMq/uIO/dVIleLoINIJGZlqO67lWV17D63rxk+DlVZ9ukfRwoy2jpWDxkdz8SOvLZcmU8vHlnbM6Dp9Kh8H7saIe6lM6LbDaNmvlghUCEAn89Oy/fjuTF7EtiMQ4s6LT0xsh2csoyeFHGo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441236; 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=nRFIVGy8uDvH2qVgIJz049kf1UIAR8ddAbzLsxHf7Fw=; b=cgrcUKSMTPlWFSq2Z40YpERdWFWGKKcfu2M4aBKye8KqvlO06bmpGEbPfZ+qbrPcjuUcLOfm5BxUqctXw/ldyktapVU6Cvf3wrQZPK25uMemeceNCc8HIHWa42q1u4pbX3XfcuxPaPYoz6VzBBqmhVzELQlBv4HVZlgBHaANxTw= 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 1783441236696487.414585464829; Tue, 7 Jul 2026 09:20:36 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8VT-0007d6-4r; Tue, 07 Jul 2026 12:18:47 -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 1wh8VF-0007Tv-Kd; Tue, 07 Jul 2026 12:18:34 -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 1wh8VC-0008Cf-N7; Tue, 07 Jul 2026 12:18:33 -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 667FmBOf4084841; Tue, 7 Jul 2026 16:18:21 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 4f6sw4r5pg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:20 +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 667G4eLp023313; Tue, 7 Jul 2026 16:18:19 GMT Received: from smtprelay07.fra02v.mail.ibm.com ([9.218.2.229]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7dgk3n3d-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:19 +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 667GIF6k44826990 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:15 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 89E1C20043; Tue, 7 Jul 2026 16:18:15 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6EC7520040; Tue, 7 Jul 2026 16:18:15 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:15 +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=nRFIVGy8uDvH2qVgI Jz049kf1UIAR8ddAbzLsxHf7Fw=; b=qZeMCmSRvKsss3C7qJRXIkNYQOol8kKXc onGJMLbTzkWnjpopCW6G2Js630EIZSEtxX6CJy8u6VlrnNih+t+ml05sQGD0Rgd+ bdOBFKUQMZah/lsKjEhmrJ4sWY96kbCioDOH/5iz0IbC+oLWQacXkowrxDJI5750 /SBksh581nNAtI51Z/g5KL0q6VTDdybJ1hINFsJbslA0EO+CPwgYJOy+e5rsuBg6 y6VCAqLOBrqRz8xIK/7Q/QTjISD3J43AYlb3NU8d9W1/VlG11rQZxK4+jr9PWzBf 2cfrZhNbOm/d5ca2tzk0cOxBqNwDrXQjiU+NhdH0ZbsMk0ICtZusQ== 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 v11 08/21] target/s390x: Minimal AES XTS support for cpacf pcc instruction Date: Tue, 7 Jul 2026 18:17:55 +0200 Message-ID: <20260707161815.40919-9-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: zDSoPNoI5Yye2EHQ59dzAZGqmRf1RS6l X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX+Imii0n42wFJ yGlUNEUj9P/4vbvQz8G/CkLUiTpXy6HfeVuFHNzCMraHCnvzwomr73uOQHIWqwgwd3mE+Kzx/wQ ubw+8F8WqTrh0PZpTKnDVrAaSCQMOsL6jvLDa5XHE2OZZIWC9zuj4KcsRX9ekSAc5zxZVIKwvMP ZXU5cDySEpv+J33eQzaKHXIdFdXZJUMnSkwC+d2P1cOyeRniKOGCemQbj7zArcRLGitErx/G8Fk dXZpzn7NTTiCS3BoJ8rhbHTvr9GU61UnckI+hfcJ8is+Ms/onNUzJsMtWnsH4TXW0b4yYWo1UPE 851RdngTwkce0Rm5EI8m1yyT7tL7awgC2RzJSW9h6t9bF8SvreOrPC8ws6TIrixhAB5Fu80dR6Q uX6jsRon1rmlUtNicgfYHa6LtWzBs/pM+rJb/yyCwYzDjbdRAvoGet+wLDsM3vmcUp/Co50dmnl NfFM/2oeqLVMnI59+Tw== X-Proofpoint-ORIG-GUID: zDSoPNoI5Yye2EHQ59dzAZGqmRf1RS6l X-Authority-Analysis: v=2.4 cv=FqQ1OWrq c=1 sm=1 tr=0 ts=6a4d26cc cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=gr50lgQh3SlUKNVXMSoA:9 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX8E6KdcwAZwQN 7gHm07t6tG43XGC6MOLCQuGNlay7k8mtceubG/RcmDyWuWOOjnjHXDTH66RaAtsUPUX4HcJBkPz M+tIIe0+MzzpTQKHNSmEQp2JY/s0TWU= 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-07_04,2026-07-06_02,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-2607070160 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: 1783441238848158500 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 | 63 ++++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 20 ++++++++++ 4 files changed, 87 insertions(+) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index 59c2a47539..1b6a874b90 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_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 e0fdf28c67..06aaaa3c28 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -289,3 +289,66 @@ 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]; + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + int keysize, i; + uint64_t addr; + 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 */ + for (i =3D 0; i < AES_BLOCK_SIZE; i++) { + addr =3D wrap_address(env, param_addr + keysize + AES_BLOCK_SIZE += i); + buf[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + + /* 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 */ + for (i =3D 0; i < keysize; i++) { + addr =3D wrap_address(env, param_addr + i); + key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + + /* fetch tweak from param block into tweak */ + for (i =3D 0; i < AES_BLOCK_SIZE; i++) { + addr =3D wrap_address(env, param_addr + keysize + i); + tweak[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + + /* 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 */ + for (i =3D 0; i < AES_BLOCK_SIZE; i++) { + addr =3D wrap_address(env, param_addr + keysize + 3 * AES_BLOCK_SI= ZE + i); + cpu_stb_mmu(env, addr, buf[i], oi, ra); + } + + 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 26 10:06:44 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=1783441280; cv=none; d=zohomail.com; s=zohoarc; b=cDJCgbwgEeyqgw2CRbyALCHcIEc9YSfrjvCQQLlvavla/Sm6+5ZpyTLcWGHeQka5mqEFiI4rzdlLS1dNQthHtkphZ8gz46HMVFXuKPNq6SPpMAXmU/+j93OAVOzLeDzds9AQJ73ovu4rLcVpkDjFPVmM5SPBd0fYHhojsV3mSIk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441280; 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=pZ+0h4/18rkE4Ug+S5fDHzohhgnYB+d/pd+cblImuSc=; b=MOS+grldKaNoN2eXQS6WIOlLrgfwZm0cMUVAapSRzpBxj/0rC+XKBrHFbIhRj8t8g6REF5SEt3rc4XkXRDMyPqF3sMX+2VUZ7v5y5upellifka3zNzGeRgi0MObERYgcd7fwcbLRvsrx+WA0i6rofaBwq0baQuJUmUDWRTcUztU= 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 178344128038868.02547249253473; Tue, 7 Jul 2026 09:21:20 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8VV-0007gM-MN; Tue, 07 Jul 2026 12:18:49 -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 1wh8VE-0007Tr-B7; Tue, 07 Jul 2026 12:18:34 -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 1wh8VB-0008Bu-1d; Tue, 07 Jul 2026 12:18:32 -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 667FmWSO669870; Tue, 7 Jul 2026 16:18:20 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 4f6qknfxwv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:20 +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 667G4apR019135; Tue, 7 Jul 2026 16:18:19 GMT Received: from smtprelay07.fra02v.mail.ibm.com ([9.218.2.229]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 4f7cgq3tuk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:19 +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 667GIFjf50659750 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:15 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id B133B20040; Tue, 7 Jul 2026 16:18:15 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 97B9C2004D; Tue, 7 Jul 2026 16:18:15 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:15 +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=pZ+0h4/18rkE4Ug+S 5fDHzohhgnYB+d/pd+cblImuSc=; b=icwOPueb4L+2NAlADy/DuSdrP1AgYlj9q VVmJBzxkMJ56UAMpBdJVY/GjWYg65bJGQDtEqPrIccHj8//J5r/Ocw6tHsVUvCPw h1vH1AlAoJR2gCpYZNqRZ3RRCvkmKWkxWRISzxTIvuvSJa+oBKYQJGVQE9Hg+F2C Ae6VF9iY4CRIByN8YyWz3ZS9okmgBE9TVT8rWvlUykobsSyQKQ2KC99dnSUaFs7i VWQwOMc2k1cIyaPP9gjXsPJFt4VIvnLg2jYHJs2wgUwoReUlS7IrrJA/HWkVwJIA Y/uzb6Zf2X4Qt6SQ4kr+QUXf4rci2gwm/echveN0j/JdFh7lSmVRA== 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 v11 09/21] target/s390x: Support AES XTS for cpacf km instruction Date: Tue, 7 Jul 2026 18:17:56 +0200 Message-ID: <20260707161815.40919-10-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-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=6a4d26cc cx=c_pps a=bLidbwmWQ0KltjZqbj+ezA==:117 a=bLidbwmWQ0KltjZqbj+ezA==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=Y2IxJ9c9Rs8Kov3niI8_:22 a=VnNF1IyMAAAA:8 a=zF3DBZfHWt6I_7Vt9OoA:9 X-Proofpoint-GUID: PbArv_iyIpsHyDa-tVaS9irlV2W6qm-f X-Proofpoint-ORIG-GUID: PbArv_iyIpsHyDa-tVaS9irlV2W6qm-f X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX6LO1drn+qxvk vGRr4gb9j4i6/jIYlNqSzSQ3OfywzaGo0a7YMcHVqDX6j0NEz201IkPVaW2FvORKEzxY7YGVkPb qBzvdS2trif4TlzrmlF2uChH8xV1/LA= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfXxzvjq5JK4KlZ KjDLk68Sxnih2YhwTdv8aUnAOLEf7Rdaj6xZkTL2Kk3hechmMUHsNvTO9pAxotLyAsaS9IYdE3C tIYoISCdZLF3yuh8WMq97jMIs9+Xw85543sWr1nfqmqSE5fTXKHMpZLwpOFynOfMEQJv/cgy1ni 6NYeUA3GMbbfSrbtgock28iNjUEy6CiULb5P+z7UDYqu8bDOTOEE7BwgiQCcInYyOiXhIluTpg8 GiGEgzYLKVOUObJliacfbSEVhy3fabDuhANkI5NyGwIEG/e5GgxptZNm/PXFJYFXELOoonFpQ1C 5EltgBSntdLXSQA8DQfMVjIN+SyVeajJxviXfYUWIjh3ESCo77LN9VCEE1lfdxtmnkbgTNGf9Gn jcwABbllYZ6cgi9mlZa2ox/H9EAnP1JBDHS4IDvxRtTrP8/yeUBINPkhTizEpTq1VvbsOAEMskR zgN2Dfo14Easx2+lkdg== 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-07_04,2026-07-06_02,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-2607070160 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: 1783441281262158500 Content-Type: text/plain; charset="utf-8" Support the subfunctions XTS-AES-128 and XTS-AES-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 | 108 +++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 6 ++ 4 files changed, 120 insertions(+) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index 1b6a874b90..f9b1a40c7c 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -924,6 +924,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 06aaaa3c28..3512c2712a 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -352,3 +352,111 @@ int cpacf_aes_pcc(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, =20 return 0; } + +static void aes_xts_prep_next_tweak(uint8_t tweak[AES_BLOCK_SIZE]) +{ + uint8_t carry; + int i; + + carry =3D tweak[AES_BLOCK_SIZE - 1] >> 7; + + for (i =3D AES_BLOCK_SIZE - 1; i > 0; i--) { + tweak[i] =3D (uint8_t)((tweak[i] << 1) | (tweak[i - 1] >> 7)); + } + + tweak[i] =3D (uint8_t)(tweak[i] << 1); + tweak[i] ^=3D (uint8_t)(0x87 & (uint8_t)(-(int8_t)carry)); +} + +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 buf1[AES_BLOCK_SIZE], buf2[AES_BLOCK_SIZE]; + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + uint64_t addr, 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 */ + for (i =3D 0; i < keysize; i++) { + addr =3D wrap_address(env, param_addr + i); + key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + + /* 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 */ + for (i =3D 0; i < AES_BLOCK_SIZE; i++) { + addr =3D wrap_address(env, param_addr + keysize + i); + tweak[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + + /* 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 buf1 */ + aes_read_block(env, mmu_idx, *src_ptr_reg + done, buf1, ra); + /* buf1 xor tweak =3D> buf2 */ + aes_xor(buf1, tweak, buf2); + if (mod) { + /* decrypt buf2 =3D> buf1 */ + AES_decrypt(buf2, buf1, &exkey); + } else { + /* encrypt buf2 =3D> buf1 */ + AES_encrypt(buf2, buf1, &exkey); + } + /* buf1 xor tweak =3D> buf2 */ + aes_xor(buf1, tweak, buf2); + /* prep tweak for next round */ + aes_xts_prep_next_tweak(tweak); + /* write out this processed block from buf2 */ + aes_write_block(env, mmu_idx, *dst_ptr_reg + done, buf2, ra); + len -=3D AES_BLOCK_SIZE; + done +=3D AES_BLOCK_SIZE; + } + + /* update tweak in param block */ + for (i =3D 0; i < AES_BLOCK_SIZE; i++) { + addr =3D wrap_address(env, param_addr + keysize + i); + cpu_stb_mmu(env, addr, tweak[i], oi, ra); + } + + *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 26 10:06:44 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=1783441211; cv=none; d=zohomail.com; s=zohoarc; b=n/6TBZYK8Cul3Zre5hN87AZeJaY6phd6dMTyyOWez4npcZQhHNIfgo7am2HxnVAVfBh7x8lYBv3U2AZSmVPau+D5oBizqa2vRFvjdxa2OOk7zGuPTyXQ9G1jGskAZh7AVYpT8KElFni20Jeo8AyXTheYELjHbPbtXkoej4bzU3I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441211; 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=cDnWlrLgXK/jDS57JoAfCI5ey18rBuiB7cHO8+wrbG8=; b=b5mbLR6uCfh26ouOHMV4xjpcWCot/kGGInYhsXi7t21TZ330C+kpiXo+QTQtLDXXyne2esGmVhGa76yKoLOopyQydRh3uOYyyCIHiONzUZgiKabgnA/K2FrCxPzbtWxtWYkNYlwDf1BDX/DhekfnbpPcn0PvInOAiON2iCH0Zv4= 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 1783441211638321.14952158142387; Tue, 7 Jul 2026 09:20:11 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8VM-0007Yf-Sw; Tue, 07 Jul 2026 12:18:40 -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 1wh8VC-0007Th-Re; Tue, 07 Jul 2026 12:18:32 -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 1wh8V9-0008BC-JR; Tue, 07 Jul 2026 12:18:30 -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 667Fmqxl3446435; Tue, 7 Jul 2026 16:18:20 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 4f6rkdrpyy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:20 +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 667G4cRV019154; Tue, 7 Jul 2026 16:18:19 GMT Received: from smtprelay01.fra02v.mail.ibm.com ([9.218.2.227]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 4f7cgq3tum-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:19 +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 667GIG4r61735396 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:16 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E2E052004D; Tue, 7 Jul 2026 16:18:15 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id BF1FC20043; Tue, 7 Jul 2026 16:18:15 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:15 +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=cDnWlrLgXK/jDS57J oAfCI5ey18rBuiB7cHO8+wrbG8=; b=tWsCvz3k8Zq8KIgQUZeWQ6Q3NM82ix1AE QPMKRLbjUNz51cVHOJZ9ueX6hBoRlQTwj32iWtDMI9Ne/wKvtWfySw0wgBjdAEwG 7R7z3kttcu22KunmTrf4CVfMD7OtLVG6J//jRkUG+DK2K9SC+w0UvZr4EPL2zge6 kjLeNqKPytZ10E7JSdw1dIqXIubN5+80vpHiuIki4ZL+ZVjiY0/EhzMCwMbxKGvt t7S7gVobMjkxjtrjgr6mRgGz0LAw1B3fLD1igkSZxZ2py59rH16d02qxqJHzxqfZ fvEJAJtL7eastPBJyvb79JPPnq3RDNWD7t5cq4t5Kdi+mRxYlgieQ== 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 v11 10/21] target/s390x: Base support for cpacf protected keys Date: Tue, 7 Jul 2026 18:17:57 +0200 Message-ID: <20260707161815.40919-11-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-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=6a4d26cc 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=pDJEeJrE-AQHYYEhGn0A:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX7BjiG0H8MqS8 DmsGlomTfWXsFxwIydJqgr+5LiFH31dLWgqvlep2sYcbP0VHguIXG/RmwSp0EMkZSUHS3mO1TII 8RHk0KtZReOSmLgrneTAYscSZTuHyW13mtgF3ssb/X2aDi/ti8zCURfHCcHYnN2AvvFGnAnfbvf Kc+4ksfRhAfF4DA6Ah9qAySZdzBiByT6v4KbEYwB/IrjbEO3i+wMWrxxhcZw86kS+IyMy4qlp2e nsZI+WsLJss3GAtAe+CZO03sfOxRbX+CaRaI6a18CxvwOSmJPe2M4fOp4NFVd3WHqp59M+F2krq wtjB8YmNrHdWTb0aQ3QgeR4hPJiBn/QqtHfoZiL5GrJXS22DC+0ubWIX55nG42MoyHduapyUjSo lYKlgLl+Jqe3/f7I2IA247hKhnsPYHbPapbgt55wxSunKVtwr7of0zJ261zuL4mhnu+T7wbhpGB RPP4aDhX1dd4irppbZw== X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX9oYAdjsqaZXa Uic/5fYshnexZJqbnDmDsuU/AzQxoc/kg0bNhvs3ZTqhHsRqmR2WL8EvNy1l9mXjvt8ocuykbVE ngDMypVT2X7sljLWpW9F5o6a+C7nZn0= X-Proofpoint-GUID: AW-1tM3k-oRPySy3NP0huiQtbAdztibY X-Proofpoint-ORIG-GUID: AW-1tM3k-oRPySy3NP0huiQtbAdztibY 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-07_04,2026-07-06_02,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-2607070160 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: 1783441212616158500 Content-Type: text/plain; charset="utf-8" Add base support for cpacf protected key handling. 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 --- target/s390x/tcg/cpacf.h | 25 +++++++++++++++++++++++ target/s390x/tcg/cpacf_aes.c | 39 ++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/target/s390x/tcg/cpacf.h b/target/s390x/tcg/cpacf.h index 61ce71476b..b5cc1f202e 100644 --- a/target/s390x/tcg/cpacf.h +++ b/target/s390x/tcg/cpacf.h @@ -254,4 +254,29 @@ 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 } + #endif /* S390X_CPACF_H */ diff --git a/target/s390x/tcg/cpacf_aes.c b/target/s390x/tcg/cpacf_aes.c index 3512c2712a..2deee597c7 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -460,3 +460,42 @@ 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]; + } +} + +/* + * '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]; + } +} --=20 2.43.0 From nobody Sun Jul 26 10:06:44 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=1783441228; cv=none; d=zohomail.com; s=zohoarc; b=kZYMOZ6OxdmG8kotmrcUohEfaQ8xtGLCDuEp7a97HX7yv36PYcqrKyrOeSLW11qpilgUuRUp+AYruGHORsIgi56oRGotMSuChbFwLRHlJSbtVowWpBoPCpf+PvhJ7LmGZNDNt6VG0XiKFlcLKk65Br5Hvz+D3AimCtXOETudJok= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441228; 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=XzPviofnnJ4c419zXG491JzW5BEKUsNAM/4uO8uuDKc=; b=Bu0+fIaFoVQJ6dNkJFb4SrrTObQ3plt7w1Sabtv9IeqEAsdmQ9NbU3koI9GK+yBRN5cFDvqFQnBtYFyXSQwvC5Y/Bvt0uB51PekxURDPoR3hUwQRCAYrVeHyA+M9QeM7JSrY4dE0L3UTRvzCUMDc8WIw36vjsp2yLHYHITdnZGw= 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 1783441228288587.9273152939203; Tue, 7 Jul 2026 09:20:28 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8Va-0007iL-Ky; Tue, 07 Jul 2026 12:18:54 -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 1wh8VZ-0007hw-UZ; Tue, 07 Jul 2026 12:18:53 -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 1wh8VW-0008Ch-MU; Tue, 07 Jul 2026 12:18:53 -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 667FmKS44084922; Tue, 7 Jul 2026 16:18:21 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 4f6sw4r5pj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:21 +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 667G4bAT005417; Tue, 7 Jul 2026 16:18:20 GMT Received: from smtprelay01.fra02v.mail.ibm.com ([9.218.2.227]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7cvw3sjr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:20 +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 667GIGdY61735398 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:16 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 183F220043; Tue, 7 Jul 2026 16:18:16 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E71FB20040; Tue, 7 Jul 2026 16:18:15 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:15 +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=XzPviofnnJ4c419zX G491JzW5BEKUsNAM/4uO8uuDKc=; b=iMfR90UVuT2QF4Pgf7QOvUrOawujOMlGi dT2K1oT/N3+/6yVU0a+kVBe/dSPsKD539n79DbYvJjOMkeIK/7HVbJDglEK+0nbf /QVwUDpZPZUzzzNs9/am24P6GHwFd6EiFnmPAomvQJRn6RqpzdB31kEhhmTO3Gh2 fuH4H6vDoZ/6FZ0HVJVfCueKf9I3l5/HPX2T5e1WfZ0FCLe7OaCYfVGXsh9i8vwy NvFvvKaBCa7Hw4ALw4OkNacNBUeuJe2EWdL341Gc/jUcgSrpnT70bfJFRYK1nEKV GOzjfae0F9pvi/BvPTzAdhQofMFVMNvU6u8T6BEjYf8J86hh6jINA== 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 v11 11/21] target/s390x: Support pckmo encrypt AES subfunctions Date: Tue, 7 Jul 2026 18:17:58 +0200 Message-ID: <20260707161815.40919-12-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: ge3CAI1ubBTltft43Xg4Z1ddbRNHC65B X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX8qPjMHHe+9VC VHGNuihnxPl64W9KpBQlSs8OuGPxsWJXDAJbcZLLiXyi5Q6ZRk0YhTBfqAkEiitN5UVRdj25zJG S6pJpG36fh70F3TN4iAUuaEGljxfDHAEwa4XnSBNTUsco7bLUz4tGNe8PORlbcnYUPbofcuDlFo nDpmgRdj0TB5QEpaOvOiWpNkr0jp97FwRjtyRRLjM0YwCA0RMthISTsthchZTytpXq2tUr/n0h2 Z+G6g9UVCpbHJCvbxL3WnxVe7itpDvQccrc2fV4QTY+B+86Awt3fjud2nCf2ytzVakw63FDdx/f OhKAkysPZAzt/Q6xRMeTE+9x3rnaVh1aaBD/1YrA5/7n0yoSnKx7rMKmXBmU860sJwJTcSQxSVF S0UuuHzxFGbAqLyHdF1Hll9ESEU6OOFyNeZvczTKRFhsifotJXWLsieeuLIkpG1IbeDhpgi8mCw 8V5WNMhjFgRCIz8jfmQ== X-Proofpoint-ORIG-GUID: ge3CAI1ubBTltft43Xg4Z1ddbRNHC65B X-Authority-Analysis: v=2.4 cv=FqQ1OWrq c=1 sm=1 tr=0 ts=6a4d26cd 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=Z4AAViVgUL_E5abT2tgA:9 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX7ejqANE5METw jHXH7kOiDxiNibUTpRSCNqn5wrcuujakAZre/L7K3gnkcB1r3YKgQy0KukQaynRIKJj19i7Xm4V qIkJ94pOb09FCeG3ORmvlAQ8qAHO1jw= 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-07_04,2026-07-06_02,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-2607070160 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: 1783441228830158500 Content-Type: text/plain; charset="utf-8" Support the subfuctions PCKMO-Encrypt-AES-128-Key, PCKMO-Encrypt-AES-192-Key and PCKMO-Encrypt-AES-256-Key. These subfunctions derive a protected key from an AES clear key by encrypting it with an internal AES wrapping key. More details can be found in the "z/Architecture Prinziples of Operation" document. Signed-off-by: Harald Freudenberger Tested-by: Holger Dengler Reviewed-by: Finn Callies --- target/s390x/gen-features.c | 3 +++ target/s390x/tcg/cpacf.h | 4 +++ target/s390x/tcg/cpacf_aes.c | 45 ++++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 21 +++++++++++++++ target/s390x/tcg/translate.c | 9 +++++-- 5 files changed, 80 insertions(+), 2 deletions(-) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index f9b1a40c7c..d3e69aaca6 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -934,6 +934,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 b5cc1f202e..1d7d9baf0c 100644 --- a/target/s390x/tcg/cpacf.h +++ b/target/s390x/tcg/cpacf.h @@ -279,4 +279,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 +/* 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 2deee597c7..28c0a0da8b 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -499,3 +499,48 @@ static void decrypt_protkey(uint8_t *key, int keysize) 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) +{ + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + uint8_t key[32]; + int keysize, i; + uint64_t addr; + + 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 */ + for (i =3D 0; i < keysize; i++) { + addr =3D wrap_address(env, param_addr + i); + key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + + /* 'derive' the protected key from the clear key */ + encrypt_clrkey(key, keysize); + + /* store the protected key into param block */ + for (i =3D 0; i < keysize; i++) { + addr =3D wrap_address(env, param_addr + i); + cpu_stb_mmu(env, addr, key[i], oi, ra); + } + /* followed by the fake wkvp */ + for (i =3D 0; i < sizeof(protkey_wkvp); i++) { + addr =3D wrap_address(env, param_addr + keysize + i); + cpu_stb_mmu(env, addr, protkey_wkvp[i], oi, ra); + } + + 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 26 10:06:44 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=1783441261; cv=none; d=zohomail.com; s=zohoarc; b=h2Ggv5y5IybThzciaJS3HKqXSvblsUIctcp7aHfOsjZA2B7V/YHiCT8IYtvMEDjGd4ot/BbQdoKBv26/Jp0k9/Fu49ZLhtqA7hmspZu6kC/XiqKqzNOU3V5ToCaUdja8DWFnA1BdZ8+MV3vJVJLYb4X2Lb3Rfq/qGOEnfSKmtgQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441261; 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=u8/tpfLQH8GAa3GsX5IQ9yu62JDdwJZoiGc0Jewyj0c=; b=MTg0pzJ9IdneM0MFaR1OA9SZFudjifFWRIxHGc0///D4yjk98Vcv69vAhSMzJS4sK0PwQrEp2LGDEYPy6ZUoy7aPlBBGL7GHA6C6DOkc9dnO0QcoCpjrT1RInYrDuRXnlSGZyMZNRKa3KbNp5tvHQzDyktiztlbsg6KnNzGL+6w= 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 1783441261957173.7774885864835; Tue, 7 Jul 2026 09:21:01 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8VV-0007gN-Ul; Tue, 07 Jul 2026 12:18:49 -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 1wh8VE-0007Ts-CC; Tue, 07 Jul 2026 12:18:34 -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 1wh8VA-0008Bk-QC; Tue, 07 Jul 2026 12:18:32 -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 667FmRkw310346; Tue, 7 Jul 2026 16:18:21 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 4f6suqqw2t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:20 +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 667G4elv019302; Tue, 7 Jul 2026 16:18:20 GMT Received: from smtprelay01.fra02v.mail.ibm.com ([9.218.2.227]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 4f7cgq3tun-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:19 +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 667GIGQl61211084 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:16 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 42BD920065; Tue, 7 Jul 2026 16:18:16 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1C80C2004D; Tue, 7 Jul 2026 16:18:16 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:16 +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=u8/tpfLQH8GAa3GsX 5IQ9yu62JDdwJZoiGc0Jewyj0c=; b=ksr0dwaWSIYRtsqQQl1bkR3+qxXKB5bqF ORTn+N8m6E/oFOhlPf7AzJj/2FWItx/8c7TsgYj5ea7/kcLCv4vH27Kp6d2D0UIM 17V8C3Df4++yKcEvd/M3nXtDFCCkNUNLZqOLVMCYwXpEt6jp84ufXDI3Ar1f/blM +qFCw8CZVBraNA8o2e3NhAjKgAPa3hi6g1eOFKB2/T3EAYiXxVOeKAVZaNyNuyXE Tu9ccuBDBjYdChzZcztORT69rIeW61LxIPsEAid43rc0yyF8ZnTqjBYgGXWXASnc kqvs61timGWKmRHesma0xKSj/7t8zY+GaAL74Uyd2uro+n/9Vzqdg== 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 v11 12/21] target/s390x: Support protected key AES ECB for cpacf km instruction Date: Tue, 7 Jul 2026 18:17:59 +0200 Message-ID: <20260707161815.40919-13-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfXz3p6SNabyWA0 rL+ZbcRvYTFhCpwKjg9u4mjCFJkcigWHgSs4JUckjWdnYJQ9MSaLwH4Y6t5gX51D2HgKECzoBks AIgGrmGTs33R4rPMzrQKHIlmeclrVvs= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfXyEYCI01zHG/I NNWsZFo3J8BeIT3AJAVmU4viyKbfSt1W1RW/5Bf59wdFkSE5QGnpSgyEtaUBIwDx4ReM+FFMBbZ yNFPN6nh4qqqmkziOUvdhblt5WAa1kFFh4mXui6YpkxKXPthslzpVeEhCbM5G/7QcwFWiwiJF5b EPI0FwgI6Pnc/0+dLQGeRtFdjyEIe8T9+UHbRYhsKJerys77We6PaX1sUv6AsbB0+SnVUV7yygD eWZLT2Y6S2uDxcfryb70TYRVUildoi582t+HtbBT75bcz/+712DTyFmwrApODG0yBvSUOvlYGGI UH4VQ/SWoh4fE+jJa9lK7gvP/Am8DDYxCgMgdtdlejXrTCfHSVrt8IL8s/FOMHiiSKpGKPYpxlJ lYKeBLmemXxEEerNzxG2QZXJonhx+7KcvPPirvk692IJW7zBVF35i9BRr0ujGiDGxHzDYDkprvI msQyBuH3WlvJqmYWlyQ== X-Proofpoint-GUID: nf6UCTm3D9tGCUn_Tqxs3kYJdYD6TDEG X-Authority-Analysis: v=2.4 cv=Oot/DS/t c=1 sm=1 tr=0 ts=6a4d26cc cx=c_pps a=bLidbwmWQ0KltjZqbj+ezA==:117 a=bLidbwmWQ0KltjZqbj+ezA==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=uAbxVGIbfxUO_5tXvNgY:22 a=VnNF1IyMAAAA:8 a=WpPIafo2g3WOFiBud6QA:9 X-Proofpoint-ORIG-GUID: nf6UCTm3D9tGCUn_Tqxs3kYJdYD6TDEG 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-07_04,2026-07-06_02,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-2607070160 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: 1783441263028158500 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 | 86 ++++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 7 +++ 4 files changed, 100 insertions(+) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index d3e69aaca6..71e0e41d6e 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -924,6 +924,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 28c0a0da8b..5ad518489b 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -544,3 +544,89 @@ 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 }; + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; + uint64_t addr, 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 */ + for (i =3D 0; i < sizeof(wkvp); i++) { + addr =3D wrap_address(env, param_addr + keysize + i); + wkvp[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + if (memcmp(wkvp, protkey_wkvp, sizeof(wkvp))) { + /* wkvp mismatch -> return with cc 1 */ + return 1; + } + + /* fetch protected key from param block */ + for (i =3D 0; i < keysize; i++) { + addr =3D wrap_address(env, param_addr + i); + key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + /* 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, *src_ptr_reg + done, in, ra); + if (mod) { + AES_decrypt(in, out, &exkey); + } else { + AES_encrypt(in, out, &exkey); + } + aes_write_block(env, mmu_idx, *dst_ptr_reg + done, out, ra); + 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 26 10:06:44 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=1783441246; cv=none; d=zohomail.com; s=zohoarc; b=E1JUXxlshhO3Z8Vp2dNWgnXeG9p7HObWj3X7Iip+BHkUvGiFsnIiOdzeal/4XOhfJj+L1o8fpawJEvkrf7tt8L6OBYwZzPXlrlHqM7Vti0pd6PRfGRzeXfU5ewCxcXaYZB7j1UiL0lgIwVOXYOc7DUB0ElCob+xd5tiNVXXI2ws= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441246; 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=iuwGFWp3U3+w2/b94Ancg5A6A6+m8z2EeclBcKForQs=; b=USP305DxLW/OecasNfhqFhagqdnxBfarjOezSdcE/JMzG/CgkjE/rFkyyTThp1S8rFW277FuP4D2PxgEhj/hS2nIUer3bXh7igwQigXV7/Gqzo9XjLHeOzl/IeD47/qHlO7Q++vOYjNrWYZ2kYx9bhWNpeZo/Sj2Pd5NDcNs94A= 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 1783441246504947.9575675192633; Tue, 7 Jul 2026 09:20:46 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8VQ-0007aA-HS; Tue, 07 Jul 2026 12:18:44 -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 1wh8VD-0007Tl-82; Tue, 07 Jul 2026 12:18:34 -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 1wh8VA-0008Be-Ky; Tue, 07 Jul 2026 12:18:30 -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 667Fmmmq3446385; Tue, 7 Jul 2026 16:18:21 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 4f6rkdrq01-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:21 +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 667G4aGe005411; Tue, 7 Jul 2026 16:18:20 GMT Received: from smtprelay01.fra02v.mail.ibm.com ([9.218.2.227]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7cvw3sjs-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:20 +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 667GIGtJ61211086 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:16 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 697442004B; Tue, 7 Jul 2026 16:18:16 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 44E472004F; Tue, 7 Jul 2026 16:18:16 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:16 +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=iuwGFWp3U3+w2/b94 Ancg5A6A6+m8z2EeclBcKForQs=; b=IlDpaePcGXVkRoZLsd1Aca1nXlrfhSBj8 TSU16xW+Bs1kyR4CqxTvdAave9aiFJ9xyd3Bn9YTTdc/mTfFnDcJsPAU4aZYj48M sWpWIDN6382JH/JptgiFtMJt8v87xnRjH/6gAxjtFEtXsn2XLMEDIu7vgFMomKSJ 862vzqnGZqbO6mhfroHuEl5WKzMeeDhKBFUdqMCbZ/8aRRu56aYyf0kOVHJ7GVsr 3jBBnK3Dy2+tfqupS5T6kld/ftoRhIfn2nfcamcq9nt7fnT0JuOKzKBCQLEeXjko iuni0mWR9sRe/3G4+zsLnRzyyxqk/4nehOPkxMo06vuLKhTiEbgvw== 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 v11 13/21] target/s390x: Support protected key AES CBC for cpacf kmc instruction Date: Tue, 7 Jul 2026 18:18:00 +0200 Message-ID: <20260707161815.40919-14-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-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=6a4d26cd cx=c_pps a=5BHTudwdYE3Te8bg5FgnPg==:117 a=5BHTudwdYE3Te8bg5FgnPg==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=V8glGbnc2Ofi9Qvn3v5h:22 a=VnNF1IyMAAAA:8 a=1XR5bUzyU_lZOmb26nMA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfXzihonaj4J8VS wGznApOYdrPN+3tsejyK3mtdpszQizv+E2wLGfoFcDZtwJgkzJLQ4RYVAvO/Qa3VK7mb04Tc7KJ k/ZxFrw2BGpn0qC3jyWiMsH62Wlb8hw3MnfG4kgMZM910yam53hjvcD2OEXBAWeSUgWSugZWYmL askq+vjWkOwr03J4ZvnM+C1Pe6m6axA7aebXEyH/DOphtJk0N/HrBY+RObR9XxlGkryyeDd/oYM FpF4LDp40ENb9p4UaOy6YGLuYleKECrkUHHGTR4XnT2nupjLxFh/keuMeXzsOe+p/R4k/V6JWMY Yom6tdghwh0d8QohClNxNCyk5KphTal2VVoMZVrN8ftzuqiGsCIOXKpmqT0mqr9HTI6fP5eRzXY 95gE09KsOt19kMwwnOmXgcXS2JyDFZO6jqkVSoFmzU7TOKH7NVrd/Z3DbIt+7ZtP9T8YPuImA2n wMHOA/UrCnUkEcJVjIA== X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX+K39J5Q5Ztnf pTp1jDx3KmFseqy6SGcUrrRHoQahAnbVo/6p5UCM7L8nWr/hIPPJlzS4xgkMTGeqbV02R3DOPvz BuxISEbmkqZYURVTm6VxLv95App7cno= X-Proofpoint-GUID: odcwdF8R8Ta9bhCzi3IVz7p-dNsmEOil X-Proofpoint-ORIG-GUID: odcwdF8R8Ta9bhCzi3IVz7p-dNsmEOil 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-07_04,2026-07-06_02,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-2607070160 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: 1783441248852158500 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 | 108 +++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 7 ++ 4 files changed, 122 insertions(+) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index 71e0e41d6e..074c53aecd 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -932,6 +932,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 5ad518489b..6874ceb1b2 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -630,3 +630,111 @@ int cpacf_paes_ecb(CPUS390XState *env, const int mmu_= idx, 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], buf[AES_BLOCK_SIZE]; + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + uint8_t key[32], wkvp[32], iv[AES_BLOCK_SIZE]; + uint64_t addr, 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 */ + for (i =3D 0; i < sizeof(wkvp); i++) { + addr =3D wrap_address(env, param_addr + AES_BLOCK_SIZE + keysize += i); + wkvp[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + if (memcmp(wkvp, protkey_wkvp, sizeof(wkvp))) { + /* wkvp mismatch -> return with cc 1 */ + return 1; + } + + /* fetch iv from param block */ + for (i =3D 0; i < AES_BLOCK_SIZE; i++) { + addr =3D wrap_address(env, param_addr + i); + iv[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + + /* fetch protected key from param block */ + for (i =3D 0; i < keysize; i++) { + addr =3D wrap_address(env, param_addr + AES_BLOCK_SIZE + i); + key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + /* 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, *src_ptr_reg + done, in, ra); + if (mod) { + /* decrypt in =3D> buf */ + AES_decrypt(in, buf, &exkey); + /* buf xor iv =3D> out */ + aes_xor(buf, iv, out); + /* prep iv for next round */ + memcpy(iv, in, AES_BLOCK_SIZE); + } else { + /* in xor iv =3D> buf */ + aes_xor(in, iv, buf); + /* encrypt buf =3D> out */ + AES_encrypt(buf, out, &exkey); + /* prep iv for next round */ + memcpy(iv, out, AES_BLOCK_SIZE); + } + aes_write_block(env, mmu_idx, *dst_ptr_reg + done, out, ra); + len -=3D AES_BLOCK_SIZE; + done +=3D AES_BLOCK_SIZE; + } + + /* update iv in param block */ + for (i =3D 0; i < AES_BLOCK_SIZE; i++) { + addr =3D wrap_address(env, param_addr + i); + cpu_stb_mmu(env, addr, iv[i], oi, ra); + } + + *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 26 10:06:44 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=1783441258; cv=none; d=zohomail.com; s=zohoarc; b=d7TnYcKGowFc8jJqi8e3SJlPRLnJscId9uP2/Kj/QmFyWxJTCcbQqXxjWPDJENwciwr/wpHfCnV6bIekuEJuoyvLCBNlT3SrxE5xkFrUlfIxHt8TnVbgbdESqZjCSg5pchBgHLBcBNEk3LlpYQX7G9B4cqdEXimA/dhDMbfV8/k= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441258; 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=EA2tsrLFHFzduI+W/VGsC4p0pqm04WsnBEKq5SBLRaQ=; b=Cd5o1wogcbelpyOTzQ8Ufc1prcsEflilexP+Qavj6pKA/48Swjj9C41qzqmgJfVQCAJCsiup2Vy7KgkG7viChd99DfvPvT4bkgjaF3dqcCtjii312kA+o25J6zdKere5SqjiCrwB9AQ0g+tLVDI84/xDg9ip/CX9txqmq8NuAao= 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 1783441258642866.5106555949425; Tue, 7 Jul 2026 09:20:58 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8VQ-0007a4-EZ; Tue, 07 Jul 2026 12:18:44 -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 1wh8VE-0007To-4k; Tue, 07 Jul 2026 12:18:34 -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 1wh8VA-0008BK-L8; Tue, 07 Jul 2026 12:18:31 -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 667FmOeS4186825; Tue, 7 Jul 2026 16:18:21 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 4f6sp3r80g-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:21 +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 667G4g6r019680; Tue, 7 Jul 2026 16:18:20 GMT Received: from smtprelay01.fra02v.mail.ibm.com ([9.218.2.227]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 4f7cgq3tur-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:20 +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 667GIGeJ61211088 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:16 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 91D9220040; Tue, 7 Jul 2026 16:18:16 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6D6EC2004D; Tue, 7 Jul 2026 16:18:16 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:16 +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=EA2tsrLFHFzduI+W/ VGsC4p0pqm04WsnBEKq5SBLRaQ=; b=HanCyDqDJyfXEM2afo4syxKxwWHPe6zUY eNJPcolJq/kFwies5jwoixsMRITj0e+COEJGRqYUmuqO5JQ7Th5tAV+0FJILB5FB GYcQQXkezimb6kxvTbZYAX30GM/ku4p4sZX82f1K5m615T/nS1Jv+TErfa2PKXsb j2DRVS723Q5eOSleGUtxzeLb8g2Tu641pN3rNgOVGPSIOrhcTt8A0+ud7RY9tQiP tIwIEuOX094HA/qt6zSAc+Azx64GXIxsQMN+WiGmgEeegLRpJeMXO6fXDIBtSFXs 4uVN2SaHjTJ++ztqMMLizrJSEf7byMViN/uqK2KwOTtysXjBirekw== 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 v11 14/21] target/s390x: Support protected key AES CTR for cpacf kmctr instruction Date: Tue, 7 Jul 2026 18:18:01 +0200 Message-ID: <20260707161815.40919-15-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-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=KsJ9H2WN c=1 sm=1 tr=0 ts=6a4d26cd 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=f59o6tnjY-_5Ge3baHwA:9 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX550ZVI/M32uP 5E4vsc7aWRKL4KEzkrLaVrKuhk7JTVA2SN/BSpHcSEVGzscA5hdCq/s+yazoK3AQDUK/NbxmCTK cRG9lwlI0Jb9oM9q8DyBzoVdRI3Y8Go= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfXz9GvcBYZXFUW eV6o52fqzmo2Or6uoTGvvzZLq+f19W6hXVqK2Ai4cYBNYC2VwLbPx38TnouGHYyVe314J3bZf15 NBEzrdS0LlP9vA6PbPwOvz2N819RzCVJ90ZGFvVf7+ARB61rjz0zERUVctTCLR101U9gAAnhHfP 7yCEpwtE4AXsJj7E+lonW8nOPKP7td/FsSVsNW3a7YNE67pY2kxU0HL5Jfbtw/3seySxXWlGOEs 9pyH+kppJ5HknO+HRlFqEXJhdXOfXZp7mfOVbtILJ6vAsNPmDEBnvRq0tmPbcvDUi+vPK1aPjDt 3BC+3h0KN47gruKRR+uF+ydurgsltS+CbgpnyVLx7NJ213SoQGXnoia0X0RoLdYrGEN38piN5e1 RFkSQHG2UrpcyC97gRWzeCs+xKTcN7A/l1PrZ6xtJKIIyejpifsjMo9dJbiNKR1pBgPmlSFZLmU +vCD6hPh4V8wcQ3eVfQ== X-Proofpoint-ORIG-GUID: SymgzX2gCbPc22skzmXW689Tolzw4isq X-Proofpoint-GUID: SymgzX2gCbPc22skzmXW689Tolzw4isq 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-07_04,2026-07-06_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 malwarescore=0 spamscore=0 adultscore=0 clxscore=1015 suspectscore=0 lowpriorityscore=0 priorityscore=1501 bulkscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2607070160 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: 1783441258920158500 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 | 89 ++++++++++++++++++++++++++++++++ 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 074c53aecd..4a131dc191 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -938,6 +938,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 6874ceb1b2..99e4d140b5 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -738,3 +738,92 @@ 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 }; + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + uint8_t ctr[AES_BLOCK_SIZE], buf[AES_BLOCK_SIZE]; + uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; + uint64_t addr, 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_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 */ + for (i =3D 0; i < sizeof(wkvp); i++) { + addr =3D wrap_address(env, param_addr + keysize + i); + wkvp[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + if (memcmp(wkvp, protkey_wkvp, sizeof(wkvp))) { + /* wkvp mismatch -> return with cc 1 */ + return 1; + } + + /* fetch protected key from param block */ + for (i =3D 0; i < keysize; i++) { + addr =3D wrap_address(env, param_addr + i); + key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + /* 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, *ctr_ptr_reg + done, ctr, ra); + /* encrypt ctr =3D> buf */ + AES_encrypt(ctr, buf, &exkey); + /* read in one block of input data =3D> in */ + aes_read_block(env, mmu_idx, *src_ptr_reg + done, in, ra); + /* exor input data with encrypted ctr =3D> out */ + aes_xor(in, buf, out); + /* write out the processed block */ + aes_write_block(env, mmu_idx, *dst_ptr_reg + done, out, ra); + 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 26 10:06:44 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=1783441248; cv=none; d=zohomail.com; s=zohoarc; b=UOabVHTme6Dvqm7zyAH0IgWjY+WCDWy3VGL9uH3zdukEKq9xdbMaqeYPbGtEE9Bvv0Vi85n40PXjXa0qYvrEOF7j1lZAH8Sc0nUKpFebAcuhYFWLzjLnX6vhvT1WedXsS4xCHux6cjMmJPuQ9pMyjD+NxYi3Ed16lC5Yd7FIVRM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441248; 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=mIbVUx0H3TH/x4zbIUp9XHnQkuON5665tVq1QWTgDLs=; b=TXq2lupzg7Xp95LquEcs57uN6fv3WRN7BxjWyxDvRdN0OcT+oX8zwLft3Uff834JXmJuKPwS66URbGOuo+XUGBtxifVU2hZnbdxVMMi22BwV/jkdT3zpD9hFrPOBJE/ss73tlO2kZZE5OfPEyleL/rUssl4TpZXoTqc/E4iqQvw= 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 1783441248096399.6965686583386; Tue, 7 Jul 2026 09:20:48 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8VN-0007Yi-07; Tue, 07 Jul 2026 12:18:41 -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 1wh8VF-0007Tu-KX; Tue, 07 Jul 2026 12:18:34 -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 1wh8VC-0008Br-P5; Tue, 07 Jul 2026 12:18:33 -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 667FmV0D310415; Tue, 7 Jul 2026 16:18:22 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 4f6suqqw2w-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:21 +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 667G4dIj005440; Tue, 7 Jul 2026 16:18:20 GMT Received: from smtprelay01.fra02v.mail.ibm.com ([9.218.2.227]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7cvw3sju-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:20 +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 667GIGBc44630344 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:16 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id BA2482004D; Tue, 7 Jul 2026 16:18:16 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9612920043; Tue, 7 Jul 2026 16:18:16 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:16 +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=mIbVUx0H3TH/x4zbI Up9XHnQkuON5665tVq1QWTgDLs=; b=bXfhijlW/wHa7nA01j9ZbDG78SfQUZvT7 cq1ooXjFAulhJD3xn0NSWPQf3wE0bsH4HACSZPXYekIIF+xIxv12gSyjPpAihshf 10kLZzaNYWspsY6J6XtX6TXcEw39gpq2G7UIrXkvQgKCdKn5kemqzMeW3Vp+dXD/ 9HjhNg94VBPHixhJgp2hdLcFG3RfI6noW705e7wuFe3tm/Mshxn/5sYOMCkOHZEJ b2RvHrSd68jO11Os8sBm5EXix1DHUC8o0ajg26bfKaiyBmmlmDEix3nvxvXTn/WC yUtJJLMCSAGN6yTpMyFhF0GK7RRgAeVBWItwdNO2CuPhSYClmYMdw== 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 v11 15/21] target/s390x: Minimal protected key AES XTS support for cpacf pcc instruction Date: Tue, 7 Jul 2026 18:18:02 +0200 Message-ID: <20260707161815.40919-16-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX1JZ7CP+aMUk6 7M6g9nOJvSu2Ra5gCdIOM2RvU+eVF3BSdlteYG5FidlBQ8wvjtTw4B2+FwOLtasNTS91BiaMuPB 2YzmXM3fckA/O2y7XWDfPTEZSHuZaYM= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfXxIg/nKiOR5+O m11+HJ6ALNt1pVAKfwdrPzz/SnEBHiGLt/tpnfAiz9f25NjJLWGq0Zyt7K8KDbO8keh/pmmtMeA 6yqSooGq28meomhnSMoCigJGObodXy2R+nKG8kPSt/o/EGKC7mAHzYp3rCMNUuD23ULWL0k5NkY yhfTdgQqXMF3GpR96pr26QhKFkQEdwb5iRpkjO3KjnrQ1lPNYPt5rokhm2Lqze4bkKYNvuvPHDa qhk7HcFxo6bid1qyH1vA108Zm/8cxtkiTPCJcGWLRkeq89uEFx5z00QrsEDctxUHEHqPY0EkBHx XmftsV1YOsb2XIPnqMTFDG06GYfaLQ3xl3fOU/GaLlj7i/YBm9jGbLvyhoymV0MqFI3YFo/49F5 SUpFRQUSoLz02gEpZkI+IIFVPaJW0Ff5YF6R2c7Vb++SYIwHsiGDsor5aGNkCcTsYGtKismJRs7 1EG4fxxwoT5QbBrK1jw== X-Proofpoint-GUID: VhR5mbbiowx4UOWUfxLr-opLXvuKZTxj X-Authority-Analysis: v=2.4 cv=Oot/DS/t c=1 sm=1 tr=0 ts=6a4d26cd 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=EmLOupEv2CnJZljdqbQA:9 X-Proofpoint-ORIG-GUID: VhR5mbbiowx4UOWUfxLr-opLXvuKZTxj 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-07_04,2026-07-06_02,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-2607070160 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: 1783441248934158500 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 | 77 ++++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 4 ++ 4 files changed, 85 insertions(+) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index 4a131dc191..126bacb281 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -943,6 +943,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 99e4d140b5..a8b789e62e 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -827,3 +827,80 @@ 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]; + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + int keysize, i; + uint64_t addr; + 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 */ + for (i =3D 0; i < sizeof(wkvp); i++) { + addr =3D wrap_address(env, param_addr + keysize + i); + wkvp[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + if (memcmp(wkvp, protkey_wkvp, sizeof(wkvp))) { + /* wkvp mismatch -> return with cc 1 */ + return 1; + } + + /* fetch block sequence nr from param block into buf */ + for (i =3D 0; i < AES_BLOCK_SIZE; i++) { + addr =3D wrap_address(env, param_addr + keysize + + sizeof(wkvp) + AES_BLOCK_SIZE + i); + buf[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + + /* 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 */ + for (i =3D 0; i < keysize; i++) { + addr =3D wrap_address(env, param_addr + i); + key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + /* decrypt the protected key */ + decrypt_protkey(key, keysize); + + /* fetch tweak from param block into tweak */ + for (i =3D 0; i < AES_BLOCK_SIZE; i++) { + addr =3D wrap_address(env, param_addr + keysize + sizeof(wkvp) + i= ); + tweak[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + + /* 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 */ + for (i =3D 0; i < AES_BLOCK_SIZE; i++) { + addr =3D wrap_address(env, param_addr + keysize + + sizeof(wkvp) + 3 * AES_BLOCK_SIZE + i); + cpu_stb_mmu(env, addr, buf[i], oi, ra); + } + + 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 26 10:06:44 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=1783441165; cv=none; d=zohomail.com; s=zohoarc; b=iZCspPQwlJLMxgFYDyQrSgQc+Sdw39hHGO2fyGxbw4naQ4vZKf4xZlBRNeyZFkfcdy4hbMVMRg8aa5pArRxto/MjwQX2VOZBvr7QWoInQobbMVnOS61VOrkpzFdSnaCs8Jwlsj2+CQKR36tmpZu8z73yxTYak8DYepCimH9E+So= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441165; 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=mHMOe1wv/V7nS6nefWACMDUZ1Hs6h8Miul9/MEqKcbc=; b=ey7X4rBWutMIXT7PWFD0Razx2bizvbjuVufc8JQX8/DjTb+I/5OqLBF6sGE9tV6gaFVQ7xX2A+DO1lvj3AjuwxZwUw1m5zizgql272tr7T6+ZHf2s/yZlRJ71VWHYdbL5Kx2N5r3+IULOsIFfSTiiSbYAowAuL+GtgqTe1D3VNs= 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 1783441165860821.6512745852003; Tue, 7 Jul 2026 09:19:25 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8VS-0007cN-LQ; Tue, 07 Jul 2026 12:18:46 -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 1wh8VE-0007Tp-5f; Tue, 07 Jul 2026 12:18:34 -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 1wh8VA-0008BX-M9; Tue, 07 Jul 2026 12:18:31 -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 667FmFqj309762; Tue, 7 Jul 2026 16:18:21 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 4f6suqqw2v-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:21 +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 667G4apI018708; Tue, 7 Jul 2026 16:18:20 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4f7eqg3d07-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:20 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 667GIHmf47645082 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:17 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E2EC320043; Tue, 7 Jul 2026 16:18:16 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id BE6022004E; Tue, 7 Jul 2026 16:18:16 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:16 +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=mHMOe1wv/V7nS6nef WACMDUZ1Hs6h8Miul9/MEqKcbc=; b=q/yMlmfTYvRHYoHv8MmTcLxGdrr3GYZ2k qcJyuYRLmjIsuX9F3dlhn1uWI7tVMZJzCE/tHaJcFKzAtVouchz5nEiGKShVzPDY lJjkT2k3civ6yEU00UFrhx9NhYFnSKIgoRIS5fIk58pcW9oVC1g0EAIB4gUhfunQ eMoWwxstumqXDSD5rFk2LU35EmcExT1JiRiGF66z5u7SppH8eMCw12IXwqGSU5A9 AIo9kwOuXBCp66qmMRdNldugACdoVmSy/XC4Fux2gcqmTbXEFeKY6j9ok0dcS3FU rhWShwcbv4KqwMkyyDx7WnNCVkORoNPKFpnHvWNmij591wH4VtlKw== 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 v11 16/21] target/s390x: Support protected key AES XTS for cpacf km instruction Date: Tue, 7 Jul 2026 18:18:03 +0200 Message-ID: <20260707161815.40919-17-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX/pJOYAmRgXZl YXxFE8zaqaYpseU9W+jOQQMr0jYEYoyZB2qjruHUsCLoS1gKicTUxlqPTYBLzNRzNrS9owHQQ4s 46ot3TdLZ3FnUT3H8xfNgVIv0WsC+fM= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX9u8u1plMsDb1 Jy66VlHXI/FJUjI+VoP+37VK2anFneVivtcBkh20GhgxZWXLIMmPhBzBL6kodwL4cZu22NNXxrf n8NK1xxoo+SS2O7WgiMBWdS0WZo/9reeHCtr0JnaYG3obNbywgYZ2WbGt5/R4vm+2aNEMtEwtS7 dEgwwQk55NgtnS2c2ZK8+plO3CGv3d6sjJaPY2KKzaOTj0ENx9QH5PvuosaUVVF86pL9UdA90tv mqGDJLI00136NQSOhhNB4AdRRIqSkfVdRTQXWxd89QNk/WBB9qS22KDOAn8QVqtkbC2V3JDbG64 r9WDf2Meg5QZTYEudjsQ6TyFdpbdK1l5pIVynLrqne3BnI9eC3WH4t8Nu5TkR0cI3q43/ovYFUK xzJkDifXGY+6jgZQ2Xr6Cn78HEEkxiBLauI4wWRPyE+HMlH0rMDMy2G7XGQU3mDXNMNZIhRz0cF SkaTHIsWRZ1onyuQW6g== X-Proofpoint-GUID: pz1OU8g6HXtDf1r5hAq5HCzYg5uiEOxi X-Authority-Analysis: v=2.4 cv=Oot/DS/t c=1 sm=1 tr=0 ts=6a4d26cd cx=c_pps a=AfN7/Ok6k8XGzOShvHwTGQ==:117 a=AfN7/Ok6k8XGzOShvHwTGQ==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=uAbxVGIbfxUO_5tXvNgY:22 a=VnNF1IyMAAAA:8 a=_Jmc02WdQjUAVPbgbKgA:9 X-Proofpoint-ORIG-GUID: pz1OU8g6HXtDf1r5hAq5HCzYg5uiEOxi 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-07_04,2026-07-06_02,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-2607070160 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: 1783441166951158500 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 | 105 +++++++++++++++++++++++++++++++ target/s390x/tcg/crypto_helper.c | 6 ++ 4 files changed, 117 insertions(+) diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index 126bacb281..c4c59c3504 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -929,6 +929,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 a8b789e62e..4449bbc0d2 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -904,3 +904,108 @@ int cpacf_paes_pcc(CPUS390XState *env, const int mmu_= idx, 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 buf1[AES_BLOCK_SIZE], buf2[AES_BLOCK_SIZE]; + const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); + uint8_t key[32], wkvp[32], tweak[AES_BLOCK_SIZE]; + uint64_t addr, 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 */ + for (i =3D 0; i < sizeof(wkvp); i++) { + addr =3D wrap_address(env, param_addr + keysize + i); + wkvp[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + if (memcmp(wkvp, protkey_wkvp, sizeof(wkvp))) { + /* wkvp mismatch -> return with cc 1 */ + return 1; + } + + /* fetch protected key from param block */ + for (i =3D 0; i < keysize; i++) { + addr =3D wrap_address(env, param_addr + i); + key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + /* 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 */ + for (i =3D 0; i < AES_BLOCK_SIZE; i++) { + addr =3D wrap_address(env, param_addr + keysize + sizeof(wkvp) + i= ); + tweak[i] =3D cpu_ldb_mmu(env, addr, oi, ra); + } + + /* 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 buf1 */ + aes_read_block(env, mmu_idx, *src_ptr_reg + done, buf1, ra); + /* buf1 xor tweak =3D> buf2 */ + aes_xor(buf1, tweak, buf2); + if (mod) { + /* decrypt buf2 =3D> buf1 */ + AES_decrypt(buf2, buf1, &exkey); + } else { + /* encrypt buf2 =3D> buf1 */ + AES_encrypt(buf2, buf1, &exkey); + } + /* buf1 xor tweak =3D> buf2 */ + aes_xor(buf1, tweak, buf2); + /* prep tweak for next round */ + aes_xts_prep_next_tweak(tweak); + /* write out this processed block from buf2 */ + aes_write_block(env, mmu_idx, *dst_ptr_reg + done, buf2, ra); + len -=3D AES_BLOCK_SIZE; + done +=3D AES_BLOCK_SIZE; + } + + /* update tweak in param block */ + for (i =3D 0; i < AES_BLOCK_SIZE; i++) { + addr =3D wrap_address(env, param_addr + keysize + sizeof(wkvp) + i= ); + cpu_stb_mmu(env, addr, tweak[i], oi, ra); + } + + *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 26 10:06:44 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=1783441186; cv=none; d=zohomail.com; s=zohoarc; b=j+lVcJU/1yWKabTb44XH9FhHB2ennakqahed7QqpKSXkWo3VrQ/jVrj+v9CvsZBDl2GR6iIyrYkYbjvoNP7HOhZ5l50+IPDs88grhbJPA+jWzIltC43dXwQhWgYaQG9pm/Bp5TvtHnWsQyK1z3r5Pc8FufJRM4Ggq7UTj5mvGKc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441186; 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=Sk6nyuL4Bsh07MoyHBnha9RuqhSiP7/cMSJV3bR9xHEv6VWBXuf5c4YagV09qWTQEZSZjgNvfywqemvJIQr73tcavTwKs5DAxTHR8uS4bPFzWgRqrO/tJDIFofXxa0ksh1eRGIMV8E4qWQuSUEKdITcOZDyhVEzg6mOjaC4gqiY= 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 1783441186437249.6424715304962; Tue, 7 Jul 2026 09:19:46 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8Vc-0007k6-Cm; Tue, 07 Jul 2026 12:18:56 -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 1wh8Va-0007i4-5X; Tue, 07 Jul 2026 12:18:54 -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 1wh8VW-0008CI-MC; Tue, 07 Jul 2026 12:18:53 -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 667FmJvv4084917; Tue, 7 Jul 2026 16:18:22 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 4f6sw4r5pp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:22 +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 667G4dOd005434; Tue, 7 Jul 2026 16:18:21 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7cvw3sjv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:21 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 667GIHgd48562510 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:17 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 170FD2004E; Tue, 7 Jul 2026 16:18:17 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E6C312005A; Tue, 7 Jul 2026 16:18:16 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:16 +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=hc2mVex3F4Cls51LVlG8aJhHGmqtdLC+M XLPSTyFZ5CDDZh5+HsgM7aG0mkL/PRHW4966AXvouOorbyGWfrrLrCWqfZIH+uuy ef4cyDApx8Vc2RgCV1zhFt/Xs1spKxh2ggNqv17NuIpTZiAxiliiG2Ho1Oet5ejZ xuCIf5S5XJxo312YkQLJL1VYwtTOlK1VBGy8WKuSWVDUljZDewfVZtj2ha8YDkMj WchpqRLBBda6fRvi1dRvXBHZv366Y8JmV/4QhdxWDFHEb4QbzdrmVWhq3oWHKg2v WEzDwLIepwt+e9cXwd9RbqLGVZqmM5phFeH+oWsbXFs01Lz668/tA== 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 v11 17/21] docs/s390: Document CPACF instructions support Date: Tue, 7 Jul 2026 18:18:04 +0200 Message-ID: <20260707161815.40919-18-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: CcCif5iwI51WF4FGcDe15X6mYxNUXdTI X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX6/QLA0+2Fg7X Vctan9kSlwzjsbyeZzAzlDo09x8Y0vAeQBq9xd0EgSSjC0Awcfs3jzUXDdJoLRk8D7gkobU7nVq 518+UXnkcLGmaQtzHRLZvlPaHmFJA2pR/Z2GR2IJujeTxqJdH31nJwfoaVpt3tvq6W6iFImMaOV OttM7zSlTgQWrvEcnqK/zZyE4SGaeRW9a0axbQd+RatiZiVomniSl9j3O9P3nZuGXLfKFuyr109 5vQ56BRqTlTqr1tJxN/c4/caJd7FCDWH/RaqjbmCBgGZ8FVcZVnMVvvIp04vZT67FFDy92ViqEA qzJ3icm3IlLIhbXmC4HHJQhp69YBNX0Ge0AVMYxaABKeKnN4wddbMg31odpaLO9LQ3/qC5CJk8y gTxyJ3H2ap8cHkQScSma2XvxwWfywdsB8iZ54BujFPXlBkgyhsBgDRQF5JuQXwFdfnNaWDr1Tzz csFszO0ZRyWwxgWCkQQ== X-Proofpoint-ORIG-GUID: CcCif5iwI51WF4FGcDe15X6mYxNUXdTI X-Authority-Analysis: v=2.4 cv=FqQ1OWrq c=1 sm=1 tr=0 ts=6a4d26ce 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=IlYB4z8HrC9mJJy16gAA:9 a=5wi_FRADO1KgGG3s:21 a=O8hF6Hzn-FEA:10 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfXzcNXOLxuMcIy aUrXShsK3KVG7jqLI5wJZ8rTHHcwaLx70KvlJCae44iiiP9XtMehdJjJwX+yOhrnMmQJZDeBKLX iJaegnsuM4KHWQD6lr00gFxXiEttIBE= 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-07_04,2026-07-06_02,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-2607070160 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: 1783441188584158500 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 26 10:06:44 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=1783441166; cv=none; d=zohomail.com; s=zohoarc; b=jI6XkqKjCQd3qvO8b1Uu9F5+u9hV8t3gFLZR9Df5JQegam9REQMbJqT+nuP1i5HsvQyANLZU2fjWaDukjriTXDSRuE2Jtpon/Nq5crnM5KygUlhVDknLGNQausmBg3z/Tlcr5nFPhg9DZph2jG8LYkIXDLSOK4l0me0iXLOT1cY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441166; 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=QD/5k5DzQ/RYiB6J58QkL3cIc1nFoqfhZ7/raOG6trQ=; b=WjpQJdAW0Bwu4WoTwEjGAxA8LCUU8VytTJE7StY0rFEC6Ov973QLoV1nJSMWWvum5wUdM+g7de3qv2TPHobPh3uoi9g3LL5FK2Ew3UwAfmjV4vGTleBVJkZceo/WF59WLsxzUm+N3p+vha/SVgXhvzGyM7SlwLdif4APghrtR/g= 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 1783441165994911.164448616613; Tue, 7 Jul 2026 09:19:25 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8Vc-0007kN-RU; Tue, 07 Jul 2026 12:18:56 -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 1wh8Vb-0007j7-DX; Tue, 07 Jul 2026 12:18:55 -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 1wh8VX-0008Cq-Fk; Tue, 07 Jul 2026 12:18:55 -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 667FmQab4085087; Tue, 7 Jul 2026 16:18:22 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 4f6sw4r5pn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:21 +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 667G4asA018702; Tue, 7 Jul 2026 16:18:21 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4f7eqg3d08-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:20 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 667GIHvc44237250 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:17 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3F96B2004F; Tue, 7 Jul 2026 16:18:17 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1AC9C20043; Tue, 7 Jul 2026 16:18:17 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:17 +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=QD/5k5 DzQ/RYiB6J58QkL3cIc1nFoqfhZ7/raOG6trQ=; b=rAgACAIZB+4mln25Gh9Pb1 Z2K7jTLq7bN5xBXjEndJnX8gEbh6jDDh8h/jaGagomM3PYD4JOwpZI9510EL3IUV 7Nxd98XKKug+Uhnq8s8VOllscZTH5SIyrVWfEhX9/Cybu000Y0J8GYckN3lYHpqU W8gqLpHWilKi3g445LIW38K2UEn8OS5lhoZK68Z/RC5gOPo1prC/tSjfvQ3hfiwJ 3wVdFtGK0EkwSx0YdkFVH87QOliSs8eU5TsJSBtt/Vgae+7CNMQPeEDGKIZQaHpJ e+JccRmt7KL8j9D6k9UMsbNJBrIvGXL+iKUaJpYkSnYw3BNAQwj0nIe0z4ftd8XA == 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 v11 18/21] crypto: Add aes-helpers file to support some AES modes Date: Tue, 7 Jul 2026 18:18:05 +0200 Message-ID: <20260707161815.40919-19-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: jOkJMlIjeK4DgbsKGgvbGEdHc2yj_-58 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX2gOpktYVo7Ox 7sQiATV3CsveX7SSm0kemlwxULMj9r5oiOexwS4Y1RfY2t7tU415tPPWqIUg3E/fjbN1avoY5j6 8mhZhiJpL4oy9B8zQ8LKMIXyej7IHYrvlo4nklKJ7TArxBskUsLe4aOqjd7S/Bc2EVtrlMjx9rh GGqXGTe7xnBuDL2OX4QZryeBv7HCBC5CYosSkrVLqrgvuPM036A4ZmmaNMpMw1B9zYdkNav0C5D gIl+9r8eUWL4JU6djX0InOqr8c8lRq0jhNhm4MZchfZ978I/W86u+Q7bh+Oq2th4ie7S8yxTQFF pcK1C1u/8UH0p1nPqgVVUBhPPJI8osAR3SdO7QTdwoB0N/wqJ6j7QOX877IJWdvTKGU3hDNydBC m++3WYjH6RJ/mYnqvKpmQLkWNyZ2AnbufIT8kZai7GObig7oCMyzLfVv/P/GzkNkzheK+3fU+qr qTP5A9hQx/20LBmktKw== X-Proofpoint-ORIG-GUID: jOkJMlIjeK4DgbsKGgvbGEdHc2yj_-58 X-Authority-Analysis: v=2.4 cv=FqQ1OWrq c=1 sm=1 tr=0 ts=6a4d26cd 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=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=ZNJHLeKVfsBpcIed2koA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX4kgbIvYgA0b0 VWbnQhe4c5RJN1e1C4jCtvDCwy8AIfeiz2Z0Z/ZSlzEnJ7AMKtPRviJK1C41GVGRi52sQvyw+I9 y3VUSqyZJYCMK+8a3NcoMbVEPY/mk0w= 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-07_04,2026-07-06_02,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-2607070160 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: 1783441166933158500 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() Signed-off-by: Harald Freudenberger Reviewed-by: Finn Callies --- crypto/aes-helpers.c | 106 +++++++++++++++++++++++++++++++++++++++++++ crypto/meson.build | 1 + include/crypto/aes.h | 14 ++++++ 3 files changed, 121 insertions(+) create mode 100644 crypto/aes-helpers.c diff --git a/crypto/aes-helpers.c b/crypto/aes-helpers.c new file mode 100644 index 0000000000..39ca153737 --- /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 +#include +#include "crypto/aes.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.h b/include/crypto/aes.h index 381f24c902..df6239cb9c 100644 --- a/include/crypto/aes.h +++ b/include/crypto/aes.h @@ -37,4 +37,18 @@ AES_Td0[x] =3D Si[x].[0e, 09, 0d, 0b]; =20 extern const uint32_t AES_Te0[256], AES_Td0[256]; =20 +void AES_xor(const unsigned char *src1, const unsigned char *src2, + unsigned char *dst); +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + unsigned char *iv, const AES_KEY *key); +void AES_cbc_decrypt(const unsigned char *in, unsigned char *out, + unsigned char *iv, const AES_KEY *key); +void AES_ctr_encrypt(const unsigned char *in, unsigned char *out, + const unsigned char *ctr, const AES_KEY *key); +void AES_xts_prep_next_tweak(unsigned char *tweak); +void AES_xts_encrypt(const unsigned char *in, unsigned char *out, + const unsigned char *tweak, const AES_KEY *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 26 10:06:44 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=1783441249; cv=none; d=zohomail.com; s=zohoarc; b=Krq/yY/cPql3s/Eo25ficTFL66TSW/1kOpqofa94WV7XG1acIBltp22C+rzih9J7AgJQmbQspc3urTKoT0josJRGyQoJbACDC2NoHEDV5nkEWBkX8muxngtowi0d+/0DhLHREkOu73y2ixos7SkreNMaP3kOpR5HTketzdw27EY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441249; 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=zuoyNuV27ihAoaiofnNxvMSMvy1KSb9j2diu0GGvKOM=; b=BI/Z42IXXVBhBzFDeyxApUyi74VfEI5Qod40TSw/cblNaZTkflQh9k6n4N8KNlNnuR3m/BYus0oSxAtYKrtaPazCWqeX1lrXpMSYFn9agM78eJ7CyLX2ZhY8cf1Jo4tHeHgBrjMSQCsR6bQyGBiHOkNFvk3kkCiF394XnA0jqTw= 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 1783441249409618.5349711648024; Tue, 7 Jul 2026 09:20:49 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8VT-0007dx-OL; Tue, 07 Jul 2026 12:18:47 -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 1wh8VE-0007Tt-WC; Tue, 07 Jul 2026 12:18:34 -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 1wh8VC-0008CB-Q5; Tue, 07 Jul 2026 12:18:32 -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 667FmLJb3445448; Tue, 7 Jul 2026 16:18:22 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 4f6rkdrq04-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:22 +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 667G4dpa005437; Tue, 7 Jul 2026 16:18:21 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7cvw3sjx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:21 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 667GIHQT53019108 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:17 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7317A20043; Tue, 7 Jul 2026 16:18:17 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 438A120065; Tue, 7 Jul 2026 16:18:17 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:17 +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=zuoyNuV27ihAoaiof nNxvMSMvy1KSb9j2diu0GGvKOM=; b=cmP9jvYjJ24b2ovvumCdgQtNtp3x4ZEAT dFnTPXBWuRhiZcudBbznefdGkWyYvE8zk6PQ+NDmnyMdTbG0QfuxNEOHwVEYbOwb IYJ2u1qGW7TBFq4f+P226j476nJGl14buEPVs7AsXrDnCe4S3XlfE5k/Bg+eqTVR Ozk21Dp3JoDbxcBg5GPBYxEDW9JQ0oGTpEwrrQLEl8r1xeKPx0xITbzgpWCJOcBz hK7HTFKCo/sDVlOPYLdVlxrOWIOitHjNG5IevgzGn4DRFlsAeiOpCTJNIY+YRkCI ZRqUkIc3YlxPlh9R8FfhbQ5JdNvW7BK+jke1oGHRFcObvLTTOZsDA== 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 v11 19/21] target/s390x: Use generic AES helper functions Date: Tue, 7 Jul 2026 18:18:06 +0200 Message-ID: <20260707161815.40919-20-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-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=6a4d26ce cx=c_pps a=5BHTudwdYE3Te8bg5FgnPg==:117 a=5BHTudwdYE3Te8bg5FgnPg==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=V8glGbnc2Ofi9Qvn3v5h:22 a=VnNF1IyMAAAA:8 a=RTVADdF_yP6blHuwIEIA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX2X4sVERmOPN0 jUPcNWxWD+lNECcH7IOZgTM/+8hQjapqqKBsYERJx91sCiHFbIUIWUJWiekO5k0jA1i4UtiPlPa KeVC2buFxi7yXM2U5UXkV2QdAHG9e0WBjKIaRQEwlij60yHeO6LNWOONWINBI2WQrJ2vnTEyfYr E9DpeOpe9PBXm8LdJHWR6yplXfID6Z7tz7qbvTy/CVPC5mZMwGJvKt/Qln8cX0HNUZ1S1+zCNlO HWFLGxGinBOMHuLVAc4nCcaYg7A84I3yU2zSaAh86BOVWQ1inkdGAcxT03UApOiY9JEOHxu41Ho ZwzimxmgHs1PgbMIg4XFmP+3dZKaEXRYvNrzS/o6MNk0OrvnRNaFww4SWrfFDzH9oFljqJ13bpw IkYDTpwDNZpwyDIX/c3UV9AxT44zsoSgzDqZci0FTgucOR6rOGFBRB1xXkeXS9qdz+gXdKlqFw9 /OI1nRcP6YL1DZxxQUA== X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX6oBGZ3oDA93E C29t+FMHSFL9dujfIYEQmiB0uqUurXj+C+J1A91PAfkJpXqsCRhqPQPFdmB98cu0L/99fo3lfLY 95XLEaj+pi2I/FkQWDCrqBGOoCqx4t4= X-Proofpoint-GUID: SraOwHWZwIY1hv8ctsD7KCj-Q4vlyhfn X-Proofpoint-ORIG-GUID: SraOwHWZwIY1hv8ctsD7KCj-Q4vlyhfn 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-07_04,2026-07-06_02,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-2607070160 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: 1783441250983158500 Content-Type: text/plain; charset="utf-8" Rewrite the cpacf implementations to use the generic AES helper functions from crypto/aes-helpers.c Signed-off-by: Harald Freudenberger Reviewed-by: Finn Callies --- target/s390x/tcg/cpacf_aes.c | 124 ++++++++++------------------------- 1 file changed, 36 insertions(+), 88 deletions(-) diff --git a/target/s390x/tcg/cpacf_aes.c b/target/s390x/tcg/cpacf_aes.c index 4449bbc0d2..e9f0db2b5a 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -110,20 +110,13 @@ int cpacf_aes_ecb(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, return !len ? 0 : 3; } =20 -static void aes_xor(const uint8_t *src1, const uint8_t *src2, uint8_t *dst) -{ - for (int i =3D 0; i < AES_BLOCK_SIZE; i++) { - dst[i] =3D src1[i] ^ src2[i]; - } -} - 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], buf[AES_BLOCK_SIZE]; + uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); uint64_t addr, len =3D *src_len_reg, done =3D 0; int i, keysize, addr_reg_size =3D 64; @@ -179,19 +172,11 @@ int cpacf_aes_cbc(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, for (i =3D 0; i < MAX_BLOCKS_PER_RUN && len >=3D AES_BLOCK_SIZE; i++) { aes_read_block(env, mmu_idx, *src_ptr_reg + done, in, ra); if (mod) { - /* decrypt in =3D> buf */ - AES_decrypt(in, buf, &exkey); - /* buf xor iv =3D> out */ - aes_xor(buf, iv, out); - /* prep iv for next round */ - memcpy(iv, in, AES_BLOCK_SIZE); + /* decrypt in =3D> out */ + AES_cbc_decrypt(in, out, iv, &exkey); } else { - /* in xor iv =3D> buf */ - aes_xor(in, iv, buf); - /* encrypt buf =3D> out */ - AES_encrypt(buf, out, &exkey); - /* prep iv for next round */ - memcpy(iv, out, AES_BLOCK_SIZE); + /* encrypt in =3D> out */ + AES_cbc_encrypt(in, out, iv, &exkey); } aes_write_block(env, mmu_idx, *dst_ptr_reg + done, out, ra); len -=3D AES_BLOCK_SIZE; @@ -221,11 +206,10 @@ int cpacf_aes_ctr(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, { enum { MAX_BLOCKS_PER_RUN =3D 8192 / AES_BLOCK_SIZE }; const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); - uint8_t ctr[AES_BLOCK_SIZE], buf[AES_BLOCK_SIZE]; uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; uint64_t addr, len =3D *src_len_reg, done =3D 0; + uint8_t ctr[AES_BLOCK_SIZE], key[32]; int i, keysize, addr_reg_size =3D 64; - uint8_t key[32]; AES_KEY exkey; =20 g_assert(type =3D=3D S390_FEAT_TYPE_KMCTR); @@ -267,12 +251,10 @@ int cpacf_aes_ctr(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, 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, *ctr_ptr_reg + done, ctr, ra); - /* encrypt ctr =3D> buf */ - AES_encrypt(ctr, buf, &exkey); /* read in one block of input data =3D> in */ aes_read_block(env, mmu_idx, *src_ptr_reg + done, in, ra); - /* xor input data with encrypted ctr =3D> out */ - aes_xor(in, buf, out); + /* 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, *dst_ptr_reg + done, out, ra); len -=3D AES_BLOCK_SIZE; @@ -353,28 +335,13 @@ int cpacf_aes_pcc(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, return 0; } =20 -static void aes_xts_prep_next_tweak(uint8_t tweak[AES_BLOCK_SIZE]) -{ - uint8_t carry; - int i; - - carry =3D tweak[AES_BLOCK_SIZE - 1] >> 7; - - for (i =3D AES_BLOCK_SIZE - 1; i > 0; i--) { - tweak[i] =3D (uint8_t)((tweak[i] << 1) | (tweak[i - 1] >> 7)); - } - - tweak[i] =3D (uint8_t)(tweak[i] << 1); - tweak[i] ^=3D (uint8_t)(0x87 & (uint8_t)(-(int8_t)carry)); -} - 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 buf1[AES_BLOCK_SIZE], buf2[AES_BLOCK_SIZE]; + uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); uint64_t addr, len =3D *src_len_reg, done =3D 0; uint8_t key[32], tweak[AES_BLOCK_SIZE]; @@ -425,23 +392,19 @@ int cpacf_aes_xts(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, =20 /* 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 buf1 */ - aes_read_block(env, mmu_idx, *src_ptr_reg + done, buf1, ra); - /* buf1 xor tweak =3D> buf2 */ - aes_xor(buf1, tweak, buf2); + /* fetch one AES block into in */ + aes_read_block(env, mmu_idx, *src_ptr_reg + done, in, ra); if (mod) { - /* decrypt buf2 =3D> buf1 */ - AES_decrypt(buf2, buf1, &exkey); + /* decrypt in =3D> out */ + AES_xts_decrypt(in, out, tweak, &exkey); } else { - /* encrypt buf2 =3D> buf1 */ - AES_encrypt(buf2, buf1, &exkey); + /* encrypt in =3D> out */ + AES_xts_encrypt(in, out, tweak, &exkey); } - /* buf1 xor tweak =3D> buf2 */ - aes_xor(buf1, tweak, buf2); /* prep tweak for next round */ - aes_xts_prep_next_tweak(tweak); - /* write out this processed block from buf2 */ - aes_write_block(env, mmu_idx, *dst_ptr_reg + done, buf2, ra); + AES_xts_prep_next_tweak(tweak); + /* write out this processed block from out */ + aes_write_block(env, mmu_idx, *dst_ptr_reg + done, out, ra); len -=3D AES_BLOCK_SIZE; done +=3D AES_BLOCK_SIZE; } @@ -637,7 +600,7 @@ int cpacf_paes_cbc(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, 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], buf[AES_BLOCK_SIZE]; + uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); uint8_t key[32], wkvp[32], iv[AES_BLOCK_SIZE]; uint64_t addr, len =3D *src_len_reg, done =3D 0; @@ -705,19 +668,11 @@ int cpacf_paes_cbc(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, for (i =3D 0; i < MAX_BLOCKS_PER_RUN && len >=3D AES_BLOCK_SIZE; i++) { aes_read_block(env, mmu_idx, *src_ptr_reg + done, in, ra); if (mod) { - /* decrypt in =3D> buf */ - AES_decrypt(in, buf, &exkey); - /* buf xor iv =3D> out */ - aes_xor(buf, iv, out); - /* prep iv for next round */ - memcpy(iv, in, AES_BLOCK_SIZE); + /* decrypt in =3D> out */ + AES_cbc_decrypt(in, out, iv, &exkey); } else { - /* in xor iv =3D> buf */ - aes_xor(in, iv, buf); - /* encrypt buf =3D> out */ - AES_encrypt(buf, out, &exkey); - /* prep iv for next round */ - memcpy(iv, out, AES_BLOCK_SIZE); + /* encrypt in =3D> out */ + AES_cbc_encrypt(in, out, iv, &exkey); } aes_write_block(env, mmu_idx, *dst_ptr_reg + done, out, ra); len -=3D AES_BLOCK_SIZE; @@ -747,11 +702,10 @@ int cpacf_paes_ctr(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, { enum { MAX_BLOCKS_PER_RUN =3D 8192 / AES_BLOCK_SIZE }; const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); - uint8_t ctr[AES_BLOCK_SIZE], buf[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 addr, 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; =20 g_assert(type =3D=3D S390_FEAT_TYPE_KMCTR); @@ -805,12 +759,10 @@ int cpacf_paes_ctr(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, 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, *ctr_ptr_reg + done, ctr, ra); - /* encrypt ctr =3D> buf */ - AES_encrypt(ctr, buf, &exkey); /* read in one block of input data =3D> in */ aes_read_block(env, mmu_idx, *src_ptr_reg + done, in, ra); - /* exor input data with encrypted ctr =3D> out */ - aes_xor(in, buf, out); + /* 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, *dst_ptr_reg + done, out, ra); len -=3D AES_BLOCK_SIZE; @@ -911,7 +863,7 @@ int cpacf_paes_xts(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, uint32_t type, uint8_t fc, uint8_t mod) { enum { MAX_BLOCKS_PER_RUN =3D 8192 / AES_BLOCK_SIZE }; - uint8_t buf1[AES_BLOCK_SIZE], buf2[AES_BLOCK_SIZE]; + uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); uint8_t key[32], wkvp[32], tweak[AES_BLOCK_SIZE]; uint64_t addr, len =3D *src_len_reg, done =3D 0; @@ -974,23 +926,19 @@ int cpacf_paes_xts(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, =20 /* 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 buf1 */ - aes_read_block(env, mmu_idx, *src_ptr_reg + done, buf1, ra); - /* buf1 xor tweak =3D> buf2 */ - aes_xor(buf1, tweak, buf2); + /* fetch one AES block into in */ + aes_read_block(env, mmu_idx, *src_ptr_reg + done, in, ra); if (mod) { - /* decrypt buf2 =3D> buf1 */ - AES_decrypt(buf2, buf1, &exkey); + /* decrypt in =3D> out */ + AES_xts_decrypt(in, out, tweak, &exkey); } else { - /* encrypt buf2 =3D> buf1 */ - AES_encrypt(buf2, buf1, &exkey); + /* encrypt in =3D> out */ + AES_xts_encrypt(in, out, tweak, &exkey); } - /* buf1 xor tweak =3D> buf2 */ - aes_xor(buf1, tweak, buf2); /* prep tweak for next round */ - aes_xts_prep_next_tweak(tweak); - /* write out this processed block from buf2 */ - aes_write_block(env, mmu_idx, *dst_ptr_reg + done, buf2, ra); + AES_xts_prep_next_tweak(tweak); + /* write out this processed block from out */ + aes_write_block(env, mmu_idx, *dst_ptr_reg + done, out, ra); len -=3D AES_BLOCK_SIZE; done +=3D AES_BLOCK_SIZE; } --=20 2.43.0 From nobody Sun Jul 26 10:06:44 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=1783441183; cv=none; d=zohomail.com; s=zohoarc; b=UeY6VksgOGlXoQYQ4ftVHQA2sOjI5Cayuai7wX2AIYYUy4kG0ngj3Qtr0MMxj7xrEAaMMA6wWdiomg3EprnDohIPLQ0z4fqP7iKoM+5WrldWmhOk636r3XsjSKdMP0+HFwUAFwOAKEi4G4rOQfbfNkd0pfrzoiXkVewbInLsDr0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441183; 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=cZnmrFGb/tJIR6vCzXKnZfoyjp6UMfQ6Br7MOrrwrvc=; b=Ks3AncRhXSpE0Cw4jkuJ+AsT65gFbEnMgUsapGph3Md9MRftOR+QKtV+lMwau15MU9AlPF8EYLF4uncT4CzSvcMrJcKMwCju8PtAFjiUl3nrr67J650LbK4lWQ1V4bOlPJE8l445/H+EDS4CVynN+WM2Uam9lV/dH+mPdHaBnaU= 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 17834411830611015.2106267029267; Tue, 7 Jul 2026 09:19:43 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8Vd-0007lB-Fl; Tue, 07 Jul 2026 12:18:57 -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 1wh8Vb-0007j5-C4; Tue, 07 Jul 2026 12:18:55 -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 1wh8VW-0008CW-MK; Tue, 07 Jul 2026 12:18:55 -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 667FmL1e309989; Tue, 7 Jul 2026 16:18:23 GMT Received: from ppma23.wdc07v.mail.ibm.com (5d.69.3da9.ip4.static.sl-reverse.com [169.61.105.93]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4f6suqqw2x-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:23 +0000 (GMT) Received: from pps.filterd (ppma23.wdc07v.mail.ibm.com [127.0.0.1]) by ppma23.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 667G4dof003243; Tue, 7 Jul 2026 16:18:22 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma23.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7e0hbh93-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:21 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (smtpav07.fra02v.mail.ibm.com [10.20.54.106]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 667GIHEi44237252 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:17 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id AF2962004D; Tue, 7 Jul 2026 16:18:17 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 77CA32004B; Tue, 7 Jul 2026 16:18:17 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:17 +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=cZnmrFGb/tJIR6vCz XKnZfoyjp6UMfQ6Br7MOrrwrvc=; b=cQJQArBZQpaEPp3IsgXuCNNK9jTuT70L0 GkSj/8Lg87h/dQOV0rsXJdDKioKeRD8ZIxfHgG8uWwWTAgcIKkkjEwKf81FRxHbQ Hu3noGfPq7cGG3VdFbZYwyvjRoay50+kw77xNoBC/esz4rKZVu/u/MFWjXOZq34q 5TqDN2fl4YbQBv49H3pplvINZhaqksa8IX9VWj/bR71AwDmW3q5q+56Q1G/KLzjP cBXYSUBkQJzajoBx3ApnNe5I03mTv2Jc9FTSlBtDkKNZaRkh8lGsLGjgcaN895I+ mfqV13heDlDEeuUkbfx+dnN+Zv/WDba4MKvMOTyabxiI6rDkbC2JQ== 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 v11 20/21] target/s390x: Improve fetch and store mem from and to guest Date: Tue, 7 Jul 2026 18:18:07 +0200 Message-ID: <20260707161815.40919-21-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX4gTS3UrxLa4B bpTDksP91QyaMq+in/eoqJ9349ry2atdbjcwt21LtCmYRPDp2xMPPHwGYvsM1UJ+cvU8YzqY2GT KG4W1rfRvC7UQ8pYNMurh15SvblZkEQ= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX3o8CABMDHLdS PpOpm+4e/r+UNNdBAumYb8udbZeHlVpi3ZemxvC3leLymSlJkMoraVwP2dPeVtYE9FLJf7Fqyxu G9Y1pmGI7W2P2JBq0W5odJ2KPfBF8HIR7vunoY5AJi7BSDgZuW8SAxcrnfbY7eF62dgkCvELrMB oT1HnAkffwVSzpv13csTnDqnfXHeDLME65rnxdXksXwifkLRQx5c7Eh3C+/dMW3Nv9ZcaqX+VUH jj8cn2HpD97nulGg5bFXx49eiGVaOmp5Ky6Ty98P9LEyahfbP8bpspN37blh1v4paWQgtkw71VB NX4VK+92fWTLbz9BpS+S7rKkRR4zwVENyjRf94fCj49AIvFeXoAjRziS20NWwmJEFVLwrqNO1nB RTTatqJkLD9wR42BKGpdkwH/38YLnNhW+rbC2zxeAwp7Mv4R7ZI4e58ZbPtUO4JudpbIR7ITSSQ Y4SGyyCBeCZZVrlG04A== X-Proofpoint-GUID: dDoAl2NGbNbtn8CG5n0G0IbL4ZINzKoT X-Authority-Analysis: v=2.4 cv=Oot/DS/t c=1 sm=1 tr=0 ts=6a4d26cf cx=c_pps a=3Bg1Hr4SwmMryq2xdFQyZA==:117 a=3Bg1Hr4SwmMryq2xdFQyZA==:17 a=RAioF0-LDSMA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=uAbxVGIbfxUO_5tXvNgY:22 a=VnNF1IyMAAAA:8 a=SH-LS3B6E9p2pXL9WtEA:9 a=ZDSMja1iq-x7GFnX:21 X-Proofpoint-ORIG-GUID: dDoAl2NGbNbtn8CG5n0G0IbL4ZINzKoT 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-07_04,2026-07-06_02,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-2607070160 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: 1783441184398158500 Content-Type: text/plain; charset="utf-8" Introduce helper functions: * copy_from_guest_wrap() * copy_to_guest_wrap() for copy some memory from guest into a local buffer and the reverse direction. Rework the other functions to use these helpers. By doing so some local variables could be removed also and the code is better readable now. Suggested-by: Ilya Leoshkevich Signed-off-by: Harald Freudenberger --- target/s390x/tcg/cpacf_aes.c | 305 ++++++++++++++--------------------- 1 file changed, 124 insertions(+), 181 deletions(-) diff --git a/target/s390x/tcg/cpacf_aes.c b/target/s390x/tcg/cpacf_aes.c index e9f0db2b5a..ece70d989d 100644 --- a/target/s390x/tcg/cpacf_aes.c +++ b/target/s390x/tcg/cpacf_aes.c @@ -15,37 +15,64 @@ #include "crypto/aes.h" #include "target/s390x/tcg/cpacf.h" =20 -static void aes_read_block(CPUS390XState *env, const int mmu_idx, - uint64_t addr, uint8_t *a, uintptr_t ra) +/* + * 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); =20 - for (int i =3D 0; i < AES_BLOCK_SIZE; i++, addr +=3D 1) { - uint64_t _addr =3D wrap_address(env, addr); - a[i] =3D cpu_ldb_mmu(env, _addr, oi, ra); + 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); } } =20 -static void aes_write_block(CPUS390XState *env, const int mmu_idx, - uint64_t addr, uint8_t *a, uintptr_t 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); =20 - for (int i =3D 0; i < AES_BLOCK_SIZE; i++, addr +=3D 1) { - uint64_t _addr =3D wrap_address(env, addr); - cpu_stb_mmu(env, _addr, a[i], oi, ra); + 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); } } =20 +/* + * 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 }; - const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; - uint64_t addr, len =3D *src_len_reg, done =3D 0; + 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; @@ -76,10 +103,7 @@ int cpacf_aes_ecb(CPUS390XState *env, const int mmu_idx= , uintptr_t ra, } =20 /* fetch key from param block */ - for (i =3D 0; i < keysize; i++) { - addr =3D wrap_address(env, param_addr + i); - key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, param_addr, key, keysize); =20 /* expand key */ if (mod) { @@ -90,13 +114,13 @@ int cpacf_aes_ecb(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, =20 /* 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, *src_ptr_reg + done, in, ra); + 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, *dst_ptr_reg + done, out, ra); + aes_write_block(env, mmu_idx, ra, *dst_ptr_reg + done, out); len -=3D AES_BLOCK_SIZE; done +=3D AES_BLOCK_SIZE; } @@ -117,8 +141,7 @@ int cpacf_aes_cbc(CPUS390XState *env, const int mmu_idx= , uintptr_t ra, { enum { MAX_BLOCKS_PER_RUN =3D 8192 / AES_BLOCK_SIZE }; uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; - const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); - uint64_t addr, len =3D *src_len_reg, done =3D 0; + 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; @@ -150,16 +173,11 @@ int cpacf_aes_cbc(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, } =20 /* fetch iv from param block */ - for (i =3D 0; i < AES_BLOCK_SIZE; i++) { - addr =3D wrap_address(env, param_addr + i); - iv[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, param_addr, iv, AES_BLOCK_SIZE); =20 /* fetch key from param block */ - for (i =3D 0; i < keysize; i++) { - addr =3D wrap_address(env, param_addr + AES_BLOCK_SIZE + i); - key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, + param_addr + AES_BLOCK_SIZE, key, keysize); =20 /* expand key */ if (mod) { @@ -170,7 +188,7 @@ int cpacf_aes_cbc(CPUS390XState *env, const int mmu_idx= , uintptr_t ra, =20 /* 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, *src_ptr_reg + done, in, ra); + 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); @@ -178,16 +196,13 @@ int cpacf_aes_cbc(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, /* encrypt in =3D> out */ AES_cbc_encrypt(in, out, iv, &exkey); } - aes_write_block(env, mmu_idx, *dst_ptr_reg + done, out, ra); + aes_write_block(env, mmu_idx, ra, *dst_ptr_reg + done, out); len -=3D AES_BLOCK_SIZE; done +=3D AES_BLOCK_SIZE; } =20 /* update iv in param block */ - for (i =3D 0; i < AES_BLOCK_SIZE; i++) { - addr =3D wrap_address(env, param_addr + i); - cpu_stb_mmu(env, addr, iv[i], oi, ra); - } + copy_to_guest_wrap(env, mmu_idx, ra, param_addr, iv, AES_BLOCK_SIZE); =20 *src_ptr_reg =3D deposit64(*src_ptr_reg, 0, addr_reg_size, *src_ptr_reg + done); @@ -205,9 +220,8 @@ int cpacf_aes_ctr(CPUS390XState *env, const int mmu_idx= , uintptr_t ra, uint8_t fc, uint8_t mod) { enum { MAX_BLOCKS_PER_RUN =3D 8192 / AES_BLOCK_SIZE }; - const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; - uint64_t addr, len =3D *src_len_reg, done =3D 0; + 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; @@ -239,10 +253,7 @@ int cpacf_aes_ctr(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, } =20 /* fetch key from param block */ - for (i =3D 0; i < keysize; i++) { - addr =3D wrap_address(env, param_addr + i); - key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, param_addr, key, keysize); =20 /* expand key */ AES_set_encrypt_key(key, keysize * 8, &exkey); @@ -250,13 +261,13 @@ int cpacf_aes_ctr(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, /* 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, *ctr_ptr_reg + done, ctr, ra); + 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, *src_ptr_reg + done, in, ra); + 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, *dst_ptr_reg + done, out, ra); + aes_write_block(env, mmu_idx, ra, *dst_ptr_reg + done, out); len -=3D AES_BLOCK_SIZE; done +=3D AES_BLOCK_SIZE; } @@ -276,9 +287,7 @@ 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]; - const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); int keysize, i; - uint64_t addr; AES_KEY exkey; =20 switch (fc) { @@ -293,10 +302,9 @@ int cpacf_aes_pcc(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, } =20 /* fetch block sequence nr from param block into buf */ - for (i =3D 0; i < AES_BLOCK_SIZE; i++) { - addr =3D wrap_address(env, param_addr + keysize + AES_BLOCK_SIZE += i); - buf[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, + param_addr + keysize + AES_BLOCK_SIZE, + buf, AES_BLOCK_SIZE); =20 /* is the block sequence nr 0 ? */ for (i =3D 0; i < AES_BLOCK_SIZE && !buf[i]; i++) { @@ -309,16 +317,11 @@ int cpacf_aes_pcc(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, } =20 /* fetch key from param block */ - for (i =3D 0; i < keysize; i++) { - addr =3D wrap_address(env, param_addr + i); - key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, param_addr, key, keysize); =20 /* fetch tweak from param block into tweak */ - for (i =3D 0; i < AES_BLOCK_SIZE; i++) { - addr =3D wrap_address(env, param_addr + keysize + i); - tweak[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, + param_addr + keysize, tweak, AES_BLOCK_SIZE); =20 /* expand key */ AES_set_encrypt_key(key, keysize * 8, &exkey); @@ -327,10 +330,9 @@ int cpacf_aes_pcc(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, AES_encrypt(tweak, buf, &exkey); =20 /* store encrypted tweak into xts parameter field of the param block */ - for (i =3D 0; i < AES_BLOCK_SIZE; i++) { - addr =3D wrap_address(env, param_addr + keysize + 3 * AES_BLOCK_SI= ZE + i); - cpu_stb_mmu(env, addr, buf[i], oi, ra); - } + copy_to_guest_wrap(env, mmu_idx, ra, + param_addr + keysize + 3 * AES_BLOCK_SIZE, + buf, AES_BLOCK_SIZE); =20 return 0; } @@ -342,8 +344,7 @@ int cpacf_aes_xts(CPUS390XState *env, const int mmu_idx= , uintptr_t ra, { enum { MAX_BLOCKS_PER_RUN =3D 8192 / AES_BLOCK_SIZE }; uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; - const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); - uint64_t addr, len =3D *src_len_reg, done =3D 0; + 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; @@ -372,10 +373,7 @@ int cpacf_aes_xts(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, } =20 /* fetch key from param block */ - for (i =3D 0; i < keysize; i++) { - addr =3D wrap_address(env, param_addr + i); - key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, param_addr, key, keysize); =20 /* expand key */ if (mod) { @@ -385,15 +383,13 @@ int cpacf_aes_xts(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, } =20 /* fetch tweak from param block */ - for (i =3D 0; i < AES_BLOCK_SIZE; i++) { - addr =3D wrap_address(env, param_addr + keysize + i); - tweak[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, + param_addr + keysize, tweak, AES_BLOCK_SIZE); =20 /* 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, *src_ptr_reg + done, in, ra); + 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); @@ -404,16 +400,14 @@ int cpacf_aes_xts(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, /* prep tweak for next round */ AES_xts_prep_next_tweak(tweak); /* write out this processed block from out */ - aes_write_block(env, mmu_idx, *dst_ptr_reg + done, out, ra); + aes_write_block(env, mmu_idx, ra, *dst_ptr_reg + done, out); len -=3D AES_BLOCK_SIZE; done +=3D AES_BLOCK_SIZE; } =20 /* update tweak in param block */ - for (i =3D 0; i < AES_BLOCK_SIZE; i++) { - addr =3D wrap_address(env, param_addr + keysize + i); - cpu_stb_mmu(env, addr, tweak[i], oi, ra); - } + copy_to_guest_wrap(env, mmu_idx, ra, + param_addr + keysize, tweak, AES_BLOCK_SIZE); =20 *src_ptr_reg =3D deposit64(*src_ptr_reg, 0, addr_reg_size, *src_ptr_reg + done); @@ -466,10 +460,8 @@ static void decrypt_protkey(uint8_t *key, int keysize) int cpacf_aes_pckmo(CPUS390XState *env, const int mmu_idx, uintptr_t ra, uint64_t param_addr, uint8_t fc) { - const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); uint8_t key[32]; - int keysize, i; - uint64_t addr; + int keysize; =20 switch (fc) { case CPACF_PCKMO_ENC_AES_128_KEY: @@ -486,24 +478,17 @@ int cpacf_aes_pckmo(CPUS390XState *env, const int mmu= _idx, uintptr_t ra, } =20 /* fetch key from param block */ - for (i =3D 0; i < keysize; i++) { - addr =3D wrap_address(env, param_addr + i); - key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, param_addr, key, keysize); =20 /* 'derive' the protected key from the clear key */ encrypt_clrkey(key, keysize); =20 /* store the protected key into param block */ - for (i =3D 0; i < keysize; i++) { - addr =3D wrap_address(env, param_addr + i); - cpu_stb_mmu(env, addr, key[i], oi, ra); - } + copy_to_guest_wrap(env, mmu_idx, ra, param_addr, key, keysize); /* followed by the fake wkvp */ - for (i =3D 0; i < sizeof(protkey_wkvp); i++) { - addr =3D wrap_address(env, param_addr + keysize + i); - cpu_stb_mmu(env, addr, protkey_wkvp[i], oi, ra); - } + copy_to_guest_wrap(env, mmu_idx, ra, + param_addr + keysize, + protkey_wkvp, sizeof(protkey_wkvp)); =20 return 0; } @@ -514,9 +499,8 @@ int cpacf_paes_ecb(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, uint32_t type, uint8_t fc, uint8_t mod) { enum { MAX_BLOCKS_PER_RUN =3D 8192 / AES_BLOCK_SIZE }; - const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; - uint64_t addr, len =3D *src_len_reg, done =3D 0; + 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; @@ -548,20 +532,15 @@ int cpacf_paes_ecb(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, } =20 /* fetch and check wkvp from param block */ - for (i =3D 0; i < sizeof(wkvp); i++) { - addr =3D wrap_address(env, param_addr + keysize + i); - wkvp[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + 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; } =20 /* fetch protected key from param block */ - for (i =3D 0; i < keysize; i++) { - addr =3D wrap_address(env, param_addr + i); - key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, param_addr, key, keysize); /* decrypt the protected key */ decrypt_protkey(key, keysize); =20 @@ -574,13 +553,13 @@ int cpacf_paes_ecb(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, =20 /* 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, *src_ptr_reg + done, in, ra); + 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, *dst_ptr_reg + done, out, ra); + aes_write_block(env, mmu_idx, ra, *dst_ptr_reg + done, out); len -=3D AES_BLOCK_SIZE; done +=3D AES_BLOCK_SIZE; } @@ -601,9 +580,8 @@ int cpacf_paes_cbc(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, { enum { MAX_BLOCKS_PER_RUN =3D 8192 / AES_BLOCK_SIZE }; uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; - const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); uint8_t key[32], wkvp[32], iv[AES_BLOCK_SIZE]; - uint64_t addr, len =3D *src_len_reg, done =3D 0; + uint64_t len =3D *src_len_reg, done =3D 0; int i, keysize, addr_reg_size =3D 64; AES_KEY exkey; =20 @@ -634,26 +612,20 @@ int cpacf_paes_cbc(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, } =20 /* fetch and check wkvp from param block */ - for (i =3D 0; i < sizeof(wkvp); i++) { - addr =3D wrap_address(env, param_addr + AES_BLOCK_SIZE + keysize += i); - wkvp[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + 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; } =20 /* fetch iv from param block */ - for (i =3D 0; i < AES_BLOCK_SIZE; i++) { - addr =3D wrap_address(env, param_addr + i); - iv[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, param_addr, iv, AES_BLOCK_SIZE); =20 /* fetch protected key from param block */ - for (i =3D 0; i < keysize; i++) { - addr =3D wrap_address(env, param_addr + AES_BLOCK_SIZE + i); - key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, + param_addr + AES_BLOCK_SIZE, key, keysize); /* decrypt the protected key */ decrypt_protkey(key, keysize); =20 @@ -666,7 +638,7 @@ int cpacf_paes_cbc(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, =20 /* 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, *src_ptr_reg + done, in, ra); + 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); @@ -674,16 +646,13 @@ int cpacf_paes_cbc(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, /* encrypt in =3D> out */ AES_cbc_encrypt(in, out, iv, &exkey); } - aes_write_block(env, mmu_idx, *dst_ptr_reg + done, out, ra); + aes_write_block(env, mmu_idx, ra, *dst_ptr_reg + done, out); len -=3D AES_BLOCK_SIZE; done +=3D AES_BLOCK_SIZE; } =20 /* update iv in param block */ - for (i =3D 0; i < AES_BLOCK_SIZE; i++) { - addr =3D wrap_address(env, param_addr + i); - cpu_stb_mmu(env, addr, iv[i], oi, ra); - } + copy_to_guest_wrap(env, mmu_idx, ra, param_addr, iv, AES_BLOCK_SIZE); =20 *src_ptr_reg =3D deposit64(*src_ptr_reg, 0, addr_reg_size, *src_ptr_reg + done); @@ -701,10 +670,9 @@ int cpacf_paes_ctr(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, uint8_t fc, uint8_t mod) { enum { MAX_BLOCKS_PER_RUN =3D 8192 / AES_BLOCK_SIZE }; - const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; uint8_t ctr[AES_BLOCK_SIZE], key[32], wkvp[32]; - uint64_t addr, len =3D *src_len_reg, done =3D 0; + uint64_t len =3D *src_len_reg, done =3D 0; int i, keysize, addr_reg_size =3D 64; AES_KEY exkey; =20 @@ -735,20 +703,15 @@ int cpacf_paes_ctr(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, } =20 /* fetch and check wkvp from param block */ - for (i =3D 0; i < sizeof(wkvp); i++) { - addr =3D wrap_address(env, param_addr + keysize + i); - wkvp[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + 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; } =20 /* fetch protected key from param block */ - for (i =3D 0; i < keysize; i++) { - addr =3D wrap_address(env, param_addr + i); - key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, param_addr, key, keysize); /* decrypt the protected key */ decrypt_protkey(key, keysize); =20 @@ -758,13 +721,13 @@ int cpacf_paes_ctr(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, /* 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, *ctr_ptr_reg + done, ctr, ra); + 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, *src_ptr_reg + done, in, ra); + 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, *dst_ptr_reg + done, out, ra); + aes_write_block(env, mmu_idx, ra, *dst_ptr_reg + done, out); len -=3D AES_BLOCK_SIZE; done +=3D AES_BLOCK_SIZE; } @@ -784,9 +747,7 @@ int cpacf_paes_pcc(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, uint64_t param_addr, uint8_t fc) { uint8_t key[32], wkvp[32], tweak[AES_BLOCK_SIZE], buf[AES_BLOCK_SIZE]; - const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); int keysize, i; - uint64_t addr; AES_KEY exkey; =20 switch (fc) { @@ -801,21 +762,17 @@ int cpacf_paes_pcc(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, } =20 /* fetch and check wkvp from param block */ - for (i =3D 0; i < sizeof(wkvp); i++) { - addr =3D wrap_address(env, param_addr + keysize + i); - wkvp[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + 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; } =20 /* fetch block sequence nr from param block into buf */ - for (i =3D 0; i < AES_BLOCK_SIZE; i++) { - addr =3D wrap_address(env, param_addr + keysize + - sizeof(wkvp) + AES_BLOCK_SIZE + i); - buf[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, + param_addr + keysize + sizeof(wkvp) + AES_BLOCK_S= IZE, + buf, AES_BLOCK_SIZE); =20 /* is the block sequence nr 0 ? */ for (i =3D 0; i < AES_BLOCK_SIZE && !buf[i]; i++) { @@ -828,18 +785,14 @@ int cpacf_paes_pcc(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, } =20 /* fetch protected key from param block */ - for (i =3D 0; i < keysize; i++) { - addr =3D wrap_address(env, param_addr + i); - key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, param_addr, key, keysize); /* decrypt the protected key */ decrypt_protkey(key, keysize); =20 /* fetch tweak from param block into tweak */ - for (i =3D 0; i < AES_BLOCK_SIZE; i++) { - addr =3D wrap_address(env, param_addr + keysize + sizeof(wkvp) + i= ); - tweak[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, + param_addr + keysize + sizeof(wkvp), + tweak, AES_BLOCK_SIZE); =20 /* expand key */ AES_set_encrypt_key(key, keysize * 8, &exkey); @@ -848,11 +801,9 @@ int cpacf_paes_pcc(CPUS390XState *env, const int mmu_i= dx, uintptr_t ra, AES_encrypt(tweak, buf, &exkey); =20 /* store encrypted tweak into xts parameter field of the param block */ - for (i =3D 0; i < AES_BLOCK_SIZE; i++) { - addr =3D wrap_address(env, param_addr + keysize + - sizeof(wkvp) + 3 * AES_BLOCK_SIZE + i); - cpu_stb_mmu(env, addr, buf[i], oi, ra); - } + copy_to_guest_wrap(env, mmu_idx, ra, + param_addr + keysize + sizeof(wkvp) + 3 * AES_BLOCK= _SIZE, + buf, AES_BLOCK_SIZE); =20 return 0; } @@ -864,9 +815,8 @@ int cpacf_paes_xts(CPUS390XState *env, const int mmu_id= x, uintptr_t ra, { enum { MAX_BLOCKS_PER_RUN =3D 8192 / AES_BLOCK_SIZE }; uint8_t in[AES_BLOCK_SIZE], out[AES_BLOCK_SIZE]; - const MemOpIdx oi =3D make_memop_idx(MO_8, mmu_idx); uint8_t key[32], wkvp[32], tweak[AES_BLOCK_SIZE]; - uint64_t addr, len =3D *src_len_reg, done =3D 0; + uint64_t len =3D *src_len_reg, done =3D 0; int i, keysize, addr_reg_size =3D 64; AES_KEY exkey; =20 @@ -894,20 +844,15 @@ int cpacf_paes_xts(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, } =20 /* fetch and check wkvp from param block */ - for (i =3D 0; i < sizeof(wkvp); i++) { - addr =3D wrap_address(env, param_addr + keysize + i); - wkvp[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + 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; } =20 /* fetch protected key from param block */ - for (i =3D 0; i < keysize; i++) { - addr =3D wrap_address(env, param_addr + i); - key[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, param_addr, key, keysize); /* decrypt the protected key */ decrypt_protkey(key, keysize); =20 @@ -919,15 +864,14 @@ int cpacf_paes_xts(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, } =20 /* fetch tweak from param block */ - for (i =3D 0; i < AES_BLOCK_SIZE; i++) { - addr =3D wrap_address(env, param_addr + keysize + sizeof(wkvp) + i= ); - tweak[i] =3D cpu_ldb_mmu(env, addr, oi, ra); - } + copy_from_guest_wrap(env, mmu_idx, ra, + param_addr + keysize + sizeof(wkvp), + tweak, AES_BLOCK_SIZE); =20 /* 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, *src_ptr_reg + done, in, ra); + 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); @@ -938,16 +882,15 @@ int cpacf_paes_xts(CPUS390XState *env, const int mmu_= idx, uintptr_t ra, /* prep tweak for next round */ AES_xts_prep_next_tweak(tweak); /* write out this processed block from out */ - aes_write_block(env, mmu_idx, *dst_ptr_reg + done, out, ra); + aes_write_block(env, mmu_idx, ra, *dst_ptr_reg + done, out); len -=3D AES_BLOCK_SIZE; done +=3D AES_BLOCK_SIZE; } =20 /* update tweak in param block */ - for (i =3D 0; i < AES_BLOCK_SIZE; i++) { - addr =3D wrap_address(env, param_addr + keysize + sizeof(wkvp) + i= ); - cpu_stb_mmu(env, addr, tweak[i], oi, ra); - } + copy_to_guest_wrap(env, mmu_idx, ra, + param_addr + keysize + sizeof(wkvp), + tweak, AES_BLOCK_SIZE); =20 *src_ptr_reg =3D deposit64(*src_ptr_reg, 0, addr_reg_size, *src_ptr_reg + done); --=20 2.43.0 From nobody Sun Jul 26 10:06:44 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=1783441167; cv=none; d=zohomail.com; s=zohoarc; b=Zt3LX1eMqSVne/2iA43wdO6V9PjzpvZQRtc245qHVLsdLQPCl20OailD6luroTq/uKtnOPwh7yxO5ewPc0VqT7JgEXUy3MRDZCCrAVlPoKe8l8UFCDqnvPkp6fAs8T9P1EJaeaA3wAt3mc6uO5GaKr7UbmS4BK4gAi/ZQrfZ5aw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1783441167; 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=XqyfHY+aLzF36owuXbFffNqf64vxLygFrSMb/gmdQ+sdStdRCfZWfdmxUWMGYEpbTlknAqVAQHAtMyje9RWWmbKDpAUzbVOxjwTw4HU3ivT3aW+6trZ+pkhIEjd6Y87SGpJ8t06B9mZ8g4ZgimXDZZR2Ibc9VNK5l5tED1Pseu0= 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 1783441167180525.0918615600302; Tue, 7 Jul 2026 09:19:27 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wh8Vg-0007mj-Tt; Tue, 07 Jul 2026 12:19:00 -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 1wh8Vf-0007mJ-L8; Tue, 07 Jul 2026 12:18:59 -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 1wh8VX-0008DN-V1; Tue, 07 Jul 2026 12:18:59 -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 667FmM3w310140; Tue, 7 Jul 2026 16:18:24 GMT Received: from ppma23.wdc07v.mail.ibm.com (5d.69.3da9.ip4.static.sl-reverse.com [169.61.105.93]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4f6suqqw33-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:24 +0000 (GMT) Received: from pps.filterd (ppma23.wdc07v.mail.ibm.com [127.0.0.1]) by ppma23.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 667G4d86003239; Tue, 7 Jul 2026 16:18:23 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma23.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4f7e0hbh94-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 Jul 2026 16:18:22 +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 667GIILl9371988 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 7 Jul 2026 16:18:18 GMT Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id F152B20040; Tue, 7 Jul 2026 16:18:17 +0000 (GMT) Received: from smtpav07.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id B42702004E; Tue, 7 Jul 2026 16:18:17 +0000 (GMT) Received: from funtu2.ibm.com (unknown [9.111.140.5]) by smtpav07.fra02v.mail.ibm.com (Postfix) with ESMTP; Tue, 7 Jul 2026 16:18:17 +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=XqgFORVMNGdYrElxpEFqnA4Shgjjb7byz gr/BsHHnUL6A6L6iHLN/DPOumbGLe/JyxIsVswbpD/foVfBOeG41XwQI4V+wqXpd fceNLlvysJeC9J0amfWWru/UuWRLykKNjphEo/ur3o7M48VikxcnkLL8NtNmYV7r xzOlTFvI5QglAV81ykZTfooJja3/PQ6Z95p1WN0ryv4icsPmeH2Y8v/DjJb8ffmP zXAyV0Qcdq81oxeSKTep1w49aZJs0cQMXwu8Qiqej2nQ0xjRIyr5TCxY121OObmF uXHEqYpcjutBG6o1beVUMMNnDN0efoiOaF2rLt4Qkk2hDFKmaEPow== 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 v11 21/21] tests/tcg/s390x: Add tests for CPACF instructions Date: Tue, 7 Jul 2026 18:18:08 +0200 Message-ID: <20260707161815.40919-22-freude@linux.ibm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260707161815.40919-1-freude@linux.ibm.com> References: <20260707161815.40919-1-freude@linux.ibm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX9QQ6gpAB/1Mm filqY7Z8nPK0WmKpgPQOWFrB/hlX9kxSg+FS8Wcgdg/WJf/CUJBiP1TV0G6s/Dv8kTeuvFl2GBl 1FtR4zIPYOm/Em1yhAeg9afVn5tdxrM= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNzA3MDE2MCBTYWx0ZWRfX4P8Np1vmfvdu kYK67w+ker7o+xkqzfmLgSxe3WOM6ZidckESJtj15St8EeNh7ZcGjYSNjCEr4NG16lfkvbVDqjM xsuzLCCvm7vn8mlWAA2mwLGeqmgh+WivMWc1N1HCVGF/pjkxnMua7WWPT9YO0YnqO3HYH8diavY EOzS6iuZ7jJfVKSgE7ppnWXg6iapiQJllPSACo66iQgzLH2SbMltuZd06NHN17z+/FyDIHCUaRY AfmdogbxTqDHZCY/ssrLOZJ0W20GYNK/2K5rorIJmXyG85M9RLGlQ9go3SOOHZi1oXjovPV2Nb3 Lj7N4XgQIyZ0m6q2bqTy3V2wa/ZxqXpcIgThEXp6ytlcz7nAnm9hL/3PktpYCZmq6LvzBVINofT JtnEBjptK4GKOe5nMkW4oW77lGv9VybYAH+lUnV/lb7trvO2W69hxpBI+zYVayTShC50RypPjK9 VKiz/NdlgTtaGVrY9Gw== X-Proofpoint-GUID: PAggGcJUxQno6Jai2OU_xMandmWqYkaF X-Authority-Analysis: v=2.4 cv=Oot/DS/t c=1 sm=1 tr=0 ts=6a4d26d0 cx=c_pps a=3Bg1Hr4SwmMryq2xdFQyZA==:117 a=3Bg1Hr4SwmMryq2xdFQyZA==: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: PAggGcJUxQno6Jai2OU_xMandmWqYkaF 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-07_04,2026-07-06_02,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-2607070160 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: 1783441168616158500 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