crypto: arm64 - move library functions to arch/arm64/lib/crypto/
authorEric Biggers <ebiggers@google.com>
Tue, 22 Apr 2025 15:27:09 +0000 (08:27 -0700)
committerHerbert Xu <herbert@gondor.apana.org.au>
Mon, 28 Apr 2025 11:40:53 +0000 (19:40 +0800)
Continue disentangling the crypto library functions from the generic
crypto infrastructure by moving the arm64 ChaCha and Poly1305 library
functions into a new directory arch/arm64/lib/crypto/ that does not
depend on CRYPTO.  This mirrors the distinction between crypto/ and
lib/crypto/.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
15 files changed:
arch/arm64/crypto/Kconfig
arch/arm64/crypto/Makefile
arch/arm64/crypto/chacha-neon-core.S [deleted file]
arch/arm64/crypto/chacha-neon-glue.c [deleted file]
arch/arm64/crypto/poly1305-armv8.pl [deleted file]
arch/arm64/crypto/poly1305-glue.c [deleted file]
arch/arm64/lib/Makefile
arch/arm64/lib/crypto/.gitignore [new file with mode: 0644]
arch/arm64/lib/crypto/Kconfig [new file with mode: 0644]
arch/arm64/lib/crypto/Makefile [new file with mode: 0644]
arch/arm64/lib/crypto/chacha-neon-core.S [new file with mode: 0644]
arch/arm64/lib/crypto/chacha-neon-glue.c [new file with mode: 0644]
arch/arm64/lib/crypto/poly1305-armv8.pl [new file with mode: 0644]
arch/arm64/lib/crypto/poly1305-glue.c [new file with mode: 0644]
lib/crypto/Kconfig

index 704d0b7e1d13796aa8267ab207f69cb47cd5ff1b..55a7d87a67690649a998e8e14ebe4caa0c03726a 100644 (file)
@@ -25,12 +25,6 @@ config CRYPTO_NHPOLY1305_NEON
          Architecture: arm64 using:
          - NEON (Advanced SIMD) extensions
 
-config CRYPTO_POLY1305_NEON
-       tristate
-       depends on KERNEL_MODE_NEON
-       select CRYPTO_ARCH_HAVE_LIB_POLY1305
-       default CRYPTO_LIB_POLY1305_INTERNAL
-
 config CRYPTO_SHA1_ARM64_CE
        tristate "Hash functions: SHA-1 (ARMv8 Crypto Extensions)"
        depends on KERNEL_MODE_NEON
@@ -180,13 +174,6 @@ config CRYPTO_AES_ARM64_NEON_BLK
          Architecture: arm64 using:
          - NEON (Advanced SIMD) extensions
 
-config CRYPTO_CHACHA20_NEON
-       tristate
-       depends on KERNEL_MODE_NEON
-       select CRYPTO_LIB_CHACHA_GENERIC
-       select CRYPTO_ARCH_HAVE_LIB_CHACHA
-       default CRYPTO_LIB_CHACHA_INTERNAL
-
 config CRYPTO_AES_ARM64_BS
        tristate "Ciphers: AES, modes: ECB/CBC/CTR/XCTR/XTS modes (bit-sliced NEON)"
        depends on KERNEL_MODE_NEON
index e7139c4768ce4e909834bfcaa479f63bcd9a4aa7..089ae3ddde8109875b170cab95d2249f0824f2c9 100644 (file)
@@ -62,13 +62,6 @@ sha256-arm64-y := sha256-glue.o sha256-core.o
 obj-$(CONFIG_CRYPTO_SHA512_ARM64) += sha512-arm64.o
 sha512-arm64-y := sha512-glue.o sha512-core.o
 
-obj-$(CONFIG_CRYPTO_CHACHA20_NEON) += chacha-neon.o
-chacha-neon-y := chacha-neon-core.o chacha-neon-glue.o
-
-obj-$(CONFIG_CRYPTO_POLY1305_NEON) += poly1305-neon.o
-poly1305-neon-y := poly1305-core.o poly1305-glue.o
-AFLAGS_poly1305-core.o += -Dpoly1305_init=poly1305_init_arm64
-
 obj-$(CONFIG_CRYPTO_NHPOLY1305_NEON) += nhpoly1305-neon.o
 nhpoly1305-neon-y := nh-neon-core.o nhpoly1305-neon-glue.o
 
@@ -87,4 +80,4 @@ $(obj)/%-core.S: $(src)/%-armv8.pl
 $(obj)/sha256-core.S: $(src)/sha512-armv8.pl
        $(call cmd,perlasm)
 
