1 /**************************************************************************** 2 * * 3 * cryptlib Internal API Header File * 4 * Copyright Peter Gutmann 1992-2014 * 5 * * 6 ****************************************************************************/ 7 8 #ifndef _INTAPI_DEFINED 9 10 #define _INTAPI_DEFINED 11 12 /* Copy a string attribute to external storage, with various range checks 13 to follow the cryptlib external API semantics. There are two variants 14 of this function depending on whether the result parameters are passed 15 in as discrete values or packed into a MESSAGE_DATA struct */ 16 17 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 18 int attributeCopy( INOUT MESSAGE_DATA *msgData, 19 IN_BUFFER( attributeLength ) const void *attribute, 20 IN_LENGTH_SHORT_Z const int attributeLength ); 21 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 22 int attributeCopyParams( OUT_BUFFER_OPT( destMaxLength, \ 23 *destLength ) void *dest, 24 IN_LENGTH_SHORT_Z const int destMaxLength, 25 OUT_LENGTH_BOUNDED_SHORT_Z( destMaxLength ) \ 26 int *destLength, 27 IN_BUFFER_OPT( sourceLength ) const void *source, 28 IN_LENGTH_SHORT_Z const int sourceLength ); 29 30 /* Check whether a password is valid or not. Currently this just checks that 31 it contains at least one character, but stronger checking can be 32 substituted if required */ 33 34 #ifdef UNICODE_CHARS 35 #define isBadPassword( password ) \ 36 ( !isReadPtrConst( password, sizeof( wchar_t ) ) || \ 37 ( wcslen( password ) < 1 ) ) 38 #else 39 #define isBadPassword( password ) \ 40 ( !isReadPtrConst( password, 1 ) || \ 41 ( strlen( password ) < 1 ) ) 42 #endif /* Unicode vs. ASCII environments */ 43 44 /* Check whether a given algorithm is available for use. This is performed 45 frequently enough that we have a special krnlSendMessage() wrapper 46 function for it rather than having to explicitly query the system 47 object */ 48 49 CHECK_RETVAL_BOOL \ 50 BOOLEAN algoAvailable( IN_ALGO const CRYPT_ALGO_TYPE cryptAlgo ); 51 52 /* For a given algorithm pair, check whether the first is stronger than the 53 second */ 54 55 CHECK_RETVAL_BOOL \ 56 BOOLEAN isStrongerHash( IN_ALGO const CRYPT_ALGO_TYPE algorithm1, 57 IN_ALGO const CRYPT_ALGO_TYPE algorithm2 ); 58 59 /* Check that a string has at least a minimal amount of entropy. This is 60 used as a sanity-check on (supposedly) random keys before we load them */ 61 62 CHECK_RETVAL_BOOL STDC_NONNULL_ARG( ( 1 ) ) \ 63 BOOLEAN checkEntropy( IN_BUFFER( dataLength ) const BYTE *data, 64 IN_LENGTH_SHORT_MIN( MIN_KEYSIZE ) const int dataLength ); 65 66 /* Return a random small integer, used to perform lightweight randomisation 67 of various algorithms in order to make DoS attacks harder */ 68 69 CHECK_RETVAL_RANGE_NOERROR( 0, 32767 ) \ 70 int getRandomInteger( void ); 71 72 /* Map one value to another, used to map values from one representation 73 (e.g. PGP algorithms or HMAC algorithms) to another (cryptlib algorithms 74 or the underlying hash used for the HMAC algorithm) */ 75 76 typedef struct { 77 int source, destination; 78 } MAP_TABLE; 79 80 CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3 ) ) \ 81 int mapValue( IN_INT_SHORT_Z const int srcValue, 82 OUT_INT_SHORT_Z int *destValue, 83 IN_ARRAY( mapTblSize ) const MAP_TABLE *mapTbl, 84 IN_LENGTH_SHORT const int mapTblSize ); 85 86 /* Read a line of text from a stream. The caller passes in a character-read 87 function callback that returns the next character from a supplied input 88 stream, and readTextLine() uses it to fetch the next line of input up to 89 an EOL. The localError flag is set when the returned error code was 90 generated by readTextLine() itself, rather than being passed up from the 91 character-read function. This allows the caller to report the errors 92 differently, for example a data-formatting error vs. a network I/O error. 93 94 It would be nice if we could declare READCHARFUNCTION as taking a 95 STREAM * but this header gets included long before the stream header does 96 so the STREAM structure isn't visible at this point */ 97 98 #if defined( USE_HTTP ) || defined( USE_BASE64 ) || defined( USE_SSH ) 99 100 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 101 int ( *READCHAR_FUNCTION )( INOUT void *streamPtr ); 102 103 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3, 5 ) ) \ 104 int readTextLine( READCHAR_FUNCTION readCharFunction, 105 INOUT void *streamPtr, 106 OUT_BUFFER( lineBufferMaxLen, *lineBufferSize ) \ 107 char *lineBuffer, 108 IN_LENGTH_SHORT_MIN( 16 ) const int lineBufferMaxLen, 109 OUT_RANGE( 0, lineBufferMaxLen ) int *lineBufferSize, 110 OUT_OPT_BOOL BOOLEAN *localError, 111 const BOOLEAN allowContinuation ); 112 #endif /* USE_HTTP || USE_BASE64 || USE_SSH */ 113 114 /**************************************************************************** 115 * * 116 * OS-specific Functions * 117 * * 118 ****************************************************************************/ 119 120 /* Get OS-specific values */ 121 122 #if defined( __WIN32__ ) || defined( __WINCE__ ) 123 typedef enum { 124 SYSVAR_NONE, /* No system variable */ 125 #if VC_LT_2005( _MSC_VER ) 126 SYSVAR_OSMAJOR, /* OS major version number */ 127 SYSVAR_OSMINOR, /* OS minor version number */ 128 #endif /* VC++ < 2005 */ 129 SYSVAR_HWCAP, /* Hardware crypto capabilities */ 130 SYSVAR_PAGESIZE, /* System page size */ 131 SYSVAR_LAST /* Last valid system variable type */ 132 } SYSVAR_TYPE; 133 #elif defined( __UNIX__ ) 134 typedef enum { 135 SYSVAR_NONE, /* No system variable */ 136 SYSVAR_HWCAP, /* Hardware crypto capabilities */ 137 SYSVAR_PAGESIZE, /* System page size */ 138 SYSVAR_LAST /* Last valid system variable type */ 139 } SYSVAR_TYPE; 140 #else 141 typedef enum { 142 SYSVAR_NONE, /* No system variable */ 143 SYSVAR_HWCAP, /* Hardware crypto capabilities */ 144 SYSVAR_LAST /* Last valid system variable type */ 145 } SYSVAR_TYPE; 146 #endif /* OS-specific system variable types */ 147 148 CHECK_RETVAL \ 149 int initSysVars( void ); 150 CHECK_RETVAL \ 151 int getSysVar( IN_ENUM( SYSVAR ) const SYSVAR_TYPE type ); 152 153 /* Flags for SYSVAR_HWCAP capabilities */ 154 155 #define HWCAP_FLAG_NONE 0x00 /* No special HW capabilities */ 156 #define HWCAP_FLAG_RDTSC 0x01 /* x86 RDTSC instruction support */ 157 #define HWCAP_FLAG_XSTORE 0x02 /* VIA XSTORE instruction support */ 158 #define HWCAP_FLAG_XCRYPT 0x04 /* VIA XCRYPT instruction support */ 159 #define HWCAP_FLAG_XSHA 0x08 /* VIA XSHA instruction support */ 160 #define HWCAP_FLAG_MONTMUL 0x10 /* VIA bignum instruction support */ 161 #define HWCAP_FLAG_TRNG 0x20 /* AMD Geode LX TRNG MSR support */ 162 #define HWCAP_FLAG_AES 0x40 /* Intel AES instruction support */ 163 #define HWCAP_FLAG_RDRAND 0x80 /* Intel RDRAND instruction support */ 164 #define HWCAP_FLAG_MAX 0xFF /* Maximum possible flag value */ 165 #define HWCAP_FLAG_LAST HWCAP_FLAG_MAX /* For range checking */ 166 167 /* cryptlib-specific feature flags used in the keyFeatures extension in 168 certificates */ 169 170 #define KEYFEATURE_FLAG_NONE 0x00 /* No special key features */ 171 #define KEYFEATURE_FLAG_RESERVED 0x01 /* Reserved for backwards-compat.*/ 172 #define KEYFEATURE_FLAG_RAISSUED 0x02 /* Cert.was issued via an RA */ 173 #define KEYFEATURE_FLAG_MAX 0x03 /* Maximum possible flag value */ 174 175 /* Windows helper functions */ 176 177 #ifdef __WINDOWS__ 178 /* Most versions of Windows support ACL-based access control mechanisms 179 for system objects, so when we create objects such as files and threads 180 we give them an ACL that allows only the creator access. The following 181 functions return the security info needed when creating objects */ 182 #ifdef __WIN32__ 183 CHECK_RETVAL_PTR \ 184 void *initACLInfo( const int access ); 185 void *getACLInfo( INOUT_OPT void *securityInfoPtr ); 186 STDC_NONNULL_ARG( ( 1 ) ) \ 187 void freeACLInfo( IN void *securityInfoPtr ); 188 #else 189 #define initACLInfo( x ) NULL 190 #define getACLInfo( x ) NULL 191 #define freeACLInfo( x ) 192 #endif /* __WIN32__ */ 193 194 /* Safely load a DLL while avoid, if possible, malicious path-specific 195 trickery */ 196 HMODULE WINAPI SafeLoadLibrary( IN_STRING LPCTSTR lpFileName ); 197 #endif /* __WINDOWS__ */ 198 199 /**************************************************************************** 200 * * 201 * String Functions * 202 * * 203 ****************************************************************************/ 204 205 /* Check whether a value is a valid text character or not. In almost all 206 cases for standard ASCII the isprint() restricts the input range to 207 0x20 ... 0x7E, we perform the explicit range check beforehand mostly to 208 ensure that the input range to isprint() isn't exceeded in cases where 209 it's implemented as a straight unchecked table lookup */ 210 211 #define isValidTextChar( value ) ( value >= 0x08 && value <= 0x7E && \ 212 isPrint( value ) ) 213 214 /* Compare two strings in a case-insensitive manner for those systems that 215 don't have this function. These are then mapped to the abstract 216 functions strCompare() (with length) and strCompareZ() (zero- 217 terminated) */ 218 219 #if defined( __UNIX__ ) && !( defined( __CYGWIN__ ) ) 220 #if defined( __TANDEM_NSK__ ) || defined( __TANDEM_OSS__ ) 221 #include <strings.h> 222 #endif /* Tandem */ 223 #define strnicmp strncasecmp 224 #define stricmp strcasecmp 225 #elif defined( __WINCE__ ) 226 #define strnicmp _strnicmp 227 #define stricmp _stricmp 228 #elif defined( _MSC_VER ) 229 /* VC++ 8 and up warn about these being deprecated Posix functions and 230 require the ANSI/ISO-conformant _strXcmp */ 231 #if _MSC_VER >= 1300 232 #define strnicmp _strnicmp 233 #define stricmp _stricmp 234 #endif /* VC++ >= 8 */ 235 #elif defined( __ECOS__ ) || defined( __iOS__ ) 236 #define strnicmp strncasecmp 237 #define stricmp strcasecmp 238 #elif defined __PALMOS__ 239 /* PalmOS has strcasecmp()/strncasecmp() but these aren't i18n-aware so we 240 have to use a system function instead */ 241 #include <StringMgr.h> 242 243 #define strnicmp StrNCaselessCompare 244 #define stricmp StrCaselessCompare 245 #elif defined( __TI_COMPILER_VERSION__ ) 246 #include <strings.h> 247 #define strnicmp strncasecmp 248 #define stricmp strcasecmp 249 #elif defined( __BEOS__ ) || defined( __SMX__ ) || \ 250 defined( __SYMBIAN32__ ) || defined( __VxWorks___ ) 251 int strnicmp( const char *src, const char *dest, const int length ); 252 int stricmp( const char *src, const char *dest ); 253 254 /* Make sure that we provide our own versions of the functions */ 255 #define NO_NATIVE_STRICMP 256 #endif /* OS-specific case-insensitive string compares */ 257 258 /* Sanitise a string before passing it back to the user. This is used to 259 clear potential problem characters (for example control characters) 260 from strings passed back from untrusted sources. The function returns a 261 pointer to the string to allow it to be used in the form 262 printf( "..%s..", sanitiseString( string, strLen ) ). In addition it 263 formats the data to fit a fixed-length buffer. If the string is longer 264 than the indicated buffer size it appends a '[...]' at the end of the 265 buffer to indicate that further data was truncated. 266 267 To avoid lots of problems with compilers and static analysers, the input 268 argument is specified as a 'void *' rather than a 'BYTE *' because the 269 fact that it converts a 'BYTE *' into a 'char *' gives these tools 270 headaches */ 271 272 STDC_NONNULL_ARG( ( 1 ) ) \ 273 char *sanitiseString( INOUT_BUFFER( strMaxLen, strLen ) void *string, 274 IN_LENGTH_SHORT const int strMaxLen, 275 IN_LENGTH_SHORT const int strLen ); 276 277 /* Perform various string-processing operations */ 278 279 CHECK_RETVAL_STRINGOP STDC_NONNULL_ARG( ( 1 ) ) \ 280 int strFindCh( IN_BUFFER( strLen ) const char *str, 281 IN_LENGTH_SHORT const int strLen, 282 IN_CHAR const int findCh ); 283 CHECK_RETVAL_STRINGOP STDC_NONNULL_ARG( ( 1, 3 ) ) \ 284 int strFindStr( IN_BUFFER( strLen ) const char *str, 285 IN_LENGTH_SHORT const int strLen, 286 IN_BUFFER( findStrLen ) const char *findStr, 287 IN_LENGTH_SHORT const int findStrLen ); 288 CHECK_RETVAL_STRINGOP STDC_NONNULL_ARG( ( 1 ) ) \ 289 int strSkipWhitespace( IN_BUFFER( strLen ) const char *str, 290 IN_LENGTH_SHORT const int strLen ); 291 CHECK_RETVAL_STRINGOP STDC_NONNULL_ARG( ( 1 ) ) \ 292 int strSkipNonWhitespace( IN_BUFFER( strLen ) const char *str, 293 IN_LENGTH_SHORT const int strLen ); 294 CHECK_RETVAL_STRINGOP STDC_NONNULL_ARG( ( 1, 2 ) ) \ 295 int strStripWhitespace( OUT_PTR_COND const char **newStringPtr, 296 IN_BUFFER( strLen ) const char *string, 297 IN_LENGTH_SHORT const int strLen ); 298 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 299 int strExtract( OUT_PTR_COND const char **newStringPtr, 300 IN_BUFFER( strLen ) const char *string, 301 IN_LENGTH_SHORT_Z const int startOffset, 302 IN_LENGTH_SHORT const int strLen ); 303 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 304 int strGetNumeric( IN_BUFFER( strLen ) const char *str, 305 IN_LENGTH_SHORT const int strLen, 306 OUT_INT_Z int *numericValue, 307 IN_RANGE( 0, 100 ) const int minValue, 308 IN_RANGE( minValue, MAX_INTLENGTH ) const int maxValue ); 309 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 310 int strGetHex( IN_BUFFER( strLen ) const char *str, 311 IN_LENGTH_SHORT const int strLen, 312 OUT_INT_Z int *numericValue, 313 IN_RANGE( 0, 100 ) const int minValue, 314 IN_RANGE( minValue, MAX_INTLENGTH ) const int maxValue ); 315 CHECK_RETVAL_BOOL STDC_NONNULL_ARG( ( 1 ) ) \ 316 BOOLEAN strIsPrintable( IN_BUFFER( strLen ) const void *str, 317 IN_LENGTH_SHORT const int strLen ); 318 319 /**************************************************************************** 320 * * 321 * Error-handling Functions * 322 * * 323 ****************************************************************************/ 324 325 /* Handle internal errors. These follow a fixed pattern of "throw an 326 exception, return an internal-error code" (with a few exceptions for 327 functions that return a pointer or void). There's also a 328 retExt_IntError() define in int_api.h for handling extended error 329 returns */ 330 331 #define INTERNAL_ERROR 0 /* Symbolic define for assertion failure */ 332 #define retIntError() \ 333 { \ 334 assert( INTERNAL_ERROR ); \ 335 return( CRYPT_ERROR_INTERNAL ); \ 336 } 337 #define retIntError_Null() \ 338 { \ 339 assert( INTERNAL_ERROR ); \ 340 return( NULL ); \ 341 } 342 #define retIntError_Boolean() \ 343 { \ 344 assert( INTERNAL_ERROR ); \ 345 return( FALSE ); \ 346 } 347 #define retIntError_Void() \ 348 { \ 349 assert( INTERNAL_ERROR ); \ 350 return; \ 351 } 352 #define retIntError_Ext( value ) \ 353 { \ 354 assert( INTERNAL_ERROR ); \ 355 return( value ); \ 356 } 357 #define retIntError_Stream( stream ) \ 358 { \ 359 assert( INTERNAL_ERROR ); \ 360 return( sSetError( stream, CRYPT_ERROR_INTERNAL ) ); \ 361 } 362 363 /* Check for an internal error. This is required in situations where 364 supplementary information is returned as a by-reference parameter but 365 we can't rely on the value of the by-reference parameter because it 366 isn't reset to its default value until the internal-error checks have 367 been performed. For example if we have a function: 368 369 CHECK_RETVAL int foo( IN_HANDLE const CRYPT_HANDLE cryptHandle, 370 OUT_INT_OPT int *errorInfo ) 371 { 372 REQUIRES( isValidHandle( cryptHandle ) ); 373 374 // Clear return value 375 *errorInfo = CRYPT_OK; 376 377 //... 378 } 379 380 which is called as: 381 382 status = foo( cryptHandle, &errorInfo ); 383 if( cryptStatusError( status ) ) 384 { 385 switch( errorInfo ) 386 { 387 // ... 388 } 389 } 390 391 then we can't act on errorInfo if the returned status is 392 CRYPT_ERROR_INTERNAL because the exception may have been triggered 393 before the return value was cleared. 394 395 An alternative option to this explicit check would be to switch the order 396 of the exception-throwing checks and the clearing of return values, but 397 this both doesn't work in the case of wrapper functions where the check 398 is performed in the wrapper but the return value isn't cleared until the 399 actual function, and creates nasty catch-22's where we can't check the 400 validity of the by-reference parameter until it's already been written 401 to: 402 403 // Clear return value 404 *errorInfo = CRYPT_OK; 405 406 REQUIRES( errorInfo != NULL ); 407 408 Both options are ugly and error-prone, but having a requirement for the 409 caller to check for isInternalError() is relatively rare so it's the 410 one that we use here */ 411 412 #define isInternalError( status ) ( ( status ) == CRYPT_ERROR_INTERNAL ) 413 414 /* Symbolic defines to handle design-by-contract predicates */ 415 416 #define REQUIRES( x ) if( !( x ) ) retIntError() 417 #define REQUIRES_N( x ) if( !( x ) ) retIntError_Null() 418 #define REQUIRES_B( x ) if( !( x ) ) retIntError_Boolean() 419 #define REQUIRES_V( x ) if( !( x ) ) retIntError_Void() 420 #define REQUIRES_EXT( x, y ) if( !( x ) ) retIntError_Ext( y ) 421 #define REQUIRES_S( x ) if( !( x ) ) retIntError_Stream( stream ) 422 423 #define ENSURES REQUIRES 424 #define ENSURES_N REQUIRES_N 425 #define ENSURES_B REQUIRES_B 426 #define ENSURES_V REQUIRES_V 427 #define ENSURES_EXT REQUIRES_EXT 428 #define ENSURES_S REQUIRES_S 429 430 /* A special-case form of the REQUIRES() predicate that's used in functions 431 that acquire a mutex. There are two versions of this, one for cryptlib 432 kernel mutexes, denoted by KRNLMUTEX, and one for native mutexes that are 433 only visible inside the kernel, denoted by MUTEX */ 434 435 #define REQUIRES_KRNLMUTEX( x, mutex ) \ 436 if( !( x ) ) \ 437 { \ 438 krnlExitMutex( mutex ); \ 439 retIntError(); \ 440 } 441 #define ENSURES_KRNLMUTEX \ 442 REQUIRES_KRNLMUTEX 443 444 #define REQUIRES_MUTEX( x, mutex ) \ 445 if( !( x ) ) \ 446 { \ 447 MUTEX_UNLOCK( mutex ); \ 448 retIntError(); \ 449 } 450 #define ENSURES_MUTEX REQUIRES_MUTEX 451 452 /* A struct to store extended error information. This provides error info 453 above and beyond that provided by cryptlib error codes. Since this 454 consumes a fair amount of memory, we make it conditional on USE_ERRMSGS 455 being defined and provide an alternative errorcode-only version if this 456 isn't enabled */ 457 458 #ifdef USE_ERRMSGS 459 460 typedef struct { 461 BUFFER( MAX_ERRMSG_SIZE, errorStringLength ) \ 462 char errorString[ MAX_ERRMSG_SIZE + 8 ]; 463 int errorStringLength; /* Error message */ 464 } ERROR_INFO; 465 #else 466 467 typedef struct { 468 int errorCode; /* Low-level error code */ 469 } ERROR_INFO; 470 471 #endif /* USE_ERRMSGS */ 472 473 /* Prototypes for various extended error-handling functions. retExt() 474 returns after setting extended error information for the object. 475 476 In addition to the standard retExt() we also have several extended-form 477 versions of the function that take additional error info parameters: 478 479 retExtArgFn() is identical to ertExtFn() but passes through 480 CRYPT_ARGERROR_xxx values, which are normally only present as leaked 481 status codes from lower-level calls (and even then they should only 482 ever occur in 'can't-occur' error situations). 483 484 retExtObj() takes a handle to an object that may provide additional 485 error information, used when (for example) an operation references 486 a keyset, where the keyset also contains extended error information. 487 488 retExtStr() takes an additional error string pointer and is used in the 489 same way as retExtErr(). 490 491 retExtErr() takes a pointer to existing error info, used when (for 492 example) a lower-level function has provided very low-level error 493 information but the higher-level function that calls it needs to 494 provide its own more general error information on top of it. This 495 function is typically used when the caller wants to convert 496 something like "Low-level error string" into "High-level error 497 string: Low-level error string". errorInfoPtr and 498 existingErrorInfoPtr can point to the same location. 499 retExtErrAlt() is a variation of the above that appends the additional 500 error information rather than prepending it */ 501 502 #ifdef USE_ERRMSGS 503 504 STDC_NONNULL_ARG( ( 1 ) ) \ 505 void clearErrorString( OUT ERROR_INFO *errorInfoPtr ); 506 STDC_NONNULL_ARG( ( 1 ) ) \ 507 int readErrorInfo( OUT ERROR_INFO *errorInfo, 508 IN_HANDLE const CRYPT_HANDLE objectHandle ); 509 STDC_NONNULL_ARG( ( 1, 2 ) ) \ 510 void setErrorString( OUT ERROR_INFO *errorInfoPtr, 511 IN_BUFFER( stringLength ) const char *string, 512 IN_LENGTH_ERRORMESSAGE const int stringLength ); 513 CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3 ) ) STDC_PRINTF_FN( 3, 4 ) \ 514 int retExtFn( IN_ERROR const int status, 515 OUT ERROR_INFO *errorInfoPtr, 516 FORMAT_STRING const char *format, ... ); 517 CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3 ) ) STDC_PRINTF_FN( 3, 4 ) \ 518 int retExtArgFn( IN_ERROR const int status, 519 OUT ERROR_INFO *errorInfoPtr, 520 FORMAT_STRING const char *format, ... ); 521 CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 4 ) ) STDC_PRINTF_FN( 4, 5 ) \ 522 int retExtObjFn( IN_ERROR const int status, 523 OUT ERROR_INFO *errorInfoPtr, 524 IN_HANDLE const CRYPT_HANDLE extErrorObject, 525 FORMAT_STRING const char *format, ... ); 526 CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3, 5 ) ) STDC_PRINTF_FN( 5, 6 ) \ 527 int retExtStrFn( IN_ERROR const int status, 528 OUT ERROR_INFO *errorInfoPtr, 529 IN_BUFFER( extErrorStringLength ) const char *extErrorString, 530 IN_LENGTH_ERRORMESSAGE const int extErrorStringLength, 531 FORMAT_STRING const char *format, ... ); 532 CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3, 4 ) ) STDC_PRINTF_FN( 4, 5 ) \ 533 int retExtErrFn( IN_ERROR const int status, 534 OUT ERROR_INFO *errorInfoPtr, 535 const ERROR_INFO *existingErrorInfoPtr, 536 FORMAT_STRING const char *format, ... ); 537 CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3 ) ) STDC_PRINTF_FN( 3, 4 ) \ 538 int retExtErrAltFn( IN_ERROR const int status, 539 INOUT ERROR_INFO *errorInfoPtr, 540 FORMAT_STRING const char *format, ... ); 541 #else 542 #define clearErrorString( errorInfoPtr ) 543 #define readErrorInfo( errorInfoPtr, objectHandle ) 544 #define setErrorString( errorInfoPtr, string, stringLength ); 545 #endif /* USE_ERRMSGS */ 546 STDC_NONNULL_ARG( ( 1, 2 ) ) \ 547 void copyErrorInfo( OUT ERROR_INFO *destErrorInfoPtr, 548 const ERROR_INFO *srcErrorInfoPtr ); 549 550 #ifdef USE_ERRMSGS 551 #define retExt( status, extStatus ) return retExtFn extStatus 552 #define retExtArg( status, extStatus ) return retExtArgFn extStatus 553 #define retExtObj( status, extStatus ) return retExtObjFn extStatus 554 #define retExtStr( status, extStatus ) return retExtStrFn extStatus 555 #define retExtErr( status, extStatus ) return retExtErrFn extStatus 556 #define retExtErrAlt( status, extStatus ) return retExtErrAltFn extStatus 557 #define retExt_IntError( status, extStatus ) \ 558 { \ 559 assert( INTERNAL_ERROR ); \ 560 return retExtFn extStatus; \ 561 } 562 #else 563 /* We're not using extended error information, just return the basic 564 status code */ 565 #define retExt( status, extStatus ) return status 566 #define retExtArg( status, extStatus ) return status 567 #define retExtObj( status, extStatus ) return status 568 #define retExtStr( status, extStatus ) return status 569 #define retExtErr( status, extStatus ) return status 570 #define retExtErrAlt( status, extStatus ) return status 571 #define retExt_IntError( status, extStatus ) \ 572 { \ 573 assert( INTERNAL_ERROR ); \ 574 return( status ); \ 575 } 576 #endif /* USE_ERRMSGS */ 577 578 /* Since this function works for all object types, we have to extract the 579 error info pointer from the object-specific data. The following defines 580 do this for each object type */ 581 582 #define ENVELOPE_ERRINFO &envelopeInfoPtr->errorInfo 583 #define KEYSET_ERRINFO &keysetInfoPtr->errorInfo 584 #define SESSION_ERRINFO &sessionInfoPtr->errorInfo 585 #define STREAM_ERRINFO stream->errorInfo 586 #define NETSTREAM_ERRINFO &netStream->errorInfo 587 588 /**************************************************************************** 589 * * 590 * Data Encode/Decode Functions * 591 * * 592 ****************************************************************************/ 593 594 /* Special-case certificate function that works somewhat like the import 595 cert messages but reads certs by sending get_next_cert messages to the 596 message source and provides extended control over the format of the 597 imported object. This isn't strictly speaking a certificate function but 598 the best (meaning least inappropriate) place to put it is with the cert- 599 management code */ 600 601 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \ 602 int iCryptImportCertIndirect( OUT_HANDLE_OPT CRYPT_CERTIFICATE *iCertificate, 603 IN_HANDLE const CRYPT_HANDLE iCertSource, 604 IN_ENUM( CRYPT_KEYID ) \ 605 const CRYPT_KEYID_TYPE keyIDtype, 606 IN_BUFFER( keyIDlength ) const void *keyID, 607 IN_LENGTH_SHORT const int keyIDlength, 608 IN_FLAGS_Z( KEYMGMT ) const int options ); 609 610 /* Read a public key from an X.509 SubjectPublicKeyInfo record, creating the 611 context necessary to contain it in the process. This is used by a variety 612 of modules including certificate-management, keyset, and crypto device. 613 614 The use of the void * instead of STREAM * is necessary because the STREAM 615 type isn't visible at the global level */ 616 617 #ifdef USE_INT_ASN1 618 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 619 int iCryptReadSubjectPublicKey( INOUT TYPECAST( STREAM * ) void *streamPtr, 620 OUT_HANDLE_OPT CRYPT_CONTEXT *iPubkeyContext, 621 IN_HANDLE const CRYPT_DEVICE iCreatorHandle, 622 const BOOLEAN deferredLoad ); 623 #endif /* USE_INT_ASN1 */ 624 625 /* Get information on encoded object data. The first parameter for this 626 function is actually a STREAM *, but we can't use this here since 627 STREAM * hasn't been defined yet */ 628 629 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 630 int queryAsn1Object( INOUT void *streamPtr, OUT QUERY_INFO *queryInfo ); 631 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 632 int queryPgpObject( INOUT void *streamPtr, OUT QUERY_INFO *queryInfo ); 633 634 /* Export/import data to/from a stream without the overhead of going via a 635 dynbuf. The first parameter for these functions is actually a STREAM *, 636 but we can't use this here since STREAM * hasn't been defined yet */ 637 638 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 639 int exportAttributeToStream( INOUT void *streamPtr, 640 IN_HANDLE const CRYPT_HANDLE cryptHandle, 641 IN_ATTRIBUTE \ 642 const CRYPT_ATTRIBUTE_TYPE attributeType ); 643 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 644 int exportVarsizeAttributeToStream( INOUT void *streamPtr, 645 IN_HANDLE const CRYPT_HANDLE cryptHandle, 646 IN_LENGTH_FIXED( CRYPT_IATTRIBUTE_RANDOM_NONCE ) \ 647 const CRYPT_ATTRIBUTE_TYPE attributeType, 648 IN_RANGE( 8, 1024 ) \ 649 const int attributeDataLength ); 650 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 651 int exportCertToStream( INOUT void *streamPtr, 652 IN_HANDLE const CRYPT_CERTIFICATE cryptCertificate, 653 IN_ENUM( CRYPT_CERTFORMAT ) \ 654 const CRYPT_CERTFORMAT_TYPE certFormatType ); 655 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 656 int importCertFromStream( INOUT void *streamPtr, 657 OUT_HANDLE_OPT CRYPT_CERTIFICATE *cryptCertificate, 658 IN_HANDLE const CRYPT_USER iCryptOwner, 659 IN_ENUM( CRYPT_CERTTYPE ) \ 660 const CRYPT_CERTTYPE_TYPE certType, 661 IN_LENGTH_SHORT_MIN( MIN_CRYPT_OBJECTSIZE ) \ 662 const int certDataLength, 663 IN_FLAGS_Z( KEYMGMT ) const int options ); 664 665 /* base64/SMIME-en/decode routines */ 666 667 #ifdef USE_BASE64 668 669 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \ 670 int base64checkHeader( IN_BUFFER( dataLength ) const BYTE *data, 671 IN_DATALENGTH const int dataLength, 672 OUT_ENUM_OPT( CRYPT_CERTFORMAT ) \ 673 CRYPT_CERTFORMAT_TYPE *format, 674 OUT_DATALENGTH_Z int *startPos ); 675 CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \ 676 int base64encodeLen( IN_DATALENGTH_MIN( 10 ) const int dataLength, 677 OUT_DATALENGTH_Z int *encodedLength, 678 IN_ENUM_OPT( CRYPT_CERTTYPE ) \ 679 const CRYPT_CERTTYPE_TYPE certType ); 680 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \ 681 int base64encode( OUT_BUFFER( destMaxLen, *destLen ) char *dest, 682 IN_DATALENGTH_MIN( 10 ) const int destMaxLen, 683 OUT_LENGTH_BOUNDED_Z( destMaxLen ) int *destLen, 684 IN_BUFFER( srcLen ) const void *src, 685 IN_DATALENGTH_MIN( 10 ) const int srcLen, 686 IN_ENUM_OPT( CRYPT_CERTTYPE ) \ 687 const CRYPT_CERTTYPE_TYPE certType ); 688 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 689 int base64decodeLen( IN_BUFFER( dataLength ) const BYTE *data, 690 IN_DATALENGTH_MIN( 10 ) const int dataLength, 691 OUT_DATALENGTH_Z int *decodedLength ); 692 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \ 693 int base64decode( OUT_BUFFER( destMaxLen, *destLen ) void *dest, 694 IN_DATALENGTH_MIN( 10 ) const int destMaxLen, 695 OUT_DATALENGTH_Z int *destLen, 696 IN_BUFFER( srcLen ) const BYTE *src, 697 IN_DATALENGTH_MIN( 10 ) const int srcLen, 698 IN_ENUM_OPT( CRYPT_CERTFORMAT ) \ 699 const CRYPT_CERTFORMAT_TYPE format ); 700 #endif /* USE_BASE64 */ 701 702 /* User data en/decode routines */ 703 704 CHECK_RETVAL_BOOL STDC_NONNULL_ARG( ( 1 ) ) \ 705 BOOLEAN isPKIUserValue( IN_BUFFER( encValLength ) const char *encVal, 706 IN_LENGTH_SHORT_MIN( 10 ) const int encValLength ); 707 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \ 708 int encodePKIUserValue( OUT_BUFFER( encValMaxLen, *encValLen ) char *encVal, 709 IN_LENGTH_SHORT_MIN( 10 ) const int encValMaxLen, 710 OUT_LENGTH_BOUNDED_Z( encValMaxLen ) int *encValLen, 711 IN_BUFFER( valueLen ) const BYTE *value, 712 IN_LENGTH_SHORT_MIN( 8 ) const int valueLen, 713 IN_RANGE( 3, 4 ) const int noCodeGroups ); 714 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \ 715 int decodePKIUserValue( OUT_BUFFER( valueMaxLen, *valueLen ) BYTE *value, 716 IN_LENGTH_SHORT_MIN( 10 ) const int valueMaxLen, 717 OUT_LENGTH_BOUNDED_Z( valueMaxLen ) int *valueLen, 718 IN_BUFFER( encValLength ) const char *encVal, 719 IN_LENGTH_SHORT const int encValLength ); 720 721 /**************************************************************************** 722 * * 723 * List Manipulation Functions * 724 * * 725 ****************************************************************************/ 726 727 /* Insert and delete elements to/from singly-linked and doubly-lined lists. 728 This is the sort of thing that we'd really need templates for, in their 729 absence we have to use (rather complex) macros */ 730 731 #define insertSingleListElement( listHead, insertPoint, newElement ) \ 732 { \ 733 if( *( listHead ) == NULL ) \ 734 { \ 735 /* It's an empty list, make this the new list */ \ 736 *( listHead ) = ( newElement ); \ 737 } \ 738 else \ 739 { \ 740 if( ( insertPoint ) == NULL ) \ 741 { \ 742 /* We're inserting at the start of the list, make this the \ 743 new first element */ \ 744 ( newElement )->next = *( listHead ); \ 745 *( listHead ) = ( newElement ); \ 746 } \ 747 else \ 748 { \ 749 /* Insert the element in the middle or the end of the list */ \ 750 ( newElement )->next = ( insertPoint )->next; \ 751 ( insertPoint )->next = ( newElement ); \ 752 } \ 753 } \ 754 } 755 756 #define insertDoubleListElements( listHead, insertPoint, newStartElement, newEndElement ) \ 757 { \ 758 if( *( listHead ) == NULL ) \ 759 { \ 760 /* If it's an empty list, make this the new list */ \ 761 *( listHead ) = ( newStartElement ); \ 762 } \ 763 else \ 764 { \ 765 if( ( insertPoint ) == NULL ) \ 766 { \ 767 /* We're inserting at the start of the list, make this the \ 768 new first element */ \ 769 ( newEndElement )->next = *( listHead ); \ 770 ( *( listHead ) )->prev = ( newEndElement ); \ 771 *( listHead ) = ( newStartElement ); \ 772 } \ 773 else \ 774 { \ 775 /* Make sure that the links are consistent */ \ 776 ENSURES( ( insertPoint )->next == NULL || \ 777 ( insertPoint )->next->prev == ( insertPoint ) ); \ 778 \ 779 /* Insert the element in the middle or the end of the list */ \ 780 ( newEndElement )->next = ( insertPoint )->next; \ 781 \ 782 /* Update the links for the next and previous elements */ \ 783 if( ( insertPoint )->next != NULL ) \ 784 ( insertPoint )->next->prev = ( newEndElement ); \ 785 ( insertPoint )->next = ( newStartElement ); \ 786 ( newStartElement )->prev = ( insertPoint ); \ 787 } \ 788 } \ 789 } 790 791 #define insertDoubleListElement( listHead, insertPoint, newElement ) \ 792 insertDoubleListElements( listHead, insertPoint, newElement, newElement ) 793 794 #define deleteSingleListElement( listHead, listPrev, element ) \ 795 { \ 796 /* Make sure that the preconditions for safe delection are met */ \ 797 REQUIRES( listHead != NULL && element != NULL ); \ 798 REQUIRES( element == *( listHead ) || listPrev != NULL ); \ 799 \ 800 if( element == *( listHead ) ) \ 801 { \ 802 /* Special case for first item */ \ 803 *( listHead ) = element->next; \ 804 } \ 805 else \ 806 { \ 807 ANALYSER_HINT( listPrev != NULL ); \ 808 \ 809 /* Delete from middle or end of the list */ \ 810 listPrev->next = element->next; \ 811 } \ 812 } 813 814 #define deleteDoubleListElement( listHead, element ) \ 815 { \ 816 /* Make sure that the preconditions for safe delection are met */ \ 817 REQUIRES( listHead != NULL && element != NULL ); \ 818 \ 819 /* Make sure that the links are consistent */ \ 820 REQUIRES( ( element )->next == NULL || \ 821 ( element )->next->prev == ( element ) ); \ 822 REQUIRES( ( element )->prev == NULL || \ 823 ( element )->prev->next == ( element ) ); \ 824 \ 825 /* Unlink the element from the list */ \ 826 if( element == *( listHead ) ) \ 827 { \ 828 /* Special case for first item */ \ 829 *( listHead ) = ( element )->next; \ 830 } \ 831 else \ 832 { \ 833 /* Further consistency check */ \ 834 REQUIRES( ( element )->prev != NULL ); \ 835 \ 836 /* Delete from the middle or the end of the list */ \ 837 ( element )->prev->next = ( element )->next; \ 838 } \ 839 if( ( element )->next != NULL ) \ 840 ( element )->next->prev = ( element )->prev; \ 841 } 842 843 /**************************************************************************** 844 * * 845 * Attribute List Manipulation Functions * 846 * * 847 ****************************************************************************/ 848 849 /* In order to work with attribute lists of different types, we need a 850 means of accessing the type-specific previous and next pointers and the 851 attribute ID information. The following callback function is passed to 852 all attribute-list manipulation functions and provides external access 853 to the required internal fields */ 854 855 typedef enum { 856 ATTR_NONE, /* No attribute get type */ 857 ATTR_CURRENT, /* Get details for current attribute */ 858 ATTR_PREV, /* Get details for previous attribute */ 859 ATTR_NEXT, /* Get details for next attribute */ 860 ATTR_LAST /* Last valid attribute get type */ 861 } ATTR_TYPE; 862 863 typedef CHECK_RETVAL_PTR \ 864 const void * ( *GETATTR_FUNCTION )( IN_OPT const void *attributePtr, 865 OUT_OPT_ATTRIBUTE_Z \ 866 CRYPT_ATTRIBUTE_TYPE *groupID, 867 OUT_OPT_ATTRIBUTE_Z \ 868 CRYPT_ATTRIBUTE_TYPE *attributeID, 869 OUT_OPT_ATTRIBUTE_Z \ 870 CRYPT_ATTRIBUTE_TYPE *instanceID, 871 IN_ENUM( ATTR ) \ 872 const ATTR_TYPE attrGetType ); 873 874 CHECK_RETVAL_PTR STDC_NONNULL_ARG( ( 2 ) ) \ 875 void *attributeFindStart( IN_OPT const void *attributePtr, 876 IN GETATTR_FUNCTION getAttrFunction ); 877 CHECK_RETVAL_PTR STDC_NONNULL_ARG( ( 2 ) ) \ 878 void *attributeFindEnd( IN_OPT const void *attributePtr, 879 IN GETATTR_FUNCTION getAttrFunction ); 880 CHECK_RETVAL_PTR STDC_NONNULL_ARG( ( 2 ) ) \ 881 void *attributeFind( IN_OPT const void *attributePtr, 882 IN GETATTR_FUNCTION getAttrFunction, 883 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attributeID ); 884 CHECK_RETVAL_PTR STDC_NONNULL_ARG( ( 2 ) ) \ 885 void *attributeFindEx( IN_OPT const void *attributePtr, 886 IN GETATTR_FUNCTION getAttrFunction, 887 IN_ENUM_OPT( CRYPT_ATTRIBUTE ) \ 888 const CRYPT_ATTRIBUTE_TYPE groupID, 889 IN_ENUM_OPT( CRYPT_ATTRIBUTE ) \ 890 const CRYPT_ATTRIBUTE_TYPE attributeID, 891 IN_ENUM_OPT( CRYPT_ATTRIBUTE ) \ 892 const CRYPT_ATTRIBUTE_TYPE instanceID ); 893 CHECK_RETVAL_PTR STDC_NONNULL_ARG( ( 2 ) ) \ 894 void *attributeFindNextInstance( IN_OPT const void *attributePtr, 895 IN GETATTR_FUNCTION getAttrFunction ); 896 CHECK_RETVAL_PTR STDC_NONNULL_ARG( ( 2 ) )\ 897 const void *attributeMoveCursor( IN_OPT const void *currentCursor, 898 IN GETATTR_FUNCTION getAttrFunction, 899 IN_ATTRIBUTE \ 900 const CRYPT_ATTRIBUTE_TYPE attributeMoveType, 901 IN_RANGE( CRYPT_CURSOR_LAST, \ 902 CRYPT_CURSOR_FIRST ) /* Values are -ve */ 903 const int cursorMoveType ); 904 905 /**************************************************************************** 906 * * 907 * Time Functions * 908 * * 909 ****************************************************************************/ 910 911 /* In exceptional circumstances an attempt to read the time can fail, 912 returning either a garbage value (unsigned time_t) or -1 (signed time_t). 913 This can be problematic because many crypto protocols and operations use 914 the time at some point. In order to protect against this, we provide a 915 safe time-read function that returns either a sane time value or zero, 916 and for situations where the absolute time isn't critical an approximate 917 current-time function that returns either a sane time value or an 918 approximate value hardcoded in at compile time. Finally, we provide a 919 reliable time function used for operations such as signing certs and 920 timestamping that tries to get the time from a hardware time source if 921 one is available */ 922 923 #include <time.h> 924 925 time_t getTime( void ); 926 time_t getApproxTime( void ); 927 time_t getReliableTime( IN_HANDLE const CRYPT_HANDLE cryptHandle ); 928 929 /* Monotonic timer interface that protect against the system clock being 930 changed during a timing operation. Even without deliberate fiddling 931 with the system clock, a timeout during a DST switch can cause something 932 like a 5s wait to turn into a 1hr 5s wait, so we have to abstract the 933 standard time API into a monotonic time API. Since these functions are 934 purely peripheral to other operations (for example handling timeouts for 935 network I/O), they never fail but simply return good-enough results if 936 there's a problem (although they assert in debug mode). This is because 937 we don't want to abort a network session just because we've detected 938 some trivial clock irregularity */ 939 940 typedef struct { 941 time_t endTime, origTimeout, timeRemaining; 942 } MONOTIMER_INFO; 943 944 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 945 int setMonoTimer( OUT MONOTIMER_INFO *timerInfo, 946 IN_INT_Z const int duration ); 947 STDC_NONNULL_ARG( ( 1 ) ) \ 948 void extendMonoTimer( INOUT MONOTIMER_INFO *timerInfo, 949 IN_INT const int duration ); 950 CHECK_RETVAL_BOOL STDC_NONNULL_ARG( ( 1 ) ) \ 951 BOOLEAN checkMonoTimerExpired( INOUT MONOTIMER_INFO *timerInfo ); 952 CHECK_RETVAL_BOOL STDC_NONNULL_ARG( ( 1 ) ) \ 953 BOOLEAN checkMonoTimerExpiryImminent( INOUT MONOTIMER_INFO *timerInfo, 954 IN_INT_Z const int timeLeft ); 955 956 /* Hardware timer read routine used for performance evaluation */ 957 958 CHECK_RETVAL_RANGE( 0, INT_MAX ) \ 959 long getTickCount( long startTime ); 960 961 /**************************************************************************** 962 * * 963 * Dynamic Memory Management Functions * 964 * * 965 ****************************************************************************/ 966 967 /* Dynamic buffer management functions. When reading variable-length 968 object data we can usually fit the data into a small fixed-length buffer, 969 but occasionally we have to cope with larger data amounts that require a 970 dynamically-allocated buffer. The following routines manage this 971 process, dynamically allocating and freeing a larger buffer if required */ 972 973 #define DYNBUF_SIZE 1024 974 975 typedef struct { 976 BUFFER_FIXED( length ) \ 977 void *data; /* Pointer to data */ 978 int length; 979 BUFFER( DYNBUF_SIZE, length ) \ 980 BYTE dataBuffer[ DYNBUF_SIZE + 8 ]; /* Data buf.if size <= DYNBUF_SIZE */ 981 } DYNBUF; 982 983 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 984 int dynCreate( OUT DYNBUF *dynBuf, 985 IN_HANDLE const CRYPT_HANDLE cryptHandle, 986 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attributeType ); 987 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 988 int dynCreateCert( OUT DYNBUF *dynBuf, 989 IN_HANDLE const CRYPT_HANDLE cryptHandle, 990 IN_ENUM( CRYPT_CERTFORMAT ) \ 991 const CRYPT_CERTFORMAT_TYPE formatType ); 992 STDC_NONNULL_ARG( ( 1 ) ) \ 993 void dynDestroy( INOUT DYNBUF *dynBuf ); 994 995 #define dynLength( dynBuf ) ( dynBuf ).length 996 #define dynData( dynBuf ) ( dynBuf ).data 997 998 /* When allocating many little blocks of memory, especially in resource- 999 constrained systems, it's better if we pre-allocate a small memory pool 1000 ourselves and grab chunks of it as required, falling back to dynamically 1001 allocating memory later on if we exhaust the pool. To use a custom 1002 memory pool, the caller declares a state variable of type MEMPOOL_STATE, 1003 calls initMemPool() to initialise the pool, and then calls getMemPool() 1004 and freeMemPool() to allocate and free memory blocks. The state pointer 1005 is declared as a void * because to the caller it's an opaque memory block 1006 while to the memPool routines it's structured storage */ 1007 1008 typedef BYTE MEMPOOL_STATE[ 32 ]; 1009 1010 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 1011 int initMemPool( OUT void *statePtr, 1012 IN_BUFFER( memPoolSize ) void *memPool, 1013 IN_LENGTH_SHORT_MIN( 64 ) const int memPoolSize ); 1014 CHECK_RETVAL_PTR STDC_NONNULL_ARG( ( 1 ) ) \ 1015 void *getMemPool( INOUT void *statePtr, IN_LENGTH_SHORT const int size ); 1016 STDC_NONNULL_ARG( ( 1, 2 ) ) \ 1017 void freeMemPool( INOUT void *statePtr, IN void *memblock ); 1018 1019 /* Almost all objects require object-subtype-specific amounts of memory to 1020 store object information. In addition some objects such as certificates 1021 contain arbitrary numbers of arbitrary-sized bits and pieces, most of 1022 which are quite small. To avoid having to allocate worst-case sized 1023 blocks of memory for objects (a problem in embedded environments) or large 1024 numbers of tiny little blocks of memory for certificate attributes, we use 1025 variable-length structures in which the payload is stored after the 1026 structure, with a pointer inside the structure pointing into the payload 1027 storage (a convenient side-effect of this is that it provides good 1028 spatial coherence when processing long lists of attributes). To make 1029 this easier to handle, we use macros to set up and tear down the 1030 necessary variables. 1031 1032 The use of 'storage[ 1 ]' means that the only element that's guaranteed 1033 to be valid is 'storage[ 0 ]' under strict C99 definitions, however 1034 declaring it as an unsized array leads to warnings of use of a zero-sized 1035 array from many compilers so we leave it as 'storage[ 1 ]'. 1036 1037 We have to insert an additional dummy value before the storage 1038 declaration to ensure the correct alignment for the storage itself, in 1039 particular on 64-bit platforms with the LLP64/LP64 memory model (which 1040 means most current systems) the storage block may end up 32-bit aligned 1041 if the compiler aligns to, at most, the nearest 32-bit integer value. We 1042 can't declare the storage as a long since under LLP64 it's only 32 bits 1043 while a pointer is still 64 bits */ 1044 1045 #define DECLARE_VARSTRUCT_VARS \ 1046 int storageSize; \ 1047 void *_align_value; \ 1048 BUFFER_FIXED( storageSize ) \ 1049 BYTE storage[ 1 ] 1050 1051 #define initVarStruct( structure, structureType, size ) \ 1052 memset( structure, 0, sizeof( structureType ) ); \ 1053 structure->value = structure->storage; \ 1054 structure->storageSize = size 1055 1056 #define copyVarStruct( destStructure, srcStructure, structureType ) \ 1057 memcpy( destStructure, srcStructure, \ 1058 sizeof( structureType ) + srcStructure->storageSize ); \ 1059 destStructure->value = destStructure->storage; 1060 1061 #define endVarStruct( structure, structureType ) \ 1062 zeroise( structure, sizeof( structureType ) + structure->storageSize ) 1063 1064 #define sizeofVarStruct( structure, structureType ) \ 1065 ( sizeof( structureType ) + structure->storageSize ) 1066 1067 /**************************************************************************** 1068 * * 1069 * Checksum/Hash Functions * 1070 * * 1071 ****************************************************************************/ 1072 1073 /* Hash state information. We can call the hash function with HASH_START, 1074 HASH_CONTINUE, or HASH_END as required to process the input in parts */ 1075 1076 typedef enum { 1077 HASH_STATE_NONE, /* No hash state */ 1078 HASH_STATE_START, /* Begin hashing */ 1079 HASH_STATE_CONTINUE, /* Continue existing hashing */ 1080 HASH_STATE_END, /* Complete existing hashing */ 1081 HASH_STATE_LAST /* Last valid hash option */ 1082 } HASH_STATE; 1083 1084 /* The hash functions are used quite a bit so we provide an internal API for 1085 them to avoid the overhead of having to set up an encryption context 1086 every time they're needed. These take a block of input data and hash it, 1087 leaving the result in the output buffer. 1088 1089 In addition to the hash-step operation, we provide a one-step atomic hash 1090 function that processes a single data quantity and returns its hash. 1091 1092 The data block is defined in terms of a long[] rather than a BYTE[] in 1093 order to deal with alignment issues */ 1094 1095 #if defined( USE_SHA2_EXT ) 1096 /* SHA2-384/512: ( 2 + 8 + 16 + 1 ) * sizeof( long long ) = 27 * 8 */ 1097 #if defined( SYSTEM_64BIT ) 1098 typedef long HASHINFO[ 27 + 1 ]; /* ( 27 * 8 ) + 8 */ 1099 #else 1100 typedef long HASHINFO[ ( 27 * 2 ) + 2 ]; /* ( 27 * 8 ) + 8 */ 1101 #endif /* 32- vs. 64-bit systems */ 1102 #elif defined( SYSTEM_64BIT ) 1103 /* RIPEMD160: 24 * sizeof( long long ) + 64 = 24 * 8 + 64 */ 1104 typedef long HASHINFO[ 24 + 8 + 1 ]; /* ( 24 * 8 ) + 64 + 8 */ 1105 #else 1106 /* SHA-256: ( 2 + 8 + 16 + 1 ) * sizeof( long ) = 27 * 4 */ 1107 typedef long HASHINFO[ 27 + 2 ]; /* ( 27 * 4 ) + 8 */ 1108 #endif /* SYSTEM_64BIT */ 1109 1110 typedef void ( *HASH_FUNCTION )( OUT_WHEN( hashState == HASH_STATE_START ) \ 1111 INOUT_WHEN( hashState != HASH_STATE_START ) \ 1112 HASHINFO hashInfo, 1113 OUT_BUFFER_OPT_FIXED( outBufMaxLength ) \ 1114 BYTE *outBuffer, 1115 IN_LENGTH_HASH_Z const int outBufMaxLength, 1116 IN_BUFFER_OPT( inLength ) const void *inBuffer, 1117 IN_LENGTH_Z const int inLength, 1118 IN_ENUM( HASH_STATE ) \ 1119 const HASH_STATE hashState ); 1120 typedef STDC_NONNULL_ARG( ( 1, 3 ) ) \ 1121 void ( *HASH_FUNCTION_ATOMIC )( OUT_BUFFER_FIXED( outBufMaxLength ) \ 1122 BYTE *outBuffer, 1123 IN_LENGTH_HASH const int outBufMaxLength, 1124 IN_BUFFER( inLength ) const void *inBuffer, 1125 IN_LENGTH const int inLength ); 1126 1127 STDC_NONNULL_ARG( ( 3 ) ) \ 1128 void getHashParameters( IN_ALGO const CRYPT_ALGO_TYPE hashAlgorithm, 1129 IN_INT_SHORT_Z const int hashParams, 1130 OUT_PTR HASH_FUNCTION *hashFunction, 1131 OUT_OPT_LENGTH_SHORT_Z int *hashOutputSize ); 1132 STDC_NONNULL_ARG( ( 3 ) ) \ 1133 void getHashAtomicParameters( IN_ALGO const CRYPT_ALGO_TYPE hashAlgorithm, 1134 IN_INT_SHORT_Z const int hashParams, 1135 OUT_PTR HASH_FUNCTION_ATOMIC *hashFunctionAtomic, 1136 OUT_OPT_LENGTH_SHORT_Z int *hashOutputSize ); 1137 1138 /* Sometimes all that we need is a quick-reject check, usually performed to 1139 lighten the load before we do a full hash check. The following function 1140 returns an integer checksum that can be used to weed out non-matches. If 1141 the checksum matches, we use the more heavyweight full hash of the data */ 1142 1143 #define HASH_DATA_SIZE 16 1144 1145 RETVAL_RANGE( MAX_ERROR, 0xFFFF ) STDC_NONNULL_ARG( ( 1 ) ) \ 1146 int checksumData( IN_BUFFER( dataLength ) const void *data, 1147 IN_DATALENGTH const int dataLength ); 1148 STDC_NONNULL_ARG( ( 1, 3 ) ) \ 1149 void hashData( OUT_BUFFER_FIXED( hashMaxLength ) BYTE *hash, 1150 IN_LENGTH_HASH const int hashMaxLength, 1151 IN_BUFFER( dataLength ) const void *data, 1152 IN_DATALENGTH const int dataLength ); 1153 1154 /* When we're comparing two cryptographic values, for example two MAC 1155 values, and the developer's been careful to implement things really 1156 badly, it may be possible to use a timing attack to guess a MAC value a 1157 byte at a time by using a high-resolution timer to check at which byte 1158 the memcmp() exits, thus guessing the MAC value a byte at a time in the 1159 same way that the old TENEX password-guessing bug worked. This seems 1160 highly unlikely given that cryptlib implementations of protocols won't 1161 allow themselves to be used as an oracle in this manner and for someone 1162 using cryptlib to implement their own protocol the overhead of a trip 1163 through the kernel will mask out a few clock cycles of difference in 1164 the memcmp() at the end, but we defend against it anyway because no doubt 1165 someone will eventually publish a CERT advisory on it being a problem in 1166 some app somewhere */ 1167 1168 CHECK_RETVAL_BOOL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 1169 BOOLEAN compareDataConstTime( IN_BUFFER( length ) const void *src, 1170 IN_BUFFER( length ) const void *dest, 1171 IN_LENGTH_SHORT const int length ); 1172 1173 /**************************************************************************** 1174 * * 1175 * Signing/Key Wrap Functions * 1176 * * 1177 ****************************************************************************/ 1178 1179 /* Signatures can have all manner of additional odds and ends associated 1180 with them, the following structure contains these additional optional 1181 values */ 1182 1183 typedef struct { 1184 /* CMS additional signature information */ 1185 BOOLEAN useDefaultAuthAttr; /* Use built-in default auth.attr */ 1186 CRYPT_CERTIFICATE iAuthAttr; /* User-supplied auth.attributes */ 1187 CRYPT_SESSION iTspSession; /* TSP session for timestamping */ 1188 1189 /* PGP additional signature information */ 1190 int sigType; /* Signature type */ 1191 BUFFER_OPT_FIXED( sigAttributeSize ) \ 1192 const void *sigAttributes; /* Additional signature attributes */ 1193 int sigAttributeSize; 1194 1195 /* SSL/TLS additional signature information */ 1196 CRYPT_CONTEXT iSecondHash; /* Second hash for dual sig.*/ 1197 } SIGPARAMS; 1198 1199 #define initSigParams( sigParams ) \ 1200 { \ 1201 memset( ( sigParams ), 0, sizeof( SIGPARAMS ) ); \ 1202 ( sigParams )->iAuthAttr = ( sigParams )->iTspSession = \ 1203 ( sigParams )->iSecondHash = CRYPT_ERROR; \ 1204 } 1205 1206 #define initSigParamsPGP( sigParams, pgpSigType, pgpAttrs, pgpAttrSize ) \ 1207 { \ 1208 memset( ( sigParams ), 0, sizeof( SIGPARAMS ) ); \ 1209 ( sigParams )->iAuthAttr = ( sigParams )->iTspSession = \ 1210 ( sigParams )->iSecondHash = CRYPT_ERROR; \ 1211 ( sigParams )->sigType = pgpSigType; \ 1212 ( sigParams )->sigAttributes = pgpAttrs; \ 1213 ( sigParams )->sigAttributeSize = pgpAttrSize; \ 1214 } 1215 1216 /* Internal forms of various external functions. These work with internal 1217 resources that are marked as being inaccessible to the corresponding 1218 external functions, and don't perform all the checking that their 1219 external equivalents perform, since the parameters have already been 1220 checked by cryptlib */ 1221 1222 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 1223 int iCryptCreateSignature( OUT_BUFFER_OPT( signatureMaxLength, *signatureLength ) \ 1224 void *signature, 1225 IN_DATALENGTH_Z const int signatureMaxLength, 1226 OUT_DATALENGTH_Z int *signatureLength, 1227 IN_ENUM( CRYPT_FORMAT ) \ 1228 const CRYPT_FORMAT_TYPE formatType, 1229 IN_HANDLE const CRYPT_CONTEXT iSignContext, 1230 IN_HANDLE const CRYPT_CONTEXT iHashContext, 1231 IN_OPT const SIGPARAMS *sigParams ); 1232 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 1233 int iCryptCheckSignature( IN_BUFFER( signatureLength ) const void *signature, 1234 IN_LENGTH_SHORT const int signatureLength, 1235 IN_ENUM( CRYPT_FORMAT ) \ 1236 const CRYPT_FORMAT_TYPE formatType, 1237 IN_HANDLE const CRYPT_HANDLE iSigCheckKey, 1238 IN_HANDLE const CRYPT_CONTEXT iHashContext, 1239 IN_HANDLE_OPT const CRYPT_CONTEXT iHash2Context, 1240 OUT_OPT_HANDLE_OPT CRYPT_HANDLE *extraData ); 1241 #ifdef USE_INT_CMS 1242 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 1243 int iCryptImportKey( IN_BUFFER( encryptedKeyLength ) const void *encryptedKey, 1244 IN_LENGTH_SHORT const int encryptedKeyLength, 1245 IN_ENUM( CRYPT_FORMAT ) \ 1246 const CRYPT_FORMAT_TYPE formatType, 1247 IN_HANDLE const CRYPT_CONTEXT iImportKey, 1248 IN_HANDLE_OPT const CRYPT_CONTEXT iSessionKeyContext, 1249 OUT_OPT_HANDLE_OPT CRYPT_CONTEXT *iReturnedContext ); 1250 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 1251 int iCryptExportKey( OUT_BUFFER_OPT( encryptedKeyMaxLength, *encryptedKeyLength ) \ 1252 void *encryptedKey, 1253 IN_DATALENGTH_Z const int encryptedKeyMaxLength, 1254 OUT_DATALENGTH_Z int *encryptedKeyLength, 1255 IN_ENUM( CRYPT_FORMAT ) \ 1256 const CRYPT_FORMAT_TYPE formatType, 1257 IN_HANDLE_OPT const CRYPT_CONTEXT iSessionKeyContext, 1258 IN_HANDLE const CRYPT_CONTEXT iExportKey ); 1259 #endif /* USE_INT_CMS */ 1260 1261 /**************************************************************************** 1262 * * 1263 * Envelope Management Functions * 1264 * * 1265 ****************************************************************************/ 1266 1267 #ifdef USE_ENVELOPES 1268 1269 /* General-purpose enveloping functions, used by various high-level 1270 protocols */ 1271 1272 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 5 ) ) \ 1273 int envelopeWrap( IN_BUFFER( inDataLength ) const void *inData, 1274 IN_DATALENGTH_MIN( 16 ) const int inDataLength, 1275 OUT_BUFFER( outDataMaxLength, *outDataLength ) void *outData, 1276 IN_DATALENGTH_MIN( 16 ) const int outDataMaxLength, 1277 OUT_DATALENGTH_Z int *outDataLength, 1278 IN_ENUM( CRYPT_FORMAT ) const CRYPT_FORMAT_TYPE formatType, 1279 IN_ENUM_OPT( CRYPT_CONTENT ) const CRYPT_CONTENT_TYPE contentType, 1280 IN_HANDLE_OPT const CRYPT_HANDLE iPublicKey, 1281 OUT ERROR_INFO *errorInfo ); 1282 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 5 ) ) \ 1283 int envelopeUnwrap( IN_BUFFER( inDataLength ) const void *inData, 1284 IN_DATALENGTH_MIN( 16 ) const int inDataLength, 1285 OUT_BUFFER( outDataMaxLength, *outDataLength ) void *outData, 1286 IN_DATALENGTH_MIN( 16 ) const int outDataMaxLength, 1287 OUT_DATALENGTH_Z int *outDataLength, 1288 IN_HANDLE_OPT const CRYPT_CONTEXT iPrivKey, 1289 OUT ERROR_INFO *errorInfo ); 1290 CHECK_RETVAL STDC_NONNULL_ARG( ( 3, 5 ) ) \ 1291 int envelopeSign( IN_BUFFER_OPT( inDataLength ) const void *inData, 1292 IN_DATALENGTH_Z const int inDataLength, 1293 OUT_BUFFER( outDataMaxLength, *outDataLength ) void *outData, 1294 IN_DATALENGTH_MIN( 16 ) const int outDataMaxLength, 1295 OUT_DATALENGTH_Z int *outDataLength, 1296 IN_ENUM_OPT( CRYPT_CONTENT ) const CRYPT_CONTENT_TYPE contentType, 1297 IN_HANDLE const CRYPT_CONTEXT iSigKey, 1298 IN_HANDLE_OPT const CRYPT_CERTIFICATE iCmsAttributes, 1299 OUT ERROR_INFO *errorInfo ); 1300 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 5, 7 ) ) \ 1301 int envelopeSigCheck( IN_BUFFER( inDataLength ) const void *inData, 1302 IN_DATALENGTH_MIN( 16 ) const int inDataLength, 1303 OUT_BUFFER( outDataMaxLength, *outDataLength ) void *outData, 1304 IN_DATALENGTH_MIN( 16 ) const int outDataMaxLength, 1305 OUT_DATALENGTH_Z int *outDataLength, 1306 IN_HANDLE_OPT const CRYPT_CONTEXT iSigCheckKey, 1307 OUT_STATUS int *sigResult, 1308 OUT_OPT_HANDLE_OPT CRYPT_CERTIFICATE *iSigningCert, 1309 OUT_OPT_HANDLE_OPT CRYPT_CERTIFICATE *iCmsAttributes, 1310 OUT ERROR_INFO *errorInfo ); 1311 #endif /* USE_ENVELOPES */ 1312 1313 /**************************************************************************** 1314 * * 1315 * Miscellaneous Functions * 1316 * * 1317 ****************************************************************************/ 1318 1319 /* Miscellaneous functions that need to be prototyped here (or at least in 1320 some globally-visible header) in order for them to be visible in the 1321 external modules that reference them */ 1322 1323 /* Prototypes for functions in mechs/sign_x509.c, used by certificates and 1324 sessions. In the standard PKIX tradition there are a whole range of 1325 b0rken PKI protocols that couldn't quite manage a cut & paste of two 1326 lines of text, adding all sorts of unnecessary extra tagging and wrappers 1327 to the signature. The encoding of these odds and handled via the 1328 X509SIG_FORMATINFO. The basic form allows a user-supplied tag and an 1329 indication of whether it's explicitly or implicitly tagged. If the 1330 explicitTag flag is clear the tag is encoded as [n] { ... }. If it's 1331 set, it's encoded as [n] { SEQUENCE { ... }}. In addition the 1332 extraLength field allows the optional insertion of extra data by the 1333 caller, with the wrapper length being written to include the 1334 extraLength, whose payload can then be appended by the caller */ 1335 1336 typedef struct { 1337 int tag; /* Tag for signature */ 1338 BOOLEAN isExplicit; /* Whether tag is expicit */ 1339 int extraLength; /* Optional length for further data */ 1340 } X509SIG_FORMATINFO; 1341 1342 #define setX509FormatInfo( formatInfo, formatTag, formatIsExplicit ) \ 1343 memset( formatInfo, 0, sizeof( X509SIG_FORMATINFO ) ); \ 1344 ( formatInfo )->tag = ( formatTag ); \ 1345 ( formatInfo )->isExplicit = ( formatIsExplicit ) 1346 1347 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \ 1348 int createX509signature( OUT_BUFFER( signedObjectMaxLength, \ 1349 *signedObjectLength ) \ 1350 void *signedObject, 1351 IN_DATALENGTH_Z const int signedObjectMaxLength, 1352 OUT_DATALENGTH_Z int *signedObjectLength, 1353 IN_BUFFER( objectLength ) const void *object, 1354 IN_DATALENGTH const int objectLength, 1355 IN_HANDLE const CRYPT_CONTEXT iSignContext, 1356 IN_ALGO const CRYPT_ALGO_TYPE hashAlgo, 1357 IN_OPT const X509SIG_FORMATINFO *formatInfo ); 1358 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 1359 int checkX509signature( IN_BUFFER( signedObjectLength ) const void *signedObject, 1360 IN_DATALENGTH const int signedObjectLength, 1361 IN_HANDLE const CRYPT_CONTEXT iSigCheckContext, 1362 IN_OPT const X509SIG_FORMATINFO *formatInfo ); 1363 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \ 1364 int createRawSignature( OUT_BUFFER( sigMaxLength, *signatureLength ) \ 1365 void *signature, 1366 IN_LENGTH_SHORT_MIN( MIN_CRYPT_OBJECTSIZE ) \ 1367 const int sigMaxLength, 1368 OUT_LENGTH_BOUNDED_Z( sigMaxLength ) \ 1369 int *signatureLength, 1370 IN_HANDLE const CRYPT_CONTEXT iSignContext, 1371 IN_HANDLE const CRYPT_CONTEXT iHashContext ); 1372 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 1373 int checkRawSignature( IN_BUFFER( signatureLength ) const void *signature, 1374 IN_LENGTH_SHORT const int signatureLength, 1375 IN_HANDLE const CRYPT_CONTEXT iSigCheckContext, 1376 IN_HANDLE const CRYPT_CONTEXT iHashContext ); 1377 1378 /* Prototypes for functions in context/key_wr.c, used by devices */ 1379 1380 CHECK_RETVAL STDC_NONNULL_ARG( ( 3, 6 ) ) \ 1381 int writeFlatPublicKey( OUT_BUFFER_OPT( bufMaxSize, *bufSize ) void *buffer, 1382 IN_LENGTH_SHORT_Z const int bufMaxSize, 1383 OUT_LENGTH_BOUNDED_Z( bufMaxSize ) int *bufSize, 1384 IN_ALGO const CRYPT_ALGO_TYPE cryptAlgo, 1385 IN_RANGE( 0, 100 ) const int intParam, 1386 IN_BUFFER( component1Length ) const void *component1, 1387 IN_LENGTH_PKC const int component1Length, 1388 IN_BUFFER( component2Length ) const void *component2, 1389 IN_LENGTH_PKC const int component2Length, 1390 IN_BUFFER_OPT( component3Length ) const void *component3, 1391 IN_LENGTH_PKC_Z const int component3Length, 1392 IN_BUFFER_OPT( component4Length ) const void *component4, 1393 IN_LENGTH_PKC_Z const int component4Length ); 1394 1395 /* Prototypes for functions in cryptcrt.c, used by devices, and a generic 1396 one used by anything that fetches a certificate */ 1397 1398 #if defined( USE_CERTIFICATES ) || defined( USE_PSEUDOCERTIFICATES ) 1399 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 1400 int createCertificateIndirect( INOUT MESSAGE_CREATEOBJECT_INFO *createInfo, 1401 STDC_UNUSED const void *auxDataPtr, 1402 STDC_UNUSED const int auxValue ); 1403 #endif /* USE_CERTIFICATES || USE_PSEUDOCERTIFICATES */ 1404 #ifdef USE_CERTIFICATES 1405 1406 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 1407 int iCryptVerifyID( IN_HANDLE const CRYPT_CERTIFICATE iCertificate, 1408 IN_ENUM( CRYPT_KEYID ) const CRYPT_KEYID_TYPE keyIDtype, 1409 IN_BUFFER( keyIDlength ) const void *keyID, 1410 IN_LENGTH_SHORT const int keyIDlength ); 1411 #endif /* USE_CERTIFICATES */ 1412 1413 /* Prototypes for functions in context/ctx_bn.c, used in the ASN.1/misc 1414 read/write routines */ 1415 1416 typedef enum { 1417 KEYSIZE_CHECK_NONE, /* Don't check for short key sizes */ 1418 KEYSIZE_CHECK_SPECIAL_NONE = KEYSIZE_CHECK_NONE, 1419 KEYSIZE_CHECK_PKC, /* Check for a short PKC key */ 1420 KEYSIZE_CHECK_ECC, /* Check for a short ECC key */ 1421 KEYSIZE_CHECK_LAST = KEYSIZE_CHECK_ECC + 1, 1422 /* Last valid normal check type */ 1423 KEYSIZE_CHECK_SPECIAL, /* Allow slightly oversize keys for DLP */ 1424 KEYSIZE_CHECK_SPECIAL_LAST /* Last valid check type */ 1425 } KEYSIZE_CHECK_TYPE; 1426 1427 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 1428 int importBignum( INOUT TYPECAST( BIGNUM * ) void *bignumPtr, 1429 IN_BUFFER( length ) const void *buffer, 1430 IN_LENGTH_SHORT const int length, 1431 IN_LENGTH_PKC const int minLength, 1432 IN_RANGE( 1, CRYPT_MAX_PKCSIZE + 8 ) \ 1433 const int maxLength, 1434 /* See DLP_OVERFLOW_SIZE = 8 in context.h */ 1435 IN_OPT TYPECAST( BIGNUM * ) const void *maxRangePtr, 1436 IN_ENUM_OPT( KEYSIZE_CHECK_SPECIAL ) \ 1437 const KEYSIZE_CHECK_TYPE checkType ); 1438 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \ 1439 int exportBignum( OUT_BUFFER( dataMaxLength, *dataLength ) void *data, 1440 IN_LENGTH_SHORT_MIN( 16 ) const int dataMaxLength, 1441 OUT_LENGTH_BOUNDED_Z( dataMaxLength ) int *dataLength, 1442 IN TYPECAST( BIGNUM * ) const void *bignumPtr ); 1443 #if defined( USE_ECDH ) || defined( USE_ECDSA ) 1444 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \ 1445 int importECCPoint( INOUT void *bignumPtr1, 1446 INOUT void *bignumPtr2, 1447 IN_BUFFER( length ) const void *buffer, 1448 IN_LENGTH_SHORT const int length, 1449 IN_LENGTH_PKC const int minLength, 1450 IN_LENGTH_PKC const int maxLength, 1451 IN_LENGTH_PKC const int fieldSize, 1452 IN_OPT const void *maxRangePtr, 1453 IN_ENUM( KEYSIZE_CHECK ) \ 1454 const KEYSIZE_CHECK_TYPE checkType ); 1455 CHECK_RETVAL STDC_NONNULL_ARG( ( 3, 4, 5 ) ) \ 1456 int exportECCPoint( OUT_BUFFER_OPT( dataMaxLength, *dataLength ) void *data, 1457 IN_LENGTH_SHORT_Z const int dataMaxLength, 1458 OUT_LENGTH_BOUNDED_PKC_Z( dataMaxLength ) int *dataLength, 1459 IN const void *bignumPtr1, 1460 IN const void *bignumPtr2, 1461 IN_LENGTH_PKC const int fieldSize ); 1462 #endif /* USE_ECDH || USE_ECDSA */ 1463 1464 #endif /* _INTAPI_DEFINED */ 1465