Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ced5b64c authored by Kees Cook's avatar Kees Cook Committed by Sami Tolvanen
Browse files

FROMLIST: crypto, x86/sha: Eliminate casts on asm implementations



In order to avoid CFI function prototype mismatches, this removes the
casts on assembly implementations of sha1/256/512 accelerators. The
safety checks from BUILD_BUG_ON() remain.

Additionally, this renames various arguments for clarity, as suggested
by Eric Biggers.

Signed-off-by: default avatarKees Cook <keescook@chromium.org>
(am from https://lore.kernel.org/patchwork/patch/1179963/)
Link: https://lore.kernel.org/lkml/202001141955.C4136E9C5@keescook


Bug: 145297900
Change-Id: I331d710f11775b66229acedc59861876a2d6708b
Signed-off-by: default avatarSami Tolvanen <samitolvanen@google.com>
parent d92fcbe3
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -62,11 +62,11 @@
 *Visit http://software.intel.com/en-us/articles/
 *and refer to improving-the-performance-of-the-secure-hash-algorithm-1/
 *
 *Updates 20-byte SHA-1 record in 'hash' for even number of
 *'num_blocks' consecutive 64-byte blocks
 *Updates 20-byte SHA-1 record at start of 'state', from 'input', for
 *even number of 'blocks' consecutive 64-byte blocks.
 *
 *extern "C" void sha1_transform_avx2(
 *	int *hash, const char* input, size_t num_blocks );
 *	struct sha1_state *state, const u8* input, int blocks );
 */

#include <linux/linkage.h>
+9 −5
Original line number Diff line number Diff line
@@ -457,9 +457,13 @@ W_PRECALC_SSSE3
	movdqu	\a,\b
.endm

/* SSSE3 optimized implementation:
 *  extern "C" void sha1_transform_ssse3(u32 *digest, const char *data, u32 *ws,
 *                                       unsigned int rounds);
/*
 * SSSE3 optimized implementation:
 *
 * extern "C" void sha1_transform_ssse3(struct sha1_state *state,
 *					const u8 *data, int blocks);
 *
 * Note that struct sha1_state is assumed to begin with u32 state[5].
 */
SHA1_VECTOR_ASM     sha1_transform_ssse3

@@ -545,8 +549,8 @@ W_PRECALC_AVX


/* AVX optimized implementation:
 *  extern "C" void sha1_transform_avx(u32 *digest, const char *data, u32 *ws,
 *                                     unsigned int rounds);
 *  extern "C" void sha1_transform_avx(struct sha1_state *state,
 *				       const u8 *data, int blocks);
 */
SHA1_VECTOR_ASM     sha1_transform_avx

+30 −40
Original line number Diff line number Diff line
@@ -27,11 +27,8 @@
#include <crypto/sha1_base.h>
#include <asm/simd.h>

typedef void (sha1_transform_fn)(u32 *digest, const char *data,
				unsigned int rounds);

static int sha1_update(struct shash_desc *desc, const u8 *data,
			     unsigned int len, sha1_transform_fn *sha1_xform)
			     unsigned int len, sha1_block_fn *sha1_xform)
{
	struct sha1_state *sctx = shash_desc_ctx(desc);

@@ -39,48 +36,47 @@ static int sha1_update(struct shash_desc *desc, const u8 *data,
	    (sctx->count % SHA1_BLOCK_SIZE) + len < SHA1_BLOCK_SIZE)
		return crypto_sha1_update(desc, data, len);

	/* make sure casting to sha1_block_fn() is safe */
	/*
	 * Make sure struct sha1_state begins directly with the SHA1
	 * 160-bit internal state, as this is what the asm functions expect.
	 */
	BUILD_BUG_ON(offsetof(struct sha1_state, state) != 0);

	kernel_fpu_begin();
	sha1_base_do_update(desc, data, len,
			    (sha1_block_fn *)sha1_xform);
	sha1_base_do_update(desc, data, len, sha1_xform);
	kernel_fpu_end();

	return 0;
}

static int sha1_finup(struct shash_desc *desc, const u8 *data,
		      unsigned int len, u8 *out, sha1_transform_fn *sha1_xform)
		      unsigned int len, u8 *out, sha1_block_fn *sha1_xform)
{
	if (!crypto_simd_usable())
		return crypto_sha1_finup(desc, data, len, out);

	kernel_fpu_begin();
	if (len)
		sha1_base_do_update(desc, data, len,
				    (sha1_block_fn *)sha1_xform);
	sha1_base_do_finalize(desc, (sha1_block_fn *)sha1_xform);
		sha1_base_do_update(desc, data, len, sha1_xform);
	sha1_base_do_finalize(desc, sha1_xform);
	kernel_fpu_end();

	return sha1_base_finish(desc, out);
}

asmlinkage void sha1_transform_ssse3(u32 *digest, const char *data,
				     unsigned int rounds);
asmlinkage void sha1_transform_ssse3(struct sha1_state *state,
				     const u8 *data, int blocks);

static int sha1_ssse3_update(struct shash_desc *desc, const u8 *data,
			     unsigned int len)
{
	return sha1_update(desc, data, len,
			(sha1_transform_fn *) sha1_transform_ssse3);
	return sha1_update(desc, data, len, sha1_transform_ssse3);
}

