1 /** 2 * High Resolution Timestamp Entropy Source 3 * 4 * Copyright: 5 * (C) 1999-2009, 2014 Jack Lloyd 6 * (C) 2014-2015 Etienne Cimon 7 * 8 * License: 9 * Botan is released under the Simplified BSD License (see LICENSE.md) 10 */ 11 module botan.entropy.hres_timer; 12 13 import botan.constants; 14 static if (BOTAN_HAS_ENTROPY_SRC_HIGH_RESOLUTION_TIMER): 15 16 import botan.entropy.entropy_src; 17 18 import botan.utils.cpuid; 19 import std.datetime; 20 21 version(Windows) import core.sys.windows.windows; 22 else version(Posix) import core.sys.linux.time; 23 24 25 /** 26 * Entropy source using high resolution timers 27 * 28 * @note Any results from timers are marked as not contributing entropy 29 * to the poll, as a local attacker could observe them directly. 30 */ 31 final class HighResolutionTimestamp : EntropySource 32 { 33 public: 34 @property string name() const { return "High Resolution Timestamp"; } 35 /* 36 * Get the timestamp 37 */ 38 void poll(ref EntropyAccumulator accum) 39 { 40 // Don't count any timestamps as contributing any entropy 41 const double ESTIMATED_ENTROPY_PER_BYTE = 1.0; 42 43 static if (is(typeof(clock_gettime))) { 44 45 void CLOCK_GETTIME_POLL(clockid_t src) 46 { 47 timespec ts; 48 clock_gettime(src, &ts); 49 accum.add(&ts, (ts).sizeof, ESTIMATED_ENTROPY_PER_BYTE); 50 } 51 52 static if (is(typeof(CLOCK_REALTIME))) { 53 CLOCK_GETTIME_POLL(CLOCK_REALTIME); 54 } 55 56 static if (is(typeof(CLOCK_MONOTONIC))) { 57 CLOCK_GETTIME_POLL(CLOCK_MONOTONIC); 58 } 59 60 static if (is(typeof(CLOCK_MONOTONIC_RAW))) { 61 CLOCK_GETTIME_POLL(CLOCK_MONOTONIC_RAW); 62 } 63 64 static if (is(typeof(CLOCK_PROCESS_CPUTIME_ID))) { 65 CLOCK_GETTIME_POLL(CLOCK_PROCESS_CPUTIME_ID); 66 } 67 68 static if (is(typeof(CLOCK_THREAD_CPUTIME_ID))) { 69 CLOCK_GETTIME_POLL(CLOCK_THREAD_CPUTIME_ID); 70 } 71 72 } 73 else 74 { 75 auto timestamp = Clock.currStdTime(); 76 accum.add(timestamp, ESTIMATED_ENTROPY_PER_BYTE); 77 78 } 79 80 static if (is(typeof(QueryPerformanceCounter))) 81 { 82 long tv; 83 QueryPerformanceCounter(&tv); 84 accum.add(tv, ESTIMATED_ENTROPY_PER_BYTE); 85 } 86 } 87 88 } 89 90 91 92 version (Windows) 93 { 94 extern (Windows) 95 { 96 export int queryPerformanceCounter(long *); 97 } 98 } 99 else version (D_InlineAsm_X86) 100 { 101 extern (D) 102 { 103 void queryPerformanceCounter(long* ctr) 104 { 105 asm 106 { 107 naked ; 108 mov ECX,EAX ; 109 rdtsc ; 110 mov [ECX],EAX ; 111 mov 4[ECX],EDX ; 112 ret ; 113 } 114 } 115 } 116 } 117 else version (D_InlineAsm_X86_64) 118 { 119 extern (D) 120 { 121 void queryPerformanceCounter(long* ctr) 122 { 123 asm 124 { 125 naked ; 126 rdtsc ; 127 mov [RDI],EAX ; 128 mov 4[RDI],EDX ; 129 ret ; 130 } 131 } 132 } 133 } 134 else 135 { 136 static assert(0); 137 }