blob: 8c9e3bd09341ebc86d5f1fadf8ed2dfeedd9c613 [file] [log] [blame]
Gilles Peskinee137ebc2021-01-29 21:12:52 +01001#line 2 "helpers.function"
SimonB0269dad2016-02-17 23:34:30 +00002/*----------------------------------------------------------------------------*/
3/* Headers */
4
Simon Butcheredb7fd92016-05-17 13:35:51 +01005#include <stdlib.h>
6
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02007#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00008#include "mbedtls/platform.h"
Manuel Pégourié-Gonnard3d49b9d2014-06-06 14:48:09 +02009#else
Rich Evans00ab4702015-02-06 13:43:58 +000010#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020011#define mbedtls_fprintf fprintf
Simon Butcher25731362016-09-30 13:11:29 +010012#define mbedtls_snprintf snprintf
13#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020014#define mbedtls_free free
15#define mbedtls_exit exit
Simon Butcherb2d5dd12016-04-27 13:35:37 +010016#define mbedtls_time time
17#define mbedtls_time_t time_t
Janos Follath55abc212016-04-18 18:18:48 +010018#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
19#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
Manuel Pégourié-Gonnard3d49b9d2014-06-06 14:48:09 +020020#endif
21
SimonB0269dad2016-02-17 23:34:30 +000022#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
23#include "mbedtls/memory_buffer_alloc.h"
24#endif
25
Paul Bakkerb3dcbc12011-03-13 16:57:25 +000026#ifdef _MSC_VER
27#include <basetsd.h>
28typedef UINT32 uint32_t;
Nicholas Wilson733676b2015-11-14 13:09:01 +000029#define strncasecmp _strnicmp
30#define strcasecmp _stricmp
Paul Bakkerb3dcbc12011-03-13 16:57:25 +000031#else
Manuel Pégourié-Gonnard93866642015-06-22 19:21:23 +020032#include <stdint.h>
Paul Bakkerb3dcbc12011-03-13 16:57:25 +000033#endif
34
Paul Bakker19343182013-08-16 13:31:10 +020035#include <string.h>
36
Janos Follath8ca53b52016-10-05 10:57:49 +010037#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
38#include <unistd.h>
39#endif
SimonB0269dad2016-02-17 23:34:30 +000040
Gilles Peskine44498ff2021-01-29 21:17:11 +010041#if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_PTHREAD) && \
42 defined(MBEDTLS_TEST_HOOKS)
43#include "mbedtls/threading.h"
44#define MBEDTLS_TEST_MUTEX_USAGE
45#endif
46
Manuel Pégourié-Gonnard426c2d42020-08-25 11:26:37 +020047/*
48 * Define the two macros
49 *
50 * #define TEST_CF_SECRET(ptr, size)
51 * #define TEST_CF_PUBLIC(ptr, size)
52 *
53 * that can be used in tests to mark a memory area as secret (no branch or
54 * memory access should depend on it) or public (default, only needs to be
55 * marked explicitly when it was derived from secret data).
56 *
57 * Arguments:
58 * - ptr: a pointer to the memory area to be marked
59 * - size: the size in bytes of the memory area
60 *
61 * Implementation:
62 * The basic idea is that of ctgrind <https://github.com/agl/ctgrind>: we can
63 * re-use tools that were designed for checking use of uninitialized memory.
64 * This file contains two implementations: one based on MemorySanitizer, the
65 * other on valgrind's memcheck. If none of them is enabled, dummy macros that
66 * do nothing are defined for convenience.
67 */
Manuel Pégourié-Gonnard40597ce2020-07-28 10:53:06 +020068#if defined(MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN)
69#include <sanitizer/msan_interface.h>
70
71/* Use macros to avoid messing up with origin tracking */
72#define TEST_CF_SECRET __msan_allocated_memory
73// void __msan_allocated_memory(const volatile void* data, size_t size);
74#define TEST_CF_PUBLIC __msan_unpoison
75// void __msan_unpoison(const volatile void *a, size_t size);
76
Manuel Pégourié-Gonnard426c2d42020-08-25 11:26:37 +020077#elif defined(MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND)
78#include <valgrind/memcheck.h>
79
80#define TEST_CF_SECRET VALGRIND_MAKE_MEM_UNDEFINED
81// VALGRIND_MAKE_MEM_UNDEFINED(_qzz_addr, _qzz_len)
82#define TEST_CF_PUBLIC VALGRIND_MAKE_MEM_DEFINED
83// VALGRIND_MAKE_MEM_DEFINED(_qzz_addr, _qzz_len)
84
85#else /* MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN ||
86 MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND */
Manuel Pégourié-Gonnard40597ce2020-07-28 10:53:06 +020087
88#define TEST_CF_SECRET(ptr, size)
89#define TEST_CF_PUBLIC(ptr, size)
90
91#endif /* MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN */
92
SimonB0269dad2016-02-17 23:34:30 +000093/*----------------------------------------------------------------------------*/
SimonB8ca7bc42016-04-17 23:24:50 +010094/* Constants */
SimonB0269dad2016-02-17 23:34:30 +000095
SimonB8ca7bc42016-04-17 23:24:50 +010096#define DEPENDENCY_SUPPORTED 0
97#define DEPENDENCY_NOT_SUPPORTED 1
98
99#define KEY_VALUE_MAPPING_FOUND 0
100#define KEY_VALUE_MAPPING_NOT_FOUND -1
101
102#define DISPATCH_TEST_SUCCESS 0
103#define DISPATCH_TEST_FN_NOT_FOUND 1
104#define DISPATCH_INVALID_TEST_DATA 2
105#define DISPATCH_UNSUPPORTED_SUITE 3
SimonB0269dad2016-02-17 23:34:30 +0000106
107
108/*----------------------------------------------------------------------------*/
109/* Macros */
110
111#define TEST_ASSERT( TEST ) \
112 do { \
113 if( ! (TEST) ) \
114 { \
SimonB31a6c492016-05-02 21:32:44 +0100115 test_fail( #TEST, __LINE__, __FILE__ ); \
SimonB0269dad2016-02-17 23:34:30 +0000116 goto exit; \
117 } \
118 } while( 0 )
119
Rich Evans4c091142015-02-02 12:04:10 +0000120#define assert(a) if( !( a ) ) \
121{ \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200122 mbedtls_fprintf( stderr, "Assertion Failed at %s:%d - %s\n", \
Rich Evans4c091142015-02-02 12:04:10 +0000123 __FILE__, __LINE__, #a ); \
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200124 mbedtls_exit( 1 ); \
Rich Evans4c091142015-02-02 12:04:10 +0000125}
126
Ronald Croneb5d0e92020-04-06 10:34:22 +0200127#if defined(__GNUC__)
128/* Test if arg and &(arg)[0] have the same type. This is true if arg is
129 * an array but not if it's a pointer. */
130#define IS_ARRAY_NOT_POINTER( arg ) \
131 ( ! __builtin_types_compatible_p( __typeof__( arg ), \
132 __typeof__( &( arg )[0] ) ) )
133#else
134/* On platforms where we don't know how to implement this check,
135 * omit it. Oh well, a non-portable check is better than nothing. */
136#define IS_ARRAY_NOT_POINTER( arg ) 1
137#endif
138
139/* A compile-time constant with the value 0. If `const_expr` is not a
140 * compile-time constant with a nonzero value, cause a compile-time error. */
141#define STATIC_ASSERT_EXPR( const_expr ) \
makise-homura03c2b8f2020-08-23 00:28:45 +0300142 ( 0 && sizeof( struct { unsigned int STATIC_ASSERT : 1 - 2 * ! ( const_expr ); } ) )
Ronald Croneb5d0e92020-04-06 10:34:22 +0200143/* Return the scalar value `value` (possibly promoted). This is a compile-time
144 * constant if `value` is. `condition` must be a compile-time constant.
145 * If `condition` is false, arrange to cause a compile-time error. */
146#define STATIC_ASSERT_THEN_RETURN( condition, value ) \
147 ( STATIC_ASSERT_EXPR( condition ) ? 0 : ( value ) )
148
149#define ARRAY_LENGTH_UNSAFE( array ) \
150 ( sizeof( array ) / sizeof( *( array ) ) )
151/** Return the number of elements of a static or stack array.
152 *
153 * \param array A value of array (not pointer) type.
154 *
155 * \return The number of elements of the array.
156 */
157#define ARRAY_LENGTH( array ) \
158 ( STATIC_ASSERT_THEN_RETURN( IS_ARRAY_NOT_POINTER( array ), \
159 ARRAY_LENGTH_UNSAFE( array ) ) )
160
161
Paul Bakkerb3dcbc12011-03-13 16:57:25 +0000162/*
163 * 32-bit integer manipulation macros (big endian)
164 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000165#ifndef GET_UINT32_BE
166#define GET_UINT32_BE(n,b,i) \
Paul Bakkerb3dcbc12011-03-13 16:57:25 +0000167{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +0000168 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
169 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
170 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
171 | ( (uint32_t) (b)[(i) + 3] ); \
Paul Bakkerb3dcbc12011-03-13 16:57:25 +0000172}
173#endif
174
Paul Bakker5c2364c2012-10-01 14:41:15 +0000175#ifndef PUT_UINT32_BE
176#define PUT_UINT32_BE(n,b,i) \
Paul Bakkerb3dcbc12011-03-13 16:57:25 +0000177{ \
178 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
179 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
180 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
181 (b)[(i) + 3] = (unsigned char) ( (n) ); \
182}
183#endif
184
SimonB0269dad2016-02-17 23:34:30 +0000185
186/*----------------------------------------------------------------------------*/
SimonB8ca7bc42016-04-17 23:24:50 +0100187/* Global variables */
188
Andres Amaya Garcia3f50f512017-10-01 16:42:29 +0100189
190static struct
191{
192 int failed;
193 const char *test;
194 const char *filename;
195 int line_no;
196}
197test_info;
SimonB8ca7bc42016-04-17 23:24:50 +0100198
199
200/*----------------------------------------------------------------------------*/
Hanno Becker47deec42017-07-24 12:27:09 +0100201/* Helper flags for complex dependencies */
202
203/* Indicates whether we expect mbedtls_entropy_init
204 * to initialize some strong entropy source. */
205#if defined(MBEDTLS_TEST_NULL_ENTROPY) || \
206 ( !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) && \
207 ( !defined(MBEDTLS_NO_PLATFORM_ENTROPY) || \
208 defined(MBEDTLS_HAVEGE_C) || \
209 defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \
210 defined(ENTROPY_NV_SEED) ) )
Hanno Beckerd4a872e2017-09-07 08:09:33 +0100211#define ENTROPY_HAVE_STRONG
Hanno Becker47deec42017-07-24 12:27:09 +0100212#endif
213
214
215/*----------------------------------------------------------------------------*/
SimonB0269dad2016-02-17 23:34:30 +0000216/* Helper Functions */
217
Simon Butcher638dceb2018-10-03 16:17:41 +0100218void test_fail( const char *test, int line_no, const char* filename )
219{
Gilles Peskined4c9fd12020-08-31 10:21:58 +0200220 if( test_info.failed )
221 {
222 /* We've already recorded the test as having failed. Don't
223 * overwrite any previous information about the failure. */
224 return;
225 }
Simon Butcher638dceb2018-10-03 16:17:41 +0100226 test_info.failed = 1;
227 test_info.test = test;
228 test_info.line_no = line_no;
229 test_info.filename = filename;
230}
231
Janos Follath8ca53b52016-10-05 10:57:49 +0100232#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
gufe44b0ab8c22020-07-30 09:02:27 +0200233static int redirect_output( FILE* out_stream, const char* path )
Janos Follath8ca53b52016-10-05 10:57:49 +0100234{
gufe44b0ab8c22020-07-30 09:02:27 +0200235 int out_fd, dup_fd;
236 FILE* path_stream;
Janos Follath8ca53b52016-10-05 10:57:49 +0100237
gufe44b0ab8c22020-07-30 09:02:27 +0200238 out_fd = fileno( out_stream );
239 dup_fd = dup( out_fd );
240
241 if( dup_fd == -1 )
Janos Follath8ca53b52016-10-05 10:57:49 +0100242 {
gufe44b0ab8c22020-07-30 09:02:27 +0200243 return( -1 );
Janos Follath8ca53b52016-10-05 10:57:49 +0100244 }
245
gufe44b0ab8c22020-07-30 09:02:27 +0200246 path_stream = fopen( path, "w" );
247 if( path_stream == NULL )
Janos Follath8ca53b52016-10-05 10:57:49 +0100248 {
gufe44b0ab8c22020-07-30 09:02:27 +0200249 close( dup_fd );
250 return( -1 );
Janos Follath8ca53b52016-10-05 10:57:49 +0100251 }
252
gufe44b0ab8c22020-07-30 09:02:27 +0200253 fflush( out_stream );
254 if( dup2( fileno( path_stream ), out_fd ) == -1 )
255 {
256 close( dup_fd );
257 fclose( path_stream );
258 return( -1 );
259 }
260
261 fclose( path_stream );
262 return( dup_fd );
Janos Follath8ca53b52016-10-05 10:57:49 +0100263}
264
gufe44b0ab8c22020-07-30 09:02:27 +0200265static int restore_output( FILE* out_stream, int dup_fd )
Janos Follath8ca53b52016-10-05 10:57:49 +0100266{
gufe44b0ab8c22020-07-30 09:02:27 +0200267 int out_fd = fileno( out_stream );
Janos Follath8ca53b52016-10-05 10:57:49 +0100268
gufe44b0ab8c22020-07-30 09:02:27 +0200269 fflush( out_stream );
270 if( dup2( dup_fd, out_fd ) == -1 )
Janos Follath8ca53b52016-10-05 10:57:49 +0100271 {
gufe44b0ab8c22020-07-30 09:02:27 +0200272 close( out_fd );
273 close( dup_fd );
274 return( -1 );
Janos Follath8ca53b52016-10-05 10:57:49 +0100275 }
276
gufe44b0ab8c22020-07-30 09:02:27 +0200277 close( dup_fd );
278 return( 0 );
Simon Butchere0192962016-10-12 23:07:30 +0100279}
Janos Follath8ca53b52016-10-05 10:57:49 +0100280#endif /* __unix__ || __APPLE__ __MACH__ */
281
Simon Butcher638dceb2018-10-03 16:17:41 +0100282int unhexify( unsigned char *obuf, const char *ibuf )
Paul Bakker367dae42009-06-28 21:50:27 +0000283{
284 unsigned char c, c2;
Rich Evans4c091142015-02-02 12:04:10 +0000285 int len = strlen( ibuf ) / 2;
SimonB0269dad2016-02-17 23:34:30 +0000286 assert( strlen( ibuf ) % 2 == 0 ); /* must be even number of bytes */
Paul Bakker367dae42009-06-28 21:50:27 +0000287
Rich Evans4c091142015-02-02 12:04:10 +0000288 while( *ibuf != 0 )
Paul Bakker367dae42009-06-28 21:50:27 +0000289 {
290 c = *ibuf++;
291 if( c >= '0' && c <= '9' )
292 c -= '0';
293 else if( c >= 'a' && c <= 'f' )
294 c -= 'a' - 10;
295 else if( c >= 'A' && c <= 'F' )
296 c -= 'A' - 10;
297 else
298 assert( 0 );
299
300 c2 = *ibuf++;
301 if( c2 >= '0' && c2 <= '9' )
302 c2 -= '0';
303 else if( c2 >= 'a' && c2 <= 'f' )
304 c2 -= 'a' - 10;
305 else if( c2 >= 'A' && c2 <= 'F' )
306 c2 -= 'A' - 10;
307 else
308 assert( 0 );
309
310 *obuf++ = ( c << 4 ) | c2;
311 }
312
313 return len;
314}
315
Simon Butcher638dceb2018-10-03 16:17:41 +0100316void hexify( unsigned char *obuf, const unsigned char *ibuf, int len )
Paul Bakker367dae42009-06-28 21:50:27 +0000317{
318 unsigned char l, h;
319
Rich Evans42914452015-02-02 12:09:25 +0000320 while( len != 0 )
Paul Bakker367dae42009-06-28 21:50:27 +0000321 {
Rich Evans42914452015-02-02 12:09:25 +0000322 h = *ibuf / 16;
323 l = *ibuf % 16;
Paul Bakker367dae42009-06-28 21:50:27 +0000324
325 if( h < 10 )
326 *obuf++ = '0' + h;
327 else
328 *obuf++ = 'a' + h - 10;
329
330 if( l < 10 )
331 *obuf++ = '0' + l;
332 else
333 *obuf++ = 'a' + l - 10;
334
335 ++ibuf;
336 len--;
337 }
338}
Paul Bakker9dcc3222011-03-08 14:16:06 +0000339
340/**
Manuel Pégourié-Gonnard0dc5e0d2014-06-13 21:09:26 +0200341 * Allocate and zeroize a buffer.
342 *
343 * If the size if zero, a pointer to a zeroized 1-byte buffer is returned.
344 *
345 * For convenience, dies if allocation fails.
346 */
347static unsigned char *zero_alloc( size_t len )
348{
349 void *p;
Rich Evans42914452015-02-02 12:09:25 +0000350 size_t actual_len = ( len != 0 ) ? len : 1;
Manuel Pégourié-Gonnard0dc5e0d2014-06-13 21:09:26 +0200351
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200352 p = mbedtls_calloc( 1, actual_len );
Paul Bakker4d0cfe82014-07-10 14:37:36 +0200353 assert( p != NULL );
Manuel Pégourié-Gonnard0dc5e0d2014-06-13 21:09:26 +0200354
355 memset( p, 0x00, actual_len );
356
357 return( p );
358}
359
360/**
Manuel Pégourié-Gonnard3d49b9d2014-06-06 14:48:09 +0200361 * Allocate and fill a buffer from hex data.
362 *
363 * The buffer is sized exactly as needed. This allows to detect buffer
364 * overruns (including overreads) when running the test suite under valgrind.
365 *
Manuel Pégourié-Gonnard0dc5e0d2014-06-13 21:09:26 +0200366 * If the size if zero, a pointer to a zeroized 1-byte buffer is returned.
367 *
Manuel Pégourié-Gonnard3d49b9d2014-06-06 14:48:09 +0200368 * For convenience, dies if allocation fails.
369 */
Simon Butcher638dceb2018-10-03 16:17:41 +0100370unsigned char *unhexify_alloc( const char *ibuf, size_t *olen )
Manuel Pégourié-Gonnard3d49b9d2014-06-06 14:48:09 +0200371{
372 unsigned char *obuf;
373
Rich Evans42914452015-02-02 12:09:25 +0000374 *olen = strlen( ibuf ) / 2;
Manuel Pégourié-Gonnard3d49b9d2014-06-06 14:48:09 +0200375
Manuel Pégourié-Gonnard0dc5e0d2014-06-13 21:09:26 +0200376 if( *olen == 0 )
377 return( zero_alloc( *olen ) );
378
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200379 obuf = mbedtls_calloc( 1, *olen );
Paul Bakker4d0cfe82014-07-10 14:37:36 +0200380 assert( obuf != NULL );
Manuel Pégourié-Gonnard3d49b9d2014-06-06 14:48:09 +0200381
382 (void) unhexify( obuf, ibuf );
383
384 return( obuf );
385}
386
387/**
Paul Bakker9dcc3222011-03-08 14:16:06 +0000388 * This function just returns data from rand().
Paul Bakker997bbd12011-03-13 15:45:42 +0000389 * Although predictable and often similar on multiple
390 * runs, this does not result in identical random on
391 * each run. So do not use this if the results of a
392 * test depend on the random data that is generated.
Paul Bakker9dcc3222011-03-08 14:16:06 +0000393 *
394 * rng_state shall be NULL.
395 */
Paul Bakkera3d195c2011-11-27 21:07:34 +0000396static int rnd_std_rand( void *rng_state, unsigned char *output, size_t len )
Paul Bakker9dcc3222011-03-08 14:16:06 +0000397{
gufe44206cb392020-08-03 17:56:50 +0200398#if !defined(__OpenBSD__) && !defined(__NetBSD__)
Paul Bakkera3d195c2011-11-27 21:07:34 +0000399 size_t i;
400
Paul Bakker9dcc3222011-03-08 14:16:06 +0000401 if( rng_state != NULL )
402 rng_state = NULL;
403
Paul Bakkera3d195c2011-11-27 21:07:34 +0000404 for( i = 0; i < len; ++i )
405 output[i] = rand();
Paul Bakkerf96f7b62014-04-30 16:02:38 +0200406#else
407 if( rng_state != NULL )
408 rng_state = NULL;
409
410 arc4random_buf( output, len );
gufe44206cb392020-08-03 17:56:50 +0200411#endif /* !OpenBSD && !NetBSD */
Paul Bakkera3d195c2011-11-27 21:07:34 +0000412
413 return( 0 );
Paul Bakker9dcc3222011-03-08 14:16:06 +0000414}
415
416/**
417 * This function only returns zeros
418 *
419 * rng_state shall be NULL.
420 */
Simon Butcher638dceb2018-10-03 16:17:41 +0100421int rnd_zero_rand( void *rng_state, unsigned char *output, size_t len )
Paul Bakker9dcc3222011-03-08 14:16:06 +0000422{
423 if( rng_state != NULL )
424 rng_state = NULL;
425
Paul Bakkera3d195c2011-11-27 21:07:34 +0000426 memset( output, 0, len );
427
Paul Bakker9dcc3222011-03-08 14:16:06 +0000428 return( 0 );
429}
430
431typedef struct
432{
433 unsigned char *buf;
Paul Bakkera3d195c2011-11-27 21:07:34 +0000434 size_t length;
Paul Bakker997bbd12011-03-13 15:45:42 +0000435} rnd_buf_info;
Paul Bakker9dcc3222011-03-08 14:16:06 +0000436
437/**
438 * This function returns random based on a buffer it receives.
439 *
Paul Bakker997bbd12011-03-13 15:45:42 +0000440 * rng_state shall be a pointer to a rnd_buf_info structure.
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100441 *
Paul Bakker997bbd12011-03-13 15:45:42 +0000442 * The number of bytes released from the buffer on each call to
443 * the random function is specified by per_call. (Can be between
444 * 1 and 4)
Paul Bakker9dcc3222011-03-08 14:16:06 +0000445 *
446 * After the buffer is empty it will return rand();
447 */
Simon Butcher638dceb2018-10-03 16:17:41 +0100448int rnd_buffer_rand( void *rng_state, unsigned char *output, size_t len )
Paul Bakker9dcc3222011-03-08 14:16:06 +0000449{
Paul Bakker997bbd12011-03-13 15:45:42 +0000450 rnd_buf_info *info = (rnd_buf_info *) rng_state;
Paul Bakkera3d195c2011-11-27 21:07:34 +0000451 size_t use_len;
Paul Bakker9dcc3222011-03-08 14:16:06 +0000452
453 if( rng_state == NULL )
Paul Bakkera3d195c2011-11-27 21:07:34 +0000454 return( rnd_std_rand( NULL, output, len ) );
Paul Bakker9dcc3222011-03-08 14:16:06 +0000455
Paul Bakkera3d195c2011-11-27 21:07:34 +0000456 use_len = len;
457 if( len > info->length )
458 use_len = info->length;
Paul Bakker997bbd12011-03-13 15:45:42 +0000459
Paul Bakkera3d195c2011-11-27 21:07:34 +0000460 if( use_len )
Paul Bakker9dcc3222011-03-08 14:16:06 +0000461 {
Paul Bakkera3d195c2011-11-27 21:07:34 +0000462 memcpy( output, info->buf, use_len );
463 info->buf += use_len;
464 info->length -= use_len;
Paul Bakker9dcc3222011-03-08 14:16:06 +0000465 }
466
Paul Bakkera3d195c2011-11-27 21:07:34 +0000467 if( len - use_len > 0 )
468 return( rnd_std_rand( NULL, output + use_len, len - use_len ) );
469
470 return( 0 );
Paul Bakker9dcc3222011-03-08 14:16:06 +0000471}
Paul Bakker997bbd12011-03-13 15:45:42 +0000472
473/**
474 * Info structure for the pseudo random function
475 *
476 * Key should be set at the start to a test-unique value.
Paul Bakkerb3dcbc12011-03-13 16:57:25 +0000477 * Do not forget endianness!
Paul Bakker997bbd12011-03-13 15:45:42 +0000478 * State( v0, v1 ) should be set to zero.
479 */
480typedef struct
481{
Paul Bakkerb3dcbc12011-03-13 16:57:25 +0000482 uint32_t key[16];
Paul Bakker997bbd12011-03-13 15:45:42 +0000483 uint32_t v0, v1;
484} rnd_pseudo_info;
485
486/**
487 * This function returns random based on a pseudo random function.
488 * This means the results should be identical on all systems.
489 * Pseudo random is based on the XTEA encryption algorithm to
490 * generate pseudorandom.
491 *
492 * rng_state shall be a pointer to a rnd_pseudo_info structure.
493 */
Simon Butcher638dceb2018-10-03 16:17:41 +0100494int rnd_pseudo_rand( void *rng_state, unsigned char *output, size_t len )
Paul Bakker997bbd12011-03-13 15:45:42 +0000495{
496 rnd_pseudo_info *info = (rnd_pseudo_info *) rng_state;
Paul Bakkera3d195c2011-11-27 21:07:34 +0000497 uint32_t i, *k, sum, delta=0x9E3779B9;
Manuel Pégourié-Gonnard217a29c2014-01-03 11:59:09 +0100498 unsigned char result[4], *out = output;
Paul Bakker997bbd12011-03-13 15:45:42 +0000499
500 if( rng_state == NULL )
Paul Bakkera3d195c2011-11-27 21:07:34 +0000501 return( rnd_std_rand( NULL, output, len ) );
Paul Bakker997bbd12011-03-13 15:45:42 +0000502
Paul Bakkerb3dcbc12011-03-13 16:57:25 +0000503 k = info->key;
Paul Bakkera3d195c2011-11-27 21:07:34 +0000504
505 while( len > 0 )
Paul Bakker997bbd12011-03-13 15:45:42 +0000506 {
Paul Bakker40dd5302012-05-15 15:02:38 +0000507 size_t use_len = ( len > 4 ) ? 4 : len;
Paul Bakkera3d195c2011-11-27 21:07:34 +0000508 sum = 0;
509
Paul Bakkera3d195c2011-11-27 21:07:34 +0000510 for( i = 0; i < 32; i++ )
511 {
Rich Evans42914452015-02-02 12:09:25 +0000512 info->v0 += ( ( ( info->v1 << 4 ) ^ ( info->v1 >> 5 ) )
513 + info->v1 ) ^ ( sum + k[sum & 3] );
Paul Bakkera3d195c2011-11-27 21:07:34 +0000514 sum += delta;
Rich Evans42914452015-02-02 12:09:25 +0000515 info->v1 += ( ( ( info->v0 << 4 ) ^ ( info->v0 >> 5 ) )
516 + info->v0 ) ^ ( sum + k[( sum>>11 ) & 3] );
Paul Bakkera3d195c2011-11-27 21:07:34 +0000517 }
518
Paul Bakker5c2364c2012-10-01 14:41:15 +0000519 PUT_UINT32_BE( info->v0, result, 0 );
Manuel Pégourié-Gonnard217a29c2014-01-03 11:59:09 +0100520 memcpy( out, result, use_len );
Paul Bakkera3d195c2011-11-27 21:07:34 +0000521 len -= use_len;
Manuel Pégourié-Gonnard217a29c2014-01-03 11:59:09 +0100522 out += 4;
Paul Bakker997bbd12011-03-13 15:45:42 +0000523 }
524
Paul Bakkera3d195c2011-11-27 21:07:34 +0000525 return( 0 );
Paul Bakker997bbd12011-03-13 15:45:42 +0000526}
SimonB0269dad2016-02-17 23:34:30 +0000527
Gilles Peskine44498ff2021-01-29 21:17:11 +0100528/** Mutex usage verification framework.
529 *
530 */
531
532#if defined(MBEDTLS_TEST_MUTEX_USAGE)
533typedef struct
534{
535 void (*init)( mbedtls_threading_mutex_t * );
536 void (*free)( mbedtls_threading_mutex_t * );
537 int (*lock)( mbedtls_threading_mutex_t * );
538 int (*unlock)( mbedtls_threading_mutex_t * );
539} mutex_functions_t;
540static mutex_functions_t mutex_functions;
541
542static void mbedtls_test_wrap_mutex_init( mbedtls_threading_mutex_t *mutex )
543{
544 mutex_functions.init( mutex );
545}
546
547static void mbedtls_test_wrap_mutex_free( mbedtls_threading_mutex_t *mutex )
548{
549 mutex_functions.free( mutex );
550}
551
552static int mbedtls_test_wrap_mutex_lock( mbedtls_threading_mutex_t *mutex )
553{
554 int ret = mutex_functions.lock( mutex );
555 return( ret );
556}
557
558static int mbedtls_test_wrap_mutex_unlock( mbedtls_threading_mutex_t *mutex )
559{
560 return( mutex_functions.unlock( mutex ) );
561}
562
563static void mbedtls_test_mutex_usage_init( void )
564{
565 mutex_functions.init = mbedtls_mutex_init;
566 mutex_functions.free = mbedtls_mutex_free;
567 mutex_functions.lock = mbedtls_mutex_lock;
568 mutex_functions.unlock = mbedtls_mutex_unlock;
569 mbedtls_mutex_init = &mbedtls_test_wrap_mutex_init;
570 mbedtls_mutex_free = &mbedtls_test_wrap_mutex_free;
571 mbedtls_mutex_lock = &mbedtls_test_wrap_mutex_lock;
572 mbedtls_mutex_unlock = &mbedtls_test_wrap_mutex_unlock;
573}
574
575#endif /* MBEDTLS_TEST_MUTEX_USAGE */