[PATCH] cipher:riscv: gate Zvkned AES backend on VLEN == 128

Jussi Kivilinna jussi.kivilinna at iki.fi
Wed May 6 08:57:20 CEST 2026


Hello,

On 2026-05-06 07:07, Michael Neuling wrote:
> cipher/rijndael-riscv-zvkned.c's m4 batching code assumes m1 holds
> exactly one 16-byte AES block (i.e. VLEN == 128).  On VLEN >= 256
> the four-block m4 group is laid out differently and AES_CRYPT m4
> vl=16 miscomputes blocks 1..3.

m4 batching code path selects 128-bit vectors (4 32-bit elements or
16 8-bit elements) and "m4" grouping. Whatever HW supports VLEN>128
or VLEN=128 not should not matter here.

> 
> Replace the existing __riscv_vsetvl_e32m1(4) == 4 gate (which only
> checked "VLEN >= 128") with __riscv_vsetvlmax_e32m1() == 4 (== 4
> if VLEN == 128). On any other VLEN the backend refuses setup
> and libgcrypt's dispatcher in cipher/rijndael.c falls through to
> USE_VP_RISCV (rijndael-vp-riscv.c), which is Zvbb-based and has
> no VLEN dependency.
> 
> Issue found by Claude Opus using qemu on Tenstorrent Ascalon model
> (-cpu tt-ascalon).

So, question is:
  * Is build system buggy for AES+m4? There was GCC bug for m4 aes
    intrinsics that configure.ac attempts to detect. Was GCC fixed
    incorrectly and is it now buggy in some other way (thus bypassing
    configure.ac check)?
  * Is QEMU implementation buggy for VLEN=256?
  * Or is the implementation actually wrong and I did get the RISC-V
    vector instruction set wrong?
  * SpaceMit K3 should have vector AES extension and VLEN=256... it
    would be nice to get hands on it and test this with real hardware.

If issue is the first one, configure.ac should be improved. Or
_gcry_aes_riscv_zvkned_setup_acceleration() to be improved to do
run-time check for buggy aes+m4 build-system/HW.

-Jussi

> 
> Tested-on: tt-ascalon (VLEN=256) under qemu 9.1.92
> Tested-on: rva23s64 (VLEN=128) under qemu 9.1.92
> Signed-off-by: Michael Neuling <mikey at neuling.org>
> ---
>  cipher/rijndael-riscv-zvkned.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/cipher/rijndael-riscv-zvkned.c 
> b/cipher/rijndael-riscv-zvkned.c
> index 434b9562be..d083c05703 100644
> --- a/cipher/rijndael-riscv-zvkned.c
> +++ b/cipher/rijndael-riscv-zvkned.c
> @@ -142,7 +142,10 @@ int ASM_FUNC_ATTR_NOINLINE FUNC_ATTR_OPT_O2
>  _gcry_aes_riscv_zvkned_setup_acceleration(RIJNDAEL_context *ctx)
>  {
>    (void)ctx;
> -  return (__riscv_vsetvl_e32m1(4) == 4);
> +  /* The m4 batching code assumes m1 holds exactly one 16-byte
> +     AES block (i.e. VLEN == 128).  Refuse the backend on any other
> +     VLEN. */
> +  return (__riscv_vsetvlmax_e32m1() == 4);
>  }



More information about the Gcrypt-devel mailing list