1#line 1 "helpers.function" 2/*----------------------------------------------------------------------------*/ 3/* Headers */ 4 5#include <stdlib.h> 6 7#if defined(MBEDTLS_PLATFORM_C) 8#include "mbedtls/platform.h" 9#else 10#include <stdio.h> 11#define mbedtls_fprintf fprintf 12#define mbedtls_snprintf snprintf 13#define mbedtls_calloc calloc 14#define mbedtls_free free 15#define mbedtls_exit exit 16#define mbedtls_time time 17#define mbedtls_time_t time_t 18#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS 19#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE 20#endif 21 22#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) 23#include "mbedtls/memory_buffer_alloc.h" 24#endif 25 26#ifdef _MSC_VER 27#include <basetsd.h> 28typedef UINT32 uint32_t; 29#define strncasecmp _strnicmp 30#define strcasecmp _stricmp 31#else 32#include <stdint.h> 33#endif 34 35#include <string.h> 36 37#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) 38#include <unistd.h> 39#endif 40 41/*----------------------------------------------------------------------------*/ 42/* Constants */ 43 44#define DEPENDENCY_SUPPORTED 0 45#define DEPENDENCY_NOT_SUPPORTED 1 46 47#define KEY_VALUE_MAPPING_FOUND 0 48#define KEY_VALUE_MAPPING_NOT_FOUND -1 49 50#define DISPATCH_TEST_SUCCESS 0 51#define DISPATCH_TEST_FN_NOT_FOUND 1 52#define DISPATCH_INVALID_TEST_DATA 2 53#define DISPATCH_UNSUPPORTED_SUITE 3 54 55 56/*----------------------------------------------------------------------------*/ 57/* Macros */ 58 59#define TEST_ASSERT( TEST ) \ 60 do { \ 61 if( ! (TEST) ) \ 62 { \ 63 test_fail( #TEST, __LINE__, __FILE__ ); \ 64 goto exit; \ 65 } \ 66 } while( 0 ) 67 68#define assert(a) if( !( a ) ) \ 69{ \ 70 mbedtls_fprintf( stderr, "Assertion Failed at %s:%d - %s\n", \ 71 __FILE__, __LINE__, #a ); \ 72 mbedtls_exit( 1 ); \ 73} 74 75/* 76 * 32-bit integer manipulation macros (big endian) 77 */ 78#ifndef GET_UINT32_BE 79#define GET_UINT32_BE(n,b,i) \ 80{ \ 81 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ 82 | ( (uint32_t) (b)[(i) + 1] << 16 ) \ 83 | ( (uint32_t) (b)[(i) + 2] << 8 ) \ 84 | ( (uint32_t) (b)[(i) + 3] ); \ 85} 86#endif 87 88#ifndef PUT_UINT32_BE 89#define PUT_UINT32_BE(n,b,i) \ 90{ \ 91 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 92 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 93 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 94 (b)[(i) + 3] = (unsigned char) ( (n) ); \ 95} 96#endif 97 98 99/*----------------------------------------------------------------------------*/ 100/* Global variables */ 101 102static int test_errors = 0; 103 104 105/*----------------------------------------------------------------------------*/ 106/* Helper Functions */ 107 108#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) 109static int redirect_output( FILE** out_stream, const char* path ) 110{ 111 int stdout_fd = dup( fileno( *out_stream ) ); 112 113 if( stdout_fd == -1 ) 114 { 115 return -1; 116 } 117 118 fflush( *out_stream ); 119 fclose( *out_stream ); 120 *out_stream = fopen( path, "w" ); 121 122 if( *out_stream == NULL ) 123 { 124 return -1; 125 } 126 127 return stdout_fd; 128} 129 130static int restore_output( FILE** out_stream, int old_fd ) 131{ 132 fflush( *out_stream ); 133 fclose( *out_stream ); 134 135 *out_stream = fdopen( old_fd, "w" ); 136 if( *out_stream == NULL ) 137 { 138 return -1; 139 } 140 141 return 0; 142} 143 144static void close_output( FILE* out_stream ) 145{ 146 fclose( out_stream ); 147} 148#endif /* __unix__ || __APPLE__ __MACH__ */ 149 150static int unhexify( unsigned char *obuf, const char *ibuf ) 151{ 152 unsigned char c, c2; 153 int len = strlen( ibuf ) / 2; 154 assert( strlen( ibuf ) % 2 == 0 ); /* must be even number of bytes */ 155 156 while( *ibuf != 0 ) 157 { 158 c = *ibuf++; 159 if( c >= '0' && c <= '9' ) 160 c -= '0'; 161 else if( c >= 'a' && c <= 'f' ) 162 c -= 'a' - 10; 163 else if( c >= 'A' && c <= 'F' ) 164 c -= 'A' - 10; 165 else 166 assert( 0 ); 167 168 c2 = *ibuf++; 169 if( c2 >= '0' && c2 <= '9' ) 170 c2 -= '0'; 171 else if( c2 >= 'a' && c2 <= 'f' ) 172 c2 -= 'a' - 10; 173 else if( c2 >= 'A' && c2 <= 'F' ) 174 c2 -= 'A' - 10; 175 else 176 assert( 0 ); 177 178 *obuf++ = ( c << 4 ) | c2; 179 } 180 181 return len; 182} 183 184static void hexify( unsigned char *obuf, const unsigned char *ibuf, int len ) 185{ 186 unsigned char l, h; 187 188 while( len != 0 ) 189 { 190 h = *ibuf / 16; 191 l = *ibuf % 16; 192 193 if( h < 10 ) 194 *obuf++ = '0' + h; 195 else 196 *obuf++ = 'a' + h - 10; 197 198 if( l < 10 ) 199 *obuf++ = '0' + l; 200 else 201 *obuf++ = 'a' + l - 10; 202 203 ++ibuf; 204 len--; 205 } 206} 207 208/** 209 * Allocate and zeroize a buffer. 210 * 211 * If the size if zero, a pointer to a zeroized 1-byte buffer is returned. 212 * 213 * For convenience, dies if allocation fails. 214 */ 215static unsigned char *zero_alloc( size_t len ) 216{ 217 void *p; 218 size_t actual_len = ( len != 0 ) ? len : 1; 219 220 p = mbedtls_calloc( 1, actual_len ); 221 assert( p != NULL ); 222 223 memset( p, 0x00, actual_len ); 224 225 return( p ); 226} 227 228/** 229 * Allocate and fill a buffer from hex data. 230 * 231 * The buffer is sized exactly as needed. This allows to detect buffer 232 * overruns (including overreads) when running the test suite under valgrind. 233 * 234 * If the size if zero, a pointer to a zeroized 1-byte buffer is returned. 235 * 236 * For convenience, dies if allocation fails. 237 */ 238static unsigned char *unhexify_alloc( const char *ibuf, size_t *olen ) 239{ 240 unsigned char *obuf; 241 242 *olen = strlen( ibuf ) / 2; 243 244 if( *olen == 0 ) 245 return( zero_alloc( *olen ) ); 246 247 obuf = mbedtls_calloc( 1, *olen ); 248 assert( obuf != NULL ); 249 250 (void) unhexify( obuf, ibuf ); 251 252 return( obuf ); 253} 254 255/** 256 * This function just returns data from rand(). 257 * Although predictable and often similar on multiple 258 * runs, this does not result in identical random on 259 * each run. So do not use this if the results of a 260 * test depend on the random data that is generated. 261 * 262 * rng_state shall be NULL. 263 */ 264static int rnd_std_rand( void *rng_state, unsigned char *output, size_t len ) 265{ 266#if !defined(__OpenBSD__) 267 size_t i; 268 269 if( rng_state != NULL ) 270 rng_state = NULL; 271 272 for( i = 0; i < len; ++i ) 273 output[i] = rand(); 274#else 275 if( rng_state != NULL ) 276 rng_state = NULL; 277 278 arc4random_buf( output, len ); 279#endif /* !OpenBSD */ 280 281 return( 0 ); 282} 283 284/** 285 * This function only returns zeros 286 * 287 * rng_state shall be NULL. 288 */ 289static int rnd_zero_rand( void *rng_state, unsigned char *output, size_t len ) 290{ 291 if( rng_state != NULL ) 292 rng_state = NULL; 293 294 memset( output, 0, len ); 295 296 return( 0 ); 297} 298 299typedef struct 300{ 301 unsigned char *buf; 302 size_t length; 303} rnd_buf_info; 304 305/** 306 * This function returns random based on a buffer it receives. 307 * 308 * rng_state shall be a pointer to a rnd_buf_info structure. 309 * 310 * The number of bytes released from the buffer on each call to 311 * the random function is specified by per_call. (Can be between 312 * 1 and 4) 313 * 314 * After the buffer is empty it will return rand(); 315 */ 316static int rnd_buffer_rand( void *rng_state, unsigned char *output, size_t len ) 317{ 318 rnd_buf_info *info = (rnd_buf_info *) rng_state; 319 size_t use_len; 320 321 if( rng_state == NULL ) 322 return( rnd_std_rand( NULL, output, len ) ); 323 324 use_len = len; 325 if( len > info->length ) 326 use_len = info->length; 327 328 if( use_len ) 329 { 330 memcpy( output, info->buf, use_len ); 331 info->buf += use_len; 332 info->length -= use_len; 333 } 334 335 if( len - use_len > 0 ) 336 return( rnd_std_rand( NULL, output + use_len, len - use_len ) ); 337 338 return( 0 ); 339} 340 341/** 342 * Info structure for the pseudo random function 343 * 344 * Key should be set at the start to a test-unique value. 345 * Do not forget endianness! 346 * State( v0, v1 ) should be set to zero. 347 */ 348typedef struct 349{ 350 uint32_t key[16]; 351 uint32_t v0, v1; 352} rnd_pseudo_info; 353 354/** 355 * This function returns random based on a pseudo random function. 356 * This means the results should be identical on all systems. 357 * Pseudo random is based on the XTEA encryption algorithm to 358 * generate pseudorandom. 359 * 360 * rng_state shall be a pointer to a rnd_pseudo_info structure. 361 */ 362static int rnd_pseudo_rand( void *rng_state, unsigned char *output, size_t len ) 363{ 364 rnd_pseudo_info *info = (rnd_pseudo_info *) rng_state; 365 uint32_t i, *k, sum, delta=0x9E3779B9; 366 unsigned char result[4], *out = output; 367 368 if( rng_state == NULL ) 369 return( rnd_std_rand( NULL, output, len ) ); 370 371 k = info->key; 372 373 while( len > 0 ) 374 { 375 size_t use_len = ( len > 4 ) ? 4 : len; 376 sum = 0; 377 378 for( i = 0; i < 32; i++ ) 379 { 380 info->v0 += ( ( ( info->v1 << 4 ) ^ ( info->v1 >> 5 ) ) 381 + info->v1 ) ^ ( sum + k[sum & 3] ); 382 sum += delta; 383 info->v1 += ( ( ( info->v0 << 4 ) ^ ( info->v0 >> 5 ) ) 384 + info->v0 ) ^ ( sum + k[( sum>>11 ) & 3] ); 385 } 386 387 PUT_UINT32_BE( info->v0, result, 0 ); 388 memcpy( out, result, use_len ); 389 len -= use_len; 390 out += 4; 391 } 392 393 return( 0 ); 394} 395 396static void test_fail( const char *test, int line_no, const char* filename ) 397{ 398 test_errors++; 399 if( test_errors == 1 ) 400 mbedtls_fprintf( stdout, "FAILED\n" ); 401 mbedtls_fprintf( stdout, " %s\n at line %d, %s\n", test, line_no, 402 filename ); 403} 404 405