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