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