From bbf703bfd3f68958d33d139eb22057ab397e6c68 Mon Sep 17 00:00:00 2001
From: David Sterba <dsterba@suse.com>
Date: Thu, 16 Feb 2023 03:22:58 +0100
Subject: [PATCH] btrfs-progs: crypto: call sha256 implementations by pointer

Change how sha256 implementation is selected. Instead of an if-else
check in the block processing function select the best version and assign
the function pointer. This is slightly faster.

At this point the selection is not implemented properly in
hash-speedtest so all results are from the fastest version. This will
be fixed once all algorithms are converted.

Signed-off-by: David Sterba <dsterba@suse.com>
---
 crypto/hash.c       |  6 ++++++
 crypto/hash.h       |  1 +
 crypto/sha.h        |  2 ++
 crypto/sha224-256.c | 37 ++++++++++++++++++++++++-------------
 4 files changed, 33 insertions(+), 13 deletions(-)

diff --git a/crypto/hash.c b/crypto/hash.c
index 0ccdab75..ee47a7d1 100644
--- a/crypto/hash.c
+++ b/crypto/hash.c
@@ -24,6 +24,7 @@ void hash_init_accel(void)
 {
 	crc32c_optimization_init();
 	blake2_init_accel();
+	sha256_init_accel();
 }
 
 void hash_init_blake2(void)
@@ -31,6 +32,11 @@ void hash_init_blake2(void)
 	blake2_init_accel();
 }
 
+void hash_init_sha256(void)
+{
+	sha256_init_accel();
+}
+
 /*
  * Default builtin implementations
  */
diff --git a/crypto/hash.h b/crypto/hash.h
index e1e073c3..7aafc3df 100644
--- a/crypto/hash.h
+++ b/crypto/hash.h
@@ -28,5 +28,6 @@ int hash_blake2b(const u8 *buf, size_t length, u8 *out);
 
 void hash_init_accel(void);
 void hash_init_blake2(void);
+void hash_init_sha256(void);
 
 #endif
diff --git a/crypto/sha.h b/crypto/sha.h
index 4cfd9730..e65418cc 100644
--- a/crypto/sha.h
+++ b/crypto/sha.h
@@ -209,4 +209,6 @@ extern int hmacFinalBits(HMACContext *context, uint8_t bits,
 extern int hmacResult(HMACContext *context,
                       uint8_t digest[USHAMaxHashSize]);
 
+void sha256_init_accel(void);
+
 #endif /* _SHA_H_ */
diff --git a/crypto/sha224-256.c b/crypto/sha224-256.c
index 80190f22..207014cb 100644
--- a/crypto/sha224-256.c
+++ b/crypto/sha224-256.c
@@ -95,6 +95,29 @@ static uint32_t SHA256_H0[SHA256HashSize/4] = {
   0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
 };
 
+static void (*sha256_process_message_block)(SHA256Context *context) = SHA224_256ProcessMessageBlock;
+
+#ifdef __SHA__
+void sha256_process_x86(uint32_t state[8], const uint8_t data[], uint32_t length);
+
+static void sha256_process_x86_dispatch(SHA256Context *context)
+{
+	/* Compiler and CPU support SHA extension. */
+	sha256_process_x86(context->Intermediate_Hash, context->Message_Block, SHA256_Message_Block_Size);
+	context->Message_Block_Index = 0;
+}
+#endif
+
+void sha256_init_accel(void)
+{
+#ifdef __SHA__
+	if (cpu_has_feature(CPU_FLAG_SHA))
+		sha256_process_message_block = sha256_process_x86_dispatch;
+	else
+#endif
+		sha256_process_message_block = SHA224_256ProcessMessageBlock;
+}
+
 /*
  * SHA224Reset
  *
@@ -209,8 +232,6 @@ int SHA256Reset(SHA256Context *context)
   return SHA224_256Reset(context, SHA256_H0);
 }
 
-void sha256_process_x86(uint32_t state[8], const uint8_t data[], uint32_t length);
-
 /*
  * SHA256Input
  *
@@ -245,17 +266,7 @@ int SHA256Input(SHA256Context *context, const uint8_t *message_array,
 
     if ((SHA224_256AddLength(context, 8) == shaSuccess) &&
       (context->Message_Block_Index == SHA256_Message_Block_Size)) {
-#if HAVE_CFLAG_msha
-        /* Do the runtime check only if compiler supports the instructions */
-        if (cpu_has_feature(CPU_FLAG_SHA)) {
-          sha256_process_x86(context->Intermediate_Hash, context->Message_Block, SHA256_Message_Block_Size);
-          context->Message_Block_Index = 0;
-        } else {
-          SHA224_256ProcessMessageBlock(context);
-        }
-#else
-        SHA224_256ProcessMessageBlock(context);
-#endif
+      sha256_process_message_block(context);
     }
 
     message_array++;