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