提交 eb9b92ec 编写于 作者: J Joey Yandle 提交者: Rich Salz

- remove insane heap walk and kernel loading code; clean up style and calling conventions

Reviewed-by: NMatt Caswell <matt@openssl.org>
Reviewed-by: NTim Hudson <tjh@openssl.org>
Reviewed-by: NRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/1079)
上级 cfe1d992
......@@ -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();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册