OLD | NEW |
---|---|
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" | 6 #include "secerr.h" |
7 | 7 |
8 #ifdef XP_WIN | 8 #ifdef XP_WIN |
9 #include <windows.h> | 9 #include <windows.h> |
10 #include <shlobj.h> /* for CSIDL constants */ | 10 #include <shlobj.h> /* for CSIDL constants */ |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
360 | 360 |
361 fclose(file); | 361 fclose(file); |
362 } | 362 } |
363 | 363 |
364 nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes | 364 nBytes = RNG_GetNoise(buffer, 20); // get up to 20 bytes |
365 RNG_RandomUpdate(buffer, nBytes); | 365 RNG_RandomUpdate(buffer, nBytes); |
366 } | 366 } |
367 | 367 |
368 | 368 |
369 /* | 369 /* |
370 * CryptoAPI requires Windows NT 4.0 or Windows 95 OSR2 and later. | |
371 * Until we drop support for Windows 95, we need to emulate some | |
372 * definitions and declarations in <wincrypt.h> and look up the | |
373 * functions in advapi32.dll at run time. | |
374 */ | |
375 | |
376 #ifndef WIN64 | |
377 typedef unsigned long HCRYPTPROV; | |
378 #endif | |
379 | |
380 #define CRYPT_VERIFYCONTEXT 0xF0000000 | |
381 | |
382 #define PROV_RSA_FULL 1 | |
383 | |
384 typedef BOOL | |
385 (WINAPI *CryptAcquireContextAFn)( | |
386 HCRYPTPROV *phProv, | |
387 LPCSTR pszContainer, | |
388 LPCSTR pszProvider, | |
389 DWORD dwProvType, | |
390 DWORD dwFlags); | |
391 | |
392 typedef BOOL | |
393 (WINAPI *CryptReleaseContextFn)( | |
394 HCRYPTPROV hProv, | |
395 DWORD dwFlags); | |
396 | |
397 typedef BOOL | |
398 (WINAPI *CryptGenRandomFn)( | |
399 HCRYPTPROV hProv, | |
400 DWORD dwLen, | |
401 BYTE *pbBuffer); | |
402 | |
403 /* | |
404 * Windows XP and Windows Server 2003 and later have RtlGenRandom, | 370 * Windows XP and Windows Server 2003 and later have RtlGenRandom, |
405 * which must be looked up by the name SystemFunction036. | 371 * which must be looked up by the name SystemFunction036. |
406 */ | 372 */ |
407 typedef BOOLEAN | 373 typedef BOOLEAN |
408 (APIENTRY *RtlGenRandomFn)( | 374 (APIENTRY *RtlGenRandomFn)( |
409 PVOID RandomBuffer, | 375 PVOID RandomBuffer, |
410 ULONG RandomBufferLength); | 376 ULONG RandomBufferLength); |
411 | 377 |
412 size_t RNG_SystemRNG(void *dest, size_t maxLen) | 378 size_t RNG_SystemRNG(void *dest, size_t maxLen) |
413 { | 379 { |
414 HMODULE hModule; | 380 HMODULE hModule; |
415 RtlGenRandomFn pRtlGenRandom; | 381 RtlGenRandomFn pRtlGenRandom; |
416 CryptAcquireContextAFn pCryptAcquireContextA; | |
417 CryptReleaseContextFn pCryptReleaseContext; | |
418 CryptGenRandomFn pCryptGenRandom; | |
419 HCRYPTPROV hCryptProv; | |
420 size_t bytes = 0; | 382 size_t bytes = 0; |
421 | 383 |
422 usedWindowsPRNG = PR_FALSE; | 384 usedWindowsPRNG = PR_FALSE; |
423 hModule = LoadLibrary("advapi32.dll"); | 385 hModule = LoadLibrary("advapi32.dll"); |
424 if (hModule == NULL) { | 386 if (hModule == NULL) { |
425 » return rng_systemFromNoise(dest,maxLen); | 387 » return bytes; |
wtc
2013/06/17 23:04:17
Note that I am not calling abort() in this functio
| |
426 } | 388 } |
427 pRtlGenRandom = (RtlGenRandomFn) | 389 pRtlGenRandom = (RtlGenRandomFn) |
428 GetProcAddress(hModule, "SystemFunction036"); | 390 GetProcAddress(hModule, "SystemFunction036"); |
429 if (pRtlGenRandom) { | 391 if (pRtlGenRandom && pRtlGenRandom(dest, maxLen)) { |
430 » if (pRtlGenRandom(dest, maxLen)) { | 392 » bytes = maxLen; |
431 » bytes = maxLen; | 393 » usedWindowsPRNG = PR_TRUE; |
432 » usedWindowsPRNG = PR_TRUE; | |
433 » } else { | |
434 » bytes = rng_systemFromNoise(dest,maxLen); | |
435 » } | |
436 » goto done; | |
437 } | 394 } |
438 pCryptAcquireContextA = (CryptAcquireContextAFn) | |
439 GetProcAddress(hModule, "CryptAcquireContextA"); | |
440 pCryptReleaseContext = (CryptReleaseContextFn) | |
441 GetProcAddress(hModule, "CryptReleaseContext"); | |
442 pCryptGenRandom = (CryptGenRandomFn) | |
443 GetProcAddress(hModule, "CryptGenRandom"); | |
444 if (!pCryptAcquireContextA || !pCryptReleaseContext || !pCryptGenRandom) { | |
445 bytes = rng_systemFromNoise(dest,maxLen); | |
446 goto done; | |
447 } | |
448 if (pCryptAcquireContextA(&hCryptProv, NULL, NULL, | |
449 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { | |
450 if (pCryptGenRandom(hCryptProv, maxLen, dest)) { | |
451 bytes = maxLen; | |
452 usedWindowsPRNG = PR_TRUE; | |
453 } | |
454 pCryptReleaseContext(hCryptProv, 0); | |
455 } | |
456 if (bytes == 0) { | |
457 bytes = rng_systemFromNoise(dest,maxLen); | |
458 } | |
459 done: | |
460 FreeLibrary(hModule); | 395 FreeLibrary(hModule); |
461 return bytes; | 396 return bytes; |
462 } | 397 } |
463 #endif /* is XP_WIN */ | 398 #endif /* is XP_WIN */ |
OLD | NEW |