From 87df2fd2fc5845a39c715217029646d385ee3e01 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sun, 21 Feb 2016 00:52:22 +0100 Subject: Crypto: update Whirlpool implementation using latest code from Crypto++. --- src/Crypto/cpu.c | 83 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 58 insertions(+), 25 deletions(-) mode change 100644 => 100755 src/Crypto/cpu.c (limited to 'src/Crypto/cpu.c') diff --git a/src/Crypto/cpu.c b/src/Crypto/cpu.c old mode 100644 new mode 100755 index 6896240c..766edea8 --- a/src/Crypto/cpu.c +++ b/src/Crypto/cpu.c @@ -3,6 +3,10 @@ #include "cpu.h" #include "misc.h" +#ifndef EXCEPTION_EXECUTE_HANDLER +#define EXCEPTION_EXECUTE_HANDLER 1 +#endif + #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY #include #include @@ -16,7 +20,7 @@ #if _MSC_VER >= 1400 && CRYPTOPP_BOOL_X64 -int CpuId(uint32 input, uint32 *output) +int CpuId(uint32 input, uint32 output[4]) { __cpuid((int *)output, input); return 1; @@ -45,12 +49,13 @@ static void SigIllHandlerSSE2(int p) longjmp(s_jmpNoSSE2, 1); } #endif + #if defined(__cplusplus) } #endif #endif -int CpuId(uint32 input, uint32 *output) +int CpuId(uint32 input, uint32 output[4]) { #ifdef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY __try @@ -58,6 +63,7 @@ int CpuId(uint32 input, uint32 *output) __asm { mov eax, input + mov ecx, 0 cpuid mov edi, output mov [edi], eax @@ -66,32 +72,42 @@ int CpuId(uint32 input, uint32 *output) mov [edi+12], edx } } - __except (1) + __except (EXCEPTION_EXECUTE_HANDLER) { return 0; } + + // function 0 returns the highest basic function understood in EAX + if(input == 0) + return !!output[0]? 1 : 0; + return 1; #else + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 + // http://stackoverflow.com/q/7721854 + volatile int result = 1; + SigHandler oldHandler = signal(SIGILL, SigIllHandlerCPUID); if (oldHandler == SIG_ERR) - return 0; + result = 0; - int result = 1; if (setjmp(s_jmpNoCPUID)) result = 0; else { - asm + asm volatile ( - // save ebx in case -fPIC is being used -#if CRYPTOPP_BOOL_X86 - "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx" + // save ebx in case -fPIC is being used + // TODO: this might need an early clobber on EDI. +#if CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 + "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx" #else - "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx" + "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx" #endif - : "=a" (output[0]), "=D" (output[1]), "=c" (output[2]), "=d" (output[3]) - : "a" (input) - ); + : "=a" (output[0]), "=D" (output[1]), "=c" (output[2]), "=d" (output[3]) + : "a" (input), "c" (0) + ); } signal(SIGILL, oldHandler); @@ -112,29 +128,33 @@ static int TrySSE2() AS2(por xmm0, xmm0) // executing SSE2 instruction #elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE __m128i x = _mm_setzero_si128(); - return _mm_cvtsi128_si32(x) == 0; + return _mm_cvtsi128_si32(x) == 0 ? 1 : 0; #endif } - __except (1) + __except (EXCEPTION_EXECUTE_HANDLER) { return 0; } return 1; #else + // longjmp and clobber warnings. Volatile is required. + // http://github.com/weidai11/cryptopp/issues/24 + // http://stackoverflow.com/q/7721854 + volatile int result = 1; + SigHandler oldHandler = signal(SIGILL, SigIllHandlerSSE2); if (oldHandler == SIG_ERR) return 0; - int result = 1; if (setjmp(s_jmpNoSSE2)) - result = 0; + result = 1; else { #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE __asm __volatile ("por %xmm0, %xmm0"); #elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE __m128i x = _mm_setzero_si128(); - result = _mm_cvtsi128_si32(x) == 0; + result = _mm_cvtsi128_si32(x) == 0? 1 : 0; #endif } @@ -147,9 +167,25 @@ int g_x86DetectionDone = 0; int g_hasISSE = 0, g_hasSSE2 = 0, g_hasSSSE3 = 0, g_hasMMX = 0, g_hasAESNI = 0, g_hasCLMUL = 0, g_isP4 = 0; uint32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; +static inline int IsIntel(const uint32 output[4]) +{ + // This is the "GenuineIntel" string + return (output[1] /*EBX*/ == 0x756e6547) && + (output[2] /*ECX*/ == 0x6c65746e) && + (output[3] /*EDX*/ == 0x49656e69); +} + +static inline int IsAMD(const uint32 output[4]) +{ + // This is the "AuthenticAMD" string + return (output[1] /*EBX*/ == 0x68747541) && + (output[2] /*ECX*/ == 0x69746E65) && + (output[3] /*EDX*/ == 0x444D4163); +} + void DetectX86Features() { - uint32 cpuid[4], cpuid1[4], tmp; + uint32 cpuid[4], cpuid1[4]; if (!CpuId(0, cpuid)) return; if (!CpuId(1, cpuid1)) @@ -175,15 +211,12 @@ void DetectX86Features() } } - tmp = cpuid[2]; - cpuid[2] = cpuid[3]; - cpuid[3] = tmp; - if (memcmp(cpuid+1, "GenuineIntel", 12) == 0) + if (IsIntel(cpuid)) { g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf; g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1); } - else if (memcmp(cpuid+1, "AuthenticAMD", 12) == 0) + else if (IsAMD(cpuid)) { CpuId(0x80000005, cpuid); g_cacheLineSize = GETBYTE(cpuid[2], 0); @@ -192,7 +225,7 @@ void DetectX86Features() if (!g_cacheLineSize) g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; - g_x86DetectionDone = 1; + *((volatile int*)&g_x86DetectionDone) = 1; } #endif -- cgit v1.2.3