blob: 9762d414daaf5fd3dcf45ee0e4ad7000824c5acf [file] [log] [blame]
Azim Khanec024482017-05-09 17:20:21 +01001#line 2 "suites/helpers.function"
SimonB0269dad2016-02-17 23:34:30 +00002/*----------------------------------------------------------------------------*/
3/* Headers */
4
Ronald Cron4b8b1992020-06-09 13:52:23 +02005#include <test/macros.h>
Ronald Cronb6d6d4c2020-06-03 10:11:18 +02006#include <test/helpers.h>
Ronald Cronb7eb67f2020-06-09 16:57:42 +02007#include <test/random.h>
Gilles Peskinef6be5902020-11-24 18:33:13 +01008#if defined(MBEDTLS_PSA_CRYPTO_C)
9#include <test/psa_crypto_helpers.h>
10#endif
Ronald Cron4b8b1992020-06-09 13:52:23 +020011
Simon Butcheredb7fd92016-05-17 13:35:51 +010012#include <stdlib.h>
13
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020014#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000015#include "mbedtls/platform.h"
Manuel Pégourié-Gonnard3d49b9d2014-06-06 14:48:09 +020016#else
Rich Evans00ab4702015-02-06 13:43:58 +000017#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020018#define mbedtls_fprintf fprintf
Simon Butcher25731362016-09-30 13:11:29 +010019#define mbedtls_snprintf snprintf
20#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020021#define mbedtls_free free
22#define mbedtls_exit exit
Simon Butcherb2d5dd12016-04-27 13:35:37 +010023#define mbedtls_time time
24#define mbedtls_time_t time_t
Janos Follath55abc212016-04-18 18:18:48 +010025#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
26#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
Manuel Pégourié-Gonnard3d49b9d2014-06-06 14:48:09 +020027#endif
28
SimonB0269dad2016-02-17 23:34:30 +000029#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
30#include "mbedtls/memory_buffer_alloc.h"
31#endif
32
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050033#if defined(MBEDTLS_CHECK_PARAMS)
34#include "mbedtls/platform_util.h"
35#include <setjmp.h>
36#endif
37
Paul Bakkerb3dcbc12011-03-13 16:57:25 +000038#ifdef _MSC_VER
39#include <basetsd.h>
Azim Khan0fa35042018-06-22 11:34:33 +010040typedef UINT8 uint8_t;
41typedef INT32 int32_t;
Paul Bakkerb3dcbc12011-03-13 16:57:25 +000042typedef UINT32 uint32_t;
Nicholas Wilson733676b2015-11-14 13:09:01 +000043#define strncasecmp _strnicmp
44#define strcasecmp _stricmp
Paul Bakkerb3dcbc12011-03-13 16:57:25 +000045#else
Manuel Pégourié-Gonnard93866642015-06-22 19:21:23 +020046#include <stdint.h>
Paul Bakkerb3dcbc12011-03-13 16:57:25 +000047#endif
48
Paul Bakker19343182013-08-16 13:31:10 +020049#include <string.h>
50
Janos Follath8ca53b52016-10-05 10:57:49 +010051#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
52#include <unistd.h>
Nicholas Wilson2682edf2017-12-05 12:08:15 +000053#include <strings.h>
Janos Follath8ca53b52016-10-05 10:57:49 +010054#endif
SimonB0269dad2016-02-17 23:34:30 +000055
Azim Khand30ca132017-06-09 04:32:58 +010056/* Type for Hex parameters */
Azim Khan5fcca462018-06-29 11:05:32 +010057typedef struct data_tag
Azim Khand30ca132017-06-09 04:32:58 +010058{
59 uint8_t * x;
60 uint32_t len;
Azim Khan5fcca462018-06-29 11:05:32 +010061} data_t;
Azim Khand30ca132017-06-09 04:32:58 +010062
SimonB0269dad2016-02-17 23:34:30 +000063/*----------------------------------------------------------------------------*/
Azim Khan62a5d7d2018-06-29 10:02:54 +010064/* Status and error constants */
SimonB0269dad2016-02-17 23:34:30 +000065
Azim Khan62a5d7d2018-06-29 10:02:54 +010066#define DEPENDENCY_SUPPORTED 0 /* Dependency supported by build */
67#define KEY_VALUE_MAPPING_FOUND 0 /* Integer expression found */
68#define DISPATCH_TEST_SUCCESS 0 /* Test dispatch successful */
SimonB8ca7bc42016-04-17 23:24:50 +010069
Azim Khan62a5d7d2018-06-29 10:02:54 +010070#define KEY_VALUE_MAPPING_NOT_FOUND -1 /* Integer expression not found */
71#define DEPENDENCY_NOT_SUPPORTED -2 /* Dependency not supported */
72#define DISPATCH_TEST_FN_NOT_FOUND -3 /* Test function not found */
73#define DISPATCH_INVALID_TEST_DATA -4 /* Invalid test parameter type.
74 Only int, string, binary data
75 and integer expressions are
76 allowed */
77#define DISPATCH_UNSUPPORTED_SUITE -5 /* Test suite not supported by the
78 build */
SimonB0269dad2016-02-17 23:34:30 +000079
SimonB0269dad2016-02-17 23:34:30 +000080/*----------------------------------------------------------------------------*/
81/* Macros */
82
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050083/**
84 * \brief This macro tests the expression passed to it as a test step or
85 * individual test in a test case.
Gilles Peskine8954d0c2018-09-27 13:51:25 +020086 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050087 * It allows a library function to return a value and return an error
88 * code that can be tested.
Gilles Peskine8954d0c2018-09-27 13:51:25 +020089 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050090 * When MBEDTLS_CHECK_PARAMS is enabled, calls to the parameter failure
91 * callback, MBEDTLS_PARAM_FAILED(), will be assumed to be a test
92 * failure.
Gilles Peskine8954d0c2018-09-27 13:51:25 +020093 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050094 * This macro is not suitable for negative parameter validation tests,
95 * as it assumes the test step will not create an error.
96 *
Jaeden Amero67ea2c52019-02-11 12:05:54 +000097 * Failing the test means:
98 * - Mark this test case as failed.
99 * - Print a message identifying the failure.
100 * - Jump to the \c exit label.
101 *
102 * This macro expands to an instruction, not an expression.
103 * It may jump to the \c exit label.
104 *
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500105 * \param TEST The test expression to be tested.
Gilles Peskine8954d0c2018-09-27 13:51:25 +0200106 */
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500107#define TEST_ASSERT( TEST ) \
108 do { \
109 if( ! (TEST) ) \
110 { \
Chris Jones9634bb12021-01-20 15:56:42 +0000111 mbedtls_test_fail( #TEST, __LINE__, __FILE__ ); \
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500112 goto exit; \
113 } \
SimonB0269dad2016-02-17 23:34:30 +0000114 } while( 0 )
115
Gilles Peskine5f7aeee2018-12-17 23:26:52 +0100116/** Evaluate two expressions and fail the test case if they have different
117 * values.
118 *
119 * \param expr1 An expression to evaluate.
120 * \param expr2 The expected value of \p expr1. This can be any
121 * expression, but it is typically a constant.
122 */
123#define TEST_EQUAL( expr1, expr2 ) \
124 TEST_ASSERT( ( expr1 ) == ( expr2 ) )
125
Gilles Peskineb75125c2018-09-27 13:52:16 +0200126/** Allocate memory dynamically and fail the test case if this fails.
Dave Rodgman2e680342020-10-15 14:00:40 +0100127 * The allocated memory will be filled with zeros.
Gilles Peskineb75125c2018-09-27 13:52:16 +0200128 *
129 * You must set \p pointer to \c NULL before calling this macro and
130 * put `mbedtls_free( pointer )` in the test's cleanup code.
131 *
Gilles Peskine7f6e3a82018-11-30 18:51:45 +0100132 * If \p length is zero, the resulting \p pointer will be \c NULL.
Gilles Peskineb75125c2018-09-27 13:52:16 +0200133 * This is usually what we want in tests since API functions are
134 * supposed to accept null pointers when a buffer size is zero.
135 *
136 * This macro expands to an instruction, not an expression.
137 * It may jump to the \c exit label.
138 *
139 * \param pointer An lvalue where the address of the allocated buffer
140 * will be stored.
141 * This expression may be evaluated multiple times.
Gilles Peskine7f6e3a82018-11-30 18:51:45 +0100142 * \param length Number of elements to allocate.
Gilles Peskineb75125c2018-09-27 13:52:16 +0200143 * This expression may be evaluated multiple times.
144 *
145 */
Gilles Peskine7f6e3a82018-11-30 18:51:45 +0100146#define ASSERT_ALLOC( pointer, length ) \
147 do \
148 { \
149 TEST_ASSERT( ( pointer ) == NULL ); \
150 if( ( length ) != 0 ) \
151 { \
152 ( pointer ) = mbedtls_calloc( sizeof( *( pointer ) ), \
153 ( length ) ); \
154 TEST_ASSERT( ( pointer ) != NULL ); \
155 } \
156 } \
Gilles Peskineb75125c2018-09-27 13:52:16 +0200157 while( 0 )
158
Gilles Peskine292672e2020-01-21 16:20:04 +0100159/** Allocate memory dynamically. If the allocation fails, skip the test case.
Gilles Peskine2cd8ecc2019-03-04 17:13:43 +0100160 *
161 * This macro behaves like #ASSERT_ALLOC, except that if the allocation
Gilles Peskine292672e2020-01-21 16:20:04 +0100162 * fails, it marks the test as skipped rather than failed.
Gilles Peskine2cd8ecc2019-03-04 17:13:43 +0100163 */
164#define ASSERT_ALLOC_WEAK( pointer, length ) \
165 do \
166 { \
167 TEST_ASSERT( ( pointer ) == NULL ); \
168 if( ( length ) != 0 ) \
169 { \
170 ( pointer ) = mbedtls_calloc( sizeof( *( pointer ) ), \
171 ( length ) ); \
Gilles Peskine292672e2020-01-21 16:20:04 +0100172 TEST_ASSUME( ( pointer ) != NULL ); \
Gilles Peskine2cd8ecc2019-03-04 17:13:43 +0100173 } \
174 } \
175 while( 0 )
176
Gilles Peskine3c225962018-09-27 13:56:31 +0200177/** Compare two buffers and fail the test case if they differ.
178 *
179 * This macro expands to an instruction, not an expression.
180 * It may jump to the \c exit label.
181 *
182 * \param p1 Pointer to the start of the first buffer.
183 * \param size1 Size of the first buffer in bytes.
184 * This expression may be evaluated multiple times.
185 * \param p2 Pointer to the start of the second buffer.
186 * \param size2 Size of the second buffer in bytes.
187 * This expression may be evaluated multiple times.
188 */
189#define ASSERT_COMPARE( p1, size1, p2, size2 ) \
190 do \
191 { \
192 TEST_ASSERT( ( size1 ) == ( size2 ) ); \
193 if( ( size1 ) != 0 ) \
194 TEST_ASSERT( memcmp( ( p1 ), ( p2 ), ( size1 ) ) == 0 ); \
195 } \
196 while( 0 )
197
Hanno Beckere69d0152019-07-05 13:31:30 +0100198/**
199 * \brief This macro tests the expression passed to it and skips the
200 * running test if it doesn't evaluate to 'true'.
201 *
202 * \param TEST The test expression to be tested.
203 */
Chris Jones9634bb12021-01-20 15:56:42 +0000204#define TEST_ASSUME( TEST ) \
205 do { \
206 if( ! (TEST) ) \
207 { \
208 mbedtls_test_skip( #TEST, __LINE__, __FILE__ ); \
209 goto exit; \
210 } \
Hanno Beckere69d0152019-07-05 13:31:30 +0100211 } while( 0 )
212
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500213#if defined(MBEDTLS_CHECK_PARAMS) && !defined(MBEDTLS_PARAM_FAILED_ALT)
214/**
215 * \brief This macro tests the statement passed to it as a test step or
216 * individual test in a test case. The macro assumes the test will fail
217 * and will generate an error.
218 *
219 * It allows a library function to return a value and tests the return
220 * code on return to confirm the given error code was returned.
221 *
222 * When MBEDTLS_CHECK_PARAMS is enabled, calls to the parameter failure
223 * callback, MBEDTLS_PARAM_FAILED(), are assumed to indicate the
224 * expected failure, and the test will pass.
225 *
226 * This macro is intended for negative parameter validation tests,
227 * where the failing function may return an error value or call
228 * MBEDTLS_PARAM_FAILED() to indicate the error.
229 *
230 * \param PARAM_ERROR_VALUE The expected error code.
231 *
232 * \param TEST The test expression to be tested.
233 */
Ronald Cron76883ec2020-07-01 15:05:21 +0200234#define TEST_INVALID_PARAM_RET( PARAM_ERR_VALUE, TEST ) \
235 do { \
236 mbedtls_test_param_failed_expect_call( ); \
237 if( ( ( TEST ) != ( PARAM_ERR_VALUE ) ) || \
238 ( mbedtls_test_param_failed_check_expected_call( ) != 0 ) ) \
239 { \
Chris Jones9634bb12021-01-20 15:56:42 +0000240 mbedtls_test_fail( #TEST, __LINE__, __FILE__ ); \
Ronald Cron76883ec2020-07-01 15:05:21 +0200241 goto exit; \
242 } \
243 mbedtls_test_param_failed_check_expected_call( ); \
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500244 } while( 0 )
245
246/**
247 * \brief This macro tests the statement passed to it as a test step or
248 * individual test in a test case. The macro assumes the test will fail
249 * and will generate an error.
250 *
251 * It assumes the library function under test cannot return a value and
252 * assumes errors can only be indicated byt calls to
253 * MBEDTLS_PARAM_FAILED().
254 *
255 * When MBEDTLS_CHECK_PARAMS is enabled, calls to the parameter failure
256 * callback, MBEDTLS_PARAM_FAILED(), are assumed to indicate the
257 * expected failure. If MBEDTLS_CHECK_PARAMS is not enabled, no test
258 * can be made.
259 *
260 * This macro is intended for negative parameter validation tests,
261 * where the failing function can only return an error by calling
262 * MBEDTLS_PARAM_FAILED() to indicate the error.
263 *
264 * \param TEST The test expression to be tested.
265 */
Ronald Cron579fd282020-07-01 15:17:05 +0200266#define TEST_INVALID_PARAM( TEST ) \
267 do { \
268 memcpy( jmp_tmp, mbedtls_test_param_failed_get_state_buf( ), \
269 sizeof( jmp_tmp ) ); \
270 if( setjmp( mbedtls_test_param_failed_get_state_buf( ) ) == 0 ) \
271 { \
272 TEST; \
Chris Jones9634bb12021-01-20 15:56:42 +0000273 mbedtls_test_fail( #TEST, __LINE__, __FILE__ ); \
Ronald Cron579fd282020-07-01 15:17:05 +0200274 goto exit; \
275 } \
276 mbedtls_test_param_failed_reset_state( ); \
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500277 } while( 0 )
278#endif /* MBEDTLS_CHECK_PARAMS && !MBEDTLS_PARAM_FAILED_ALT */
279
280/**
281 * \brief This macro tests the statement passed to it as a test step or
282 * individual test in a test case. The macro assumes the test will not fail.
283 *
284 * It assumes the library function under test cannot return a value and
285 * assumes errors can only be indicated by calls to
286 * MBEDTLS_PARAM_FAILED().
287 *
288 * When MBEDTLS_CHECK_PARAMS is enabled, calls to the parameter failure
289 * callback, MBEDTLS_PARAM_FAILED(), are assumed to indicate the
290 * expected failure. If MBEDTLS_CHECK_PARAMS is not enabled, no test
291 * can be made.
292 *
293 * This macro is intended to test that functions returning void
294 * accept all of the parameter values they're supposed to accept - eg
295 * that they don't call MBEDTLS_PARAM_FAILED() when a parameter
296 * that's allowed to be NULL happens to be NULL.
297 *
298 * Note: for functions that return something other that void,
299 * checking that they accept all the parameters they're supposed to
300 * accept is best done by using TEST_ASSERT() and checking the return
301 * value as well.
302 *
303 * Note: this macro is available even when #MBEDTLS_CHECK_PARAMS is
304 * disabled, as it makes sense to check that the functions accept all
305 * legal values even if this option is disabled - only in that case,
306 * the test is more about whether the function segfaults than about
307 * whether it invokes MBEDTLS_PARAM_FAILED().
308 *
309 * \param TEST The test expression to be tested.
310 */
311#define TEST_VALID_PARAM( TEST ) \
312 TEST_ASSERT( ( TEST, 1 ) );
313
Gilles Peskine28405302018-09-27 13:52:16 +0200314/** Allocate memory dynamically and fail the test case if this fails.
315 *
316 * You must set \p pointer to \c NULL before calling this macro and
317 * put `mbedtls_free( pointer )` in the test's cleanup code.
318 *
Gilles Peskine6608e712018-11-30 18:51:45 +0100319 * If \p length is zero, the resulting \p pointer will be \c NULL.
Gilles Peskine28405302018-09-27 13:52:16 +0200320 * This is usually what we want in tests since API functions are
321 * supposed to accept null pointers when a buffer size is zero.
322 *
323 * This macro expands to an instruction, not an expression.
324 * It may jump to the \c exit label.
325 *
326 * \param pointer An lvalue where the address of the allocated buffer
327 * will be stored.
328 * This expression may be evaluated multiple times.
Gilles Peskine6608e712018-11-30 18:51:45 +0100329 * \param length Number of elements to allocate.
Gilles Peskine28405302018-09-27 13:52:16 +0200330 * This expression may be evaluated multiple times.
331 *
332 */
Gilles Peskine6608e712018-11-30 18:51:45 +0100333#define ASSERT_ALLOC( pointer, length ) \
334 do \
335 { \
336 TEST_ASSERT( ( pointer ) == NULL ); \
337 if( ( length ) != 0 ) \
338 { \
339 ( pointer ) = mbedtls_calloc( sizeof( *( pointer ) ), \
340 ( length ) ); \
341 TEST_ASSERT( ( pointer ) != NULL ); \
342 } \
343 } \
Gilles Peskine28405302018-09-27 13:52:16 +0200344 while( 0 )
345
SimonB0269dad2016-02-17 23:34:30 +0000346/*----------------------------------------------------------------------------*/
SimonB8ca7bc42016-04-17 23:24:50 +0100347/* Global variables */
348
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500349#if defined(MBEDTLS_CHECK_PARAMS)
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500350jmp_buf jmp_tmp;
351#endif
352
SimonB8ca7bc42016-04-17 23:24:50 +0100353/*----------------------------------------------------------------------------*/
Hanno Becker47deec42017-07-24 12:27:09 +0100354/* Helper flags for complex dependencies */
355
356/* Indicates whether we expect mbedtls_entropy_init
357 * to initialize some strong entropy source. */
358#if defined(MBEDTLS_TEST_NULL_ENTROPY) || \
359 ( !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) && \
360 ( !defined(MBEDTLS_NO_PLATFORM_ENTROPY) || \
361 defined(MBEDTLS_HAVEGE_C) || \
362 defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \
363 defined(ENTROPY_NV_SEED) ) )
Hanno Beckerd4a872e2017-09-07 08:09:33 +0100364#define ENTROPY_HAVE_STRONG
Hanno Becker47deec42017-07-24 12:27:09 +0100365#endif
366
367
368/*----------------------------------------------------------------------------*/
SimonB0269dad2016-02-17 23:34:30 +0000369/* Helper Functions */
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500370
Gilles Peskinec85c2012021-01-06 20:47:16 +0100371#if defined(MBEDTLS_PSA_CRYPTO_C)
372/** Check that no PSA Crypto key slots are in use.
373 *
374 * If any slots are in use, mark the current test as failed.
375 *
376 * \return 0 if the key store is empty, 1 otherwise.
377 */
378int test_fail_if_psa_leaking( int line_no, const char *filename )
379{
380 const char *msg = mbedtls_test_helper_is_psa_leaking( );
381 if( msg == NULL )
382 return 0;
383 else
384 {
Chris Jones9634bb12021-01-20 15:56:42 +0000385 mbedtls_test_fail( msg, line_no, filename );
Gilles Peskinec85c2012021-01-06 20:47:16 +0100386 return 1;
387 }
388}
389#endif /* defined(MBEDTLS_PSA_CRYPTO_C) */
390
Janos Follath8ca53b52016-10-05 10:57:49 +0100391#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
gufe44067f6e02020-07-30 09:02:27 +0200392static int redirect_output( FILE* out_stream, const char* path )
Janos Follath8ca53b52016-10-05 10:57:49 +0100393{
gufe44067f6e02020-07-30 09:02:27 +0200394 int out_fd, dup_fd;
395 FILE* path_stream;
Janos Follath8ca53b52016-10-05 10:57:49 +0100396
gufe44067f6e02020-07-30 09:02:27 +0200397 out_fd = fileno( out_stream );
398 dup_fd = dup( out_fd );
399
400 if( dup_fd == -1 )
Janos Follath8ca53b52016-10-05 10:57:49 +0100401 {
gufe44067f6e02020-07-30 09:02:27 +0200402 return( -1 );
Janos Follath8ca53b52016-10-05 10:57:49 +0100403 }
404
gufe44067f6e02020-07-30 09:02:27 +0200405 path_stream = fopen( path, "w" );
406 if( path_stream == NULL )
Janos Follath8ca53b52016-10-05 10:57:49 +0100407 {
gufe44067f6e02020-07-30 09:02:27 +0200408 close( dup_fd );
409 return( -1 );
Janos Follath8ca53b52016-10-05 10:57:49 +0100410 }
411
gufe44067f6e02020-07-30 09:02:27 +0200412 fflush( out_stream );
413 if( dup2( fileno( path_stream ), out_fd ) == -1 )
414 {
415 close( dup_fd );
416 fclose( path_stream );
417 return( -1 );
418 }
419
420 fclose( path_stream );
421 return( dup_fd );
Janos Follath8ca53b52016-10-05 10:57:49 +0100422}
423
gufe44067f6e02020-07-30 09:02:27 +0200424static int restore_output( FILE* out_stream, int dup_fd )
Janos Follath8ca53b52016-10-05 10:57:49 +0100425{
gufe44067f6e02020-07-30 09:02:27 +0200426 int out_fd = fileno( out_stream );
Janos Follath8ca53b52016-10-05 10:57:49 +0100427
gufe44067f6e02020-07-30 09:02:27 +0200428 fflush( out_stream );
429 if( dup2( dup_fd, out_fd ) == -1 )
Janos Follath8ca53b52016-10-05 10:57:49 +0100430 {
gufe44067f6e02020-07-30 09:02:27 +0200431 close( out_fd );
432 close( dup_fd );
433 return( -1 );
Janos Follath8ca53b52016-10-05 10:57:49 +0100434 }
435
gufe44067f6e02020-07-30 09:02:27 +0200436 close( dup_fd );
437 return( 0 );
Simon Butchere0192962016-10-12 23:07:30 +0100438}
Janos Follath8ca53b52016-10-05 10:57:49 +0100439#endif /* __unix__ || __APPLE__ __MACH__ */