1952979da315370f3a76afe67084bffbb8eb2361
[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
249
250 \f
251 /* Try and connect to the system RNG if there's one present. */
252 static void 
253 init_system_rng (void)
254 {
255   system_rng_available = 0;
256   hRNGProv = NULL;
257
258   hAdvAPI32 = GetModuleHandle ("AdvAPI32.dll");
259   if (!hAdvAPI32)
260     return;
261
262   pCryptAcquireContext = (CRYPTACQUIRECONTEXT)
263     GetProcAddress (hAdvAPI32, "CryptAcquireContextA");
264   pCryptGenRandom = (CRYPTGENRANDOM)
265     GetProcAddress (hAdvAPI32, "CryptGenRandom");
266   pCryptReleaseContext = (CRYPTRELEASECONTEXT)
267     GetProcAddress (hAdvAPI32, "CryptReleaseContext");
268   
269   /* Get a pointer to the native randomness function if it's available.  
270      This isn't exported by name, so we have to get it by ordinal.  */
271   pRtlGenRandom = (RTLGENRANDOM)
272     GetProcAddress (hAdvAPI32, "SystemFunction036");
273
274   /* Try and connect to the PIII RNG CSP.  The AMD 768 southbridge (from 
275      the 760 MP chipset) also has a hardware RNG, but there doesn't appear 
276      to be any driver support for this as there is for the Intel RNG so we 
277      can't do much with it.  OTOH the Intel RNG is also effectively dead 
278      as well, mostly due to virtually nonexistant support/marketing by 
279      Intel, it's included here mostly for form's sake.  */
280   if ( (!pCryptAcquireContext || !pCryptGenRandom || !pCryptReleaseContext
281         || !pCryptAcquireContext (&hRNGProv, NULL, INTEL_DEF_PROV,
282                                   PROV_INTEL_SEC, 0) )
283        && !pRtlGenRandom)
284     {
285       hAdvAPI32 = NULL;
286     }
287   else
288     system_rng_available = 1;
289 }
290
291
292 /* Read data from the system RNG if availavle.  */
293 static void 
294 read_system_rng (void (*add)(const void*, size_t, enum random_origins),
295                  enum random_origins requester)
296 {
297   BYTE buffer[ SYSTEMRNG_BYTES + 8 ];
298   int quality = 0;
299
300   if (!system_rng_available)
301     return;
302
303   /* Read SYSTEMRNG_BYTES bytes from the system RNG.  We don't rely on
304      this for all our randomness requirements (particularly the
305      software RNG) in case it's broken in some way.  */
306   if (hRNGProv)
307     {
308       if (pCryptGenRandom (hRNGProv, SYSTEMRNG_BYTES, buffer))
309         quality = 80;
310     }
311   else if (pRtlGenRandom)
312     {
313       if ( pRtlGenRandom (buffer, SYSTEMRNG_BYTES))
314         quality = 50;
315     }
316   if (quality > 0)
317     {
318       if (debug_me)
319         log_debug ("rndw32#read_system_rng: got %d bytes of quality %d\n",
320                    SYSTEMRNG_BYTES, quality);
321       (*add) (buffer, SYSTEMRNG_BYTES, requester);
322       wipememory (buffer, SYSTEMRNG_BYTES);
323     }
324 }
325
326
327 /* Read data from MBM.  This communicates via shared memory, so all we
328    need to do is map a file and read the data out.  */
329 static void
330 read_mbm_data (void (*add)(const void*, size_t, enum random_origins), 
331                enum random_origins requester)
332 {
333   HANDLE hMBMData;
334   SharedData *mbmDataPtr;
335
336   hMBMData = OpenFileMapping (FILE_MAP_READ, FALSE, "$M$B$M$5$S$D$" );
337   if (hMBMData)
338     {
339       mbmDataPtr = (SharedData*)MapViewOfFile (hMBMData, FILE_MAP_READ,0,0,0);
340       if (mbmDataPtr)
341         {
342           if (debug_me)
343             log_debug ("rndw32#read_mbm_data: got %d bytes\n",
344                        (int)sizeof (SharedData));
345           (*add) (mbmDataPtr, sizeof (SharedData), requester);
346           UnmapViewOfFile (mbmDataPtr);
347         }
348       CloseHandle (hMBMData);
349     }
350 }
351
352
353 /* Fallback method using the registry to poll the statistics.  */
354 static void
355 registry_poll (void (*add)(const void*, size_t, enum random_origins), 
356                enum random_origins requester)
357 {
358   static int cbPerfData = PERFORMANCE_BUFFER_SIZE;
359   int iterations;
360   DWORD dwSize, status;
361   PERF_DATA_BLOCK *pPerfData;
362
363   /* Get information from the system performance counters.  This can take a
364      few seconds to do.  In some environments the call to RegQueryValueEx()
365      can produce an access violation at some random time in the future, in
366      some cases adding a short delay after the following code block makes
367      the problem go away.  This problem is extremely difficult to
368      reproduce, I haven't been able to get it to occur despite running it
369      on a number of machines.  MS knowledge base article Q178887 covers
370      this type of problem, it's typically caused by an external driver or
371      other program that adds its own values under the
372      HKEY_PERFORMANCE_DATA key.  The NT kernel, via Advapi32.dll, calls the
373      required external module to map in the data inside an SEH try/except
374      block, so problems in the module's collect function don't pop up until
375      after it has finished, so the fault appears to occur in Advapi32.dll.
376      There may be problems in the NT kernel as well though, a low-level
377      memory checker indicated that ExpandEnvironmentStrings() in
378      Kernel32.dll, called an interminable number of calls down inside
379      RegQueryValueEx(), was overwriting memory (it wrote twice the
380      allocated size of a buffer to a buffer allocated by the NT kernel).
381      OTOH this could be coming from the external module calling back into
382      the kernel, which eventually causes the problem described above.
383
384      Possibly as an extension of the problem that the krnlWaitSemaphore()
385      call above works around, running two instances of cryptlib (e.g. two
386      applications that use it) under NT4 can result in one of them hanging
387      in the RegQueryValueEx() call.  This happens only under NT4 and is
388      hard to reproduce in any consistent manner.
389
390      One workaround that helps a bit is to read the registry as a remote
391      (rather than local) registry, it's possible that the use of a network
392      RPC call isolates the calling app from the problem in that whatever
393      service handles the RPC is taking the hit and not affecting the
394      calling app.  Since this would require another round of extensive
395      testing to verify and the NT native API call is working fine, we'll
396      stick with the native API call for now.
397
398      Some versions of NT4 had a problem where the amount of data returned
399      was mis-reported and would never settle down, because of this the code
400      below includes a safety-catch that bails out after 10 attempts have
401      been made, this results in no data being returned but at does ensure
402      that the thread will terminate.
403
404      In addition to these problems the code in RegQueryValueEx() that
405      estimates the amount of memory required to return the performance
406      counter information isn't very accurate (it's much worse than the
407      "slightly-inaccurate" level that the MS docs warn about, it's usually
408      wildly off) since it always returns a worst-case estimate which is
409      usually nowhere near the actual amount required.  For example it may
410      report that 128K of memory is required, but only return 64K of data.
411
412      Even worse than the registry-based performance counters is the
413      performance data helper (PDH) shim that tries to make the counters
414      look like the old Win16 API (which is also used by Win95).  Under NT
415      this can consume tens of MB of memory and huge amounts of CPU time
416      while it gathers its data, and even running once can still consume
417      about 1/2MB of memory */
418   pPerfData = gcry_xmalloc (cbPerfData);
419   for (iterations=0; iterations < 10; iterations++)
420     {
421       dwSize = cbPerfData;
422       if ( debug_me )
423         log_debug ("rndw32#slow_gatherer_nt: get perf data\n" );
424
425       status = RegQueryValueEx (HKEY_PERFORMANCE_DATA, "Global", NULL,
426                                 NULL, (LPBYTE) pPerfData, &dwSize);
427       if (status == ERROR_SUCCESS)
428         {
429           if (!memcmp (pPerfData->Signature, L"PERF", 8))
430             (*add) ( pPerfData, dwSize, requester );
431           else
432             log_debug ("rndw32: no PERF signature\n");
433           break;
434         }
435       else if (status == ERROR_MORE_DATA)
436         {
437           cbPerfData += PERFORMANCE_BUFFER_STEP;
438           pPerfData = gcry_xrealloc (pPerfData, cbPerfData);
439         }
440       else
441         {
442           static int been_here;
443
444           /* Silence the error message.  In particular under Wine (as
445              of 2008) we would get swamped with such diagnotiscs.  One
446              such diagnotiscs should be enough.  */
447           if (been_here != status)
448             {
449               been_here = status;
450               log_debug ("rndw32: get performance data problem: ec=%ld\n",
451                          status);
452             }
453           break;
454         }
455     }
456   gcry_free (pPerfData);
457
458   /* Although this isn't documented in the Win32 API docs, it's necessary
459      to explicitly close the HKEY_PERFORMANCE_DATA key after use (it's
460      implicitly opened on the first call to RegQueryValueEx()).  If this
461      isn't done then any system components which provide performance data
462      can't be removed or changed while the handle remains active.  */
463   RegCloseKey (HKEY_PERFORMANCE_DATA);
464 }
465
466
467 static void
468 slow_gatherer ( void (*add)(const void*, size_t, enum random_origins), 
469                 enum random_origins requester )
470 {
471   static int is_initialized = 0;
472   static int is_workstation = 1;
473   HANDLE hDevice;
474   DWORD dwType, dwSize, dwResult;
475   ULONG ulSize;
476   int drive_no, status;
477   int no_results = 0;
478   void *buffer;
479
480   if ( !is_initialized )
481     {
482       HKEY hKey;
483
484       if ( debug_me )
485         log_debug ("rndw32#slow_gatherer: init toolkit\n" );
486       /* Find out whether this is an NT server or workstation if necessary */
487       if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
488                         "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
489                         0, KEY_READ, &hKey) == ERROR_SUCCESS)
490         {
491           BYTE szValue[32 + 8];
492           dwSize = 32;
493
494           if ( debug_me )
495             log_debug ("rndw32#slow_gatherer: check product options\n" );
496
497           status = RegQueryValueEx (hKey, "ProductType", 0, NULL,
498                                     szValue, &dwSize);
499           if (status == ERROR_SUCCESS && stricmp (szValue, "WinNT"))
500             {
501               /* Note: There are (at least) three cases for ProductType:
502                  WinNT = NT Workstation, ServerNT = NT Server, LanmanNT =
503                  NT Server acting as a Domain Controller.  */
504               is_workstation = 0;
505               if ( debug_me )
506                 log_debug ("rndw32: this is a NT server\n");
507             }
508           RegCloseKey (hKey);
509         }
510
511       /* The following are fixed for the lifetime of the process so we
512          only add them once */
513       /* readPnPData ();  - we have not implemented that.  */
514
515       /* Initialize the NetAPI32 function pointers if necessary */
516       hNetAPI32 = LoadLibrary ("NETAPI32.DLL");
517       if (hNetAPI32)
518         {
519           if (debug_me)
520             log_debug ("rndw32#slow_gatherer: netapi32 loaded\n" );
521           pNetStatisticsGet = (NETSTATISTICSGET)
522             GetProcAddress (hNetAPI32, "NetStatisticsGet");
523           pNetApiBufferSize = (NETAPIBUFFERSIZE)
524             GetProcAddress (hNetAPI32, "NetApiBufferSize");
525           pNetApiBufferFree = (NETAPIBUFFERFREE)
526             GetProcAddress (hNetAPI32, "NetApiBufferFree");
527
528           if (!pNetStatisticsGet || !pNetApiBufferSize || !pNetApiBufferFree)
529             {
530               FreeLibrary (hNetAPI32);
531               hNetAPI32 = NULL;
532               log_debug ("rndw32: No NETAPI found\n" );
533             }
534         }
535
536       /* Initialize the NT kernel native API function pointers if necessary */
537       hNTAPI = GetModuleHandle ("NTDll.dll");
538       if (hNTAPI)
539         {
540           /* Get a pointer to the NT native information query functions */
541           pNtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)
542             GetProcAddress (hNTAPI, "NtQuerySystemInformation");
543           pNtQueryInformationProcess = (NTQUERYINFORMATIONPROCESS)
544             GetProcAddress (hNTAPI, "NtQueryInformationProcess");
545           pNtPowerInformation = (NTPOWERINFORMATION)
546             GetProcAddress(hNTAPI, "NtPowerInformation");
547
548           if (!pNtQuerySystemInformation || !pNtQueryInformationProcess)
549             hNTAPI = NULL;
550         }
551
552
553       is_initialized = 1;
554     }
555   
556   read_system_rng ( add, requester );
557   read_mbm_data ( add, requester );
558   
559   /* Get network statistics.    Note: Both NT Workstation and NT Server by
560      default will be running both the workstation and server services.  The
561      heuristic below is probably useful though on the assumption that the
562      majority of the network traffic will be via the appropriate service.
563      In any case the network statistics return almost no randomness.  */
564   {
565     LPBYTE lpBuffer;
566     
567     if (hNetAPI32
568         && !pNetStatisticsGet (NULL,
569                                is_workstation ? L"LanmanWorkstation" :
570                                L"LanmanServer", 0, 0, &lpBuffer))
571       {
572         if ( debug_me )
573           log_debug ("rndw32#slow_gatherer: get netstats\n" );
574         pNetApiBufferSize (lpBuffer, &dwSize);
575         (*add) ( lpBuffer, dwSize, requester );
576         pNetApiBufferFree (lpBuffer);
577       }
578   }
579
580   /* Get disk I/O statistics for all the hard drives.  100 is an
581      arbitrary failsafe limit.  */
582   for (drive_no = 0; drive_no < 100 ; drive_no++)
583     {
584       char diskPerformance[SIZEOF_DISK_PERFORMANCE_STRUCT + 8];
585       char szDevice[50];
586       
587       /* Check whether we can access this device.  */
588       snprintf (szDevice, sizeof szDevice, "\\\\.\\PhysicalDrive%d",
589                 drive_no);
590       hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
591                             NULL, OPEN_EXISTING, 0, NULL);
592       if (hDevice == INVALID_HANDLE_VALUE)
593         break; /* No more drives.  */
594         
595       /* Note: This only works if you have turned on the disk performance
596          counters with 'diskperf -y'.  These counters are off by default. */
597       dwSize = sizeof diskPerformance;
598       if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
599                            diskPerformance, SIZEOF_DISK_PERFORMANCE_STRUCT,
600                            &dwSize, NULL))
601         {
602           if ( debug_me )
603             log_debug ("rndw32#slow_gatherer: iostat drive %d\n",
604                        drive_no);
605           (*add) (diskPerformance, dwSize, requester);
606         }
607       else
608         {
609           log_info ("NOTE: you should run 'diskperf -y' "
610                     "to enable the disk statistics\n");
611         }
612       CloseHandle (hDevice);
613     }
614
615   /* In theory we should be using the Win32 performance query API to obtain
616      unpredictable data from the system, however this is so unreliable (see
617      the multiple sets of comments in registryPoll()) that it's too risky
618      to rely on it except as a fallback in emergencies.  Instead, we rely
619      mostly on the NT native API function NtQuerySystemInformation(), which
620      has the dual advantages that it doesn't have as many (known) problems
621      as the Win32 equivalent and that it doesn't access the data indirectly
622      via pseudo-registry keys, which means that it's much faster.  Note
623      that the Win32 equivalent actually works almost all of the time, the
624      problem is that on one or two systems it can fail in strange ways that
625      are never the same and can't be reproduced on any other system, which
626      is why we use the native API here.  Microsoft officially documented
627      this function in early 2003, so it'll be fairly safe to use.  */
628   if ( !hNTAPI )
629     {
630       registry_poll (add, requester);
631       return;
632     }
633
634
635   /* Scan the first 64 possible information types (we don't bother with
636      increasing the buffer size as we do with the Win32 version of the
637      performance data read, we may miss a few classes but it's no big deal).
638      This scan typically yields around 20 pieces of data, there's nothing
639      in the range 65...128 so chances are there won't be anything above
640      there either.  */
641   buffer = gcry_xmalloc (PERFORMANCE_BUFFER_SIZE);
642   for (dwType = 0; dwType < 64; dwType++)
643     {
644       switch (dwType)
645         {
646           /* Some information types are write-only (the IDs are shared with
647              a set-information call), we skip these.  */
648         case 26: case 27: case 38: case 46: case 47: case 48: case 52:
649           continue;
650
651           /* ID 53 = SystemSessionProcessInformation reads input from the
652              output buffer, which has to contain a session ID and pointer
653              to the actual buffer in which to store the session information.
654              Because this isn't a standard query, we skip this.  */
655         case  53:
656           continue;
657         }
658
659       /* Query the info for this ID.  Some results (for example for
660          ID = 6, SystemCallCounts) are only available in checked builds
661          of the kernel.  A smaller subcless of results require that
662          certain system config flags be set, for example
663          SystemObjectInformation requires that the
664          FLG_MAINTAIN_OBJECT_TYPELIST be set in NtGlobalFlags.  To avoid
665          having to special-case all of these, we try reading each one and
666          only use those for which we get a success status.  */
667       dwResult = pNtQuerySystemInformation (dwType, buffer,
668                                             PERFORMANCE_BUFFER_SIZE - 2048,
669                                             &ulSize);
670       if (dwResult != ERROR_SUCCESS)
671         continue;
672
673       /* Some calls (e.g. ID = 23, SystemProcessorStatistics, and ID = 24,
674          SystemDpcInformation) incorrectly return a length of zero, so we
675          manually adjust the length to the correct value.  */
676       if ( !ulSize )
677         {
678           if (dwType == 23)
679             ulSize = 6 * sizeof (ULONG);
680           else if (dwType == 24)
681             ulSize = 5 * sizeof (ULONG);
682         }
683
684       /* If we got some data back, add it to the entropy pool.  */
685       if (ulSize > 0 && ulSize <= PERFORMANCE_BUFFER_SIZE - 2048)
686         {
687           if (debug_me)
688             log_debug ("rndw32#slow_gatherer: %lu bytes from sysinfo %ld\n",
689                        ulSize, dwType);
690           (*add) (buffer, ulSize, requester);
691           no_results++;
692         }
693     }
694
695   /* Now we would do the same for the process information.  This
696      call would rather ugly in that it requires an exact length
697      match for the data returned, failing with a
698      STATUS_INFO_LENGTH_MISMATCH error code (0xC0000004) if the
699      length isn't an exact match.  It requires a compiler to handle
700      complex nested structs, alignment issues, and so on, and
701      without the headers in which the entries are declared it's
702      almost impossible to do.  Thus we don't.  */
703
704
705   /* Finally, do the same for the system power status information.  There
706      are only a limited number of useful information types available so we
707      restrict ourselves to the useful types.  In addition since this
708      function doesn't return length information, we have to hardcode in
709      length data.  */
710   if (pNtPowerInformation)
711     {
712       static const struct { int type; int size; } powerInfo[] = {
713         { 0, 128 },     /* SystemPowerPolicyAc */
714         { 1, 128 },     /* SystemPowerPolicyDc */
715         { 4, 64 },      /* SystemPowerCapabilities */
716         { 5, 48 },      /* SystemBatteryState */
717         { 11, 48 },     /* ProcessorInformation */
718         { 12, 24 },     /* SystemPowerInformation */
719         { -1, -1 }
720       };
721       int i;
722
723       /* The 100 is a failsafe limit.  */
724       for (i = 0; powerInfo[i].type != -1 && i < 100; i++ )
725         {
726           /* Query the info for this ID */
727           dwResult = pNtPowerInformation (powerInfo[i].type, NULL, 0, buffer,
728                                           PERFORMANCE_BUFFER_SIZE - 2048);
729           if (dwResult != ERROR_SUCCESS)
730             continue;
731           if (debug_me)
732             log_debug ("rndw32#slow_gatherer: %u bytes from powerinfo %d\n",
733                        powerInfo[i].size, i);
734           (*add) (buffer, powerInfo[i].size, requester);
735           no_results++;
736         }
737       gcry_assert (i < 100);
738     }
739   gcry_free (buffer);
740
741   /* We couldn't get enough results from the kernel, fall back to the
742      somewhat troublesome registry poll.  */
743   if (no_results < 15)
744     registry_poll (add, requester);
745 }
746
747
748 int
749 _gcry_rndw32_gather_random (void (*add)(const void*, size_t,
750                                         enum random_origins),
751                             enum random_origins origin,
752                             size_t length, int level )
753 {
754   static int is_initialized;
755
756   if (!level)
757     return 0;
758
759   /* We don't differentiate between level 1 and 2 here because there
760      is no internal entropy pool as a scary resource.  It may all work
761      slower, but because our entropy source will never block but
762      deliver some not easy to measure entropy, we assume level 2.  */
763
764   if (!is_initialized)
765     {
766       OSVERSIONINFO osvi = { sizeof( osvi ) };
767
768       GetVersionEx( &osvi );
769       if ( osvi.dwPlatformId != VER_PLATFORM_WIN32_NT)
770         log_fatal ("can only run on a Windows NT platform\n" );
771       init_system_rng ();
772       is_initialized = 1;
773     }
774
775   if (debug_me)
776     log_debug ("rndw32#gather_random: ori=%d len=%u lvl=%d\n",
777                origin, (unsigned int)length, level );
778
779   slow_gatherer (add, origin);
780
781   return 0;
782 }
783
784
785
786 void
787 _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
788                                              enum random_origins),
789                                  enum random_origins origin)
790 {
791   static int addedFixedItems = 0;
792
793   if ( debug_me )
794     log_debug ("rndw32#gather_random_fast: ori=%d\n", origin );
795
796   /* Get various basic pieces of system information: Handle of active
797      window, handle of window with mouse capture, handle of clipboard
798      owner handle of start of clpboard viewer list, pseudohandle of
799      current process, current process ID, pseudohandle of current
800      thread, current thread ID, handle of desktop window, handle of
801      window with keyboard focus, whether system queue has any events,
802      cursor position for last message, 1 ms time for last message,
803      handle of window with clipboard open, handle of process heap,
804      handle of procs window station, types of events in input queue,
805      and milliseconds since Windows was started.  */
806
807   {
808     byte buffer[20*sizeof(ulong)], *bufptr;
809
810     bufptr = buffer;
811 #define ADD(f)  do { ulong along = (ulong)(f);                  \
812                      memcpy (bufptr, &along, sizeof (along) );  \
813                      bufptr += sizeof (along);                  \
814                    } while (0)
815
816     ADD ( GetActiveWindow ());
817     ADD ( GetCapture ());
818     ADD ( GetClipboardOwner ());
819     ADD ( GetClipboardViewer ());
820     ADD ( GetCurrentProcess ());
821     ADD ( GetCurrentProcessId ());
822     ADD ( GetCurrentThread ());
823     ADD ( GetCurrentThreadId ());
824     ADD ( GetDesktopWindow ());
825     ADD ( GetFocus ());
826     ADD ( GetInputState ());
827     ADD ( GetMessagePos ());
828     ADD ( GetMessageTime ());
829     ADD ( GetOpenClipboardWindow ());
830     ADD ( GetProcessHeap ());
831     ADD ( GetProcessWindowStation ());
832     ADD ( GetQueueStatus (QS_ALLEVENTS));
833     ADD ( GetTickCount ());
834
835     gcry_assert ( bufptr-buffer < sizeof (buffer) );
836     (*add) ( buffer, bufptr-buffer, origin );
837 #undef ADD
838   }
839
840   /* Get multiword system information: Current caret position, current
841      mouse cursor position.  */
842   {
843     POINT point;
844
845     GetCaretPos (&point);
846     (*add) ( &point, sizeof (point), origin );
847     GetCursorPos (&point);
848     (*add) ( &point, sizeof (point), origin );
849   }
850
851   /* Get percent of memory in use, bytes of physical memory, bytes of
852      free physical memory, bytes in paging file, free bytes in paging
853      file, user bytes of address space, and free user bytes.  */
854   {
855     MEMORYSTATUS memoryStatus;
856
857     memoryStatus.dwLength = sizeof (MEMORYSTATUS);
858     GlobalMemoryStatus (&memoryStatus);
859     (*add) ( &memoryStatus, sizeof (memoryStatus), origin );
860   }
861
862   /* Get thread and process creation time, exit time, time in kernel
863      mode, and time in user mode in 100ns intervals.  */
864   {
865     HANDLE handle;
866     FILETIME creationTime, exitTime, kernelTime, userTime;
867     DWORD minimumWorkingSetSize, maximumWorkingSetSize;
868
869     handle = GetCurrentThread ();
870     GetThreadTimes (handle, &creationTime, &exitTime,
871                     &kernelTime, &userTime);
872     (*add) ( &creationTime, sizeof (creationTime), origin );
873     (*add) ( &exitTime, sizeof (exitTime), origin );
874     (*add) ( &kernelTime, sizeof (kernelTime), origin );
875     (*add) ( &userTime, sizeof (userTime), origin );
876
877     handle = GetCurrentProcess ();
878     GetProcessTimes (handle, &creationTime, &exitTime,
879                      &kernelTime, &userTime);
880     (*add) ( &creationTime, sizeof (creationTime), origin );
881     (*add) ( &exitTime, sizeof (exitTime), origin );
882     (*add) ( &kernelTime, sizeof (kernelTime), origin );
883     (*add) ( &userTime, sizeof (userTime), origin );
884
885     /* Get the minimum and maximum working set size for the current
886        process.  */
887     GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
888                               &maximumWorkingSetSize);
889     (*add) ( &minimumWorkingSetSize,
890              sizeof (minimumWorkingSetSize), origin );
891     (*add) ( &maximumWorkingSetSize,
892              sizeof (maximumWorkingSetSize), origin );
893   }
894
895
896   /* The following are fixed for the lifetime of the process so we only
897    * add them once */
898   if (!addedFixedItems)
899     {
900       STARTUPINFO startupInfo;
901
902       /* Get name of desktop, console window title, new window
903          position and size, window flags, and handles for stdin,
904          stdout, and stderr.  */
905       startupInfo.cb = sizeof (STARTUPINFO);
906       GetStartupInfo (&startupInfo);
907       (*add) ( &startupInfo, sizeof (STARTUPINFO), origin );
908       addedFixedItems = 1;
909     }
910
911   /* The performance of QPC varies depending on the architecture it's
912      running on and on the OS, the MS documentation is vague about the
913      details because it varies so much.  Under Win9x/ME it reads the
914      1.193180 MHz PIC timer.  Under NT/Win2K/XP it may or may not read the
915      64-bit TSC depending on the HAL and assorted other circumstances,
916      generally on machines with a uniprocessor HAL
917      KeQueryPerformanceCounter() uses a 3.579545MHz timer and on machines
918      with a multiprocessor or APIC HAL it uses the TSC (the exact time
919      source is controlled by the HalpUse8254 flag in the kernel).  That
920      choice of time sources is somewhat peculiar because on a
921      multiprocessor machine it's theoretically possible to get completely
922      different TSC readings depending on which CPU you're currently
923      running on, while for uniprocessor machines it's not a problem.
924      However, the kernel appears to synchronise the TSCs across CPUs at
925      boot time (it resets the TSC as part of its system init), so this
926      shouldn't really be a problem.  Under WinCE it's completely platform-
927      dependant, if there's no hardware performance counter available, it
928      uses the 1ms system timer.
929      
930      Another feature of the TSC (although it doesn't really affect us here)
931      is that mobile CPUs will turn off the TSC when they idle, Pentiums
932      will change the rate of the counter when they clock-throttle (to
933      match the current CPU speed), and hyperthreading Pentiums will turn
934      it off when both threads are idle (this more or less makes sense,
935      since the CPU will be in the halted state and not executing any
936      instructions to count).
937      
938      To make things unambiguous, we detect a CPU new enough to call RDTSC
939      directly by checking for CPUID capabilities, and fall back to QPC if
940      this isn't present.  */
941 #ifdef __GNUC__  
942 /*   FIXME: We need to implement the CPU feature tests first.  */
943 /*   if (cpu_has_feature_rdtsc) */
944 /*     { */
945 /*       uint32_t lo, hi; */
946       /* We cannot use "=A", since this would use %rax on x86_64. */
947 /*       __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); */
948       /* Ignore high 32 bits, hwich are >1s res.  */
949 /*       (*add) (&lo, 4, origin ); */
950 /*     } */
951 /*   else */
952 #endif /*!__GNUC__*/
953     {
954       LARGE_INTEGER performanceCount;
955       
956       if (QueryPerformanceCounter (&performanceCount))
957         {
958           if ( debug_me )
959           log_debug ("rndw32#gather_random_fast: perf data\n");
960           (*add) (&performanceCount, sizeof (performanceCount), origin);
961         }
962       else
963         {
964           /* Millisecond accuracy at best... */
965           DWORD aword = GetTickCount ();
966           (*add) (&aword, sizeof (aword), origin );
967         }
968     }
969
970
971 }