cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
mac.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * Macintosh Randomness-Gathering Code *
4 * Copyright Peter Gutmann and Matthijs van Duin 1997-2002 *
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 /* Mac threads are cooperatively scheduled (so they're what Win32 calls
12  fibers rather than true threads) and there isn't any real equivalent of a
13  mutex (only critical sections which prevent any other thread from being
14  scheduled, which defeats the point of multithreading), so we don't support
15  this pseudo-threading for randomness polling. If proper threading were
16  available, we'd use NewThread()/DisposeThread() to create/destroy the
17  background randomness-polling thread */
18 
19 /* General includes */
20 
21 #include "crypt.h"
22 #include "random/random.h"
23 
24 /* OS-specific includes */
25 /* Filled in by Matthijs van Duin */
26 
27 #include <Power.h>
28 #include <Sound.h>
29 #include <Threads.h>
30 #include <Events.h>
31 #include <Scrap.h>
32 #include <MacTypes.h>
33 #include <Serial.h>
34 #include <Processes.h>
35 #include <Devices.h>
36 #include <Disks.h>
37 #include <OSUtils.h>
38 #include <Start.h>
39 #include <AppleTalk.h>
40 #include <DeskBus.h>
41 #include <Retrace.h>
42 #include <SCSI.h>
43 #include <SpeechSynthesis.h>
44 #include <Resources.h>
45 #include <Script.h>
46 
47 #if defined __MWERKS__
48  #pragma mpwc_relax off
49  #pragma extended_errorcheck on
50 #endif
51 
52 /* The size of the intermediate buffer used to accumulate polled data */
53 
54 #define RANDOM_BUFSIZE 4096
55 
56 void fastPoll( void )
57  {
58  RANDOM_STATE randomState;
59  BYTE buffer[ RANDOM_BUFSIZE + 8 ];
60 /* BatteryTimeRec batteryTimeInfo; */
61  SMStatus soundStatus;
62  ThreadID threadID;
63  ThreadState threadState;
64  EventRecord eventRecord;
65  Point point;
66  WindowPtr windowPtr;
67  PScrapStuff scrapInfo;
68  UnsignedWide usSinceStartup;
69  BYTE dataBuffer[ 2 + 8 ];
70 /* short driverRefNum; */
71  UInt32 dateTime;
72 /* int count, dummy; */
73  NumVersion version;
74 
75  initRandomData( randomState, buffer, RANDOM_BUFSIZE );
76 
77  /* Get the status of the last alert, how much battery time is remaining
78  and the voltage from all batteries, the internal battery status, the
79  current date and time and time since system startup in ticks, the
80  application heap limit and current and heap zone, free memory in the
81  current and system heap, microseconds since system startup, whether
82  QuickDraw has finished drawing, modem status, SCSI status
83  information, maximum block allocatable without compacting, available
84  stack space, the last QuickDraw error code */
85 /* addRandomValue( randomState, GetAlertStage() );
86  count = BatteryCount();
87  while( count-- > 0 )
88  {
89  addRandomValue( randomState,
90  GetBatteryVoltage( count ) );
91  GetBatteryTimes( count, &batteryTimeInfo );
92  addRandomData( randomState, &batteryTimeInfo,
93  sizeof( BatteryTimeRec ) );
94  }
95  if( !BatteryStatus( buffer, dataBuffer + 1 ) )
96  addRandomValue( randomState, dataBuffer );
97 */ GetDateTime( &dateTime );
98  addRandomValue( randomState, dateTime );
99  addRandomValue( randomState, TickCount() );
100 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
101  addRandomValue( randomState, GetApplLimit() );
102  addRandomValue( randomState, GetZone() );
103  addRandomValue( randomState, SystemZone() );
104  addRandomValue( randomState, FreeMem() );
105  addRandomValue( randomState, FreeMemSys() );
106 #endif
107 /* MicroSeconds( &usSinceStartup );
108  addRandomData( randomState, &usSinceStartup, sizeof( UnsignedWide ) ); */
109  addRandomValue( randomState, QDDone( NULL ) );
110 /* ModemStatus( dataBuffer );
111  addRandomValue( randomState, dataBuffer[ 0 ] ); */
112 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
113  addRandomValue( randomState, SCSIStat() );
114 #endif
115  addRandomValue( randomState, MaxBlock() );
116  addRandomValue( randomState, StackSpace() );
117  addRandomValue( randomState, QDError() );
118 
119  /* Get the event code and message, time, and mouse location for the next
120  event in the event queue and the OS event queue */
121  if( EventAvail( everyEvent, &eventRecord ) )
122  addRandomData( randomState, &eventRecord, sizeof( EventRecord ) );
123 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
124  if( OSEventAvail( everyEvent, &eventRecord ) )
125  addRandomData( randomState, &eventRecord, sizeof( EventRecord ) );
126 #endif
127 
128  /* Get all sorts of information such as device-specific info, grafport
129  information, visible and clipping region, pattern, pen, text, and
130  colour information, and other details, on the topmost window. Also
131  get the window variant. If there's a colour table record, add the
132  colour table as well */
133  if( ( windowPtr = FrontWindow() ) != NULL )
134  {
135 /* CTabHandle colourHandle; */
136 
137 #if !defined OPAQUE_TOOLBOX_STRUCTS || !OPAQUE_TOOLBOX_STRUCTS
138  addRandomData( randomState, windowPtr, sizeof( GrafPort ) );
139 #endif
140  addRandomValue( randomState, GetWVariant( windowPtr ) );
141 /* if( GetAuxWin( windowPtr, colourHandle ) )
142  {
143  CTabPtr colourPtr;
144 
145  HLock( colourHandle );
146  colourPtr = *colourHandle;
147  addRandomData( randomState, colourPtr, sizeof( ColorTable ) );
148  HUnlock( colourHandle );
149  } */
150  }
151 
152  /* Get mouse-related such as the mouse button status and mouse position,
153  information on the window underneath the mouse */
154  addRandomValue( randomState, Button() );
155  GetMouse( &point );
156  addRandomData( randomState, &point, sizeof( Point ) );
157  FindWindow( point, &windowPtr );
158 #if !defined OPAQUE_TOOLBOX_STRUCTS || !OPAQUE_TOOLBOX_STRUCTS
159  if( windowPtr != NULL )
160  addRandomData( randomState, windowPtr, sizeof( GrafPort ) );
161 #endif
162 
163  /* Get the size, handle, and location of the desk scrap/clipboard */
164 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
165  scrapInfo = InfoScrap();
166  addRandomData( randomState, scrapInfo, sizeof( ScrapStuff ) );
167 #endif
168 
169  /* Get information on the current thread */
170  threadID = kCurrentThreadID; /*GetThreadID( &threadID ); */
171  GetThreadState( threadID, &threadState );
172  addRandomData( randomState, &threadState, sizeof( ThreadState ) );
173 
174  /* Get the sound mananger status. This gets the number of allocated
175  sound channels and the current CPU load from these channels */
176  SndManagerStatus( sizeof( SMStatus ), &soundStatus );
177  addRandomData( randomState, &soundStatus, sizeof( SMStatus ) );
178 
179  /* Get the speech manager version and status */
180 /* version = SpeechManagerVersion();
181  addRandomData( randomState, &version, sizeof( NumVersion ) );
182  addRandomValue( randomState, SpeechBusy() );
183 */
184  /* Get the status of the serial port. This gets information on recent
185  errors, read and write pending status, and flow control values */
186 /* if( !OpenDriver( "\p.AIn", &driverRefNum ) )
187  {
188  SerStaRec serialStatus;
189 
190  SetStatus( driverRefNum, &serialStatus );
191  addRandomData( randomState, &serialStatus, sizeof( SerStaRec ) );
192  }
193  if( !OpenDriver( "\p.AOut", &driverRefNum ) )
194  {
195  SerStaRec serialStatus;
196 
197  SetStatus( driverRefNum, &serialStatus );
198  addRandomData( randomState, &serialStatus, sizeof( SerStaRec ) );
199  } */
200 
201  /* Flush any remaining data through */
202  endRandomData( randomState, 10 );
203  }
204 
205 void slowPoll( void )
206  {
207  RANDOM_STATE randomState;
208  BYTE buffer[ RANDOM_BUFSIZE + 8 ];
209  ProcessSerialNumber psn;
210  GDHandle deviceHandle;
211  GrafPtr currPort;
212  QElemPtr queuePtr;
213  QHdrPtr queueHdr;
214  static BOOLEAN addedFixedItems = FALSE;
215 
216  initRandomData( randomState, buffer, RANDOM_BUFSIZE );
217 
218  /* Walk through the list of graphics devices adding information about
219  a device (IM VI 21-21) */
220  deviceHandle = GetDeviceList();
221  while( deviceHandle != NULL )
222  {
223  GDHandle currentHandle = deviceHandle;
224  GDPtr devicePtr;
225 
226  HLock( ( Handle ) currentHandle );
227  devicePtr = *currentHandle;
228  deviceHandle = devicePtr->gdNextGD;
229  addRandomData( randomState, devicePtr, sizeof( GDevice ) );
230  HUnlock( ( Handle ) currentHandle );
231  }
232 
233  /* Walk through the list of processes adding information about each
234  process, including the name and serial number of the process, file and
235  resource information, memory usage information, the name of the
236  launching process, launch time, and accumulated CPU time (IM VI 29-17) */
237  psn.highLongOfPSN = 0;
238  psn.lowLongOfPSN = kNoProcess;
239  while( !GetNextProcess( &psn ) )
240  {
241  ProcessInfoRec infoRec;
242  GetProcessInformation( &psn, &infoRec );
243  addRandomData( randomState, &infoRec, sizeof( ProcessInfoRec ) );
244  }
245 
246  /* Get the command type, trap address, and parameters for all commands in
247  the file I/O queue. The parameters are quite complex and are listed
248  on page 117 of IM IV, and include reference numbers, attributes, time
249  stamps, length and file allocation information, finder info, and large
250  amounts of other volume and filesystem-related data */
251 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
252  if( ( queueHdr = GetFSQHdr() ) != NULL )
253  queuePtr = queueHdr->qHead;
254  while( queuePtr != NULL )
255  {
256  /* The queue entries are variant records of variable length so we
257  need to adjust the length parameter depending on the record
258  type */
259  addRandomData( randomState, queuePtr, 32 ); /* dunno how big.. */
260  queuePtr = queuePtr->qLink;
261  }
262 #endif
263  /* The following are fixed for the lifetime of the process so we only
264  add them once */
265  if( !addedFixedItems )
266  {
267  Str255 appName, volName;
268  GDHandle deviceHandle;
269  Handle appHandle;
270  DrvSts driveStatus;
271  MachineLocation machineLocation;
272  ProcessInfoRec processInfo;
273  QHdrPtr vblQueue;
274  SysEnvRec sysEnvirons;
275  SysPPtr pramPtr;
276  DefStartRec startupInfo;
277  DefVideoRec videoInfo;
278  DefOSRec osInfo;
279  XPPParamBlock appleTalkParams;
280  unsigned char *driverNames[] = {
281  "\p.AIn", "\p.AOut", "\p.AppleCD", "\p.ATP", "\p.BIn", "\p.BOut", "\p.MPP",
282  "\p.Print", "\p.Sony", "\p.Sound", "\p.XPP", NULL
283  };
284  SInt16 count, dummy, i, node, net, vRefNum, script;
285  SInt32 lcount, volume;
286 
287  /* Get the current font family ID, node ID of the local AppleMumble
288  router, caret blink delay, CPU speed, double-click delay, sound
289  volume, application and system heap zone, the number of resource
290  types in the application, the number of sounds voices available,
291  the FRef of the current resource file, volume of the sysbeep,
292  primary line direction, computer SCSI disk mode ID, timeout before
293  the screen is dimmed and before the computer is put to sleep,
294  number of available threads in the thread pool, whether hard drive
295  spin-down is disabled, the handle to the i18n resources, timeout
296  time for the internal HDD, */
297  addRandomValue( randomState, GetAppFont() );
298 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
299  addRandomValue( randomState, GetBridgeAddress() );
300 #endif
301  addRandomValue( randomState, GetCaretTime() );
302 /* addRandomValue( randomState, GetCPUSpeed() ); */
303  addRandomValue( randomState, GetDblTime() );
304  GetSysBeepVolume( &volume );
305  addRandomValue( randomState, volume );
306  GetDefaultOutputVolume( &volume );
307  addRandomValue( randomState, volume );
308 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
309  addRandomValue( randomState, ApplicationZone() );
310  addRandomValue( randomState, SystemZone() );
311 #endif
312  addRandomValue( randomState, CountTypes() );
313 /* CountVoices( &count ); ** seems to crash
314  addRandomValue( randomState, count ); */
315  addRandomValue( randomState, CurResFile() );
316  GetSysBeepVolume( &lcount );
317  addRandomValue( randomState, lcount );
318  addRandomValue( randomState, GetSysDirection() );
319 /* addRandomValue( randomState, GetSCSIDiskModeAddress() );
320  addRandomValue( randomState, GetDimmingTimeout() );
321  addRandomValue( randomState, GetSleepTimeout() ); */
322  GetFreeThreadCount( kCooperativeThread, &count );
323  addRandomValue( randomState, count );
324 /* addRandomValue( randomState, IsSpindownDisabled() ); */
325  addRandomValue( randomState, GetIntlResource( 0 ) );
326 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
327  GetTimeout( &count );
328  addRandomValue( randomState, count );
329 #endif
330 
331  /* Get the number of documents/files which were selected when the app
332  started and for each document get the vRefNum, name, type, and
333  version -- OBSOLETE
334  CountAppFiles( &dummy, &count );
335  addRandomValue( randomState, count );
336  while( count > 0 )
337  {
338  AppFile theFile;
339  GetAppFiles( count, &theFile );
340  addRandomData( randomState, &theFile, sizeof( AppFile ) );
341  count--;
342  } */
343 
344  /* Get the app's name, resource file reference number, and handle to
345  the finder information -- OBSOLETE
346  GetAppParams( appName, appHandle, &count );
347  addRandomData( randomState, appName, sizeof( Str255 ) );
348  addRandomValue( randomState, appHandle );
349  addRandomValue( randomState, count ); */
350 
351  /* Get all sorts of statistics such as physical information, disk and
352  write-protect present status, error status, and handler queue
353  information, on floppy drives attached to the system. Also get
354  the volume name, volume reference number and number of bytes free,
355  for the volume in the drive */
356 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
357  if( !DriveStatus( 1, &driveStatus ) )
358  addRandomData( randomState, &driveStatus, sizeof (DrvSts) );
359 #endif
360 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
361  if( !GetVInfo( 1, volName, &vRefNum, &lcount ) )
362  {
363  addRandomData( randomState, volName, sizeof( Str255 ) );
364  addRandomValue( randomState, vRefNum );
365  addRandomValue( randomState, lcount );
366  }
367 #endif
368 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
369  if( !DriveStatus( 2, &driveStatus ) )
370  addRandomData( randomState, &driveStatus, sizeof (DrvSts) );
371 #endif
372 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
373  if( !GetVInfo( 2, volName, &vRefNum, &lcount ) )
374  {
375  addRandomData( randomState, volName, sizeof( Str255 ) );
376  addRandomValue( randomState, vRefNum );
377  addRandomValue( randomState, lcount );
378  }
379 #endif
380  /* Get information on the head and tail of the vertical retrace
381  queue */
382 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
383  if( ( vblQueue = GetVBLQHdr() ) != NULL )
384  addRandomData( randomState, vblQueue, sizeof( QHdr ) );
385 #endif
386  /* Get the parameter RAM settings */
387  pramPtr = GetSysPPtr();
388  addRandomData( randomState, pramPtr, sizeof( SysParmType ) );
389 
390  /* Get information about the machines geographic location */
391  ReadLocation( &machineLocation );
392  addRandomData( randomState, &machineLocation,
393  sizeof( MachineLocation ) );
394 
395  /* Get information on current graphics devices including device
396  information such as dimensions and cursor information, and a
397  number of handles to device-related data blocks and functions, and
398  information about the dimentions and contents of the devices pixel
399  image as well as the images resolution, storage format, depth, and
400  colour usage */
401  deviceHandle = GetDeviceList();
402  do
403  {
404  GDPtr gdPtr;
405 
406  addRandomValue( randomState, deviceHandle );
407  HLock( ( Handle ) deviceHandle );
408  gdPtr = ( GDPtr ) *deviceHandle;
409  addRandomData( randomState, gdPtr, sizeof( GDevice ) );
410  addRandomData( randomState, gdPtr->gdPMap, sizeof( PixMap ) );
411  HUnlock( ( Handle ) deviceHandle );
412  }
413  while( ( deviceHandle = GetNextDevice( deviceHandle ) ) != NULL );
414 
415  /* Get the current system environment, including the machine and
416  system software type, the keyboard type, where there's a colour
417  display attached, the AppleTalk driver version, and the VRefNum of
418  the system folder */
419 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
420  SysEnvirons( curSysEnvVers, &sysEnvirons );
421  addRandomData( randomState, &sysEnvirons, sizeof( SysEnvRec ) );
422 #endif
423 
424  /* Get the AppleTalk node ID and network number for this machine */
425 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
426  if( GetNodeAddress( &node, &net ) )
427  {
428  addRandomValue( randomState, node );
429  addRandomValue( randomState, net );
430  }
431 #endif
432  /* Get information on each device connected to the ADB including the
433  device handler ID, the devices ADB address, and the address of the
434  devices handler and storage area */
435 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
436  count = CountADBs();
437  while( count-- > 0 )
438  {
439  ADBDataBlock adbInfo;
440 
441  GetIndADB( &adbInfo, count );
442  addRandomData( randomState, &adbInfo, sizeof( ADBDataBlock ) );
443  }
444 #endif
445  /* Open the most common device types and get the general device
446  status information and (if possible) device-specific status. The
447  general device information contains the device handle and flags,
448  I/O queue information, event information, and other driver-related
449  details */
450 
451 /* Try something like this again.. and ur a dead man, Peter ;-)
452  -xmath */
453 
454 /* for( count = 0; driverNames[ count ] != NULL; count++ )
455  {
456  AuxDCEHandle dceHandle;
457  short driverRefNum;
458 
459  ** Try and open the driver **
460  if( OpenDriver( driverNames[ count ], &driverRefNum ) )
461  continue;
462 
463  ** Get a handle to the driver control information (this could
464  also be done with GetDCtlHandle()) **
465  Status( driverRefNum, 1, &dceHandle );
466  HLock( dceHandle );
467  addRandomData( randomState, *dceHandle,
468  sizeof( AuxDCE ) );
469  HUnlock( dceHandle );
470  CloseDriver( driverRefNum );
471  } */
472 
473  /* Get the name and volume reference number for the current volume */
474 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
475  GetVol( volName, &vRefNum );
476  addRandomData( randomState, volName, sizeof( Str255 ) );
477  addRandomValue( randomState, vRefNum );
478 #endif
479  /* Get the time information, attributes, directory information and
480  bitmap, volume allocation information, volume and drive
481  information, pointers to various pieces of volume-related
482  information, and details on path and directory caches, for each
483  volume */
484 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
485  if( ( queueHdr = GetVCBQHdr() ) != NULL )
486  queuePtr = queueHdr->qHead;
487  while ( queuePtr != NULL )
488  {
489  addRandomData( randomState, queuePtr, sizeof( VCB ) );
490  queuePtr = queuePtr->qLink;
491  }
492 #endif
493 
494  /* Get the driver reference number, FS type, and media size for each
495  drive */
496 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
497  if( ( queueHdr = GetDrvQHdr() ) != NULL )
498  queuePtr = queueHdr->qHead;
499  while ( queuePtr != NULL )
500  {
501  addRandomData( randomState, queuePtr, sizeof( DrvQEl ) );
502  queuePtr = queuePtr->qLink;
503  }
504 #endif
505  /* Get global script manager variables and vectors, including the
506  globals changed count, font, script, and i18n flags, various
507  script types, and cache information */
508  for( count = 0; count < 30; count++ )
509  addRandomValue( randomState, GetScriptManagerVariable( count ) );
510 
511  /* Get the script code for the font script the i18n script, and for
512  each one add the changed count, font, script, i18n, and display
513  flags, resource ID's, and script file information */
514  script = FontScript();
515  addRandomValue( randomState, script );
516  for( count = 0; count < 30; count++ )
517  addRandomValue( randomState, GetScriptVariable( script, count ) );
518  script = IntlScript();
519  addRandomValue( randomState, script );
520  for( count = 0; count < 30; count++ )
521  addRandomValue( randomState, GetScriptVariable( script, count ) );
522 
523  /* Get the device ID, partition, slot number, resource ID, and driver
524  reference number for the default startup device */
525 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
526  GetDefaultStartup( &startupInfo );
527  addRandomData( randomState, &startupInfo, sizeof( DefStartRec ) );
528 #endif
529  /* Get the slot number and resource ID for the default video device */
530 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
531  GetVideoDefault( &videoInfo );
532  addRandomData( randomState, &videoInfo, sizeof( DefVideoRec ) );
533 #endif
534  /* Get the default OS type */
535 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
536  GetOSDefault( &osInfo );
537  addRandomData( randomState, &osInfo, sizeof( DefOSRec ) );
538 #endif
539  /* Get the AppleTalk command block and data size and number of
540  sessions */
541 #if !defined CALL_NOT_IN_CARBON || CALL_NOT_IN_CARBON
542  ASPGetParms( &appleTalkParams, FALSE );
543  addRandomData( randomState, &appleTalkParams,
544  sizeof( XPPParamBlock ) );
545 #endif
546  addedFixedItems = TRUE;
547  }
548 
549  /* Flush any remaining data through */
550  endRandomData( randomState, 100 );
551  }