diff options
author | Jeffrey Walton <noloader@gmail.com> | 2019-05-19 06:59:12 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-19 06:59:12 -0400 |
commit | 4c9ca6b723b5ec5aab7eec720ad4d22598abe941 (patch) | |
tree | 58ddee7860612888b43175d9d33cbdc936d044aa /sha.cpp | |
parent | 8c99b1cd7592818072bc0882e9498e7c29402c5c (diff) | |
download | cryptopp-git-4c9ca6b723b5ec5aab7eec720ad4d22598abe941.tar.gz |
Add ARM SHA256 asm implementation from Cryptogams (GH #840, PR #840)
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 45% faster than C/C++ code. Testing on a 1 GHz Cortex-A7 shows Cryptograms at 17 cpb, and C++ at 30 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.cpp | 50 |
1 files changed, 49 insertions, 1 deletions
@@ -69,6 +69,11 @@ extern void SHA1_HashMultipleBlocks_ARMV8(word32 *state, const word32 *data, siz extern void SHA256_HashMultipleBlocks_ARMV8(word32 *state, const word32 *data, size_t length, ByteOrder order);
#endif
+#if (CRYPTOGAMS_ARM_SHA256)
+extern "C" unsigned int CRYPTOGAMS_armcaps;
+extern "C" int sha256_block_data_order(word32* state, const word32 *data, size_t blocks);
+#endif
+
#if CRYPTOPP_ARM_SHA512_AVAILABLE
extern void SHA512_HashMultipleBlocks_ARMV8(word32 *state, const word32 *data, size_t length, ByteOrder order);
#endif
@@ -309,7 +314,8 @@ size_t SHA1::HashMultipleBlocks(const word32 *input, size_t length) // 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;
+ static const unsigned int unused = CRYPTOGAMS_armcaps = HasNEON() ? (1<<0) : 0;
+ CRYPTOPP_UNUSED(unused);
sha1_block_data_order(m_state, input, length / SHA1::BLOCKSIZE);
return length & (SHA1::BLOCKSIZE - 1);
@@ -428,6 +434,12 @@ std::string SHA256_AlgorithmProvider() if (HasSSE2())
return "SSE2";
#endif
+#if CRYPTOGAMS_ARM_SHA256
+ if (HasNEON())
+ return "NEON";
+ if (HasARMv7())
+ return "ARMv7";
+#endif
#if CRYPTOPP_ARM_SHA2_AVAILABLE
if (HasSHA2())
return "ARMv8";
@@ -811,6 +823,14 @@ void SHA256::Transform(word32 *state, const word32 *data) return;
}
#endif
+#if CRYPTOGAMS_ARM_SHA256 && 0
+ // TODO: convert LE to BE and use Cryptogams code
+ if (HasARMv7())
+ {
+ sha256_block_data_order(state, data, 1);
+ return;
+ }
+#endif
#if CRYPTOPP_ARM_SHA2_AVAILABLE
if (HasSHA2())
{
@@ -849,6 +869,20 @@ size_t SHA256::HashMultipleBlocks(const word32 *input, size_t length) return res;
}
#endif
+#if CRYPTOGAMS_ARM_SHA256
+ 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 const unsigned int unused = CRYPTOGAMS_armcaps = HasNEON() ? (1<<0) : 0;
+ CRYPTOPP_UNUSED(unused);
+
+ sha256_block_data_order(m_state, input, length / SHA256::BLOCKSIZE);
+ return length & (SHA256::BLOCKSIZE - 1);
+ }
+#endif
#if CRYPTOPP_ARM_SHA2_AVAILABLE
if (HasSHA2())
{
@@ -905,6 +939,20 @@ size_t SHA224::HashMultipleBlocks(const word32 *input, size_t length) return res;
}
#endif
+#if CRYPTOGAMS_ARM_SHA256
+ 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 const unsigned int unused = CRYPTOGAMS_armcaps = HasNEON() ? (1<<0) : 0;
+ CRYPTOPP_UNUSED(unused);
+
+ sha256_block_data_order(m_state, input, length / SHA256::BLOCKSIZE);
+ return length & (SHA256::BLOCKSIZE - 1);
+ }
+#endif
#if CRYPTOPP_ARM_SHA2_AVAILABLE
if (HasSHA2())
{
|