Skip to content

Commit

Permalink
Merge remote-tracking branch 'restricted/pr/684' into mbedtls-2.22.0r0
Browse files Browse the repository at this point in the history
  • Loading branch information
yanesca committed Apr 14, 2020
2 parents 105c996 + e62bdef commit ac15f84
Show file tree
Hide file tree
Showing 11 changed files with 620 additions and 112 deletions.
9 changes: 9 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ mbed TLS ChangeLog (Sorted per branch, date)
New deprecations
* Deprecate MBEDTLS_SSL_HW_RECORD_ACCEL that enables function hooks in the
SSL module for hardware acceleration of individual records.
* Deprecate mbedtls_ssl_get_max_frag_len() in favour of
mbedtls_ssl_get_output_max_frag_len() and
mbedtls_ssl_get_input_max_frag_len() to be more precise about which max
fragment length is desired.

Security
* Fix issue in DTLS handling of new associations with the same parameters
Expand Down Expand Up @@ -37,6 +41,11 @@ Bugfix
Changes
* Mbed Crypto is no longer a Git submodule. The crypto part of the library
is back directly in the present repository.
* Split mbedtls_ssl_get_max_frag_len() into
mbedtls_ssl_get_output_max_frag_len() and
mbedtls_ssl_get_input_max_frag_len() to ensure that a sufficient input
buffer is allocated by the server (if MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
is defined), regardless of what MFL was configured for it.

= mbed TLS 2.21.0 branch released 2020-02-20

Expand Down
60 changes: 52 additions & 8 deletions include/mbedtls/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3523,18 +3523,61 @@ int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl );

#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
/**
* \brief Return the maximum fragment length (payload, in bytes).
* This is the value negotiated with peer if any,
* or the locally configured value.
* \brief Return the maximum fragment length (payload, in bytes) for
* the output buffer. For the client, this is the configured
* value. For the server, it is the minimum of two - the
* configured value and the negotiated one.
*
* \sa mbedtls_ssl_conf_max_frag_len()
* \sa mbedtls_ssl_get_max_record_payload()
*
* \param ssl SSL context
*
* \return Current maximum fragment length.
* \return Current maximum fragment length for the output buffer.
*/
size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl );
size_t mbedtls_ssl_get_output_max_frag_len( const mbedtls_ssl_context *ssl );

/**
* \brief Return the maximum fragment length (payload, in bytes) for
* the input buffer. This is the negotiated maximum fragment
* length, or, if there is none, MBEDTLS_SSL_MAX_CONTENT_LEN.
* If it is not defined either, the value is 2^14. This function
* works as its predecessor, \c mbedtls_ssl_get_max_frag_len().
*
* \sa mbedtls_ssl_conf_max_frag_len()
* \sa mbedtls_ssl_get_max_record_payload()
*
* \param ssl SSL context
*
* \return Current maximum fragment length for the output buffer.
*/
size_t mbedtls_ssl_get_input_max_frag_len( const mbedtls_ssl_context *ssl );

#if !defined(MBEDTLS_DEPRECATED_REMOVED)

#if defined(MBEDTLS_DEPRECATED_WARNING)
#define MBEDTLS_DEPRECATED __attribute__((deprecated))
#else
#define MBEDTLS_DEPRECATED
#endif

