Store outgoing record sequence number outside record buffer

This commit is another step towards supporting the packing of
multiple records within a single datagram.

Previously, the incremental outgoing record sequence number was
statically stored within the record buffer, at its final place
within the record header. This slightly increased efficiency
as it was not necessary to copy the sequence number when writing
outgoing records.

When allowing multiple records within a single datagram, it is
necessary to allow the position of the current record within the
datagram buffer to be flexible; in particular, there is no static
address for the record sequence number field within the record header.

This commit introduces an additional field `cur_out_ctr` within
the main SSL context structure `mbedtls_ssl_context` to keep track
of the outgoing record sequence number independent of the buffer used
for the current record / datagram. Whenever a new record is written,
this sequence number is copied to the the address `out_ctr` of the
sequence number header field within the current outgoing record.
This commit is contained in:
Hanno Becker 2018-08-06 09:40:20 +01:00
parent 5aa4e2cedd
commit 198594709b
3 changed files with 13 additions and 8 deletions

View file

@ -1116,6 +1116,8 @@ struct mbedtls_ssl_context
size_t out_msglen; /*!< record header: message length */ size_t out_msglen; /*!< record header: message length */
size_t out_left; /*!< amount of data not yet written */ size_t out_left; /*!< amount of data not yet written */
unsigned char cur_out_ctr[8]; /*!< Outgoing record sequence number. */
#if defined(MBEDTLS_ZLIB_SUPPORT) #if defined(MBEDTLS_ZLIB_SUPPORT)
unsigned char *compress_buf; /*!< zlib data buffer */ unsigned char *compress_buf; /*!< zlib data buffer */
#endif #endif

View file

@ -1294,7 +1294,7 @@ read_record_header:
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
} }
memcpy( ssl->out_ctr + 2, ssl->in_ctr + 2, 6 ); memcpy( ssl->cur_out_ctr + 2, ssl->in_ctr + 2, 6 );
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 ) if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 )

View file

@ -2798,8 +2798,8 @@ static void ssl_swap_epochs( mbedtls_ssl_context *ssl )
ssl->handshake->alt_transform_out = tmp_transform; ssl->handshake->alt_transform_out = tmp_transform;
/* Swap epoch + sequence_number */ /* Swap epoch + sequence_number */
memcpy( tmp_out_ctr, ssl->out_ctr, 8 ); memcpy( tmp_out_ctr, ssl->cur_out_ctr, 8 );
memcpy( ssl->out_ctr, ssl->handshake->alt_out_ctr, 8 ); memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, 8 );
memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 ); memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 );
/* Adjust to the newly activated transform */ /* Adjust to the newly activated transform */
@ -3210,6 +3210,7 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl )
mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
ssl->conf->transport, ssl->out_hdr + 1 ); ssl->conf->transport, ssl->out_hdr + 1 );
memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 );
ssl->out_len[0] = (unsigned char)( len >> 8 ); ssl->out_len[0] = (unsigned char)( len >> 8 );
ssl->out_len[1] = (unsigned char)( len ); ssl->out_len[1] = (unsigned char)( len );
@ -5671,14 +5672,14 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
/* Remember current epoch settings for resending */ /* Remember current epoch settings for resending */
ssl->handshake->alt_transform_out = ssl->transform_out; ssl->handshake->alt_transform_out = ssl->transform_out;
memcpy( ssl->handshake->alt_out_ctr, ssl->out_ctr, 8 ); memcpy( ssl->handshake->alt_out_ctr, ssl->cur_out_ctr, 8 );
/* Set sequence_number to zero */ /* Set sequence_number to zero */
memset( ssl->out_ctr + 2, 0, 6 ); memset( ssl->cur_out_ctr + 2, 0, 6 );
/* Increment epoch */ /* Increment epoch */
for( i = 2; i > 0; i-- ) for( i = 2; i > 0; i-- )
if( ++ssl->out_ctr[i - 1] != 0 ) if( ++ssl->cur_out_ctr[i - 1] != 0 )
break; break;
/* The loop goes to its end iff the counter is wrapping */ /* The loop goes to its end iff the counter is wrapping */
@ -5690,7 +5691,7 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
} }
else else
#endif /* MBEDTLS_SSL_PROTO_DTLS */ #endif /* MBEDTLS_SSL_PROTO_DTLS */
memset( ssl->out_ctr, 0, 8 ); memset( ssl->cur_out_ctr, 0, 8 );
ssl->transform_out = ssl->transform_negotiate; ssl->transform_out = ssl->transform_negotiate;
ssl->session_out = ssl->session_negotiate; ssl->session_out = ssl->session_negotiate;
@ -6166,6 +6167,8 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
ssl->split_done = 0; ssl->split_done = 0;
#endif #endif
memset( ssl->cur_out_ctr, 0, sizeof( ssl->cur_out_ctr ) );
ssl->transform_in = NULL; ssl->transform_in = NULL;
ssl->transform_out = NULL; ssl->transform_out = NULL;
@ -7381,7 +7384,7 @@ static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl )
in_ctr_cmp = memcmp( ssl->in_ctr + ep_len, in_ctr_cmp = memcmp( ssl->in_ctr + ep_len,
ssl->conf->renego_period + ep_len, 8 - ep_len ); ssl->conf->renego_period + ep_len, 8 - ep_len );
out_ctr_cmp = memcmp( ssl->out_ctr + ep_len, out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len,
ssl->conf->renego_period + ep_len, 8 - ep_len ); ssl->conf->renego_period + ep_len, 8 - ep_len );
if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 ) if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 )