[PATCH 07/12] sm3: add RISC-V Zvksh intrinsics implementation
Jussi Kivilinna
jussi.kivilinna at iki.fi
Sun Oct 11 19:23:16 CEST 2026
* cipher/Makefile.am: Add 'sm3-riscv-zvksh-zvkb.c',
'sm3-riscv-zvksh-zvkb-m1.c' and 'sm3-riscv-zvksh-zvkb.h'.
(riscv_vector_crypto_sm3_cflags)
(riscv_vector_crypto_sm3_m1_cflags): New.
* cipher/sm3-riscv-zvksh-zvkb.c: New.
* cipher/sm3-riscv-zvksh-zvkb-m1.c: New.
* cipher/sm3-riscv-zvksh-zvkb.h: New.
* cipher/sm3.c (USE_RISCV_V_CRYPTO): New.
[USE_RISCV_V_CRYPTO] (_gcry_sm3_riscv_v_check_hw)
(_gcry_sm3_transform_riscv_zvksh_zvkb)
(do_sm3_transform_riscv_zvksh): New.
(sm3_init) [USE_RISCV_V_CRYPTO]: Enable new implementation if supported
by HW.
* configure.ac: Add 'sm3-riscv-zvksh-zvkb.lo' and
'sm3-riscv-zvksh-zvkb-m1.lo'.
(GCRY_RISCV_VECTOR_CRYPTO_INTRINSICS_TEST): Add SM3 intrinsics test.
* doc/gcrypt.texi: Add "riscv-zvksh".
* src/g10lib.h [HAVE_CPU_ARCH_RISCV] (HWF_RISCV_ZVKSH): New.
* src/hwf-riscv.c (HWF_RISCV_HWPROBE_EXT_ZVKSH): New.
(hwprobe_features): Add Zvksh.
* src/hwfeatures.c (hwflist) [HAVE_CPU_ARCH_RISCV]: Add "riscv-zvksh".
--
LMUL=1 is used with VLEN>=256 and LMUL=2 with VLEN=128. clang requires
zvl256b for LMUL=1 SM3 intrinsics, so LMUL=1 variant is placed in
separate file compiled with zvl256b. LMUL=2 variant and code-path
selection are compiled without zvl256b as they run on VLEN=128.
Benchmark on SpacemiT K3, X100 core (out-of-order, VLEN=256):
Before:
| nanosecs/byte mebibytes/sec cycles/byte auto Mhz
SM3 | 6.29 ns/B 151.5 MiB/s 12.56 c/B 1996
After (~4.2x faster):
| nanosecs/byte mebibytes/sec cycles/byte auto Mhz
SM3 | 1.49 ns/B 639.1 MiB/s 2.98 c/B 1997
Benchmark on SpacemiT K3, A100 core (in-order, VLEN=1024):
Before:
| nanosecs/byte mebibytes/sec cycles/byte auto Mhz
SM3 | 11.71 ns/B 81.42 MiB/s 21.08 c/B 1800
After (~2.8x faster):
| nanosecs/byte mebibytes/sec cycles/byte auto Mhz
SM3 | 4.16 ns/B 229.0 MiB/s 7.50 c/B 1800
Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
cipher/Makefile.am | 23 +++++-
cipher/sm3-riscv-zvksh-zvkb-m1.c | 58 ++++++++++++++
cipher/sm3-riscv-zvksh-zvkb.c | 75 ++++++++++++++++++
cipher/sm3-riscv-zvksh-zvkb.h | 126 +++++++++++++++++++++++++++++++
cipher/sm3.c | 35 +++++++++
configure.ac | 22 ++++++
doc/gcrypt.texi | 1 +
src/g10lib.h | 1 +
src/hwf-riscv.c | 2 +
src/hwfeatures.c | 1 +
10 files changed, 343 insertions(+), 1 deletion(-)
create mode 100644 cipher/sm3-riscv-zvksh-zvkb-m1.c
create mode 100644 cipher/sm3-riscv-zvksh-zvkb.c
create mode 100644 cipher/sm3-riscv-zvksh-zvkb.h
diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index 6c51ee94..50509914 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -158,7 +158,8 @@ EXTRA_libcipher_la_SOURCES = \
sha512-riscv-zvknhb-zvkb-m1.c \
sha512-ssse3-i386.c \
sm3.c sm3-avx-bmi2-amd64.S sm3-intel-avx2-amd64.S sm3-aarch64.S \
- sm3-armv8-aarch64-ce.S \
+ sm3-armv8-aarch64-ce.S sm3-riscv-zvksh-zvkb.c sm3-riscv-zvksh-zvkb.h \
+ sm3-riscv-zvksh-zvkb-m1.c \
keccak.c keccak_permute_32.h keccak_permute_64.h \
keccak-armv7-neon.S keccak-amd64-avx512.S \
stribog.c \
@@ -471,6 +472,8 @@ riscv_vector_crypto_aes_cflags = -O2 -march=@MARCH_RVA23U64_BASE at _zvkned_zvkb
riscv_vector_crypto_sha256_cflags = -O2 -march=@MARCH_RVA23U64_BASE at _zvknha_zvkb
riscv_vector_crypto_sha512_cflags = -O2 -march=@MARCH_RVA23U64_BASE at _zvknhb_zvkb
riscv_vector_crypto_sha512_m1_cflags = -O2 -march=@MARCH_RVA23U64_BASE at _zvknhb_zvkb_zvl256b
+riscv_vector_crypto_sm3_cflags = -O2 -march=@MARCH_RVA23U64_BASE at _zvksh_zvkb
+riscv_vector_crypto_sm3_m1_cflags = -O2 -march=@MARCH_RVA23U64_BASE at _zvksh_zvkb_zvl256b
riscv_vector_crypto_gcm_cflags = -O2 -march=@MARCH_RVA23U64_BASE at _zvkg_zvkb
else
riscv_vector_crypto_zvkb_cflags =
@@ -478,6 +481,8 @@ riscv_vector_crypto_aes_cflags =
riscv_vector_crypto_sha256_cflags =
riscv_vector_crypto_sha512_cflags =
riscv_vector_crypto_sha512_m1_cflags =
+riscv_vector_crypto_sm3_cflags =
+riscv_vector_crypto_sm3_m1_cflags =
riscv_vector_crypto_gcm_cflags =
endif
@@ -528,3 +533,19 @@ sha512-riscv-zvknhb-zvkb-m1.o: $(srcdir)/sha512-riscv-zvknhb-zvkb-m1.c Makefile
sha512-riscv-zvknhb-zvkb-m1.lo: $(srcdir)/sha512-riscv-zvknhb-zvkb-m1.c Makefile
`echo $(LTCOMPILE) $(riscv_vector_crypto_sha512_m1_cflags) $(custom_depflags) -c $< | $(instrumentation_munging) `
$(custom_depfile_lo)
+
+sm3-riscv-zvksh-zvkb.o: $(srcdir)/sm3-riscv-zvksh-zvkb.c Makefile
+ `echo $(COMPILE) $(riscv_vector_crypto_sm3_cflags) $(custom_depflags) -c $< | $(instrumentation_munging) `
+ $(custom_depfile_o)
+
+sm3-riscv-zvksh-zvkb.lo: $(srcdir)/sm3-riscv-zvksh-zvkb.c Makefile
+ `echo $(LTCOMPILE) $(riscv_vector_crypto_sm3_cflags) $(custom_depflags) -c $< | $(instrumentation_munging) `
+ $(custom_depfile_lo)
+
+sm3-riscv-zvksh-zvkb-m1.o: $(srcdir)/sm3-riscv-zvksh-zvkb-m1.c Makefile
+ `echo $(COMPILE) $(riscv_vector_crypto_sm3_m1_cflags) $(custom_depflags) -c $< | $(instrumentation_munging) `
+ $(custom_depfile_o)
+
+sm3-riscv-zvksh-zvkb-m1.lo: $(srcdir)/sm3-riscv-zvksh-zvkb-m1.c Makefile
+ `echo $(LTCOMPILE) $(riscv_vector_crypto_sm3_m1_cflags) $(custom_depflags) -c $< | $(instrumentation_munging) `
+ $(custom_depfile_lo)
diff --git a/cipher/sm3-riscv-zvksh-zvkb-m1.c b/cipher/sm3-riscv-zvksh-zvkb-m1.c
new file mode 100644
index 00000000..278037a5
--- /dev/null
+++ b/cipher/sm3-riscv-zvksh-zvkb-m1.c
@@ -0,0 +1,58 @@
+/* sm3-riscv-zvksh-zvkb-m1.c - RISC-V vector crypto SM3, VLEN>=256 variant
+ * 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_SM3)
+
+#include "g10lib.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
+
+
+#define SM3_LMUL m1
+#include "sm3-riscv-zvksh-zvkb.h"
+
+unsigned int
+_gcry_sm3_transform_riscv_zvksh_zvkb_m1(u32 state[8],
+ const unsigned char *input_data,
+ size_t num_blks)
+{
+ return sm3_transform_zvksh_zvkb_m1(state, input_data, num_blks);
+}
+
+#endif /* HAVE_COMPATIBLE_CC_RISCV_VECTOR_INTRINSICS */
diff --git a/cipher/sm3-riscv-zvksh-zvkb.c b/cipher/sm3-riscv-zvksh-zvkb.c
new file mode 100644
index 00000000..fca9651e
--- /dev/null
+++ b/cipher/sm3-riscv-zvksh-zvkb.c
@@ -0,0 +1,75 @@
+/* sm3-riscv-zvksh-zvkb.c - RISC-V vector crypto implementation of SM3
+ * 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_SM3)
+
+#include "g10lib.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
+
+
+/* m2 variant for VLEN == 128 */
+#define SM3_LMUL m2
+#include "sm3-riscv-zvksh-zvkb.h"
+
+/* m1 variant for VLEN >= 256, compiled separately with zvl256b */
+extern unsigned int
+_gcry_sm3_transform_riscv_zvksh_zvkb_m1(u32 state[8],
+ const unsigned char *input_data,
+ size_t num_blks);
+
+unsigned int
+_gcry_sm3_transform_riscv_zvksh_zvkb(u32 state[8],
+ const unsigned char *input_data,
+ size_t num_blks)
+{
+ if (__riscv_vsetvlmax_e8m1() >= 32)
+ return _gcry_sm3_transform_riscv_zvksh_zvkb_m1(state, input_data,
+ num_blks);
+ else
+ return sm3_transform_zvksh_zvkb_m2(state, input_data, num_blks);
+}
+
+unsigned int ASM_FUNC_ATTR FUNC_ATTR_OPT_O2
+_gcry_sm3_riscv_v_check_hw(void)
+{
+ return (__riscv_vsetvl_e32m2(8) == 8);
+}
+
+#endif /* HAVE_COMPATIBLE_CC_RISCV_VECTOR_INTRINSICS */
diff --git a/cipher/sm3-riscv-zvksh-zvkb.h b/cipher/sm3-riscv-zvksh-zvkb.h
new file mode 100644
index 00000000..ec22cda7
--- /dev/null
+++ b/cipher/sm3-riscv-zvksh-zvkb.h
@@ -0,0 +1,126 @@
+/* sm3-riscv-zvksh-zvkb.h - RISC-V vector crypto SM3 LMUL template
+ * 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/>.
+ */
+
+/* Included once for each LMUL with SM3_LMUL set. */
+
+#define CAT_(a, b) a##b
+#define CAT(a, b) CAT_(a, b)
+
+#define FN(name) CAT(name##_, SM3_LMUL)
+#define V(name) CAT(__riscv_##name##_u32, SM3_LMUL)
+#define V8(name) CAT(__riscv_##name##_u8, SM3_LMUL)
+#define VEC_T CAT(CAT(vuint32, SM3_LMUL), _t)
+
+
+/* Prepare vsm3c message inputs for eight rounds from W[j..j+7] in 'wa'
+ * and W[j+8..j+15] in 'wb'. vsm3c takes W[i], W[i+1] from elements 0-1
+ * and W[i+4], W[i+5] from elements 4-5. */
+#define PREP_W(wa, wb, s1, s2, s3) \
+ s1 = __riscv_vslidedown(wa, 2, vl); \
+ s2 = __riscv_vslidedown(wa, 4, vl); \
+ s2 = __riscv_vslideup(s2, wb, 4, vl); \
+ s3 = __riscv_vslidedown(s2, 2, vl);
+
+/* Eight rounds with message inputs 'wa', 's1', 's2' and 's3'. */
+#define EIGHT_ROUNDS(wa, s1, s2, s3, rnds, prep_next, expand) \
+ v_hash_work = __riscv_vsm3c(v_hash_work, wa, (rnds) + 0, vl); \
+ prep_next; \
+ v_hash_work = __riscv_vsm3c(v_hash_work, s1, (rnds) + 1, vl); \
+ expand; \
+ v_hash_work = __riscv_vsm3c(v_hash_work, s2, (rnds) + 2, vl); \
+ v_hash_work = __riscv_vsm3c(v_hash_work, s3, (rnds) + 3, vl);
+
+
+static ASM_FUNC_ATTR_INLINE VEC_T
+FN(load_msg) (const byte *p, size_t vl)
+{
+#ifdef RVV_UNALIGNED_NOT_ALLOWED
+ return V(vreinterpret)(V8(vle8_v)(p, vl * 4));
+#else
+ return V(vle32_v)((const void *)p, vl);
+#endif
+}
+
+static ASM_FUNC_ATTR_NOINLINE FUNC_ATTR_OPT_O2 unsigned int
+FN(sm3_transform_zvksh_zvkb) (u32 state[8], const byte *data, size_t nblocks)
+{
+ size_t vl;
+ VEC_T v_hash, v_hash_work;
+ VEC_T w0, w1, w2;
+ VEC_T a1, a2, a3, b1, b2, b3;
+
+ vl = 8;
+
+ /* State is kept in big-endian byte order. */
+ v_hash = __riscv_vrev8(V(vle32_v)(state, vl), vl);
+
+ while (nblocks > 0)
+ {
+ v_hash_work = v_hash;
+
+ w0 = FN(load_msg)(data + 0, vl);
+ w1 = FN(load_msg)(data + 32, vl);
+
+ w2 = __riscv_vsm3me(w1, w0, vl);
+ PREP_W(w0, w1, a1, a2, a3);
+
+ EIGHT_ROUNDS(w0, a1, a2, a3, 0,
+ PREP_W(w1, w2, b1, b2, b3),
+ w0 = __riscv_vsm3me(w2, w1, vl));
+ EIGHT_ROUNDS(w1, b1, b2, b3, 4,
+ PREP_W(w2, w0, a1, a2, a3),
+ w1 = __riscv_vsm3me(w0, w2, vl));
+ EIGHT_ROUNDS(w2, a1, a2, a3, 8,
+ PREP_W(w0, w1, b1, b2, b3),
+ w2 = __riscv_vsm3me(w1, w0, vl));
+ EIGHT_ROUNDS(w0, b1, b2, b3, 12,
+ PREP_W(w1, w2, a1, a2, a3),
+ w0 = __riscv_vsm3me(w2, w1, vl));
+ EIGHT_ROUNDS(w1, a1, a2, a3, 16,
+ PREP_W(w2, w0, b1, b2, b3),
+ w1 = __riscv_vsm3me(w0, w2, vl));
+ EIGHT_ROUNDS(w2, b1, b2, b3, 20,
+ PREP_W(w0, w1, a1, a2, a3),
+ w2 = __riscv_vsm3me(w1, w0, vl));
+ EIGHT_ROUNDS(w0, a1, a2, a3, 24,
+ PREP_W(w1, w2, b1, b2, b3),
+ (void)0);
+ EIGHT_ROUNDS(w1, b1, b2, b3, 28, (void)0, (void)0);
+
+ v_hash = __riscv_vxor(v_hash, v_hash_work, vl);
+
+ data += 64;
+ nblocks--;
+ }
+
+ __riscv_vse32(state, __riscv_vrev8(v_hash, vl), vl);
+
+ clear_vec_regs();
+ return 0;
+}
+
+#undef EIGHT_ROUNDS
+#undef PREP_W
+#undef VEC_T
+#undef V8
+#undef V
+#undef FN
+#undef CAT
+#undef CAT_
+#undef SM3_LMUL
diff --git a/cipher/sm3.c b/cipher/sm3.c
index 6001afff..8e1e71ed 100644
--- a/cipher/sm3.c
+++ b/cipher/sm3.c
@@ -87,6 +87,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
+
typedef struct {
gcry_md_block_ctx_t bctx;
@@ -167,6 +176,23 @@ do_sm3_transform_armv8_ce(void *context, const unsigned char *data,
}
#endif /* USE_ARM_CE */
+#ifdef USE_RISCV_V_CRYPTO
+unsigned int _gcry_sm3_riscv_v_check_hw(void);
+
+unsigned int
+_gcry_sm3_transform_riscv_zvksh_zvkb(u32 state[8],
+ const unsigned char *input_data,
+ size_t num_blks);
+
+static unsigned int
+do_sm3_transform_riscv_zvksh(void *ctx, const unsigned char *data,
+ size_t nblks)
+{
+ SM3_CONTEXT *hd = ctx;
+ return _gcry_sm3_transform_riscv_zvksh_zvkb (hd->h, data, nblks);
+}
+#endif /* USE_RISCV_V_CRYPTO */
+
static unsigned int
transform (void *c, const unsigned char *data, size_t nblks);
@@ -211,6 +237,15 @@ sm3_init (void *context, unsigned int flags)
if (features & HWF_ARM_SM3)
hd->bctx.bwrite = do_sm3_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) */
+ && (features & HWF_RISCV_ZVKSH) /* Optional in RVA23U64 (Zvks) */
+ && _gcry_sm3_riscv_v_check_hw())
+ hd->bctx.bwrite = do_sm3_transform_riscv_zvksh;
+#endif
(void)features;
}
diff --git a/configure.ac b/configure.ac
index e32519c9..a6b1f325 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3038,6 +3038,22 @@ m4_define([GCRY_RISCV_VECTOR_CRYPTO_INTRINSICS_TEST],
vuint32m1_t d = __riscv_vghsh_vv_u32m1(a, b, c, vl);
__riscv_vse32_v_u32m1(ptr + 0 * vl, d, vl);
}
+ void test_sm3(unsigned int *ptr)
+ {
+ int vl = __riscv_vsetvl_e32m2 (8);
+ vuint32m2_t a = __riscv_vle32_v_u32m2(ptr + 0 * vl, vl);
+ vuint32m2_t b = __riscv_vle32_v_u32m2(ptr + 1 * vl, vl);
+ vuint32m2_t c = __riscv_vsm3me_vv_u32m2(a, b, vl);
+ vuint32m2_t d = __riscv_vsm3c_vi_u32m2(a, c, 31, vl);
+ vuint32m1_t e, f, g;
+ __riscv_vse32_v_u32m2(ptr + 0 * vl, d, vl);
+ vl = __riscv_vsetvl_e32m1 (8);
+ e = __riscv_vle32_v_u32m1(ptr + 0 * vl, vl);
+ f = __riscv_vle32_v_u32m1(ptr + 1 * vl, vl);
+ g = __riscv_vsm3me_vv_u32m1(e, f, vl);
+ e = __riscv_vsm3c_vi_u32m1(e, g, 31, vl);
+ __riscv_vse32_v_u32m1(ptr + 0 * vl, e, vl);
+ }
void test_rev8(unsigned int *ptr)
{
int vl = __riscv_vsetvl_e32m1 (4);
@@ -3076,6 +3092,7 @@ m4_define([GCRY_RISCV_VECTOR_CRYPTO_INTRINSICS_TEST],
test_aes_key(buf);
test_aes_crypt(buf);
test_ghash(buf);
+ test_sm3(buf);
test_rev8(buf);
test_rotate(buf);
test_inline_vec_asm(buf);
@@ -4269,6 +4286,11 @@ if test "$found" = "1" ; then
GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sm3-aarch64.lo"
GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sm3-armv8-aarch64-ce.lo"
;;
+ riscv64-*-*)
+ # Build with the RISC-V vector cryptography implementation
+ GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sm3-riscv-zvksh-zvkb.lo"
+ GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sm3-riscv-zvksh-zvkb-m1.lo"
+ ;;
esac
fi
diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi
index 8497bf4d..613920d8 100644
--- a/doc/gcrypt.texi
+++ b/doc/gcrypt.texi
@@ -623,6 +623,7 @@ are
@item riscv-zvkned
@item riscv-zvknha
@item riscv-zvknhb
+ at item riscv-zvksh
@end table
To disable a feature for all processes using Libgcrypt 1.6 or newer,
diff --git a/src/g10lib.h b/src/g10lib.h
index 0b4ca0c7..8a2d706c 100644
--- a/src/g10lib.h
+++ b/src/g10lib.h
@@ -288,6 +288,7 @@ char **_gcry_strtokenize (const char *string, const char *delim);
#define HWF_RISCV_ZVKNED (1 << 7)
#define HWF_RISCV_ZVKNHA (1 << 8)
#define HWF_RISCV_ZVKNHB (1 << 9)
+#define HWF_RISCV_ZVKSH (1 << 10)
#endif
diff --git a/src/hwf-riscv.c b/src/hwf-riscv.c
index 43a9cab4..adec2b02 100644
--- a/src/hwf-riscv.c
+++ b/src/hwf-riscv.c
@@ -197,6 +197,7 @@ detect_riscv_at_hwcap(void)
#define HWF_RISCV_HWPROBE_EXT_ZVKNED (1U << 21)
#define HWF_RISCV_HWPROBE_EXT_ZVKNHA (1U << 22)
#define HWF_RISCV_HWPROBE_EXT_ZVKNHB (1U << 23)
+#define HWF_RISCV_HWPROBE_EXT_ZVKSH (1U << 25)
#define HWF_RISCV_HWPROBE_EXT_ZICOND (U64_C(1) << 35)
#define HWF_RISCV_HWPROBE_IMA_FDC (HWF_RISCV_HWPROBE_IMA_FD \
@@ -227,6 +228,7 @@ static const struct hwprobe_feature_map_s hwprobe_features[] =
{ HWF_RISCV_HWPROBE_EXT_ZVKNED, HWF_RISCV_ZVKNED },
{ HWF_RISCV_HWPROBE_EXT_ZVKNHA, HWF_RISCV_ZVKNHA },
{ HWF_RISCV_HWPROBE_EXT_ZVKNHB, HWF_RISCV_ZVKNHB },
+ { HWF_RISCV_HWPROBE_EXT_ZVKSH, HWF_RISCV_ZVKSH },
};
static int
diff --git a/src/hwfeatures.c b/src/hwfeatures.c
index 08281feb..2f836079 100644
--- a/src/hwfeatures.c
+++ b/src/hwfeatures.c
@@ -127,6 +127,7 @@ static struct
{ HWF_RISCV_ZVKNED, "riscv-zvkned" },
{ HWF_RISCV_ZVKNHA, "riscv-zvknha" },
{ HWF_RISCV_ZVKNHB, "riscv-zvknhb" },
+ { HWF_RISCV_ZVKSH, "riscv-zvksh" },
#endif
};
--
2.53.0
More information about the Gcrypt-devel
mailing list