From patchwork Mon Jun 24 07:38:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 167555 Delivered-To: patch@linaro.org Received: by 2002:a92:4782:0:0:0:0:0 with SMTP id e2csp3867000ilk; Mon, 24 Jun 2019 00:38:38 -0700 (PDT) X-Google-Smtp-Source: APXvYqwfF+qQ20YIYQJMXvfhM/tSv0ecgmq8ZqylGOy5QpZTzc09I6nxthgjGmMrwMgdj6aM631s X-Received: by 2002:a63:3683:: with SMTP id d125mr9071897pga.252.1561361918244; Mon, 24 Jun 2019 00:38:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561361918; cv=none; d=google.com; s=arc-20160816; b=w3hJqEyVBx/ETzjVg5ErDkoWh88H0tZZ8q3tPfakDe6y25ZrCk16BrYz0nW1uOz5s2 NP/zVyhWXk5x9a3JXXcLmv0MM51AcioM0rfUoYq/zp2Pzc22llWFqHFknnlZ+cH2VQo+ XPchhqOSoMjK/PNBrC8sZJsHZxNzUsN9AfEHp32Sn3BvBjfhcImEeGDEwMKMzyEE4Z9u flgBd3Rv0pQ0Ni+dqrRMZirRC2XxbPbUvIhV87NiQgxkxXfUKYiVeahQAQh95QMqkM37 zqS0/m34kyR/0lqrBT1tCDwa/Dt2JmXq/wTJJowWOuQM7Zigs89QDS3gJDHmNOSEN2EM CM8A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=923foVD9gLovB0Clhw+C5MS1BecE623/4WPm3/kqlks=; b=Wdw7cifauZwRmIlFluIaDHMKOEYelPjH3wZQddxth3kYts2V1wh30wJkzGN9YKV0QN yb8COH1MvxQSeckOEDndCMWlvNgXQ/X7JEJO3+qZ2/Bais1e6UnUOM9E27QNk7nfFRVy zD1YW14b/hw9WOGuobZAg+SUObA3je0JxYn1D8jpxcKJj+D749ugDmkhZNs/2M12XR7a wIf0NpcpzBz3Rs4AAQL5IJkbbrAaq+x/f59YJxSOxM1vYbiItX+xxjgCtTR1uyeYjFEx bo9gSozVxwJF+pfQwQRHN2I/ZMXneA5cxQvRDvx8HxKSYLsZO/Wec3a8jX2vi2OCbT+M vL+w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=SOPGrPDK; spf=pass (google.com: best guess record for domain of linux-crypto-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h5si9375669pgd.419.2019.06.24.00.38.38; Mon, 24 Jun 2019 00:38:38 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-crypto-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=SOPGrPDK; spf=pass (google.com: best guess record for domain of linux-crypto-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727022AbfFXHih (ORCPT + 3 others); Mon, 24 Jun 2019 03:38:37 -0400 Received: from mail-wm1-f68.google.com ([209.85.128.68]:39486 "EHLO mail-wm1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726077AbfFXHih (ORCPT ); Mon, 24 Jun 2019 03:38:37 -0400 Received: by mail-wm1-f68.google.com with SMTP id z23so12196032wma.4 for ; Mon, 24 Jun 2019 00:38:35 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=923foVD9gLovB0Clhw+C5MS1BecE623/4WPm3/kqlks=; b=SOPGrPDKEtTWRgHEo/QtVnXTYMT9EWsCejMLqNCh+rc8DcPwE3A0Ca0OwHQWiDGehw 6cAh4i95iKDiTSt/u3elGr7CQ4Yr+RXvDyMw/c+H0PrCEHjyQJWulbggCdcqn2zEchCd Is/xwQZTxvgXV+8OOfZEld8t+cNONRPudHH9lTjuYPfmQFTsqQT22jXa+HBMXpaWS7af wAft6VrIAX4rpUQJR/+62tBJBywS7WmPl2uaKTJz744IfKXR35xHRgB/UVYFwlnBnFf7 YTY8357gfJBPyFjOisdYb1mKMuTV2tdLboNvFnD6Wf8YaW74Dz1DrmziWW6Y/Ur/e9DZ kR8Q== 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:mime-version:content-transfer-encoding; bh=923foVD9gLovB0Clhw+C5MS1BecE623/4WPm3/kqlks=; b=HWyn0f46x1xZT//2JSm5vtIWEhHDycTFHocd7Uon4BHwvWIWXtbZI0A5017m66eATX uwCrAbiMjGH+9fZ2Eh1c008jn9OaxqkXAms+rGtxVUGXp7cZOfzonu0qVJNIsJKHjCcx Vvp1v9tyDpuhPA7Mz7CU8W4QY2hxEs1zHrXCJVh/NV4yhOdNSBySV6167frugrvygEVc qpjFoacCwGooaLzj03jx7ymK11Ax8ydNXInDh/4bT4uNw+nfTEnR3gM3RhYfxAvYqyyD as+MGbp5FlbH/bAdiybEBlTDhzwDhD+kuslFL4rn01GBXqIFMJSNKOZnpkSTv72pZS6h iaow== X-Gm-Message-State: APjAAAVtePPXyI3yTRa0MTI1vVVa7ed3pUfCndGhIJWSOGteJAFLacrj oJzBrcvNMtQMgACnNvM4OAIqIrrwuG/rUQ== X-Received: by 2002:a7b:c398:: with SMTP id s24mr9739069wmj.53.1561361914433; Mon, 24 Jun 2019 00:38:34 -0700 (PDT) Received: from sudo.home ([2a01:cb1d:112:6f00:4866:7cdc:a930:8455]) by smtp.gmail.com with ESMTPSA id 203sm7419280wmc.30.2019.06.24.00.38.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 24 Jun 2019 00:38:33 -0700 (PDT) From: Ard Biesheuvel To: linux-crypto@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, Ard Biesheuvel , Eric Biggers , Ondrej Mosnacek , Herbert Xu , Steve Capper Subject: [PATCH 5/6] crypto: aegis128 - provide a SIMD implementation based on NEON intrinsics Date: Mon, 24 Jun 2019 09:38:17 +0200 Message-Id: <20190624073818.29296-6-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190624073818.29296-1-ard.biesheuvel@linaro.org> References: <20190624073818.29296-1-ard.biesheuvel@linaro.org> MIME-Version: 1.0 Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org Provide an accelerated implementation of aegis128 by wiring up the SIMD hooks in the generic driver to an implementation based on NEON intrinsics, which can be compiled to both ARM and arm64 code. This results in a performance of 2.2 cycles per byte on Cortex-A53, which is a performance increase of ~11x compared to the generic code. Signed-off-by: Ard Biesheuvel --- crypto/Kconfig | 5 + crypto/Makefile | 12 ++ crypto/aegis128-neon-inner.c | 142 ++++++++++++++++++++ crypto/aegis128-neon.c | 43 ++++++ 4 files changed, 202 insertions(+) -- 2.20.1 diff --git a/crypto/Kconfig b/crypto/Kconfig index 3d056e7da65f..c4b96f2e1344 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -311,6 +311,11 @@ config CRYPTO_AEGIS128 help Support for the AEGIS-128 dedicated AEAD algorithm. +config CRYPTO_AEGIS128_SIMD + bool "Support SIMD acceleration for AEGIS-128" + depends on CRYPTO_AEGIS128 && ((ARM || ARM64) && KERNEL_MODE_NEON) + default y + config CRYPTO_AEGIS128L tristate "AEGIS-128L AEAD algorithm" select CRYPTO_AEAD diff --git a/crypto/Makefile b/crypto/Makefile index 266a4cdbb9e2..f4a55cfb7f17 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -92,6 +92,18 @@ obj-$(CONFIG_CRYPTO_GCM) += gcm.o obj-$(CONFIG_CRYPTO_CCM) += ccm.o obj-$(CONFIG_CRYPTO_CHACHA20POLY1305) += chacha20poly1305.o obj-$(CONFIG_CRYPTO_AEGIS128) += aegis128.o +aegis128-y := aegis128.o + +ifeq ($(ARCH),arm) +CFLAGS_aegis128-neon-inner.o += -ffreestanding -march=armv7-a -mfloat-abi=softfp -mfpu=crypto-neon-fp-armv8 +aegis128-$(CONFIG_CRYPTO_AEGIS128_SIMD) += aegis128-neon.o aegis128-neon-inner.o +endif +ifeq ($(ARCH),arm64) +CFLAGS_aegis128-neon-inner.o += -ffreestanding -mcpu=generic+crypto +CFLAGS_REMOVE_aegis128-neon-inner.o += -mgeneral-regs-only +aegis128-$(CONFIG_CRYPTO_AEGIS128_SIMD) += aegis128-neon.o aegis128-neon-inner.o +endif + obj-$(CONFIG_CRYPTO_AEGIS128L) += aegis128l.o obj-$(CONFIG_CRYPTO_AEGIS256) += aegis256.o obj-$(CONFIG_CRYPTO_MORUS640) += morus640.o diff --git a/crypto/aegis128-neon-inner.c b/crypto/aegis128-neon-inner.c new file mode 100644 index 000000000000..c6d90390ac38 --- /dev/null +++ b/crypto/aegis128-neon-inner.c @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2019 Linaro, Ltd. + */ + +#ifdef CONFIG_ARM64 +#include +#else +#include +#endif + +#define AEGIS_BLOCK_SIZE 16 + +#include + +void *memcpy(void *dest, const void *src, size_t n); +void *memset(void *s, int c, size_t n); + +struct aegis128_state { + uint8x16_t v[5]; +}; + +static struct aegis128_state aegis128_update_neon(struct aegis128_state st, + uint8x16_t m) +{ + uint8x16_t z = {}; + uint8x16_t t; + + t = vaesmcq_u8(vaeseq_u8(st.v[3], z)); + st.v[3] ^= vaesmcq_u8(vaeseq_u8(st.v[2], z)); + st.v[2] ^= vaesmcq_u8(vaeseq_u8(st.v[1], z)); + st.v[1] ^= vaesmcq_u8(vaeseq_u8(st.v[0], z)); + st.v[0] ^= vaesmcq_u8(vaeseq_u8(st.v[4], z)) ^ m; + st.v[4] ^= t; + + return st; +} + +void crypto_aegis128_update_neon(void *state, const void *msg) +{ + struct aegis128_state st = { { + vld1q_u8(state), + vld1q_u8(state + 16), + vld1q_u8(state + 32), + vld1q_u8(state + 48), + vld1q_u8(state + 64) + } }; + + st = aegis128_update_neon(st, vld1q_u8(msg)); + + vst1q_u8(state, st.v[0]); + vst1q_u8(state + 16, st.v[1]); + vst1q_u8(state + 32, st.v[2]); + vst1q_u8(state + 48, st.v[3]); + vst1q_u8(state + 64, st.v[4]); +} + +void crypto_aegis128_encrypt_chunk_neon(void *state, void *dst, const void *src, + unsigned int size) +{ + struct aegis128_state st = { { + vld1q_u8(state), + vld1q_u8(state + 16), + vld1q_u8(state + 32), + vld1q_u8(state + 48), + vld1q_u8(state + 64) + } }; + uint8x16_t tmp; + + while (size >= AEGIS_BLOCK_SIZE) { + uint8x16_t s = vld1q_u8(src); + + tmp = s ^ st.v[1] ^ (st.v[2] & st.v[3]) ^ st.v[4]; + st = aegis128_update_neon(st, s); + vst1q_u8(dst, tmp); + + size -= AEGIS_BLOCK_SIZE; + src += AEGIS_BLOCK_SIZE; + dst += AEGIS_BLOCK_SIZE; + } + + if (size > 0) { + uint8_t buf[AEGIS_BLOCK_SIZE] = {}; + uint8x16_t msg; + + memcpy(buf, src, size); + msg = vld1q_u8(buf); + tmp = msg ^ st.v[1] ^ (st.v[2] & st.v[3]) ^ st.v[4]; + st = aegis128_update_neon(st, msg); + vst1q_u8(buf, tmp); + memcpy(dst, buf, size); + } + + vst1q_u8(state, st.v[0]); + vst1q_u8(state + 16, st.v[1]); + vst1q_u8(state + 32, st.v[2]); + vst1q_u8(state + 48, st.v[3]); + vst1q_u8(state + 64, st.v[4]); +} + +void crypto_aegis128_decrypt_chunk_neon(void *state, void *dst, const void *src, + unsigned int size) +{ + struct aegis128_state st = { { + vld1q_u8(state), + vld1q_u8(state + 16), + vld1q_u8(state + 32), + vld1q_u8(state + 48), + vld1q_u8(state + 64) + } }; + uint8x16_t tmp; + + while (size >= AEGIS_BLOCK_SIZE) { + tmp = vld1q_u8(src) ^ st.v[1] ^ (st.v[2] & st.v[3]) ^ st.v[4]; + st = aegis128_update_neon(st, tmp); + vst1q_u8(dst, tmp); + + size -= AEGIS_BLOCK_SIZE; + src += AEGIS_BLOCK_SIZE; + dst += AEGIS_BLOCK_SIZE; + } + + if (size > 0) { + uint8_t buf[AEGIS_BLOCK_SIZE] = {}; + uint8x16_t msg; + + memcpy(buf, src, size); + msg = vld1q_u8(buf) ^ st.v[1] ^ (st.v[2] & st.v[3]) ^ st.v[4]; + vst1q_u8(buf, msg); + memcpy(dst, buf, size); + + memset(buf + size, 0, AEGIS_BLOCK_SIZE - size); + msg = vld1q_u8(buf); + st = aegis128_update_neon(st, msg); + } + + vst1q_u8(state, st.v[0]); + vst1q_u8(state + 16, st.v[1]); + vst1q_u8(state + 32, st.v[2]); + vst1q_u8(state + 48, st.v[3]); + vst1q_u8(state + 64, st.v[4]); +} diff --git a/crypto/aegis128-neon.c b/crypto/aegis128-neon.c new file mode 100644 index 000000000000..c1c0a1686f67 --- /dev/null +++ b/crypto/aegis128-neon.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2019 Linaro Ltd + */ + +#include +#include + +#include "aegis.h" + +void crypto_aegis128_update_neon(void *state, const void *msg); +void crypto_aegis128_encrypt_chunk_neon(void *state, void *dst, const void *src, + unsigned int size); +void crypto_aegis128_decrypt_chunk_neon(void *state, void *dst, const void *src, + unsigned int size); + +bool crypto_aegis128_have_simd(void) +{ + return cpu_have_feature(cpu_feature(AES)); +} + +void crypto_aegis128_update_simd(union aegis_block *state, const void *msg) +{ + kernel_neon_begin(); + crypto_aegis128_update_neon(state, msg); + kernel_neon_end(); +} + +void crypto_aegis128_encrypt_chunk_simd(union aegis_block *state, u8 *dst, + const u8 *src, unsigned int size) +{ + kernel_neon_begin(); + crypto_aegis128_encrypt_chunk_neon(state, dst, src, size); + kernel_neon_end(); +} + +void crypto_aegis128_decrypt_chunk_simd(union aegis_block *state, u8 *dst, + const u8 *src, unsigned int size) +{ + kernel_neon_begin(); + crypto_aegis128_decrypt_chunk_neon(state, dst, src, size); + kernel_neon_end(); +}