Applied spelling fixes and more verbose test diagnositcs by Brad Hards.
[libgcrypt.git] / random / rndw32.c
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.  */
122 typedef DWORD (WINAPI *NETSTATISTICSGET)(LPWSTR szServer, LPWSTR szService,
123                                          DWORD dwLevel, DWORD dwOptions,
124                                          LPBYTE *lpBuffer);
125 typedef DWORD (WINAPI *NETAPIBUFFERSIZE)(LPVOID lpBuffer, LPDWORD cbBuffer);
126 typedef DWORD (WINAPI *NETAPIBUFFERFREE)(LPVOID lpBuffer);
127
128 /* Type definitions for function pointers to call native NT functions.  */
129 typedef DWORD (WINAPI *NTQUERYSYSTEMINFORMATION)(DWORD systemInformationClass,
130                                                  PVOID systemInformation,
131                                                  ULONG systemInformationLength,
132                                                  PULONG returnLength);
133 typedef DWORD (WINAPI *NTQUERYINFORMATIONPROCESS)
134      (HANDLE processHandle, DWORD processInformationClass,
135       PVOID processInformation, ULONG processInformationLength,
136       PULONG returnLength);
137 typedef 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. */
142 typedef BOOL (WINAPI *CRYPTACQUIRECONTEXT)(HCRYPTPROV *phProv,
143                                            LPCTSTR pszContainer,
144                                            LPCTSTR pszProvider, 
145                                            DWORD dwProvType,
146                                            DWORD dwFlags);
147 typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,
148                                       BYTE *pbBuffer);
149 typedef 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.  */
159 typedef 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
170 typedef struct 
171 {
172   SensorType iType;               /* Type of sensor.  */
173   int Count;                      /* Number of sensor for that type.  */
174 } SharedIndex;
175
176 typedef 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
192 typedef 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
204 typedef 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.  */
226 static HANDLE hNetAPI32;
227 static NETSTATISTICSGET pNetStatisticsGet;
228 static NETAPIBUFFERSIZE pNetApiBufferSize;
229 static NETAPIBUFFERFREE pNetApiBufferFree;
230
231 static HANDLE hNTAPI;
232 static NTQUERYSYSTEMINFORMATION  pNtQuerySystemInformation;
233 static NTQUERYINFORMATIONPROCESS pNtQueryInformationProcess;
234 static NTPOWERINFORMATION        pNtPowerInformation;
235
236 static HANDLE hAdvAPI32;
237 static CRYPTACQUIRECONTEXT pCryptAcquireContext;
238 static CRYPTGENRANDOM      pCryptGenRandom;
239 static CRYPTRELEASECONTEXT pCryptReleaseContext;
240 static RTLGENRANDOM        pRtlGenRandom;
241
242
243 /* Other module global variables.  */
244 static int system_rng_available; /* Whether a system RNG is available.  */
245 static HCRYPTPROV hRNGProv;      /* Handle to Intel RNG CSP. */
246
247 static int debug_me;  /* Debug flag.  */
248
249 static int system_is_w2000;     /* True if running on W2000.  */
250
251
252
253 \f
254 /* Try and connect to the system RNG if there's one present. */
255 static void 
256 init_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.  */
296 static void 
297 read_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.  */
332 static void
333 read_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.  */
357 static void
358 registry_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   pPerfData = gcry_xmalloc (cbPerfData);
422   for (iterations=0; iterations < 10; iterations++)
423     {
424       dwSize = cbPerfData;
425       if ( debug_me )
426         log_debug ("rndw32#slow_gatherer_nt: get perf data\n" );
427
428       status = RegQueryValueEx (HKEY_PERFORMANCE_DATA, "Global", NULL,
429                                 NULL, (LPBYTE) pPerfData, &dwSize);
430       if (status == ERROR_SUCCESS)
431         {
432           if (!memcmp (pPerfData->Signature, L"PERF", 8))
433             (*add) ( pPerfData, dwSize, requester );
434           else
435             log_debug ("rndw32: no PERF signature\n");
436           break;
437         }
438       else if (status == ERROR_MORE_DATA)
439         {
440           cbPerfData += PERFORMANCE_BUFFER_STEP;
441           pPerfData = gcry_xrealloc (pPerfData, cbPerfData);
442         }
443       else
444         {
445           static int been_here;
446
447           /* Silence the error message.  In particular under Wine (as
448              of 2008) we would get swamped with such diagnotiscs.  One
449              such diagnotiscs should be enough.  */
450           if (been_here != status)
451             {
452               been_here = status;
453               log_debug ("rndw32: get performance data problem: ec=%ld\n",
454                          status);
455             }
456           break;
457         }
458     }
459   gcry_free (pPerfData);
460
461   /* Although this isn't documented in the Win32 API docs, it's necessary
462      to explicitly close the HKEY_PERFORMANCE_DATA key after use (it's
463      implicitly opened on the first call to RegQueryValueEx()).  If this
464      isn't done then any system components which provide performance data
465      can't be removed or changed while the handle remains active.  */
466   RegCloseKey (HKEY_PERFORMANCE_DATA);
467 }
468
469
470 static void
471 slow_gatherer ( void (*add)(const void*, size_t, enum random_origins), 
472                 enum random_origins requester )
473 {
474   static int is_initialized = 0;
475   static int is_workstation = 1;
476   HANDLE hDevice;
477   DWORD dwType, dwSize, dwResult;
478   ULONG ulSize;
479   int drive_no, status;
480   int no_results = 0;
481   void *buffer;
482
483   if ( !is_initialized )
484     {
485       HKEY hKey;
486
487       if ( debug_me )
488         log_debug ("rndw32#slow_gatherer: init toolkit\n" );
489       /* Find out whether this is an NT server or workstation if necessary */
490       if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
491                         "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
492                         0, KEY_READ, &hKey) == ERROR_SUCCESS)
493         {
494           BYTE szValue[32 + 8];
495           dwSize = 32;
496
497           if ( debug_me )
498             log_debug ("rndw32#slow_gatherer: check product options\n" );
499
500           status = RegQueryValueEx (hKey, "ProductType", 0, NULL,
501                                     szValue, &dwSize);
502           if (status == ERROR_SUCCESS && stricmp (szValue, "WinNT"))
503             {
504               /* Note: There are (at least) three cases for ProductType:
505                  WinNT = NT Workstation, ServerNT = NT Server, LanmanNT =
506                  NT Server acting as a Domain Controller.  */
507               is_workstation = 0;
508               if ( debug_me )
509                 log_debug ("rndw32: this is a NT server\n");
510             }
511           RegCloseKey (hKey);
512         }
513
514       /* The following are fixed for the lifetime of the process so we
515          only add them once */
516       /* readPnPData ();  - we have not implemented that.  */
517
518       /* Initialize the NetAPI32 function pointers if necessary */
519       hNetAPI32 = LoadLibrary ("NETAPI32.DLL");
520       if (hNetAPI32)
521         {
522           if (debug_me)
523             log_debug ("rndw32#slow_gatherer: netapi32 loaded\n" );
524           pNetStatisticsGet = (NETSTATISTICSGET)
525             GetProcAddress (hNetAPI32, "NetStatisticsGet");
526           pNetApiBufferSize = (NETAPIBUFFERSIZE)
527             GetProcAddress (hNetAPI32, "NetApiBufferSize");
528           pNetApiBufferFree = (NETAPIBUFFERFREE)
529             GetProcAddress (hNetAPI32, "NetApiBufferFree");
530
531           if (!pNetStatisticsGet || !pNetApiBufferSize || !pNetApiBufferFree)
532             {
533               FreeLibrary (hNetAPI32);
534               hNetAPI32 = NULL;
535               log_debug ("rndw32: No NETAPI found\n" );
536             }
537         }
538
539       /* Initialize the NT kernel native API function pointers if necessary */
540       hNTAPI = GetModuleHandle ("NTDll.dll");
541       if (hNTAPI)
542         {
543           /* Get a pointer to the NT native information query functions */
544           pNtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)
545             GetProcAddress (hNTAPI, "NtQuerySystemInformation");
546           pNtQueryInformationProcess = (NTQUERYINFORMATIONPROCESS)
547             GetProcAddress (hNTAPI, "NtQueryInformationProcess");
548           pNtPowerInformation = (NTPOWERINFORMATION)
549             GetProcAddress(hNTAPI, "NtPowerInformation");
550
551           if (!pNtQuerySystemInformation || !pNtQueryInformationProcess)
552             hNTAPI = NULL;
553         }
554
555
556       is_initialized = 1;
557     }
558   
559   read_system_rng ( add, requester );
560   read_mbm_data ( add, requester );
561
562   /* Get network statistics.    Note: Both NT Workstation and NT Server by
563      default will be running both the workstation and server services.  The
564      heuristic below is probably useful though on the assumption that the
565      majority of the network traffic will be via the appropriate service.
566      In any case the network statistics return almost no randomness.  */
567   {
568     LPBYTE lpBuffer;
569     
570     if (hNetAPI32
571         && !pNetStatisticsGet (NULL,
572                                is_workstation ? L"LanmanWorkstation" :
573                                L"LanmanServer", 0, 0, &lpBuffer))
574       {
575         if ( debug_me )
576           log_debug ("rndw32#slow_gatherer: get netstats\n" );
577         pNetApiBufferSize (lpBuffer, &dwSize);
578         (*add) ( lpBuffer, dwSize, requester );
579         pNetApiBufferFree (lpBuffer);
580       }
581   }
582
583   /* Get disk I/O statistics for all the hard drives.  100 is an
584      arbitrary failsafe limit.  */
585   for (drive_no = 0; drive_no < 100 ; drive_no++)
586     {
587       char diskPerformance[SIZEOF_DISK_PERFORMANCE_STRUCT + 8];
588       char szDevice[50];
589       
590       /* Check whether we can access this device.  */
591       snprintf (szDevice, sizeof szDevice, "\\\\.\\PhysicalDrive%d",
592                 drive_no);
593       hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
594                             NULL, OPEN_EXISTING, 0, NULL);
595       if (hDevice == INVALID_HANDLE_VALUE)
596         break; /* No more drives.  */
597         
598       /* Note: This only works if you have turned on the disk performance
599          counters with 'diskperf -y'.  These counters are off by default. */
600       dwSize = sizeof diskPerformance;
601       if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
602                            diskPerformance, SIZEOF_DISK_PERFORMANCE_STRUCT,
603                            &dwSize, NULL))
604         {
605           if ( debug_me )
606             log_debug ("rndw32#slow_gatherer: iostat drive %d\n",
607                        drive_no);
608           (*add) (diskPerformance, dwSize, requester);
609         }
610       else
611         {
612           log_info ("NOTE: you should run 'diskperf -y' "
613                     "to enable the disk statistics\n");
614         }
615       CloseHandle (hDevice);
616     }
617
618   /* In theory we should be using the Win32 performance query API to obtain
619      unpredictable data from the system, however this is so unreliable (see
620      the multiple sets of comments in registryPoll()) that it's too risky
621      to rely on it except as a fallback in emergencies.  Instead, we rely
622      mostly on the NT native API function NtQuerySystemInformation(), which
623      has the dual advantages that it doesn't have as many (known) problems
624      as the Win32 equivalent and that it doesn't access the data indirectly
625      via pseudo-registry keys, which means that it's much faster.  Note
626      that the Win32 equivalent actually works almost all of the time, the
627      problem is that on one or two systems it can fail in strange ways that
628      are never the same and can't be reproduced on any other system, which
629      is why we use the native API here.  Microsoft officially documented
630      this function in early 2003, so it'll be fairly safe to use.  */
631   if ( !hNTAPI )
632     {
633       registry_poll (add, requester);
634       return;
635     }
636
637
638   /* Scan the first 64 possible information types (we don't bother with
639      increasing the buffer size as we do with the Win32 version of the
640      performance data read, we may miss a few classes but it's no big deal).
641      This scan typically yields around 20 pieces of data, there's nothing
642      in the range 65...128 so chances are there won't be anything above
643      there either.  */
644   buffer = gcry_xmalloc (PERFORMANCE_BUFFER_SIZE);
645   for (dwType = 0; dwType < 64; dwType++)
646     {
647       switch (dwType)
648         {
649           /* ID 17 = SystemObjectInformation hangs on some win2k systems.  */
650         case 17:
651           if (system_is_w2000)
652             continue;
653           break;
654
655           /* Some information types are write-only (the IDs are shared with
656              a set-information call), we skip these.  */
657         case 26: case 27: case 38: case 46: case 47: case 48: case 52:
658           continue;
659
660           /* ID 53 = SystemSessionProcessInformation reads input from the
661              output buffer, which has to contain a session ID and pointer
662              to the actual buffer in which to store the session information.
663              Because this isn't a standard query, we skip this.  */
664         case  53:
665           continue;
666         }
667
668       /* Query the info for this ID.  Some results (for example for
669          ID = 6, SystemCallCounts) are only available in checked builds
670          of the kernel.  A smaller subcless of results require that
671          certain system config flags be set, for example
672          SystemObjectInformation requires that the
673          FLG_MAINTAIN_OBJECT_TYPELIST be set in NtGlobalFlags.  To avoid
674          having to special-case all of these, we try reading each one and
675          only use those for which we get a success status.  */
676       dwResult = pNtQuerySystemInformation (dwType, buffer,
677                                             PERFORMANCE_BUFFER_SIZE - 2048,
678                                             &ulSize);
679       if (dwResult != ERROR_SUCCESS)
680         continue;
681
682       /* Some calls (e.g. ID = 23, SystemProcessorStatistics, and ID = 24,
683          SystemDpcInformation) incorrectly return a length of zero, so we
684          manually adjust the length to the correct value.  */
685       if ( !ulSize )
686         {
687           if (dwType == 23)
688             ulSize = 6 * sizeof (ULONG);
689           else if (dwType == 24)
690             ulSize = 5 * sizeof (ULONG);
691         }
692
693       /* If we got some data back, add it to the entropy pool.  */
694       if (ulSize > 0 && ulSize <= PERFORMANCE_BUFFER_SIZE - 2048)
695         {
696           if (debug_me)
697             log_debug ("rndw32#slow_gatherer: %lu bytes from sysinfo %ld\n",
698                        ulSize, dwType);
699           (*add) (buffer, ulSize, requester);
700           no_results++;
701         }
702     }
703
704   /* Now we would do the same for the process information.  This
705      call would rather ugly in that it requires an exact length
706      match for the data returned, failing with a
707      STATUS_INFO_LENGTH_MISMATCH error code (0xC0000004) if the
708      length isn't an exact match.  It requires a compiler to handle
709      complex nested structs, alignment issues, and so on, and
710      without the headers in which the entries are declared it's
711      almost impossible to do.  Thus we don't.  */
712
713
714   /* Finally, do the same for the system power status information.  There
715      are only a limited number of useful information types available so we
716      restrict ourselves to the useful types.  In addition since this
717      function doesn't return length information, we have to hardcode in
718      length data.  */
719   if (pNtPowerInformation)
720     {
721       static const struct { int type; int size; } powerInfo[] = {
722         { 0, 128 },     /* SystemPowerPolicyAc */
723         { 1, 128 },     /* SystemPowerPolicyDc */
724         { 4, 64 },      /* SystemPowerCapabilities */
725         { 5, 48 },      /* SystemBatteryState */
726         { 11, 48 },     /* ProcessorInformation */
727         { 12, 24 },     /* SystemPowerInformation */
728         { -1, -1 }
729       };
730       int i;
731
732       /* The 100 is a failsafe limit.  */
733       for (i = 0; powerInfo[i].type != -1 && i < 100; i++ )
734         {
735           /* Query the info for this ID */
736           dwResult = pNtPowerInformation (powerInfo[i].type, NULL, 0, buffer,
737                                           PERFORMANCE_BUFFER_SIZE - 2048);
738           if (dwResult != ERROR_SUCCESS)
739             continue;
740           if (debug_me)
741             log_debug ("rndw32#slow_gatherer: %u bytes from powerinfo %d\n",
742                        powerInfo[i].size, i);
743           (*add) (buffer, powerInfo[i].size, requester);
744           no_results++;
745         }
746       gcry_assert (i < 100);
747     }
748   gcry_free (buffer);
749
750   /* We couldn't get enough results from the kernel, fall back to the
751      somewhat troublesome registry poll.  */
752   if (no_results < 15)
753     registry_poll (add, requester);
754 }
755
756
757 int
758 _gcry_rndw32_gather_random (void (*add)(const void*, size_t,
759                                         enum random_origins),
760                             enum random_origins origin,
761                             size_t length, int level )
762 {
763   static int is_initialized;
764
765   if (!level)
766     return 0;
767
768   /* We don't differentiate between level 1 and 2 here because there
769      is no internal entropy pool as a scary resource.  It may all work
770      slower, but because our entropy source will never block but
771      deliver some not easy to measure entropy, we assume level 2.  */
772
773   if (!is_initialized)
774     {
775       OSVERSIONINFO osvi = { sizeof( osvi ) };
776
777       GetVersionEx( &osvi );
778       if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT)
779         log_fatal ("can only run on a Windows NT platform\n" );
780       system_is_w2000 = (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0);
781       init_system_rng ();
782       is_initialized = 1;
783     }
784
785   if (debug_me)
786     log_debug ("rndw32#gather_random: ori=%d len=%u lvl=%d\n",
787                origin, (unsigned int)length, level );
788
789   slow_gatherer (add, origin);
790
791   return 0;
792 }
793
794
795
796 void
797 _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
798                                              enum random_origins),
799                                  enum random_origins origin)
800 {
801   static int addedFixedItems = 0;
802
803   if ( debug_me )
804     log_debug ("rndw32#gather_random_fast: ori=%d\n", origin );
805
806   /* Get various basic pieces of system information: Handle of active
807      window, handle of window with mouse capture, handle of clipboard
808      owner handle of start of clpboard viewer list, pseudohandle of
809      current process, current process ID, pseudohandle of current
810      thread, current thread ID, handle of desktop window, handle of
811      window with keyboard focus, whether system queue has any events,
812      cursor position for last message, 1 ms time for last message,
813      handle of window with clipboard open, handle of process heap,
814      handle of procs window station, types of events in input queue,
815      and milliseconds since Windows was started.  */
816
817   {
818     byte buffer[20*sizeof(ulong)], *bufptr;
819
820     bufptr = buffer;
821 #define ADD(f)  do { ulong along = (ulong)(f);                  \
822                      memcpy (bufptr, &along, sizeof (along) );  \
823                      bufptr += sizeof (along);                  \
824                    } while (0)
825
826     ADD ( GetActiveWindow ());
827     ADD ( GetCapture ());
828     ADD ( GetClipboardOwner ());
829     ADD ( GetClipboardViewer ());
830     ADD ( GetCurrentProcess ());
831     ADD ( GetCurrentProcessId ());
832     ADD ( GetCurrentThread ());
833     ADD ( GetCurrentThreadId ());
834     ADD ( GetDesktopWindow ());
835     ADD ( GetFocus ());
836     ADD ( GetInputState ());
837     ADD ( GetMessagePos ());
838     ADD ( GetMessageTime ());
839     ADD ( GetOpenClipboardWindow ());
840     ADD ( GetProcessHeap ());
841     ADD ( GetProcessWindowStation ());
842     ADD ( GetQueueStatus (QS_ALLEVENTS));
843     ADD ( GetTickCount ());
844
845     gcry_assert ( bufptr-buffer < sizeof (buffer) );
846     (*add) ( buffer, bufptr-buffer, origin );
847 #undef ADD
848   }
849
850   /* Get multiword system information: Current caret position, current
851      mouse cursor position.  */
852   {
853     POINT point;
854
855     GetCaretPos (&point);
856     (*add) ( &point, sizeof (point), origin );
857     GetCursorPos (&point);
858     (*add) ( &point, sizeof (point), origin );
859   }
860
861   /* Get percent of memory in use, bytes of physical memory, bytes of
862      free physical memory, bytes in paging file, free bytes in paging
863      file, user bytes of address space, and free user bytes.  */
864   {
865     MEMORYSTATUS memoryStatus;
866
867     memoryStatus.dwLength = sizeof (MEMORYSTATUS);
868     GlobalMemoryStatus (&memoryStatus);
869     (*add) ( &memoryStatus, sizeof (memoryStatus), origin );
870   }
871
872   /* Get thread and process creation time, exit time, time in kernel
873      mode, and time in user mode in 100ns intervals.  */
874   {
875     HANDLE handle;
876     FILETIME creationTime, exitTime, kernelTime, userTime;
877     DWORD minimumWorkingSetSize, maximumWorkingSetSize;
878
879     handle = GetCurrentThread ();
880     GetThreadTimes (handle, &creationTime, &exitTime,
881                     &kernelTime, &userTime);
882     (*add) ( &creationTime, sizeof (creationTime), origin );
883     (*add) ( &exitTime, sizeof (exitTime), origin );
884     (*add) ( &kernelTime, sizeof (kernelTime), origin );
885     (*add) ( &userTime, sizeof (userTime), origin );
886
887     handle = GetCurrentProcess ();
888     GetProcessTimes (handle, &creationTime, &exitTime,
889                      &kernelTime, &userTime);
890     (*add) ( &creationTime, sizeof (creationTime), origin );
891     (*add) ( &exitTime, sizeof (exitTime), origin );
892     (*add) ( &kernelTime, sizeof (kernelTime), origin );
893     (*add) ( &userTime, sizeof (userTime), origin );
894
895     /* Get the minimum and maximum working set size for the current
896        process.  */
897     GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
898                               &maximumWorkingSetSize);
899     (*add) ( &minimumWorkingSetSize,
900              sizeof (minimumWorkingSetSize), origin );
901     (*add) ( &maximumWorkingSetSize,
902              sizeof (maximumWorkingSetSize), origin );
903   }
904
905
906   /* The following are fixed for the lifetime of the process so we only
907    * add them once */
908   if (!addedFixedItems)
909     {
910       STARTUPINFO startupInfo;
911
912       /* Get name of desktop, console window title, new window
913          position and size, window flags, and handles for stdin,
914          stdout, and stderr.  */
915       startupInfo.cb = sizeof (STARTUPINFO);
916       GetStartupInfo (&startupInfo);
917       (*add) ( &startupInfo, sizeof (STARTUPINFO), origin );
918       addedFixedItems = 1;
919     }
920
921   /* The performance of QPC varies depending on the architecture it's
922      running on and on the OS, the MS documentation is vague about the
923      details because it varies so much.  Under Win9x/ME it reads the
924      1.193180 MHz PIC timer.  Under NT/Win2K/XP it may or may not read the
925      64-bit TSC depending on the HAL and assorted other circumstances,
926      generally on machines with a uniprocessor HAL
927      KeQueryPerformanceCounter() uses a 3.579545MHz timer and on machines
928      with a multiprocessor or APIC HAL it uses the TSC (the exact time
929      source is controlled by the HalpUse8254 flag in the kernel).  That
930      choice of time sources is somewhat peculiar because on a
931      multiprocessor machine it's theoretically possible to get completely
932      different TSC readings depending on which CPU you're currently
933      running on, while for uniprocessor machines it's not a problem.
934      However, the kernel appears to synchronise the TSCs across CPUs at
935      boot time (it resets the TSC as part of its system init), so this
936      shouldn't really be a problem.  Under WinCE it's completely platform-
937      dependant, if there's no hardware performance counter available, it
938      uses the 1ms system timer.
939      
940      Another feature of the TSC (although it doesn't really affect us here)
941      is that mobile CPUs will turn off the TSC when they idle, Pentiums
942      will change the rate of the counter when they clock-throttle (to
943      match the current CPU speed), and hyperthreading Pentiums will turn
944      it off when both threads are idle (this more or less makes sense,
945      since the CPU will be in the halted state and not executing any
946      instructions to count).
947      
948      To make things unambiguous, we detect a CPU new enough to call RDTSC
949      directly by checking for CPUID capabilities, and fall back to QPC if
950      this isn't present.  */
951 #ifdef __GNUC__  
952 /*   FIXME: We would need to implement the CPU feature tests first.  */
953 /*   if (cpu_has_feature_rdtsc) */
954 /*     { */
955 /*       uint32_t lo, hi; */
956       /* We cannot use "=A", since this would use %rax on x86_64. */
957 /*       __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); */
958       /* Ignore high 32 bits, hwich are >1s res.  */
959 /*       (*add) (&lo, 4, origin ); */
960 /*     } */
961 /*   else */
962 #endif /*!__GNUC__*/
963     {
964       LARGE_INTEGER performanceCount;
965       
966       if (QueryPerformanceCounter (&performanceCount))
967         {
968           if ( debug_me )
969           log_debug ("rndw32#gather_random_fast: perf data\n");
970           (*add) (&performanceCount, sizeof (performanceCount), origin);
971         }
972       else
973         {
974           /* Millisecond accuracy at best... */
975           DWORD aword = GetTickCount ();
976           (*add) (&aword, sizeof (aword), origin );
977         }
978     }
979
980
981 }