diff options
Diffstat (limited to 'crypto/rand')
-rw-r--r-- | crypto/rand/rand_win.c | 69 | ||||
-rw-r--r-- | crypto/rand/randfile.c | 17 |
2 files changed, 72 insertions, 14 deletions
diff --git a/crypto/rand/rand_win.c b/crypto/rand/rand_win.c index 00dbe42..5198351 100644 --- a/crypto/rand/rand_win.c +++ b/crypto/rand/rand_win.c @@ -463,7 +463,7 @@ int RAND_poll(void) PROCESSENTRY32 p; THREADENTRY32 t; MODULEENTRY32 m; - DWORD stoptime = 0; + DWORD starttime = 0; snap = (CREATETOOLHELP32SNAPSHOT) GetProcAddress(kernel, "CreateToolhelp32Snapshot"); @@ -494,12 +494,29 @@ int RAND_poll(void) * each entry. Consider each field a source of 1 byte * of entropy. */ + ZeroMemory(&hlist, sizeof(HEAPLIST32)); hlist.dwSize = sizeof(HEAPLIST32); - if (good) stoptime = GetTickCount() + MAXDELAY; + 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, @@ -510,10 +527,42 @@ int RAND_poll(void) RAND_add(&hentry, hentry.dwSize, 5); while (heap_next(&hentry) + && (!good || (GetTickCount()-starttime)<MAXDELAY) && --entrycnt > 0); } - } while (heaplist_next(handle, - &hlist) && GetTickCount() < stoptime); + } + __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 @@ -522,11 +571,11 @@ int RAND_poll(void) */ p.dwSize = sizeof(PROCESSENTRY32); - if (good) stoptime = GetTickCount() + MAXDELAY; + if (good) starttime = GetTickCount(); if (process_first(handle, &p)) do RAND_add(&p, p.dwSize, 9); - while (process_next(handle, &p) && GetTickCount() < stoptime); + while (process_next(handle, &p) && (!good || (GetTickCount()-starttime)<MAXDELAY)); /* thread walking */ /* THREADENTRY32 contains 6 fields that will change @@ -534,11 +583,11 @@ int RAND_poll(void) * 1 byte of entropy. */ t.dwSize = sizeof(THREADENTRY32); - if (good) stoptime = GetTickCount() + MAXDELAY; + if (good) starttime = GetTickCount(); if (thread_first(handle, &t)) do RAND_add(&t, t.dwSize, 6); - while (thread_next(handle, &t) && GetTickCount() < stoptime); + while (thread_next(handle, &t) && (!good || (GetTickCount()-starttime)<MAXDELAY)); /* module walking */ /* MODULEENTRY32 contains 9 fields that will change @@ -546,12 +595,12 @@ int RAND_poll(void) * 1 byte of entropy. */ m.dwSize = sizeof(MODULEENTRY32); - if (good) stoptime = GetTickCount() + MAXDELAY; + if (good) starttime = GetTickCount(); if (module_first(handle, &m)) do RAND_add(&m, m.dwSize, 9); while (module_next(handle, &m) - && (GetTickCount() < stoptime)); + && (!good || (GetTickCount()-starttime)<MAXDELAY)); if (close_snap) close_snap(handle); else diff --git a/crypto/rand/randfile.c b/crypto/rand/randfile.c index d108353..84276d7 100644 --- a/crypto/rand/randfile.c +++ b/crypto/rand/randfile.c @@ -117,6 +117,15 @@ int RAND_load_file(const char *file, long bytes) if (file == NULL) return(0); +#ifdef PURIFY + /* struct stat can have padding and unused fields that may not be + * initialized in the call to stat(). We need to clear the entire + * structure before calling RAND_add() to avoid complaints from + * applications such as Valgrind. + */ + memset(&sb, 0, sizeof(sb)); +#endif + if (stat(file,&sb) < 0) return(0); RAND_add(&sb,sizeof(sb),0.0); if (bytes == 0) return(ret); @@ -127,8 +136,8 @@ int RAND_load_file(const char *file, long bytes) in=fopen(file,"rb"); #endif if (in == NULL) goto err; -#if defined(S_IFBLK) && defined(S_IFCHR) - if (sb.st_mode & (S_IFBLK | S_IFCHR)) { +#if defined(S_ISBLK) && defined(S_ISCHR) + if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { /* this file is a device. we don't want read an infinite number * of bytes from a random device, nor do we want to use buffered * I/O because we will waste system entropy. @@ -174,8 +183,8 @@ int RAND_write_file(const char *file) i=stat(file,&sb); if (i != -1) { -#if defined(S_IFBLK) && defined(S_IFCHR) - if (sb.st_mode & (S_IFBLK | S_IFCHR)) { +#if defined(S_ISBLK) && defined(S_ISCHR) + if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { /* this file is a device. we don't write back to it. * we "succeed" on the assumption this is some sort * of random device. Otherwise attempting to write to |