Commit e96cb950 authored by Eric Biggers's avatar Eric Biggers
Browse files

lib/crypto: sha256: Consolidate into single module



Consolidate the CPU-based SHA-256 code into a single module, following
what I did with SHA-512:

- Each arch now provides a header file lib/crypto/$(SRCARCH)/sha256.h,
  replacing lib/crypto/$(SRCARCH)/sha256.c.  The header defines
  sha256_blocks() and optionally sha256_mod_init_arch().  It is included
  by lib/crypto/sha256.c, and thus the code gets built into the single
  libsha256 module, with proper inlining and dead code elimination.

- sha256_blocks_generic() is moved from lib/crypto/sha256-generic.c into
  lib/crypto/sha256.c.  It's now a static function marked with
  __maybe_unused, so the compiler automatically eliminates it in any
  cases where it's not used.

- Whether arch-optimized SHA-256 is buildable is now controlled
  centrally by lib/crypto/Kconfig instead of by
  lib/crypto/$(SRCARCH)/Kconfig.  The conditions for enabling it remain
  the same as before, and it remains enabled by default.

- Any additional arch-specific translation units for the optimized
  SHA-256 code (such as assembly files) are now compiled by
  lib/crypto/Makefile instead of lib/crypto/$(SRCARCH)/Makefile.

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


Signed-off-by: default avatarEric Biggers <ebiggers@kernel.org>
parent 9f9846a7
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -23,12 +23,6 @@ config CAVIUM_OCTEON_CVMSEG_SIZE
	  legally range is from zero to 54 cache blocks (i.e. CVMSEG LM is
	  between zero and 6192 bytes).

config CRYPTO_SHA256_OCTEON
	tristate
	default CRYPTO_LIB_SHA256
	select CRYPTO_ARCH_HAVE_LIB_SHA256
	select CRYPTO_LIB_SHA256_GENERIC

endif # CPU_CAVIUM_OCTEON

if CAVIUM_OCTEON_SOC
+0 −1
Original line number Diff line number Diff line
@@ -7,4 +7,3 @@ obj-y += octeon-crypto.o

obj-$(CONFIG_CRYPTO_MD5_OCTEON)		+= octeon-md5.o
obj-$(CONFIG_CRYPTO_SHA1_OCTEON)	+= octeon-sha1.o
obj-$(CONFIG_CRYPTO_SHA256_OCTEON)	+= octeon-sha256.o

include/crypto/internal/sha2.h

deleted100644 → 0
+0 −52
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef _CRYPTO_INTERNAL_SHA2_H
#define _CRYPTO_INTERNAL_SHA2_H

#include <crypto/sha2.h>
#include <linux/compiler_attributes.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/unaligned.h>

void sha256_blocks_generic(struct sha256_block_state *state,
			   const u8 *data, size_t nblocks);
void sha256_blocks_arch(struct sha256_block_state *state,
			const u8 *data, size_t nblocks);

static __always_inline void sha256_choose_blocks(
	u32 state[SHA256_STATE_WORDS], const u8 *data, size_t nblocks,
	bool force_generic, bool force_simd)
{
	if (!IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_SHA256) || force_generic)
		sha256_blocks_generic((struct sha256_block_state *)state, data, nblocks);
	else
		sha256_blocks_arch((struct sha256_block_state *)state, data, nblocks);
}

static __always_inline void sha256_finup(
	struct crypto_sha256_state *sctx, u8 buf[SHA256_BLOCK_SIZE],
	size_t len, u8 out[SHA256_DIGEST_SIZE], size_t digest_size,
	bool force_generic, bool force_simd)
{
	const size_t bit_offset = SHA256_BLOCK_SIZE - 8;
	__be64 *bits = (__be64 *)&buf[bit_offset];
	int i;

	buf[len++] = 0x80;
	if (len > bit_offset) {
		memset(&buf[len], 0, SHA256_BLOCK_SIZE - len);
		sha256_choose_blocks(sctx->state, buf, 1, force_generic,
				     force_simd);
		len = 0;
	}

	memset(&buf[len], 0, bit_offset - len);
	*bits = cpu_to_be64(sctx->count << 3);
	sha256_choose_blocks(sctx->state, buf, 1, force_generic, force_simd);

	for (i = 0; i < digest_size; i += 4)
		put_unaligned_be32(sctx->state[i / 4], out + i);
}

#endif /* _CRYPTO_INTERNAL_SHA2_H */
+10 −16
Original line number Diff line number Diff line
@@ -144,20 +144,17 @@ config CRYPTO_LIB_SHA256
	  by either the generic implementation or an arch-specific one, if one
	  is available and enabled.

