|
|
1.1.1.6 root 1: /* Legal Notice: The source code contained in this file has been derived from
2: the source code of Encryption for the Masses 2.02a, which is Copyright (c)
3: 1998-99 Paul Le Roux and which is covered by the 'License Agreement for
4: Encryption for the Masses'. Modifications and additions to that source code
5: contained in this file are Copyright (c) 2004-2005 TrueCrypt Foundation and
6: Copyright (c) 2004 TrueCrypt Team, and are covered by TrueCrypt License 2.0
7: the full text of which is contained in the file License.txt included in
8: TrueCrypt binary and source code distribution archives. */
1.1 root 9:
1.1.1.6 root 10: #include "Tcdefs.h"
1.1 root 11:
12: #include <tlhelp32.h>
13:
1.1.1.6 root 14: #include "Crc.h"
15: #include "Random.h"
16: #include "Apidrvr.h"
17: #include "Dlgcode.h"
1.1 root 18:
19: unsigned char *pRandPool = NULL;
1.1.1.2 root 20: int nRandIndex = 0, randPoolReadIndex = 0;
1.1 root 21:
1.1.1.6 root 22: int hashFunction = DEFAULT_HASH_ALGORITHM;
1.1.1.3 root 23:
1.1 root 24: /* Macro to add a single byte to the pool */
25: #define RandaddByte(x) {\
1.1.1.6 root 26: if (nRandIndex == RNG_POOL_SIZE) nRandIndex = 0;\
1.1 root 27: pRandPool[nRandIndex] = (unsigned char) ((unsigned char)x + pRandPool[nRandIndex]); \
1.1.1.6 root 28: if (nRandIndex % 8 == 0) Randmix();\
1.1 root 29: nRandIndex++; \
30: }
31:
32: /* Macro to add four bytes to the pool */
1.1.1.6 root 33: #define RandaddInt32(x) _RandaddInt32((unsigned __int32)x);
1.1 root 34:
35: #pragma warning( disable : 4710 ) /* inline func. not expanded warning */
36:
1.1.1.6 root 37: _inline void _RandaddInt32(unsigned __int32 x)
1.1 root 38: {
39: RandaddByte(x);
40: RandaddByte((x >> 8));
41: RandaddByte((x >> 16));
42: RandaddByte((x >> 24));
43: }
44:
45: HHOOK hMouse = NULL; /* Mouse hook for the random number generator */
1.1.1.6 root 46: HHOOK hKeyboard = NULL; /* Keyboard hook for the random number generator */
1.1 root 47:
48: /* Variables for thread control, the thread is used to gather up info about
49: the system in in the background */
50: CRITICAL_SECTION critRandProt; /* The critical section */
1.1.1.6 root 51: BOOL volatile bThreadTerminate = FALSE; /* This variable is shared among thread's so its made volatile */
1.1 root 52: BOOL bDidSlowPoll = FALSE; /* We do the slow poll only once */
1.1.1.7 ! root 53: BOOL volatile bFastPollEnabled = TRUE; /* Used to reduce CPU load when performing benchmarks */
! 54: BOOL volatile bRandmixEnabled = TRUE; /* Used to reduce CPU load when performing benchmarks */
1.1 root 55:
56: /* Network library handle for the slowPollWinNT function */
57: HANDLE hNetAPI32 = NULL;
58:
1.1.1.4 root 59: // CryptoAPI
60: HCRYPTPROV hCryptProv;
1.1.1.6 root 61: unsigned __int8 buffer[RNG_POOL_SIZE];
1.1.1.4 root 62:
1.1 root 63: BOOL bRandDidInit = FALSE;
64:
65: /* Init the random number generator, setup the hooks, and start the thread */
66: int
67: Randinit ()
68: {
69: HANDLE threadID;
70:
1.1.1.6 root 71: if(bRandDidInit) return 0;
1.1 root 72:
73: InitializeCriticalSection (&critRandProt);
74:
75: bRandDidInit = TRUE;
76:
77: pRandPool = (unsigned char *) TCalloc (RANDOMPOOL_ALLOCSIZE);
78: if (pRandPool == NULL)
79: goto error;
80: else
81: memset (pRandPool, 0, RANDOMPOOL_ALLOCSIZE);
82:
1.1.1.2 root 83: VirtualLock (pRandPool, RANDOMPOOL_ALLOCSIZE);
84:
1.1 root 85: hKeyboard = SetWindowsHookEx (WH_KEYBOARD, (HOOKPROC)&KeyboardProc, NULL, GetCurrentThreadId ());
1.1.1.4 root 86: if (hKeyboard == 0) handleWin32Error (0);
87:
88: hMouse = SetWindowsHookEx (WH_MOUSE, (HOOKPROC)&MouseProc, NULL, GetCurrentThreadId ());
89: if (hMouse == 0)
90: {
91: handleWin32Error (0);
1.1 root 92: goto error;
1.1.1.4 root 93: }
94:
95: if (!CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)
96: && !CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
97: {
1.1.1.6 root 98: hCryptProv = 0;
1.1.1.4 root 99: }
1.1 root 100:
101: threadID = (HANDLE) _beginthread (ThreadSafeThreadFunction, 8192, NULL);
102: if (threadID == (HANDLE) - 1)
103: goto error;
104:
105: return 0;
106:
1.1.1.4 root 107: error:
1.1 root 108: Randfree ();
109: return 1;
110: }
111:
112: /* Close everything down, including the thread which is closed down by
113: setting a flag which eventually causes the thread function to exit */
114: void
115: Randfree ()
116: {
117: if (bRandDidInit == FALSE)
118: return;
119:
120: EnterCriticalSection (&critRandProt);
121:
122: if (hMouse != 0)
123: UnhookWindowsHookEx (hMouse);
124: if (hKeyboard != 0)
125: UnhookWindowsHookEx (hKeyboard);
126:
127: bThreadTerminate = TRUE;
128:
129: LeaveCriticalSection (&critRandProt);
130:
131: for (;;)
132: {
133: Sleep (250);
134: EnterCriticalSection (&critRandProt);
135: if (bThreadTerminate == FALSE)
136: {
137: LeaveCriticalSection (&critRandProt);
138: break;
139: }
140: LeaveCriticalSection (&critRandProt);
141: }
142:
143: if (pRandPool != NULL)
144: {
145: burn (pRandPool, RANDOMPOOL_ALLOCSIZE);
146: TCfree (pRandPool);
147: pRandPool = NULL;
148: }
149:
150: if (hNetAPI32 != 0)
151: {
152: FreeLibrary (hNetAPI32);
153: hNetAPI32 = NULL;
154: }
155:
1.1.1.4 root 156: if (hCryptProv)
157: {
158: CryptReleaseContext (hCryptProv, 0);
159: hCryptProv = 0;
160: }
161:
1.1 root 162: hMouse = NULL;
163: hKeyboard = NULL;
164: nRandIndex = 0;
165: bThreadTerminate = FALSE;
166: DeleteCriticalSection (&critRandProt);
167: bRandDidInit = FALSE;
168: }
169:
1.1.1.6 root 170: void RandSetHashFunction (int hash_algo_id)
1.1.1.3 root 171: {
1.1.1.6 root 172: hashFunction = hash_algo_id;
1.1.1.3 root 173: }
174:
1.1.1.6 root 175: int RandGetHashFunction (void)
176: {
177: return hashFunction;
178: }
179:
180: /* The random pool mixing function */
1.1 root 181: void
182: Randmix ()
183: {
1.1.1.6 root 184: if (bRandmixEnabled)
1.1 root 185: {
1.1.1.6 root 186: unsigned char hashOutputBuffer [MAX_DIGESTSIZE];
187: WHIRLPOOL_CTX wctx;
188: RMD160_CTX rctx;
189: sha1_ctx sctx;
190: int poolIndex, digestIndex, digestSize;
191:
192: switch (hashFunction)
193: {
194: case SHA1:
195: digestSize = SHA1_DIGESTSIZE;
196: break;
1.1 root 197:
1.1.1.6 root 198: case RIPEMD160:
199: digestSize = RIPEMD160_DIGESTSIZE;
200: break;
201:
202: case WHIRLPOOL:
203: digestSize = WHIRLPOOL_DIGESTSIZE;
204: break;
205: }
1.1.1.3 root 206:
1.1.1.6 root 207: for (poolIndex = 0; poolIndex < RNG_POOL_SIZE; poolIndex += digestSize)
208: {
209: /* Compute the message digest of the entire pool using the selected hash function. */
210: switch (hashFunction)
211: {
212: case SHA1:
213: sha1_begin (&sctx);
214: sha1_hash (pRandPool, RNG_POOL_SIZE, &sctx);
215: sha1_end (hashOutputBuffer, &sctx);
216: break;
217:
218: case RIPEMD160:
219: RMD160Init(&rctx);
220: RMD160Update(&rctx, pRandPool, RNG_POOL_SIZE);
221: RMD160Final(hashOutputBuffer, &rctx);
222: break;
223:
224: case WHIRLPOOL:
225: WHIRLPOOL_init (&wctx);
226: WHIRLPOOL_add (pRandPool, RNG_POOL_SIZE * 8, &wctx);
227: WHIRLPOOL_finalize (&wctx, hashOutputBuffer);
228: break;
229: }
230:
231: /* XOR the resultant message digest to the pool at the poolIndex position. */
232: for (digestIndex = 0; digestIndex < digestSize; digestIndex++)
233: {
234: pRandPool [poolIndex + digestIndex] ^= hashOutputBuffer [digestIndex];
235: }
236: }
237:
238: /* Prevent leaks */
239: memset (hashOutputBuffer, 0, MAX_DIGESTSIZE);
240: switch (hashFunction)
241: {
242: case SHA1:
243: memset (&sctx, 0, sizeof(sctx));
244: break;
245:
246: case RIPEMD160:
247: memset (&rctx, 0, sizeof(rctx));
248: break;
249:
250: case WHIRLPOOL:
251: memset (&wctx, 0, sizeof(wctx));
252: break;
253: }
1.1 root 254: }
255: }
256:
257: /* Add a buffer to the pool */
258: void
259: RandaddBuf (void *buf, int len)
260: {
261: int i;
262: for (i = 0; i < len; i++)
263: {
264: RandaddByte (((unsigned char *) buf)[i]);
265: }
266: }
267:
268: void
1.1.1.4 root 269: RandpeekBytes (unsigned char *buf, int len)
1.1 root 270: {
1.1.1.6 root 271: if (len > RNG_POOL_SIZE)
1.1.1.7 ! root 272: {
! 273: Error ("ERR_NOT_ENOUGH_RANDOM_DATA");
1.1.1.6 root 274: len = RNG_POOL_SIZE;
1.1.1.7 ! root 275: }
1.1.1.6 root 276:
1.1 root 277: EnterCriticalSection (&critRandProt);
278: memcpy (buf, pRandPool, len);
279: LeaveCriticalSection (&critRandProt);
280: }
281:
1.1.1.6 root 282: /* Get len random bytes from the pool (max. RNG_POOL_SIZE bytes per a single call) */
1.1 root 283: void
1.1.1.4 root 284: RandgetBytes (unsigned char *buf, int len, BOOL forceSlowPoll)
1.1 root 285: {
286: int i;
287:
288: EnterCriticalSection (&critRandProt);
289:
1.1.1.2 root 290: if (bDidSlowPoll == FALSE || forceSlowPoll)
1.1 root 291: {
292: bDidSlowPoll = TRUE;
1.1.1.2 root 293: SlowPollWinNT ();
1.1 root 294: }
1.1.1.2 root 295:
296: FastPoll ();
1.1 root 297:
1.1.1.6 root 298: /* There's never more than RNG_POOL_SIZE worth of randomess */
299: if (len > RNG_POOL_SIZE)
300: {
301: Error ("ERR_NOT_ENOUGH_RANDOM_DATA");
302: len = RNG_POOL_SIZE;
303: }
1.1 root 304:
1.1.1.2 root 305: // Requested number of bytes is copied from pool to output buffer,
306: // pool is rehashed, and output buffer is XORed with new data from pool
307: for (i = 0; i < len; i++)
308: {
309: buf[i] = pRandPool[randPoolReadIndex++];
1.1.1.6 root 310: if (randPoolReadIndex == RNG_POOL_SIZE) randPoolReadIndex = 0;
1.1.1.2 root 311: }
312:
1.1.1.6 root 313: /* Invert the pool */
314: for (i = 0; i < RNG_POOL_SIZE / 4; i++)
1.1 root 315: {
1.1.1.6 root 316: ((unsigned __int32 *) pRandPool)[i] = ~((unsigned __int32 *) pRandPool)[i];
1.1 root 317: }
318:
1.1.1.6 root 319: // Mix the pool
1.1.1.4 root 320: FastPoll ();
321:
1.1.1.6 root 322: // XOR the current pool content into the output buffer to prevent pool state leaks
1.1.1.4 root 323: for (i = 0; i < len; i++)
324: {
325: buf[i] ^= pRandPool[randPoolReadIndex++];
1.1.1.6 root 326: if (randPoolReadIndex == RNG_POOL_SIZE) randPoolReadIndex = 0;
1.1.1.4 root 327: }
1.1 root 328:
329: LeaveCriticalSection (&critRandProt);
330: }
331:
332: /* Capture the mouse, and as long as the event is not the same as the last
1.1.1.6 root 333: two events, add the crc of the event, and the crc of the time difference
1.1 root 334: between this event and the last + the current time to the pool */
335: LRESULT CALLBACK
336: MouseProc (int nCode, WPARAM wParam, LPARAM lParam)
337: {
338: static DWORD dwLastTimer;
1.1.1.6 root 339: static unsigned __int32 lastCrc, lastCrc2;
1.1 root 340: MOUSEHOOKSTRUCT *lpMouse = (MOUSEHOOKSTRUCT *) lParam;
341:
342: if (nCode < 0)
343: return CallNextHookEx (hMouse, nCode, wParam, lParam);
344: else
345: {
346: DWORD dwTimer = GetTickCount ();
347: DWORD j = dwLastTimer - dwTimer;
1.1.1.6 root 348: unsigned __int32 crc = 0L;
1.1 root 349: int i;
350:
351: dwLastTimer = dwTimer;
352:
353: for (i = 0; i < sizeof (MOUSEHOOKSTRUCT); i++)
354: {
355: crc = UPDC32 (((unsigned char *) lpMouse)[i], crc);
356: }
357:
358: if (crc != lastCrc && crc != lastCrc2)
359: {
1.1.1.6 root 360: unsigned __int32 timeCrc = 0L;
1.1 root 361:
362: for (i = 0; i < 4; i++)
363: {
364: timeCrc = UPDC32 (((unsigned char *) &j)[i], timeCrc);
365: }
366:
367: for (i = 0; i < 4; i++)
368: {
369: timeCrc = UPDC32 (((unsigned char *) &dwTimer)[i], timeCrc);
370: }
371:
372: EnterCriticalSection (&critRandProt);
1.1.1.6 root 373: RandaddInt32 ((unsigned __int32) (crc + timeCrc));
1.1 root 374: LeaveCriticalSection (&critRandProt);
375: }
376: lastCrc2 = lastCrc;
377: lastCrc = crc;
378:
379: }
380: return 0;
381: }
382:
383: /* Capture the keyboard, as long as the event is not the same as the last two
1.1.1.6 root 384: events, add the crc of the event to the pool along with the crc of the time
1.1 root 385: difference between this event and the last */
386: LRESULT CALLBACK
387: KeyboardProc (int nCode, WPARAM wParam, LPARAM lParam)
388: {
389: static int lLastKey, lLastKey2;
390: static DWORD dwLastTimer;
391: int nKey = (lParam & 0x00ff0000) >> 16;
392: int nCapture = 0;
393:
394: if (nCode < 0)
395: return CallNextHookEx (hMouse, nCode, wParam, lParam);
396:
397: if ((lParam & 0x0000ffff) == 1 && !(lParam & 0x20000000) &&
398: (lParam & 0x80000000))
399: {
400: if (nKey != lLastKey)
401: nCapture = 1; /* Capture this key */
402: else if (nKey != lLastKey2)
403: nCapture = 1; /* Allow for one repeat */
404: }
405: if (nCapture)
406: {
407: DWORD dwTimer = GetTickCount ();
408: DWORD j = dwLastTimer - dwTimer;
1.1.1.6 root 409: unsigned __int32 timeCrc = 0L;
1.1 root 410: int i;
411:
412: dwLastTimer = dwTimer;
413: lLastKey2 = lLastKey;
414: lLastKey = nKey;
415:
416: for (i = 0; i < 4; i++)
417: {
418: timeCrc = UPDC32 (((unsigned char *) &j)[i], timeCrc);
419: }
420:
421: for (i = 0; i < 4; i++)
422: {
423: timeCrc = UPDC32 (((unsigned char *) &dwTimer)[i], timeCrc);
424: }
425:
426: EnterCriticalSection (&critRandProt);
1.1.1.6 root 427: RandaddInt32 ((unsigned __int32) (crc32int(&lParam) + timeCrc));
1.1 root 428: LeaveCriticalSection (&critRandProt);
429: }
430: return 0;
431: }
432:
433: /* This is the thread function which will poll the system for randomness */
434: void
435: ThreadSafeThreadFunction (void *dummy)
436: {
437: if (dummy); /* Remove unused parameter warning */
438:
439: for (;;)
440: {
441: EnterCriticalSection (&critRandProt);
442:
1.1.1.6 root 443: if (bThreadTerminate)
1.1 root 444: {
445: bThreadTerminate = FALSE;
446: LeaveCriticalSection (&critRandProt);
447: _endthread ();
448: }
1.1.1.6 root 449: else if (bFastPollEnabled)
1.1 root 450: {
451: FastPoll ();
452: }
453:
454: LeaveCriticalSection (&critRandProt);
455:
1.1.1.6 root 456: Sleep (500);
1.1 root 457: }
458: }
459:
460: /* Type definitions for function pointers to call NetAPI32 functions */
461:
462: typedef
463: DWORD (WINAPI * NETSTATISTICSGET) (LPWSTR szServer, LPWSTR szService,
464: DWORD dwLevel, DWORD dwOptions,
465: LPBYTE * lpBuffer);
466: typedef
467: DWORD (WINAPI * NETAPIBUFFERSIZE) (LPVOID lpBuffer, LPDWORD cbBuffer);
468: typedef
469: DWORD (WINAPI * NETAPIBUFFERFREE) (LPVOID lpBuffer);
470:
471: NETSTATISTICSGET pNetStatisticsGet = NULL;
472: NETAPIBUFFERSIZE pNetApiBufferSize = NULL;
473: NETAPIBUFFERFREE pNetApiBufferFree = NULL;
474:
475: /* This is the slowpoll function which gathers up network/hard drive
476: performance data for the random pool */
477: void
478: SlowPollWinNT (void)
479: {
480: static int isWorkstation = -1;
481: static int cbPerfData = 0x10000;
482: HANDLE hDevice;
483: LPBYTE lpBuffer;
484: DWORD dwSize, status;
485: LPWSTR lpszLanW, lpszLanS;
1.1.1.4 root 486: int i, nDrive;
1.1 root 487:
488: /* Find out whether this is an NT server or workstation if necessary */
489: if (isWorkstation == -1)
490: {
491: HKEY hKey;
492:
493: if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
494: "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
495: 0, KEY_READ, &hKey) == ERROR_SUCCESS)
496: {
497: unsigned char szValue[32];
498: dwSize = sizeof (szValue);
499:
500: isWorkstation = TRUE;
501: status = RegQueryValueEx (hKey, "ProductType", 0, NULL,
502: szValue, &dwSize);
503:
504: if (status == ERROR_SUCCESS && _stricmp ((char *) szValue, "WinNT"))
505: /* Note: There are (at least) three cases for
506: ProductType: WinNT = NT Workstation,
507: ServerNT = NT Server, LanmanNT = NT Server
508: acting as a Domain Controller */
509: isWorkstation = FALSE;
510:
511: RegCloseKey (hKey);
512: }
513: }
514: /* Initialize the NetAPI32 function pointers if necessary */
515: if (hNetAPI32 == NULL)
516: {
517: /* Obtain a handle to the module containing the Lan Manager
518: functions */
519: hNetAPI32 = LoadLibrary ("NETAPI32.DLL");
520: if (hNetAPI32 != NULL)
521: {
522: /* Now get pointers to the functions */
523: pNetStatisticsGet = (NETSTATISTICSGET) GetProcAddress (hNetAPI32,
524: "NetStatisticsGet");
525: pNetApiBufferSize = (NETAPIBUFFERSIZE) GetProcAddress (hNetAPI32,
526: "NetApiBufferSize");
527: pNetApiBufferFree = (NETAPIBUFFERFREE) GetProcAddress (hNetAPI32,
528: "NetApiBufferFree");
529:
530: /* Make sure we got valid pointers for every NetAPI32
531: function */
532: if (pNetStatisticsGet == NULL ||
533: pNetApiBufferSize == NULL ||
534: pNetApiBufferFree == NULL)
535: {
536: /* Free the library reference and reset the
537: static handle */
538: FreeLibrary (hNetAPI32);
539: hNetAPI32 = NULL;
540: }
541: }
542: }
543:
544: /* Get network statistics. Note: Both NT Workstation and NT Server
545: by default will be running both the workstation and server
546: services. The heuristic below is probably useful though on the
547: assumption that the majority of the network traffic will be via
548: the appropriate service */
549: lpszLanW = (LPWSTR) WIDE ("LanmanWorkstation");
550: lpszLanS = (LPWSTR) WIDE ("LanmanServer");
551: if (hNetAPI32 &&
552: pNetStatisticsGet (NULL,
553: isWorkstation ? lpszLanW : lpszLanS,
554: 0, 0, &lpBuffer) == 0)
555: {
556: pNetApiBufferSize (lpBuffer, &dwSize);
557: RandaddBuf ((unsigned char *) lpBuffer, dwSize);
558: pNetApiBufferFree (lpBuffer);
559: }
560:
561: /* Get disk I/O statistics for all the hard drives */
562: for (nDrive = 0;; nDrive++)
563: {
564: DISK_PERFORMANCE diskPerformance;
565: char szDevice[24];
566:
567: /* Check whether we can access this device */
568: sprintf (szDevice, "\\\\.\\PhysicalDrive%d", nDrive);
569: hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
570: NULL, OPEN_EXISTING, 0, NULL);
571: if (hDevice == INVALID_HANDLE_VALUE)
572: break;
573:
574:
575: /* Note: This only works if you have turned on the disk
576: performance counters with 'diskperf -y'. These counters
577: are off by default */
578: if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
579: &diskPerformance, sizeof (DISK_PERFORMANCE),
580: &dwSize, NULL))
581: {
582: RandaddBuf ((unsigned char *) &diskPerformance, dwSize);
583: }
584: CloseHandle (hDevice);
585: }
586:
1.1.1.4 root 587: // CryptoAPI
1.1.1.7 ! root 588: for (i = 0; i < 100; i++)
1.1.1.4 root 589: {
1.1.1.6 root 590: if (hCryptProv && CryptGenRandom(hCryptProv, sizeof (buffer), buffer))
1.1.1.4 root 591: RandaddBuf (buffer, sizeof (buffer));
1.1 root 592: }
593:
1.1.1.6 root 594: Randmix();
1.1 root 595: }
596:
597:
1.1.1.6 root 598: /* This is the fastpoll function which gathers up info by calling various api's */
1.1 root 599: void
600: FastPoll (void)
601: {
602: static BOOL addedFixedItems = FALSE;
603: FILETIME creationTime, exitTime, kernelTime, userTime;
604: DWORD minimumWorkingSetSize, maximumWorkingSetSize;
605: LARGE_INTEGER performanceCount;
606: MEMORYSTATUS memoryStatus;
607: HANDLE handle;
608: POINT point;
1.1.1.6 root 609: int nOriginalRandIndex = nRandIndex;
1.1 root 610:
611: /* Get various basic pieces of system information */
1.1.1.6 root 612: RandaddInt32 (GetActiveWindow ()); /* Handle of active window */
613: RandaddInt32 (GetCapture ()); /* Handle of window with mouse
1.1 root 614: capture */
1.1.1.6 root 615: RandaddInt32 (GetClipboardOwner ()); /* Handle of clipboard owner */
616: RandaddInt32 (GetClipboardViewer ()); /* Handle of start of
1.1 root 617: clpbd.viewer list */
1.1.1.6 root 618: RandaddInt32 (GetCurrentProcess ()); /* Pseudohandle of current
1.1 root 619: process */
1.1.1.6 root 620: RandaddInt32 (GetCurrentProcessId ()); /* Current process ID */
621: RandaddInt32 (GetCurrentThread ()); /* Pseudohandle of current
1.1 root 622: thread */
1.1.1.6 root 623: RandaddInt32 (GetCurrentThreadId ()); /* Current thread ID */
624: RandaddInt32 (GetCurrentTime ()); /* Milliseconds since Windows
1.1 root 625: started */
1.1.1.6 root 626: RandaddInt32 (GetDesktopWindow ()); /* Handle of desktop window */
627: RandaddInt32 (GetFocus ()); /* Handle of window with kb.focus */
628: RandaddInt32 (GetInputState ()); /* Whether sys.queue has any events */
629: RandaddInt32 (GetMessagePos ()); /* Cursor pos.for last message */
630: RandaddInt32 (GetMessageTime ()); /* 1 ms time for last message */
631: RandaddInt32 (GetOpenClipboardWindow ()); /* Handle of window with
1.1 root 632: clpbd.open */
1.1.1.6 root 633: RandaddInt32 (GetProcessHeap ()); /* Handle of process heap */
634: RandaddInt32 (GetProcessWindowStation ()); /* Handle of procs
1.1 root 635: window station */
1.1.1.6 root 636: RandaddInt32 (GetQueueStatus (QS_ALLEVENTS)); /* Types of events in
1.1 root 637: input queue */
638:
639: /* Get multiword system information */
640: GetCaretPos (&point); /* Current caret position */
641: RandaddBuf ((unsigned char *) &point, sizeof (POINT));
642: GetCursorPos (&point); /* Current mouse cursor position */
643: RandaddBuf ((unsigned char *) &point, sizeof (POINT));
644:
645: /* Get percent of memory in use, bytes of physical memory, bytes of
646: free physical memory, bytes in paging file, free bytes in paging
647: file, user bytes of address space, and free user bytes */
648: memoryStatus.dwLength = sizeof (MEMORYSTATUS);
649: GlobalMemoryStatus (&memoryStatus);
650: RandaddBuf ((unsigned char *) &memoryStatus, sizeof (MEMORYSTATUS));
651:
652: /* Get thread and process creation time, exit time, time in kernel
653: mode, and time in user mode in 100ns intervals */
654: handle = GetCurrentThread ();
655: GetThreadTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime);
656: RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME));
657: RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME));
658: RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME));
659: RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME));
660: handle = GetCurrentProcess ();
661: GetProcessTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime);
662: RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME));
663: RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME));
664: RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME));
665: RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME));
666:
667: /* Get the minimum and maximum working set size for the current
668: process */
669: GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
670: &maximumWorkingSetSize);
1.1.1.6 root 671: RandaddInt32 (minimumWorkingSetSize);
672: RandaddInt32 (maximumWorkingSetSize);
1.1 root 673:
674: /* The following are fixed for the lifetime of the process so we only
675: add them once */
676: if (addedFixedItems == 0)
677: {
678: STARTUPINFO startupInfo;
679:
680: /* Get name of desktop, console window title, new window
681: position and size, window flags, and handles for stdin,
682: stdout, and stderr */
683: startupInfo.cb = sizeof (STARTUPINFO);
684: GetStartupInfo (&startupInfo);
685: RandaddBuf ((unsigned char *) &startupInfo, sizeof (STARTUPINFO));
686: addedFixedItems = TRUE;
687: }
688: /* The docs say QPC can fail if appropriate hardware is not
689: available. It works on 486 & Pentium boxes, but hasn't been tested
690: for 386 or RISC boxes */
691: if (QueryPerformanceCounter (&performanceCount))
692: RandaddBuf ((unsigned char *) &performanceCount, sizeof (LARGE_INTEGER));
693: else
694: {
695: /* Millisecond accuracy at best... */
696: DWORD dwTicks = GetTickCount ();
697: RandaddBuf ((unsigned char *) &dwTicks, sizeof (dwTicks));
698: }
1.1.1.4 root 699:
700: // CryptoAPI
1.1.1.6 root 701: if (hCryptProv && CryptGenRandom(hCryptProv, sizeof (buffer), buffer))
1.1.1.4 root 702: RandaddBuf (buffer, sizeof (buffer));
1.1.1.6 root 703:
704: /* Apply the pool mixing function */
705: Randmix();
706:
707: /* Restore the original pool cursor position. If this wasn't done, mouse coordinates
708: could be written to a limited area of the pool, especially when moving the mouse
709: uninterruptedly. The severity of the problem would depend on the length of data
710: written by FastPoll (if it was equal to the size of the pool, mouse coordinates
711: would be written only to a particular 4-byte area, whenever moving the mouse
712: uninterruptedly). */
713: nRandIndex = nOriginalRandIndex;
1.1 root 714: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.