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.  */
122typedef DWORD (WINAPI *NETSTATISTICSGET)(LPWSTR szServer, LPWSTR szService,
123                                         DWORD dwLevel, DWORD dwOptions,
124                                         LPBYTE *lpBuffer);
125typedef DWORD (WINAPI *NETAPIBUFFERSIZE)(LPVOID lpBuffer, LPDWORD cbBuffer);
126typedef DWORD (WINAPI *NETAPIBUFFERFREE)(LPVOID lpBuffer);
127
128/* Type definitions for function pointers to call native NT functions.  */
129typedef DWORD (WINAPI *NTQUERYSYSTEMINFORMATION)(DWORD systemInformationClass,
130                                                 PVOID systemInformation,
131                                                 ULONG systemInformationLength,
132                                                 PULONG returnLength);
133typedef DWORD (WINAPI *NTQUERYINFORMATIONPROCESS)
134     (HANDLE processHandle, DWORD processInformationClass,
135      PVOID processInformation, ULONG processInformationLength,
136      PULONG returnLength);
137typedef 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. */
142typedef BOOL (WINAPI *CRYPTACQUIRECONTEXT)(HCRYPTPROV *phProv,
143                                           LPCTSTR pszContainer,
144                                           LPCTSTR pszProvider,
145                                           DWORD dwProvType,
146                                           DWORD dwFlags);
147typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,
148                                      BYTE *pbBuffer);
149typedef 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.  */
159typedef 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
170typedef struct
171{
172  SensorType iType;               /* Type of sensor.  */
173  int Count;                      /* Number of sensor for that type.  */
174} SharedIndex;
175
176typedef 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
192typedef 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
204typedef 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.  */
226static HANDLE hNetAPI32;
227static NETSTATISTICSGET pNetStatisticsGet;
228static NETAPIBUFFERSIZE pNetApiBufferSize;
229static NETAPIBUFFERFREE pNetApiBufferFree;
230
231static HANDLE hNTAPI;
232static NTQUERYSYSTEMINFORMATION  pNtQuerySystemInformation;
233static NTQUERYINFORMATIONPROCESS pNtQueryInformationProcess;
234static NTPOWERINFORMATION        pNtPowerInformation;
235
236static HANDLE hAdvAPI32;
237static CRYPTACQUIRECONTEXT pCryptAcquireContext;
238static CRYPTGENRANDOM      pCryptGenRandom;
239static CRYPTRELEASECONTEXT pCryptReleaseContext;
240static RTLGENRANDOM        pRtlGenRandom;
241
242
243/* Other module global variables.  */
244static int system_rng_available; /* Whether a system RNG is available.  */
245static HCRYPTPROV hRNGProv;      /* Handle to Intel RNG CSP. */
246
247static int debug_me;  /* Debug flag.  */
248
249static int system_is_w2000;     /* True if running on W2000.  */
250
251
252
253
254/* Try and connect to the system RNG if there's one present. */
255static void
256init_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.  */
296static void
297read_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.  */
332static void
333read_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.  */
357static void
358registry_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
483static void
484slow_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
770int
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
809void
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}
995