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