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