[PATCH 2/2] Require RISC-V B extension for vector intrinsics implementations
Jussi Kivilinna <[email protected]> Sat, 16 Aug 2025 21:36:29 +0300
| Newsgroups | gmane.comp.encryption.gpg.libgcrypt.devel |
|---|---|
| Message-ID | <[email protected]> |
* 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 <[email protected]> --- 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@_zvkned -mstrict-align +riscv_vector_crypto_sha_cflags = -O2 -march=@MARCH_RVA23U64_BASE@_zvknha_zvknhb_zvkb -mstrict-align +riscv_vector_crypto_gcm_cflags = -O2 -march=@MARCH_RVA23U64_BASE@_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