summaryrefslogtreecommitdiff
path: root/sha.cpp
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2019-05-18 23:07:17 -0400
committerGitHub <noreply@github.com>2019-05-18 23:07:17 -0400
commit1a63112faf5af60e0ebcc60654eef806e7f6f11a (patch)
tree5144dbd6968ef0643f5e7d03086e916c2e27ab99 /sha.cpp
parent4a21619bff1b1690a97789b76fd70cbb226f7b87 (diff)
downloadcryptopp-git-1a63112faf5af60e0ebcc60654eef806e7f6f11a.tar.gz
Add ARM SHA1 asm implementation from Cryptogams (GH #837, PR #838)
Add ARM SHA1 asm implementation from Cryptogams. Cryptogams is Andy Polyakov's project used to create high speed crypto algorithms and share them with other developers. Cryptogams has a dual license. First is the OpenSSL license because Andy contributes to OpenSSL. Second is a BSD license for those who want a more permissive license. Andy's implementation runs about 30% faster than C/C++ code. Testing on a 1 GHz Cortex-A7 shows Cryptograms at 16 cpb, and C++ at 23 cpb. The integration instructions are documented at [Cryptogams SHA](https://wiki.openssl.org/index.php/Cryptogams_SHA) on the OpenSSL wiki.
Diffstat (limited to 'sha.cpp')
-rw-r--r--sha.cpp32
1 files changed, 32 insertions, 0 deletions
diff --git a/sha.cpp b/sha.cpp
index 87cf749a..70b6d48a 100644
--- a/sha.cpp
+++ b/sha.cpp
@@ -56,6 +56,11 @@ extern void SHA1_HashMultipleBlocks_SHANI(word32 *state, const word32 *data, siz
extern void SHA256_HashMultipleBlocks_SHANI(word32 *state, const word32 *data, size_t length, ByteOrder order);
#endif
+#if (CRYPTOGAMS_ARM_SHA1)
+extern "C" unsigned int CRYPTOGAMS_armcaps;
+extern "C" int sha1_block_data_order(word32* state, const word32 *data, size_t blocks);
+#endif
+
#if CRYPTOPP_ARM_SHA1_AVAILABLE
extern void SHA1_HashMultipleBlocks_ARMV8(word32 *state, const word32 *data, size_t length, ByteOrder order);
#endif
@@ -232,6 +237,12 @@ std::string SHA1::AlgorithmProvider() const
if (HasSSE2())
return "SSE2";
#endif
+#if CRYPTOGAMS_ARM_SHA1
+ if (HasNEON())
+ return "NEON";
+ if (HasARMv7())
+ return "ARMv7";
+#endif
#if CRYPTOPP_ARM_SHA1_AVAILABLE
if (HasSHA1())
return "ARMv8";
@@ -260,6 +271,14 @@ void SHA1::Transform(word32 *state, const word32 *data)
return;
}
#endif
+#if CRYPTOGAMS_ARM_SHA1 && 0
+ // TODO: convert LE to BE and use Cryptogams code
+ if (HasARMv7())
+ {
+ sha1_block_data_order(state, data, 1);
+ return;
+ }
+#endif
#if CRYPTOPP_ARM_SHA1_AVAILABLE
if (HasSHA1())
{
@@ -283,6 +302,19 @@ size_t SHA1::HashMultipleBlocks(const word32 *input, size_t length)
return length & (SHA1::BLOCKSIZE - 1);
}
#endif
+#if CRYPTOGAMS_ARM_SHA1
+ if (HasARMv7())
+ {
+ // The Cryptogams code uses a global variable named CRYPTOGAMS_armcaps
+ // for capabilities like ARMv7 and NEON. Storage is allocated in the
+ // module. We still need to set CRYPTOGAMS_armcaps accordingly.
+ // The Cryptogams code defines NEON as 1<<0; see ARMV7_NEON.
+ static unsigned int unused = CRYPTOGAMS_armcaps = HasNEON() ? (1<<0) : 0;
+
+ sha1_block_data_order(m_state, input, length / SHA1::BLOCKSIZE);
+ return length & (SHA1::BLOCKSIZE - 1);
+ }
+#endif
#if CRYPTOPP_ARM_SHA1_AVAILABLE
if (HasSHA1())
{