- MEMORYSTATUS m;
- HCRYPTPROV hProvider = 0;
- BYTE buf[64];
- DWORD w;
- HWND h;
-
- HMODULE advapi, kernel, user;
- CRYPTACQUIRECONTEXT acquire;
- CRYPTGENRANDOM gen;
- CRYPTRELEASECONTEXT release;
-
- /* load functions dynamically - not available on all systems */
- advapi = GetModuleHandle("ADVAPI32.DLL");
- kernel = GetModuleHandle("KERNEL32.DLL");
- user = GetModuleHandle("USER32.DLL");
-
- if (advapi)
- {
- acquire = (CRYPTACQUIRECONTEXT) GetProcAddress(advapi,
- "CryptAcquireContextA");
- gen = (CRYPTGENRANDOM) GetProcAddress(advapi,
- "CryptGenRandom");
- release = (CRYPTRELEASECONTEXT) GetProcAddress(advapi,
- "CryptReleaseContext");
- }
-
- if (acquire && gen && release)
- {
- /* poll the CryptoAPI PRNG */
- if (acquire(&hProvider, 0, 0, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT))
- {
- if (gen(hProvider, sizeof(buf), buf) != 0)
- {
- RAND_add(buf, sizeof(buf), 0);
-#ifdef DEBUG
- printf("randomness from PROV_RSA_FULL\n");
-#endif
- }
- release(hProvider, 0);
- }
-
- /* poll the Pentium PRG with CryptoAPI */
- if (acquire(&hProvider, 0, INTEL_DEF_PROV, PROV_INTEL_SEC, 0))
- {
- if (gen(hProvider, sizeof(buf), buf) != 0)
- {
- RAND_add(buf, sizeof(buf), 0);
-#ifdef DEBUG
- printf("randomness from PROV_INTEL_SEC\n");
-#endif
- }
- release(hProvider, 0);
- }
- }
-
- /* timer data */
- readtimer();
-
- /* memory usage statistics */
- GlobalMemoryStatus(&m);
- RAND_add(&m, sizeof(m), 1);
-
- /* process ID */
- w = GetCurrentProcessId();
- RAND_add(&w, sizeof(w), 0);
-
- if (user)
- {
- GETCURSORINFO cursor;
- GETFOREGROUNDWINDOW win;
- GETQUEUESTATUS queue;
-
- win = (GETFOREGROUNDWINDOW) GetProcAddress(user, "GetForegroundWindow");
- cursor = (GETCURSORINFO) GetProcAddress(user, "GetCursorInfo");
- queue = (GETQUEUESTATUS) GetProcAddress(user, "GetQueueStatus");
-
- if (win)
- {
- /* window handle */
- h = win();
- RAND_add(&h, sizeof(h), 0);
- }
-
- if (cursor)
- {
- /* cursor position */
- cursor((PCURSORINFO)buf);
- RAND_add(buf, sizeof(buf), 0);
- }
-
- if (queue)
- {
- /* message queue status */
- w = queue(QS_ALLEVENTS);
- RAND_add(&w, sizeof(w), 0);
- }
- }
-
- /* Toolhelp32 snapshot: enumerate processes, threads, modules and heap
- * http://msdn.microsoft.com/library/psdk/winbase/toolhelp_5pfd.htm
- * (Win 9x only, not available on NT)
- *
- * This seeding method was proposed in Peter Gutmann, Software
- * Generation of Practically Strong Random Numbers,
- * http://www.cs.auckland.ac.nz/~pgut001/pubs/random2.pdf
- * (The assignment of entropy estimates below is arbitrary, but based
- * on Peter's analysis the full poll appears to be safe. Additional
- * interactive seeding is encouraged.)
- */
-
- if (kernel)
- {
- CREATETOOLHELP32SNAPSHOT snap;
- HANDLE handle;
-
- HEAP32FIRST heap_first;
- HEAP32NEXT heap_next;
- HEAP32LIST heaplist_first, heaplist_next;
- PROCESS32 process_first, process_next;
- THREAD32 thread_first, thread_next;
- MODULE32 module_first, module_next;
-
- HEAPLIST32 hlist;
- HEAPENTRY32 hentry;
- PROCESSENTRY32 p;
- THREADENTRY32 t;
- MODULEENTRY32 m;
-
- snap = (CREATETOOLHELP32SNAPSHOT)
- GetProcAddress(kernel, "CreateToolhelp32Snapshot");
- heap_first = (HEAP32FIRST) GetProcAddress(kernel, "Heap32First");
- heap_next = (HEAP32NEXT) GetProcAddress(kernel, "Heap32Next");
- heaplist_first = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListFirst");
- heaplist_next = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListNext");
- process_first = (PROCESS32) GetProcAddress(kernel, "Process32First");
- process_next = (PROCESS32) GetProcAddress(kernel, "Process32Next");
- thread_first = (THREAD32) GetProcAddress(kernel, "Thread32First");
- thread_next = (THREAD32) GetProcAddress(kernel, "Thread32Next");
- module_first = (MODULE32) GetProcAddress(kernel, "Module32First");
- module_next = (MODULE32) GetProcAddress(kernel, "Module32Next");
-
- if (snap && heap_first && heap_next && heaplist_first &&
- heaplist_next && process_first && process_next &&
- thread_first && thread_next && module_first &&
- module_next && (handle = snap(TH32CS_SNAPALL,0))
- != NULL)
- {
- /* heap list and heap walking */
- hlist.dwSize = sizeof(HEAPLIST32);
- if (heaplist_first(handle, &hlist))
- do
- {
- RAND_add(&hlist, hlist.dwSize, 0);
- hentry.dwSize = sizeof(HEAPENTRY32);
- if (heap_first(&hentry,
- hlist.th32ProcessID,
- hlist.th32HeapID))
- do
- RAND_add(&hentry,
- hentry.dwSize, 0);
- while (heap_next(&hentry));
- } while (heaplist_next(handle,
- &hlist));
-
- /* process walking */
- p.dwSize = sizeof(PROCESSENTRY32);
- if (process_first(handle, &p))
- do
- RAND_add(&p, p.dwSize, 0);
- while (process_next(handle, &p));
-
- /* thread walking */
- t.dwSize = sizeof(THREADENTRY32);
- if (thread_first(handle, &t))
- do
- RAND_add(&t, t.dwSize, 0);
- while (thread_next(handle, &t));
-
- /* module walking */
- m.dwSize = sizeof(MODULEENTRY32);
- if (module_first(handle, &m))
- do
- RAND_add(&m, m.dwSize, 1);
- while (module_next(handle, &m));
-
- CloseHandle(handle);
- }
- }
-
-#ifdef DEBUG
- printf("Exiting RAND_poll\n");
-#endif
-
- return(1);
+ MEMORYSTATUS mst;
+# ifndef RAND_WINDOWS_USE_BCRYPT
+ HCRYPTPROV hProvider;
+# endif
+ DWORD w;
+ BYTE buf[64];
+
+# ifdef RAND_WINDOWS_USE_BCRYPT
+ if (BCryptGenRandom(NULL, buf, (ULONG)sizeof(buf), BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS) {
+ RAND_add(buf, sizeof(buf), sizeof(buf));
+ }
+# else
+ /* poll the CryptoAPI PRNG */
+ /* The CryptoAPI returns sizeof(buf) bytes of randomness */
+ if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
+ if (CryptGenRandom(hProvider, (DWORD)sizeof(buf), buf) != 0) {
+ RAND_add(buf, sizeof(buf), sizeof(buf));
+ }
+ CryptReleaseContext(hProvider, 0);
+ }
+
+ /* poll the Pentium PRG with CryptoAPI */
+ if (CryptAcquireContextW(&hProvider, NULL, INTEL_DEF_PROV, PROV_INTEL_SEC, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
+ if (CryptGenRandom(hProvider, (DWORD)sizeof(buf), buf) != 0) {
+ RAND_add(buf, sizeof(buf), sizeof(buf));
+ }
+ CryptReleaseContext(hProvider, 0);
+ }
+# endif
+
+ /* timer data */
+ readtimer();
+
+ /* memory usage statistics */
+ GlobalMemoryStatus(&mst);
+ RAND_add(&mst, sizeof(mst), 1);
+
+ /* process ID */
+ w = GetCurrentProcessId();
+ RAND_add(&w, sizeof(w), 1);
+
+ return (1);