/**
* \brief This function is a deprecated approach to getting the max
* fragment length. Its an alias for
* \c mbedtls_ssl_get_output_max_frag_len(), as the behaviour
* is the same. See \c mbedtls_ssl_get_output_max_frag_len() for
* more detail.
*
* \sa mbedtls_ssl_get_input_max_frag_len()
* \sa mbedtls_ssl_get_output_max_frag_len()
*
* \param ssl SSL context
*
* \return Current maximum fragment length for the output buffer.
*/
MBEDTLS_DEPRECATED size_t mbedtls_ssl_get_max_frag_len(
const mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */

/**
Expand All @@ -3555,7 +3598,8 @@ size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl );
* when record compression is enabled.
*
* \sa mbedtls_ssl_set_mtu()
* \sa mbedtls_ssl_get_max_frag_len()
* \sa mbedtls_ssl_get_output_max_frag_len()
* \sa mbedtls_ssl_get_input_max_frag_len()
* \sa mbedtls_ssl_get_record_expansion()
*
* \param ssl SSL context
Expand Down Expand Up @@ -3863,8 +3907,8 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
* or negotiated with the peer), then:
* - with TLS, less bytes than requested are written.
* - with DTLS, MBEDTLS_ERR_SSL_BAD_INPUT_DATA is returned.
* \c mbedtls_ssl_get_max_frag_len() may be used to query the
* active maximum fragment length.
* \c mbedtls_ssl_get_output_max_frag_len() may be used to
* query the active maximum fragment length.
*
* \note Attempting to write 0 bytes will result in an empty TLS
* application record being sent.
Expand Down
8 changes: 4 additions & 4 deletions include/mbedtls/ssl_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,23 +260,23 @@
static inline uint32_t mbedtls_ssl_get_output_buflen( const mbedtls_ssl_context *ctx )
{
#if defined (MBEDTLS_SSL_DTLS_CONNECTION_ID)
return (uint32_t) mbedtls_ssl_get_max_frag_len( ctx )
return (uint32_t) mbedtls_ssl_get_output_max_frag_len( ctx )
+ MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD
+ MBEDTLS_SSL_CID_OUT_LEN_MAX;
#else
return (uint32_t) mbedtls_ssl_get_max_frag_len( ctx )
return (uint32_t) mbedtls_ssl_get_output_max_frag_len( ctx )
+ MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD;
#endif
}

static inline uint32_t mbedtls_ssl_get_input_buflen( const mbedtls_ssl_context *ctx )
{
#if defined (MBEDTLS_SSL_DTLS_CONNECTION_ID)
return (uint32_t) mbedtls_ssl_get_max_frag_len( ctx )
return (uint32_t) mbedtls_ssl_get_input_max_frag_len( ctx )
+ MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD
+ MBEDTLS_SSL_CID_IN_LEN_MAX;
#else
return (uint32_t) mbedtls_ssl_get_max_frag_len( ctx )
return (uint32_t) mbedtls_ssl_get_input_max_frag_len( ctx )
+ MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD;
#endif
}
Expand Down
2 changes: 1 addition & 1 deletion library/ssl_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl
size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;

#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl );
const size_t mfl = mbedtls_ssl_get_output_max_frag_len( ssl );

if( max_len > mfl )
max_len = mfl;
Expand Down
142 changes: 102 additions & 40 deletions library/ssl_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -3673,36 +3673,51 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl )
/* If the buffers are too small - reallocate */
{
int modified = 0;
if( ssl->in_buf_len < MBEDTLS_SSL_IN_BUFFER_LEN )
size_t written_in = 0;
size_t written_out = 0;
if( ssl->in_buf != NULL )
{
if( resize_buffer( &ssl->in_buf, MBEDTLS_SSL_IN_BUFFER_LEN,
&ssl->in_buf_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "input buffer resizing failed - out of memory" ) );
}
else
written_in = ssl->in_msg - ssl->in_buf;
if( ssl->in_buf_len < MBEDTLS_SSL_IN_BUFFER_LEN )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating in_buf to %d", MBEDTLS_SSL_IN_BUFFER_LEN ) );
modified = 1;
if( resize_buffer( &ssl->in_buf, MBEDTLS_SSL_IN_BUFFER_LEN,
&ssl->in_buf_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "input buffer resizing failed - out of memory" ) );
}
else
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating in_buf to %d", MBEDTLS_SSL_IN_BUFFER_LEN ) );
modified = 1;
}
}
}
if( ssl->out_buf_len < MBEDTLS_SSL_OUT_BUFFER_LEN )

if( ssl->out_buf != NULL )
{
if( resize_buffer( &ssl->out_buf, MBEDTLS_SSL_OUT_BUFFER_LEN,
&ssl->out_buf_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "output buffer resizing failed - out of memory" ) );
}
else
written_out = ssl->out_msg - ssl->out_buf;
if( ssl->out_buf_len < MBEDTLS_SSL_OUT_BUFFER_LEN )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating out_buf to %d", MBEDTLS_SSL_OUT_BUFFER_LEN ) );
modified = 1;
if( resize_buffer( &ssl->out_buf, MBEDTLS_SSL_OUT_BUFFER_LEN,
&ssl->out_buf_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "output buffer resizing failed - out of memory" ) );
}
else
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating out_buf to %d", MBEDTLS_SSL_OUT_BUFFER_LEN ) );
modified = 1;
}
}
}
if( modified )
{
/* Update pointers here to avoid doing it twice. */
mbedtls_ssl_reset_in_out_pointers( ssl );
/* Fields below might not be properly updated with record
* splitting, so they are manually updated here. */
ssl->out_msg = ssl->out_buf + written_out;
ssl->in_msg = ssl->in_buf + written_in;
}
}
#endif
Expand Down Expand Up @@ -4889,7 +4904,42 @@ const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl )
}

#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )
size_t mbedtls_ssl_get_input_max_frag_len( const mbedtls_ssl_context *ssl )
{
size_t max_len = MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t read_mfl;

/* Use the configured MFL for the client if we're past SERVER_HELLO_DONE */
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
ssl->state >= MBEDTLS_SSL_SERVER_HELLO_DONE )
{
return ssl_mfl_code_to_length( ssl->conf->mfl_code );
}

