Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Side by Side Diff: nss/lib/freebl/win_rand.c

Issue 195763027: Update NSS to NSS_3_16_RC0. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/nss/
Patch Set: Use the RTM tag Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « nss/lib/freebl/sysrand.c ('k') | nss/lib/libpkix/include/pkix_pl_pki.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* This Source Code Form is subject to the terms of the Mozilla Public 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 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/. */ 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 4
5 #include "secrng.h" 5 #include "secrng.h"
6 #include "secerr.h"
7 6
8 #ifdef XP_WIN 7 #ifdef XP_WIN
9 #include <windows.h> 8 #include <windows.h>
10 #include <shlobj.h> /* for CSIDL constants */
11 #include <time.h> 9 #include <time.h>
12 #include <io.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <stdio.h>
16 #include "prio.h"
17 #include "prerror.h"
18
19 static PRInt32 filesToRead;
20 static DWORD totalFileBytes;
21 static DWORD maxFileBytes = 250000; /* 250 thousand */
22 static DWORD dwNumFiles, dwReadEvery, dwFileToRead;
23 static PRBool usedWindowsPRNG;
24 10
25 static BOOL 11 static BOOL
26 CurrentClockTickTime(LPDWORD lpdwHigh, LPDWORD lpdwLow) 12 CurrentClockTickTime(LPDWORD lpdwHigh, LPDWORD lpdwLow)
27 { 13 {
28 LARGE_INTEGER liCount; 14 LARGE_INTEGER liCount;
29 15
30 if (!QueryPerformanceCounter(&liCount)) 16 if (!QueryPerformanceCounter(&liCount))
31 return FALSE; 17 return FALSE;
32 18
33 *lpdwHigh = liCount.u.HighPart; 19 *lpdwHigh = liCount.u.HighPart;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 63
78 // get the time in seconds since midnight Jan 1, 1970 64 // get the time in seconds since midnight Jan 1, 1970
79 time(&sTime); 65 time(&sTime);
80 nBytes = sizeof(sTime) > maxbuf ? maxbuf : sizeof(sTime); 66 nBytes = sizeof(sTime) > maxbuf ? maxbuf : sizeof(sTime);
81 memcpy(((char *)buf) + n, &sTime, nBytes); 67 memcpy(((char *)buf) + n, &sTime, nBytes);
82 n += nBytes; 68 n += nBytes;
83 69
84 return n; 70 return n;
85 } 71 }
86 72
87 typedef PRInt32 (* Handler)(const PRUnichar *);
88 #define MAX_DEPTH 2
89 #define MAX_FOLDERS 4
90 #define MAX_FILES 1024
91
92 static void
93 EnumSystemFilesInFolder(Handler func, PRUnichar* szSysDir, int maxDepth)
94 {
95 int iContinue;
96 unsigned int uFolders = 0;
97 unsigned int uFiles = 0;
98 HANDLE lFindHandle;
99 WIN32_FIND_DATAW fdData;
100 PRUnichar szFileName[_MAX_PATH];
101
102 if (maxDepth < 0)
103 return;
104 // append *.* so we actually look for files.
105 _snwprintf(szFileName, _MAX_PATH, L"%s\\*.*", szSysDir);
106 szFileName[_MAX_PATH - 1] = L'\0';
107
108 lFindHandle = FindFirstFileW(szFileName, &fdData);
109 if (lFindHandle == INVALID_HANDLE_VALUE)
110 return;
111 do {
112 iContinue = 1;
113 if (wcscmp(fdData.cFileName, L".") == 0 ||
114 wcscmp(fdData.cFileName, L"..") == 0) {
115 // skip "." and ".."
116 } else {
117 // pass the full pathname to the callback
118 _snwprintf(szFileName, _MAX_PATH, L"%s\\%s", szSysDir,
119 fdData.cFileName);
120 szFileName[_MAX_PATH - 1] = L'\0';
121 if (fdData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
122 if (++uFolders <= MAX_FOLDERS)
123 EnumSystemFilesInFolder(func, szFileName, maxDepth - 1);
124 } else {
125 iContinue = (++uFiles <= MAX_FILES) && !(*func)(szFileName);
126 }
127 }
128 if (iContinue)
129 iContinue = FindNextFileW(lFindHandle, &fdData);
130 } while (iContinue);
131 FindClose(lFindHandle);
132 }
133
134 static BOOL
135 EnumSystemFiles(Handler func)
136 {
137 PRUnichar szSysDir[_MAX_PATH];
138 static const int folders[] = {
139 CSIDL_BITBUCKET,
140 CSIDL_RECENT,
141 CSIDL_INTERNET_CACHE,
142 CSIDL_HISTORY,
143 0
144 };
145 int i = 0;
146 if (_MAX_PATH > (i = GetTempPathW(_MAX_PATH, szSysDir))) {
147 if (i > 0 && szSysDir[i-1] == L'\\')
148 szSysDir[i-1] = L'\0'; // we need to lop off the trailing slash
149 EnumSystemFilesInFolder(func, szSysDir, MAX_DEPTH);
150 }
151 for(i = 0; folders[i]; i++) {
152 DWORD rv = SHGetSpecialFolderPathW(NULL, szSysDir, folders[i], 0);
153 if (szSysDir[0])
154 EnumSystemFilesInFolder(func, szSysDir, MAX_DEPTH);
155 szSysDir[0] = L'\0';
156 }
157 return PR_TRUE;
158 }
159
160 static PRInt32
161 CountFiles(const PRUnichar *file)
162 {
163 dwNumFiles++;
164 return 0;
165 }
166
167 static int
168 ReadSingleFile(const char *filename)
169 {
170 PRFileDesc * file;
171 unsigned char buffer[1024];
172
173 file = PR_Open(filename, PR_RDONLY, 0);
174 if (file != NULL) {
175 while (PR_Read(file, buffer, sizeof buffer) > 0)
176 ;
177 PR_Close(file);
178 }
179 return (file != NULL);
180 }
181
182 static PRInt32
183 ReadOneFile(const PRUnichar *szFileName)
184 {
185 char narrowFileName[_MAX_PATH];
186
187 if (dwNumFiles == dwFileToRead) {
188 int success = WideCharToMultiByte(CP_ACP, 0, szFileName, -1,
189 narrowFileName, _MAX_PATH,
190 NULL, NULL);
191 if (success)
192 success = ReadSingleFile(narrowFileName);
193 if (!success)
194 dwFileToRead++; /* couldn't read this one, read the next one. */
195 }
196 dwNumFiles++;
197 return dwNumFiles > dwFileToRead;
198 }
199
200 static PRInt32
201 ReadFiles(const PRUnichar *szFileName)
202 {
203 char narrowFileName[_MAX_PATH];
204
205 if ((dwNumFiles % dwReadEvery) == 0) {
206 ++filesToRead;
207 }
208 if (filesToRead) {
209 DWORD prevFileBytes = totalFileBytes;
210 int iContinue = WideCharToMultiByte(CP_ACP, 0, szFileName, -1,
211 narrowFileName, _MAX_PATH,
212 NULL, NULL);
213 if (iContinue) {
214 RNG_FileForRNG(narrowFileName);
215 }
216 if (prevFileBytes < totalFileBytes) {
217 --filesToRead;
218 }
219 }
220 dwNumFiles++;
221 return (totalFileBytes >= maxFileBytes);
222 }
223
224 static void
225 ReadSystemFiles(void)
226 {
227 // first count the number of files
228 dwNumFiles = 0;
229 if (!EnumSystemFiles(CountFiles))
230 return;
231
232 RNG_RandomUpdate(&dwNumFiles, sizeof(dwNumFiles));
233
234 // now read the first 10 readable files, then 10 or 11 files
235 // spread throughout the system directory
236 filesToRead = 10;
237 if (dwNumFiles == 0)
238 return;
239
240 dwReadEvery = dwNumFiles / 10;
241 if (dwReadEvery == 0)
242 dwReadEvery = 1; // less than 10 files
243
244 dwNumFiles = 0;
245 totalFileBytes = 0;
246 EnumSystemFiles(ReadFiles);
247 }
248
249 void RNG_SystemInfoForRNG(void) 73 void RNG_SystemInfoForRNG(void)
250 { 74 {
251 DWORD dwVal; 75 DWORD dwVal;
252 char buffer[256]; 76 char buffer[256];
253 int nBytes; 77 int nBytes;
254 MEMORYSTATUS sMem; 78 MEMORYSTATUS sMem;
255 HANDLE hVal; 79 HANDLE hVal;
256 DWORD dwSerialNum; 80 DWORD dwSerialNum;
257 DWORD dwComponentLen; 81 DWORD dwComponentLen;
258 DWORD dwSysFlags; 82 DWORD dwSysFlags;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 RNG_RandomUpdate(buffer, strlen(buffer)); 125 RNG_RandomUpdate(buffer, strlen(buffer));
302 126
303 if (GetDiskFreeSpace(NULL, &dwSectors, &dwBytes, &dwFreeClusters, 127 if (GetDiskFreeSpace(NULL, &dwSectors, &dwBytes, &dwFreeClusters,
304 &dwNumClusters)) { 128 &dwNumClusters)) {
305 RNG_RandomUpdate(&dwSectors, sizeof(dwSectors)); 129 RNG_RandomUpdate(&dwSectors, sizeof(dwSectors));
306 RNG_RandomUpdate(&dwBytes, sizeof(dwBytes)); 130 RNG_RandomUpdate(&dwBytes, sizeof(dwBytes));
307 RNG_RandomUpdate(&dwFreeClusters, sizeof(dwFreeClusters)); 131 RNG_RandomUpdate(&dwFreeClusters, sizeof(dwFreeClusters));
308 RNG_RandomUpdate(&dwNumClusters, sizeof(dwNumClusters)); 132 RNG_RandomUpdate(&dwNumClusters, sizeof(dwNumClusters));
309 } 133 }
310 134
311 // Skip the potentially slow file scanning if the OS's PRNG worked.
312 if (!usedWindowsPRNG)
313 ReadSystemFiles();
314
315 nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes
316 RNG_RandomUpdate(buffer, nBytes);
317 }
318
319 static void rng_systemJitter(void)
320 {
321 dwNumFiles = 0;
322 EnumSystemFiles(ReadOneFile);
323 dwFileToRead++;
324 if (dwFileToRead >= dwNumFiles) {
325 dwFileToRead = 0;
326 }
327 }
328
329
330 void RNG_FileForRNG(const char *filename)
331 {
332 FILE* file;
333 int nBytes;
334 struct stat stat_buf;
335 unsigned char buffer[1024];
336
337 /* windows doesn't initialize all the bytes in the stat buf,
338 * so initialize them all here to avoid UMRs.
339 */
340 memset(&stat_buf, 0, sizeof stat_buf);
341
342 if (stat((char *)filename, &stat_buf) < 0)
343 return;
344
345 RNG_RandomUpdate((unsigned char*)&stat_buf, sizeof(stat_buf));
346
347 file = fopen((char *)filename, "r");
348 if (file != NULL) {
349 for (;;) {
350 size_t bytes = fread(buffer, 1, sizeof(buffer), file);
351
352 if (bytes == 0)
353 break;
354
355 RNG_RandomUpdate(buffer, bytes);
356 totalFileBytes += bytes;
357 if (totalFileBytes > maxFileBytes)
358 break;
359 }
360
361 fclose(file);
362 }
363
364 nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes 135 nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes
365 RNG_RandomUpdate(buffer, nBytes); 136 RNG_RandomUpdate(buffer, nBytes);
366 } 137 }
367 138
368 139
369 /* 140 /*
370 * Windows XP and Windows Server 2003 and later have RtlGenRandom, 141 * The RtlGenRandom function is declared in <ntsecapi.h>, but the
371 * which must be looked up by the name SystemFunction036. 142 * declaration is missing a calling convention specifier. So we
143 * declare it manually here.
372 */ 144 */
373 typedef BOOLEAN 145 #define RtlGenRandom SystemFunction036
374 (APIENTRY *RtlGenRandomFn)( 146 DECLSPEC_IMPORT BOOLEAN WINAPI RtlGenRandom(
375 PVOID RandomBuffer, 147 PVOID RandomBuffer,
376 ULONG RandomBufferLength); 148 ULONG RandomBufferLength);
377 149
378 size_t RNG_SystemRNG(void *dest, size_t maxLen) 150 size_t RNG_SystemRNG(void *dest, size_t maxLen)
379 { 151 {
380 HMODULE hModule;
381 RtlGenRandomFn pRtlGenRandom;
382 size_t bytes = 0; 152 size_t bytes = 0;
383 153
384 usedWindowsPRNG = PR_FALSE; 154 if (RtlGenRandom(dest, maxLen)) {
385 hModule = LoadLibrary("advapi32.dll"); 155 » bytes = maxLen;
386 if (hModule == NULL) {
387 » return bytes;
388 } 156 }
389 pRtlGenRandom = (RtlGenRandomFn)
390 GetProcAddress(hModule, "SystemFunction036");
391 if (pRtlGenRandom && pRtlGenRandom(dest, maxLen)) {
392 bytes = maxLen;
393 usedWindowsPRNG = PR_TRUE;
394 }
395 FreeLibrary(hModule);
396 return bytes; 157 return bytes;
397 } 158 }
398 #endif /* is XP_WIN */ 159 #endif /* is XP_WIN */
OLDNEW
« no previous file with comments | « nss/lib/freebl/sysrand.c ('k') | nss/lib/libpkix/include/pkix_pl_pki.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698