From nobody Wed Feb 11 05:36:37 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.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=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.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 [209.51.188.17]) by mx.zohomail.com with SMTPS id 154698814305085.80688056487611; Tue, 8 Jan 2019 14:55:43 -0800 (PST) Received: from localhost ([127.0.0.1]:45703 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gh0Hd-0005wi-UG for importer@patchew.org; Tue, 08 Jan 2019 17:55:42 -0500 Received: from eggs.gnu.org ([209.51.188.92]:53083) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ggzvZ-0000jN-JN for qemu-devel@nongnu.org; Tue, 08 Jan 2019 17:32:54 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ggzvX-0005L6-Lf for qemu-devel@nongnu.org; Tue, 08 Jan 2019 17:32:53 -0500 Received: from mail-pg1-x544.google.com ([2607:f8b0:4864:20::544]:46783) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ggzvV-0005Hy-39 for qemu-devel@nongnu.org; Tue, 08 Jan 2019 17:32:49 -0500 Received: by mail-pg1-x544.google.com with SMTP id w7so2341383pgp.13 for ; Tue, 08 Jan 2019 14:32:47 -0800 (PST) Received: from cloudburst.lan (2001-44b8-2176-c800-8cc6-2630-7d99-5ef1.static.ipv6.internode.on.net. [2001:44b8:2176:c800:8cc6:2630:7d99:5ef1]) by smtp.gmail.com with ESMTPSA id w128sm100686177pfw.79.2019.01.08.14.32.44 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 08 Jan 2019 14:32:45 -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=TVFC2GnajrDi6vJcNao7tzlaxbm1uciSrDAJDzmWUhc=; b=A5JIwu+pyzJ3BqLvQ6ru+ifXw28m5YgYAZTpsByI2hsP5NS8WmrKMyUvZEakVJJUYi FdMJ8s3MMXzFpNiw7q2y8iHeK/MKZZ+jWqPA8Ruov+MmVEAbXUvmGgmv90E2rM6/kxVy xe2OT6XRcK6lYHkF7Fl2qRx61Rksuh77HFM1w= 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=TVFC2GnajrDi6vJcNao7tzlaxbm1uciSrDAJDzmWUhc=; b=mpYC5HE5LcDD7u2AFCo4EBy0RietOgEgEO0upVtZ41Tdc5bNi/Q5Vgf3a1a0rVU6Yg JDgkekZtFqMNGL1uw3sQOtAPh4ju+J9IX/HDuMMM6+UC78Y/PCENDWyXX7xOvxPjeDnI Zsfe/9ElRsmZKwlrPid2xsQ7D4T7ONByOMgWWkJvfEmJ5b/yGl85+nQc421DztCiHCH5 ooqm+SFxD9jf2Vrj5JKrDG7yCm8fQDX+slHUJJA3ODVs+sVHHDRP+q6TKYAz6zgNQOUk SMi/90EYwCG/dQGGXJ4ZdSpTkvYdOqzIhbtkhdAB+R5Qq8E0io8PDi6ePz+v6M4LKtZt wPfQ== X-Gm-Message-State: AJcUukfFc4PvW9flttOgkMWUhplzVhuKNIKGO/qD329AGxzguubAXySi oJ1NFPDOhBBbzZAK1fFhNEQdPIgNeL4= X-Google-Smtp-Source: ALg8bN6y8lu+BiTJap6P3arTuLJ0kuGV/FJXLLO59Spy0inwe6h27xRM+8eI5cyx/yDub/vS6xovQg== X-Received: by 2002:a63:e655:: with SMTP id p21mr3139069pgj.70.1546986766407; Tue, 08 Jan 2019 14:32:46 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Wed, 9 Jan 2019 08:31:25 +1000 Message-Id: <20190108223129.5570-28-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190108223129.5570-1-richard.henderson@linaro.org> References: <20190108223129.5570-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::544 Subject: [Qemu-devel] [PATCH v3 27/31] 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 Reviewed-by: Peter Maydell --- target/arm/pauth_helper.c | 241 +++++++++++++++++++++++++++++++++++++- 1 file changed, 240 insertions(+), 1 deletion(-) diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c index bc89dd8c11..bc0c9b84e7 100644 --- a/target/arm/pauth_helper.c +++ b/target/arm/pauth_helper.c @@ -26,10 +26,249 @@ #include "tcg/tcg-gvec-desc.h" =20 =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 extract64(i, 32, 4) << 32; + o |=3D extract64(i, 12, 4) << 36; + o |=3D extract64(i, 56, 4) << 40; + o |=3D extract64(i, 20, 4) << 44; + + o |=3D extract64(i, 8, 4) << 48; + o |=3D extract64(i, 36, 4) << 52; + o |=3D extract64(i, 16, 4) << 56; + o |=3D extract64(i, 60, 4) << 60; + + 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) +{ + /* 4-bit rotate left by n. */ + cell |=3D cell << 4; + return extract32(cell, 4 - n, 4); +} + +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, 1) ^ 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