1/* rndw32.c - W32 entropy gatherer 2 * Copyright (C) 1999, 2000, 2002, 2003, 2007, 3 * 2010 Free Software Foundation, Inc. 4 * Copyright Peter Gutmann, Matt Thomlinson and Blake Coverett 1996-2006 5 * 6 * This file is part of Libgcrypt. 7 * 8 ************************************************************************* 9 * The code here is based on code from Cryptlib 3.0 beta by Peter Gutmann. 10 * Source file misc/rndwin32.c "Win32 Randomness-Gathering Code" with this 11 * copyright notice: 12 * 13 * This module is part of the cryptlib continuously seeded pseudorandom 14 * number generator. For usage conditions, see lib_rand.c 15 * 16 * [Here is the notice from lib_rand.c, which is now called dev_sys.c] 17 * 18 * This module and the misc/rnd*.c modules represent the cryptlib 19 * continuously seeded pseudorandom number generator (CSPRNG) as described in 20 * my 1998 Usenix Security Symposium paper "The generation of random numbers 21 * for cryptographic purposes". 22 * 23 * The CSPRNG code is copyright Peter Gutmann (and various others) 1996, 24 * 1997, 1998, 1999, all rights reserved. Redistribution of the CSPRNG 25 * modules and use in source and binary forms, with or without modification, 26 * are permitted provided that the following conditions are met: 27 * 28 * 1. Redistributions of source code must retain the above copyright notice 29 * and this permission notice in its entirety. 30 * 31 * 2. Redistributions in binary form must reproduce the copyright notice in 32 * the documentation and/or other materials provided with the distribution. 33 * 34 * 3. A copy of any bugfixes or enhancements made must be provided to the 35 * author, <pgut001@cs.auckland.ac.nz> to allow them to be added to the 36 * baseline version of the code. 37 * 38 * ALTERNATIVELY, the code may be distributed under the terms of the 39 * GNU Lesser General Public License, version 2.1 or any later version 40 * published by the Free Software Foundation, in which case the 41 * provisions of the GNU LGPL are required INSTEAD OF the above 42 * restrictions. 43 * 44 * Although not required under the terms of the LGPL, it would still 45 * be nice if you could make any changes available to the author to 46 * allow a consistent code base to be maintained. 47 ************************************************************************* 48 * The above alternative was changed from GPL to LGPL on 2007-08-22 with 49 * permission from Peter Gutmann: 50 *========== 51 From: pgut001 <pgut001@cs.auckland.ac.nz> 52 Subject: Re: LGPL for the windows entropy gatherer 53 To: wk@gnupg.org 54 Date: Wed, 22 Aug 2007 03:05:42 +1200 55 56 Hi, 57 58 >As of now libgcrypt is GPL under Windows due to that module and some people 59 >would really like to see it under LGPL too. Can you do such a license change 60 >to LGPL version 2? Note that LGPL give the user the option to relicense it 61 >under GPL, so the change would be pretty easy and backwar compatible. 62 63 Sure. I assumed that since GPG was GPLd, you'd prefer the GPL for the entropy 64 code as well, but Ian asked for LGPL as an option so as of the next release 65 I'll have LGPL in there. You can consider it to be retroactive, so your 66 current version will be LGPLd as well. 67 68 Peter. 69 *========== 70 */ 71 72#include <config.h> 73#include <stdio.h> 74#include <stdlib.h> 75#include <errno.h> 76#include <string.h> 77#ifdef __GNUC__ 78#include <stdint.h> 79#endif 80 81#include <windows.h> 82 83 84#include "types.h" 85#include "g10lib.h" 86#include "rand-internal.h" 87 88 89/* Definitions which are missing from the current GNU Windows32Api. */ 90#ifndef IOCTL_DISK_PERFORMANCE 91#define IOCTL_DISK_PERFORMANCE 0x00070020 92#endif 93 94/* This used to be (6*8+5*4+8*2), but Peter Gutmann figured a larger 95 value in a newer release. So we use a far larger value. */ 96#define SIZEOF_DISK_PERFORMANCE_STRUCT 256 97 98/* We don't include wincrypt.h so define it here. */ 99#define HCRYPTPROV HANDLE 100 101 102/* When we query the performance counters, we allocate an initial buffer and 103 * then reallocate it as required until RegQueryValueEx() stops returning 104 * ERROR_MORE_DATA. The following values define the initial buffer size and 105 * step size by which the buffer is increased 106 */ 107#define PERFORMANCE_BUFFER_SIZE 65536 /* Start at 64K */ 108#define PERFORMANCE_BUFFER_STEP 16384 /* Step by 16K */ 109 110 111/* The number of bytes to read from the system RNG on each slow poll. */ 112#define SYSTEMRNG_BYTES 64 113 114/* Intel Chipset CSP type and name */ 115#define PROV_INTEL_SEC 22 116#define INTEL_DEF_PROV "Intel Hardware Cryptographic Service Provider" 117 118 119 120 121/* Type definitions for function pointers to call NetAPI32 functions. */ 122typedef DWORD (WINAPI *NETSTATISTICSGET)(LPWSTR szServer, LPWSTR szService, 123 DWORD dwLevel, DWORD dwOptions, 124 LPBYTE *lpBuffer); 125typedef DWORD (WINAPI *NETAPIBUFFERSIZE)(LPVOID lpBuffer, LPDWORD cbBuffer); 126typedef DWORD (WINAPI *NETAPIBUFFERFREE)(LPVOID lpBuffer); 127 128/* Type definitions for function pointers to call native NT functions. */ 129typedef DWORD (WINAPI *NTQUERYSYSTEMINFORMATION)(DWORD systemInformationClass, 130 PVOID systemInformation, 131 ULONG systemInformationLength, 132 PULONG returnLength); 133typedef DWORD (WINAPI *NTQUERYINFORMATIONPROCESS) 134 (HANDLE processHandle, DWORD processInformationClass, 135 PVOID processInformation, ULONG processInformationLength, 136 PULONG returnLength); 137typedef DWORD (WINAPI *NTPOWERINFORMATION) 138 (DWORD powerInformationClass, PVOID inputBuffer, 139 ULONG inputBufferLength, PVOID outputBuffer, ULONG outputBufferLength ); 140 141/* Type definitions for function pointers to call CryptoAPI functions. */ 142typedef BOOL (WINAPI *CRYPTACQUIRECONTEXT)(HCRYPTPROV *phProv, 143 LPCTSTR pszContainer, 144 LPCTSTR pszProvider, 145 DWORD dwProvType, 146 DWORD dwFlags); 147typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen, 148 BYTE *pbBuffer); 149typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV hProv, DWORD dwFlags); 150 151/* Somewhat alternative functionality available as a direct call, for 152 Windows XP and newer. This is the CryptoAPI RNG, which isn't anywhere 153 near as good as the HW RNG, but we use it if it's present on the basis 154 that at least it can't make things any worse. This direct access version 155 is only available under Windows XP, we don't go out of our way to access 156 the more general CryptoAPI one since the main purpose of using it is to 157 take advantage of any possible future hardware RNGs that may be added, 158 for example via TCPA devices. */ 159typedef BOOL (WINAPI *RTLGENRANDOM)(PVOID RandomBuffer, 160 ULONG RandomBufferLength); 161 162 163 164/* MBM data structures, originally by Alexander van Kaam, converted to C by 165 Anders@Majland.org, finally updated by Chris Zahrt <techn0@iastate.edu> */ 166#define BusType char 167#define SMBType char 168#define SensorType char 169 170typedef struct 171{ 172 SensorType iType; /* Type of sensor. */ 173 int Count; /* Number of sensor for that type. */ 174} SharedIndex; 175 176typedef struct 177{ 178 SensorType ssType; /* Type of sensor */ 179 unsigned char ssName[12]; /* Name of sensor */ 180 char sspadding1[3]; /* Padding of 3 bytes */ 181 double ssCurrent; /* Current value */ 182 double ssLow; /* Lowest readout */ 183 double ssHigh; /* Highest readout */ 184 long ssCount; /* Total number of readout */ 185 char sspadding2[4]; /* Padding of 4 bytes */ 186 long double ssTotal; /* Total amout of all readouts */ 187 char sspadding3[6]; /* Padding of 6 bytes */ 188 double ssAlarm1; /* Temp & fan: high alarm; voltage: % off */ 189 double ssAlarm2; /* Temp: low alarm */ 190} SharedSensor; 191 192typedef struct 193{ 194 short siSMB_Base; /* SMBus base address */ 195 BusType siSMB_Type; /* SMBus/Isa bus used to access chip */ 196 SMBType siSMB_Code; /* SMBus sub type, Intel, AMD or ALi */ 197 char siSMB_Addr; /* Address of sensor chip on SMBus */ 198 unsigned char siSMB_Name[41]; /* Nice name for SMBus */ 199 short siISA_Base; /* ISA base address of sensor chip on ISA */ 200 int siChipType; /* Chip nr, connects with Chipinfo.ini */ 201 char siVoltageSubType; /* Subvoltage option selected */ 202} SharedInfo; 203 204typedef struct 205{ 206 double sdVersion; /* Version number (example: 51090) */ 207 SharedIndex sdIndex[10]; /* Sensor index */ 208 SharedSensor sdSensor[100]; /* Sensor info */ 209 SharedInfo sdInfo; /* Misc.info */ 210 unsigned char sdStart[41]; /* Start time */ 211 212 /* We don't use the next two fields both because they're not random 213 and because it provides a nice safety margin in case of data size 214 mis- estimates (we always under-estimate the buffer size). */ 215#if 0 216 unsigned char sdCurrent[41]; /* Current time */ 217 unsigned char sdPath[256]; /* MBM path */ 218#endif /*0*/ 219} SharedData; 220 221 222 223/* One time intialized handles and function pointers. We use dynamic 224 loading of the DLLs to do without them in case libgcrypt does not 225 need any random. */ 226static HANDLE hNetAPI32; 227static NETSTATISTICSGET pNetStatisticsGet; 228static NETAPIBUFFERSIZE pNetApiBufferSize; 229static NETAPIBUFFERFREE pNetApiBufferFree; 230 231static HANDLE hNTAPI; 232static NTQUERYSYSTEMINFORMATION pNtQuerySystemInformation; 233static NTQUERYINFORMATIONPROCESS pNtQueryInformationProcess; 234static NTPOWERINFORMATION pNtPowerInformation; 235 236static HANDLE hAdvAPI32; 237static CRYPTACQUIRECONTEXT pCryptAcquireContext; 238static CRYPTGENRANDOM pCryptGenRandom; 239static CRYPTRELEASECONTEXT pCryptReleaseContext; 240static RTLGENRANDOM pRtlGenRandom; 241 242 243/* Other module global variables. */ 244static int system_rng_available; /* Whether a system RNG is available. */ 245static HCRYPTPROV hRNGProv; /* Handle to Intel RNG CSP. */ 246 247static int debug_me; /* Debug flag. */ 248 249static int system_is_w2000; /* True if running on W2000. */ 250 251 252 253 254/* Try and connect to the system RNG if there's one present. */ 255static void 256init_system_rng (void) 257{ 258 system_rng_available = 0; 259 hRNGProv = NULL; 260 261 hAdvAPI32 = GetModuleHandle ("AdvAPI32.dll"); 262 if (!hAdvAPI32) 263 return; 264 265 pCryptAcquireContext = (CRYPTACQUIRECONTEXT) 266 GetProcAddress (hAdvAPI32, "CryptAcquireContextA"); 267 pCryptGenRandom = (CRYPTGENRANDOM) 268 GetProcAddress (hAdvAPI32, "CryptGenRandom"); 269 pCryptReleaseContext = (CRYPTRELEASECONTEXT) 270 GetProcAddress (hAdvAPI32, "CryptReleaseContext"); 271 272 /* Get a pointer to the native randomness function if it's available. 273 This isn't exported by name, so we have to get it by ordinal. */ 274 pRtlGenRandom = (RTLGENRANDOM) 275 GetProcAddress (hAdvAPI32, "SystemFunction036"); 276 277 /* Try and connect to the PIII RNG CSP. The AMD 768 southbridge (from 278 the 760 MP chipset) also has a hardware RNG, but there doesn't appear 279 to be any driver support for this as there is for the Intel RNG so we 280 can't do much with it. OTOH the Intel RNG is also effectively dead 281 as well, mostly due to virtually nonexistent support/marketing by 282 Intel, it's included here mostly for form's sake. */ 283 if ( (!pCryptAcquireContext || !pCryptGenRandom || !pCryptReleaseContext 284 || !pCryptAcquireContext (&hRNGProv, NULL, INTEL_DEF_PROV, 285 PROV_INTEL_SEC, 0) ) 286 && !pRtlGenRandom) 287 { 288 hAdvAPI32 = NULL; 289 } 290 else 291 system_rng_available = 1; 292} 293 294 295/* Read data from the system RNG if availavle. */ 296static void 297read_system_rng (void (*add)(const void*, size_t, enum random_origins), 298 enum random_origins requester) 299{ 300 BYTE buffer[ SYSTEMRNG_BYTES + 8 ]; 301 int quality = 0; 302 303 if (!system_rng_available) 304 return; 305 306 /* Read SYSTEMRNG_BYTES bytes from the system RNG. We don't rely on 307 this for all our randomness requirements (particularly the 308 software RNG) in case it's broken in some way. */ 309 if (hRNGProv) 310 { 311 if (pCryptGenRandom (hRNGProv, SYSTEMRNG_BYTES, buffer)) 312 quality = 80; 313 } 314 else if (pRtlGenRandom) 315 { 316 if ( pRtlGenRandom (buffer, SYSTEMRNG_BYTES)) 317 quality = 50; 318 } 319 if (quality > 0) 320 { 321 if (debug_me) 322 log_debug ("rndw32#read_system_rng: got %d bytes of quality %d\n", 323 SYSTEMRNG_BYTES, quality); 324 (*add) (buffer, SYSTEMRNG_BYTES, requester); 325 wipememory (buffer, SYSTEMRNG_BYTES); 326 } 327} 328 329 330/* Read data from MBM. This communicates via shared memory, so all we 331 need to do is map a file and read the data out. */ 332static void 333read_mbm_data (void (*add)(const void*, size_t, enum random_origins), 334 enum random_origins requester) 335{ 336 HANDLE hMBMData; 337 SharedData *mbmDataPtr; 338 339 hMBMData = OpenFileMapping (FILE_MAP_READ, FALSE, "$M$B$M$5$S$D$" ); 340 if (hMBMData) 341 { 342 mbmDataPtr = (SharedData*)MapViewOfFile (hMBMData, FILE_MAP_READ,0,0,0); 343 if (mbmDataPtr) 344 { 345 if (debug_me) 346 log_debug ("rndw32#read_mbm_data: got %d bytes\n", 347 (int)sizeof (SharedData)); 348 (*add) (mbmDataPtr, sizeof (SharedData), requester); 349 UnmapViewOfFile (mbmDataPtr); 350 } 351 CloseHandle (hMBMData); 352 } 353} 354 355 356/* Fallback method using the registry to poll the statistics. */ 357static void 358registry_poll (void (*add)(const void*, size_t, enum random_origins), 359 enum random_origins requester) 360{ 361 static int cbPerfData = PERFORMANCE_BUFFER_SIZE; 362 int iterations; 363 DWORD dwSize, status; 364 PERF_DATA_BLOCK *pPerfData; 365 366 /* Get information from the system performance counters. This can take a 367 few seconds to do. In some environments the call to RegQueryValueEx() 368 can produce an access violation at some random time in the future, in 369 some cases adding a short delay after the following code block makes 370 the problem go away. This problem is extremely difficult to 371 reproduce, I haven't been able to get it to occur despite running it 372 on a number of machines. MS knowledge base article Q178887 covers 373 this type of problem, it's typically caused by an external driver or 374 other program that adds its own values under the 375 HKEY_PERFORMANCE_DATA key. The NT kernel, via Advapi32.dll, calls the 376 required external module to map in the data inside an SEH try/except 377 block, so problems in the module's collect function don't pop up until 378 after it has finished, so the fault appears to occur in Advapi32.dll. 379 There may be problems in the NT kernel as well though, a low-level 380 memory checker indicated that ExpandEnvironmentStrings() in 381 Kernel32.dll, called an interminable number of calls down inside 382 RegQueryValueEx(), was overwriting memory (it wrote twice the 383 allocated size of a buffer to a buffer allocated by the NT kernel). 384 OTOH this could be coming from the external module calling back into 385 the kernel, which eventually causes the problem described above. 386 387 Possibly as an extension of the problem that the krnlWaitSemaphore() 388 call above works around, running two instances of cryptlib (e.g. two 389 applications that use it) under NT4 can result in one of them hanging 390 in the RegQueryValueEx() call. This happens only under NT4 and is 391 hard to reproduce in any consistent manner. 392 393 One workaround that helps a bit is to read the registry as a remote 394 (rather than local) registry, it's possible that the use of a network 395 RPC call isolates the calling app from the problem in that whatever 396 service handles the RPC is taking the hit and not affecting the 397 calling app. Since this would require another round of extensive 398 testing to verify and the NT native API call is working fine, we'll 399 stick with the native API call for now. 400 401 Some versions of NT4 had a problem where the amount of data returned 402 was mis-reported and would never settle down, because of this the code 403 below includes a safety-catch that bails out after 10 attempts have 404 been made, this results in no data being returned but at does ensure 405 that the thread will terminate. 406 407 In addition to these problems the code in RegQueryValueEx() that 408 estimates the amount of memory required to return the performance 409 counter information isn't very accurate (it's much worse than the 410 "slightly-inaccurate" level that the MS docs warn about, it's usually 411 wildly off) since it always returns a worst-case estimate which is 412 usually nowhere near the actual amount required. For example it may 413 report that 128K of memory is required, but only return 64K of data. 414 415 Even worse than the registry-based performance counters is the 416 performance data helper (PDH) shim that tries to make the counters 417 look like the old Win16 API (which is also used by Win95). Under NT 418 this can consume tens of MB of memory and huge amounts of CPU time 419 while it gathers its data, and even running once can still consume 420 about 1/2MB of memory */ 421 if (getenv ("GNUPG_RNDW32_NOPERF")) 422 { 423 static int shown; 424 425 if (!shown) 426 { 427 shown = 1; 428 log_info ("note: get performance data has been disabled\n"); 429 } 430 } 431 else 432 { 433 pPerfData = gcry_xmalloc (cbPerfData); 434 for (iterations=0; iterations < 10; iterations++) 435 { 436 dwSize = cbPerfData; 437 if ( debug_me ) 438 log_debug ("rndw32#slow_gatherer_nt: get perf data\n" ); 439 440 status = RegQueryValueEx (HKEY_PERFORMANCE_DATA, "Global", NULL, 441 NULL, (LPBYTE) pPerfData, &dwSize); 442 if (status == ERROR_SUCCESS) 443 { 444 if (!memcmp (pPerfData->Signature, L"PERF", 8)) 445 (*add) ( pPerfData, dwSize, requester ); 446 else 447 log_debug ("rndw32: no PERF signature\n"); 448 break; 449 } 450 else if (status == ERROR_MORE_DATA) 451 { 452 cbPerfData += PERFORMANCE_BUFFER_STEP; 453 pPerfData = gcry_xrealloc (pPerfData, cbPerfData); 454 } 455 else 456 { 457 static int been_here; 458 459 /* Silence the error message. In particular under Wine (as 460 of 2008) we would get swamped with such diagnotiscs. One 461 such diagnotiscs should be enough. */ 462 if (been_here != status) 463 { 464 been_here = status; 465 log_debug ("rndw32: get performance data problem: ec=%ld\n", 466 status); 467 } 468 break; 469 } 470 } 471 gcry_free (pPerfData); 472 } 473 474 /* Although this isn't documented in the Win32 API docs, it's necessary 475 to explicitly close the HKEY_PERFORMANCE_DATA key after use (it's 476 implicitly opened on the first call to RegQueryValueEx()). If this 477 isn't done then any system components which provide performance data 478 can't be removed or changed while the handle remains active. */ 479 RegCloseKey (HKEY_PERFORMANCE_DATA); 480} 481 482 483static void 484slow_gatherer ( void (*add)(const void*, size_t, enum random_origins), 485 enum random_origins requester ) 486{ 487 static int is_initialized = 0; 488 static int is_workstation = 1; 489 HANDLE hDevice; 490 DWORD dwType, dwSize, dwResult; 491 ULONG ulSize; 492 int drive_no, status; 493 int no_results = 0; 494 void *buffer; 495 496 if ( !is_initialized ) 497 { 498 HKEY hKey; 499 500 if ( debug_me ) 501 log_debug ("rndw32#slow_gatherer: init toolkit\n" ); 502 /* Find out whether this is an NT server or workstation if necessary */ 503 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, 504 "SYSTEM\\CurrentControlSet\\Control\\ProductOptions", 505 0, KEY_READ, &hKey) == ERROR_SUCCESS) 506 { 507 BYTE szValue[32 + 8]; 508 dwSize = 32; 509 510 if ( debug_me ) 511 log_debug ("rndw32#slow_gatherer: check product options\n" ); 512 513 status = RegQueryValueEx (hKey, "ProductType", 0, NULL, 514 szValue, &dwSize); 515 if (status == ERROR_SUCCESS && stricmp (szValue, "WinNT")) 516 { 517 /* Note: There are (at least) three cases for ProductType: 518 WinNT = NT Workstation, ServerNT = NT Server, LanmanNT = 519 NT Server acting as a Domain Controller. */ 520 is_workstation = 0; 521 if ( debug_me ) 522 log_debug ("rndw32: this is a NT server\n"); 523 } 524 RegCloseKey (hKey); 525 } 526 527 /* The following are fixed for the lifetime of the process so we 528 only add them once */ 529 /* readPnPData (); - we have not implemented that. */ 530 531 /* Initialize the NetAPI32 function pointers if necessary */ 532 hNetAPI32 = LoadLibrary ("NETAPI32.DLL"); 533 if (hNetAPI32) 534 { 535 if (debug_me) 536 log_debug ("rndw32#slow_gatherer: netapi32 loaded\n" ); 537 pNetStatisticsGet = (NETSTATISTICSGET) 538 GetProcAddress (hNetAPI32, "NetStatisticsGet"); 539 pNetApiBufferSize = (NETAPIBUFFERSIZE) 540 GetProcAddress (hNetAPI32, "NetApiBufferSize"); 541 pNetApiBufferFree = (NETAPIBUFFERFREE) 542 GetProcAddress (hNetAPI32, "NetApiBufferFree"); 543 544 if (!pNetStatisticsGet || !pNetApiBufferSize || !pNetApiBufferFree) 545 { 546 FreeLibrary (hNetAPI32); 547 hNetAPI32 = NULL; 548 log_debug ("rndw32: No NETAPI found\n" ); 549 } 550 } 551 552 /* Initialize the NT kernel native API function pointers if necessary */ 553 hNTAPI = GetModuleHandle ("NTDll.dll"); 554 if (hNTAPI) 555 { 556 /* Get a pointer to the NT native information query functions */ 557 pNtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION) 558 GetProcAddress (hNTAPI, "NtQuerySystemInformation"); 559 pNtQueryInformationProcess = (NTQUERYINFORMATIONPROCESS) 560 GetProcAddress (hNTAPI, "NtQueryInformationProcess"); 561 pNtPowerInformation = (NTPOWERINFORMATION) 562 GetProcAddress(hNTAPI, "NtPowerInformation"); 563 564 if (!pNtQuerySystemInformation || !pNtQueryInformationProcess) 565 hNTAPI = NULL; 566 } 567 568 569 is_initialized = 1; 570 } 571 572 read_system_rng ( add, requester ); 573 read_mbm_data ( add, requester ); 574 575 /* Get network statistics. Note: Both NT Workstation and NT Server by 576 default will be running both the workstation and server services. The 577 heuristic below is probably useful though on the assumption that the 578 majority of the network traffic will be via the appropriate service. 579 In any case the network statistics return almost no randomness. */ 580 { 581 LPBYTE lpBuffer; 582 583 if (hNetAPI32 584 && !pNetStatisticsGet (NULL, 585 is_workstation ? L"LanmanWorkstation" : 586 L"LanmanServer", 0, 0, &lpBuffer)) 587 { 588 if ( debug_me ) 589 log_debug ("rndw32#slow_gatherer: get netstats\n" ); 590 pNetApiBufferSize (lpBuffer, &dwSize); 591 (*add) ( lpBuffer, dwSize, requester ); 592 pNetApiBufferFree (lpBuffer); 593 } 594 } 595 596 /* Get disk I/O statistics for all the hard drives. 100 is an 597 arbitrary failsafe limit. */ 598 for (drive_no = 0; drive_no < 100 ; drive_no++) 599 { 600 char diskPerformance[SIZEOF_DISK_PERFORMANCE_STRUCT + 8]; 601 char szDevice[50]; 602 603 /* Check whether we can access this device. */ 604 snprintf (szDevice, sizeof szDevice, "\\\\.\\PhysicalDrive%d", 605 drive_no); 606 hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 607 NULL, OPEN_EXISTING, 0, NULL); 608 if (hDevice == INVALID_HANDLE_VALUE) 609 break; /* No more drives. */ 610 611 /* Note: This only works if you have turned on the disk performance 612 counters with 'diskperf -y'. These counters are off by default. */ 613 dwSize = sizeof diskPerformance; 614 if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, 615 diskPerformance, SIZEOF_DISK_PERFORMANCE_STRUCT, 616 &dwSize, NULL)) 617 { 618 if ( debug_me ) 619 log_debug ("rndw32#slow_gatherer: iostat drive %d\n", 620 drive_no); 621 (*add) (diskPerformance, dwSize, requester); 622 } 623 else 624 { 625 log_info ("NOTE: you should run 'diskperf -y' " 626 "to enable the disk statistics\n"); 627 } 628 CloseHandle (hDevice); 629 } 630 631 /* In theory we should be using the Win32 performance query API to obtain 632 unpredictable data from the system, however this is so unreliable (see 633 the multiple sets of comments in registryPoll()) that it's too risky 634 to rely on it except as a fallback in emergencies. Instead, we rely 635 mostly on the NT native API function NtQuerySystemInformation(), which 636 has the dual advantages that it doesn't have as many (known) problems 637 as the Win32 equivalent and that it doesn't access the data indirectly 638 via pseudo-registry keys, which means that it's much faster. Note 639 that the Win32 equivalent actually works almost all of the time, the 640 problem is that on one or two systems it can fail in strange ways that 641 are never the same and can't be reproduced on any other system, which 642 is why we use the native API here. Microsoft officially documented 643 this function in early 2003, so it'll be fairly safe to use. */ 644 if ( !hNTAPI ) 645 { 646 registry_poll (add, requester); 647 return; 648 } 649 650 651 /* Scan the first 64 possible information types (we don't bother with 652 increasing the buffer size as we do with the Win32 version of the 653 performance data read, we may miss a few classes but it's no big deal). 654 This scan typically yields around 20 pieces of data, there's nothing 655 in the range 65...128 so chances are there won't be anything above 656 there either. */ 657 buffer = gcry_xmalloc (PERFORMANCE_BUFFER_SIZE); 658 for (dwType = 0; dwType < 64; dwType++) 659 { 660 switch (dwType) 661 { 662 /* ID 17 = SystemObjectInformation hangs on some win2k systems. */ 663 case 17: 664 if (system_is_w2000) 665 continue; 666 break; 667 668 /* Some information types are write-only (the IDs are shared with 669 a set-information call), we skip these. */ 670 case 26: case 27: case 38: case 46: case 47: case 48: case 52: 671 continue; 672 673 /* ID 53 = SystemSessionProcessInformation reads input from the 674 output buffer, which has to contain a session ID and pointer 675 to the actual buffer in which to store the session information. 676 Because this isn't a standard query, we skip this. */ 677 case 53: 678 continue; 679 } 680 681 /* Query the info for this ID. Some results (for example for 682 ID = 6, SystemCallCounts) are only available in checked builds 683 of the kernel. A smaller subcless of results require that 684 certain system config flags be set, for example 685 SystemObjectInformation requires that the 686 FLG_MAINTAIN_OBJECT_TYPELIST be set in NtGlobalFlags. To avoid 687 having to special-case all of these, we try reading each one and 688 only use those for which we get a success status. */ 689 dwResult = pNtQuerySystemInformation (dwType, buffer, 690 PERFORMANCE_BUFFER_SIZE - 2048, 691 &ulSize); 692 if (dwResult != ERROR_SUCCESS) 693 continue; 694 695 /* Some calls (e.g. ID = 23, SystemProcessorStatistics, and ID = 24, 696 SystemDpcInformation) incorrectly return a length of zero, so we 697 manually adjust the length to the correct value. */ 698 if ( !ulSize ) 699 { 700 if (dwType == 23) 701 ulSize = 6 * sizeof (ULONG); 702 else if (dwType == 24) 703 ulSize = 5 * sizeof (ULONG); 704 } 705 706 /* If we got some data back, add it to the entropy pool. */ 707 if (ulSize > 0 && ulSize <= PERFORMANCE_BUFFER_SIZE - 2048) 708 { 709 if (debug_me) 710 log_debug ("rndw32#slow_gatherer: %lu bytes from sysinfo %ld\n", 711 ulSize, dwType); 712 (*add) (buffer, ulSize, requester); 713 no_results++; 714 } 715 } 716 717 /* Now we would do the same for the process information. This 718 call would rather ugly in that it requires an exact length 719 match for the data returned, failing with a 720 STATUS_INFO_LENGTH_MISMATCH error code (0xC0000004) if the 721 length isn't an exact match. It requires a compiler to handle 722 complex nested structs, alignment issues, and so on, and 723 without the headers in which the entries are declared it's 724 almost impossible to do. Thus we don't. */ 725 726 727 /* Finally, do the same for the system power status information. There 728 are only a limited number of useful information types available so we 729 restrict ourselves to the useful types. In addition since this 730 function doesn't return length information, we have to hardcode in 731 length data. */ 732 if (pNtPowerInformation) 733 { 734 static const struct { int type; int size; } powerInfo[] = { 735 { 0, 128 }, /* SystemPowerPolicyAc */ 736 { 1, 128 }, /* SystemPowerPolicyDc */ 737 { 4, 64 }, /* SystemPowerCapabilities */ 738 { 5, 48 }, /* SystemBatteryState */ 739 { 11, 48 }, /* ProcessorInformation */ 740 { 12, 24 }, /* SystemPowerInformation */ 741 { -1, -1 } 742 }; 743 int i; 744 745 /* The 100 is a failsafe limit. */ 746 for (i = 0; powerInfo[i].type != -1 && i < 100; i++ ) 747 { 748 /* Query the info for this ID */ 749 dwResult = pNtPowerInformation (powerInfo[i].type, NULL, 0, buffer, 750 PERFORMANCE_BUFFER_SIZE - 2048); 751 if (dwResult != ERROR_SUCCESS) 752 continue; 753 if (debug_me) 754 log_debug ("rndw32#slow_gatherer: %u bytes from powerinfo %d\n", 755 powerInfo[i].size, i); 756 (*add) (buffer, powerInfo[i].size, requester); 757 no_results++; 758 } 759 gcry_assert (i < 100); 760 } 761 gcry_free (buffer); 762 763 /* We couldn't get enough results from the kernel, fall back to the 764 somewhat troublesome registry poll. */ 765 if (no_results < 15) 766 registry_poll (add, requester); 767} 768 769 770int 771_gcry_rndw32_gather_random (void (*add)(const void*, size_t, 772 enum random_origins), 773 enum random_origins origin, 774 size_t length, int level ) 775{ 776 static int is_initialized; 777 778 if (!level) 779 return 0; 780 781 /* We don't differentiate between level 1 and 2 here because there 782 is no internal entropy pool as a scary resource. It may all work 783 slower, but because our entropy source will never block but 784 deliver some not easy to measure entropy, we assume level 2. */ 785 786 if (!is_initialized) 787 { 788 OSVERSIONINFO osvi = { sizeof( osvi ) }; 789 790 GetVersionEx( &osvi ); 791 if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) 792 log_fatal ("can only run on a Windows NT platform\n" ); 793 system_is_w2000 = (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0); 794 init_system_rng (); 795 is_initialized = 1; 796 } 797 798 if (debug_me) 799 log_debug ("rndw32#gather_random: ori=%d len=%u lvl=%d\n", 800 origin, (unsigned int)length, level ); 801 802 slow_gatherer (add, origin); 803 804 return 0; 805} 806 807 808 809void 810_gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t, 811 enum random_origins), 812 enum random_origins origin) 813{ 814 static int addedFixedItems = 0; 815 816 if ( debug_me ) 817 log_debug ("rndw32#gather_random_fast: ori=%d\n", origin ); 818 819 /* Get various basic pieces of system information: Handle of active 820 window, handle of window with mouse capture, handle of clipboard 821 owner handle of start of clpboard viewer list, pseudohandle of 822 current process, current process ID, pseudohandle of current 823 thread, current thread ID, handle of desktop window, handle of 824 window with keyboard focus, whether system queue has any events, 825 cursor position for last message, 1 ms time for last message, 826 handle of window with clipboard open, handle of process heap, 827 handle of procs window station, types of events in input queue, 828 and milliseconds since Windows was started. */ 829 830 { 831 byte buffer[20*sizeof(ulong)], *bufptr; 832 833 bufptr = buffer; 834#define ADD(f) do { ulong along = (ulong)(f); \ 835 memcpy (bufptr, &along, sizeof (along) ); \ 836 bufptr += sizeof (along); \ 837 } while (0) 838 839 ADD ( GetActiveWindow ()); 840 ADD ( GetCapture ()); 841 ADD ( GetClipboardOwner ()); 842 ADD ( GetClipboardViewer ()); 843 ADD ( GetCurrentProcess ()); 844 ADD ( GetCurrentProcessId ()); 845 ADD ( GetCurrentThread ()); 846 ADD ( GetCurrentThreadId ()); 847 ADD ( GetDesktopWindow ()); 848 ADD ( GetFocus ()); 849 ADD ( GetInputState ()); 850 ADD ( GetMessagePos ()); 851 ADD ( GetMessageTime ()); 852 ADD ( GetOpenClipboardWindow ()); 853 ADD ( GetProcessHeap ()); 854 ADD ( GetProcessWindowStation ()); 855 ADD ( GetQueueStatus (QS_ALLEVENTS)); 856 ADD ( GetTickCount ()); 857 858 gcry_assert ( bufptr-buffer < sizeof (buffer) ); 859 (*add) ( buffer, bufptr-buffer, origin ); 860#undef ADD 861 } 862 863 /* Get multiword system information: Current caret position, current 864 mouse cursor position. */ 865 { 866 POINT point; 867 868 GetCaretPos (&point); 869 (*add) ( &point, sizeof (point), origin ); 870 GetCursorPos (&point); 871 (*add) ( &point, sizeof (point), origin ); 872 } 873 874 /* Get percent of memory in use, bytes of physical memory, bytes of 875 free physical memory, bytes in paging file, free bytes in paging 876 file, user bytes of address space, and free user bytes. */ 877 { 878 MEMORYSTATUS memoryStatus; 879 880 memoryStatus.dwLength = sizeof (MEMORYSTATUS); 881 GlobalMemoryStatus (&memoryStatus); 882 (*add) ( &memoryStatus, sizeof (memoryStatus), origin ); 883 } 884 885 /* Get thread and process creation time, exit time, time in kernel 886 mode, and time in user mode in 100ns intervals. */ 887 { 888 HANDLE handle; 889 FILETIME creationTime, exitTime, kernelTime, userTime; 890 DWORD minimumWorkingSetSize, maximumWorkingSetSize; 891 892 handle = GetCurrentThread (); 893 GetThreadTimes (handle, &creationTime, &exitTime, 894 &kernelTime, &userTime); 895 (*add) ( &creationTime, sizeof (creationTime), origin ); 896 (*add) ( &exitTime, sizeof (exitTime), origin ); 897 (*add) ( &kernelTime, sizeof (kernelTime), origin ); 898 (*add) ( &userTime, sizeof (userTime), origin ); 899 900 handle = GetCurrentProcess (); 901 GetProcessTimes (handle, &creationTime, &exitTime, 902 &kernelTime, &userTime); 903 (*add) ( &creationTime, sizeof (creationTime), origin ); 904 (*add) ( &exitTime, sizeof (exitTime), origin ); 905 (*add) ( &kernelTime, sizeof (kernelTime), origin ); 906 (*add) ( &userTime, sizeof (userTime), origin ); 907 908 /* Get the minimum and maximum working set size for the current 909 process. */ 910 GetProcessWorkingSetSize (handle, &minimumWorkingSetSize, 911 &maximumWorkingSetSize); 912 (*add) ( &minimumWorkingSetSize, 913 sizeof (minimumWorkingSetSize), origin ); 914 (*add) ( &maximumWorkingSetSize, 915 sizeof (maximumWorkingSetSize), origin ); 916 } 917 918 919 /* The following are fixed for the lifetime of the process so we only 920 * add them once */ 921 if (!addedFixedItems) 922 { 923 STARTUPINFO startupInfo; 924 925 /* Get name of desktop, console window title, new window 926 position and size, window flags, and handles for stdin, 927 stdout, and stderr. */ 928 startupInfo.cb = sizeof (STARTUPINFO); 929 GetStartupInfo (&startupInfo); 930 (*add) ( &startupInfo, sizeof (STARTUPINFO), origin ); 931 addedFixedItems = 1; 932 } 933 934 /* The performance of QPC varies depending on the architecture it's 935 running on and on the OS, the MS documentation is vague about the 936 details because it varies so much. Under Win9x/ME it reads the 937 1.193180 MHz PIC timer. Under NT/Win2K/XP it may or may not read the 938 64-bit TSC depending on the HAL and assorted other circumstances, 939 generally on machines with a uniprocessor HAL 940 KeQueryPerformanceCounter() uses a 3.579545MHz timer and on machines 941 with a multiprocessor or APIC HAL it uses the TSC (the exact time 942 source is controlled by the HalpUse8254 flag in the kernel). That 943 choice of time sources is somewhat peculiar because on a 944 multiprocessor machine it's theoretically possible to get completely 945 different TSC readings depending on which CPU you're currently 946 running on, while for uniprocessor machines it's not a problem. 947 However, the kernel appears to synchronise the TSCs across CPUs at 948 boot time (it resets the TSC as part of its system init), so this 949 shouldn't really be a problem. Under WinCE it's completely platform- 950 dependant, if there's no hardware performance counter available, it 951 uses the 1ms system timer. 952 953 Another feature of the TSC (although it doesn't really affect us here) 954 is that mobile CPUs will turn off the TSC when they idle, Pentiums 955 will change the rate of the counter when they clock-throttle (to 956 match the current CPU speed), and hyperthreading Pentiums will turn 957 it off when both threads are idle (this more or less makes sense, 958 since the CPU will be in the halted state and not executing any 959 instructions to count). 960 961 To make things unambiguous, we detect a CPU new enough to call RDTSC 962 directly by checking for CPUID capabilities, and fall back to QPC if 963 this isn't present. */ 964#ifdef __GNUC__ 965/* FIXME: We would need to implement the CPU feature tests first. */ 966/* if (cpu_has_feature_rdtsc) */ 967/* { */ 968/* uint32_t lo, hi; */ 969 /* We cannot use "=A", since this would use %rax on x86_64. */ 970/* __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); */ 971 /* Ignore high 32 bits, hwich are >1s res. */ 972/* (*add) (&lo, 4, origin ); */ 973/* } */ 974/* else */ 975#endif /*!__GNUC__*/ 976 { 977 LARGE_INTEGER performanceCount; 978 979 if (QueryPerformanceCounter (&performanceCount)) 980 { 981 if ( debug_me ) 982 log_debug ("rndw32#gather_random_fast: perf data\n"); 983 (*add) (&performanceCount, sizeof (performanceCount), origin); 984 } 985 else 986 { 987 /* Millisecond accuracy at best... */ 988 DWORD aword = GetTickCount (); 989 (*add) (&aword, sizeof (aword), origin ); 990 } 991 } 992 993 994} 995