Jeffrey Altman wrote:
> 
> This patch should solve all of the entropy failures on NT4 as reported
> to openssl-users.  The patch:
> 
>  . corrects prototypes for NET API functions to work with VC6 headers
> 
>  . ensures that Registry Performance Data will not be queried on W2K
> 
>  . provides a conservative non-zero value for the number of bytes of
>    entropy that may be provided by each block of data fed to
>    RAND_add() based upon an examination of the data structures.
> 
> zhu qun-ying, would you please apply this patch and confirm to
> [EMAIL PROTECTED] that it compiles on VC6 and mwing32 and that
> it solves the problem on your NT4 SP6 system.  If you can confirm this
> before Richard needs to start building Beta 3 it would be appreciated.
> 
> - Jeff

call me qun-ying is fine (FYI, my family name is zhu). it is my pleasure to help
the development of openssl.

Ya. It works. SNAP-20000919 test cases passed for mingw32/VC6 under NT-SP6.
cygwin built is fine also.

But your patch can not be applied cleanly for there are some "ambiguous" entries
that "patch" program cannot decide. :) have to manually apply some of the
rejected lines.

Here attached is a patch generated by diff with the "-u" switch, should be
easier to apply.

The patch is against the version in SNAP-20000919.

-- 
(~._.~)  Öì Ⱥ Ó¢  (Qun-Ying)          (65) 874-6743
 ( O )   TrustCopy Pte Ltd / Kent Ridge Digital Labs
()~*~()  21 Heng Mui Keng Terrace,  Singapore 119613
(_)-(_)    [EMAIL PROTECTED]  *  [EMAIL PROTECTED]
--- org/rand_win.c      Mon Sep 18 20:00:30 2000
+++ rand/rand_win.c     Thu Sep 21 09:20:28 2000
@@ -171,13 +171,19 @@
 
 #include <lmcons.h>
 #include <lmstats.h>
-#if 0 /* Some compilers use LMSTR, others (VC6, for example) use LPTSTR.
+#if 1 /* Some compilers use LMSTR, others (VC6, for example) use LPTSTR.
        * This part is disabled until a fix is found.
+       *
+       * The NET API is Unicode only.  It requires the use of the UNICODE
+       * macro.  When UNICODE is defined LPTSTR becomes LPWSTR.  LMSTR was
+       * was added to the Platform SDK to allow the NET API to be used in
+       * non-Unicode applications provided that Unicode strings were still
+       * used for input.  LMSTR is defined as LPWSTR.
        */
 typedef NET_API_STATUS (NET_API_FUNCTION * NETSTATGET)
-        (LMSTR, LMSTR, DWORD, DWORD, LPBYTE*);
+        (LPWSTR, LPWSTR, DWORD, DWORD, LPBYTE*);
 typedef NET_API_STATUS (NET_API_FUNCTION * NETFREE)(LPBYTE);
-#endif /* 0 */
+#endif /* 1 */
 
 int RAND_poll(void)
 {
@@ -191,13 +197,20 @@
        CRYPTACQUIRECONTEXT acquire = 0;
        CRYPTGENRANDOM gen = 0;
        CRYPTRELEASECONTEXT release = 0;
-#if 0 /* This part is disabled until a fix for the problem with the
+#if 1 /* This part is disabled until a fix for the problem with the
        * definition of NETSTATGET is found.
        */
        NETSTATGET netstatget = 0;
        NETFREE netfree = 0;
-#endif /* 0 */
+#endif /* 1 */
 
+      /* Determine the OS version we are on so we can turn off things 
+       * that do not work properly.
+       */
+        OSVERSIONINFO osverinfo ;
+        osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO) ;
+        GetVersionEx( &osverinfo ) ;
+
        /* load functions dynamically - not available on all systems */
        advapi = LoadLibrary("ADVAPI32.DLL");
        kernel = LoadLibrary("KERNEL32.DLL");
@@ -204,9 +217,12 @@
        user = LoadLibrary("USER32.DLL");
        netapi = LoadLibrary("NETAPI32.DLL");
 
-#if 0 /* This part is disabled until a fix for the problem with the
+#if 1 /* This part is disabled until a fix for the problem with the
        * definition of NETSTATGET is found.  Also, note that VC6 doesn't
        * understand strings starting with L".
