Botan  1.10.9
hres_timer.cpp
Go to the documentation of this file.
1 /*
2 * High Resolution Timestamp Entropy Source
3 * (C) 1999-2009,2011 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/internal/hres_timer.h>
9 #include <botan/cpuid.h>
10 #include <botan/time.h>
11 
12 #if defined(BOTAN_TARGET_OS_IS_WINDOWS)
13  #include <windows.h>
14 #endif
15 
16 namespace Botan {
17 
18 /*
19 * Get the timestamp
20 */
22  {
23  // If Windows, grab the Performance Counter (usually TSC or PIT)
24 #if defined(BOTAN_TARGET_OS_IS_WINDOWS)
25  {
26  LARGE_INTEGER tv;
27  ::QueryPerformanceCounter(&tv);
28  accum.add(tv.QuadPart, 0);
29  }
30 #endif
31 
32 #if defined(BOTAN_TARGET_OS_HAS_CLOCK_GETTIME)
33 
34 #define CLOCK_POLL(src) \
35  do { \
36  struct timespec ts; \
37  clock_gettime(src, &ts); \
38  accum.add(&ts, sizeof(ts), 0); \
39  } while(0)
40 
41 #if defined(CLOCK_REALTIME)
42  CLOCK_POLL(CLOCK_REALTIME);
43 #endif
44 
45 #if defined(CLOCK_MONOTONIC)
46  CLOCK_POLL(CLOCK_MONOTONIC);
47 #endif
48 
49 #if defined(CLOCK_MONOTONIC_RAW)
50  CLOCK_POLL(CLOCK_MONOTONIC_RAW);
51 #endif
52 
53 #if defined(CLOCK_PROCESS_CPUTIME_ID)
54  CLOCK_POLL(CLOCK_PROCESS_CPUTIME_ID);
55 #endif
56 
57 #if defined(CLOCK_THREAD_CPUTIME_ID)
58  CLOCK_POLL(CLOCK_THREAD_CPUTIME_ID);
59 #endif
60 
61 #undef CLOCK_POLL
62 
63 #endif
64 
65 #if BOTAN_USE_GCC_INLINE_ASM
66 
67  u64bit rtc = 0;
68 
69 #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
70  if(CPUID::has_rdtsc()) // not availble on all x86 CPUs
71  {
72  u32bit rtc_low = 0, rtc_high = 0;
73  asm volatile("rdtsc" : "=d" (rtc_high), "=a" (rtc_low));
74  rtc = (static_cast<u64bit>(rtc_high) << 32) | rtc_low;
75  }
76 
77 #elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
78  u32bit rtc_low = 0, rtc_high = 0;
79  asm volatile("mftbu %0; mftb %1" : "=r" (rtc_high), "=r" (rtc_low));
80  rtc = (static_cast<u64bit>(rtc_high) << 32) | rtc_low;
81 
82 #elif defined(BOTAN_TARGET_ARCH_IS_ALPHA)
83  asm volatile("rpcc %0" : "=r" (rtc));
84 
85 #elif defined(BOTAN_TARGET_ARCH_IS_SPARC64) && !defined(BOTAN_TARGET_OS_IS_OPENBSD)
86  asm volatile("rd %%tick, %0" : "=r" (rtc));
87 
88 #elif defined(BOTAN_TARGET_ARCH_IS_IA64)
89  asm volatile("mov %0=ar.itc" : "=r" (rtc));
90 
91 #elif defined(BOTAN_TARGET_ARCH_IS_S390X)
92  asm volatile("stck 0(%0)" : : "a" (&rtc) : "memory", "cc");
93 
94 #elif defined(BOTAN_TARGET_ARCH_IS_HPPA)
95  asm volatile("mfctl 16,%0" : "=r" (rtc)); // 64-bit only?
96 
97 #endif
98 
99  // Don't count the timestamp as contributing entropy
100  accum.add(rtc, 0);
101 
102 #endif
103  }
104 
105 }
void add(const void *bytes, size_t length, double entropy_bits_per_byte)
Definition: entropy_src.h:70
unsigned long long u64bit
Definition: types.h:49
static bool has_rdtsc()
Definition: cpuid.h:34
void poll(Entropy_Accumulator &accum)
Definition: hres_timer.cpp:21
unsigned int u32bit
Definition: types.h:32