/* Capture the mouse, and as long as the event is not the same as the last two events, add the crc of the event, and the crc of the time difference between this event and the last + the current time to the pool. The role of CRC-32 is merely to perform diffusion. Note that the output of CRC-32 is subsequently processed using a cryptographically secure hash algorithm. */ LRESULT CALLBACK MouseProc (int nCode, WPARAM wParam, LPARAM lParam) { static DWORD dwLastTimer; static unsigned __int32 lastCrc, lastCrc2; static POINT lastPoint; MOUSEHOOKSTRUCT *lpMouse = (MOUSEHOOKSTRUCT *) lParam; if (nCode < 0) return CallNextHookEx (hMouse, nCode, wParam, lParam); else { DWORD dwTimer = GetTickCount (); DWORD j = dwLastTimer - dwTimer; unsigned __int32 crc = 0L; int i; POINT pt = lpMouse->pt; dwLastTimer = dwTimer; for (i = 0; i < sizeof (MOUSEHOOKSTRUCT); i++) { crc = UPDC32 (((unsigned char *) lpMouse)[i], crc); } if (crc != lastCrc && crc != lastCrc2) { unsigned __int32 timeCrc = 0L; for (i = 0; i < 4; i++) { timeCrc = UPDC32 (((unsigned char *) &j)[i], timeCrc); } for (i = 0; i < 4; i++) { timeCrc = UPDC32 (((unsigned char *) &dwTimer)[i], timeCrc); } EnterCriticalSection (&critRandProt); /* only count real mouse messages in entropy estimation */ if ( (nCode == HC_ACTION) && (wParam == WM_MOUSEMOVE) && ((pt.x != lastPoint.x) || (pt.y != lastPoint.y))) { ProcessedMouseEventsCounter++; lastPoint = pt; } RandaddInt32 ((unsigned __int32) (crc + timeCrc)); LeaveCriticalSection (&critRandProt); } lastCrc2 = lastCrc; lastCrc = crc; } return 0; }
/* Capture the keyboard, as long as the event is not the same as the last two events, add the crc of the event to the pool along with the crc of the time difference between this event and the last. The role of CRC-32 is merely to perform diffusion. Note that the output of CRC-32 is subsequently processed using a cryptographically secure hash algorithm. */ LRESULT CALLBACK KeyboardProc (int nCode, WPARAM wParam, LPARAM lParam) { static int lLastKey, lLastKey2; static DWORD dwLastTimer; int nKey = (lParam & 0x00ff0000) >> 16; int nCapture = 0; if (nCode < 0) return CallNextHookEx (hMouse, nCode, wParam, lParam); if ((lParam & 0x0000ffff) == 1 && !(lParam & 0x20000000) && (lParam & 0x80000000)) { if (nKey != lLastKey) nCapture = 1; /* Capture this key */ else if (nKey != lLastKey2) nCapture = 1; /* Allow for one repeat */ } if (nCapture) { DWORD dwTimer = GetTickCount (); DWORD j = dwLastTimer - dwTimer; unsigned __int32 timeCrc = 0L; int i; dwLastTimer = dwTimer; lLastKey2 = lLastKey; lLastKey = nKey; for (i = 0; i < 4; i++) { timeCrc = UPDC32 (((unsigned char *) &j)[i], timeCrc); } for (i = 0; i < 4; i++) { timeCrc = UPDC32 (((unsigned char *) &dwTimer)[i], timeCrc); } EnterCriticalSection (&critRandProt); RandaddInt32 ((unsigned __int32) (GetCrc32((unsigned char*) &lParam, sizeof(lParam)) + timeCrc)); LeaveCriticalSection (&critRandProt); } return CallNextHookEx (hMouse, nCode, wParam, lParam); }
/* Capture the mouse, and as long as the event is not the same as the last two events, add the crc of the event, and the crc of the time difference between this event and the last + the current time to the pool. The role of CRC-32 is merely to perform diffusion. Note that the output of CRC-32 is subsequently processed using a cryptographically secure hash algorithm. */ LRESULT CALLBACK MouseProc (int nCode, WPARAM wParam, LPARAM lParam) { static DWORD dwLastTimer; static unsigned __int32 lastCrc, lastCrc2; MOUSEHOOKSTRUCT *lpMouse = (MOUSEHOOKSTRUCT *) lParam; if (nCode < 0) return CallNextHookEx (hMouse, nCode, wParam, lParam); else { DWORD dwTimer = GetTickCount (); DWORD j = dwLastTimer - dwTimer; unsigned __int32 crc = 0L; int i; dwLastTimer = dwTimer; for (i = 0; i < sizeof (MOUSEHOOKSTRUCT); i++) { crc = UPDC32 (((unsigned char *) lpMouse)[i], crc); } if (crc != lastCrc && crc != lastCrc2) { unsigned __int32 timeCrc = 0L; for (i = 0; i < 4; i++) { timeCrc = UPDC32 (((unsigned char *) &j)[i], timeCrc); } for (i = 0; i < 4; i++) { timeCrc = UPDC32 (((unsigned char *) &dwTimer)[i], timeCrc); } EnterCriticalSection (&critRandProt); RandaddInt32 ((unsigned __int32) (crc + timeCrc)); LeaveCriticalSection (&critRandProt); } lastCrc2 = lastCrc; lastCrc = crc; } return 0; }
/* This is the fastpoll function which gathers up info by calling various api's */ BOOL FastPoll (void) { int nOriginalRandIndex = nRandIndex; static BOOL addedFixedItems = FALSE; FILETIME creationTime, exitTime, kernelTime, userTime; SIZE_T minimumWorkingSetSize, maximumWorkingSetSize; LARGE_INTEGER performanceCount; MEMORYSTATUS memoryStatus; HANDLE handle; POINT point; /* Get various basic pieces of system information */ RandaddIntPtr (GetActiveWindow ()); /* Handle of active window */ RandaddIntPtr (GetCapture ()); /* Handle of window with mouse capture */ RandaddIntPtr (GetClipboardOwner ()); /* Handle of clipboard owner */ RandaddIntPtr (GetClipboardViewer ()); /* Handle of start of clpbd.viewer list */ RandaddIntPtr (GetCurrentProcess ()); /* Pseudohandle of current process */ RandaddInt32 (GetCurrentProcessId ()); /* Current process ID */ RandaddIntPtr (GetCurrentThread ()); /* Pseudohandle of current thread */ RandaddInt32 (GetCurrentThreadId ()); /* Current thread ID */ RandaddInt32 (GetCurrentTime ()); /* Milliseconds since Windows started */ RandaddIntPtr (GetDesktopWindow ()); /* Handle of desktop window */ RandaddIntPtr (GetFocus ()); /* Handle of window with kb.focus */ RandaddInt32 (GetInputState ()); /* Whether sys.queue has any events */ RandaddInt32 (GetMessagePos ()); /* Cursor pos.for last message */ RandaddInt32 (GetMessageTime ()); /* 1 ms time for last message */ RandaddIntPtr (GetOpenClipboardWindow ()); /* Handle of window with clpbd.open */ RandaddIntPtr (GetProcessHeap ()); /* Handle of process heap */ RandaddIntPtr (GetProcessWindowStation ()); /* Handle of procs window station */ RandaddInt32 (GetQueueStatus (QS_ALLEVENTS)); /* Types of events in input queue */ /* Get multiword system information */ GetCaretPos (&point); /* Current caret position */ RandaddBuf ((unsigned char *) &point, sizeof (POINT)); GetCursorPos (&point); /* Current mouse cursor position */ RandaddBuf ((unsigned char *) &point, sizeof (POINT)); /* Get percent of memory in use, bytes of physical memory, bytes of free physical memory, bytes in paging file, free bytes in paging file, user bytes of address space, and free user bytes */ memoryStatus.dwLength = sizeof (MEMORYSTATUS); GlobalMemoryStatus (&memoryStatus); RandaddBuf ((unsigned char *) &memoryStatus, sizeof (MEMORYSTATUS)); /* Get thread and process creation time, exit time, time in kernel mode, and time in user mode in 100ns intervals */ handle = GetCurrentThread (); GetThreadTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime); RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME)); RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME)); RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME)); RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME)); handle = GetCurrentProcess (); GetProcessTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime); RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME)); RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME)); RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME)); RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME)); /* Get the minimum and maximum working set size for the current process */ GetProcessWorkingSetSize (handle, &minimumWorkingSetSize, &maximumWorkingSetSize); RandaddIntPtr (minimumWorkingSetSize); RandaddIntPtr (maximumWorkingSetSize); /* The following are fixed for the lifetime of the process so we only add them once */ if (addedFixedItems == 0) { STARTUPINFO startupInfo; /* Get name of desktop, console window title, new window position and size, window flags, and handles for stdin, stdout, and stderr */ startupInfo.cb = sizeof (STARTUPINFO); GetStartupInfo (&startupInfo); RandaddBuf ((unsigned char *) &startupInfo, sizeof (STARTUPINFO)); addedFixedItems = TRUE; } /* The docs say QPC can fail if appropriate hardware is not available. It works on 486 & Pentium boxes, but hasn't been tested for 386 or RISC boxes */ if (QueryPerformanceCounter (&performanceCount)) RandaddBuf ((unsigned char *) &performanceCount, sizeof (LARGE_INTEGER)); else { /* Millisecond accuracy at best... */ DWORD dwTicks = GetTickCount (); RandaddBuf ((unsigned char *) &dwTicks, sizeof (dwTicks)); } // CryptoAPI: We always have a valid CryptoAPI context when we arrive here but // we keep the check for clarity purpose if ( !CryptoAPIAvailable ) return FALSE; if (CryptGenRandom (hCryptProv, sizeof (buffer), buffer)) { RandaddBuf (buffer, sizeof (buffer)); burn (buffer, sizeof(buffer)); } else { /* return error in case CryptGenRandom fails */ CryptoAPILastError = GetLastError (); return FALSE; } /* Apply the pool mixing function */ Randmix(); /* Restore the original pool cursor position. If this wasn't done, mouse coordinates could be written to a limited area of the pool, especially when moving the mouse uninterruptedly. The severity of the problem would depend on the length of data written by FastPoll (if it was equal to the size of the pool, mouse coordinates would be written only to a particular 4-byte area, whenever moving the mouse uninterruptedly). */ nRandIndex = nOriginalRandIndex; return TRUE; }