- remove insane heap walk and kernel loading code; clean up style and calling conventions
authorJoey Yandle <dragon@dancingdragon.be>
Sat, 12 Dec 2015 01:53:03 +0000 (17:53 -0800)
committerRich Salz <rsalz@openssl.org>
Sun, 29 May 2016 17:36:59 +0000 (13:36 -0400)
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/1079)

crypto/rand/rand_win.c

index cb0c1edf093756dc42979ae64a42b0e4234180a5..87869985d9f231e85cedf8386dbc0fb5dcc55b5b 100644 (file)
@@ -97,360 +97,24 @@ int RAND_poll(void)
     MEMORYSTATUS mst;
     HCRYPTPROV hProvider = 0;
     DWORD w;
-    int good = 0;
-
-# if defined(OPENSSL_SYS_WINCE)
-#  if defined(_WIN32_WCE) && _WIN32_WCE>=300
-    /*
-     * Even though MSDN says _WIN32_WCE>=210, it doesn't seem to be available
-     * in commonly available implementations prior 300...
-     */
-    {
-        BYTE buf[64];
-        /* poll the CryptoAPI PRNG */
-        /* The CryptoAPI returns sizeof(buf) bytes of randomness */
-        if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL,
-                                 CRYPT_VERIFYCONTEXT)) {
-            if (CryptGenRandom(hProvider, sizeof(buf), buf))
-                RAND_add(buf, sizeof(buf), sizeof(buf));
-            CryptReleaseContext(hProvider, 0);
-        }
-    }
-#  endif
-# else                          /* OPENSSL_SYS_WINCE */
-    /*
-     * None of below libraries are present on Windows CE, which is
-     * why we #ifndef the whole section. This also excuses us from
-     * handling the GetProcAddress issue. The trouble is that in
-     * real Win32 API GetProcAddress is available in ANSI flavor
-     * only. In WinCE on the other hand GetProcAddress is a macro
-     * most commonly defined as GetProcAddressW, which accepts
-     * Unicode argument. If we were to call GetProcAddress under
-     * WinCE, I'd recommend to either redefine GetProcAddress as
-     * GetProcAddressA (there seem to be one in common CE spec) or
-     * implement own shim routine, which would accept ANSI argument
-     * and expand it to Unicode.
-     */
-    {
-        /* load functions dynamically - not available on all systems */
-        HMODULE advapi = LoadLibrary(TEXT("ADVAPI32.DLL"));
-        HMODULE kernel = LoadLibrary(TEXT("KERNEL32.DLL"));
-        HMODULE user = NULL;
-        HMODULE netapi = LoadLibrary(TEXT("NETAPI32.DLL"));
-        CRYPTACQUIRECONTEXTW acquire = NULL;
-        CRYPTGENRANDOM gen = NULL;
-        CRYPTRELEASECONTEXT release = NULL;
-        NETSTATGET netstatget = NULL;
-        NETFREE netfree = NULL;
-        BYTE buf[64];
-
-        if (netapi) {
-            netstatget =
-                (NETSTATGET) GetProcAddress(netapi, "NetStatisticsGet");
-            netfree = (NETFREE) GetProcAddress(netapi, "NetApiBufferFree");
-        }
+    BYTE buf[64];
 
-        if (netstatget && netfree) {
-            LPBYTE outbuf;
-            /*
-             * NetStatisticsGet() is a Unicode only function
-             * STAT_WORKSTATION_0 contains 45 fields and STAT_SERVER_0
-             * contains 17 fields.  We treat each field as a source of one
-             * byte of entropy.
-             */
-
-            if (netstatget(NULL, L"LanmanWorkstation", 0, 0, &outbuf) == 0) {
-                RAND_add(outbuf, sizeof(STAT_WORKSTATION_0), 45);
-                netfree(outbuf);
-            }
-            if (netstatget(NULL, L"LanmanServer", 0, 0, &outbuf) == 0) {
-                RAND_add(outbuf, sizeof(STAT_SERVER_0), 17);
-                netfree(outbuf);
-            }
-        }
-
-        if (netapi)
-            FreeLibrary(netapi);
-
-        /*
-         * It appears like this can cause an exception deep within
-         * ADVAPI32.DLL at random times on Windows 2000.  Reported by Jeffrey
-         * Altman. Only use it on NT.
-         */
-
-        if (advapi) {
-            /*
-             * If it's available, then it's available in both ANSI
-             * and UNICODE flavors even in Win9x, documentation says.
-             * We favor Unicode...
-             */
-            acquire = (CRYPTACQUIRECONTEXTW) GetProcAddress(advapi,
-                                                            "CryptAcquireContextW");
-            gen = (CRYPTGENRANDOM) GetProcAddress(advapi, "CryptGenRandom");
-            release = (CRYPTRELEASECONTEXT) GetProcAddress(advapi,
-                                                           "CryptReleaseContext");
-        }
-
-        if (acquire && gen && release) {
-            /* poll the CryptoAPI PRNG */
-            /* The CryptoAPI returns sizeof(buf) bytes of randomness */
-            if (acquire(&hProvider, NULL, NULL, PROV_RSA_FULL,
-                        CRYPT_VERIFYCONTEXT)) {
-                if (gen(hProvider, sizeof(buf), buf) != 0) {
-                    RAND_add(buf, sizeof(buf), 0);
-                    good = 1;
-                }
-                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), sizeof(buf));
-                    good = 1;
-                }
-                release(hProvider, 0);
-            }
-        }
-
-        if (advapi)
-            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);
+    /* poll the CryptoAPI PRNG */
+    /* The CryptoAPI returns sizeof(buf) bytes of randomness */
+    if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+        if (CryptGenRandom(hProvider, sizeof(buf), buf) != 0) {
+            RAND_add(buf, sizeof(buf), sizeof(buf));
         }
