From patchwork Tue Jan 8 22:31:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 155036 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp48618jaa; Tue, 8 Jan 2019 14:56:34 -0800 (PST) X-Google-Smtp-Source: ALg8bN6IZf3ney2u2bxgO//eYoxcbTKnQB6BnuG8SbL9x4qabztE7SZxteVyl48TST7Ri+i7qGfZ X-Received: by 2002:a1c:9a0d:: with SMTP id c13mr3335708wme.41.1546988194241; Tue, 08 Jan 2019 14:56:34 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1546988194; cv=none; d=google.com; s=arc-20160816; b=YdKY2p0fwpEefhajcnqUEJik4UnBiL7hSHJ+n4fWZPXl8W7lOK3YeP7PguGeU7KYE1 BTV0yzhrBL7XCzoRp9ls0DLmyB7oL9rs3f1TUn2kkGVI0AOKUXr5ZtPs2HhwJZyDXZY0 zlLIfybpyxrPAzzfitDVfX2ay+OSVOmmngbuYIqkqyyo+1NlijlXXF7qK7eoTGMLEi51 7u/dKpN0HbRhZ/GXVLk78Pm3CMDPfF+EK4EuwaDwwGBXzCUxyOvIEAiU8qAmuJY962U1 Nv8FpMmmg81JbriZ3rbGGeaqaGN7ix+rk0luCzexAEF8yigrQKlhiRuUFdR+UyGazVL7 kyRA== 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=TVFC2GnajrDi6vJcNao7tzlaxbm1uciSrDAJDzmWUhc=; b=qbqn/NM2af2Tdc0whOXil2T6qTC0/HVPq6AbrQrpGVwHOsoRSceT22CMHLUA5sft7b UZRurHf9rc7KiMCF1q5edcQAyO+0B3GNBHW5SNbfeBSF9qcTzjTfr5j6FfcRnR/r159o 2Edbzk64y/QsBX5b1G6LHAb0BtHu5mJ4t+DqRuXh2yli7T0A8n8fQdh71wNW92V3avlS lwTeNfAjCbi5vuVp1HB6IZRpCF3muLsBHyVLCZIq5J0rVtEg272t2XX2GPm/xw6+q7Lw iOw1HtxO5G+I8DsTGlyI2N8xTn0A/7jALwJOeVLbv8D8YJ+MRd4LCNit7GGFojuAzvjI peTQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=A5JIwu+p; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 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. [209.51.188.17]) by mx.google.com with ESMTPS id h16si37180457wrq.337.2019.01.08.14.56.33 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 08 Jan 2019 14:56:34 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=A5JIwu+p; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 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 ([127.0.0.1]:45703 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gh0IT-0005wi-3y for patch@linaro.org; Tue, 08 Jan 2019 17:56:33 -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) 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-Received: by 2002:a63:e655:: with SMTP id p21mr3139069pgj.70.1546986766407; Tue, 08 Jan 2019 14:32:46 -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) 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+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/pauth_helper.c | 241 +++++++++++++++++++++++++++++++++++++- 1 file changed, 240 insertions(+), 1 deletion(-) -- 2.17.2 Reviewed-by: Peter Maydell 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" +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 |= extract64(i, 32, 4) << 32; + o |= extract64(i, 12, 4) << 36; + o |= extract64(i, 56, 4) << 40; + o |= extract64(i, 20, 4) << 44; + + o |= extract64(i, 8, 4) << 48; + o |= extract64(i, 36, 4) << 52; + o |= extract64(i, 16, 4) << 56; + o |= extract64(i, 60, 4) << 60; + + 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) +{ + /* 4-bit rotate left by n. */ + cell |= cell << 4; + return extract32(cell, 4 - n, 4); +} + +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, 1) ^ 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,