-clean-files += poly1305-core.S sha256-core.S sha512-core.S
+clean-files += sha256-core.S sha512-core.S
diff --git a/arch/arm64/crypto/chacha-neon-core.S b/arch/arm64/crypto/chacha-neon-core.S
deleted file mode 100644 (file)
index 8007958..0000000
+++ /dev/null
@@ -1,805 +0,0 @@
-/*
- * ChaCha/HChaCha NEON helper functions
- *
- * Copyright (C) 2016-2018 Linaro, Ltd. <ard.biesheuvel@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Originally based on:
- * ChaCha20 256-bit cipher algorithm, RFC7539, x64 SSSE3 functions
- *
- * Copyright (C) 2015 Martin Willi
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <asm/cache.h>
-
-       .text
-       .align          6
-
-/*
- * chacha_permute - permute one block
- *
- * Permute one 64-byte block where the state matrix is stored in the four NEON
- * registers v0-v3.  It performs matrix operations on four words in parallel,
- * but requires shuffling to rearrange the words after each round.
- *
- * The round count is given in w3.
- *
- * Clobbers: w3, x10, v4, v12
- */
-SYM_FUNC_START_LOCAL(chacha_permute)
-
-       adr_l           x10, ROT8
-       ld1             {v12.4s}, [x10]
-
-.Ldoubleround:
-       // x0 += x1, x3 = rotl32(x3 ^ x0, 16)
-       add             v0.4s, v0.4s, v1.4s
-       eor             v3.16b, v3.16b, v0.16b
-       rev32           v3.8h, v3.8h
-
-       // x2 += x3, x1 = rotl32(x1 ^ x2, 12)
-       add             v2.4s, v2.4s, v3.4s
-       eor             v4.16b, v1.16b, v2.16b
-       shl             v1.4s, v4.4s, #12
-       sri             v1.4s, v4.4s, #20
-
-       // x0 += x1, x3 = rotl32(x3 ^ x0, 8)
-       add             v0.4s, v0.4s, v1.4s
-       eor             v3.16b, v3.16b, v0.16b
-       tbl             v3.16b, {v3.16b}, v12.16b
-
-       // x2 += x3, x1 = rotl32(x1 ^ x2, 7)
-       add             v2.4s, v2.4s, v3.4s
-       eor             v4.16b, v1.16b, v2.16b
-       shl             v1.4s, v4.4s, #7
-       sri             v1.4s, v4.4s, #25
-
-       // x1 = shuffle32(x1, MASK(0, 3, 2, 1))
-       ext             v1.16b, v1.16b, v1.16b, #4
-       // x2 = shuffle32(x2, MASK(1, 0, 3, 2))
-       ext             v2.16b, v2.16b, v2.16b, #8
-       // x3 = shuffle32(x3, MASK(2, 1, 0, 3))
-       ext             v3.16b, v3.16b, v3.16b, #12
-
-       // x0 += x1, x3 = rotl32(x3 ^ x0, 16)
-       add             v0.4s, v0.4s, v1.4s
-       eor             v3.16b, v3.16b, v0.16b
-       rev32           v3.8h, v3.8h
-
-       // x2 += x3, x1 = rotl32(x1 ^ x2, 12)
-       add             v2.4s, v2.4s, v3.4s
-       eor             v4.16b, v1.16b, v2.16b
-       shl             v1.4s, v4.4s, #12
-       sri             v1.4s, v4.4s, #20
-
-       // x0 += x1, x3 = rotl32(x3 ^ x0, 8)
-       add             v0.4s, v0.4s, v1.4s
-       eor             v3.16b, v3.16b, v0.16b
-       tbl             v3.16b, {v3.16b}, v12.16b
-
-       // x2 += x3, x1 = rotl32(x1 ^ x2, 7)
-       add             v2.4s, v2.4s, v3.4s
-       eor             v4.16b, v1.16b, v2.16b
-       shl             v1.4s, v4.4s, #7
-       sri             v1.4s, v4.4s, #25
-
-       // x1 = shuffle32(x1, MASK(2, 1, 0, 3))
-       ext             v1.16b, v1.16b, v1.16b, #12
-       // x2 = shuffle32(x2, MASK(1, 0, 3, 2))
-       ext             v2.16b, v2.16b, v2.16b, #8
-       // x3 = shuffle32(x3, MASK(0, 3, 2, 1))
-       ext             v3.16b, v3.16b, v3.16b, #4
-
-       subs            w3, w3, #2
-       b.ne            .Ldoubleround
-
-       ret
-SYM_FUNC_END(chacha_permute)
-
-SYM_FUNC_START(chacha_block_xor_neon)
-       // x0: Input state matrix, s
-       // x1: 1 data block output, o
-       // x2: 1 data block input, i
-       // w3: nrounds
-
-       stp             x29, x30, [sp, #-16]!
-       mov             x29, sp
-
-       // x0..3 = s0..3
-       ld1             {v0.4s-v3.4s}, [x0]
-       ld1             {v8.4s-v11.4s}, [x0]
-
-       bl              chacha_permute
-
-       ld1             {v4.16b-v7.16b}, [x2]
-
-       // o0 = i0 ^ (x0 + s0)
-       add             v0.4s, v0.4s, v8.4s
-       eor             v0.16b, v0.16b, v4.16b
-
-       // o1 = i1 ^ (x1 + s1)
-       add             v1.4s, v1.4s, v9.4s
-       eor             v1.16b, v1.16b, v5.16b
-
-       // o2 = i2 ^ (x2 + s2)
-       add             v2.4s, v2.4s, v10.4s
-       eor             v2.16b, v2.16b, v6.16b
-
-       // o3 = i3 ^ (x3 + s3)
-       add             v3.4s, v3.4s, v11.4s
-       eor             v3.16b, v3.16b, v7.16b
-
-       st1             {v0.16b-v3.16b}, [x1]
-
-       ldp             x29, x30, [sp], #16
-       ret
-SYM_FUNC_END(chacha_block_xor_neon)
-
-SYM_FUNC_START(hchacha_block_neon)
-       // x0: Input state matrix, s
-       // x1: output (8 32-bit words)
-       // w2: nrounds
-
-       stp             x29, x30, [sp, #-16]!
-       mov             x29, sp
-
-       ld1             {v0.4s-v3.4s}, [x0]
-
-       mov             w3, w2
-       bl              chacha_permute
-
-       st1             {v0.4s}, [x1], #16
-       st1             {v3.4s}, [x1]
-
-       ldp             x29, x30, [sp], #16
-       ret
-SYM_FUNC_END(hchacha_block_neon)
-
-       a0              .req    w12
-       a1              .req    w13
-       a2              .req    w14
-       a3              .req    w15
-       a4              .req    w16
-       a5              .req    w17
-       a6              .req    w19
-       a7              .req    w20
-       a8              .req    w21
-       a9              .req    w22
-       a10             .req    w23
-       a11             .req    w24
-       a12             .req    w25
-       a13             .req    w26
-       a14             .req    w27
-       a15             .req    w28
-
-       .align          6
-SYM_FUNC_START(chacha_4block_xor_neon)
-       frame_push      10
-
-       // x0: Input state matrix, s
-       // x1: 4 data blocks output, o
-       // x2: 4 data blocks input, i
-       // w3: nrounds
-       // x4: byte count
-
-       adr_l           x10, .Lpermute
-       and             x5, x4, #63
-       add             x10, x10, x5
-
-       //
-       // This function encrypts four consecutive ChaCha blocks by loading
-       // the state matrix in NEON registers four times. The algorithm performs
-       // each operation on the corresponding word of each state matrix, hence
-       // requires no word shuffling. For final XORing step we transpose the
-       // matrix by interleaving 32- and then 64-bit words, which allows us to
-       // do XOR in NEON registers.
-       //
-       // At the same time, a fifth block is encrypted in parallel using
-       // scalar registers
-       //
-       adr_l           x9, CTRINC              // ... and ROT8
-       ld1             {v30.4s-v31.4s}, [x9]
-
-       // x0..15[0-3] = s0..3[0..3]
-       add             x8, x0, #16
-       ld4r            { v0.4s- v3.4s}, [x0]
-       ld4r            { v4.4s- v7.4s}, [x8], #16
-       ld4r            { v8.4s-v11.4s}, [x8], #16
-       ld4r            {v12.4s-v15.4s}, [x8]
-
-       mov             a0, v0.s[0]
-       mov             a1, v1.s[0]
-       mov             a2, v2.s[0]
-       mov             a3, v3.s[0]
-       mov             a4, v4.s[0]
-       mov             a5, v5.s[0]
-       mov             a6, v6.s[0]
-       mov             a7, v7.s[0]
-       mov             a8, v8.s[0]
-       mov             a9, v9.s[0]
-       mov             a10, v10.s[0]
-       mov             a11, v11.s[0]
-       mov             a12, v12.s[0]
-       mov             a13, v13.s[0]
-       mov             a14, v14.s[0]
-       mov             a15, v15.s[0]
-
-       // x12 += counter values 1-4
-       add             v12.4s, v12.4s, v30.4s
-
-.Ldoubleround4:
-       // x0 += x4, x12 = rotl32(x12 ^ x0, 16)
-       // x1 += x5, x13 = rotl32(x13 ^ x1, 16)
-       // x2 += x6, x14 = rotl32(x14 ^ x2, 16)
-       // x3 += x7, x15 = rotl32(x15 ^ x3, 16)
-       add             v0.4s, v0.4s, v4.4s
-         add           a0, a0, a4
-       add             v1.4s, v1.4s, v5.4s
-         add           a1, a1, a5
-       add             v2.4s, v2.4s, v6.4s
-         add           a2, a2, a6
-       add             v3.4s, v3.4s, v7.4s
-         add           a3, a3, a7
-
-       eor             v12.16b, v12.16b, v0.16b
-         eor           a12, a12, a0
-       eor             v13.16b, v13.16b, v1.16b
-         eor           a13, a13, a1
-       eor             v14.16b, v14.16b, v2.16b
-         eor           a14, a14, a2
-       eor             v15.16b, v15.16b, v3.16b
-         eor           a15, a15, a3
-
-       rev32           v12.8h, v12.8h
-         ror           a12, a12, #16
-       rev32           v13.8h, v13.8h
-         ror           a13, a13, #16
-       rev32           v14.8h, v14.8h
-         ror           a14, a14, #16
-       rev32           v15.8h, v15.8h
-         ror           a15, a15, #16
-
-       // x8 += x12, x4 = rotl32(x4 ^ x8, 12)
-       // x9 += x13, x5 = rotl32(x5 ^ x9, 12)
-       // x10 += x14, x6 = rotl32(x6 ^ x10, 12)
-       // x11 += x15, x7 = rotl32(x7 ^ x11, 12)
-       add             v8.4s, v8.4s, v12.4s
-         add           a8, a8, a12
-       add             v9.4s, v9.4s, v13.4s
-         add           a9, a9, a13
-       add             v10.4s, v10.4s, v14.4s
-         add           a10, a10, a14
-       add             v11.4s, v11.4s, v15.4s
-         add           a11, a11, a15
-
-       eor             v16.16b, v4.16b, v8.16b
-         eor           a4, a4, a8
-       eor             v17.16b, v5.16b, v9.16b
-         eor           a5, a5, a9
-       eor             v18.16b, v6.16b, v10.16b
-         eor           a6, a6, a10
-       eor             v19.16b, v7.16b, v11.16b
-         eor           a7, a7, a11
-
-       shl             v4.4s, v16.4s, #12
-       shl             v5.4s, v17.4s, #12
-       shl             v6.4s, v18.4s, #12
-       shl             v7.4s, v19.4s, #12
-
-       sri             v4.4s, v16.4s, #20
-         ror           a4, a4, #20
-       sri             v5.4s, v17.4s, #20
-         ror           a5, a5, #20
-       sri             v6.4s, v18.4s, #20
-         ror           a6, a6, #20
-       sri             v7.4s, v19.4s, #20
-         ror           a7, a7, #20
-
-       // x0 += x4, x12 = rotl32(x12 ^ x0, 8)
-       // x1 += x5, x13 = rotl32(x13 ^ x1, 8)
-       // x2 += x6, x14 = rotl32(x14 ^ x2, 8)
-       // x3 += x7, x15 = rotl32(x15 ^ x3, 8)
-       add             v0.4s, v0.4s, v4.4s
-         add           a0, a0, a4
-       add             v1.4s, v1.4s, v5.4s
-         add           a1, a1, a5
-       add             v2.4s, v2.4s, v6.4s
-         add           a2, a2, a6
-       add             v3.4s, v3.4s, v7.4s
-         add           a3, a3, a7
-
-       eor             v12.16b, v12.16b, v0.16b
-         eor           a12, a12, a0
-       eor             v13.16b, v13.16b, v1.16b
-         eor           a13, a13, a1
-       eor             v14.16b, v14.16b, v2.16b
-         eor           a14, a14, a2
-       eor             v15.16b, v15.16b, v3.16b
-         eor           a15, a15, a3
-
-       tbl             v12.16b, {v12.16b}, v31.16b
-         ror           a12, a12, #24
-       tbl             v13.16b, {v13.16b}, v31.16b
-         ror           a13, a13, #24
-       tbl             v14.16b, {v14.16b}, v31.16b
-         ror           a14, a14, #24
-       tbl             v15.16b, {v15.16b}, v31.16b
-         ror           a15, a15, #24
-
-       // x8 += x12, x4 = rotl32(x4 ^ x8, 7)
-       // x9 += x13, x5 = rotl32(x5 ^ x9, 7)
-       // x10 += x14, x6 = rotl32(x6 ^ x10, 7)
-       // x11 += x15, x7 = rotl32(x7 ^ x11, 7)
-       add             v8.4s, v8.4s, v12.4s
-         add           a8, a8, a12
-       add             v9.4s, v9.4s, v13.4s
-         add           a9, a9, a13
-       add             v10.4s, v10.4s, v14.4s
-         add           a10, a10, a14
-       add             v11.4s, v11.4s, v15.4s
-         add           a11, a11, a15
-
-       eor             v16.16b, v4.16b, v8.16b
-         eor           a4, a4, a8
-       eor             v17.16b, v5.16b, v9.16b
-         eor           a5, a5, a9
-       eor             v18.16b, v6.16b, v10.16b
-         eor           a6, a6, a10
-       eor             v19.16b, v7.16b, v11.16b
-         eor           a7, a7, a11
-
-       shl             v4.4s, v16.4s, #7
-       shl             v5.4s, v17.4s, #7
-       shl             v6.4s, v18.4s, #7
-       shl             v7.4s, v19.4s, #7
-
-       sri             v4.4s, v16.4s, #25
-         ror           a4, a4, #25
-       sri             v5.4s, v17.4s, #25
-         ror           a5, a5, #25
-       sri             v6.4s, v18.4s, #25
-        ror            a6, a6, #25
-       sri             v7.4s, v19.4s, #25
-         ror           a7, a7, #25
-
-       // x0 += x5, x15 = rotl32(x15 ^ x0, 16)
-       // x1 += x6, x12 = rotl32(x12 ^ x1, 16)
-       // x2 += x7, x13 = rotl32(x13 ^ x2, 16)
-       // x3 += x4, x14 = rotl32(x14 ^ x3, 16)
-       add             v0.4s, v0.4s, v5.4s
-         add           a0, a0, a5
-       add             v1.4s, v1.4s, v6.4s
-         add           a1, a1, a6
-       add             v2.4s, v2.4s, v7.4s
-         add           a2, a2, a7
-       add             v3.4s, v3.4s, v4.4s
-         add           a3, a3, a4
-
-       eor             v15.16b, v15.16b, v0.16b
-         eor           a15, a15, a0
-       eor             v12.16b, v12.16b, v1.16b
-         eor           a12, a12, a1
-       eor             v13.16b, v13.16b, v2.16b
-         eor           a13, a13, a2
-       eor             v14.16b, v14.16b, v3.16b
-         eor           a14, a14, a3
-
-       rev32           v15.8h, v15.8h
-         ror           a15, a15, #16
-       rev32           v12.8h, v12.8h
-         ror           a12, a12, #16
-       rev32           v13.8h, v13.8h
-         ror           a13, a13, #16
-       rev32           v14.8h, v14.8h
-         ror           a14, a14, #16
-
-       // x10 += x15, x5 = rotl32(x5 ^ x10, 12)
-       // x11 += x12, x6 = rotl32(x6 ^ x11, 12)
-       // x8 += x13, x7 = rotl32(x7 ^ x8, 12)
-       // x9 += x14, x4 = rotl32(x4 ^ x9, 12)
-       add             v10.4s, v10.4s, v15.4s
-         add           a10, a10, a15
-       add             v11.4s, v11.4s, v12.4s
-         add           a11, a11, a12
-       add             v8.4s, v8.4s, v13.4s
-         add           a8, a8, a13
-       add             v9.4s, v9.4s, v14.4s
-         add           a9, a9, a14
-
-       eor             v16.16b, v5.16b, v10.16b
-         eor           a5, a5, a10
-       eor             v17.16b, v6.16b, v11.16b
-         eor           a6, a6, a11
-       eor             v18.16b, v7.16b, v8.16b
-         eor           a7, a7, a8
-       eor             v19.16b, v4.16b, v9.16b
-         eor           a4, a4, a9
-
-       shl             v5.4s, v16.4s, #12
-       shl             v6.4s, v17.4s, #12
-       shl             v7.4s, v18.4s, #12
-       shl             v4.4s, v19.4s, #12
-
-       sri             v5.4s, v16.4s, #20
-         ror           a5, a5, #20
-       sri             v6.4s, v17.4s, #20
-         ror           a6, a6, #20
-       sri             v7.4s, v18.4s, #20
-         ror           a7, a7, #20
-       sri             v4.4s, v19.4s, #20
-         ror           a4, a4, #20
-
-       // x0 += x5, x15 = rotl32(x15 ^ x0, 8)
-       // x1 += x6, x12 = rotl32(x12 ^ x1, 8)
-       // x2 += x7, x13 = rotl32(x13 ^ x2, 8)
-       // x3 += x4, x14 = rotl32(x14 ^ x3, 8)
-       add             v0.4s, v0.4s, v5.4s
-         add           a0, a0, a5
-       add             v1.4s, v1.4s, v6.4s
-         add           a1, a1, a6
-       add             v2.4s, v2.4s, v7.4s
-         add           a2, a2, a7
-       add             v3.4s, v3.4s, v4.4s
-         add           a3, a3, a4
-
-       eor             v15.16b, v15.16b, v0.16b
-         eor           a15, a15, a0
-       eor             v12.16b, v12.16b, v1.16b
-         eor           a12, a12, a1
-       eor             v13.16b, v13.16b, v2.16b
-         eor           a13, a13, a2
-       eor             v14.16b, v14.16b, v3.16b
-         eor           a14, a14, a3
-
-       tbl             v15.16b, {v15.16b}, v31.16b
-         ror           a15, a15, #24
-       tbl             v12.16b, {v12.16b}, v31.16b
-         ror           a12, a12, #24
-       tbl             v13.16b, {v13.16b}, v31.16b
-         ror           a13, a13, #24
-       tbl             v14.16b, {v14.16b}, v31.16b
-         ror           a14, a14, #24
-
-       // x10 += x15, x5 = rotl32(x5 ^ x10, 7)
-       // x11 += x12, x6 = rotl32(x6 ^ x11, 7)
-       // x8 += x13, x7 = rotl32(x7 ^ x8, 7)
-       // x9 += x14, x4 = rotl32(x4 ^ x9, 7)
-       add             v10.4s, v10.4s, v15.4s
-         add           a10, a10, a15
-       add             v11.4s, v11.4s, v12.4s
-         add           a11, a11, a12
-       add             v8.4s, v8.4s, v13.4s
-         add           a8, a8, a13
-       add             v9.4s, v9.4s, v14.4s
-         add           a9, a9, a14
-
-       eor             v16.16b, v5.16b, v10.16b
-         eor           a5, a5, a10
-       eor             v17.16b, v6.16b, v11.16b
-         eor           a6, a6, a11
-       eor             v18.16b, v7.16b, v8.16b
-         eor           a7, a7, a8
-       eor             v19.16b, v4.16b, v9.16b
-         eor           a4, a4, a9
-
-       shl             v5.4s, v16.4s, #7
-       shl             v6.4s, v17.4s, #7
-       shl             v7.4s, v18.4s, #7
-       shl             v4.4s, v19.4s, #7
-
-       sri             v5.4s, v16.4s, #25
-         ror           a5, a5, #25
-       sri             v6.4s, v17.4s, #25
-         ror           a6, a6, #25
-       sri             v7.4s, v18.4s, #25
-         ror           a7, a7, #25
-       sri             v4.4s, v19.4s, #25
-         ror           a4, a4, #25
-
-       subs            w3, w3, #2
-       b.ne            .Ldoubleround4
-
-       ld4r            {v16.4s-v19.4s}, [x0], #16
-       ld4r            {v20.4s-v23.4s}, [x0], #16
-
-       // x12 += counter values 0-3
-       add             v12.4s, v12.4s, v30.4s
-
-       // x0[0-3] += s0[0]
-       // x1[0-3] += s0[1]
-       // x2[0-3] += s0[2]
-       // x3[0-3] += s0[3]
-       add             v0.4s, v0.4s, v16.4s
-         mov           w6, v16.s[0]
-         mov           w7, v17.s[0]
-       add             v1.4s, v1.4s, v17.4s
-         mov           w8, v18.s[0]
-         mov           w9, v19.s[0]
-       add             v2.4s, v2.4s, v18.4s
-         add           a0, a0, w6
-         add           a1, a1, w7
-       add             v3.4s, v3.4s, v19.4s
-         add           a2, a2, w8
-         add           a3, a3, w9
-CPU_BE(          rev           a0, a0          )
-CPU_BE(          rev           a1, a1          )
-CPU_BE(          rev           a2, a2          )
-CPU_BE(          rev           a3, a3          )
-
-       ld4r            {v24.4s-v27.4s}, [x0], #16
-       ld4r            {v28.4s-v31.4s}, [x0]
-
-       // x4[0-3] += s1[0]
-       // x5[0-3] += s1[1]
-       // x6[0-3] += s1[2]
-       // x7[0-3] += s1[3]
-       add             v4.4s, v4.4s, v20.4s
-         mov           w6, v20.s[0]
-         mov           w7, v21.s[0]
-       add             v5.4s, v5.4s, v21.4s
-         mov           w8, v22.s[0]
-         mov           w9, v23.s[0]
-       add             v6.4s, v6.4s, v22.4s
-         add           a4, a4, w6
-         add           a5, a5, w7
-       add             v7.4s, v7.4s, v23.4s
-         add           a6, a6, w8
-         add           a7, a7, w9
-CPU_BE(          rev           a4, a4          )
-CPU_BE(          rev           a5, a5          )
-CPU_BE(          rev           a6, a6          )
-CPU_BE(          rev           a7, a7          )
-
-       // x8[0-3] += s2[0]
-       // x9[0-3] += s2[1]
-       // x10[0-3] += s2[2]
-       // x11[0-3] += s2[3]
-       add             v8.4s, v8.4s, v24.4s
-         mov           w6, v24.s[0]
-         mov           w7, v25.s[0]
-       add             v9.4s, v9.4s, v25.4s
-         mov           w8, v26.s[0]
-         mov           w9, v27.s[0]
-       add             v10.4s, v10.4s, v26.4s
-         add           a8, a8, w6
-         add           a9, a9, w7
-       add             v11.4s, v11.4s, v27.4s
-         add           a10, a10, w8
-         add           a11, a11, w9
-CPU_BE(          rev           a8, a8          )
-CPU_BE(          rev           a9, a9          )
-CPU_BE(          rev           a10, a10        )
-CPU_BE(          rev           a11, a11        )
-
-       // x12[0-3] += s3[0]
-       // x13[0-3] += s3[1]
-       // x14[0-3] += s3[2]
-       // x15[0-3] += s3[3]
-       add             v12.4s, v12.4s, v28.4s
-         mov           w6, v28.s[0]
-         mov           w7, v29.s[0]
-       add             v13.4s, v13.4s, v29.4s
-         mov           w8, v30.s[0]
-         mov           w9, v31.s[0]
-       add             v14.4s, v14.4s, v30.4s
-         add           a12, a12, w6
-         add           a13, a13, w7
-       add             v15.4s, v15.4s, v31.4s
-         add           a14, a14, w8
-         add           a15, a15, w9
-CPU_BE(          rev           a12, a12        )
-CPU_BE(          rev           a13, a13        )
-CPU_BE(          rev           a14, a14        )
-CPU_BE(          rev           a15, a15        )
-
-       // interleave 32-bit words in state n, n+1
-         ldp           w6, w7, [x2], #64
-       zip1            v16.4s, v0.4s, v1.4s
-         ldp           w8, w9, [x2, #-56]
-         eor           a0, a0, w6
-       zip2            v17.4s, v0.4s, v1.4s
-         eor           a1, a1, w7
-       zip1            v18.4s, v2.4s, v3.4s
-         eor           a2, a2, w8
-       zip2            v19.4s, v2.4s, v3.4s
-         eor           a3, a3, w9
-         ldp           w6, w7, [x2, #-48]
-       zip1            v20.4s, v4.4s, v5.4s
-         ldp           w8, w9, [x2, #-40]
-         eor           a4, a4, w6
-       zip2            v21.4s, v4.4s, v5.4s
-         eor           a5, a5, w7
-       zip1            v22.4s, v6.4s, v7.4s
-         eor           a6, a6, w8
-       zip2            v23.4s, v6.4s, v7.4s
-         eor           a7, a7, w9
-         ldp           w6, w7, [x2, #-32]
-       zip1            v24.4s, v8.4s, v9.4s
-         ldp           w8, w9, [x2, #-24]
-         eor           a8, a8, w6
-       zip2            v25.4s, v8.4s, v9.4s
-         eor           a9, a9, w7
-       zip1            v26.4s, v10.4s, v11.4s
-         eor           a10, a10, w8
-       zip2            v27.4s, v10.4s, v11.4s
-         eor           a11, a11, w9
-         ldp           w6, w7, [x2, #-16]
-       zip1            v28.4s, v12.4s, v13.4s
-         ldp           w8, w9, [x2, #-8]
-         eor           a12, a12, w6
-       zip2            v29.4s, v12.4s, v13.4s
-         eor           a13, a13, w7
-       zip1            v30.4s, v14.4s, v15.4s
-         eor           a14, a14, w8
-       zip2            v31.4s, v14.4s, v15.4s
-         eor           a15, a15, w9
-
-       add             x3, x2, x4
-       sub             x3, x3, #128            // start of last block
-
-       subs            x5, x4, #128
-       csel            x2, x2, x3, ge
-
-       // interleave 64-bit words in state n, n+2
-       zip1            v0.2d, v16.2d, v18.2d
-       zip2            v4.2d, v16.2d, v18.2d
-         stp           a0, a1, [x1], #64
-       zip1            v8.2d, v17.2d, v19.2d
-       zip2            v12.2d, v17.2d, v19.2d
-         stp           a2, a3, [x1, #-56]
-
-       subs            x6, x4, #192
-       ld1             {v16.16b-v19.16b}, [x2], #64
-       csel            x2, x2, x3, ge
-
-       zip1            v1.2d, v20.2d, v22.2d
-       zip2            v5.2d, v20.2d, v22.2d
-         stp           a4, a5, [x1, #-48]
-       zip1            v9.2d, v21.2d, v23.2d
-       zip2            v13.2d, v21.2d, v23.2d
-         stp           a6, a7, [x1, #-40]
-
-       subs            x7, x4, #256
-       ld1             {v20.16b-v23.16b}, [x2], #64
-       csel            x2, x2, x3, ge
-
-       zip1            v2.2d, v24.2d, v26.2d
-       zip2            v6.2d, v24.2d, v26.2d
-         stp           a8, a9, [x1, #-32]
-       zip1            v10.2d, v25.2d, v27.2d
-       zip2            v14.2d, v25.2d, v27.2d
-         stp           a10, a11, [x1, #-24]
-
-       subs            x8, x4, #320
-       ld1             {v24.16b-v27.16b}, [x2], #64
-       csel            x2, x2, x3, ge
-
-       zip1            v3.2d, v28.2d, v30.2d
-       zip2            v7.2d, v28.2d, v30.2d
-         stp           a12, a13, [x1, #-16]
-       zip1            v11.2d, v29.2d, v31.2d
-       zip2            v15.2d, v29.2d, v31.2d
-         stp           a14, a15, [x1, #-8]
-
-       tbnz            x5, #63, .Lt128
-       ld1             {v28.16b-v31.16b}, [x2]
-
-       // xor with corresponding input, write to output
-       eor             v16.16b, v16.16b, v0.16b
-       eor             v17.16b, v17.16b, v1.16b
-       eor             v18.16b, v18.16b, v2.16b
-       eor             v19.16b, v19.16b, v3.16b
-
-       tbnz            x6, #63, .Lt192
-
-       eor             v20.16b, v20.16b, v4.16b
-       eor             v21.16b, v21.16b, v5.16b
-       eor             v22.16b, v22.16b, v6.16b
-       eor             v23.16b, v23.16b, v7.16b
-
-       st1             {v16.16b-v19.16b}, [x1], #64
-       tbnz            x7, #63, .Lt256
-
-       eor             v24.16b, v24.16b, v8.16b
-       eor             v25.16b, v25.16b, v9.16b
-       eor             v26.16b, v26.16b, v10.16b
-       eor             v27.16b, v27.16b, v11.16b
-
-       st1             {v20.16b-v23.16b}, [x1], #64
-       tbnz            x8, #63, .Lt320
-
-       eor             v28.16b, v28.16b, v12.16b
-       eor             v29.16b, v29.16b, v13.16b
-       eor             v30.16b, v30.16b, v14.16b
-       eor             v31.16b, v31.16b, v15.16b
-
-       st1             {v24.16b-v27.16b}, [x1], #64
-       st1             {v28.16b-v31.16b}, [x1]
-
-.Lout: frame_pop
-       ret
-
-       // fewer than 192 bytes of in/output
-.Lt192:        cbz             x5, 1f                          // exactly 128 bytes?
-       ld1             {v28.16b-v31.16b}, [x10]
-       add             x5, x5, x1
-       tbl             v28.16b, {v4.16b-v7.16b}, v28.16b
-       tbl             v29.16b, {v4.16b-v7.16b}, v29.16b
-       tbl             v30.16b, {v4.16b-v7.16b}, v30.16b
-       tbl             v31.16b, {v4.16b-v7.16b}, v31.16b
-
-0:     eor             v20.16b, v20.16b, v28.16b
-       eor             v21.16b, v21.16b, v29.16b
-       eor             v22.16b, v22.16b, v30.16b
-       eor             v23.16b, v23.16b, v31.16b
-       st1             {v20.16b-v23.16b}, [x5]         // overlapping stores
-1:     st1             {v16.16b-v19.16b}, [x1]
-       b               .Lout
-
-       // fewer than 128 bytes of in/output
-.Lt128:        ld1             {v28.16b-v31.16b}, [x10]
-       add             x5, x5, x1
-       sub             x1, x1, #64
-       tbl             v28.16b, {v0.16b-v3.16b}, v28.16b
-       tbl             v29.16b, {v0.16b-v3.16b}, v29.16b
-       tbl             v30.16b, {v0.16b-v3.16b}, v30.16b
-       tbl             v31.16b, {v0.16b-v3.16b}, v31.16b
-       ld1             {v16.16b-v19.16b}, [x1]         // reload first output block
-       b               0b
-
-       // fewer than 256 bytes of in/output
-.Lt256:        cbz             x6, 2f                          // exactly 192 bytes?
-       ld1             {v4.16b-v7.16b}, [x10]
-       add             x6, x6, x1
-       tbl             v0.16b, {v8.16b-v11.16b}, v4.16b
-       tbl             v1.16b, {v8.16b-v11.16b}, v5.16b
-       tbl             v2.16b, {v8.16b-v11.16b}, v6.16b
-       tbl             v3.16b, {v8.16b-v11.16b}, v7.16b
-
-       eor             v28.16b, v28.16b, v0.16b
-       eor             v29.16b, v29.16b, v1.16b
-       eor             v30.16b, v30.16b, v2.16b
-       eor             v31.16b, v31.16b, v3.16b
-       st1             {v28.16b-v31.16b}, [x6]         // overlapping stores
-2:     st1             {v20.16b-v23.16b}, [x1]
-       b               .Lout
-
-       // fewer than 320 bytes of in/output
-.Lt320:        cbz             x7, 3f                          // exactly 256 bytes?
-       ld1             {v4.16b-v7.16b}, [x10]
-       add             x7, x7, x1
-       tbl             v0.16b, {v12.16b-v15.16b}, v4.16b
-       tbl             v1.16b, {v12.16b-v15.16b}, v5.16b
-       tbl             v2.16b, {v12.16b-v15.16b}, v6.16b
-       tbl             v3.16b, {v12.16b-v15.16b}, v7.16b
-
-       eor             v28.16b, v28.16b, v0.16b
-       eor             v29.16b, v29.16b, v1.16b
-       eor             v30.16b, v30.16b, v2.16b
-       eor             v31.16b, v31.16b, v3.16b
-       st1             {v28.16b-v31.16b}, [x7]         // overlapping stores
-3:     st1             {v24.16b-v27.16b}, [x1]
-       b               .Lout
-SYM_FUNC_END(chacha_4block_xor_neon)
-
-       .section        ".rodata", "a", %progbits
-       .align          L1_CACHE_SHIFT
-.Lpermute:
-       .set            .Li, 0
-       .rept           128
-       .byte           (.Li - 64)
-       .set            .Li, .Li + 1
-       .endr
-
-CTRINC:        .word           1, 2, 3, 4
-ROT8:  .word           0x02010003, 0x06050407, 0x0a09080b, 0x0e0d0c0f
diff --git a/arch/arm64/crypto/chacha-neon-glue.c b/arch/arm64/crypto/chacha-neon-glue.c
deleted file mode 100644 (file)
index 14a2836..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * ChaCha and HChaCha functions (ARM64 optimized)
- *
- * Copyright (C) 2016 - 2017 Linaro, Ltd. <ard.biesheuvel@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Based on:
- * ChaCha20 256-bit cipher algorithm, RFC7539, SIMD glue code
- *
- * Copyright (C) 2015 Martin Willi
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <crypto/chacha.h>
-#include <crypto/internal/simd.h>
-#include <linux/jump_label.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <asm/hwcap.h>
-#include <asm/neon.h>
-#include <asm/simd.h>
-
-asmlinkage void chacha_block_xor_neon(u32 *state, u8 *dst, const u8 *src,
-                                     int nrounds);
-asmlinkage void chacha_4block_xor_neon(u32 *state, u8 *dst, const u8 *src,
-                                      int nrounds, int bytes);
-asmlinkage void hchacha_block_neon(const u32 *state, u32 *out, int nrounds);
-
-static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_neon);
-
-static void chacha_doneon(u32 *state, u8 *dst, const u8 *src,
-                         int bytes, int nrounds)
-{
-       while (bytes > 0) {
-               int l = min(bytes, CHACHA_BLOCK_SIZE * 5);
-
-               if (l <= CHACHA_BLOCK_SIZE) {
-                       u8 buf[CHACHA_BLOCK_SIZE];
-
-                       memcpy(buf, src, l);
-                       chacha_block_xor_neon(state, buf, buf, nrounds);
-                       memcpy(dst, buf, l);
-                       state[12] += 1;
-                       break;
-               }
-               chacha_4block_xor_neon(state, dst, src, nrounds, l);
-               bytes -= l;
-               src += l;
-               dst += l;
-               state[12] += DIV_ROUND_UP(l, CHACHA_BLOCK_SIZE);
-       }
-}
-
-void hchacha_block_arch(const u32 *state, u32 *stream, int nrounds)
-{
-       if (!static_branch_likely(&have_neon) || !crypto_simd_usable()) {
-               hchacha_block_generic(state, stream, nrounds);
-       } else {
-               kernel_neon_begin();
-               hchacha_block_neon(state, stream, nrounds);
-               kernel_neon_end();
-       }
-}
-EXPORT_SYMBOL(hchacha_block_arch);
-
-void chacha_crypt_arch(u32 *state, u8 *dst, const u8 *src, unsigned int bytes,
-                      int nrounds)
-{
-       if (!static_branch_likely(&have_neon) || bytes <= CHACHA_BLOCK_SIZE ||
-           !crypto_simd_usable())
-               return chacha_crypt_generic(state, dst, src, bytes, nrounds);
-
-       do {
-               unsigned int todo = min_t(unsigned int, bytes, SZ_4K);
-
-               kernel_neon_begin();
-               chacha_doneon(state, dst, src, todo, nrounds);
-               kernel_neon_end();
-
-               bytes -= todo;
-               src += todo;
-               dst += todo;
-       } while (bytes);
-}
-EXPORT_SYMBOL(chacha_crypt_arch);
-
-bool chacha_is_arch_optimized(void)
-{
-       return static_key_enabled(&have_neon);
-}
-EXPORT_SYMBOL(chacha_is_arch_optimized);
-
-static int __init chacha_simd_mod_init(void)
-{
-       if (cpu_have_named_feature(ASIMD))
-               static_branch_enable(&have_neon);
-       return 0;
-}
-arch_initcall(chacha_simd_mod_init);
-
-static void __exit chacha_simd_mod_exit(void)
-{
-}
-module_exit(chacha_simd_mod_exit);
-
-MODULE_DESCRIPTION("ChaCha and HChaCha functions (ARM64 optimized)");
-MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
-MODULE_LICENSE("GPL v2");
diff --git a/arch/arm64/crypto/poly1305-armv8.pl b/arch/arm64/crypto/poly1305-armv8.pl
deleted file mode 100644 (file)
index 22c9069..0000000
+++ /dev/null
@@ -1,917 +0,0 @@
-#!/usr/bin/env perl
-# SPDX-License-Identifier: GPL-1.0+ OR BSD-3-Clause
-#
-# ====================================================================
-# Written by Andy Polyakov, @dot-asm, initially for the OpenSSL
-# project.
-# ====================================================================
-#
-# This module implements Poly1305 hash for ARMv8.
-#
-# June 2015
-#
-# Numbers are cycles per processed byte with poly1305_blocks alone.
-#
-#              IALU/gcc-4.9    NEON
-#
-# Apple A7     1.86/+5%        0.72
-# Cortex-A53   2.69/+58%       1.47
-# Cortex-A57   2.70/+7%        1.14
-# Denver       1.64/+50%       1.18(*)
-# X-Gene       2.13/+68%       2.27
-# Mongoose     1.77/+75%       1.12
-# Kryo         2.70/+55%       1.13
-# ThunderX2    1.17/+95%       1.36
-#
-# (*)  estimate based on resources availability is less than 1.0,
-#      i.e. measured result is worse than expected, presumably binary
-#      translator is not almighty;
-
-$flavour=shift;
-$output=shift;
-
-if ($flavour && $flavour ne "void") {
-    $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-    ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
-    ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
-    die "can't locate arm-xlate.pl";
-
-    open STDOUT,"| \"$^X\" $xlate $flavour $output";
-} else {
-    open STDOUT,">$output";
-}
-
-my ($ctx,$inp,$len,$padbit) = map("x$_",(0..3));
-my ($mac,$nonce)=($inp,$len);
-
-my ($h0,$h1,$h2,$r0,$r1,$s1,$t0,$t1,$d0,$d1,$d2) = map("x$_",(4..14));
-
-$code.=<<___;
-#ifndef __KERNEL__
-# include "arm_arch.h"
-.extern        OPENSSL_armcap_P
-#endif
-
-.text
-
-// forward "declarations" are required for Apple
-.globl poly1305_blocks
-.globl poly1305_emit
-
-.globl poly1305_init
-.type  poly1305_init,%function
-.align 5
-poly1305_init:
-       cmp     $inp,xzr
-       stp     xzr,xzr,[$ctx]          // zero hash value
-       stp     xzr,xzr,[$ctx,#16]      // [along with is_base2_26]
-
-       csel    x0,xzr,x0,eq
-       b.eq    .Lno_key
-
-#ifndef        __KERNEL__
-       adrp    x17,OPENSSL_armcap_P
-       ldr     w17,[x17,#:lo12:OPENSSL_armcap_P]
-#endif
-
-       ldp     $r0,$r1,[$inp]          // load key
-       mov     $s1,#0xfffffffc0fffffff
-       movk    $s1,#0x0fff,lsl#48
-#ifdef __AARCH64EB__
-       rev     $r0,$r0                 // flip bytes
-       rev     $r1,$r1
-#endif
-       and     $r0,$r0,$s1             // &=0ffffffc0fffffff
-       and     $s1,$s1,#-4
-       and     $r1,$r1,$s1             // &=0ffffffc0ffffffc
-       mov     w#$s1,#-1
-       stp     $r0,$r1,[$ctx,#32]      // save key value
-       str     w#$s1,[$ctx,#48]        // impossible key power value
-
-#ifndef        __KERNEL__
-       tst     w17,#ARMV7_NEON
-
-       adr     $d0,.Lpoly1305_blocks
-       adr     $r0,.Lpoly1305_blocks_neon
-       adr     $d1,.Lpoly1305_emit
-
-       csel    $d0,$d0,$r0,eq
-
-# ifdef        __ILP32__
-       stp     w#$d0,w#$d1,[$len]
-# else
-       stp     $d0,$d1,[$len]
-# endif
-#endif
-       mov     x0,#1
-.Lno_key:
-       ret
-.size  poly1305_init,.-poly1305_init
-
-.type  poly1305_blocks,%function
-.align 5
-poly1305_blocks:
-.Lpoly1305_blocks:
-       ands    $len,$len,#-16
-       b.eq    .Lno_data
-
-       ldp     $h0,$h1,[$ctx]          // load hash value
-       ldp     $h2,x17,[$ctx,#16]      // [along with is_base2_26]
-       ldp     $r0,$r1,[$ctx,#32]      // load key value
-
-#ifdef __AARCH64EB__
-       lsr     $d0,$h0,#32
-       mov     w#$d1,w#$h0
-       lsr     $d2,$h1,#32
-       mov     w15,w#$h1
-       lsr     x16,$h2,#32
-#else
-       mov     w#$d0,w#$h0
-       lsr     $d1,$h0,#32
-       mov     w#$d2,w#$h1
-       lsr     x15,$h1,#32
-       mov     w16,w#$h2
-#endif
-
-       add     $d0,$d0,$d1,lsl#26      // base 2^26 -> base 2^64
-       lsr     $d1,$d2,#12
-       adds    $d0,$d0,$d2,lsl#52
-       add     $d1,$d1,x15,lsl#14
-       adc     $d1,$d1,xzr
-       lsr     $d2,x16,#24
-       adds    $d1,$d1,x16,lsl#40
-       adc     $d2,$d2,xzr
-
-       cmp     x17,#0                  // is_base2_26?
-       add     $s1,$r1,$r1,lsr#2       // s1 = r1 + (r1 >> 2)
-       csel    $h0,$h0,$d0,eq          // choose between radixes
-       csel    $h1,$h1,$d1,eq
-       csel    $h2,$h2,$d2,eq
-
-.Loop:
-       ldp     $t0,$t1,[$inp],#16      // load input
-       sub     $len,$len,#16
-#ifdef __AARCH64EB__
-       rev     $t0,$t0
-       rev     $t1,$t1
-#endif
-       adds    $h0,$h0,$t0             // accumulate input
-       adcs    $h1,$h1,$t1
-
-       mul     $d0,$h0,$r0             // h0*r0
-       adc     $h2,$h2,$padbit
-       umulh   $d1,$h0,$r0
-
-       mul     $t0,$h1,$s1             // h1*5*r1
-       umulh   $t1,$h1,$s1
-
-       adds    $d0,$d0,$t0
-       mul     $t0,$h0,$r1             // h0*r1
-       adc     $d1,$d1,$t1
-       umulh   $d2,$h0,$r1
-
-       adds    $d1,$d1,$t0
-       mul     $t0,$h1,$r0             // h1*r0
-       adc     $d2,$d2,xzr
-       umulh   $t1,$h1,$r0
-
-       adds    $d1,$d1,$t0
-       mul     $t0,$h2,$s1             // h2*5*r1
-       adc     $d2,$d2,$t1
-       mul     $t1,$h2,$r0             // h2*r0
-
-       adds    $d1,$d1,$t0
-       adc     $d2,$d2,$t1
-
-       and     $t0,$d2,#-4             // final reduction
-       and     $h2,$d2,#3
-       add     $t0,$t0,$d2,lsr#2
-       adds    $h0,$d0,$t0
-       adcs    $h1,$d1,xzr
-       adc     $h2,$h2,xzr
-
-       cbnz    $len,.Loop
-
-       stp     $h0,$h1,[$ctx]          // store hash value
-       stp     $h2,xzr,[$ctx,#16]      // [and clear is_base2_26]
-
-.Lno_data:
-       ret
-.size  poly1305_blocks,.-poly1305_blocks
-
-.type  poly1305_emit,%function
-.align 5
-poly1305_emit:
-.Lpoly1305_emit:
-       ldp     $h0,$h1,[$ctx]          // load hash base 2^64
-       ldp     $h2,$r0,[$ctx,#16]      // [along with is_base2_26]
-       ldp     $t0,$t1,[$nonce]        // load nonce
-
-#ifdef __AARCH64EB__
-       lsr     $d0,$h0,#32
-       mov     w#$d1,w#$h0
-       lsr     $d2,$h1,#32
-       mov     w15,w#$h1
-       lsr     x16,$h2,#32
-#else
-       mov     w#$d0,w#$h0
-       lsr     $d1,$h0,#32
-       mov     w#$d2,w#$h1
-       lsr     x15,$h1,#32
-       mov     w16,w#$h2
-#endif
-
-       add     $d0,$d0,$d1,lsl#26      // base 2^26 -> base 2^64
-       lsr     $d1,$d2,#12
-       adds    $d0,$d0,$d2,lsl#52
-       add     $d1,$d1,x15,lsl#14
-       adc     $d1,$d1,xzr
-       lsr     $d2,x16,#24
-       adds    $d1,$d1,x16,lsl#40
-       adc     $d2,$d2,xzr
-
-       cmp     $r0,#0                  // is_base2_26?
-       csel    $h0,$h0,$d0,eq          // choose between radixes
-       csel    $h1,$h1,$d1,eq
-       csel    $h2,$h2,$d2,eq
-
-       adds    $d0,$h0,#5              // compare to modulus
-       adcs    $d1,$h1,xzr
-       adc     $d2,$h2,xzr
-
-       tst     $d2,#-4                 // see if it's carried/borrowed
-
-       csel    $h0,$h0,$d0,eq
-       csel    $h1,$h1,$d1,eq
-
-#ifdef __AARCH64EB__
-       ror     $t0,$t0,#32             // flip nonce words
-       ror     $t1,$t1,#32
-#endif
-       adds    $h0,$h0,$t0             // accumulate nonce
-       adc     $h1,$h1,$t1
-#ifdef __AARCH64EB__
-       rev     $h0,$h0                 // flip output bytes
-       rev     $h1,$h1
-#endif
-       stp     $h0,$h1,[$mac]          // write result
-
-       ret
-.size  poly1305_emit,.-poly1305_emit
-___
-my ($R0,$R1,$S1,$R2,$S2,$R3,$S3,$R4,$S4) = map("v$_.4s",(0..8));
-my ($IN01_0,$IN01_1,$IN01_2,$IN01_3,$IN01_4) = map("v$_.2s",(9..13));
-my ($IN23_0,$IN23_1,$IN23_2,$IN23_3,$IN23_4) = map("v$_.2s",(14..18));
-my ($ACC0,$ACC1,$ACC2,$ACC3,$ACC4) = map("v$_.2d",(19..23));
-my ($H0,$H1,$H2,$H3,$H4) = map("v$_.2s",(24..28));
-my ($T0,$T1,$MASK) = map("v$_",(29..31));
-
-my ($in2,$zeros)=("x16","x17");
-my $is_base2_26 = $zeros;              # borrow
-
-$code.=<<___;
-.type  poly1305_mult,%function
-.align 5
-poly1305_mult:
-       mul     $d0,$h0,$r0             // h0*r0
-       umulh   $d1,$h0,$r0
-
-       mul     $t0,$h1,$s1             // h1*5*r1
-       umulh   $t1,$h1,$s1
-
-       adds    $d0,$d0,$t0
-       mul     $t0,$h0,$r1             // h0*r1
-       adc     $d1,$d1,$t1
-       umulh   $d2,$h0,$r1
-
-       adds    $d1,$d1,$t0
-       mul     $t0,$h1,$r0             // h1*r0
-       adc     $d2,$d2,xzr
-       umulh   $t1,$h1,$r0
-
-       adds    $d1,$d1,$t0
-       mul     $t0,$h2,$s1             // h2*5*r1
-       adc     $d2,$d2,$t1
-       mul     $t1,$h2,$r0             // h2*r0
-
-       adds    $d1,$d1,$t0
-       adc     $d2,$d2,$t1
-
-       and     $t0,$d2,#-4             // final reduction
-       and     $h2,$d2,#3
-       add     $t0,$t0,$d2,lsr#2
-       adds    $h0,$d0,$t0
-       adcs    $h1,$d1,xzr
-       adc     $h2,$h2,xzr
-
-       ret
-.size  poly1305_mult,.-poly1305_mult
-
-.type  poly1305_splat,%function
-.align 4
-poly1305_splat:
-       and     x12,$h0,#0x03ffffff     // base 2^64 -> base 2^26
-       ubfx    x13,$h0,#26,#26
-       extr    x14,$h1,$h0,#52
-       and     x14,x14,#0x03ffffff
-       ubfx    x15,$h1,#14,#26
-       extr    x16,$h2,$h1,#40
-
-       str     w12,[$ctx,#16*0]        // r0
-       add     w12,w13,w13,lsl#2       // r1*5
-       str     w13,[$ctx,#16*1]        // r1
-       add     w13,w14,w14,lsl#2       // r2*5
-       str     w12,[$ctx,#16*2]        // s1
-       str     w14,[$ctx,#16*3]        // r2
-       add     w14,w15,w15,lsl#2       // r3*5
-       str     w13,[$ctx,#16*4]        // s2
-       str     w15,[$ctx,#16*5]        // r3
-       add     w15,w16,w16,lsl#2       // r4*5
-       str     w14,[$ctx,#16*6]        // s3
-       str     w16,[$ctx,#16*7]        // r4
-       str     w15,[$ctx,#16*8]        // s4
-
-       ret
-.size  poly1305_splat,.-poly1305_splat
-
-#ifdef __KERNEL__
-.globl poly1305_blocks_neon
-#endif
-.type  poly1305_blocks_neon,%function
-.align 5
-poly1305_blocks_neon:
-.Lpoly1305_blocks_neon:
-       ldr     $is_base2_26,[$ctx,#24]
-       cmp     $len,#128
-       b.lo    .Lpoly1305_blocks
-
-       .inst   0xd503233f              // paciasp
-       stp     x29,x30,[sp,#-80]!
-       add     x29,sp,#0
-
-       stp     d8,d9,[sp,#16]          // meet ABI requirements
-       stp     d10,d11,[sp,#32]
-       stp     d12,d13,[sp,#48]
-       stp     d14,d15,[sp,#64]
-
-       cbz     $is_base2_26,.Lbase2_64_neon
-
-       ldp     w10,w11,[$ctx]          // load hash value base 2^26
-       ldp     w12,w13,[$ctx,#8]
-       ldr     w14,[$ctx,#16]
-
-       tst     $len,#31
-       b.eq    .Leven_neon
-
-       ldp     $r0,$r1,[$ctx,#32]      // load key value
-
-       add     $h0,x10,x11,lsl#26      // base 2^26 -> base 2^64
-       lsr     $h1,x12,#12
-       adds    $h0,$h0,x12,lsl#52
-       add     $h1,$h1,x13,lsl#14
-       adc     $h1,$h1,xzr
-       lsr     $h2,x14,#24
-       adds    $h1,$h1,x14,lsl#40
-       adc     $d2,$h2,xzr             // can be partially reduced...
-
-       ldp     $d0,$d1,[$inp],#16      // load input
-       sub     $len,$len,#16
-       add     $s1,$r1,$r1,lsr#2       // s1 = r1 + (r1 >> 2)
-
-#ifdef __AARCH64EB__
-       rev     $d0,$d0
-       rev     $d1,$d1
-#endif
-       adds    $h0,$h0,$d0             // accumulate input
-       adcs    $h1,$h1,$d1
-       adc     $h2,$h2,$padbit
-
-       bl      poly1305_mult
-
-       and     x10,$h0,#0x03ffffff     // base 2^64 -> base 2^26
-       ubfx    x11,$h0,#26,#26
-       extr    x12,$h1,$h0,#52
-       and     x12,x12,#0x03ffffff
-       ubfx    x13,$h1,#14,#26
-       extr    x14,$h2,$h1,#40
-
-       b       .Leven_neon
-
-.align 4
-.Lbase2_64_neon:
-       ldp     $r0,$r1,[$ctx,#32]      // load key value
-
-       ldp     $h0,$h1,[$ctx]          // load hash value base 2^64
-       ldr     $h2,[$ctx,#16]
-
-       tst     $len,#31
-       b.eq    .Linit_neon
-
-       ldp     $d0,$d1,[$inp],#16      // load input
-       sub     $len,$len,#16
-       add     $s1,$r1,$r1,lsr#2       // s1 = r1 + (r1 >> 2)
-#ifdef __AARCH64EB__
-       rev     $d0,$d0
-       rev     $d1,$d1
-#endif
-       adds    $h0,$h0,$d0             // accumulate input
-       adcs    $h1,$h1,$d1
-       adc     $h2,$h2,$padbit
-
-       bl      poly1305_mult
-
-.Linit_neon:
-       ldr     w17,[$ctx,#48]          // first table element
-       and     x10,$h0,#0x03ffffff     // base 2^64 -> base 2^26
-       ubfx    x11,$h0,#26,#26
-       extr    x12,$h1,$h0,#52
-       and     x12,x12,#0x03ffffff
-       ubfx    x13,$h1,#14,#26
-       extr    x14,$h2,$h1,#40
-
-       cmp     w17,#-1                 // is value impossible?
-       b.ne    .Leven_neon
-
-       fmov    ${H0},x10
-       fmov    ${H1},x11
-       fmov    ${H2},x12
-       fmov    ${H3},x13
-       fmov    ${H4},x14
-
-       ////////////////////////////////// initialize r^n table
-       mov     $h0,$r0                 // r^1
-       add     $s1,$r1,$r1,lsr#2       // s1 = r1 + (r1 >> 2)
-       mov     $h1,$r1
-       mov     $h2,xzr
-       add     $ctx,$ctx,#48+12
-       bl      poly1305_splat
-
-       bl      poly1305_mult           // r^2
-       sub     $ctx,$ctx,#4
-       bl      poly1305_splat
-
-       bl      poly1305_mult           // r^3
-       sub     $ctx,$ctx,#4
-       bl      poly1305_splat
-
-       bl      poly1305_mult           // r^4
-       sub     $ctx,$ctx,#4
-       bl      poly1305_splat
-       sub     $ctx,$ctx,#48           // restore original $ctx
-       b       .Ldo_neon
-
-.align 4
-.Leven_neon:
-       fmov    ${H0},x10
-       fmov    ${H1},x11
-       fmov    ${H2},x12
-       fmov    ${H3},x13
-       fmov    ${H4},x14
-
-.Ldo_neon:
-       ldp     x8,x12,[$inp,#32]       // inp[2:3]
-       subs    $len,$len,#64
-       ldp     x9,x13,[$inp,#48]
-       add     $in2,$inp,#96
-       adrp    $zeros,.Lzeros
-       add     $zeros,$zeros,#:lo12:.Lzeros
-
-       lsl     $padbit,$padbit,#24
-       add     x15,$ctx,#48
-
-#ifdef __AARCH64EB__
-       rev     x8,x8
-       rev     x12,x12
-       rev     x9,x9
-       rev     x13,x13
-#endif
-       and     x4,x8,#0x03ffffff       // base 2^64 -> base 2^26
-       and     x5,x9,#0x03ffffff
-       ubfx    x6,x8,#26,#26
-       ubfx    x7,x9,#26,#26
-       add     x4,x4,x5,lsl#32         // bfi  x4,x5,#32,#32
-       extr    x8,x12,x8,#52
-       extr    x9,x13,x9,#52
-       add     x6,x6,x7,lsl#32         // bfi  x6,x7,#32,#32
-       fmov    $IN23_0,x4
-       and     x8,x8,#0x03ffffff
-       and     x9,x9,#0x03ffffff
-       ubfx    x10,x12,#14,#26
-       ubfx    x11,x13,#14,#26
-       add     x12,$padbit,x12,lsr#40
-       add     x13,$padbit,x13,lsr#40
-       add     x8,x8,x9,lsl#32         // bfi  x8,x9,#32,#32
-       fmov    $IN23_1,x6
-       add     x10,x10,x11,lsl#32      // bfi  x10,x11,#32,#32
-       add     x12,x12,x13,lsl#32      // bfi  x12,x13,#32,#32
-       fmov    $IN23_2,x8
-       fmov    $IN23_3,x10
-       fmov    $IN23_4,x12
-
-       ldp     x8,x12,[$inp],#16       // inp[0:1]
-       ldp     x9,x13,[$inp],#48
-
-       ld1     {$R0,$R1,$S1,$R2},[x15],#64
-       ld1     {$S2,$R3,$S3,$R4},[x15],#64
-       ld1     {$S4},[x15]
-
-#ifdef __AARCH64EB__
-       rev     x8,x8
-       rev     x12,x12
-       rev     x9,x9
-       rev     x13,x13
-#endif
-       and     x4,x8,#0x03ffffff       // base 2^64 -> base 2^26
-       and     x5,x9,#0x03ffffff
-       ubfx    x6,x8,#26,#26
-       ubfx    x7,x9,#26,#26
-       add     x4,x4,x5,lsl#32         // bfi  x4,x5,#32,#32
-       extr    x8,x12,x8,#52
-       extr    x9,x13,x9,#52
-       add     x6,x6,x7,lsl#32         // bfi  x6,x7,#32,#32
-       fmov    $IN01_0,x4
-       and     x8,x8,#0x03ffffff
-       and     x9,x9,#0x03ffffff
-       ubfx    x10,x12,#14,#26
-       ubfx    x11,x13,#14,#26
-       add     x12,$padbit,x12,lsr#40
-       add     x13,$padbit,x13,lsr#40
-       add     x8,x8,x9,lsl#32         // bfi  x8,x9,#32,#32
-       fmov    $IN01_1,x6
-       add     x10,x10,x11,lsl#32      // bfi  x10,x11,#32,#32
-       add     x12,x12,x13,lsl#32      // bfi  x12,x13,#32,#32
-       movi    $MASK.2d,#-1
-       fmov    $IN01_2,x8
-       fmov    $IN01_3,x10
-       fmov    $IN01_4,x12
-       ushr    $MASK.2d,$MASK.2d,#38
-
-       b.ls    .Lskip_loop
-
-.align 4
-.Loop_neon:
-       ////////////////////////////////////////////////////////////////
-       // ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2
-       // ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r
-       //   \___________________/
-       // ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2
-       // ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r
-       //   \___________________/ \____________________/
-       //
-       // Note that we start with inp[2:3]*r^2. This is because it
-       // doesn't depend on reduction in previous iteration.
-       ////////////////////////////////////////////////////////////////
-       // d4 = h0*r4 + h1*r3   + h2*r2   + h3*r1   + h4*r0
-       // d3 = h0*r3 + h1*r2   + h2*r1   + h3*r0   + h4*5*r4
-       // d2 = h0*r2 + h1*r1   + h2*r0   + h3*5*r4 + h4*5*r3
-       // d1 = h0*r1 + h1*r0   + h2*5*r4 + h3*5*r3 + h4*5*r2
-       // d0 = h0*r0 + h1*5*r4 + h2*5*r3 + h3*5*r2 + h4*5*r1
-
-       subs    $len,$len,#64
-       umull   $ACC4,$IN23_0,${R4}[2]
-       csel    $in2,$zeros,$in2,lo
-       umull   $ACC3,$IN23_0,${R3}[2]
-       umull   $ACC2,$IN23_0,${R2}[2]
-        ldp    x8,x12,[$in2],#16       // inp[2:3] (or zero)
-       umull   $ACC1,$IN23_0,${R1}[2]
-        ldp    x9,x13,[$in2],#48
-       umull   $ACC0,$IN23_0,${R0}[2]
-#ifdef __AARCH64EB__
-        rev    x8,x8
-        rev    x12,x12
-        rev    x9,x9
-        rev    x13,x13
-#endif
-
-       umlal   $ACC4,$IN23_1,${R3}[2]
-        and    x4,x8,#0x03ffffff       // base 2^64 -> base 2^26
-       umlal   $ACC3,$IN23_1,${R2}[2]
-        and    x5,x9,#0x03ffffff
-       umlal   $ACC2,$IN23_1,${R1}[2]
-        ubfx   x6,x8,#26,#26
-       umlal   $ACC1,$IN23_1,${R0}[2]
-        ubfx   x7,x9,#26,#26
-       umlal   $ACC0,$IN23_1,${S4}[2]
-        add    x4,x4,x5,lsl#32         // bfi  x4,x5,#32,#32
-
-       umlal   $ACC4,$IN23_2,${R2}[2]
-        extr   x8,x12,x8,#52
-       umlal   $ACC3,$IN23_2,${R1}[2]
-        extr   x9,x13,x9,#52
-       umlal   $ACC2,$IN23_2,${R0}[2]
-        add    x6,x6,x7,lsl#32         // bfi  x6,x7,#32,#32
-       umlal   $ACC1,$IN23_2,${S4}[2]
-        fmov   $IN23_0,x4
-       umlal   $ACC0,$IN23_2,${S3}[2]
-        and    x8,x8,#0x03ffffff
-
-       umlal   $ACC4,$IN23_3,${R1}[2]
-        and    x9,x9,#0x03ffffff
-       umlal   $ACC3,$IN23_3,${R0}[2]
-        ubfx   x10,x12,#14,#26
-       umlal   $ACC2,$IN23_3,${S4}[2]
-        ubfx   x11,x13,#14,#26
-       umlal   $ACC1,$IN23_3,${S3}[2]
-        add    x8,x8,x9,lsl#32         // bfi  x8,x9,#32,#32
-       umlal   $ACC0,$IN23_3,${S2}[2]
-        fmov   $IN23_1,x6
-
-       add     $IN01_2,$IN01_2,$H2
-        add    x12,$padbit,x12,lsr#40
-       umlal   $ACC4,$IN23_4,${R0}[2]
-        add    x13,$padbit,x13,lsr#40
-       umlal   $ACC3,$IN23_4,${S4}[2]
-        add    x10,x10,x11,lsl#32      // bfi  x10,x11,#32,#32
-       umlal   $ACC2,$IN23_4,${S3}[2]
-        add    x12,x12,x13,lsl#32      // bfi  x12,x13,#32,#32
-       umlal   $ACC1,$IN23_4,${S2}[2]
-        fmov   $IN23_2,x8
-       umlal   $ACC0,$IN23_4,${S1}[2]
-        fmov   $IN23_3,x10
-
-       ////////////////////////////////////////////////////////////////
-       // (hash+inp[0:1])*r^4 and accumulate
-
-       add     $IN01_0,$IN01_0,$H0
-        fmov   $IN23_4,x12
-       umlal   $ACC3,$IN01_2,${R1}[0]
-        ldp    x8,x12,[$inp],#16       // inp[0:1]
-       umlal   $ACC0,$IN01_2,${S3}[0]
-        ldp    x9,x13,[$inp],#48
-       umlal   $ACC4,$IN01_2,${R2}[0]
-       umlal   $ACC1,$IN01_2,${S4}[0]
-       umlal   $ACC2,$IN01_2,${R0}[0]
-#ifdef __AARCH64EB__
-        rev    x8,x8
-        rev    x12,x12
-        rev    x9,x9
-        rev    x13,x13
-#endif
-
-       add     $IN01_1,$IN01_1,$H1
-       umlal   $ACC3,$IN01_0,${R3}[0]
-       umlal   $ACC4,$IN01_0,${R4}[0]
-        and    x4,x8,#0x03ffffff       // base 2^64 -> base 2^26
-       umlal   $ACC2,$IN01_0,${R2}[0]
-        and    x5,x9,#0x03ffffff
-       umlal   $ACC0,$IN01_0,${R0}[0]
-        ubfx   x6,x8,#26,#26
-       umlal   $ACC1,$IN01_0,${R1}[0]
-        ubfx   x7,x9,#26,#26
-
-       add     $IN01_3,$IN01_3,$H3
-        add    x4,x4,x5,lsl#32         // bfi  x4,x5,#32,#32
-       umlal   $ACC3,$IN01_1,${R2}[0]
-        extr   x8,x12,x8,#52
-       umlal   $ACC4,$IN01_1,${R3}[0]
-        extr   x9,x13,x9,#52
-       umlal   $ACC0,$IN01_1,${S4}[0]
-        add    x6,x6,x7,lsl#32         // bfi  x6,x7,#32,#32
-       umlal   $ACC2,$IN01_1,${R1}[0]
-        fmov   $IN01_0,x4
-       umlal   $ACC1,$IN01_1,${R0}[0]
-        and    x8,x8,#0x03ffffff
-
-       add     $IN01_4,$IN01_4,$H4
-        and    x9,x9,#0x03ffffff
-       umlal   $ACC3,$IN01_3,${R0}[0]
-        ubfx   x10,x12,#14,#26
-       umlal   $ACC0,$IN01_3,${S2}[0]
-        ubfx   x11,x13,#14,#26
-       umlal   $ACC4,$IN01_3,${R1}[0]
-        add    x8,x8,x9,lsl#32         // bfi  x8,x9,#32,#32
-       umlal   $ACC1,$IN01_3,${S3}[0]
-        fmov   $IN01_1,x6
-       umlal   $ACC2,$IN01_3,${S4}[0]
-        add    x12,$padbit,x12,lsr#40
-
-       umlal   $ACC3,$IN01_4,${S4}[0]
-        add    x13,$padbit,x13,lsr#40
-       umlal   $ACC0,$IN01_4,${S1}[0]
-        add    x10,x10,x11,lsl#32      // bfi  x10,x11,#32,#32
-       umlal   $ACC4,$IN01_4,${R0}[0]
-        add    x12,x12,x13,lsl#32      // bfi  x12,x13,#32,#32
-       umlal   $ACC1,$IN01_4,${S2}[0]
-        fmov   $IN01_2,x8
-       umlal   $ACC2,$IN01_4,${S3}[0]
-        fmov   $IN01_3,x10
-        fmov   $IN01_4,x12
-
-       /////////////////////////////////////////////////////////////////
-       // lazy reduction as discussed in "NEON crypto" by D.J. Bernstein
-       // and P. Schwabe
-       //
-       // [see discussion in poly1305-armv4 module]
-
-       ushr    $T0.2d,$ACC3,#26
-       xtn     $H3,$ACC3
-        ushr   $T1.2d,$ACC0,#26
-        and    $ACC0,$ACC0,$MASK.2d
-       add     $ACC4,$ACC4,$T0.2d      // h3 -> h4
-       bic     $H3,#0xfc,lsl#24        // &=0x03ffffff
-        add    $ACC1,$ACC1,$T1.2d      // h0 -> h1
-
-       ushr    $T0.2d,$ACC4,#26
-       xtn     $H4,$ACC4
-        ushr   $T1.2d,$ACC1,#26
-        xtn    $H1,$ACC1
-       bic     $H4,#0xfc,lsl#24
-        add    $ACC2,$ACC2,$T1.2d      // h1 -> h2
-
-       add     $ACC0,$ACC0,$T0.2d
-       shl     $T0.2d,$T0.2d,#2
-        shrn   $T1.2s,$ACC2,#26
-        xtn    $H2,$ACC2
-       add     $ACC0,$ACC0,$T0.2d      // h4 -> h0
-        bic    $H1,#0xfc,lsl#24
-        add    $H3,$H3,$T1.2s          // h2 -> h3
-        bic    $H2,#0xfc,lsl#24
-
-       shrn    $T0.2s,$ACC0,#26
-       xtn     $H0,$ACC0
-        ushr   $T1.2s,$H3,#26
-        bic    $H3,#0xfc,lsl#24
-        bic    $H0,#0xfc,lsl#24
-       add     $H1,$H1,$T0.2s          // h0 -> h1
-        add    $H4,$H4,$T1.2s          // h3 -> h4
-
-       b.hi    .Loop_neon
-
-.Lskip_loop:
-       dup     $IN23_2,${IN23_2}[0]
-       add     $IN01_2,$IN01_2,$H2
-
-       ////////////////////////////////////////////////////////////////
-       // multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1
-
-       adds    $len,$len,#32
-       b.ne    .Long_tail
-
-       dup     $IN23_2,${IN01_2}[0]
-       add     $IN23_0,$IN01_0,$H0
-       add     $IN23_3,$IN01_3,$H3
-       add     $IN23_1,$IN01_1,$H1
-       add     $IN23_4,$IN01_4,$H4
-
-.Long_tail:
-       dup     $IN23_0,${IN23_0}[0]
-       umull2  $ACC0,$IN23_2,${S3}
-       umull2  $ACC3,$IN23_2,${R1}
-       umull2  $ACC4,$IN23_2,${R2}
-       umull2  $ACC2,$IN23_2,${R0}
-       umull2  $ACC1,$IN23_2,${S4}
-
-       dup     $IN23_1,${IN23_1}[0]
-       umlal2  $ACC0,$IN23_0,${R0}
-       umlal2  $ACC2,$IN23_0,${R2}
-       umlal2  $ACC3,$IN23_0,${R3}
-       umlal2  $ACC4,$IN23_0,${R4}
-       umlal2  $ACC1,$IN23_0,${R1}
-
-       dup     $IN23_3,${IN23_3}[0]
-       umlal2  $ACC0,$IN23_1,${S4}
-       umlal2  $ACC3,$IN23_1,${R2}
-       umlal2  $ACC2,$IN23_1,${R1}
-       umlal2  $ACC4,$IN23_1,${R3}
-       umlal2  $ACC1,$IN23_1,${R0}
-
-       dup     $IN23_4,${IN23_4}[0]
-       umlal2  $ACC3,$IN23_3,${R0}
-       umlal2  $ACC4,$IN23_3,${R1}
-       umlal2  $ACC0,$IN23_3,${S2}
-       umlal2  $ACC1,$IN23_3,${S3}
-       umlal2  $ACC2,$IN23_3,${S4}
-
-       umlal2  $ACC3,$IN23_4,${S4}
-       umlal2  $ACC0,$IN23_4,${S1}
-       umlal2  $ACC4,$IN23_4,${R0}
-       umlal2  $ACC1,$IN23_4,${S2}
-       umlal2  $ACC2,$IN23_4,${S3}
-
-       b.eq    .Lshort_tail
-
-       ////////////////////////////////////////////////////////////////
-       // (hash+inp[0:1])*r^4:r^3 and accumulate
-
-       add     $IN01_0,$IN01_0,$H0
-       umlal   $ACC3,$IN01_2,${R1}
-       umlal   $ACC0,$IN01_2,${S3}
-       umlal   $ACC4,$IN01_2,${R2}
-       umlal   $ACC1,$IN01_2,${S4}
-       umlal   $ACC2,$IN01_2,${R0}
-
-       add     $IN01_1,$IN01_1,$H1
-       umlal   $ACC3,$IN01_0,${R3}
-       umlal   $ACC0,$IN01_0,${R0}
-       umlal   $ACC4,$IN01_0,${R4}
-       umlal   $ACC1,$IN01_0,${R1}
-       umlal   $ACC2,$IN01_0,${R2}
-
-       add     $IN01_3,$IN01_3,$H3
-       umlal   $ACC3,$IN01_1,${R2}
-       umlal   $ACC0,$IN01_1,${S4}
-       umlal   $ACC4,$IN01_1,${R3}
-       umlal   $ACC1,$IN01_1,${R0}
-       umlal   $ACC2,$IN01_1,${R1}
-
-       add     $IN01_4,$IN01_4,$H4
-       umlal   $ACC3,$IN01_3,${R0}
-       umlal   $ACC0,$IN01_3,${S2}
-       umlal   $ACC4,$IN01_3,${R1}
-       umlal   $ACC1,$IN01_3,${S3}
-       umlal   $ACC2,$IN01_3,${S4}
-
-       umlal   $ACC3,$IN01_4,${S4}
-       umlal   $ACC0,$IN01_4,${S1}
-       umlal   $ACC4,$IN01_4,${R0}
-       umlal   $ACC1,$IN01_4,${S2}
-       umlal   $ACC2,$IN01_4,${S3}
-
-.Lshort_tail:
-       ////////////////////////////////////////////////////////////////
-       // horizontal add
-
-       addp    $ACC3,$ACC3,$ACC3
-        ldp    d8,d9,[sp,#16]          // meet ABI requirements
-       addp    $ACC0,$ACC0,$ACC0
-        ldp    d10,d11,[sp,#32]
-       addp    $ACC4,$ACC4,$ACC4
-        ldp    d12,d13,[sp,#48]
-       addp    $ACC1,$ACC1,$ACC1
-        ldp    d14,d15,[sp,#64]
-       addp    $ACC2,$ACC2,$ACC2
-        ldr    x30,[sp,#8]
-
-       ////////////////////////////////////////////////////////////////
-       // lazy reduction, but without narrowing
-
-       ushr    $T0.2d,$ACC3,#26
-       and     $ACC3,$ACC3,$MASK.2d
-        ushr   $T1.2d,$ACC0,#26
-        and    $ACC0,$ACC0,$MASK.2d
-
-       add     $ACC4,$ACC4,$T0.2d      // h3 -> h4
-        add    $ACC1,$ACC1,$T1.2d      // h0 -> h1
-
-       ushr    $T0.2d,$ACC4,#26
-       and     $ACC4,$ACC4,$MASK.2d
-        ushr   $T1.2d,$ACC1,#26
-        and    $ACC1,$ACC1,$MASK.2d
-        add    $ACC2,$ACC2,$T1.2d      // h1 -> h2
-
-       add     $ACC0,$ACC0,$T0.2d
-       shl     $T0.2d,$T0.2d,#2
-        ushr   $T1.2d,$ACC2,#26
-        and    $ACC2,$ACC2,$MASK.2d
-       add     $ACC0,$ACC0,$T0.2d      // h4 -> h0
-        add    $ACC3,$ACC3,$T1.2d      // h2 -> h3
-
-       ushr    $T0.2d,$ACC0,#26
-       and     $ACC0,$ACC0,$MASK.2d
-        ushr   $T1.2d,$ACC3,#26
-        and    $ACC3,$ACC3,$MASK.2d
-       add     $ACC1,$ACC1,$T0.2d      // h0 -> h1
-        add    $ACC4,$ACC4,$T1.2d      // h3 -> h4
-
-       ////////////////////////////////////////////////////////////////
-       // write the result, can be partially reduced
-
-       st4     {$ACC0,$ACC1,$ACC2,$ACC3}[0],[$ctx],#16
-       mov     x4,#1
-       st1     {$ACC4}[0],[$ctx]
-       str     x4,[$ctx,#8]            // set is_base2_26
-
-       ldr     x29,[sp],#80
-        .inst  0xd50323bf              // autiasp
-       ret
-.size  poly1305_blocks_neon,.-poly1305_blocks_neon
-
-.pushsection .rodata
-.align 5
-.Lzeros:
-.long  0,0,0,0,0,0,0,0
-.asciz "Poly1305 for ARMv8, CRYPTOGAMS by \@dot-asm"
-.popsection
-
-.align 2
-#if !defined(__KERNEL__) && !defined(_WIN64)
-.comm  OPENSSL_armcap_P,4,4
-.hidden        OPENSSL_armcap_P
-#endif
-___
-
-foreach (split("\n",$code)) {
-       s/\b(shrn\s+v[0-9]+)\.[24]d/$1.2s/                      or
-       s/\b(fmov\s+)v([0-9]+)[^,]*,\s*x([0-9]+)/$1d$2,x$3/     or
-       (m/\bdup\b/ and (s/\.[24]s/.2d/g or 1))                 or
-       (m/\b(eor|and)/ and (s/\.[248][sdh]/.16b/g or 1))       or
-       (m/\bum(ul|la)l\b/ and (s/\.4s/.2s/g or 1))             or
-       (m/\bum(ul|la)l2\b/ and (s/\.2s/.4s/g or 1))            or
-       (m/\bst[1-4]\s+{[^}]+}\[/ and (s/\.[24]d/.s/g or 1));
-
-       s/\.[124]([sd])\[/.$1\[/;
-       s/w#x([0-9]+)/w$1/g;
-
-       print $_,"\n";
-}
-close STDOUT;
diff --git a/arch/arm64/crypto/poly1305-glue.c b/arch/arm64/crypto/poly1305-glue.c
deleted file mode 100644 (file)
index 906970d..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * OpenSSL/Cryptogams accelerated Poly1305 transform for arm64
- *
- * Copyright (C) 2019 Linaro Ltd. <ard.biesheuvel@linaro.org>
- */
-
-#include <asm/hwcap.h>
-#include <asm/neon.h>
-#include <asm/simd.h>
-#include <crypto/poly1305.h>
-#include <crypto/internal/simd.h>
-#include <linux/cpufeature.h>
-#include <linux/jump_label.h>
-#include <linux/module.h>
-#include <linux/unaligned.h>
-
-asmlinkage void poly1305_init_arm64(void *state, const u8 *key);
-asmlinkage void poly1305_blocks(void *state, const u8 *src, u32 len, u32 hibit);
-asmlinkage void poly1305_blocks_neon(void *state, const u8 *src, u32 len, u32 hibit);
-asmlinkage void poly1305_emit(void *state, u8 *digest, const u32 *nonce);
-
-static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_neon);
-
-void poly1305_init_arch(struct poly1305_desc_ctx *dctx, const u8 key[POLY1305_KEY_SIZE])
-{
-       poly1305_init_arm64(&dctx->h, key);
-       dctx->s[0] = get_unaligned_le32(key + 16);
-       dctx->s[1] = get_unaligned_le32(key + 20);
-       dctx->s[2] = get_unaligned_le32(key + 24);
-       dctx->s[3] = get_unaligned_le32(key + 28);
-       dctx->buflen = 0;
-}
-EXPORT_SYMBOL(poly1305_init_arch);
-
-void poly1305_update_arch(struct poly1305_desc_ctx *dctx, const u8 *src,
-                         unsigned int nbytes)
-{
-       if (unlikely(dctx->buflen)) {
-               u32 bytes = min(nbytes, POLY1305_BLOCK_SIZE - dctx->buflen);
-
-               memcpy(dctx->buf + dctx->buflen, src, bytes);
-               src += bytes;
-               nbytes -= bytes;
-               dctx->buflen += bytes;
-
-               if (dctx->buflen == POLY1305_BLOCK_SIZE) {
-                       poly1305_blocks(&dctx->h, dctx->buf, POLY1305_BLOCK_SIZE, 1);
-                       dctx->buflen = 0;
-               }
-       }
-
-       if (likely(nbytes >= POLY1305_BLOCK_SIZE)) {
-               unsigned int len = round_down(nbytes, POLY1305_BLOCK_SIZE);
-
-               if (static_branch_likely(&have_neon) && crypto_simd_usable()) {
-                       do {
-                               unsigned int todo = min_t(unsigned int, len, SZ_4K);
-
-                               kernel_neon_begin();
-                               poly1305_blocks_neon(&dctx->h, src, todo, 1);
-                               kernel_neon_end();
-
-                               len -= todo;
-                               src += todo;
-                       } while (len);
-               } else {
-                       poly1305_blocks(&dctx->h, src, len, 1);
-                       src += len;
-               }
-               nbytes %= POLY1305_BLOCK_SIZE;
-       }
-
-       if (unlikely(nbytes)) {
-               dctx->buflen = nbytes;
-               memcpy(dctx->buf, src, nbytes);
-       }
-}
-EXPORT_SYMBOL(poly1305_update_arch);
-
-void poly1305_final_arch(struct poly1305_desc_ctx *dctx, u8 *dst)
-{
-       if (unlikely(dctx->buflen)) {
-               dctx->buf[dctx->buflen++] = 1;
-               memset(dctx->buf + dctx->buflen, 0,
-                      POLY1305_BLOCK_SIZE - dctx->buflen);
-               poly1305_blocks(&dctx->h, dctx->buf, POLY1305_BLOCK_SIZE, 0);
-       }
-
-       poly1305_emit(&dctx->h, dst, dctx->s);
-       memzero_explicit(dctx, sizeof(*dctx));
-}
-EXPORT_SYMBOL(poly1305_final_arch);
-
-bool poly1305_is_arch_optimized(void)
-{
-       /* We always can use at least the ARM64 scalar implementation. */
-       return true;
-}
-EXPORT_SYMBOL(poly1305_is_arch_optimized);
-
-static int __init neon_poly1305_mod_init(void)
-{
-       if (cpu_have_named_feature(ASIMD))
-               static_branch_enable(&have_neon);
-       return 0;
-}
-arch_initcall(neon_poly1305_mod_init);
-
-static void __exit neon_poly1305_mod_exit(void)
-{
-}
-module_exit(neon_poly1305_mod_exit);
-
-MODULE_DESCRIPTION("Poly1305 authenticator (ARM64 optimized)");
-MODULE_LICENSE("GPL v2");
index 4d49dff721a84e5e6cd4f28ed727d7002adc946a..25be7825f28d899d6266ec229123415fbc26c717 100644 (file)
@@ -1,4 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
+
+obj-y += crypto/
+
 lib-y          := clear_user.o delay.o copy_from_user.o                \
                   copy_to_user.o copy_page.o                           \
                   clear_page.o csum.o insn.o memchr.o memcpy.o         \
diff --git a/arch/arm64/lib/crypto/.gitignore b/arch/arm64/lib/crypto/.gitignore
new file mode 100644 (file)
index 0000000..0d47d4f
--- /dev/null
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+poly1305-core.S
diff --git a/arch/arm64/lib/crypto/Kconfig b/arch/arm64/lib/crypto/Kconfig
new file mode 100644 (file)
index 0000000..1693115
--- /dev/null
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config CRYPTO_CHACHA20_NEON
+       tristate
+       depends on KERNEL_MODE_NEON
+       default CRYPTO_LIB_CHACHA_INTERNAL
+       select CRYPTO_LIB_CHACHA_GENERIC
+       select CRYPTO_ARCH_HAVE_LIB_CHACHA
+
+config CRYPTO_POLY1305_NEON
+       tristate
+       depends on KERNEL_MODE_NEON
+       default CRYPTO_LIB_POLY1305_INTERNAL
+       select CRYPTO_ARCH_HAVE_LIB_POLY1305
diff --git a/arch/arm64/lib/crypto/Makefile b/arch/arm64/lib/crypto/Makefile
new file mode 100644 (file)
index 0000000..ac624c3
--- /dev/null
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_CRYPTO_CHACHA20_NEON) += chacha-neon.o
+chacha-neon-y := chacha-neon-core.o chacha-neon-glue.o
+
+obj-$(CONFIG_CRYPTO_POLY1305_NEON) += poly1305-neon.o
+poly1305-neon-y := poly1305-core.o poly1305-glue.o
+AFLAGS_poly1305-core.o += -Dpoly1305_init=poly1305_init_arm64
+
+quiet_cmd_perlasm = PERLASM $@
+      cmd_perlasm = $(PERL) $(<) void $(@)
+
+$(obj)/%-core.S: $(src)/%-armv8.pl
+       $(call cmd,perlasm)
+
+clean-files += poly1305-core.S
diff --git a/arch/arm64/lib/crypto/chacha-neon-core.S b/arch/arm64/lib/crypto/chacha-neon-core.S
new file mode 100644 (file)
index 0000000..8007958
--- /dev/null
@@ -0,0 +1,805 @@
+/*
+ * ChaCha/HChaCha NEON helper functions
+ *
+ * Copyright (C) 2016-2018 Linaro, Ltd. <ard.biesheuvel@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Originally based on:
+ * ChaCha20 256-bit cipher algorithm, RFC7539, x64 SSSE3 functions
+ *
+ * Copyright (C) 2015 Martin Willi
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/cache.h>
+
+       .text
+       .align          6
+
+/*
+ * chacha_permute - permute one block
+ *
+ * Permute one 64-byte block where the state matrix is stored in the four NEON
+ * registers v0-v3.  It performs matrix operations on four words in parallel,
+ * but requires shuffling to rearrange the words after each round.
+ *
+ * The round count is given in w3.
+ *
+ * Clobbers: w3, x10, v4, v12
+ */
+SYM_FUNC_START_LOCAL(chacha_permute)
+
+       adr_l           x10, ROT8
+       ld1             {v12.4s}, [x10]
+
+.Ldoubleround:
+       // x0 += x1, x3 = rotl32(x3 ^ x0, 16)
+       add             v0.4s, v0.4s, v1.4s
+       eor             v3.16b, v3.16b, v0.16b
+       rev32           v3.8h, v3.8h
+
+       // x2 += x3, x1 = rotl32(x1 ^ x2, 12)
+       add             v2.4s, v2.4s, v3.4s
+       eor             v4.16b, v1.16b, v2.16b
+       shl             v1.4s, v4.4s, #12
+       sri             v1.4s, v4.4s, #20
+
+       // x0 += x1, x3 = rotl32(x3 ^ x0, 8)
+       add             v0.4s, v0.4s, v1.4s
+       eor             v3.16b, v3.16b, v0.16b
+       tbl             v3.16b, {v3.16b}, v12.16b
+
+       // x2 += x3, x1 = rotl32(x1 ^ x2, 7)
+       add             v2.4s, v2.4s, v3.4s
+       eor             v4.16b, v1.16b, v2.16b
+       shl             v1.4s, v4.4s, #7
+       sri             v1.4s, v4.4s, #25
+
+       // x1 = shuffle32(x1, MASK(0, 3, 2, 1))
+       ext             v1.16b, v1.16b, v1.16b, #4
+       // x2 = shuffle32(x2, MASK(1, 0, 3, 2))
+       ext             v2.16b, v2.16b, v2.16b, #8
+       // x3 = shuffle32(x3, MASK(2, 1, 0, 3))
+       ext             v3.16b, v3.16b, v3.16b, #12
+
+       // x0 += x1, x3 = rotl32(x3 ^ x0, 16)
+       add             v0.4s, v0.4s, v1.4s
+       eor             v3.16b, v3.16b, v0.16b
+       rev32           v3.8h, v3.8h
+
+       // x2 += x3, x1 = rotl32(x1 ^ x2, 12)
+       add             v2.4s, v2.4s, v3.4s
+       eor             v4.16b, v1.16b, v2.16b
+       shl             v1.4s, v4.4s, #12
+       sri             v1.4s, v4.4s, #20
+
+       // x0 += x1, x3 = rotl32(x3 ^ x0, 8)
+       add             v0.4s, v0.4s, v1.4s
+       eor             v3.16b, v3.16b, v0.16b
+       tbl             v3.16b, {v3.16b}, v12.16b
+
+       // x2 += x3, x1 = rotl32(x1 ^ x2, 7)
+       add             v2.4s, v2.4s, v3.4s
+       eor             v4.16b, v1.16b, v2.16b
+       shl             v1.4s, v4.4s, #7
+       sri             v1.4s, v4.4s, #25
+
+       // x1 = shuffle32(x1, MASK(2, 1, 0, 3))
+       ext             v1.16b, v1.16b, v1.16b, #12
+       // x2 = shuffle32(x2, MASK(1, 0, 3, 2))
+       ext             v2.16b, v2.16b, v2.16b, #8
+       // x3 = shuffle32(x3, MASK(0, 3, 2, 1))
+       ext             v3.16b, v3.16b, v3.16b, #4
+
+       subs            w3, w3, #2
+       b.ne            .Ldoubleround
+
+       ret
+SYM_FUNC_END(chacha_permute)
+
+SYM_FUNC_START(chacha_block_xor_neon)
+       // x0: Input state matrix, s
+       // x1: 1 data block output, o
+       // x2: 1 data block input, i
+       // w3: nrounds
+
+       stp             x29, x30, [sp, #-16]!
+       mov             x29, sp
+
+       // x0..3 = s0..3
+       ld1             {v0.4s-v3.4s}, [x0]
+       ld1             {v8.4s-v11.4s}, [x0]
+
+       bl              chacha_permute
+
+       ld1             {v4.16b-v7.16b}, [x2]
+
+       // o0 = i0 ^ (x0 + s0)
+       add             v0.4s, v0.4s, v8.4s
+       eor             v0.16b, v0.16b, v4.16b
+
+       // o1 = i1 ^ (x1 + s1)
+       add             v1.4s, v1.4s, v9.4s
+       eor             v1.16b, v1.16b, v5.16b
+
+       // o2 = i2 ^ (x2 + s2)
+       add             v2.4s, v2.4s, v10.4s
+       eor             v2.16b, v2.16b, v6.16b
+
+       // o3 = i3 ^ (x3 + s3)
+       add             v3.4s, v3.4s, v11.4s
+       eor             v3.16b, v3.16b, v7.16b
+
+       st1             {v0.16b-v3.16b}, [x1]
+
+       ldp             x29, x30, [sp], #16
+       ret
+SYM_FUNC_END(chacha_block_xor_neon)
+
+SYM_FUNC_START(hchacha_block_neon)
+       // x0: Input state matrix, s
+       // x1: output (8 32-bit words)
+       // w2: nrounds
+
+       stp             x29, x30, [sp, #-16]!
+       mov             x29, sp
+
+       ld1             {v0.4s-v3.4s}, [x0]
+
+       mov             w3, w2
+       bl              chacha_permute
+
+       st1             {v0.4s}, [x1], #16
+       st1             {v3.4s}, [x1]
+
+       ldp             x29, x30, [sp], #16
+       ret
+SYM_FUNC_END(hchacha_block_neon)
+
+       a0              .req    w12
+       a1              .req    w13
+       a2              .req    w14
+       a3              .req    w15
+       a4              .req    w16
+       a5              .req    w17
+       a6              .req    w19
+       a7              .req    w20
+       a8              .req    w21
+       a9              .req    w22
+       a10             .req    w23
+       a11             .req    w24
+       a12             .req    w25
+       a13             .req    w26
+       a14             .req    w27
+       a15             .req    w28
+
+       .align          6
+SYM_FUNC_START(chacha_4block_xor_neon)
+       frame_push      10
+
+       // x0: Input state matrix, s
+       // x1: 4 data blocks output, o
+       // x2: 4 data blocks input, i
+       // w3: nrounds
+       // x4: byte count
+
+       adr_l           x10, .Lpermute
+       and             x5, x4, #63
+       add             x10, x10, x5
+
+       //
+       // This function encrypts four consecutive ChaCha blocks by loading
+       // the state matrix in NEON registers four times. The algorithm performs
+       // each operation on the corresponding word of each state matrix, hence
+       // requires no word shuffling. For final XORing step we transpose the
+       // matrix by interleaving 32- and then 64-bit words, which allows us to
+       // do XOR in NEON registers.
+       //
+       // At the same time, a fifth block is encrypted in parallel using
+       // scalar registers
+       //
+       adr_l           x9, CTRINC              // ... and ROT8
+       ld1             {v30.4s-v31.4s}, [x9]
+
+       // x0..15[0-3] = s0..3[0..3]
+       add             x8, x0, #16
+       ld4r            { v0.4s- v3.4s}, [x0]
+       ld4r            { v4.4s- v7.4s}, [x8], #16
+       ld4r            { v8.4s-v11.4s}, [x8], #16
+       ld4r            {v12.4s-v15.4s}, [x8]
+
+       mov             a0, v0.s[0]
+       mov             a1, v1.s[0]
+       mov             a2, v2.s[0]
+       mov             a3, v3.s[0]
+       mov             a4, v4.s[0]
+       mov             a5, v5.s[0]
+       mov             a6, v6.s[0]
+       mov             a7, v7.s[0]
+       mov             a8, v8.s[0]
+       mov             a9, v9.s[0]
+       mov             a10, v10.s[0]
+       mov             a11, v11.s[0]
+       mov             a12, v12.s[0]
+       mov             a13, v13.s[0]
+       mov             a14, v14.s[0]
+       mov             a15, v15.s[0]
+
+       // x12 += counter values 1-4
+       add             v12.4s, v12.4s, v30.4s
+
+.Ldoubleround4:
+       // x0 += x4, x12 = rotl32(x12 ^ x0, 16)
+       // x1 += x5, x13 = rotl32(x13 ^ x1, 16)
+       // x2 += x6, x14 = rotl32(x14 ^ x2, 16)
+       // x3 += x7, x15 = rotl32(x15 ^ x3, 16)
+       add             v0.4s, v0.4s, v4.4s
+         add           a0, a0, a4
+       add             v1.4s, v1.4s, v5.4s
+         add           a1, a1, a5
+       add             v2.4s, v2.4s, v6.4s
+         add           a2, a2, a6
+       add             v3.4s, v3.4s, v7.4s
+         add           a3, a3, a7
+
+       eor             v12.16b, v12.16b, v0.16b
+         eor           a12, a12, a0
+       eor             v13.16b, v13.16b, v1.16b
+         eor           a13, a13, a1
+       eor             v14.16b, v14.16b, v2.16b
+         eor           a14, a14, a2
+       eor             v15.16b, v15.16b, v3.16b
+         eor           a15, a15, a3
+
+       rev32           v12.8h, v12.8h
+         ror           a12, a12, #16
+       rev32           v13.8h, v13.8h
+         ror           a13, a13, #16
+       rev32           v14.8h, v14.8h
+         ror           a14, a14, #16
+       rev32           v15.8h, v15.8h
+         ror           a15, a15, #16
+
+       // x8 += x12, x4 = rotl32(x4 ^ x8, 12)
+       // x9 += x13, x5 = rotl32(x5 ^ x9, 12)
+       // x10 += x14, x6 = rotl32(x6 ^ x10, 12)
+       // x11 += x15, x7 = rotl32(x7 ^ x11, 12)
+       add             v8.4s, v8.4s, v12.4s
+         add           a8, a8, a12
+       add             v9.4s, v9.4s, v13.4s
+         add           a9, a9, a13
+       add             v10.4s, v10.4s, v14.4s
+         add           a10, a10, a14
+       add             v11.4s, v11.4s, v15.4s
+         add           a11, a11, a15
+
+       eor             v16.16b, v4.16b, v8.16b
+         eor           a4, a4, a8
+       eor             v17.16b, v5.16b, v9.16b
+         eor           a5, a5, a9
+       eor             v18.16b, v6.16b, v10.16b
+         eor           a6, a6, a10
+       eor             v19.16b, v7.16b, v11.16b
+         eor           a7, a7, a11
+
+       shl             v4.4s, v16.4s, #12
+       shl             v5.4s, v17.4s, #12
+       shl             v6.4s, v18.4s, #12
+       shl             v7.4s, v19.4s, #12
+
+       sri             v4.4s, v16.4s, #20
+         ror           a4, a4, #20
+       sri             v5.4s, v17.4s, #20
+         ror           a5, a5, #20
+       sri             v6.4s, v18.4s, #20
+         ror           a6, a6, #20
+       sri             v7.4s, v19.4s, #20
+         ror           a7, a7, #20
+
+       // x0 += x4, x12 = rotl32(x12 ^ x0, 8)
+       // x1 += x5, x13 = rotl32(x13 ^ x1, 8)
+       // x2 += x6, x14 = rotl32(x14 ^ x2, 8)
+       // x3 += x7, x15 = rotl32(x15 ^ x3, 8)
+       add             v0.4s, v0.4s, v4.4s
+         add           a0, a0, a4
+       add             v1.4s, v1.4s, v5.4s
+         add           a1, a1, a5
+       add             v2.4s, v2.4s, v6.4s
+         add           a2, a2, a6
+       add             v3.4s, v3.4s, v7.4s
+         add           a3, a3, a7
+
+       eor             v12.16b, v12.16b, v0.16b
+         eor           a12, a12, a0
+       eor             v13.16b, v13.16b, v1.16b
+         eor           a13, a13, a1
+       eor             v14.16b, v14.16b, v2.16b
+         eor           a14, a14, a2
+       eor             v15.16b, v15.16b, v3.16b
+         eor           a15, a15, a3
+
+       tbl             v12.16b, {v12.16b}, v31.16b
+         ror           a12, a12, #24
+       tbl             v13.16b, {v13.16b}, v31.16b
+         ror           a13, a13, #24
+       tbl             v14.16b, {v14.16b}, v31.16b
+         ror           a14, a14, #24
+       tbl             v15.16b, {v15.16b}, v31.16b
+         ror           a15, a15, #24
+
+       // x8 += x12, x4 = rotl32(x4 ^ x8, 7)
+       // x9 += x13, x5 = rotl32(x5 ^ x9, 7)
+       // x10 += x14, x6 = rotl32(x6 ^ x10, 7)
+       // x11 += x15, x7 = rotl32(x7 ^ x11, 7)
+       add             v8.4s, v8.4s, v12.4s
+         add           a8, a8, a12
+       add             v9.4s, v9.4s, v13.4s
+         add           a9, a9, a13
+       add             v10.4s, v10.4s, v14.4s
+         add           a10, a10, a14
+       add             v11.4s, v11.4s, v15.4s
+         add           a11, a11, a15
+
+       eor             v16.16b, v4.16b, v8.16b
+         eor           a4, a4, a8
+       eor             v17.16b, v5.16b, v9.16b
+         eor           a5, a5, a9
+       eor             v18.16b, v6.16b, v10.16b
+         eor           a6, a6, a10
+       eor             v19.16b, v7.16b, v11.16b
+         eor           a7, a7, a11
+
+       shl             v4.4s, v16.4s, #7
+       shl             v5.4s, v17.4s, #7
+       shl             v6.4s, v18.4s, #7
+       shl             v7.4s, v19.4s, #7
+
+       sri             v4.4s, v16.4s, #25
+         ror           a4, a4, #25
+       sri             v5.4s, v17.4s, #25
+         ror           a5, a5, #25
+       sri             v6.4s, v18.4s, #25
+        ror            a6, a6, #25
+       sri             v7.4s, v19.4s, #25
+         ror           a7, a7, #25
+
+       // x0 += x5, x15 = rotl32(x15 ^ x0, 16)
+       // x1 += x6, x12 = rotl32(x12 ^ x1, 16)
+       // x2 += x7, x13 = rotl32(x13 ^ x2, 16)
+       // x3 += x4, x14 = rotl32(x14 ^ x3, 16)
+       add             v0.4s, v0.4s, v5.4s
+         add           a0, a0, a5
+       add             v1.4s, v1.4s, v6.4s
+         add           a1, a1, a6
+       add             v2.4s, v2.4s, v7.4s
+         add           a2, a2, a7
+       add             v3.4s, v3.4s, v4.4s
+         add           a3, a3, a4
+
+       eor             v15.16b, v15.16b, v0.16b
+         eor           a15, a15, a0
+       eor             v12.16b, v12.16b, v1.16b
+         eor           a12, a12, a1
+       eor             v13.16b, v13.16b, v2.16b
+         eor           a13, a13, a2
+       eor             v14.16b, v14.16b, v3.16b
+         eor           a14, a14, a3
+
+       rev32           v15.8h, v15.8h
+         ror           a15, a15, #16
+       rev32           v12.8h, v12.8h
+         ror           a12, a12, #16
+       rev32           v13.8h, v13.8h
+         ror           a13, a13, #16
+       rev32           v14.8h, v14.8h
+         ror           a14, a14, #16
+
+       // x10 += x15, x5 = rotl32(x5 ^ x10, 12)
+       // x11 += x12, x6 = rotl32(x6 ^ x11, 12)
+       // x8 += x13, x7 = rotl32(x7 ^ x8, 12)
+       // x9 += x14, x4 = rotl32(x4 ^ x9, 12)
+       add             v10.4s, v10.4s, v15.4s
+         add           a10, a10, a15
+       add             v11.4s, v11.4s, v12.4s
+         add           a11, a11, a12
+       add             v8.4s, v8.4s, v13.4s
+         add           a8, a8, a13
+       add             v9.4s, v9.4s, v14.4s
+         add           a9, a9, a14
+
+       eor             v16.16b, v5.16b, v10.16b
+         eor           a5, a5, a10
+       eor             v17.16b, v6.16b, v11.16b
+         eor           a6, a6, a11
+       eor             v18.16b, v7.16b, v8.16b
+         eor           a7, a7, a8
+       eor             v19.16b, v4.16b, v9.16b
+         eor           a4, a4, a9
+
+       shl             v5.4s, v16.4s, #12
+       shl             v6.4s, v17.4s, #12
+       shl             v7.4s, v18.4s, #12
+       shl             v4.4s, v19.4s, #12
+
+       sri             v5.4s, v16.4s, #20
+         ror           a5, a5, #20
+       sri             v6.4s, v17.4s, #20
+         ror           a6, a6, #20
+       sri             v7.4s, v18.4s, #20
+         ror           a7, a7, #20
+       sri             v4.4s, v19.4s, #20
+         ror           a4, a4, #20
+
+       // x0 += x5, x15 = rotl32(x15 ^ x0, 8)
+       // x1 += x6, x12 = rotl32(x12 ^ x1, 8)
+       // x2 += x7, x13 = rotl32(x13 ^ x2, 8)
+       // x3 += x4, x14 = rotl32(x14 ^ x3, 8)
+       add             v0.4s, v0.4s, v5.4s
+         add           a0, a0, a5
+       add             v1.4s, v1.4s, v6.4s
+         add           a1, a1, a6
+       add             v2.4s, v2.4s, v7.4s
+         add           a2, a2, a7
+       add             v3.4s, v3.4s, v4.4s
+         add           a3, a3, a4
+
+       eor             v15.16b, v15.16b, v0.16b
+         eor           a15, a15, a0
+       eor             v12.16b, v12.16b, v1.16b
+         eor           a12, a12, a1
+       eor             v13.16b, v13.16b, v2.16b
+         eor           a13, a13, a2
+       eor             v14.16b, v14.16b, v3.16b
+         eor           a14, a14, a3
+
+       tbl             v15.16b, {v15.16b}, v31.16b
+         ror           a15, a15, #24
+       tbl             v12.16b, {v12.16b}, v31.16b
+         ror           a12, a12, #24
+       tbl             v13.16b, {v13.16b}, v31.16b
+         ror           a13, a13, #24
+       tbl             v14.16b, {v14.16b}, v31.16b
+         ror           a14, a14, #24
+
+       // x10 += x15, x5 = rotl32(x5 ^ x10, 7)
+       // x11 += x12, x6 = rotl32(x6 ^ x11, 7)
+       // x8 += x13, x7 = rotl32(x7 ^ x8, 7)
+       // x9 += x14, x4 = rotl32(x4 ^ x9, 7)
+       add             v10.4s, v10.4s, v15.4s
+         add           a10, a10, a15
+       add             v11.4s, v11.4s, v12.4s
+         add           a11, a11, a12
+       add             v8.4s, v8.4s, v13.4s
+         add           a8, a8, a13
+       add             v9.4s, v9.4s, v14.4s
+         add           a9, a9, a14
+
+       eor             v16.16b, v5.16b, v10.16b
+         eor           a5, a5, a10
+       eor             v17.16b, v6.16b, v11.16b
+         eor           a6, a6, a11
+       eor             v18.16b, v7.16b, v8.16b
+         eor           a7, a7, a8
+       eor             v19.16b, v4.16b, v9.16b
+         eor           a4, a4, a9
+
+       shl             v5.4s, v16.4s, #7
+       shl             v6.4s, v17.4s, #7
+       shl             v7.4s, v18.4s, #7
+       shl             v4.4s, v19.4s, #7
+
+       sri             v5.4s, v16.4s, #25
+         ror           a5, a5, #25
+       sri             v6.4s, v17.4s, #25
+         ror           a6, a6, #25
+       sri             v7.4s, v18.4s, #25
+         ror           a7, a7, #25
+       sri             v4.4s, v19.4s, #25
+         ror           a4, a4, #25
+
+       subs            w3, w3, #2
+       b.ne            .Ldoubleround4
+
+       ld4r            {v16.4s-v19.4s}, [x0], #16
+       ld4r            {v20.4s-v23.4s}, [x0], #16
+
+       // x12 += counter values 0-3
+       add             v12.4s, v12.4s, v30.4s
+
+       // x0[0-3] += s0[0]
+       // x1[0-3] += s0[1]
+       // x2[0-3] += s0[2]
+       // x3[0-3] += s0[3]
+       add             v0.4s, v0.4s, v16.4s
+         mov           w6, v16.s[0]
+         mov           w7, v17.s[0]
+       add             v1.4s, v1.4s, v17.4s
+         mov           w8, v18.s[0]
+         mov           w9, v19.s[0]
+       add             v2.4s, v2.4s, v18.4s
+         add           a0, a0, w6
+         add           a1, a1, w7
+       add             v3.4s, v3.4s, v19.4s
+         add           a2, a2, w8
+         add           a3, a3, w9
+CPU_BE(          rev           a0, a0          )
+CPU_BE(          rev           a1, a1          )
+CPU_BE(          rev           a2, a2          )
+CPU_BE(          rev           a3, a3          )
+
+       ld4r            {v24.4s-v27.4s}, [x0], #16
+       ld4r            {v28.4s-v31.4s}, [x0]
+
+       // x4[0-3] += s1[0]
+       // x5[0-3] += s1[1]
+       // x6[0-3] += s1[2]
+       // x7[0-3] += s1[3]
+       add             v4.4s, v4.4s, v20.4s
+         mov           w6, v20.s[0]
+         mov           w7, v21.s[0]
+       add             v5.4s, v5.4s, v21.4s
+         mov           w8, v22.s[0]
+         mov           w9, v23.s[0]
+       add             v6.4s, v6.4s, v22.4s
+         add           a4, a4, w6
+         add           a5, a5, w7
+       add             v7.4s, v7.4s, v23.4s
+         add           a6, a6, w8
+         add           a7, a7, w9
+CPU_BE(          rev           a4, a4          )
+CPU_BE(          rev           a5, a5          )
+CPU_BE(          rev           a6, a6          )
+CPU_BE(          rev           a7, a7          )
+
+       // x8[0-3] += s2[0]
+       // x9[0-3] += s2[1]
+       // x10[0-3] += s2[2]
+       // x11[0-3] += s2[3]
+       add             v8.4s, v8.4s, v24.4s
+         mov           w6, v24.s[0]
+         mov           w7, v25.s[0]
+       add             v9.4s, v9.4s, v25.4s
+         mov           w8, v26.s[0]
+         mov           w9, v27.s[0]
+       add             v10.4s, v10.4s, v26.4s
+         add           a8, a8, w6
+         add           a9, a9, w7
+       add             v11.4s, v11.4s, v27.4s
+         add           a10, a10, w8
+         add           a11, a11, w9
+CPU_BE(          rev           a8, a8          )
+CPU_BE(          rev           a9, a9          )
+CPU_BE(          rev           a10, a10        )
+CPU_BE(          rev           a11, a11        )
+
+       // x12[0-3] += s3[0]
+       // x13[0-3] += s3[1]
+       // x14[0-3] += s3[2]
+       // x15[0-3] += s3[3]
+       add             v12.4s, v12.4s, v28.4s
+         mov           w6, v28.s[0]
+         mov           w7, v29.s[0]
+       add             v13.4s, v13.4s, v29.4s
+         mov           w8, v30.s[0]
+         mov           w9, v31.s[0]
+       add             v14.4s, v14.4s, v30.4s
+         add           a12, a12, w6
+         add           a13, a13, w7
+       add             v15.4s, v15.4s, v31.4s
+         add           a14, a14, w8
+         add           a15, a15, w9
+CPU_BE(          rev           a12, a12        )
+CPU_BE(          rev           a13, a13        )
+CPU_BE(          rev           a14, a14        )
+CPU_BE(          rev           a15, a15        )
+
+       // interleave 32-bit words in state n, n+1
+         ldp           w6, w7, [x2], #64
+       zip1            v16.4s, v0.4s, v1.4s
+         ldp           w8, w9, [x2, #-56]
+         eor           a0, a0, w6
+       zip2            v17.4s, v0.4s, v1.4s
+         eor           a1, a1, w7
+       zip1            v18.4s, v2.4s, v3.4s
+         eor           a2, a2, w8
+       zip2            v19.4s, v2.4s, v3.4s
+         eor           a3, a3, w9
+         ldp           w6, w7, [x2, #-48]
+       zip1            v20.4s, v4.4s, v5.4s
+         ldp           w8, w9, [x2, #-40]
+         eor           a4, a4, w6
+       zip2            v21.4s, v4.4s, v5.4s
+         eor           a5, a5, w7
+       zip1            v22.4s, v6.4s, v7.4s
+         eor           a6, a6, w8
+       zip2            v23.4s, v6.4s, v7.4s
+         eor           a7, a7, w9
+         ldp           w6, w7, [x2, #-32]
+       zip1            v24.4s, v8.4s, v9.4s
+         ldp           w8, w9, [x2, #-24]
+         eor           a8, a8, w6
+       zip2            v25.4s, v8.4s, v9.4s
+         eor           a9, a9, w7
+       zip1            v26.4s, v10.4s, v11.4s
+         eor           a10, a10, w8
+       zip2            v27.4s, v10.4s, v11.4s
+         eor           a11, a11, w9
+         ldp           w6, w7, [x2, #-16]
+       zip1            v28.4s, v12.4s, v13.4s
+         ldp           w8, w9, [x2, #-8]
+         eor           a12, a12, w6
+       zip2            v29.4s, v12.4s, v13.4s
+         eor           a13, a13, w7
+       zip1            v30.4s, v14.4s, v15.4s
+         eor           a14, a14, w8
+       zip2            v31.4s, v14.4s, v15.4s
+         eor           a15, a15, w9
+
+       add             x3, x2, x4
+       sub             x3, x3, #128            // start of last block
+
+       subs            x5, x4, #128
+       csel            x2, x2, x3, ge
+
+       // interleave 64-bit words in state n, n+2
+       zip1            v0.2d, v16.2d, v18.2d
+       zip2            v4.2d, v16.2d, v18.2d
+         stp           a0, a1, [x1], #64
+       zip1            v8.2d, v17.2d, v19.2d
+       zip2            v12.2d, v17.2d, v19.2d
+         stp           a2, a3, [x1, #-56]
+
+       subs            x6, x4, #192
+       ld1             {v16.16b-v19.16b}, [x2], #64
+       csel            x2, x2, x3, ge
+
+       zip1            v1.2d, v20.2d, v22.2d
+       zip2            v5.2d, v20.2d, v22.2d
+         stp           a4, a5, [x1, #-48]
+       zip1            v9.2d, v21.2d, v23.2d
+       zip2            v13.2d, v21.2d, v23.2d
+         stp           a6, a7, [x1, #-40]
+
+       subs            x7, x4, #256
+       ld1             {v20.16b-v23.16b}, [x2], #64
+       csel            x2, x2, x3, ge
+
+       zip1            v2.2d, v24.2d, v26.2d
+       zip2            v6.2d, v24.2d, v26.2d
+         stp           a8, a9, [x1, #-32]
+       zip1            v10.2d, v25.2d, v27.2d
+       zip2            v14.2d, v25.2d, v27.2d
+         stp           a10, a11, [x1, #-24]
+
+       subs            x8, x4, #320
+       ld1             {v24.16b-v27.16b}, [x2], #64
+       csel            x2, x2, x3, ge
+
+       zip1            v3.2d, v28.2d, v30.2d
+       zip2            v7.2d, v28.2d, v30.2d
+         stp           a12, a13, [x1, #-16]
+       zip1            v11.2d, v29.2d, v31.2d
+       zip2            v15.2d, v29.2d, v31.2d
+         stp           a14, a15, [x1, #-8]
+
+       tbnz            x5, #63, .Lt128
+       ld1             {v28.16b-v31.16b}, [x2]
+
+       // xor with corresponding input, write to output
+       eor             v16.16b, v16.16b, v0.16b
+       eor             v17.16b, v17.16b, v1.16b
+       eor             v18.16b, v18.16b, v2.16b
+       eor             v19.16b, v19.16b, v3.16b
+
+       tbnz            x6, #63, .Lt192
+
+       eor             v20.16b, v20.16b, v4.16b
+       eor             v21.16b, v21.16b, v5.16b
+       eor             v22.16b, v22.16b, v6.16b
+       eor             v23.16b, v23.16b, v7.16b
+
+       st1             {v16.16b-v19.16b}, [x1], #64
+       tbnz            x7, #63, .Lt256
+
+       eor             v24.16b, v24.16b, v8.16b
+       eor             v25.16b, v25.16b, v9.16b
+       eor             v26.16b, v26.16b, v10.16b
+       eor             v27.16b, v27.16b, v11.16b
+
+       st1             {v20.16b-v23.16b}, [x1], #64
+       tbnz            x8, #63, .Lt320
+
+       eor             v28.16b, v28.16b, v12.16b
+       eor             v29.16b, v29.16b, v13.16b
+       eor             v30.16b, v30.16b, v14.16b
+       eor             v31.16b, v31.16b, v15.16b
+
+       st1             {v24.16b-v27.16b}, [x1], #64
+       st1             {v28.16b-v31.16b}, [x1]
+
+.Lout: frame_pop
+       ret
+
+       // fewer than 192 bytes of in/output
+.Lt192:        cbz             x5, 1f                          // exactly 128 bytes?
+       ld1             {v28.16b-v31.16b}, [x10]
+       add             x5, x5, x1
+       tbl             v28.16b, {v4.16b-v7.16b}, v28.16b
+       tbl             v29.16b, {v4.16b-v7.16b}, v29.16b
+       tbl             v30.16b, {v4.16b-v7.16b}, v30.16b
+       tbl             v31.16b, {v4.16b-v7.16b}, v31.16b
+
+0:     eor             v20.16b, v20.16b, v28.16b
+       eor             v21.16b, v21.16b, v29.16b
+       eor             v22.16b, v22.16b, v30.16b
+       eor             v23.16b, v23.16b, v31.16b
+       st1             {v20.16b-v23.16b}, [x5]         // overlapping stores
+1:     st1             {v16.16b-v19.16b}, [x1]
+       b               .Lout
+
+       // fewer than 128 bytes of in/output
+.Lt128:        ld1             {v28.16b-v31.16b}, [x10]
+       add             x5, x5, x1
+       sub             x1, x1, #64
+       tbl             v28.16b, {v0.16b-v3.16b}, v28.16b
+       tbl             v29.16b, {v0.16b-v3.16b}, v29.16b
+       tbl             v30.16b, {v0.16b-v3.16b}, v30.16b
+       tbl             v31.16b, {v0.16b-v3.16b}, v31.16b
+       ld1             {v16.16b-v19.16b}, [x1]         // reload first output block
+       b               0b
+
+       // fewer than 256 bytes of in/output
+.Lt256:        cbz             x6, 2f                          // exactly 192 bytes?
+       ld1             {v4.16b-v7.16b}, [x10]
+       add             x6, x6, x1
+       tbl             v0.16b, {v8.16b-v11.16b}, v4.16b
+       tbl             v1.16b, {v8.16b-v11.16b}, v5.16b
+       tbl             v2.16b, {v8.16b-v11.16b}, v6.16b
+       tbl             v3.16b, {v8.16b-v11.16b}, v7.16b
+
+       eor             v28.16b, v28.16b, v0.16b
+       eor             v29.16b, v29.16b, v1.16b
+       eor             v30.16b, v30.16b, v2.16b
+       eor             v31.16b, v31.16b, v3.16b
+       st1             {v28.16b-v31.16b}, [x6]         // overlapping stores
+2:     st1             {v20.16b-v23.16b}, [x1]
+       b               .Lout
+
+       // fewer than 320 bytes of in/output
+.Lt320:        cbz             x7, 3f                          // exactly 256 bytes?
+       ld1             {v4.16b-v7.16b}, [x10]
+       add             x7, x7, x1
+       tbl             v0.16b, {v12.16b-v15.16b}, v4.16b
+       tbl             v1.16b, {v12.16b-v15.16b}, v5.16b
+       tbl             v2.16b, {v12.16b-v15.16b}, v6.16b
+       tbl             v3.16b, {v12.16b-v15.16b}, v7.16b
+
+       eor             v28.16b, v28.16b, v0.16b
+       eor             v29.16b, v29.16b, v1.16b
+       eor             v30.16b, v30.16b, v2.16b
+       eor             v31.16b, v31.16b, v3.16b
+       st1             {v28.16b-v31.16b}, [x7]         // overlapping stores
+3:     st1             {v24.16b-v27.16b}, [x1]
+       b               .Lout
+SYM_FUNC_END(chacha_4block_xor_neon)
+
+       .section        ".rodata", "a", %progbits
+       .align          L1_CACHE_SHIFT
+.Lpermute:
+       .set            .Li, 0
+       .rept           128
+       .byte           (.Li - 64)
+       .set            .Li, .Li + 1
+       .endr
+
+CTRINC:        .word           1, 2, 3, 4
+ROT8:  .word           0x02010003, 0x06050407, 0x0a09080b, 0x0e0d0c0f
diff --git a/arch/arm64/lib/crypto/chacha-neon-glue.c b/arch/arm64/lib/crypto/chacha-neon-glue.c
new file mode 100644 (file)
index 0000000..14a2836
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * ChaCha and HChaCha functions (ARM64 optimized)
+ *
+ * Copyright (C) 2016 - 2017 Linaro, Ltd. <ard.biesheuvel@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Based on:
+ * ChaCha20 256-bit cipher algorithm, RFC7539, SIMD glue code
+ *
+ * Copyright (C) 2015 Martin Willi
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <crypto/chacha.h>
+#include <crypto/internal/simd.h>
+#include <linux/jump_label.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/hwcap.h>
+#include <asm/neon.h>
+#include <asm/simd.h>
+
+asmlinkage void chacha_block_xor_neon(u32 *state, u8 *dst, const u8 *src,
+                                     int nrounds);
+asmlinkage void chacha_4block_xor_neon(u32 *state, u8 *dst, const u8 *src,
+                                      int nrounds, int bytes);
+asmlinkage void hchacha_block_neon(const u32 *state, u32 *out, int nrounds);
+
+static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_neon);
+
+static void chacha_doneon(u32 *state, u8 *dst, const u8 *src,
+                         int bytes, int nrounds)
+{
+       while (bytes > 0) {
+               int l = min(bytes, CHACHA_BLOCK_SIZE * 5);
+
+               if (l <= CHACHA_BLOCK_SIZE) {
+                       u8 buf[CHACHA_BLOCK_SIZE];
+
+                       memcpy(buf, src, l);
+                       chacha_block_xor_neon(state, buf, buf, nrounds);
+                       memcpy(dst, buf, l);
+                       state[12] += 1;
+                       break;
+               }
+               chacha_4block_xor_neon(state, dst, src, nrounds, l);
+               bytes -= l;
+               src += l;
+               dst += l;
+               state[12] += DIV_ROUND_UP(l, CHACHA_BLOCK_SIZE);
+       }
+}
+
+void hchacha_block_arch(const u32 *state, u32 *stream, int nrounds)
+{
+       if (!static_branch_likely(&have_neon) || !crypto_simd_usable()) {
+               hchacha_block_generic(state, stream, nrounds);
+       } else {
+               kernel_neon_begin();
+               hchacha_block_neon(state, stream, nrounds);
+               kernel_neon_end();
+       }
+}
+EXPORT_SYMBOL(hchacha_block_arch);
+
+void chacha_crypt_arch(u32 *state, u8 *dst, const u8 *src, unsigned int bytes,
+                      int nrounds)
+{
+       if (!static_branch_likely(&have_neon) || bytes <= CHACHA_BLOCK_SIZE ||
+           !crypto_simd_usable())
+               return chacha_crypt_generic(state, dst, src, bytes, nrounds);
+
+       do {
+               unsigned int todo = min_t(unsigned int, bytes, SZ_4K);
+
+               kernel_neon_begin();
+               chacha_doneon(state, dst, src, todo, nrounds);
+               kernel_neon_end();
+
+               bytes -= todo;
+               src += todo;
+               dst += todo;
+       } while (bytes);
+}
+EXPORT_SYMBOL(chacha_crypt_arch);
+
+bool chacha_is_arch_optimized(void)
+{
+       return static_key_enabled(&have_neon);
+}
+EXPORT_SYMBOL(chacha_is_arch_optimized);
+
+static int __init chacha_simd_mod_init(void)
+{
+       if (cpu_have_named_feature(ASIMD))
+               static_branch_enable(&have_neon);
+       return 0;
+}
+arch_initcall(chacha_simd_mod_init);
+
+static void __exit chacha_simd_mod_exit(void)
+{
+}
+module_exit(chacha_simd_mod_exit);
+
+MODULE_DESCRIPTION("ChaCha and HChaCha functions (ARM64 optimized)");
+MODULE_AUTHOR("Ard Biesheuvel <ard.biesheuvel@linaro.org>");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm64/lib/crypto/poly1305-armv8.pl b/arch/arm64/lib/crypto/poly1305-armv8.pl
new file mode 100644 (file)
index 0000000..22c9069
--- /dev/null
@@ -0,0 +1,917 @@
+#!/usr/bin/env perl
+# SPDX-License-Identifier: GPL-1.0+ OR BSD-3-Clause
+#
+# ====================================================================
+# Written by Andy Polyakov, @dot-asm, initially for the OpenSSL
+# project.
+# ====================================================================
+#
+# This module implements Poly1305 hash for ARMv8.
+#
+# June 2015
+#
+# Numbers are cycles per processed byte with poly1305_blocks alone.
+#
+#              IALU/gcc-4.9    NEON
+#
+# Apple A7     1.86/+5%        0.72
+# Cortex-A53   2.69/+58%       1.47
+# Cortex-A57   2.70/+7%        1.14
+# Denver       1.64/+50%       1.18(*)
+# X-Gene       2.13/+68%       2.27
+# Mongoose     1.77/+75%       1.12
+# Kryo         2.70/+55%       1.13
+# ThunderX2    1.17/+95%       1.36
+#
+# (*)  estimate based on resources availability is less than 1.0,
+#      i.e. measured result is worse than expected, presumably binary
+#      translator is not almighty;
+
+$flavour=shift;
+$output=shift;
+
+if ($flavour && $flavour ne "void") {
+    $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+    ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
+    ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
+    die "can't locate arm-xlate.pl";
+
+    open STDOUT,"| \"$^X\" $xlate $flavour $output";
+} else {
+    open STDOUT,">$output";
+}
+
+my ($ctx,$inp,$len,$padbit) = map("x$_",(0..3));
+my ($mac,$nonce)=($inp,$len);
+
+my ($h0,$h1,$h2,$r0,$r1,$s1,$t0,$t1,$d0,$d1,$d2) = map("x$_",(4..14));
+
+$code.=<<___;
+#ifndef __KERNEL__
+# include "arm_arch.h"
+.extern        OPENSSL_armcap_P
+#endif
+
+.text
+
+// forward "declarations" are required for Apple
+.globl poly1305_blocks
+.globl poly1305_emit
+
+.globl poly1305_init
+.type  poly1305_init,%function
+.align 5
+poly1305_init:
+       cmp     $inp,xzr
+       stp     xzr,xzr,[$ctx]          // zero hash value
+       stp     xzr,xzr,[$ctx,#16]      // [along with is_base2_26]
+
+       csel    x0,xzr,x0,eq
+       b.eq    .Lno_key
+
+#ifndef        __KERNEL__
+       adrp    x17,OPENSSL_armcap_P
+       ldr     w17,[x17,#:lo12:OPENSSL_armcap_P]
+#endif
+
+       ldp     $r0,$r1,[$inp]          // load key
+       mov     $s1,#0xfffffffc0fffffff
+       movk    $s1,#0x0fff,lsl#48
+#ifdef __AARCH64EB__
+       rev     $r0,$r0                 // flip bytes
+       rev     $r1,$r1
+#endif
+       and     $r0,$r0,$s1             // &=0ffffffc0fffffff
+       and     $s1,$s1,#-4
+       and     $r1,$r1,$s1             // &=0ffffffc0ffffffc
+       mov     w#$s1,#-1
+       stp     $r0,$r1,[$ctx,#32]      // save key value
+       str     w#$s1,[$ctx,#48]        // impossible key power value
+
+#ifndef        __KERNEL__
+       tst     w17,#ARMV7_NEON
+
+       adr     $d0,.Lpoly1305_blocks
+       adr     $r0,.Lpoly1305_blocks_neon
+       adr     $d1,.Lpoly1305_emit
+
+       csel    $d0,$d0,$r0,eq
+
+# ifdef        __ILP32__
+       stp     w#$d0,w#$d1,[$len]
+# else
+       stp     $d0,$d1,[$len]
+# endif
+#endif
+       mov     x0,#1
+.Lno_key:
+       ret
+.size  poly1305_init,.-poly1305_init
+
+.type  poly1305_blocks,%function
+.align 5
+poly1305_blocks:
+.Lpoly1305_blocks:
+       ands    $len,$len,#-16
+       b.eq    .Lno_data
+
+       ldp     $h0,$h1,[$ctx]          // load hash value
+       ldp     $h2,x17,[$ctx,#16]      // [along with is_base2_26]
+       ldp     $r0,$r1,[$ctx,#32]      // load key value
+
+#ifdef __AARCH64EB__
+       lsr     $d0,$h0,#32
+       mov     w#$d1,w#$h0
+       lsr     $d2,$h1,#32
+       mov     w15,w#$h1
+       lsr     x16,$h2,#32
+#else
+       mov     w#$d0,w#$h0
+       lsr     $d1,$h0,#32
+       mov     w#$d2,w#$h1
+       lsr     x15,$h1,#32
+       mov     w16,w#$h2
+#endif
+
+       add     $d0,$d0,$d1,lsl#26      // base 2^26 -> base 2^64
+       lsr     $d1,$d2,#12
+       adds    $d0,$d0,$d2,lsl#52
+       add     $d1,$d1,x15,lsl#14
+       adc     $d1,$d1,xzr
+       lsr     $d2,x16,#24
+       adds    $d1,$d1,x16,lsl#40
+       adc     $d2,$d2,xzr
+
+       cmp     x17,#0                  // is_base2_26?
+       add     $s1,$r1,$r1,lsr#2       // s1 = r1 + (r1 >> 2)
+       csel    $h0,$h0,$d0,eq          // choose between radixes
+       csel    $h1,$h1,$d1,eq
+       csel    $h2,$h2,$d2,eq
+
+.Loop:
+       ldp     $t0,$t1,[$inp],#16      // load input
+       sub     $len,$len,#16
+#ifdef __AARCH64EB__
+       rev     $t0,$t0
+       rev     $t1,$t1
+#endif
+       adds    $h0,$h0,$t0             // accumulate input
+       adcs    $h1,$h1,$t1
+
+       mul     $d0,$h0,$r0             // h0*r0
+       adc     $h2,$h2,$padbit
+       umulh   $d1,$h0,$r0
+
+       mul     $t0,$h1,$s1             // h1*5*r1
+       umulh   $t1,$h1,$s1
+
+       adds    $d0,$d0,$t0
+       mul     $t0,$h0,$r1             // h0*r1
+       adc     $d1,$d1,$t1
+       umulh   $d2,$h0,$r1
+
+       adds    $d1,$d1,$t0
+       mul     $t0,$h1,$r0             // h1*r0
+       adc     $d2,$d2,xzr
+       umulh   $t1,$h1,$r0
+
+       adds    $d1,$d1,$t0
+       mul     $t0,$h2,$s1             // h2*5*r1
+       adc     $d2,$d2,$t1
+       mul     $t1,$h2,$r0             // h2*r0
+
+       adds    $d1,$d1,$t0
+       adc     $d2,$d2,$t1
+
+       and     $t0,$d2,#-4             // final reduction
+       and     $h2,$d2,#3
+       add     $t0,$t0,$d2,lsr#2
+       adds    $h0,$d0,$t0
+       adcs    $h1,$d1,xzr
+       adc     $h2,$h2,xzr
+
+       cbnz    $len,.Loop
+
+       stp     $h0,$h1,[$ctx]          // store hash value
+       stp     $h2,xzr,[$ctx,#16]      // [and clear is_base2_26]
+
+.Lno_data:
+       ret
+.size  poly1305_blocks,.-poly1305_blocks
+
+.type  poly1305_emit,%function
+.align 5
+poly1305_emit:
+.Lpoly1305_emit:
+       ldp     $h0,$h1,[$ctx]          // load hash base 2^64
+       ldp     $h2,$r0,[$ctx,#16]      // [along with is_base2_26]
+       ldp     $t0,$t1,[$nonce]        // load nonce
+
+#ifdef __AARCH64EB__
+       lsr     $d0,$h0,#32
+       mov     w#$d1,w#$h0
+       lsr     $d2,$h1,#32
+       mov     w15,w#$h1
+       lsr     x16,$h2,#32
+#else
+       mov     w#$d0,w#$h0
+       lsr     $d1,$h0,#32
+       mov     w#$d2,w#$h1
+       lsr     x15,$h1,#32
+       mov     w16,w#$h2
+#endif
+
+       add     $d0,$d0,$d1,lsl#26      // base 2^26 -> base 2^64
+       lsr     $d1,$d2,#12
+       adds    $d0,$d0,$d2,lsl#52
+       add     $d1,$d1,x15,lsl#14
+       adc     $d1,$d1,xzr
+       lsr     $d2,x16,#24
+       adds    $d1,$d1,x16,lsl#40
+       adc     $d2,$d2,xzr
+
+       cmp     $r0,#0                  // is_base2_26?
+       csel    $h0,$h0,$d0,eq          // choose between radixes
+       csel    $h1,$h1,$d1,eq
+       csel    $h2,$h2,$d2,eq
+
+       adds    $d0,$h0,#5              // compare to modulus
+       adcs    $d1,$h1,xzr
+       adc     $d2,$h2,xzr
+
+       tst     $d2,#-4                 // see if it's carried/borrowed
+
+       csel    $h0,$h0,$d0,eq
+       csel    $h1,$h1,$d1,eq
+
+#ifdef __AARCH64EB__
+       ror     $t0,$t0,#32             // flip nonce words
+       ror     $t1,$t1,#32
+#endif
+       adds    $h0,$h0,$t0             // accumulate nonce
+       adc     $h1,$h1,$t1
+#ifdef __AARCH64EB__
+       rev     $h0,$h0                 // flip output bytes
+       rev     $h1,$h1
+#endif
+       stp     $h0,$h1,[$mac]          // write result
+
+       ret
+.size  poly1305_emit,.-poly1305_emit
+___
+my ($R0,$R1,$S1,$R2,$S2,$R3,$S3,$R4,$S4) = map("v$_.4s",(0..8));
+my ($IN01_0,$IN01_1,$IN01_2,$IN01_3,$IN01_4) = map("v$_.2s",(9..13));
+my ($IN23_0,$IN23_1,$IN23_2,$IN23_3,$IN23_4) = map("v$_.2s",(14..18));
+my ($ACC0,$ACC1,$ACC2,$ACC3,$ACC4) = map("v$_.2d",(19..23));
+my ($H0,$H1,$H2,$H3,$H4) = map("v$_.2s",(24..28));
+my ($T0,$T1,$MASK) = map("v$_",(29..31));
+
+my ($in2,$zeros)=("x16","x17");
+my $is_base2_26 = $zeros;              # borrow
+
+$code.=<<___;
+.type  poly1305_mult,%function
+.align 5
+poly1305_mult:
+       mul     $d0,$h0,$r0             // h0*r0
+       umulh   $d1,$h0,$r0
+
+       mul     $t0,$h1,$s1             // h1*5*r1
+       umulh   $t1,$h1,$s1
+
+       adds    $d0,$d0,$t0
+       mul     $t0,$h0,$r1             // h0*r1
+       adc     $d1,$d1,$t1
+       umulh   $d2,$h0,$r1
+
+       adds    $d1,$d1,$t0
+       mul     $t0,$h1,$r0             // h1*r0
+       adc     $d2,$d2,xzr
+       umulh   $t1,$h1,$r0
+
+       adds    $d1,$d1,$t0
+       mul     $t0,$h2,$s1             // h2*5*r1
+       adc     $d2,$d2,$t1
+       mul     $t1,$h2,$r0             // h2*r0
+
+       adds    $d1,$d1,$t0
+       adc     $d2,$d2,$t1
+
+       and     $t0,$d2,#-4             // final reduction
+       and     $h2,$d2,#3
+       add     $t0,$t0,$d2,lsr#2
+       adds    $h0,$d0,$t0
+       adcs    $h1,$d1,xzr
+       adc     $h2,$h2,xzr
+
+       ret
+.size  poly1305_mult,.-poly1305_mult
+
+.type  poly1305_splat,%function
+.align 4
+poly1305_splat:
+       and     x12,$h0,#0x03ffffff     // base 2^64 -> base 2^26
+       ubfx    x13,$h0,#26,#26
+       extr    x14,$h1,$h0,#52
+       and     x14,x14,#0x03ffffff
+       ubfx    x15,$h1,#14,#26
+       extr    x16,$h2,$h1,#40
+
+       str     w12,[$ctx,#16*0]        // r0
+       add     w12,w13,w13,lsl#2       // r1*5
+       str     w13,[$ctx,#16*1]        // r1
+       add     w13,w14,w14,lsl#2       // r2*5
+       str     w12,[$ctx,#16*2]        // s1
+       str     w14,[$ctx,#16*3]        // r2
+       add     w14,w15,w15,lsl#2       // r3*5
+       str     w13,[$ctx,#16*4]        // s2
+       str     w15,[$ctx,#16*5]        // r3
+       add     w15,w16,w16,lsl#2       // r4*5
+       str     w14,[$ctx,#16*6]        // s3
+       str     w16,[$ctx,#16*7]        // r4
+       str     w15,[$ctx,#16*8]        // s4
+
+       ret
+.size  poly1305_splat,.-poly1305_splat
+
+#ifdef __KERNEL__
+.globl poly1305_blocks_neon
+#endif
+.type  poly1305_blocks_neon,%function
+.align 5
+poly1305_blocks_neon:
+.Lpoly1305_blocks_neon:
+       ldr     $is_base2_26,[$ctx,#24]
+       cmp     $len,#128
+       b.lo    .Lpoly1305_blocks
+
+       .inst   0xd503233f              // paciasp
+       stp     x29,x30,[sp,#-80]!
+       add     x29,sp,#0
+
+       stp     d8,d9,[sp,#16]          // meet ABI requirements
+       stp     d10,d11,[sp,#32]
+       stp     d12,d13,[sp,#48]
+       stp     d14,d15,[sp,#64]
+
+       cbz     $is_base2_26,.Lbase2_64_neon
+
+       ldp     w10,w11,[$ctx]          // load hash value base 2^26
+       ldp     w12,w13,[$ctx,#8]
+       ldr     w14,[$ctx,#16]
+
+       tst     $len,#31
+       b.eq    .Leven_neon
+
+       ldp     $r0,$r1,[$ctx,#32]      // load key value
+
+       add     $h0,x10,x11,lsl#26      // base 2^26 -> base 2^64
+       lsr     $h1,x12,#12
+       adds    $h0,$h0,x12,lsl#52
+       add     $h1,$h1,x13,lsl#14
+       adc     $h1,$h1,xzr
+       lsr     $h2,x14,#24
+       adds    $h1,$h1,x14,lsl#40
+       adc     $d2,$h2,xzr             // can be partially reduced...
+
+       ldp     $d0,$d1,[$inp],#16      // load input
+       sub     $len,$len,#16
+       add     $s1,$r1,$r1,lsr#2       // s1 = r1 + (r1 >> 2)
+
+#ifdef __AARCH64EB__
+       rev     $d0,$d0
+       rev     $d1,$d1
+#endif
+       adds    $h0,$h0,$d0             // accumulate input
+       adcs    $h1,$h1,$d1
+       adc     $h2,$h2,$padbit
+
+       bl      poly1305_mult
+
+       and     x10,$h0,#0x03ffffff     // base 2^64 -> base 2^26
+       ubfx    x11,$h0,#26,#26
+       extr    x12,$h1,$h0,#52
+       and     x12,x12,#0x03ffffff
+       ubfx    x13,$h1,#14,#26
+       extr    x14,$h2,$h1,#40
+
+       b       .Leven_neon
+
+.align 4
+.Lbase2_64_neon:
+       ldp     $r0,$r1,[$ctx,#32]      // load key value
+
+       ldp     $h0,$h1,[$ctx]          // load hash value base 2^64
+       ldr     $h2,[$ctx,#16]
+
+       tst     $len,#31
+       b.eq    .Linit_neon
+
+       ldp     $d0,$d1,[$inp],#16      // load input
+       sub     $len,$len,#16
+       add     $s1,$r1,$r1,lsr#2       // s1 = r1 + (r1 >> 2)
+#ifdef __AARCH64EB__
+       rev     $d0,$d0
+       rev     $d1,$d1
+#endif
+       adds    $h0,$h0,$d0             // accumulate input
+       adcs    $h1,$h1,$d1
+       adc     $h2,$h2,$padbit
+
+       bl      poly1305_mult
+
+.Linit_neon:
+       ldr     w17,[$ctx,#48]          // first table element
+       and     x10,$h0,#0x03ffffff     // base 2^64 -> base 2^26
+       ubfx    x11,$h0,#26,#26
+       extr    x12,$h1,$h0,#52
+       and     x12,x12,#0x03ffffff
+       ubfx    x13,$h1,#14,#26
+       extr    x14,$h2,$h1,#40
+
+       cmp     w17,#-1                 // is value impossible?
+       b.ne    .Leven_neon
+
+       fmov    ${H0},x10
+       fmov    ${H1},x11
+       fmov    ${H2},x12
+       fmov    ${H3},x13
+       fmov    ${H4},x14
+
+       ////////////////////////////////// initialize r^n table
+       mov     $h0,$r0                 // r^1
+       add     $s1,$r1,$r1,lsr#2       // s1 = r1 + (r1 >> 2)
+       mov     $h1,$r1
+       mov     $h2,xzr
+       add     $ctx,$ctx,#48+12
+       bl      poly1305_splat
+
+       bl      poly1305_mult           // r^2
+       sub     $ctx,$ctx,#4
+       bl      poly1305_splat
+
+       bl      poly1305_mult           // r^3
+       sub     $ctx,$ctx,#4
+       bl      poly1305_splat
+
+       bl      poly1305_mult           // r^4
+       sub     $ctx,$ctx,#4
+       bl      poly1305_splat
+       sub     $ctx,$ctx,#48           // restore original $ctx
+       b       .Ldo_neon
+
+.align 4
+.Leven_neon:
+       fmov    ${H0},x10
+       fmov    ${H1},x11
+       fmov    ${H2},x12
+       fmov    ${H3},x13
+       fmov    ${H4},x14
+
+.Ldo_neon:
+       ldp     x8,x12,[$inp,#32]       // inp[2:3]
+       subs    $len,$len,#64
+       ldp     x9,x13,[$inp,#48]
+       add     $in2,$inp,#96
+       adrp    $zeros,.Lzeros
+       add     $zeros,$zeros,#:lo12:.Lzeros
+
+       lsl     $padbit,$padbit,#24
+       add     x15,$ctx,#48
+
+#ifdef __AARCH64EB__
+       rev     x8,x8
+       rev     x12,x12
+       rev     x9,x9
+       rev     x13,x13
+#endif
+       and     x4,x8,#0x03ffffff       // base 2^64 -> base 2^26
+       and     x5,x9,#0x03ffffff
+       ubfx    x6,x8,#26,#26
+       ubfx    x7,x9,#26,#26
+       add     x4,x4,x5,lsl#32         // bfi  x4,x5,#32,#32
+       extr    x8,x12,x8,#52
+       extr    x9,x13,x9,#52
+       add     x6,x6,x7,lsl#32         // bfi  x6,x7,#32,#32
+       fmov    $IN23_0,x4
+       and     x8,x8,#0x03ffffff
+       and     x9,x9,#0x03ffffff
+       ubfx    x10,x12,#14,#26
+       ubfx    x11,x13,#14,#26
+       add     x12,$padbit,x12,lsr#40
+       add     x13,$padbit,x13,lsr#40
+       add     x8,x8,x9,lsl#32         // bfi  x8,x9,#32,#32
+       fmov    $IN23_1,x6
+       add     x10,x10,x11,lsl#32      // bfi  x10,x11,#32,#32
+       add     x12,x12,x13,lsl#32      // bfi  x12,x13,#32,#32
+       fmov    $IN23_2,x8
+       fmov    $IN23_3,x10
+       fmov    $IN23_4,x12
+
+       ldp     x8,x12,[$inp],#16       // inp[0:1]
+       ldp     x9,x13,[$inp],#48
+
+       ld1     {$R0,$R1,$S1,$R2},[x15],#64
+       ld1     {$S2,$R3,$S3,$R4},[x15],#64
+       ld1     {$S4},[x15]
+
+#ifdef __AARCH64EB__
+       rev     x8,x8
+       rev     x12,x12
+       rev     x9,x9
+       rev     x13,x13
+#endif
+       and     x4,x8,#0x03ffffff       // base 2^64 -> base 2^26
+       and     x5,x9,#0x03ffffff
+       ubfx    x6,x8,#26,#26
+       ubfx    x7,x9,#26,#26
+       add     x4,x4,x5,lsl#32         // bfi  x4,x5,#32,#32
+       extr    x8,x12,x8,#52
+       extr    x9,x13,x9,#52
+       add     x6,x6,x7,lsl#32         // bfi  x6,x7,#32,#32
+       fmov    $IN01_0,x4
+       and     x8,x8,#0x03ffffff
+       and     x9,x9,#0x03ffffff
+       ubfx    x10,x12,#14,#26
+       ubfx    x11,x13,#14,#26
+       add     x12,$padbit,x12,lsr#40
+       add     x13,$padbit,x13,lsr#40
+       add     x8,x8,x9,lsl#32         // bfi  x8,x9,#32,#32
+       fmov    $IN01_1,x6
+       add     x10,x10,x11,lsl#32      // bfi  x10,x11,#32,#32
+       add     x12,x12,x13,lsl#32      // bfi  x12,x13,#32,#32
+       movi    $MASK.2d,#-1
+       fmov    $IN01_2,x8
+       fmov    $IN01_3,x10
+       fmov    $IN01_4,x12
+       ushr    $MASK.2d,$MASK.2d,#38
+
+       b.ls    .Lskip_loop
+
+.align 4
+.Loop_neon:
+       ////////////////////////////////////////////////////////////////
+       // ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2
+       // ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^3+inp[7]*r
+       //   \___________________/
+       // ((inp[0]*r^4+inp[2]*r^2+inp[4])*r^4+inp[6]*r^2+inp[8])*r^2
+       // ((inp[1]*r^4+inp[3]*r^2+inp[5])*r^4+inp[7]*r^2+inp[9])*r
+       //   \___________________/ \____________________/
+       //
+       // Note that we start with inp[2:3]*r^2. This is because it
+       // doesn't depend on reduction in previous iteration.
+       ////////////////////////////////////////////////////////////////
+       // d4 = h0*r4 + h1*r3   + h2*r2   + h3*r1   + h4*r0
+       // d3 = h0*r3 + h1*r2   + h2*r1   + h3*r0   + h4*5*r4
+       // d2 = h0*r2 + h1*r1   + h2*r0   + h3*5*r4 + h4*5*r3
+       // d1 = h0*r1 + h1*r0   + h2*5*r4 + h3*5*r3 + h4*5*r2
+       // d0 = h0*r0 + h1*5*r4 + h2*5*r3 + h3*5*r2 + h4*5*r1
+
+       subs    $len,$len,#64
+       umull   $ACC4,$IN23_0,${R4}[2]
+       csel    $in2,$zeros,$in2,lo
+       umull   $ACC3,$IN23_0,${R3}[2]
+       umull   $ACC2,$IN23_0,${R2}[2]
+        ldp    x8,x12,[$in2],#16       // inp[2:3] (or zero)
+       umull   $ACC1,$IN23_0,${R1}[2]
+        ldp    x9,x13,[$in2],#48
+       umull   $ACC0,$IN23_0,${R0}[2]
+#ifdef __AARCH64EB__
+        rev    x8,x8
+        rev    x12,x12
+        rev    x9,x9
+        rev    x13,x13
+#endif
+
+       umlal   $ACC4,$IN23_1,${R3}[2]
+        and    x4,x8,#0x03ffffff       // base 2^64 -> base 2^26
+       umlal   $ACC3,$IN23_1,${R2}[2]
+        and    x5,x9,#0x03ffffff
+       umlal   $ACC2,$IN23_1,${R1}[2]
+        ubfx   x6,x8,#26,#26
+       umlal   $ACC1,$IN23_1,${R0}[2]
+        ubfx   x7,x9,#26,#26
+       umlal   $ACC0,$IN23_1,${S4}[2]
+        add    x4,x4,x5,lsl#32         // bfi  x4,x5,#32,#32
+
+       umlal   $ACC4,$IN23_2,${R2}[2]
+        extr   x8,x12,x8,#52
+       umlal   $ACC3,$IN23_2,${R1}[2]
+        extr   x9,x13,x9,#52
+       umlal   $ACC2,$IN23_2,${R0}[2]
+        add    x6,x6,x7,lsl#32         // bfi  x6,x7,#32,#32
+       umlal   $ACC1,$IN23_2,${S4}[2]
+        fmov   $IN23_0,x4
+       umlal   $ACC0,$IN23_2,${S3}[2]
+        and    x8,x8,#0x03ffffff
+
+       umlal   $ACC4,$IN23_3,${R1}[2]
+        and    x9,x9,#0x03ffffff
+       umlal   $ACC3,$IN23_3,${R0}[2]
+        ubfx   x10,x12,#14,#26
+       umlal   $ACC2,$IN23_3,${S4}[2]
+        ubfx   x11,x13,#14,#26
+       umlal   $ACC1,$IN23_3,${S3}[2]
+        add    x8,x8,x9,lsl#32         // bfi  x8,x9,#32,#32
+       umlal   $ACC0,$IN23_3,${S2}[2]
+        fmov   $IN23_1,x6
+
+       add     $IN01_2,$IN01_2,$H2
+        add    x12,$padbit,x12,lsr#40
+       umlal   $ACC4,$IN23_4,${R0}[2]
+        add    x13,$padbit,x13,lsr#40
+       umlal   $ACC3,$IN23_4,${S4}[2]
+        add    x10,x10,x11,lsl#32      // bfi  x10,x11,#32,#32
+       umlal   $ACC2,$IN23_4,${S3}[2]
+        add    x12,x12,x13,lsl#32      // bfi  x12,x13,#32,#32
+       umlal   $ACC1,$IN23_4,${S2}[2]
+        fmov   $IN23_2,x8
+       umlal   $ACC0,$IN23_4,${S1}[2]
+        fmov   $IN23_3,x10
+
+       ////////////////////////////////////////////////////////////////
+       // (hash+inp[0:1])*r^4 and accumulate
+
+       add     $IN01_0,$IN01_0,$H0
+        fmov   $IN23_4,x12
+       umlal   $ACC3,$IN01_2,${R1}[0]
+        ldp    x8,x12,[$inp],#16       // inp[0:1]
+       umlal   $ACC0,$IN01_2,${S3}[0]
+        ldp    x9,x13,[$inp],#48
+       umlal   $ACC4,$IN01_2,${R2}[0]
+       umlal   $ACC1,$IN01_2,${S4}[0]
+       umlal   $ACC2,$IN01_2,${R0}[0]
+#ifdef __AARCH64EB__
+        rev    x8,x8
+        rev    x12,x12
+        rev    x9,x9
+        rev    x13,x13
+#endif
+
+       add     $IN01_1,$IN01_1,$H1
+       umlal   $ACC3,$IN01_0,${R3}[0]
+       umlal   $ACC4,$IN01_0,${R4}[0]
+        and    x4,x8,#0x03ffffff       // base 2^64 -> base 2^26
+       umlal   $ACC2,$IN01_0,${R2}[0]
+        and    x5,x9,#0x03ffffff
+       umlal   $ACC0,$IN01_0,${R0}[0]
+        ubfx   x6,x8,#26,#26
+       umlal   $ACC1,$IN01_0,${R1}[0]
+        ubfx   x7,x9,#26,#26
+
+       add     $IN01_3,$IN01_3,$H3
+        add    x4,x4,x5,lsl#32         // bfi  x4,x5,#32,#32
+       umlal   $ACC3,$IN01_1,${R2}[0]
+        extr   x8,x12,x8,#52
+       umlal   $ACC4,$IN01_1,${R3}[0]
+        extr   x9,x13,x9,#52
+       umlal   $ACC0,$IN01_1,${S4}[0]
+        add    x6,x6,x7,lsl#32         // bfi  x6,x7,#32,#32
+       umlal   $ACC2,$IN01_1,${R1}[0]
+        fmov   $IN01_0,x4
+       umlal   $ACC1,$IN01_1,${R0}[0]
+        and    x8,x8,#0x03ffffff
+
+       add     $IN01_4,$IN01_4,$H4
+        and    x9,x9,#0x03ffffff
+       umlal   $ACC3,$IN01_3,${R0}[0]
+        ubfx   x10,x12,#14,#26
+       umlal   $ACC0,$IN01_3,${S2}[0]
+        ubfx   x11,x13,#14,#26
+       umlal   $ACC4,$IN01_3,${R1}[0]
+        add    x8,x8,x9,lsl#32         // bfi  x8,x9,#32,#32
+       umlal   $ACC1,$IN01_3,${S3}[0]
+        fmov   $IN01_1,x6
+       umlal   $ACC2,$IN01_3,${S4}[0]
+        add    x12,$padbit,x12,lsr#40
+
+       umlal   $ACC3,$IN01_4,${S4}[0]
+        add    x13,$padbit,x13,lsr#40
+       umlal   $ACC0,$IN01_4,${S1}[0]
+        add    x10,x10,x11,lsl#32      // bfi  x10,x11,#32,#32
+       umlal   $ACC4,$IN01_4,${R0}[0]
+        add    x12,x12,x13,lsl#32      // bfi  x12,x13,#32,#32
+       umlal   $ACC1,$IN01_4,${S2}[0]
+        fmov   $IN01_2,x8
+       umlal   $ACC2,$IN01_4,${S3}[0]
+        fmov   $IN01_3,x10
+        fmov   $IN01_4,x12
+
+       /////////////////////////////////////////////////////////////////
+       // lazy reduction as discussed in "NEON crypto" by D.J. Bernstein
+       // and P. Schwabe
+       //
+       // [see discussion in poly1305-armv4 module]
+
+       ushr    $T0.2d,$ACC3,#26
+       xtn     $H3,$ACC3
+        ushr   $T1.2d,$ACC0,#26
+        and    $ACC0,$ACC0,$MASK.2d
+       add     $ACC4,$ACC4,$T0.2d      // h3 -> h4
+       bic     $H3,#0xfc,lsl#24        // &=0x03ffffff
+        add    $ACC1,$ACC1,$T1.2d      // h0 -> h1
+
+       ushr    $T0.2d,$ACC4,#26
+       xtn     $H4,$ACC4
+        ushr   $T1.2d,$ACC1,#26
+        xtn    $H1,$ACC1
+       bic     $H4,#0xfc,lsl#24
+        add    $ACC2,$ACC2,$T1.2d      // h1 -> h2
+
+       add     $ACC0,$ACC0,$T0.2d
+       shl     $T0.2d,$T0.2d,#2
+        shrn   $T1.2s,$ACC2,#26
+        xtn    $H2,$ACC2
+       add     $ACC0,$ACC0,$T0.2d      // h4 -> h0
+        bic    $H1,#0xfc,lsl#24
+        add    $H3,$H3,$T1.2s          // h2 -> h3
+        bic    $H2,#0xfc,lsl#24
+
+       shrn    $T0.2s,$ACC0,#26
+       xtn     $H0,$ACC0
+        ushr   $T1.2s,$H3,#26
+        bic    $H3,#0xfc,lsl#24
+        bic    $H0,#0xfc,lsl#24
+       add     $H1,$H1,$T0.2s          // h0 -> h1
+        add    $H4,$H4,$T1.2s          // h3 -> h4
+
+       b.hi    .Loop_neon
+
+.Lskip_loop:
+       dup     $IN23_2,${IN23_2}[0]
+       add     $IN01_2,$IN01_2,$H2
+
+       ////////////////////////////////////////////////////////////////
+       // multiply (inp[0:1]+hash) or inp[2:3] by r^2:r^1
+
+       adds    $len,$len,#32
+       b.ne    .Long_tail
+
+       dup     $IN23_2,${IN01_2}[0]
+       add     $IN23_0,$IN01_0,$H0
+       add     $IN23_3,$IN01_3,$H3
+       add     $IN23_1,$IN01_1,$H1
+       add     $IN23_4,$IN01_4,$H4
+
+.Long_tail:
+       dup     $IN23_0,${IN23_0}[0]
+       umull2  $ACC0,$IN23_2,${S3}
+       umull2  $ACC3,$IN23_2,${R1}
+       umull2  $ACC4,$IN23_2,${R2}
+       umull2  $ACC2,$IN23_2,${R0}
+       umull2  $ACC1,$IN23_2,${S4}
+
+       dup     $IN23_1,${IN23_1}[0]
+       umlal2  $ACC0,$IN23_0,${R0}
+       umlal2  $ACC2,$IN23_0,${R2}
+       umlal2  $ACC3,$IN23_0,${R3}
+       umlal2  $ACC4,$IN23_0,${R4}
+       umlal2  $ACC1,$IN23_0,${R1}
+
+       dup     $IN23_3,${IN23_3}[0]
+       umlal2  $ACC0,$IN23_1,${S4}
+       umlal2  $ACC3,$IN23_1,${R2}
+       umlal2  $ACC2,$IN23_1,${R1}
+       umlal2  $ACC4,$IN23_1,${R3}
+       umlal2  $ACC1,$IN23_1,${R0}
+
+       dup     $IN23_4,${IN23_4}[0]
+       umlal2  $ACC3,$IN23_3,${R0}
+       umlal2  $ACC4,$IN23_3,${R1}
+       umlal2  $ACC0,$IN23_3,${S2}
+       umlal2  $ACC1,$IN23_3,${S3}
+       umlal2  $ACC2,$IN23_3,${S4}
+
+       umlal2  $ACC3,$IN23_4,${S4}
+       umlal2  $ACC0,$IN23_4,${S1}
+       umlal2  $ACC4,$IN23_4,${R0}
+       umlal2  $ACC1,$IN23_4,${S2}
+       umlal2  $ACC2,$IN23_4,${S3}
+
+       b.eq    .Lshort_tail
+
+       ////////////////////////////////////////////////////////////////
+       // (hash+inp[0:1])*r^4:r^3 and accumulate
+
+       add     $IN01_0,$IN01_0,$H0
+       umlal   $ACC3,$IN01_2,${R1}
+       umlal   $ACC0,$IN01_2,${S3}
+       umlal   $ACC4,$IN01_2,${R2}
+       umlal   $ACC1,$IN01_2,${S4}
+       umlal   $ACC2,$IN01_2,${R0}
+
+       add     $IN01_1,$IN01_1,$H1
+       umlal   $ACC3,$IN01_0,${R3}
+       umlal   $ACC0,$IN01_0,${R0}
+       umlal   $ACC4,$IN01_0,${R4}
+       umlal   $ACC1,$IN01_0,${R1}
+       umlal   $ACC2,$IN01_0,${R2}
+
+       add     $IN01_3,$IN01_3,$H3
+       umlal   $ACC3,$IN01_1,${R2}
+       umlal   $ACC0,$IN01_1,${S4}
+       umlal   $ACC4,$IN01_1,${R3}
+       umlal   $ACC1,$IN01_1,${R0}
+       umlal   $ACC2,$IN01_1,${R1}
+
+       add     $IN01_4,$IN01_4,$H4
+       umlal   $ACC3,$IN01_3,${R0}
+       umlal   $ACC0,$IN01_3,${S2}
+       umlal   $ACC4,$IN01_3,${R1}
+       umlal   $ACC1,$IN01_3,${S3}
+       umlal   $ACC2,$IN01_3,${S4}
+
+       umlal   $ACC3,$IN01_4,${S4}
+       umlal   $ACC0,$IN01_4,${S1}
+       umlal   $ACC4,$IN01_4,${R0}
+       umlal   $ACC1,$IN01_4,${S2}
+       umlal   $ACC2,$IN01_4,${S3}
+
+.Lshort_tail:
+       ////////////////////////////////////////////////////////////////
+       // horizontal add
+
+       addp    $ACC3,$ACC3,$ACC3
+        ldp    d8,d9,[sp,#16]          // meet ABI requirements
+       addp    $ACC0,$ACC0,$ACC0
+        ldp    d10,d11,[sp,#32]
+       addp    $ACC4,$ACC4,$ACC4
+        ldp    d12,d13,[sp,#48]
+       addp    $ACC1,$ACC1,$ACC1
+        ldp    d14,d15,[sp,#64]
+       addp    $ACC2,$ACC2,$ACC2
+        ldr    x30,[sp,#8]
+
+       ////////////////////////////////////////////////////////////////
+       // lazy reduction, but without narrowing
+
+       ushr    $T0.2d,$ACC3,#26
+       and     $ACC3,$ACC3,$MASK.2d
+        ushr   $T1.2d,$ACC0,#26
+        and    $ACC0,$ACC0,$MASK.2d
+
+       add     $ACC4,$ACC4,$T0.2d      // h3 -> h4
+        add    $ACC1,$ACC1,$T1.2d      // h0 -> h1
+
+       ushr    $T0.2d,$ACC4,#26
+       and     $ACC4,$ACC4,$MASK.2d
+        ushr   $T1.2d,$ACC1,#26
+        and    $ACC1,$ACC1,$MASK.2d
+        add    $ACC2,$ACC2,$T1.2d      // h1 -> h2
+
+       add     $ACC0,$ACC0,$T0.2d
+       shl     $T0.2d,$T0.2d,#2
+        ushr   $T1.2d,$ACC2,#26
+        and    $ACC2,$ACC2,$MASK.2d
+       add     $ACC0,$ACC0,$T0.2d      // h4 -> h0
+        add    $ACC3,$ACC3,$T1.2d      // h2 -> h3
+
+       ushr    $T0.2d,$ACC0,#26
+       and     $ACC0,$ACC0,$MASK.2d
+        ushr   $T1.2d,$ACC3,#26
+        and    $ACC3,$ACC3,$MASK.2d
+       add     $ACC1,$ACC1,$T0.2d      // h0 -> h1
+        add    $ACC4,$ACC4,$T1.2d      // h3 -> h4
+
+       ////////////////////////////////////////////////////////////////
+       // write the result, can be partially reduced
+
+       st4     {$ACC0,$ACC1,$ACC2,$ACC3}[0],[$ctx],#16
+       mov     x4,#1
+       st1     {$ACC4}[0],[$ctx]
+       str     x4,[$ctx,#8]            // set is_base2_26
+
+       ldr     x29,[sp],#80
+        .inst  0xd50323bf              // autiasp
+       ret
+.size  poly1305_blocks_neon,.-poly1305_blocks_neon
+
+.pushsection .rodata
+.align 5
+.Lzeros:
+.long  0,0,0,0,0,0,0,0
+.asciz "Poly1305 for ARMv8, CRYPTOGAMS by \@dot-asm"
+.popsection
+
+.align 2
+#if !defined(__KERNEL__) && !defined(_WIN64)
+.comm  OPENSSL_armcap_P,4,4
+.hidden        OPENSSL_armcap_P
+#endif
+___
+
+foreach (split("\n",$code)) {
+       s/\b(shrn\s+v[0-9]+)\.[24]d/$1.2s/                      or
+       s/\b(fmov\s+)v([0-9]+)[^,]*,\s*x([0-9]+)/$1d$2,x$3/     or
+       (m/\bdup\b/ and (s/\.[24]s/.2d/g or 1))                 or
+       (m/\b(eor|and)/ and (s/\.[248][sdh]/.16b/g or 1))       or
+       (m/\bum(ul|la)l\b/ and (s/\.4s/.2s/g or 1))             or
+       (m/\bum(ul|la)l2\b/ and (s/\.2s/.4s/g or 1))            or
+       (m/\bst[1-4]\s+{[^}]+}\[/ and (s/\.[24]d/.s/g or 1));
+
+       s/\.[124]([sd])\[/.$1\[/;
+       s/w#x([0-9]+)/w$1/g;
+
+       print $_,"\n";
+}
+close STDOUT;
diff --git a/arch/arm64/lib/crypto/poly1305-glue.c b/arch/arm64/lib/crypto/poly1305-glue.c
new file mode 100644 (file)
index 0000000..906970d
--- /dev/null
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * OpenSSL/Cryptogams accelerated Poly1305 transform for arm64
+ *
+ * Copyright (C) 2019 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ */
+
+#include <asm/hwcap.h>
+#include <asm/neon.h>
+#include <asm/simd.h>
+#include <crypto/poly1305.h>
+#include <crypto/internal/simd.h>
+#include <linux/cpufeature.h>
+#include <linux/jump_label.h>
+#include <linux/module.h>
+#include <linux/unaligned.h>
+
+asmlinkage void poly1305_init_arm64(void *state, const u8 *key);
+asmlinkage void poly1305_blocks(void *state, const u8 *src, u32 len, u32 hibit);
+asmlinkage void poly1305_blocks_neon(void *state, const u8 *src, u32 len, u32 hibit);
+asmlinkage void poly1305_emit(void *state, u8 *digest, const u32 *nonce);
+
+static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_neon);
+
+void poly1305_init_arch(struct poly1305_desc_ctx *dctx, const u8 key[POLY1305_KEY_SIZE])
+{
+       poly1305_init_arm64(&dctx->h, key);
+       dctx->s[0] = get_unaligned_le32(key + 16);
+       dctx->s[1] = get_unaligned_le32(key + 20);
+       dctx->s[2] = get_unaligned_le32(key + 24);
+       dctx->s[3] = get_unaligned_le32(key + 28);
+       dctx->buflen = 0;
+}
+EXPORT_SYMBOL(poly1305_init_arch);
+
+void poly1305_update_arch(struct poly1305_desc_ctx *dctx, const u8 *src,
+                         unsigned int nbytes)
+{
+       if (unlikely(dctx->buflen)) {
+               u32 bytes = min(nbytes, POLY1305_BLOCK_SIZE - dctx->buflen);
+
+               memcpy(dctx->buf + dctx->buflen, src, bytes);
+               src += bytes;
+               nbytes -= bytes;
+               dctx->buflen += bytes;
+
+               if (dctx->buflen == POLY1305_BLOCK_SIZE) {
+                       poly1305_blocks(&dctx->h, dctx->buf, POLY1305_BLOCK_SIZE, 1);
+                       dctx->buflen = 0;
+               }
+       }
+
+       if (likely(nbytes >= POLY1305_BLOCK_SIZE)) {
+               unsigned int len = round_down(nbytes, POLY1305_BLOCK_SIZE);
+
+               if (static_branch_likely(&have_neon) && crypto_simd_usable()) {
+                       do {
+                               unsigned int todo = min_t(unsigned int, len, SZ_4K);
+
+                               kernel_neon_begin();
+                               poly1305_blocks_neon(&dctx->h, src, todo, 1);
+                               kernel_neon_end();
+
+                               len -= todo;
+                               src += todo;
+                       } while (len);
+               } else {
+                       poly1305_blocks(&dctx->h, src, len, 1);
+                       src += len;
+               }
+               nbytes %= POLY1305_BLOCK_SIZE;
+       }
+
+       if (unlikely(nbytes)) {
+               dctx->buflen = nbytes;
+               memcpy(dctx->buf, src, nbytes);
+       }
+}
+EXPORT_SYMBOL(poly1305_update_arch);
+
+void poly1305_final_arch(struct poly1305_desc_ctx *dctx, u8 *dst)
+{
+       if (unlikely(dctx->buflen)) {
+               dctx->buf[dctx->buflen++] = 1;
+               memset(dctx->buf + dctx->buflen, 0,
+                      POLY1305_BLOCK_SIZE - dctx->buflen);
+               poly1305_blocks(&dctx->h, dctx->buf, POLY1305_BLOCK_SIZE, 0);
+       }
+
+       poly1305_emit(&dctx->h, dst, dctx->s);
+       memzero_explicit(dctx, sizeof(*dctx));
+}
+EXPORT_SYMBOL(poly1305_final_arch);
+
+bool poly1305_is_arch_optimized(void)
+{
+       /* We always can use at least the ARM64 scalar implementation. */
+       return true;
+}
+EXPORT_SYMBOL(poly1305_is_arch_optimized);
+
+static int __init neon_poly1305_mod_init(void)
+{
+       if (cpu_have_named_feature(ASIMD))
+               static_branch_enable(&have_neon);
+       return 0;
+}
+arch_initcall(neon_poly1305_mod_init);
+
+static void __exit neon_poly1305_mod_exit(void)
+{
+}
+module_exit(neon_poly1305_mod_exit);
+
+MODULE_DESCRIPTION("Poly1305 authenticator (ARM64 optimized)");
+MODULE_LICENSE("GPL v2");
index 59135009e4f02c49f385b391966d581d56d0a4a5..7395234d654b798a0fcfe85b866ef297fadb2129 100644 (file)
@@ -159,6 +159,9 @@ if !KMSAN # avoid false positives from assembly
 if ARM
 source "arch/arm/lib/crypto/Kconfig"
 endif
+if ARM64
+source "arch/arm64/lib/crypto/Kconfig"
+endif
 endif
 
 endmenu