diff options
author | lloyd <[email protected]> | 2009-10-28 22:55:12 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2009-10-28 22:55:12 +0000 |
commit | 3623be3fd05d890309cc3da4b3a1e319e357df65 (patch) | |
tree | 34ca43fcf8a7007cc01a3919f63e9ab6763cb673 /src/utils | |
parent | fc1e61500e77fcabe67e6d2607810c1ba071bbdd (diff) | |
parent | 9462f875b13a321f42a127166d49670ca04afcde (diff) |
propagate from branch 'net.randombit.botan.1_8' (head 3158f8272a3582dd44dfb771665eb71f7d005339)
to branch 'net.randombit.botan' (head bf629b13dd132b263e76a72b7eca0f7e4ab19aac)
Diffstat (limited to 'src/utils')
-rw-r--r-- | src/utils/asm_amd64/info.txt | 4 | ||||
-rw-r--r-- | src/utils/asm_ia32/info.txt | 4 | ||||
-rw-r--r-- | src/utils/cpuid.cpp | 101 | ||||
-rw-r--r-- | src/utils/cpuid.h | 74 | ||||
-rw-r--r-- | src/utils/info.txt | 24 | ||||
-rw-r--r-- | src/utils/loadstor.h | 125 | ||||
-rw-r--r-- | src/utils/mlock.cpp | 2 | ||||
-rw-r--r-- | src/utils/mlock.h | 32 | ||||
-rw-r--r-- | src/utils/parsing.cpp | 3 | ||||
-rw-r--r-- | src/utils/prefetch.h | 43 | ||||
-rw-r--r-- | src/utils/rounding.h | 35 | ||||
-rw-r--r-- | src/utils/util.cpp | 68 | ||||
-rw-r--r-- | src/utils/util.h | 39 |
13 files changed, 406 insertions, 148 deletions
diff --git a/src/utils/asm_amd64/info.txt b/src/utils/asm_amd64/info.txt index 19035b545..6fa4d1de5 100644 --- a/src/utils/asm_amd64/info.txt +++ b/src/utils/asm_amd64/info.txt @@ -14,3 +14,7 @@ amd64 gcc icc </cc> + +<requires> +amd64_eng +</requires> diff --git a/src/utils/asm_ia32/info.txt b/src/utils/asm_ia32/info.txt index 4340c35aa..8485d33b9 100644 --- a/src/utils/asm_ia32/info.txt +++ b/src/utils/asm_ia32/info.txt @@ -14,3 +14,7 @@ ia32 gcc icc </cc> + +<requires> +ia32_eng +</requires> diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp new file mode 100644 index 000000000..f79e3a912 --- /dev/null +++ b/src/utils/cpuid.cpp @@ -0,0 +1,101 @@ +/** +* Runtime CPU detection +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/cpuid.h> +#include <botan/types.h> +#include <botan/loadstor.h> +#include <botan/mem_ops.h> + +#if defined(BOTAN_TARGET_ARCH_IS_IA32) || defined(BOTAN_TARGET_ARCH_IS_AMD64) + +#if defined(BOTAN_BUILD_COMPILER_IS_MSVC) + + #include <intrin.h> + #define CALL_CPUID(type, out) do { __cpuid((int*)out, type); } while(0) + +#elif defined(BOTAN_BUILD_COMPILER_IS_ICC) + + #include <ia32intrin.h> + #define CALL_CPUID(type, out) do { __cpuid(out, type) } while(0); + +#elif defined(BOTAN_BUILD_COMPILER_IS_GCC) + + #include <cpuid.h> + #define CALL_CPUID(type, out) \ + do { __get_cpuid(type, out, out+1, out+2, out+3); } while(0); + +#endif + +#endif + +#ifndef CALL_CPUID + // In all other cases, just zeroize the supposed cpuid output + #define CALL_CPUID(type, out) \ + do { out[0] = out[1] = out[2] = out[3] = 0; } while(0); +#endif + +namespace Botan { + +namespace { + +u32bit get_x86_cache_line_size() + { + const u32bit INTEL_CPUID[3] = { 0x756E6547, 0x6C65746E, 0x49656E69 }; + const u32bit AMD_CPUID[3] = { 0x68747541, 0x444D4163, 0x69746E65 }; + + u32bit cpuid[4] = { 0 }; + CALL_CPUID(0, cpuid); + + if(same_mem(cpuid + 1, INTEL_CPUID, 3)) + { + CALL_CPUID(1, cpuid); + return 8 * get_byte(2, cpuid[1]); + } + else if(same_mem(cpuid + 1, AMD_CPUID, 3)) + { + CALL_CPUID(0x80000005, cpuid); + return get_byte(3, cpuid[2]); + } + else + return 32; // default cache line guess + } + +} + +/* +* Call the x86 CPUID instruction and return the contents of ecx and +* edx, which contain the feature masks. +*/ +u64bit CPUID::x86_processor_flags() + { + static u64bit proc_flags = 0; + + if(proc_flags) + return proc_flags; + + u32bit cpuid[4] = { 0 }; + CALL_CPUID(1, cpuid); + + // Set the FPU bit on to force caching in proc_flags + proc_flags = ((u64bit)cpuid[2] << 32) | cpuid[3] | 1; + + return proc_flags; + } + +u32bit CPUID::cache_line_size() + { + static u32bit cl_size = 0; + + if(cl_size) + return cl_size; + + cl_size = get_x86_cache_line_size(); + + return cl_size; + } + +} diff --git a/src/utils/cpuid.h b/src/utils/cpuid.h new file mode 100644 index 000000000..0b210768a --- /dev/null +++ b/src/utils/cpuid.h @@ -0,0 +1,74 @@ +/** +* Runtime CPU detection +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_CPUID_H__ +#define BOTAN_CPUID_H__ + +#include <botan/types.h> + +namespace Botan { + +class CPUID + { + public: + enum CPUID_bits { + CPUID_RDTSC_BIT = 4, + CPUID_SSE2_BIT = 26, + CPUID_SSSE3_BIT = 41, + CPUID_SSE41_BIT = 51, + CPUID_SSE42_BIT = 52, + CPUID_INTEL_AES_BIT = 57, + }; + + /** + * Return a best guess of the cache line size + */ + static u32bit cache_line_size(); + + /** + * Check if the processor supports RDTSC + */ + static bool has_rdtsc() + { return ((x86_processor_flags() >> CPUID_RDTSC_BIT) & 1); } + + /** + * Check if the processor supports SSE2 + */ + static bool has_sse2() + { return ((x86_processor_flags() >> CPUID_SSE2_BIT) & 1); } + + /** + * Check if the processor supports SSSE3 + */ + static bool has_ssse3() + { return ((x86_processor_flags() >> CPUID_SSSE3_BIT) & 1); } + + /** + * Check if the processor supports SSE4.1 + */ + static bool has_sse41() + { return ((x86_processor_flags() >> CPUID_SSE41_BIT) & 1); } + + /** + * Check if the processor supports SSE4.2 + */ + static bool has_sse42() + { return ((x86_processor_flags() >> CPUID_SSE42_BIT) & 1); } + + /** + * Check if the processor supports Intel AES instructions + */ + static bool has_intel_aes() + { return ((x86_processor_flags() >> CPUID_INTEL_AES_BIT) & 1); } + + private: + static u64bit x86_processor_flags(); + }; + +} + +#endif diff --git a/src/utils/info.txt b/src/utils/info.txt index ab50b88ad..6380fd6c2 100644 --- a/src/utils/info.txt +++ b/src/utils/info.txt @@ -7,27 +7,3 @@ load_on always <libs> tru64 -> rt </libs> - -<add> -bit_ops.h -bswap.h -charset.cpp -charset.h -exceptn.cpp -exceptn.h -loadstor.h -mem_ops.h -mlock.cpp -parsing.cpp -parsing.h -rotate.h -stl_util.h -types.h -ui.cpp -ui.h -util.cpp -util.h -version.cpp -version.h -xor_buf.h -</add> diff --git a/src/utils/loadstor.h b/src/utils/loadstor.h index 77ed1554e..6f91c2fa5 100644 --- a/src/utils/loadstor.h +++ b/src/utils/loadstor.h @@ -12,6 +12,7 @@ #include <botan/types.h> #include <botan/bswap.h> #include <botan/rotate.h> +#include <botan/prefetch.h> #if BOTAN_TARGET_UNALIGNED_LOADSTOR_OK @@ -165,6 +166,70 @@ inline u64bit load_le<u64bit>(const byte in[], u32bit off) #endif } +template<typename T> +inline void load_le(const byte in[], T& x0, T& x1) + { + x0 = load_le<T>(in, 0); + x1 = load_le<T>(in, 1); + } + +template<typename T> +inline void load_le(const byte in[], + T& x0, T& x1, T& x2, T& x3) + { + x0 = load_le<T>(in, 0); + x1 = load_le<T>(in, 1); + x2 = load_le<T>(in, 2); + x3 = load_le<T>(in, 3); + } + +template<typename T> +inline void load_le(const byte in[], + T& x0, T& x1, T& x2, T& x3, + T& x4, T& x5, T& x6, T& x7) + { + x0 = load_le<T>(in, 0); + x1 = load_le<T>(in, 1); + x2 = load_le<T>(in, 2); + x3 = load_le<T>(in, 3); + x4 = load_le<T>(in, 4); + x5 = load_le<T>(in, 5); + x6 = load_le<T>(in, 6); + x7 = load_le<T>(in, 7); + } + +template<typename T> +inline void load_be(const byte in[], T& x0, T& x1) + { + x0 = load_be<T>(in, 0); + x1 = load_be<T>(in, 1); + } + +template<typename T> +inline void load_be(const byte in[], + T& x0, T& x1, T& x2, T& x3) + { + x0 = load_be<T>(in, 0); + x1 = load_be<T>(in, 1); + x2 = load_be<T>(in, 2); + x3 = load_be<T>(in, 3); + } + +template<typename T> +inline void load_be(const byte in[], + T& x0, T& x1, T& x2, T& x3, + T& x4, T& x5, T& x6, T& x7) + { + x0 = load_be<T>(in, 0); + x1 = load_be<T>(in, 1); + x2 = load_be<T>(in, 2); + x3 = load_be<T>(in, 3); + x4 = load_be<T>(in, 4); + x5 = load_be<T>(in, 5); + x6 = load_be<T>(in, 6); + x7 = load_be<T>(in, 7); + } + /* * Endian-Specific Word Storing Operations */ @@ -245,35 +310,63 @@ inline void store_le(u64bit in, byte out[8]) } template<typename T> -inline void store_le(byte out[], T a, T b) +inline void store_le(byte out[], T x0, T x1) + { + store_le(x0, out + (0 * sizeof(T))); + store_le(x1, out + (1 * sizeof(T))); + } + +template<typename T> +inline void store_be(byte out[], T x0, T x1) + { + store_be(x0, out + (0 * sizeof(T))); + store_be(x1, out + (1 * sizeof(T))); + } + +template<typename T> +inline void store_le(byte out[], T x0, T x1, T x2, T x3) { - store_le(a, out + (0 * sizeof(T))); - store_le(b, out + (1 * sizeof(T))); + store_le(x0, out + (0 * sizeof(T))); + store_le(x1, out + (1 * sizeof(T))); + store_le(x2, out + (2 * sizeof(T))); + store_le(x3, out + (3 * sizeof(T))); } template<typename T> -inline void store_be(byte out[], T a, T b) +inline void store_be(byte out[], T x0, T x1, T x2, T x3) { - store_be(a, out + (0 * sizeof(T))); - store_be(b, out + (1 * sizeof(T))); + store_be(x0, out + (0 * sizeof(T))); + store_be(x1, out + (1 * sizeof(T))); + store_be(x2, out + (2 * sizeof(T))); + store_be(x3, out + (3 * sizeof(T))); } template<typename T> -inline void store_le(byte out[], T a, T b, T c, T d) +inline void store_le(byte out[], T x0, T x1, T x2, T x3, + T x4, T x5, T x6, T x7) { - store_le(a, out + (0 * sizeof(T))); - store_le(b, out + (1 * sizeof(T))); - store_le(c, out + (2 * sizeof(T))); - store_le(d, out + (3 * sizeof(T))); + store_le(x0, out + (0 * sizeof(T))); + store_le(x1, out + (1 * sizeof(T))); + store_le(x2, out + (2 * sizeof(T))); + store_le(x3, out + (3 * sizeof(T))); + store_le(x4, out + (4 * sizeof(T))); + store_le(x5, out + (5 * sizeof(T))); + store_le(x6, out + (6 * sizeof(T))); + store_le(x7, out + (7 * sizeof(T))); } template<typename T> -inline void store_be(byte out[], T a, T b, T c, T d) +inline void store_be(byte out[], T x0, T x1, T x2, T x3, + T x4, T x5, T x6, T x7) { - store_be(a, out + (0 * sizeof(T))); - store_be(b, out + (1 * sizeof(T))); - store_be(c, out + (2 * sizeof(T))); - store_be(d, out + (3 * sizeof(T))); + store_be(x0, out + (0 * sizeof(T))); + store_be(x1, out + (1 * sizeof(T))); + store_be(x2, out + (2 * sizeof(T))); + store_be(x3, out + (3 * sizeof(T))); + store_be(x4, out + (4 * sizeof(T))); + store_be(x5, out + (5 * sizeof(T))); + store_be(x6, out + (6 * sizeof(T))); + store_be(x7, out + (7 * sizeof(T))); } } diff --git a/src/utils/mlock.cpp b/src/utils/mlock.cpp index 9bb062da5..6453d8a30 100644 --- a/src/utils/mlock.cpp +++ b/src/utils/mlock.cpp @@ -5,7 +5,7 @@ * Distributed under the terms of the Botan license */ -#include <botan/util.h> +#include <botan/mlock.h> #if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) #include <sys/types.h> diff --git a/src/utils/mlock.h b/src/utils/mlock.h new file mode 100644 index 000000000..0811e8190 --- /dev/null +++ b/src/utils/mlock.h @@ -0,0 +1,32 @@ +/* +* Memory Locking Functions +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_MLOCK_H__ +#define BOTAN_MLOCK_H__ + +#include <botan/types.h> + +namespace Botan { + +/** +* Lock memory into RAM if possible +* @param addr the start of the memory block +* @param length the length of the memory block in bytes +* @returns true if successful, false otherwise +*/ +BOTAN_DLL bool lock_mem(void* addr, u32bit length); + +/** +* Unlock memory locked with lock_mem() +* @param addr the start of the memory block +* @param length the length of the memory block in bytes +*/ +BOTAN_DLL void unlock_mem(void* addr, u32bit length); + +} + +#endif diff --git a/src/utils/parsing.cpp b/src/utils/parsing.cpp index bdb9e79dc..58a8e0b38 100644 --- a/src/utils/parsing.cpp +++ b/src/utils/parsing.cpp @@ -23,6 +23,9 @@ u32bit to_u32bit(const std::string& number) { const u32bit OVERFLOW_MARK = 0xFFFFFFFF / 10; + if(*j == ' ') + continue; + byte digit = Charset::char2digit(*j); if((n > OVERFLOW_MARK) || (n == OVERFLOW_MARK && digit > 5)) diff --git a/src/utils/prefetch.h b/src/utils/prefetch.h new file mode 100644 index 000000000..7afdbda0a --- /dev/null +++ b/src/utils/prefetch.h @@ -0,0 +1,43 @@ +/* +* Prefetching Operations +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_PREFETCH_H__ +#define BOTAN_PREFETCH_H__ + +#include <botan/cpuid.h> + +namespace Botan { + +namespace PREFETCH { + +template<typename T> +inline void readonly(const T* addr, u32bit length) + { +#if defined(__GNUG__) + const u32bit Ts_per_cache_line = CPUID::cache_line_size() / sizeof(T); + + for(u32bit i = 0; i <= length; i += Ts_per_cache_line) + __builtin_prefetch(addr + i, 0); +#endif + } + +template<typename T> +inline void readwrite(const T* addr, u32bit length) + { +#if defined(__GNUG__) + const u32bit Ts_per_cache_line = CPUID::cache_line_size() / sizeof(T); + + for(u32bit i = 0; i <= length; i += Ts_per_cache_line) + __builtin_prefetch(addr + i, 0); +#endif + } + +} + +} + +#endif diff --git a/src/utils/rounding.h b/src/utils/rounding.h new file mode 100644 index 000000000..11ab90b8d --- /dev/null +++ b/src/utils/rounding.h @@ -0,0 +1,35 @@ +/* +* Integer Rounding Functions +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_ROUNDING_H__ +#define BOTAN_ROUNDING_H__ + +#include <botan/types.h> + +namespace Botan { + +/* +* Round up n to multiple of align_to +*/ +inline u32bit round_up(u32bit n, u32bit align_to) + { + if(n % align_to || n == 0) + n += align_to - (n % align_to); + return n; + } + +/* +* Round down n to multiple of align_to +*/ +inline u32bit round_down(u32bit n, u32bit align_to) + { + return (n - (n % align_to)); + } + +} + +#endif diff --git a/src/utils/util.cpp b/src/utils/util.cpp deleted file mode 100644 index 84dfd1a14..000000000 --- a/src/utils/util.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* -* Utility Functions -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/util.h> -#include <algorithm> -#include <cmath> - -namespace Botan { - -/* -* Round up n to multiple of align_to -*/ -u32bit round_up(u32bit n, u32bit align_to) - { - if(n % align_to || n == 0) - n += align_to - (n % align_to); - return n; - } - -/* -* Round down n to multiple of align_to -*/ -u32bit round_down(u32bit n, u32bit align_to) - { - return (n - (n % align_to)); - } - -/* -* Choose the exponent size for a DL group -*/ -u32bit dl_work_factor(u32bit bits) - { -#if 0 - /* - These values were taken from RFC 3526 - */ - if(bits <= 1536) - return 90; - else if(bits <= 2048) - return 110; - else if(bits <= 3072) - return 130; - else if(bits <= 4096) - return 150; - else if(bits <= 6144) - return 170; - else if(bits <= 8192) - return 190; - return 256; -#else - const u32bit MIN_ESTIMATE = 64; - - const double log_x = bits / 1.44; - - const double strength = - 2.76 * std::pow(log_x, 1.0/3.0) * std::pow(std::log(log_x), 2.0/3.0); - - if(strength > MIN_ESTIMATE) - return static_cast<u32bit>(strength); - return MIN_ESTIMATE; -#endif - } - -} diff --git a/src/utils/util.h b/src/utils/util.h deleted file mode 100644 index ac7867390..000000000 --- a/src/utils/util.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -* Utility Functions -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_UTIL_H__ -#define BOTAN_UTIL_H__ - -#include <botan/types.h> - -namespace Botan { - -/* -* Time Access Functions -*/ -BOTAN_DLL u64bit system_time(); - -/* -* Memory Locking Functions -*/ -BOTAN_DLL bool lock_mem(void*, u32bit); -BOTAN_DLL void unlock_mem(void*, u32bit); - -/* -* Misc Utility Functions -*/ -BOTAN_DLL u32bit round_up(u32bit, u32bit); -BOTAN_DLL u32bit round_down(u32bit, u32bit); - -/* -* Work Factor Estimates -*/ -BOTAN_DLL u32bit dl_work_factor(u32bit); - -} - -#endif |