From patchwork Fri Dec 7 10:36:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 153125 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp343928ljp; Fri, 7 Dec 2018 02:48:52 -0800 (PST) X-Google-Smtp-Source: AFSGD/V4opCQbgjDxVkp7jHsYi6IYO2vHbTu2vSRGxMoNQPWaJg2dcyMC4tYssB5tLqSpSBqLdQg X-Received: by 2002:a37:6191:: with SMTP id v139mr1325010qkb.25.1544179731906; Fri, 07 Dec 2018 02:48:51 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544179731; cv=none; d=google.com; s=arc-20160816; b=hOM1/23jg+Gg5PYpOCFUh/hS/0MM2QtsKV3DWueCx78maPvMX9+b+kOJVT/h0uA9La AHg0PNUvQhvFPDprQ8eJgEDtGf1aDFkR36ANiZEdfHPRZqS6iKpJ0I6FTWilJdsEOw/U DJfOAWQZW0xDdSws5rscQUnEi+ldYsdnIQHPj7PX8o2olN57hGyDNdJkVztbL0Q5WK8A mlGC16dTGDBNITNSm9cCvlmAcuOATbpAMThYlKSNXg/o4PhWryO1Y+/LmzBEQNjjjJ2h 7GYBxAbhwullTEdnw1+k49Y51oAbWKCb6MGnrZU1pSkYfTkG5wdfEtLWSluf4VXYavvs Kgrg== 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=uB5+GUDHh+mqCdQwaG/2qelvT+02F/oQB88LhTrzX2I=; b=wbiw8hufVLA2LD1K1koZgVP0PgIPzCc8LOo+wYpzDtIPPcEau0ggFhdjDH0WfH6hZe rCU4UZM/XzdmbJIZ+uMIlCR+0ZaQLx1wF5ctowXs37zvKyqj2z5PCe4rg1kp6xLSwlkL EWtQxG9VuOFJ2TjfWC/ZYdB/fjHh+H1McsD97u7WjuzY4Pl5dEq3wF61LrNvPgXdA/qM 8TnIA2UxmpMAdjjjYAEW3P19QQVMnsdJkE36lvz1UqswrTQTOs8noWnwx1hFww+u0Ge7 rlhqvuL4CH5/BDqdjLChj655fqQpFkCf28Fxv+fr+88I/sV7UvVH3safRcP5oV2iepQG x1Cg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b="fGwb/B1R"; 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 i13si60948qtm.380.2018.12.07.02.48.51 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 07 Dec 2018 02:48:51 -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="fGwb/B1R"; 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]:45314 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gVDgh-0005U7-Cw for patch@linaro.org; Fri, 07 Dec 2018 05:48:51 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59326) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gVDVQ-0008Ph-Ue for qemu-devel@nongnu.org; Fri, 07 Dec 2018 05:37:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gVDVP-00080Z-3S for qemu-devel@nongnu.org; Fri, 07 Dec 2018 05:37:12 -0500 Received: from mail-ot1-x342.google.com ([2607:f8b0:4864:20::342]:39207) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gVDVN-0007wZ-3E for qemu-devel@nongnu.org; Fri, 07 Dec 2018 05:37:10 -0500 Received: by mail-ot1-x342.google.com with SMTP id n8so3360342otl.6 for ; Fri, 07 Dec 2018 02:37:09 -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=uB5+GUDHh+mqCdQwaG/2qelvT+02F/oQB88LhTrzX2I=; b=fGwb/B1ReikzSKUzONQ+uGm79PNaBWsX3+/rykpO/7Vxq1ECFC2jklIf/kQMKcngMO 3aWfoEotl3wuOwtmqMYbJY6X4tRTv+Tu445I665K7ngMfF412rJuO8BpQdmCeCBP2bBB KoFFyByTh1VF2FklZINCVOfqdu4gyW0xbfVAo= 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=uB5+GUDHh+mqCdQwaG/2qelvT+02F/oQB88LhTrzX2I=; b=lnbKfW7H06MST/p/n9kU/Ko8AA4cDVfGn63teYk++s5IojkM9fyFnPLGLwCM1i2exY /+KYs9nQaRlOe/dtRvCgw6lI3tV82OoGpcBgZF27/28OmQM1Hn3yRq4i0lpnOvP2qLLp x5b5UOlgTwW9+ZSc0SNMyVF2fLbEs+39HOTQUTdJXeEX+vOLyPVe/ZE2Qfzw1topW9Yv h4GB+Q0mEzNo+JVPJd+yMsm23+ma7XEuSAhGL7cB4KiEa4ouSSDqL/UsCJ8KFeCFVWWc Gl3XN9QY29JV674oS5BWNazz/A0jBEWnJPC/wuxoFW9fEbPfBQ7mwHAr63Vr/mV283tc c3vQ== X-Gm-Message-State: AA+aEWYTVMWrdYawxREDrpnr0/Y+sPCgVK/OlEB0b7Q/kRG4CW0fC/AF kc9Z9JTVqucKZkFoxHLpoK1ThgMdy2s= X-Received: by 2002:a9d:58f:: with SMTP id 15mr1029746otd.218.1544179027988; Fri, 07 Dec 2018 02:37:07 -0800 (PST) Received: from cloudburst.twiddle.net (172.189-204-159.bestel.com.mx. [189.204.159.172]) by smtp.gmail.com with ESMTPSA id c19sm2037594otl.16.2018.12.07.02.37.06 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 07 Dec 2018 02:37:07 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Fri, 7 Dec 2018 04:36:27 -0600 Message-Id: <20181207103631.28193-23-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20181207103631.28193-1-richard.henderson@linaro.org> References: <20181207103631.28193-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::342 Subject: [Qemu-devel] [PATCH 22/26] 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, ramana.radhakrishnan@arm.com 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 | 240 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 239 insertions(+), 1 deletion(-) -- 2.17.2 diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c index 28bdf6f0b2..c6755a7a07 100644 --- a/target/arm/helper-a64.c +++ b/target/arm/helper-a64.c @@ -1057,10 +1057,248 @@ 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; +} + +/* Note that in the ARM pseudocode, key0 contains bits <127:64> + * and key1 contains bits <63:0> of the 128-bit key. + */ static uint64_t pauth_computepac(uint64_t data, uint64_t modifier, uint64_t key0, uint64_t key1) { - g_assert_not_reached(); /* FIXME */ + static const uint64_t RC[5] = { + 0x0000000000000000ull, + 0x13198A2E03707344ull, + 0xA4093822299F31D0ull, + 0x082EFA98EC4E6C89ull, + 0x452821E638D01377ull, + }; + const uint64_t alpha = 0xC0AC29B7C97C50DDull; + 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,