1
0
mirror of https://github.com/Mbed-TLS/mbedtls.git synced 2025-07-29 11:41:15 +03:00

Merge 'mbedtls/development' into merge-crypto-unremoved-20200304

Merge the latest state of the target branch (mbedtls/development) into the
pull request to merge mbed-crypto into mbedtls.

Conflicts:

* ChangeLog: add/add conflict. Resolve by using the usual section order.
This commit is contained in:
Gilles Peskine
2020-03-23 18:02:07 +01:00
16 changed files with 717 additions and 63 deletions

View File

@ -245,6 +245,29 @@ int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst,
return( 0 );
}
#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
static int resize_buffer( unsigned char **buffer, size_t len_new, size_t *len_old )
{
unsigned char* resized_buffer = mbedtls_calloc( 1, len_new );
if( resized_buffer == NULL )
return -1;
/* We want to copy len_new bytes when downsizing the buffer, and
* len_old bytes when upsizing, so we choose the smaller of two sizes,
* to fit one buffer into another. Size checks, ensuring that no data is
* lost, are done outside of this function. */
memcpy( resized_buffer, *buffer,
( len_new < *len_old ) ? len_new : *len_old );
mbedtls_platform_zeroize( *buffer, *len_old );
mbedtls_free( *buffer );
*buffer = resized_buffer;
*len_old = len_new;
return 0;
}
#endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */
/*
* Key material generation
*/
@ -804,7 +827,7 @@ typedef int ssl_tls_prf_t(const unsigned char *, size_t, const char *,
* - [in] minor_ver: SSL/TLS minor version
* - [in] endpoint: client or server
* - [in] ssl: optionally used for:
* - MBEDTLS_SSL_HW_RECORD_ACCEL: whole context
* - MBEDTLS_SSL_HW_RECORD_ACCEL: whole context (non-const)
* - MBEDTLS_SSL_EXPORT_KEYS: ssl->conf->{f,p}_export_keys
* - MBEDTLS_DEBUG_C: ssl->conf->{f,p}_dbg
*/
@ -826,7 +849,10 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform,
const unsigned char randbytes[64],
int minor_ver,
unsigned endpoint,
const mbedtls_ssl_context *ssl )
#if !defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
const
#endif
mbedtls_ssl_context *ssl )
{
int ret = 0;
#if defined(MBEDTLS_USE_PSA_CRYPTO)
@ -3643,6 +3669,43 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl )
{
ssl->handshake = mbedtls_calloc( 1, sizeof(mbedtls_ssl_handshake_params) );
}
#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
/* If the buffers are too small - reallocate */
{
int modified = 0;
if( ssl->in_buf_len < MBEDTLS_SSL_IN_BUFFER_LEN )
{
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( 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 );
}
}
#endif
/* All pointers should exist and can be directly freed without issue */
if( ssl->handshake == NULL ||
@ -3729,6 +3792,8 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
const mbedtls_ssl_config *conf )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
ssl->conf = conf;
@ -3739,18 +3804,24 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
/* Set to NULL in case of an error condition */
ssl->out_buf = NULL;
ssl->in_buf = mbedtls_calloc( 1, MBEDTLS_SSL_IN_BUFFER_LEN );
#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
ssl->in_buf_len = in_buf_len;
#endif
ssl->in_buf = mbedtls_calloc( 1, in_buf_len );
if( ssl->in_buf == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_IN_BUFFER_LEN) );
MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", in_buf_len ) );
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
goto error;
}
ssl->out_buf = mbedtls_calloc( 1, MBEDTLS_SSL_OUT_BUFFER_LEN );
#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
ssl->out_buf_len = out_buf_len;
#endif
ssl->out_buf = mbedtls_calloc( 1, out_buf_len );
if( ssl->out_buf == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_OUT_BUFFER_LEN) );
MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", out_buf_len ) );
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
goto error;
}
@ -3768,6 +3839,10 @@ error:
ssl->conf = NULL;
#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
ssl->in_buf_len = 0;
ssl->out_buf_len = 0;
#endif
ssl->in_buf = NULL;
ssl->out_buf = NULL;
@ -3796,6 +3871,13 @@ error:
int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
{
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
size_t in_buf_len = ssl->in_buf_len;
size_t out_buf_len = ssl->out_buf_len;
#else
size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
#endif
#if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) || \
!defined(MBEDTLS_SSL_SRV_C)
@ -3851,14 +3933,14 @@ int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
ssl->session_in = NULL;
ssl->session_out = NULL;
memset( ssl->out_buf, 0, MBEDTLS_SSL_OUT_BUFFER_LEN );
memset( ssl->out_buf, 0, out_buf_len );
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
if( partial == 0 )
#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
{
ssl->in_left = 0;
memset( ssl->in_buf, 0, MBEDTLS_SSL_IN_BUFFER_LEN );
memset( ssl->in_buf, 0, in_buf_len );
}
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
@ -5799,6 +5881,60 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
mbedtls_platform_zeroize( handshake,
sizeof( mbedtls_ssl_handshake_params ) );
#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
/* If the buffers are too big - reallocate. Because of the way Mbed TLS
* processes datagrams and the fact that a datagram is allowed to have
* several records in it, it is possible that the I/O buffers are not
* empty at this stage */
{
int modified = 0;
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 )
{
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 )
{
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
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating out_buf to %d", buf_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
}
void mbedtls_ssl_session_free( mbedtls_ssl_session *session )
@ -6463,6 +6599,14 @@ int mbedtls_ssl_context_load( mbedtls_ssl_context *context,
*/
void mbedtls_ssl_free( mbedtls_ssl_context *ssl )
{
#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
size_t in_buf_len = ssl->in_buf_len;
size_t out_buf_len = ssl->out_buf_len;
#else
size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
#endif
if( ssl == NULL )
return;
@ -6470,14 +6614,16 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl )
if( ssl->out_buf != NULL )
{
mbedtls_platform_zeroize( ssl->out_buf, MBEDTLS_SSL_OUT_BUFFER_LEN );
mbedtls_platform_zeroize( ssl->out_buf, out_buf_len );
mbedtls_free( ssl->out_buf );
ssl->out_buf = NULL;
}
if( ssl->in_buf != NULL )
{
mbedtls_platform_zeroize( ssl->in_buf, MBEDTLS_SSL_IN_BUFFER_LEN );
mbedtls_platform_zeroize( ssl->in_buf, in_buf_len );
mbedtls_free( ssl->in_buf );
ssl->in_buf = NULL;
}
#if defined(MBEDTLS_ZLIB_SUPPORT)