blob: db968e16c9a85c1f003c2a8ea7df0c0e3a199b61 [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
Paul Bakkerde56ca12013-09-15 17:05:21 +0200104FUNCTION_CODE
105SUITE_POST_DEP
106
Paul Bakker19343182013-08-16 13:31:10 +0200107int dep_check( char *str )
108{
109 if( str == NULL )
110 return( 1 );
111
112DEP_CHECK_CODE
113
114 return( 1 );
115}
116
Paul Bakker19343182013-08-16 13:31:10 +0200117int dispatch_test(int cnt, char *params[50])
118{
119 int ret;
Paul Bakkerb34fef22013-08-20 12:06:33 +0200120 ((void) cnt);
121 ((void) params);
Paul Bakker19343182013-08-16 13:31:10 +0200122
Paul Bakkerb34fef22013-08-20 12:06:33 +0200123#if defined(TEST_SUITE_ACTIVE)
Paul Bakker19343182013-08-16 13:31:10 +0200124DISPATCH_FUNCTION
125 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200126 mbedtls_fprintf( stdout, "FAILED\nSkipping unknown test function '%s'\n", params[0] );
Paul Bakker19343182013-08-16 13:31:10 +0200127 fflush( stdout );
128 return( 1 );
129 }
Paul Bakkerb34fef22013-08-20 12:06:33 +0200130#else
131 return( 3 );
132#endif
Paul Bakker19343182013-08-16 13:31:10 +0200133 return( ret );
134}
135
Gilles Peskinee38900b2017-09-29 15:45:12 +0200136/** Retrieve one input line into buf, which must have room for len
137 * bytes. The trailing line break (if any) is stripped from the result.
138 * Lines beginning with the character '#' are skipped. Lines that are
139 * more than len-1 bytes long including the trailing line break are
140 * truncated; note that the following bytes remain in the input stream.
141 *
142 * \return 0 on success, -1 on error or end of file
143 */
Paul Bakker19343182013-08-16 13:31:10 +0200144int get_line( FILE *f, char *buf, size_t len )
145{
146 char *ret;
147
Gilles Peskinee38900b2017-09-29 15:45:12 +0200148 do
149 {
150 ret = fgets( buf, len, f );
151 if( ret == NULL )
152 return( -1 );
153 }
154 while( buf[0] == '#' );
Paul Bakker19343182013-08-16 13:31:10 +0200155
Gilles Peskinee38900b2017-09-29 15:45:12 +0200156 ret = buf + strlen( buf );
157 if( ret-- > buf && *ret == '\n' )
158 *ret = '\0';
159 if( ret-- > buf && *ret == '\r' )
160 *ret = '\0';
Paul Bakker19343182013-08-16 13:31:10 +0200161
162 return( 0 );
163}
164
165int parse_arguments( char *buf, size_t len, char *params[50] )
166{
167 int cnt = 0, i;
168 char *cur = buf;
169 char *p = buf, *q;
170
171 params[cnt++] = cur;
172
173 while( *p != '\0' && p < buf + len )
174 {
175 if( *p == '\\' )
176 {
Manuel Pégourié-Gonnard2d5f1422014-01-22 16:01:17 +0100177 p++;
178 p++;
Paul Bakker19343182013-08-16 13:31:10 +0200179 continue;
180 }
181 if( *p == ':' )
182 {
183 if( p + 1 < buf + len )
184 {
185 cur = p + 1;
186 params[cnt++] = cur;
187 }
188 *p = '\0';
189 }
190
Manuel Pégourié-Gonnard2d5f1422014-01-22 16:01:17 +0100191 p++;
Paul Bakker19343182013-08-16 13:31:10 +0200192 }
193
194 // Replace newlines, question marks and colons in strings
195 for( i = 0; i < cnt; i++ )
196 {
197 p = params[i];
198 q = params[i];
199
200 while( *p != '\0' )
201 {
202 if( *p == '\\' && *(p + 1) == 'n' )
203 {
204 p += 2;
205 *(q++) = '\n';
206 }
207 else if( *p == '\\' && *(p + 1) == ':' )
208 {
209 p += 2;
210 *(q++) = ':';
211 }
212 else if( *p == '\\' && *(p + 1) == '?' )
213 {
214 p += 2;
215 *(q++) = '?';
216 }
217 else
218 *(q++) = *(p++);
219 }
220 *q = '\0';
221 }
222
223 return( cnt );
224}
225
Manuel Pégourié-Gonnard7b6dcbe2015-06-22 10:48:01 +0200226static int test_snprintf( size_t n, const char ref_buf[10], int ref_ret )
227{
228 int ret;
229 char buf[10] = "xxxxxxxxx";
Manuel Pégourié-Gonnard4b00f082015-06-26 11:24:32 +0200230 const char ref[10] = "xxxxxxxxx";
Manuel Pégourié-Gonnard7b6dcbe2015-06-22 10:48:01 +0200231
232 ret = mbedtls_snprintf( buf, n, "%s", "123" );
233 if( ret < 0 || (size_t) ret >= n )
234 ret = -1;
235
Manuel Pégourié-Gonnard4b00f082015-06-26 11:24:32 +0200236 if( strncmp( ref_buf, buf, sizeof( buf ) ) != 0 ||
237 ref_ret != ret ||
238 memcmp( buf + n, ref + n, sizeof( buf ) - n ) != 0 )
Manuel Pégourié-Gonnard7b6dcbe2015-06-22 10:48:01 +0200239 {
240 return( 1 );
241 }
242
243 return( 0 );
244}
245
246static int run_test_snprintf( void )
247{
248 return( test_snprintf( 0, "xxxxxxxxx", -1 ) != 0 ||
Manuel Pégourié-Gonnard4b00f082015-06-26 11:24:32 +0200249 test_snprintf( 1, "", -1 ) != 0 ||
250 test_snprintf( 2, "1", -1 ) != 0 ||
251 test_snprintf( 3, "12", -1 ) != 0 ||
252 test_snprintf( 4, "123", 3 ) != 0 ||
253 test_snprintf( 5, "123", 3 ) != 0 );
Manuel Pégourié-Gonnard7b6dcbe2015-06-22 10:48:01 +0200254}
255
Paul Bakker19343182013-08-16 13:31:10 +0200256int main()
257{
258 int ret, i, cnt, total_errors = 0, total_tests = 0, total_skipped = 0;
259 const char *filename = "TEST_FILENAME";
260 FILE *file;
261 char buf[5000];
262 char *params[50];
Manuel Pégourié-Gonnardd14acbc2015-05-29 11:26:37 +0200263 void *pointer;
Paul Bakker19343182013-08-16 13:31:10 +0200264
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200265#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
Manuel Pégourié-Gonnard765bb312014-11-27 11:55:27 +0100266 !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC)
Paul Bakker1337aff2013-09-29 14:45:34 +0200267 unsigned char alloc_buf[1000000];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200268 mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
Paul Bakker19343182013-08-16 13:31:10 +0200269#endif
270
Manuel Pégourié-Gonnardd14acbc2015-05-29 11:26:37 +0200271 /*
272 * The C standard doesn't guarantee that all-bits-0 is the representation
273 * of a NULL pointer. We do however use that in our code for initializing
274 * structures, which should work on every modern platform. Let's be sure.
275 */
276 memset( &pointer, 0, sizeof( void * ) );
277 if( pointer != NULL )
278 {
279 mbedtls_fprintf( stderr, "all-bits-zero is not a NULL pointer\n" );
280 return( 1 );
281 }
282
Manuel Pégourié-Gonnard7b6dcbe2015-06-22 10:48:01 +0200283 /*
284 * Make sure we have a snprintf that correctly zero-terminates
285 */
286 if( run_test_snprintf() != 0 )
287 {
288 mbedtls_fprintf( stderr, "the snprintf implementation is broken\n" );
289 return( 0 );
290 }
291
Paul Bakker19343182013-08-16 13:31:10 +0200292 file = fopen( filename, "r" );
293 if( file == NULL )
294 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200295 mbedtls_fprintf( stderr, "Failed to open\n" );
Paul Bakker19343182013-08-16 13:31:10 +0200296 return( 1 );
297 }
298
299 while( !feof( file ) )
300 {
301 int skip = 0;
302
303 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
304 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200305 mbedtls_fprintf( stdout, "%s%.66s", test_errors ? "\n" : "", buf );
306 mbedtls_fprintf( stdout, " " );
Paul Bakker19343182013-08-16 13:31:10 +0200307 for( i = strlen( buf ) + 1; i < 67; i++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200308 mbedtls_fprintf( stdout, "." );
309 mbedtls_fprintf( stdout, " " );
Paul Bakker19343182013-08-16 13:31:10 +0200310 fflush( stdout );
311
312 total_tests++;
313
314 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
315 break;
316 cnt = parse_arguments( buf, strlen(buf), params );
317
318 if( strcmp( params[0], "depends_on" ) == 0 )
319 {
320 for( i = 1; i < cnt; i++ )
321 if( dep_check( params[i] ) != 0 )
322 skip = 1;
323
324 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
325 break;
326 cnt = parse_arguments( buf, strlen(buf), params );
327 }
328
329 if( skip == 0 )
330 {
331 test_errors = 0;
332 ret = dispatch_test( cnt, params );
333 }
334
335 if( skip == 1 || ret == 3 )
336 {
337 total_skipped++;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338 mbedtls_fprintf( stdout, "----\n" );
Paul Bakker19343182013-08-16 13:31:10 +0200339 fflush( stdout );
340 }
Paul Bakker33b43f12013-08-20 11:48:36 +0200341 else if( ret == 0 && test_errors == 0 )
Paul Bakker19343182013-08-16 13:31:10 +0200342 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200343 mbedtls_fprintf( stdout, "PASS\n" );
Paul Bakker19343182013-08-16 13:31:10 +0200344 fflush( stdout );
345 }
346 else if( ret == 2 )
347 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200348 mbedtls_fprintf( stderr, "FAILED: FATAL PARSE ERROR\n" );
Paul Bakker19343182013-08-16 13:31:10 +0200349 fclose(file);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200350 mbedtls_exit( 2 );
Paul Bakker19343182013-08-16 13:31:10 +0200351 }
352 else
353 total_errors++;
354
355 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
356 break;
357 if( strlen(buf) != 0 )
358 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200359 mbedtls_fprintf( stderr, "Should be empty %d\n", (int) strlen(buf) );
Paul Bakker19343182013-08-16 13:31:10 +0200360 return( 1 );
361 }
362 }
363 fclose(file);
364
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200365 mbedtls_fprintf( stdout, "\n----------------------------------------------------------------------------\n\n");
Paul Bakker19343182013-08-16 13:31:10 +0200366 if( total_errors == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200367 mbedtls_fprintf( stdout, "PASSED" );
Paul Bakker19343182013-08-16 13:31:10 +0200368 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200369 mbedtls_fprintf( stdout, "FAILED" );
Paul Bakker19343182013-08-16 13:31:10 +0200370
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200371 mbedtls_fprintf( stdout, " (%d / %d tests (%d skipped))\n",
Paul Bakker19343182013-08-16 13:31:10 +0200372 total_tests - total_errors, total_tests, total_skipped );
373
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200374#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
Manuel Pégourié-Gonnard765bb312014-11-27 11:55:27 +0100375 !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200376#if defined(MBEDTLS_MEMORY_DEBUG)
377 mbedtls_memory_buffer_alloc_status();
Paul Bakker19343182013-08-16 13:31:10 +0200378#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200379 mbedtls_memory_buffer_alloc_free();
Paul Bakker1337aff2013-09-29 14:45:34 +0200380#endif
Paul Bakker19343182013-08-16 13:31:10 +0200381
382 return( total_errors != 0 );
383}
384