/* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ /* based on Wei Dai's misc.cpp from CryptoPP */ #include "runtime.hpp" #include "misc.hpp" #ifdef __GNUC__ #include #include #endif #ifdef USE_SYS_STL #include #else #include "algorithm.hpp" #endif namespace STL = STL_NAMESPACE; #ifdef YASSL_PURE_C void* operator new(size_t sz, TaoCrypt::new_t) { void* ptr = malloc(sz ? sz : 1); if (!ptr) abort(); return ptr; } void operator delete(void* ptr, TaoCrypt::new_t) { if (ptr) free(ptr); } void* operator new[](size_t sz, TaoCrypt::new_t nt) { return ::operator new(sz, nt); } void operator delete[](void* ptr, TaoCrypt::new_t nt) { ::operator delete(ptr, nt); } /* uncomment to test // make sure not using globals anywhere by forgetting to use overloaded void* operator new(size_t sz); void operator delete(void* ptr); void* operator new[](size_t sz); void operator delete[](void* ptr); */ namespace TaoCrypt { new_t tc; // for library new } #ifdef __sun // Handler for pure virtual functions namespace __Crun { void pure_error() { } } #endif #if defined(__ICC) || defined(__INTEL_COMPILER) || (__GNUC__ > 2) extern "C" { int __cxa_pure_virtual() { return 0; } } // extern "C" #endif #endif // YASSL_PURE_C namespace TaoCrypt { inline void XorWords(word* r, const word* a, unsigned int n) { for (unsigned int i=0; i> (i-1)*8) break; return i; } unsigned int BitPrecision(word value) { if (!value) return 0; unsigned int l = 0, h = 8 * sizeof(value); while (h-l > 1) { unsigned int t = (l+h)/2; if (value >> t) l = t; else h = t; } return h; } word Crop(word value, unsigned int size) { if (size < 8*sizeof(value)) return (value & ((1L << size) - 1)); else return value; } #ifdef TAOCRYPT_X86ASM_AVAILABLE bool HaveCpuId() { #ifdef _MSC_VER __try { __asm { mov eax, 0 cpuid } } __except (1) { return false; } return true; #else word32 eax, ebx; __asm__ __volatile ( /* Put EFLAGS in eax and ebx */ "pushf;" "pushf;" "pop %0;" "movl %0,%1;" /* Flip the cpuid bit and store back in EFLAGS */ "xorl $0x200000,%0;" "push %0;" "popf;" /* Read EFLAGS again */ "pushf;" "pop %0;" "popf" : "=r" (eax), "=r" (ebx) : : "cc" ); if (eax == ebx) return false; return true; #endif } void CpuId(word32 input, word32 *output) { #ifdef __GNUC__ __asm__ ( // save ebx in case -fPIC is being used "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx" : "=a" (output[0]), "=D" (output[1]), "=c" (output[2]), "=d"(output[3]) : "a" (input) ); #else __asm { mov eax, input cpuid mov edi, output mov [edi], eax mov [edi+4], ebx mov [edi+8], ecx mov [edi+12], edx } #endif } bool IsPentium() { if (!HaveCpuId()) return false; word32 cpuid[4]; CpuId(0, cpuid); STL::swap(cpuid[2], cpuid[3]); if (memcmp(cpuid+1, "GenuineIntel", 12) != 0) return false; CpuId(1, cpuid); byte family = ((cpuid[0] >> 8) & 0xf); if (family < 5) return false; return true; } static bool IsMmx() { if (!IsPentium()) return false; word32 cpuid[4]; CpuId(1, cpuid); if ((cpuid[3] & (1 << 23)) == 0) return false; return true; } bool isMMX = IsMmx(); #endif // TAOCRYPT_X86ASM_AVAILABLE } // namespace