1 /**************************************************************************** 2 * * 3 * cryptlib Kernel Header File * 4 * Copyright Peter Gutmann 1992-2005 * 5 * * 6 ****************************************************************************/ 7 8 #ifndef _KERNEL_DEFINED 9 10 #define _KERNEL_DEFINED 11 12 #if defined( INC_ALL ) 13 #include "thread.h" 14 #else 15 #include "kernel/thread.h" 16 #endif /* Compiler-specific includes */ 17 18 /* RAY and EGON look over code. 19 20 EGON: The structure of this kernel is exactly like the kind of telemetry 21 tracker that NASA uses to secure dead pulsars in deep space. 22 23 RAY: All message dispatch mechanisms and callback functions. 24 25 PETER (to other jailbirds): Everyone getting this so far? So what? I 26 guess they just don't make them like they used to. 27 28 RAY: No! Nobody ever made them like this! The architect was either a 29 certified genius or an authentic wacko! */ 30 31 /* "There is a fine line between genius and insanity. 32 I have erased this line" - Oscar Levant 33 (or "Nullum magnum ingenium sine mixtura dementiae" if you want it in 34 the usual style) */ 35 36 /**************************************************************************** 37 * * 38 * Parameter Checking Macros * 39 * * 40 ****************************************************************************/ 41 42 /* Macros to perform validity checks on objects and handles. These checks 43 are: 44 45 isValidHandle(): Whether a handle is a valid index into the object table. 46 isValidObject(): Whether a handle refers to an object in the table. 47 isFreeObject(): Whether a handle refers to an empty entry in the table. 48 isInternalObject(): Whether an object is an internal object. 49 isInvalidObjectState(): Whether an object is in an invalid (error) state. 50 isInUse(): Whether an object is currently in use (processing a message). 51 isObjectOwner(): If inUse == TRUE, whether this thread is the one using 52 the object. 53 isInHighState(): Whether an object is in the 'high' security state. 54 isSameOwningObject(): Whether two objects have the same owner. We also 55 have to handle the situation where the first object 56 is a user object, in which case it has to be the 57 owner of the second object. 58 isObjectAccessValid(): Internal/external object access check. 59 isValidMessage(): Whether a message type is valid. 60 isInternalMessage(): Whether a message is an internal message. 61 isValidType(): Whether an object type is valid 62 isValidSubtype(): Whether an object subtype is allowed based on access 63 bitflags */ 64 65 #define isValidHandle( handle ) \ 66 ( ( handle ) >= 0 && ( handle ) < krnlData->objectTableSize ) 67 #define isValidObject( handle ) \ 68 ( isValidHandle( handle ) && \ 69 krnlData->objectTable[ ( handle ) ].objectPtr != NULL ) 70 #define isFreeObject( handle ) \ 71 ( isValidHandle( handle ) && \ 72 krnlData->objectTable[ ( handle ) ].objectPtr == NULL ) 73 #define isInternalObject( handle ) \ 74 ( krnlData->objectTable[ handle ].flags & OBJECT_FLAG_INTERNAL ) 75 #define isObjectAccessValid( objectHandle, message ) \ 76 !( isInternalObject( objectHandle ) && \ 77 !( message & MESSAGE_FLAG_INTERNAL ) ) 78 #define isInvalidObjectState( handle ) \ 79 ( krnlData->objectTable[ ( handle ) ].flags & OBJECT_FLAGMASK_STATUS ) 80 #define isInUse( handle ) \ 81 ( krnlData->objectTable[ ( handle ) ].lockCount > 0 ) 82 #define isObjectOwner( handle ) \ 83 THREAD_SAME( krnlData->objectTable[ ( handle ) ].lockOwner, THREAD_SELF() ) 84 #define isInHighState( handle ) \ 85 ( krnlData->objectTable[ ( handle ) ].flags & OBJECT_FLAG_HIGH ) 86 #define isSameOwningObject( handle1, handle2 ) \ 87 ( krnlData->objectTable[ ( handle1 ) ].owner == CRYPT_UNUSED || \ 88 krnlData->objectTable[ ( handle2 ) ].owner == CRYPT_UNUSED || \ 89 ( krnlData->objectTable[ ( handle1 ) ].owner == \ 90 krnlData->objectTable[ ( handle2 ) ].owner ) || \ 91 ( ( handle1 ) == krnlData->objectTable[ ( handle2 ) ].owner ) ) 92 #define isValidMessage( message ) \ 93 ( ( message ) > MESSAGE_NONE && ( message ) < MESSAGE_LAST ) 94 #define isInternalMessage( message ) \ 95 ( ( message ) & MESSAGE_FLAG_INTERNAL ) 96 #define isValidType( type ) \ 97 ( ( type ) > OBJECT_TYPE_NONE && ( type ) < OBJECT_TYPE_LAST ) 98 #define isValidSubtype( subtypeMask, subtype ) \ 99 ( ( ( subtypeMask ) & ( subtype ) ) == ( subtype ) ) 100 101 /* The set of object checks is used frequently enough that we combine them 102 into a composite check that performs all of the checks in one place */ 103 104 #define fullObjectCheck( objectHandle, message ) \ 105 ( isValidObject( objectHandle ) && \ 106 isObjectAccessValid( objectHandle, message ) && \ 107 checkObjectOwnership( objectTable[ objectHandle ] ) ) 108 109 /* Macros to test whether a message falls into a certain class. These tests 110 are: 111 112 isParamMessage(): Whether a message contains an object as a parameter */ 113 114 #define isParamMessage( message ) \ 115 ( ( message ) == MESSAGE_CRT_SIGN || \ 116 ( message ) == MESSAGE_CRT_SIGCHECK ) 117 118 /* Macros to manage object ownership, if the OS supports it */ 119 120 #define checkObjectOwnership( objectPtr ) \ 121 ( !( ( objectPtr ).flags & OBJECT_FLAG_OWNED ) || \ 122 THREAD_SAME( ( objectPtr ).objectOwner, THREAD_SELF() ) ) 123 124 /* A macro to turn an abnormal status indicated in an object's flags into a 125 status code. The values are prioritised so that notinited > signalled > 126 busy */ 127 128 #define getObjectStatusValue( flags ) \ 129 ( ( flags & OBJECT_FLAG_NOTINITED ) ? CRYPT_ERROR_NOTINITED : \ 130 ( flags & OBJECT_FLAG_SIGNALLED ) ? CRYPT_ERROR_SIGNALLED : CRYPT_OK ) 131 132 /**************************************************************************** 133 * * 134 * Object Definitions and Information * 135 * * 136 ****************************************************************************/ 137 138 /* The information maintained by the kernel for each object */ 139 140 typedef struct { 141 /* Object type and value */ 142 OBJECT_TYPE type; /* Object type */ 143 OBJECT_SUBTYPE subType; /* Object subtype */ 144 void *objectPtr; /* Object data */ 145 int objectSize; /* Object data size */ 146 147 /* Object properties */ 148 int flags; /* Internal-only, locked, etc */ 149 int actionFlags; /* Permitted actions */ 150 int intRefCount, extRefCount;/* Number of int/ext refs.to this object */ 151 int lockCount; /* Message-processing lock recursion count */ 152 #ifdef USE_THREADS 153 THREAD_HANDLE lockOwner; /* Lock owner if lockCount > 0 */ 154 #endif /* USE_THREADS */ 155 int uniqueID; /* Unique ID for this object */ 156 /* time_t lastAccess; // Last access time */ 157 158 /* Object security properties */ 159 int forwardCount; /* Number of times ownership can be transferred */ 160 int usageCount; /* Number of times obj.can be used */ 161 #ifdef USE_THREADS 162 THREAD_HANDLE objectOwner; /* The object's owner */ 163 #endif /* USE_THREADS */ 164 165 /* Object methods */ 166 FNPTR_DECLARE( MESSAGE_FUNCTION, messageFunction ); 167 /* The object's message handler */ 168 169 /* Owning and dependent objects */ 170 CRYPT_USER owner; /* Owner object handle */ 171 CRYPT_HANDLE dependentObject; /* Dependent object (context or cert) */ 172 CRYPT_HANDLE dependentDevice; /* Dependent crypto device */ 173 } OBJECT_INFO; 174 175 /* The flags that apply to each object in the table */ 176 177 #define OBJECT_FLAG_NONE 0x0000 /* Non-flag */ 178 #define OBJECT_FLAG_INTERNAL 0x0001 /* Internal-use only */ 179 #define OBJECT_FLAG_NOTINITED 0x0002 /* Still being initialised */ 180 #define OBJECT_FLAG_HIGH 0x0004 /* In 'high' security state */ 181 #define OBJECT_FLAG_SIGNALLED 0x0008 /* In signalled state */ 182 #define OBJECT_FLAG_SECUREMALLOC 0x0010 /* Uses secure memory */ 183 #define OBJECT_FLAG_OWNED 0x0020 /* Object is bound to a thread */ 184 #define OBJECT_FLAG_ATTRLOCKED 0x0040 /* Security properties can't be modified */ 185 186 /* The flags that convey information about an object's status */ 187 188 #define OBJECT_FLAGMASK_STATUS \ 189 ( OBJECT_FLAG_NOTINITED | OBJECT_FLAG_SIGNALLED ) 190 191 /**************************************************************************** 192 * * 193 * Kernel Data Structures * 194 * * 195 ****************************************************************************/ 196 197 /* The object allocation state data. This controls the allocation of 198 handles to newly-created objects. The first NO_SYSTEM_OBJECTS handles 199 are system objects that exist with fixed handles, the remainder are 200 allocated pseudorandomly under the control of an LFSR */ 201 202 typedef struct { 203 long lfsrMask, lfsrPoly; /* LFSR state values */ 204 int objectHandle; /* Current object handle */ 205 } OBJECT_STATE_INFO; 206 207 /* A structure to store the details of a message sent to an object, and the 208 size of the message queue. This defines the maximum nesting depth of 209 messages sent by an object. Because of the way krnlSendMessage() handles 210 message processing, it's extremely difficult to ever have more than two 211 or three messages in the queue unless an object starts recursively 212 sending itself messages */ 213 214 typedef struct { 215 int objectHandle; /* Handle to send message to */ 216 const void *handlingInfoPtr;/* Message handling info */ 217 MESSAGE_TYPE message; 218 const void *messageDataPtr; 219 int messageValue; /* Message parameters */ 220 } MESSAGE_QUEUE_DATA; 221 222 #define MESSAGE_QUEUE_SIZE 16 223 224 /* Semaphores are one-shots, so that once set and cleared they can't be 225 reset. This is handled by enforcing the following state transitions: 226 227 Uninited -> Set | Clear 228 Set -> Set | Clear 229 Clear -> Clear 230 231 The handling is complicated somewhat by the fact that on some systems the 232 semaphore has to be explicitly deleted, but only the last thread to use 233 it can safely delete it. In order to handle this, we reference-count the 234 semaphore and let the last thread out delete it. In order to do this we 235 introduce an additional state, preClear, which indicates that while the 236 semaphore object is still present, the last thread out should delete it, 237 bringing it to the true clear state */ 238 239 typedef enum { 240 SEMAPHORE_STATE_UNINITED, 241 SEMAPHORE_STATE_CLEAR, 242 SEMAPHORE_STATE_PRECLEAR, 243 SEMAPHORE_STATE_SET, 244 SEMAPHORE_STATE_LAST 245 } SEMAPHORE_STATE; 246 247 typedef struct { 248 SEMAPHORE_STATE state; /* Semaphore state */ 249 MUTEX_HANDLE object; /* Handle to system synchronisation object */ 250 int refCount; /* Reference count for handle */ 251 } SEMAPHORE_INFO; 252 253 /* A structure to store the details of a thread */ 254 255 typedef struct { 256 FNPTR_DECLARE( THREAD_FUNCTION, threadFunction ); 257 /* Function to call from thread */ 258 THREAD_PARAMS threadParams; /* Thread function parameters */ 259 SEMAPHORE_TYPE semaphore; /* Optional semaphore to set */ 260 MUTEX_HANDLE syncHandle; /* Handle to use for thread sync */ 261 } THREAD_INFO; 262 263 /* When the kernel starts up and closes down it does so in a multi-stage 264 process that's equivalent to Unix runlevels. For the startup at the 265 first level the kernel data block and all kernel-level primitive 266 objects like mutexes have been initialised. 267 268 For the shutdown, at the first level all internal worker threads/tasks 269 must exist. At the next level all messages to objects except destroy 270 messages fail. At the final level all kernel-managed primitives such as 271 mutexes and semaphores are no longer available */ 272 273 typedef enum { 274 INIT_LEVEL_NONE, /* Uninitialised */ 275 INIT_LEVEL_KRNLDATA, /* Kernel data block initialised */ 276 INIT_LEVEL_FULL, /* Full initialisation */ 277 INIT_LEVEL_LAST /* Last possible init level */ 278 } INIT_LEVEL; 279 280 typedef enum { 281 SHUTDOWN_LEVEL_NONE, /* Normal operation */ 282 SHUTDOWN_LEVEL_THREADS, /* Internal threads must exit */ 283 SHUTDOWN_LEVEL_MESSAGES, /* Only destroy messages are valid */ 284 SHUTDOWN_LEVEL_MUTEXES, /* Kernel objects become invalid */ 285 SHUTDOWN_LEVEL_ALL, /* Complete shutdown */ 286 SHUTDOWN_LEVEL_LAST /* Last possible shutdown level */ 287 } SHUTDOWN_LEVEL; 288 289 /* The kernel data block, containing all variables used by the kernel. With 290 the exception of the special-case values at the start, all values in this 291 block should be set to use zero/NULL as their ground state (for example a 292 boolean variable should have a ground state of FALSE (zero) rather than 293 TRUE (nonzero)). 294 295 If the objectTable giant lock (or more strictly speaking monolithic lock, 296 since the kernel's message-handling is designed to be straight-line code 297 and so never blocks for any amount of time like the Linux giant lock can) 298 ever proves to be a problem then the solution would be to use lock 299 striping, dividing the load of the object table across NO_TABLE_LOCKS 300 locks. This gets a bit tricky because the object table is dynamically 301 resizeable, a basic mod_NO_TABLE_LOCKS strategy where every n-th entry 302 uses the same lock works but then we'd still need a giant lock to check 303 whether the table is being resized. To avoid this we can use a lock-free 304 implementation that operates by acquiring each lock (to make sure we have 305 complete control of the table), checking whether another thread beat us to 306 it, and if not resizing the table. The pseudocode for this is as 307 follows: 308 309 // Remember the original table size 310 const int oldSize = krnlData->objectTableSize; 311 312 // Acquire each lock 313 for( i = 0; i < NO_LOCKS; i++ ) 314 THREAD_LOCK( krnlData->locks[ i ] ); 315 316 // Check whether another thread beat us to the resize while we were 317 // acquiring locks 318 if( krnlData->objectTableSize != oldSize ) 319 { 320 // Unlock all the locks 321 // ... // 322 return; 323 } 324 325 // We hold all the locks and therefore have exclusive control of the 326 // table, resize it 327 // ... // 328 329 // Release each lock again // 330 for( i = 0; i < NO_LOCKS; i++ ) 331 THREAD_UNLOCK( krnlData->locks[ i ] ); 332 333 This is a conventional lock-free implementation of such an algorithm but 334 is conceptually ugly in that it accesses protected data outside the lock, 335 which will cause concurrency-checking tools to complain. Until the fast- 336 path through the kernel actually becomes a real bottleneck it's probably 337 best to leave well enough alone */ 338 339 typedef struct { 340 /* The kernel initialisation state and a lock to protect it. The 341 lock and shutdown level value are handled externally and aren't 342 cleared when the kernel data block as a whole is cleared. Note 343 that the shutdown level has to be before the lock so that we can 344 statically initialise the data with '{ 0 }', which won't work if 345 the lock data is non-scalar */ 346 SHUTDOWN_LEVEL shutdownLevel; /* Kernel shutdown level */ 347 #ifdef USE_THREADS 348 MUTEX_DECLARE_STORAGE( initialisation ); 349 #endif /* USE_THREADS */ 350 /* Everything from this point on is cleared at init and shutdown */ 351 int initLevel; /* Kernel initialisation level */ 352 353 /* The kernel object table and object table management info */ 354 OBJECT_INFO *objectTable; /* Pointer to object table */ 355 int objectTableSize; /* Current table size */ 356 int objectUniqueID; /* Unique ID for next object */ 357 OBJECT_STATE_INFO objectStateInfo; /* Object allocation state */ 358 #ifdef USE_THREADS 359 MUTEX_DECLARE_STORAGE( objectTable ); 360 #endif /* USE_THREADS */ 361 362 /* The kernel message dispatcher queue */ 363 BUFFER( MESSAGE_QUEUE_SIZE, queueEnd ) \ 364 MESSAGE_QUEUE_DATA messageQueue[ MESSAGE_QUEUE_SIZE + 8 ]; 365 int queueEnd; /* Points past last queue element */ 366 367 /* The kernel semaphores */ 368 BUFFER_FIXED( SEMAPHORE_LAST ) \ 369 SEMAPHORE_INFO semaphoreInfo[ SEMAPHORE_LAST + 8 ]; 370 #ifdef USE_THREADS 371 MUTEX_DECLARE_STORAGE( semaphore ); 372 #endif /* USE_THREADS */ 373 374 /* The kernel mutexes. Since mutexes usually aren't scalar values and 375 are declared and accessed via macros that manipulate various fields, 376 we have to declare a pile of them individually rather than using an 377 array of mutexes */ 378 #ifdef USE_THREADS 379 MUTEX_DECLARE_STORAGE( mutex1 ); 380 MUTEX_DECLARE_STORAGE( mutex2 ); 381 MUTEX_DECLARE_STORAGE( mutex3); 382 #endif /* USE_THREADS */ 383 384 /* The kernel thread data */ 385 #ifdef USE_THREADS 386 THREAD_INFO threadInfo; 387 #endif /* USE_THREADS */ 388 389 /* The kernel secure memory list and a lock to protect it */ 390 void *allocatedListHead, *allocatedListTail; 391 #ifdef USE_THREADS 392 MUTEX_DECLARE_STORAGE( allocation ); 393 #endif /* USE_THREADS */ 394 395 /* A marker for the end of the kernel data, used during init/shutdown */ 396 int endMarker; 397 } KERNEL_DATA; 398 399 /* When we start up and shut down the kernel, we need to clear the kernel 400 data. However, the init lock may have been set by an external management 401 function, so we can't clear that part of the kernel data. In addition, 402 on shutdown the shutdown level value must stay set so that any threads 403 still running will be forced to exit at the earliest possible instance, 404 and remain set after the shutdown has completed. To handle this, we use 405 the following macro to clear only the appropriate area of the kernel data 406 block */ 407 408 #ifdef __STDC__ 409 410 #include <stddef.h> /* For offsetof() */ 411 412 #define CLEAR_KERNEL_DATA() \ 413 zeroise( ( BYTE * ) krnlData + offsetof( KERNEL_DATA, initLevel ), \ 414 sizeof( KERNEL_DATA ) - offsetof( KERNEL_DATA, initLevel ) ) 415 #else 416 417 #define CLEAR_KERNEL_DATA() \ 418 assert( &krnlDataBlock.endMarker - \ 419 &krnlDataBlock.initLevel < sizeof( krnlDataBlock ) ); \ 420 zeroise( ( void * ) ( &krnlDataBlock.initLevel ), \ 421 &krnlDataBlock.endMarker - &krnlDataBlock.initLevel ) 422 #endif /* C89 compilers */ 423 424 /**************************************************************************** 425 * * 426 * ACL Functions * 427 * * 428 ****************************************************************************/ 429 430 /* Prototypes for functions in certm_acl.c */ 431 432 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 433 int preDispatchCheckCertMgmtAccess( IN_HANDLE const int objectHandle, 434 IN_MESSAGE const MESSAGE_TYPE message, 435 IN_BUFFER_C( sizeof( MESSAGE_CERTMGMT_INFO ) ) \ 436 const void *messageDataPtr, 437 IN_ENUM( CRYPT_CERTACTION ) \ 438 const int messageValue, 439 STDC_UNUSED const void *dummy ); 440 441 /* Prototypes for functions in key_acl.c */ 442 443 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 444 int preDispatchCheckKeysetAccess( IN_HANDLE const int objectHandle, 445 IN_MESSAGE const MESSAGE_TYPE message, 446 IN_BUFFER_C( sizeof( MESSAGE_KEYMGMT_INFO ) ) \ 447 const void *messageDataPtr, 448 IN_ENUM( KEYMGMT_ITEM ) const int messageValue, 449 STDC_UNUSED const void *dummy ); 450 451 /* Prototypes for functions in mech_acl.c */ 452 453 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 454 int preDispatchCheckMechanismWrapAccess( IN_HANDLE const int objectHandle, 455 IN_MESSAGE const MESSAGE_TYPE message, 456 IN_BUFFER_C( sizeof( MECHANISM_WRAP_INFO ) ) \ 457 TYPECAST( MECHANISM_WRAP_INFO * ) \ 458 const void *messageDataPtr, 459 IN_ENUM( MECHANISM ) const int messageValue, 460 STDC_UNUSED const void *dummy ); 461 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 462 int preDispatchCheckMechanismSignAccess( IN_HANDLE const int objectHandle, 463 IN_MESSAGE const MESSAGE_TYPE message, 464 IN_BUFFER_C( sizeof( MECHANISM_SIGN_INFO ) ) \ 465 TYPECAST( MECHANISM_SIGN_INFO * ) \ 466 const void *messageDataPtr, 467 IN_ENUM( MECHANISM ) const int messageValue, 468 STDC_UNUSED const void *dummy ); 469 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 470 int preDispatchCheckMechanismDeriveAccess( IN_HANDLE const int objectHandle, 471 IN_MESSAGE const MESSAGE_TYPE message, 472 IN_BUFFER_C( sizeof( MECHANISM_DERIVE_INFO ) ) \ 473 TYPECAST( MECHANISM_DERIVE_INFO * ) \ 474 const void *messageDataPtr, 475 IN_ENUM( MECHANISM ) const int messageValue, 476 STDC_UNUSED const void *dummy ); 477 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 478 int preDispatchCheckMechanismKDFAccess( IN_HANDLE const int objectHandle, 479 IN_MESSAGE const MESSAGE_TYPE message, 480 IN_BUFFER_C( sizeof( MECHANISM_KDF_INFO ) ) \ 481 TYPECAST( MECHANISM_KDF_INFO * ) \ 482 const void *messageDataPtr, 483 IN_ENUM( MECHANISM ) const int messageValue, 484 STDC_UNUSED const void *dummy ); 485 486 /* Prototypes for functions in msg_acl.c */ 487 488 CHECK_RETVAL_BOOL STDC_NONNULL_ARG( ( 1 ) ) \ 489 BOOLEAN paramAclConsistent( const PARAM_ACL *paramACL, 490 const BOOLEAN mustBeEmpty ); 491 CHECK_RETVAL \ 492 int preDispatchSignalDependentObjects( IN_HANDLE const int objectHandle, 493 STDC_UNUSED const MESSAGE_TYPE dummy1, 494 STDC_UNUSED const void *dummy2, 495 STDC_UNUSED const int dummy3, 496 STDC_UNUSED const void *dummy4 ); 497 CHECK_RETVAL STDC_NONNULL_ARG( ( 5 ) ) \ 498 int preDispatchCheckAttributeAccess( IN_HANDLE const int objectHandle, 499 IN_MESSAGE const MESSAGE_TYPE message, 500 IN_OPT const void *messageDataPtr, 501 IN_ATTRIBUTE const int messageValue, 502 IN TYPECAST( ATTRIBUTE_ACL * ) \ 503 const void *auxInfo ); 504 CHECK_RETVAL \ 505 int preDispatchCheckCompareParam( IN_HANDLE const int objectHandle, 506 IN_MESSAGE const MESSAGE_TYPE message, 507 const void *messageDataPtr, 508 IN_ENUM( MESSAGE_COMPARE ) const int messageValue, 509 STDC_UNUSED const void *dummy2 ); 510 CHECK_RETVAL \ 511 int preDispatchCheckCheckParam( IN_HANDLE const int objectHandle, 512 IN_MESSAGE const MESSAGE_TYPE message, 513 STDC_UNUSED const void *dummy1, 514 IN_ENUM( MESSAGE_CHECK ) const int messageValue, 515 STDC_UNUSED const void *dummy2 ); 516 CHECK_RETVAL \ 517 int preDispatchCheckActionAccess( IN_HANDLE const int objectHandle, 518 IN_MESSAGE const MESSAGE_TYPE message, 519 STDC_UNUSED const void *dummy1, 520 STDC_UNUSED const int dummy2, 521 STDC_UNUSED const void *dummy3 ); 522 CHECK_RETVAL \ 523 int preDispatchCheckState( IN_HANDLE const int objectHandle, 524 IN_MESSAGE const MESSAGE_TYPE message, 525 STDC_UNUSED const void *dummy1, 526 STDC_UNUSED const int dummy2, 527 STDC_UNUSED const void *dummy3 ); 528 CHECK_RETVAL \ 529 int preDispatchCheckParamHandleOpt( IN_HANDLE const int objectHandle, 530 IN_MESSAGE const MESSAGE_TYPE message, 531 STDC_UNUSED const void *dummy1, 532 const int messageValue, 533 IN TYPECAST( MESSAGE_ACL * ) \ 534 const void *auxInfo ); 535 CHECK_RETVAL \ 536 int preDispatchCheckStateParamHandle( IN_HANDLE const int objectHandle, 537 IN_MESSAGE const MESSAGE_TYPE message, 538 STDC_UNUSED const void *dummy1, 539 const int messageValue, 540 IN TYPECAST( MESSAGE_ACL * ) \ 541 const void *auxInfo ); 542 CHECK_RETVAL \ 543 int preDispatchCheckExportAccess( IN_HANDLE const int objectHandle, 544 IN_MESSAGE const MESSAGE_TYPE message, 545 const void *messageDataPtr, 546 IN_ENUM( CRYPT_CERTFORMAT ) const int messageValue, 547 STDC_UNUSED const void *dummy2 ); 548 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 549 int preDispatchCheckData( IN_HANDLE const int objectHandle, 550 IN_MESSAGE const MESSAGE_TYPE message, 551 IN_BUFFER_C( sizeof( MESSAGE_DATA ) ) \ 552 const void *messageDataPtr, 553 STDC_UNUSED const int dummy1, 554 STDC_UNUSED const void *dummy2 ); 555 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 556 int preDispatchCheckCreate( IN_HANDLE const int objectHandle, 557 IN_MESSAGE const MESSAGE_TYPE message, 558 IN_BUFFER_C( sizeof( MESSAGE_CREATEOBJECT_INFO ) ) \ 559 const void *messageDataPtr, 560 IN_ENUM( OBJECT_TYPE ) const int messageValue, 561 STDC_UNUSED const void *dummy ); 562 CHECK_RETVAL \ 563 int preDispatchCheckUserMgmtAccess( IN_HANDLE const int objectHandle, 564 IN_MESSAGE const MESSAGE_TYPE message, 565 STDC_UNUSED const void *dummy1, 566 IN_ENUM( MESSAGE_USERMGMT ) const int messageValue, 567 STDC_UNUSED const void *dummy2 ); 568 CHECK_RETVAL \ 569 int preDispatchCheckTrustMgmtAccess( IN_HANDLE const int objectHandle, 570 IN_MESSAGE const MESSAGE_TYPE message, 571 const void *messageDataPtr, 572 STDC_UNUSED const int messageValue, 573 STDC_UNUSED const void *dummy ); 574 CHECK_RETVAL \ 575 int postDispatchSignalDependentDevices( IN_HANDLE const int objectHandle, 576 STDC_UNUSED const MESSAGE_TYPE dummy1, 577 STDC_UNUSED const void *dummy2, 578 STDC_UNUSED const int dummy3, 579 STDC_UNUSED const void *dummy4 ); 580 CHECK_RETVAL \ 581 int postDispatchMakeObjectExternal( STDC_UNUSED const int dummy, 582 IN_MESSAGE const MESSAGE_TYPE message, 583 const void *messageDataPtr, 584 const int messageValue, 585 const void *auxInfo ); 586 CHECK_RETVAL \ 587 int postDispatchForwardToDependentObject( IN_HANDLE const int objectHandle, 588 IN_MESSAGE const MESSAGE_TYPE message, 589 STDC_UNUSED const void *dummy1, 590 IN_ENUM( MESSAGE_CHECK ) const int messageValue, 591 STDC_UNUSED const void *dummy2 ); 592 CHECK_RETVAL \ 593 int postDispatchUpdateUsageCount( IN_HANDLE const int objectHandle, 594 STDC_UNUSED const MESSAGE_TYPE dummy1, 595 STDC_UNUSED const void *dummy2, 596 STDC_UNUSED const int dummy3, 597 STDC_UNUSED const void *dummy4 ); 598 CHECK_RETVAL \ 599 int postDispatchChangeState( IN_HANDLE const int objectHandle, 600 STDC_UNUSED const MESSAGE_TYPE dummy1, 601 STDC_UNUSED const void *dummy2, 602 STDC_UNUSED const int dummy3, 603 STDC_UNUSED const void *dummy4 ); 604 CHECK_RETVAL \ 605 int postDispatchChangeStateOpt( IN_HANDLE const int objectHandle, 606 STDC_UNUSED const MESSAGE_TYPE dummy1, 607 STDC_UNUSED const void *dummy2, 608 const int messageValue, 609 IN TYPECAST( ATTRIBUTE_ACL * ) const void *auxInfo ); 610 CHECK_RETVAL \ 611 int postDispatchHandleZeroise( IN_HANDLE const int objectHandle, 612 IN_MESSAGE const MESSAGE_TYPE message, 613 STDC_UNUSED const void *dummy2, 614 IN_ENUM( MESSAGE_USERMGMT ) const int messageValue, 615 STDC_UNUSED const void *dummy3 ); 616 617 /**************************************************************************** 618 * * 619 * Kernel Functions * 620 * * 621 ****************************************************************************/ 622 623 /* Prototypes for functions in attr_acl.c */ 624 625 CHECK_RETVAL_PTR \ 626 const void *findAttributeACL( IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute, 627 const BOOLEAN isInternalMessage ); 628 629 /* Prototypes for functions in int_msg.c */ 630 631 CHECK_RETVAL \ 632 int convertIntToExtRef( IN_HANDLE const int objectHandle ); 633 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 634 int getPropertyAttribute( IN_HANDLE const int objectHandle, 635 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute, 636 OUT_BUFFER_FIXED_C( sizeof( int ) ) void *messageDataPtr ); 637 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 638 int setPropertyAttribute( IN_HANDLE const int objectHandle, 639 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute, 640 IN_BUFFER_C( sizeof( int ) ) void *messageDataPtr ); 641 CHECK_RETVAL \ 642 int incRefCount( IN_HANDLE const int objectHandle, 643 STDC_UNUSED const int dummy1, 644 STDC_UNUSED const void *dummy2, 645 const BOOLEAN isInternal ); 646 CHECK_RETVAL \ 647 int decRefCount( IN_HANDLE const int objectHandle, 648 STDC_UNUSED const int dummy1, 649 STDC_UNUSED const void *dummy2, 650 const BOOLEAN isInternal ); 651 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 652 int getDependentObject( IN_HANDLE const int objectHandle, 653 const int targetType, 654 IN_BUFFER_C( sizeof( int ) ) \ 655 const void *messageDataPtr, 656 /* This is a bit of a lie since we actually 657 return the dependent object through this 658 pointer, however making it non-const means 659 that we'd have to also un-const every other 660 use of this parameter in all other functions 661 accessed via this function pointer */ 662 STDC_UNUSED const BOOLEAN dummy ); 663 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 664 int setDependentObject( IN_HANDLE const int objectHandle, 665 IN_ENUM( SETDEP_OPTION ) const int option, 666 IN_BUFFER_C( sizeof( int ) ) \ 667 const void *messageDataPtr, 668 STDC_UNUSED const BOOLEAN dummy ); 669 CHECK_RETVAL \ 670 int cloneObject( IN_HANDLE const int objectHandle, 671 IN_HANDLE const int clonedObject, 672 STDC_UNUSED const void *dummy1, 673 STDC_UNUSED const BOOLEAN dummy2 ); 674 675 /* Prototypes for functions in sendmsg.c */ 676 677 CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \ 678 int checkTargetType( IN_HANDLE const CRYPT_HANDLE originalObjectHandle, 679 OUT_HANDLE_OPT CRYPT_HANDLE *targetObjectHandle, 680 const long targets ); 681 CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \ 682 int findTargetType( IN_HANDLE const CRYPT_HANDLE originalObjectHandle, 683 OUT_HANDLE_OPT CRYPT_HANDLE *targetObjectHandle, 684 const long targets ); 685 CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \ 686 int waitForObject( IN_HANDLE const int objectHandle, 687 OUT_PTR_COND OBJECT_INFO **objectInfoPtrPtr ); 688 #ifndef NDEBUG 689 const char *getObjectDescriptionNT( IN_HANDLE const int objectHandle ); 690 #endif /* NDEBUG */ 691 692 /* Prototypes for functions in objects.c */ 693 694 CHECK_RETVAL \ 695 int destroyObjectData( IN_HANDLE const int objectHandle ); 696 CHECK_RETVAL \ 697 int destroyObjects( void ); 698 699 /* Prototypes for functions in semaphore.c */ 700 701 void setSemaphore( IN_ENUM( SEMAPHORE ) const SEMAPHORE_TYPE semaphore, 702 const MUTEX_HANDLE object ); 703 void clearSemaphore( IN_ENUM( SEMAPHORE ) const SEMAPHORE_TYPE semaphore ); 704 705 /* Init/shutdown functions for each kernel module */ 706 707 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 708 int initAllocation( INOUT KERNEL_DATA *krnlDataPtr ); 709 void endAllocation( void ); 710 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 711 int initAttributeACL( INOUT KERNEL_DATA *krnlDataPtr ); 712 void endAttributeACL( void ); 713 #if defined( USE_CERTIFICATES ) && defined( USE_KEYSETS ) 714 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 715 int initCertMgmtACL( INOUT KERNEL_DATA *krnlDataPtr ); 716 void endCertMgmtACL( void ); 717 #else 718 #define initCertMgmtACL( krnlDataPtr ) CRYPT_OK 719 #define endCertMgmtACL() 720 #endif /* USE_CERTIFICATES && USE_KEYSETS */ 721 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 722 int initInternalMsgs( INOUT KERNEL_DATA *krnlDataPtr ); 723 void endInternalMsgs( void ); 724 #ifdef USE_KEYSETS 725 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 726 int initKeymgmtACL( INOUT KERNEL_DATA *krnlDataPtr ); 727 void endKeymgmtACL( void ); 728 #else 729 #define initKeymgmtACL( krnlDataPtr ) CRYPT_OK 730 #define endKeymgmtACL() 731 #endif /* USE_KEYSETS */ 732 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 733 int initMechanismACL( INOUT KERNEL_DATA *krnlDataPtr ); 734 void endMechanismACL( void ); 735 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 736 int initMessageACL( INOUT KERNEL_DATA *krnlDataPtr ); 737 void endMessageACL( void ); 738 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 739 int initObjects( INOUT KERNEL_DATA *krnlDataPtr ); 740 void endObjects( void ); 741 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 742 int initObjectAltAccess( INOUT KERNEL_DATA *krnlDataPtr ); 743 void endObjectAltAccess( void ); 744 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 745 int initSemaphores( INOUT KERNEL_DATA *krnlDataPtr ); 746 void endSemaphores( void ); 747 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 748 int initSendMessage( INOUT KERNEL_DATA *krnlDataPtr ); 749 void endSendMessage( void ); 750 751 #endif /* _KERNEL_DEFINED */ 752