+       * 
+       * VC6 does recognize strings beginning with L".  The definition of
+       * TEXT() when UNICODE is defined is L##"x" which evaluates to L"x".
        */
        if (netapi)
                {
@@ -217,15 +233,20 @@
        if (netstatget && netfree)
                {
                LPBYTE outbuf;
-               /* NetStatisticsGet() is a Unicode only function */
+               /* 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), 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), 0);
+                       RAND_add(outbuf, sizeof(STAT_SERVER_0), 17);
                        netfree(outbuf);
                        }
                }
@@ -232,17 +253,20 @@
 
        if (netapi)
                FreeLibrary(netapi);
-#endif /* 0 */
+#endif /* 1 */
  
-#if 0 /* It appears like this can cause an exception deep within ADVAPI32.DLL
-       * at random times.  Reported by Jeffrey Altman.
+        /* 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 ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
+             osverinfo.dwMajorVersion < 5)
+      {
        /* Read Performance Statistics from NT/2000 registry */
        /* The size of the performance data can vary from call to call */
        /* so we must guess the size of the buffer to use and increase */
        /* its size if we get an ERROR_MORE_DATA return instead of     */
        /* ERROR_SUCCESS.                                              */
-       {
        LONG   rc=ERROR_MORE_DATA;
        char * buf=NULL;
        DWORD bufsz=0;
@@ -261,13 +285,15 @@
                }
        if (rc == ERROR_SUCCESS)
                {
+                        /* For entropy count assume only least significant byte 
+                         * of each DWORD is random.
+                         */
                RAND_add(&length, sizeof(length), 0);
-               RAND_add(buf, length, 0);
+               RAND_add(buf, length, length / 4.0);
                }
        if (buf)
                free(buf);
        }
-#endif /* 0 */
 
        if (advapi)
                {
@@ -282,12 +308,13 @@
        if (acquire && gen && release)
                {
                /* poll the CryptoAPI PRNG */
+                /* The CryptoAPI returns sizeof(buf) bytes of randomness */
                if (acquire(&hProvider, 0, 0, PROV_RSA_FULL,
                        CRYPT_VERIFYCONTEXT))
                        {
                        if (gen(hProvider, sizeof(buf), buf) != 0)
                                {
-                               RAND_add(buf, sizeof(buf), 0);
+                               RAND_add(buf, sizeof(buf), sizeof(buf));
 #ifdef DEBUG
                                printf("randomness from PROV_RSA_FULL\n");
 #endif
@@ -300,7 +327,7 @@
                        {
                        if (gen(hProvider, sizeof(buf), buf) != 0)
                                {
-                               RAND_add(buf, sizeof(buf), 0);
+                               RAND_add(buf, sizeof(buf), sizeof(buf));
 #ifdef DEBUG
                                printf("randomness from PROV_INTEL_SEC\n");
 #endif
@@ -321,7 +348,7 @@
 
        /* process ID */
        w = GetCurrentProcessId();
-       RAND_add(&w, sizeof(w), 0);
+       RAND_add(&w, sizeof(w), 1);
 
        if (user)
                {
@@ -339,7 +366,6 @@
                        h = win();
                        RAND_add(&h, sizeof(h), 0);
                }
-
                if (cursor)
                        {
                        /* unfortunately, its not safe to call GetCursorInfo()
@@ -346,29 +372,26 @@
                         * on NT4 even though it exists in SP3 (or SP6) and
                         * higher.
                         */
-                       OSVERSIONINFO osverinfo ;
-                       osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO) ;
-                       GetVersionEx( &osverinfo ) ;
-
                        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, 0);
+                               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), 0);
+                       RAND_add(&w, sizeof(w), 1);
                        }
 
                FreeLibrary(user);
@@ -425,11 +448,18 @@
                        != NULL)
                        {
                        /* 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 (heaplist_first(handle, &hlist))
                                do
                                        {
-                                       RAND_add(&hlist, hlist.dwSize, 0);
+                                       RAND_add(&hlist, hlist.dwSize, 3);
                                        hentry.dwSize = sizeof(HEAPENTRY32);
                                        if (heap_first(&hentry,
                                                hlist.th32ProcessID,
@@ -438,7 +468,7 @@
                                                int entrycnt = 50;
                                                do
                                                        RAND_add(&hentry,
-                                                               hentry.dwSize, 0);
+                                                               hentry.dwSize, 5);
                                                while (heap_next(&hentry)
                                                        && --entrycnt > 0);
                                                }
@@ -446,24 +476,36 @@
                                                &hlist));
 
                        /* 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 (process_first(handle, &p))
                                do
-                                       RAND_add(&p, p.dwSize, 0);
+                                       RAND_add(&p, p.dwSize, 9);
                                while (process_next(handle, &p));
                        
                        /* 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 (thread_first(handle, &t))
                                do
-                                       RAND_add(&t, t.dwSize, 0);
+                                       RAND_add(&t, t.dwSize, 6);
                                while (thread_next(handle, &t));
                        
                        /* 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 (module_first(handle, &m))
                                do
-                                       RAND_add(&m, m.dwSize, 1);
+                                       RAND_add(&m, m.dwSize, 9);
                                while (module_next(handle, &m));
                        
                        CloseHandle(handle);

Reply via email to