From 0cdd24456b33defc7f8176fa82ab694fbc284385 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Wed, 29 Apr 2015 18:18:07 +0300 Subject: Prepare random/win32.c fast poll for 64-bit Windows * random/win32.c (_gcry_rndw32_gather_random_fast) [ADD]: Rename to ADDINT. (_gcry_rndw32_gather_random_fast): Add ADDPTR. (_gcry_rndw32_gather_random_fast): Disable entropy gathering from GetQueueStatus(QS_ALLEVENTS). (_gcry_rndw32_gather_random_fast): Change minimumWorkingSetSize and maximumWorkingSetSize to SIZE_T from DWORD. (_gcry_rndw32_gather_random_fast): Only add lower 32-bits of minimumWorkingSetSize and maximumWorkingSetSize to random poll. (_gcry_rndw32_gather_random_fast) [__WIN64__]: Read TSC directly using intrinsic. -- Introduce entropy gatherer changes related to 64-bit Windows platform as done in cryptlib fast poll: - Change ADD macro to ADDPTR/ADDINT to handle pointer values. ADDPTR discards high 32-bits of 64-bit pointer values. - minimum/maximumWorkingSetSize changed to SIZE_T type to avoid stack corruption on 64-bit; only low 32-bits are used for entropy. - Use __rdtsc() intrinsic on 64-bit (as TSC is always available). Signed-off-by: Jussi Kivilinna --- random/rndw32.c | 83 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 31 deletions(-) diff --git a/random/rndw32.c b/random/rndw32.c index c495131d..4ab1bca3 100644 --- a/random/rndw32.c +++ b/random/rndw32.c @@ -826,39 +826,47 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, cursor position for last message, 1 ms time for last message, handle of window with clipboard open, handle of process heap, handle of procs window station, types of events in input queue, - and milliseconds since Windows was started. */ + and milliseconds since Windows was started. On 64-bit platform + some of these return values are pointers and thus 64-bit wide. + We discard the upper 32-bit of those values. */ { byte buffer[20*sizeof(ulong)], *bufptr; bufptr = buffer; -#define ADD(f) do { ulong along = (ulong)(f); \ - memcpy (bufptr, &along, sizeof (along) ); \ - bufptr += sizeof (along); \ - } while (0) - - ADD ( GetActiveWindow ()); - ADD ( GetCapture ()); - ADD ( GetClipboardOwner ()); - ADD ( GetClipboardViewer ()); - ADD ( GetCurrentProcess ()); - ADD ( GetCurrentProcessId ()); - ADD ( GetCurrentThread ()); - ADD ( GetCurrentThreadId ()); - ADD ( GetDesktopWindow ()); - ADD ( GetFocus ()); - ADD ( GetInputState ()); - ADD ( GetMessagePos ()); - ADD ( GetMessageTime ()); - ADD ( GetOpenClipboardWindow ()); - ADD ( GetProcessHeap ()); - ADD ( GetProcessWindowStation ()); - ADD ( GetQueueStatus (QS_ALLEVENTS)); - ADD ( GetTickCount ()); +#define ADDINT(f) do { ulong along = (ulong)(f); \ + memcpy (bufptr, &along, sizeof (along) ); \ + bufptr += sizeof (along); \ + } while (0) +#define ADDPTR(f) do { void *aptr = (f); \ + ADDINT((SIZE_T)aptr); \ + } while (0) + + ADDPTR ( GetActiveWindow ()); + ADDPTR ( GetCapture ()); + ADDPTR ( GetClipboardOwner ()); + ADDPTR ( GetClipboardViewer ()); + ADDPTR ( GetCurrentProcess ()); + ADDINT ( GetCurrentProcessId ()); + ADDPTR ( GetCurrentThread ()); + ADDINT ( GetCurrentThreadId ()); + ADDPTR ( GetDesktopWindow ()); + ADDPTR ( GetFocus ()); + ADDINT ( GetInputState ()); + ADDINT ( GetMessagePos ()); + ADDINT ( GetMessageTime ()); + ADDPTR ( GetOpenClipboardWindow ()); + ADDPTR ( GetProcessHeap ()); + ADDPTR ( GetProcessWindowStation ()); + /* Following function in some cases stops returning events, and cannot + be used as an entropy source. */ + /*ADDINT ( GetQueueStatus (QS_ALLEVENTS));*/ + ADDINT ( GetTickCount ()); gcry_assert ( bufptr-buffer < sizeof (buffer) ); (*add) ( buffer, bufptr-buffer, origin ); -#undef ADD +#undef ADDINT +#undef ADDPTR } /* Get multiword system information: Current caret position, current @@ -888,7 +896,7 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, { HANDLE handle; FILETIME creationTime, exitTime, kernelTime, userTime; - DWORD minimumWorkingSetSize, maximumWorkingSetSize; + SIZE_T minimumWorkingSetSize, maximumWorkingSetSize; handle = GetCurrentThread (); GetThreadTimes (handle, &creationTime, &exitTime, @@ -910,10 +918,9 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, process. */ GetProcessWorkingSetSize (handle, &minimumWorkingSetSize, &maximumWorkingSetSize); - (*add) ( &minimumWorkingSetSize, - sizeof (minimumWorkingSetSize), origin ); - (*add) ( &maximumWorkingSetSize, - sizeof (maximumWorkingSetSize), origin ); + /* On 64-bit system, discard the high 32-bits. */ + (*add) ( &minimumWorkingSetSize, sizeof (int), origin ); + (*add) ( &maximumWorkingSetSize, sizeof (int), origin ); } @@ -961,7 +968,20 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, To make things unambiguous, we detect a CPU new enough to call RDTSC directly by checking for CPUID capabilities, and fall back to QPC if - this isn't present. */ + this isn't present. + + On AMD64, TSC is always available and intrinsic is provided for accessing + it. */ +#ifdef __WIN64__ + { + unsigned __int64 aint64; + + /* Note: cryptlib does not discard upper 32 bits of TSC on WIN64, but does + * on WIN32. Is this correct? */ + aint64 = __rdtsc(); + (*add) (&aint64, sizeof(aint64), origin); + } +#else #ifdef __GNUC__ /* FIXME: We would need to implement the CPU feature tests first. */ /* if (cpu_has_feature_rdtsc) */ @@ -990,6 +1010,7 @@ _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, (*add) (&aword, sizeof (aword), origin ); } } +#endif /*__WIN64__*/ } -- cgit v1.2.1