Changes by Jeffrey Altman <jaltman@columbia.edu> to make RAND_poll()
work better in Win32. Verified by zhu qun-ying <qyzhu@krdl.org.sg>.
This commit is contained in:
parent
c19b6c922a
commit
10bb0dbfec
@ -171,13 +171,16 @@ typedef BOOL (WINAPI *MODULE32)(HANDLE, LPMODULEENTRY32);
|
|||||||
|
|
||||||
#include <lmcons.h>
|
#include <lmcons.h>
|
||||||
#include <lmstats.h>
|
#include <lmstats.h>
|
||||||
#if 0 /* Some compilers use LMSTR, others (VC6, for example) use LPTSTR.
|
#if 1 /* The NET API is Unicode only. It requires the use of the UNICODE
|
||||||
* This part is disabled until a fix is found.
|
* 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)
|
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);
|
typedef NET_API_STATUS (NET_API_FUNCTION * NETFREE)(LPBYTE);
|
||||||
#endif /* 0 */
|
#endif /* 1 */
|
||||||
|
|
||||||
int RAND_poll(void)
|
int RAND_poll(void)
|
||||||
{
|
{
|
||||||
@ -191,12 +194,20 @@ int RAND_poll(void)
|
|||||||
CRYPTACQUIRECONTEXT acquire = 0;
|
CRYPTACQUIRECONTEXT acquire = 0;
|
||||||
CRYPTGENRANDOM gen = 0;
|
CRYPTGENRANDOM gen = 0;
|
||||||
CRYPTRELEASECONTEXT release = 0;
|
CRYPTRELEASECONTEXT release = 0;
|
||||||
#if 0 /* This part is disabled until a fix for the problem with the
|
#if 1 /* There was previously a problem with NETSTATGET. Currently, this
|
||||||
* definition of NETSTATGET is found.
|
* section is still experimental, but if all goes well, this conditional
|
||||||
|
* will be removed
|
||||||
*/
|
*/
|
||||||
NETSTATGET netstatget = 0;
|
NETSTATGET netstatget = 0;
|
||||||
NETFREE netfree = 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 */
|
/* load functions dynamically - not available on all systems */
|
||||||
advapi = LoadLibrary("ADVAPI32.DLL");
|
advapi = LoadLibrary("ADVAPI32.DLL");
|
||||||
@ -204,9 +215,9 @@ int RAND_poll(void)
|
|||||||
user = LoadLibrary("USER32.DLL");
|
user = LoadLibrary("USER32.DLL");
|
||||||
netapi = LoadLibrary("NETAPI32.DLL");
|
netapi = LoadLibrary("NETAPI32.DLL");
|
||||||
|
|
||||||
#if 0 /* This part is disabled until a fix for the problem with the
|
#if 1 /* There was previously a problem with NETSTATGET. Currently, this
|
||||||
* definition of NETSTATGET is found. Also, note that VC6 doesn't
|
* section is still experimental, but if all goes well, this conditional
|
||||||
* understand strings starting with L".
|
* will be removed
|
||||||
*/
|
*/
|
||||||
if (netapi)
|
if (netapi)
|
||||||
{
|
{
|
||||||
@ -217,32 +228,41 @@ int RAND_poll(void)
|
|||||||
if (netstatget && netfree)
|
if (netstatget && netfree)
|
||||||
{
|
{
|
||||||
LPBYTE outbuf;
|
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)
|
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);
|
netfree(outbuf);
|
||||||
}
|
}
|
||||||
if (netstatget(NULL, L"LanmanServer", 0, 0, &outbuf) == 0)
|
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);
|
netfree(outbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netapi)
|
if (netapi)
|
||||||
FreeLibrary(netapi);
|
FreeLibrary(netapi);
|
||||||
#endif /* 0 */
|
#endif /* 1 */
|
||||||
|
|
||||||
#if 0 /* It appears like this can cause an exception deep within ADVAPI32.DLL
|
/* It appears like this can cause an exception deep within ADVAPI32.DLL
|
||||||
* at random times. Reported by Jeffrey Altman.
|
* at random times on Windows 2000. Reported by Jeffrey Altman.
|
||||||
|
* Only use it on NT.
|
||||||
*/
|
*/
|
||||||
/* Read Performance Statistics from NT/2000 registry */
|
if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
|
||||||
/* The size of the performance data can vary from call to call */
|
osverinfo.dwMajorVersion < 5)
|
||||||
/* 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. */
|
|
||||||
{
|
{
|
||||||
|
/* 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;
|
LONG rc=ERROR_MORE_DATA;
|
||||||
char * buf=NULL;
|
char * buf=NULL;
|
||||||
DWORD bufsz=0;
|
DWORD bufsz=0;
|
||||||
@ -261,13 +281,15 @@ int RAND_poll(void)
|
|||||||
}
|
}
|
||||||
if (rc == ERROR_SUCCESS)
|
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(&length, sizeof(length), 0);
|
||||||
RAND_add(buf, length, 0);
|
RAND_add(buf, length, length / 4.0);
|
||||||
}
|
}
|
||||||
if (buf)
|
if (buf)
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
#endif /* 0 */
|
|
||||||
|
|
||||||
if (advapi)
|
if (advapi)
|
||||||
{
|
{
|
||||||
@ -282,12 +304,13 @@ int RAND_poll(void)
|
|||||||
if (acquire && gen && release)
|
if (acquire && gen && release)
|
||||||
{
|
{
|
||||||
/* poll the CryptoAPI PRNG */
|
/* poll the CryptoAPI PRNG */
|
||||||
|
/* The CryptoAPI returns sizeof(buf) bytes of randomness */
|
||||||
if (acquire(&hProvider, 0, 0, PROV_RSA_FULL,
|
if (acquire(&hProvider, 0, 0, PROV_RSA_FULL,
|
||||||
CRYPT_VERIFYCONTEXT))
|
CRYPT_VERIFYCONTEXT))
|
||||||
{
|
{
|
||||||
if (gen(hProvider, sizeof(buf), buf) != 0)
|
if (gen(hProvider, sizeof(buf), buf) != 0)
|
||||||
{
|
{
|
||||||
RAND_add(buf, sizeof(buf), 0);
|
RAND_add(buf, sizeof(buf), sizeof(buf));
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("randomness from PROV_RSA_FULL\n");
|
printf("randomness from PROV_RSA_FULL\n");
|
||||||
#endif
|
#endif
|
||||||
@ -300,7 +323,7 @@ int RAND_poll(void)
|
|||||||
{
|
{
|
||||||
if (gen(hProvider, sizeof(buf), buf) != 0)
|
if (gen(hProvider, sizeof(buf), buf) != 0)
|
||||||
{
|
{
|
||||||
RAND_add(buf, sizeof(buf), 0);
|
RAND_add(buf, sizeof(buf), sizeof(buf));
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("randomness from PROV_INTEL_SEC\n");
|
printf("randomness from PROV_INTEL_SEC\n");
|
||||||
#endif
|
#endif
|
||||||
@ -321,7 +344,7 @@ int RAND_poll(void)
|
|||||||
|
|
||||||
/* process ID */
|
/* process ID */
|
||||||
w = GetCurrentProcessId();
|
w = GetCurrentProcessId();
|
||||||
RAND_add(&w, sizeof(w), 0);
|
RAND_add(&w, sizeof(w), 1);
|
||||||
|
|
||||||
if (user)
|
if (user)
|
||||||
{
|
{
|
||||||
@ -339,36 +362,32 @@ int RAND_poll(void)
|
|||||||
h = win();
|
h = win();
|
||||||
RAND_add(&h, sizeof(h), 0);
|
RAND_add(&h, sizeof(h), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cursor)
|
if (cursor)
|
||||||
{
|
{
|
||||||
/* unfortunately, its not safe to call GetCursorInfo()
|
/* unfortunately, its not safe to call GetCursorInfo()
|
||||||
* on NT4 even though it exists in SP3 (or SP6) and
|
* on NT4 even though it exists in SP3 (or SP6) and
|
||||||
* higher.
|
* higher.
|
||||||
*/
|
*/
|
||||||
OSVERSIONINFO osverinfo ;
|
|
||||||
osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO) ;
|
|
||||||
GetVersionEx( &osverinfo ) ;
|
|
||||||
|
|
||||||
if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
|
if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
|
||||||
osverinfo.dwMajorVersion < 5)
|
osverinfo.dwMajorVersion < 5)
|
||||||
cursor = 0;
|
cursor = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cursor)
|
if (cursor)
|
||||||
{
|
{
|
||||||
/* cursor position */
|
/* cursor position */
|
||||||
|
/* assume 2 bytes of entropy */
|
||||||
CURSORINFO ci;
|
CURSORINFO ci;
|
||||||
ci.cbSize = sizeof(CURSORINFO);
|
ci.cbSize = sizeof(CURSORINFO);
|
||||||
if (cursor(&ci))
|
if (cursor(&ci))
|
||||||
RAND_add(&ci, ci.cbSize, 0);
|
RAND_add(&ci, ci.cbSize, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (queue)
|
if (queue)
|
||||||
{
|
{
|
||||||
/* message queue status */
|
/* message queue status */
|
||||||
|
/* assume 1 byte of entropy */
|
||||||
w = queue(QS_ALLEVENTS);
|
w = queue(QS_ALLEVENTS);
|
||||||
RAND_add(&w, sizeof(w), 0);
|
RAND_add(&w, sizeof(w), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeLibrary(user);
|
FreeLibrary(user);
|
||||||
@ -425,11 +444,18 @@ int RAND_poll(void)
|
|||||||
!= NULL)
|
!= NULL)
|
||||||
{
|
{
|
||||||
/* heap list and heap walking */
|
/* 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);
|
hlist.dwSize = sizeof(HEAPLIST32);
|
||||||
if (heaplist_first(handle, &hlist))
|
if (heaplist_first(handle, &hlist))
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
RAND_add(&hlist, hlist.dwSize, 0);
|
RAND_add(&hlist, hlist.dwSize, 3);
|
||||||
hentry.dwSize = sizeof(HEAPENTRY32);
|
hentry.dwSize = sizeof(HEAPENTRY32);
|
||||||
if (heap_first(&hentry,
|
if (heap_first(&hentry,
|
||||||
hlist.th32ProcessID,
|
hlist.th32ProcessID,
|
||||||
@ -438,7 +464,7 @@ int RAND_poll(void)
|
|||||||
int entrycnt = 50;
|
int entrycnt = 50;
|
||||||
do
|
do
|
||||||
RAND_add(&hentry,
|
RAND_add(&hentry,
|
||||||
hentry.dwSize, 0);
|
hentry.dwSize, 5);
|
||||||
while (heap_next(&hentry)
|
while (heap_next(&hentry)
|
||||||
&& --entrycnt > 0);
|
&& --entrycnt > 0);
|
||||||
}
|
}
|
||||||
@ -446,24 +472,36 @@ int RAND_poll(void)
|
|||||||
&hlist));
|
&hlist));
|
||||||
|
|
||||||
/* process walking */
|
/* 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);
|
p.dwSize = sizeof(PROCESSENTRY32);
|
||||||
if (process_first(handle, &p))
|
if (process_first(handle, &p))
|
||||||
do
|
do
|
||||||
RAND_add(&p, p.dwSize, 0);
|
RAND_add(&p, p.dwSize, 9);
|
||||||
while (process_next(handle, &p));
|
while (process_next(handle, &p));
|
||||||
|
|
||||||
/* thread walking */
|
/* 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);
|
t.dwSize = sizeof(THREADENTRY32);
|
||||||
if (thread_first(handle, &t))
|
if (thread_first(handle, &t))
|
||||||
do
|
do
|
||||||
RAND_add(&t, t.dwSize, 0);
|
RAND_add(&t, t.dwSize, 6);
|
||||||
while (thread_next(handle, &t));
|
while (thread_next(handle, &t));
|
||||||
|
|
||||||
/* module walking */
|
/* 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);
|
m.dwSize = sizeof(MODULEENTRY32);
|
||||||
if (module_first(handle, &m))
|
if (module_first(handle, &m))
|
||||||
do
|
do
|
||||||
RAND_add(&m, m.dwSize, 1);
|
RAND_add(&m, m.dwSize, 9);
|
||||||
while (module_next(handle, &m));
|
while (module_next(handle, &m));
|
||||||
|
|
||||||
CloseHandle(handle);
|
CloseHandle(handle);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user