config CRYPTO_ARCH_HAVE_LIB_SHA256
config CRYPTO_LIB_SHA256_ARCH
	bool
	help
	  Declares whether the architecture provides an arch-specific
	  accelerated implementation of the SHA-256 library interface.

config CRYPTO_LIB_SHA256_GENERIC
	tristate
	default CRYPTO_LIB_SHA256 if !CRYPTO_ARCH_HAVE_LIB_SHA256
	help
	  This symbol can be selected by arch implementations of the SHA-256
	  library interface that require the generic code as a fallback, e.g.,
	  for SIMD implementations. If no arch specific implementation is
	  enabled, this implementation serves the users of CRYPTO_LIB_SHA256.
	depends on CRYPTO_LIB_SHA256 && !UML
	default y if ARM && !CPU_V7M
	default y if ARM64
	default y if MIPS && CPU_CAVIUM_OCTEON
	default y if PPC && SPE
	default y if RISCV && 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO
	default y if S390
	default y if SPARC64
	default y if X86_64

config CRYPTO_LIB_SHA512
	tristate
@@ -199,9 +196,6 @@ endif
if S390
source "lib/crypto/s390/Kconfig"
endif
if SPARC
source "lib/crypto/sparc/Kconfig"
endif
if X86
source "lib/crypto/x86/Kconfig"
endif
+34 −5
Original line number Diff line number Diff line
@@ -66,11 +66,39 @@ libpoly1305-generic-y += poly1305-generic.o
obj-$(CONFIG_CRYPTO_LIB_SHA1)			+= libsha1.o
libsha1-y					:= sha1.o

################################################################################

obj-$(CONFIG_CRYPTO_LIB_SHA256) += libsha256.o
libsha256-y := sha256.o
ifeq ($(CONFIG_CRYPTO_LIB_SHA256_ARCH),y)
CFLAGS_sha256.o += -I$(src)/$(SRCARCH)

obj-$(CONFIG_CRYPTO_LIB_SHA256_GENERIC)		+= libsha256-generic.o
libsha256-generic-y				:= sha256-generic.o
ifeq ($(CONFIG_ARM),y)
libsha256-y += arm/sha256-ce.o arm/sha256-core.o
$(obj)/arm/sha256-core.S: $(src)/arm/sha256-armv4.pl
	$(call cmd,perlasm)
clean-files += arm/sha256-core.S
AFLAGS_arm/sha256-core.o += $(aflags-thumb2-y)
endif

ifeq ($(CONFIG_ARM64),y)
libsha256-y += arm64/sha256-core.o
$(obj)/arm64/sha256-core.S: $(src)/arm64/sha2-armv8.pl
	$(call cmd,perlasm_with_args)
clean-files += arm64/sha256-core.S
libsha256-$(CONFIG_KERNEL_MODE_NEON) += arm64/sha256-ce.o
endif

libsha256-$(CONFIG_PPC) += powerpc/sha256-spe-asm.o
libsha256-$(CONFIG_RISCV) += riscv/sha256-riscv64-zvknha_or_zvknhb-zvkb.o
libsha256-$(CONFIG_SPARC) += sparc/sha256_asm.o
libsha256-$(CONFIG_X86) += x86/sha256-ssse3-asm.o \
			   x86/sha256-avx-asm.o \
			   x86/sha256-avx2-asm.o \
			   x86/sha256-ni-asm.o
endif # CONFIG_CRYPTO_LIB_SHA256_ARCH

################################################################################

obj-$(CONFIG_CRYPTO_LIB_SHA512) += libsha512.o
libsha512-y := sha512.o
@@ -100,6 +128,8 @@ libsha512-$(CONFIG_X86) += x86/sha512-ssse3-asm.o \
			   x86/sha512-avx2-asm.o
endif # CONFIG_CRYPTO_LIB_SHA512_ARCH

################################################################################

obj-$(CONFIG_MPILIB) += mpi/

obj-$(CONFIG_CRYPTO_SELFTESTS_FULL)		+= simd.o
@@ -113,5 +143,4 @@ obj-$(CONFIG_MIPS) += mips/
obj-$(CONFIG_PPC) += powerpc/
obj-$(CONFIG_RISCV) += riscv/
obj-$(CONFIG_S390) += s390/
obj-$(CONFIG_SPARC) += sparc/
obj-$(CONFIG_X86) += x86/
Loading