cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
objects.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * Kernel Object Management *
4 * Copyright Peter Gutmann 1997-2009 *
5 * *
6 ****************************************************************************/
7 
8 #if defined( INC_ALL )
9  #include "crypt.h"
10  #include "acl.h"
11  #include "kernel.h"
12 #else
13  #include "crypt.h"
14  #include "kernel/acl.h"
15  #include "kernel/kernel.h"
16 #endif /* Compiler-specific includes */
17 
18 /* The initial allocation size of the object table. In memory-starved
19  environments we limit the size, in general these are embedded systems or
20  single-tasking OSes that aren't going to need many objects anyway */
21 
22 #if defined( CONFIG_CONSERVE_MEMORY )
23  #define OBJECT_TABLE_ALLOCSIZE 128
24  #define INITIAL_LFSRPOLY 0x83
25 #elif defined( CONFIG_NO_OBJECTS )
26  #define OBJECT_TABLE_ALLOCSIZE CONFIG_NO_OBJECTS
27  #if CONFIG_NO_OBJECTS == 512
28  #define INITIAL_LFSRPOLY 0x211
29  #elif CONFIG_NO_OBJECTS == 1024
30  #define INITIAL_LFSRPOLY 0x409
31  #elif CONFIG_NO_OBJECTS == 2048
32  #define INITIAL_LFSRPOLY 0x805
33  #elif CONFIG_NO_OBJECTS == 4096
34  #define INITIAL_LFSRPOLY 0x1053
35  #elif CONFIG_NO_OBJECTS == 8192
36  #define INITIAL_LFSRPOLY 0x201B
37  #elif CONFIG_NO_OBJECTS == 16384
38  #define INITIAL_LFSRPOLY 0x402B
39  #else
40  #error CONFIG_NO_OBJECTS must be 512, 1K, 2K, 4K, 8K, or 16K
41  #endif /* CONFIG_NO_OBJECTS settings */
42 #else
43  #define OBJECT_TABLE_ALLOCSIZE 1024
44  #define INITIAL_LFSRPOLY 0x409
45 #endif /* Memory-starved environments */
46 
47 /* A pointer to the kernel data block */
48 
49 static KERNEL_DATA *krnlData = NULL;
50 
51 /* A template used to initialise object table entries. Some of the entries
52  are either object handles that have to be set to CRYPT_ERROR or values
53  for which 0 is significant (so they're set to CRYPT_UNUSED), because of
54  this we can't just memset the entry to all zeroes */
55 
56 static const OBJECT_INFO FAR_BSS OBJECT_INFO_TEMPLATE = {
57  OBJECT_TYPE_NONE, 0, /* Type, subtype */
58  NULL, 0, /* Object data and size */
60  0, /* Action flags */
61  0, 0, /* Ref.count, lock count */
62 #ifdef USE_THREADS
63  THREAD_INITIALISER, /* Lock owner */
64 #endif /* USE_THREADS */
65  0, /* Unique ID */
66  CRYPT_UNUSED, CRYPT_UNUSED, /* Forward count, usage count */
67 #ifdef USE_THREADS
68  THREAD_INITIALISER, /* Owner */
69 #endif /* USE_THREADS */
70  NULL, /* Message function */
72  CRYPT_ERROR /* Owning/dependent objects */
73  };
74 
75 /* A template used to initialise the object allocation state data */
76 
77 static const OBJECT_STATE_INFO FAR_BSS OBJECT_STATE_INFO_TEMPLATE = {
78  OBJECT_TABLE_ALLOCSIZE, /* Mask for LFSR output */
79  INITIAL_LFSRPOLY, /* LFSR polynomial */
80  -1 /* Initial-1'th object handle */
81  };
82 
83 /****************************************************************************
84 * *
85 * Init/Shutdown Functions *
86 * *
87 ****************************************************************************/
88 
89 /* Create and destroy the object table. The destroy process is handled in
90  two stages, the first of which is called fairly early in the shutdown
91  process to destroy any remaining objects, and the second which is called
92  at the end of the shutdown when the kernel data is being deleted. This
93  is because some of the objects are tied to things like external devices,
94  and deleting them at the end when everything else has been shut down
95  isn't possible */
96 
98 int initObjects( INOUT KERNEL_DATA *krnlDataPtr )
99  {
100  int i, status;
101 
102  assert( isWritePtr( krnlDataPtr, sizeof( KERNEL_DATA ) ) );
103 
104  /* Perform a consistency check on various things that need to be set
105  up in a certain way for things to work properly */
107  "Object table param" );
108  static_assert_opt( OBJECT_INFO_TEMPLATE.type == OBJECT_TYPE_NONE, \
109  "Object table param" );
110  static_assert_opt( OBJECT_INFO_TEMPLATE.subType == 0, \
111  "Object table param" );
112  static_assert_opt( OBJECT_INFO_TEMPLATE.objectPtr == NULL, \
113  "Object table param" );
114  static_assert_opt( OBJECT_INFO_TEMPLATE.objectSize == 0, \
115  "Object table param" );
116  static_assert_opt( OBJECT_INFO_TEMPLATE.flags == \
118  "Object table param" );
119  static_assert_opt( OBJECT_INFO_TEMPLATE.actionFlags == 0, \
120  "Object table param" );
121  static_assert_opt( OBJECT_INFO_TEMPLATE.forwardCount == CRYPT_UNUSED, \
122  "Object table param" );
123  static_assert_opt( OBJECT_INFO_TEMPLATE.usageCount == CRYPT_UNUSED, \
124  "Object table param" );
125  static_assert_opt( OBJECT_INFO_TEMPLATE.owner == CRYPT_ERROR, \
126  "Object table param" );
127  static_assert_opt( OBJECT_INFO_TEMPLATE.dependentDevice == CRYPT_ERROR, \
128  "Object table param" );
129  static_assert_opt( OBJECT_INFO_TEMPLATE.dependentObject == CRYPT_ERROR, \
130  "Object table param" );
132  "Object table param" );
134  "Object table param" );
135 
136  /* Set up the reference to the kernel data block */
137  krnlData = krnlDataPtr;
138 
139  /* Allocate and initialise the object table */
140  krnlData->objectTable = \
141  clAlloc( "initObjectTable",
142  OBJECT_TABLE_ALLOCSIZE * sizeof( OBJECT_INFO ) );
143  if( krnlData->objectTable == NULL )
144  return( CRYPT_ERROR_MEMORY );
145  for( i = 0; i < OBJECT_TABLE_ALLOCSIZE; i++ )
146  krnlData->objectTable[ i ] = OBJECT_INFO_TEMPLATE;
147  krnlData->objectTableSize = OBJECT_TABLE_ALLOCSIZE;
148  krnlData->objectStateInfo = OBJECT_STATE_INFO_TEMPLATE;
149 
150  /* Initialise object-related information. This isn't strictly part of
151  the object table but is used to assign unique ID values to objects
152  within the table, since table entries (object handles) may be reused
153  as objects are destroyed and new ones created in their place */
154  krnlData->objectUniqueID = 0;
155 
156  /* Initialize any data structures required to make the object table
157  thread-safe */
158  MUTEX_CREATE( objectTable, status );
159  if( cryptStatusError( status ) )
160  {
161  clFree( "initObjectTable", krnlData->objectTable );
162  retIntError();
163  }
164 
165  /* Postconditions */
166  ENSURES( krnlData->objectTable != NULL );
167  ENSURES( krnlData->objectTableSize == OBJECT_TABLE_ALLOCSIZE );
168  FORALL( i, 0, OBJECT_TABLE_ALLOCSIZE, \
169  !memcmp( &krnlData->objectTable[ i ], \
170  &OBJECT_INFO_TEMPLATE, sizeof( OBJECT_INFO ) ) );
171  ENSURES( krnlData->objectStateInfo.lfsrMask == OBJECT_TABLE_ALLOCSIZE && \
172  krnlData->objectStateInfo.lfsrPoly == INITIAL_LFSRPOLY && \
174  ENSURES( krnlData->objectUniqueID == 0 );
175 
176  return( CRYPT_OK );
177  }
178 
179 void endObjects( void )
180  {
181  /* Hinc igitur effuge */
182  MUTEX_LOCK( objectTable );
183  zeroise( krnlData->objectTable,
184  krnlData->objectTableSize * sizeof( OBJECT_INFO ) );
185  clFree( "endObjectTable", krnlData->objectTable );
186  krnlData->objectTable = NULL;
187  krnlData->objectTableSize = 0;
188  krnlData->objectUniqueID = 0;
189  MUTEX_UNLOCK( objectTable );
190  MUTEX_DESTROY( objectTable );
191  krnlData = NULL;
192  }
193 
194 /****************************************************************************
195 * *
196 * Object Table Management *
197 * *
198 ****************************************************************************/
199 
200 /* Destroy an object's instance data and object table entry */
201 
202 CHECK_RETVAL \
203 int destroyObjectData( IN_HANDLE const int objectHandle )
204  {
205  OBJECT_INFO *objectInfoPtr;
206  int status;
207 
208  /* Precondition: It's a valid object */
209  REQUIRES( isValidObject( objectHandle ) );
210 
211  objectInfoPtr = &krnlData->objectTable[ objectHandle ];
212 
213  /* Inner precondition: There's valid object data present */
214  REQUIRES( objectInfoPtr->objectPtr != NULL && \
215  objectInfoPtr->objectSize > 0 && \
216  objectInfoPtr->objectSize < MAX_INTLENGTH );
217 
218  /* Destroy the object's data and clear the object table entry */
219  if( objectInfoPtr->flags & OBJECT_FLAG_SECUREMALLOC )
220  {
221  status = krnlMemfree( &objectInfoPtr->objectPtr );
222  ENSURES( cryptStatusOK( status ) );
223  }
224  else
225  {
226  /* Mors ultima linea rerum est */
227  zeroise( objectInfoPtr->objectPtr, objectInfoPtr->objectSize );
228  clFree( "destroyObjectData", objectInfoPtr->objectPtr );
229  }
230  krnlData->objectTable[ objectHandle ] = OBJECT_INFO_TEMPLATE;
231 
232  return( CRYPT_OK );
233  }
234 
235 /* Destroy an object. This is only called when cryptlib is shutting down,
236  normally objects are destroyed directly in response to messages */
237 
238 CHECK_RETVAL \
239 static int destroyObject( IN_HANDLE const int objectHandle )
240  {
241  const OBJECT_INFO *objectInfoPtr;
243 
244  /* Precondition: It's a valid object */
245  REQUIRES( isValidObject( objectHandle ) );
246 
247  objectInfoPtr = &krnlData->objectTable[ objectHandle ];
248  messageFunction = objectInfoPtr->messageFunction;
249 
250  /* If there's no object present at this position, just clear the entry
251  (it should be cleared anyway) */
252  if( messageFunction == NULL )
253  {
254  krnlData->objectTable[ objectHandle ] = OBJECT_INFO_TEMPLATE;
255  return( CRYPT_OK );
256  }
257 
258  /* Destroy the object and its object table entry */
259  if( objectInfoPtr->type == OBJECT_TYPE_DEVICE )
260  {
262 
263  /* Device objects are unlockable so we have to pass in extended
264  information to handle this */
265  initMessageExtInfo( &messageExtInfo, objectInfoPtr->objectPtr );
266  objectInfoPtr->messageFunction( &messageExtInfo,
267  MESSAGE_DESTROY, NULL, 0 );
268  }
269  else
270  {
271  objectInfoPtr->messageFunction( objectInfoPtr->objectPtr,
272  MESSAGE_DESTROY, NULL, 0 );
273  }
274  return( destroyObjectData( objectHandle ) );
275  }
276 
277 /* Destroy all objects at a given nesting level */
278 
279 CHECK_RETVAL \
280 static int destroySelectedObjects( IN_RANGE( 1, 3 ) const int currentDepth )
281  {
282  const OBJECT_INFO *objectTable = krnlData->objectTable;
283  int objectHandle, status = CRYPT_OK;
284 
285  /* Preconditions: We're destroying objects at a fixed depth */
286  REQUIRES( currentDepth >= 1 && currentDepth <= 3 );
287 
288  for( objectHandle = NO_SYSTEM_OBJECTS; \
289  objectHandle < krnlData->objectTableSize && \
290  objectHandle < MAX_OBJECTS; \
291  objectHandle++ )
292  {
293  const int dependentObject = \
294  objectTable[ objectHandle ].dependentObject;
295  int depth = 1;
296 
297  /* If there's nothing there, continue */
298  if( objectTable[ objectHandle ].objectPtr == NULL )
299  continue;
300 
301  /* There's an object still present, determine its nesting depth.
302  Dependent devices are terminal so we only follow the path down for
303  dependent objects */
304  if( isValidObject( dependentObject ) )
305  {
306  if( isValidObject( objectTable[ dependentObject ].dependentObject ) )
307  depth = 3;
308  else
309  {
310  if( isValidObject( objectTable[ dependentObject ].dependentDevice ) )
311  depth = 2;
312  }
313  }
314  else
315  {
316  if( isValidObject( objectTable[ objectHandle ].dependentDevice ) )
317  depth = 2;
318  }
319 
320  /* If the nesting level of the object matches the current level,
321  destroy it. We unlock the object table around the access to
322  prevent remaining active objects from blocking the shutdown (the
323  closingDown flag takes care of any other messages that may arrive
324  during this process).
325 
326  "For death is come up into our windows, and it is entered into
327  our palaces, to cut off the children from the without"
328  -- Jeremiah 9:21 */
329  if( depth >= currentDepth )
330  {
331  objectTable = NULL;
332  MUTEX_UNLOCK( objectTable );
333  krnlSendNotifier( objectHandle, IMESSAGE_DESTROY );
334  status = CRYPT_ERROR_INCOMPLETE;
335  MUTEX_LOCK( objectTable );
336  objectTable = krnlData->objectTable;
337  }
338  }
339  ENSURES( objectHandle < MAX_OBJECTS );
340 
341  return( status );
342  }
343 
344 /* Destroy all objects (homini necesse est mori) */
345 
346 CHECK_RETVAL \
347 int destroyObjects( void )
348  {
349  int depth, objectHandle, localStatus, status = DUMMY_INIT;
350 
351  /* Preconditions: We either didn't complete the initialisation and are
352  shutting down during a krnlBeginInit(), or we've completed
353  initialisation and are shutting down after a krnlBeginShutdown() */
354  REQUIRES( ( krnlData->initLevel == INIT_LEVEL_KRNLDATA && \
355  krnlData->shutdownLevel == SHUTDOWN_LEVEL_NONE ) || \
356  ( krnlData->initLevel == INIT_LEVEL_KRNLDATA && \
357  krnlData->shutdownLevel == SHUTDOWN_LEVEL_THREADS ) );
358 
359  /* Indicate that we're shutting down the object handling. From now on
360  all messages other than object-destruction ones will be rejected by
361  the kernel. This is needed in order to have any remaining active
362  objects exit quickly, since we don't want them to block the shutdown.
363  Note that we do this before we lock the object table to encourage
364  anything that might have the table locked to exit quickly once we try
365  and lock the table */
367 
368  /* Lock the object table to ensure that other threads don't try to
369  access it */
370  MUTEX_LOCK( objectTable );
371 
372  /* Destroy all system objects except the root system object ("The death
373  of God left the angels in a strange position" - Donald Barthelme, "On
374  Angels"). We have to do this before we destroy any unclaimed
375  leftover objects because some of them may depend on system objects,
376  if the system objects aren't destroyed they'll be erroneously flagged
377  as leftover objects. The destruction is done explicitly by invoking
378  the object's message function directly because the message dispatcher
379  checks to make sure that they're never destroyed through a standard
380  message, which would indicate a programming error */
381  for( objectHandle = SYSTEM_OBJECT_HANDLE + 1;
382  objectHandle < NO_SYSTEM_OBJECTS; objectHandle++ )
383  {
384  status = destroyObject( objectHandle );
385  ENSURES( cryptStatusOK( status ) );
386  }
387 
388  /* Postcondition: All system objects except the root system object have
389  been destroyed */
390  FORALL( i, SYSTEM_OBJECT_HANDLE + 1, NO_SYSTEM_OBJECTS,
391  !memcmp( &krnlData->objectTable[ i ], &OBJECT_INFO_TEMPLATE, \
392  sizeof( OBJECT_INFO ) ) );
393 
394  /* Delete any unclaimed leftover objects. This is rather more complex
395  than just rumbling through deleting each object we find since some
396  objects have dependent objects underneath them, and deleting the
397  lower-level object causes problems when we later delete their parents
398  (the code handles it cleanly, but we get a kernel trap warning us that
399  we're trying to delete a non-present object). Because of this we have
400  to delete the objects in order of depth, first all three-level objects
401  (e.g. cert -> context -> device), then all two-level objects, and
402  finally all one-level objects. This means that we can never delete
403  another object out from under a dependent object */
404  for( depth = 3; depth > 0; depth-- )
405  {
406  localStatus = destroySelectedObjects( depth );
407  if( cryptStatusError( localStatus ) )
408  status = localStatus;
409  }
410 
411  /* Postcondition: All objects except the root system object have been
412  destroyed */
413  FORALL( i, SYSTEM_OBJECT_HANDLE + 1, krnlData->objectTableSize,
414  !memcmp( &krnlData->objectTable[ i ], &OBJECT_INFO_TEMPLATE, \
415  sizeof( OBJECT_INFO ) ) );
416 
417  /* Finally, destroy the system root object. We need to preserve the
418  possible error status from cleaning up any leftover objects so we use
419  a local status value to get the destroy-object results */
420  localStatus = destroyObject( SYSTEM_OBJECT_HANDLE );
421  ENSURES( cryptStatusOK( localStatus ) );
422 
423  /* Unlock the object table to allow access by other threads */
424  MUTEX_UNLOCK( objectTable );
425 
426  return( status );
427  }
428 
429 /****************************************************************************
430 * *
431 * Object Creation/Destruction *
432 * *
433 ****************************************************************************/
434 
435 /* Create a new object. This function has to be very careful about locking
436  to ensure that another thread can't manipulate the newly-created object
437  while it's in an indeterminate state. To accomplish this it locks the
438  object table and tries to create the new object. If this succeeds it sets
439  the OBJECT_FLAG_NOTINITED flag pending completion of the object's
440  initialisation by the caller, unlocks the object table, and returns
441  control to the caller. While the object is in this state, the kernel
442  will allow it to process only two message types, either a notification
443  from the caller that the init stage is complete (which sets the object's
444  state to OK), or a destroy object message, which sets the
445  OBJECT_FLAG_SIGNALLED flag pending arrival of the init complete
446  notification, whereupon the object is immediately destroyed. The state
447  diagram for this is:
448  State
449  Notinited Signalled
450  --------+-------------------+-----------------
451  -> OK | state -> OK, | Msg -> Destroy
452  | ret( OK ) |
453  Msg. Destroy | state -> Sig'd, | state -> Sig'd,
454  | ret( OK ) | ret( OK )
455  CtrlMsg | process as usual | process as usual
456  NonCtrl | ret( Notinited ) | ret( Sig'd )
457 
458  The initialisation process for an object is therefore:
459 
460  status = krnlCreateObject( ... );
461  if( cryptStatusError( status ) )
462  return( status );
463 
464  // Complete object-specific initialisation
465  initStatus = ...;
466 
467  status = krnlSendMessage( ..., state -> CRYPT_OK );
468  return( ( cryptStatusError( initStatus ) ? initStatus : status );
469 
470  If the object is destroyed during the object-specific initialisation
471  (either by the init code when an error is encountered or due to an
472  external signal), the destroy is deferred until the change state message
473  at the end occurs. If a destroy is pending, the change state is converted
474  to a destroy and the newly-created object is destroyed.
475 
476  This mechanism ensures that the object table is only locked for a very
477  short time (typically for only a few lines of executed code in the create
478  object function) so that slow initialisation (for example of keyset
479  objects associated with network links) can't block other objects.
480 
481  In addition to the locking, we need to be careful with how we create new
482  objects because if we just allocate handles sequentially and reuse handles
483  as soon as possible, an existing object could be signalled and a new one
484  created in its place without the caller or owning object realizing that
485  they're now working with a different object (although the kernel can tell
486  them apart because it maintains an internal unique ID for each object).
487  Unix systems handle this by always incrementing pids and assuming that
488  there won't be any problems when they wrap, we do the same thing but in
489  addition allocate handles in a non-sequential manner using an LFSR to
490  step through the object table. There's no strong reason for this apart
491  from helping disabuse users of the notion that any cryptlib objects have
492  stdin/stdout-style fixed handles, but it only costs a few extra clocks so
493  we may as well do it */
494 
495 CHECK_RETVAL \
496 static int findFreeResource( int value )
497  {
498  int oldValue = value, iterations;
499 
500  /* Preconditions: We're starting with a valid object handle, and it's not
501  a system object */
502  REQUIRES( isValidHandle( value ) );
503  REQUIRES( value >= NO_SYSTEM_OBJECTS );
504 
505  /* Step through the entire table looking for a free entry */
506  for( iterations = 0; isValidHandle( value ) && \
507  iterations < krnlData->objectTableSize && \
508  iterations < MAX_OBJECTS;
509  iterations++ )
510  {
511  /* Invariant: We're not stuck in an endless loop */
512  ENSURES( iterations < krnlData->objectTableSize );
513 
514  /* Get the next value: Multiply by x and reduce by the polynomial */
515  value <<= 1;
516  if( value & krnlData->objectStateInfo.lfsrMask )
517  value ^= krnlData->objectStateInfo.lfsrPoly;
518 
519  /* Invariant: We're still within the object table */
520  ENSURES( isValidHandle( value ) );
521 
522  /* If we've found a free object or we've covered the entire table,
523  exit. We do this check after we update the value rather than as
524  part of the loop test to ensure that we always progress to a new
525  object handle whenever we call this function. If we did the
526  check as part of the loop test then deleting and creating an
527  object would result in the handle of the deleted object being
528  re-assigned to the new object */
529  if( isFreeObject( value ) || value == oldValue )
530  break;
531  }
532  ENSURES( iterations < MAX_OBJECTS );
533  if( value == oldValue || iterations >= krnlData->objectTableSize || \
534  !isValidHandle( value ) )
535  {
536  /* Postcondition: We tried all locations and there are no free slots
537  available (or, vastly less likely, an internal error has
538  occurred) */
539  ENSURES( iterations == krnlData->objectTableSize - 2 );
540  FORALL( i, 0, krnlData->objectTableSize,
541  krnlData->objectTable[ i ].objectPtr != NULL );
542 
543  return( CRYPT_ERROR );
544  }
545 
546  /* Postconditions: We found a handle to a free slot */
547  ENSURES( isValidHandle( value ) );
548  ENSURES( isFreeObject( value ) );
549 
550  return( value );
551  }
552 
553 CHECK_RETVAL \
554 static int expandObjectTable( void )
555  {
556  static const long FAR_BSS lfsrPolyTable[] = \
557  { 0x83, 0x11D, 0x211, 0x409,
558  0x805, 0x1053, 0x201B, 0x402B,
559  0x8003L, 0x1002DL, 0x20009L, 0x40027L,
560  0x80027L, 0x100009L, 0x200005L, 0x400003L,
561  0L, 0L };
562  OBJECT_INFO *newTable;
563  int objectHandle, i;
564  ORIGINAL_INT_VAR( oldLfsrPoly, krnlData->objectStateInfo.lfsrPoly );
565 
566  /* If we're already at the maximum number of allowed objects, don't
567  create any more. This prevents both accidental runaway code that
568  creates huge numbers of objects and DoS attacks */
569  if( krnlData->objectTableSize <= 0 || \
570  krnlData->objectTableSize >= MAX_OBJECTS / 2 )
571  return( CRYPT_ERROR_OVERFLOW );
572 
573  /* Precondition: We haven't exceeded the maximum number of objects */
574  REQUIRES( krnlData->objectTableSize > 0 && \
575  krnlData->objectTableSize < MAX_OBJECTS / 2 );
576 
577  /* Expand the table */
578  newTable = clDynAlloc( "krnlCreateObject", \
579  ( krnlData->objectTableSize * 2 ) * \
580  sizeof( OBJECT_INFO ) );
581  if( newTable == NULL )
582  return( CRYPT_ERROR_MEMORY );
583 
584  /* Copy the information across to the new table, set up the newly-
585  allocated entries, and clear the old table */
586  memcpy( newTable, krnlData->objectTable,
587  krnlData->objectTableSize * sizeof( OBJECT_INFO ) );
588  for( i = krnlData->objectTableSize;
589  i < krnlData->objectTableSize * 2 && i < MAX_OBJECTS; i++ )
590  newTable[ i ] = OBJECT_INFO_TEMPLATE;
591  ENSURES( i < MAX_OBJECTS );
592  zeroise( krnlData->objectTable, \
593  krnlData->objectTableSize * sizeof( OBJECT_INFO ) );
594  clFree( "krnlCreateObject", krnlData->objectTable );
595  krnlData->objectTable = newTable;
596  krnlData->objectTableSize *= 2;
597 
598  /* Add the new object at the end of the existing table */
599  krnlData->objectStateInfo.lfsrMask <<= 1;
600  for( i = 0; i < 16; i++ )
601  {
602  if( lfsrPolyTable[ i ] > krnlData->objectStateInfo.lfsrPoly )
603  break;
604  }
605  ENSURES( i < 16 );
606  krnlData->objectStateInfo.lfsrPoly = lfsrPolyTable[ i ];
607  objectHandle = findFreeResource( krnlData->objectStateInfo.objectHandle );
608 
609  /* Postcondition: We've moved on to the next LFSR polynomial value,
610  the LFSR output covers the entire table, and we now have roonm for
611  the new object */
612  ENSURES( ( krnlData->objectStateInfo.lfsrPoly & ~0x7F ) == \
613  ( ( ORIGINAL_VALUE( oldLfsrPoly ) & ~0xFF ) << 1 ) );
614  ENSURES( krnlData->objectStateInfo.lfsrMask == \
615  ( krnlData->objectStateInfo.lfsrPoly & ~0x7F ) );
616  ENSURES( krnlData->objectTableSize == \
617  krnlData->objectStateInfo.lfsrMask );
618  ENSURES( isValidHandle( objectHandle ) );
619 
620  return( objectHandle );
621  }
622 
624 int krnlCreateObject( OUT_HANDLE_OPT int *objectHandle,
625  OUT_BUFFER_ALLOC_OPT( objectDataSize ) void **objectDataPtr,
627  IN_ENUM( OBJECT ) const OBJECT_TYPE type,
628  IN_ENUM( OBJECT_SUB ) const OBJECT_SUBTYPE subType,
629  IN_FLAGS( CREATEOBJECT ) const int createObjectFlags,
630  IN_HANDLE const CRYPT_USER owner,
631  IN_FLAGS( ACTION ) const int actionFlags,
632  IN CALLBACK_FUNCTION MESSAGE_FUNCTION messageFunction )
633  {
634  OBJECT_INFO objectInfo;
635  OBJECT_STATE_INFO *objectStateInfo = &krnlData->objectStateInfo;
636  OBJECT_SUBTYPE bitCount;
637  int localObjectHandle;
638 
639  assert( isWritePtr( krnlData, sizeof( KERNEL_DATA ) ) );
640  assert( isWritePtrConst( objectDataPtr, sizeof( void * ) ) );
641 
642  /* Preconditions (the subType check is just the standard hakmem bitcount
643  which ensures that we don't try and create multi-typed objects, the
644  sole exception to this rule is the default user object, which acts as
645  both a user and an SO object) */
646  REQUIRES( objectDataSize > 16 && objectDataSize < 16384 );
647  REQUIRES( isValidType( type ) );
648  REQUIRES( \
649  ( bitCount = ( subType & ~SUBTYPE_CLASS_MASK ) - \
650  ( ( ( subType & ~SUBTYPE_CLASS_MASK ) >> 1 ) & 033333333333L ) - \
651  ( ( ( subType & ~SUBTYPE_CLASS_MASK ) >> 2 ) & 011111111111L ) ) != 0 );
652  REQUIRES( ( ( bitCount + ( bitCount >> 3 ) ) & 030707070707L ) % 63 == 1 );
653  REQUIRES( !( createObjectFlags & \
656  REQUIRES( owner == CRYPT_UNUSED || isValidHandle( owner ) );
657  REQUIRES( actionFlags >= 0 && actionFlags < ACTION_PERM_LAST );
658  REQUIRES( messageFunction != NULL );
659 
660  /* Clear return values */
661  *objectHandle = CRYPT_ERROR;
662  *objectDataPtr = NULL;
663 
664  /* If we haven't been initialised yet or we're in the middle of a
665  shutdown, we can't create any new objects */
666  if( !isWritePtrConst( krnlData, sizeof( KERNEL_DATA ) ) || \
667  krnlData->initLevel <= INIT_LEVEL_NONE )
668  return( CRYPT_ERROR_NOTINITED );
669  if( krnlData->shutdownLevel >= SHUTDOWN_LEVEL_MESSAGES )
670  {
671  DEBUG_DIAG(( "Can't create new objects during a shutdown" ));
672  assert( DEBUG_WARN );
673  return( CRYPT_ERROR_PERMISSION );
674  }
675 
676  /* Allocate memory for the object and set up as much as we can of the
677  object table entry (the remainder has to be set up inside the object-
678  table lock). The object is always created as an internal object,
679  it's up to the caller to make it externally visible */
680  if( createObjectFlags & CREATEOBJECT_FLAG_SECUREMALLOC )
681  {
682  int status = krnlMemalloc( objectDataPtr, objectDataSize );
683  if( cryptStatusError( status ) )
684  return( status );
685  }
686  else
687  {
688  if( ( *objectDataPtr = clAlloc( "krnlCreateObject", \
689  objectDataSize ) ) == NULL )
690  return( CRYPT_ERROR_MEMORY );
691  }
692  memset( *objectDataPtr, 0, objectDataSize );
693  objectInfo = OBJECT_INFO_TEMPLATE;
694  objectInfo.objectPtr = *objectDataPtr;
695  objectInfo.objectSize = objectDataSize;
696  if( createObjectFlags & CREATEOBJECT_FLAG_SECUREMALLOC )
697  objectInfo.flags |= OBJECT_FLAG_SECUREMALLOC;
698  objectInfo.owner = owner;
699  objectInfo.type = type;
700  objectInfo.subType = subType;
701  objectInfo.actionFlags = actionFlags;
702  objectInfo.messageFunction = messageFunction;
703 
704  /* Make sure that the kernel has been initialised and lock the object
705  table for exclusive access */
706  MUTEX_LOCK( initialisation );
707  MUTEX_LOCK( objectTable );
708  MUTEX_UNLOCK( initialisation );
709 
710  /* Finish setting up the object table entry with any remaining data */
711  objectInfo.uniqueID = krnlData->objectUniqueID;
712 
713  /* The first objects created are internal objects with predefined
714  handles (spes lucis aeternae). As we create these objects we ratchet
715  up through the fixed handles until we reach the last fixed object,
716  whereupon we allocate handles normally */
717  localObjectHandle = objectStateInfo->objectHandle;
718  if( localObjectHandle < NO_SYSTEM_OBJECTS - 1 )
719  {
720  REQUIRES( ( localObjectHandle == SYSTEM_OBJECT_HANDLE - 1 && \
721  owner == CRYPT_UNUSED && \
722  type == OBJECT_TYPE_DEVICE && \
723  subType == SUBTYPE_DEV_SYSTEM ) || \
724  ( localObjectHandle == DEFAULTUSER_OBJECT_HANDLE - 1 && \
725  owner == SYSTEM_OBJECT_HANDLE && \
726  type == OBJECT_TYPE_USER && \
727  subType == SUBTYPE_USER_SO ) );
728  localObjectHandle++;
729  ENSURES( isValidHandle( localObjectHandle ) && \
730  localObjectHandle < NO_SYSTEM_OBJECTS && \
731  localObjectHandle == objectStateInfo->objectHandle + 1 );
732  }
733  else
734  {
735  REQUIRES( isValidHandle( owner ) );
736 
737  /* Search the table for a free entry */
738  localObjectHandle = findFreeResource( localObjectHandle );
739  }
740 
741  /* If the table is full, expand it */
742  if( !isValidHandle( localObjectHandle ) )
743  {
744  localObjectHandle = expandObjectTable();
745  if( cryptStatusError( localObjectHandle ) )
746  {
747  MUTEX_UNLOCK( objectTable );
748 
749  /* Free the object instance data storage that we allocated
750  earlier */
751  if( objectInfo.flags & OBJECT_FLAG_SECUREMALLOC )
752  {
753  int status = krnlMemfree( &objectInfo.objectPtr );
754  ENSURES( cryptStatusOK( status ) );
755  }
756  else
757  {
758  zeroise( objectInfo.objectPtr, objectInfo.objectSize );
759  clFree( "destroyObjectData", objectInfo.objectPtr );
760  }
761  return( localObjectHandle );
762  }
763  }
764 
765  /* Inner precondition: This object table slot is free */
766  REQUIRES( isFreeObject( localObjectHandle ) );
767 
768  /* Set up the new object entry in the table and update the object table
769  state */
770  krnlData->objectTable[ localObjectHandle ] = objectInfo;
771  if( localObjectHandle == NO_SYSTEM_OBJECTS - 1 )
772  {
773  time_t theTime;
774 
775  /* Get a non-constant seed to use for the initial object handle.
776  See the comment in findFreeResource() for why this is done, and
777  why it only uses a relatively weak seed. Since we may be running
778  on an embedded system with no reliable time source available we
779  use getApproxTime() rather than getTime(), the check for correct
780  functioning of the time source on non-embedded systems has
781  already been done in the init code */
782  theTime = getApproxTime();
783 
784  /* If this is the last system object, we've been allocating handles
785  sequentially up to this point. From now on we start allocating
786  handles starting from a randomised location in the table */
787  objectStateInfo->objectHandle = \
788  ( int ) theTime & ( objectStateInfo->lfsrMask - 1 );
789  if( objectStateInfo->objectHandle < NO_SYSTEM_OBJECTS )
790  {
791  /* Can occur with probability
792  NO_SYSTEM_OBJECTS / OBJECT_TABLE_ALLOCSIZE */
793  objectStateInfo->objectHandle = NO_SYSTEM_OBJECTS + 42;
794  }
795  }
796  else
797  objectStateInfo->objectHandle = localObjectHandle;
798 
799  /* Update the object unique ID value */
800  if( krnlData->objectUniqueID < 0 || \
801  krnlData->objectUniqueID >= INT_MAX - 1 )
802  krnlData->objectUniqueID = NO_SYSTEM_OBJECTS;
803  else
804  krnlData->objectUniqueID++;
805  ENSURES( krnlData->objectUniqueID > 0 && \
806  krnlData->objectUniqueID < INT_MAX );
807 
808  /* Postconditions: It's a valid object that's been set up as required */
809  ENSURES( isValidObject( localObjectHandle ) );
810  ENSURES( objectInfo.objectPtr == *objectDataPtr );
811  ENSURES( objectInfo.owner == owner );
812  ENSURES( objectInfo.type == type );
813  ENSURES( objectInfo.subType == subType );
814  ENSURES( objectInfo.actionFlags == actionFlags );
815  ENSURES( objectInfo.messageFunction == messageFunction );
816 
817  MUTEX_UNLOCK( objectTable );
818 
819  *objectHandle = localObjectHandle;
820 
821  return( CRYPT_OK );
822  }