blob: 54b7cc4a34ef9c63d67a34c495956ed76f9b7ec7 [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
SimonB0284f582016-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
SimonB0284f582016-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
SimonB0284f582016-02-15 23:27:28 +0000144
145/*----------------------------------------------------------------------------*/
146/* Main Test code */
147
Gilles Peskinee38900b2017-09-29 15:45:12 +0200148/** Retrieve one input line into buf, which must have room for len
149 * bytes. The trailing line break (if any) is stripped from the result.
150 * Lines beginning with the character '#' are skipped. Lines that are
151 * more than len-1 bytes long including the trailing line break are
152 * truncated; note that the following bytes remain in the input stream.
153 *
154 * \return 0 on success, -1 on error or end of file
155 */
Paul Bakker19343182013-08-16 13:31:10 +0200156int get_line( FILE *f, char *buf, size_t len )
157{
158 char *ret;
159
Gilles Peskinee38900b2017-09-29 15:45:12 +0200160 do
161 {
162 ret = fgets( buf, len, f );
163 if( ret == NULL )
164 return( -1 );
165 }
166 while( buf[0] == '#' );
Paul Bakker19343182013-08-16 13:31:10 +0200167
Gilles Peskinee38900b2017-09-29 15:45:12 +0200168 ret = buf + strlen( buf );
169 if( ret-- > buf && *ret == '\n' )
170 *ret = '\0';
171 if( ret-- > buf && *ret == '\r' )
172 *ret = '\0';
Paul Bakker19343182013-08-16 13:31:10 +0200173
174 return( 0 );
175}
176
177int parse_arguments( char *buf, size_t len, char *params[50] )
178{
179 int cnt = 0, i;
180 char *cur = buf;
181 char *p = buf, *q;
182
183 params[cnt++] = cur;
184
185 while( *p != '\0' && p < buf + len )
186 {
187 if( *p == '\\' )
188 {
Manuel Pégourié-Gonnard2d5f1422014-01-22 16:01:17 +0100189 p++;
190 p++;
Paul Bakker19343182013-08-16 13:31:10 +0200191 continue;
192 }
193 if( *p == ':' )
194 {
195 if( p + 1 < buf + len )
196 {
197 cur = p + 1;
198 params[cnt++] = cur;
199 }
200 *p = '\0';
201 }
202
Manuel Pégourié-Gonnard2d5f1422014-01-22 16:01:17 +0100203 p++;
Paul Bakker19343182013-08-16 13:31:10 +0200204 }
205
206 // Replace newlines, question marks and colons in strings
207 for( i = 0; i < cnt; i++ )
208 {
209 p = params[i];
210 q = params[i];
211
212 while( *p != '\0' )
213 {
214 if( *p == '\\' && *(p + 1) == 'n' )
215 {
216 p += 2;
217 *(q++) = '\n';
218 }
219 else if( *p == '\\' && *(p + 1) == ':' )
220 {
221 p += 2;
222 *(q++) = ':';
223 }
224 else if( *p == '\\' && *(p + 1) == '?' )
225 {
226 p += 2;
227 *(q++) = '?';
228 }
229 else
230 *(q++) = *(p++);
231 }
232 *q = '\0';
233 }
234
235 return( cnt );
236}
237
Manuel Pégourié-Gonnard7b6dcbe2015-06-22 10:48:01 +0200238static int test_snprintf( size_t n, const char ref_buf[10], int ref_ret )
239{
240 int ret;
241 char buf[10] = "xxxxxxxxx";
Manuel Pégourié-Gonnard4b00f082015-06-26 11:24:32 +0200242 const char ref[10] = "xxxxxxxxx";
Manuel Pégourié-Gonnard7b6dcbe2015-06-22 10:48:01 +0200243
244 ret = mbedtls_snprintf( buf, n, "%s", "123" );
245 if( ret < 0 || (size_t) ret >= n )
246 ret = -1;
247
Manuel Pégourié-Gonnard4b00f082015-06-26 11:24:32 +0200248 if( strncmp( ref_buf, buf, sizeof( buf ) ) != 0 ||
249 ref_ret != ret ||
250 memcmp( buf + n, ref + n, sizeof( buf ) - n ) != 0 )
Manuel Pégourié-Gonnard7b6dcbe2015-06-22 10:48:01 +0200251 {
252 return( 1 );
253 }
254
255 return( 0 );
256}
257
258static int run_test_snprintf( void )
259{
260 return( test_snprintf( 0, "xxxxxxxxx", -1 ) != 0 ||
Manuel Pégourié-Gonnard4b00f082015-06-26 11:24:32 +0200261 test_snprintf( 1, "", -1 ) != 0 ||
262 test_snprintf( 2, "1", -1 ) != 0 ||
263 test_snprintf( 3, "12", -1 ) != 0 ||
264 test_snprintf( 4, "123", 3 ) != 0 ||
265 test_snprintf( 5, "123", 3 ) != 0 );
Manuel Pégourié-Gonnard7b6dcbe2015-06-22 10:48:01 +0200266}
267
Paul Bakker19343182013-08-16 13:31:10 +0200268int main()
269{
270 int ret, i, cnt, total_errors = 0, total_tests = 0, total_skipped = 0;
271 const char *filename = "TEST_FILENAME";
272 FILE *file;
273 char buf[5000];
274 char *params[50];
Manuel Pégourié-Gonnardd14acbc2015-05-29 11:26:37 +0200275 void *pointer;
Paul Bakker19343182013-08-16 13:31:10 +0200276
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200277#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
Manuel Pégourié-Gonnard765bb312014-11-27 11:55:27 +0100278 !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC)
Paul Bakker1337aff2013-09-29 14:45:34 +0200279 unsigned char alloc_buf[1000000];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200280 mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
Paul Bakker19343182013-08-16 13:31:10 +0200281#endif
282
Manuel Pégourié-Gonnardd14acbc2015-05-29 11:26:37 +0200283 /*
284 * The C standard doesn't guarantee that all-bits-0 is the representation
285 * of a NULL pointer. We do however use that in our code for initializing
286 * structures, which should work on every modern platform. Let's be sure.
287 */
288 memset( &pointer, 0, sizeof( void * ) );
289 if( pointer != NULL )
290 {
291 mbedtls_fprintf( stderr, "all-bits-zero is not a NULL pointer\n" );
292 return( 1 );
293 }
294
Manuel Pégourié-Gonnard7b6dcbe2015-06-22 10:48:01 +0200295 /*
296 * Make sure we have a snprintf that correctly zero-terminates
297 */
298 if( run_test_snprintf() != 0 )
299 {
300 mbedtls_fprintf( stderr, "the snprintf implementation is broken\n" );
301 return( 0 );
302 }
303
Paul Bakker19343182013-08-16 13:31:10 +0200304 file = fopen( filename, "r" );
305 if( file == NULL )
306 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200307 mbedtls_fprintf( stderr, "Failed to open\n" );
Paul Bakker19343182013-08-16 13:31:10 +0200308 return( 1 );
309 }
310
311 while( !feof( file ) )
312 {
313 int skip = 0;
314
315 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
316 break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200317 mbedtls_fprintf( stdout, "%s%.66s", test_errors ? "\n" : "", buf );
318 mbedtls_fprintf( stdout, " " );
Paul Bakker19343182013-08-16 13:31:10 +0200319 for( i = strlen( buf ) + 1; i < 67; i++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200320 mbedtls_fprintf( stdout, "." );
321 mbedtls_fprintf( stdout, " " );
Paul Bakker19343182013-08-16 13:31:10 +0200322 fflush( stdout );
323
324 total_tests++;
325
326 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
327 break;
328 cnt = parse_arguments( buf, strlen(buf), params );
329
330 if( strcmp( params[0], "depends_on" ) == 0 )
331 {
332 for( i = 1; i < cnt; i++ )
333 if( dep_check( params[i] ) != 0 )
334 skip = 1;
335
336 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
337 break;
338 cnt = parse_arguments( buf, strlen(buf), params );
339 }
340
341 if( skip == 0 )
342 {
343 test_errors = 0;
344 ret = dispatch_test( cnt, params );
345 }
346
347 if( skip == 1 || ret == 3 )
348 {
349 total_skipped++;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200350 mbedtls_fprintf( stdout, "----\n" );
Paul Bakker19343182013-08-16 13:31:10 +0200351 fflush( stdout );
352 }
Paul Bakker33b43f12013-08-20 11:48:36 +0200353 else if( ret == 0 && test_errors == 0 )
Paul Bakker19343182013-08-16 13:31:10 +0200354 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200355 mbedtls_fprintf( stdout, "PASS\n" );
Paul Bakker19343182013-08-16 13:31:10 +0200356 fflush( stdout );
357 }
358 else if( ret == 2 )
359 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360 mbedtls_fprintf( stderr, "FAILED: FATAL PARSE ERROR\n" );
Paul Bakker19343182013-08-16 13:31:10 +0200361 fclose(file);
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200362 mbedtls_exit( 2 );
Paul Bakker19343182013-08-16 13:31:10 +0200363 }
364 else
365 total_errors++;
366
367 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
368 break;
369 if( strlen(buf) != 0 )
370 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200371 mbedtls_fprintf( stderr, "Should be empty %d\n", (int) strlen(buf) );
Paul Bakker19343182013-08-16 13:31:10 +0200372 return( 1 );
373 }
374 }
375 fclose(file);
376
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377 mbedtls_fprintf( stdout, "\n----------------------------------------------------------------------------\n\n");
Paul Bakker19343182013-08-16 13:31:10 +0200378 if( total_errors == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200379 mbedtls_fprintf( stdout, "PASSED" );
Paul Bakker19343182013-08-16 13:31:10 +0200380 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200381 mbedtls_fprintf( stdout, "FAILED" );
Paul Bakker19343182013-08-16 13:31:10 +0200382
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200383 mbedtls_fprintf( stdout, " (%d / %d tests (%d skipped))\n",
Paul Bakker19343182013-08-16 13:31:10 +0200384 total_tests - total_errors, total_tests, total_skipped );
385
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200386#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
Manuel Pégourié-Gonnard765bb312014-11-27 11:55:27 +0100387 !defined(TEST_SUITE_MEMORY_BUFFER_ALLOC)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388#if defined(MBEDTLS_MEMORY_DEBUG)
389 mbedtls_memory_buffer_alloc_status();
Paul Bakker19343182013-08-16 13:31:10 +0200390#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391 mbedtls_memory_buffer_alloc_free();
Paul Bakker1337aff2013-09-29 14:45:34 +0200392#endif
Paul Bakker19343182013-08-16 13:31:10 +0200393
394 return( total_errors != 0 );
395}
396