Commit b67b6f9a authored by Eric Biggers's avatar Eric Biggers Committed by Herbert Xu
Browse files

crypto: mips/sha256 - implement library instead of shash



Instead of providing crypto_shash algorithms for the arch-optimized
SHA-256 code, instead implement the SHA-256 library.  This is much
simpler, it makes the SHA-256 library functions be arch-optimized, and
it fixes the longstanding issue where the arch-optimized SHA-256 was
disabled by default.  SHA-256 still remains available through
crypto_shash, but individual architectures no longer need to handle it.

Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 6e36be51
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -23,6 +23,12 @@ 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
+27 −108
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Cryptographic API.
 *
 * SHA-224 and SHA-256 Secure Hash Algorithm.
 * SHA-256 Secure Hash Algorithm.
 *
 * Adapted for OCTEON by Aaro Koskinen <aaro.koskinen@iki.fi>.
 *
@@ -15,9 +13,7 @@
 */

#include <asm/octeon/octeon.h>
#include <crypto/internal/hash.h>
#include <crypto/sha2.h>
#include <crypto/sha256_base.h>
#include <crypto/internal/sha2.h>
#include <linux/kernel.h>
#include <linux/module.h>

@@ -27,31 +23,24 @@
 * We pass everything as 64-bit. OCTEON can handle misaligned data.
 */

static void octeon_sha256_store_hash(struct crypto_sha256_state *sctx)
void sha256_blocks_arch(u32 state[SHA256_STATE_WORDS],
			const u8 *data, size_t nblocks)
{
	u64 *hash = (u64 *)sctx->state;

	write_octeon_64bit_hash_dword(hash[0], 0);
	write_octeon_64bit_hash_dword(hash[1], 1);
	write_octeon_64bit_hash_dword(hash[2], 2);
	write_octeon_64bit_hash_dword(hash[3], 3);
}
	struct octeon_cop2_state cop2_state;
	u64 *state64 = (u64 *)state;
	unsigned long flags;

static void octeon_sha256_read_hash(struct crypto_sha256_state *sctx)
{
	u64 *hash = (u64 *)sctx->state;
	if (!octeon_has_crypto())
		return sha256_blocks_generic(state, data, nblocks);

	hash[0] = read_octeon_64bit_hash_dword(0);
	hash[1] = read_octeon_64bit_hash_dword(1);
	hash[2] = read_octeon_64bit_hash_dword(2);
	hash[3] = read_octeon_64bit_hash_dword(3);
}
	flags = octeon_crypto_enable(&cop2_state);
	write_octeon_64bit_hash_dword(state64[0], 0);
	write_octeon_64bit_hash_dword(state64[1], 1);
	write_octeon_64bit_hash_dword(state64[2], 2);
	write_octeon_64bit_hash_dword(state64[3], 3);

static void octeon_sha256_transform(struct crypto_sha256_state *sctx,
				    const u8 *src, int blocks)
{
	do {
		const u64 *block = (const u64 *)src;
		const u64 *block = (const u64 *)data;

		write_octeon_64bit_block_dword(block[0], 0);
		write_octeon_64bit_block_dword(block[1], 1);
@@ -62,93 +51,23 @@ static void octeon_sha256_transform(struct crypto_sha256_state *sctx,
		write_octeon_64bit_block_dword(block[6], 6);
		octeon_sha256_start(block[7]);

		src += SHA256_BLOCK_SIZE;
	} while (--blocks);
}

static int octeon_sha256_update(struct shash_desc *desc, const u8 *data,
				unsigned int len)
{
	struct crypto_sha256_state *sctx = shash_desc_ctx(desc);
	struct octeon_cop2_state state;
	unsigned long flags;
	int remain;
		data += SHA256_BLOCK_SIZE;
	} while (--nblocks);

	flags = octeon_crypto_enable(&state);
	octeon_sha256_store_hash(sctx);

	remain = sha256_base_do_update_blocks(desc, data, len,
					      octeon_sha256_transform);

	octeon_sha256_read_hash(sctx);
	octeon_crypto_disable(&state, flags);
	return remain;
	state64[0] = read_octeon_64bit_hash_dword(0);
	state64[1] = read_octeon_64bit_hash_dword(1);
	state64[2] = read_octeon_64bit_hash_dword(2);
	state64[3] = read_octeon_64bit_hash_dword(3);
	octeon_crypto_disable(&cop2_state, flags);
}
EXPORT_SYMBOL(sha256_blocks_arch);

