- FreeLibrary(advapi);
-
- if ((osverinfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
- !OPENSSL_isservice()) &&
- (user = LoadLibrary(TEXT("USER32.DLL"))))
- {
- 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 */
- HWND h = win();
- RAND_add(&h, sizeof(h), 0);
- }
- if (cursor)
- {
- /* unfortunately, its not safe to call GetCursorInfo()
- * on NT4 even though it exists in SP3 (or SP6) and
- * higher.
- */
- if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
- osverinfo.dwMajorVersion < 5)
- cursor = 0;
- }
- if (cursor)
- {
- /* cursor position */
- /* assume 2 bytes of entropy */
- CURSORINFO ci;
- ci.cbSize = sizeof(CURSORINFO);
- if (cursor(&ci))
- RAND_add(&ci, ci.cbSize, 2);
- }
-
- if (queue)
- {
- /* message queue status */
- /* assume 1 byte of entropy */
- w = queue(QS_ALLEVENTS);
- RAND_add(&w, sizeof(w), 1);
- }
-
- FreeLibrary(user);
- }
-
- /* Toolhelp32 snapshot: enumerate processes, threads, modules and heap
- * http://msdn.microsoft.com/library/psdk/winbase/toolhelp_5pfd.htm
- * (Win 9x and 2000 only, not available on NT)
- *
- * This seeding method was proposed in Peter Gutmann, Software
- * Generation of Practically Strong Random Numbers,
- * http://www.usenix.org/publications/library/proceedings/sec98/gutmann.html
- * revised version at http://www.cryptoengines.com/~peter/06_random.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;
- CLOSETOOLHELP32SNAPSHOT close_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;
- DWORD stoptime = 0;
-
- snap = (CREATETOOLHELP32SNAPSHOT)
- GetProcAddress(kernel, "CreateToolhelp32Snapshot");
- close_snap = (CLOSETOOLHELP32SNAPSHOT)
- GetProcAddress(kernel, "CloseToolhelp32Snapshot");
- 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))
- != INVALID_HANDLE_VALUE)
- {
- /* heap list and heap walking */
- /* HEAPLIST32 contains 3 fields that will change with
- * each entry. Consider each field a source of 1 byte
- * of entropy.
- * HEAPENTRY32 contains 5 fields that will change with
- * each entry. Consider each field a source of 1 byte
- * of entropy.
- */
- hlist.dwSize = sizeof(HEAPLIST32);
- if (good) stoptime = GetTickCount() + MAXDELAY;
- if (heaplist_first(handle, &hlist))
- do
- {
- RAND_add(&hlist, hlist.dwSize, 3);
- hentry.dwSize = sizeof(HEAPENTRY32);
- if (heap_first(&hentry,
- hlist.th32ProcessID,
- hlist.th32HeapID))
- {
- int entrycnt = 80;
- do
- RAND_add(&hentry,
- hentry.dwSize, 5);
- while (heap_next(&hentry)
- && --entrycnt > 0);
- }
- } while (heaplist_next(handle,
- &hlist) && GetTickCount() < stoptime);
-
- /* process walking */
- /* PROCESSENTRY32 contains 9 fields that will change
- * with each entry. Consider each field a source of
- * 1 byte of entropy.
- */
- p.dwSize = sizeof(PROCESSENTRY32);
-
- if (good) stoptime = GetTickCount() + MAXDELAY;
- if (process_first(handle, &p))
- do
- RAND_add(&p, p.dwSize, 9);
- while (process_next(handle, &p) && GetTickCount() < stoptime);
-
- /* thread walking */
- /* THREADENTRY32 contains 6 fields that will change
- * with each entry. Consider each field a source of
- * 1 byte of entropy.
- */
- t.dwSize = sizeof(THREADENTRY32);
- if (good) stoptime = GetTickCount() + MAXDELAY;
- if (thread_first(handle, &t))
- do
- RAND_add(&t, t.dwSize, 6);
- while (thread_next(handle, &t) && GetTickCount() < stoptime);
-
- /* module walking */
- /* MODULEENTRY32 contains 9 fields that will change
- * with each entry. Consider each field a source of
- * 1 byte of entropy.
- */
- m.dwSize = sizeof(MODULEENTRY32);
- if (good) stoptime = GetTickCount() + MAXDELAY;
- if (module_first(handle, &m))
- do
- RAND_add(&m, m.dwSize, 9);
- while (module_next(handle, &m)
- && (GetTickCount() < stoptime));
- if (close_snap)
- close_snap(handle);
- else
- CloseHandle(handle);
-
- }
-
- FreeLibrary(kernel);
- }
- }
-#endif /* !OPENSSL_SYS_WINCE */
-
- /* timer data */
- readtimer();
-
- /* memory usage statistics */
- GlobalMemoryStatus(&m);
- RAND_add(&m, sizeof(m), 1);
-
- /* process ID */
- w = GetCurrentProcessId();
- RAND_add(&w, sizeof(w), 1);
-
-#if 0
- printf("Exiting RAND_poll\n");
-#endif
-
- return(1);
-}
-
-int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam)
- {
- double add_entropy=0;
-
- switch (iMsg)
- {
- case WM_KEYDOWN:
- {
- static WPARAM key;
- if (key != wParam)
- add_entropy = 0.05;
- key = wParam;
+ FreeLibrary(advapi);
+
+ if ((!check_winnt() ||
+ !OPENSSL_isservice()) &&
+ (user = LoadLibrary(TEXT("USER32.DLL")))) {
+ 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 */
+ HWND h = win();
+ RAND_add(&h, sizeof(h), 0);
+ }
+ if (cursor) {
+ /*
+ * unfortunately, its not safe to call GetCursorInfo() on NT4
+ * even though it exists in SP3 (or SP6) and higher.
+ */
+ if (check_winnt() && !check_win_minplat(5))
+ cursor = 0;
+ }
+ if (cursor) {
+ /* cursor position */
+ /* assume 2 bytes of entropy */
+ CURSORINFO ci;
+ ci.cbSize = sizeof(CURSORINFO);
+ if (cursor(&ci))
+ RAND_add(&ci, ci.cbSize, 2);
+ }
+
+ if (queue) {
+ /* message queue status */
+ /* assume 1 byte of entropy */
+ w = queue(QS_ALLEVENTS);
+ RAND_add(&w, sizeof(w), 1);
+ }
+
+ FreeLibrary(user);
+ }
+
+ /*-
+ * Toolhelp32 snapshot: enumerate processes, threads, modules and heap
+ * http://msdn.microsoft.com/library/psdk/winbase/toolhelp_5pfd.htm
+ * (Win 9x and 2000 only, not available on NT)
+ *
+ * This seeding method was proposed in Peter Gutmann, Software
+ * Generation of Practically Strong Random Numbers,
+ * http://www.usenix.org/publications/library/proceedings/sec98/gutmann.html
+ * revised version at http://www.cryptoengines.com/~peter/06_random.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;
+ CLOSETOOLHELP32SNAPSHOT close_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;
+ DWORD starttime = 0;
+
+ snap = (CREATETOOLHELP32SNAPSHOT)
+ GetProcAddress(kernel, "CreateToolhelp32Snapshot");
+ close_snap = (CLOSETOOLHELP32SNAPSHOT)
+ GetProcAddress(kernel, "CloseToolhelp32Snapshot");
+ 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))
+ != INVALID_HANDLE_VALUE) {
+ /* heap list and heap walking */
+ /*
+ * HEAPLIST32 contains 3 fields that will change with each
+ * entry. Consider each field a source of 1 byte of entropy.
+ * HEAPENTRY32 contains 5 fields that will change with each
+ * entry. Consider each field a source of 1 byte of entropy.
+ */
+ ZeroMemory(&hlist, sizeof(HEAPLIST32));
+ hlist.dwSize = sizeof(HEAPLIST32);
+ if (good)
+ starttime = GetTickCount();
+# ifdef _MSC_VER
+ if (heaplist_first(handle, &hlist)) {
+ /*
+ * following discussion on dev ML, exception on WinCE (or
+ * other Win platform) is theoretically of unknown
+ * origin; prevent infinite loop here when this
+ * theoretical case occurs; otherwise cope with the
+ * expected (MSDN documented) exception-throwing
+ * behaviour of Heap32Next() on WinCE.
+ *
+ * based on patch in original message by Tanguy Fautré
+ * (2009/03/02) Subject: RAND_poll() and
+ * CreateToolhelp32Snapshot() stability
+ */
+ int ex_cnt_limit = 42;
+ do {
+ RAND_add(&hlist, hlist.dwSize, 3);
+ __try {
+ ZeroMemory(&hentry, sizeof(HEAPENTRY32));
+ hentry.dwSize = sizeof(HEAPENTRY32);
+ if (heap_first(&hentry,
+ hlist.th32ProcessID,
+ hlist.th32HeapID)) {
+ int entrycnt = 80;
+ do
+ RAND_add(&hentry, hentry.dwSize, 5);
+ while (heap_next(&hentry)
+ && (!good
+ || (GetTickCount() - starttime) <
+ MAXDELAY)
+ && --entrycnt > 0);
+ }