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