cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
beos.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * BeOS Randomness-Gathering Code *
4 * Copyright Peter Gutmann and Osma Ahvenlampi 1996-2003 *
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 #include "random/random.h"
15 
16 /* These get defined by the Be headers */
17 
18 #undef min
19 #undef max
20 
21 /* OS-specific includes */
22 
23 #include <fcntl.h>
24 #include <sys/time.h>
25 #include <kernel/fs_info.h>
26 #include <kernel/OS.h>
27 #include <kernel/image.h>
28 
29 /* The following is defined in <interface/InterfaceDefs.h>, however we
30  can't include that header because it uses some C++ keywords and so won't
31  compile when used with C code.
32 
33  Unfortunately the C++-isms go further than that, extending to the
34  interface kit functions like idle_time(), modifiers(), and get_key_info(),
35  which are only present in libraries in C++ name-mangled form and can't
36  safely be called from a C-only module */
37 
38 typedef struct {
39  uint32 modifiers;
40  uint8 key_states[16];
41  } key_info;
42 
43 /* The size of the intermediate buffer used to accumulate polled data */
44 
45 #define RANDOM_BUFSIZE 4096
46 
47 void fastPoll( void )
48  {
49  RANDOM_STATE randomState;
50  BYTE buffer[ RANDOM_BUFSIZE + 8 ];
51  struct timeval tv;
52  system_info info;
53  bigtime_t idleTime;
54  uint32 value;
55 
56  initRandomData( randomState, buffer, RANDOM_BUFSIZE );
57 
58  gettimeofday( &tv, NULL );
59  addRandomValue( randomState, tv.tv_sec );
60  addRandomValue( randomState, tv.tv_usec );
61 
62  /* Get the number of microseconds since the user last provided any input
63  to any part of the system, the state of keyboard shift keys */
64 #if 0 /* See comment at start */
65  idleTime = idle_time();
66  addRandomData( randomState, &idleTime, sizeof( bigtime_t ) );
67  value = modifiers();
68  addRandomValue( randomState, value );
69 #endif /* 0 */
70 
71  /* Get various fixed values (the 64-bit machine ID, CPU count and type(s),
72  clock speed, platform type, etc) and variable resources (number of in-
73  use pages, semaphores, ports, threads, teams, number of page faults,
74  and number of microseconds the CPU has been active) */
75  get_system_info( &info );
76  addRandomData( randomState, &info, sizeof( info ) );
77 
78  /* Flush any remaining data through */
79  endRandomData( randomState, 5 );
80  }
81 
82 #define DEVRANDOM_BITS 4096
83 
84 void slowPoll( void )
85  {
86  RANDOM_STATE randomState;
87  BYTE buffer[ RANDOM_BUFSIZE + 8 ];
89  team_info teami;
90  thread_info threadi;
91  area_info areai;
92  port_info porti;
93  sem_info semi;
94  image_info imagei;
95  double temperature;
96  int32 devID, cookie;
97  int fd, value;
98 
99  if( ( fd = open( "/dev/urandom", O_RDONLY ) ) >= 0 )
100  {
102  BYTE buffer[ ( DEVRANDOM_BITS / 8 ) + 8 ];
103  static const int quality = 100;
104 
105  /* Read data from /dev/urandom, which won't block (although the
106  quality of the noise is lesser). */
107  read( fd, buffer, DEVRANDOM_BITS / 8 );
108  setMessageData( &msgData, buffer, DEVRANDOM_BITS / 8 );
110  &msgData, CRYPT_IATTRIBUTE_ENTROPY );
111  zeroise( buffer, DEVRANDOM_BITS / 8 );
112  close( fd );
113 
115  ( MESSAGE_CAST ) &quality,
116  CRYPT_IATTRIBUTE_ENTROPY_QUALITY );
117  return;
118  }
119 
120  initRandomData( randomState, buffer, RANDOM_BUFSIZE );
121 
122  /* Get the state of all keys on the keyboard and various other
123  system states */
124 #if 0 /* See comment at start */
125  if( get_key_info( &keyInfo ) == B_NO_ERROR )
126  addRandomData( randomState, &keyInfo, sizeof( key_info ) );
127 #endif /* 0 */
128  value = is_computer_on(); /* Returns 1 if computer is on */
129  addRandomValue( randomState, value );
130  temperature = is_computer_on_fire(); /* MB temp.if on fire */
131  addRandomData( randomState, &temperature, sizeof( double ) );
132 
133  /* Get information on all running teams (thread groups, ie applications).
134  This returns the team ID, number of threads, images, and areas,
135  debugger port and thread ID, program args, and uid and gid */
136  cookie = 0;
137  while( get_next_team_info( &cookie, &teami ) == B_NO_ERROR )
138  addRandomData( randomState, &teami, sizeof( teami ) );
139 
140  /* Get information on all running threads. This returns the thread ID,
141  team ID, thread name and state (eg running, suspended, asleep,
142  blocked), the thread priority, elapsed user and kernel time, and
143  thread stack information */
144  cookie = 0;
145  while( get_next_thread_info( 0, &cookie, &threadi ) == B_NO_ERROR )
146  {
147  addRandomValue( randomState, has_data( threadi.thread ) );
148  addRandomData( randomState, &threadi, sizeof( threadi ) );
149  }
150 
151  /* Get information on all memory areas (chunks of virtual memory). This
152  returns the area ID, name, size, locking scheme and protection bits,
153  ID of the owning team, start address, number of resident bytes, copy-
154  on-write count, an number of pages swapped in and out */
155  cookie = 0;
156  while( get_next_area_info( 0, &cookie, &areai ) == B_NO_ERROR )
157  addRandomData( randomState, &areai, sizeof( areai ) );
158 
159  /* Get information on all message ports. This returns the port ID, ID of
160  the owning team, message queue length, number of messages in the
161  queue, and total number of messages processed */
162  cookie = 0;
163  while( get_next_port_info( 0, &cookie, &porti ) == B_NO_ERROR )
164  addRandomData( randomState, &porti, sizeof( porti ) );
165 
166  /* Get information on all semaphores. This returns the semaphore and
167  owning team ID, the name, thread count, and the ID of the last thread
168  which acquired the semaphore */
169  cookie = 0;
170  while( get_next_sem_info( 0, &cookie, &semi ) == B_NO_ERROR )
171  addRandomData( randomState, &semi, sizeof( semi ) );
172 
173  /* Get information on all images (code blocks, eg applications, shared
174  libraries, and add-on images (DLL's on steroids). This returns the
175  image ID and type (app, library, or add-on), the order in which the
176  image was loaded compared to other images, the address of the init
177  and shutdown routines, the device and node where the image lives,
178  and the image text and data sizes) */
179  cookie = 0;
180  while( get_next_image_info( 0, &cookie, &imagei ) == B_NO_ERROR )
181  addRandomData( randomState, &imagei, sizeof( imagei ) );
182 
183  /* Get information on all storage devices. This returns the device
184  number, root inode, various device parameters such as I/O block size,
185  and the number of free and used blocks and inodes */
186  devID = 0;
187  while( next_dev( &devID ) >= 0 )
188  {
189  fs_info fsInfo;
190 
191  if( fs_stat_dev( devID, &fsInfo ) == B_NO_ERROR )
192  addRandomData( randomState, &fsInfo, sizeof( fs_info ) );
193  }
194 
195  /* Flush any remaining data through */
196  endRandomData( randomState, 100 );
197  }