aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils
diff options
context:
space:
mode:
authorlloyd <[email protected]>2009-10-28 22:55:12 +0000
committerlloyd <[email protected]>2009-10-28 22:55:12 +0000
commit3623be3fd05d890309cc3da4b3a1e319e357df65 (patch)
tree34ca43fcf8a7007cc01a3919f63e9ab6763cb673 /src/utils
parentfc1e61500e77fcabe67e6d2607810c1ba071bbdd (diff)
parent9462f875b13a321f42a127166d49670ca04afcde (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.txt4
-rw-r--r--src/utils/asm_ia32/info.txt4
-rw-r--r--src/utils/cpuid.cpp101
-rw-r--r--src/utils/cpuid.h74
-rw-r--r--src/utils/info.txt24
-rw-r--r--src/utils/loadstor.h125
-rw-r--r--src/utils/mlock.cpp2
-rw-r--r--src/utils/mlock.h32
-rw-r--r--src/utils/parsing.cpp3
-rw-r--r--src/utils/prefetch.h43
-rw-r--r--src/utils/rounding.h35
-rw-r--r--src/utils/util.cpp68
-rw-r--r--src/utils/util.h39
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