diff --git a/blake2.cpp b/blake2.cpp index e8f3ca68..13923792 100644 --- a/blake2.cpp +++ b/blake2.cpp @@ -14,21 +14,9 @@ NAMESPACE_BEGIN(CryptoPP) // Uncomment for benchmarking C++ against SSE2 or NEON -#undef CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE +// #undef CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE // #undef CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE -// Visual Studio needs both VS2005 (1400) and _M_64 for SSE2 and _mm_set_epi64x() -// http://msdn.microsoft.com/en-us/library/y0dh78ez%28v=vs.80%29.aspx -#if defined(_MSC_VER) && ((_MSC_VER < 1400) || !defined(_M_X64)) -# undef CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE -#endif - -// Visual Studio needs VS2008 (1500); no dependency on _mm_set_epi64x() -// http://msdn.microsoft.com/en-us/library/bb892950%28v=vs.90%29.aspx -#if defined(_MSC_VER) && (_MSC_VER < 1500) -# undef CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE -#endif - // Apple Clang 6.0/Clang 3.5 does not have SSSE3 intrinsics // http://llvm.org/bugs/show_bug.cgi?id=20213 #if (defined(CRYPTOPP_APPLE_CLANG_VERSION) && (CRYPTOPP_APPLE_CLANG_VERSION <= 60000)) || (defined(CRYPTOPP_LLVM_CLANG_VERSION) && (CRYPTOPP_LLVM_CLANG_VERSION <= 30500)) @@ -37,12 +25,12 @@ NAMESPACE_BEGIN(CryptoPP) // Sun Studio 12.3 and earlier lack SSE2's _mm_set_epi64x. // Also see http://stackoverflow.com/a/38547909/608639 -#if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5130) -inline __m128i _mm_set_epi64x(const uint64_t a, const uint64_t b) +#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE && ((__SUNPRO_CC >= 0x5100 && __SUNPRO_CC < 0x5130) || (_MSC_VER >= 1200 && _MSC_VER < 1600)) +inline __m128i _mm_set_epi64x(const word64 a, const word64 b) { union INT_128_64x2 { __m128i v128; - uint64_t v64[2]; + word64 v64[2]; }; INT_128_64x2 val; diff --git a/config.h b/config.h index a5c0c09b..73af8e27 100644 --- a/config.h +++ b/config.h @@ -217,6 +217,9 @@ typedef unsigned int word32; #if defined(_MSC_VER) || defined(__BORLANDC__) typedef unsigned __int64 word64; #define W64LIT(x) x##ui64 +#elif ((__arm64__ || __aarch64__) && (_LP64 || __LP64__)) + typedef unsigned long word64; + #define W64LIT(x) x##UL #else typedef unsigned long long word64; #define W64LIT(x) x##ULL diff --git a/config.recommend b/config.recommend index 587ff044..19c32822 100644 --- a/config.recommend +++ b/config.recommend @@ -217,6 +217,9 @@ typedef unsigned int word32; #if defined(_MSC_VER) || defined(__BORLANDC__) typedef unsigned __int64 word64; #define W64LIT(x) x##ui64 +#elif ((__arm64__ || __aarch64__) && (_LP64 || __LP64__)) + typedef unsigned long word64; + #define W64LIT(x) x##UL #else typedef unsigned long long word64; #define W64LIT(x) x##ULL diff --git a/cpu.cpp b/cpu.cpp index 8ce4cb13..fba59220 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -319,8 +319,8 @@ void DetectX86Features() // http://community.arm.com/groups/android-community/blog/2014/10/10/runtime-detection-of-cpu-features-on-an-armv8-a-cpu // bool CRYPTOPP_SECTION_INIT g_ArmDetectionDone = false; -bool CRYPTOPP_SECTION_INIT g_hasNEON = false, CRYPTOPP_SECTION_INIT g_hasCRC32 = false, CRYPTOPP_SECTION_INIT g_hasAES = false, CRYPTOPP_SECTION_INIT g_hasSHA1 = false; -bool CRYPTOPP_SECTION_INIT g_hasSHA2 = false; +bool CRYPTOPP_SECTION_INIT g_hasNEON = false, CRYPTOPP_SECTION_INIT g_hasPMULL = false, CRYPTOPP_SECTION_INIT g_hasCRC32 = false; +bool CRYPTOPP_SECTION_INIT g_hasAES = false, CRYPTOPP_SECTION_INIT g_hasSHA1 = false, CRYPTOPP_SECTION_INIT g_hasSHA2 = false; word32 CRYPTOPP_SECTION_INIT g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY @@ -332,6 +332,12 @@ extern "C" longjmp(s_jmpNoNEON, 1); } + static jmp_buf s_jmpNoPMULL; + static void SigIllHandlerPMULL(int) + { + longjmp(s_jmpNoPMULL, 1); + } + static jmp_buf s_jmpNoCRC32; static void SigIllHandlerCRC32(int) { @@ -426,6 +432,59 @@ static bool TryNEON() #endif // CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE } +static bool TryPMULL() +{ +#if (CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE) +# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) + volatile bool result = true; + __try + { + const poly64_t a1={1}, b1={2}; + const poly64x2_t a2={1}, b2={2}; + const poly128_t r1 = vmull_p64(a1, b1); + const poly128_t r2 = vmull_high_p64(a2, b2); + + result = (r1 != r2); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + return result; +# else + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854 + volatile bool result = true; + + volatile SigHandler oldHandler = signal(SIGILL, SigIllHandlerPMULL); + if (oldHandler == SIG_ERR) + return false; + + volatile sigset_t oldMask; + if (sigprocmask(0, NULL, (sigset_t*)&oldMask)) + return false; + + if (setjmp(s_jmpNoPMULL)) + result = false; + else + { + const poly64_t a1={1}, b1={2}; + const poly64x2_t a2={1}, b2={2}; + const poly128_t r1 = vmull_p64(a1, b1); + const poly128_t r2 = vmull_high_p64(a2, b2); + + result = (r1 != r2); + } + + sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULL); + signal(SIGILL, oldHandler); + return result; +# endif +#else + return false; +#endif // CRYPTOPP_BOOL_CRYPTO_INTRINSICS_AVAILABLE +} + static bool TryCRC32() { #if (CRYPTOPP_BOOL_ARM_CRC32_INTRINSICS_AVAILABLE) @@ -660,6 +719,7 @@ void DetectArmFeatures() #endif { g_hasNEON = TryNEON(); + g_hasPMULL = TryPMULL(); g_hasCRC32 = TryCRC32(); g_hasAES = TryAES(); g_hasSHA1 = TrySHA1(); diff --git a/cpu.h b/cpu.h index 3fe5d4f2..55f1a12b 100644 --- a/cpu.h +++ b/cpu.h @@ -364,7 +364,7 @@ inline int GetCacheLineSize() #elif (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64) extern bool g_ArmDetectionDone; -extern bool g_hasNEON, g_hasCRC32, g_hasAES, g_hasSHA1, g_hasSHA2; +extern bool g_hasNEON, g_hasPMULL, g_hasCRC32, g_hasAES, g_hasSHA1, g_hasSHA2; void CRYPTOPP_API DetectArmFeatures(); //! \brief Determine if an ARM processor has Advanced SIMD available @@ -380,6 +380,19 @@ inline bool HasNEON() return g_hasNEON; } +//! \brief Determine if an ARM processor provides Polynomial Multiplication (long) +//! \returns true if the hardware is capable of polynomial multiplications at runtime, false otherwise. +//! \details The multiplication instructions are available under Aarch64 (ARM-64) and Aarch32 (ARM-32). +//! \details Runtime support requires compile time support. When compiling with GCC, you may +//! need to compile with -march=armv8-a+crypto; while Apple requires +//! -arch arm64. Also see ARM's __ARM_FEATURE_CRYPTO preprocessor macro. +inline bool HasPMULL() +{ + if (!g_ArmDetectionDone) + DetectArmFeatures(); + return g_hasPMULL; +} + //! \brief Determine if an ARM processor has CRC32 available //! \returns true if the hardware is capable of CRC32 at runtime, false otherwise. //! \details CRC32 instructions provide access to the processor's CRC32 and CRC32-C intructions. @@ -485,20 +498,6 @@ inline int GetCacheLineSize() #else #define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY -#if defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION) || defined(CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) - #define NEW_LINE "\n" - #define INTEL_PREFIX ".intel_syntax;" - #define INTEL_NOPREFIX ".intel_syntax;" - #define ATT_PREFIX ".att_syntax;" - #define ATT_NOPREFIX ".att_syntax;" -#else - #define NEW_LINE - #define INTEL_PREFIX ".intel_syntax prefix;" - #define INTEL_NOPREFIX ".intel_syntax noprefix;" - #define ATT_PREFIX ".att_syntax prefix;" - #define ATT_NOPREFIX ".att_syntax noprefix;" -#endif - // define these in two steps to allow arguments to be expanded #define GNU_AS1(x) #x ";" NEW_LINE #define GNU_AS2(x, y) #x ", " #y ";" NEW_LINE @@ -519,21 +518,6 @@ inline int GetCacheLineSize() #define IF0(y) #define IF1(y) y -// Should be confined to GCC, but its used to help manage Clang 3.4 compiler error. -// Also see LLVM Bug 24232, http://llvm.org/bugs/show_bug.cgi?id=24232 . -#ifndef INTEL_PREFIX - #define INTEL_PREFIX -#endif -#ifndef INTEL_NOPREFIX - #define INTEL_NOPREFIX -#endif -#ifndef ATT_PREFIX - #define ATT_PREFIX -#endif -#ifndef ATT_NOPREFIX - #define ATT_NOPREFIX -#endif - #ifdef CRYPTOPP_GENERATE_X64_MASM #define ASM_MOD(x, y) ((x) MOD (y)) #define XMMWORD_PTR XMMWORD PTR @@ -666,6 +650,21 @@ inline int GetCacheLineSize() #endif // X86/X32/X64 +// Applies to both X86/X32/X64 and ARM32/ARM64 +#if defined(CRYPTOPP_LLVM_CLANG_VERSION) || defined(CRYPTOPP_APPLE_CLANG_VERSION) || defined(CRYPTOPP_CLANG_INTEGRATED_ASSEMBLER) + #define NEW_LINE "\n" + #define INTEL_PREFIX ".intel_syntax;" + #define INTEL_NOPREFIX ".intel_syntax;" + #define ATT_PREFIX ".att_syntax;" + #define ATT_NOPREFIX ".att_syntax;" +#else + #define NEW_LINE + #define INTEL_PREFIX ".intel_syntax prefix;" + #define INTEL_NOPREFIX ".intel_syntax noprefix;" + #define ATT_PREFIX ".att_syntax prefix;" + #define ATT_NOPREFIX ".att_syntax noprefix;" +#endif + NAMESPACE_END #endif // CRYPTOPP_CPU_H diff --git a/datatest.cpp b/datatest.cpp index 97a0fbd6..315b93da 100644 --- a/datatest.cpp +++ b/datatest.cpp @@ -24,7 +24,7 @@ #endif #if defined(__COVERITY__) -extern "C" void __coverity_tainted_data_sanitize__(void *); +extern "C" void __coverity_tainted_data_sanitize__(void *); #endif USING_NAMESPACE(CryptoPP) @@ -113,7 +113,7 @@ void PutDecodedDatumInto(const TestData &data, const char *name, BufferedTransfo repeat = atoi(s1.c_str()+1); s1 = s1.substr(s1.find(' ')+1); } - + s2 = ""; // MSVC 6 doesn't have clear(); if (s1[0] == '\"') @@ -184,9 +184,9 @@ public: else return false; } - + const std::string &value = i->second; - + if (valueType == typeid(int)) *reinterpret_cast(pValue) = atoi(value.c_str()); else if (valueType == typeid(Integer)) @@ -637,7 +637,7 @@ void TestKeyDerivationFunction(TestData &v) reinterpret_cast(key.data()), key.size(), reinterpret_cast(salt.data()), salt.size(), reinterpret_cast(info.data()), info.size()); - + if(calc != derived || ret != length) SignalTestFailure(); } diff --git a/dlltest.cpp b/dlltest.cpp index 342458f0..01906207 100644 --- a/dlltest.cpp +++ b/dlltest.cpp @@ -80,7 +80,7 @@ void FIPS140_SampleApplication() const byte message[] = {'a', 'b', 'c'}; const byte expectedDigest[] = {0xA9,0x99,0x3E,0x36,0x47,0x06,0x81,0x6A,0xBA,0x3E,0x25,0x71,0x78,0x50,0xC2,0x6C,0x9C,0xD0,0xD8,0x9D}; byte digest[20]; - + SHA1 sha; sha.Update(message, 3); sha.Final(digest); diff --git a/fipstest.cpp b/fipstest.cpp index 6edfa5b1..48704e91 100644 --- a/fipstest.cpp +++ b/fipstest.cpp @@ -82,8 +82,8 @@ void KnownAnswerTest(RandomNumberGenerator &rng, const char *output) template void X917RNG_KnownAnswerTest( - const char *key, - const char *seed, + const char *key, + const char *seed, const char *deterministicTimeVector, const char *output, CIPHER *dummy = NULL) @@ -119,9 +119,9 @@ void KnownAnswerTest(StreamTransformation &encryption, StreamTransformation &dec template void SymmetricEncryptionKnownAnswerTest( - const char *key, - const char *hexIV, - const char *plaintext, + const char *key, + const char *hexIV, + const char *plaintext, const char *ecb, const char *cbc, const char *cfb, @@ -210,22 +210,22 @@ void EncryptionPairwiseConsistencyTest(const PK_Encryptor &encryptor, const PK_D std::string ciphertext, decrypted; StringSource( - testMessage, - true, + testMessage, + true, new PK_EncryptorFilter( - rng, - encryptor, + rng, + encryptor, new StringSink(ciphertext))); if (ciphertext == testMessage) throw 0; StringSource( - ciphertext, - true, + ciphertext, + true, new PK_DecryptorFilter( - rng, - decryptor, + rng, + decryptor, new StringSink(decrypted))); if (decrypted != testMessage) @@ -244,11 +244,11 @@ void SignaturePairwiseConsistencyTest(const PK_Signer &signer, const PK_Verifier RandomPool rng; StringSource( - "test message", - true, + "test message", + true, new SignerFilter( - rng, - signer, + rng, + signer, new VerifierFilter(verifier, NULL, VerifierFilter::THROW_EXCEPTION), true)); } @@ -530,7 +530,7 @@ void DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleMac "Sample #2", "0922d3405faa3d194f82a45830737d5cc6c75d24"); - const char *keyRSA1 = + const char *keyRSA1 = "30820150020100300d06092a864886f70d01010105000482013a3082013602010002400a66791dc6988168de7ab77419bb7fb0" "c001c62710270075142942e19a8d8c51d053b3e3782a1de5dc5af4ebe99468170114a1dfe67cdc9a9af55d655620bbab0203010001" "02400123c5b61ba36edb1d3679904199a89ea80c09b9122e1400c09adcf7784676d01d23356a7d44d6bd8bd50e94bfc723fa" @@ -615,8 +615,8 @@ NAMESPACE_END #ifdef CRYPTOPP_WIN32_AVAILABLE // DllMain needs to be in the global namespace -BOOL APIENTRY DllMain(HANDLE hModule, - DWORD dwReason, +BOOL APIENTRY DllMain(HANDLE hModule, + DWORD dwReason, LPVOID /*lpReserved*/) { if (dwReason == DLL_PROCESS_ATTACH) diff --git a/setenv-ios.sh b/setenv-ios.sh index 309caf50..929f3b59 100755 --- a/setenv-ios.sh +++ b/setenv-ios.sh @@ -112,7 +112,6 @@ done # Defaults if not set if [ -z "$APPLE_SDK" ]; then APPLE_SDK=iPhoneOS - IOS_ARCH=armv7 fi if [ -z "$IOS_ARCH" ]; then diff --git a/test.cpp b/test.cpp index 509d3848..61965685 100644 --- a/test.cpp +++ b/test.cpp @@ -299,7 +299,7 @@ int CRYPTOPP_API main(int argc, char *argv[]) #endif if (fname.find(".txt") == std::string::npos) fname = "TestVectors/" + fname + ".txt"; - + PrintSeedAndThreads(seed); return !RunTestDataFile(fname.c_str()); } @@ -431,7 +431,7 @@ T StringToValue(const std::string& str) { std::istringstream iss(str); T value; iss >> value; - + // Use fail(), not bad() if (iss.fail()) throw InvalidArgument("cryptest.exe: '" + str +"' is not a value"); @@ -441,7 +441,7 @@ T StringToValue(const std::string& str) { throw InvalidArgument("cryptest.exe: '" + str +"' is negative"); #endif - return value; + return value; } template<> @@ -449,11 +449,11 @@ int StringToValue(const std::string& str) { Integer n(str.c_str()); long l = n.ConvertToLong(); - + int r; if(!SafeConvert(l, r)) throw InvalidArgument("cryptest.exe: '" + str +"' is not an integer value"); - + return r; } @@ -754,8 +754,8 @@ void GzipFile(const char *in, const char *out, int deflate_level) // \ Gunzip // \ | // \ v - // > ComparisonFilter - + // > ComparisonFilter + EqualityComparisonFilter comparison; Gunzip gunzip(new ChannelSwitch(comparison, "0")); @@ -815,12 +815,12 @@ void ForwardTcpPort(const char *sourcePortName, const char *destinationHost, con sockListen.Create(); sockListen.Bind(sourcePort); - + int err = setsockopt(sockListen, IPPROTO_TCP, TCP_NODELAY, "\x01", 1); assert(err == 0); if(err != 0) throw Socket::Err(sockListen, "setsockopt", sockListen.GetLastError()); - + cout << "Listing on port " << sourcePort << ".\n"; sockListen.Listen(); @@ -966,7 +966,7 @@ bool Validate(int alg, bool thorough, const char *seedInput) tm localTime = {}; char timeBuf[64]; errno_t err; - + const time_t endTime = time(NULL); err = localtime_s(&localTime, &endTime); assert(err == 0); diff --git a/validat1.cpp b/validat1.cpp index 55c74e33..9fb1b3de 100644 --- a/validat1.cpp +++ b/validat1.cpp @@ -317,13 +317,14 @@ bool TestSettings() #elif (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64) bool hasNEON = HasNEON(); + bool hasPMULL = HasPMULL(); bool hasCRC32 = HasCRC32(); bool hasAES = HasAES(); bool hasSHA1 = HasSHA1(); bool hasSHA2 = HasSHA2(); cout << "passed: "; - cout << "hasNEON == " << hasNEON << ", hasCRC32 == " << hasCRC32 << ", hasAES == " << hasAES << ", hasSHA1 == " << hasSHA1 << ", hasSHA2 == " << hasSHA2 << endl; + cout << "hasNEON == " << hasNEON << ", hasPMULL == " << hasPMULL << ", hasCRC32 == " << hasCRC32 << ", hasAES == " << hasAES << ", hasSHA1 == " << hasSHA1 << ", hasSHA2 == " << hasSHA2 << endl; #endif if (!pass)