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)