|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 #include "secrng.h" |
|
6 |
|
7 #ifdef XP_WIN |
|
8 #include <windows.h> |
|
9 #include <time.h> |
|
10 |
|
11 static BOOL |
|
12 CurrentClockTickTime(LPDWORD lpdwHigh, LPDWORD lpdwLow) |
|
13 { |
|
14 LARGE_INTEGER liCount; |
|
15 |
|
16 if (!QueryPerformanceCounter(&liCount)) |
|
17 return FALSE; |
|
18 |
|
19 *lpdwHigh = liCount.u.HighPart; |
|
20 *lpdwLow = liCount.u.LowPart; |
|
21 return TRUE; |
|
22 } |
|
23 |
|
24 size_t RNG_GetNoise(void *buf, size_t maxbuf) |
|
25 { |
|
26 DWORD dwHigh, dwLow, dwVal; |
|
27 int n = 0; |
|
28 int nBytes; |
|
29 time_t sTime; |
|
30 |
|
31 if (maxbuf <= 0) |
|
32 return 0; |
|
33 |
|
34 CurrentClockTickTime(&dwHigh, &dwLow); |
|
35 |
|
36 // get the maximally changing bits first |
|
37 nBytes = sizeof(dwLow) > maxbuf ? maxbuf : sizeof(dwLow); |
|
38 memcpy((char *)buf, &dwLow, nBytes); |
|
39 n += nBytes; |
|
40 maxbuf -= nBytes; |
|
41 |
|
42 if (maxbuf <= 0) |
|
43 return n; |
|
44 |
|
45 nBytes = sizeof(dwHigh) > maxbuf ? maxbuf : sizeof(dwHigh); |
|
46 memcpy(((char *)buf) + n, &dwHigh, nBytes); |
|
47 n += nBytes; |
|
48 maxbuf -= nBytes; |
|
49 |
|
50 if (maxbuf <= 0) |
|
51 return n; |
|
52 |
|
53 // get the number of milliseconds that have elapsed since Windows started |
|
54 dwVal = GetTickCount(); |
|
55 |
|
56 nBytes = sizeof(dwVal) > maxbuf ? maxbuf : sizeof(dwVal); |
|
57 memcpy(((char *)buf) + n, &dwVal, nBytes); |
|
58 n += nBytes; |
|
59 maxbuf -= nBytes; |
|
60 |
|
61 if (maxbuf <= 0) |
|
62 return n; |
|
63 |
|
64 // get the time in seconds since midnight Jan 1, 1970 |
|
65 time(&sTime); |
|
66 nBytes = sizeof(sTime) > maxbuf ? maxbuf : sizeof(sTime); |
|
67 memcpy(((char *)buf) + n, &sTime, nBytes); |
|
68 n += nBytes; |
|
69 |
|
70 return n; |
|
71 } |
|
72 |
|
73 void RNG_SystemInfoForRNG(void) |
|
74 { |
|
75 DWORD dwVal; |
|
76 char buffer[256]; |
|
77 int nBytes; |
|
78 MEMORYSTATUS sMem; |
|
79 HANDLE hVal; |
|
80 DWORD dwSerialNum; |
|
81 DWORD dwComponentLen; |
|
82 DWORD dwSysFlags; |
|
83 char volName[128]; |
|
84 DWORD dwSectors, dwBytes, dwFreeClusters, dwNumClusters; |
|
85 |
|
86 nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes |
|
87 RNG_RandomUpdate(buffer, nBytes); |
|
88 |
|
89 sMem.dwLength = sizeof(sMem); |
|
90 GlobalMemoryStatus(&sMem); // assorted memory stats |
|
91 RNG_RandomUpdate(&sMem, sizeof(sMem)); |
|
92 |
|
93 dwVal = GetLogicalDrives(); |
|
94 RNG_RandomUpdate(&dwVal, sizeof(dwVal)); // bitfields in bits 0-25 |
|
95 |
|
96 dwVal = sizeof(buffer); |
|
97 if (GetComputerName(buffer, &dwVal)) |
|
98 RNG_RandomUpdate(buffer, dwVal); |
|
99 |
|
100 hVal = GetCurrentProcess(); // 4 or 8 byte pseudo handle (a |
|
101 // constant!) of current process |
|
102 RNG_RandomUpdate(&hVal, sizeof(hVal)); |
|
103 |
|
104 dwVal = GetCurrentProcessId(); // process ID (4 bytes) |
|
105 RNG_RandomUpdate(&dwVal, sizeof(dwVal)); |
|
106 |
|
107 dwVal = GetCurrentThreadId(); // thread ID (4 bytes) |
|
108 RNG_RandomUpdate(&dwVal, sizeof(dwVal)); |
|
109 |
|
110 volName[0] = '\0'; |
|
111 buffer[0] = '\0'; |
|
112 GetVolumeInformation(NULL, |
|
113 volName, |
|
114 sizeof(volName), |
|
115 &dwSerialNum, |
|
116 &dwComponentLen, |
|
117 &dwSysFlags, |
|
118 buffer, |
|
119 sizeof(buffer)); |
|
120 |
|
121 RNG_RandomUpdate(volName, strlen(volName)); |
|
122 RNG_RandomUpdate(&dwSerialNum, sizeof(dwSerialNum)); |
|
123 RNG_RandomUpdate(&dwComponentLen, sizeof(dwComponentLen)); |
|
124 RNG_RandomUpdate(&dwSysFlags, sizeof(dwSysFlags)); |
|
125 RNG_RandomUpdate(buffer, strlen(buffer)); |
|
126 |
|
127 if (GetDiskFreeSpace(NULL, &dwSectors, &dwBytes, &dwFreeClusters, |
|
128 &dwNumClusters)) { |
|
129 RNG_RandomUpdate(&dwSectors, sizeof(dwSectors)); |
|
130 RNG_RandomUpdate(&dwBytes, sizeof(dwBytes)); |
|
131 RNG_RandomUpdate(&dwFreeClusters, sizeof(dwFreeClusters)); |
|
132 RNG_RandomUpdate(&dwNumClusters, sizeof(dwNumClusters)); |
|
133 } |
|
134 |
|
135 nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes |
|
136 RNG_RandomUpdate(buffer, nBytes); |
|
137 } |
|
138 |
|
139 |
|
140 /* |
|
141 * The RtlGenRandom function is declared in <ntsecapi.h>, but the |
|
142 * declaration is missing a calling convention specifier. So we |
|
143 * declare it manually here. |
|
144 */ |
|
145 #define RtlGenRandom SystemFunction036 |
|
146 DECLSPEC_IMPORT BOOLEAN WINAPI RtlGenRandom( |
|
147 PVOID RandomBuffer, |
|
148 ULONG RandomBufferLength); |
|
149 |
|
150 size_t RNG_SystemRNG(void *dest, size_t maxLen) |
|
151 { |
|
152 size_t bytes = 0; |
|
153 |
|
154 if (RtlGenRandom(dest, maxLen)) { |
|
155 bytes = maxLen; |
|
156 } |
|
157 return bytes; |
|
158 } |
|
159 #endif /* is XP_WIN */ |