[PATCH 2/2] Require RISC-V B extension for vector intrinsics implementations

Jussi Kivilinna jussi.kivilinna at iki.fi
Sat Aug 16 20:36:29 CEST 2025


* cipher/Makefile.am (riscv_vector_cflags, riscv_vector_crypto_aes_cflags)
(riscv_vector_crypto_sha_cflags, riscv_vector_crypto_gcm_cflags): Use
MARCH_RVA22U64_WITH_VEC and MARCH_RVA23U64_BASE.
* cipher/chacha20.c (chacha20_do_setkey) [USE_RISCV_V]: Require HWF_RISCV_B.
* cipher/cipher-gcm.c (setupM) [GCM_UNSE_RISCV_ZVKG]: Likewise.
* cipher/rijndael.c (do_setkey) [USE_RISCV_V_CRYPTO]: Likewise.
(do_setkey) [USE_VP_RISCV]: Likewise.
* cipher/sha256.c (sha256_common_init) [USE_RISCV_V_CRYPTO]: Likewise.
* cipher/sha512.c (sha512_init_common) [USE_RISCV_V_CRYPTO]: Likewise.
* configure.ac (MARCH_RVA22U64_WITH_VEC, MARCH_RVA23U64_BASE)
(MARCH_RVA23U64_WITH_VEC_CRYPTO): New.
* src/g10lib.h (HWF_RISCV_B): Insert before HWF_RISCV_V.
* src/hwf-riscv.c (hwcap_features, hwprobe_features): Add HWF_RISCV_V.
(detect_riscv_hwf_by_toolchain) [__riscv_zba&&__riscv_zbb&&__riscv_zbs]: Add
faulty toolchain check for B extension.
* src/hwfeatures.c (hwflist) [HAVE_CPU_ARCH_RISCV]: Add "riscv-b".
--

Patch adds B extension as requirement for vector intrinsics implementations
to improve code generation. B extension is mandatory in RVA22U64 profile.
It is unlikely to encounter V extension (optional in RVA22U64, mandatory
in RVA23U64) without B extension.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
 cipher/Makefile.am  |  8 ++++----
 cipher/chacha20.c   |  3 ++-
 cipher/cipher-gcm.c |  5 +++--
 cipher/rijndael.c   |  8 +++++---
 cipher/sha256.c     |  8 +++++---
 cipher/sha512.c     |  7 ++++---
 configure.ac        | 17 +++++++++++++----
 src/g10lib.h        | 17 +++++++++--------
 src/hwf-riscv.c     | 42 ++++++++++++++++++++++++++++++++++++++++++
 src/hwfeatures.c    |  1 +
 10 files changed, 88 insertions(+), 28 deletions(-)

diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index b7a5c327..bbcd518a 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -359,7 +359,7 @@ serpent-avx512-x86.lo: $(srcdir)/serpent-avx512-x86.c Makefile
 
 # Note: -mstrict-align needed for GCC-14 bug (disable unaligned vector loads)
 if ENABLE_RISCV_VECTOR_INTRINSICS_EXTRA_CFLAGS
-riscv_vector_cflags = -O2 -march=rv64imafdcv -mstrict-align
+riscv_vector_cflags = -O2 -march=@MARCH_RVA22U64_WITH_VEC@ -mstrict-align
 else
 if SUPPORT_CC_RISCV_MSTRICT_ALIGN
 riscv_vector_cflags = -O2 -mstrict-align
@@ -382,9 +382,9 @@ rijndael-vp-riscv.lo: $(srcdir)/rijndael-vp-riscv.c Makefile
 
 # Note: -mstrict-align needed for GCC-14 bug (disable unaligned vector loads)
 if ENABLE_RISCV_VECTOR_CRYPTO_INTRINSICS_EXTRA_CFLAGS
