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