From 1a63112faf5af60e0ebcc60654eef806e7f6f11a Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Sat, 18 May 2019 23:07:17 -0400 Subject: 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. --- sha.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'sha.cpp') 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()) { -- cgit v1.2.1