[PATCH] crypto: riscv/poly1305 - import OpenSSL/CRYPTOGAMS implementation

Andy Polyakov appro at cryptogams.org
Thu Jun 5 09:42:16 PDT 2025


> This is a straight import of the OpenSSL/CRYPTOGAMS Poly1305
> implementation for riscv authored by Andy Polyakov.
> The file 'poly1305-riscv.pl' is taken straight from this upstream
> GitHub repository [0] at commit 33fe84bc21219a16825459b37c825bf4580a0a7b,
> and this commit fixed a bug in riscv 64bit implementation.

Just in case for reference, the commit fixed a bug in the 32-bit code 
path when it's compiled for 64-bit architecture. For better/adequate 
performance on a 64-bit system the 64-bit code path should be used. And 
it was fine all along. It even passed an algorithmic verification, in 
other words confidence level goes beyond the unit tests.

> Also, this patch passed extra run-time self tests.
> 
> [0] https://github.com/dot-asm/cryptogams
> 
> Signed-off-by: Zhihang Shao <zhihang.shao.iscas at gmail.com>
> ---
>   arch/riscv/crypto/Kconfig           |  10 +
>   arch/riscv/crypto/Makefile          |  17 +
>   arch/riscv/crypto/poly1305-glue.c   | 202 +++++++
>   arch/riscv/crypto/poly1305-riscv.pl | 797 ++++++++++++++++++++++++++++
>   drivers/net/Kconfig                 |   1 +
>   lib/crypto/Kconfig                  |   2 +-
>   6 files changed, 1028 insertions(+), 1 deletion(-)
>   create mode 100644 arch/riscv/crypto/poly1305-glue.c
>   create mode 100644 arch/riscv/crypto/poly1305-riscv.pl
> 
> diff --git a/arch/riscv/crypto/Kconfig b/arch/riscv/crypto/Kconfig
> index c67095a3d669..228bb3c6940d 100644
> --- a/arch/riscv/crypto/Kconfig
> +++ b/arch/riscv/crypto/Kconfig
> @@ -38,6 +38,16 @@ config CRYPTO_GHASH_RISCV64
>   	  Architecture: riscv64 using:
>   	  - Zvkg vector crypto extension
>   
> +config CRYPTO_POLY1305_RISCV
> +	tristate "Hash functions: Poly1305"
> +	select CRYPTO_HASH
> +	select CRYPTO_ARCH_HAVE_LIB_POLY1305
> +	help
> +	  Poly1305 authenticator algorithm (RFC7539)
> +
> +	  Architecture: riscv using:
> +	  - V vector extension

Implementation in question doesn't use RISC-V vector extension, only 
Integer Multiplication extension.

> +static void riscv64_poly1305_blocks(struct poly1305_desc_ctx *dctx, const u8 *src,
> +				 u32 len, u32 hibit)
> +{
> +	if (unlikely(!dctx->sset)) {
> +		if (!dctx->rset) {
> +			poly1305_init_riscv(&dctx->h, src);
> +			src += POLY1305_BLOCK_SIZE;
> +			len -= POLY1305_BLOCK_SIZE;
> +			dctx->rset = 1;
> +		}
> +		if (len >= POLY1305_BLOCK_SIZE) {
> +			dctx->s[0] = get_unaligned_le32(src +  0);
> +			dctx->s[1] = get_unaligned_le32(src +  4);
> +			dctx->s[2] = get_unaligned_le32(src +  8);
> +			dctx->s[3] = get_unaligned_le32(src + 12);
> +			src += POLY1305_BLOCK_SIZE;
> +			len -= POLY1305_BLOCK_SIZE;
> +			dctx->sset = true;
> +		}
> +		if (len < POLY1305_BLOCK_SIZE)
> +			return;
> +	}
> +
> +	len &= ~(POLY1305_BLOCK_SIZE - 1);
> +
> +	poly1305_blocks(&dctx->h, src, len, hibit);
> +}

This interface doesn't make sense. It looks like it's supposed to 
accommodate concatenated key, nonce and data input of arbitrary length. 
However the data length is truncated to the multiples of poly1305 
blocks, in which case |hibit| is supposed to be 1 unconditionally. Or in 
other words, considered in isolation this subroutine shouldn't have 
|hibit| as a parameter, but simply pass 1 as the last argument to 
poly1305_blocks.

On a general note. The poly1305 implementation in question supports both 
32- and 64-bit architectures, so maybe riscv_ prefixes would be more 
appropriate. As opposed to riscv64_ that is :-)

Cheers.




More information about the linux-riscv mailing list