~ubuntu-branches/ubuntu/raring/libgcrypt11/raring

« back to all changes in this revision

Viewing changes to random/rndw32.c

  • Committer: Bazaar Package Importer
  • Author(s): Bhavani Shankar
  • Date: 2009-05-16 20:13:32 UTC
  • mfrom: (1.1.6 upstream) (2.1.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090516201332-czkobpu32w318i16
Tags: 1.4.4-2ubuntu1
* Merge from Debian unstable (LP: #364535), remaining changes:
  - Add libgcrypt11-udeb for use by cryptsetup-udeb.
  - Add clean-la.mk, and add a symlink for the .la
  - Install to /lib.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
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 would 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
}