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);