1 /*
2  *  Common code library for SSL test programs.
3  *
4  *  In addition to the functions in this file, there is shared source code
5  *  that cannot be compiled separately in "ssl_test_common_source.c".
6  *
7  *  Copyright The Mbed TLS Contributors
8  *  SPDX-License-Identifier: Apache-2.0
9  *
10  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
11  *  not use this file except in compliance with the License.
12  *  You may obtain a copy of the License at
13  *
14  *  http://www.apache.org/licenses/LICENSE-2.0
15  *
16  *  Unless required by applicable law or agreed to in writing, software
17  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  *  See the License for the specific language governing permissions and
20  *  limitations under the License.
21  */
22 
23 #define MBEDTLS_ALLOW_PRIVATE_ACCESS
24 
25 #include "ssl_test_lib.h"
26 
27 #if defined(MBEDTLS_TEST_HOOKS)
28 #include "test/helpers.h"
29 #endif
30 
31 #if !defined(MBEDTLS_SSL_TEST_IMPOSSIBLE)
32 
my_debug(void * ctx,int level,const char * file,int line,const char * str)33 void my_debug( void *ctx, int level,
34                const char *file, int line,
35                const char *str )
36 {
37     const char *p, *basename;
38 
39     /* Extract basename from file */
40     for( p = basename = file; *p != '\0'; p++ )
41         if( *p == '/' || *p == '\\' )
42             basename = p + 1;
43 
44     mbedtls_fprintf( (FILE *) ctx, "%s:%04d: |%d| %s",
45                      basename, line, level, str );
46     fflush( (FILE *) ctx  );
47 }
48 
dummy_constant_time(mbedtls_time_t * time)49 mbedtls_time_t dummy_constant_time( mbedtls_time_t* time )
50 {
51     (void) time;
52     return 0x5af2a056;
53 }
54 
55 #if !defined(MBEDTLS_TEST_USE_PSA_CRYPTO_RNG)
dummy_entropy(void * data,unsigned char * output,size_t len)56 static int dummy_entropy( void *data, unsigned char *output, size_t len )
57 {
58     size_t i;
59     int ret;
60     (void) data;
61 
62     ret = mbedtls_entropy_func( data, output, len );
63     for( i = 0; i < len; i++ )
64     {
65         //replace result with pseudo random
66         output[i] = (unsigned char) rand();
67     }
68     return( ret );
69 }
70 #endif
71 
rng_init(rng_context_t * rng)72 void rng_init( rng_context_t *rng )
73 {
74 #if defined(MBEDTLS_TEST_USE_PSA_CRYPTO_RNG)
75     (void) rng;
76     psa_crypto_init( );
77 #else /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
78 
79 #if defined(MBEDTLS_CTR_DRBG_C)
80     mbedtls_ctr_drbg_init( &rng->drbg );
81 #elif defined(MBEDTLS_HMAC_DRBG_C)
82     mbedtls_hmac_drbg_init( &rng->drbg );
83 #else
84 #error "No DRBG available"
85 #endif
86 
87     mbedtls_entropy_init( &rng->entropy );
88 #endif /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
89 }
90 
rng_seed(rng_context_t * rng,int reproducible,const char * pers)91 int rng_seed( rng_context_t *rng, int reproducible, const char *pers )
92 {
93 #if defined(MBEDTLS_USE_PSA_CRYPTO)
94     if( reproducible )
95     {
96         mbedtls_fprintf( stderr,
97                          "MBEDTLS_USE_PSA_CRYPTO does not support reproducible mode.\n" );
98         return( -1 );
99     }
100 #endif
101 #if defined(MBEDTLS_TEST_USE_PSA_CRYPTO_RNG)
102     /* The PSA crypto RNG does its own seeding. */
103     (void) rng;
104     (void) pers;
105     if( reproducible )
106     {
107         mbedtls_fprintf( stderr,
108                          "The PSA RNG does not support reproducible mode.\n" );
109         return( -1 );
110     }
111     return( 0 );
112 #else /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
113     int ( *f_entropy )( void *, unsigned char *, size_t ) =
114         ( reproducible ? dummy_entropy : mbedtls_entropy_func );
115 
116     if ( reproducible )
117         srand( 1 );
118 
119 #if defined(MBEDTLS_CTR_DRBG_C)
120     int ret = mbedtls_ctr_drbg_seed( &rng->drbg,
121                                      f_entropy, &rng->entropy,
122                                      (const unsigned char *) pers,
123                                      strlen( pers ) );
124 #elif defined(MBEDTLS_HMAC_DRBG_C)
125 #if defined(MBEDTLS_SHA256_C)
126     const mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256;
127 #elif defined(MBEDTLS_SHA512_C)
128     const mbedtls_md_type_t md_type = MBEDTLS_MD_SHA512;
129 #else
130 #error "No message digest available for HMAC_DRBG"
131 #endif
132     int ret = mbedtls_hmac_drbg_seed( &rng->drbg,
133                                       mbedtls_md_info_from_type( md_type ),
134                                       f_entropy, &rng->entropy,
135                                       (const unsigned char *) pers,
136                                       strlen( pers ) );
137 #else /* !defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_HMAC_DRBG_C) */
138 #error "No DRBG available"
139 #endif /* !defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_HMAC_DRBG_C) */
140 
141     if( ret != 0 )
142     {
143         mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned -0x%x\n",
144                         (unsigned int) -ret );
145         return( ret );
146     }
147 #endif /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
148 
149     return( 0 );
150 }
151 
rng_free(rng_context_t * rng)152 void rng_free( rng_context_t *rng )
153 {
154 #if defined(MBEDTLS_TEST_USE_PSA_CRYPTO_RNG)
155     (void) rng;
156     /* Deinitialize the PSA crypto subsystem. This deactivates all PSA APIs.
157      * This is ok because none of our applications try to do any crypto after
158      * deinitializing the RNG. */
159     mbedtls_psa_crypto_free( );
160 #else /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
161 
162 #if defined(MBEDTLS_CTR_DRBG_C)
163     mbedtls_ctr_drbg_free( &rng->drbg );
164 #elif defined(MBEDTLS_HMAC_DRBG_C)
165     mbedtls_hmac_drbg_free( &rng->drbg );
166 #else
167 #error "No DRBG available"
168 #endif
169 
170     mbedtls_entropy_free( &rng->entropy );
171 #endif /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
172 }
173 
rng_get(void * p_rng,unsigned char * output,size_t output_len)174 int rng_get( void *p_rng, unsigned char *output, size_t output_len )
175 {
176 #if defined(MBEDTLS_TEST_USE_PSA_CRYPTO_RNG)
177     (void) p_rng;
178     return( mbedtls_psa_get_random( MBEDTLS_PSA_RANDOM_STATE,
179                                     output, output_len ) );
180 #else /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
181     rng_context_t *rng = p_rng;
182 
183 #if defined(MBEDTLS_CTR_DRBG_C)
184     return( mbedtls_ctr_drbg_random( &rng->drbg, output, output_len ) );
185 #elif defined(MBEDTLS_HMAC_DRBG_C)
186     return( mbedtls_hmac_drbg_random( &rng->drbg, output, output_len ) );
187 #else
188 #error "No DRBG available"
189 #endif
190 
191 #endif /* !MBEDTLS_TEST_USE_PSA_CRYPTO_RNG */
192 }
193 
194 #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
ca_callback(void * data,mbedtls_x509_crt const * child,mbedtls_x509_crt ** candidates)195 int ca_callback( void *data, mbedtls_x509_crt const *child,
196                  mbedtls_x509_crt **candidates )
197 {
198     int ret = 0;
199     mbedtls_x509_crt *ca = (mbedtls_x509_crt *) data;
200     mbedtls_x509_crt *first;
201 
202     /* This is a test-only implementation of the CA callback
203      * which always returns the entire list of trusted certificates.
204      * Production implementations managing a large number of CAs
205      * should use an efficient presentation and lookup for the
206      * set of trusted certificates (such as a hashtable) and only
207      * return those trusted certificates which satisfy basic
208      * parental checks, such as the matching of child `Issuer`
209      * and parent `Subject` field or matching key identifiers. */
210     ((void) child);
211 
212     first = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
213     if( first == NULL )
214     {
215         ret = -1;
216         goto exit;
217     }
218     mbedtls_x509_crt_init( first );
219 
220     if( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) != 0 )
221     {
222         ret = -1;
223         goto exit;
224     }
225 
226     while( ca->next != NULL )
227     {
228         ca = ca->next;
229         if( mbedtls_x509_crt_parse_der( first, ca->raw.p, ca->raw.len ) != 0 )
230         {
231             ret = -1;
232             goto exit;
233         }
234     }
235 
236 exit:
237 
238     if( ret != 0 )
239     {
240         mbedtls_x509_crt_free( first );
241         mbedtls_free( first );
242         first = NULL;
243     }
244 
245     *candidates = first;
246     return( ret );
247 }
248 #endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
249 
delayed_recv(void * ctx,unsigned char * buf,size_t len)250 int delayed_recv( void *ctx, unsigned char *buf, size_t len )
251 {
252     static int first_try = 1;
253     int ret;
254 
255     if( first_try )
256     {
257         first_try = 0;
258         return( MBEDTLS_ERR_SSL_WANT_READ );
259     }
260 
261     ret = mbedtls_net_recv( ctx, buf, len );
262     if( ret != MBEDTLS_ERR_SSL_WANT_READ )
263         first_try = 1; /* Next call will be a new operation */
264     return( ret );
265 }
266 
delayed_send(void * ctx,const unsigned char * buf,size_t len)267 int delayed_send( void *ctx, const unsigned char *buf, size_t len )
268 {
269     static int first_try = 1;
270     int ret;
271 
272     if( first_try )
273     {
274         first_try = 0;
275         return( MBEDTLS_ERR_SSL_WANT_WRITE );
276     }
277 
278     ret = mbedtls_net_send( ctx, buf, len );
279     if( ret != MBEDTLS_ERR_SSL_WANT_WRITE )
280         first_try = 1; /* Next call will be a new operation */
281     return( ret );
282 }
283 
284 #if !defined(MBEDTLS_TIMING_C)
idle(mbedtls_net_context * fd,int idle_reason)285 int idle( mbedtls_net_context *fd,
286           int idle_reason )
287 #else
288 int idle( mbedtls_net_context *fd,
289           mbedtls_timing_delay_context *timer,
290           int idle_reason )
291 #endif
292 {
293     int ret;
294     int poll_type = 0;
295 
296     if( idle_reason == MBEDTLS_ERR_SSL_WANT_WRITE )
297         poll_type = MBEDTLS_NET_POLL_WRITE;
298     else if( idle_reason == MBEDTLS_ERR_SSL_WANT_READ )
299         poll_type = MBEDTLS_NET_POLL_READ;
300 #if !defined(MBEDTLS_TIMING_C)
301     else
302         return( 0 );
303 #endif
304 
305     while( 1 )
306     {
307         /* Check if timer has expired */
308 #if defined(MBEDTLS_TIMING_C)
309         if( timer != NULL &&
310             mbedtls_timing_get_delay( timer ) == 2 )
311         {
312             break;
313         }
314 #endif /* MBEDTLS_TIMING_C */
315 
316         /* Check if underlying transport became available */
317         if( poll_type != 0 )
318         {
319             ret = mbedtls_net_poll( fd, poll_type, 0 );
320             if( ret < 0 )
321                 return( ret );
322             if( ret == poll_type )
323                 break;
324         }
325     }
326 
327     return( 0 );
328 }
329 
330 #if defined(MBEDTLS_TEST_HOOKS)
331 
test_hooks_init(void)332 void test_hooks_init( void )
333 {
334     mbedtls_test_info_reset( );
335 
336 #if defined(MBEDTLS_TEST_MUTEX_USAGE)
337     mbedtls_test_mutex_usage_init( );
338 #endif
339 }
340 
test_hooks_failure_detected(void)341 int test_hooks_failure_detected( void )
342 {
343 #if defined(MBEDTLS_TEST_MUTEX_USAGE)
344     /* Errors are reported via mbedtls_test_info. */
345     mbedtls_test_mutex_usage_check( );
346 #endif
347 
348     if( mbedtls_test_info.result != MBEDTLS_TEST_RESULT_SUCCESS )
349         return( 1 );
350     return( 0 );
351 }
352 
test_hooks_free(void)353 void test_hooks_free( void )
354 {
355 }
356 
357 #endif /* MBEDTLS_TEST_HOOKS */
358 
359 #endif /* !defined(MBEDTLS_SSL_TEST_IMPOSSIBLE) */
360