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