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