blob: 67ddd063ed6a78b9d296b98c6f85038017d21d68 [file] [log] [blame]
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include <mbedtls/ssl.h>
Manuel Pégourié-Gonnard5e94dde2015-05-26 11:57:05 +02003#include <mbedtls/ssl_internal.h>
Hanno Beckera18d1322018-01-03 14:27:32 +00004
Janos Follath6264e662019-11-26 11:11:15 +00005
6/*
7 * Buffer structure for custom I/O callbacks.
8 */
9
10typedef struct mbedtls_test_buffer
11{
12 size_t start;
13 size_t content_length;
14 size_t capacity;
15 unsigned char *buffer;
16} mbedtls_test_buffer;
17
18/*
19 * Initialises \p buf. After calling this function it is safe to call
20 * `mbedtls_test_buffer_free()` on \p buf.
21 */
22void mbedtls_test_buffer_init( mbedtls_test_buffer *buf )
23{
24 memset( buf, 0, sizeof( *buf ) );
25}
26
27/*
28 * Sets up \p buf. After calling this function it is safe to call
29 * `mbedtls_test_buffer_put()` and `mbedtls_test_buffer_get()` on \p buf.
30 */
31int mbedtls_test_buffer_setup( mbedtls_test_buffer *buf, size_t capacity )
32{
33 buf->buffer = (unsigned char*) mbedtls_calloc( capacity,
34 sizeof(unsigned char) );
35 if( NULL == buf->buffer )
36 return MBEDTLS_ERR_SSL_ALLOC_FAILED;
37 buf->capacity = capacity;
38
39 return 0;
40}
41
42void mbedtls_test_buffer_free( mbedtls_test_buffer *buf )
43{
44 if( buf->buffer != NULL )
45 mbedtls_free( buf->buffer );
46
47 memset( buf, 0, sizeof( *buf ) );
48}
49
50/*
51 * Puts \p input_len bytes from the \p input buffer into the ring buffer \p buf.
52 *
53 * \p buf must have been initialized and set up by calling
54 * `mbedtls_test_buffer_init()` and `mbedtls_test_buffer_setup()`.
55 *
56 * \retval \p input_len, if the data fits.
57 * \retval 0 <= value < \p input_len, if the data does not fit.
58 * \retval -1, if \p buf is NULL, it hasn't been set up or \p input_len is not
59 * zero and \p input is NULL.
60 */
61int mbedtls_test_buffer_put( mbedtls_test_buffer *buf,
62 const unsigned char* input, size_t input_len )
63{
64 size_t overflow = 0;
65
66 if( ( buf == NULL ) || ( buf->buffer == NULL ) )
67 return -1;
68
69 /* Reduce input_len to a number that fits in the buffer. */
70 if ( ( buf->content_length + input_len ) > buf->capacity )
71 {
72 input_len = buf->capacity - buf->content_length;
73 }
74
75 if( input == NULL )
76 {
77 return ( input_len == 0 ) ? 0 : -1;
78 }
79
80 /* Calculate the number of bytes that need to be placed at lower memory
81 * address */
82 if( buf->start + buf->content_length + input_len
83 > buf->capacity )
84 {
85 overflow = ( buf->start + buf->content_length + input_len )
86 % buf->capacity;
87 }
88
89 memcpy( buf->buffer + buf->start + buf->content_length, input,
90 input_len - overflow );
91 memcpy( buf->buffer, input + input_len - overflow, overflow );
92 buf->content_length += input_len;
93
94 return input_len;
95}
96
97/*
98 * Gets \p output_len bytes from the \p output buffer into the ring buffer
99 * \p buf.
100 *
101 * \p buf must have been initialized and set up by calling
102 * `mbedtls_test_buffer_init()` and `mbedtls_test_buffer_setup()`.
103 *
104 * \retval \p output_len, if the data is available.
105 * \retval 0 <= value < \p output_len, if the data is not available.
106 * \retval -1, if \buf is NULL, it hasn't been set up or \p output_len is not
107 * zero and \p output is NULL
108 */
109int mbedtls_test_buffer_get( mbedtls_test_buffer *buf,
110 unsigned char* output, size_t output_len )
111{
112 size_t overflow = 0;
113
114 if( ( buf == NULL ) || ( buf->buffer == NULL ) )
115 return -1;
116
117 if( output == NULL )
118 {
119 return ( output_len == 0 ) ? 0 : -1;
120 }
121
122 if( buf->content_length < output_len )
123 output_len = buf->content_length;
124
125 /* Calculate the number of bytes that need to be drawn from lower memory
126 * address */
127 if( buf->start + output_len > buf->capacity )
128 {
129 overflow = ( buf->start + output_len ) % buf->capacity;
130 }
131
132 memcpy( output, buf->buffer + buf->start, output_len - overflow );
133 memcpy( output + output_len - overflow, buf->buffer, overflow );
134 buf->content_length -= output_len;
135 buf->start = ( buf->start + output_len ) % buf->capacity;
136
137 return output_len;
138}
139
Hanno Beckera18d1322018-01-03 14:27:32 +0000140/*
Janos Follath031827f2019-11-27 11:12:14 +0000141 * Context for the I/O callbacks simulating network connection.
142 */
143
144#define MBEDTLS_MOCK_SOCKET_CONNECTED 1
145
146typedef struct mbedtls_mock_socket
147{
148 int status;
149 mbedtls_test_buffer *input;
150 mbedtls_test_buffer *output;
151 struct mbedtls_mock_socket *peer;
152} mbedtls_mock_socket;
153
154/*
155 * Setup and teardown functions for mock sockets.
156 */
157void mbedtls_mock_socket_init( mbedtls_mock_socket *socket )
158{
159 memset( socket, 0, sizeof( *socket ) );
160}
161
162/*
163 * Closes the socket \p socket.
164 *
165 * \p socket must have been previously initialized by calling
166 * mbedtls_mock_socket_init().
167 *
168 * This function frees all allocated resources and both sockets are aware of the
169 * new connection state.
170 *
171 * That is, this function does not simulate half-open TCP connections and the
172 * phenomenon that when closing a UDP connection the peer is not aware of the
173 * connection having been closed.
174 */
175void mbedtls_mock_socket_close( mbedtls_mock_socket* socket )
176{
177 if( socket == NULL )
178 return;
179
180 if( socket->input != NULL )
181 {
182 mbedtls_test_buffer_free( socket->input );
183 mbedtls_free( socket->input );
184 }
185
186 if( socket->output != NULL )
187 {
188 mbedtls_test_buffer_free( socket->output );
189 mbedtls_free( socket->output );
190 }
191
192 if( socket->peer != NULL )
193 memset( socket->peer, 0, sizeof( *socket->peer ) );
194
195 memset( socket, 0, sizeof( *socket ) );
196}
197
198/*
199 * Establishes a connection between \p peer1 and \p peer2.
200 *
201 * \p peer1 and \p peer2 must have been previously initialized by calling
202 * mbedtls_mock_socket_init().
203 *
204 * The capacites of the internal buffers are set to \p bufsize. Setting this to
205 * the correct value allows for simulation of MTU, sanity testing the mock
206 * implementation and mocking TCP connections with lower memory cost.
207 */
208int mbedtls_mock_socket_connect( mbedtls_mock_socket* peer1,
209 mbedtls_mock_socket* peer2,
210 size_t bufsize )
211{
212 int ret = -1;
213
214 peer1->input = peer2->output =
215 (mbedtls_test_buffer*) mbedtls_calloc( 1, sizeof(mbedtls_test_buffer) );
216 if( peer1->input == NULL )
217 {
218 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
219 goto exit;
220 }
221 mbedtls_test_buffer_init( peer1->input );
222 if( 0 != ( ret = mbedtls_test_buffer_setup( peer1->input, bufsize ) ) )
223 {
224 goto exit;
225 }
226
227 peer1->output = peer2->input =
228 (mbedtls_test_buffer*) mbedtls_calloc( 1, sizeof(mbedtls_test_buffer) );
229 if( peer1->output == NULL )
230 {
231 ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
232 goto exit;
233 }
234 mbedtls_test_buffer_init( peer1->output );
235 if( 0 != ( ret = mbedtls_test_buffer_setup( peer1->output, bufsize ) ) )
236 {
237 goto exit;
238 }
239
240 peer1->peer = peer2;
241 peer2->peer = peer1;
242
243 peer1->status = peer2->status = MBEDTLS_MOCK_SOCKET_CONNECTED;
244 ret = 0;
245
246exit:
247
248 if( ret != 0 )
249 {
250 mbedtls_mock_socket_close( peer1 );
251 mbedtls_mock_socket_close( peer2 );
252 }
253
254 return ret;
255}
256
257/*
258 * Callbacks for simulating blocking I/O over connection-oriented transport.
259 */
260
261int mbedtls_mock_tcp_send_b( void *ctx, const unsigned char *buf, size_t len )
262{
263 mbedtls_mock_socket *socket = (mbedtls_mock_socket*) ctx;
264
265 if( socket == NULL || socket->status != MBEDTLS_MOCK_SOCKET_CONNECTED )
266 return -1;
267
268 return mbedtls_test_buffer_put( socket->output, buf, len );
269}
270
271int mbedtls_mock_tcp_recv_b( void *ctx, unsigned char *buf, size_t len )
272{
273 mbedtls_mock_socket *socket = (mbedtls_mock_socket*) ctx;
274
275 if( socket == NULL || socket->status != MBEDTLS_MOCK_SOCKET_CONNECTED )
276 return -1;
277
278 return mbedtls_test_buffer_get( socket->input, buf, len );
279}
280
281/*
Hanno Beckera18d1322018-01-03 14:27:32 +0000282 * Helper function setting up inverse record transformations
283 * using given cipher, hash, EtM mode, authentication tag length,
284 * and version.
285 */
286
287#define CHK( x ) \
288 do \
289 { \
290 if( !( x ) ) \
Hanno Becker81e16a32019-03-01 11:21:44 +0000291 { \
Hanno Beckera5780f12019-04-05 09:55:37 +0100292 ret = -1; \
Hanno Becker81e16a32019-03-01 11:21:44 +0000293 goto cleanup; \
294 } \
Hanno Beckera18d1322018-01-03 14:27:32 +0000295 } while( 0 )
296
Hanno Beckerd856c822019-04-29 17:30:59 +0100297#if MBEDTLS_SSL_CID_OUT_LEN_MAX > MBEDTLS_SSL_CID_IN_LEN_MAX
298#define SSL_CID_LEN_MIN MBEDTLS_SSL_CID_IN_LEN_MAX
299#else
300#define SSL_CID_LEN_MIN MBEDTLS_SSL_CID_OUT_LEN_MAX
301#endif
Hanno Beckera18d1322018-01-03 14:27:32 +0000302
303static int build_transforms( mbedtls_ssl_transform *t_in,
304 mbedtls_ssl_transform *t_out,
305 int cipher_type, int hash_id,
Hanno Beckerd856c822019-04-29 17:30:59 +0100306 int etm, int tag_mode, int ver,
307 size_t cid0_len,
308 size_t cid1_len )
Hanno Beckera18d1322018-01-03 14:27:32 +0000309{
310 mbedtls_cipher_info_t const *cipher_info;
Hanno Beckera5780f12019-04-05 09:55:37 +0100311 int ret = 0;
Hanno Beckera18d1322018-01-03 14:27:32 +0000312
313 size_t keylen, maclen, ivlen;
Hanno Becker81e16a32019-03-01 11:21:44 +0000314 unsigned char *key0 = NULL, *key1 = NULL;
Hanno Beckera18d1322018-01-03 14:27:32 +0000315 unsigned char iv_enc[16], iv_dec[16];
316
Hanno Beckera0e20d02019-05-15 14:03:01 +0100317#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Beckerd856c822019-04-29 17:30:59 +0100318 unsigned char cid0[ SSL_CID_LEN_MIN ];
319 unsigned char cid1[ SSL_CID_LEN_MIN ];
320
321 rnd_std_rand( NULL, cid0, sizeof( cid0 ) );
322 rnd_std_rand( NULL, cid1, sizeof( cid1 ) );
Hanno Becker43c24b82019-05-01 09:45:57 +0100323#else
324 ((void) cid0_len);
325 ((void) cid1_len);
Hanno Beckera0e20d02019-05-15 14:03:01 +0100326#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Beckerd856c822019-04-29 17:30:59 +0100327
Hanno Beckera18d1322018-01-03 14:27:32 +0000328 maclen = 0;
329
330 /* Pick cipher */
331 cipher_info = mbedtls_cipher_info_from_type( cipher_type );
332 CHK( cipher_info != NULL );
333 CHK( cipher_info->iv_size <= 16 );
334 CHK( cipher_info->key_bitlen % 8 == 0 );
335
336 /* Pick keys */
337 keylen = cipher_info->key_bitlen / 8;
Hanno Becker78d1f702019-04-05 09:56:10 +0100338 /* Allocate `keylen + 1` bytes to ensure that we get
339 * a non-NULL pointers from `mbedtls_calloc` even if
340 * `keylen == 0` in the case of the NULL cipher. */
341 CHK( ( key0 = mbedtls_calloc( 1, keylen + 1 ) ) != NULL );
342 CHK( ( key1 = mbedtls_calloc( 1, keylen + 1 ) ) != NULL );
Hanno Beckera18d1322018-01-03 14:27:32 +0000343 memset( key0, 0x1, keylen );
344 memset( key1, 0x2, keylen );
345
346 /* Setup cipher contexts */
347 CHK( mbedtls_cipher_setup( &t_in->cipher_ctx_enc, cipher_info ) == 0 );
348 CHK( mbedtls_cipher_setup( &t_in->cipher_ctx_dec, cipher_info ) == 0 );
349 CHK( mbedtls_cipher_setup( &t_out->cipher_ctx_enc, cipher_info ) == 0 );
350 CHK( mbedtls_cipher_setup( &t_out->cipher_ctx_dec, cipher_info ) == 0 );
351
352#if defined(MBEDTLS_CIPHER_MODE_CBC)
353 if( cipher_info->mode == MBEDTLS_MODE_CBC )
354 {
355 CHK( mbedtls_cipher_set_padding_mode( &t_in->cipher_ctx_enc,
356 MBEDTLS_PADDING_NONE ) == 0 );
357 CHK( mbedtls_cipher_set_padding_mode( &t_in->cipher_ctx_dec,
358 MBEDTLS_PADDING_NONE ) == 0 );
359 CHK( mbedtls_cipher_set_padding_mode( &t_out->cipher_ctx_enc,
360 MBEDTLS_PADDING_NONE ) == 0 );
361 CHK( mbedtls_cipher_set_padding_mode( &t_out->cipher_ctx_dec,
362 MBEDTLS_PADDING_NONE ) == 0 );
363 }
364#endif /* MBEDTLS_CIPHER_MODE_CBC */
365
366 CHK( mbedtls_cipher_setkey( &t_in->cipher_ctx_enc, key0,
367 keylen << 3, MBEDTLS_ENCRYPT ) == 0 );
368 CHK( mbedtls_cipher_setkey( &t_in->cipher_ctx_dec, key1,
369 keylen << 3, MBEDTLS_DECRYPT ) == 0 );
370 CHK( mbedtls_cipher_setkey( &t_out->cipher_ctx_enc, key1,
371 keylen << 3, MBEDTLS_ENCRYPT ) == 0 );
372 CHK( mbedtls_cipher_setkey( &t_out->cipher_ctx_dec, key0,
373 keylen << 3, MBEDTLS_DECRYPT ) == 0 );
Hanno Beckera18d1322018-01-03 14:27:32 +0000374
375 /* Setup MAC contexts */
376#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
377 if( cipher_info->mode == MBEDTLS_MODE_CBC ||
378 cipher_info->mode == MBEDTLS_MODE_STREAM )
379 {
380 mbedtls_md_info_t const *md_info;
381 unsigned char *md0, *md1;
382
383 /* Pick hash */
384 md_info = mbedtls_md_info_from_type( hash_id );
385 CHK( md_info != NULL );
386
387 /* Pick hash keys */
388 maclen = mbedtls_md_get_size( md_info );
Hanno Becker3ee54212019-04-04 16:31:26 +0100389 CHK( ( md0 = mbedtls_calloc( 1, maclen ) ) != NULL );
390 CHK( ( md1 = mbedtls_calloc( 1, maclen ) ) != NULL );
Hanno Beckera18d1322018-01-03 14:27:32 +0000391 memset( md0, 0x5, maclen );
392 memset( md1, 0x6, maclen );
393
394 CHK( mbedtls_md_setup( &t_out->md_ctx_enc, md_info, 1 ) == 0 );
395 CHK( mbedtls_md_setup( &t_out->md_ctx_dec, md_info, 1 ) == 0 );
396 CHK( mbedtls_md_setup( &t_in->md_ctx_enc, md_info, 1 ) == 0 );
397 CHK( mbedtls_md_setup( &t_in->md_ctx_dec, md_info, 1 ) == 0 );
398
399 if( ver > MBEDTLS_SSL_MINOR_VERSION_0 )
400 {
401 CHK( mbedtls_md_hmac_starts( &t_in->md_ctx_enc,
402 md0, maclen ) == 0 );
403 CHK( mbedtls_md_hmac_starts( &t_in->md_ctx_dec,
404 md1, maclen ) == 0 );
405 CHK( mbedtls_md_hmac_starts( &t_out->md_ctx_enc,
406 md1, maclen ) == 0 );
407 CHK( mbedtls_md_hmac_starts( &t_out->md_ctx_dec,
408 md0, maclen ) == 0 );
409 }
410#if defined(MBEDTLS_SSL_PROTO_SSL3)
411 else
412 {
413 memcpy( &t_in->mac_enc, md0, maclen );
414 memcpy( &t_in->mac_dec, md1, maclen );
415 memcpy( &t_out->mac_enc, md1, maclen );
416 memcpy( &t_out->mac_dec, md0, maclen );
417 }
418#endif
419
Hanno Becker3ee54212019-04-04 16:31:26 +0100420 mbedtls_free( md0 );
421 mbedtls_free( md1 );
Hanno Beckera18d1322018-01-03 14:27:32 +0000422 }
423#else
424 ((void) hash_id);
425#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
426
427
428 /* Pick IV's (regardless of whether they
429 * are being used by the transform). */
430 ivlen = cipher_info->iv_size;
431 memset( iv_enc, 0x3, sizeof( iv_enc ) );
432 memset( iv_dec, 0x4, sizeof( iv_dec ) );
433
434 /*
435 * Setup transforms
436 */
437
Jaeden Amero2de07f12019-06-05 13:32:08 +0100438#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \
439 defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
Hanno Beckera18d1322018-01-03 14:27:32 +0000440 t_out->encrypt_then_mac = etm;
441 t_in->encrypt_then_mac = etm;
442#else
443 ((void) etm);
444#endif
445
446 t_out->minor_ver = ver;
447 t_in->minor_ver = ver;
448 t_out->ivlen = ivlen;
449 t_in->ivlen = ivlen;
450
451 switch( cipher_info->mode )
452 {
453 case MBEDTLS_MODE_GCM:
454 case MBEDTLS_MODE_CCM:
455 t_out->fixed_ivlen = 4;
456 t_in->fixed_ivlen = 4;
457 t_out->maclen = 0;
458 t_in->maclen = 0;
459 switch( tag_mode )
460 {
461 case 0: /* Full tag */
462 t_out->taglen = 16;
463 t_in->taglen = 16;
464 break;
465 case 1: /* Partial tag */
466 t_out->taglen = 8;
467 t_in->taglen = 8;
468 break;
469 default:
470 return( 1 );
471 }
472 break;
473
474 case MBEDTLS_MODE_CHACHAPOLY:
475 t_out->fixed_ivlen = 12;
476 t_in->fixed_ivlen = 12;
477 t_out->maclen = 0;
478 t_in->maclen = 0;
479 switch( tag_mode )
480 {
481 case 0: /* Full tag */
482 t_out->taglen = 16;
483 t_in->taglen = 16;
484 break;
485 case 1: /* Partial tag */
486 t_out->taglen = 8;
487 t_in->taglen = 8;
488 break;
489 default:
490 return( 1 );
491 }
492 break;
493
494 case MBEDTLS_MODE_STREAM:
495 case MBEDTLS_MODE_CBC:
496 t_out->fixed_ivlen = 0; /* redundant, must be 0 */
497 t_in->fixed_ivlen = 0; /* redundant, must be 0 */
498 t_out->taglen = 0;
499 t_in->taglen = 0;
500 switch( tag_mode )
501 {
502 case 0: /* Full tag */
503 t_out->maclen = maclen;
504 t_in->maclen = maclen;
505 break;
506 case 1: /* Partial tag */
507 t_out->maclen = 10;
508 t_in->maclen = 10;
509 break;
510 default:
511 return( 1 );
512 }
513 break;
514 default:
515 return( 1 );
516 break;
517 }
518
519 /* Setup IV's */
520
521 memcpy( &t_in->iv_dec, iv_dec, sizeof( iv_dec ) );
522 memcpy( &t_in->iv_enc, iv_enc, sizeof( iv_enc ) );
523 memcpy( &t_out->iv_dec, iv_enc, sizeof( iv_enc ) );
524 memcpy( &t_out->iv_enc, iv_dec, sizeof( iv_dec ) );
525
Hanno Beckera0e20d02019-05-15 14:03:01 +0100526#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Beckerd856c822019-04-29 17:30:59 +0100527 /* Add CID */
528 memcpy( &t_in->in_cid, cid0, cid0_len );
529 memcpy( &t_in->out_cid, cid1, cid1_len );
530 t_in->in_cid_len = cid0_len;
531 t_in->out_cid_len = cid1_len;
532 memcpy( &t_out->in_cid, cid1, cid1_len );
533 memcpy( &t_out->out_cid, cid0, cid0_len );
534 t_out->in_cid_len = cid1_len;
535 t_out->out_cid_len = cid0_len;
Hanno Beckera0e20d02019-05-15 14:03:01 +0100536#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Beckerd856c822019-04-29 17:30:59 +0100537
Hanno Becker81e16a32019-03-01 11:21:44 +0000538cleanup:
539
Hanno Becker3ee54212019-04-04 16:31:26 +0100540 mbedtls_free( key0 );
541 mbedtls_free( key1 );
Hanno Becker81e16a32019-03-01 11:21:44 +0000542
Hanno Beckera5780f12019-04-05 09:55:37 +0100543 return( ret );
Hanno Beckera18d1322018-01-03 14:27:32 +0000544}
545
Manuel Pégourié-Gonnard3caa6ca2019-05-23 10:06:14 +0200546/*
Manuel Pégourié-Gonnard686adb42019-06-03 09:55:16 +0200547 * Populate a session structure for serialization tests.
Manuel Pégourié-Gonnard3caa6ca2019-05-23 10:06:14 +0200548 * Choose dummy values, mostly non-0 to distinguish from the init default.
549 */
550static int ssl_populate_session( mbedtls_ssl_session *session,
Manuel Pégourié-Gonnard220403b2019-05-24 09:54:21 +0200551 int ticket_len,
552 const char *crt_file )
Manuel Pégourié-Gonnard3caa6ca2019-05-23 10:06:14 +0200553{
554#if defined(MBEDTLS_HAVE_TIME)
555 session->start = mbedtls_time( NULL ) - 42;
556#endif
557 session->ciphersuite = 0xabcd;
558 session->compression = 1;
559 session->id_len = sizeof( session->id );
560 memset( session->id, 66, session->id_len );
Manuel Pégourié-Gonnard220403b2019-05-24 09:54:21 +0200561 memset( session->master, 17, sizeof( session->master ) );
Manuel Pégourié-Gonnard3caa6ca2019-05-23 10:06:14 +0200562
Manuel Pégourié-Gonnard1f6033a2019-05-24 10:17:52 +0200563#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_FS_IO)
Manuel Pégourié-Gonnard3caa6ca2019-05-23 10:06:14 +0200564 if( strlen( crt_file ) != 0 )
565 {
Manuel Pégourié-Gonnardee13a732019-07-29 13:00:39 +0200566 mbedtls_x509_crt tmp_crt;
Manuel Pégourié-Gonnard3caa6ca2019-05-23 10:06:14 +0200567 int ret;
Manuel Pégourié-Gonnard6b840702019-05-24 09:40:17 +0200568
Manuel Pégourié-Gonnardee13a732019-07-29 13:00:39 +0200569 mbedtls_x509_crt_init( &tmp_crt );
570 ret = mbedtls_x509_crt_parse_file( &tmp_crt, crt_file );
571 if( ret != 0 )
572 return( ret );
573
574#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
575 /* Move temporary CRT. */
Manuel Pégourié-Gonnard6b840702019-05-24 09:40:17 +0200576 session->peer_cert = mbedtls_calloc( 1, sizeof( *session->peer_cert ) );
577 if( session->peer_cert == NULL )
578 return( -1 );
Manuel Pégourié-Gonnardee13a732019-07-29 13:00:39 +0200579 *session->peer_cert = tmp_crt;
580 memset( &tmp_crt, 0, sizeof( tmp_crt ) );
581#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
582 /* Calculate digest of temporary CRT. */
583 session->peer_cert_digest =
584 mbedtls_calloc( 1, MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN );
585 if( session->peer_cert_digest == NULL )
586 return( -1 );
587 ret = mbedtls_md( mbedtls_md_info_from_type(
588 MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE ),
589 tmp_crt.raw.p, tmp_crt.raw.len,
590 session->peer_cert_digest );
Manuel Pégourié-Gonnard3caa6ca2019-05-23 10:06:14 +0200591 if( ret != 0 )
592 return( ret );
Manuel Pégourié-Gonnardee13a732019-07-29 13:00:39 +0200593 session->peer_cert_digest_type =
594 MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE;
595 session->peer_cert_digest_len =
596 MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN;
597#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
598
599 mbedtls_x509_crt_free( &tmp_crt );
Manuel Pégourié-Gonnard3caa6ca2019-05-23 10:06:14 +0200600 }
Manuel Pégourié-Gonnardee13a732019-07-29 13:00:39 +0200601#else /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard3caa6ca2019-05-23 10:06:14 +0200602 (void) crt_file;
Manuel Pégourié-Gonnardee13a732019-07-29 13:00:39 +0200603#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_FS_IO */
Manuel Pégourié-Gonnard3caa6ca2019-05-23 10:06:14 +0200604 session->verify_result = 0xdeadbeef;
605
606#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
607 if( ticket_len != 0 )
608 {
609 session->ticket = mbedtls_calloc( 1, ticket_len );
Manuel Pégourié-Gonnard220403b2019-05-24 09:54:21 +0200610 if( session->ticket == NULL )
Manuel Pégourié-Gonnard3caa6ca2019-05-23 10:06:14 +0200611 return( -1 );
612 memset( session->ticket, 33, ticket_len );
613 }
614 session->ticket_len = ticket_len;
615 session->ticket_lifetime = 86401;
616#else
617 (void) ticket_len;
618#endif
619
620#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
621 session->mfl_code = 1;
622#endif
623#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
624 session->trunc_hmac = 1;
625#endif
626#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
627 session->encrypt_then_mac = 1;
628#endif
629
630 return( 0 );
631}
632
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +0200633/* END_HEADER */
634
635/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200636 * depends_on:MBEDTLS_SSL_TLS_C
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +0200637 * END_DEPENDENCIES
638 */
639
Janos Follath6264e662019-11-26 11:11:15 +0000640/* BEGIN_CASE */
641void test_callback_buffer_sanity()
642{
643 enum { MSGLEN = 10 };
644 mbedtls_test_buffer buf;
645 unsigned char input[MSGLEN];
646 unsigned char output[MSGLEN];
647
648 memset( input, 0, sizeof(input) );
649
650 /* Make sure calling put and get on NULL buffer results in error. */
651 TEST_ASSERT( mbedtls_test_buffer_put( NULL, input, sizeof( input ) )
652 == -1 );
653 TEST_ASSERT( mbedtls_test_buffer_get( NULL, output, sizeof( output ) )
654 == -1 );
655 TEST_ASSERT( mbedtls_test_buffer_put( NULL, NULL, sizeof( input ) ) == -1 );
656 TEST_ASSERT( mbedtls_test_buffer_get( NULL, NULL, sizeof( output ) )
657 == -1 );
658 TEST_ASSERT( mbedtls_test_buffer_put( NULL, NULL, 0 ) == -1 );
659 TEST_ASSERT( mbedtls_test_buffer_get( NULL, NULL, 0 ) == -1 );
660
661 /* Make sure calling put and get on a buffer that hasn't been set up results
662 * in eror. */
663 mbedtls_test_buffer_init( &buf );
664
665 TEST_ASSERT( mbedtls_test_buffer_put( &buf, input, sizeof( input ) ) == -1 );
666 TEST_ASSERT( mbedtls_test_buffer_get( &buf, output, sizeof( output ) )
667 == -1 );
668 TEST_ASSERT( mbedtls_test_buffer_put( &buf, NULL, sizeof( input ) ) == -1 );
669 TEST_ASSERT( mbedtls_test_buffer_get( &buf, NULL, sizeof( output ) )
670 == -1 );
671 TEST_ASSERT( mbedtls_test_buffer_put( &buf, NULL, 0 ) == -1 );
672 TEST_ASSERT( mbedtls_test_buffer_get( &buf, NULL, 0 ) == -1 );
673
674 /* Make sure calling put end get on NULL input and output only results in
675 * error if the length is not zero. */
676
677 TEST_ASSERT( mbedtls_test_buffer_setup( &buf, sizeof( input ) ) == 0 );
678
679 TEST_ASSERT( mbedtls_test_buffer_put( &buf, NULL, sizeof( input ) ) == -1 );
680 TEST_ASSERT( mbedtls_test_buffer_get( &buf, NULL, sizeof( output ) )
681 == -1 );
682 TEST_ASSERT( mbedtls_test_buffer_put( &buf, NULL, 0 ) == 0 );
683 TEST_ASSERT( mbedtls_test_buffer_get( &buf, NULL, 0 ) == 0 );
684
685exit:
686
687 mbedtls_test_buffer_free( &buf );
688}
689/* END_CASE */
690
691/*
692 * Test if the implementation of `mbedtls_test_buffer` related functions is
693 * correct and works as expected.
694 *
695 * That is
696 * - If we try to put in \p put1 bytes then we can put in \p put1_ret bytes.
697 * - Afterwards if we try to get \p get1 bytes then we can get \get1_ret bytes.
698 * - Next, if we try to put in \p put1 bytes then we can put in \p put1_ret
699 * bytes.
700 * - Afterwards if we try to get \p get1 bytes then we can get \get1_ret bytes.
701 * - All of the bytes we got match the bytes we put in in a FIFO manner.
702 */
703
704/* BEGIN_CASE */
705void test_callback_buffer( int size, int put1, int put1_ret,
706 int get1, int get1_ret, int put2, int put2_ret,
707 int get2, int get2_ret )
708{
709 enum { ROUNDS = 2 };
710 size_t put[ROUNDS];
711 int put_ret[ROUNDS];
712 size_t get[ROUNDS];
713 int get_ret[ROUNDS];
714 mbedtls_test_buffer buf;
715 unsigned char* input = NULL;
716 size_t input_len;
717 unsigned char* output = NULL;
718 size_t output_len;
Janos Follath031827f2019-11-27 11:12:14 +0000719 size_t i, j, written, read;
Janos Follath6264e662019-11-26 11:11:15 +0000720
721 mbedtls_test_buffer_init( &buf );
722 TEST_ASSERT( mbedtls_test_buffer_setup( &buf, size ) == 0 );
723
724 /* Check the sanity of input parameters and initialise local variables. That
725 * is, ensure that the amount of data is not negative and that we are not
726 * expecting more to put or get than we actually asked for. */
727 TEST_ASSERT( put1 >= 0 );
728 put[0] = put1;
729 put_ret[0] = put1_ret;
730 TEST_ASSERT( put1_ret <= put1 );
731 TEST_ASSERT( put2 >= 0 );
732 put[1] = put2;
733 put_ret[1] = put2_ret;
734 TEST_ASSERT( put2_ret <= put2 );
735
736 TEST_ASSERT( get1 >= 0 );
737 get[0] = get1;
738 get_ret[0] = get1_ret;
739 TEST_ASSERT( get1_ret <= get1 );
740 TEST_ASSERT( get2 >= 0 );
741 get[1] = get2;
742 get_ret[1] = get2_ret;
743 TEST_ASSERT( get2_ret <= get2 );
744
745 input_len = 0;
746 /* Calculate actual input and output lengths */
747 for( j = 0; j < ROUNDS; j++ )
748 {
749 if( put_ret[j] > 0 )
750 {
751 input_len += put_ret[j];
752 }
753 }
754 /* In order to always have a valid pointer we always allocate at least 1
755 * byte. */
756 if( input_len == 0 )
757 input_len = 1;
758 ASSERT_ALLOC( input, input_len );
759
760 output_len = 0;
761 for( j = 0; j < ROUNDS; j++ )
762 {
763 if( get_ret[j] > 0 )
764 {
765 output_len += get_ret[j];
766 }
767 }
768 TEST_ASSERT( output_len <= input_len );
769 /* In order to always have a valid pointer we always allocate at least 1
770 * byte. */
771 if( output_len == 0 )
772 output_len = 1;
773 ASSERT_ALLOC( output, output_len );
774
775 /* Fill up the buffer with structured data so that unwanted changes
776 * can be detected */
777 for( i = 0; i < input_len; i++ )
778 {
779 input[i] = i & 0xFF;
780 }
781
782 written = read = 0;
783 for( j = 0; j < ROUNDS; j++ )
784 {
785 TEST_ASSERT( put_ret[j] == mbedtls_test_buffer_put( &buf,
786 input + written, put[j] ) );
787 written += put_ret[j];
788 TEST_ASSERT( get_ret[j] == mbedtls_test_buffer_get( &buf,
789 output + read, get[j] ) );
790 read += get_ret[j];
791 TEST_ASSERT( read <= written );
792 if( get_ret[j] > 0 )
793 {
794 TEST_ASSERT( memcmp( output + read - get_ret[j],
795 input + read - get_ret[j], get_ret[j] )
796 == 0 );
797 }
798 }
799
800exit:
801
802 mbedtls_free( input );
803 mbedtls_free( output );
804 mbedtls_test_buffer_free( &buf );
805}
806/* END_CASE */
807
Janos Follath031827f2019-11-27 11:12:14 +0000808/*
809 * Test if the implementation of `mbedtls_mock_socket` related functions is
810 * correct and works as expected.
811 */
812
813/* BEGIN_CASE */
814void ssl_mock_tcp()
815{
816 enum { ROUNDS = 2 };
817 enum { MSGLEN = 105 };
818 unsigned char message[ROUNDS][MSGLEN];
819 unsigned char received[ROUNDS][MSGLEN];
820 mbedtls_mock_socket client;
821 mbedtls_mock_socket server;
822 size_t written[ROUNDS];
823 size_t read[ROUNDS];
824 int send_ret[ROUNDS];
825 int recv_ret[ROUNDS];
826 unsigned i, j, progress;
827
828 mbedtls_mock_socket_init( &client );
829 mbedtls_mock_socket_init( &server );
830
831 /* Fill up the buffers with structured data so that unwanted changes
832 * can be detected */
833 for( i = 0; i < ROUNDS; i++ )
834 {
835 for( j = 0; j < MSGLEN; j++ )
836 {
837 message[i][j] = ( i * MSGLEN + j ) & 0xFF;
838 }
839 }
840
841 /* Try sending or receiving on an unconnected socket */
842 TEST_ASSERT( mbedtls_mock_tcp_send_b( &client, message[0], MSGLEN ) < 0 );
843 TEST_ASSERT( mbedtls_mock_tcp_recv_b( &client, received[0], MSGLEN ) < 0 );
844
845 /* Make sure that sending a message takes a few iterations. */
846 TEST_ASSERT( 0 == mbedtls_mock_socket_connect( &client, &server,
847 MSGLEN / 5 ) );
848
849 /* Send the message to the server */
850 send_ret[0] = recv_ret[0] = 1;
851 written[0] = read[0] = 0;
852 while( send_ret[0] != 0 || recv_ret[0] != 0 )
853 {
854 send_ret[0] = mbedtls_mock_tcp_send_b( &client,
855 message[0] + written[0],
856 MSGLEN - written[0] );
857 TEST_ASSERT( send_ret[0] >= 0 );
858 written[0] += send_ret[0];
859
860 recv_ret[0] = mbedtls_mock_tcp_recv_b( &server,
861 received[0] + read[0],
862 MSGLEN - read[0] );
863 TEST_ASSERT( recv_ret[0] >= 0 );
864 read[0] += recv_ret[0];
865 }
866 TEST_ASSERT( memcmp( message[0], received[0], MSGLEN ) == 0 );
867
868 /* Reset connection for the next test */
869 mbedtls_mock_socket_close( &client );
870 mbedtls_mock_socket_close( &server );
871 mbedtls_mock_socket_init( &client );
872 mbedtls_mock_socket_init( &server );
873 /* Make sure that sending a message takes a few iterations. */
874 TEST_ASSERT( 0 == mbedtls_mock_socket_connect( &client, &server,
875 MSGLEN / 5 ) );
876
877 /* Send the message from both sides, interleaving. */
878 progress = 1;
879 for( i = 0; i < ROUNDS; i++ )
880 {
881 written[i] = 0;
882 read[i] = 0;
883 }
884 /* This loop does not stop as long as there was a successful write or read
885 * of at least one byte on either side. */
886 while( progress != 0 )
887 {
888 send_ret[0] = mbedtls_mock_tcp_send_b( &client,
889 message[0] + written[0],
890 MSGLEN - written[0] );
891 TEST_ASSERT( send_ret[0] >= 0 );
892 written[0] += send_ret[0];
893
894 send_ret[1] = mbedtls_mock_tcp_send_b( &server,
895 message[1] + written[1],
896 MSGLEN - written[1] );
897 TEST_ASSERT( send_ret[1] >= 0 );
898 written[1] += send_ret[1];
899
900 recv_ret[0] = mbedtls_mock_tcp_recv_b( &server,
901 received[0] + read[0],
902 MSGLEN - read[0] );
903 TEST_ASSERT( recv_ret[0] >= 0 );
904 read[0] += recv_ret[0];
905
906 recv_ret[1] = mbedtls_mock_tcp_recv_b( &client,
907 received[1] + read[1],
908 MSGLEN - read[1] );
909 TEST_ASSERT( recv_ret[1] >= 0 );
910 read[1] += recv_ret[1];
911
912 progress = 0;
913 for( i = 0; i < ROUNDS; i++ )
914 {
915 if( send_ret[i] > 0 )
916 progress++;
917
918 if( recv_ret[i] > 0 )
919 progress++;
920 }
921 }
922
923 for( i = 0; i < ROUNDS; i++ )
924 TEST_ASSERT( memcmp( message[i], received[i], MSGLEN ) == 0 );
925
926exit:
927
928 mbedtls_mock_socket_close( &client );
929 mbedtls_mock_socket_close( &server );
930}
931/* END_CASE */
932
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200933/* BEGIN_CASE depends_on:MBEDTLS_SSL_DTLS_ANTI_REPLAY */
Azim Khan5fcca462018-06-29 11:05:32 +0100934void ssl_dtls_replay( data_t * prevs, data_t * new, int ret )
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +0200935{
Azim Khand30ca132017-06-09 04:32:58 +0100936 uint32_t len = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200937 mbedtls_ssl_context ssl;
Manuel Pégourié-Gonnarddef0bbe2015-05-04 14:56:36 +0200938 mbedtls_ssl_config conf;
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +0200939
Manuel Pégourié-Gonnard41d479e2015-04-29 00:48:22 +0200940 mbedtls_ssl_init( &ssl );
Manuel Pégourié-Gonnarddef0bbe2015-05-04 14:56:36 +0200941 mbedtls_ssl_config_init( &conf );
Manuel Pégourié-Gonnard41d479e2015-04-29 00:48:22 +0200942
Manuel Pégourié-Gonnard419d5ae2015-05-04 19:32:36 +0200943 TEST_ASSERT( mbedtls_ssl_config_defaults( &conf,
944 MBEDTLS_SSL_IS_CLIENT,
Manuel Pégourié-Gonnardb31c5f62015-06-17 13:53:47 +0200945 MBEDTLS_SSL_TRANSPORT_DATAGRAM,
946 MBEDTLS_SSL_PRESET_DEFAULT ) == 0 );
Manuel Pégourié-Gonnarddef0bbe2015-05-04 14:56:36 +0200947 TEST_ASSERT( mbedtls_ssl_setup( &ssl, &conf ) == 0 );
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +0200948
949 /* Read previous record numbers */
Azim Khand30ca132017-06-09 04:32:58 +0100950 for( len = 0; len < prevs->len; len += 6 )
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +0200951 {
Azim Khand30ca132017-06-09 04:32:58 +0100952 memcpy( ssl.in_ctr + 2, prevs->x + len, 6 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200953 mbedtls_ssl_dtls_replay_update( &ssl );
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +0200954 }
955
956 /* Check new number */
Azim Khand30ca132017-06-09 04:32:58 +0100957 memcpy( ssl.in_ctr + 2, new->x, 6 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200958 TEST_ASSERT( mbedtls_ssl_dtls_replay_check( &ssl ) == ret );
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +0200959
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200960 mbedtls_ssl_free( &ssl );
Manuel Pégourié-Gonnarddef0bbe2015-05-04 14:56:36 +0200961 mbedtls_ssl_config_free( &conf );
Manuel Pégourié-Gonnard4956fd72014-09-24 11:13:44 +0200962}
963/* END_CASE */
Hanno Beckerb25c0c72017-05-05 11:24:30 +0100964
965/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */
966void ssl_set_hostname_twice( char *hostname0, char *hostname1 )
967{
968 mbedtls_ssl_context ssl;
969 mbedtls_ssl_init( &ssl );
970
971 TEST_ASSERT( mbedtls_ssl_set_hostname( &ssl, hostname0 ) == 0 );
972 TEST_ASSERT( mbedtls_ssl_set_hostname( &ssl, hostname1 ) == 0 );
973
974 mbedtls_ssl_free( &ssl );
975}
Darryl Green11999bb2018-03-13 15:22:58 +0000976/* END_CASE */
Hanno Beckera18d1322018-01-03 14:27:32 +0000977
978/* BEGIN_CASE */
979void ssl_crypt_record( int cipher_type, int hash_id,
Hanno Beckerd856c822019-04-29 17:30:59 +0100980 int etm, int tag_mode, int ver,
981 int cid0_len, int cid1_len )
Hanno Beckera18d1322018-01-03 14:27:32 +0000982{
983 /*
984 * Test several record encryptions and decryptions
985 * with plenty of space before and after the data
986 * within the record buffer.
987 */
988
989 int ret;
990 int num_records = 16;
991 mbedtls_ssl_context ssl; /* ONLY for debugging */
992
993 mbedtls_ssl_transform t0, t1;
Hanno Becker81e16a32019-03-01 11:21:44 +0000994 unsigned char *buf = NULL;
Hanno Beckera18d1322018-01-03 14:27:32 +0000995 size_t const buflen = 512;
996 mbedtls_record rec, rec_backup;
997
998 mbedtls_ssl_init( &ssl );
999 mbedtls_ssl_transform_init( &t0 );
1000 mbedtls_ssl_transform_init( &t1 );
1001 TEST_ASSERT( build_transforms( &t0, &t1, cipher_type, hash_id,
Hanno Beckerd856c822019-04-29 17:30:59 +01001002 etm, tag_mode, ver,
1003 (size_t) cid0_len,
1004 (size_t) cid1_len ) == 0 );
Hanno Beckera18d1322018-01-03 14:27:32 +00001005
Hanno Becker3ee54212019-04-04 16:31:26 +01001006 TEST_ASSERT( ( buf = mbedtls_calloc( 1, buflen ) ) != NULL );
Hanno Beckera18d1322018-01-03 14:27:32 +00001007
1008 while( num_records-- > 0 )
1009 {
1010 mbedtls_ssl_transform *t_dec, *t_enc;
1011 /* Take turns in who's sending and who's receiving. */
1012 if( num_records % 3 == 0 )
1013 {
1014 t_dec = &t0;
1015 t_enc = &t1;
1016 }
1017 else
1018 {
1019 t_dec = &t1;
1020 t_enc = &t0;
1021 }
1022
1023 /*
1024 * The record header affects the transformation in two ways:
1025 * 1) It determines the AEAD additional data
1026 * 2) The record counter sometimes determines the IV.
1027 *
1028 * Apart from that, the fields don't have influence.
1029 * In particular, it is currently not the responsibility
1030 * of ssl_encrypt/decrypt_buf to check if the transform
1031 * version matches the record version, or that the
1032 * type is sensible.
1033 */
1034
1035 memset( rec.ctr, num_records, sizeof( rec.ctr ) );
1036 rec.type = 42;
1037 rec.ver[0] = num_records;
1038 rec.ver[1] = num_records;
Hanno Beckera0e20d02019-05-15 14:03:01 +01001039#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Beckerd856c822019-04-29 17:30:59 +01001040 rec.cid_len = 0;
Hanno Beckera0e20d02019-05-15 14:03:01 +01001041#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Beckera18d1322018-01-03 14:27:32 +00001042
1043 rec.buf = buf;
1044 rec.buf_len = buflen;
1045 rec.data_offset = 16;
1046 /* Make sure to vary the length to exercise different
1047 * paddings. */
1048 rec.data_len = 1 + num_records;
1049
1050 memset( rec.buf + rec.data_offset, 42, rec.data_len );
1051
1052 /* Make a copy for later comparison */
1053 rec_backup = rec;
1054
1055 /* Encrypt record */
1056 ret = mbedtls_ssl_encrypt_buf( &ssl, t_enc, &rec,
1057 rnd_std_rand, NULL );
1058 TEST_ASSERT( ret == 0 || ret == MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
1059 if( ret != 0 )
1060 {
1061 continue;
1062 }
1063
1064 /* Decrypt record with t_dec */
Hanno Beckerd856c822019-04-29 17:30:59 +01001065 ret = mbedtls_ssl_decrypt_buf( &ssl, t_dec, &rec );
1066 TEST_ASSERT( ret == 0 );
Hanno Beckera18d1322018-01-03 14:27:32 +00001067
1068 /* Compare results */
1069 TEST_ASSERT( rec.type == rec_backup.type );
1070 TEST_ASSERT( memcmp( rec.ctr, rec_backup.ctr, 8 ) == 0 );
1071 TEST_ASSERT( rec.ver[0] == rec_backup.ver[0] );
1072 TEST_ASSERT( rec.ver[1] == rec_backup.ver[1] );
1073 TEST_ASSERT( rec.data_len == rec_backup.data_len );
1074 TEST_ASSERT( rec.data_offset == rec_backup.data_offset );
1075 TEST_ASSERT( memcmp( rec.buf + rec.data_offset,
1076 rec_backup.buf + rec_backup.data_offset,
1077 rec.data_len ) == 0 );
1078 }
1079
Hanno Becker81e16a32019-03-01 11:21:44 +00001080exit:
1081
Hanno Beckera18d1322018-01-03 14:27:32 +00001082 /* Cleanup */
1083 mbedtls_ssl_free( &ssl );
1084 mbedtls_ssl_transform_free( &t0 );
1085 mbedtls_ssl_transform_free( &t1 );
1086
Hanno Becker3ee54212019-04-04 16:31:26 +01001087 mbedtls_free( buf );
Hanno Beckera18d1322018-01-03 14:27:32 +00001088}
1089/* END_CASE */
Hanno Beckerb3268da2018-01-05 15:20:24 +00001090
1091/* BEGIN_CASE */
1092void ssl_crypt_record_small( int cipher_type, int hash_id,
Hanno Beckerd856c822019-04-29 17:30:59 +01001093 int etm, int tag_mode, int ver,
1094 int cid0_len, int cid1_len )
Hanno Beckerb3268da2018-01-05 15:20:24 +00001095{
1096 /*
1097 * Test pairs of encryption and decryption with an increasing
1098 * amount of space in the record buffer - in more detail:
1099 * 1) Try to encrypt with 0, 1, 2, ... bytes available
1100 * in front of the plaintext, and expect the encryption
1101 * to succeed starting from some offset. Always keep
1102 * enough space in the end of the buffer.
1103 * 2) Try to encrypt with 0, 1, 2, ... bytes available
1104 * at the end of the plaintext, and expect the encryption
1105 * to succeed starting from some offset. Always keep
1106 * enough space at the beginning of the buffer.
1107 * 3) Try to encrypt with 0, 1, 2, ... bytes available
1108 * both at the front and end of the plaintext,
1109 * and expect the encryption to succeed starting from
1110 * some offset.
1111 *
1112 * If encryption succeeds, check that decryption succeeds
1113 * and yields the original record.
1114 */
1115
1116 mbedtls_ssl_context ssl; /* ONLY for debugging */
1117
1118 mbedtls_ssl_transform t0, t1;
Hanno Becker81e16a32019-03-01 11:21:44 +00001119 unsigned char *buf = NULL;
Hanno Beckerd856c822019-04-29 17:30:59 +01001120 size_t const buflen = 256;
Hanno Beckerb3268da2018-01-05 15:20:24 +00001121 mbedtls_record rec, rec_backup;
1122
1123 int ret;
Hanno Beckerd856c822019-04-29 17:30:59 +01001124 int mode; /* Mode 1, 2 or 3 as explained above */
1125 size_t offset; /* Available space at beginning/end/both */
1126 size_t threshold = 96; /* Maximum offset to test against */
Hanno Beckerb3268da2018-01-05 15:20:24 +00001127
Hanno Beckerd856c822019-04-29 17:30:59 +01001128 size_t default_pre_padding = 64; /* Pre-padding to use in mode 2 */
1129 size_t default_post_padding = 128; /* Post-padding to use in mode 1 */
Hanno Beckerb3268da2018-01-05 15:20:24 +00001130
1131 int seen_success; /* Indicates if in the current mode we've
1132 * already seen a successful test. */
1133
1134 mbedtls_ssl_init( &ssl );
1135 mbedtls_ssl_transform_init( &t0 );
1136 mbedtls_ssl_transform_init( &t1 );
1137 TEST_ASSERT( build_transforms( &t0, &t1, cipher_type, hash_id,
Hanno Beckerd856c822019-04-29 17:30:59 +01001138 etm, tag_mode, ver,
1139 (size_t) cid0_len,
1140 (size_t) cid1_len ) == 0 );
Hanno Beckerb3268da2018-01-05 15:20:24 +00001141
Hanno Becker3ee54212019-04-04 16:31:26 +01001142 TEST_ASSERT( ( buf = mbedtls_calloc( 1, buflen ) ) != NULL );
Hanno Beckerb3268da2018-01-05 15:20:24 +00001143
1144 for( mode=1; mode <= 3; mode++ )
1145 {
1146 seen_success = 0;
1147 for( offset=0; offset <= threshold; offset++ )
1148 {
1149 mbedtls_ssl_transform *t_dec, *t_enc;
Hanno Becker6c87b3f2019-04-29 17:24:44 +01001150 t_dec = &t0;
1151 t_enc = &t1;
Hanno Beckerb3268da2018-01-05 15:20:24 +00001152
1153 memset( rec.ctr, offset, sizeof( rec.ctr ) );
1154 rec.type = 42;
1155 rec.ver[0] = offset;
1156 rec.ver[1] = offset;
1157 rec.buf = buf;
1158 rec.buf_len = buflen;
Hanno Beckera0e20d02019-05-15 14:03:01 +01001159#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
Hanno Beckerd856c822019-04-29 17:30:59 +01001160 rec.cid_len = 0;
Hanno Beckera0e20d02019-05-15 14:03:01 +01001161#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
Hanno Beckerb3268da2018-01-05 15:20:24 +00001162
1163 switch( mode )
1164 {
1165 case 1: /* Space in the beginning */
1166 rec.data_offset = offset;
1167 rec.data_len = buflen - offset - default_post_padding;
1168 break;
1169
1170 case 2: /* Space in the end */
1171 rec.data_offset = default_pre_padding;
1172 rec.data_len = buflen - default_pre_padding - offset;
1173 break;
1174
1175 case 3: /* Space in the beginning and end */
1176 rec.data_offset = offset;
1177 rec.data_len = buflen - 2 * offset;
1178 break;
1179
1180 default:
1181 TEST_ASSERT( 0 );
1182 break;
1183 }
1184
1185 memset( rec.buf + rec.data_offset, 42, rec.data_len );
1186
1187 /* Make a copy for later comparison */
1188 rec_backup = rec;
1189
1190 /* Encrypt record */
1191 ret = mbedtls_ssl_encrypt_buf( &ssl, t_enc, &rec, rnd_std_rand, NULL );
1192
1193 if( ( mode == 1 || mode == 2 ) && seen_success )
1194 {
1195 TEST_ASSERT( ret == 0 );
1196 }
1197 else
1198 {
1199 TEST_ASSERT( ret == 0 || ret == MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
1200 if( ret == 0 )
1201 seen_success = 1;
1202 }
1203
1204 if( ret != 0 )
1205 continue;
1206
1207 /* Decrypt record with t_dec */
1208 TEST_ASSERT( mbedtls_ssl_decrypt_buf( &ssl, t_dec, &rec ) == 0 );
1209
1210 /* Compare results */
1211 TEST_ASSERT( rec.type == rec_backup.type );
1212 TEST_ASSERT( memcmp( rec.ctr, rec_backup.ctr, 8 ) == 0 );
1213 TEST_ASSERT( rec.ver[0] == rec_backup.ver[0] );
1214 TEST_ASSERT( rec.ver[1] == rec_backup.ver[1] );
1215 TEST_ASSERT( rec.data_len == rec_backup.data_len );
1216 TEST_ASSERT( rec.data_offset == rec_backup.data_offset );
1217 TEST_ASSERT( memcmp( rec.buf + rec.data_offset,
1218 rec_backup.buf + rec_backup.data_offset,
1219 rec.data_len ) == 0 );
1220 }
1221
1222 TEST_ASSERT( seen_success == 1 );
1223 }
1224
Hanno Becker81e16a32019-03-01 11:21:44 +00001225exit:
1226
Hanno Beckerb3268da2018-01-05 15:20:24 +00001227 /* Cleanup */
1228 mbedtls_ssl_free( &ssl );
1229 mbedtls_ssl_transform_free( &t0 );
1230 mbedtls_ssl_transform_free( &t1 );
1231
Hanno Becker3ee54212019-04-04 16:31:26 +01001232 mbedtls_free( buf );
Hanno Beckerb3268da2018-01-05 15:20:24 +00001233}
1234/* END_CASE */
Ron Eldor824ad7b2019-05-13 14:09:00 +03001235
1236/* BEGIN_CASE */
1237void ssl_tls_prf( int type, data_t * secret, data_t * random,
1238 char *label, data_t *result_hex_str, int exp_ret )
1239{
1240 unsigned char *output;
1241
1242 output = mbedtls_calloc( 1, result_hex_str->len );
1243 if( output == NULL )
1244 goto exit;
1245
Ron Eldor6b9b1b82019-05-15 17:04:33 +03001246#if defined(MBEDTLS_USE_PSA_CRYPTO)
1247 TEST_ASSERT( psa_crypto_init() == 0 );
1248#endif
1249
Ron Eldor824ad7b2019-05-13 14:09:00 +03001250 TEST_ASSERT( mbedtls_ssl_tls_prf( type, secret->x, secret->len,
1251 label, random->x, random->len,
1252 output, result_hex_str->len ) == exp_ret );
1253
1254 if( exp_ret == 0 )
1255 {
1256 TEST_ASSERT( hexcmp( output, result_hex_str->x,
1257 result_hex_str->len, result_hex_str->len ) == 0 );
1258 }
1259exit:
1260
1261 mbedtls_free( output );
1262}
1263/* END_CASE */
Manuel Pégourié-Gonnard6eac11b2019-05-23 09:30:55 +02001264
Manuel Pégourié-Gonnardf9deaec2019-05-24 09:41:39 +02001265/* BEGIN_CASE */
Manuel Pégourié-Gonnard686adb42019-06-03 09:55:16 +02001266void ssl_serialize_session_save_load( int ticket_len, char *crt_file )
Manuel Pégourié-Gonnardf9deaec2019-05-24 09:41:39 +02001267{
1268 mbedtls_ssl_session original, restored;
1269 unsigned char *buf = NULL;
1270 size_t len;
1271
1272 /*
1273 * Test that a save-load pair is the identity
1274 */
1275
1276 mbedtls_ssl_session_init( &original );
1277 mbedtls_ssl_session_init( &restored );
1278
1279 /* Prepare a dummy session to work on */
1280 TEST_ASSERT( ssl_populate_session( &original, ticket_len, crt_file ) == 0 );
1281
Manuel Pégourié-Gonnard686adb42019-06-03 09:55:16 +02001282 /* Serialize it */
Manuel Pégourié-Gonnardf9deaec2019-05-24 09:41:39 +02001283 TEST_ASSERT( mbedtls_ssl_session_save( &original, NULL, 0, &len )
1284 == MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
1285 TEST_ASSERT( ( buf = mbedtls_calloc( 1, len ) ) != NULL );
1286 TEST_ASSERT( mbedtls_ssl_session_save( &original, buf, len, &len )
1287 == 0 );
1288
Manuel Pégourié-Gonnard686adb42019-06-03 09:55:16 +02001289 /* Restore session from serialized data */
Manuel Pégourié-Gonnardf9deaec2019-05-24 09:41:39 +02001290 TEST_ASSERT( mbedtls_ssl_session_load( &restored, buf, len) == 0 );
1291
1292 /*
1293 * Make sure both session structures are identical
1294 */
1295#if defined(MBEDTLS_HAVE_TIME)
1296 TEST_ASSERT( original.start == restored.start );
1297#endif
1298 TEST_ASSERT( original.ciphersuite == restored.ciphersuite );
1299 TEST_ASSERT( original.compression == restored.compression );
1300 TEST_ASSERT( original.id_len == restored.id_len );
1301 TEST_ASSERT( memcmp( original.id,
1302 restored.id, sizeof( original.id ) ) == 0 );
1303 TEST_ASSERT( memcmp( original.master,
1304 restored.master, sizeof( original.master ) ) == 0 );
1305
1306#if defined(MBEDTLS_X509_CRT_PARSE_C)
Manuel Pégourié-Gonnardee13a732019-07-29 13:00:39 +02001307#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
Manuel Pégourié-Gonnardf9deaec2019-05-24 09:41:39 +02001308 TEST_ASSERT( ( original.peer_cert == NULL ) ==
1309 ( restored.peer_cert == NULL ) );
1310 if( original.peer_cert != NULL )
1311 {
1312 TEST_ASSERT( original.peer_cert->raw.len ==
1313 restored.peer_cert->raw.len );
1314 TEST_ASSERT( memcmp( original.peer_cert->raw.p,
1315 restored.peer_cert->raw.p,
1316 original.peer_cert->raw.len ) == 0 );
1317 }
Manuel Pégourié-Gonnardee13a732019-07-29 13:00:39 +02001318#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
1319 TEST_ASSERT( original.peer_cert_digest_type ==
1320 restored.peer_cert_digest_type );
1321 TEST_ASSERT( original.peer_cert_digest_len ==
1322 restored.peer_cert_digest_len );
1323 TEST_ASSERT( ( original.peer_cert_digest == NULL ) ==
1324 ( restored.peer_cert_digest == NULL ) );
1325 if( original.peer_cert_digest != NULL )
1326 {
1327 TEST_ASSERT( memcmp( original.peer_cert_digest,
1328 restored.peer_cert_digest,
1329 original.peer_cert_digest_len ) == 0 );
1330 }
1331#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
1332#endif /* MBEDTLS_X509_CRT_PARSE_C */
Manuel Pégourié-Gonnardf9deaec2019-05-24 09:41:39 +02001333 TEST_ASSERT( original.verify_result == restored.verify_result );
1334
1335#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
1336 TEST_ASSERT( original.ticket_len == restored.ticket_len );
1337 if( original.ticket_len != 0 )
1338 {
1339 TEST_ASSERT( original.ticket != NULL );
1340 TEST_ASSERT( restored.ticket != NULL );
1341 TEST_ASSERT( memcmp( original.ticket,
1342 restored.ticket, original.ticket_len ) == 0 );
1343 }
1344 TEST_ASSERT( original.ticket_lifetime == restored.ticket_lifetime );
1345#endif
1346
1347#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
1348 TEST_ASSERT( original.mfl_code == restored.mfl_code );
1349#endif
1350
1351#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
1352 TEST_ASSERT( original.trunc_hmac == restored.trunc_hmac );
1353#endif
1354
1355#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
1356 TEST_ASSERT( original.encrypt_then_mac == restored.encrypt_then_mac );
1357#endif
1358
1359exit:
1360 mbedtls_ssl_session_free( &original );
1361 mbedtls_ssl_session_free( &restored );
1362 mbedtls_free( buf );
1363}
1364/* END_CASE */
1365
Manuel Pégourié-Gonnardaa755832019-06-03 10:53:47 +02001366/* BEGIN_CASE */
Manuel Pégourié-Gonnard686adb42019-06-03 09:55:16 +02001367void ssl_serialize_session_load_save( int ticket_len, char *crt_file )
Manuel Pégourié-Gonnard6eac11b2019-05-23 09:30:55 +02001368{
1369 mbedtls_ssl_session session;
1370 unsigned char *buf1 = NULL, *buf2 = NULL;
1371 size_t len0, len1, len2;
1372
1373 /*
1374 * Test that a load-save pair is the identity
1375 */
1376
1377 mbedtls_ssl_session_init( &session );
1378
Manuel Pégourié-Gonnard3caa6ca2019-05-23 10:06:14 +02001379 /* Prepare a dummy session to work on */
Manuel Pégourié-Gonnard6b840702019-05-24 09:40:17 +02001380 TEST_ASSERT( ssl_populate_session( &session, ticket_len, crt_file ) == 0 );
Manuel Pégourié-Gonnard3caa6ca2019-05-23 10:06:14 +02001381
Manuel Pégourié-Gonnard686adb42019-06-03 09:55:16 +02001382 /* Get desired buffer size for serializing */
Manuel Pégourié-Gonnard6eac11b2019-05-23 09:30:55 +02001383 TEST_ASSERT( mbedtls_ssl_session_save( &session, NULL, 0, &len0 )
1384 == MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
1385
1386 /* Allocate first buffer */
1387 buf1 = mbedtls_calloc( 1, len0 );
1388 TEST_ASSERT( buf1 != NULL );
1389
Manuel Pégourié-Gonnard686adb42019-06-03 09:55:16 +02001390 /* Serialize to buffer and free live session */
Manuel Pégourié-Gonnard6eac11b2019-05-23 09:30:55 +02001391 TEST_ASSERT( mbedtls_ssl_session_save( &session, buf1, len0, &len1 )
1392 == 0 );
1393 TEST_ASSERT( len0 == len1 );
1394 mbedtls_ssl_session_free( &session );
1395
Manuel Pégourié-Gonnard686adb42019-06-03 09:55:16 +02001396 /* Restore session from serialized data */
Manuel Pégourié-Gonnard220403b2019-05-24 09:54:21 +02001397 TEST_ASSERT( mbedtls_ssl_session_load( &session, buf1, len1 ) == 0 );
Manuel Pégourié-Gonnard6eac11b2019-05-23 09:30:55 +02001398
Manuel Pégourié-Gonnard686adb42019-06-03 09:55:16 +02001399 /* Allocate second buffer and serialize to it */
Manuel Pégourié-Gonnard6eac11b2019-05-23 09:30:55 +02001400 buf2 = mbedtls_calloc( 1, len0 );
Manuel Pégourié-Gonnardb4079902019-05-24 09:52:10 +02001401 TEST_ASSERT( buf2 != NULL );
Manuel Pégourié-Gonnard6eac11b2019-05-23 09:30:55 +02001402 TEST_ASSERT( mbedtls_ssl_session_save( &session, buf2, len0, &len2 )
1403 == 0 );
1404
Manuel Pégourié-Gonnard686adb42019-06-03 09:55:16 +02001405 /* Make sure both serialized versions are identical */
Manuel Pégourié-Gonnard6eac11b2019-05-23 09:30:55 +02001406 TEST_ASSERT( len1 == len2 );
1407 TEST_ASSERT( memcmp( buf1, buf2, len1 ) == 0 );
1408
1409exit:
1410 mbedtls_ssl_session_free( &session );
1411 mbedtls_free( buf1 );
1412 mbedtls_free( buf2 );
1413}
1414/* END_CASE */
Manuel Pégourié-Gonnardf5fa0aa2019-05-23 10:38:11 +02001415
1416/* BEGIN_CASE */
Manuel Pégourié-Gonnard686adb42019-06-03 09:55:16 +02001417void ssl_serialize_session_save_buf_size( int ticket_len, char *crt_file )
Manuel Pégourié-Gonnardf5fa0aa2019-05-23 10:38:11 +02001418{
1419 mbedtls_ssl_session session;
1420 unsigned char *buf = NULL;
1421 size_t good_len, bad_len, test_len;
1422
1423 /*
1424 * Test that session_save() fails cleanly on small buffers
1425 */
1426
1427 mbedtls_ssl_session_init( &session );
1428
Manuel Pégourié-Gonnard686adb42019-06-03 09:55:16 +02001429 /* Prepare dummy session and get serialized size */
Manuel Pégourié-Gonnard6b840702019-05-24 09:40:17 +02001430 TEST_ASSERT( ssl_populate_session( &session, ticket_len, crt_file ) == 0 );
Manuel Pégourié-Gonnardf5fa0aa2019-05-23 10:38:11 +02001431 TEST_ASSERT( mbedtls_ssl_session_save( &session, NULL, 0, &good_len )
1432 == MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
1433
1434 /* Try all possible bad lengths */
1435 for( bad_len = 1; bad_len < good_len; bad_len++ )
1436 {
1437 /* Allocate exact size so that asan/valgrind can detect any overwrite */
1438 mbedtls_free( buf );
1439 TEST_ASSERT( ( buf = mbedtls_calloc( 1, bad_len ) ) != NULL );
1440 TEST_ASSERT( mbedtls_ssl_session_save( &session, buf, bad_len,
1441 &test_len )
1442 == MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
1443 TEST_ASSERT( test_len == good_len );
1444 }
1445
1446exit:
1447 mbedtls_ssl_session_free( &session );
1448 mbedtls_free( buf );
1449}
1450/* END_CASE */
Manuel Pégourié-Gonnarda3d831b2019-05-23 12:28:45 +02001451
1452/* BEGIN_CASE */
Manuel Pégourié-Gonnard686adb42019-06-03 09:55:16 +02001453void ssl_serialize_session_load_buf_size( int ticket_len, char *crt_file )
Manuel Pégourié-Gonnarda3d831b2019-05-23 12:28:45 +02001454{
1455 mbedtls_ssl_session session;
1456 unsigned char *good_buf = NULL, *bad_buf = NULL;
1457 size_t good_len, bad_len;
1458
1459 /*
1460 * Test that session_load() fails cleanly on small buffers
1461 */
1462
1463 mbedtls_ssl_session_init( &session );
1464
Manuel Pégourié-Gonnard686adb42019-06-03 09:55:16 +02001465 /* Prepare serialized session data */
Manuel Pégourié-Gonnard6b840702019-05-24 09:40:17 +02001466 TEST_ASSERT( ssl_populate_session( &session, ticket_len, crt_file ) == 0 );
Manuel Pégourié-Gonnarda3d831b2019-05-23 12:28:45 +02001467 TEST_ASSERT( mbedtls_ssl_session_save( &session, NULL, 0, &good_len )
1468 == MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
1469 TEST_ASSERT( ( good_buf = mbedtls_calloc( 1, good_len ) ) != NULL );
1470 TEST_ASSERT( mbedtls_ssl_session_save( &session, good_buf, good_len,
1471 &good_len ) == 0 );
1472 mbedtls_ssl_session_free( &session );
1473
1474 /* Try all possible bad lengths */
1475 for( bad_len = 0; bad_len < good_len; bad_len++ )
1476 {
1477 /* Allocate exact size so that asan/valgrind can detect any overread */
1478 mbedtls_free( bad_buf );
1479 bad_buf = mbedtls_calloc( 1, bad_len ? bad_len : 1 );
1480 TEST_ASSERT( bad_buf != NULL );
1481 memcpy( bad_buf, good_buf, bad_len );
1482
1483 TEST_ASSERT( mbedtls_ssl_session_load( &session, bad_buf, bad_len )
1484 == MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
1485 }
1486
1487exit:
1488 mbedtls_ssl_session_free( &session );
1489 mbedtls_free( good_buf );
1490 mbedtls_free( bad_buf );
1491}
1492/* END_CASE */
Hanno Becker861d0bb2019-05-21 16:39:30 +01001493
Hanno Becker363b6462019-05-29 12:44:28 +01001494/* BEGIN_CASE */
1495void ssl_session_serialize_version_check( int corrupt_major,
Hanno Becker861d0bb2019-05-21 16:39:30 +01001496 int corrupt_minor,
1497 int corrupt_patch,
1498 int corrupt_config )
1499{
Hanno Becker363b6462019-05-29 12:44:28 +01001500 unsigned char serialized_session[ 2048 ];
1501 size_t serialized_session_len;
Hanno Beckerfe1275e2019-05-29 12:45:21 +01001502 unsigned cur_byte;
Hanno Becker861d0bb2019-05-21 16:39:30 +01001503 mbedtls_ssl_session session;
Hanno Beckerfe1275e2019-05-29 12:45:21 +01001504 uint8_t should_corrupt_byte[] = { corrupt_major == 1,
1505 corrupt_minor == 1,
1506 corrupt_patch == 1,
1507 corrupt_config == 1,
1508 corrupt_config == 1 };
1509
Hanno Becker861d0bb2019-05-21 16:39:30 +01001510 mbedtls_ssl_session_init( &session );
1511
Hanno Beckerfe1275e2019-05-29 12:45:21 +01001512 /* Infer length of serialized session. */
Hanno Becker861d0bb2019-05-21 16:39:30 +01001513 TEST_ASSERT( mbedtls_ssl_session_save( &session,
Hanno Becker363b6462019-05-29 12:44:28 +01001514 serialized_session,
1515 sizeof( serialized_session ),
1516 &serialized_session_len ) == 0 );
Hanno Becker861d0bb2019-05-21 16:39:30 +01001517
Hanno Beckerfe1275e2019-05-29 12:45:21 +01001518 mbedtls_ssl_session_free( &session );
Hanno Becker861d0bb2019-05-21 16:39:30 +01001519
Hanno Beckerfe1275e2019-05-29 12:45:21 +01001520 /* Without any modification, we should be able to successfully
Hanno Becker363b6462019-05-29 12:44:28 +01001521 * de-serialize the session - double-check that. */
Hanno Becker861d0bb2019-05-21 16:39:30 +01001522 TEST_ASSERT( mbedtls_ssl_session_load( &session,
Hanno Becker363b6462019-05-29 12:44:28 +01001523 serialized_session,
1524 serialized_session_len ) == 0 );
Hanno Becker861d0bb2019-05-21 16:39:30 +01001525 mbedtls_ssl_session_free( &session );
1526
Hanno Beckerfe1275e2019-05-29 12:45:21 +01001527 /* Go through the bytes in the serialized session header and
1528 * corrupt them bit-by-bit. */
1529 for( cur_byte = 0; cur_byte < sizeof( should_corrupt_byte ); cur_byte++ )
Hanno Becker861d0bb2019-05-21 16:39:30 +01001530 {
Hanno Beckerfe1275e2019-05-29 12:45:21 +01001531 int cur_bit;
1532 unsigned char * const byte = &serialized_session[ cur_byte ];
1533
1534 if( should_corrupt_byte[ cur_byte ] == 0 )
1535 continue;
1536
1537 for( cur_bit = 0; cur_bit < CHAR_BIT; cur_bit++ )
1538 {
1539 unsigned char const corrupted_bit = 0x1u << cur_bit;
1540 /* Modify a single bit in the serialized session. */
1541 *byte ^= corrupted_bit;
1542
1543 /* Attempt to deserialize */
1544 TEST_ASSERT( mbedtls_ssl_session_load( &session,
1545 serialized_session,
1546 serialized_session_len ) ==
Hanno Beckerf9b33032019-06-03 12:58:39 +01001547 MBEDTLS_ERR_SSL_VERSION_MISMATCH );
Hanno Beckerfe1275e2019-05-29 12:45:21 +01001548
1549 /* Undo the change */
1550 *byte ^= corrupted_bit;
1551 }
Hanno Becker861d0bb2019-05-21 16:39:30 +01001552 }
1553
Hanno Becker861d0bb2019-05-21 16:39:30 +01001554}
1555/* END_CASE */