[PATCH] sha1: add RISC-V Zvkb intrinsics implementation
Jussi Kivilinna
jussi.kivilinna at iki.fi
Sat Oct 17 09:39:38 CEST 2026
* cipher/Makefile.am: Add 'sha1-riscv-zvkb.c' and 'sha1-riscv-zvkb.h'.
* cipher/sha1-riscv-zvkb.c: New.
* cipher/sha1-riscv-zvkb.h: New.
* cipher/sha1.c (USE_RISCV_V_CRYPTO): New.
[USE_RISCV_V_CRYPTO] (_gcry_sha1_riscv_v_check_hw)
(_gcry_sha1_transform_riscv_zvkb, do_sha1_transform_riscv_zvkb): New.
(sha1_init) [USE_RISCV_V_CRYPTO]: Enable new implementation if supported
by HW.
* configure.ac: Add 'sha1-riscv-zvkb.lo'.
--
RISC-V vector crypto extensions do not have SHA-1 instructions. This
implementation does message expansion with vector instructions and
rounds with scalar instructions, similar to the Intel SSSE3/AVX
implementations.
One block variant is used with VLEN=128 (LMUL=1) and VLEN=256
(LMUL=1/2). With VLEN>=512, two blocks are processed in parallel with
LMUL=1/2.
Benchmark on SpacemiT K3, X100 core (out-of-order, VLEN=256):
Before:
| nanosecs/byte mebibytes/sec cycles/byte auto Mhz
SHA1 | 3.97 ns/B 240.5 MiB/s 7.92 c/B 1997
After (~1.9x faster):
| nanosecs/byte mebibytes/sec cycles/byte auto Mhz
SHA1 | 2.07 ns/B 459.7 MiB/s 4.14 c/B 1997
Benchmark on SpacemiT K3, A100 core (in-order, VLEN=1024):
Before:
| nanosecs/byte mebibytes/sec cycles/byte auto Mhz
SHA1 | 4.73 ns/B 201.5 MiB/s 8.52 c/B 1800
After (~3% faster):
| nanosecs/byte mebibytes/sec cycles/byte auto Mhz
SHA1 | 4.61 ns/B 206.8 MiB/s 8.30 c/B 1800
Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
cipher/Makefile.am | 11 +-
cipher/sha1-riscv-zvkb.c | 97 ++++++++++
cipher/sha1-riscv-zvkb.h | 404 +++++++++++++++++++++++++++++++++++++++
cipher/sha1.c | 33 ++++
configure.ac | 4 +
5 files changed, 548 insertions(+), 1 deletion(-)
create mode 100644 cipher/sha1-riscv-zvkb.c
create mode 100644 cipher/sha1-riscv-zvkb.h
diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index 65b03d76..d2007815 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -147,7 +147,8 @@ EXTRA_libcipher_la_SOURCES = \
sm4-ppc.c sm4-riscv-zvksed-zvkb.c sm4-riscv-zvksed-zvkb.h \
sha1.c sha1-ssse3-amd64.S sha1-avx-amd64.S sha1-avx-bmi2-amd64.S \
sha1-avx2-bmi2-amd64.S sha1-armv7-neon.S sha1-armv8-aarch32-ce.S \
- sha1-armv8-aarch64-ce.S sha1-intel-shaext.c \
+ sha1-armv8-aarch64-ce.S sha1-intel-shaext.c sha1-riscv-zvkb.c \
+ sha1-riscv-zvkb.h \
sha256.c sha256-ssse3-amd64.S sha256-avx-amd64.S \
sha256-avx2-bmi2-amd64.S \
sha256-armv8-aarch32-ce.S sha256-armv8-aarch64-ce.S \
@@ -538,6 +539,14 @@ rijndael-riscv-zvkned.lo: $(srcdir)/rijndael-riscv-zvkned.c Makefile
`echo $(LTCOMPILE) $(riscv_vector_crypto_aes_cflags) $(custom_depflags) -c $< | $(instrumentation_munging) `
$(custom_depfile_lo)
+sha1-riscv-zvkb.o: $(srcdir)/sha1-riscv-zvkb.c Makefile
+ `echo $(COMPILE) $(riscv_vector_crypto_zvkb_cflags) $(custom_depflags) -c $< | $(instrumentation_munging) `
+ $(custom_depfile_o)
+
+sha1-riscv-zvkb.lo: $(srcdir)/sha1-riscv-zvkb.c Makefile
+ `echo $(LTCOMPILE) $(riscv_vector_crypto_zvkb_cflags) $(custom_depflags) -c $< | $(instrumentation_munging) `
+ $(custom_depfile_lo)
+
sha256-riscv-zvknha-zvkb.o: $(srcdir)/sha256-riscv-zvknha-zvkb.c Makefile
`echo $(COMPILE) $(riscv_vector_crypto_sha256_cflags) $(custom_depflags) -c $< | $(instrumentation_munging) `
$(custom_depfile_o)
diff --git a/cipher/sha1-riscv-zvkb.c b/cipher/sha1-riscv-zvkb.c
new file mode 100644
index 00000000..02684bef
--- /dev/null
+++ b/cipher/sha1-riscv-zvkb.c
@@ -0,0 +1,97 @@
+/* sha1-riscv-zvkb.c - RISC-V vector SHA-1 with Zvkb
+ * Copyright (C) 2026 Jussi Kivilinna <jussi.kivilinna at iki.fi>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#if defined (__riscv) && \
+ defined(HAVE_COMPATIBLE_CC_RISCV_VECTOR_INTRINSICS) && \
+ defined(HAVE_COMPATIBLE_CC_RISCV_VECTOR_CRYPTO_INTRINSICS) && \
+ defined(USE_SHA1)
+
+#include "g10lib.h"
+#include "bithelp.h"
+#include "simd-common-riscv.h"
+#include <riscv_vector.h>
+
+
+#define ALWAYS_INLINE inline __attribute__((always_inline))
+#define NO_INLINE __attribute__((noinline))
+#define NO_INSTRUMENT_FUNCTION __attribute__((no_instrument_function))
+
+#define ASM_FUNC_ATTR NO_INSTRUMENT_FUNCTION
+#define ASM_FUNC_ATTR_INLINE ASM_FUNC_ATTR ALWAYS_INLINE
+#define ASM_FUNC_ATTR_NOINLINE ASM_FUNC_ATTR NO_INLINE
+
+#ifdef HAVE_GCC_ATTRIBUTE_OPTIMIZE
+# define FUNC_ATTR_OPT_O2 __attribute__((optimize("-O2")))
+#else
+# define FUNC_ATTR_OPT_O2
+#endif
+
+
+/* One block, VLEN == 128 */
+#define SHA1_LMUL m1
+#define SHA1_NBLK 1
+#include "sha1-riscv-zvkb.h"
+
+/* One block, VLEN >= 256 */
+#define SHA1_LMUL mf2
+#define SHA1_NBLK 1
+#include "sha1-riscv-zvkb.h"
+
+/* Two blocks, VLEN >= 512 */
+#define SHA1_LMUL mf2
+#define SHA1_NBLK 2
+#include "sha1-riscv-zvkb.h"
+
+unsigned int ASM_FUNC_ATTR
+_gcry_sha1_transform_riscv_zvkb(void *state_ptr,
+ const unsigned char *input_data,
+ size_t num_blks)
+{
+ u32 *state = state_ptr;
+ size_t vlenb = __riscv_vsetvlmax_e8m1();
+ unsigned int burn = 0;
+ unsigned int nburn;
+
+ if (vlenb < 32)
+ return sha1_transform_zvkb_m1x1(state, input_data, num_blks);
+
+ if (vlenb < 64 || num_blks < 2)
+ return sha1_transform_zvkb_mf2x1(state, input_data, num_blks);
+
+ if (num_blks & 1)
+ {
+ burn = sha1_transform_zvkb_mf2x1(state, input_data, 1);
+ input_data += 64;
+ num_blks--;
+ }
+
+ nburn = sha1_transform_zvkb_mf2x2(state, input_data, num_blks);
+
+ return nburn > burn ? nburn : burn;
+}
+
+unsigned int ASM_FUNC_ATTR FUNC_ATTR_OPT_O2
+_gcry_sha1_riscv_v_check_hw(void)
+{
+ return (__riscv_vsetvl_e32m1(4) == 4);
+}
+
+#endif /* HAVE_COMPATIBLE_CC_RISCV_VECTOR_INTRINSICS */
diff --git a/cipher/sha1-riscv-zvkb.h b/cipher/sha1-riscv-zvkb.h
new file mode 100644
index 00000000..dbda3452
--- /dev/null
+++ b/cipher/sha1-riscv-zvkb.h
@@ -0,0 +1,404 @@
+/* sha1-riscv-zvkb.h - RISC-V vector SHA-1 LMUL template
+ * Copyright (C) 2026 Jussi Kivilinna <jussi.kivilinna at iki.fi>
+ *
+ * Based on sha1.c:
+ * Copyright (C) 1998, 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Included once for each variant with SHA1_LMUL and SHA1_NBLK set. */
+
+#define CAT_(a, b) a##b
+#define CAT(a, b) CAT_(a, b)
+
+#define FN(name) CAT(CAT(name##_, SHA1_LMUL), CAT(x, SHA1_NBLK))
+#define V(name) CAT(__riscv_##name##_u32, SHA1_LMUL)
+#define V8(name) CAT(__riscv_##name##_u8, SHA1_LMUL)
+#define VEC_T CAT(CAT(vuint32, SHA1_LMUL), _t)
+
+#define LAST_BLK (SHA1_NBLK - 1)
+
+#define K1 0x5A827999
+#define K2 0x6ED9EBA1
+#define K3 0x8F1BBCDC
+#define K4 0xCA62C1D6
+
+#define F1(x,y,z) ( z ^ ( x & ( y ^ z ) ) )
+#define F2(x,y,z) ( x ^ y ^ z )
+#define F3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) )
+#define F4(x,y,z) ( x ^ y ^ z )
+
+#define R(a,b,c,d,e,f,i,blk) \
+ e += rol (a, 5) + f (b, c, d) + wk[(i) * SHA1_NBLK + (blk)]; \
+ b = rol (b, 30)
+
+#define UPDATE_STATE() \
+ a = (h0 += a); \
+ b = (h1 += b); \
+ c = (h2 += c); \
+ d = (h3 += d); \
+ e = (h4 += e)
+
+#define STORE_WK(i, w, k) \
+ __riscv_vse32 (wk + (i) * SHA1_NBLK, __riscv_vadd (w, k, vl), vl)
+
+#define W_00_15(i, w, k) \
+ w = FN(load_w) (data + (i) * 4, vl); \
+ STORE_WK (i, w, k)
+
+#define W_16_31(i, w, wm04, wm08, wm12, wm16, k) \
+ t0 = __riscv_vslidedown (wm16, 2 * SHA1_NBLK, vl); \
+ t0 = __riscv_vslideup (t0, wm12, 2 * SHA1_NBLK, vl); \
+ t1 = __riscv_vslidedown_tu (zero, wm04, SHA1_NBLK, vl - SHA1_NBLK); \
+ t0 = __riscv_vxor (t0, wm08, vl); \
+ t1 = __riscv_vxor (t1, wm16, vl); \
+ t0 = __riscv_vxor (t0, t1, vl); \
+ w = __riscv_vror (t0, 31, vl); \
+ t1 = __riscv_vslideup (zero, t0, 3 * SHA1_NBLK, vl); \
+ t1 = __riscv_vror (t1, 30, vl); \
+ w = __riscv_vxor (w, t1, vl); \
+ STORE_WK (i, w, k)
+
+#define W_32_79(i, w, wm04, wm08, wm16, wm28, k) \
+ t0 = __riscv_vslidedown (wm08, 2 * SHA1_NBLK, vl); \
+ t0 = __riscv_vslideup (t0, wm04, 2 * SHA1_NBLK, vl); \
+ w = __riscv_vxor (w, wm28, vl); \
+ t0 = __riscv_vxor (t0, wm16, vl); \
+ w = __riscv_vxor (w, t0, vl); \
+ w = __riscv_vror (w, 30, vl); \
+ STORE_WK (i, w, k)
+
+
+static ASM_FUNC_ATTR_INLINE VEC_T
+FN(load_w) (const byte *p, size_t vl)
+{
+ VEC_T w;
+#if SHA1_NBLK == 1
+#ifdef RVV_UNALIGNED_NOT_ALLOWED
+ w = V(vreinterpret)(V8(vle8_v)(p, vl * 4));
+#else
+ w = V(vle32_v)((const void *)p, vl);
+#endif
+#else
+ vuint32mf2_t x, y;
+ vuint64m1_t z;
+
+#ifdef RVV_UNALIGNED_NOT_ALLOWED
+ x = __riscv_vreinterpret_u32mf2 (__riscv_vle8_v_u8mf2 (p, 16));
+ y = __riscv_vreinterpret_u32mf2 (__riscv_vle8_v_u8mf2 (p + 64, 16));
+#else
+ x = __riscv_vle32_v_u32mf2 ((const void *)p, 4);
+ y = __riscv_vle32_v_u32mf2 ((const void *)(p + 64), 4);
+#endif
+ z = __riscv_vwaddu_vv_u64m1 (x, y, 4);
+ z = __riscv_vwmaccu_vx_u64m1 (z, 0xffffffffU, y, 4);
+ w = CAT(__riscv_vlmul_trunc_u32, SHA1_LMUL) (__riscv_vreinterpret_u32m1 (z));
+#endif
+ return __riscv_vrev8 (w, vl);
+}
+
+static ASM_FUNC_ATTR_NOINLINE FUNC_ATTR_OPT_O2 unsigned int
+FN(sha1_transform_zvkb) (u32 state[5], const byte *data, size_t nblks)
+{
+ const size_t vl = 4 * SHA1_NBLK;
+ u32 wk[80 * SHA1_NBLK];
+ u32 a, b, c, d, e;
+ u32 h0, h1, h2, h3, h4;
+ VEC_T w0, w1, w2, w3, w4, w5, w6, w7;
+ VEC_T t0, t1, zero;
+
+ zero = V(vmv_v_x) (0, vl);
+
+ a = h0 = state[0];
+ b = h1 = state[1];
+ c = h2 = state[2];
+ d = h3 = state[3];
+ e = h4 = state[4];
+
+ W_00_15 (0, w0, K1);
+ W_00_15 (4, w7, K1);
+ W_00_15 (8, w6, K1);
+ W_00_15 (12, w5, K1);
+ W_16_31 (16, w4, w5, w6, w7, w0, K1);
+ W_16_31 (20, w3, w4, w5, w6, w7, K2);
+ W_16_31 (24, w2, w3, w4, w5, w6, K2);
+ W_16_31 (28, w1, w2, w3, w4, w5, K2);
+
+ for (;;)
+ {
+ data += 64 * SHA1_NBLK;
+
+ R (a, b, c, d, e, F1, 0, 0);
+ R (e, a, b, c, d, F1, 1, 0);
+ R (d, e, a, b, c, F1, 2, 0);
+ R (c, d, e, a, b, F1, 3, 0);
+ W_32_79 (32, w0, w1, w2, w4, w7, K2);
+ R (b, c, d, e, a, F1, 4, 0);
+ R (a, b, c, d, e, F1, 5, 0);
+ R (e, a, b, c, d, F1, 6, 0);
+ R (d, e, a, b, c, F1, 7, 0);
+ W_32_79 (36, w7, w0, w1, w3, w6, K2);
+ R (c, d, e, a, b, F1, 8, 0);
+ R (b, c, d, e, a, F1, 9, 0);
+ R (a, b, c, d, e, F1, 10, 0);
+ R (e, a, b, c, d, F1, 11, 0);
+ W_32_79 (40, w6, w7, w0, w2, w5, K3);
+ R (d, e, a, b, c, F1, 12, 0);
+ R (c, d, e, a, b, F1, 13, 0);
+ R (b, c, d, e, a, F1, 14, 0);
+ R (a, b, c, d, e, F1, 15, 0);
+ W_32_79 (44, w5, w6, w7, w1, w4, K3);
+ R (e, a, b, c, d, F1, 16, 0);
+ R (d, e, a, b, c, F1, 17, 0);
+ R (c, d, e, a, b, F1, 18, 0);
+ R (b, c, d, e, a, F1, 19, 0);
+ W_32_79 (48, w4, w5, w6, w0, w3, K3);
+ R (a, b, c, d, e, F2, 20, 0);
+ R (e, a, b, c, d, F2, 21, 0);
+ R (d, e, a, b, c, F2, 22, 0);
+ R (c, d, e, a, b, F2, 23, 0);
+ W_32_79 (52, w3, w4, w5, w7, w2, K3);
+ R (b, c, d, e, a, F2, 24, 0);
+ R (a, b, c, d, e, F2, 25, 0);
+ R (e, a, b, c, d, F2, 26, 0);
+ R (d, e, a, b, c, F2, 27, 0);
+ W_32_79 (56, w2, w3, w4, w6, w1, K3);
+ R (c, d, e, a, b, F2, 28, 0);
+ R (b, c, d, e, a, F2, 29, 0);
+ R (a, b, c, d, e, F2, 30, 0);
+ R (e, a, b, c, d, F2, 31, 0);
+ W_32_79 (60, w1, w2, w3, w5, w0, K4);
+ R (d, e, a, b, c, F2, 32, 0);
+ R (c, d, e, a, b, F2, 33, 0);
+ R (b, c, d, e, a, F2, 34, 0);
+ R (a, b, c, d, e, F2, 35, 0);
+ W_32_79 (64, w0, w1, w2, w4, w7, K4);
+ R (e, a, b, c, d, F2, 36, 0);
+ R (d, e, a, b, c, F2, 37, 0);
+ R (c, d, e, a, b, F2, 38, 0);
+ R (b, c, d, e, a, F2, 39, 0);
+ W_32_79 (68, w7, w0, w1, w3, w6, K4);
+ R (a, b, c, d, e, F3, 40, 0);
+ R (e, a, b, c, d, F3, 41, 0);
+ R (d, e, a, b, c, F3, 42, 0);
+ R (c, d, e, a, b, F3, 43, 0);
+ W_32_79 (72, w6, w7, w0, w2, w5, K4);
+ R (b, c, d, e, a, F3, 44, 0);
+ R (a, b, c, d, e, F3, 45, 0);
+ R (e, a, b, c, d, F3, 46, 0);
+ R (d, e, a, b, c, F3, 47, 0);
+ W_32_79 (76, w5, w6, w7, w1, w4, K4);
+#if SHA1_NBLK == 2
+ R (c, d, e, a, b, F3, 48, 0);
+ R (b, c, d, e, a, F3, 49, 0);
+ R (a, b, c, d, e, F3, 50, 0);
+ R (e, a, b, c, d, F3, 51, 0);
+ R (d, e, a, b, c, F3, 52, 0);
+ R (c, d, e, a, b, F3, 53, 0);
+ R (b, c, d, e, a, F3, 54, 0);
+ R (a, b, c, d, e, F3, 55, 0);
+ R (e, a, b, c, d, F3, 56, 0);
+ R (d, e, a, b, c, F3, 57, 0);
+ R (c, d, e, a, b, F3, 58, 0);
+ R (b, c, d, e, a, F3, 59, 0);
+ R (a, b, c, d, e, F4, 60, 0);
+ R (e, a, b, c, d, F4, 61, 0);
+ R (d, e, a, b, c, F4, 62, 0);
+ R (c, d, e, a, b, F4, 63, 0);
+ R (b, c, d, e, a, F4, 64, 0);
+ R (a, b, c, d, e, F4, 65, 0);
+ R (e, a, b, c, d, F4, 66, 0);
+ R (d, e, a, b, c, F4, 67, 0);
+ R (c, d, e, a, b, F4, 68, 0);
+ R (b, c, d, e, a, F4, 69, 0);
+ R (a, b, c, d, e, F4, 70, 0);
+ R (e, a, b, c, d, F4, 71, 0);
+ R (d, e, a, b, c, F4, 72, 0);
+ R (c, d, e, a, b, F4, 73, 0);
+ R (b, c, d, e, a, F4, 74, 0);
+ R (a, b, c, d, e, F4, 75, 0);
+ R (e, a, b, c, d, F4, 76, 0);
+ R (d, e, a, b, c, F4, 77, 0);
+ R (c, d, e, a, b, F4, 78, 0);
+ R (b, c, d, e, a, F4, 79, 0);
+ UPDATE_STATE ();
+
+ R (a, b, c, d, e, F1, 0, 1);
+ R (e, a, b, c, d, F1, 1, 1);
+ R (d, e, a, b, c, F1, 2, 1);
+ R (c, d, e, a, b, F1, 3, 1);
+ R (b, c, d, e, a, F1, 4, 1);
+ R (a, b, c, d, e, F1, 5, 1);
+ R (e, a, b, c, d, F1, 6, 1);
+ R (d, e, a, b, c, F1, 7, 1);
+ R (c, d, e, a, b, F1, 8, 1);
+ R (b, c, d, e, a, F1, 9, 1);
+ R (a, b, c, d, e, F1, 10, 1);
+ R (e, a, b, c, d, F1, 11, 1);
+ R (d, e, a, b, c, F1, 12, 1);
+ R (c, d, e, a, b, F1, 13, 1);
+ R (b, c, d, e, a, F1, 14, 1);
+ R (a, b, c, d, e, F1, 15, 1);
+ R (e, a, b, c, d, F1, 16, 1);
+ R (d, e, a, b, c, F1, 17, 1);
+ R (c, d, e, a, b, F1, 18, 1);
+ R (b, c, d, e, a, F1, 19, 1);
+ R (a, b, c, d, e, F2, 20, 1);
+ R (e, a, b, c, d, F2, 21, 1);
+ R (d, e, a, b, c, F2, 22, 1);
+ R (c, d, e, a, b, F2, 23, 1);
+ R (b, c, d, e, a, F2, 24, 1);
+ R (a, b, c, d, e, F2, 25, 1);
+ R (e, a, b, c, d, F2, 26, 1);
+ R (d, e, a, b, c, F2, 27, 1);
+ R (c, d, e, a, b, F2, 28, 1);
+ R (b, c, d, e, a, F2, 29, 1);
+ R (a, b, c, d, e, F2, 30, 1);
+ R (e, a, b, c, d, F2, 31, 1);
+ R (d, e, a, b, c, F2, 32, 1);
+ R (c, d, e, a, b, F2, 33, 1);
+ R (b, c, d, e, a, F2, 34, 1);
+ R (a, b, c, d, e, F2, 35, 1);
+ R (e, a, b, c, d, F2, 36, 1);
+ R (d, e, a, b, c, F2, 37, 1);
+ R (c, d, e, a, b, F2, 38, 1);
+ R (b, c, d, e, a, F2, 39, 1);
+ R (a, b, c, d, e, F3, 40, 1);
+ R (e, a, b, c, d, F3, 41, 1);
+ R (d, e, a, b, c, F3, 42, 1);
+ R (c, d, e, a, b, F3, 43, 1);
+ R (b, c, d, e, a, F3, 44, 1);
+ R (a, b, c, d, e, F3, 45, 1);
+ R (e, a, b, c, d, F3, 46, 1);
+ R (d, e, a, b, c, F3, 47, 1);
+#endif
+
+ nblks -= SHA1_NBLK;
+ if (nblks == 0)
+ break;
+
+ R (c, d, e, a, b, F3, 48, LAST_BLK);
+ R (b, c, d, e, a, F3, 49, LAST_BLK);
+ R (a, b, c, d, e, F3, 50, LAST_BLK);
+ R (e, a, b, c, d, F3, 51, LAST_BLK);
+ W_00_15 (0, w0, K1);
+ R (d, e, a, b, c, F3, 52, LAST_BLK);
+ R (c, d, e, a, b, F3, 53, LAST_BLK);
+ R (b, c, d, e, a, F3, 54, LAST_BLK);
+ R (a, b, c, d, e, F3, 55, LAST_BLK);
+ W_00_15 (4, w7, K1);
+ R (e, a, b, c, d, F3, 56, LAST_BLK);
+ R (d, e, a, b, c, F3, 57, LAST_BLK);
+ R (c, d, e, a, b, F3, 58, LAST_BLK);
+ R (b, c, d, e, a, F3, 59, LAST_BLK);
+ W_00_15 (8, w6, K1);
+ R (a, b, c, d, e, F4, 60, LAST_BLK);
+ R (e, a, b, c, d, F4, 61, LAST_BLK);
+ R (d, e, a, b, c, F4, 62, LAST_BLK);
+ R (c, d, e, a, b, F4, 63, LAST_BLK);
+ W_00_15 (12, w5, K1);
+ R (b, c, d, e, a, F4, 64, LAST_BLK);
+ R (a, b, c, d, e, F4, 65, LAST_BLK);
+ R (e, a, b, c, d, F4, 66, LAST_BLK);
+ R (d, e, a, b, c, F4, 67, LAST_BLK);
+ W_16_31 (16, w4, w5, w6, w7, w0, K1);
+ R (c, d, e, a, b, F4, 68, LAST_BLK);
+ R (b, c, d, e, a, F4, 69, LAST_BLK);
+ R (a, b, c, d, e, F4, 70, LAST_BLK);
+ R (e, a, b, c, d, F4, 71, LAST_BLK);
+ W_16_31 (20, w3, w4, w5, w6, w7, K2);
+ R (d, e, a, b, c, F4, 72, LAST_BLK);
+ R (c, d, e, a, b, F4, 73, LAST_BLK);
+ R (b, c, d, e, a, F4, 74, LAST_BLK);
+ R (a, b, c, d, e, F4, 75, LAST_BLK);
+ W_16_31 (24, w2, w3, w4, w5, w6, K2);
+ R (e, a, b, c, d, F4, 76, LAST_BLK);
+ R (d, e, a, b, c, F4, 77, LAST_BLK);
+ R (c, d, e, a, b, F4, 78, LAST_BLK);
+ R (b, c, d, e, a, F4, 79, LAST_BLK);
+ W_16_31 (28, w1, w2, w3, w4, w5, K2);
+ UPDATE_STATE ();
+ }
+
+ R (c, d, e, a, b, F3, 48, LAST_BLK);
+ R (b, c, d, e, a, F3, 49, LAST_BLK);
+ R (a, b, c, d, e, F3, 50, LAST_BLK);
+ R (e, a, b, c, d, F3, 51, LAST_BLK);
+ R (d, e, a, b, c, F3, 52, LAST_BLK);
+ R (c, d, e, a, b, F3, 53, LAST_BLK);
+ R (b, c, d, e, a, F3, 54, LAST_BLK);
+ R (a, b, c, d, e, F3, 55, LAST_BLK);
+ R (e, a, b, c, d, F3, 56, LAST_BLK);
+ R (d, e, a, b, c, F3, 57, LAST_BLK);
+ R (c, d, e, a, b, F3, 58, LAST_BLK);
+ R (b, c, d, e, a, F3, 59, LAST_BLK);
+ R (a, b, c, d, e, F4, 60, LAST_BLK);
+ R (e, a, b, c, d, F4, 61, LAST_BLK);
+ R (d, e, a, b, c, F4, 62, LAST_BLK);
+ R (c, d, e, a, b, F4, 63, LAST_BLK);
+ R (b, c, d, e, a, F4, 64, LAST_BLK);
+ R (a, b, c, d, e, F4, 65, LAST_BLK);
+ R (e, a, b, c, d, F4, 66, LAST_BLK);
+ R (d, e, a, b, c, F4, 67, LAST_BLK);
+ R (c, d, e, a, b, F4, 68, LAST_BLK);
+ R (b, c, d, e, a, F4, 69, LAST_BLK);
+ R (a, b, c, d, e, F4, 70, LAST_BLK);
+ R (e, a, b, c, d, F4, 71, LAST_BLK);
+ R (d, e, a, b, c, F4, 72, LAST_BLK);
+ R (c, d, e, a, b, F4, 73, LAST_BLK);
+ R (b, c, d, e, a, F4, 74, LAST_BLK);
+ R (a, b, c, d, e, F4, 75, LAST_BLK);
+ R (e, a, b, c, d, F4, 76, LAST_BLK);
+ R (d, e, a, b, c, F4, 77, LAST_BLK);
+ R (c, d, e, a, b, F4, 78, LAST_BLK);
+ R (b, c, d, e, a, F4, 79, LAST_BLK);
+ UPDATE_STATE ();
+
+ state[0] = h0;
+ state[1] = h1;
+ state[2] = h2;
+ state[3] = h3;
+ state[4] = h4;
+
+ clear_vec_regs ();
+
+ return sizeof (wk) + 16 * sizeof (void *);
+}
+
+#undef W_32_79
+#undef W_16_31
+#undef W_00_15
+#undef STORE_WK
+#undef UPDATE_STATE
+#undef R
+#undef F4
+#undef F3
+#undef F2
+#undef F1
+#undef K4
+#undef K3
+#undef K2
+#undef K1
+#undef LAST_BLK
+#undef VEC_T
+#undef V8
+#undef V
+#undef FN
+#undef CAT
+#undef CAT_
+#undef SHA1_NBLK
+#undef SHA1_LMUL
diff --git a/cipher/sha1.c b/cipher/sha1.c
index e4069e1d..e8854b0c 100644
--- a/cipher/sha1.c
+++ b/cipher/sha1.c
@@ -107,6 +107,15 @@
# endif
#endif
+/* USE_RISCV_V_CRYPTO indicates whether to enable RISC-V vector cryptography
+ * extension code. */
+#undef USE_RISCV_V_CRYPTO
+#if defined (__riscv) && \
+ defined(HAVE_COMPATIBLE_CC_RISCV_VECTOR_INTRINSICS) && \
+ defined(HAVE_COMPATIBLE_CC_RISCV_VECTOR_CRYPTO_INTRINSICS)
+# define USE_RISCV_V_CRYPTO 1
+#endif
+
/* A macro to test whether P is properly aligned for an u32 type.
Note that config.h provides a suitable replacement for uintptr_t if
@@ -253,6 +262,22 @@ do_sha1_transform_armv8_ce (void *ctx, const unsigned char *data,
}
#endif
+#ifdef USE_RISCV_V_CRYPTO
+unsigned int _gcry_sha1_riscv_v_check_hw (void);
+
+unsigned int
+_gcry_sha1_transform_riscv_zvkb (void *state, const unsigned char *data,
+ size_t nblks);
+
+static unsigned int
+do_sha1_transform_riscv_zvkb (void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SHA1_CONTEXT *hd = ctx;
+ return _gcry_sha1_transform_riscv_zvkb (&hd->h0, data, nblks);
+}
+#endif
+
#ifdef SHA1_USE_S390X_CRYPTO
#include "asm-inline-s390x.h"
@@ -347,6 +372,14 @@ sha1_init (void *context, unsigned int flags)
if ((features & HWF_ARM_SHA1) != 0)
hd->bctx.bwrite = do_sha1_transform_armv8_ce;
#endif
+#ifdef USE_RISCV_V_CRYPTO
+ if ((features & HWF_RISCV_IMAFDC)
+ && (features & HWF_RISCV_B) /* Mandatory in RVA23U64 */
+ && (features & HWF_RISCV_V) /* Mandatory in RVA23U64 */
+ && (features & HWF_RISCV_ZVKB) /* Mandatory in RVA23U64 (Zvbb) */
+ && _gcry_sha1_riscv_v_check_hw ())
+ hd->bctx.bwrite = do_sha1_transform_riscv_zvkb;
+#endif
#ifdef SHA1_USE_S390X_CRYPTO
hd->use_s390x_crypto = 0;
if ((features & HWF_S390X_MSA) != 0)
diff --git a/configure.ac b/configure.ac
index 2371edea..fc8bcf05 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4383,6 +4383,10 @@ case "${host}" in
# Build with the assembly implementation
GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sha1-armv8-aarch64-ce.lo"
;;
+ riscv64-*-*)
+ # Build with the RISC-V vector implementation
+ GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sha1-riscv-zvkb.lo"
+ ;;
esac
case "$mpi_cpu_arch" in
--
2.53.0
More information about the Gcrypt-devel
mailing list