static int octeon_sha256_finup(struct shash_desc *desc, const u8 *src,
			       unsigned int len, u8 *out)
bool sha256_is_arch_optimized(void)
{
	struct crypto_sha256_state *sctx = shash_desc_ctx(desc);
	struct octeon_cop2_state state;
	unsigned long flags;

	flags = octeon_crypto_enable(&state);
	octeon_sha256_store_hash(sctx);

	sha256_base_do_finup(desc, src, len, octeon_sha256_transform);

	octeon_sha256_read_hash(sctx);
	octeon_crypto_disable(&state, flags);
	return sha256_base_finish(desc, out);
}

static struct shash_alg octeon_sha256_algs[2] = { {
	.digestsize	=	SHA256_DIGEST_SIZE,
	.init		=	sha256_base_init,
	.update		=	octeon_sha256_update,
	.finup		=	octeon_sha256_finup,
	.descsize	=	sizeof(struct crypto_sha256_state),
	.base		=	{
		.cra_name	=	"sha256",
		.cra_driver_name=	"octeon-sha256",
		.cra_priority	=	OCTEON_CR_OPCODE_PRIORITY,
		.cra_flags	=	CRYPTO_AHASH_ALG_BLOCK_ONLY,
		.cra_blocksize	=	SHA256_BLOCK_SIZE,
		.cra_module	=	THIS_MODULE,
	}
}, {
	.digestsize	=	SHA224_DIGEST_SIZE,
	.init		=	sha224_base_init,
	.update		=	octeon_sha256_update,
	.finup		=	octeon_sha256_finup,
	.descsize	=	sizeof(struct crypto_sha256_state),
	.base		=	{
		.cra_name	=	"sha224",
		.cra_driver_name=	"octeon-sha224",
		.cra_priority	=	OCTEON_CR_OPCODE_PRIORITY,
		.cra_flags	=	CRYPTO_AHASH_ALG_BLOCK_ONLY,
		.cra_blocksize	=	SHA224_BLOCK_SIZE,
		.cra_module	=	THIS_MODULE,
	}
} };

static int __init octeon_sha256_mod_init(void)
{
	if (!octeon_has_crypto())
		return -ENOTSUPP;
	return crypto_register_shashes(octeon_sha256_algs,
				       ARRAY_SIZE(octeon_sha256_algs));
	return octeon_has_crypto();
}

static void __exit octeon_sha256_mod_fini(void)
{
	crypto_unregister_shashes(octeon_sha256_algs,
				  ARRAY_SIZE(octeon_sha256_algs));
}

module_init(octeon_sha256_mod_init);
module_exit(octeon_sha256_mod_fini);
EXPORT_SYMBOL(sha256_is_arch_optimized);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm (OCTEON)");
MODULE_DESCRIPTION("SHA-256 Secure Hash Algorithm (OCTEON)");
MODULE_AUTHOR("Aaro Koskinen <aaro.koskinen@iki.fi>");
+0 −1
Original line number Diff line number Diff line
@@ -157,7 +157,6 @@ CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_MD5_OCTEON=y
CONFIG_CRYPTO_SHA1_OCTEON=m
CONFIG_CRYPTO_SHA256_OCTEON=m
CONFIG_CRYPTO_SHA512_OCTEON=m
CONFIG_CRYPTO_DES=y
CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
+0 −10
Original line number Diff line number Diff line
@@ -22,16 +22,6 @@ config CRYPTO_SHA1_OCTEON

	  Architecture: mips OCTEON

config CRYPTO_SHA256_OCTEON
	tristate "Hash functions: SHA-224 and SHA-256 (OCTEON)"
	depends on CPU_CAVIUM_OCTEON
	select CRYPTO_SHA256
	select CRYPTO_HASH
	help
	  SHA-224 and SHA-256 secure hash algorithms (FIPS 180)

	  Architecture: mips OCTEON using crypto instructions, when available

config CRYPTO_SHA512_OCTEON
	tristate "Hash functions: SHA-384 and SHA-512 (OCTEON)"
	depends on CPU_CAVIUM_OCTEON