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