-riscv_vector_crypto_aes_cflags = -O2 -march=rv64imafdcv_zvkned -mstrict-align
-riscv_vector_crypto_sha_cflags = -O2 -march=rv64imafdcv_zvknha_zvknhb_zvkb -mstrict-align
-riscv_vector_crypto_gcm_cflags = -O2 -march=rv64imafdcv_zvkg -mstrict-align
+riscv_vector_crypto_aes_cflags = -O2 -march=@MARCH_RVA23U64_BASE at _zvkned -mstrict-align
+riscv_vector_crypto_sha_cflags = -O2 -march=@MARCH_RVA23U64_BASE at _zvknha_zvknhb_zvkb -mstrict-align
+riscv_vector_crypto_gcm_cflags = -O2 -march=@MARCH_RVA23U64_BASE at _zvkg -mstrict-align
 else
 if SUPPORT_CC_RISCV_MSTRICT_ALIGN
 riscv_vector_crypto_aes_cflags = -O2 -mstrict-align
diff --git a/cipher/chacha20.c b/cipher/chacha20.c
index 848adbe5..17b9b9f0 100644
--- a/cipher/chacha20.c
+++ b/cipher/chacha20.c
@@ -564,7 +564,8 @@ chacha20_do_setkey (CHACHA20_context_t *ctx,
 #endif
 #ifdef USE_RISCV_V
   ctx->use_riscv_v = (features & HWF_RISCV_IMAFDC)
-		     && (features & HWF_RISCV_V)
+		     && (features & HWF_RISCV_B) /* Mandatory in RVA22U64 */
+		     && (features & HWF_RISCV_V) /* Optional in RVA22U64 */
 		     && _gcry_chacha20_riscv_v_check_hw();
 #endif
 
diff --git a/cipher/cipher-gcm.c b/cipher/cipher-gcm.c
index 143ae52a..4c9f9ff5 100644
--- a/cipher/cipher-gcm.c
+++ b/cipher/cipher-gcm.c
@@ -640,8 +640,9 @@ setupM (gcry_cipher_hd_t c)
 #endif
 #ifdef GCM_USE_RISCV_ZVKG
   else if ((features & HWF_RISCV_IMAFDC)
-	   && (features & HWF_RISCV_V)
-	   && (features & HWF_RISCV_ZVKG)
+	   && (features & HWF_RISCV_B)      /* Mandatory in RVA23U64 */
+	   && (features & HWF_RISCV_V)      /* Mandatory in RVA23U64 */
+	   && (features & HWF_RISCV_ZVKG)   /* Optional in RVA23U64 */
 	   && _gcry_ghash_setup_riscv_zvkg (c))
     {
       c->u_mode.gcm.ghash_fn = _gcry_ghash_riscv_zvkg;
diff --git a/cipher/rijndael.c b/cipher/rijndael.c
index 52500e59..972685b4 100644
--- a/cipher/rijndael.c
+++ b/cipher/rijndael.c
@@ -833,8 +833,9 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen,
 #endif
 #ifdef USE_RISCV_V_CRYPTO
     else if ((hwfeatures & HWF_RISCV_IMAFDC)
-	     && (hwfeatures & HWF_RISCV_V)
-	     && (hwfeatures & HWF_RISCV_ZVKNED)
+	     && (hwfeatures & HWF_RISCV_B)      /* Mandatory in RVA23U64 */
+	     && (hwfeatures & HWF_RISCV_V)      /* Mandatory in RVA23U64 */
+	     && (hwfeatures & HWF_RISCV_ZVKNED) /* Optional in RVA23U64 */
 	     && _gcry_aes_riscv_zvkned_setup_acceleration(ctx))
     {
       hw_setkey = _gcry_aes_riscv_zvkned_setkey;
@@ -859,7 +860,8 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen,
 #endif
 #ifdef USE_VP_RISCV
   else if ((hwfeatures & HWF_RISCV_IMAFDC)
-	   && (hwfeatures & HWF_RISCV_V)
+	   && (hwfeatures & HWF_RISCV_B) /* Mandatory in RVA22U64 */
+	   && (hwfeatures & HWF_RISCV_V) /* Optional in RVA22U64 */
 	   && _gcry_aes_vp_riscv_setup_acceleration(ctx))
     {
       hw_setkey = _gcry_aes_vp_riscv_do_setkey;
diff --git a/cipher/sha256.c b/cipher/sha256.c
index 27d4b1d4..abaf995d 100644
--- a/cipher/sha256.c
+++ b/cipher/sha256.c
@@ -352,9 +352,11 @@ sha256_common_init (SHA256_CONTEXT *hd)
 #endif
 #ifdef USE_RISCV_V_CRYPTO
   if ((features & HWF_RISCV_IMAFDC)
-      && (features & HWF_RISCV_V)
-      && (features & HWF_RISCV_ZVKB)
-      && ((features & HWF_RISCV_ZVKNHA) || (features & HWF_RISCV_ZVKNHB))
+      && (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_ZVKNHA)     /* Optional in RVA23U64 (Zvkng) */
+          || (features & HWF_RISCV_ZVKNHB)) /* Optional in RVA23U64 (Zvkng) */
       && _gcry_sha256_riscv_v_check_hw())
     hd->bctx.bwrite = do_sha256_transform_riscv_zvknha;
 #endif
diff --git a/cipher/sha512.c b/cipher/sha512.c
index a0c0bf1c..51bf6641 100644
--- a/cipher/sha512.c
+++ b/cipher/sha512.c
@@ -510,9 +510,10 @@ sha512_init_common (SHA512_CONTEXT *ctx, unsigned int flags)
 #endif
 #ifdef USE_RISCV_V_CRYPTO
   if ((features & HWF_RISCV_IMAFDC)
-      && (features & HWF_RISCV_V)
-      && (features & HWF_RISCV_ZVKB)
-      && (features & HWF_RISCV_ZVKNHB)
+      && (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_ZVKNHB) /* Optional in RVA23U64 (Zvkng) */
       && _gcry_sha512_riscv_v_check_hw())
     ctx->bctx.bwrite = do_sha512_transform_riscv_zvknhb;
 #endif
diff --git a/configure.ac b/configure.ac
index 81110e00..80d38496 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2751,8 +2751,12 @@ if test "$gcry_cv_cc_riscv_vector_intrinsics" = "yes" ; then
 fi
 
 _gcc_cflags_save=$CFLAGS
+# Enable B extension (Zba+Zbb+Zbs) to align with RVA22U64 profile and for
+# better code generation for RISC-V vector implementations.
+MARCH_RVA22U64_WITH_VEC=rv64imafdcv_zba_zbb_zbs
+AC_SUBST([MARCH_RVA22U64_WITH_VEC])
 # Note: -mstrict-align needed for GCC-14 bug (disable unaligned vector loads)
-CFLAGS="$CFLAGS -O2 -march=rv64imafdcv -mstrict-align"
+CFLAGS="$CFLAGS -O2 -march=$MARCH_RVA22U64_WITH_VEC -mstrict-align"
 
 if test "$gcry_cv_cc_riscv_vector_intrinsics" = "no" &&
    test "$mpi_cpu_arch" = "riscv64" &&
@@ -2882,8 +2886,13 @@ if test "$gcry_cv_cc_riscv_vector_crypto_intrinsics" = "yes" ; then
 fi
 
 _gcc_cflags_save=$CFLAGS
+# Enable B extension (Zba+Zbb+Zbs) to align with RVA23U64 profile and for
+# better code generation for RISC-V vector implementations.
+MARCH_RVA23U64_BASE=${MARCH_RVA22U64_WITH_VEC}
+MARCH_RVA23U64_WITH_VEC_CRYPTO=${MARCH_RVA23U64_BASE}_zvbc_zvkg_zvkn_zvks
+AC_SUBST([MARCH_RVA23U64_BASE])
 # Note: -mstrict-align needed for GCC-14 bug (disable unaligned vector loads)
-CFLAGS="$CFLAGS -O2 -march=rv64imafdcv_zvbc_zvkg_zvkn_zvks -mstrict-align"
+CFLAGS="$CFLAGS -O2 -march=$MARCH_RVA23U64_WITH_VEC_CRYPTO -mstrict-align"
 
 if test "$gcry_cv_cc_riscv_vector_crypto_intrinsics" = "no" &&
    test "$mpi_cpu_arch" = "riscv64" &&
@@ -2922,7 +2931,7 @@ if test "$gcry_cv_cc_riscv_vector_crypto_intrinsics" = "yes" ||
   # Setup flags for test if needed.
   _gcc_cflags_save=$CFLAGS
   if test "$gcry_cv_cc_riscv_vector_crypto_intrinsics_cflags" = "yes"; then
-    CFLAGS="$CFLAGS -O2 -march=rv64imafdcv_zvbc_zvkg_zvkn_zvks -mstrict-align"
+    CFLAGS="$CFLAGS -O2 -march=$MARCH_RVA23U64_WITH_VEC_CRYPTO -mstrict-align"
   fi
 
   AC_CACHE_CHECK([whether compiler has working RISC-V __riscv_vsha2cl intrinsics],
@@ -2967,7 +2976,7 @@ if test "$gcry_cv_cc_riscv_vector_crypto_intrinsics" = "yes" ||
   # Setup flags for test.
   _gcc_cflags_save=$CFLAGS
   if test "$gcry_cv_cc_riscv_vector_crypto_intrinsics_cflags" = "yes"; then
-    CFLAGS="$CFLAGS -O2 -march=rv64imafdcv_zvbc_zvkg_zvkn_zvks -mstrict-align"
+    CFLAGS="$CFLAGS -O2 -march=$MARCH_RVA23U64_WITH_VEC_CRYPTO -mstrict-align"
   else
     CFLAGS="$CFLAGS -O2"
   fi
diff --git a/src/g10lib.h b/src/g10lib.h
index 6a4b9313..68ce5405 100644
--- a/src/g10lib.h
+++ b/src/g10lib.h
@@ -277,14 +277,15 @@ char **_gcry_strtokenize (const char *string, const char *delim);
 #elif defined(HAVE_CPU_ARCH_RISCV)
 
 #define HWF_RISCV_IMAFDC        (1 << 0)
-#define HWF_RISCV_V             (1 << 1)
-#define HWF_RISCV_ZBB           (1 << 2)
-#define HWF_RISCV_ZBC           (1 << 3)
-#define HWF_RISCV_ZVKB          (1 << 4)
-#define HWF_RISCV_ZVKG          (1 << 5)
-#define HWF_RISCV_ZVKNED        (1 << 6)
-#define HWF_RISCV_ZVKNHA        (1 << 7)
-#define HWF_RISCV_ZVKNHB        (1 << 8)
+#define HWF_RISCV_B             (1 << 1)
+#define HWF_RISCV_V             (1 << 2)
+#define HWF_RISCV_ZBB           (1 << 3)
+#define HWF_RISCV_ZBC           (1 << 4)
+#define HWF_RISCV_ZVKB          (1 << 5)
+#define HWF_RISCV_ZVKG          (1 << 6)
+#define HWF_RISCV_ZVKNED        (1 << 7)
+#define HWF_RISCV_ZVKNHA        (1 << 8)
+#define HWF_RISCV_ZVKNHB        (1 << 9)
 
 #endif
 
diff --git a/src/hwf-riscv.c b/src/hwf-riscv.c
index 5a7cf777..6c642a10 100644
--- a/src/hwf-riscv.c
+++ b/src/hwf-riscv.c
@@ -90,6 +90,7 @@ static const struct hwcap_feature_map_s hwcap_features[] =
   {
     { HWCAP_ISA_IMAFDC,  HWF_RISCV_IMAFDC },
     { HWCAP_ISA('v'),    HWF_RISCV_V },
+    { HWCAP_ISA('b'),    HWF_RISCV_B },
     { HWCAP_ISA('b'),    HWF_RISCV_ZBB },
   };
 
@@ -216,6 +217,9 @@ static const struct hwprobe_feature_map_s hwprobe_features[] =
     { HWF_RISCV_HWPROBE_IMA_V,       HWF_RISCV_V },
     { HWF_RISCV_HWPROBE_EXT_ZBB,     HWF_RISCV_ZBB },
     { HWF_RISCV_HWPROBE_EXT_ZBC,     HWF_RISCV_ZBC },
+    { HWF_RISCV_HWPROBE_EXT_ZBA
+      | HWF_RISCV_HWPROBE_EXT_ZBB
+      | HWF_RISCV_HWPROBE_EXT_ZBS,   HWF_RISCV_B },
     { HWF_RISCV_HWPROBE_EXT_ZVKB,    HWF_RISCV_ZVKB },
     { HWF_RISCV_HWPROBE_EXT_ZVKG,    HWF_RISCV_ZVKG },
     { HWF_RISCV_HWPROBE_EXT_ZVKNED,  HWF_RISCV_ZVKNED },
@@ -296,6 +300,44 @@ detect_riscv_hwf_by_toolchain (void)
   }
 #endif
 
+#if defined(__riscv_zba) && __riscv_zba >= 1000000 && \
+    defined(__riscv_zbb) && __riscv_zbb >= 1000000 && \
+    defined(__riscv_zbs) && __riscv_zbs >= 1000000 && \
+    defined(HAVE_GCC_INLINE_ASM_RISCV)
+  {
+    unsigned int tmp = 0;
+
+    /* Early test for Zba instructions to detect faulty toolchain
+     * configuration. */
+    asm volatile (".option push;\n\t"
+		  ".option arch, +zba;\n\t"
+		  "sh2add %0, %1, %2;\n\t"
+		  ".option pop;\n\t"
+		  : "=r" (tmp)
+		  : "r" (321), "r" (123));
+
+    /* Early test for Zbb instructions to detect faulty toolchain
+     * configuration. */
+    asm volatile (".option push;\n\t"
+		  ".option arch, +zbb;\n\t"
+		  "cpop %0, %1;\n\t"
+		  ".option pop;\n\t"
+		  : "=r" (tmp)
+		  : "r" (321));
+
+    /* Early test for Zbs instructions to detect faulty toolchain
+     * configuration. */
+    asm volatile (".option push;\n\t"
+		  ".option arch, +zbs;\n\t"
+		  "bclr %0, %1, %2;\n\t"
+		  ".option pop;\n\t"
+		  : "=r" (tmp)
+		  : "r" (321), "r" (15));
+
+    features |= HWF_RISCV_B;
+  }
+#endif
+
 #if defined(__riscv_zbc) && __riscv_zbc >= 1000000 && \
     defined(HAVE_GCC_INLINE_ASM_RISCV)
   {
diff --git a/src/hwfeatures.c b/src/hwfeatures.c
index aae9fdd3..06709da7 100644
--- a/src/hwfeatures.c
+++ b/src/hwfeatures.c
@@ -93,6 +93,7 @@ static struct
     { HWF_S390X_VX,            "s390x-vx" },
 #elif defined(HAVE_CPU_ARCH_RISCV)
     { HWF_RISCV_IMAFDC,        "riscv-imafdc" },
+    { HWF_RISCV_B,             "riscv-b" },
     { HWF_RISCV_V,             "riscv-v" },
     { HWF_RISCV_ZBB,           "riscv-zbb" },
     { HWF_RISCV_ZBC,           "riscv-zbc" },
-- 
2.48.1




More information about the Gcrypt-devel mailing list