1 /****************************************************************************
2 *																			*
3 *					  cryptlib OS-Specific Defines Header File 				*
4 *						Copyright Peter Gutmann 1992-2012					*
5 *																			*
6 ****************************************************************************/
7 
8 #ifndef _OSSPEC_DEFINED
9 
10 #define _OSSPEC_DEFINED
11 
12 /* To build the static .LIB under Win32, uncomment the following define (this
13    it not recommended since the init/shutdown is no longer completely thread-
14    safe).  In theory it should be possible to detect the build of a DLL vs.a
15    LIB with the _DLL define which is set when the /MD (multithreaded DLL)
16    option is used, however VC++ only defines _DLL when /MD is used *and*
17    it's linked with the MT DLL runtime.  If it's linked with the statically
18    linked runtime, _DLL isn't defined, which would result in the unsafe LIB
19    version being built as a DLL */
20 
21 /* #define STATIC_LIB */
22 
23 /* os_spec.h performs OS and compiler detection that's used by config.h, so
24    this file must be applied before config.h */
25 
26 #ifdef _CONFIG_DEFINED
27   #error "os_spec.h must be included before config.h"
28 #endif /* _CONFIG_DEFINED */
29 
30 /****************************************************************************
31 *																			*
32 *									OS Detection							*
33 *																			*
34 ****************************************************************************/
35 
36 /* Try and figure out if we're running under Windows and Win16/Win32/WinCE.
37    We have to jump through all sorts of hoops later on, not helped by the
38    fact that the method of detecting Windows at compile time changes with
39    different versions of Visual C (it's different for each of VC 2.0, 2.1,
40    4.0, and 4.1.  It actually remains the same after 4.1) */
41 
42 #ifndef __WINDOWS__
43   #if defined( _Windows ) || defined( _WINDOWS )
44 	#define __WINDOWS__
45   #endif /* Older Windows compilers */
46   #ifdef __MINGW32__
47 	#define __WINDOWS__
48   #endif /* MinGW */
49 #endif /* Windows */
50 #if !defined( __WIN32__ ) && ( defined( WIN32 ) || defined( _WIN32 ) )
51   #ifndef __WINDOWS__
52 	#define __WINDOWS__		/* Win32 or WinCE */
53   #endif /* __WINDOWS__ */
54   #ifdef _WIN32_WCE
55 	#define __WINCE__
56   #else
57 	#define __WIN32__
58   #endif /* WinCE vs. Win32 */
59   #if defined( _M_X64 )
60 	#define __WIN64__
61   #endif /* Win64 */
62 #endif /* Win32 or WinCE */
63 #if defined( __WINDOWS__ ) && \
64 	!( defined( __WIN32__ ) || defined( __WINCE__ ) )
65   #define __WIN16__
66 #endif /* Windows without Win32 or WinCE */
67 
68 /* If we're using a DOS compiler and it's not a 32-bit one, record this.
69    __MSDOS__ is predefined by a number of compilers, so we use __MSDOS16__
70    for stuff that's 16-bit DOS specific, and __MSDOS32__ for stuff that's
71    32-bit DOS specific */
72 
73 #if defined( __MSDOS__ ) && !defined( __MSDOS32__ )
74   #define __MSDOS16__
75 #endif /* 16-bit DOS */
76 #if defined( __WATCOMC__ ) && defined( __DOS__ )
77   #ifndef __MSDOS__
78 	#define __MSDOS__
79   #endif /* 16- or 32-bit DOS */
80   #if defined( __386__ ) && !defined( __MSDOS32__ )
81 	#define __MSDOS32__
82   #endif /* 32-bit DOS */
83 #endif /* Watcom C under DOS */
84 
85 /* Make the defines for various OSes look a bit more like the usual ANSI
86   defines that are used to identify the other OS types */
87 
88 #ifdef __TANDEM
89   #if defined( _OSS_TARGET )
90 	#define __TANDEM_OSS__
91   #elif defined( _GUARDIAN_TARGET )
92 	#define __TANDEM_NSK__
93   #else
94 	#error "Can't determine Tandem OS target type (NSK or OSS)"
95   #endif /* Tandem OSS vs. NSK */
96 #endif /* Tandem */
97 
98 #if defined( __MWERKS__ ) || defined( SYMANTEC_C ) || defined( __MRC__ )
99   #define __MAC__
100 #endif /* Macintosh */
101 
102 #if defined( __OS400__ ) || defined( __ILEC400__ )
103   #define __AS400__
104 #endif /* AS/400 */
105 
106 #ifdef __PALMSOURCE__
107   #define __PALMOS__
108 #endif /* Palm OS */
109 
110 #ifdef __VMS
111   #define __VMS__
112 #endif /* VMS */
113 
114 #if defined( __APPLE__ )
115   /* Apple provides an environment-specific file that provides detailed
116 	 information about the target enviroment, defining TARGET_OS_xxx to 1
117 	 for a given target environment */
118   #include <TargetConditionals.h>
119   #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
120 	#define __iOS__
121   #elif TARGET_OS_WATCH
122 	/* It's a bit unclear what the OS for Apple's watch will eventually end
123 	   up as, for now we treat it as iOS since we're only accessing the low-
124 	   level functionality */
125 	#define __iOS__
126   #endif /* iOS aliases */
127 #endif /* __APPLE__ */
128 
129 /* In some cases we're using a Windows system as an emulated cross-
130    development platform, in which case we are we add extra defines to turn
131    off some Windows-specific features.  The override for BOOLEAN is required
132    because once __WIN32__ is turned off we try and typedef BOOLEAN, but
133    under Windows it's already typedef'd which leads to error messages */
134 
135 #if defined( __WIN32__ ) && ( _MSC_VER == 1200 ) && defined( CROSSCOMPILE )
136   /* Embedded OS variant.  Remember to change Project | Settings | C/C++ |
137 	 Preprocessor | Additional include directories as per the code
138 	 comments */
139 //	#define __ARINC653__	/* Extra include: ./,./embedded/arinc653 */
140 //	#define __CMSIS__		/* Extra include: ./,./embedded/cmsis */
141 //  #define __EmbOS__		/* Extra include: ./,./embedded/embos */
142 //	#define __FreeRTOS__	/* Extra include: ./,./embedded/freertos */
143 //	#define __ITRON__		/* Extra include: ./,./embedded/itron */
144 //	#define __Nucleus__		/* Extra include: ./,./embedded/nucleus */
145 //	#define __RTEMS__		/* Extra include: ./,./embedded/rtems */
146 //	#define __SMX__			/* Extra include: ./,./embedded/smx/xsmx,./embedded/smx/xfs */
147 //	#define __ThreadX__		/* Extra include: ./,./embedded/threadx */
148 //	#define __TKernel__		/* Extra include: ./,./embedded/tk */
149 //  #define __UCOS__		/* Extra include: ./,./embedded/ucos */
150 	#define __VxWorks__		/* Extra include: ./,./embedded/vxworks/,./embedded/vxworks/wrn/coreip/ */
151 
152   /* Embedded OS additions (filesystems, networking).  Include directory
153      changes as before */
154   #define USE_LWIP			/* Extra include: ...,./embedded */
155 							/* LWIP uses absolute paths, so the 'lwip' in
156 							   the path is part of the #include */
157 
158   /* Undo Windows defines */
159   #undef __WINDOWS__
160   #undef __WIN32__
161   #if !defined( __Nucleus__ ) && !defined( __SMX__ ) && !defined( __UCOS__ )
162 	#define BOOLEAN			FNORDIAN
163   #endif /* Systems that typedef BOOLEAN */
164   #ifdef __Nucleus__
165 	#undef FAR
166   #endif /* Systems that define FAR */
167 
168   /* Embedded SDK-specific additional defines */
169   #if defined( __VxWorks__ ) && !defined( _WRS_KERNEL )
170 	#define _WRS_KERNEL		1
171   #endif /* SDK-specific defines */
172 
173   /* In addition '__i386__' (assuming gcc with an x86 target) needs to be
174      defined globally via Project Settings | C/C++ | Preprocessor.  This
175 	 is already defined for the 'Crosscompile' build configuration */
176 #endif /* Windows emulated cross-compile environment */
177 
178 #ifdef _SCCTK
179   #define __IBM4758__
180 #endif /* IBM 4758 cross-compiled under Windows */
181 
182 /****************************************************************************
183 *																			*
184 *						OS-Specific Compiler Configuration					*
185 *																			*
186 ****************************************************************************/
187 
188 /* Visual C++ capabilities have changed somewhat over the years, the
189    following defines make explicit what we're testing for in a check of
190    _MSC_VER.
191 
192 	Visual C++ 1.5 _MSC_VER = 800
193 	Visual C++ 2.0 _MSC_VER = 900
194 	Visual C++ 4.0 _MSC_VER = 1000
195 	Visual C++ 5.0 _MSC_VER = 1100
196 	Visual C++ 6.0 _MSC_VER = 1200
197 	Visual C++ 7.0 (VC++.NET/2002) _MSC_VER = 1300
198 	Visual C++ 7.1 (VC++.NET/2003) _MSC_VER = 1310
199 	Visual C++ 8.0 (VC2005) _MSC_VER = 1400
200 	Visual C++ 9.0 (VC2008) _MSC_VER = 1500
201 	Visual C++ 10.0 (VC2010) _MSC_VER = 1600
202 	Visual C++ 11.0 (VC2012) _MSC_VER = 1700
203 	Visual C++ 12.0 (VC2013) _MSC_VER = 1800
204 	Visual C++ 14.0 (VC2015) _MSC_VER = 1900 */
205 
206 #ifdef _MSC_VER
207   #define VC_16BIT( version )		( version <= 800 )
208   #define VC_LE_VC6( version )		( version <= 1200 )
209   #define VC_GE_2002( version )		( version >= 1300 )
210   #define VC_LT_2005( version )		( version < 1400 )
211   #define VC_GE_2005( version )		( version >= 1400 )
212   #define VC_GE_2008( version )		( version >= 1500 )
213   #define VC_LT_2010( version )		( version < 1600 )
214   #define VC_GE_2010( version )		( version >= 1600 )
215   #define VC_GE_2012( version )		( version >= 1700 )
216   #define VC_GE_2013( version )		( version >= 1800 )
217   #define VC_GE_2015( version )		( version >= 1900 )
218 #else
219   /* These aren't specifically required on non-VC++ systems, but some
220      preprocessors get confused if they aren't defined */
221   #define VC_16BIT( version )		0
222   #define VC_LE_VC6( version )		0
223   #define VC_GE_2002( version )		0
224   #define VC_LT_2005( version )		0
225   #define VC_GE_2005( version )		0
226   #define VC_GE_2008( version )		0
227   #define VC_GE_2010( version )		0
228   #define VC_GE_2012( version )		0
229   #define VC_GE_2013( version )		0
230   #define VC_GE_2015( version )		0
231 #endif /* Visual C++ */
232 
233 /* If we're compiling under VC++ with the maximum level of warnings, turn
234    off some of the more irritating warnings */
235 
236 #if defined( _MSC_VER )
237   #if VC_16BIT( _MSC_VER )
238 	#pragma warning( disable: 4135 )/* Conversion bet.diff.integral types */
239 	#pragma warning( disable: 4761 )/* Integral size mismatch in argument */
240   #endif /* 16-bit VC++ */
241 
242   /* Warning level 3:
243 
244 	 4017: Comparing signed <-> unsigned value.  The compiler has to convert
245 		   the signed value to unsigned to perform the comparison.  This
246 		   leads to around 25 false-positive warnings.  Note that this is
247 		   a variant of the VC++ 2005-only warning 4267, this one warns
248 		   about comparing the result of a sizeof() operation to an int and
249 		   4267 warns about size_t types in general */
250   #pragma warning( disable: 4018 )	/* Comparing signed <-> unsigned value */
251 
252   /* Warning level 4:
253 
254 	 4054, 4055: Cast from function pointer -> generic (data) pointer, cast
255 		   from generic (data) pointer -> function pointer.  These are
256 		   orthogonal and impossible to disable as they override the
257 		   universal 'void *' pointer type.
258 
259 	 4057: Different types via indirection.  An annoying dual-purpose
260 		   warning that leads to huge numbers of false positives for
261 		   'char *' vs. 'unsigned char *' (for example due to a PKCS #11
262 		   token label, declared as 'unsigned char *', being passed to a
263 		   string function, these are pretty much un-fixable as 'char'
264 		   vs. 'unsigned char's percolate up and down the code tree),
265 		   but that also provides useful warnings of potential problems
266 		   (for example 'int *' passed to function expecting 'long *').
267 
268 	 4204, 4221: Struct initialised with non-const value, struct initialised
269 		   with address of automatic variable.  Standards extensions that
270 		   the struct STATIC_INIT macros manage for us.
271 
272 	 4206: Empty C module due to #ifdef'd out code.  Annoying noise caused
273 		   by empty modules due to disabled functionality.
274 
275 	 The only useful ones are 4057, which can be turned off on a one-off
276 	 basis to identify new true-positive issues before being disabled again
277 	 to avoid all of the false-positives, currently 100 for 4057 */
278   #pragma warning( disable: 4054 )	/* Cast from fn.ptr -> generic (data) ptr.*/
279   #pragma warning( disable: 4055 )	/* Cast from generic (data) ptr. -> fn.ptr.*/
280   #pragma warning( disable: 4057 )	/* Different types via indirection */
281   #pragma warning( disable: 4204 )	/* Struct initialised with non-const value */
282   #pragma warning( disable: 4206 )	/* Empty C module due to #ifdef'd out code */
283   #pragma warning( disable: 4221 )	/* Struct initialised with addr.of auto.var */
284   #if VC_GE_2005( _MSC_VER )
285 	#pragma warning( disable: 4267 )/* int <-> size_t */
286   #endif /* VC++ 2005 or newer */
287 
288   /* Different versions of VC++ generates extra warnings at level 4 due to
289 	 problems in VC++/Platform SDK headers */
290   #pragma warning( disable: 4201 )/* Nameless struct/union in SQL/networking hdrs*/
291   #if VC_GE_2005( _MSC_VER )
292 	#pragma warning( disable: 4214 )/* bit field types other than int */
293   #endif /* VC++ 2005 or newer */
294 
295   /* Code analysis generates even more warnings.  C6011 is particularly
296 	 problematic, it's issued whenever a pointer is derefenced without first
297 	 checking that it's not NULL, which makes it more or less unusable */
298   #if defined( _MSC_VER ) && defined( _PREFAST_ )
299 	#pragma warning( disable: 6011 )/* Deferencing NULL pointer */
300   #endif /* VC++ with source analysis enabled */
301 
302   /* Windows DDK free builds treat warnings as errors and the DDK headers
303 	 have some problems so we have to disable additional warnings */
304   #ifdef WIN_DDK
305 	#pragma warning( disable: 4242 )/* MS-only bit field type used */
306 	#pragma warning( disable: 4731 )/* Frame pointer modified by inline asm */
307   #endif /* WIN_DDK */
308 
309   /* gcc -wall type warnings.  The highest warning level generates large
310 	 numbers of spurious warnings (including ones in VC++ headers), so it's
311 	 best to only enable them for one-off test builds requiring manual
312 	 checking for real errors */
313   #pragma warning( disable: 4100 )	/* Unreferenced parameter */
314 #endif /* Visual C++ */
315 
316 /* Under VC++/VS a number of warnings are disabled by default, including
317    some potentially useful ones, so we re-enable them.  The warnings are:
318 
319 	C4242 'identifier': conversion from 'type1' to 'type2', possible loss of
320 		  data.
321 	C4255 'function': no function prototype given: converting '()' to
322 		  '(void)'.
323 	C4287 'operator': unsigned/negative constant mismatch.
324 	C4296 'operator': expression is always false.
325 	C4302 'conversion' : truncation from 'type 1' to 'type 2'.
326 	C4311 'variable' : pointer truncation from 'type' to 'type'.
327 	C4431 missing type specifier - int assumed.
328 	C4545 expression before comma evaluates to a function which is missing
329 		  an argument list.
330 	C4546 function call before comma missing argument list.
331 	C4547 'operator' : operator before comma has no effect; expected
332 		  operator with side-effect.
333 	C4548 expression before comma has no effect; expected expression with
334 		  side-effect.
335 	C4549 'operator' : operator before comma has no effect; did you intend
336 		  'operator'?
337 	C4555 expression has no effect; expected expression with side-effect.
338 	C4619 #pragma warning : there is no warning number 'number'.
339 	C4668 'symbol' is not defined as a preprocessor macro, replacing with
340 		  '0' for 'directives'.
341 		  Note that enabling this check causes warnings in Windows header
342 		  files.
343 	C4826 Conversion from 'type1 ' to 'type2' is sign-extended.
344 
345    These are all defined only for newer versions of VC++ (2005 and 2010), so
346    they need a recent compiler in order to be evaluated.
347 
348    These versions also have the potentially useful warning 'C4390 empty
349    controlled statement found' (e.g. 'if( i );'), on by default for W3 and
350    above, however this warning has no effect in either VS 2005 or VS 2010,
351    it seems to be triggered by random misplaced semicolons rather than the
352    presence of empty controlled statements, e.g. 'if( foo; )' */
353 
354 #if defined( _MSC_VER )
355   #pragma warning( 3: 4242 )
356   #pragma warning( 3: 4255 )
357   #pragma warning( 3: 4287 )
358   #pragma warning( 3: 4302 )
359   #pragma warning( 3: 4311 )
360   #pragma warning( 3: 4296 )
361   #pragma warning( 3: 4431 )
362   #pragma warning( 3: 4545 )
363   #pragma warning( 3: 4546 )
364   #pragma warning( 3: 4547 )
365   #pragma warning( 3: 4548 )
366   #pragma warning( 3: 4549 )
367   #pragma warning( 3: 4555 )
368   #pragma warning( 3: 4619 )
369   #pragma warning( 3: 4668 )
370   #pragma warning( 3: 4826 )
371 #endif /* Visual C++ */
372 
373 /* VC++ 2005 implements the TR 24731 security extensions but doesn't yet
374    define __STDC_LIB_EXT1__, so if we detect this version of the compiler we
375    define it ourselves */
376 
377 #if defined( _MSC_VER ) && VC_GE_2005( _MSC_VER ) && \
378 	!defined( __STDC_LIB_EXT1__ )
379   #define __STDC_LIB_EXT1__
380 #endif /* VC++ 2005 without __STDC_LIB_EXT1__ defined */
381 
382 /* The ability to modify warnings via the project file in BC++ 5.0x is
383    completely broken, the only way to do this is via pragmas in the source
384    code */
385 
386 #if defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x550 )
387   /* Spurious warnings to disable */
388   #pragma warn -aus						/* Assigned but never used.  This is
389 										   frequently misreported even when
390 										   the value is quite obviously used */
391   #pragma warn -csu						/* Comparing signed/unsigned value */
392   #pragma warn -par						/* Parameter is never used	*/
393   #pragma warn -sig						/* Conversion may lose significant digits */
394   #pragma warn -ucp						/* Signed/unsigned char assignment */
395 
396   /* Useful warnings to enable */
397   #pragma warn +amb						/* Ambiguous operators need parentheses */
398   #pragma warn +amp						/* Superfluous & with function */
399   #pragma warn +asm						/* Unknown assembler instruction */
400   #pragma warn +ccc						/* Condition is always true/false */
401   #pragma warn +cln						/* Constant is long */
402   #pragma warn +def						/* Use of ident before definition */
403   #pragma warn +stv						/* Structure passed by value */
404 #endif /* Broken BC++ 5.0x warning handling */
405 
406 /* The TI compiler needs to have a few annoying warnings disabled */
407 
408 #if defined( __TI_COMPILER_VERSION__ )
409   #pragma diag_suppress 190				/* enum vs. int */
410 #endif /* TI compiler */
411 
412 /* All Windows CE functions are Unicode-only, this was an attempt to clean
413    up the ASCII vs. Unicode kludges in Win32 but unfortunately was made just
414    before UTF8 took off.  Because UTF8 allows everyone to keep using their
415    old ASCII stuff while being nominally Unicode-aware, it's unlikely that
416    any new Unicode-only systems will appear in the future, leaving WinCE's
417    Unicode-only API an orphan.  The easiest way to handle this is to convert
418    all strings to ASCII/8 bit as they come in from the external cryptlib API
419    and convert them back to Unicode as required when they're passed to WinCE
420    OS functions.  In other words Unicode is treated just like EBCDIC and
421    pushed out to the edges of cryptlib.  This requires the minimum amount of
422    conversion and special-case handling internally */
423 
424 #ifdef __WINCE__
425   #define UNICODE_CHARS
426 #endif /* WinCE */
427 
428 /* Include stdint.h if it's available, since this greatly simplifies the
429    handling of data types in a portable manner */
430 
431 #if defined( __STDC_VERSION__ ) && ( __STDC_VERSION__ >= 199901L )
432   /* stdint.h via C99 compatibility */
433   #include <stdint.h>
434 #elif defined( __GNUC__ ) && ( __GNUC__ > 3 )
435   /* stdint.h via GNU headers */
436   #include <stdint.h>
437 #elif defined( _MSC_VER ) && VC_GE_2015( _MSC_VER )
438   /* stdint.h via Visual Studio */
439   #include <stdint.h>
440 #elif defined( _MSC_VER )
441   #ifdef __WIN64__
442 	typedef unsigned __int64	uintptr_t;
443   #else
444 	typedef unsigned long		uintptr_t;
445   #endif /* 64- vs 32-bit systems */
446 #else
447   #if ULONG_MAX > 0xFFFFFFFFUL
448 	typedef unsigned long long	uintptr_t;
449   #else
450 	typedef unsigned long		uintptr_t;
451   #endif /* 64- vs 32-bit systems */
452 #endif /* Various stdint.h options */
453 
454 /* If we're compiling on the AS/400, make enums a fixed size rather than
455    using the variable-length values that IBM compilers default to, and force
456    strings into a read-only segment (by default they're writeable) */
457 
458 #ifdef __AS400__
459   #pragma enumsize( 4 )
460   #pragma strings( readonly )
461   #define EBCDIC_CHARS
462 #endif /* AS/400 */
463 
464 /* If we're compiling under MVS or VM/CMS, make enums a fixed size rather
465    than using the variable-length values that IBM compilers default to */
466 
467 #if defined( __MVS__ ) || defined( __VMCMS__ )
468   #pragma enum( 4 )
469   #define USE_ETOA		/* Use built-in ASCII <-> EBCDIC conversion */
470   #define EBCDIC_CHARS
471 #endif /* __MVS__ */
472 
473 /* If we're compiling under QNX, make enums a fixed size rather than using
474    the variable-length values that the Watcom compiler defaults to */
475 
476 #if defined( __QNX__ ) && defined( __WATCOMC__ )
477   #pragma enum int
478 #endif /* QNX and Watcom C */
479 
480 /* Symbian has rather inconsistent defines depending in which toolchain
481    we're using, with the original ARM tools the define was __SYMBIAN32__
482    with __MARM__ for the ARM architecture, with the ex-Metrowerks Nokia
483    compiler the define is __EMU_SYMBIAN_OS__ for the emulated environment
484    and who knows what for the gcc toolchain.  To make checking easier we
485    require __SYMBIAN32__ for all environments, with __MARM__ vs.
486    __EMU_SYMBIAN_OS__ distinguishing between ARM and x86 emulator */
487 
488 #if defined( __EMU_SYMBIAN_OS__ ) && !defined( __SYMBIAN32__ )
489   #error Need to define '__SYMBIAN32__' for the Symbian build
490 #endif /* __EMU_SYMBIAN_OS__ && !__SYMBIAN32__ */
491 #if defined( __SYMBIAN32__ ) && \
492 	!( defined( __MARM__ ) || defined( __EMU_SYMBIAN_OS__ ) )
493   #error Need to define a Symbian target architecture type, e.g. ARM or x86
494 #endif /* __SYMBIAN32__ && !( __MARM__ || __EMU_SYMBIAN_OS__ ) */
495 
496 /* A few rare operations are word-size-dependant */
497 
498 #if INT_MAX <= 32768L
499   #define SYSTEM_16BIT
500 #elif ULONG_MAX > 0xFFFFFFFFUL
501   #define SYSTEM_64BIT
502 #else
503   #define SYSTEM_32BIT
504 #endif /* 16- vs.32- vs.64-bit system */
505 
506 /* Useful data types.  Newer compilers provide a 'bool' datatype via
507    stdbool.h, but in a fit of braindamage generally make this a char instead
508    of an int.  While Microsoft's use of char for BOOLEAN in the early 1980s
509    with 8/16-bit 8086s and 129K of RAM makes sense, it's a pretty stupid
510    choice for 32- or 64-bit CPUs because alignment issues mean that it'll
511    generally still require 32 or 64 bits of storage (except for special
512    cases like an array of bool), but then the difficulty or even inability
513    of many CPUs and/or architectures in performing byte-level accesses means
514    that in order to update a boolean the system has to fetch a full machine
515    word, mask out the byte data, or/and in the value, and write the word
516    back out.  So 'bool' = 'char' combines most of the worst features of both
517    char and int.  It also leads to really hard-to-find implementation bugs
518    due to the fact that '(bool) int = true' produces different results to
519    '*(bool *) intptr = true', something that was resolved years ago in enums
520    without causing such breakage.
521 
522    Because of this we avoid the use of bool and just define it to int */
523 
524 typedef unsigned char		BYTE;
525 #if defined( __STDC_VERSION__ ) && ( __STDC_VERSION__ >= 199901L ) && 0
526   #include <stdbool.h>
527   typedef bool              BOOLEAN;
528 #elif defined( __WIN32__ ) || defined( __WINCE__ )
529   /* VC++ typedefs BOOLEAN so we need to use the preprocessor to override it */
530   #define BOOLEAN			int
531 #elif defined( __UCOS__ ) || defined( __SMX__ )
532   /* Some OSes typedef BOOLEAN themselves so we set it as a #define, which
533 	 means that we can then work around the typedef by undefining and
534 	 redefining it around the include of the OS-specific headers:
535 
536 		#undef BOOLEAN
537 		#include <smx.h>
538 		#define BOOLEAN int */
539   #if defined( __SMX__ ) && !defined( _MSC_VER )
540 	typedef int				BOOLEAN
541   #else
542 	#define BOOLEAN			int
543   #endif /* OS-specific BOOLEAN juggling */
544 #elif defined( __Nucleus__ )
545   /* Nucleus defines BOOLEAN as 'unsigned char' so we override it to be an
546      int */
547   #undef  BOOLEAN
548   #define BOOLEAN			int
549 #else
550   typedef int				BOOLEAN;
551 #endif /* Boolean data type on different platforms */
552 
553 /* If we're building the Win32 kernel driver version, include the DDK
554    headers */
555 
556 #if defined( __WIN32__ ) && defined( NT_DRIVER )
557   #include <ntddk.h>
558 #endif /* NT kernel driver */
559 
560 /* In 16-bit environments the BSS data is large enough that it overflows the
561    (64K) BSS segment.  Because of this we move as much of it as possible
562    into its own segment with the following define */
563 
564 #if defined( __WIN16__ )
565   #ifdef _MSC_VER
566 	#define FAR_BSS	__far
567   #else
568 	#define FAR_BSS	far
569   #endif /* VC++ vs.other compilers */
570 #else
571   #define FAR_BSS
572 #endif /* 16-bit systems */
573 
574 /* If we're using eCOS, include the system config file that tells us which
575    parts of the eCOS kernel are available */
576 
577 #ifdef __ECOS__
578   #include <pkgconf/system.h>
579 #endif /* __ECOS__ */
580 
581 /* The VxWorks SDK defines the value 'SH' (to indicate the use of SuperH
582    CPU family) in vxCpu.h which conflicts with the 'struct SH' in ssh.h.
583    To fix this we undefine it, this shouldn't be a problem since the define
584    SH32 is set to the same value as SH and presumably no-one will be using
585    the basic 20-year-old SuperH any more.
586 
587    VxWorks also uses some global symbols that clash with cryptlib's ones,
588    to resolve this we redefine the cryptlib ones to have a 'cl_' prefix */
589 
590 #ifdef __VxWorks__
591   /* Correct the use of the VxWorks preprocessor define 'SH' overriding
592      'struct SH' in ssh.h */
593   #if defined( SH )
594 	#undef SH
595   #endif /* SH */
596 
597   /* Correct clashing global symbols in VxWorks */
598   #define setSerialNumber		cl_setSerialNumber
599   #define inflate				cl_inflate
600   #define addAction				cl_addAction
601   #define inflate_copyright		cl_inflate_copyright
602   #define zlibVersion			cl_zlibVersion
603 #endif /* __VxWorks__ */
604 
605 /* Some versions of the WinCE SDK define 'interface' as part of a complex
606    series of kludges for OLE support (made even more amusing by the fact
607    that 'interface' is an optional keyword in eVC++ which may or may not
608    be recognised as such by the compiler), to avoid conflicts we undefine
609    it if it's defined since we're not using any OLE functionality */
610 
611 #if defined( __WINCE__ ) && defined( interface )
612   #undef interface
613 #endif /* WinCE SDK */
614 
615 /* Some systems (typically 16-bit or embedded ones) have rather limited
616    amounts of memory available, if we're building on one of these we limit
617    the size of some of the buffers that we use and the size of the object
618    table */
619 
620 #if defined( __MSDOS16__ ) || defined( __uClinux__ )
621   #define CONFIG_CONSERVE_MEMORY
622   #define CONFIG_NUM_OBJECTS		128
623 #endif /* Memory-starved systems */
624 
625 /* Since the Win32 randomness-gathering uses a background randomness polling
626    thread, we can't build a Win32 version with NO_THREADS */
627 
628 #if defined( __WIN32__ ) && defined( NO_THREADS )
629   #error The Win32 version of cryptlib must have threading enabled
630 #endif /* Win32 without threading */
631 
632 /* Boolean constants */
633 
634 #ifndef TRUE
635   #define FALSE			0
636   #define TRUE			!FALSE
637 #endif /* Boolean values */
638 
639 /* cryptlib contains a few locations that require forward declarations for
640    static data:
641 
642 	extern const int foo[];
643 
644 	foo[ i ] = bar;
645 
646 	static const int foo[] = { ... };
647 
648    Compiler opinions on how to handle this vary.  Some compile it as is
649    (i.e. 'static const ...'), some don't allow the 'static', some allow both
650    variants, and some produce warnings with both but allow them anyway
651    (there are probably more variants with further compilers).  To get around
652    this, we use the following define and then vary it for broken compilers
653    (the following is the minimum required to get it to compile, other broken
654    compilers will still produce warnings) */
655 
656 #if ( defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x550 ) ) || \
657 	defined( __VMCMS__ ) || defined( __MVS__ ) || defined( __MRC__ ) || \
658 	defined( __TANDEM_NSK__ ) || defined( __TANDEM_OSS__ ) || \
659 	( defined( __UNIX__ ) && ( defined( __HP_cc ) || defined( __HP_aCC ) ) ) || \
660 	( defined( __UNIX__ ) && defined( _MPRAS ) )
661   #define STATIC_DATA
662 #else
663   #define STATIC_DATA	static
664 #endif /* Fn.prototyping workarounds for borken compilers */
665 
666 /* A few compilers won't allow initialisation of a struct at runtime, so
667    we have to kludge the init with macros.  This is rather ugly since
668    instead of saying "struct = { a, b, c }" we have to set each field
669    individually by name.  The real reason for doing this though is that
670    if the compiler can initialise the struct directly, we can make the
671    fields const for better usage checking by the compiler.
672 
673    There are two forms of this, one for simple structs and one for arrays
674    of structs.  At the moment the only use for the array-init is for the
675    situation where the array represents a sequence of search options with
676    the last one being a terminator entry, so we provide a simplified form
677    that only sets the required fields.
678 
679    The value of __SUNPRO_C bears no relation whatsoever to the actual
680    version number of the compiler and even Sun's docs give different values
681    in different places for the same compiler version, but 0x570 seems to
682    work */
683 
684 #if ( defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x550 ) ) || \
685 	defined( _CRAY ) || \
686 	( defined( __hpux ) && !defined( __GNUC__ ) ) || \
687 	( defined( __QNX__ ) && ( OSVERSION <= 4 ) ) || \
688 	defined( __RVCT2_1__ ) || \
689 	( defined( __SUNPRO_C ) && ( __SUNPRO_C <= 0x570 ) ) || \
690 	defined( __SCO_VERSION__ ) || defined(  __TANDEM )
691   #define CONST_INIT
692   #define CONST_INIT_STRUCT_3( decl, init1, init2, init3 ) \
693 		  decl
694   #define CONST_INIT_STRUCT_4( decl, init1, init2, init3, init4 ) \
695 		  decl
696   #define CONST_INIT_STRUCT_5( decl, init1, init2, init3, init4, init5 ) \
697 		  decl
698   #define CONST_SET_STRUCT( init ) \
699 		  init
700 
701   #define CONST_INIT_STRUCT_A2( decl, init1, init2 ) \
702 		  decl
703   #define CONST_SET_STRUCT_A( init ) \
704 		  init
705 #else
706   #define CONST_INIT	const
707   #define CONST_INIT_STRUCT_3( decl, init1, init2, init3 ) \
708 		  decl = { init1, init2, init3 }
709   #define CONST_INIT_STRUCT_4( decl, init1, init2, init3, init4 ) \
710 		  decl = { init1, init2, init3, init4 }
711   #define CONST_INIT_STRUCT_5( decl, init1, init2, init3, init4, init5 ) \
712 		  decl = { init1, init2, init3, init4, init5 }
713   #define CONST_SET_STRUCT( init )
714 
715   #define CONST_INIT_STRUCT_A2( decl, init1, init2 ) \
716 		  const decl = { { init1, 0 }, { init2, 0 } }
717   #define CONST_SET_STRUCT_A( init )
718 #endif /* Watcom C || SunPro C || SCO C */
719 
720 /* The Tandem mktime() is broken and can't convert dates beyond 2023, so we
721    replace it with our own version which can */
722 
723 #if defined( __TANDEM_NSK__ ) || defined( __TANDEM_OSS__ )
724   #define mktime	my_mktime
725 #endif /* __TANDEM_NSK__ || __TANDEM_OSS__ */
726 
727 /* Enable use of assembly-language alternatives to C functions if possible.
728    Note that the following asm defines are duplicated in crypt/osconfig.h,
729    because the OpenSSL headers are non-orthogonal to the cryptlib ones.  Any
730    changes made here need to be reflected in osconfig.h */
731 
732 #if defined( __WIN32__ ) && \
733 	!( defined( __WIN64__ ) || defined( __BORLANDC__ ) || defined( NO_ASM ) )
734   /* Enable use of the AES ASM code */
735   #define AES_ASM
736 
737   /* Enable use of zlib ASM longest-match and decompression code.  Assemble
738      with "ml /Zp /coff /c gvmat32.asm" and "yasm -f win32 inffas32y.asm" */
739   #define ASMV
740   #define ASMINF
741 #endif /* Win32 */
742 
743 /* Alongside the general crypto asm code there's also inline asm to handle
744    things like CPU hardware features, if we're running under Win64 we have
745    to disable this as well */
746 
747 #if defined( __WIN64__ )
748   #define NO_ASM
749 #endif /* Win64 */
750 
751 /* In some environments va_list is a scalar, so it can't be compared with
752    NULL in order to verify its validity.  This was particularly problematic
753    with the ARM ABI, which changed the type in late 2009 to
754    'struct __va_list { void *__ap; }', breaking compatibility with all
755    existing code.  We can detect this by taking advantage of the fact that
756    support for the change was added in gcc 4.4, so any newer version with
757    ARM_EABI defined will have a scalar va_list.
758 
759    Super-H variants also have scalar va_lists, the Super-H varargs header
760    va-sh.h uses a complex structure to handle va_lists for all SH3 and SH4
761    variants, this presumably extends to SH5 as well so we treat va_lists on
762    Super-H as scalars */
763 
764 #if 1
765   #if defined( __ARM_EABI__ )
766 	/* In theory we could check __ap but in practice it's too risky to rely
767 	   on the type and state of hidden internal fields, and in any case it's
768 	   only a sanity check, not a hard requirement, so we just no-op the
769 	   check out */
770 	#define verifyVAList( x ) TRUE
771   #elif defined( __sh__ )
772 	#define verifyVAList( x ) TRUE
773   #endif /* Architecture-specific scalar va_lists */
774 #elif defined( __RVCT2_1__ ) || defined( __IAR_SYSTEMS_ICC__ )
775   /* The RealView and IAR compilers have the same issue */
776   #define verifyVAList( x ) TRUE
777 #endif /* Nonstandard va_list types */
778 #ifndef verifyVAList
779   #define verifyVAList( x ) ( ( x ) != NULL )
780 #endif /* Verify function for vector arg lists */
781 
782 /* cryptlib has many code sequences of the form:
783 
784 	status = foo();
785 	if( cryptStatusOK( status ) )
786 		status = bar();
787 	if( cryptStatusOK( status ) )
788 		status = baz();
789 	if( cryptStatusOK( status ) )
790 		...
791 
792    These can be made more efficient when the compiler can assume that the
793    majority case has 'status == CRYPT_OK'.  gcc provides a means of doing
794    this via __builtin_expect().  As usual for gcc the documentation for this
795    is quite confusing:
796 
797      "if( __builtin_expect( x, 0 ) ) foo (); would indicate that we do not
798 	 expect to call foo, since we expect x to be zero"
799 
800    In this case the test is actually the expression 'x', which is evaluated
801    as 'x != 0', with the second parameter only taking values 0 (to mean 'not
802    likely') or 1 (to mean 'likely').  So the appropriate usage is
803    "__builtin_expect( expr, 0 )" to mean that we don't expect something and
804    "__builtin_expect( expr, 1 )" to mean that we do expect it.  The
805    following forms of cryptStatusError() and cryptStatusOK() assume that in
806    the majority of situations we won't encounter the error case */
807 
808 #if defined( __GNUC__ ) && ( __GNUC__ >= 3 )
809   #undef cryptStatusError
810   #undef cryptStatusOK
811   #define cryptStatusError( status ) \
812 		  __builtin_expect( ( status ) < CRYPT_OK, 0 )
813   #define cryptStatusOK( status ) \
814 		  __builtin_expect( ( status ) == CRYPT_OK, 1 )
815 #endif /* gcc 3.x and newer */
816 
817 /* Nucleus has it's own functions for allocating and freeing memory, so
818    we provide wrappers for them that override the default clAlloc()/clFree()
819    mappings */
820 
821 #ifdef __Nucleus__
822   #define clAlloc( string, size )		clAllocFn( size )
823   #define clFree( string, memblock )	clFreeFn( memblock )
824   void *clAllocFn( size_t size );
825   void clFreeFn( void *memblock );
826 #endif /* __Nucleus__ */
827 
828 /****************************************************************************
829 *																			*
830 *								Dynamic Loading Support						*
831 *																			*
832 ****************************************************************************/
833 
834 /* On systems that support dynamic loading, we bind various drivers and
835    libraries at runtime rather than at compile time.  Under Windows this is
836    fairly easy but under Unix it's supported somewhat selectively and may be
837    buggy or platform-specific */
838 
839 #if defined( __WINDOWS__ ) || \
840 	( defined( __UNIX__ ) && \
841 	  ( ( defined( sun ) && OSVERSION > 4 ) || defined( __linux__ ) || (defined(__FreeBSD__)||defined(__DragonFly__)) || \
842 		defined( _AIX ) || ( defined( __APPLE__ ) && !defined( __MAC__ ) ) ) ) || \
843 	defined( __ANDROID__ )
844   #define DYNAMIC_LOAD
845 
846   /* Macros to map OS-specific dynamic-load values to generic ones */
847   #if defined( __WINDOWS__ )
848 	#define INSTANCE_HANDLE		HINSTANCE
849 	#define NULL_INSTANCE		( HINSTANCE ) NULL
850 	#ifdef __WINCE__
851 	  #define DynamicLoad( name ) LoadLibrary( name )
852 	#else
853 	  #define DynamicLoad( name ) SafeLoadLibrary( name )
854 	#endif /* Win32 vs. WinCE */
855 	#define DynamicUnload		FreeLibrary
856 	#define DynamicBind			GetProcAddress
857   #elif defined( __UNIX__ ) || defined( __ANDROID__ )
858     /* Older versions of OS X didn't have dlopen() support but required
859 	   the use of the rather painful low-level dyld() interface.  If you're
860 	   running an older version of OS X and don't have the dlcompat wrapper
861 	   installed, get Peter O'Gorman's dlopen() implementation, which wraps
862 	   the dyld() interface */
863 	#include <dlfcn.h>
864 	#define INSTANCE_HANDLE		void *
865 	#define NULL_INSTANCE		NULL
866 	#define DynamicLoad( name )	dlopen( name, RTLD_LAZY )
867 	#define DynamicUnload		dlclose
868 	#define DynamicBind			dlsym
869   #elif defined __VMCMS__
870 	#include <dll.h>
871 
872 	#define INSTANCE_HANDLE		dllhandle *
873 	#define NULL_INSTANCE		NULL
874 	#define DynamicLoad( name )	dllload( name, RTLD_LAZY )
875 	#define DynamicUnload		dllfree
876 	#define DynamicBind			dlqueryfn
877   #endif /* OS-specific instance handles */
878 #endif /* Windows || Some Unix versions */
879 
880 /****************************************************************************
881 *																			*
882 *								Endianness Defines							*
883 *																			*
884 ****************************************************************************/
885 
886 /* If the endianness isn't predefined and the compiler can tell us what
887    endianness we've got, use this in preference to all other methods.  This
888    is only really necessary on non-Unix systems since the makefile runtime
889    test will tell us the endianness under Unix */
890 
891 #if defined( CONFIG_DATA_LITTLEENDIAN ) || defined( CONFIG_DATA_BIGENDIAN )
892   /* If we're cross-compiling for another system, the endianness auto-
893 	 detection will have been overridden.  In this case we force it to be
894 	 what the user has specified rather than what we've auto-detected */
895   #undef DATA_LITTLEENDIAN
896   #undef DATA_BIGENDIAN
897   #ifdef CONFIG_DATA_LITTLEENDIAN
898 	#define DATA_LITTLEENDIAN
899   #else
900 	#define DATA_BIGENDIAN
901   #endif /* CONFIG_DATA_LITTLEENDIAN */
902 #endif /* Forced big vs.little-endian */
903 
904 #if !defined( DATA_LITTLEENDIAN ) && !defined( DATA_BIGENDIAN )
905   #if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN ) && defined( BYTE_ORDER )
906 	/* Some systems define both BIG_ENDIAN and LITTLE_ENDIAN, then define
907 	   BYTE_ORDER to the appropriate one, so we check this and define the
908 	   appropriate value */
909 	#if ( BYTE_ORDER == BIG_ENDIAN ) && !defined( DATA_BIGENDIAN )
910 	  #define DATA_BIGENDIAN
911 	#elif ( BYTE_ORDER == LITTLE_ENDIAN ) && !defined( DATA_LITTLEENDIAN )
912 	  #define DATA_LITTLEENDIAN
913 	#else
914 	  #error BYTE_ORDER is neither BIG_ENDIAN nor LITTLE_ENDIAN
915 	#endif /* BYTE_ORDER-specific define */
916   #elif defined( _M_I86 ) || defined( _M_IX86 ) || defined( _M_X64 ) || \
917 		defined( __TURBOC__ ) || defined( __OS2__ )
918 	#define DATA_LITTLEENDIAN	/* Intel architecture always little-endian */
919   #elif defined( __WINCE__ )
920 	/* For WinCE it can get a bit complicated, however because of x86 cargo
921 	   cult programming WinCE systems always tend to be set up in little-
922 	   endian mode */
923 	#define DATA_LITTLEENDIAN	/* Intel architecture always little-endian */
924   #elif defined( AMIGA ) || defined( __MWERKS__ ) || defined( SYMANTEC_C ) || \
925 		defined( THINK_C ) || defined( applec ) || defined( __MRC__ )
926 	#define DATA_BIGENDIAN		/* Motorola architecture always big-endian */
927   #elif defined( VMS ) || defined( __VMS )
928 	#define DATA_LITTLEENDIAN	/* VAX architecture always little-endian */
929   #elif defined( __TANDEM_NSK__ ) || defined( __TANDEM_OSS__ )
930 	#define DATA_BIGENDIAN		/* Tandem architecture always big-endian */
931   #elif defined( __AS400__ ) || defined( __VMCMS__ ) || defined( __MVS__ )
932 	#define DATA_BIGENDIAN		/* IBM big iron always big-endian */
933   #elif defined( __SYMBIAN32__ ) && \
934 		( defined( __MARM__ ) || defined( __EMU_SYMBIAN_OS__ ) )
935 	#define DATA_LITTLEENDIAN	/* Symbian on ARM/x86 always little-endian */
936   #elif defined( __Nucleus__ ) && defined( __RVCT2_1__ )
937 	#if defined( __BIG_ENDIAN )	/* Realview for Nucleus */
938 	  #define DATA_BIGENDIAN
939 	#else
940 	  #define DATA_LITTLEENDIAN
941 	#endif /* Big vs.little-endian */
942   #elif defined( __m68k__  )
943 	#define DATA_BIGENDIAN		/* 68K always big-endian */
944   #elif defined( __TI_COMPILER_VERSION__ )
945 	/* The TI compiler can masquerade as gcc so we need to check for it
946 	   before we check for Gnu indicators */
947 	#if CPU_BYTE_ORDER == LOW_BYTE_FIRST
948 	  #define DATA_LITTLEENDIAN
949 	#elif CPU_BYTE_ORDER == HIGH_BYTE_FIRST
950 	  #define DATA_BIGENDIAN
951 	#else
952 	  #error Couldnt get endianness from CPU_BYTE_ORDER
953 	#endif /* TI compiler endianness detection */
954   #elif defined __GNUC__
955 	#ifdef BYTES_BIG_ENDIAN
956 	  #define DATA_BIGENDIAN	/* Big-endian byte order */
957 	#else
958 	  #define DATA_LITTLEENDIAN	/* Undefined = little-endian byte order */
959 	#endif /* __GNUC__ */
960   #endif /* Compiler-specific endianness checks */
961 #endif /* !( DATA_LITTLEENDIAN || DATA_BIGENDIAN ) */
962 
963 /* The last-resort method.  Thanks to Shawn Clifford
964    <sysop@robot.nuceng.ufl.edu> for this trick.
965 
966    NB: A number of compilers aren't tough enough for this test */
967 
968 #if !defined( DATA_LITTLEENDIAN ) && !defined( DATA_BIGENDIAN )
969   #if ( ( ( unsigned short ) ( 'AB' ) >> 8 ) == 'B' )
970 	#define DATA_LITTLEENDIAN
971   #elif ( ( ( unsigned short ) ( 'AB' ) >> 8 ) == 'A' )
972 	#define DATA_BIGENDIAN
973   #else
974 	#error "Cannot determine processor endianness - edit misc/os_spec.h and recompile"
975   #endif /* Endianness test */
976 #endif /* !( DATA_LITTLEENDIAN || DATA_BIGENDIAN ) */
977 
978 /* Sanity check to catch both values being defined */
979 
980 #if defined( DATA_LITTLEENDIAN ) && defined( DATA_BIGENDIAN )
981   #error Both DATA_LITTLEENDIAN and DATA_BIGENDIAN are defined
982 #endif /* DATA_LITTLEENDIAN && DATA_BIGENDIAN */
983 
984 /****************************************************************************
985 *																			*
986 *								Filesystem Values							*
987 *																			*
988 ****************************************************************************/
989 
990 /* When performing file I/O we need to know how large path names can get in
991    order to perform range checking and allocate buffers.  This gets a bit
992    tricky since not all systems have PATH_MAX, so we first try for PATH_MAX,
993    if that fails we try _POSIX_PATH_MAX (which is a generic 255 bytes and if
994    defined always seems to be less than whatever the real PATH_MAX should be),
995    if that also fails we grab stdio.h and try and get FILENAME_MAX, with an
996    extra check for PATH_MAX in case it's defined in stdio.h instead of
997    limits.h where it should be.  FILENAME_MAX isn't really correct since it's
998    the maximum length of a filename rather than a path, but some environments
999    treat it as if it were PATH_MAX and in any case it's the best that we can
1000    do in the absence of anything better */
1001 
1002 #if defined( PATH_MAX )
1003   #define MAX_PATH_LENGTH		PATH_MAX
1004 #elif defined( _POSIX_PATH_MAX )
1005   #define MAX_PATH_LENGTH		_POSIX_PATH_MAX
1006 #elif defined( __FileX__ )
1007   #define MAX_PATH_LENGTH		FX_MAXIMUM_PATH
1008 #else
1009   #ifndef FILENAME_MAX
1010 	#include <stdio.h>
1011   #endif /* FILENAME_MAX */
1012   #if defined( PATH_MAX )
1013 	#define MAX_PATH_LENGTH		PATH_MAX
1014   #elif defined( MAX_PATH )
1015 	#define MAX_PATH_LENGTH		MAX_PATH
1016   #elif defined( FILENAME_MAX )
1017 	#define MAX_PATH_LENGTH		FILENAME_MAX
1018   #elif defined( __MSDOS16__ )
1019 	#define FILENAME_MAX	80
1020   #else
1021 	#error Need to add a MAX_PATH_LENGTH define in misc/os_spec.h
1022   #endif /* PATH_MAX, MAX_PATH, or FILENAME_MAX */
1023 #endif /* PATH_MAX */
1024 #if MAX_PATH_LENGTH <= 32
1025   #error MAX_PATH_LENGTH is <= 32 characters, check your build environment
1026 #endif /* Too-short MAX_PATH values */
1027 
1028 /* SunOS 4 doesn't have memmove(), but Solaris does, so we define memmove()
1029    to bcopy() under 4.  In addition SunOS doesn't define the fseek()
1030    position indicators so we define these as well */
1031 
1032 #if defined( __UNIX__ ) && defined( sun ) && ( OSVERSION == 4 )
1033   #define memmove				bcopy
1034 
1035   #define SEEK_SET				0
1036   #define SEEK_CUR				1
1037   #define SEEK_END				2
1038 #endif /* SunOS 4 */
1039 
1040 /****************************************************************************
1041 *																			*
1042 *									Charset Support							*
1043 *																			*
1044 ****************************************************************************/
1045 
1046 /* Widechar handling.  Most systems now support this, the only support that
1047    we require is the wchar_t type define.
1048 
1049    Unfortunately in order to check for explicitly enabled widechar support
1050    via config.h we have to include config.h at this point, because this
1051    file, containing OS- and compiler-specific settings, both detects the
1052    OSes and compilers that support widechars in the "OS Detection" section
1053    above, and then sets the appropriate widechar settings here.  In between
1054    the two, config.h uses the OS/compiler-detection output to enable or
1055    disable widechars as required, so we need to slip it in between the two
1056    sections */
1057 
1058 #if defined( INC_ALL )
1059   #include "config.h"
1060 #else
1061   #include "misc/config.h"
1062 #endif /* Compiler-specific includes */
1063 
1064 #ifdef USE_WIDECHARS
1065   #if !( defined( __ECOS__ ) || \
1066 		 ( defined( __QNX__ ) && ( OSVERSION <= 4 ) ) || \
1067 		 ( defined( __WIN32__ ) && defined( __BORLANDC__ ) ) || \
1068 		 ( defined( __WINCE__ ) && _WIN32_WCE < 400 ) || \
1069 		 defined( __XMK__ ) )
1070 	#include <wchar.h>
1071   #endif /* Systems with widechar support in stdlib.h */
1072 #else
1073   /* No native widechar support, define the necesary types ourselves unless
1074 	 we're running under older OS X (Darwin 6.x), which defines wchar_t in
1075 	 stdlib.h even though there's no wchar support present, or PalmOS, which
1076 	 defines it in wchar.h but then defines it differently in stddef.h, and
1077 	 in any case has no wchar support present */
1078   #if !( defined( __APPLE__ ) || defined( __MVS__ ) || \
1079 		 defined( __OpenBSD__ ) || defined( __PALMOS__ ) || \
1080 		 defined( __SMX__ ) )
1081 	typedef unsigned short int wchar_t;
1082   #endif /* __APPLE__ */
1083 #endif /* USE_WIDECHARS */
1084 #define WCSIZE					( sizeof( wchar_t ) )
1085 #ifndef WCHAR_MAX
1086   #define WCHAR_MAX				( ( wchar_t ) -1 )
1087 #endif /* !WCHAR_MAX */
1088 
1089 /* The EOL convention used when outputting text.  Technically speaking
1090    Nucleus, SMX, and XMK don't use any particular EOL convention, but since
1091    the typical development environment is debug output sent to a Windows
1092    terminal emulator, we use CRLF */
1093 
1094 #if defined( __MSDOS16__ ) || defined( __MSDOS32__ ) || \
1095 	defined( __Nucleus__ ) || defined( __OS2__ ) || \
1096 	defined( __SMX__ ) || defined( __SYMBIAN32__ ) || \
1097 	defined( __WINDOWS__ ) || defined( __XMK__ )
1098   #define EOL					"\r\n"
1099   #define EOL_LEN				2
1100 #elif ( defined( __APPLE__ ) && !defined( __MAC__ ) ) || \
1101 	  defined( __BEOS__ ) || defined( __IBM4758__ ) || \
1102 	  defined( __MVS__ ) || defined( __PALMOS__ ) || \
1103 	  defined( __TANDEM_NSK__ ) || defined( __TANDEM_OSS__ ) || \
1104 	  defined( __UNIX__ ) || defined( __VMCMS__ )
1105   #define EOL					"\n"
1106   #define EOL_LEN				1
1107 #elif defined( __MAC__ )
1108   #define EOL					"\r"
1109   #define EOL_LEN				1
1110 #elif defined( USE_EMBEDDED_OS )
1111   /* For embedded OSes we assume a generic Unix-like text environment, these
1112 	 aren't exactly used for interactive operations like text editing so
1113 	 there's usually no fixed text format, and many will handle both CRLF
1114 	 and LF-only text, with the lowest common denominator being the Unix-
1115 	 style LF-only */
1116   #define EOL					"\n"
1117   #define EOL_LEN				1
1118 #else
1119   #error "You need to add the OS-specific define to enable end-of-line handling"
1120 #endif /* OS-specific EOL markers */
1121 
1122 /* If we're compiling on IBM mainframes, enable EBCDIC <-> ASCII string
1123    conversion.  Since cryptlib uses ASCII internally for all strings, we
1124    need to check to make sure it's been built with ASCII strings enabled
1125    before we go any further */
1126 
1127 #ifdef EBCDIC_CHARS
1128   #if 'A' != 0x41
1129 	#error cryptlib must be compiled with ASCII literals
1130   #endif /* Check for use of ASCII */
1131 
1132   int asciiToEbcdic( char *dest, const char *src, const int length );
1133   int ebcdicToAscii( char *dest, const char *src, const int length );
1134   char *bufferToEbcdic( char *buffer, const char *string );
1135   char *bufferToAscii( char *buffer, const char *string );
1136 #endif /* IBM mainframes */
1137 
1138 /* If we're compiling on Windows CE, enable Unicode <-> ASCII string
1139    conversion */
1140 
1141 #ifdef UNICODE_CHARS
1142   int asciiToUnicode( wchar_t *dest, const int destMaxLen,
1143 					  const char *src, const int length );
1144   int unicodeToAscii( char *dest, const int destMaxLen,
1145 					  const wchar_t *src, const int length );
1146 #endif /* Windows CE */
1147 
1148 /* Since cryptlib uses ASCII internally, we have to force the use of
1149    ASCII-compatible versions of system library functions if the system
1150    uses EBCDIC */
1151 
1152 #ifdef EBCDIC_CHARS
1153   #define ASCII_ALPHA			0x01
1154   #define ASCII_LOWER			0x02
1155   #define ASCII_NUMERIC			0x04
1156   #define ASCII_SPACE			0x08
1157   #define ASCII_UPPER			0x10
1158   #define ASCII_HEX				0x20
1159   extern const BYTE asciiCtypeTbl[];
1160 
1161   #define isAlnum( ch ) \
1162 		  ( asciiCtypeTbl[ byteToInt( ch ) ] & ( ASCII_ALPHA | ASCII_NUMERIC ) )
1163   #define isAlpha( ch ) \
1164 		  ( asciiCtypeTbl[ byteToInt( ch ) ] & ASCII_ALPHA )
1165   #define isDigit( ch ) \
1166 		  ( asciiCtypeTbl[ byteToInt( ch ) ] & ASCII_NUMERIC )
1167   #define isPrint( ch ) \
1168 		  ( ( byteToInt( ch ) ) >= 0x20 && ( byteToInt( ch ) ) <= 0x7E )
1169   #define isXDigit( ch ) \
1170 		  ( asciiCtypeTbl[ byteToInt( ch ) ] & ASCII_HEX )
1171   #define toLower( ch ) \
1172 		  ( ( asciiCtypeTbl[ byteToInt( ch ) ] & ASCII_UPPER ) ? \
1173 			( byteToInt( ch ) ) + 32 : ( byteToInt( ch ) ) )
1174   #define toUpper( ch ) \
1175 		  ( ( asciiCtypeTbl[ byteToInt( ch ) ] & ASCII_LOWER ) ? \
1176 			( byteToInt( ch ) ) - 32 : ( byteToInt( ch ) ) )
1177   int strCompareZ( const char *src, const char *dest );
1178   int strCompare( const char *src, const char *dest, int length );
1179   #define sprintf_s				sPrintf_s
1180   #define vsprintf_s			sPrintf_s
1181 #else
1182   #if defined( __Nucleus__ )
1183 	#include <nu_ctype.h>
1184 	#include <nu_string.h>
1185   #else
1186 	#include <ctype.h>
1187   #endif /* OS-specific includes */
1188 
1189   #define isAlnum( ch )			isalnum( byteToInt( ch ) )
1190   #define isAlpha( ch )			isalpha( byteToInt( ch ) )
1191   #define isDigit( ch )			isdigit( byteToInt( ch ) )
1192   #define isPrint( ch )			isprint( byteToInt( ch ) )
1193   #define isXDigit( ch )		isxdigit( byteToInt( ch ) )
1194   #define toLower( ch )			tolower( byteToInt( ch ) )
1195   #define toUpper( ch )			toupper( byteToInt( ch ) )
1196   #define strCompareZ( str1, str2 )	\
1197 								stricmp( str1, str2 )
1198   #define strCompare( str1, str2, len )	\
1199 								strnicmp( str1, str2, len )
1200 #endif /* EBCDIC_CHARS */
1201 
1202 /* SunOS and older Slowaris have broken sprintf() handling.  In SunOS 4.x
1203    this was documented as returning a pointer to the output data as per the
1204    Berkeley original.  Under Slowaris the manpage was changed so that it
1205    looks like any other sprintf(), but it still returns the pointer to the
1206    output buffer in some versions so we use a wrapper that checks at
1207    runtime to see what we've got and adjusts its behaviour accordingly */
1208 
1209 #if defined( sun ) && ( OSVERSION <= 5 )
1210   int fixedSprintf( char *buffer, const int bufSize,
1211 					const char *format, ... );
1212 
1213   #undef sPrintf_s
1214   #define sPrintf_s				fixedSprintf
1215 #endif /* Old SunOS */
1216 
1217 /* Borland C++ before 5.50 doesn't have snprintf() or vsnprintf() */
1218 
1219 #if defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x550 )
1220   #include <stdarg.h>
1221 
1222   int bcSnprintf( char *buffer, const int bufSize,
1223 				  const char *format, ... );
1224   int bcVsnprintf( char *buffer, const int bufSize,
1225 				   const char *format, va_list argPtr );
1226 #endif /* BC++ before 5.50 */
1227 
1228 /****************************************************************************
1229 *																			*
1230 *						TR 24731 Safe stdlib Extensions						*
1231 *																			*
1232 ****************************************************************************/
1233 
1234 /* ISO/IEC TR 24731 defines alternative stdlib functions designed to perform
1235    additional parameter checking and avoid some types of common buffer
1236    overflows.  We use these if possible, if they're not available we map
1237    them down to the traditional stdlib equivalents, via the preprocessor if
1238    possible or using wrapper functions if not.  In addition we use the
1239    OpenBSD et al strlcpy()/strlcat() functions, whose truncation semantics
1240    make them more useful than the TR 24731 equivalents (for example
1241    strcpy_s() does nothing on overflow while the equivalent strlcpy() copies
1242    with truncation).  Microsoft recognise this as well, implementing them in
1243    TR 24731 by allowing the caller to specify _TRUNCATE semantics */
1244 
1245 #ifdef __STDC_LIB_EXT1__
1246   #if defined( _MSC_VER ) && VC_GE_2005( _MSC_VER )
1247 	/* The VC++ implementation of TR 24731 is based on preliminary versions
1248 	   of the design for the spec, and in some cases needs re-mapping onto
1249 	   the final versions.  Instances of this are:
1250 
1251 		TR 24731: struct tm *gmtime_s( const time_t *timer, struct tm *result );
1252 		VC++: errno_t gmtime_s( struct tm *result, const time_t timer );
1253 
1254 	   Because this could potentially result in a circular definition, we
1255 	   have to kludge in an intermediate layer by renaming the call to
1256 	   gmTime_s(), which we then remap to the VC++ gmtime_s() */
1257 	#define gmTime_s( timer, result )	\
1258 			( ( gmtime_s( result, timer ) == 0 ) ? result : NULL )
1259 
1260 	/* Complicating things further, the Windows DDK doesn't have gmtime_s(),
1261 	   although it does have all of the other TR 24731 functions.  To handle
1262 	   this, we use the same workaround as for the non-TR 24731 libcs */
1263 	#ifdef WIN_DDK
1264 	  #undef gmTime_s
1265 	  #define gmTime_s( timer, result )	gmtime( timer )
1266 	#endif /* WIN_DDK */
1267 
1268 	/* MS implements strlcpy/strlcat-equivalents via the TR 24731
1269 	   functions */
1270 	#define strlcpy_s( s1, s1max, s2 )	strncpy_s( s1, s1max, s2, _TRUNCATE )
1271 	#define strlcat_s( s1, s1max, s2 )	strncat_s( s1, s1max, s2, _TRUNCATE )
1272   #else
1273 	#define gmTime_s					gmtime_s
1274   #endif /* VC++ >= 2005 */
1275 #else
1276   /* String functions.  The OpenBSD strlcpy()/strlcat() functions with their
1277      truncation semantics are quite useful so we use these as well,
1278 	 overlaying them with a macro that make them match the TR 24731 look
1279 	 and feel */
1280   #define strcpy_s( s1, s1max, s2 )		strcpy( s1, s2 )
1281   #if defined( __UNIX__ ) && \
1282 	  ( defined( __APPLE__ ) || (defined( __FreeBSD__ )||defined(__DragonFly__)) || \
1283 		defined( __NetBSD__ ) || defined( __OpenBSD__ ) || \
1284 		( defined( sun ) && OSVERSION >= 7 ) )
1285 	/* Despite the glibc maintainer's pigheaded opposition to these
1286 	   functions, some Unix OSes support them via custom libc patches */
1287 	#define strlcpy_s( s1, s1max, s2 )	strlcpy( s1, s2, s1max )
1288 	#define strlcat_s( s1, s1max, s2 )	strlcat( s1, s2, s1max )
1289   #else
1290 	int strlcpy_s( char *dest, const int destLen, const char *src );
1291 	int strlcat_s( char *dest, const int destLen, const char *src );
1292 	#define NO_NATIVE_STRLCPY
1293   #endif /* OpenBSD safe string functions */
1294 
1295   /* Widechar functions */
1296   int mbstowcs_s( size_t *retval, wchar_t *dst, size_t dstmax,
1297 				  const char *src, size_t len );
1298   int wcstombs_s( size_t *retval, char *dst, size_t dstmax,
1299 				  const wchar_t *src, size_t len );
1300 
1301   /* printf() */
1302   #if defined( _MSC_VER ) && VC_LT_2005( _MSC_VER )
1303 	#define sprintf_s					_snprintf
1304 	#define vsprintf_s					_vsnprintf
1305   #elif defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x550 )
1306 	#define sprintf_s					bcSnprintf
1307 	#define vsprintf_s					bcVsnprintf
1308   #elif defined( __QNX__ ) && ( OSVERSION <= 4 )
1309 	/* snprintf() exists under QNX 4.x but causes a SIGSEGV when called */
1310 	#define sprintf_s					_bprintf
1311 	#define vsnprintf					_vbprintf
1312   #elif defined( EBCDIC_CHARS )
1313 	/* We provide our own replacements for these functions which handle
1314 	   output in ASCII (rather than EBCDIC) form */
1315   #else
1316     #include <stdio.h>
1317 
1318 	#define sprintf_s					snprintf
1319 	#define vsprintf_s					vsnprintf
1320   #endif /* Compiler-specific safe printf() support */
1321 
1322   /* Misc.functions.  gmtime() is an ugly non-thread-safe function that runs
1323      into the same problems as gethostbyname() (see the long comment in
1324 	 io/tcp.h), to deal with this as best we can we map it to the reentrant
1325 	 gmtime_r() if it's available.  In addition some OSes use TLS for the
1326 	 result value so it's handled automatically, see the comments in
1327 	 io/tcp.h for more on this */
1328   #if defined( USE_THREADS ) && defined( __GLIBC__ ) && ( __GLIBC__ >= 2 )
1329 	#define gmTime_s					gmtime_r
1330   #else
1331 	#define gmTime_s( timer, result )	gmtime( timer )
1332   #endif /* USE_THREADS and libraries that provide gmtime_r() */
1333 #endif /* TR 24731 safe stdlib extensions */
1334 
1335 /****************************************************************************
1336 *																			*
1337 *				Miscellaneous System-specific Support Functions				*
1338 *																			*
1339 ****************************************************************************/
1340 
1341 /* Perform various operations on pointers */
1342 
1343 void *ptr_align( const void *ptr, const int units );
1344 int ptr_diff( const void *ptr1, const void *ptr2 );
1345 
1346 /* Check whether a pointer is aligned to a particular value, used by some
1347    low-level functions that check for potentially unaligned accesses and
1348    clean them up if possible.  This is mostly a hygiene check in that if it
1349    can't be easily implemented we continue anyway but with the possible
1350    overhead of an unaligned-access fixup, thus the _OPT qualifier.
1351 
1352    The apparently redundant cast to void * before the uintptr_t is necessary
1353    because the conversion is only guaranteed for a void *, so if it's some
1354    other type of pointer then we have to cast it to a void * first */
1355 
1356 #if ( defined( __STDC_VERSION__ ) && ( __STDC_VERSION__ >= 199901L ) ) || \
1357 	( defined( _MSC_VER ) && VC_GE_2005( _MSC_VER ) )
1358   #define IS_ALIGNED_OPT( pointer, value ) \
1359 		  ( ( ( uintptr_t )( const void * )( pointer ) ) % ( value ) == 0 )
1360 #else
1361   #define IS_ALIGNED_OPT( pointer, value )	TRUE
1362 #endif /* C99 check */
1363 
1364 #endif /* _OSSPEC_DEFINED */
1365