Add test for AES, SHA1 and SHA2 from ARM Crypto extension from arm-neon branch
parent
9678e80eb4
commit
2a163e0b14
149
cpu.cpp
149
cpu.cpp
|
|
@ -94,8 +94,7 @@ bool CpuId(word32 input, word32 output[4])
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
// longjmp and clobber warnings. Volatile is required.
|
// longjmp and clobber warnings. Volatile is required.
|
||||||
// http://github.com/weidai11/cryptopp/issues/24
|
// http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854
|
||||||
// http://stackoverflow.com/q/7721854
|
|
||||||
volatile bool result = true;
|
volatile bool result = true;
|
||||||
|
|
||||||
SigHandler oldHandler = signal(SIGILL, SigIllHandlerCPUID);
|
SigHandler oldHandler = signal(SIGILL, SigIllHandlerCPUID);
|
||||||
|
|
@ -149,8 +148,7 @@ static bool TrySSE2()
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
// longjmp and clobber warnings. Volatile is required.
|
// longjmp and clobber warnings. Volatile is required.
|
||||||
// http://github.com/weidai11/cryptopp/issues/24
|
// http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854
|
||||||
// http://stackoverflow.com/q/7721854
|
|
||||||
volatile bool result = true;
|
volatile bool result = true;
|
||||||
|
|
||||||
SigHandler oldHandler = signal(SIGILL, SigIllHandlerSSE2);
|
SigHandler oldHandler = signal(SIGILL, SigIllHandlerSSE2);
|
||||||
|
|
@ -262,7 +260,7 @@ void DetectX86Features()
|
||||||
#elif (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64)
|
#elif (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64)
|
||||||
|
|
||||||
bool g_ArmDetectionDone = false;
|
bool g_ArmDetectionDone = false;
|
||||||
bool g_hasNEON = false, g_hasCRC32 = false, g_hasCrypto = false;
|
bool g_hasNEON = false, g_hasCRC32 = false, g_hasAES = false, g_hasSHA1 = false, g_hasSHA2 = false;
|
||||||
|
|
||||||
word32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
|
word32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
|
||||||
|
|
||||||
|
|
@ -292,10 +290,22 @@ extern "C" {
|
||||||
longjmp(s_jmpNoCRC32, 1);
|
longjmp(s_jmpNoCRC32, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static jmp_buf s_jmpNoCrypto;
|
static jmp_buf s_jmpNoAES;
|
||||||
static void SigIllHandlerCrypto(int)
|
static void SigIllHandlerAES(int)
|
||||||
{
|
{
|
||||||
longjmp(s_jmpNoCrypto, 1);
|
longjmp(s_jmpNoAES, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static jmp_buf s_jmpNoSHA1;
|
||||||
|
static void SigIllHandlerSHA1(int)
|
||||||
|
{
|
||||||
|
longjmp(s_jmpNoSHA1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static jmp_buf s_jmpNoSHA2;
|
||||||
|
static void SigIllHandlerSHA2(int)
|
||||||
|
{
|
||||||
|
longjmp(s_jmpNoSHA2, 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif // Not CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
|
#endif // Not CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
|
||||||
|
|
@ -325,8 +335,7 @@ static bool TryNEON()
|
||||||
return true;
|
return true;
|
||||||
# else
|
# else
|
||||||
// longjmp and clobber warnings. Volatile is required.
|
// longjmp and clobber warnings. Volatile is required.
|
||||||
// http://github.com/weidai11/cryptopp/issues/24
|
// http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854
|
||||||
// http://stackoverflow.com/q/7721854
|
|
||||||
volatile bool result = true;
|
volatile bool result = true;
|
||||||
|
|
||||||
SigHandler oldHandler = signal(SIGILL, SigIllHandlerNEON);
|
SigHandler oldHandler = signal(SIGILL, SigIllHandlerNEON);
|
||||||
|
|
@ -376,8 +385,7 @@ static bool TryCRC32()
|
||||||
return true;
|
return true;
|
||||||
# else
|
# else
|
||||||
// longjmp and clobber warnings. Volatile is required.
|
// longjmp and clobber warnings. Volatile is required.
|
||||||
// http://github.com/weidai11/cryptopp/issues/24
|
// http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854
|
||||||
// http://stackoverflow.com/q/7721854
|
|
||||||
volatile bool result = true;
|
volatile bool result = true;
|
||||||
|
|
||||||
SigHandler oldHandler = signal(SIGILL, SigIllHandlerCRC32);
|
SigHandler oldHandler = signal(SIGILL, SigIllHandlerCRC32);
|
||||||
|
|
@ -402,7 +410,7 @@ static bool TryCRC32()
|
||||||
#endif // CRYPTOPP_BOOL_ARM_CRC32_INTRINSICS_AVAILABLE
|
#endif // CRYPTOPP_BOOL_ARM_CRC32_INTRINSICS_AVAILABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool TryCrypto()
|
static bool TryAES()
|
||||||
{
|
{
|
||||||
#if (CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE)
|
#if (CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE)
|
||||||
# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY)
|
# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY)
|
||||||
|
|
@ -412,8 +420,7 @@ static bool TryCrypto()
|
||||||
static const uint8x16_t data = vdupq_n_u8(0), key = vdupq_n_u8(0);
|
static const uint8x16_t data = vdupq_n_u8(0), key = vdupq_n_u8(0);
|
||||||
uint8x16_t r1 = vaeseq_u8(data, key);
|
uint8x16_t r1 = vaeseq_u8(data, key);
|
||||||
uint8x16_t r2 = vaesdq_u8(data, key);
|
uint8x16_t r2 = vaesdq_u8(data, key);
|
||||||
|
CRYPTOPP_UNUSED(r1), CRYPTOPP_UNUSED(r2);
|
||||||
//
|
|
||||||
}
|
}
|
||||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
|
|
@ -422,21 +429,121 @@ static bool TryCrypto()
|
||||||
return true;
|
return true;
|
||||||
# else
|
# else
|
||||||
// longjmp and clobber warnings. Volatile is required.
|
// longjmp and clobber warnings. Volatile is required.
|
||||||
// http://github.com/weidai11/cryptopp/issues/24
|
// http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854
|
||||||
// http://stackoverflow.com/q/7721854
|
|
||||||
volatile bool result = true;
|
volatile bool result = true;
|
||||||
|
|
||||||
SigHandler oldHandler = signal(SIGILL, SigIllHandlerCrypto);
|
SigHandler oldHandler = signal(SIGILL, SigIllHandlerAES);
|
||||||
if (oldHandler == SIG_ERR)
|
if (oldHandler == SIG_ERR)
|
||||||
result = false;
|
result = false;
|
||||||
|
|
||||||
if (setjmp(s_jmpNoCrypto))
|
if (setjmp(s_jmpNoAES))
|
||||||
result = false;
|
result = false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
static const uint8x16_t data = vdupq_n_u8(0), key = vdupq_n_u8(0);
|
static const uint8x16_t data = vdupq_n_u8(0), key = vdupq_n_u8(0);
|
||||||
uint8x16_t r1 = vaeseq_u8(data, key);
|
uint8x16_t r1 = vaeseq_u8(data, key);
|
||||||
uint8x16_t r2 = vaesdq_u8(data, key);
|
uint8x16_t r2 = vaesdq_u8(data, key);
|
||||||
|
CRYPTOPP_UNUSED(r1), CRYPTOPP_UNUSED(r2);
|
||||||
|
}
|
||||||
|
|
||||||
|
signal(SIGILL, oldHandler);
|
||||||
|
return result;
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif // CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool TrySHA1()
|
||||||
|
{
|
||||||
|
#if (CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE)
|
||||||
|
# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY)
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
static const uint32x4_t data = vdupq_n_u32(0);
|
||||||
|
static const uint32_t hash = 0x0;
|
||||||
|
|
||||||
|
uint32x4_t r1 = vsha1cq_u32 (data, hash, data);
|
||||||
|
uint32x4_t r2 = vsha1mq_u32 (data, hash, data);
|
||||||
|
uint32x4_t r3 = vsha1pq_u32 (data, hash, data);
|
||||||
|
CRYPTOPP_UNUSED(r1), CRYPTOPP_UNUSED(r2), CRYPTOPP_UNUSED(r3);
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
# 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;
|
||||||
|
|
||||||
|
SigHandler oldHandler = signal(SIGILL, SigIllHandlerSHA1);
|
||||||
|
if (oldHandler == SIG_ERR)
|
||||||
|
result = false;
|
||||||
|
|
||||||
|
if (setjmp(s_jmpNoSHA1))
|
||||||
|
result = false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static const uint32x4_t data = vdupq_n_u32(0);
|
||||||
|
static const uint32_t hash = 0x0;
|
||||||
|
|
||||||
|
uint32x4_t r1 = vsha1cq_u32 (data, hash, data);
|
||||||
|
uint32x4_t r2 = vsha1mq_u32 (data, hash, data);
|
||||||
|
uint32x4_t r3 = vsha1pq_u32 (data, hash, data);
|
||||||
|
CRYPTOPP_UNUSED(r1), CRYPTOPP_UNUSED(r2), CRYPTOPP_UNUSED(r3);
|
||||||
|
}
|
||||||
|
|
||||||
|
signal(SIGILL, oldHandler);
|
||||||
|
return result;
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif // CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool TrySHA2()
|
||||||
|
{
|
||||||
|
#if (CRYPTOPP_BOOL_ARM_CRYPTO_INTRINSICS_AVAILABLE)
|
||||||
|
# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY)
|
||||||
|
__try
|
||||||
|
{
|
||||||
|
static const uint32x4_t data = vdupq_n_u32(0);
|
||||||
|
static const uint32x4_t hash = vdupq_n_u32(0);
|
||||||
|
|
||||||
|
uint32x4_t r1 = vsha256hq_u32 (hash, hash, data);
|
||||||
|
uint32x4_t r2 = vsha256h2q_u32 (hash, hash, data);
|
||||||
|
uint32x4_t r3 = vsha256su0q_u32 (data, data);
|
||||||
|
uint32x4_t r4 = vsha256su1q_u32 (data, data, data);
|
||||||
|
CRYPTOPP_UNUSED(r1), CRYPTOPP_UNUSED(r2), CRYPTOPP_UNUSED(r3), CRYPTOPP_UNUSED(r4);
|
||||||
|
}
|
||||||
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
# 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;
|
||||||
|
|
||||||
|
SigHandler oldHandler = signal(SIGILL, SigIllHandlerSHA2);
|
||||||
|
if (oldHandler == SIG_ERR)
|
||||||
|
result = false;
|
||||||
|
|
||||||
|
if (setjmp(s_jmpNoSHA2))
|
||||||
|
result = false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static const uint32x4_t data = vdupq_n_u32(0);
|
||||||
|
static const uint32x4_t hash = vdupq_n_u32(0);
|
||||||
|
|
||||||
|
uint32x4_t r1 = vsha256hq_u32 (hash, hash, data);
|
||||||
|
uint32x4_t r2 = vsha256h2q_u32 (hash, hash, data);
|
||||||
|
uint32x4_t r3 = vsha256su0q_u32 (data, data);
|
||||||
|
uint32x4_t r4 = vsha256su1q_u32 (data, data, data);
|
||||||
|
CRYPTOPP_UNUSED(r1), CRYPTOPP_UNUSED(r2), CRYPTOPP_UNUSED(r3), CRYPTOPP_UNUSED(r4);
|
||||||
}
|
}
|
||||||
|
|
||||||
signal(SIGILL, oldHandler);
|
signal(SIGILL, oldHandler);
|
||||||
|
|
@ -457,7 +564,9 @@ void DetectArmFeatures()
|
||||||
{
|
{
|
||||||
g_hasNEON = TryNEON();
|
g_hasNEON = TryNEON();
|
||||||
g_hasCRC32 = TryCRC32();
|
g_hasCRC32 = TryCRC32();
|
||||||
g_hasCrypto = TryCrypto();
|
g_hasAES = TryAES();
|
||||||
|
g_hasSHA1 = TrySHA1();
|
||||||
|
g_hasSHA2 = TrySHA2();
|
||||||
|
|
||||||
*((volatile bool*)&g_ArmDetectionDone) = true;
|
*((volatile bool*)&g_ArmDetectionDone) = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
46
cpu.h
46
cpu.h
|
|
@ -240,7 +240,7 @@ inline int GetCacheLineSize()
|
||||||
#elif (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64)
|
#elif (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64)
|
||||||
|
|
||||||
extern bool g_ArmDetectionDone;
|
extern bool g_ArmDetectionDone;
|
||||||
extern bool g_hasNEON, g_hasCRC32, g_hasCrypto;
|
extern bool g_hasNEON, g_hasCRC32, g_hasAES, g_hasSHA1, g_hasSHA2;
|
||||||
void CRYPTOPP_API DetectArmFeatures();
|
void CRYPTOPP_API DetectArmFeatures();
|
||||||
|
|
||||||
//! \brief Determine if an ARM processor has Advanced SIMD available
|
//! \brief Determine if an ARM processor has Advanced SIMD available
|
||||||
|
|
@ -271,19 +271,49 @@ inline bool HasCRC32()
|
||||||
return g_hasCRC32;
|
return g_hasCRC32;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \brief Determine if an ARM processor has Crypto available
|
//! \brief Determine if an ARM processor has AES available
|
||||||
//! \returns true if the hardware is capable of Crypto at runtime, false otherwise.
|
//! \returns true if the hardware is capable of AES at runtime, false otherwise.
|
||||||
//! \details Crypto instructions provide access to the processor's AES, SHA-1, SHA-224 and SHA-256 intructions.
|
//! \details AES is part of the Crypto extensions from ARM C Language Extensions 2.0 (ACLE 2.0)
|
||||||
//! They are provided by ARM C Language Extensions 2.0 (ACLE 2.0) and available under Aarch64
|
//! and available under Aarch64 (ARM-64) and Aarch32 (ARM-32) running on Aarch64 (i.e., an
|
||||||
//! (ARM-64) and Aarch32 (ARM-32) running on Aarch64 (i.e., an AArch32 execution environment).
|
//! AArch32 execution environment).
|
||||||
//! \details Runtime support requires compile time support. When compiling with GCC, you may
|
//! \details Runtime support requires compile time support. When compiling with GCC, you may
|
||||||
//! need to compile with <tt>-march=armv8-a+crypto</tt>; while Apple requires
|
//! need to compile with <tt>-march=armv8-a+crypto</tt>; while Apple requires
|
||||||
//! <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRYPTO</tt> preprocessor macro.
|
//! <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRYPTO</tt> preprocessor macro.
|
||||||
inline bool HasCrypto()
|
inline bool HasAES()
|
||||||
{
|
{
|
||||||
if (!g_ArmDetectionDone)
|
if (!g_ArmDetectionDone)
|
||||||
DetectArmFeatures();
|
DetectArmFeatures();
|
||||||
return g_hasCrypto;
|
return g_hasAES;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \brief Determine if an ARM processor has SHA1 available
|
||||||
|
//! \returns true if the hardware is capable of SHA1 at runtime, false otherwise.
|
||||||
|
//! \details SHA1 is part of the Crypto extensions from ARM C Language Extensions 2.0 (ACLE 2.0)
|
||||||
|
//! and available under Aarch64 (ARM-64) and Aarch32 (ARM-32) running on Aarch64 (i.e., an
|
||||||
|
//! AArch32 execution environment).
|
||||||
|
//! \details Runtime support requires compile time support. When compiling with GCC, you may
|
||||||
|
//! need to compile with <tt>-march=armv8-a+crypto</tt>; while Apple requires
|
||||||
|
//! <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRYPTO</tt> preprocessor macro.
|
||||||
|
inline bool HasSHA1()
|
||||||
|
{
|
||||||
|
if (!g_ArmDetectionDone)
|
||||||
|
DetectArmFeatures();
|
||||||
|
return g_hasSHA1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! \brief Determine if an ARM processor has SHA2 available
|
||||||
|
//! \returns true if the hardware is capable of SHA2 at runtime, false otherwise.
|
||||||
|
//! \details SHA2 is part of the Crypto extensions from ARM C Language Extensions 2.0 (ACLE 2.0)
|
||||||
|
//! and available under Aarch64 (ARM-64) and Aarch32 (ARM-32) running on Aarch64 (i.e., an
|
||||||
|
//! AArch32 execution environment).
|
||||||
|
//! \details Runtime support requires compile time support. When compiling with GCC, you may
|
||||||
|
//! need to compile with <tt>-march=armv8-a+crypto</tt>; while Apple requires
|
||||||
|
//! <tt>-arch arm64</tt>. Also see ARM's <tt>__ARM_FEATURE_CRYPTO</tt> preprocessor macro.
|
||||||
|
inline bool HasSHA2()
|
||||||
|
{
|
||||||
|
if (!g_ArmDetectionDone)
|
||||||
|
DetectArmFeatures();
|
||||||
|
return g_hasSHA2;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \brief Provides the cache line size at runtime
|
//! \brief Provides the cache line size at runtime
|
||||||
|
|
|
||||||
10
validat1.cpp
10
validat1.cpp
|
|
@ -311,6 +311,16 @@ bool TestSettings()
|
||||||
|
|
||||||
cout << "hasMMX == " << hasMMX << ", hasISSE == " << hasISSE << ", hasSSE2 == " << hasSSE2 << ", hasSSSE3 == " << hasSSE4 << ", hasSSE4 == " << hasSSSE3 << ", hasAESNI == " << HasAESNI() << ", hasRDRAND == " << HasRDRAND() << ", hasRDSEED == " << HasRDSEED() << ", hasCLMUL == " << HasCLMUL() << ", isP4 == " << isP4 << ", cacheLineSize == " << cacheLineSize;
|
cout << "hasMMX == " << hasMMX << ", hasISSE == " << hasISSE << ", hasSSE2 == " << hasSSE2 << ", hasSSSE3 == " << hasSSE4 << ", hasSSE4 == " << hasSSSE3 << ", hasAESNI == " << HasAESNI() << ", hasRDRAND == " << HasRDRAND() << ", hasRDSEED == " << HasRDSEED() << ", hasCLMUL == " << HasCLMUL() << ", isP4 == " << isP4 << ", cacheLineSize == " << cacheLineSize;
|
||||||
cout << ", AESNI_INTRINSICS == " << CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE << endl;
|
cout << ", AESNI_INTRINSICS == " << CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE << endl;
|
||||||
|
|
||||||
|
#elif (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64)
|
||||||
|
bool hasNEON = HasNEON();
|
||||||
|
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;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!pass)
|
if (!pass)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue