cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
win32.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * Win32 Randomness-Gathering Code *
4 * Copyright Peter Gutmann, Matt Thomlinson and Blake Coverett 1996-2010 *
5 * *
6 ****************************************************************************/
7 
8 /* This module is part of the cryptlib continuously seeded pseudorandom number
9  generator. For usage conditions, see random.c */
10 
11 /* General includes */
12 
13 #include "crypt.h"
14 #include "random/random.h"
15 
16 /* OS-specific includes */
17 
18 #include <tlhelp32.h>
19 #include <winperf.h>
20 #include <winioctl.h>
21 #include <process.h>
22 
23 /* Some new CPU opcodes aren't supported by all compiler versions, if
24  they're not available we define them here. BC++ can only handle the
25  emit directive outside an asm block, so we have to terminate the current
26  block, emit the opcode, and then restart the asm block. In addition
27  while the 16-bit versions of BC++ had built-in asm support, the 32-bit
28  versions removed it and generate a temporary asm file which is passed
29  to Tasm32. This is only included with some high-end versions of BC++
30  and it's not possible to order it separately, so if you're building with
31  BC++ and get error messages about a missing tasm32.exe, add NO_ASM to
32  Project Options | Compiler | Defines */
33 
34 #if defined( _MSC_VER )
35  #if _MSC_VER <= 1100
36  #define cpuid __asm _emit 0x0F __asm _emit 0xA2
37  #define rdtsc __asm _emit 0x0F __asm _emit 0x31
38  #endif /* VC++ 5.0 or earlier */
39  #define xstore_rng __asm _emit 0x0F __asm _emit 0xA7 __asm _emit 0xC0
40  #define rdrand_eax __asm _emit 0x0F __asm _emit 0xC7 __asm _emit 0xF0
41 #endif /* VC++ */
42 #if defined __BORLANDC__
43  #define cpuid } __emit__( 0x0F, 0xA2 ); __asm {
44  #define rdtsc } __emit__( 0x0F, 0x31 ); __asm {
45  #define xstore_rng } __emit__( 0x0F, 0xA7, 0xC0 ); __asm {
46  #define rdrand_eax } __emit__( 0x0F, 0xC7, 0xF0 ); __asm {
47 #endif /* BC++ */
48 
49 /* Map a value that may be 32 or 64 bits depending on the platform to a
50  long */
51 
52 #if defined( _MSC_VER ) && ( _MSC_VER >= 1400 )
53  #define addRandomHandle( randomState, handle ) \
54  addRandomLong( randomState, PtrToUlong( handle ) )
55 #else
56  #define addRandomHandle addRandomValue
57 #endif /* 32- vs. 64-bit VC++ */
58 
59 /* The size of the intermediate buffer used to accumulate polled data */
60 
61 #define RANDOM_BUFSIZE 4096
62 #if RANDOM_BUFSIZE > MAX_INTLENGTH_SHORT
63  #error RANDOM_BUFSIZE exceeds randomness accumulator size
64 #endif /* RANDOM_BUFSIZE > MAX_INTLENGTH_SHORT */
65 
66 /* Handles to various randomness objects */
67 
68 static HANDLE hAdvAPI32; /* Handle to misc.library */
69 static HANDLE hNetAPI32; /* Handle to networking library */
70 static HANDLE hNTAPI; /* Handle to NT kernel library */
71 static HANDLE hThread; /* Background polling thread handle */
72 static unsigned int threadID; /* Background polling thread ID */
73 
74 /****************************************************************************
75 * *
76 * System RNG Interface *
77 * *
78 ****************************************************************************/
79 
80 /* The number of bytes to read from the system RNG on each slow poll */
81 
82 #define SYSTEMRNG_BYTES 64
83 
84 /* Intel Chipset CSP type and name */
85 
86 #define PROV_INTEL_SEC 22
87 #define INTEL_DEF_PROV "Intel Hardware Cryptographic Service Provider"
88 
89 /* A mapping from CryptoAPI to standard data types */
90 
91 #define HCRYPTPROV HANDLE
92 
93 /* Type definitions for function pointers to call CryptoAPI functions */
94 
95 typedef BOOL ( WINAPI *CRYPTACQUIRECONTEXT )( HCRYPTPROV *phProv,
96  LPCTSTR pszContainer,
97  LPCTSTR pszProvider, DWORD dwProvType,
98  DWORD dwFlags );
99 typedef BOOL ( WINAPI *CRYPTGENRANDOM )( HCRYPTPROV hProv, DWORD dwLen,
100  BYTE *pbBuffer );
101 typedef BOOL ( WINAPI *CRYPTRELEASECONTEXT )( HCRYPTPROV hProv, DWORD dwFlags );
102 
103 /* Somewhat alternative functionality available as a direct call, for
104  Windows XP and newer. This is the CryptoAPI RNG, which isn't anywhere
105  near as good as the HW RNG, but we use it if it's present on the basis
106  that at least it can't make things any worse. This direct access version
107  is only available under Windows XP and newer, we don't go out of our way
108  to access the more general CryptoAPI one since the main purpose of using
109  it is to take advantage of any possible future hardware RNGs that may be
110  added, for example via TCPA devices */
111 
112 typedef BOOL ( WINAPI *RTLGENRANDOM )( PVOID RandomBuffer,
114 
115 /* Global function pointers. These are necessary because the functions need
116  to be dynamically linked since older versions of Win95 and NT don't contain
117  them */
118 
119 static CRYPTACQUIRECONTEXT pCryptAcquireContext = NULL;
120 static CRYPTGENRANDOM pCryptGenRandom = NULL;
121 static CRYPTRELEASECONTEXT pCryptReleaseContext = NULL;
122 static RTLGENRANDOM pRtlGenRandom = NULL;
123 
124 /* Handle to the RNG CSP */
125 
126 static BOOLEAN systemRngAvailable; /* Whether system RNG is available */
127 static HCRYPTPROV hProv; /* Handle to Intel RNG CSP */
128 
129 /* Try and connect to the system RNG if there's one present. In theory we
130  could also try and get data from a TPM if there's one present, but the
131  TPM functions are only available under Vista (so they'd have to be
132  dynamically bound), the chances of a TPM being present and accessible
133  are pretty slim, and since we have to talk to the TPM at the raw APDU
134  level (not to mention all the horror stories in the MSDN forums about
135  getting any of this stuff to work) the amount of effort required versus
136  the potential gain really doesn't make it worthwhile:
137 
138  #include <tbs.h>
139 
140  TBS_HCONTEXT hTbsContext;
141  TBS_CONTEXT_PARAMS tbsContextParams;
142  HRESULT hResult;
143 
144  // Include dynamic-linking management for all functions
145 
146  // Get a handle to the TBS interface
147  memset( &tspContextParams, 0, sizeof( TBS_CONTEXT_PARAMS ) );
148  tspContextParams.version = TBS_CONTEXT_VERSION_ONE;
149  result = Tbsi_Context_Create( &tbsContextParams, &hTbsContext );
150  if( SUCCEEDED( hResult ) )
151  {
152  BYTE tpmCommand[] = {
153  0x00, 0xC1, // WORD: TPM_TAG_RQU_COMMAND
154  0x00, 0x00, 0x00, 0x0E, // LONG: Total packet length
155  0x00, 0x00, 0x00, 0x46, // LONG: Command TPM_ORD_GetRandom
156  0x00, 0x00, 0x00, 0x20 // Data: Get 0x20 bytes
157  BYTE buffer[ 14 + 32 + 8 ];
158  int length;
159 
160  hResult = Tbsip_Submit_Command( hTbsContext,
161  TBS_COMMAND_LOCALITY_ZERO,
162  TBS_COMMAND_PRIORITY_NORMAL,
163  tpmCommand, 14, buffer, &length );
164  if( SUCCEEDED( hResult ) )
165  {
166  // Start of buffer contains the 14 bytes of returned command
167  // followed by 32 bytes of random data
168  }
169  Tbsip_Context_Close( hTbsContext );
170  } */
171 
172 static void initSystemRNG( void )
173  {
174  systemRngAvailable = FALSE;
175  hProv = NULL;
176  if( ( hAdvAPI32 = GetModuleHandle( "AdvAPI32.dll" ) ) == NULL )
177  return;
178 
179  /* Get pointers to the CSP functions. Although the acquire context
180  function looks like a standard function, it's actually a macro which
181  is mapped to (depending on the build type) CryptAcquireContextA or
182  CryptAcquireContextW, so we access it under the straight-ASCII-
183  function name */
184  pCryptAcquireContext = ( CRYPTACQUIRECONTEXT ) GetProcAddress( hAdvAPI32,
185  "CryptAcquireContextA" );
186  pCryptGenRandom = ( CRYPTGENRANDOM ) GetProcAddress( hAdvAPI32,
187  "CryptGenRandom" );
188  pCryptReleaseContext = ( CRYPTRELEASECONTEXT ) GetProcAddress( hAdvAPI32,
189  "CryptReleaseContext" );
190 
191  /* Get a pointer to the native randomness function if it's available.
192  This isn't exported by name, so we have to get it by ordinal */
193  pRtlGenRandom = ( RTLGENRANDOM ) GetProcAddress( hAdvAPI32,
194  "SystemFunction036" );
195 
196  /* Try and connect to the PIII RNG CSP. The AMD 768 southbridge (from
197  the 760 MP chipset) also has a hardware RNG, but there doesn't appear
198  to be any driver support for this as there is for the Intel RNG so we
199  can't do much with it. OTOH the Intel RNG is also effectively dead
200  as well, mostly due to virtually nonexistant support/marketing by
201  Intel, it's included here mostly for form's sake */
202  if( ( pCryptAcquireContext == NULL || \
203  pCryptGenRandom == NULL || pCryptReleaseContext == NULL || \
204  pCryptAcquireContext( &hProv, NULL, INTEL_DEF_PROV,
205  PROV_INTEL_SEC, 0 ) == FALSE ) && \
206  ( pRtlGenRandom == NULL ) )
207  {
208  hAdvAPI32 = NULL;
209  hProv = NULL;
210  }
211  else
212  {
213  /* Remember that we have a system RNG available for use */
214  systemRngAvailable = TRUE;
215  }
216  }
217 
218 /* Read data from the system RNG, in theory the PIII hardware RNG but in
219  practice more likely the CryptoAPI software RNG */
220 
221 static void readSystemRNG( void )
222  {
223  BYTE buffer[ SYSTEMRNG_BYTES + 8 ];
224  int quality = 0;
225 
226  if( !systemRngAvailable )
227  return;
228 
229  /* Read SYSTEMRNG_BYTES bytes from the system RNG. Rather presciently,
230  the code up until late 2007 stated that "We don't rely on this for
231  all our randomness requirements (particularly the software RNG) in
232  case it's broken in some way", and in November 2007 an analysis paper
233  by Leo Dorrendorf, Zvi Gutterman, and Benny Pinkas showed that the
234  CryptoAPI RNG is indeed broken, being neither forwards- nor
235  backwards-secure, being reseeded far too infrequently, and (as far as
236  their reverse-engineering was able to tell) using far less entropy
237  sources than cryptlib's built-in mechanisms even though the CryptoAPI
238  one is deeply embedded in the OS.
239 
240  The way the CryptoAPI RNG works is that a system RNG is used to key
241  a set of eight RC4 ciphers, each of which is used in turn in a round-
242  robin fashion to output 20 bytes of randomness which are then hashed
243  with SHA1, with the operation being approximately:
244 
245  output[ 0...19 ] = SHA1( RC4[ i++ % 8 ] );
246  output[ 20...39 ] = SHA1( RC4[ i++ % 8 ] );
247  [...]
248 
249  Each RC4 cipher is re-keyed every 16KB of output, so for 8 ciphers
250  the rekey interval is every 128KB of output. Furthermore, although
251  the kernel RNG used to key the RC4 ciphers stores its state in-
252  kernel, the RC4 cipher state is stored in user-space and per-process.
253  This means that in most cases the RNG is never re-keyed. Finally,
254  the way the RNG works means that it's possible to recover earlier
255  state in O( 2^23 ). See "Cryptanalysis of the Random Number
256  Generator of the Windows Operating System" for details */
257  if( hProv != NULL )
258  {
259  if( pCryptGenRandom( hProv, SYSTEMRNG_BYTES, buffer ) )
260  quality = 70;
261  }
262  else
263  {
264  if( pRtlGenRandom( buffer, SYSTEMRNG_BYTES ) )
265  quality = 30;
266  }
267  if( quality > 0 )
268  {
270  int status;
271 
272  setMessageData( &msgData, buffer, SYSTEMRNG_BYTES );
274  IMESSAGE_SETATTRIBUTE_S, &msgData,
275  CRYPT_IATTRIBUTE_ENTROPY );
276  if( cryptStatusOK( status ) )
277  {
280  ( MESSAGE_CAST ) &quality,
281  CRYPT_IATTRIBUTE_ENTROPY_QUALITY );
282  }
283  zeroise( buffer, SYSTEMRNG_BYTES );
284  }
285  }
286 
287 /* Clean up the system RNG access */
288 
289 static void endSystemRNG( void )
290  {
291  if( hProv != NULL )
292  {
293  pCryptReleaseContext( hProv, 0 );
294  hProv = NULL;
295  }
296  }
297 
298 /****************************************************************************
299 * *
300 * Hardware Monitoring Interface *
301 * *
302 ****************************************************************************/
303 
304 /* These interfaces currently support data supplied by MBM, Everest,
305  SysTool, RivaTuner, HMonitor, ATI Tray Tools, CoreTemp, and GPU-Z. Two
306  notable omissions are SVPro and HWMonitor, unfortunately the authors
307  haven't responded to any requests for interfacing information */
308 
309 /* MBM data structures, originally by Alexander van Kaam, converted to C by
310  [email protected], finally updated by Chris Zahrt <[email protected]>.
311  The __int64 values below are actually (64-bit) doubles, but we overlay
312  them with __int64s since we don't care about the values */
313 
314 #define BusType char
315 #define SMBType char
316 #define SensorType char
317 
318 typedef struct {
319  SensorType iType; /* Type of sensor */
320  int Count; /* Number of sensor for that type */
321  } SharedIndex;
322 
323 typedef struct {
324  SensorType ssType; /* Type of sensor */
325  unsigned char ssName[ 12 ]; /* Name of sensor */
326  char sspadding1[ 3 ]; /* Padding of 3 bytes */
327  __int64 /*double*/ ssCurrent;/* Current value */
328  __int64 /*double*/ ssLow; /* Lowest readout */
329  __int64 /*double*/ ssHigh; /* Highest readout */
330  long ssCount; /* Total number of readout */
331  char sspadding2[ 4 ]; /* Padding of 4 bytes */
332  BYTE /*long double*/ ssTotal[ 8 ]; /* Total amout of all readouts */
333  char sspadding3[ 6 ]; /* Padding of 6 bytes */
334  __int64 /*double*/ ssAlarm1;/* Temp & fan: high alarm; voltage: % off */
335  __int64 /*double*/ ssAlarm2;/* Temp: low alarm */
336  } SharedSensor;
337 
338 typedef struct {
339  short siSMB_Base; /* SMBus base address */
340  BusType siSMB_Type; /* SMBus/Isa bus used to access chip */
341  SMBType siSMB_Code; /* SMBus sub type, Intel, AMD or ALi */
342  char siSMB_Addr; /* Address of sensor chip on SMBus */
343  unsigned char siSMB_Name[ 41 ]; /* Nice name for SMBus */
344  short siISA_Base; /* ISA base address of sensor chip on ISA */
345  int siChipType; /* Chip nr, connects with Chipinfo.ini */
346  char siVoltageSubType; /* Subvoltage option selected */
347  } SharedInfo;
348 
349 typedef struct {
350  __int64 /*double*/ sdVersion;/* Version number (example: 51090) */
351  SharedIndex sdIndex[ 10 ]; /* Sensor index */
352  SharedSensor sdSensor[ 100 ]; /* Sensor info */
353  SharedInfo sdInfo; /* Misc.info */
354  unsigned char sdStart[ 41 ]; /* Start time */
355  /* We don't use the next two fields both because they're not random and
356  because it provides a nice safety margin in case of data size mis-
357  estimates (we always under-estimate the buffer size) */
358 /* unsigned char sdCurrent[ 41 ]; /* Current time */
359 /* unsigned char sdPath[ 256 ]; /* MBM path */
360  } SharedData;
361 
362 /* Read data from MBM via the shared-memory interface */
363 
364 static void readMBMData( void )
365  {
366  HANDLE hMBMData;
367  const SharedData *mbmDataPtr;
368 
369  if( ( hMBMData = OpenFileMapping( FILE_MAP_READ, FALSE,
370  "$M$B$M$5$S$D$" ) ) == NULL )
371  return;
372  if( ( mbmDataPtr = ( SharedData * ) \
373  MapViewOfFile( hMBMData, FILE_MAP_READ, 0, 0, 0 ) ) != NULL )
374  {
376  static const int quality = 20;
377 
378  setMessageData( &msgData, ( MESSAGE_CAST ) mbmDataPtr,
379  sizeof( SharedData ) );
381  &msgData, CRYPT_IATTRIBUTE_ENTROPY );
383  ( MESSAGE_CAST ) &quality,
384  CRYPT_IATTRIBUTE_ENTROPY_QUALITY );
385  UnmapViewOfFile( mbmDataPtr );
386  }
387  CloseHandle( hMBMData );
388  }
389 
390 /* Read data from Everest via the shared-memory interface. Everest returns
391  information as an enormous XML text string so we have to be careful about
392  handling of lengths. In general the returned length is 1-3K, so we
393  hard-limit it at 2K to ensure there are no problems if the trailing null
394  gets lost */
395 
396 static void readEverestData( void )
397  {
398  HANDLE hEverestData;
399  const void *everestDataPtr;
400 
401  if( ( hEverestData = OpenFileMapping( FILE_MAP_READ, FALSE,
402  "EVEREST_SensorValues" ) ) == NULL )
403  return;
404  if( ( everestDataPtr = MapViewOfFile( hEverestData,
405  FILE_MAP_READ, 0, 0, 0 ) ) != NULL )
406  {
407  const int length = strlen( everestDataPtr );
408 
409  if( length > 128 )
410  {
412  static const int quality = 40;
413 
414  setMessageData( &msgData, ( MESSAGE_CAST ) everestDataPtr,
415  min( length, 2048 ) );
417  &msgData, CRYPT_IATTRIBUTE_ENTROPY );
419  ( MESSAGE_CAST ) &quality,
420  CRYPT_IATTRIBUTE_ENTROPY_QUALITY );
421  }
422  UnmapViewOfFile( everestDataPtr );
423  }
424  CloseHandle( hEverestData );
425  }
426 
427 /* SysTool data structures, from forums.techpowerup.com. This uses the
428  standard shared memory interface, but it gets a bit tricky because it
429  uses the OLE 'VARIANT' data type which we can't access because it's
430  included via a complex nested inclusion framework in windows.h, and the
431  use of '#pragma once' when we included it for use in crypt.h means that
432  we can't re-include any of the necessary files. Since we don't actually
433  care what's inside a VARIANT, and it has a fixed size of 16 bytes, we
434  just use it as an opaque blob */
435 
436 typedef BYTE VARIANT[ 16 ]; /* Kludge for OLE data type */
437 typedef BYTE UINT8;
438 typedef WORD UINT16;
439 
440 #define SH_MEM_MAX_SENSORS 128
441 
445 
446 typedef struct {
447  WCHAR m_name[ 255 ]; /* Sensor name */
448  WCHAR m_section[ 64 ]; /* Section in which this sensor appears */
450  LONG m_updateInProgress;/* Nonzero when sensor is being updated */
451  UINT32 m_timestamp; /* GetTickCount() of last update */
452  VARIANT m_value; /* Sensor data */
453  WCHAR m_unit[ 8 ]; /* Unit for text output */
454  UINT8 m_nDecimals; /* Default number of decimals for formatted output */
456 
457 typedef struct {
458  UINT32 m_version; /* Version of shared memory structure */
459  UINT16 m_nSensors; /* Number of records with data in m_sensors */
461  } SYSTOOL_SHMEM;
462 
463 static void readSysToolData( void )
464  {
465  HANDLE hSysToolData;
466  const SYSTOOL_SHMEM *sysToolDataPtr;
467 
468  if( ( hSysToolData = OpenFileMapping( FILE_MAP_READ, FALSE,
469  "SysToolSensors" ) ) == NULL )
470  return;
471  if( ( sysToolDataPtr = ( SYSTOOL_SHMEM * ) \
472  MapViewOfFile( hSysToolData, FILE_MAP_READ, 0, 0, 0 ) ) != NULL )
473  {
475  static const int quality = 40;
476 
477  setMessageData( &msgData, ( MESSAGE_CAST ) sysToolDataPtr,
478  sizeof( SYSTOOL_SHMEM ) );
480  &msgData, CRYPT_IATTRIBUTE_ENTROPY );
482  ( MESSAGE_CAST ) &quality,
483  CRYPT_IATTRIBUTE_ENTROPY_QUALITY );
484  UnmapViewOfFile( sysToolDataPtr );
485  }
486  CloseHandle( hSysToolData );
487  }
488 
489 /* RivaTuner data structures via the shared-memory interface, from the
490  RivaTuner sample source. The DWORD values below are actually (32-bit)
491  floats, but we overlay them with DWORDs since we don't care about the
492  values. The information is only accessible when the RivaTuner hardware
493  monitoring window is open. This one is the easiest of the shared-mem
494  interfaces to monitor because for fowards-compatibility reasons it
495  stores a Windows-style indicator of the size of each struct entry in the
496  data header, so we can get the total size simply by multiplying out the
497  number of entries by the indicated size. As a safety measure we limit
498  the maximum data size to 2K in case a value gets corrupted */
499 
500 typedef struct {
501  DWORD dwSignature; /* 'RTHM' if active */
502  DWORD dwVersion; /* Must be 0x10001 or above */
503  DWORD dwNumEntries; /* No.of RTHM_SHARED_MEMORY_ENTRY entries */
504  time_t time; /* Last polling time */
505  DWORD dwEntrySize; /* Size of entries in RTHM_SHARED_MEMORY_ENTRY array */
507 
508 typedef struct {
509  char czSrc[ 32 ]; /* Source description */
510  char czDim[ 16 ]; /* Source measurement units */
511  DWORD /*float*/ data; /* Source data */
512  DWORD /*float*/ offset; /* Source offset, e.g. temp.compensation */
513  DWORD /*float*/ dataTransformed;/* Source data in transformed(?) form */
514  DWORD flags; /* Misc.flags */
516 
517 static void readRivaTunerData( void )
518  {
519  HANDLE hRivaTunerData;
520  RTHM_SHARED_MEMORY_HEADER *rivaTunerHeaderPtr;
521 
522  if( ( hRivaTunerData = OpenFileMapping( FILE_MAP_READ, FALSE,
523  "RTHMSharedMemory" ) ) == NULL )
524  return;
525  if( ( rivaTunerHeaderPtr = ( RTHM_SHARED_MEMORY_HEADER * ) \
526  MapViewOfFile( hRivaTunerData, FILE_MAP_READ, 0, 0, 0 ) ) != NULL )
527  {
528  if( rivaTunerHeaderPtr->dwSignature == 'RTHM' && \
529  rivaTunerHeaderPtr->dwVersion >= 0x10001 )
530  {
532  const BYTE *entryPtr = ( ( BYTE * ) rivaTunerHeaderPtr ) + \
533  sizeof( RTHM_SHARED_MEMORY_HEADER );
534  const int entryTotalSize = rivaTunerHeaderPtr->dwNumEntries * \
535  rivaTunerHeaderPtr->dwEntrySize;
536  static const int quality = 10;
537 
538  setMessageData( &msgData, ( MESSAGE_CAST ) entryPtr,
539  min( entryTotalSize, 2048 ) );
541  &msgData, CRYPT_IATTRIBUTE_ENTROPY );
543  ( MESSAGE_CAST ) &quality,
544  CRYPT_IATTRIBUTE_ENTROPY_QUALITY );
545  }
546  UnmapViewOfFile( rivaTunerHeaderPtr );
547  }
548  CloseHandle( hRivaTunerData );
549  }
550 
551 /* Read data from HMonitor via the shared-memory interface. The DWORD
552  values below are actually (32-bit) floats, but we overlay them with
553  DWORDs since we don't care about the values. Like RivaTuner's data the
554  info structure contains a length value at the start, so it's fairly easy
555  to work with */
556 
557 typedef struct {
558  WORD length;
559  WORD version; /* Single 'DWORD length' before version 4.1 */
560  DWORD /*float*/ temp[ 3 ];
561  DWORD /*float*/ voltage[ 7 ];
562  int fan[ 3 ];
563  } HMONITOR_DATA;
564 
565 static void readHMonitorData( void )
566  {
567  HANDLE hHMonitorData;
568  HMONITOR_DATA *hMonitorDataPtr;
569 
570  if( ( hHMonitorData = OpenFileMapping( FILE_MAP_READ, FALSE,
571  "Hmonitor_Counters_Block" ) ) == NULL )
572  return;
573  if( ( hMonitorDataPtr = ( HMONITOR_DATA * ) \
574  MapViewOfFile( hHMonitorData, FILE_MAP_READ, 0, 0, 0 ) ) != NULL )
575  {
576  if( hMonitorDataPtr->version >= 0x4100 && \
577  ( hMonitorDataPtr->length >= 48 && hMonitorDataPtr->length <= 1024 ) )
578  {
580  static const int quality = 40;
581 
582  setMessageData( &msgData, hMonitorDataPtr, hMonitorDataPtr->length );
584  &msgData, CRYPT_IATTRIBUTE_ENTROPY );
586  ( MESSAGE_CAST ) &quality,
587  CRYPT_IATTRIBUTE_ENTROPY_QUALITY );
588  }
589  UnmapViewOfFile( hMonitorDataPtr );
590  }
591  CloseHandle( hHMonitorData );
592  }
593 
594 /* Read data from ATI Tray Tools via the shared-memory interface. This has
595  an added twist in that just because it's available to be read doesn't
596  mean that it contains any data, so we check that at least the GPU speed
597  and temp-monitoring-supported flag have nonzero values */
598 
599 typedef struct {
600  DWORD CurGPU; /* GPU speed */
601  DWORD CurMEM; /* Video memory speed */
603  DWORD is3DActive; /* Boolean: 3D mode active */
604  DWORD isTempMonSupported; /* Boolean: Temp monitoring available */
605  DWORD GPUTemp; /* GPU temp */
606  DWORD ENVTemp; /* Video card temp */
607  DWORD FanDuty; /* Fan duty cycle */
608  DWORD MAXGpuTemp, MINGpuTemp; /* Min/max GPU temp */
609  DWORD MAXEnvTemp, MINEnvTemp; /* Min/max video card temp */
610  DWORD CurD3DAA, CurD3DAF; /* Direct3D info */
611  DWORD CurOGLAA, CurOGLAF; /* OpenGL info */
612  DWORD IsActive; /* Another 3D boolean */
613  DWORD CurFPS; /* FPS rate */
614  DWORD FreeVideo; /* Available video memory */
615  DWORD FreeTexture; /* Available texture memory */
616  DWORD Cur3DApi; /* API used (D3D, OpenGL, etc) */
617  DWORD MemUsed; /* ? */
618  } TRAY_TOOLS_DATA;
619 
620 static void readATITrayToolsData( void )
621  {
622  HANDLE hTrayToolsData;
623  TRAY_TOOLS_DATA *trayToolsDataPtr;
624 
625  if( ( hTrayToolsData = OpenFileMapping( FILE_MAP_READ, FALSE,
626  "ATITRAY_SMEM" ) ) == NULL )
627  return;
628  if( ( trayToolsDataPtr = ( TRAY_TOOLS_DATA * ) \
629  MapViewOfFile( hTrayToolsData, FILE_MAP_READ, 0, 0, 0 ) ) != NULL )
630  {
631  if( trayToolsDataPtr->CurGPU >= 100 && \
632  trayToolsDataPtr->isTempMonSupported != 0 )
633  {
635  static const int quality = 10;
636 
637  setMessageData( &msgData, trayToolsDataPtr,
638  sizeof( TRAY_TOOLS_DATA ) );
640  &msgData, CRYPT_IATTRIBUTE_ENTROPY );
642  ( MESSAGE_CAST ) &quality,
643  CRYPT_IATTRIBUTE_ENTROPY_QUALITY );
644  }
645  UnmapViewOfFile( trayToolsDataPtr );
646  }
647  CloseHandle( hTrayToolsData );
648  }
649 
650 /* CoreTemp data structure, from www.alcpu.com/CoreTemp. The DWORD values
651  below are actually (32-bit) floats but we overlay them with DWORDs since
652  we don't care about the values */
653 
654 typedef struct
655  {
656  unsigned int uiLoad[ 256 ];
657  unsigned int uiTjMax[ 128 ];
658  unsigned int uiCoreCnt;
659  unsigned int uiCPUCnt;
660  DWORD /*float*/ fTemp[ 256 ];
661  DWORD /*float*/ fVID;
662  DWORD /*float*/ fCPUSpeed;
663  DWORD /*float*/ fFSBSpeed;
664  DWORD /*float*/ fMultipier;
665  DWORD /*float*/ sCPUName[ 100 ];
666  unsigned char ucFahrenheit;
667  unsigned char ucDeltaToTjMax;
669 
670 static void readCoreTempData( void )
671  {
672  HANDLE hCoreTempData;
673  CORE_TEMP_SHARED_DATA *coreTempDataPtr;
674 
675  if( ( hCoreTempData = OpenFileMapping( FILE_MAP_READ, FALSE,
676  "CoreTempMappingObject" ) ) == NULL )
677  return;
678  if( ( coreTempDataPtr = ( CORE_TEMP_SHARED_DATA * ) \
679  MapViewOfFile( hCoreTempData, FILE_MAP_READ, 0, 0, 0 ) ) != NULL )
680  {
682  static const int quality = 15;
683 
684  setMessageData( &msgData, coreTempDataPtr,
685  sizeof( CORE_TEMP_SHARED_DATA ) );
687  &msgData, CRYPT_IATTRIBUTE_ENTROPY );
689  ( MESSAGE_CAST ) &quality,
690  CRYPT_IATTRIBUTE_ENTROPY_QUALITY );
691  UnmapViewOfFile( coreTempDataPtr );
692  }
693  CloseHandle( hCoreTempData );
694  }
695 
696 /* GPU-Z data structures, from forums.techpowerup.com. This uses an
697  incredibly wasteful memory layout so we end up having to submit around
698  200kB of data, unfortunately we can't easily pick out the few values of
699  interest because the 'data' entries push out the values of interest, the
700  'sensors' entries, to the end of the memory block */
701 
702 #define MAX_RECORDS 128
703 
704 #pragma pack(push, 1)
705 
706 typedef struct {
707  WCHAR key[ 256 ];
708  WCHAR value[ 256 ];
709  } GPUZ_RECORD;
710 
711 typedef struct {
712  WCHAR name[ 256 ];
713  WCHAR unit[ 8 ];
714  UINT32 digits;
715  double value;
717 
718 typedef struct {
719  UINT32 version; /* Version number, should be 1 */
720  volatile LONG busy; /* Data-update flag */
721  UINT32 lastUpdate; /* GetTickCount() of last update */
724  } GPUZ_SH_MEM;
725 
726 #pragma pack(pop)
727 
728 static void readGPUZData( void )
729  {
730  HANDLE hGPUZData;
731  const GPUZ_SH_MEM *gpuzDataPtr;
732 
733  if( ( hGPUZData = OpenFileMapping( FILE_MAP_READ, FALSE,
734  "GPUZShMem" ) ) == NULL )
735  return;
736  if( ( gpuzDataPtr = ( GPUZ_SH_MEM * ) \
737  MapViewOfFile( hGPUZData, FILE_MAP_READ, 0, 0, 0 ) ) != NULL )
738  {
739  if( gpuzDataPtr->version == 1 )
740  {
742  static const int quality = 10;
743 
744  setMessageData( &msgData, ( MESSAGE_CAST ) gpuzDataPtr,
745  sizeof( GPUZ_SH_MEM ) );
747  &msgData, CRYPT_IATTRIBUTE_ENTROPY );
749  ( MESSAGE_CAST ) &quality,
750  CRYPT_IATTRIBUTE_ENTROPY_QUALITY );
751  }
752  UnmapViewOfFile( gpuzDataPtr );
753  }
754  CloseHandle( hGPUZData );
755  }
756 
757 /****************************************************************************
758 * *
759 * Hardware Configuration Data *
760 * *
761 ****************************************************************************/
762 
763 /* Read PnP configuration data. This is mostly static per machine, but
764  differs somewhat across machines. We have to define the values ourselves
765  here due to a combination of some of the values and functions not
766  existing at the time VC++ 6.0 was released */
767 
768 typedef void * HDEVINFO;
769 
770 #define DIGCF_PRESENT 0x02
771 #define DIGCF_ALLCLASSES 0x04
772 
773 #define SPDRP_HARDWAREID 0x01
774 
775 typedef struct _SP_DEVINFO_DATA {
777  GUID classGuid;
779  ULONG *reserved;
781 
782 typedef BOOL ( WINAPI *SETUPDIDESTROYDEVICEINFOLIST )( HDEVINFO DeviceInfoSet );
783 typedef BOOL ( WINAPI *SETUPDIENUMDEVICEINFO )( HDEVINFO DeviceInfoSet,
785  PSP_DEVINFO_DATA DeviceInfoData );
786 typedef HDEVINFO ( WINAPI *SETUPDIGETCLASSDEVS )( /*CONST LPGUID*/ void *ClassGuid,
787  /*PCTSTR*/ void *Enumerator,
788  HWND hwndParent, DWORD Flags );
789 typedef BOOL ( WINAPI *SETUPDIGETDEVICEREGISTRYPROPERTY )( HDEVINFO DeviceInfoSet,
790  PSP_DEVINFO_DATA DeviceInfoData,
792  PBYTE PropertyBuffer,
794 
795 static void readPnPData( void )
796  {
797  HANDLE hSetupAPI;
798  HDEVINFO hDevInfo;
799  SETUPDIDESTROYDEVICEINFOLIST pSetupDiDestroyDeviceInfoList = NULL;
800  SETUPDIENUMDEVICEINFO pSetupDiEnumDeviceInfo = NULL;
801  SETUPDIGETCLASSDEVS pSetupDiGetClassDevs = NULL;
802  SETUPDIGETDEVICEREGISTRYPROPERTY pSetupDiGetDeviceRegistryProperty = NULL;
803 
804  if( ( hSetupAPI = DynamicLoad( "SetupAPI.dll" ) ) == NULL )
805  return;
806 
807  /* Get pointers to the PnP functions. Although the get class-devs
808  and get device registry functions look like standard functions,
809  they're actually macros that are mapped to (depending on the build
810  type) xxxA or xxxW, so we access them under the straight-ASCII-
811  function name */
812  pSetupDiDestroyDeviceInfoList = ( SETUPDIDESTROYDEVICEINFOLIST ) \
813  GetProcAddress( hSetupAPI, "SetupDiDestroyDeviceInfoList" );
814  pSetupDiEnumDeviceInfo = ( SETUPDIENUMDEVICEINFO ) \
815  GetProcAddress( hSetupAPI, "SetupDiEnumDeviceInfo" );
816  pSetupDiGetClassDevs = ( SETUPDIGETCLASSDEVS ) \
817  GetProcAddress( hSetupAPI, "SetupDiGetClassDevsA" );
818  pSetupDiGetDeviceRegistryProperty = ( SETUPDIGETDEVICEREGISTRYPROPERTY ) \
819  GetProcAddress( hSetupAPI, "SetupDiGetDeviceRegistryPropertyA" );
820  if( pSetupDiDestroyDeviceInfoList == NULL || \
821  pSetupDiEnumDeviceInfo == NULL || pSetupDiGetClassDevs == NULL || \
822  pSetupDiGetDeviceRegistryProperty == NULL )
823  {
824  DynamicUnload( hSetupAPI );
825  return;
826  }
827 
828  /* Get info on all PnP devices */
829  hDevInfo = pSetupDiGetClassDevs( NULL, NULL, NULL,
831  if( hDevInfo != INVALID_HANDLE_VALUE )
832  {
833  SP_DEVINFO_DATA devInfoData;
834  RANDOM_STATE randomState;
835  BYTE buffer[ RANDOM_BUFSIZE + 8 ];
836  BYTE pnpBuffer[ 512 + 8 ];
837  DWORD cbPnPBuffer;
838  int deviceCount, iterationCount, status;
839 
840  /* Enumerate all PnP devices */
841  status = initRandomData( randomState, buffer, RANDOM_BUFSIZE );
842  if( cryptStatusError( status ) )
844  memset( &devInfoData, 0, sizeof( devInfoData ) );
845  devInfoData.cbSize = sizeof( SP_DEVINFO_DATA );
846  for( deviceCount = 0, iterationCount = 0;
847  pSetupDiEnumDeviceInfo( hDevInfo, deviceCount,
848  &devInfoData ) && \
849  iterationCount < FAILSAFE_ITERATIONS_MAX;
850  deviceCount++, iterationCount++ )
851  {
852  if( pSetupDiGetDeviceRegistryProperty( hDevInfo, &devInfoData,
853  SPDRP_HARDWAREID, NULL,
854  pnpBuffer, 512, &cbPnPBuffer ) )
855  addRandomData( randomState, pnpBuffer, cbPnPBuffer );
856  }
857  ENSURES_V( iterationCount < FAILSAFE_ITERATIONS_MAX );
858  pSetupDiDestroyDeviceInfoList( hDevInfo );
859  endRandomData( randomState, 5 );
860  }
861 
862  DynamicUnload( hSetupAPI );
863  }
864 
865 /****************************************************************************
866 * *
867 * Fast Poll *
868 * *
869 ****************************************************************************/
870 
871 /* The shared Win32 fast poll routine */
872 
873 void fastPoll( void )
874  {
875  static BOOLEAN addedFixedItems = FALSE;
876  FILETIME creationTime, exitTime, kernelTime, userTime;
877  SIZE_T minimumWorkingSetSize, maximumWorkingSetSize;
878  MEMORYSTATUS memoryStatus;
879  HANDLE handle;
880  POINT point;
881  RANDOM_STATE randomState;
882  BYTE buffer[ RANDOM_BUFSIZE + 8 ];
883  int trngValue = 0, status;
884 
885  if( krnlIsExiting() )
886  return;
887 
888  status = initRandomData( randomState, buffer, RANDOM_BUFSIZE );
889  if( cryptStatusError( status ) )
891 
892  /* Get various basic pieces of system information: Handle of active
893  window, handle of window with mouse capture, handle of clipboard owner
894  handle of start of clpboard viewer list, pseudohandle of current
895  process, current process ID, pseudohandle of current thread, current
896  thread ID, handle of desktop window, handle of window with keyboard
897  focus, whether system queue has any events, cursor position for last
898  message, 1 ms time for last message, handle of window with clipboard
899  open, handle of process heap, handle of procs window station, types of
900  events in input queue, and milliseconds since Windows was started.
901  Since a HWND/HANDLE can be a 64-bit value on a 64-bit platform, we
902  have to use a mapping macro that discards the high 32 bits (which
903  presumably won't be of much interest anyway).
904 
905  Note that there's another call that does almost the same thing as
906  GetTickCount(), timeGetTime() from the multimedia API, however this
907  has a fairly constant delta between ticks while GetTickCount()
908  wanders all over the place (while still averaging a fixed value). So
909  timeGetTime() (which uses KeQueryInterruptTime()) isn't necessarily
910  more accurate than GetTickCount() (which uses KeQueryTickCount()),
911  just more regular. Since we're interested in unpredictability, we
912  use GetTickCount() and not timeGetTime() */
913  addRandomHandle( randomState, GetActiveWindow() );
914  addRandomHandle( randomState, GetCapture() );
915  addRandomHandle( randomState, GetClipboardOwner() );
916  addRandomHandle( randomState, GetClipboardViewer() );
917  addRandomHandle( randomState, GetCurrentProcess() );
918  addRandomValue( randomState, GetCurrentProcessId() );
919  addRandomHandle( randomState, GetCurrentThread() );
920  addRandomValue( randomState, GetCurrentThreadId() );
921  addRandomHandle( randomState, GetDesktopWindow() );
922  addRandomHandle( randomState, GetFocus() );
923  addRandomValue( randomState, GetInputState() );
924  addRandomValue( randomState, GetMessagePos() );
925  addRandomValue( randomState, GetMessageTime() );
926  addRandomHandle( randomState, GetOpenClipboardWindow() );
927  addRandomHandle( randomState, GetProcessHeap() );
928  addRandomHandle( randomState, GetProcessWindowStation() );
929  addRandomValue( randomState, GetTickCount() );
930  if( krnlIsExiting() )
931  return;
932 
933  /* Calling the following function can cause problems in some cases in
934  that a calling application eventually stops getting events from its
935  event loop, so we can't (safely) use it as an entropy source */
936 /* addRandomValue( randomState, GetQueueStatus( QS_ALLEVENTS ) ); */
937 
938  /* Get multiword system information: Current caret position, current
939  mouse cursor position */
940  GetCaretPos( &point );
941  addRandomData( randomState, &point, sizeof( POINT ) );
942  GetCursorPos( &point );
943  addRandomData( randomState, &point, sizeof( POINT ) );
944 
945  /* Get percent of memory in use, bytes of physical memory, bytes of free
946  physical memory, bytes in paging file, free bytes in paging file, user
947  bytes of address space, and free user bytes */
948  memoryStatus.dwLength = sizeof( MEMORYSTATUS );
949  GlobalMemoryStatus( &memoryStatus );
950  addRandomData( randomState, &memoryStatus, sizeof( MEMORYSTATUS ) );
951 
952  /* Get thread and process creation time, exit time, time in kernel mode,
953  and time in user mode in 100ns intervals */
954  handle = GetCurrentThread();
955  GetThreadTimes( handle, &creationTime, &exitTime, &kernelTime, &userTime );
956  addRandomData( randomState, &creationTime, sizeof( FILETIME ) );
957  addRandomData( randomState, &exitTime, sizeof( FILETIME ) );
958  addRandomData( randomState, &kernelTime, sizeof( FILETIME ) );
959  addRandomData( randomState, &userTime, sizeof( FILETIME ) );
960  handle = GetCurrentProcess();
961  GetProcessTimes( handle, &creationTime, &exitTime, &kernelTime, &userTime );
962  addRandomData( randomState, &creationTime, sizeof( FILETIME ) );
963  addRandomData( randomState, &exitTime, sizeof( FILETIME ) );
964  addRandomData( randomState, &kernelTime, sizeof( FILETIME ) );
965  addRandomData( randomState, &userTime, sizeof( FILETIME ) );
966 
967  /* Get the minimum and maximum working set size for the current process */
968  GetProcessWorkingSetSize( handle, &minimumWorkingSetSize,
969  &maximumWorkingSetSize );
970  addRandomValue( randomState, minimumWorkingSetSize );
971  addRandomValue( randomState, maximumWorkingSetSize );
972 
973  /* The following are fixed for the lifetime of the process so we only
974  add them once */
975  if( !addedFixedItems )
976  {
977  STARTUPINFO startupInfo;
978 
979  /* Get name of desktop, console window title, new window position and
980  size, window flags, and handles for stdin, stdout, and stderr */
981  startupInfo.cb = sizeof( STARTUPINFO );
982  GetStartupInfo( &startupInfo );
983  addRandomData( randomState, &startupInfo, sizeof( STARTUPINFO ) );
984 
985  /* Remember that we've got the fixed info */
986  addedFixedItems = TRUE;
987  }
988 
989  /* The performance of QPC varies depending on the architecture it's
990  running on and on the OS, the MS documentation is vague about the
991  details because it varies so much. Under Win9x/ME it reads the
992  1.193180 MHz PIC timer. Under NT/Win2K/XP it may or may not read the
993  64-bit TSC depending on the HAL and assorted other circumstances,
994  generally on machines with a uniprocessor HAL
995  KeQueryPerformanceCounter() uses a 3.579545MHz timer and on machines
996  with a multiprocessor or APIC HAL it uses the TSC (the exact time
997  source is controlled by the HalpUse8254 flag in the kernel). Since
998  Vista-era machines are generally running on multiprocessor HALs we
999  usually get the TSC under Vista.
1000 
1001  This choice of time sources is somewhat peculiar because on a
1002  multiprocessor machine it's theoretically possible to get completely
1003  different TSC readings depending on which CPU you're currently
1004  running on, while for uniprocessor machines it's not a problem.
1005  However the kernel synchronises the TSCs across CPUs at boot time if
1006  a multiprocessor HAL is used (it resets the TSC as part of its system
1007  init) so this shouldn't really be a problem. Under WinCE it's
1008  completely platform-dependant, if there's no hardware performance
1009  counter available it uses the 1ms system timer.
1010 
1011  Another feature of the TSC (although it doesn't really affect us
1012  here) is that mobile CPUs will turn off the TSC when they idle,
1013  newer Pentiums and Athlons with advanced power management/clock
1014  throttling will change the rate of the counter when they clock-
1015  throttle (to match the current CPU speed), and hyperthreading
1016  Pentiums will turn it off when both threads are idle (this more or
1017  less makes sense since the CPU will be in the halted state and not
1018  executing any instructions to count). What makes this even more
1019  exciting is that the resulting handling of the TSC is almost entirely
1020  nondeterministic, the only thing that's guaranteed is that the
1021  counter is monotonically incrementing. For example when a newer
1022  processor with power-saving features enabled ramps down its core
1023  clock the TSC rate is lowered to correspond to the clock rate
1024  (assuming that the BIOS sets this up correctly, which isn't always
1025  the case). However various events like cache probes can cause the
1026  core to temporarily return to the original rate to process the
1027  event before dropping back to the throttled rate, which can cause
1028  TSC drift across multiple cores. Hardware-specific events like
1029  AMDs STPCLK signalling ("shut 'er down ma, she's glowing red") can
1030  reach different cores at different times and lead to ramping up
1031  and down and different times and for different durations, leading
1032  to further drift. Newer AMD CPUs fix this by providing drift-
1033  invariant TSCs if the TscInvariant CPUID feature flag is set.
1034 
1035  As a result, if we're on a system with multiple cores and it doesn't
1036  have the AMD TscInvariant fix then the TSC skew can also be a source
1037  of entropy. To some extent this is just timing the context switch
1038  time across CPUs (which in itself is a source of some entropy), but
1039  what's left is the TSC skew across cores. If this is if interest we
1040  can do it with code something like the following. Note that this is
1041  only sample code, there are various complications such as the fact
1042  that another thread may change the process affinity mask between the
1043  call to the initial GetProcessAffinityMask() and the final
1044  SetThreadAffinityMask() to restore the original mask, even if we
1045  insert another GetProcessAffinityMask() just before the
1046  SetThreadAffinityMask() there's still a small race condition present
1047  but no real way to avoid it without OS API-level support:
1048 
1049  DWORD processAfinityMask, systemAffinityMask, mask = 0x10000;
1050 
1051  // Get the available processors that the thread can be scheduled on
1052  if( !GetProcessAffinityMask( GetCurrentProcess(), processAfinityMask,
1053  systemAffinityMask ) )
1054  return;
1055 
1056  // Move the thread to each processor and read the TSC
1057  while( mask != 0 )
1058  {
1059  mask >>= 1;
1060  if( !( mask & processAfinityMask ) )
1061  continue;
1062 
1063  SetThreadAffinityMask( GetCurrentThread(), mask );
1064  // RDTSC
1065  }
1066 
1067  // Restore the original thread affinity
1068  SetThreadAffinityMask( GetCurrentThread(), processAfinityMask );
1069 
1070  Finally, there's the HPET, but this is only supported in Vista and
1071  it's not clear how to access it from user-level APIs rather than as
1072  part of the multimedia subsystem.
1073 
1074  To make things unambiguous, we call RDTSC directly if possible and
1075  fall back to QPC in the highly unlikely situation where this isn't
1076  present */
1077 #if defined( __WIN64__ )
1078  {
1079  unsigned __int64 value;
1080 
1081  /* x86-64 always has a TSC, and the read is supported as an intrinsic */
1082  value = __rdtsc();
1083  addRandomData( randomState, &value, sizeof( __int64 ) );
1084  }
1085 #else
1086  #ifndef NO_ASM
1088  {
1089  unsigned long value;
1090 
1091  __asm {
1092  xor eax, eax
1093  xor edx, edx /* Tell VC++ that EDX:EAX will be trashed */
1094  rdtsc
1095  mov [value], eax /* Ignore high 32 bits, which are > 1s res */
1096  }
1097  addRandomValue( randomState, value );
1098  }
1099  #endif /* NO_ASM */
1100  else
1101  {
1102  LARGE_INTEGER performanceCount;
1103 
1104  if( QueryPerformanceCounter( &performanceCount ) )
1105  addRandomData( randomState, &performanceCount,
1106  sizeof( LARGE_INTEGER ) );
1107  else
1108  {
1109  /* Millisecond accuracy at best... */
1110  addRandomValue( randomState, GetTickCount() );
1111  }
1112  }
1113 #endif /* Win32 vs. Win64 */
1114 
1115  /* If there's a hardware RNG present, read data from it. We check that
1116  the RNG is still present/enabled on each fetch since it could (at
1117  least in theory) be disabled by the OS between fetches. We also read
1118  the data into an explicitly dword-aligned buffer (which the standard
1119  buffer should be anyway, but we make it explicit here just to be
1120  safe). Note that we have to force alignment using a LONGLONG rather
1121  than a #pragma pack, since chars don't need alignment it would have
1122  no effect on the BYTE [] member */
1123 #ifndef NO_ASM
1125  {
1126  struct alignStruct {
1127  LONGLONG dummy1; /* Force alignment of following member */
1128  BYTE buffer[ 64 ];
1129  };
1130  struct alignStruct *rngBuffer = ( struct alignStruct * ) buffer;
1131  void *bufPtr = rngBuffer->buffer; /* Get it into a form asm can handle */
1132  int byteCount = 0;
1133 
1134  __asm {
1135  push es
1136  xor ecx, ecx /* Tell VC++ that ECX will be trashed */
1137  mov eax, 0xC0000001 /* Centaur extended feature flags */
1138  cpuid
1139  and edx, 01100b
1140  cmp edx, 01100b /* Check for RNG present + enabled flags */
1141  jne rngDisabled /* RNG was disabled after our initial check */
1142  push ds
1143  pop es
1144  mov edi, bufPtr /* ES:EDI = buffer */
1145  xor edx, edx /* Fetch 8 bytes */
1146  xstore_rng
1147  and eax, 011111b /* Get count of bytes returned */
1148  jz rngDisabled /* Nothing read, exit */
1149  mov [byteCount], eax
1150  rngDisabled:
1151  pop es
1152  }
1153  if( byteCount > 0 )
1154  {
1155  addRandomData( randomState, bufPtr, byteCount );
1156  trngValue = 45;
1157  }
1158  }
1160  {
1161  unsigned long buffer[ 8 + 8 ];
1162  int byteCount = 0;
1163 
1164  __asm {
1165  xor eax, eax /* Tell VC++ that EAX will be trashed */
1166  xor ecx, ecx
1167  trngLoop:
1168  rdrand_eax
1169  jnc trngExit /* TRNG result bad, exit with byteCount = 0 */
1170  mov [buffer+ecx], eax
1171  add ecx, 4
1172  cmp ecx, 32 /* Fill 32 bytes worth */
1173  jl trngLoop
1174  mov [byteCount], ecx
1175  trngExit:
1176  }
1177  if( byteCount > 0 )
1178  {
1179  addRandomData( randomState, buffer, byteCount );
1180  trngValue = 45;
1181  }
1182  }
1184  {
1185  unsigned long value = 0;
1186 
1187  __asm {
1188  xor eax, eax
1189  xor edx, edx /* Tell VC++ that EDX:EAX will be trashed */
1190  mov ecx, 0x58002006 /* GLD_MSR_CTRL */
1191  rdmsr
1192  and eax, 0110000000000b
1193  cmp eax, 0010000000000b /* Check whether TRNG is enabled */
1194  jne trngDisabled /* TRNG isn't enabled */
1195  trngDisabled:
1196  }
1197  if( value )
1198  {
1199  addRandomValue( randomState, value );
1200  trngValue = 20;
1201  }
1202  }
1203 #endif /* NO_ASM */
1204 
1205  /* Flush any remaining data through. Quality = int( 33 1/3 % ) + any
1206  additional quality from the TRNG if there's one present */
1207  endRandomData( randomState, 34 + trngValue );
1208  }
1209 
1210 /****************************************************************************
1211 * *
1212 * Slow Poll *
1213 * *
1214 ****************************************************************************/
1215 
1216 /* If we're running under Win64 there's no need to include Win95/98
1217  backwards-compatibility features */
1218 
1219 #ifndef __WIN64__
1220 
1221 /* Type definitions for function pointers to call Toolhelp32 functions */
1222 
1223 #ifdef _MSC_VER
1224  #if VC_GE_2005( _MSC_VER )
1225  #define THREAD_ID ULONG_PTR
1226  #else
1227  #define THREAD_ID DWORD
1228  #endif /* VC++ < 2005 */
1229 #endif /* VC++ */
1230 
1231 typedef BOOL ( WINAPI *MODULEWALK )( HANDLE hSnapshot, LPMODULEENTRY32 lpme );
1232 typedef BOOL ( WINAPI *THREADWALK )( HANDLE hSnapshot, LPTHREADENTRY32 lpte );
1233 typedef BOOL ( WINAPI *PROCESSWALK )( HANDLE hSnapshot, LPPROCESSENTRY32 lppe );
1234 typedef BOOL ( WINAPI *HEAPLISTWALK )( HANDLE hSnapshot, LPHEAPLIST32 lphl );
1235 typedef BOOL ( WINAPI *HEAPFIRST )( LPHEAPENTRY32 lphe, DWORD th32ProcessID, THREAD_ID th32HeapID );
1236 typedef BOOL ( WINAPI *HEAPNEXT )( LPHEAPENTRY32 lphe );
1237 typedef HANDLE ( WINAPI *CREATESNAPSHOT )( DWORD dwFlags, DWORD th32ProcessID );
1238 
1239 /* Global function pointers. These are necessary because the functions need to
1240  be dynamically linked since only the Win95 kernel currently contains them.
1241  Explicitly linking to them will make the program unloadable under NT */
1242 
1243 static CREATESNAPSHOT pCreateToolhelp32Snapshot = NULL;
1244 static MODULEWALK pModule32First = NULL;
1245 static MODULEWALK pModule32Next = NULL;
1246 static PROCESSWALK pProcess32First = NULL;
1247 static PROCESSWALK pProcess32Next = NULL;
1248 static THREADWALK pThread32First = NULL;
1249 static THREADWALK pThread32Next = NULL;
1250 static HEAPLISTWALK pHeap32ListFirst = NULL;
1251 static HEAPLISTWALK pHeap32ListNext = NULL;
1252 static HEAPFIRST pHeap32First = NULL;
1253 static HEAPNEXT pHeap32Next = NULL;
1254 
1255 /* Since there are a significant number of ToolHelp data blocks, we use a
1256  larger-than-usual intermediate buffer to cut down on kernel traffic */
1257 
1258 #define BIG_RANDOM_BUFSIZE ( RANDOM_BUFSIZE * 4 )
1259 #if BIG_RANDOM_BUFSIZE > MAX_INTLENGTH_SHORT
1260  #error BIG_RANDOM_BUFSIZE exceeds randomness accumulator size
1261 #endif /* RANDOM_BUFSIZE > MAX_INTLENGTH_SHORT */
1262 
1263 static void slowPollWin95( void )
1264  {
1265  static BOOLEAN addedFixedItems = FALSE;
1266  PROCESSENTRY32 pe32;
1267  THREADENTRY32 te32;
1268  MODULEENTRY32 me32;
1269  HEAPLIST32 hl32;
1270  HANDLE hSnapshot;
1271  RANDOM_STATE randomState;
1272  BYTE buffer[ BIG_RANDOM_BUFSIZE + 8 ];
1273  int iterationCount, status;
1274 
1275  /* The following are fixed for the lifetime of the process so we only
1276  add them once */
1277  if( !addedFixedItems )
1278  {
1279  readPnPData();
1280  addedFixedItems = TRUE;
1281  }
1282 
1283  /* Initialize the Toolhelp32 function pointers if necessary */
1284  if( pCreateToolhelp32Snapshot == NULL )
1285  {
1286  HANDLE hKernel;
1287 
1288  /* Obtain the module handle of the kernel to retrieve the addresses
1289  of the Toolhelp32 functions */
1290  if( ( hKernel = GetModuleHandle( "Kernel32.dll" ) ) == NULL )
1291  return;
1292 
1293  /* Now get pointers to the functions */
1294  pCreateToolhelp32Snapshot = ( CREATESNAPSHOT ) GetProcAddress( hKernel,
1295  "CreateToolhelp32Snapshot" );
1296  pModule32First = ( MODULEWALK ) GetProcAddress( hKernel,
1297  "Module32First" );
1298  pModule32Next = ( MODULEWALK ) GetProcAddress( hKernel,
1299  "Module32Next" );
1300  pProcess32First = ( PROCESSWALK ) GetProcAddress( hKernel,
1301  "Process32First" );
1302  pProcess32Next = ( PROCESSWALK ) GetProcAddress( hKernel,
1303  "Process32Next" );
1304  pThread32First = ( THREADWALK ) GetProcAddress( hKernel,
1305  "Thread32First" );
1306  pThread32Next = ( THREADWALK ) GetProcAddress( hKernel,
1307  "Thread32Next" );
1308  pHeap32ListFirst = ( HEAPLISTWALK ) GetProcAddress( hKernel,
1309  "Heap32ListFirst" );
1310  pHeap32ListNext = ( HEAPLISTWALK ) GetProcAddress( hKernel,
1311  "Heap32ListNext" );
1312  pHeap32First = ( HEAPFIRST ) GetProcAddress( hKernel,
1313  "Heap32First" );
1314  pHeap32Next = ( HEAPNEXT ) GetProcAddress( hKernel,
1315  "Heap32Next" );
1316 
1317  /* Make sure we got valid pointers for every Toolhelp32 function */
1318  if( pModule32First == NULL || pModule32Next == NULL || \
1319  pProcess32First == NULL || pProcess32Next == NULL || \
1320  pThread32First == NULL || pThread32Next == NULL || \
1321  pHeap32ListFirst == NULL || pHeap32ListNext == NULL || \
1322  pHeap32First == NULL || pHeap32Next == NULL || \
1323  pCreateToolhelp32Snapshot == NULL )
1324  {
1325  /* Mark the main function as unavailable in case for future
1326  reference */
1327  pCreateToolhelp32Snapshot = NULL;
1328  return;
1329  }
1330  }
1331  if( krnlIsExiting() )
1332  return;
1333 
1334  status = initRandomData( randomState, buffer, BIG_RANDOM_BUFSIZE );
1335  if( cryptStatusError( status ) )
1336  retIntError_Void();
1337 
1338  /* Take a snapshot of everything we can get to that's currently in the
1339  system */
1340  hSnapshot = pCreateToolhelp32Snapshot( TH32CS_SNAPALL, 0 );
1341  if( !hSnapshot )
1342  return;
1343 
1344  /* Walk through the local heap. We have to be careful to not spend
1345  excessive amounts of time on this if we're linked into a large
1346  application with a great many heaps and/or heap blocks, since the
1347  heap-traversal functions are rather slow. Fortunately this is
1348  quite rare under Win95/98, since it implies a large/long-running
1349  server app that would be run under NT/Win2K/et al rather than
1350  Win95 (the performance of the mapped ToolHelp32 helper functions
1351  under these OSes is even worse than under Win95, fortunately we
1352  don't have to use them there).
1353 
1354  Ideally in order to prevent excessive delays we'd count the number
1355  of heaps and ensure that no_heaps * no_heap_blocks doesn't exceed
1356  some maximum value, however this requires two passes of (slow) heap
1357  traversal rather than one, which doesn't help the situation much.
1358  To provide at least some protection, we limit the total number of
1359  heaps and heap entries traversed, although this leads to slightly
1360  suboptimal performance if we have a small number of deep heaps
1361  rather than the current large number of shallow heaps.
1362 
1363  There is however a second consideration that needs to be taken into
1364  account when doing this, which is that the heap-management functions
1365  aren't completely thread-safe, so that under (very rare) conditions
1366  of heavy allocation/deallocation this can cause problems when calling
1367  HeapNext(). By limiting the amount of time that we spend in each
1368  heap, we can reduce our exposure somewhat */
1369  hl32.dwSize = sizeof( HEAPLIST32 );
1370  if( pHeap32ListFirst( hSnapshot, &hl32 ) )
1371  {
1372  int listCount = 0;
1373 
1374  do
1375  {
1376  HEAPENTRY32 he32;
1377 
1378  /* First add the information from the basic Heaplist32
1379  structure */
1380  if( krnlIsExiting() )
1381  {
1382  CloseHandle( hSnapshot );
1383  return;
1384  }
1385  addRandomData( randomState, &hl32, sizeof( HEAPLIST32 ) );
1386 
1387  /* Now walk through the heap blocks getting information
1388  on each of them */
1389  he32.dwSize = sizeof( HEAPENTRY32 );
1390  if( pHeap32First( &he32, hl32.th32ProcessID, hl32.th32HeapID ) )
1391  {
1392  int entryCount = 0;
1393 
1394  do
1395  {
1396  if( krnlIsExiting() )
1397  {
1398  CloseHandle( hSnapshot );
1399  return;
1400  }
1401  addRandomData( randomState, &he32,
1402  sizeof( HEAPENTRY32 ) );
1403  }
1404  while( entryCount++ < 20 && pHeap32Next( &he32 ) );
1405  }
1406  }
1407  while( listCount++ < 20 && pHeap32ListNext( hSnapshot, &hl32 ) );
1408  }
1409 
1410  /* Walk through all processes */
1411  pe32.dwSize = sizeof( PROCESSENTRY32 );
1412  iterationCount = 0;
1413  if( pProcess32First( hSnapshot, &pe32 ) )
1414  {
1415  do
1416  {
1417  if( krnlIsExiting() )
1418  {
1419  CloseHandle( hSnapshot );
1420  return;
1421  }
1422  addRandomData( randomState, &pe32, sizeof( PROCESSENTRY32 ) );
1423  }
1424  while( pProcess32Next( hSnapshot, &pe32 ) && \
1425  iterationCount++ < FAILSAFE_ITERATIONS_LARGE );
1426  }
1427 
1428  /* Walk through all threads */
1429  te32.dwSize = sizeof( THREADENTRY32 );
1430  iterationCount = 0;
1431  if( pThread32First( hSnapshot, &te32 ) )
1432  {
1433  do
1434  {
1435  if( krnlIsExiting() )
1436  {
1437  CloseHandle( hSnapshot );
1438  return;
1439  }
1440  addRandomData( randomState, &te32, sizeof( THREADENTRY32 ) );
1441  }
1442  while( pThread32Next( hSnapshot, &te32 ) && \
1443  iterationCount++ < FAILSAFE_ITERATIONS_LARGE );
1444  }
1445 
1446  /* Walk through all modules associated with the process */
1447  me32.dwSize = sizeof( MODULEENTRY32 );
1448  iterationCount = 0;
1449  if( pModule32First( hSnapshot, &me32 ) )
1450  {
1451  do
1452  {
1453  if( krnlIsExiting() )
1454  {
1455  CloseHandle( hSnapshot );
1456  return;
1457  }
1458  addRandomData( randomState, &me32, sizeof( MODULEENTRY32 ) );
1459  }
1460  while( pModule32Next( hSnapshot, &me32 ) && \
1461  iterationCount++ < FAILSAFE_ITERATIONS_LARGE );
1462  }
1463 
1464  /* Clean up the snapshot */
1465  CloseHandle( hSnapshot );
1466  if( krnlIsExiting() )
1467  return;
1468 
1469  /* Flush any remaining data through */
1470  endRandomData( randomState, 100 );
1471  }
1472 
1473 /* Perform a thread-safe slow poll for Windows 95 */
1474 
1475 unsigned __stdcall threadSafeSlowPollWin95( void *dummy )
1476  {
1477  UNUSED_ARG( dummy );
1478 
1479  slowPollWin95();
1480  _endthreadex( 0 );
1481  return( 0 );
1482  }
1483 #endif /* __WIN64__ */
1484 
1485 /* Type definitions for function pointers to call NetAPI32 functions */
1486 
1487 typedef DWORD ( WINAPI *NETSTATISTICSGET )( LPWSTR szServer, LPWSTR szService,
1489  LPBYTE *lpBuffer );
1490 typedef DWORD ( WINAPI *NETAPIBUFFERSIZE )( LPVOID lpBuffer, LPDWORD cbBuffer );
1491 typedef DWORD ( WINAPI *NETAPIBUFFERFREE )( LPVOID lpBuffer );
1492 
1493 /* Type definitions for functions to call native NT functions */
1494 
1495 typedef DWORD ( WINAPI *NTQUERYSYSTEMINFORMATION )( DWORD systemInformationClass,
1498  PULONG returnLength );
1499 typedef DWORD ( WINAPI *NTQUERYINFORMATIONPROCESS )( HANDLE processHandle,
1501  PVOID processInformation,
1503  PULONG returnLength );
1504 typedef DWORD ( WINAPI *NTPOWERINFORMATION )( DWORD powerInformationClass,
1506  PVOID outputBuffer, ULONG outputBufferLength );
1507 
1508 /* Global function pointers. These are necessary because the functions need to
1509  be dynamically linked since only the WinNT kernel currently contains them.
1510  Explicitly linking to them will make the program unloadable under Win95 */
1511 
1512 static NETSTATISTICSGET pNetStatisticsGet = NULL;
1513 static NETAPIBUFFERSIZE pNetApiBufferSize = NULL;
1514 static NETAPIBUFFERFREE pNetApiBufferFree = NULL;
1515 static NTQUERYSYSTEMINFORMATION pNtQuerySystemInformation = NULL;
1516 static NTQUERYINFORMATIONPROCESS pNtQueryInformationProcess = NULL;
1517 static NTPOWERINFORMATION pNtPowerInformation = NULL;
1518 
1519 /* When we query the performance counters, we allocate an initial buffer and
1520  then reallocate it as required until RegQueryValueEx() stops returning
1521  ERROR_MORE_DATA. The following values define the initial buffer size and
1522  step size by which the buffer is increased */
1523 
1524 #define PERFORMANCE_BUFFER_SIZE 65536 /* Start at 64K */
1525 #define PERFORMANCE_BUFFER_STEP 16384 /* Step by 16K */
1526 
1527 static void registryPoll( void )
1528  {
1529  static int cbPerfData = PERFORMANCE_BUFFER_SIZE;
1530  PPERF_DATA_BLOCK pPerfData;
1532  DWORD dwSize, dwStatus;
1533  int iterations = 0, status;
1534 
1535  /* Wait for any async keyset driver binding to complete. You may be
1536  wondering what this call is doing here... the reason why it's
1537  necessary is because RegQueryValueEx() will hang indefinitely if the
1538  async driver bind is in progress. The problem occurs in the dynamic
1539  loading and linking of driver DLL's, which work as follows:
1540 
1541  hDriver = DynamicLoad( DRIVERNAME );
1542  pFunction1 = ( TYPE_FUNC1 ) GetProcAddress( hDriver, NAME_FUNC1 );
1543  pFunction2 = ( TYPE_FUNC1 ) GetProcAddress( hDriver, NAME_FUNC2 );
1544 
1545  If RegQueryValueEx() is called while the GetProcAddress()'s are in
1546  progress, it will hang indefinitely. This is probably due to some
1547  synchronisation problem in the NT kernel where the GetProcAddress()
1548  calls affect something like a module reference count or function
1549  reference count while RegQueryValueEx() is trying to take a snapshot of
1550  the statistics, which include the reference counts. Because of this,
1551  we have to wait until any async driver bind has completed before we can
1552  call RegQueryValueEx() */
1554  {
1555  /* The kernel is shutting down, bail out */
1556  return;
1557  }
1558 
1559  /* Get information from the system performance counters. This can take a
1560  few seconds to do. In some environments the call to RegQueryValueEx()
1561  can produce an access violation at some random time in the future, in
1562  some cases adding a short delay after the following code block makes
1563  the problem go away. This problem is extremely difficult to
1564  reproduce, I haven't been able to get it to occur despite running it
1565  on a number of machines. MS knowledge base article Q178887 covers
1566  this type of problem, it's typically caused by an external driver or
1567  other program that adds its own values under the
1568  HKEY_PERFORMANCE_DATA key. The NT kernel, via Advapi32.dll, calls the
1569  required external module to map in the data inside an SEH try/except
1570  block, so problems in the module's collect function don't pop up until
1571  after it has finished, so the fault appears to occur in Advapi32.dll.
1572  There may be problems in the NT kernel as well though, a low-level
1573  memory checker indicated that ExpandEnvironmentStrings() in
1574  Kernel32.dll, called an interminable number of calls down inside
1575  RegQueryValueEx(), was overwriting memory (it wrote twice the
1576  allocated size of a buffer to a buffer allocated by the NT kernel).
1577  OTOH this could be coming from the external module calling back into
1578  the kernel, which eventually causes the problem described above.
1579 
1580  Possibly as an extension of the problem that the krnlWaitSemaphore()
1581  call above works around, running two instances of cryptlib (e.g. two
1582  applications that use it) under NT4 can result in one of them hanging
1583  in the RegQueryValueEx() call. This happens only under NT4 and is
1584  hard to reproduce in any consistent manner.
1585 
1586  One workaround that helps a bit is to read the registry as a remote
1587  (rather than local) registry, it's possible that the use of a network
1588  RPC call isolates the calling app from the problem in that whatever
1589  service handles the RPC is taking the hit and not affecting the
1590  calling app. Since this would require another round of extensive
1591  testing to verify and the NT native API call is working fine, we'll
1592  stick with the native API call for now.
1593 
1594  Some versions of NT4 had a problem where the amount of data returned
1595  was mis-reported and would never settle down, because of this the code
1596  below includes a safety-catch that bails out after 10 attempts have
1597  been made, this results in no data being returned but at does ensure
1598  that the thread will terminate.
1599 
1600  In addition to these problems the code in RegQueryValueEx() that
1601  estimates the amount of memory required to return the performance
1602  counter information isn't very accurate (it's much worse than the
1603  "slightly-inaccurate" level that the MS docs warn about, it's usually
1604  wildly off) since it always returns a worst-case estimate which is
1605  usually nowhere near the actual amount required. For example it may
1606  report that 128K of memory is required, but only return 64K of data.
1607 
1608  Even worse than the registry-based performance counters is the
1609  performance data helper (PDH) shim that tries to make the counters
1610  look like the old Win16 API (which is also used by Win95). Under NT
1611  this can consume tens of MB of memory and huge amounts of CPU time
1612  while it gathers its data, and even running once can still consume
1613  about 1/2MB of memory.
1614 
1615  "Windows NT is a thing of genuine beauty, if you're seriously into
1616  genuine ugliness. It's like a woman with a history of insanity in
1617  the family, only worse" -- Hans Chloride, "Why I Love Windows NT" */
1618  pPerfData = ( PPERF_DATA_BLOCK ) clAlloc( "slowPollNT", cbPerfData );
1619  while( pPerfData != NULL && iterations++ < 10 )
1620  {
1621  dwSize = cbPerfData;
1622  dwStatus = RegQueryValueEx( HKEY_PERFORMANCE_DATA, "Global", NULL,
1623  NULL, ( LPBYTE ) pPerfData, &dwSize );
1624  if( dwStatus == ERROR_SUCCESS )
1625  {
1626  if( !memcmp( pPerfData->Signature, L"PERF", 8 ) )
1627  {
1628  static const int quality = 100;
1629 
1630  setMessageData( &msgData, pPerfData, dwSize );
1632  IMESSAGE_SETATTRIBUTE_S, &msgData,
1633  CRYPT_IATTRIBUTE_ENTROPY );
1634  if( cryptStatusOK( status ) )
1637  ( MESSAGE_CAST ) &quality,
1638  CRYPT_IATTRIBUTE_ENTROPY_QUALITY );
1639  }
1640  clFree( "slowPollWinNT", pPerfData );
1641  pPerfData = NULL;
1642  }
1643  else
1644  {
1645  if( dwStatus == ERROR_MORE_DATA )
1646  {
1647  PPERF_DATA_BLOCK pTempPerfData;
1648 
1649  cbPerfData += PERFORMANCE_BUFFER_STEP;
1650  pTempPerfData = ( PPERF_DATA_BLOCK ) realloc( pPerfData, cbPerfData );
1651  if( pTempPerfData == NULL )
1652  {
1653  /* The realloc failed, free the original block and force
1654  a loop exit */
1655  clFree( "slowPollWinNT", pPerfData );
1656  pPerfData = NULL;
1657  }
1658  else
1659  pPerfData = pTempPerfData;
1660  }
1661  }
1662  }
1663 
1664  /* Although this isn't documented in the Win32 API docs, it's necessary to
1665  explicitly close the HKEY_PERFORMANCE_DATA key after use (it's
1666  implicitly opened on the first call to RegQueryValueEx()). If this
1667  isn't done then any system components that provide performance data
1668  can't be removed or changed while the handle remains active */
1669  RegCloseKey( HKEY_PERFORMANCE_DATA );
1670  }
1671 
1672 static void slowPollWinNT( void )
1673  {
1674  static BOOLEAN addedFixedItems = FALSE;
1675  static int isWorkstation = CRYPT_ERROR;
1677  HANDLE hDevice;
1678  LPBYTE lpBuffer;
1679  ULONG ulSize;
1680  DWORD dwType, dwSize, dwResult;
1681  void *buffer;
1682  int nDrive, noResults = 0, status;
1683 
1684  /* Find out whether this is an NT server or workstation if necessary */
1685  if( isWorkstation == CRYPT_ERROR )
1686  {
1687  HKEY hKey;
1688 
1689  if( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
1690  "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
1691  0, KEY_READ, &hKey ) == ERROR_SUCCESS )
1692  {
1693  BYTE szValue[ 32 + 8 ];
1694  dwSize = 32;
1695 
1696  isWorkstation = TRUE;
1697  if( RegQueryValueEx( hKey, "ProductType", 0, NULL, szValue,
1698  &dwSize ) == ERROR_SUCCESS && \
1699  dwSize >= 5 && strCompare( szValue, "WinNT", 5 ) )
1700  {
1701  /* Note: There are (at least) three cases for ProductType:
1702  WinNT = NT Workstation, ServerNT = NT Server, LanmanNT =
1703  NT Server acting as a Domain Controller */
1704  isWorkstation = FALSE;
1705  }
1706 
1707  RegCloseKey( hKey );
1708  }
1709  }
1710 
1711  /* The following are fixed for the lifetime of the process so we only
1712  add them once */
1713  if( !addedFixedItems )
1714  {
1715  readPnPData();
1716  addedFixedItems = TRUE;
1717  }
1718 
1719  /* Initialize the NetAPI32 function pointers if necessary */
1720  if( hNetAPI32 == NULL )
1721  {
1722  /* Obtain a handle to the module containing the Lan Manager functions */
1723  if( ( hNetAPI32 = DynamicLoad( "NetAPI32.dll" ) ) != NULL )
1724  {
1725  /* Now get pointers to the functions */
1726  pNetStatisticsGet = ( NETSTATISTICSGET ) GetProcAddress( hNetAPI32,
1727  "NetStatisticsGet" );
1728  pNetApiBufferSize = ( NETAPIBUFFERSIZE ) GetProcAddress( hNetAPI32,
1729  "NetApiBufferSize" );
1730  pNetApiBufferFree = ( NETAPIBUFFERFREE ) GetProcAddress( hNetAPI32,
1731  "NetApiBufferFree" );
1732 
1733  /* Make sure we got valid pointers for every NetAPI32 function */
1734  if( pNetStatisticsGet == NULL ||
1735  pNetApiBufferSize == NULL ||
1736  pNetApiBufferFree == NULL )
1737  {
1738  /* Free the library reference and reset the static handle */
1739  DynamicUnload( hNetAPI32 );
1740  hNetAPI32 = NULL;
1741  }
1742  }
1743  }
1744 
1745  /* Initialize the NT kernel native API function pointers if necessary */
1746  if( hNTAPI == NULL && \
1747  ( hNTAPI = GetModuleHandle( "NTDll.dll" ) ) != NULL )
1748  {
1749  /* Get a pointer to the NT native information query functions */
1750  pNtQuerySystemInformation = ( NTQUERYSYSTEMINFORMATION ) \
1751  GetProcAddress( hNTAPI, "NtQuerySystemInformation" );
1752  pNtQueryInformationProcess = ( NTQUERYINFORMATIONPROCESS ) \
1753  GetProcAddress( hNTAPI, "NtQueryInformationProcess" );
1754  if( pNtQuerySystemInformation == NULL || \
1755  pNtQueryInformationProcess == NULL )
1756  hNTAPI = NULL;
1757  pNtPowerInformation = ( NTPOWERINFORMATION ) \
1758  GetProcAddress( hNTAPI, "NtPowerInformation" );
1759  }
1760  if( krnlIsExiting() )
1761  return;
1762 
1763  /* Get network statistics. Note: Both NT Workstation and NT Server by
1764  default will be running both the workstation and server services. The
1765  heuristic below is probably useful though on the assumption that the
1766  majority of the network traffic will be via the appropriate service. In
1767  any case the network statistics return almost no randomness */
1768  if( hNetAPI32 != NULL &&
1769  pNetStatisticsGet( NULL,
1770  isWorkstation ? L"LanmanWorkstation" : L"LanmanServer",
1771  0, 0, &lpBuffer ) == 0 )
1772  {
1773  pNetApiBufferSize( lpBuffer, &dwSize );
1774  setMessageData( &msgData, lpBuffer, dwSize );
1776  &msgData, CRYPT_IATTRIBUTE_ENTROPY );
1777  pNetApiBufferFree( lpBuffer );
1778  }
1779 
1780  /* Get disk I/O statistics for all the hard drives */
1781  for( nDrive = 0; nDrive < FAILSAFE_ITERATIONS_MED; nDrive++ )
1782  {
1783  BYTE diskPerformance[ 256 + 8 ];
1784  char szDevice[ 32 + 8 ];
1785 
1786  /* Check whether we can access this device */
1787  sprintf_s( szDevice, 32, "\\\\.\\PhysicalDrive%d", nDrive );
1788  hDevice = CreateFile( szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
1789  NULL, OPEN_EXISTING, 0, NULL );
1790  if( hDevice == INVALID_HANDLE_VALUE )
1791  break;
1792 
1793  /* Note: This only works if the user has turned on the disk
1794  performance counters with 'diskperf -y'. These counters were
1795  traditionally disabled under NT, although in newer installs of
1796  Win2K and newer the physical disk object is enabled by default
1797  while the logical disk object is disabled by default
1798  ('diskperf -yv' turns on the counters for logical drives in this
1799  case, since they're already on for physical drives).
1800 
1801  In addition using the documented DISK_PERFORMANCE data structure
1802  to contain the returned data returns ERROR_INSUFFICIENT_BUFFER
1803  (which is wrong) and doesn't change dwSize (which is also wrong)
1804  so we pass in a larger buffer and pre-set dwSize to a safe
1805  value. Finally, there's a bug in pre-SP4 Win2K in which enabling
1806  diskperf, installing a file system filter driver, and then
1807  disabling diskperf, causes diskperf to corrupt the registry key
1808  HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
1809  {71A27CDD-812A-11D0-BEC7-08002BE2092F}\Upper Filters, resulting
1810  in a Stop 0x7B bugcheck */
1811  dwSize = sizeof( diskPerformance );
1812  if( DeviceIoControl( hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
1813  &diskPerformance, 256, &dwSize, NULL ) )
1814  {
1815  if( krnlIsExiting() )
1816  {
1817  CloseHandle( hDevice );
1818  return;
1819  }
1820  setMessageData( &msgData, &diskPerformance, dwSize );
1822  &msgData, CRYPT_IATTRIBUTE_ENTROPY );
1823  }
1824  CloseHandle( hDevice );
1825  }
1826  if( krnlIsExiting() )
1827  return;
1828 
1829  /* In theory we should be using the Win32 performance query API to obtain
1830  unpredictable data from the system, however this is so unreliable (see
1831  the multiple sets of comments in registryPoll()) that it's too risky
1832  to rely on it except as a fallback in emergencies. Instead, we rely
1833  mostly on the NT native API function NtQuerySystemInformation(), which
1834  has the dual advantages that it doesn't have as many (known) problems
1835  as the Win32 equivalent and that it doesn't access the data indirectly
1836  via pseudo-registry keys, which means that it's much faster. Note
1837  that the Win32 equivalent actually works almost all of the time, the
1838  problem is that on one or two systems it can fail in strange ways that
1839  are never the same and can't be reproduced on any other system, which
1840  is why we use the native API here. Microsoft officially documented
1841  this function in early 2003, so it'll be fairly safe to use */
1842  if( ( hNTAPI == NULL ) || \
1843  ( buffer = clAlloc( "slowPollNT", PERFORMANCE_BUFFER_SIZE ) ) == NULL )
1844  {
1845  registryPoll();
1846  return;
1847  }
1848 
1849  /* Clear the buffer before use. We have to do this because even though
1850  NtQuerySystemInformation() tells us that it's filled in ulSize bytes,
1851  it doesn't necessarily mean that it actually has provided that much
1852  data */
1853  memset( buffer, 0, PERFORMANCE_BUFFER_SIZE );
1854 
1855  /* Scan the first 64 possible information types (we don't bother with
1856  increasing the buffer size as we do with the Win32 version of the
1857  performance data read, we may miss a few classes but it's no big deal).
1858  This scan typically yields around 20 pieces of data, there's nothing
1859  in the range 65...128 so chances are there won't be anything above
1860  there either */
1861  for( dwType = 0; dwType < 64; dwType++ )
1862  {
1863  /* Some information types are write-only (the IDs are shared with
1864  a set-information call), we skip these */
1865  if( dwType == 26 || dwType == 27 || dwType == 38 || \
1866  dwType == 38 || dwType == 46 || dwType == 47 || \
1867  dwType == 48 || dwType == 52 )
1868  continue;
1869 
1870  /* ID 53 = SystemSessionProcessInformation reads input from the
1871  output buffer, which has to contain a session ID and pointer
1872  to the actual buffer in which to store the session information.
1873  Because this isn't a standard query, we skip this */
1874  if( dwType == 53 )
1875  continue;
1876 
1877  /* Query the info for this ID. Some results (for example for
1878  ID = 6, SystemCallCounts) are only available in checked builds
1879  of the kernel. A smaller subcless of results require that
1880  certain system config flags be set, for example
1881  SystemObjectInformation requires that the
1882  FLG_MAINTAIN_OBJECT_TYPELIST be set in NtGlobalFlags. To avoid
1883  having to special-case all of these, we try reading each one and
1884  only use those for which we get a success status */
1885  dwResult = pNtQuerySystemInformation( dwType, buffer,
1886  PERFORMANCE_BUFFER_SIZE - 2048,
1887  &ulSize );
1888  if( dwResult != ERROR_SUCCESS )
1889  continue;
1890 
1891  /* Some calls (e.g. ID = 23, SystemProcessorStatistics, and ID = 24,
1892  SystemDpcInformation) incorrectly return a length of zero, so we
1893  manually adjust the length to the correct value */
1894  if( ulSize == 0 )
1895  {
1896  if( dwType == 23 )
1897  ulSize = 6 * sizeof( ULONG );
1898  if( dwType == 24 )
1899  ulSize = 5 * sizeof( ULONG );
1900  }
1901 
1902  /* If we got some data back, add it to the entropy pool. Note that
1903  just because NtQuerySystemInformation() tells us that it's
1904  provided ulSize bytes doesn't necessarily mean that it has, see
1905  the comment after the malloc() for details */
1906  if( ulSize > 0 && ulSize <= PERFORMANCE_BUFFER_SIZE - 2048 )
1907  {
1908  if( krnlIsExiting() )
1909  {
1910  clFree( "slowPollWinNT", buffer );
1911  return;
1912  }
1913  setMessageData( &msgData, buffer, ulSize );
1915  IMESSAGE_SETATTRIBUTE_S, &msgData,
1916  CRYPT_IATTRIBUTE_ENTROPY );
1917  if( cryptStatusOK( status ) )
1918  noResults++;
1919  }
1920  }
1921 
1922  /* Now do the same for the process information. This call is rather ugly
1923  in that it requires an exact length match for the data returned,
1924  failing with a STATUS_INFO_LENGTH_MISMATCH error code (0xC0000004) if
1925  the length isn't an exact match */
1926 #if 0 /* This requires compiler-level assistance to handle complex nested
1927  structs, alignment issues, and so on. Without the headers in
1928  which the entries are declared it's almost impossible to do */
1929  for( dwType = 0; dwType < 32; dwType++ )
1930  {
1931  static const struct { int type; int size; } processInfo[] = {
1933  };
1934  int i;
1935 
1936  for( i = 0; processInfo[ i ].type != CRYPT_ERROR && \
1937  i < FAILSAFE_ITERATIONS_SMALL; i++ )
1938  {
1939  /* Query the info for this ID */
1940  dwResult = pNtQueryInformationProcess( GetCurrentProcess(),
1941  processInfo[ i ].type, buffer,
1942  processInfo[ i ].size, &ulSize );
1943  if( dwResult != ERROR_SUCCESS )
1944  continue;
1945 
1946  /* If we got some data back, add it to the entropy pool */
1947  if( ulSize > 0 && ulSize <= PERFORMANCE_BUFFER_SIZE - 2048 )
1948  {
1949  if( krnlIsExiting() )
1950  {
1951  clFree( "slowPollWinNT", buffer );
1952  return;
1953  }
1954  setMessageData( &msgData, buffer, ulSize );
1956  IMESSAGE_SETATTRIBUTE_S, &msgData,
1957  CRYPT_IATTRIBUTE_ENTROPY );
1958  if( cryptStatusOK( status ) )
1959  noResults++;
1960  }
1961  }
1962  ENSURES( i < FAILSAFE_ITERATIONS_SMALL );
1963  }
1964 #endif /* 0 */
1965 
1966  /* Finally do the same for the system power status information. There
1967  are only a limited number of useful information types available so we
1968  restrict ourselves to the useful types. In addition since this
1969  function doesn't return length information we have to hardcode in
1970  length data */
1971  if( pNtPowerInformation != NULL )
1972  {
1973  static const struct { int type; int size; } powerInfo[] = {
1974  { 0, 128 }, /* SystemPowerPolicyAc */
1975  { 1, 128 }, /* SystemPowerPolicyDc */
1976  { 4, 64 }, /* SystemPowerCapabilities */
1977  { 5, 48 }, /* SystemBatteryState */
1978  { 11, 48 }, /* ProcessorInformation */
1979  { 12, 24 }, /* SystemPowerInformation */
1981  };
1982  int i;
1983 
1984  for( i = 0; powerInfo[ i ].type != CRYPT_ERROR && \
1985  i < FAILSAFE_ITERATIONS_MED; i++ )
1986  {
1987  /* Query the info for this ID */
1988  dwResult = pNtPowerInformation( powerInfo[ i ].type, NULL, 0, buffer,
1989  PERFORMANCE_BUFFER_SIZE - 2048 );
1990  if( dwResult != ERROR_SUCCESS )
1991  continue;
1992  if( krnlIsExiting() )
1993  {
1994  clFree( "slowPollWinNT", buffer );
1995  return;
1996  }
1997  setMessageData( &msgData, buffer, powerInfo[ i ].size );
1999  IMESSAGE_SETATTRIBUTE_S, &msgData,
2000  CRYPT_IATTRIBUTE_ENTROPY );
2001  if( cryptStatusOK( status ) )
2002  noResults++;
2003  }
2004  ENSURES_V( i < FAILSAFE_ITERATIONS_MED );
2005  }
2006  clFree( "slowPollWinNT", buffer );
2007 
2008  /* If we got enough data, we can leave now without having to try for a
2009  Win32-level performance information query */
2010  if( noResults > 15 )
2011  {
2012  static const int quality = 100;
2013 
2014  if( krnlIsExiting() )
2015  return;
2017  ( MESSAGE_CAST ) &quality,
2018  CRYPT_IATTRIBUTE_ENTROPY_QUALITY );
2019  return;
2020  }
2021  if( krnlIsExiting() )
2022  return;
2023 
2024  /* We couldn't get enough results from the kernel, fall back to the
2025  somewhat troublesome registry poll */
2026  registryPoll();
2027  }
2028 
2029 /* Perform a thread-safe slow poll for Windows NT */
2030 
2031 unsigned __stdcall threadSafeSlowPollWinNT( void *dummy )
2032  {
2033 #if 0
2034  typedef BOOL ( WINAPI *CREATERESTRICTEDTOKEN )( HANDLE ExistingTokenHandle,
2035  DWORD Flags, DWORD DisableSidCount,
2036  PSID_AND_ATTRIBUTES SidsToDisable,
2037  DWORD DeletePrivilegeCount,
2038  PLUID_AND_ATTRIBUTES PrivilegesToDelete,
2039  DWORD RestrictedSidCount,
2040  PSID_AND_ATTRIBUTES SidsToRestrict,
2041  PHANDLE NewTokenHandle );
2042  static CREATERESTRICTEDTOKEN pCreateRestrictedToken = NULL;
2043  static BOOLEAN isInited = FALSE;
2044 #endif /* 0 */
2045 
2046  UNUSED_ARG( dummy );
2047 
2048  /* If the poll performed any kind of active operation like the Unix one
2049  rather than just basic data reads it'd be a good idea to drop
2050  privileges before we begin, something that can be performed by the
2051  following code. Note though that this creates all sorts of
2052  complications when cryptlib is running as a service and/or performing
2053  impersonation, which is why it's disabled by default */
2054 #if 0
2055  if( !isInited )
2056  {
2057  /* Since CreateRestrictedToken() is a Win2K function we can only use
2058  it on a post-NT4 system, and have to bind it at runtime */
2059  if( getSysVar( SYSVAR_OSVERSION ) > 4 )
2060  {
2061  const HINSTANCE hAdvAPI32 = GetModuleHandle( "AdvAPI32.dll" );
2062 
2063  pCreateRestrictedToken = ( CREATERESTRICTEDTOKEN ) \
2064  GetProcAddress( hAdvAPI32, "CreateRestrictedToken" );
2065  }
2066  isInited = TRUE;
2067  }
2068  if( pCreateRestrictedToken != NULL )
2069  {
2070  HANDLE hToken, hNewToken;
2071 
2072  ImpersonateSelf( SecurityImpersonation );
2073  OpenThreadToken( GetCurrentThread(),
2074  TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | \
2075  TOKEN_QUERY | TOKEN_ADJUST_DEFAULT | \
2076  TOKEN_IMPERSONATE, TRUE, &hToken );
2077  CreateRestrictedToken( hToken, DISABLE_MAX_PRIVILEGE, 0, NULL, 0, NULL,
2078  0, NULL, &hNewToken );
2079  SetThreadToken( &hThread, hNewToken );
2080  }
2081 #endif /* 0 */
2082 
2083  slowPollWinNT();
2084 #if 0
2085  if( pCreateRestrictedToken != NULL )
2086  RevertToSelf();
2087 #endif /* 0 */
2088  _endthreadex( 0 );
2089  return( 0 );
2090  }
2091 
2092 /* Perform a generic slow poll. This starts the OS-specific poll in a
2093  separate thread */
2094 
2095 void slowPoll( void )
2096  {
2097  if( krnlIsExiting() )
2098  return;
2099 
2100  /* Read data from various hardware sources */
2101  readSystemRNG();
2102  readMBMData();
2103  readEverestData();
2104  readSysToolData();
2105  readRivaTunerData();
2106  readHMonitorData();
2107  readATITrayToolsData();
2108  readCoreTempData();
2109  readGPUZData();
2110 
2111  /* Start a threaded slow poll. If a slow poll is already running, we
2112  just return since there isn't much point in running two of them at the
2113  same time */
2115  return;
2116  if( hThread != NULL )
2117  {
2119  return;
2120  }
2121 #ifndef __WIN64__
2122  if( getSysVar( SYSVAR_ISWIN95 ) == TRUE )
2123  {
2124  hThread = ( HANDLE ) _beginthreadex( NULL, 0, threadSafeSlowPollWin95,
2125  NULL, 0, &threadID );
2126  }
2127  else
2128 #endif /* __WIN64__ */
2129  {
2130  /* In theory since the thread is gathering info used (eventually)
2131  for crypto keys we could set an ACL on the thread to make it
2132  explicit that no-one else can mess with it:
2133 
2134  void *aclInfo = initACLInfo( THREAD_ALL_ACCESS );
2135 
2136  hThread = ( HANDLE ) _beginthreadex( getACLInfo( aclInfo ),
2137  0, threadSafeSlowPollWinNT,
2138  NULL, 0, &threadID );
2139  freeACLInfo( aclInfo );
2140 
2141  However, although this is supposed to be the default access for
2142  threads anyway, when used from a service (running under the
2143  LocalSystem account) under Win2K SP4 and up, the thread creation
2144  fails with error = 22 (invalid parameter). Presumably MS patched
2145  some security hole or other in SP4, which causes the thread
2146  creation to fail. Because of this problem, we don't set an ACL for
2147  the thread */
2148  hThread = ( HANDLE ) _beginthreadex( NULL, 0,
2150  NULL, 0, &threadID );
2151  }
2153  assert( hThread );
2154  }
2155 
2156 /* Wait for the randomness gathering to finish. Anything that requires the
2157  gatherer process to have completed gathering entropy should call
2158  waitforRandomCompletion(), which will block until the background process
2159  completes */
2160 
2161 CHECK_RETVAL \
2163  {
2164  DWORD dwResult;
2165  const DWORD timeout = force ? 2000 : 300000L;
2166  int status;
2167 
2168  /* If there's no polling thread running, there's nothing to do. Note
2169  that this isn't entirely thread-safe because someone may start
2170  another poll after we perform this check, but there's no way to
2171  handle this without some form of interlock mechanism with the
2172  randomness mutex and the WaitForSingleObject(). In any case all
2173  that'll happen is that the caller won't get all of the currently-
2174  polling entropy */
2175  if( hThread == NULL )
2176  return( CRYPT_OK );
2177 
2178  /* Wait for the polling thread to terminate. If it's a forced shutdown
2179  we only wait a short amount of time (2s) before we bail out,
2180  otherwise we hang around for as long as it takes (with a sanity-check
2181  upper limit of 5 minutes) */
2182  dwResult = WaitForSingleObject( hThread, timeout );
2183  if( dwResult != WAIT_OBJECT_0 )
2184  {
2185  /* Since this is a cleanup function there's not much that we can do
2186  at this point, although we warn in debug mode */
2187  DEBUG_DIAG(( "Error %lX waiting for object", dwResult ));
2188  assert( DEBUG_WARN );
2189  return( CRYPT_OK );
2190  }
2191  assert( dwResult != WAIT_FAILED ); /* Warn in debug mode */
2192 
2193  /* Clean up */
2194  status = krnlEnterMutex( MUTEX_RANDOM );
2195  if( cryptStatusError( status ) )
2196  return( status );
2197  if( hThread != NULL )
2198  {
2199  CloseHandle( hThread );
2200  hThread = NULL;
2201  }
2203 
2204  return( CRYPT_OK );
2205  }
2206 
2207 /* Initialise and clean up any auxiliary randomness-related objects */
2208 
2209 void initRandomPolling( void )
2210  {
2211  /* Reset the various module and object handles and status info and
2212  initialise the system RNG interface if it's present */
2213  hAdvAPI32 = hNetAPI32 = hThread = NULL;
2214  initSystemRNG();
2215  }
2216 
2217 void endRandomPolling( void )
2218  {
2219  assert( hThread == NULL );
2220  if( hNetAPI32 )
2221  {
2222  DynamicUnload( hNetAPI32 );
2223  hNetAPI32 = NULL;
2224  }
2225  endSystemRNG();
2226  }