|
@@ -501,6 +501,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
|
|
unsigned char *key2;
|
|
unsigned char *key2;
|
|
unsigned char *mac_enc;
|
|
unsigned char *mac_enc;
|
|
unsigned char *mac_dec;
|
|
unsigned char *mac_dec;
|
|
|
|
+ size_t mac_key_len;
|
|
size_t iv_copy_len;
|
|
size_t iv_copy_len;
|
|
const mbedtls_cipher_info_t *cipher_info;
|
|
const mbedtls_cipher_info_t *cipher_info;
|
|
const mbedtls_md_info_t *md_info;
|
|
const mbedtls_md_info_t *md_info;
|
|
@@ -692,6 +693,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
|
|
cipher_info->mode == MBEDTLS_MODE_CCM )
|
|
cipher_info->mode == MBEDTLS_MODE_CCM )
|
|
{
|
|
{
|
|
transform->maclen = 0;
|
|
transform->maclen = 0;
|
|
|
|
+ mac_key_len = 0;
|
|
|
|
|
|
transform->ivlen = 12;
|
|
transform->ivlen = 12;
|
|
transform->fixed_ivlen = 4;
|
|
transform->fixed_ivlen = 4;
|
|
@@ -712,7 +714,8 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
|
|
}
|
|
}
|
|
|
|
|
|
/* Get MAC length */
|
|
/* Get MAC length */
|
|
- transform->maclen = mbedtls_md_get_size( md_info );
|
|
|
|
|
|
+ mac_key_len = mbedtls_md_get_size( md_info );
|
|
|
|
+ transform->maclen = mac_key_len;
|
|
|
|
|
|
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
|
|
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
|
|
/*
|
|
/*
|
|
@@ -721,7 +724,16 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
|
|
* so we only need to adjust the length here.
|
|
* so we only need to adjust the length here.
|
|
*/
|
|
*/
|
|
if( session->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED )
|
|
if( session->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED )
|
|
|
|
+ {
|
|
transform->maclen = MBEDTLS_SSL_TRUNCATED_HMAC_LEN;
|
|
transform->maclen = MBEDTLS_SSL_TRUNCATED_HMAC_LEN;
|
|
|
|
+
|
|
|
|
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT)
|
|
|
|
+ /* Fall back to old, non-compliant version of the truncated
|
|
|
|
+ * HMAC implementation which also truncates the key
|
|
|
|
+ * (Mbed TLS versions from 1.3 to 2.6.0) */
|
|
|
|
+ mac_key_len = transform->maclen;
|
|
|
|
+#endif
|
|
|
|
+ }
|
|
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
|
|
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
|
|
|
|
|
|
/* IV length */
|
|
/* IV length */
|
|
@@ -783,11 +795,11 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
|
|
#if defined(MBEDTLS_SSL_CLI_C)
|
|
#if defined(MBEDTLS_SSL_CLI_C)
|
|
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
|
|
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
|
|
{
|
|
{
|
|
- key1 = keyblk + transform->maclen * 2;
|
|
|
|
- key2 = keyblk + transform->maclen * 2 + transform->keylen;
|
|
|
|
|
|
+ key1 = keyblk + mac_key_len * 2;
|
|
|
|
+ key2 = keyblk + mac_key_len * 2 + transform->keylen;
|
|
|
|
|
|
mac_enc = keyblk;
|
|
mac_enc = keyblk;
|
|
- mac_dec = keyblk + transform->maclen;
|
|
|
|
|
|
+ mac_dec = keyblk + mac_key_len;
|
|
|
|
|
|
/*
|
|
/*
|
|
* This is not used in TLS v1.1.
|
|
* This is not used in TLS v1.1.
|
|
@@ -803,10 +815,10 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
|
|
#if defined(MBEDTLS_SSL_SRV_C)
|
|
#if defined(MBEDTLS_SSL_SRV_C)
|
|
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
|
|
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
|
|
{
|
|
{
|
|
- key1 = keyblk + transform->maclen * 2 + transform->keylen;
|
|
|
|
- key2 = keyblk + transform->maclen * 2;
|
|
|
|
|
|
+ key1 = keyblk + mac_key_len * 2 + transform->keylen;
|
|
|
|
+ key2 = keyblk + mac_key_len * 2;
|
|
|
|
|
|
- mac_enc = keyblk + transform->maclen;
|
|
|
|
|
|
+ mac_enc = keyblk + mac_key_len;
|
|
mac_dec = keyblk;
|
|
mac_dec = keyblk;
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -828,14 +840,14 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
|
|
#if defined(MBEDTLS_SSL_PROTO_SSL3)
|
|
#if defined(MBEDTLS_SSL_PROTO_SSL3)
|
|
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
|
|
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
|
|
{
|
|
{
|
|
- if( transform->maclen > sizeof transform->mac_enc )
|
|
|
|
|
|
+ if( mac_key_len > sizeof transform->mac_enc )
|
|
{
|
|
{
|
|
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
|
|
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
|
|
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
|
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
|
}
|
|
}
|
|
|
|
|
|
- memcpy( transform->mac_enc, mac_enc, transform->maclen );
|
|
|
|
- memcpy( transform->mac_dec, mac_dec, transform->maclen );
|
|
|
|
|
|
+ memcpy( transform->mac_enc, mac_enc, mac_key_len );
|
|
|
|
+ memcpy( transform->mac_dec, mac_dec, mac_key_len );
|
|
}
|
|
}
|
|
else
|
|
else
|
|
#endif /* MBEDTLS_SSL_PROTO_SSL3 */
|
|
#endif /* MBEDTLS_SSL_PROTO_SSL3 */
|
|
@@ -843,8 +855,13 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
|
|
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
|
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
|
if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
|
|
if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
|
|
{
|
|
{
|
|
- mbedtls_md_hmac_starts( &transform->md_ctx_enc, mac_enc, transform->maclen );
|
|
|
|
- mbedtls_md_hmac_starts( &transform->md_ctx_dec, mac_dec, transform->maclen );
|
|
|
|
|
|
+ /* For HMAC-based ciphersuites, initialize the HMAC transforms.
|
|
|
|
+ For AEAD-based ciphersuites, there is nothing to do here. */
|
|
|
|
+ if( mac_key_len != 0 )
|
|
|
|
+ {
|
|
|
|
+ mbedtls_md_hmac_starts( &transform->md_ctx_enc, mac_enc, mac_key_len );
|
|
|
|
+ mbedtls_md_hmac_starts( &transform->md_ctx_dec, mac_dec, mac_key_len );
|
|
|
|
+ }
|
|
}
|
|
}
|
|
else
|
|
else
|
|
#endif
|
|
#endif
|
|
@@ -864,7 +881,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
|
|
transform->iv_enc, transform->iv_dec,
|
|
transform->iv_enc, transform->iv_dec,
|
|
iv_copy_len,
|
|
iv_copy_len,
|
|
mac_enc, mac_dec,
|
|
mac_enc, mac_dec,
|
|
- transform->maclen ) ) != 0 )
|
|
|
|
|
|
+ mac_key_len ) ) != 0 )
|
|
{
|
|
{
|
|
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_init", ret );
|
|
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_init", ret );
|
|
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
|
|
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
|
|
@@ -877,7 +894,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
|
|
{
|
|
{
|
|
ssl->conf->f_export_keys( ssl->conf->p_export_keys,
|
|
ssl->conf->f_export_keys( ssl->conf->p_export_keys,
|
|
session->master, keyblk,
|
|
session->master, keyblk,
|
|
- transform->maclen, transform->keylen,
|
|
|
|
|
|
+ mac_key_len, transform->keylen,
|
|
iv_copy_len );
|
|
iv_copy_len );
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
@@ -1136,6 +1153,9 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
|
|
* other_secret already set by the ClientKeyExchange message,
|
|
* other_secret already set by the ClientKeyExchange message,
|
|
* and is 48 bytes long
|
|
* and is 48 bytes long
|
|
*/
|
|
*/
|
|
|
|
+ if( end - p < 2 )
|
|
|
|
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
|
|
|
+
|
|
*p++ = 0;
|
|
*p++ = 0;
|
|
*p++ = 48;
|
|
*p++ = 48;
|
|
p += 48;
|
|
p += 48;
|
|
@@ -1261,6 +1281,27 @@ static void ssl_mac( mbedtls_md_context_t *md_ctx,
|
|
#define SSL_SOME_MODES_USE_MAC
|
|
#define SSL_SOME_MODES_USE_MAC
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+/* The function below is only used in the Lucky 13 counter-measure in
|
|
|
|
+ * ssl_decrypt_buf(). These are the defines that guard the call site. */
|
|
|
|
+#if defined(SSL_SOME_MODES_USE_MAC) && \
|
|
|
|
+ ( defined(MBEDTLS_SSL_PROTO_TLS1) || \
|
|
|
|
+ defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
|
|
|
|
+ defined(MBEDTLS_SSL_PROTO_TLS1_2) )
|
|
|
|
+/* This function makes sure every byte in the memory region is accessed
|
|
|
|
+ * (in ascending addresses order) */
|
|
|
|
+static void ssl_read_memory( unsigned char *p, size_t len )
|
|
|
|
+{
|
|
|
|
+ unsigned char acc = 0;
|
|
|
|
+ volatile unsigned char force;
|
|
|
|
+
|
|
|
|
+ for( ; len != 0; p++, len-- )
|
|
|
|
+ acc ^= *p;
|
|
|
|
+
|
|
|
|
+ force = acc;
|
|
|
|
+ (void) force;
|
|
|
|
+}
|
|
|
|
+#endif /* SSL_SOME_MODES_USE_MAC && ( TLS1 || TLS1_1 || TLS1_2 ) */
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Encryption/decryption functions
|
|
* Encryption/decryption functions
|
|
*/
|
|
*/
|
|
@@ -1541,6 +1582,8 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
|
|
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
|
|
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
|
|
if( auth_done == 0 )
|
|
if( auth_done == 0 )
|
|
{
|
|
{
|
|
|
|
+ unsigned char mac[MBEDTLS_SSL_MAC_ADD];
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* MAC(MAC_write_key, seq_num +
|
|
* MAC(MAC_write_key, seq_num +
|
|
* TLSCipherText.type +
|
|
* TLSCipherText.type +
|
|
@@ -1563,10 +1606,12 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
|
|
mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, pseudo_hdr, 13 );
|
|
mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, pseudo_hdr, 13 );
|
|
mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc,
|
|
mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc,
|
|
ssl->out_iv, ssl->out_msglen );
|
|
ssl->out_iv, ssl->out_msglen );
|
|
- mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc,
|
|
|
|
- ssl->out_iv + ssl->out_msglen );
|
|
|
|
|
|
+ mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, mac );
|
|
mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc );
|
|
mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc );
|
|
|
|
|
|
|
|
+ memcpy( ssl->out_iv + ssl->out_msglen, mac,
|
|
|
|
+ ssl->transform_out->maclen );
|
|
|
|
+
|
|
ssl->out_msglen += ssl->transform_out->maclen;
|
|
ssl->out_msglen += ssl->transform_out->maclen;
|
|
auth_done++;
|
|
auth_done++;
|
|
}
|
|
}
|
|
@@ -1885,27 +1930,27 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
|
|
* and fake check up to 256 bytes of padding
|
|
* and fake check up to 256 bytes of padding
|
|
*/
|
|
*/
|
|
size_t pad_count = 0, real_count = 1;
|
|
size_t pad_count = 0, real_count = 1;
|
|
- size_t padding_idx = ssl->in_msglen - padlen - 1;
|
|
|
|
|
|
+ size_t padding_idx = ssl->in_msglen - padlen;
|
|
|
|
|
|
/*
|
|
/*
|
|
* Padding is guaranteed to be incorrect if:
|
|
* Padding is guaranteed to be incorrect if:
|
|
- * 1. padlen >= ssl->in_msglen
|
|
|
|
|
|
+ * 1. padlen > ssl->in_msglen
|
|
*
|
|
*
|
|
- * 2. padding_idx >= MBEDTLS_SSL_MAX_CONTENT_LEN +
|
|
|
|
|
|
+ * 2. padding_idx > MBEDTLS_SSL_MAX_CONTENT_LEN +
|
|
* ssl->transform_in->maclen
|
|
* ssl->transform_in->maclen
|
|
*
|
|
*
|
|
* In both cases we reset padding_idx to a safe value (0) to
|
|
* In both cases we reset padding_idx to a safe value (0) to
|
|
* prevent out-of-buffer reads.
|
|
* prevent out-of-buffer reads.
|
|
*/
|
|
*/
|
|
- correct &= ( ssl->in_msglen >= padlen + 1 );
|
|
|
|
- correct &= ( padding_idx < MBEDTLS_SSL_MAX_CONTENT_LEN +
|
|
|
|
|
|
+ correct &= ( padlen <= ssl->in_msglen );
|
|
|
|
+ correct &= ( padding_idx <= MBEDTLS_SSL_MAX_CONTENT_LEN +
|
|
ssl->transform_in->maclen );
|
|
ssl->transform_in->maclen );
|
|
|
|
|
|
padding_idx *= correct;
|
|
padding_idx *= correct;
|
|
|
|
|
|
- for( i = 1; i <= 256; i++ )
|
|
|
|
|
|
+ for( i = 0; i < 256; i++ )
|
|
{
|
|
{
|
|
- real_count &= ( i <= padlen );
|
|
|
|
|
|
+ real_count &= ( i < padlen );
|
|
pad_count += real_count *
|
|
pad_count += real_count *
|
|
( ssl->in_msg[padding_idx + i] == padlen - 1 );
|
|
( ssl->in_msg[padding_idx + i] == padlen - 1 );
|
|
}
|
|
}
|
|
@@ -1936,8 +1981,10 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
|
|
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
|
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
|
|
MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption",
|
|
MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption",
|
|
ssl->in_msg, ssl->in_msglen );
|
|
ssl->in_msg, ssl->in_msglen );
|
|
|
|
+#endif
|
|
|
|
|
|
/*
|
|
/*
|
|
* Authenticate if not done yet.
|
|
* Authenticate if not done yet.
|
|
@@ -1970,20 +2017,69 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
|
|
{
|
|
{
|
|
/*
|
|
/*
|
|
* Process MAC and always update for padlen afterwards to make
|
|
* Process MAC and always update for padlen afterwards to make
|
|
- * total time independent of padlen
|
|
|
|
- *
|
|
|
|
- * extra_run compensates MAC check for padlen
|
|
|
|
|
|
+ * total time independent of padlen.
|
|
*
|
|
*
|
|
* Known timing attacks:
|
|
* Known timing attacks:
|
|
* - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf)
|
|
* - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf)
|
|
*
|
|
*
|
|
- * We use ( ( Lx + 8 ) / 64 ) to handle 'negative Lx' values
|
|
|
|
- * correctly. (We round down instead of up, so -56 is the correct
|
|
|
|
- * value for our calculations instead of -55)
|
|
|
|
|
|
+ * To compensate for different timings for the MAC calculation
|
|
|
|
+ * depending on how much padding was removed (which is determined
|
|
|
|
+ * by padlen), process extra_run more blocks through the hash
|
|
|
|
+ * function.
|
|
|
|
+ *
|
|
|
|
+ * The formula in the paper is
|
|
|
|
+ * extra_run = ceil( (L1-55) / 64 ) - ceil( (L2-55) / 64 )
|
|
|
|
+ * where L1 is the size of the header plus the decrypted message
|
|
|
|
+ * plus CBC padding and L2 is the size of the header plus the
|
|
|
|
+ * decrypted message. This is for an underlying hash function
|
|
|
|
+ * with 64-byte blocks.
|
|
|
|
+ * We use ( (Lx+8) / 64 ) to handle 'negative Lx' values
|
|
|
|
+ * correctly. We round down instead of up, so -56 is the correct
|
|
|
|
+ * value for our calculations instead of -55.
|
|
|
|
+ *
|
|
|
|
+ * Repeat the formula rather than defining a block_size variable.
|
|
|
|
+ * This avoids requiring division by a variable at runtime
|
|
|
|
+ * (which would be marginally less efficient and would require
|
|
|
|
+ * linking an extra division function in some builds).
|
|
*/
|
|
*/
|
|
size_t j, extra_run = 0;
|
|
size_t j, extra_run = 0;
|
|
- extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 -
|
|
|
|
- ( 13 + ssl->in_msglen + 8 ) / 64;
|
|
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * The next two sizes are the minimum and maximum values of
|
|
|
|
+ * in_msglen over all padlen values.
|
|
|
|
+ *
|
|
|
|
+ * They're independent of padlen, since we previously did
|
|
|
|
+ * in_msglen -= padlen.
|
|
|
|
+ *
|
|
|
|
+ * Note that max_len + maclen is never more than the buffer
|
|
|
|
+ * length, as we previously did in_msglen -= maclen too.
|
|
|
|
+ */
|
|
|
|
+ const size_t max_len = ssl->in_msglen + padlen;
|
|
|
|
+ const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0;
|
|
|
|
+
|
|
|
|
+ switch( ssl->transform_in->ciphersuite_info->mac )
|
|
|
|
+ {
|
|
|
|
+#if defined(MBEDTLS_MD5_C) || defined(MBEDTLS_SHA1_C) || \
|
|
|
|
+ defined(MBEDTLS_SHA256_C)
|
|
|
|
+ case MBEDTLS_MD_MD5:
|
|
|
|
+ case MBEDTLS_MD_SHA1:
|
|
|
|
+ case MBEDTLS_MD_SHA256:
|
|
|
|
+ /* 8 bytes of message size, 64-byte compression blocks */
|
|
|
|
+ extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 -
|
|
|
|
+ ( 13 + ssl->in_msglen + 8 ) / 64;
|
|
|
|
+ break;
|
|
|
|
+#endif
|
|
|
|
+#if defined(MBEDTLS_SHA512_C)
|
|
|
|
+ case MBEDTLS_MD_SHA384:
|
|
|
|
+ /* 16 bytes of message size, 128-byte compression blocks */
|
|
|
|
+ extra_run = ( 13 + ssl->in_msglen + padlen + 16 ) / 128 -
|
|
|
|
+ ( 13 + ssl->in_msglen + 16 ) / 128;
|
|
|
|
+ break;
|
|
|
|
+#endif
|
|
|
|
+ default:
|
|
|
|
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
|
|
|
|
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
|
|
|
+ }
|
|
|
|
|
|
extra_run &= correct * 0xFF;
|
|
extra_run &= correct * 0xFF;
|
|
|
|
|
|
@@ -1992,12 +2088,25 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
|
|
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_len, 2 );
|
|
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_len, 2 );
|
|
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg,
|
|
mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg,
|
|
ssl->in_msglen );
|
|
ssl->in_msglen );
|
|
|
|
+ /* Make sure we access everything even when padlen > 0. This
|
|
|
|
+ * makes the synchronisation requirements for just-in-time
|
|
|
|
+ * Prime+Probe attacks much tighter and hopefully impractical. */
|
|
|
|
+ ssl_read_memory( ssl->in_msg + ssl->in_msglen, padlen );
|
|
mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect );
|
|
mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect );
|
|
- /* Call mbedtls_md_process at least once due to cache attacks */
|
|
|
|
|
|
+
|
|
|
|
+ /* Call mbedtls_md_process at least once due to cache attacks
|
|
|
|
+ * that observe whether md_process() was called of not */
|
|
for( j = 0; j < extra_run + 1; j++ )
|
|
for( j = 0; j < extra_run + 1; j++ )
|
|
mbedtls_md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg );
|
|
mbedtls_md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg );
|
|
|
|
|
|
mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec );
|
|
mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec );
|
|
|
|
+
|
|
|
|
+ /* Make sure we access all the memory that could contain the MAC,
|
|
|
|
+ * before we check it in the next code block. This makes the
|
|
|
|
+ * synchronisation requirements for just-in-time Prime+Probe
|
|
|
|
+ * attacks much tighter and hopefully impractical. */
|
|
|
|
+ ssl_read_memory( ssl->in_msg + min_len,
|
|
|
|
+ max_len - min_len + ssl->transform_in->maclen );
|
|
}
|
|
}
|
|
else
|
|
else
|
|
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
|
|
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
|
|
@@ -2007,9 +2116,11 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
|
|
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
|
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
|
|
MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, ssl->transform_in->maclen );
|
|
MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, ssl->transform_in->maclen );
|
|
MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_msg + ssl->in_msglen,
|
|
MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_msg + ssl->in_msglen,
|
|
ssl->transform_in->maclen );
|
|
ssl->transform_in->maclen );
|
|
|
|
+#endif
|
|
|
|
|
|
if( mbedtls_ssl_safer_memcmp( ssl->in_msg + ssl->in_msglen, mac_expect,
|
|
if( mbedtls_ssl_safer_memcmp( ssl->in_msg + ssl->in_msglen, mac_expect,
|
|
ssl->transform_in->maclen ) != 0 )
|
|
ssl->transform_in->maclen ) != 0 )
|
|
@@ -2020,13 +2131,13 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
|
|
correct = 0;
|
|
correct = 0;
|
|
}
|
|
}
|
|
auth_done++;
|
|
auth_done++;
|
|
-
|
|
|
|
- /*
|
|
|
|
- * Finally check the correct flag
|
|
|
|
- */
|
|
|
|
- if( correct == 0 )
|
|
|
|
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
|
|
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Finally check the correct flag
|
|
|
|
+ */
|
|
|
|
+ if( correct == 0 )
|
|
|
|
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
|
|
#endif /* SSL_SOME_MODES_USE_MAC */
|
|
#endif /* SSL_SOME_MODES_USE_MAC */
|
|
|
|
|
|
/* Make extra sure authentication was performed, exactly once */
|
|
/* Make extra sure authentication was performed, exactly once */
|
|
@@ -2038,6 +2149,16 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
|
|
|
|
|
|
if( ssl->in_msglen == 0 )
|
|
if( ssl->in_msglen == 0 )
|
|
{
|
|
{
|
|
|
|
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
|
|
|
+ if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3
|
|
|
|
+ && ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
|
|
|
|
+ {
|
|
|
|
+ /* TLS v1.2 explicitly disallows zero-length messages which are not application data */
|
|
|
|
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid zero-length message type: %d", ssl->in_msgtype ) );
|
|
|
|
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
|
|
|
|
+ }
|
|
|
|
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
|
|
|
+
|
|
ssl->nb_zero++;
|
|
ssl->nb_zero++;
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -2091,6 +2212,7 @@ static int ssl_compress_buf( mbedtls_ssl_context *ssl )
|
|
{
|
|
{
|
|
int ret;
|
|
int ret;
|
|
unsigned char *msg_post = ssl->out_msg;
|
|
unsigned char *msg_post = ssl->out_msg;
|
|
|
|
+ ptrdiff_t bytes_written = ssl->out_msg - ssl->out_buf;
|
|
size_t len_pre = ssl->out_msglen;
|
|
size_t len_pre = ssl->out_msglen;
|
|
unsigned char *msg_pre = ssl->compress_buf;
|
|
unsigned char *msg_pre = ssl->compress_buf;
|
|
|
|
|
|
@@ -2110,7 +2232,7 @@ static int ssl_compress_buf( mbedtls_ssl_context *ssl )
|
|
ssl->transform_out->ctx_deflate.next_in = msg_pre;
|
|
ssl->transform_out->ctx_deflate.next_in = msg_pre;
|
|
ssl->transform_out->ctx_deflate.avail_in = len_pre;
|
|
ssl->transform_out->ctx_deflate.avail_in = len_pre;
|
|
ssl->transform_out->ctx_deflate.next_out = msg_post;
|
|
ssl->transform_out->ctx_deflate.next_out = msg_post;
|
|
- ssl->transform_out->ctx_deflate.avail_out = MBEDTLS_SSL_BUFFER_LEN;
|
|
|
|
|
|
+ ssl->transform_out->ctx_deflate.avail_out = MBEDTLS_SSL_BUFFER_LEN - bytes_written;
|
|
|
|
|
|
ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH );
|
|
ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH );
|
|
if( ret != Z_OK )
|
|
if( ret != Z_OK )
|
|
@@ -2120,7 +2242,7 @@ static int ssl_compress_buf( mbedtls_ssl_context *ssl )
|
|
}
|
|
}
|
|
|
|
|
|
ssl->out_msglen = MBEDTLS_SSL_BUFFER_LEN -
|
|
ssl->out_msglen = MBEDTLS_SSL_BUFFER_LEN -
|
|
- ssl->transform_out->ctx_deflate.avail_out;
|
|
|
|
|
|
+ ssl->transform_out->ctx_deflate.avail_out - bytes_written;
|
|
|
|
|
|
MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ",
|
|
MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ",
|
|
ssl->out_msglen ) );
|
|
ssl->out_msglen ) );
|
|
@@ -2137,6 +2259,7 @@ static int ssl_decompress_buf( mbedtls_ssl_context *ssl )
|
|
{
|
|
{
|
|
int ret;
|
|
int ret;
|
|
unsigned char *msg_post = ssl->in_msg;
|
|
unsigned char *msg_post = ssl->in_msg;
|
|
|
|
+ ptrdiff_t header_bytes = ssl->in_msg - ssl->in_buf;
|
|
size_t len_pre = ssl->in_msglen;
|
|
size_t len_pre = ssl->in_msglen;
|
|
unsigned char *msg_pre = ssl->compress_buf;
|
|
unsigned char *msg_pre = ssl->compress_buf;
|
|
|
|
|
|
@@ -2156,7 +2279,8 @@ static int ssl_decompress_buf( mbedtls_ssl_context *ssl )
|
|
ssl->transform_in->ctx_inflate.next_in = msg_pre;
|
|
ssl->transform_in->ctx_inflate.next_in = msg_pre;
|
|
ssl->transform_in->ctx_inflate.avail_in = len_pre;
|
|
ssl->transform_in->ctx_inflate.avail_in = len_pre;
|
|
ssl->transform_in->ctx_inflate.next_out = msg_post;
|
|
ssl->transform_in->ctx_inflate.next_out = msg_post;
|
|
- ssl->transform_in->ctx_inflate.avail_out = MBEDTLS_SSL_MAX_CONTENT_LEN;
|
|
|
|
|
|
+ ssl->transform_in->ctx_inflate.avail_out = MBEDTLS_SSL_BUFFER_LEN -
|
|
|
|
+ header_bytes;
|
|
|
|
|
|
ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH );
|
|
ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH );
|
|
if( ret != Z_OK )
|
|
if( ret != Z_OK )
|
|
@@ -2165,8 +2289,8 @@ static int ssl_decompress_buf( mbedtls_ssl_context *ssl )
|
|
return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
|
|
return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
|
|
}
|
|
}
|
|
|
|
|
|
- ssl->in_msglen = MBEDTLS_SSL_MAX_CONTENT_LEN -
|
|
|
|
- ssl->transform_in->ctx_inflate.avail_out;
|
|
|
|
|
|
+ ssl->in_msglen = MBEDTLS_SSL_BUFFER_LEN -
|
|
|
|
+ ssl->transform_in->ctx_inflate.avail_out - header_bytes;
|
|
|
|
|
|
MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ",
|
|
MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ",
|
|
ssl->in_msglen ) );
|
|
ssl->in_msglen ) );
|
|
@@ -2422,6 +2546,14 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
|
|
if( ret < 0 )
|
|
if( ret < 0 )
|
|
return( ret );
|
|
return( ret );
|
|
|
|
|
|
|
|
+ if ( (size_t)ret > len || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) )
|
|
|
|
+ {
|
|
|
|
+ MBEDTLS_SSL_DEBUG_MSG( 1,
|
|
|
|
+ ( "f_recv returned %d bytes but only %lu were requested",
|
|
|
|
+ ret, (unsigned long)len ) );
|
|
|
|
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
|
|
|
+ }
|
|
|
|
+
|
|
ssl->in_left += ret;
|
|
ssl->in_left += ret;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -2469,6 +2601,14 @@ int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
|
|
if( ret <= 0 )
|
|
if( ret <= 0 )
|
|
return( ret );
|
|
return( ret );
|
|
|
|
|
|
|
|
+ if( (size_t)ret > ssl->out_left || ( INT_MAX > SIZE_MAX && ret > SIZE_MAX ) )
|
|
|
|
+ {
|
|
|
|
+ MBEDTLS_SSL_DEBUG_MSG( 1,
|
|
|
|
+ ( "f_send returned %d bytes but only %lu bytes were sent",
|
|
|
|
+ ret, (unsigned long)ssl->out_left ) );
|
|
|
|
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
|
|
|
+ }
|
|
|
|
+
|
|
ssl->out_left -= ret;
|
|
ssl->out_left -= ret;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3095,6 +3235,7 @@ static int ssl_reassemble_dtls_handshake( mbedtls_ssl_context *ssl )
|
|
|
|
|
|
memcpy( ssl->in_msg, ssl->handshake->hs_msg, ssl->in_hslen );
|
|
memcpy( ssl->in_msg, ssl->handshake->hs_msg, ssl->in_hslen );
|
|
|
|
|
|
|
|
+ mbedtls_zeroize( ssl->handshake->hs_msg, ssl->in_hslen );
|
|
mbedtls_free( ssl->handshake->hs_msg );
|
|
mbedtls_free( ssl->handshake->hs_msg );
|
|
ssl->handshake->hs_msg = NULL;
|
|
ssl->handshake->hs_msg = NULL;
|
|
|
|
|
|
@@ -4091,6 +4232,16 @@ int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl )
|
|
|
|
|
|
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
|
|
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
|
|
{
|
|
{
|
|
|
|
+ if( ssl->in_msglen != 2 )
|
|
|
|
+ {
|
|
|
|
+ /* Note: Standard allows for more than one 2 byte alert
|
|
|
|
+ to be packed in a single message, but Mbed TLS doesn't
|
|
|
|
+ currently support this. */
|
|
|
|
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid alert message, len: %d",
|
|
|
|
+ ssl->in_msglen ) );
|
|
|
|
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
|
|
|
|
+ }
|
|
|
|
+
|
|
MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%d:%d]",
|
|
MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%d:%d]",
|
|
ssl->in_msg[0], ssl->in_msg[1] ) );
|
|
ssl->in_msg[0], ssl->in_msg[1] ) );
|
|
|
|
|
|
@@ -4514,6 +4665,12 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
|
|
|
|
|
|
while( i < ssl->in_hslen )
|
|
while( i < ssl->in_hslen )
|
|
{
|
|
{
|
|
|
|
+ if ( i + 3 > ssl->in_hslen ) {
|
|
|
|
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
|
|
|
|
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
|
|
|
|
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
|
|
|
|
+ return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
|
|
|
|
+ }
|
|
if( ssl->in_msg[i] != 0 )
|
|
if( ssl->in_msg[i] != 0 )
|
|
{
|
|
{
|
|
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
|
|
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
|
|
@@ -5655,13 +5812,14 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
|
|
/*
|
|
/*
|
|
* Prepare base structures
|
|
* Prepare base structures
|
|
*/
|
|
*/
|
|
|
|
+ ssl->in_buf = NULL;
|
|
|
|
+ ssl->out_buf = NULL;
|
|
if( ( ssl-> in_buf = mbedtls_calloc( 1, len ) ) == NULL ||
|
|
if( ( ssl-> in_buf = mbedtls_calloc( 1, len ) ) == NULL ||
|
|
( ssl->out_buf = mbedtls_calloc( 1, len ) ) == NULL )
|
|
( ssl->out_buf = mbedtls_calloc( 1, len ) ) == NULL )
|
|
{
|
|
{
|
|
MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", len ) );
|
|
MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", len ) );
|
|
- mbedtls_free( ssl->in_buf );
|
|
|
|
- ssl->in_buf = NULL;
|
|
|
|
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
|
|
|
|
|
|
+ ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
|
|
|
|
+ goto error;
|
|
}
|
|
}
|
|
|
|
|
|
#if defined(MBEDTLS_SSL_PROTO_DTLS)
|
|
#if defined(MBEDTLS_SSL_PROTO_DTLS)
|
|
@@ -5696,9 +5854,32 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
|
|
}
|
|
}
|
|
|
|
|
|
if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
|
|
if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
|
|
- return( ret );
|
|
|
|
|
|
+ goto error;
|
|
|
|
|
|
return( 0 );
|
|
return( 0 );
|
|
|
|
+
|
|
|
|
+error:
|
|
|
|
+ mbedtls_free( ssl->in_buf );
|
|
|
|
+ mbedtls_free( ssl->out_buf );
|
|
|
|
+
|
|
|
|
+ ssl->conf = NULL;
|
|
|
|
+
|
|
|
|
+ ssl->in_buf = NULL;
|
|
|
|
+ ssl->out_buf = NULL;
|
|
|
|
+
|
|
|
|
+ ssl->in_hdr = NULL;
|
|
|
|
+ ssl->in_ctr = NULL;
|
|
|
|
+ ssl->in_len = NULL;
|
|
|
|
+ ssl->in_iv = NULL;
|
|
|
|
+ ssl->in_msg = NULL;
|
|
|
|
+
|
|
|
|
+ ssl->out_hdr = NULL;
|
|
|
|
+ ssl->out_ctr = NULL;
|
|
|
|
+ ssl->out_len = NULL;
|
|
|
|
+ ssl->out_iv = NULL;
|
|
|
|
+ ssl->out_msg = NULL;
|
|
|
|
+
|
|
|
|
+ return( ret );
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -5759,7 +5940,11 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
|
|
ssl->transform_in = NULL;
|
|
ssl->transform_in = NULL;
|
|
ssl->transform_out = NULL;
|
|
ssl->transform_out = NULL;
|
|
|
|
|
|
|
|
+ ssl->session_in = NULL;
|
|
|
|
+ ssl->session_out = NULL;
|
|
|
|
+
|
|
memset( ssl->out_buf, 0, MBEDTLS_SSL_BUFFER_LEN );
|
|
memset( ssl->out_buf, 0, MBEDTLS_SSL_BUFFER_LEN );
|
|
|
|
+
|
|
if( partial == 0 )
|
|
if( partial == 0 )
|
|
memset( ssl->in_buf, 0, MBEDTLS_SSL_BUFFER_LEN );
|
|
memset( ssl->in_buf, 0, MBEDTLS_SSL_BUFFER_LEN );
|
|
|
|
|
|
@@ -5981,27 +6166,27 @@ static int ssl_append_key_cert( mbedtls_ssl_key_cert **head,
|
|
mbedtls_x509_crt *cert,
|
|
mbedtls_x509_crt *cert,
|
|
mbedtls_pk_context *key )
|
|
mbedtls_pk_context *key )
|
|
{
|
|
{
|
|
- mbedtls_ssl_key_cert *new;
|
|
|
|
|
|
+ mbedtls_ssl_key_cert *new_cert;
|
|
|
|
|
|
- new = mbedtls_calloc( 1, sizeof( mbedtls_ssl_key_cert ) );
|
|
|
|
- if( new == NULL )
|
|
|
|
|
|
+ new_cert = mbedtls_calloc( 1, sizeof( mbedtls_ssl_key_cert ) );
|
|
|
|
+ if( new_cert == NULL )
|
|
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
|
|
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
|
|
|
|
|
|
- new->cert = cert;
|
|
|
|
- new->key = key;
|
|
|
|
- new->next = NULL;
|
|
|
|
|
|
+ new_cert->cert = cert;
|
|
|
|
+ new_cert->key = key;
|
|
|
|
+ new_cert->next = NULL;
|
|
|
|
|
|
/* Update head is the list was null, else add to the end */
|
|
/* Update head is the list was null, else add to the end */
|
|
if( *head == NULL )
|
|
if( *head == NULL )
|
|
{
|
|
{
|
|
- *head = new;
|
|
|
|
|
|
+ *head = new_cert;
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
mbedtls_ssl_key_cert *cur = *head;
|
|
mbedtls_ssl_key_cert *cur = *head;
|
|
while( cur->next != NULL )
|
|
while( cur->next != NULL )
|
|
cur = cur->next;
|
|
cur = cur->next;
|
|
- cur->next = new;
|
|
|
|
|
|
+ cur->next = new_cert;
|
|
}
|
|
}
|
|
|
|
|
|
return( 0 );
|
|
return( 0 );
|
|
@@ -6532,17 +6717,18 @@ const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl )
|
|
|
|
|
|
int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
|
|
int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
|
|
{
|
|
{
|
|
- size_t transform_expansion;
|
|
|
|
|
|
+ size_t transform_expansion = 0;
|
|
const mbedtls_ssl_transform *transform = ssl->transform_out;
|
|
const mbedtls_ssl_transform *transform = ssl->transform_out;
|
|
|
|
+ unsigned block_size;
|
|
|
|
+
|
|
|
|
+ if( transform == NULL )
|
|
|
|
+ return( (int) mbedtls_ssl_hdr_len( ssl ) );
|
|
|
|
|
|
#if defined(MBEDTLS_ZLIB_SUPPORT)
|
|
#if defined(MBEDTLS_ZLIB_SUPPORT)
|
|
if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL )
|
|
if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL )
|
|
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
|
|
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
|
|
#endif
|
|
#endif
|
|
|
|
|
|
- if( transform == NULL )
|
|
|
|
- return( (int) mbedtls_ssl_hdr_len( ssl ) );
|
|
|
|
-
|
|
|
|
switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) )
|
|
switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) )
|
|
{
|
|
{
|
|
case MBEDTLS_MODE_GCM:
|
|
case MBEDTLS_MODE_GCM:
|
|
@@ -6552,8 +6738,25 @@ int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
|
|
break;
|
|
break;
|
|
|
|
|
|
case MBEDTLS_MODE_CBC:
|
|
case MBEDTLS_MODE_CBC:
|
|
- transform_expansion = transform->maclen
|
|
|
|
- + mbedtls_cipher_get_block_size( &transform->cipher_ctx_enc );
|
|
|
|
|
|
+
|
|
|
|
+ block_size = mbedtls_cipher_get_block_size(
|
|
|
|
+ &transform->cipher_ctx_enc );
|
|
|
|
+
|
|
|
|
+ /* Expansion due to the addition of the MAC. */
|
|
|
|
+ transform_expansion += transform->maclen;
|
|
|
|
+
|
|
|
|
+ /* Expansion due to the addition of CBC padding;
|
|
|
|
+ * Theoretically up to 256 bytes, but we never use
|
|
|
|
+ * more than the block size of the underlying cipher. */
|
|
|
|
+ transform_expansion += block_size;
|
|
|
|
+
|
|
|
|
+ /* For TLS 1.1 or higher, an explicit IV is added
|
|
|
|
+ * after the record header. */
|
|
|
|
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
|
|
|
+ if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
|
|
|
|
+ transform_expansion += block_size;
|
|
|
|
+#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
|
|
|
|
+
|
|
break;
|
|
break;
|
|
|
|
|
|
default:
|
|
default:
|
|
@@ -6880,41 +7083,6 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- /*
|
|
|
|
- * TODO
|
|
|
|
- *
|
|
|
|
- * The logic should be streamlined here:
|
|
|
|
- *
|
|
|
|
- * Instead of
|
|
|
|
- *
|
|
|
|
- * - Manually checking whether ssl->in_offt is NULL
|
|
|
|
- * - Fetching a new record if yes
|
|
|
|
- * - Setting ssl->in_offt if one finds an application record
|
|
|
|
- * - Resetting keep_current_message after handling the application data
|
|
|
|
- *
|
|
|
|
- * one should
|
|
|
|
- *
|
|
|
|
- * - Adapt read_record to set ssl->in_offt automatically
|
|
|
|
- * when a new application data record is processed.
|
|
|
|
- * - Always call mbedtls_ssl_read_record here.
|
|
|
|
- *
|
|
|
|
- * This way, the logic of ssl_read would be much clearer:
|
|
|
|
- *
|
|
|
|
- * (1) Always call record layer and see what kind of record is on
|
|
|
|
- * and have it ready for consumption (in particular, in_offt
|
|
|
|
- * properly set for application data records).
|
|
|
|
- * (2) If it's application data (either freshly fetched
|
|
|
|
- * or something already being partially processed),
|
|
|
|
- * serve the read request from it.
|
|
|
|
- * (3) If it's something different from application data,
|
|
|
|
- * handle it accordingly, e.g. potentially start a
|
|
|
|
- * renegotiation.
|
|
|
|
- *
|
|
|
|
- * This will also remove the need to manually reset
|
|
|
|
- * ssl->keep_current_message = 0 below.
|
|
|
|
- *
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
if( ssl->in_offt == NULL )
|
|
if( ssl->in_offt == NULL )
|
|
{
|
|
{
|
|
/* Start timer if not already running */
|
|
/* Start timer if not already running */
|
|
@@ -7136,8 +7304,16 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
- * Send application data to be encrypted by the SSL layer,
|
|
|
|
- * taking care of max fragment length and buffer size
|
|
|
|
|
|
+ * Send application data to be encrypted by the SSL layer, taking care of max
|
|
|
|
+ * fragment length and buffer size.
|
|
|
|
+ *
|
|
|
|
+ * According to RFC 5246 Section 6.2.1:
|
|
|
|
+ *
|
|
|
|
+ * Zero-length fragments of Application data MAY be sent as they are
|
|
|
|
+ * potentially useful as a traffic analysis countermeasure.
|
|
|
|
+ *
|
|
|
|
+ * Therefore, it is possible that the input message length is 0 and the
|
|
|
|
+ * corresponding return code is 0 on success.
|
|
*/
|
|
*/
|
|
static int ssl_write_real( mbedtls_ssl_context *ssl,
|
|
static int ssl_write_real( mbedtls_ssl_context *ssl,
|
|
const unsigned char *buf, size_t len )
|
|
const unsigned char *buf, size_t len )
|
|
@@ -7165,6 +7341,12 @@ static int ssl_write_real( mbedtls_ssl_context *ssl,
|
|
|
|
|
|
if( ssl->out_left != 0 )
|
|
if( ssl->out_left != 0 )
|
|
{
|
|
{
|
|
|
|
+ /*
|
|
|
|
+ * The user has previously tried to send the data and
|
|
|
|
+ * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially
|
|
|
|
+ * written. In this case, we expect the high-level write function
|
|
|
|
+ * (e.g. mbedtls_ssl_write()) to be called with the same parameters
|
|
|
|
+ */
|
|
if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
|
|
if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
|
|
{
|
|
{
|
|
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
|
|
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
|
|
@@ -7173,6 +7355,11 @@ static int ssl_write_real( mbedtls_ssl_context *ssl,
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
|
|
+ /*
|
|
|
|
+ * The user is trying to send a message the first time, so we need to
|
|
|
|
+ * copy the data into the internal buffers and setup the data structure
|
|
|
|
+ * to keep track of partial writes
|
|
|
|
+ */
|
|
ssl->out_msglen = len;
|
|
ssl->out_msglen = len;
|
|
ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
|
|
ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
|
|
memcpy( ssl->out_msg, buf, len );
|
|
memcpy( ssl->out_msg, buf, len );
|
|
@@ -7673,8 +7860,14 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
|
|
* Default
|
|
* Default
|
|
*/
|
|
*/
|
|
default:
|
|
default:
|
|
- conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
|
|
|
|
- conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_1; /* TLS 1.0 */
|
|
|
|
|
|
+ conf->min_major_ver = ( MBEDTLS_SSL_MIN_MAJOR_VERSION >
|
|
|
|
+ MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION ) ?
|
|
|
|
+ MBEDTLS_SSL_MIN_MAJOR_VERSION :
|
|
|
|
+ MBEDTLS_SSL_MIN_VALID_MAJOR_VERSION;
|
|
|
|
+ conf->min_minor_ver = ( MBEDTLS_SSL_MIN_MINOR_VERSION >
|
|
|
|
+ MBEDTLS_SSL_MIN_VALID_MINOR_VERSION ) ?
|
|
|
|
+ MBEDTLS_SSL_MIN_MINOR_VERSION :
|
|
|
|
+ MBEDTLS_SSL_MIN_VALID_MINOR_VERSION;
|
|
conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
|
|
conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION;
|
|
conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
|
|
conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
|
|
|
|
|