static int sha1_ssse3_finup(struct shash_desc *desc, const u8 *data,
			      unsigned int len, u8 *out)
{
	return sha1_finup(desc, data, len, out,
			(sha1_transform_fn *) sha1_transform_ssse3);
	return sha1_finup(desc, data, len, out, sha1_transform_ssse3);
}

/* Add padding and return the message digest. */
@@ -119,21 +115,19 @@ static void unregister_sha1_ssse3(void)
}

#ifdef CONFIG_AS_AVX
asmlinkage void sha1_transform_avx(u32 *digest, const char *data,
				   unsigned int rounds);
asmlinkage void sha1_transform_avx(struct sha1_state *state,
				   const u8 *data, int blocks);

static int sha1_avx_update(struct shash_desc *desc, const u8 *data,
			     unsigned int len)
{
	return sha1_update(desc, data, len,
			(sha1_transform_fn *) sha1_transform_avx);
	return sha1_update(desc, data, len, sha1_transform_avx);
}

static int sha1_avx_finup(struct shash_desc *desc, const u8 *data,
			      unsigned int len, u8 *out)
{
	return sha1_finup(desc, data, len, out,
			(sha1_transform_fn *) sha1_transform_avx);
	return sha1_finup(desc, data, len, out, sha1_transform_avx);
}

static int sha1_avx_final(struct shash_desc *desc, u8 *out)
@@ -190,8 +184,8 @@ static inline void unregister_sha1_avx(void) { }
#if defined(CONFIG_AS_AVX2) && (CONFIG_AS_AVX)
#define SHA1_AVX2_BLOCK_OPTSIZE	4	/* optimal 4*64 bytes of SHA1 blocks */

asmlinkage void sha1_transform_avx2(u32 *digest, const char *data,
				    unsigned int rounds);
asmlinkage void sha1_transform_avx2(struct sha1_state *state,
				    const u8 *data, int blocks);

static bool avx2_usable(void)
{
@@ -203,28 +197,26 @@ static bool avx2_usable(void)
	return false;
}

static void sha1_apply_transform_avx2(u32 *digest, const char *data,
				unsigned int rounds)
static void sha1_apply_transform_avx2(struct sha1_state *state,
				      const u8 *data, int blocks)
{
	/* Select the optimal transform based on data block size */
	if (rounds >= SHA1_AVX2_BLOCK_OPTSIZE)
		sha1_transform_avx2(digest, data, rounds);
	if (blocks >= SHA1_AVX2_BLOCK_OPTSIZE)
		sha1_transform_avx2(state, data, blocks);
	else
		sha1_transform_avx(digest, data, rounds);
		sha1_transform_avx(state, data, blocks);
}

static int sha1_avx2_update(struct shash_desc *desc, const u8 *data,
			     unsigned int len)
{
	return sha1_update(desc, data, len,
		(sha1_transform_fn *) sha1_apply_transform_avx2);
	return sha1_update(desc, data, len, sha1_apply_transform_avx2);
}

static int sha1_avx2_finup(struct shash_desc *desc, const u8 *data,
			      unsigned int len, u8 *out)
{
	return sha1_finup(desc, data, len, out,
		(sha1_transform_fn *) sha1_apply_transform_avx2);
	return sha1_finup(desc, data, len, out, sha1_apply_transform_avx2);
}

static int sha1_avx2_final(struct shash_desc *desc, u8 *out)
@@ -267,21 +259,19 @@ static inline void unregister_sha1_avx2(void) { }
#endif

#ifdef CONFIG_AS_SHA1_NI
asmlinkage void sha1_ni_transform(u32 *digest, const char *data,
				   unsigned int rounds);
asmlinkage void sha1_ni_transform(struct sha1_state *digest, const u8 *data,
				  int rounds);

static int sha1_ni_update(struct shash_desc *desc, const u8 *data,
			     unsigned int len)
{
	return sha1_update(desc, data, len,
		(sha1_transform_fn *) sha1_ni_transform);
	return sha1_update(desc, data, len, sha1_ni_transform);
}

static int sha1_ni_finup(struct shash_desc *desc, const u8 *data,
			      unsigned int len, u8 *out)
{
	return sha1_finup(desc, data, len, out,
		(sha1_transform_fn *) sha1_ni_transform);
	return sha1_finup(desc, data, len, out, sha1_ni_transform);
}

static int sha1_ni_final(struct shash_desc *desc, u8 *out)
+2 −2
Original line number Diff line number Diff line
@@ -341,8 +341,8 @@ a = TMP_
.endm

########################################################################
## void sha256_transform_avx(void *input_data, UINT32 digest[8], UINT64 num_blks)
## arg 1 : pointer to digest
## void sha256_transform_avx(state sha256_state *state, const u8 *data, int blocks)
## arg 1 : pointer to state
## arg 2 : pointer to input data
## arg 3 : Num blocks
########################################################################
+2 −2
Original line number Diff line number Diff line
@@ -520,8 +520,8 @@ STACK_SIZE = _RSP + _RSP_SIZE
.endm

########################################################################
## void sha256_transform_rorx(void *input_data, UINT32 digest[8], UINT64 num_blks)
## arg 1 : pointer to digest
## void sha256_transform_rorx(struct sha256_state *state, const u8 *data, int blocks)
## arg 1 : pointer to state
## arg 2 : pointer to input data
## arg 3 : Num blocks
########################################################################
Loading