| #line 2 "suites/helpers.function" |
| /*----------------------------------------------------------------------------*/ |
| /* Headers */ |
| |
| #include <test/macros.h> |
| #include <test/helpers.h> |
| #include <test/random.h> |
| |
| #include <stdlib.h> |
| |
| #if defined(MBEDTLS_PLATFORM_C) |
| #include "mbedtls/platform.h" |
| #else |
| #include <stdio.h> |
| #define mbedtls_fprintf fprintf |
| #define mbedtls_snprintf snprintf |
| #define mbedtls_calloc calloc |
| #define mbedtls_free free |
| #define mbedtls_exit exit |
| #define mbedtls_time time |
| #define mbedtls_time_t time_t |
| #define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS |
| #define MBEDTLS_EXIT_FAILURE EXIT_FAILURE |
| #endif |
| |
| #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) |
| #include "mbedtls/memory_buffer_alloc.h" |
| #endif |
| |
| #if defined(MBEDTLS_CHECK_PARAMS) |
| #include "mbedtls/platform_util.h" |
| #include <setjmp.h> |
| #endif |
| |
| #ifdef _MSC_VER |
| #include <basetsd.h> |
| typedef UINT8 uint8_t; |
| typedef INT32 int32_t; |
| typedef UINT32 uint32_t; |
| #define strncasecmp _strnicmp |
| #define strcasecmp _stricmp |
| #else |
| #include <stdint.h> |
| #endif |
| |
| #include <string.h> |
| |
| #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) |
| #include <unistd.h> |
| #include <strings.h> |
| #endif |
| |
| /* Type for Hex parameters */ |
| typedef struct data_tag |
| { |
| uint8_t * x; |
| uint32_t len; |
| } data_t; |
| |
| /*----------------------------------------------------------------------------*/ |
| /* Status and error constants */ |
| |
| #define DEPENDENCY_SUPPORTED 0 /* Dependency supported by build */ |
| #define KEY_VALUE_MAPPING_FOUND 0 /* Integer expression found */ |
| #define DISPATCH_TEST_SUCCESS 0 /* Test dispatch successful */ |
| |
| #define KEY_VALUE_MAPPING_NOT_FOUND -1 /* Integer expression not found */ |
| #define DEPENDENCY_NOT_SUPPORTED -2 /* Dependency not supported */ |
| #define DISPATCH_TEST_FN_NOT_FOUND -3 /* Test function not found */ |
| #define DISPATCH_INVALID_TEST_DATA -4 /* Invalid test parameter type. |
| Only int, string, binary data |
| and integer expressions are |
| allowed */ |
| #define DISPATCH_UNSUPPORTED_SUITE -5 /* Test suite not supported by the |
| build */ |
| |
| /*----------------------------------------------------------------------------*/ |
| /* Macros */ |
| |
| /** |
| * \brief This macro tests the expression passed to it as a test step or |
| * individual test in a test case. |
| * |
| * It allows a library function to return a value and return an error |
| * code that can be tested. |
| * |
| * When MBEDTLS_CHECK_PARAMS is enabled, calls to the parameter failure |
| * callback, MBEDTLS_PARAM_FAILED(), will be assumed to be a test |
| * failure. |
| * |
| * This macro is not suitable for negative parameter validation tests, |
| * as it assumes the test step will not create an error. |
| * |
| * Failing the test means: |
| * - Mark this test case as failed. |
| * - Print a message identifying the failure. |
| * - Jump to the \c exit label. |
| * |
| * This macro expands to an instruction, not an expression. |
| * It may jump to the \c exit label. |
| * |
| * \param TEST The test expression to be tested. |
| */ |
| #define TEST_ASSERT( TEST ) \ |
| do { \ |
| if( ! (TEST) ) \ |
| { \ |
| test_fail( #TEST, __LINE__, __FILE__ ); \ |
| goto exit; \ |
| } \ |
| } while( 0 ) |
| |
| /** Evaluate two expressions and fail the test case if they have different |
| * values. |
| * |
| * \param expr1 An expression to evaluate. |
| * \param expr2 The expected value of \p expr1. This can be any |
| * expression, but it is typically a constant. |
| */ |
| #define TEST_EQUAL( expr1, expr2 ) \ |
| TEST_ASSERT( ( expr1 ) == ( expr2 ) ) |
| |
| /** Allocate memory dynamically and fail the test case if this fails. |
| * The allocated memory will be filled with zeros. |
| * |
| * You must set \p pointer to \c NULL before calling this macro and |
| * put `mbedtls_free( pointer )` in the test's cleanup code. |
| * |
| * If \p length is zero, the resulting \p pointer will be \c NULL. |
| * This is usually what we want in tests since API functions are |
| * supposed to accept null pointers when a buffer size is zero. |
| * |
| * This macro expands to an instruction, not an expression. |
| * It may jump to the \c exit label. |
| * |
| * \param pointer An lvalue where the address of the allocated buffer |
| * will be stored. |
| * This expression may be evaluated multiple times. |
| * \param length Number of elements to allocate. |
| * This expression may be evaluated multiple times. |
| * |
| */ |
| #define ASSERT_ALLOC( pointer, length ) \ |
| do \ |
| { \ |
| TEST_ASSERT( ( pointer ) == NULL ); \ |
| if( ( length ) != 0 ) \ |
| { \ |
| ( pointer ) = mbedtls_calloc( sizeof( *( pointer ) ), \ |
| ( length ) ); \ |
| TEST_ASSERT( ( pointer ) != NULL ); \ |
| } \ |
| } \ |
| while( 0 ) |
| |
| /** Allocate memory dynamically. If the allocation fails, skip the test case. |
| * |
| * This macro behaves like #ASSERT_ALLOC, except that if the allocation |
| * fails, it marks the test as skipped rather than failed. |
| */ |
| #define ASSERT_ALLOC_WEAK( pointer, length ) \ |
| do \ |
| { \ |
| TEST_ASSERT( ( pointer ) == NULL ); \ |
| if( ( length ) != 0 ) \ |
| { \ |
| ( pointer ) = mbedtls_calloc( sizeof( *( pointer ) ), \ |
| ( length ) ); \ |
| TEST_ASSUME( ( pointer ) != NULL ); \ |
| } \ |
| } \ |
| while( 0 ) |
| |
| /** Compare two buffers and fail the test case if they differ. |
| * |
| * This macro expands to an instruction, not an expression. |
| * It may jump to the \c exit label. |
| * |
| * \param p1 Pointer to the start of the first buffer. |
| * \param size1 Size of the first buffer in bytes. |
| * This expression may be evaluated multiple times. |
| * \param p2 Pointer to the start of the second buffer. |
| * \param size2 Size of the second buffer in bytes. |
| * This expression may be evaluated multiple times. |
| */ |
| #define ASSERT_COMPARE( p1, size1, p2, size2 ) \ |
| do \ |
| { \ |
| TEST_ASSERT( ( size1 ) == ( size2 ) ); \ |
| if( ( size1 ) != 0 ) \ |
| TEST_ASSERT( memcmp( ( p1 ), ( p2 ), ( size1 ) ) == 0 ); \ |
| } \ |
| while( 0 ) |
| |
| /** |
| * \brief This macro tests the expression passed to it and skips the |
| * running test if it doesn't evaluate to 'true'. |
| * |
| * \param TEST The test expression to be tested. |
| */ |
| #define TEST_ASSUME( TEST ) \ |
| do { \ |
| if( ! (TEST) ) \ |
| { \ |
| test_skip( #TEST, __LINE__, __FILE__ ); \ |
| goto exit; \ |
| } \ |
| } while( 0 ) |
| |
| #if defined(MBEDTLS_CHECK_PARAMS) && !defined(MBEDTLS_PARAM_FAILED_ALT) |
| /** |
| * \brief This macro tests the statement passed to it as a test step or |
| * individual test in a test case. The macro assumes the test will fail |
| * and will generate an error. |
| * |
| * It allows a library function to return a value and tests the return |
| * code on return to confirm the given error code was returned. |
| * |
| * When MBEDTLS_CHECK_PARAMS is enabled, calls to the parameter failure |
| * callback, MBEDTLS_PARAM_FAILED(), are assumed to indicate the |
| * expected failure, and the test will pass. |
| * |
| * This macro is intended for negative parameter validation tests, |
| * where the failing function may return an error value or call |
| * MBEDTLS_PARAM_FAILED() to indicate the error. |
| * |
| * \param PARAM_ERROR_VALUE The expected error code. |
| * |
| * \param TEST The test expression to be tested. |
| */ |
| #define TEST_INVALID_PARAM_RET( PARAM_ERR_VALUE, TEST ) \ |
| do { \ |
| mbedtls_test_param_failed_expect_call( ); \ |
| if( ( ( TEST ) != ( PARAM_ERR_VALUE ) ) || \ |
| ( mbedtls_test_param_failed_check_expected_call( ) != 0 ) ) \ |
| { \ |
| test_fail( #TEST, __LINE__, __FILE__ ); \ |
| goto exit; \ |
| } \ |
| mbedtls_test_param_failed_check_expected_call( ); \ |
| } while( 0 ) |
| |
| /** |
| * \brief This macro tests the statement passed to it as a test step or |
| * individual test in a test case. The macro assumes the test will fail |
| * and will generate an error. |
| * |
| * It assumes the library function under test cannot return a value and |
| * assumes errors can only be indicated byt calls to |
| * MBEDTLS_PARAM_FAILED(). |
| * |
| * When MBEDTLS_CHECK_PARAMS is enabled, calls to the parameter failure |
| * callback, MBEDTLS_PARAM_FAILED(), are assumed to indicate the |
| * expected failure. If MBEDTLS_CHECK_PARAMS is not enabled, no test |
| * can be made. |
| * |
| * This macro is intended for negative parameter validation tests, |
| * where the failing function can only return an error by calling |
| * MBEDTLS_PARAM_FAILED() to indicate the error. |
| * |
| * \param TEST The test expression to be tested. |
| */ |
| #define TEST_INVALID_PARAM( TEST ) \ |
| do { \ |
| memcpy( jmp_tmp, mbedtls_test_param_failed_get_state_buf( ), \ |
| sizeof( jmp_tmp ) ); \ |
| if( setjmp( mbedtls_test_param_failed_get_state_buf( ) ) == 0 ) \ |
| { \ |
| TEST; \ |
| test_fail( #TEST, __LINE__, __FILE__ ); \ |
| goto exit; \ |
| } \ |
| mbedtls_test_param_failed_reset_state( ); \ |
| } while( 0 ) |
| #endif /* MBEDTLS_CHECK_PARAMS && !MBEDTLS_PARAM_FAILED_ALT */ |
| |
| /** |
| * \brief This macro tests the statement passed to it as a test step or |
| * individual test in a test case. The macro assumes the test will not fail. |
| * |
| * It assumes the library function under test cannot return a value and |
| * assumes errors can only be indicated by calls to |
| * MBEDTLS_PARAM_FAILED(). |
| * |
| * When MBEDTLS_CHECK_PARAMS is enabled, calls to the parameter failure |
| * callback, MBEDTLS_PARAM_FAILED(), are assumed to indicate the |
| * expected failure. If MBEDTLS_CHECK_PARAMS is not enabled, no test |
| * can be made. |
| * |
| * This macro is intended to test that functions returning void |
| * accept all of the parameter values they're supposed to accept - eg |
| * that they don't call MBEDTLS_PARAM_FAILED() when a parameter |
| * that's allowed to be NULL happens to be NULL. |
| * |
| * Note: for functions that return something other that void, |
| * checking that they accept all the parameters they're supposed to |
| * accept is best done by using TEST_ASSERT() and checking the return |
| * value as well. |
| * |
| * Note: this macro is available even when #MBEDTLS_CHECK_PARAMS is |
| * disabled, as it makes sense to check that the functions accept all |
| * legal values even if this option is disabled - only in that case, |
| * the test is more about whether the function segfaults than about |
| * whether it invokes MBEDTLS_PARAM_FAILED(). |
| * |
| * \param TEST The test expression to be tested. |
| */ |
| #define TEST_VALID_PARAM( TEST ) \ |
| TEST_ASSERT( ( TEST, 1 ) ); |
| |
| /** Allocate memory dynamically and fail the test case if this fails. |
| * |
| * You must set \p pointer to \c NULL before calling this macro and |
| * put `mbedtls_free( pointer )` in the test's cleanup code. |
| * |
| * If \p length is zero, the resulting \p pointer will be \c NULL. |
| * This is usually what we want in tests since API functions are |
| * supposed to accept null pointers when a buffer size is zero. |
| * |
| * This macro expands to an instruction, not an expression. |
| * It may jump to the \c exit label. |
| * |
| * \param pointer An lvalue where the address of the allocated buffer |
| * will be stored. |
| * This expression may be evaluated multiple times. |
| * \param length Number of elements to allocate. |
| * This expression may be evaluated multiple times. |
| * |
| */ |
| #define ASSERT_ALLOC( pointer, length ) \ |
| do \ |
| { \ |
| TEST_ASSERT( ( pointer ) == NULL ); \ |
| if( ( length ) != 0 ) \ |
| { \ |
| ( pointer ) = mbedtls_calloc( sizeof( *( pointer ) ), \ |
| ( length ) ); \ |
| TEST_ASSERT( ( pointer ) != NULL ); \ |
| } \ |
| } \ |
| while( 0 ) |
| |
| /*----------------------------------------------------------------------------*/ |
| /* Global variables */ |
| |
| typedef enum |
| { |
| TEST_RESULT_SUCCESS = 0, |
| TEST_RESULT_FAILED, |
| TEST_RESULT_SKIPPED |
| } test_result_t; |
| |
| typedef struct |
| { |
| test_result_t result; |
| const char *test; |
| const char *filename; |
| int line_no; |
| unsigned long step; |
| } |
| test_info_t; |
| static test_info_t test_info; |
| |
| #if defined(MBEDTLS_CHECK_PARAMS) |
| jmp_buf jmp_tmp; |
| #endif |
| |
| /*----------------------------------------------------------------------------*/ |
| /* Helper flags for complex dependencies */ |
| |
| /* Indicates whether we expect mbedtls_entropy_init |
| * to initialize some strong entropy source. */ |
| #if defined(MBEDTLS_TEST_NULL_ENTROPY) || \ |
| ( !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) && \ |
| ( !defined(MBEDTLS_NO_PLATFORM_ENTROPY) || \ |
| defined(MBEDTLS_HAVEGE_C) || \ |
| defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \ |
| defined(ENTROPY_NV_SEED) ) ) |
| #define ENTROPY_HAVE_STRONG |
| #endif |
| |
| |
| /*----------------------------------------------------------------------------*/ |
| /* Helper Functions */ |
| |
| /** Set the test step number for failure reports. |
| * |
| * Call this function to display "step NNN" in addition to the line number |
| * and file name if a test fails. Typically the "step number" is the index |
| * of a for loop but it can be whatever you want. |
| * |
| * \param step The step number to report. |
| */ |
| void test_set_step( unsigned long step ) |
| { |
| test_info.step = step; |
| } |
| |
| void test_fail( const char *test, int line_no, const char* filename ) |
| { |
| if( test_info.result == TEST_RESULT_FAILED ) |
| { |
| /* We've already recorded the test as having failed. Don't |
| * overwrite any previous information about the failure. */ |
| return; |
| } |
| test_info.result = TEST_RESULT_FAILED; |
| test_info.test = test; |
| test_info.line_no = line_no; |
| test_info.filename = filename; |
| } |
| |
| void test_skip( const char *test, int line_no, const char* filename ) |
| { |
| test_info.result = TEST_RESULT_SKIPPED; |
| test_info.test = test; |
| test_info.line_no = line_no; |
| test_info.filename = filename; |
| } |
| |
| #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) |
| static int redirect_output( FILE* out_stream, const char* path ) |
| { |
| int out_fd, dup_fd; |
| FILE* path_stream; |
| |
| out_fd = fileno( out_stream ); |
| dup_fd = dup( out_fd ); |
| |
| if( dup_fd == -1 ) |
| { |
| return( -1 ); |
| } |
| |
| path_stream = fopen( path, "w" ); |
| if( path_stream == NULL ) |
| { |
| close( dup_fd ); |
| return( -1 ); |
| } |
| |
| fflush( out_stream ); |
| if( dup2( fileno( path_stream ), out_fd ) == -1 ) |
| { |
| close( dup_fd ); |
| fclose( path_stream ); |
| return( -1 ); |
| } |
| |
| fclose( path_stream ); |
| return( dup_fd ); |
| } |
| |
| static int restore_output( FILE* out_stream, int dup_fd ) |
| { |
| int out_fd = fileno( out_stream ); |
| |
| fflush( out_stream ); |
| if( dup2( dup_fd, out_fd ) == -1 ) |
| { |
| close( out_fd ); |
| close( dup_fd ); |
| return( -1 ); |
| } |
| |
| close( dup_fd ); |
| return( 0 ); |
| } |
| #endif /* __unix__ || __APPLE__ __MACH__ */ |