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