diff options
author | lloyd <[email protected]> | 2009-12-01 12:00:48 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2009-12-01 12:00:48 +0000 |
commit | 874dbb8323dd4d7eff3ff16cff0cfafc16ddbfa7 (patch) | |
tree | bc3a84c43c5924119972f24da3af89317694f0cb | |
parent | 78f5726220b637cd8ae117bbcf8ff8d6c8dfeaed (diff) |
Consolidate the non-canonical epoch timers, like cpuid and Win32's
QueryPerformanceCounter, into an entropy source hres_timer. Its
results, if any, do not count as contributing entropy to the poll.
Convert the other (monotonic/fixed epoch) timers to a single function
get_nanoseconds_clock(), living in time.h, which statically chooses
the 'best' timer type (clock_gettime, gettimeofday, std::clock, in
that order depending on what is available). Add feature test macros
for clock_gettime and gettimeofday.
Remove the Timer class and timer.h. Remove the Timer& argument to the
algorithm benchmark function.
54 files changed, 228 insertions, 474 deletions
diff --git a/checks/bench.cpp b/checks/bench.cpp index f821e04e3..631bf8476 100644 --- a/checks/bench.cpp +++ b/checks/bench.cpp @@ -9,6 +9,7 @@ #include <botan/engine.h> #include <botan/parsing.h> #include <botan/symkey.h> +#include <botan/time.h> #include "common.h" #include "bench.h" @@ -152,13 +153,12 @@ bool bench_algo(const std::string& algo, Botan::RandomNumberGenerator& rng, double seconds) { - Botan::Default_Benchmark_Timer timer; Botan::Algorithm_Factory& af = Botan::global_state().algorithm_factory(); u32bit milliseconds = static_cast<u32bit>(seconds * 1000); std::map<std::string, double> speeds = - algorithm_benchmark(algo, milliseconds, timer, rng, af); + algorithm_benchmark(algo, milliseconds, rng, af); if(speeds.empty()) // maybe a cipher mode, then? { @@ -198,7 +198,7 @@ bool bench_algo(const std::string& algo, Botan::Pipe pipe(filt, new Botan::BitBucket); pipe.start_msg(); - const u64bit start = timer.clock(); + const u64bit start = Botan::get_nanoseconds_clock(); u64bit nanoseconds_used = 0; u64bit reps = 0; @@ -206,7 +206,7 @@ bool bench_algo(const std::string& algo, { pipe.write(&buf[0], buf.size()); ++reps; - nanoseconds_used = timer.clock() - start; + nanoseconds_used = Botan::get_nanoseconds_clock() - start; } double mbytes_per_second = diff --git a/checks/cvc_tests.cpp b/checks/cvc_tests.cpp index d62099b6e..8ca00e048 100644 --- a/checks/cvc_tests.cpp +++ b/checks/cvc_tests.cpp @@ -27,8 +27,8 @@ #include <botan/look_pk.h> #include <botan/cvc_self.h> #include <botan/cvc_cert.h> -#include <botan/timer.h> #include <botan/cvc_ado.h> +#include <botan/time.h> #define TEST_DATA_DIR "checks/ecc_testdata" diff --git a/checks/timer.cpp b/checks/timer.cpp index 8460257d4..1bdaebb7f 100644 --- a/checks/timer.cpp +++ b/checks/timer.cpp @@ -1,5 +1,5 @@ #include "timer.h" -#include <botan/benchmark.h> +#include <botan/time.h> #include <iomanip> Timer::Timer(const std::string& n, u32bit e_mul) : @@ -32,8 +32,7 @@ void Timer::stop() u64bit Timer::get_clock() { - Botan::Default_Benchmark_Timer timer; - return timer.clock(); + return Botan::get_nanoseconds_clock(); } std::ostream& operator<<(std::ostream& out, Timer& timer) diff --git a/doc/examples/bench.cpp b/doc/examples/bench.cpp index cc43fade0..6a15df7c0 100644 --- a/doc/examples/bench.cpp +++ b/doc/examples/bench.cpp @@ -64,11 +64,10 @@ void benchmark_algo(const std::string& algo, RandomNumberGenerator& rng) { u32bit milliseconds = 3000; - Default_Benchmark_Timer timer; Algorithm_Factory& af = global_state().algorithm_factory(); std::map<std::string, double> speeds = - algorithm_benchmark(algo, milliseconds, timer, rng, af); + algorithm_benchmark(algo, milliseconds, rng, af); std::cout << algo << ":"; diff --git a/doc/examples/benchmark.cpp b/doc/examples/benchmark.cpp index d046e8d20..fa91726e5 100644 --- a/doc/examples/benchmark.cpp +++ b/doc/examples/benchmark.cpp @@ -17,7 +17,6 @@ int main(int argc, char* argv[]) Botan::LibraryInitializer init; Botan::AutoSeeded_RNG rng; - Botan::Default_Benchmark_Timer timer; Botan::Algorithm_Factory& af = Botan::global_state().algorithm_factory(); @@ -28,7 +27,7 @@ int main(int argc, char* argv[]) std::string algo = argv[i]; std::map<std::string, double> results = - Botan::algorithm_benchmark(algo, ms, timer, rng, af); + Botan::algorithm_benchmark(algo, ms, rng, af); std::cout << algo << ":\n"; for(std::map<std::string, double>::iterator r = results.begin(); diff --git a/doc/examples/ca.cpp b/doc/examples/ca.cpp index 9195be418..b98e6620e 100644 --- a/doc/examples/ca.cpp +++ b/doc/examples/ca.cpp @@ -15,7 +15,7 @@ #include <botan/botan.h> #include <botan/x509_ca.h> -#include <botan/util.h> +#include <botan/timer.h> using namespace Botan; #include <iostream> diff --git a/doc/examples/gen_certs.cpp b/doc/examples/gen_certs.cpp index 90cb80038..1c95402f4 100644 --- a/doc/examples/gen_certs.cpp +++ b/doc/examples/gen_certs.cpp @@ -5,7 +5,7 @@ #include <botan/botan.h> #include <botan/rsa.h> -#include <botan/util.h> +#include <botan/timer.h> #include <botan/x509self.h> #include <botan/x509_ca.h> diff --git a/doc/examples/hash_quickly.cpp b/doc/examples/hash_quickly.cpp index e719a7178..c8c8ca5fb 100644 --- a/doc/examples/hash_quickly.cpp +++ b/doc/examples/hash_quickly.cpp @@ -23,12 +23,10 @@ void set_fastest_implementation(const std::string& algo, Botan::RandomNumberGenerator& rng, double ms = 30) { - Botan::Default_Benchmark_Timer timer; - Botan::Algorithm_Factory& af = Botan::global_state().algorithm_factory(); std::map<std::string, double> results = - Botan::algorithm_benchmark(algo, ms, timer, rng, af); + Botan::algorithm_benchmark(algo, ms, rng, af); std::string fastest_provider = ""; double best_res = 0; diff --git a/src/asn1/asn1_tm.cpp b/src/asn1/asn1_tm.cpp index 09bc4d347..c57d1bc73 100644 --- a/src/asn1/asn1_tm.cpp +++ b/src/asn1/asn1_tm.cpp @@ -10,7 +10,7 @@ #include <botan/ber_dec.h> #include <botan/charset.h> #include <botan/parsing.h> -#include <botan/timer.h> +#include <botan/time.h> namespace Botan { diff --git a/src/asn1/info.txt b/src/asn1/info.txt index 621b8b628..d836b4c0b 100644 --- a/src/asn1/info.txt +++ b/src/asn1/info.txt @@ -26,5 +26,4 @@ alloc bigint filters oid_lookup -timer </requires> diff --git a/src/benchmark/benchmark.cpp b/src/benchmark/benchmark.cpp index 41c9cd10c..69d3a40ec 100644 --- a/src/benchmark/benchmark.cpp +++ b/src/benchmark/benchmark.cpp @@ -11,6 +11,7 @@ #include <botan/stream_cipher.h> #include <botan/hash.h> #include <botan/mac.h> +#include <botan/time.h> #include <memory> namespace Botan { @@ -21,19 +22,19 @@ namespace { * Benchmark BufferedComputation (hash or MAC) */ std::pair<u64bit, u64bit> bench_buf_comp(BufferedComputation* buf_comp, - Timer& timer, u64bit nanoseconds_max, const byte buf[], u32bit buf_len) { - const u64bit start = timer.clock(); - u64bit nanoseconds_used = 0; u64bit reps = 0; + const u64bit start = get_nanoseconds_clock(); + u64bit nanoseconds_used = 0; + while(nanoseconds_used < nanoseconds_max) { buf_comp->update(buf, buf_len); ++reps; - nanoseconds_used = timer.clock() - start; + nanoseconds_used = get_nanoseconds_clock() - start; } return std::make_pair(reps * buf_len, nanoseconds_used); @@ -44,15 +45,15 @@ std::pair<u64bit, u64bit> bench_buf_comp(BufferedComputation* buf_comp, */ std::pair<u64bit, u64bit> bench_block_cipher(BlockCipher* block_cipher, - Timer& timer, u64bit nanoseconds_max, byte buf[], u32bit buf_len) { - const u64bit start = timer.clock(); - u64bit nanoseconds_used = 0; + const u32bit in_blocks = buf_len / block_cipher->BLOCK_SIZE; + u64bit reps = 0; - const u32bit in_blocks = buf_len / block_cipher->BLOCK_SIZE; + const u64bit start = get_nanoseconds_clock(); + u64bit nanoseconds_used = 0; block_cipher->set_key(buf, block_cipher->MAXIMUM_KEYLENGTH); @@ -61,7 +62,7 @@ bench_block_cipher(BlockCipher* block_cipher, block_cipher->encrypt_n(buf, buf, in_blocks); ++reps; - nanoseconds_used = timer.clock() - start; + nanoseconds_used = get_nanoseconds_clock() - start; } return std::make_pair(reps * in_blocks * block_cipher->BLOCK_SIZE, @@ -73,21 +74,21 @@ bench_block_cipher(BlockCipher* block_cipher, */ std::pair<u64bit, u64bit> bench_stream_cipher(StreamCipher* stream_cipher, - Timer& timer, u64bit nanoseconds_max, byte buf[], u32bit buf_len) { - const u64bit start = timer.clock(); - u64bit nanoseconds_used = 0; u64bit reps = 0; + const u64bit start = get_nanoseconds_clock(); + u64bit nanoseconds_used = 0; + stream_cipher->set_key(buf, stream_cipher->MAXIMUM_KEYLENGTH); while(nanoseconds_used < nanoseconds_max) { stream_cipher->cipher1(buf, buf_len); ++reps; - nanoseconds_used = timer.clock() - start; + nanoseconds_used = get_nanoseconds_clock() - start; } return std::make_pair(reps * buf_len, nanoseconds_used); @@ -97,11 +98,11 @@ bench_stream_cipher(StreamCipher* stream_cipher, * Benchmark hash */ std::pair<u64bit, u64bit> -bench_hash(HashFunction* hash, Timer& timer, +bench_hash(HashFunction* hash, u64bit nanoseconds_max, const byte buf[], u32bit buf_len) { - return bench_buf_comp(hash, timer, nanoseconds_max, buf, buf_len); + return bench_buf_comp(hash, nanoseconds_max, buf, buf_len); } /** @@ -109,12 +110,11 @@ bench_hash(HashFunction* hash, Timer& timer, */ std::pair<u64bit, u64bit> bench_mac(MessageAuthenticationCode* mac, - Timer& timer, u64bit nanoseconds_max, const byte buf[], u32bit buf_len) { mac->set_key(buf, mac->MAXIMUM_KEYLENGTH); - return bench_buf_comp(mac, timer, nanoseconds_max, buf, buf_len); + return bench_buf_comp(mac, nanoseconds_max, buf, buf_len); } } @@ -122,7 +122,6 @@ bench_mac(MessageAuthenticationCode* mac, std::map<std::string, double> algorithm_benchmark(const std::string& name, u32bit milliseconds, - Timer& timer, RandomNumberGenerator& rng, Algorithm_Factory& af) { @@ -148,7 +147,7 @@ algorithm_benchmark(const std::string& name, af.prototype_block_cipher(name, provider)) { std::auto_ptr<BlockCipher> block_cipher(proto->clone()); - results = bench_block_cipher(block_cipher.get(), timer, + results = bench_block_cipher(block_cipher.get(), ns_per_provider, &buf[0], buf.size()); } @@ -156,7 +155,7 @@ algorithm_benchmark(const std::string& name, af.prototype_stream_cipher(name, provider)) { std::auto_ptr<StreamCipher> stream_cipher(proto->clone()); - results = bench_stream_cipher(stream_cipher.get(), timer, + results = bench_stream_cipher(stream_cipher.get(), ns_per_provider, &buf[0], buf.size()); } @@ -164,14 +163,14 @@ algorithm_benchmark(const std::string& name, af.prototype_hash_function(name, provider)) { std::auto_ptr<HashFunction> hash(proto->clone()); - results = bench_hash(hash.get(), timer, ns_per_provider, + results = bench_hash(hash.get(), ns_per_provider, &buf[0], buf.size()); } else if(const MessageAuthenticationCode* proto = af.prototype_mac(name, provider)) { std::auto_ptr<MessageAuthenticationCode> mac(proto->clone()); - results = bench_mac(mac.get(), timer, ns_per_provider, + results = bench_mac(mac.get(), ns_per_provider, &buf[0], buf.size()); } diff --git a/src/benchmark/benchmark.h b/src/benchmark/benchmark.h index 1b2730105..9c4e410f1 100644 --- a/src/benchmark/benchmark.h +++ b/src/benchmark/benchmark.h @@ -9,40 +9,16 @@ #define BOTAN_RUNTIME_BENCHMARK_H__ #include <botan/algo_factory.h> -#include <botan/timer.h> #include <botan/rng.h> #include <map> #include <string> -/** -* Choose some sort of default timer implementation to use, since some -* (like hardware tick counters and current Win32 timer) are not -* reliable for benchmarking. -*/ -#if defined(BOTAN_HAS_TIMER_POSIX) - #include <botan/tm_posix.h> -#elif defined(BOTAN_HAS_TIMER_UNIX) - #include <botan/tm_unix.h> -#endif - namespace Botan { -#if defined(BOTAN_HAS_TIMER_POSIX) - typedef POSIX_Timer Default_Benchmark_Timer; -#elif defined(BOTAN_HAS_TIMER_UNIX) - typedef Unix_Timer Default_Benchmark_Timer; -#else - /* I have not had good success using clock(), the results seem - * pretty bogus, but as a last resort it works. - */ - typedef ANSI_Clock_Timer Default_Benchmark_Timer; -#endif - /** * Algorithm benchmark * @param name the name of the algorithm to test (cipher, hash, or MAC) * @param milliseconds total time for the benchmark to run -* @param timer the timer to use * @param rng the rng to use to generate random inputs * @param af the algorithm factory used to create objects * @return results a map from provider to speed in mebibytes per second @@ -50,7 +26,6 @@ namespace Botan { std::map<std::string, double> BOTAN_DLL algorithm_benchmark(const std::string& name, u32bit milliseconds, - Timer& timer, RandomNumberGenerator& rng, Algorithm_Factory& af); diff --git a/src/benchmark/info.txt b/src/benchmark/info.txt index f148ae5ce..0210971f7 100644 --- a/src/benchmark/info.txt +++ b/src/benchmark/info.txt @@ -15,5 +15,4 @@ hash mac rng stream -timer </requires> diff --git a/src/build-data/os/aix.txt b/src/build-data/os/aix.txt index 0063948c7..312377096 100644 --- a/src/build-data/os/aix.txt +++ b/src/build-data/os/aix.txt @@ -1,5 +1,9 @@ os_type unix +<target_features> +gettimeofday +</target_features> + <supports_shared> all </supports_shared> diff --git a/src/build-data/os/beos.txt b/src/build-data/os/beos.txt index b843bd525..f6a06b7af 100644 --- a/src/build-data/os/beos.txt +++ b/src/build-data/os/beos.txt @@ -5,6 +5,10 @@ header_dir ../develop/headers lib_dir system/lib doc_dir documentation +<target_features> +gettimeofday +</target_features> + <supports_shared> all </supports_shared> diff --git a/src/build-data/os/cygwin.txt b/src/build-data/os/cygwin.txt index 7290648c2..f7c1f49ed 100644 --- a/src/build-data/os/cygwin.txt +++ b/src/build-data/os/cygwin.txt @@ -3,6 +3,10 @@ os_type unix install_root c:\Botan doc_dir docs +<target_features> +gettimeofday +</target_features> + # Cygwin supports shared libs fine, but there are problems with making a Botan # shared library when libraries it depends on are static-only (such as libz). # So until I can figure out a work-around, it's disabled. diff --git a/src/build-data/os/darwin.txt b/src/build-data/os/darwin.txt index fb18ee191..af60e1bed 100644 --- a/src/build-data/os/darwin.txt +++ b/src/build-data/os/darwin.txt @@ -8,6 +8,10 @@ ar_needs_ranlib yes doc_dir doc +<target_features> +gettimeofday +</target_features> + <supports_shared> all </supports_shared> diff --git a/src/build-data/os/dragonfly.txt b/src/build-data/os/dragonfly.txt index 6823de5b6..7a002a65d 100644 --- a/src/build-data/os/dragonfly.txt +++ b/src/build-data/os/dragonfly.txt @@ -1,6 +1,8 @@ os_type unix <target_features> +clock_gettime +gettimeofday posix_mlock </target_features> diff --git a/src/build-data/os/freebsd.txt b/src/build-data/os/freebsd.txt index 6823de5b6..3bcf58d62 100644 --- a/src/build-data/os/freebsd.txt +++ b/src/build-data/os/freebsd.txt @@ -2,6 +2,7 @@ os_type unix <target_features> posix_mlock +gettimeofday </target_features> <supports_shared> diff --git a/src/build-data/os/hpux.txt b/src/build-data/os/hpux.txt index 9ff0f7f62..e7aa30e9c 100644 --- a/src/build-data/os/hpux.txt +++ b/src/build-data/os/hpux.txt @@ -2,6 +2,10 @@ os_type unix so_suffix sl +<target_features> +gettimeofday +</target_features> + <supports_shared> all </supports_shared> diff --git a/src/build-data/os/irix.txt b/src/build-data/os/irix.txt index 0063948c7..312377096 100644 --- a/src/build-data/os/irix.txt +++ b/src/build-data/os/irix.txt @@ -1,5 +1,9 @@ os_type unix +<target_features> +gettimeofday +</target_features> + <supports_shared> all </supports_shared> diff --git a/src/build-data/os/linux.txt b/src/build-data/os/linux.txt index 3a92f9dd7..b3c227533 100644 --- a/src/build-data/os/linux.txt +++ b/src/build-data/os/linux.txt @@ -1,6 +1,8 @@ os_type unix <target_features> +clock_gettime +gettimeofday posix_mlock </target_features> diff --git a/src/build-data/os/netbsd.txt b/src/build-data/os/netbsd.txt index 0063948c7..312377096 100644 --- a/src/build-data/os/netbsd.txt +++ b/src/build-data/os/netbsd.txt @@ -1,5 +1,9 @@ os_type unix +<target_features> +gettimeofday +</target_features> + <supports_shared> all </supports_shared> diff --git a/src/build-data/os/openbsd.txt b/src/build-data/os/openbsd.txt index 0063948c7..312377096 100644 --- a/src/build-data/os/openbsd.txt +++ b/src/build-data/os/openbsd.txt @@ -1,5 +1,9 @@ os_type unix +<target_features> +gettimeofday +</target_features> + <supports_shared> all </supports_shared> diff --git a/src/build-data/os/qnx.txt b/src/build-data/os/qnx.txt index 0063948c7..312377096 100644 --- a/src/build-data/os/qnx.txt +++ b/src/build-data/os/qnx.txt @@ -1,5 +1,9 @@ os_type unix +<target_features> +gettimeofday +</target_features> + <supports_shared> all </supports_shared> diff --git a/src/build-data/os/solaris.txt b/src/build-data/os/solaris.txt index 47b06dcc4..df951d4fc 100644 --- a/src/build-data/os/solaris.txt +++ b/src/build-data/os/solaris.txt @@ -2,6 +2,7 @@ os_type unix <target_features> posix_mlock +gettimeofday </target_features> <supports_shared> diff --git a/src/build-data/os/tru64.txt b/src/build-data/os/tru64.txt index 8fc301d79..677c38955 100644 --- a/src/build-data/os/tru64.txt +++ b/src/build-data/os/tru64.txt @@ -1,5 +1,9 @@ os_type unix +<target_features> +gettimeofday +</target_features> + <supports_shared> all </supports_shared> diff --git a/src/cert/cvc/asn1_eac_tm.cpp b/src/cert/cvc/asn1_eac_tm.cpp index 947b9e66d..f361e6098 100644 --- a/src/cert/cvc/asn1_eac_tm.cpp +++ b/src/cert/cvc/asn1_eac_tm.cpp @@ -12,7 +12,7 @@ #include <botan/charset.h> #include <botan/parsing.h> #include <botan/rounding.h> -#include <botan/timer.h> +#include <botan/time.h> namespace Botan { diff --git a/src/cert/cvc/cvc_self.cpp b/src/cert/cvc/cvc_self.cpp index 777347a18..227ff4136 100644 --- a/src/cert/cvc/cvc_self.cpp +++ b/src/cert/cvc/cvc_self.cpp @@ -14,7 +14,7 @@ #include <botan/look_pk.h> #include <botan/cvc_req.h> #include <botan/cvc_ado.h> -#include <botan/timer.h> +#include <botan/time.h> #include <sstream> namespace Botan { diff --git a/src/cert/x509/crl_ent.cpp b/src/cert/x509/crl_ent.cpp index a8a989c24..42a742ebb 100644 --- a/src/cert/x509/crl_ent.cpp +++ b/src/cert/x509/crl_ent.cpp @@ -11,7 +11,7 @@ #include <botan/ber_dec.h> #include <botan/bigint.h> #include <botan/oids.h> -#include <botan/timer.h> +#include <botan/time.h> namespace Botan { diff --git a/src/cert/x509/x509_ca.cpp b/src/cert/x509/x509_ca.cpp index a4159ad2b..16b7b3b9b 100644 --- a/src/cert/x509/x509_ca.cpp +++ b/src/cert/x509/x509_ca.cpp @@ -14,7 +14,7 @@ #include <botan/lookup.h> #include <botan/look_pk.h> #include <botan/oids.h> -#include <botan/timer.h> +#include <botan/time.h> #include <algorithm> #include <typeinfo> #include <iterator> diff --git a/src/cert/x509/x509opt.cpp b/src/cert/x509/x509opt.cpp index 03bcd20f4..c6421d9ca 100644 --- a/src/cert/x509/x509opt.cpp +++ b/src/cert/x509/x509opt.cpp @@ -8,7 +8,7 @@ #include <botan/x509self.h> #include <botan/oids.h> #include <botan/parsing.h> -#include <botan/timer.h> +#include <botan/time.h> namespace Botan { diff --git a/src/cert/x509/x509stor.cpp b/src/cert/x509/x509stor.cpp index 40801148c..e9e8f4575 100644 --- a/src/cert/x509/x509stor.cpp +++ b/src/cert/x509/x509stor.cpp @@ -10,7 +10,7 @@ #include <botan/pubkey.h> #include <botan/look_pk.h> #include <botan/oids.h> -#include <botan/timer.h> +#include <botan/time.h> #include <algorithm> #include <memory> diff --git a/src/timer/cpu_counter/tm_hard.cpp b/src/entropy/hres_timer/hres_timer.cpp index 9e31aee39..74ea801c4 100644 --- a/src/timer/cpu_counter/tm_hard.cpp +++ b/src/entropy/hres_timer/hres_timer.cpp @@ -1,25 +1,43 @@ /* -* Hardware Timer -* (C) 1999-2007 Jack Lloyd +* High Resolution Timestamp Entropy Source +* (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ -#include <botan/tm_hard.h> +#include <botan/hres_timer.h> +#include <botan/cpuid.h> +#include <botan/time.h> + +#if defined(BOTAN_TARGET_OS_IS_WINDOWS) + #include <windows.h> +#endif namespace Botan { /* * Get the timestamp */ -u64bit Hardware_Timer::clock() const +void High_Resolution_Timestamp::poll(Entropy_Accumulator& accum) { + // If Windows, grab the Performance Counter (usually TSC or PIT) +#if defined(BOTAN_TARGET_OS_IS_WINDOWS) + LARGE_INTEGER tv; + ::QueryPerformanceCounter(&tv); + accum.add(tv.QuadPart, 0); +#endif + +#if defined(BOTAN_USE_GCC_INLINE_ASM) + u64bit rtc = 0; #if defined(BOTAN_TARGET_ARCH_IS_IA32) || defined(BOTAN_TARGET_ARCH_IS_AMD64) - u32bit rtc_low = 0, rtc_high = 0; - asm volatile("rdtsc" : "=d" (rtc_high), "=a" (rtc_low)); - rtc = (static_cast<u64bit>(rtc_high) << 32) | rtc_low; + if(CPUID::has_rdtsc()) // not availble on all x86 CPUs + { + u32bit rtc_low = 0, rtc_high = 0; + asm volatile("rdtsc" : "=d" (rtc_high), "=a" (rtc_low)); + rtc = (static_cast<u64bit>(rtc_high) << 32) | rtc_low; + } #elif defined(BOTAN_TARGET_ARCH_IS_PPC) || defined(BOTAN_TARGET_ARCH_IS_PPC64) u32bit rtc_low = 0, rtc_high = 0; @@ -41,11 +59,12 @@ u64bit Hardware_Timer::clock() const #elif defined(BOTAN_TARGET_ARCH_IS_HPPA) asm volatile("mfctl 16,%0" : "=r" (rtc)); // 64-bit only? -#else - #error "Unsure how to access hardware timer on this system" #endif - return rtc; + // Don't count the timestamp as contributing entropy + accum.add(rtc, 0); + +#endif } } diff --git a/src/entropy/hres_timer/hres_timer.h b/src/entropy/hres_timer/hres_timer.h new file mode 100644 index 000000000..8dfbfc2d7 --- /dev/null +++ b/src/entropy/hres_timer/hres_timer.h @@ -0,0 +1,27 @@ +/* +* High Resolution Timestamp Entropy Source +* (C) 1999-2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_ENTROPY_SRC_HRES_TIMER_H__ +#define BOTAN_ENTROPY_SRC_HRES_TIMER_H__ + +#include <botan/entropy_src.h> + +namespace Botan { + +/* +* High Resolution Timestamp Source +*/ +class BOTAN_DLL High_Resolution_Timestamp : public EntropySource + { + public: + std::string name() const { return "High Resolution Timestamp"; } + void poll(Entropy_Accumulator& accum); + }; + +} + +#endif diff --git a/src/timer/cpu_counter/info.txt b/src/entropy/hres_timer/info.txt index 2ab1343bc..566ce4ef6 100644 --- a/src/timer/cpu_counter/info.txt +++ b/src/entropy/hres_timer/info.txt @@ -1,14 +1,10 @@ -define TIMER_HARDWARE +define ENTROPY_SRC_HIGH_RESOLUTION_TIMER load_on asm_ok -<add> -tm_hard.cpp -tm_hard.h -</add> - <cc> gcc +icc </cc> <arch> @@ -30,7 +26,3 @@ ia64 # ar.itc s390x hppa </arch> - -<requires> -timer -</requires> diff --git a/src/rng/auto_rng/auto_rng.cpp b/src/rng/auto_rng/auto_rng.cpp index f02a9249f..6906d9d17 100644 --- a/src/rng/auto_rng/auto_rng.cpp +++ b/src/rng/auto_rng/auto_rng.cpp @@ -7,7 +7,6 @@ #include <botan/auto_rng.h> #include <botan/parsing.h> -#include <botan/timer.h> #include <botan/hmac.h> #include <botan/sha2_32.h> #include <botan/sha2_64.h> @@ -28,20 +27,8 @@ #include <botan/aes.h> #endif -#if defined(BOTAN_HAS_TIMER_HARDWARE) - #include <botan/tm_hard.h> -#endif - -#if defined(BOTAN_HAS_TIMER_POSIX) - #include <botan/tm_posix.h> -#endif - -#if defined(BOTAN_HAS_TIMER_UNIX) - #include <botan/tm_unix.h> -#endif - -#if defined(BOTAN_HAS_TIMER_WIN32) - #include <botan/tm_win32.h> +#if defined(BOTAN_HAS_ENTROPY_SRC_HIGH_RESOLUTION_TIMER) + #include <botan/hres_timer.h> #endif #if defined(BOTAN_HAS_ENTROPY_SRC_DEVICE) @@ -81,16 +68,8 @@ namespace { */ void add_entropy_sources(RandomNumberGenerator* rng) { - - // Add a high resolution timer, if available -#if defined(BOTAN_HAS_TIMER_HARDWARE) - rng->add_entropy_source(new Hardware_Timer); -#elif defined(BOTAN_HAS_TIMER_POSIX) - rng->add_entropy_source(new POSIX_Timer); -#elif defined(BOTAN_HAS_TIMER_UNIX) - rng->add_entropy_source(new Unix_Timer); -#elif defined(BOTAN_HAS_TIMER_WIN32) - rng->add_entropy_source(new Win32_Timer); +#if defined(BOTAN_HAS_ENTROPY_SRC_HIGH_RESOLUTION_TIMER) + rng->add_entropy_source(new High_Resolution_Timestamp); #endif #if defined(BOTAN_HAS_ENTROPY_SRC_DEVICE) diff --git a/src/rng/auto_rng/info.txt b/src/rng/auto_rng/info.txt index d5abfc757..357dc17ad 100644 --- a/src/rng/auto_rng/info.txt +++ b/src/rng/auto_rng/info.txt @@ -10,5 +10,4 @@ auto_rng.cpp <requires> hmac sha2 -timer </requires> diff --git a/src/rng/randpool/randpool.cpp b/src/rng/randpool/randpool.cpp index fb51db300..8f9a16edc 100644 --- a/src/rng/randpool/randpool.cpp +++ b/src/rng/randpool/randpool.cpp @@ -8,7 +8,6 @@ #include <botan/randpool.h> #include <botan/loadstor.h> #include <botan/xor_buf.h> -#include <botan/timer.h> #include <botan/stl_util.h> #include <algorithm> @@ -51,12 +50,9 @@ void Randpool::randomize(byte out[], u32bit length) */ void Randpool::update_buffer() { - const u64bit timestamp = system_time(); - for(u32bit i = 0; i != counter.size(); ++i) if(++counter[i]) break; - store_be(timestamp, counter + 4); mac->update(static_cast<byte>(GEN_OUTPUT)); mac->update(counter, counter.size()); diff --git a/src/timer/cpu_counter/tm_hard.h b/src/timer/cpu_counter/tm_hard.h deleted file mode 100644 index 2e338eca8..000000000 --- a/src/timer/cpu_counter/tm_hard.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -* Hardware Timer -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_TIMER_HARDWARE_H__ -#define BOTAN_TIMER_HARDWARE_H__ - -#include <botan/timer.h> - -namespace Botan { - -/* -* Hardware Timer -*/ -class BOTAN_DLL Hardware_Timer : public Timer - { - public: - /* - @todo: Add sync(Timer& wall_clock, bool milliseconds) which busy - loops using wall_clock and tries to guess the tick rate of the - hardware counter, allowing it to be used for benchmarks, etc - */ - - std::string name() const { return "Hardware Timer"; } - u64bit clock() const; - }; - -} - -#endif diff --git a/src/timer/gettimeofday/info.txt b/src/timer/gettimeofday/info.txt deleted file mode 100644 index d1f6f7d74..000000000 --- a/src/timer/gettimeofday/info.txt +++ /dev/null @@ -1,24 +0,0 @@ -define TIMER_UNIX - -load_on auto - -<os> -aix -beos -cygwin -darwin -freebsd -dragonfly -hpux -irix -linux -netbsd -openbsd -qnx -solaris -tru64 -</os> - -<requires> -timer -</requires> diff --git a/src/timer/gettimeofday/tm_unix.cpp b/src/timer/gettimeofday/tm_unix.cpp deleted file mode 100644 index 9d8ac4a04..000000000 --- a/src/timer/gettimeofday/tm_unix.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* -* Unix Timer -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/tm_unix.h> -#include <sys/time.h> - -namespace Botan { - -/* -* Get the timestamp -*/ -u64bit Unix_Timer::clock() const - { - struct ::timeval tv; - ::gettimeofday(&tv, 0); - return combine_timers(tv.tv_sec, tv.tv_usec, 1000000); - } - -} diff --git a/src/timer/gettimeofday/tm_unix.h b/src/timer/gettimeofday/tm_unix.h deleted file mode 100644 index c304dbb5c..000000000 --- a/src/timer/gettimeofday/tm_unix.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -* Unix Timer -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_TIMER_UNIX_H__ -#define BOTAN_TIMER_UNIX_H__ - -#include <botan/timer.h> - -namespace Botan { - -/* -* Unix Timer -*/ -class BOTAN_DLL Unix_Timer : public Timer - { - public: - std::string name() const { return "Unix gettimeofday"; } - u64bit clock() const; - }; - -} - -#endif diff --git a/src/timer/info.txt b/src/timer/info.txt deleted file mode 100644 index 1dff5ab6f..000000000 --- a/src/timer/info.txt +++ /dev/null @@ -1,12 +0,0 @@ -define TIMER - -load_on auto - -<add> -timer.cpp -timer.h -</add> - -<requires> -rng -</requires> diff --git a/src/timer/posix_rt/info.txt b/src/timer/posix_rt/info.txt deleted file mode 100644 index 4b23a74fc..000000000 --- a/src/timer/posix_rt/info.txt +++ /dev/null @@ -1,26 +0,0 @@ -define TIMER_POSIX - -load_on auto - -<add> -tm_posix.cpp -tm_posix.h -</add> - -<libs> -linux -> rt -</libs> - -# The *BSDs put clock_gettime in sys/time.h, not time.h like POSIX says -<os> -cygwin -linux -#freebsd -dragonfly -#netbsd -#openbsd -</os> - -<requires> -timer -</requires> diff --git a/src/timer/posix_rt/tm_posix.cpp b/src/timer/posix_rt/tm_posix.cpp deleted file mode 100644 index 96182025c..000000000 --- a/src/timer/posix_rt/tm_posix.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* -* POSIX Timer -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/tm_posix.h> - -#ifndef _POSIX_C_SOURCE - #define _POSIX_C_SOURCE 199309 -#endif - -#include <time.h> - -#ifndef CLOCK_REALTIME - #define CLOCK_REALTIME 0 -#endif - -namespace Botan { - -/* -* Get the timestamp -*/ -u64bit POSIX_Timer::clock() const - { - struct ::timespec tv; - ::clock_gettime(CLOCK_REALTIME, &tv); - return combine_timers(tv.tv_sec, tv.tv_nsec, 1000000000); - } - -} diff --git a/src/timer/posix_rt/tm_posix.h b/src/timer/posix_rt/tm_posix.h deleted file mode 100644 index 8bedccfa2..000000000 --- a/src/timer/posix_rt/tm_posix.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -* POSIX Timer -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_TIMER_POSIX_H__ -#define BOTAN_TIMER_POSIX_H__ - -#include <botan/timer.h> - -namespace Botan { - -/* -* POSIX Timer -*/ -class BOTAN_DLL POSIX_Timer : public Timer - { - public: - std::string name() const { return "POSIX clock_gettime"; } - u64bit clock() const; - }; - -} - -#endif diff --git a/src/timer/timer.h b/src/timer/timer.h deleted file mode 100644 index 603027f6d..000000000 --- a/src/timer/timer.h +++ /dev/null @@ -1,53 +0,0 @@ -/** -* Timestamp Functions -* (C) 1999-2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_TIMERS_H__ -#define BOTAN_TIMERS_H__ - -#include <botan/rng.h> -#include <ctime> - -namespace Botan { - -/* -* Time Access/Conversion Functions -*/ -BOTAN_DLL u64bit system_time(); - -BOTAN_DLL std::tm time_t_to_tm(u64bit); - -/** -* Timer Interface -*/ -class BOTAN_DLL Timer : public EntropySource - { - public: - /** - @return nanoseconds resolution timestamp, unknown epoch - */ - virtual u64bit clock() const = 0; - - void poll(Entropy_Accumulator& accum); - - virtual ~Timer() {} - protected: - static u64bit combine_timers(u32bit, u32bit, u32bit); - }; - -/** -* ANSI Clock Timer -*/ -class BOTAN_DLL ANSI_Clock_Timer : public Timer - { - public: - std::string name() const { return "ANSI clock"; } - u64bit clock() const; - }; - -} - -#endif diff --git a/src/timer/win32_query_perf_ctr/info.txt b/src/timer/win32_query_perf_ctr/info.txt deleted file mode 100644 index 67db5bc95..000000000 --- a/src/timer/win32_query_perf_ctr/info.txt +++ /dev/null @@ -1,17 +0,0 @@ -define TIMER_WIN32 - -load_on auto - -<os> -cygwin -windows -mingw -</os> - -<libs> -windows -> user32.lib -</libs> - -<requires> -timer -</requires> diff --git a/src/timer/win32_query_perf_ctr/tm_win32.cpp b/src/timer/win32_query_perf_ctr/tm_win32.cpp deleted file mode 100644 index 6b878e6e2..000000000 --- a/src/timer/win32_query_perf_ctr/tm_win32.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* -* Win32 Timer -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/tm_win32.h> -#include <windows.h> - -namespace Botan { - -/* -* Get the timestamp -*/ -u64bit Win32_Timer::clock() const - { - LARGE_INTEGER tv; - ::QueryPerformanceCounter(&tv); - return tv.QuadPart; - } - -} diff --git a/src/timer/win32_query_perf_ctr/tm_win32.h b/src/timer/win32_query_perf_ctr/tm_win32.h deleted file mode 100644 index 5bcb720ab..000000000 --- a/src/timer/win32_query_perf_ctr/tm_win32.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -* Win32 Timer -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_TIMER_WIN32_H__ -#define BOTAN_TIMER_WIN32_H__ - -#include <botan/timer.h> - -namespace Botan { - -/* -* Win32 Timer -*/ -class BOTAN_DLL Win32_Timer : public Timer - { - public: - std::string name() const { return "Win32 QueryPerformanceCounter"; } - u64bit clock() const; - }; - -} - -#endif diff --git a/src/utils/info.txt b/src/utils/info.txt index 3d024fa09..110afeb64 100644 --- a/src/utils/info.txt +++ b/src/utils/info.txt @@ -3,5 +3,5 @@ define UTIL_FUNCTIONS load_on always <libs> -tru64 -> rt +linux,tru64 -> rt </libs> diff --git a/src/timer/timer.cpp b/src/utils/time.cpp index 16d7dc368..856b1c7be 100644 --- a/src/timer/timer.cpp +++ b/src/utils/time.cpp @@ -1,16 +1,50 @@ /** -* Timestamp Functions +* Time Functions * (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ -#include <botan/timer.h> -#include <botan/loadstor.h> +#include <botan/time.h> +#include <botan/exceptn.h> #include <ctime> +#if defined(BOTAN_TARGET_OS_HAS_GETTIMEOFDAY) + #include <sys/time.h> +#endif + +#if defined(BOTAN_TARGET_OS_HAS_CLOCK_GETTIME) + +#ifndef _POSIX_C_SOURCE + #define _POSIX_C_SOURCE 199309 +#endif + +#include <time.h> + +#ifndef CLOCK_REALTIME + #define CLOCK_REALTIME 0 +#endif + +#endif + namespace Botan { +namespace { + +/** +* Combine a two time values into a single one +*/ +u64bit combine_timers(u32bit seconds, u32bit parts, u32bit parts_hz) + { + static const u64bit NANOSECONDS_UNITS = 1000000000; + + u64bit res = seconds * NANOSECONDS_UNITS; + res += parts * (NANOSECONDS_UNITS / parts_hz); + return res; + } + +} + /** * Get the system clock */ @@ -32,33 +66,22 @@ std::tm time_t_to_tm(u64bit timer) return (*tm_p); } -/** -* Read the clock and return the output -*/ -void Timer::poll(Entropy_Accumulator& accum) - { - const u64bit clock_value = this->clock(); - accum.add(clock_value, 0); - } - -/** -* Combine a two time values into a single one -*/ -u64bit Timer::combine_timers(u32bit seconds, u32bit parts, u32bit parts_hz) +u64bit get_nanoseconds_clock() { - static const u64bit NANOSECONDS_UNITS = 1000000000; +#if defined(BOTAN_TARGET_OS_HAS_CLOCK_GETTIME) + struct ::timespec tv; + ::clock_gettime(CLOCK_REALTIME, &tv); + return combine_timers(tv.tv_sec, tv.tv_nsec, 1000000000); - u64bit res = seconds * NANOSECONDS_UNITS; - res += parts * (NANOSECONDS_UNITS / parts_hz); - return res; - } +#elif defined(BOTAN_TARGET_OS_HAS_GETTIMEOFDAY) + struct ::timeval tv; + ::gettimeofday(&tv, 0); + return combine_timers(tv.tv_sec, tv.tv_usec, 1000000); -/** -* ANSI Clock -*/ -u64bit ANSI_Clock_Timer::clock() const - { +#else return combine_timers(std::time(0), std::clock(), CLOCKS_PER_SEC); + +#endif } } diff --git a/src/utils/time.h b/src/utils/time.h new file mode 100644 index 000000000..c7f459096 --- /dev/null +++ b/src/utils/time.h @@ -0,0 +1,30 @@ +/** +* Time Functions +* (C) 1999-2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_TIME_H__ +#define BOTAN_TIME_H__ + +#include <botan/types.h> +#include <ctime> + +namespace Botan { + +/* +* Time Access/Conversion Functions +*/ +BOTAN_DLL u64bit system_time(); + +BOTAN_DLL std::tm time_t_to_tm(u64bit); + +/** +@return nanoseconds resolution timestamp, unknown epoch +*/ +BOTAN_DLL u64bit get_nanoseconds_clock(); + +} + +#endif |