+        CryptReleaseContext(hProvider, 0);
+    }
 
-        /*-
-         * 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);
-                            }
-                        }
-                        __except(EXCEPTION_EXECUTE_HANDLER) {
-                            /*
-                             * ignore access violations when walking the heap
-                             * list
-                             */
-                            ex_cnt_limit--;
-                        }
-                    } while (heaplist_next(handle, &hlist)
-                             && (!good
-                                 || (GetTickCount() - starttime) < MAXDELAY)
-                             && ex_cnt_limit > 0);
-                }
-#  else
-                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)
-                             && (!good
-                                 || (GetTickCount() - starttime) < MAXDELAY));
-                }
-#  endif
-
-                /* 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)
-                    starttime = GetTickCount();
-                if (process_first(handle, &p))
-                    do
-                        RAND_add(&p, p.dwSize, 9);
-                    while (process_next(handle, &p)
-                           && (!good
-                               || (GetTickCount() - starttime) < MAXDELAY));
-
-                /* 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)
-                    starttime = GetTickCount();
-                if (thread_first(handle, &t))
-                    do
-                        RAND_add(&t, t.dwSize, 6);
-                    while (thread_next(handle, &t)
-                           && (!good
-                               || (GetTickCount() - starttime) < MAXDELAY));
-
-                /* 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)
-                    starttime = GetTickCount();
-                if (module_first(handle, &m))
-                    do
-                        RAND_add(&m, m.dwSize, 9);
-                    while (module_next(handle, &m)
-                           && (!good
-                               || (GetTickCount() - starttime) < MAXDELAY));
-                if (close_snap)
-                    close_snap(handle);
-                else
-                    CloseHandle(handle);
-
-            }
-
-            FreeLibrary(kernel);
+    /* poll the Pentium PRG with CryptoAPI */
+    if (CryptAcquireContextW(&hProvider, NULL, INTEL_DEF_PROV, PROV_INTEL_SEC, CRYPT_VERIFYCONTEXT)) {
+        if (CryptGenRandom(hProvider, sizeof(buf), buf) != 0) {
+            RAND_add(buf, sizeof(buf), sizeof(buf));
         }
+        CryptReleaseContext(hProvider, 0);
     }
-# endif                         /* !OPENSSL_SYS_WINCE */
 
     /* timer data */
     readtimer();