From c8c3d7f6eecd753aa87a882b1458346682e606db Mon Sep 17 00:00:00 2001 From: lloyd Date: Tue, 11 Aug 2009 19:34:50 +0000 Subject: Make encrypt_n public for all BlockCipher implementations - unlike the enc/dec functions it replaces, these are public interfaces. Add the first bits of a SSE2 implementation of Serpent. Currently incomplete. --- src/engine/sse2_eng/eng_sse2.cpp | 23 ++++++++++++++++++++--- src/engine/sse2_eng/eng_sse2.h | 5 ++++- 2 files changed, 24 insertions(+), 4 deletions(-) (limited to 'src/engine/sse2_eng') diff --git a/src/engine/sse2_eng/eng_sse2.cpp b/src/engine/sse2_eng/eng_sse2.cpp index c738b3d96..9f68a070e 100644 --- a/src/engine/sse2_eng/eng_sse2.cpp +++ b/src/engine/sse2_eng/eng_sse2.cpp @@ -1,6 +1,6 @@ /** * SSE2 Assembly Engine -* (C) 1999-2008 Jack Lloyd +* (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -11,10 +11,27 @@ #include #endif +#if defined(BOTAN_HAS_SERPENT_SSE2) + #include +#endif + namespace Botan { -HashFunction* SSE2_Assembler_Engine::find_hash(const SCAN_Name& request, - Algorithm_Factory&) const +BlockCipher* +SSE2_Assembler_Engine::find_block_cipher(const SCAN_Name& request, + Algorithm_Factory&) const + { +#if defined(BOTAN_HAS_SERPENT_SSE2) + if(request.algo_name() == "Serpent") + return new Serpent_SSE2; +#endif + + return 0; + } + +HashFunction* +SSE2_Assembler_Engine::find_hash(const SCAN_Name& request, + Algorithm_Factory&) const { #if defined(BOTAN_HAS_SHA1_SSE2) if(request.algo_name() == "SHA-160") diff --git a/src/engine/sse2_eng/eng_sse2.h b/src/engine/sse2_eng/eng_sse2.h index 129697e8f..c6b0ce889 100644 --- a/src/engine/sse2_eng/eng_sse2.h +++ b/src/engine/sse2_eng/eng_sse2.h @@ -1,6 +1,6 @@ /** * SSE2 Assembly Engine -* (C) 1999-2008 Jack Lloyd +* (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -17,6 +17,9 @@ class BOTAN_DLL SSE2_Assembler_Engine : public Engine public: std::string provider_name() const { return "sse2"; } private: + BlockCipher* find_block_cipher(const SCAN_Name&, + Algorithm_Factory&) const; + HashFunction* find_hash(const SCAN_Name& reqeust, Algorithm_Factory&) const; }; -- cgit v1.2.3 From 6897292463197ed6880d91e76c4ee13f624905c3 Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 27 Aug 2009 18:14:55 +0000 Subject: Instead of each SSE2 implementation specifying which compilers + CPUs it works on, have sse2_eng rely on a specific compiler/arch; each sse2 impl depends on the engine anyway, so they will only be loaded if OK. --- src/block/serpent_sse2/info.txt | 12 ------------ src/engine/sse2_eng/info.txt | 9 ++++++++- src/hash/sha1_sse2/info.txt | 12 ------------ 3 files changed, 8 insertions(+), 25 deletions(-) (limited to 'src/engine/sse2_eng') diff --git a/src/block/serpent_sse2/info.txt b/src/block/serpent_sse2/info.txt index 09733e98f..b00ab6e88 100644 --- a/src/block/serpent_sse2/info.txt +++ b/src/block/serpent_sse2/info.txt @@ -10,18 +10,6 @@ serp_sse2.h serp_sse2_sbox.h - -pentium-m -pentium4 -prescott -amd64 - - - -gcc -icc - - serpent sse2_eng diff --git a/src/engine/sse2_eng/info.txt b/src/engine/sse2_eng/info.txt index 6242c7fee..7595b8eb5 100644 --- a/src/engine/sse2_eng/info.txt +++ b/src/engine/sse2_eng/info.txt @@ -10,6 +10,13 @@ eng_sse2.h -ia32 +pentium-m +pentium4 +prescott amd64 + + +gcc +icc + diff --git a/src/hash/sha1_sse2/info.txt b/src/hash/sha1_sse2/info.txt index b8d693b70..995c2513e 100644 --- a/src/hash/sha1_sse2/info.txt +++ b/src/hash/sha1_sse2/info.txt @@ -10,18 +10,6 @@ sha1_sse2.cpp sha1_sse2.h - -pentium-m -pentium4 -prescott -amd64 - - - -gcc -icc - - sha1 sse2_eng -- cgit v1.2.3 From 02fc388212efa21a3f489a28e7b3738956a1358c Mon Sep 17 00:00:00 2001 From: lloyd Date: Sun, 13 Sep 2009 18:00:05 +0000 Subject: Enable SSE2 engine under VC++ --- src/engine/sse2_eng/info.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'src/engine/sse2_eng') diff --git a/src/engine/sse2_eng/info.txt b/src/engine/sse2_eng/info.txt index 7595b8eb5..7508b9874 100644 --- a/src/engine/sse2_eng/info.txt +++ b/src/engine/sse2_eng/info.txt @@ -19,4 +19,5 @@ amd64 gcc icc +msvc -- cgit v1.2.3 From 03f41b6ceb6e9dcfbe4b134239431de43afd7e6b Mon Sep 17 00:00:00 2001 From: lloyd Date: Fri, 25 Sep 2009 11:51:55 +0000 Subject: Add runtime cpuid support. Check in the SSE2 engine that SSE2 is actually existing on the current CPU before returning an object. --- doc/log.txt | 1 + src/engine/sse2_eng/eng_sse2.cpp | 7 +++ src/utils/cpuid.cpp | 108 +++++++++++++++++++++++++++++++++++++++ src/utils/cpuid.h | 51 ++++++++++++++++++ src/utils/info.txt | 2 + 5 files changed, 169 insertions(+) create mode 100644 src/utils/cpuid.cpp create mode 100644 src/utils/cpuid.h (limited to 'src/engine/sse2_eng') diff --git a/doc/log.txt b/doc/log.txt index df48d532c..5bb2d3ee1 100644 --- a/doc/log.txt +++ b/doc/log.txt @@ -1,6 +1,7 @@ * 1.9.1-pre, 2009-??-?? - Enable SSE2 optimizations under Visual C++ + - Add runtime checking for SSE2 availability - Add an implementation of Blue Midnight Wish (BMW-512) - Alter Skein-512 to match the tweaked 1.2 specification diff --git a/src/engine/sse2_eng/eng_sse2.cpp b/src/engine/sse2_eng/eng_sse2.cpp index 9f68a070e..07c625c7c 100644 --- a/src/engine/sse2_eng/eng_sse2.cpp +++ b/src/engine/sse2_eng/eng_sse2.cpp @@ -6,6 +6,7 @@ */ #include +#include #if defined(BOTAN_HAS_SHA1_SSE2) #include @@ -21,6 +22,9 @@ BlockCipher* SSE2_Assembler_Engine::find_block_cipher(const SCAN_Name& request, Algorithm_Factory&) const { + if(!CPUID::has_sse2()) + return 0; + #if defined(BOTAN_HAS_SERPENT_SSE2) if(request.algo_name() == "Serpent") return new Serpent_SSE2; @@ -33,6 +37,9 @@ HashFunction* SSE2_Assembler_Engine::find_hash(const SCAN_Name& request, Algorithm_Factory&) const { + if(!CPUID::has_sse2()) + return 0; + #if defined(BOTAN_HAS_SHA1_SSE2) if(request.algo_name() == "SHA-160") return new SHA_160_SSE2; diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp new file mode 100644 index 000000000..4f22ef867 --- /dev/null +++ b/src/utils/cpuid.cpp @@ -0,0 +1,108 @@ +/** +* Runtime CPU detection +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include +#include + +#if defined(_MSC_VER) + #include +#endif + +namespace Botan { + +namespace CPUID { + +namespace { + +/* +* Call the x86 CPUID instruction and return the contents of ecx and +* edx, which contain the feature masks. +*/ +u64bit x86_processor_flags() + { + static u64bit proc_flags = 0; + + if(proc_flags) + return proc_flags; + +#if defined(BOTAN_TARGET_ARCH_IS_X86) || defined(BOTAN_TARGET_ARCH_IS_AMD64) + +#if defined(__GNUG__) + + u32bit a = 1, b = 0, c = 0, d = 0; + +#if defined(__i386__) && defined(__PIC__) + // ebx is used in PIC on 32-bit x86, so save and restore it + asm("xchgl %%ebx, %1\n\t" + "cpuid\n\t" + "xchgl %%ebx, %1\n\t" + : "=a" (a), "=r" (b), "=c" (c), "=d" (d) : "0" (a)); +#else + // if not PIC or in 64-bit mode, can smash ebx + asm("cpuid" : "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "0" (a)); + +#endif + + proc_flags = ((u64bit)c << 32) | d; + +#elif defined(_MSC_VER) + + int cpuinfo[4] = { 0 }; + __cpuid(cpuinfo, 1); + + proc_flags = ((u64bit)cpuinfo[2] << 32) | cpuinfo[3]; + +#endif + +#endif + + return proc_flags; + } + +enum CPUID_bits { + CPUID_RDTSC_BIT = 4, + CPUID_SSE2_BIT = 26, + CPUID_SSSE3_BIT = 41, + CPUID_SSE41_BIT = 51, + CPUID_SSE42_BIT = 52 +}; + +} + +u32bit cache_line_size() + { + return 32; // FIXME! + } + +bool has_rdtsc() + { + return ((x86_processor_flags() >> CPUID_RDTSC_BIT) & 1); + } + +bool has_sse2() + { + return ((x86_processor_flags() >> CPUID_SSE2_BIT) & 1); + } + +bool has_ssse3() + { + return ((x86_processor_flags() >> CPUID_SSSE3_BIT) & 1); + } + +bool has_sse41() + { + return ((x86_processor_flags() >> CPUID_SSE41_BIT) & 1); + } + +bool has_sse42() + { + return ((x86_processor_flags() >> CPUID_SSE42_BIT) & 1); + } + +} + +} diff --git a/src/utils/cpuid.h b/src/utils/cpuid.h new file mode 100644 index 000000000..557590db8 --- /dev/null +++ b/src/utils/cpuid.h @@ -0,0 +1,51 @@ +/** +* Runtime CPU detection +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_CPUID_H__ +#define BOTAN_CPUID_H__ + +#include + +namespace Botan { + +namespace CPUID { + +/** +* Return a best guess of the cache line size +*/ +u32bit cache_line_size(); + +/** +* Check if the processor supports RDTSC +*/ +bool has_rdtsc(); + +/** +* Check if the processor supports SSE2 +*/ +bool has_sse2(); + +/** +* Check if the processor supports SSSE3 +*/ +bool has_ssse3(); + +/** +* Check if the processor supports SSE4.1 +*/ +bool has_sse41(); + +/** +* Check if the processor supports SSE4.2 +*/ +bool has_sse42(); + +} + +} + +#endif diff --git a/src/utils/info.txt b/src/utils/info.txt index 68981729f..f530fb03a 100644 --- a/src/utils/info.txt +++ b/src/utils/info.txt @@ -13,6 +13,8 @@ bit_ops.h bswap.h charset.cpp charset.h +cpuid.cpp +cpuid.h exceptn.cpp exceptn.h loadstor.h -- cgit v1.2.3