From nobody Fri Nov 7 02:28:29 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1544766075644824.8940386245242; Thu, 13 Dec 2018 21:41:15 -0800 (PST) Received: from localhost ([::1]:59517 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXgDq-0002KR-JE for importer@patchew.org; Fri, 14 Dec 2018 00:41:14 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55878) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXfxu-0004mb-5v for qemu-devel@nongnu.org; Fri, 14 Dec 2018 00:24:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gXfxq-0005Uu-1U for qemu-devel@nongnu.org; Fri, 14 Dec 2018 00:24:46 -0500 Received: from mail-oi1-x243.google.com ([2607:f8b0:4864:20::243]:39256) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gXfxo-0005Th-6a for qemu-devel@nongnu.org; Fri, 14 Dec 2018 00:24:40 -0500 Received: by mail-oi1-x243.google.com with SMTP id i6so3628562oia.6 for ; Thu, 13 Dec 2018 21:24:39 -0800 (PST) Received: from cloudburst.twiddle.net ([187.217.227.243]) by smtp.gmail.com with ESMTPSA id r1sm1845379oti.44.2018.12.13.21.24.38 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 13 Dec 2018 21:24:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=250qEhnq+TUnyD+ms+pDEFXmUEcfmZeEXSJ+VxZZrPM=; b=NNSXb+dL2xmJUDJroMRiCyupXFFv37bwgKHgxh/6KD1Xt8vgvkpxYxM+KTDHyl+KL/ n/XtXarbxe0vFjoMA0z7BXkLzEvQ6kT1JjH8UGxLe9RozXE5yZAnN02BY/xyBGYsz2jY nvmPoXahPncD+ph7KNjKUXG9FrhyGwH1JDXHQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=250qEhnq+TUnyD+ms+pDEFXmUEcfmZeEXSJ+VxZZrPM=; b=VuBqpYZ9Wr3nYMgzwaCcR/YfVIIsK+8yRfm6ahwZ47+2jJnh+BakDl3AcwQHVrW/Sj COPdiV4BY78Vb2pmJcaYRuXr2RT1iX/0W05lRB1d6pxYVgDUsO5nqYIMxF8Siso4P9su HRdXs1MsiVWkddDen48n+fclNzq4lIiV6UQs6KaVlr/RN52dRG4DXnUIwUCtzILdGpeu qutcTbeMl5aBJiVcTAf7KGjnJzWjo8vv07qxSlNLaScUDsmDn7KrsZcMPHHnkAd7VTwL zoX1qszzuhFS7Ixfiehuel+q8sh2WmvwIovCL80WbzDkTYzwAge5R4ZihOh5u0mnOir6 DiIQ== X-Gm-Message-State: AA+aEWY2sdZgMVMLT8DnnsGBaMs06LDI5uVtKn+cCsPRejYaqDx9dAIe Vf9ihH/o0VlC2t7v5vpHPgGWIbQ7hi6e+w== X-Google-Smtp-Source: AFSGD/Wdm6XWcElYu7uUKSwjzyWZOtgupbDImtjT1c3HB8PWEeWSTujyTS0N4kWL0NqGVXOTzNV++g== X-Received: by 2002:aca:32d7:: with SMTP id y206mr908748oiy.151.1544765078990; Thu, 13 Dec 2018 21:24:38 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Thu, 13 Dec 2018 23:24:06 -0600 Message-Id: <20181214052410.11863-24-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20181214052410.11863-1-richard.henderson@linaro.org> References: <20181214052410.11863-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::243 Subject: [Qemu-devel] [PATCH v2 23/27] target/arm: Implement pauth_computepac X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This is the main crypto routine, an implementation of QARMA. This matches, as much as possible, ARM pseudocode. Signed-off-by: Richard Henderson --- target/arm/helper-a64.c | 241 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 240 insertions(+), 1 deletion(-) diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c index 19486b9677..1da7867a42 100644 --- a/target/arm/helper-a64.c +++ b/target/arm/helper-a64.c @@ -1057,10 +1057,249 @@ uint32_t HELPER(sqrt_f16)(uint32_t a, void *fpstp) * Helpers for ARMv8.3-PAuth. */ =20 +static uint64_t pac_cell_shuffle(uint64_t i) +{ + uint64_t o =3D 0; + + o |=3D extract64(i, 52, 4); + o |=3D extract64(i, 24, 4) << 4; + o |=3D extract64(i, 44, 4) << 8; + o |=3D extract64(i, 0, 4) << 12; + + o |=3D extract64(i, 28, 4) << 16; + o |=3D extract64(i, 48, 4) << 20; + o |=3D extract64(i, 4, 4) << 24; + o |=3D extract64(i, 40, 4) << 28; + + o |=3D i & MAKE_64BIT_MASK(32, 4); + o |=3D extract64(i, 12, 4) << 36; + o |=3D extract64(i, 56, 4) << 40; + o |=3D extract64(i, 8, 4) << 44; + + o |=3D extract64(i, 36, 4) << 48; + o |=3D extract64(i, 16, 4) << 52; + o |=3D extract64(i, 40, 4) << 56; + o |=3D i & MAKE_64BIT_MASK(60, 4); + + return o; +} + +static uint64_t pac_cell_inv_shuffle(uint64_t i) +{ + uint64_t o =3D 0; + + o |=3D extract64(i, 12, 4); + o |=3D extract64(i, 24, 4) << 4; + o |=3D extract64(i, 48, 4) << 8; + o |=3D extract64(i, 36, 4) << 12; + + o |=3D extract64(i, 56, 4) << 16; + o |=3D extract64(i, 44, 4) << 20; + o |=3D extract64(i, 4, 4) << 24; + o |=3D extract64(i, 16, 4) << 28; + + o |=3D i & MAKE_64BIT_MASK(32, 4); + o |=3D extract64(i, 52, 4) << 36; + o |=3D extract64(i, 28, 4) << 40; + o |=3D extract64(i, 8, 4) << 44; + + o |=3D extract64(i, 20, 4) << 48; + o |=3D extract64(i, 0, 4) << 52; + o |=3D extract64(i, 40, 4) << 56; + o |=3D i & MAKE_64BIT_MASK(60, 4); + + return o; +} + +static uint64_t pac_sub(uint64_t i) +{ + static const uint8_t sub[16] =3D { + 0xb, 0x6, 0x8, 0xf, 0xc, 0x0, 0x9, 0xe, + 0x3, 0x7, 0x4, 0x5, 0xd, 0x2, 0x1, 0xa, + }; + uint64_t o =3D 0; + int b; + + for (b =3D 0; b < 64; b +=3D 16) { + o |=3D (uint64_t)sub[(i >> b) & 0xf] << b; + } + return o; +} + +static uint64_t pac_inv_sub(uint64_t i) +{ + static const uint8_t inv_sub[16] =3D { + 0x5, 0xe, 0xd, 0x8, 0xa, 0xb, 0x1, 0x9, + 0x2, 0x6, 0xf, 0x0, 0x4, 0xc, 0x7, 0x3, + }; + uint64_t o =3D 0; + int b; + + for (b =3D 0; b < 64; b +=3D 16) { + o |=3D (uint64_t)inv_sub[(i >> b) & 0xf] << b; + } + return o; +} + +static int rot_cell(int cell, int n) +{ + cell |=3D cell << 4; + cell >>=3D n; + return cell & 0xf; +} + +static uint64_t pac_mult(uint64_t i) +{ + uint64_t o =3D 0; + int b; + + for (b =3D 0; b < 4 * 4; b +=3D 4) { + int i0, i4, i8, ic, t0, t1, t2, t3; + + i0 =3D extract64(i, b, 4); + i4 =3D extract64(i, b + 4 * 4, 4); + i8 =3D extract64(i, b + 8 * 4, 4); + ic =3D extract64(i, b + 12 * 4, 4); + + t0 =3D rot_cell(i8, 1) ^ rot_cell(i4, 2) ^ rot_cell(i0, 1); + t1 =3D rot_cell(ic, 1) ^ rot_cell(i4, 1) ^ rot_cell(i0, 2); + t2 =3D rot_cell(ic, 2) ^ rot_cell(i8, 1) ^ rot_cell(i0, 1); + t3 =3D rot_cell(ic, 2) ^ rot_cell(i8, 2) ^ rot_cell(i4, 1); + + o |=3D (uint64_t)t3 << b; + o |=3D (uint64_t)t2 << (b + 4 * 4); + o |=3D (uint64_t)t1 << (b + 8 * 4); + o |=3D (uint64_t)t0 << (b + 12 * 4); + } + return o; +} + +static uint64_t tweak_cell_rot(uint64_t cell) +{ + return (cell >> 1) | (((cell ^ (cell >> 1)) & 1) << 3); +} + +static uint64_t tweak_shuffle(uint64_t i) +{ + uint64_t o =3D 0; + + o |=3D extract64(i, 16, 4) << 0; + o |=3D extract64(i, 20, 4) << 4; + o |=3D tweak_cell_rot(extract64(i, 24, 4)) << 8; + o |=3D extract64(i, 28, 4) << 12; + + o |=3D tweak_cell_rot(extract64(i, 44, 4)) << 16; + o |=3D extract64(i, 8, 4) << 20; + o |=3D extract64(i, 12, 4) << 24; + o |=3D tweak_cell_rot(extract64(i, 32, 4)) << 28; + + o |=3D extract64(i, 48, 4) << 32; + o |=3D extract64(i, 52, 4) << 36; + o |=3D extract64(i, 56, 4) << 40; + o |=3D tweak_cell_rot(extract64(i, 60, 4)) << 44; + + o |=3D tweak_cell_rot(extract64(i, 0, 4)) << 48; + o |=3D extract64(i, 4, 4) << 52; + o |=3D tweak_cell_rot(extract64(i, 40, 4)) << 56; + o |=3D tweak_cell_rot(extract64(i, 36, 4)) << 60; + + return o; +} + +static uint64_t tweak_cell_inv_rot(uint64_t cell) +{ + return ((cell << 1) & 0xf) | ((cell & 1) ^ (cell >> 3)); +} + +static uint64_t tweak_inv_shuffle(uint64_t i) +{ + uint64_t o =3D 0; + + o |=3D tweak_cell_inv_rot(extract64(i, 48, 4)); + o |=3D extract64(i, 52, 4) << 4; + o |=3D extract64(i, 20, 4) << 8; + o |=3D extract64(i, 24, 4) << 12; + + o |=3D extract64(i, 0, 4) << 16; + o |=3D extract64(i, 4, 4) << 20; + o |=3D tweak_cell_inv_rot(extract64(i, 8, 4)) << 24; + o |=3D extract64(i, 12, 4) << 28; + + o |=3D tweak_cell_inv_rot(extract64(i, 28, 4)) << 32; + o |=3D tweak_cell_inv_rot(extract64(i, 60, 4)) << 36; + o |=3D tweak_cell_inv_rot(extract64(i, 56, 4)) << 40; + o |=3D tweak_cell_inv_rot(extract64(i, 16, 4)) << 44; + + o |=3D extract64(i, 32, 4) << 48; + o |=3D extract64(i, 36, 4) << 52; + o |=3D extract64(i, 40, 4) << 56; + o |=3D tweak_cell_inv_rot(extract64(i, 44, 4)) << 60; + + return o; +} + static uint64_t pauth_computepac(uint64_t data, uint64_t modifier, ARMPACKey key) { - g_assert_not_reached(); /* FIXME */ + static const uint64_t RC[5] =3D { + 0x0000000000000000ull, + 0x13198A2E03707344ull, + 0xA4093822299F31D0ull, + 0x082EFA98EC4E6C89ull, + 0x452821E638D01377ull, + }; + const uint64_t alpha =3D 0xC0AC29B7C97C50DDull; + /* Note that in the ARM pseudocode, key0 contains bits <127:64> + * and key1 contains bits <63:0> of the 128-bit key. + */ + uint64_t key0 =3D key.hi, key1 =3D key.lo; + uint64_t workingval, runningmod, roundkey, modk0; + int i; + + modk0 =3D (key0 << 63) | ((key0 >> 1) ^ (key0 >> 63)); + runningmod =3D modifier; + workingval =3D data ^ key0; + + for (i =3D 0; i <=3D 4; ++i) { + roundkey =3D key1 ^ runningmod; + workingval ^=3D roundkey; + workingval ^=3D RC[i]; + if (i > 0) { + workingval =3D pac_cell_shuffle(workingval); + workingval =3D pac_mult(workingval); + } + workingval =3D pac_sub(workingval); + runningmod =3D tweak_shuffle(runningmod); + } + roundkey =3D modk0 ^ runningmod; + workingval ^=3D roundkey; + workingval =3D pac_cell_shuffle(workingval); + workingval =3D pac_mult(workingval); + workingval =3D pac_sub(workingval); + workingval =3D pac_cell_shuffle(workingval); + workingval =3D pac_mult(workingval); + workingval ^=3D key1; + workingval =3D pac_cell_inv_shuffle(workingval); + workingval =3D pac_inv_sub(workingval); + workingval =3D pac_mult(workingval); + workingval =3D pac_cell_inv_shuffle(workingval); + workingval ^=3D key0; + workingval ^=3D runningmod; + for (i =3D 0; i <=3D 4; ++i) { + workingval =3D pac_inv_sub(workingval); + if (i < 4) { + workingval =3D pac_mult(workingval); + workingval =3D pac_cell_inv_shuffle(workingval); + } + runningmod =3D tweak_inv_shuffle(runningmod); + roundkey =3D key1 ^ runningmod; + workingval ^=3D RC[4-i]; + workingval ^=3D roundkey; + workingval ^=3D alpha; + } + workingval ^=3D modk0; + + return workingval; } =20 static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modi= fier, --=20 2.17.2