From patchwork Fri Dec 14 05:24:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 153760 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp1680088ljp; Thu, 13 Dec 2018 21:39:57 -0800 (PST) X-Google-Smtp-Source: AFSGD/WhnMYLpT+mVTTBIko7QmSkdA9HgLvKDn+2d5DER/Qy3hY0YA/Uu4J0J2YhloLz9HrHzDEx X-Received: by 2002:a37:d1c5:: with SMTP id o66mr1408010qkl.293.1544765997554; Thu, 13 Dec 2018 21:39:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544765997; cv=none; d=google.com; s=arc-20160816; b=jC6e7ZF4jbrPcAwwjCVNeWrnaqvCYz/J6Qo4SDdl0ONs+EY8uZmWu+vLlujc8bXLEf kRJR3NUlVq+xXSXAdCsB69pf1mYSZWHmj5KRxumXEnF/qDuIhHiv5N+h+Z/HgVOuXxp2 0HyDCZ0amJajQh6Z+GzTpjeNmkdDLkFR5J0RKvBKV7o1+HemNscU5UZaaJSntrwMoxPy uPXRL59rqtYbfQU9E3rAnFR2tGzH1ZngsaKfVqkGlxWa+jn7WEg1+G3P2W1L6Qx0OOS4 5fNTw5ZbGhyeyGHvEbkrhnZDKD05awdJYyuwM5GrIZbhJjpWmgc0smgkANd/BdlNAzBg D2eA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=250qEhnq+TUnyD+ms+pDEFXmUEcfmZeEXSJ+VxZZrPM=; b=ZJgAOMRQjtqvDMkuA6rc1aOrcgCfIoEwhk/EIe4B3K4CKNy/MYVJxpcpjaP7LWWlMJ 5w9Vy0kMRuh23xd5kP8m4GGZFyQ5h/AH3/Wrjjor6ITzIFWYsh0wiTRUaNK/Gxcu86Ae zXSFdWGbhD84PKOGwWOb78lm8bJbe0cfNxJmFSYq64D+iXJdhxcNNvi6MPhbregSLu4A 6WbYHNgac7RT90hO7Oo48bNmF/w/pLdOJcAXlG/unbjgB/5T3XL7W2EgVmFqheQN1qHd rfMbbSYoGVHFQLEMYUfs9EP4refoSZrBl7Mxd6rG4SVB7DaJOVwftE+4ZWxMnKlAz90l aadQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=NNSXb+dL; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id c41si1664270qtk.178.2018.12.13.21.39.57 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 13 Dec 2018 21:39:57 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=NNSXb+dL; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:59509 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gXgCb-0001Qh-1u for patch@linaro.org; Fri, 14 Dec 2018 00:39:57 -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) 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-Received: by 2002:aca:32d7:: with SMTP id y206mr908748oiy.151.1544765078990; Thu, 13 Dec 2018 21:24:38 -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) 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+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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(-) -- 2.17.2 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. */ +static uint64_t pac_cell_shuffle(uint64_t i) +{ + uint64_t o = 0; + + o |= extract64(i, 52, 4); + o |= extract64(i, 24, 4) << 4; + o |= extract64(i, 44, 4) << 8; + o |= extract64(i, 0, 4) << 12; + + o |= extract64(i, 28, 4) << 16; + o |= extract64(i, 48, 4) << 20; + o |= extract64(i, 4, 4) << 24; + o |= extract64(i, 40, 4) << 28; + + o |= i & MAKE_64BIT_MASK(32, 4); + o |= extract64(i, 12, 4) << 36; + o |= extract64(i, 56, 4) << 40; + o |= extract64(i, 8, 4) << 44; + + o |= extract64(i, 36, 4) << 48; + o |= extract64(i, 16, 4) << 52; + o |= extract64(i, 40, 4) << 56; + o |= i & MAKE_64BIT_MASK(60, 4); + + return o; +} + +static uint64_t pac_cell_inv_shuffle(uint64_t i) +{ + uint64_t o = 0; + + o |= extract64(i, 12, 4); + o |= extract64(i, 24, 4) << 4; + o |= extract64(i, 48, 4) << 8; + o |= extract64(i, 36, 4) << 12; + + o |= extract64(i, 56, 4) << 16; + o |= extract64(i, 44, 4) << 20; + o |= extract64(i, 4, 4) << 24; + o |= extract64(i, 16, 4) << 28; + + o |= i & MAKE_64BIT_MASK(32, 4); + o |= extract64(i, 52, 4) << 36; + o |= extract64(i, 28, 4) << 40; + o |= extract64(i, 8, 4) << 44; + + o |= extract64(i, 20, 4) << 48; + o |= extract64(i, 0, 4) << 52; + o |= extract64(i, 40, 4) << 56; + o |= i & MAKE_64BIT_MASK(60, 4); + + return o; +} + +static uint64_t pac_sub(uint64_t i) +{ + static const uint8_t sub[16] = { + 0xb, 0x6, 0x8, 0xf, 0xc, 0x0, 0x9, 0xe, + 0x3, 0x7, 0x4, 0x5, 0xd, 0x2, 0x1, 0xa, + }; + uint64_t o = 0; + int b; + + for (b = 0; b < 64; b += 16) { + o |= (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] = { + 0x5, 0xe, 0xd, 0x8, 0xa, 0xb, 0x1, 0x9, + 0x2, 0x6, 0xf, 0x0, 0x4, 0xc, 0x7, 0x3, + }; + uint64_t o = 0; + int b; + + for (b = 0; b < 64; b += 16) { + o |= (uint64_t)inv_sub[(i >> b) & 0xf] << b; + } + return o; +} + +static int rot_cell(int cell, int n) +{ + cell |= cell << 4; + cell >>= n; + return cell & 0xf; +} + +static uint64_t pac_mult(uint64_t i) +{ + uint64_t o = 0; + int b; + + for (b = 0; b < 4 * 4; b += 4) { + int i0, i4, i8, ic, t0, t1, t2, t3; + + i0 = extract64(i, b, 4); + i4 = extract64(i, b + 4 * 4, 4); + i8 = extract64(i, b + 8 * 4, 4); + ic = extract64(i, b + 12 * 4, 4); + + t0 = rot_cell(i8, 1) ^ rot_cell(i4, 2) ^ rot_cell(i0, 1); + t1 = rot_cell(ic, 1) ^ rot_cell(i4, 1) ^ rot_cell(i0, 2); + t2 = rot_cell(ic, 2) ^ rot_cell(i8, 1) ^ rot_cell(i0, 1); + t3 = rot_cell(ic, 2) ^ rot_cell(i8, 2) ^ rot_cell(i4, 1); + + o |= (uint64_t)t3 << b; + o |= (uint64_t)t2 << (b + 4 * 4); + o |= (uint64_t)t1 << (b + 8 * 4); + o |= (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 = 0; + + o |= extract64(i, 16, 4) << 0; + o |= extract64(i, 20, 4) << 4; + o |= tweak_cell_rot(extract64(i, 24, 4)) << 8; + o |= extract64(i, 28, 4) << 12; + + o |= tweak_cell_rot(extract64(i, 44, 4)) << 16; + o |= extract64(i, 8, 4) << 20; + o |= extract64(i, 12, 4) << 24; + o |= tweak_cell_rot(extract64(i, 32, 4)) << 28; + + o |= extract64(i, 48, 4) << 32; + o |= extract64(i, 52, 4) << 36; + o |= extract64(i, 56, 4) << 40; + o |= tweak_cell_rot(extract64(i, 60, 4)) << 44; + + o |= tweak_cell_rot(extract64(i, 0, 4)) << 48; + o |= extract64(i, 4, 4) << 52; + o |= tweak_cell_rot(extract64(i, 40, 4)) << 56; + o |= 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 = 0; + + o |= tweak_cell_inv_rot(extract64(i, 48, 4)); + o |= extract64(i, 52, 4) << 4; + o |= extract64(i, 20, 4) << 8; + o |= extract64(i, 24, 4) << 12; + + o |= extract64(i, 0, 4) << 16; + o |= extract64(i, 4, 4) << 20; + o |= tweak_cell_inv_rot(extract64(i, 8, 4)) << 24; + o |= extract64(i, 12, 4) << 28; + + o |= tweak_cell_inv_rot(extract64(i, 28, 4)) << 32; + o |= tweak_cell_inv_rot(extract64(i, 60, 4)) << 36; + o |= tweak_cell_inv_rot(extract64(i, 56, 4)) << 40; + o |= tweak_cell_inv_rot(extract64(i, 16, 4)) << 44; + + o |= extract64(i, 32, 4) << 48; + o |= extract64(i, 36, 4) << 52; + o |= extract64(i, 40, 4) << 56; + o |= 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] = { + 0x0000000000000000ull, + 0x13198A2E03707344ull, + 0xA4093822299F31D0ull, + 0x082EFA98EC4E6C89ull, + 0x452821E638D01377ull, + }; + const uint64_t alpha = 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 = key.hi, key1 = key.lo; + uint64_t workingval, runningmod, roundkey, modk0; + int i; + + modk0 = (key0 << 63) | ((key0 >> 1) ^ (key0 >> 63)); + runningmod = modifier; + workingval = data ^ key0; + + for (i = 0; i <= 4; ++i) { + roundkey = key1 ^ runningmod; + workingval ^= roundkey; + workingval ^= RC[i]; + if (i > 0) { + workingval = pac_cell_shuffle(workingval); + workingval = pac_mult(workingval); + } + workingval = pac_sub(workingval); + runningmod = tweak_shuffle(runningmod); + } + roundkey = modk0 ^ runningmod; + workingval ^= roundkey; + workingval = pac_cell_shuffle(workingval); + workingval = pac_mult(workingval); + workingval = pac_sub(workingval); + workingval = pac_cell_shuffle(workingval); + workingval = pac_mult(workingval); + workingval ^= key1; + workingval = pac_cell_inv_shuffle(workingval); + workingval = pac_inv_sub(workingval); + workingval = pac_mult(workingval); + workingval = pac_cell_inv_shuffle(workingval); + workingval ^= key0; + workingval ^= runningmod; + for (i = 0; i <= 4; ++i) { + workingval = pac_inv_sub(workingval); + if (i < 4) { + workingval = pac_mult(workingval); + workingval = pac_cell_inv_shuffle(workingval); + } + runningmod = tweak_inv_shuffle(runningmod); + roundkey = key1 ^ runningmod; + workingval ^= RC[4-i]; + workingval ^= roundkey; + workingval ^= alpha; + } + workingval ^= modk0; + + return workingval; } static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,