blob: 2a21441a492c88f301fef311f21d29b45a02cf72 [file] [log] [blame]
Rich Evans77d36382015-01-30 12:12:11 +00001#include <string.h>
2
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00004#include "mbedtls/platform.h"
Rich Evans77d36382015-01-30 12:12:11 +00005#else
Rich Evans012acfc2015-01-30 12:12:11 +00006#include <stdio.h>
Manuel Pégourié-Gonnard7b6dcbe2015-06-22 10:48:01 +02007#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02008#define mbedtls_exit exit
9#define mbedtls_free free
Manuel Pégourié-Gonnard7b6dcbe2015-06-22 10:48:01 +020010#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020011#define mbedtls_fprintf fprintf
12#define mbedtls_printf printf
Manuel Pégourié-Gonnard7b6dcbe2015-06-22 10:48:01 +020013#define mbedtls_snprintf snprintf
Rich Evans77d36382015-01-30 12:12:11 +000014#endif
15
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020016#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000017#include "mbedtls/memory_buffer_alloc.h"
Manuel Pégourié-Gonnard0ac1d2d2015-01-26 14:58:04 +010018#endif
19
Paul Bakker19343182013-08-16 13:31:10 +020020static int test_errors = 0;
21
Paul Bakkerde56ca12013-09-15 17:05:21 +020022SUITE_PRE_DEP
23#define TEST_SUITE_ACTIVE
24
Manuel Pégourié-Gonnarde91e21c2015-06-22 18:47:07 +020025static void test_fail( const char *test )
Paul Bakker19343182013-08-16 13:31:10 +020026{
Paul Bakker19343182013-08-16 13:31:10 +020027 test_errors++;
Paul Bakker55a7e902013-08-19 14:02:10 +020028 if( test_errors == 1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020029 mbedtls_printf( "FAILED\n" );
30 mbedtls_printf( " %s\n", test );
Paul Bakker19343182013-08-16 13:31:10 +020031}
32
Paul Bakkerbb20f4b2013-08-20 12:41:33 +020033#define TEST_ASSERT( TEST ) \
Manuel Pégourié-Gonnarde91e21c2015-06-22 18:47:07 +020034 do { \
35 if( ! (TEST) ) \
36 { \
37 test_fail( #TEST ); \
38 goto exit; \
39 } \
40 } while( 0 )
Paul Bakker19343182013-08-16 13:31:10 +020041
42int verify_string( char **str )
43{
44 if( (*str)[0] != '"' ||
45 (*str)[strlen( *str ) - 1] != '"' )
46 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047 mbedtls_printf( "Expected string (with \"\") for parameter and got: %s\n", *str );
Paul Bakker19343182013-08-16 13:31:10 +020048 return( -1 );
49 }
50
51 (*str)++;
52 (*str)[strlen( *str ) - 1] = '\0';
53
54 return( 0 );
55}
56
57int verify_int( char *str, int *value )
58{
59 size_t i;
60 int minus = 0;
61 int digits = 1;
62 int hex = 0;
63
64 for( i = 0; i < strlen( str ); i++ )
65 {
66 if( i == 0 && str[i] == '-' )
67 {
68 minus = 1;
69 continue;
70 }
71
72 if( ( ( minus && i == 2 ) || ( !minus && i == 1 ) ) &&
73 str[i - 1] == '0' && str[i] == 'x' )
74 {
75 hex = 1;
76 continue;
77 }
78
Manuel Pégourié-Gonnard725afd82014-02-01 11:54:28 +010079 if( ! ( ( str[i] >= '0' && str[i] <= '9' ) ||
80 ( hex && ( ( str[i] >= 'a' && str[i] <= 'f' ) ||
81 ( str[i] >= 'A' && str[i] <= 'F' ) ) ) ) )
Paul Bakker19343182013-08-16 13:31:10 +020082 {
83 digits = 0;
84 break;
85 }
86 }
87
88 if( digits )
89 {
90 if( hex )
91 *value = strtol( str, NULL, 16 );
92 else
93 *value = strtol( str, NULL, 10 );
94
95 return( 0 );
96 }
97
98MAPPING_CODE
99
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200100 mbedtls_printf( "Expected integer for parameter and got: %s\n", str );
Paul Bakker19343182013-08-16 13:31:10 +0200101 return( -1 );
102}
103
SimonB152ea182016-02-15 23:27:28 +0000104
105/*----------------------------------------------------------------------------*/
106/* Test Case code */
107
Paul Bakkerde56ca12013-09-15 17:05:21 +0200108FUNCTION_CODE
109SUITE_POST_DEP
110
SimonB152ea182016-02-15 23:27:28 +0000111
112/*----------------------------------------------------------------------------*/
113/* Test dispatch code */
114
Paul Bakker19343182013-08-16 13:31:10 +0200115int dep_check( char *str )
116{
117 if( str == NULL )
118 return( 1 );
119
120DEP_CHECK_CODE
121
122 return( 1 );
123}
124
Paul Bakker19343182013-08-16 13:31:10 +0200125int dispatch_test(int cnt, char *params[50])
126{
127 int ret;
Paul Bakkerb34fef22013-08-20 12:06:33 +0200128 ((void) cnt);
129 ((void) params);
Paul Bakker19343182013-08-16 13:31:10 +0200130
Paul Bakkerb34fef22013-08-20 12:06:33 +0200131#if defined(TEST_SUITE_ACTIVE)
Paul Bakker19343182013-08-16 13:31:10 +0200132DISPATCH_FUNCTION
133 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200134 mbedtls_fprintf( stdout, "FAILED\nSkipping unknown test function '%s'\n", params[0] );
Paul Bakker19343182013-08-16 13:31:10 +0200135 fflush( stdout );
136 return( 1 );
137 }
Paul Bakkerb34fef22013-08-20 12:06:33 +0200138#else
139 return( 3 );
140#endif
Paul Bakker19343182013-08-16 13:31:10 +0200141 return( ret );
142}
143
SimonB152ea182016-02-15 23:27:28 +0000144
145/*----------------------------------------------------------------------------*/
146/* Main Test code */
147
Paul Bakker19343182013-08-16 13:31:10 +0200148int get_line( FILE *f, char *buf, size_t len )
149{
150 char *ret;
151
152 ret = fgets( buf, len, f );
153 if( ret == NULL )
154 return( -1 );
155
156 if( strlen( buf ) && buf[strlen(buf) - 1] == '\n' )
157 buf[strlen(buf) - 1] = '\0';
158 if( strlen( buf ) && buf[strlen(buf) - 1] == '\r' )
159 buf[strlen(buf) - 1] = '\0';
160
161 return( 0 );
162}
163
164int parse_arguments( char *buf, size_t len, char *params[50] )
165{
166 int cnt = 0, i;
167 char *cur = buf;
168 char *p = buf, *q;
169
170 params[cnt++] = cur;
171
172 while( *p != '\0' && p < buf + len )
173 {
174 if( *p == '\\' )
175 {
Manuel Pégourié-Gonnard2d5f1422014-01-22 16:01:17 +0100176 p++;
177 p++;
Paul Bakker19343182013-08-16 13:31:10 +0200178 continue;
179 }
180 if( *p == ':' )
181 {
182 if( p + 1 < buf + len )
183 {
184 cur = p + 1;
185 params[cnt++] = cur;
186 }
187 *p = '\0';
188 }
189
Manuel Pégourié-Gonnard2d5f1422014-01-22 16:01:17 +0100190 p++;
Paul Bakker19343182013-08-16 13:31:10 +0200191 }
192
193 // Replace newlines, question marks and colons in strings
194 for( i = 0; i < cnt; i++ )
195 {
196 p = params[i];
197 q = params[i];
198
199 while( *p != '\0' )
200 {
201 if( *p == '\\' && *(p + 1) == 'n' )
202 {
203 p += 2;
204 *(q++) = '\n';
205 }
206 else if( *p == '\\' && *(p + 1) == ':' )
207 {
208 p += 2;
209 *(q++) = ':';
210 }
211 else if( *p == '\\' && *(p + 1) == '?' )
212 {
213 p += 2;
214 *(q++) = '?';
215 }
216 else
217 *(q++) = *(p++);
218 }
219 *q = '\0';
220 }
221
222 return( cnt );
223}
224
Manuel Pégourié-Gonnard7b6dcbe2015-06-22 10:48:01 +0200225static int test_snprintf( size_t n, const char ref_buf[10], int ref_ret )
226{
227 int ret;
228 char buf[10] = "xxxxxxxxx";
Manuel Pégourié-Gonnard4b00f082015-06-26 11:24:32 +0200229 const char ref[10] = "xxxxxxxxx";
Manuel Pégourié-Gonnard7b6dcbe2015-06-22 10:48:01 +0200230
231 ret = mbedtls_snprintf( buf, n, "%s", "123" );
232 if( ret < 0 || (size_t) ret >= n )
233 ret = -1;
234
Manuel Pégourié-Gonnard4b00f082015-06-26 11:24:32 +0200235 if( strncmp( ref_buf, buf, sizeof( buf ) ) != 0 ||
236 ref_ret != ret ||
237 memcmp( buf + n, ref + n, sizeof( buf ) - n ) != 0 )
Manuel Pégourié-Gonnard7b6dcbe2015-06-22 10:48:01 +0200238 {
239 return( 1 );
240 }
241
242 return( 0 );
243}
244
245static int run_test_snprintf( void )
246{
247 return( test_snprintf( 0, "xxxxxxxxx", -1 ) != 0 ||
Manuel Pégourié-Gonnard4b00f082015-06-26 11:24:32 +0200248 test_snprintf( 1, "", -1 ) != 0 ||
249 test_snprintf( 2, "1", -1 ) != 0 ||
250 test_snprintf( 3, "12", -1 ) != 0 ||
251 test_snprintf( 4, "123", 3 ) != 0 ||
252 test_snprintf( 5, "123", 3 ) != 0 );
Manuel Pégourié-Gonnard7b6dcbe2015-06-22 10:48:01 +0200253}
254
Simon Butcheraad787f2016-01-26 22:13:58 +0000255int main(int argc, const char *argv[])
Paul Bakker19343182013-08-16 13:31:10 +0200256{
Simon Butcheraad787f2016-01-26 22:13:58 +0000257 int testfile_index, testfile_count, ret, i, cnt;
258 int total_errors = 0, total_tests = 0, total_skipped = 0;
259 const char *default_filename = "TEST_FILENAME";
260 const char *test_filename = NULL;
261 const char **test_files = NULL;
Paul Bakker19343182013-08-16 13:31:10 +0200262 FILE *file;
263 char buf[5000];
264 char *params[50];
Manuel Pégourié-Gonnardd14acbc2015-05-29 11:26:37 +0200265 void *pointer;
Paul Bakker19343182013-08-16 13:31:10 +0200266
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200267#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
Manuel Pégourié-Gonnard765bb312014-11-27 11:55:27 +0100268 !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC)
Paul Bakker1337aff2013-09-29 14:45:34 +0200269 unsigned char alloc_buf[1000000];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200270 mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
Paul Bakker19343182013-08-16 13:31:10 +0200271#endif
272
Manuel Pégourié-Gonnardd14acbc2015-05-29 11:26:37 +0200273 /*
274 * The C standard doesn't guarantee that all-bits-0 is the representation
275 * of a NULL pointer. We do however use that in our code for initializing
276 * structures, which should work on every modern platform. Let's be sure.
277 */
278 memset( &pointer, 0, sizeof( void * ) );
279 if( pointer != NULL )
280 {
281 mbedtls_fprintf( stderr, "all-bits-zero is not a NULL pointer\n" );
282 return( 1 );
283 }
284
Manuel Pégourié-Gonnard7b6dcbe2015-06-22 10:48:01 +0200285 /*
286 * Make sure we have a snprintf that correctly zero-terminates
287 */
288 if( run_test_snprintf() != 0 )
289 {
290 mbedtls_fprintf( stderr, "the snprintf implementation is broken\n" );
291 return( 0 );
292 }
293
Simon Butcheraad787f2016-01-26 22:13:58 +0000294 if ( argc <= 1 )
Paul Bakker19343182013-08-16 13:31:10 +0200295 {
Simon Butcheraad787f2016-01-26 22:13:58 +0000296 test_files = &default_filename;
297 testfile_count = 1;
298 }
299 else
300 {
301 test_files = &argv[1];
302 testfile_count = argc - 1;
Paul Bakker19343182013-08-16 13:31:10 +0200303 }
304
Simon Butcheraad787f2016-01-26 22:13:58 +0000305 for ( testfile_index = 0;
306 testfile_index < testfile_count;
307 testfile_index++ )
Paul Bakker19343182013-08-16 13:31:10 +0200308 {
Simon Butcheraad787f2016-01-26 22:13:58 +0000309 test_filename = test_files[ testfile_index ];
Paul Bakker19343182013-08-16 13:31:10 +0200310
Simon Butcheraad787f2016-01-26 22:13:58 +0000311 file = fopen( test_filename, "r" );
312 if( file == NULL )
Paul Bakker19343182013-08-16 13:31:10 +0200313 {
Simon Butcheraad787f2016-01-26 22:13:58 +0000314 mbedtls_fprintf( stderr, "Failed to open test file: %s\n",
315 test_filename );
316 return( 1 );
317 }
318
319 while( !feof( file ) )
320 {
321 int skip = 0;
322
323 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
324 break;
325 mbedtls_fprintf( stdout, "%s%.66s", test_errors ? "\n" : "", buf );
326 mbedtls_fprintf( stdout, " " );
327 for( i = strlen( buf ) + 1; i < 67; i++ )
328 mbedtls_fprintf( stdout, "." );
329 mbedtls_fprintf( stdout, " " );
330 fflush( stdout );
331
332 total_tests++;
Paul Bakker19343182013-08-16 13:31:10 +0200333
334 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
335 break;
336 cnt = parse_arguments( buf, strlen(buf), params );
Paul Bakker19343182013-08-16 13:31:10 +0200337
Simon Butcheraad787f2016-01-26 22:13:58 +0000338 if( strcmp( params[0], "depends_on" ) == 0 )
339 {
340 for( i = 1; i < cnt; i++ )
341 if( dep_check( params[i] ) != 0 )
342 skip = 1;
Paul Bakker19343182013-08-16 13:31:10 +0200343
Simon Butcheraad787f2016-01-26 22:13:58 +0000344 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
345 break;
346 cnt = parse_arguments( buf, strlen(buf), params );
347 }
Paul Bakker19343182013-08-16 13:31:10 +0200348
Simon Butcheraad787f2016-01-26 22:13:58 +0000349 if( skip == 0 )
350 {
351 test_errors = 0;
352 ret = dispatch_test( cnt, params );
353 }
354
355 if( skip == 1 || ret == 3 )
356 {
357 total_skipped++;
358 mbedtls_fprintf( stdout, "----\n" );
359 fflush( stdout );
360 }
361 else if( ret == 0 && test_errors == 0 )
362 {
363 mbedtls_fprintf( stdout, "PASS\n" );
364 fflush( stdout );
365 }
366 else if( ret == 2 )
367 {
368 mbedtls_fprintf( stderr, "FAILED: FATAL PARSE ERROR\n" );
369 fclose(file);
370 mbedtls_exit( 2 );
371 }
372 else
373 total_errors++;
374
375 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
376 break;
377 if( strlen(buf) != 0 )
378 {
379 mbedtls_fprintf( stderr, "Should be empty %d\n",
380 (int) strlen(buf) );
381 return( 1 );
382 }
Paul Bakker19343182013-08-16 13:31:10 +0200383 }
Simon Butcheraad787f2016-01-26 22:13:58 +0000384 fclose(file);
Paul Bakker19343182013-08-16 13:31:10 +0200385 }
Paul Bakker19343182013-08-16 13:31:10 +0200386
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200387 mbedtls_fprintf( stdout, "\n----------------------------------------------------------------------------\n\n");
Paul Bakker19343182013-08-16 13:31:10 +0200388 if( total_errors == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389 mbedtls_fprintf( stdout, "PASSED" );
Paul Bakker19343182013-08-16 13:31:10 +0200390 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391 mbedtls_fprintf( stdout, "FAILED" );
Paul Bakker19343182013-08-16 13:31:10 +0200392
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200393 mbedtls_fprintf( stdout, " (%d / %d tests (%d skipped))\n",
Paul Bakker19343182013-08-16 13:31:10 +0200394 total_tests - total_errors, total_tests, total_skipped );
395
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200396#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
Manuel Pégourié-Gonnard765bb312014-11-27 11:55:27 +0100397 !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200398#if defined(MBEDTLS_MEMORY_DEBUG)
399 mbedtls_memory_buffer_alloc_status();
Paul Bakker19343182013-08-16 13:31:10 +0200400#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200401 mbedtls_memory_buffer_alloc_free();
Paul Bakker1337aff2013-09-29 14:45:34 +0200402#endif
Paul Bakker19343182013-08-16 13:31:10 +0200403
404 return( total_errors != 0 );
405}
406