Commit 9f97707b authored by Eric Biggers's avatar Eric Biggers
Browse files

lib/crypto: sha256: Remove sha256_blocks_simd()



Instead of having both sha256_blocks_arch() and sha256_blocks_simd(),
instead have just sha256_blocks_arch() which uses the most efficient
implementation that is available in the calling context.

This is simpler, as it reduces the API surface.  It's also safer, since
sha256_blocks_arch() just works in all contexts, including contexts
where the FPU/SIMD/vector registers cannot be used.  This doesn't mean
that SHA-256 computations *should* be done in such contexts, but rather
we should just do the right thing instead of corrupting a random task's
registers.  Eliminating this footgun and simplifying the code is well
worth the very small performance cost of doing the check.

Note: in the case of arm and arm64, what used to be sha256_blocks_arch()
is renamed back to its original name of sha256_block_data_order().
sha256_blocks_arch() is now used for the higher-level dispatch function.
This renaming also required an update to lib/crypto/arm64/sha512.h,
since sha2-armv8.pl is shared by both SHA-256 and SHA-512.

Acked-by: default avatarArd Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20250630160645.3198-5-ebiggers@kernel.org


Signed-off-by: default avatarEric Biggers <ebiggers@kernel.org>
parent 3135d5be
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -3,7 +3,6 @@
#ifndef _CRYPTO_INTERNAL_SHA2_H
#define _CRYPTO_INTERNAL_SHA2_H

#include <crypto/internal/simd.h>
#include <crypto/sha2.h>
#include <linux/compiler_attributes.h>
#include <linux/string.h>
@@ -22,8 +21,6 @@ void sha256_blocks_generic(u32 state[SHA256_STATE_WORDS],
			   const u8 *data, size_t nblocks);
void sha256_blocks_arch(u32 state[SHA256_STATE_WORDS],
			const u8 *data, size_t nblocks);
void sha256_blocks_simd(u32 state[SHA256_STATE_WORDS],
			const u8 *data, size_t nblocks);

static __always_inline void sha256_choose_blocks(
	u32 state[SHA256_STATE_WORDS], const u8 *data, size_t nblocks,
@@ -31,9 +28,6 @@ static __always_inline void sha256_choose_blocks(
{
	if (!IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_SHA256) || force_generic)
		sha256_blocks_generic(state, data, nblocks);
	else if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_SHA256_SIMD) &&
		 (force_simd || crypto_simd_usable()))
		sha256_blocks_simd(state, data, nblocks);
	else
		sha256_blocks_arch(state, data, nblocks);
}
+0 −8
Original line number Diff line number Diff line
@@ -150,14 +150,6 @@ config CRYPTO_ARCH_HAVE_LIB_SHA256
	  Declares whether the architecture provides an arch-specific
	  accelerated implementation of the SHA-256 library interface.

config CRYPTO_ARCH_HAVE_LIB_SHA256_SIMD
	bool
	help
	  Declares whether the architecture provides an arch-specific
	  accelerated implementation of the SHA-256 library interface
	  that is SIMD-based and therefore not usable in hardirq
	  context.

config CRYPTO_LIB_SHA256_GENERIC
	tristate
	default CRYPTO_LIB_SHA256 if !CRYPTO_ARCH_HAVE_LIB_SHA256
+0 −1
Original line number Diff line number Diff line
@@ -28,4 +28,3 @@ config CRYPTO_SHA256_ARM
	depends on !CPU_V7M
	default CRYPTO_LIB_SHA256
	select CRYPTO_ARCH_HAVE_LIB_SHA256
	select CRYPTO_ARCH_HAVE_LIB_SHA256_SIMD
+10 −10
Original line number Diff line number Diff line
@@ -204,18 +204,18 @@ K256:
.word	0				@ terminator
#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
.LOPENSSL_armcap:
.word	OPENSSL_armcap_P-sha256_blocks_arch
.word	OPENSSL_armcap_P-sha256_block_data_order
#endif
.align	5

.global	sha256_blocks_arch
.type	sha256_blocks_arch,%function
sha256_blocks_arch:
.Lsha256_blocks_arch:
.global	sha256_block_data_order
.type	sha256_block_data_order,%function
sha256_block_data_order:
.Lsha256_block_data_order:
#if __ARM_ARCH__<7
	sub	r3,pc,#8		@ sha256_blocks_arch
	sub	r3,pc,#8		@ sha256_block_data_order
#else
	adr	r3,.Lsha256_blocks_arch
	adr	r3,.Lsha256_block_data_order
#endif
#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
	ldr	r12,.LOPENSSL_armcap
@@ -282,7 +282,7 @@ $code.=<<___;
	moveq	pc,lr			@ be binary compatible with V4, yet
	bx	lr			@ interoperable with Thumb ISA:-)
#endif
.size	sha256_blocks_arch,.-sha256_blocks_arch
.size	sha256_block_data_order,.-sha256_block_data_order
___
######################################################################
# NEON stuff
@@ -470,8 +470,8 @@ sha256_block_data_order_neon:
	stmdb	sp!,{r4-r12,lr}

	sub	$H,sp,#16*4+16
	adr	$Ktbl,.Lsha256_blocks_arch
	sub	$Ktbl,$Ktbl,#.Lsha256_blocks_arch-K256
	adr	$Ktbl,.Lsha256_block_data_order
	sub	$Ktbl,$Ktbl,#.Lsha256_block_data_order-K256
	bic	$H,$H,#15		@ align for 128-bit stores
	mov	$t2,sp
	mov	sp,$H			@ alloca
+7 −7
Original line number Diff line number Diff line
@@ -6,12 +6,12 @@
 */
#include <asm/neon.h>
#include <crypto/internal/sha2.h>
#include <crypto/internal/simd.h>
#include <linux/kernel.h>
#include <linux/module.h>

asmlinkage void sha256_blocks_arch(u32 state[SHA256_STATE_WORDS],
asmlinkage void sha256_block_data_order(u32 state[SHA256_STATE_WORDS],
					const u8 *data, size_t nblocks);
EXPORT_SYMBOL_GPL(sha256_blocks_arch);
asmlinkage void sha256_block_data_order_neon(u32 state[SHA256_STATE_WORDS],
					     const u8 *data, size_t nblocks);
asmlinkage void sha256_ce_transform(u32 state[SHA256_STATE_WORDS],
@@ -20,11 +20,11 @@ asmlinkage void sha256_ce_transform(u32 state[SHA256_STATE_WORDS],
static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_neon);
static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_ce);

void sha256_blocks_simd(u32 state[SHA256_STATE_WORDS],
void sha256_blocks_arch(u32 state[SHA256_STATE_WORDS],
			const u8 *data, size_t nblocks)
{
	if (IS_ENABLED(CONFIG_KERNEL_MODE_NEON) &&
	    static_branch_likely(&have_neon)) {
	    static_branch_likely(&have_neon) && crypto_simd_usable()) {
		kernel_neon_begin();
		if (static_branch_likely(&have_ce))
			sha256_ce_transform(state, data, nblocks);
@@ -32,10 +32,10 @@ void sha256_blocks_simd(u32 state[SHA256_STATE_WORDS],
			sha256_block_data_order_neon(state, data, nblocks);
		kernel_neon_end();
	} else {
		sha256_blocks_arch(state, data, nblocks);
		sha256_block_data_order(state, data, nblocks);
	}
}
EXPORT_SYMBOL_GPL(sha256_blocks_simd);
EXPORT_SYMBOL_GPL(sha256_blocks_arch);

bool sha256_is_arch_optimized(void)
{
Loading