cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
win16.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * Win16 Randomness-Gathering Code *
4 * Copyright Peter Gutmann 1996-2006 *
5 * *
6 ****************************************************************************/
7 
8 /* This module is part of the cryptlib continuously seeded pseudorandom
9  number generator. For usage conditions, see random.c */
10 
11 /* General includes */
12 
13 #include "crypt.h"
14 
15 /* OS-specific includes */
16 
17 #include <stress.h>
18 #include <toolhelp.h>
19 
20 /* The size of the intermediate buffer used to accumulate polled data */
21 
22 #define RANDOM_BUFSIZE 1024
23 
24 void fastPoll( void )
25  {
26  RANDOM_STATE randomState;
28  SYSHEAPINFO sysHeapInfo;
29  MEMMANINFO memManInfo;
30  TIMERINFO timerInfo;
31  POINT point;
32 
33  initRandomData( randomState, buffer, RANDOM_BUFSIZE );
34 
35  /* Get various basic pieces of system information: Handle of the window
36  with mouse capture, handle of window with input focus, amount of
37  space in global heap, whether system queue has any events, cursor
38  position for last message, 55 ms time for last message, number of
39  active tasks, 55 ms time since Windows started, current mouse cursor
40  position, current caret position */
41  addRandomValue( randomState, GetCapture() );
42  addRandomValue( randomState, GetFocus() );
43  addRandomValue( randomState, GetFreeSpace( 0 ) );
44  addRandomValue( randomState, GetInputState() );
45  addRandomValue( randomState, GetMessagePos() );
46  addRandomValue( randomState, GetMessageTime() );
47  addRandomValue( randomState, GetNumTasks() );
48  addRandomValue( randomState, GetTickCount() );
49  GetCursorPos( &point );
50  addRandomData( randomState, &point, sizeof( POINT ) );
51  GetCaretPos( &point );
52  addRandomData( randomState, &point, sizeof( POINT ) );
53 
54  /* Get the largest free memory block, number of lockable pages, number of
55  unlocked pages, number of free and used pages, and number of swapped
56  pages */
57  memManInfo.dwSize = sizeof( MEMMANINFO );
58  MemManInfo( &memManInfo );
59  addRandomData( randomState, &memManInfo, sizeof( MEMMANINFO ) );
60 
61  /* Get the execution times of the current task and VM to approximately
62  1ms resolution */
63  timerInfo.dwSize = sizeof( TIMERINFO );
64  TimerCount( &timerInfo );
65  addRandomData( randomState, &timerInfo, sizeof( TIMERINFO ) );
66 
67  /* Get the percentage free and segment of the user and GDI heap */
68  sysHeapInfo.dwSize = sizeof( SYSHEAPINFO );
69  SystemHeapInfo( &sysHeapInfo );
70  addRandomData( randomState, &sysHeapInfo, sizeof( SYSHEAPINFO ) );
71 
72  /* Flush any remaining data through */
73  endRandomData( randomState, 25 );
74  }
75 
76 /* The slow poll can get *very* slow because of the overhead involved in
77  obtaining the necessary information. On a moderately loaded system there
78  are often 500+ objects on the global heap and 50+ modules, so we limit
79  the number checked to a reasonable level to make sure we don't spend
80  forever polling. We give the global heap walk the most leeway since this
81  provides the best source of randomness */
82 
83 void slowPoll( void )
84  {
85  RANDOM_STATE randomState;
87  MODULEENTRY moduleEntry;
88  GLOBALENTRY globalEntry;
89  TASKENTRY taskEntry;
90  int count;
91 
92  initRandomData( randomState, buffer, RANDOM_BUFSIZE );
93 
94  /* Walk the global heap getting information on each entry in it. This
95  retrieves the objects linear address, size, handle, lock count, owner,
96  object type, and segment type */
97  count = 0;
98  globalEntry.dwSize = sizeof( GLOBALENTRY );
99  if( GlobalFirst( &globalEntry, GLOBAL_ALL ) )
100  do
101  {
102  addRandomData( randomState, &globalEntry, sizeof( GLOBALENTRY ) );
103  count++;
104  }
105  while( count < 70 && GlobalNext( &globalEntry, GLOBAL_ALL ) );
106 
107  /* Walk the module list getting information on each entry in it. This
108  retrieves the module name, handle, reference count, executable path,
109  and next module */
110  count = 0;
111  moduleEntry.dwSize = sizeof( MODULEENTRY );
112  if( ModuleFirst( &moduleEntry ) )
113  do
114  {
115  addRandomData( randomState, &moduleEntry, sizeof( MODULEENTRY ) );
116  count++;
117  }
118  while( count < 20 && ModuleNext( &moduleEntry ) );
119 
120  /* Walk the task list getting information on each entry in it. This
121  retrieves the task handle, parent task handle, instance handle, stack
122  segment and offset, stack size, number of pending events, task queue,
123  and the name of module executing the task. We also call TaskGetCSIP()
124  for the code segment and offset of each task if it's safe to do so
125  (note that this call can cause odd things to happen in debuggers and
126  runtime code checkers because of the way TaskGetCSIP() is implemented) */
127  count = 0;
128  taskEntry.dwSize = sizeof( TASKENTRY );
129  if( TaskFirst( &taskEntry ) )
130  do
131  {
132  addRandomData( randomState, &taskEntry, sizeof( TASKENTRY ) );
133  if( taskEntry.hTask != GetCurrentTask() )
134  addRandomValue( randomState,
135  TaskGetCSIP( taskEntry.hTask ) );
136  count++;
137  }
138  while( count < 100 && TaskNext( &taskEntry ) );
139 
140  /* Flush any remaining data through */
141  endRandomData( randomState, 100 );
142  }