/* Check if a smaller max length was negotiated */
if( ssl->session_out != NULL )
{
read_mfl = ssl_mfl_code_to_length( ssl->session_out->mfl_code );
if( read_mfl < max_len )
{
max_len = read_mfl;
}
}

// During a handshake, use the value being negotiated
if( ssl->session_negotiate != NULL )
{
read_mfl = ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code );
if( read_mfl < max_len )
{
max_len = read_mfl;
}
}

return( max_len );
}

size_t mbedtls_ssl_get_output_max_frag_len( const mbedtls_ssl_context *ssl )
{
size_t max_len;

Expand All @@ -4914,6 +4964,13 @@ size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )

return( max_len );
}

#if !defined(MBEDTLS_DEPRECATED_REMOVED)
size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )
{
return mbedtls_ssl_get_output_max_frag_len( ssl );
}
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */

#if defined(MBEDTLS_SSL_PROTO_DTLS)
Expand Down Expand Up @@ -4946,7 +5003,7 @@ int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl )
#endif

#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl );
const size_t mfl = mbedtls_ssl_get_output_max_frag_len( ssl );

if( max_len > mfl )
max_len = mfl;
Expand Down Expand Up @@ -5892,36 +5949,41 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
uint32_t buf_len = mbedtls_ssl_get_input_buflen( ssl );
size_t written_in = 0;
size_t written_out = 0;
if( ssl->in_buf != NULL &&
ssl->in_buf_len > buf_len &&
ssl->in_left < buf_len )
if( ssl->in_buf != NULL )
{
written_in = ssl->in_msg - ssl->in_buf;
if( resize_buffer( &ssl->in_buf, buf_len, &ssl->in_buf_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "input buffer resizing failed - out of memory" ) );
}
else
if( ssl->in_buf_len > buf_len && ssl->in_left < buf_len )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating in_buf to %d", buf_len ) );
modified = 1;
written_in = ssl->in_msg - ssl->in_buf;
if( resize_buffer( &ssl->in_buf, buf_len, &ssl->in_buf_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "input buffer resizing failed - out of memory" ) );
}
else
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating in_buf to %d", buf_len ) );
modified = 1;
}
}
}


buf_len = mbedtls_ssl_get_output_buflen( ssl );
if( ssl->out_buf != NULL &&
ssl->out_buf_len > mbedtls_ssl_get_output_buflen( ssl ) &&
ssl->out_left < buf_len )
if(ssl->out_buf != NULL )
{
written_out = ssl->out_msg - ssl->out_buf;
if( resize_buffer( &ssl->out_buf, buf_len, &ssl->out_buf_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "output buffer resizing failed - out of memory" ) );
}
else
if( ssl->out_buf_len > mbedtls_ssl_get_output_buflen( ssl ) &&
ssl->out_left < buf_len )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating out_buf to %d", buf_len ) );
modified = 1;
if( resize_buffer( &ssl->out_buf, buf_len, &ssl->out_buf_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "output buffer resizing failed - out of memory" ) );
}
else
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating out_buf to %d", buf_len ) );
modified = 1;
}
}
}
if( modified )
Expand Down
6 changes: 4 additions & 2 deletions programs/ssl/ssl_client2.c
Original file line number Diff line number Diff line change
Expand Up @@ -2553,8 +2553,10 @@ int main( int argc, char *argv[] )
mbedtls_printf( " [ Record expansion is unknown (compression) ]\n" );

#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
mbedtls_printf( " [ Maximum fragment length is %u ]\n",
(unsigned int) mbedtls_ssl_get_max_frag_len( &ssl ) );
mbedtls_printf( " [ Maximum input fragment length is %u ]\n",
(unsigned int) mbedtls_ssl_get_input_max_frag_len( &ssl ) );
mbedtls_printf( " [ Maximum output fragment length is %u ]\n",
(unsigned int) mbedtls_ssl_get_output_max_frag_len( &ssl ) );
#endif

#if defined(MBEDTLS_SSL_ALPN)
Expand Down
6 changes: 4 additions & 2 deletions programs/ssl/ssl_server2.c
Original file line number Diff line number Diff line change
Expand Up @@ -3633,8 +3633,10 @@ int main( int argc, char *argv[] )
mbedtls_printf( " [ Record expansion is unknown (compression) ]\n" );

#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
mbedtls_printf( " [ Maximum fragment length is %u ]\n",
(unsigned int) mbedtls_ssl_get_max_frag_len( &ssl ) );
mbedtls_printf( " [ Maximum input fragment length is %u ]\n",
(unsigned int) mbedtls_ssl_get_input_max_frag_len( &ssl ) );
mbedtls_printf( " [ Maximum output fragment length is %u ]\n",
(unsigned int) mbedtls_ssl_get_output_max_frag_len( &ssl ) );
#endif

#if defined(MBEDTLS_SSL_ALPN)
Expand Down
Loading

0 comments on commit ac15f84

Please sign in to comment.