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