Add CRYPTOPP_NO_CPU_FEATURE_PROBES (GH #511)

We determine machine capabilities by performing an os/platform *query* first, like getauxv(). If the *query* fails, we move onto a cpu *probe*. The cpu *probe* tries to exeute an instruction and then catches a SIGILL on Linux or the exception EXCEPTION_ILLEGAL_INSTRUCTION on Windows. Some OSes fail to hangle a SIGILL gracefully, like Apple OSes. Apple machines corrupt memory and variables around the probe.
pull/484/merge
Jeffrey Walton 2017-09-19 21:08:37 -04:00
parent 6440921723
commit 6102333fc3
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
10 changed files with 168 additions and 34 deletions

View File

@ -2158,6 +2158,63 @@ if true; then
fi
fi
############################################
# Debug build, NO_CPU_FEATURE_PROBES
if true; then
############################################
# Debug build
echo
echo "************************************" | tee -a "$TEST_RESULTS"
echo "Testing: Debug, NO_CPU_FEATURE_PROBES" | tee -a "$TEST_RESULTS"
echo
"$MAKE" clean > /dev/null 2>&1
rm -f adhoc.cpp > /dev/null 2>&1
CXXFLAGS="$DEBUG_CXXFLAGS -DCRYPTOPP_NO_CPU_FEATURE_PROBES=1"
CXX="$CXX" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS"
else
./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS"
fi
./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS"
fi
fi
############################################
# Release build
echo
echo "************************************" | tee -a "$TEST_RESULTS"
echo "Testing: Release, NO_CPU_FEATURE_PROBES" | tee -a "$TEST_RESULTS"
echo
"$MAKE" clean > /dev/null 2>&1
rm -f adhoc.cpp > /dev/null 2>&1
CXXFLAGS="$RELEASE_CXXFLAGS -DCRYPTOPP_NO_CPU_FEATURE_PROBES=1"
CXX="$CXX" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS"
else
./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS"
fi
./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS"
fi
fi
fi
############################################
# c++03 debug and release build
if [[ "$HAVE_CXX03" -ne "0" ]]; then

View File

@ -664,6 +664,18 @@ NAMESPACE_END
# define CRYPTOPP_CONSTANT(x) enum {x};
#endif
// How to disable CPU feature probing. We determine machine
// capabilities by performing an os/platform *query* first,
// like getauxv(). If the *query* fails, we move onto a
// cpu *probe*. The cpu *probe* tries to exeute an instruction
// and then catches a SIGILL on Linux or the exception
// EXCEPTION_ILLEGAL_INSTRUCTION on Windows. Some OSes
// fail to hangle a SIGILL gracefully, like Apple OSes. Apple
// machines corrupt memory and variables around the probe.
#if defined(__APPLE__)
# define CRYPTOPP_NO_CPU_FEATURE_PROBES 1
#endif
// ***************** Initialization and Constructor priorities ********************
// CRYPTOPP_INIT_PRIORITY attempts to manage initialization of C++ static objects.

View File

@ -102,7 +102,9 @@ extern "C"
// cpu.cpp (131): E2211 Inline assembly not allowed in inline and template functions
bool CpuId(word32 func, word32 subfunc, word32 output[4])
{
#if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) || defined(__BORLANDC__)
#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
return false;
#elif defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) || defined(__BORLANDC__)
__try
{
// Borland/Embarcadero and Issue 500
@ -182,7 +184,9 @@ bool CpuId(word32 func, word32 subfunc, word32 output[4])
static bool CPU_ProbeSSE2()
{
#if CRYPTOPP_BOOL_X64
#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
return false;
#elif CRYPTOPP_BOOL_X64
return true;
#elif defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY)
__try

View File

@ -56,7 +56,9 @@ extern "C" {
bool CPU_ProbeCRC32()
{
#if (CRYPTOPP_ARM_CRC32_AVAILABLE)
#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
return false;
#elif (CRYPTOPP_ARM_CRC32_AVAILABLE)
# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY)
volatile bool result = true;
__try
@ -78,11 +80,6 @@ bool CPU_ProbeCRC32()
return result;
#else
# if defined(__APPLE__)
// No SIGILL probes on Apple platforms.
return false;
# endif
// longjmp and clobber warnings. Volatile is required.
// http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854
volatile bool result = true;

View File

@ -2158,6 +2158,63 @@ if true; then
fi
fi
############################################
# Debug build, NO_CPU_FEATURE_PROBES
if true; then
############################################
# Debug build
echo
echo "************************************" | tee -a "$TEST_RESULTS"
echo "Testing: Debug, NO_CPU_FEATURE_PROBES" | tee -a "$TEST_RESULTS"
echo
"$MAKE" clean > /dev/null 2>&1
rm -f adhoc.cpp > /dev/null 2>&1
CXXFLAGS="$DEBUG_CXXFLAGS -DCRYPTOPP_NO_CPU_FEATURE_PROBES=1"
CXX="$CXX" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS"
else
./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS"
fi
./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS"
fi
fi
############################################
# Release build
echo
echo "************************************" | tee -a "$TEST_RESULTS"
echo "Testing: Release, NO_CPU_FEATURE_PROBES" | tee -a "$TEST_RESULTS"
echo
"$MAKE" clean > /dev/null 2>&1
rm -f adhoc.cpp > /dev/null 2>&1
CXXFLAGS="$RELEASE_CXXFLAGS -DCRYPTOPP_NO_CPU_FEATURE_PROBES=1"
CXX="$CXX" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS"
else
./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS"
fi
./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS"
fi
fi
fi
############################################
# c++03 debug and release build
if [[ "$HAVE_CXX03" -ne "0" ]]; then

View File

@ -198,7 +198,9 @@ extern "C" {
#if (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64)
bool CPU_ProbePMULL()
{
#if (CRYPTOPP_ARM_PMULL_AVAILABLE)
#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
return false;
#elif (CRYPTOPP_ARM_PMULL_AVAILABLE)
# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY)
volatile bool result = true;
__try

View File

@ -47,7 +47,9 @@ extern "C" {
bool CPU_ProbeNEON()
{
#if (CRYPTOPP_ARM_NEON_AVAILABLE)
#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
return false;
#elif (CRYPTOPP_ARM_NEON_AVAILABLE)
# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY)
volatile bool result = true;
__try

View File

@ -67,7 +67,9 @@ extern "C" {
#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64)
bool CPU_ProbeAltivec()
{
#if (CRYPTOPP_ALTIVEC_AVAILABLE)
#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
return false;
#elif (CRYPTOPP_ALTIVEC_AVAILABLE)
# if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY)
// longjmp and clobber warnings. Volatile is required.
@ -117,7 +119,9 @@ bool CPU_ProbeAltivec()
#if 0
bool CPU_ProbePower7()
{
#if (CRYPTOPP_POWER7_AVAILABLE)
#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
return false;
#elif (CRYPTOPP_POWER7_AVAILABLE)
# if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY)
// longjmp and clobber warnings. Volatile is required.
@ -161,7 +165,9 @@ bool CPU_ProbePower7()
bool CPU_ProbePower8()
{
#if (CRYPTOPP_POWER8_AVAILABLE)
#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
return false;
#elif (CRYPTOPP_POWER8_AVAILABLE)
# if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY)
// longjmp and clobber warnings. Volatile is required.
@ -204,7 +210,9 @@ bool CPU_ProbePower8()
bool CPU_ProbeAES()
{
#if (CRYPTOPP_POWER8_AES_AVAILABLE)
#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
return false;
#elif (CRYPTOPP_POWER8_AES_AVAILABLE)
# if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY)
// longjmp and clobber warnings. Volatile is required.
@ -255,7 +263,9 @@ bool CPU_ProbeAES()
bool CPU_ProbeSHA1()
{
#if (CRYPTOPP_ALTIVEC_AVAILABLE)
#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
return false;
#elif (CRYPTOPP_ALTIVEC_AVAILABLE)
# if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY)
// longjmp and clobber warnings. Volatile is required.
@ -288,7 +298,9 @@ bool CPU_ProbeSHA1()
bool CPU_ProbeSHA2()
{
#if (CRYPTOPP_ALTIVEC_AVAILABLE)
#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
return false;
#elif (CRYPTOPP_ALTIVEC_AVAILABLE)
# if defined(CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY)
// longjmp and clobber warnings. Volatile is required.

View File

@ -92,7 +92,9 @@ extern "C" {
#if (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64)
bool CPU_ProbeAES()
{
#if (CRYPTOPP_ARM_AES_AVAILABLE)
#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
return false;
#elif (CRYPTOPP_ARM_AES_AVAILABLE)
# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY)
volatile bool result = true;
__try
@ -113,11 +115,6 @@ bool CPU_ProbeAES()
return result;
# else
# if defined(__APPLE__)
// No SIGILL probes on Apple platforms.
return false;
# endif
// longjmp and clobber warnings. Volatile is required.
// http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854
volatile bool result = true;

View File

@ -61,7 +61,9 @@ extern "C" {
#if (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64)
bool CPU_ProbeSHA1()
{
#if (CRYPTOPP_ARM_SHA_AVAILABLE)
#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
return false;
#elif (CRYPTOPP_ARM_SHA_AVAILABLE)
# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY)
volatile bool result = true;
__try
@ -83,11 +85,6 @@ bool CPU_ProbeSHA1()
return result;
# else
# if defined(__APPLE__)
// No SIGILL probes on Apple platforms.
return false;
# endif
// longjmp and clobber warnings. Volatile is required.
// http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854
volatile bool result = true;
@ -126,7 +123,9 @@ bool CPU_ProbeSHA1()
bool CPU_ProbeSHA2()
{
#if (CRYPTOPP_ARM_SHA_AVAILABLE)
#if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES)
return false;
#elif (CRYPTOPP_ARM_SHA_AVAILABLE)
# if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY)
volatile bool result = true;
__try
@ -147,11 +146,6 @@ bool CPU_ProbeSHA2()
return result;
#else
# if defined(__APPLE__)
// No SIGILL probes on Apple platforms.
return false;
# endif
// longjmp and clobber warnings. Volatile is required.
// http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854
volatile bool result = true;