|
|
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
1.1.1.8 ! root 5: contained in this file are Copyright (c) 2004-2006 TrueCrypt Foundation and
1.1.1.6 root 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:
1.1.1.8 ! root 268: BOOL
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);
1.1.1.8 ! root 280:
! 281: return TRUE;
1.1 root 282: }
283:
1.1.1.6 root 284: /* Get len random bytes from the pool (max. RNG_POOL_SIZE bytes per a single call) */
1.1.1.8 ! root 285: BOOL
1.1.1.4 root 286: RandgetBytes (unsigned char *buf, int len, BOOL forceSlowPoll)
1.1 root 287: {
288: int i;
289:
290: EnterCriticalSection (&critRandProt);
291:
1.1.1.2 root 292: if (bDidSlowPoll == FALSE || forceSlowPoll)
1.1 root 293: {
294: bDidSlowPoll = TRUE;
1.1.1.2 root 295: SlowPollWinNT ();
1.1 root 296: }
1.1.1.2 root 297:
298: FastPoll ();
1.1 root 299:
1.1.1.6 root 300: /* There's never more than RNG_POOL_SIZE worth of randomess */
301: if (len > RNG_POOL_SIZE)
302: {
303: Error ("ERR_NOT_ENOUGH_RANDOM_DATA");
304: len = RNG_POOL_SIZE;
305: }
1.1 root 306:
1.1.1.2 root 307: // Requested number of bytes is copied from pool to output buffer,
308: // pool is rehashed, and output buffer is XORed with new data from pool
309: for (i = 0; i < len; i++)
310: {
311: buf[i] = pRandPool[randPoolReadIndex++];
1.1.1.6 root 312: if (randPoolReadIndex == RNG_POOL_SIZE) randPoolReadIndex = 0;
1.1.1.2 root 313: }
314:
1.1.1.6 root 315: /* Invert the pool */
316: for (i = 0; i < RNG_POOL_SIZE / 4; i++)
1.1 root 317: {
1.1.1.6 root 318: ((unsigned __int32 *) pRandPool)[i] = ~((unsigned __int32 *) pRandPool)[i];
1.1 root 319: }
320:
1.1.1.6 root 321: // Mix the pool
1.1.1.4 root 322: FastPoll ();
323:
1.1.1.6 root 324: // XOR the current pool content into the output buffer to prevent pool state leaks
1.1.1.4 root 325: for (i = 0; i < len; i++)
326: {
327: buf[i] ^= pRandPool[randPoolReadIndex++];
1.1.1.6 root 328: if (randPoolReadIndex == RNG_POOL_SIZE) randPoolReadIndex = 0;
1.1.1.4 root 329: }
1.1 root 330:
331: LeaveCriticalSection (&critRandProt);
1.1.1.8 ! root 332: return TRUE;
1.1 root 333: }
334:
335: /* Capture the mouse, and as long as the event is not the same as the last
1.1.1.6 root 336: two events, add the crc of the event, and the crc of the time difference
1.1 root 337: between this event and the last + the current time to the pool */
338: LRESULT CALLBACK
339: MouseProc (int nCode, WPARAM wParam, LPARAM lParam)
340: {
341: static DWORD dwLastTimer;
1.1.1.6 root 342: static unsigned __int32 lastCrc, lastCrc2;
1.1 root 343: MOUSEHOOKSTRUCT *lpMouse = (MOUSEHOOKSTRUCT *) lParam;
344:
345: if (nCode < 0)
346: return CallNextHookEx (hMouse, nCode, wParam, lParam);
347: else
348: {
349: DWORD dwTimer = GetTickCount ();
350: DWORD j = dwLastTimer - dwTimer;
1.1.1.6 root 351: unsigned __int32 crc = 0L;
1.1 root 352: int i;
353:
354: dwLastTimer = dwTimer;
355:
356: for (i = 0; i < sizeof (MOUSEHOOKSTRUCT); i++)
357: {
358: crc = UPDC32 (((unsigned char *) lpMouse)[i], crc);
359: }
360:
361: if (crc != lastCrc && crc != lastCrc2)
362: {
1.1.1.6 root 363: unsigned __int32 timeCrc = 0L;
1.1 root 364:
365: for (i = 0; i < 4; i++)
366: {
367: timeCrc = UPDC32 (((unsigned char *) &j)[i], timeCrc);
368: }
369:
370: for (i = 0; i < 4; i++)
371: {
372: timeCrc = UPDC32 (((unsigned char *) &dwTimer)[i], timeCrc);
373: }
374:
375: EnterCriticalSection (&critRandProt);
1.1.1.6 root 376: RandaddInt32 ((unsigned __int32) (crc + timeCrc));
1.1 root 377: LeaveCriticalSection (&critRandProt);
378: }
379: lastCrc2 = lastCrc;
380: lastCrc = crc;
381:
382: }
383: return 0;
384: }
385:
386: /* Capture the keyboard, as long as the event is not the same as the last two
1.1.1.6 root 387: events, add the crc of the event to the pool along with the crc of the time
1.1 root 388: difference between this event and the last */
389: LRESULT CALLBACK
390: KeyboardProc (int nCode, WPARAM wParam, LPARAM lParam)
391: {
392: static int lLastKey, lLastKey2;
393: static DWORD dwLastTimer;
394: int nKey = (lParam & 0x00ff0000) >> 16;
395: int nCapture = 0;
396:
397: if (nCode < 0)
398: return CallNextHookEx (hMouse, nCode, wParam, lParam);
399:
400: if ((lParam & 0x0000ffff) == 1 && !(lParam & 0x20000000) &&
401: (lParam & 0x80000000))
402: {
403: if (nKey != lLastKey)
404: nCapture = 1; /* Capture this key */
405: else if (nKey != lLastKey2)
406: nCapture = 1; /* Allow for one repeat */
407: }
408: if (nCapture)
409: {
410: DWORD dwTimer = GetTickCount ();
411: DWORD j = dwLastTimer - dwTimer;
1.1.1.6 root 412: unsigned __int32 timeCrc = 0L;
1.1 root 413: int i;
414:
415: dwLastTimer = dwTimer;
416: lLastKey2 = lLastKey;
417: lLastKey = nKey;
418:
419: for (i = 0; i < 4; i++)
420: {
421: timeCrc = UPDC32 (((unsigned char *) &j)[i], timeCrc);
422: }
423:
424: for (i = 0; i < 4; i++)
425: {
426: timeCrc = UPDC32 (((unsigned char *) &dwTimer)[i], timeCrc);
427: }
428:
429: EnterCriticalSection (&critRandProt);
1.1.1.6 root 430: RandaddInt32 ((unsigned __int32) (crc32int(&lParam) + timeCrc));
1.1 root 431: LeaveCriticalSection (&critRandProt);
432: }
433: return 0;
434: }
435:
436: /* This is the thread function which will poll the system for randomness */
437: void
438: ThreadSafeThreadFunction (void *dummy)
439: {
440: if (dummy); /* Remove unused parameter warning */
441:
442: for (;;)
443: {
444: EnterCriticalSection (&critRandProt);
445:
1.1.1.6 root 446: if (bThreadTerminate)
1.1 root 447: {
448: bThreadTerminate = FALSE;
449: LeaveCriticalSection (&critRandProt);
450: _endthread ();
451: }
1.1.1.6 root 452: else if (bFastPollEnabled)
1.1 root 453: {
454: FastPoll ();
455: }
456:
457: LeaveCriticalSection (&critRandProt);
458:
1.1.1.6 root 459: Sleep (500);
1.1 root 460: }
461: }
462:
463: /* Type definitions for function pointers to call NetAPI32 functions */
464:
465: typedef
466: DWORD (WINAPI * NETSTATISTICSGET) (LPWSTR szServer, LPWSTR szService,
467: DWORD dwLevel, DWORD dwOptions,
468: LPBYTE * lpBuffer);
469: typedef
470: DWORD (WINAPI * NETAPIBUFFERSIZE) (LPVOID lpBuffer, LPDWORD cbBuffer);
471: typedef
472: DWORD (WINAPI * NETAPIBUFFERFREE) (LPVOID lpBuffer);
473:
474: NETSTATISTICSGET pNetStatisticsGet = NULL;
475: NETAPIBUFFERSIZE pNetApiBufferSize = NULL;
476: NETAPIBUFFERFREE pNetApiBufferFree = NULL;
477:
478: /* This is the slowpoll function which gathers up network/hard drive
479: performance data for the random pool */
480: void
481: SlowPollWinNT (void)
482: {
483: static int isWorkstation = -1;
484: static int cbPerfData = 0x10000;
485: HANDLE hDevice;
486: LPBYTE lpBuffer;
487: DWORD dwSize, status;
488: LPWSTR lpszLanW, lpszLanS;
1.1.1.4 root 489: int i, nDrive;
1.1 root 490:
491: /* Find out whether this is an NT server or workstation if necessary */
492: if (isWorkstation == -1)
493: {
494: HKEY hKey;
495:
496: if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
497: "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
498: 0, KEY_READ, &hKey) == ERROR_SUCCESS)
499: {
500: unsigned char szValue[32];
501: dwSize = sizeof (szValue);
502:
503: isWorkstation = TRUE;
504: status = RegQueryValueEx (hKey, "ProductType", 0, NULL,
505: szValue, &dwSize);
506:
507: if (status == ERROR_SUCCESS && _stricmp ((char *) szValue, "WinNT"))
508: /* Note: There are (at least) three cases for
509: ProductType: WinNT = NT Workstation,
510: ServerNT = NT Server, LanmanNT = NT Server
511: acting as a Domain Controller */
512: isWorkstation = FALSE;
513:
514: RegCloseKey (hKey);
515: }
516: }
517: /* Initialize the NetAPI32 function pointers if necessary */
518: if (hNetAPI32 == NULL)
519: {
520: /* Obtain a handle to the module containing the Lan Manager
521: functions */
522: hNetAPI32 = LoadLibrary ("NETAPI32.DLL");
523: if (hNetAPI32 != NULL)
524: {
525: /* Now get pointers to the functions */
526: pNetStatisticsGet = (NETSTATISTICSGET) GetProcAddress (hNetAPI32,
527: "NetStatisticsGet");
528: pNetApiBufferSize = (NETAPIBUFFERSIZE) GetProcAddress (hNetAPI32,
529: "NetApiBufferSize");
530: pNetApiBufferFree = (NETAPIBUFFERFREE) GetProcAddress (hNetAPI32,
531: "NetApiBufferFree");
532:
533: /* Make sure we got valid pointers for every NetAPI32
534: function */
535: if (pNetStatisticsGet == NULL ||
536: pNetApiBufferSize == NULL ||
537: pNetApiBufferFree == NULL)
538: {
539: /* Free the library reference and reset the
540: static handle */
541: FreeLibrary (hNetAPI32);
542: hNetAPI32 = NULL;
543: }
544: }
545: }
546:
547: /* Get network statistics. Note: Both NT Workstation and NT Server
548: by default will be running both the workstation and server
549: services. The heuristic below is probably useful though on the
550: assumption that the majority of the network traffic will be via
551: the appropriate service */
552: lpszLanW = (LPWSTR) WIDE ("LanmanWorkstation");
553: lpszLanS = (LPWSTR) WIDE ("LanmanServer");
554: if (hNetAPI32 &&
555: pNetStatisticsGet (NULL,
556: isWorkstation ? lpszLanW : lpszLanS,
557: 0, 0, &lpBuffer) == 0)
558: {
559: pNetApiBufferSize (lpBuffer, &dwSize);
560: RandaddBuf ((unsigned char *) lpBuffer, dwSize);
561: pNetApiBufferFree (lpBuffer);
562: }
563:
564: /* Get disk I/O statistics for all the hard drives */
565: for (nDrive = 0;; nDrive++)
566: {
567: DISK_PERFORMANCE diskPerformance;
568: char szDevice[24];
569:
570: /* Check whether we can access this device */
571: sprintf (szDevice, "\\\\.\\PhysicalDrive%d", nDrive);
572: hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
573: NULL, OPEN_EXISTING, 0, NULL);
574: if (hDevice == INVALID_HANDLE_VALUE)
575: break;
576:
577:
578: /* Note: This only works if you have turned on the disk
579: performance counters with 'diskperf -y'. These counters
580: are off by default */
581: if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
582: &diskPerformance, sizeof (DISK_PERFORMANCE),
583: &dwSize, NULL))
584: {
585: RandaddBuf ((unsigned char *) &diskPerformance, dwSize);
586: }
587: CloseHandle (hDevice);
588: }
589:
1.1.1.4 root 590: // CryptoAPI
1.1.1.7 root 591: for (i = 0; i < 100; i++)
1.1.1.4 root 592: {
1.1.1.6 root 593: if (hCryptProv && CryptGenRandom(hCryptProv, sizeof (buffer), buffer))
1.1.1.4 root 594: RandaddBuf (buffer, sizeof (buffer));
1.1 root 595: }
596:
1.1.1.6 root 597: Randmix();
1.1 root 598: }
599:
600:
1.1.1.6 root 601: /* This is the fastpoll function which gathers up info by calling various api's */
1.1 root 602: void
603: FastPoll (void)
604: {
605: static BOOL addedFixedItems = FALSE;
606: FILETIME creationTime, exitTime, kernelTime, userTime;
607: DWORD minimumWorkingSetSize, maximumWorkingSetSize;
608: LARGE_INTEGER performanceCount;
609: MEMORYSTATUS memoryStatus;
610: HANDLE handle;
611: POINT point;
1.1.1.6 root 612: int nOriginalRandIndex = nRandIndex;
1.1 root 613:
614: /* Get various basic pieces of system information */
1.1.1.6 root 615: RandaddInt32 (GetActiveWindow ()); /* Handle of active window */
616: RandaddInt32 (GetCapture ()); /* Handle of window with mouse
1.1 root 617: capture */
1.1.1.6 root 618: RandaddInt32 (GetClipboardOwner ()); /* Handle of clipboard owner */
619: RandaddInt32 (GetClipboardViewer ()); /* Handle of start of
1.1 root 620: clpbd.viewer list */
1.1.1.6 root 621: RandaddInt32 (GetCurrentProcess ()); /* Pseudohandle of current
1.1 root 622: process */
1.1.1.6 root 623: RandaddInt32 (GetCurrentProcessId ()); /* Current process ID */
624: RandaddInt32 (GetCurrentThread ()); /* Pseudohandle of current
1.1 root 625: thread */
1.1.1.6 root 626: RandaddInt32 (GetCurrentThreadId ()); /* Current thread ID */
627: RandaddInt32 (GetCurrentTime ()); /* Milliseconds since Windows
1.1 root 628: started */
1.1.1.6 root 629: RandaddInt32 (GetDesktopWindow ()); /* Handle of desktop window */
630: RandaddInt32 (GetFocus ()); /* Handle of window with kb.focus */
631: RandaddInt32 (GetInputState ()); /* Whether sys.queue has any events */
632: RandaddInt32 (GetMessagePos ()); /* Cursor pos.for last message */
633: RandaddInt32 (GetMessageTime ()); /* 1 ms time for last message */
634: RandaddInt32 (GetOpenClipboardWindow ()); /* Handle of window with
1.1 root 635: clpbd.open */
1.1.1.6 root 636: RandaddInt32 (GetProcessHeap ()); /* Handle of process heap */
637: RandaddInt32 (GetProcessWindowStation ()); /* Handle of procs
1.1 root 638: window station */
1.1.1.6 root 639: RandaddInt32 (GetQueueStatus (QS_ALLEVENTS)); /* Types of events in
1.1 root 640: input queue */
641:
642: /* Get multiword system information */
643: GetCaretPos (&point); /* Current caret position */
644: RandaddBuf ((unsigned char *) &point, sizeof (POINT));
645: GetCursorPos (&point); /* Current mouse cursor position */
646: RandaddBuf ((unsigned char *) &point, sizeof (POINT));
647:
648: /* Get percent of memory in use, bytes of physical memory, bytes of
649: free physical memory, bytes in paging file, free bytes in paging
650: file, user bytes of address space, and free user bytes */
651: memoryStatus.dwLength = sizeof (MEMORYSTATUS);
652: GlobalMemoryStatus (&memoryStatus);
653: RandaddBuf ((unsigned char *) &memoryStatus, sizeof (MEMORYSTATUS));
654:
655: /* Get thread and process creation time, exit time, time in kernel
656: mode, and time in user mode in 100ns intervals */
657: handle = GetCurrentThread ();
658: GetThreadTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime);
659: RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME));
660: RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME));
661: RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME));
662: RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME));
663: handle = GetCurrentProcess ();
664: GetProcessTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime);
665: RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME));
666: RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME));
667: RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME));
668: RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME));
669:
670: /* Get the minimum and maximum working set size for the current
671: process */
672: GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
673: &maximumWorkingSetSize);
1.1.1.6 root 674: RandaddInt32 (minimumWorkingSetSize);
675: RandaddInt32 (maximumWorkingSetSize);
1.1 root 676:
677: /* The following are fixed for the lifetime of the process so we only
678: add them once */
679: if (addedFixedItems == 0)
680: {
681: STARTUPINFO startupInfo;
682:
683: /* Get name of desktop, console window title, new window
684: position and size, window flags, and handles for stdin,
685: stdout, and stderr */
686: startupInfo.cb = sizeof (STARTUPINFO);
687: GetStartupInfo (&startupInfo);
688: RandaddBuf ((unsigned char *) &startupInfo, sizeof (STARTUPINFO));
689: addedFixedItems = TRUE;
690: }
691: /* The docs say QPC can fail if appropriate hardware is not
692: available. It works on 486 & Pentium boxes, but hasn't been tested
693: for 386 or RISC boxes */
694: if (QueryPerformanceCounter (&performanceCount))
695: RandaddBuf ((unsigned char *) &performanceCount, sizeof (LARGE_INTEGER));
696: else
697: {
698: /* Millisecond accuracy at best... */
699: DWORD dwTicks = GetTickCount ();
700: RandaddBuf ((unsigned char *) &dwTicks, sizeof (dwTicks));
701: }
1.1.1.4 root 702:
703: // CryptoAPI
1.1.1.6 root 704: if (hCryptProv && CryptGenRandom(hCryptProv, sizeof (buffer), buffer))
1.1.1.4 root 705: RandaddBuf (buffer, sizeof (buffer));
1.1.1.6 root 706:
707: /* Apply the pool mixing function */
708: Randmix();
709:
710: /* Restore the original pool cursor position. If this wasn't done, mouse coordinates
711: could be written to a limited area of the pool, especially when moving the mouse
712: uninterruptedly. The severity of the problem would depend on the length of data
713: written by FastPoll (if it was equal to the size of the pool, mouse coordinates
714: would be written only to a particular 4-byte area, whenever moving the mouse
715: uninterruptedly). */
716: nRandIndex = nOriginalRandIndex;
1.1 root 717: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.