From bf8a765c32acf7d5b32bbcfc4642e5fe3ad9a9b4 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Sat, 28 Sep 2019 21:37:58 -0400 Subject: [PATCH] Fix Rijndael recursion overflow when -DCRYPTOPP_DISABLE_SSSE3 (GH #880, PR #886) --- config_asm.h | 28 +++++++ cpu.h | 224 +++++++++++++++++++++++++++++++++------------------ rdrand.cpp | 23 ++++-- 3 files changed, 189 insertions(+), 86 deletions(-) diff --git a/config_asm.h b/config_asm.h index 23fea931..87125773 100644 --- a/config_asm.h +++ b/config_asm.h @@ -172,6 +172,34 @@ #define CRYPTOPP_SHANI_AVAILABLE 1 #endif +// RDRAND uses byte codes. All we need is x86 ASM for it. +// However tie it to AES-NI since SecureKey was available with it. +#if !defined(CRYPTOPP_DISABLE_RDRAND) && defined(CRYPTOPP_AESNI_AVAILABLE) && \ + !(defined(__ANDROID__) || defined(ANDROID)) && \ + defined(CRYPTOPP_X86_ASM_AVAILABLE) + #define CRYPTOPP_RDRAND_AVAILABLE 1 +#endif + +// RDSEED uses byte codes. All we need is x86 ASM for it. +// However tie it to AES-NI since SecureKey was available with it. +#if !defined(CRYPTOPP_DISABLE_RDSEED) && defined(CRYPTOPP_AESNI_AVAILABLE) && \ + !(defined(__ANDROID__) || defined(ANDROID)) && \ + defined(CRYPTOPP_X86_ASM_AVAILABLE) + #define CRYPTOPP_RDSEED_AVAILABLE 1 +#endif + +// PadlockRNG uses byte codes. All we need is x86 ASM for it. +#if !defined(CRYPTOPP_DISABLE_PADLOCK) && \ + !(defined(__ANDROID__) || defined(ANDROID) || defined(__APPLE__)) && \ + defined(CRYPTOPP_X86_ASM_AVAILABLE) + #define CRYPTOPP_PADLOCK_AVAILABLE 1 + #define CRYPTOPP_PADLOCK_RNG_AVAILABLE 1 + #define CRYPTOPP_PADLOCK_ACE_AVAILABLE 1 + #define CRYPTOPP_PADLOCK_ACE2_AVAILABLE 1 + #define CRYPTOPP_PADLOCK_PHE_AVAILABLE 1 + #define CRYPTOPP_PADLOCK_PMM_AVAILABLE 1 +#endif + // Fixup Android and SSE, Crypto. It may be enabled based on compiler version. #if (defined(__ANDROID__) || defined(ANDROID)) # if (CRYPTOPP_BOOL_X86) diff --git a/cpu.h b/cpu.h index cced64d6..b1d1f004 100644 --- a/cpu.h +++ b/cpu.h @@ -115,12 +115,14 @@ CRYPTOPP_DLL bool CRYPTOPP_API CpuId(word32 func, word32 subfunc, word32 output[ /// \note This function is only available on Intel IA-32 platforms inline bool HasSSE2() { -#if CRYPTOPP_BOOL_X64 +#if (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32) return true; -#else +#elif (CRYPTOPP_SSE2_ASM_AVAILABLE || CRYPTOPP_SSE2_INTRIN_AVAILABLE) if (!g_x86DetectionDone) DetectX86Features(); return g_hasSSE2; +#else + return false; #endif } @@ -130,9 +132,13 @@ inline bool HasSSE2() /// \note This function is only available on Intel IA-32 platforms inline bool HasSSSE3() { +#if CRYPTOPP_SSSE3_AVAILABLE if (!g_x86DetectionDone) DetectX86Features(); return g_hasSSSE3; +#else + return false; +#endif } /// \brief Determines SSE4.1 availability @@ -141,9 +147,13 @@ inline bool HasSSSE3() /// \note This function is only available on Intel IA-32 platforms inline bool HasSSE41() { +#if CRYPTOPP_SSE41_AVAILABLE if (!g_x86DetectionDone) DetectX86Features(); return g_hasSSE41; +#else + return false; +#endif } /// \brief Determines SSE4.2 availability @@ -152,9 +162,13 @@ inline bool HasSSE41() /// \note This function is only available on Intel IA-32 platforms inline bool HasSSE42() { +#if CRYPTOPP_SSE42_AVAILABLE if (!g_x86DetectionDone) DetectX86Features(); return g_hasSSE42; +#else + return false; +#endif } /// \brief Determines AES-NI availability @@ -164,9 +178,13 @@ inline bool HasSSE42() /// \note This function is only available on Intel IA-32 platforms inline bool HasAESNI() { +#if CRYPTOPP_AESNI_AVAILABLE if (!g_x86DetectionDone) DetectX86Features(); return g_hasAESNI; +#else + return false; +#endif } /// \brief Determines Carryless Multiply availability @@ -176,9 +194,13 @@ inline bool HasAESNI() /// \note This function is only available on Intel IA-32 platforms inline bool HasCLMUL() { +#if CRYPTOPP_CLMUL_AVAILABLE if (!g_x86DetectionDone) DetectX86Features(); return g_hasCLMUL; +#else + return false; +#endif } /// \brief Determines SHA availability @@ -188,9 +210,13 @@ inline bool HasCLMUL() /// \note This function is only available on Intel IA-32 platforms inline bool HasSHA() { +#if CRYPTOPP_SHANI_AVAILABLE if (!g_x86DetectionDone) DetectX86Features(); return g_hasSHA; +#else + return false; +#endif } /// \brief Determines ADX availability @@ -200,9 +226,13 @@ inline bool HasSHA() /// \note This function is only available on Intel IA-32 platforms inline bool HasADX() { +#if CRYPTOPP_ADX_AVAILABLE if (!g_x86DetectionDone) DetectX86Features(); return g_hasADX; +#else + return false; +#endif } /// \brief Determines AVX availability @@ -212,9 +242,13 @@ inline bool HasADX() /// \note This function is only available on Intel IA-32 platforms inline bool HasAVX() { +#if CRYPTOPP_AVX_AVAILABLE if (!g_x86DetectionDone) DetectX86Features(); return g_hasAVX; +#else + return false; +#endif } /// \brief Determines AVX2 availability @@ -224,9 +258,118 @@ inline bool HasAVX() /// \note This function is only available on Intel IA-32 platforms inline bool HasAVX2() { +#if CRYPTOPP_AVX2_AVAILABLE if (!g_x86DetectionDone) DetectX86Features(); return g_hasAVX2; +#else + return false; +#endif +} + +/// \brief Determines RDRAND availability +/// \returns true if RDRAND is determined to be available, false otherwise +/// \details HasRDRAND() is a runtime check performed using CPUID +/// \note This function is only available on Intel IA-32 platforms +inline bool HasRDRAND() +{ +#if CRYPTOPP_RDRAND_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasRDRAND; +#else + return false; +#endif +} + +/// \brief Determines RDSEED availability +/// \returns true if RDSEED is determined to be available, false otherwise +/// \details HasRDSEED() is a runtime check performed using CPUID +/// \note This function is only available on Intel IA-32 platforms +inline bool HasRDSEED() +{ +#if CRYPTOPP_RDSEED_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasRDSEED; +#else + return false; +#endif +} + +/// \brief Determines Padlock RNG availability +/// \returns true if VIA Padlock RNG is determined to be available, false otherwise +/// \details HasPadlockRNG() is a runtime check performed using CPUID +/// \note This function is only available on Intel IA-32 platforms +inline bool HasPadlockRNG() +{ +#if CRYPTOPP_PADLOCK_RNG_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasPadlockRNG; +#else + return false; +#endif +} + +/// \brief Determines Padlock ACE availability +/// \returns true if VIA Padlock ACE is determined to be available, false otherwise +/// \details HasPadlockACE() is a runtime check performed using CPUID +/// \note This function is only available on Intel IA-32 platforms +inline bool HasPadlockACE() +{ +#if CRYPTOPP_PADLOCK_ACE_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasPadlockACE; +#else + return false; +#endif +} + +/// \brief Determines Padlock ACE2 availability +/// \returns true if VIA Padlock ACE2 is determined to be available, false otherwise +/// \details HasPadlockACE2() is a runtime check performed using CPUID +/// \note This function is only available on Intel IA-32 platforms +inline bool HasPadlockACE2() +{ +#if CRYPTOPP_PADLOCK_ACE2_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasPadlockACE2; +#else + return false; +#endif +} + +/// \brief Determines Padlock PHE availability +/// \returns true if VIA Padlock PHE is determined to be available, false otherwise +/// \details HasPadlockPHE() is a runtime check performed using CPUID +/// \note This function is only available on Intel IA-32 platforms +inline bool HasPadlockPHE() +{ +#if CRYPTOPP_PADLOCK_PHE_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasPadlockPHE; +#else + return false; +#endif +} + +/// \brief Determines Padlock PMM availability +/// \returns true if VIA Padlock PMM is determined to be available, false otherwise +/// \details HasPadlockPMM() is a runtime check performed using CPUID +/// \note This function is only available on Intel IA-32 platforms +inline bool HasPadlockPMM() +{ +#if CRYPTOPP_PADLOCK_PMM_AVAILABLE + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasPadlockPMM; +#else + return false; +#endif } /// \brief Determines if the CPU is an Intel P4 @@ -240,83 +383,6 @@ inline bool IsP4() return g_isP4; } -/// \brief Determines RDRAND availability -/// \returns true if RDRAND is determined to be available, false otherwise -/// \details HasRDRAND() is a runtime check performed using CPUID -/// \note This function is only available on Intel IA-32 platforms -inline bool HasRDRAND() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_hasRDRAND; -} - -/// \brief Determines RDSEED availability -/// \returns true if RDSEED is determined to be available, false otherwise -/// \details HasRDSEED() is a runtime check performed using CPUID -/// \note This function is only available on Intel IA-32 platforms -inline bool HasRDSEED() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_hasRDSEED; -} - -/// \brief Determines Padlock RNG availability -/// \returns true if VIA Padlock RNG is determined to be available, false otherwise -/// \details HasPadlockRNG() is a runtime check performed using CPUID -/// \note This function is only available on Intel IA-32 platforms -inline bool HasPadlockRNG() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_hasPadlockRNG; -} - -/// \brief Determines Padlock ACE availability -/// \returns true if VIA Padlock ACE is determined to be available, false otherwise -/// \details HasPadlockACE() is a runtime check performed using CPUID -/// \note This function is only available on Intel IA-32 platforms -inline bool HasPadlockACE() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_hasPadlockACE; -} - -/// \brief Determines Padlock ACE2 availability -/// \returns true if VIA Padlock ACE2 is determined to be available, false otherwise -/// \details HasPadlockACE2() is a runtime check performed using CPUID -/// \note This function is only available on Intel IA-32 platforms -inline bool HasPadlockACE2() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_hasPadlockACE2; -} - -/// \brief Determines Padlock PHE availability -/// \returns true if VIA Padlock PHE is determined to be available, false otherwise -/// \details HasPadlockPHE() is a runtime check performed using CPUID -/// \note This function is only available on Intel IA-32 platforms -inline bool HasPadlockPHE() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_hasPadlockPHE; -} - -/// \brief Determines Padlock PMM availability -/// \returns true if VIA Padlock PMM is determined to be available, false otherwise -/// \details HasPadlockPMM() is a runtime check performed using CPUID -/// \note This function is only available on Intel IA-32 platforms -inline bool HasPadlockPMM() -{ - if (!g_x86DetectionDone) - DetectX86Features(); - return g_hasPadlockPMM; -} - /// \brief Provides the cache line size /// \returns lower bound on the size of a cache line in bytes, if available /// \details GetCacheLineSize() returns the lower bound on the size of a cache line, if it diff --git a/rdrand.cpp b/rdrand.cpp index 0c83aaab..dd998cd1 100644 --- a/rdrand.cpp +++ b/rdrand.cpp @@ -24,20 +24,25 @@ ///////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////// -#if defined(CRYPTOPP_CPUID_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM) - +#if defined(CRYPTOPP_RDRAND_AVAILABLE) # if defined(CRYPTOPP_MSC_VERSION) # define MASM_RDRAND_ASM_AVAILABLE 1 -# define MASM_RDSEED_ASM_AVAILABLE 1 # endif - # if (__SUNPRO_CC >= 0x5100) || (CRYPTOPP_APPLE_CLANG_VERSION >= 30000) || \ (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) || (CRYPTOPP_GCC_VERSION >= 30200) # define GCC_RDRAND_ASM_AVAILABLE 1 +# endif +#endif // CRYPTOPP_RDRAND_AVAILABLE + +#if defined(CRYPTOPP_RDSEED_AVAILABLE) +# if defined(CRYPTOPP_MSC_VERSION) +# define MASM_RDSEED_ASM_AVAILABLE 1 +# endif +# if (__SUNPRO_CC >= 0x5100) || (CRYPTOPP_APPLE_CLANG_VERSION >= 30000) || \ + (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) || (CRYPTOPP_GCC_VERSION >= 30200) # define GCC_RDSEED_ASM_AVAILABLE 1 # endif - -#endif // CRYPTOPP_CPUID_AVAILABLE +#endif // CRYPTOPP_RDSEED_AVAILABLE typedef unsigned char byte; @@ -54,7 +59,7 @@ extern "C" void CRYPTOPP_FASTCALL MASM_RDSEED_GenerateBlock(byte*, size_t); NAMESPACE_BEGIN(CryptoPP) -#if defined(CRYPTOPP_CPUID_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM) +#if defined(CRYPTOPP_RDRAND_AVAILABLE) // Fills 4 bytes inline void RDRAND32(void* output) @@ -159,9 +164,13 @@ void RDRAND::DiscardBytes(size_t n) } } +#endif // CRYPTOPP_RDRAND_AVAILABLE + ///////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////// +#if defined(CRYPTOPP_RDSEED_AVAILABLE) + // Fills 4 bytes inline void RDSEED32(void* output) {