Merge pull request #5314 from gilles-peskine-arm/missing-ret-check-mbedtls_md_hmac-2.x

Backport 2.x: Check HMAC return values
This commit is contained in:
Dave Rodgman 2021-12-13 10:51:28 +00:00 committed by GitHub
commit 1c68ba1afd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 250 additions and 74 deletions

View file

@ -5,6 +5,8 @@ Bugfix
This does not concern the implementation provided with Mbed TLS, This does not concern the implementation provided with Mbed TLS,
where this function cannot fail, or full-module replacements with where this function cannot fail, or full-module replacements with
MBEDTLS_AES_ALT or MBEDTLS_DES_ALT. Reported by Armelle Duboc in #1092. MBEDTLS_AES_ALT or MBEDTLS_DES_ALT. Reported by Armelle Duboc in #1092.
* Some failures of HMAC operations were ignored. These failures could only
happen with an alternative implementation of the underlying hash module.
Features Features
* Warn if errors from certain functions are ignored. This is currently * Warn if errors from certain functions are ignored. This is currently
@ -13,5 +15,5 @@ Features
(where supported) for critical functions where ignoring the return (where supported) for critical functions where ignoring the return
value is almost always a bug. Enable the new configuration option value is almost always a bug. Enable the new configuration option
MBEDTLS_CHECK_RETURN_WARNING to get warnings for other functions. This MBEDTLS_CHECK_RETURN_WARNING to get warnings for other functions. This
is currently implemented in the AES and DES modules, and will be extended is currently implemented in the AES, DES and md modules, and will be
to other modules in the future. extended to other modules in the future.

View file

@ -0,0 +1,5 @@
Security
* Zeroize intermediate variables used to calculate the MAC in CBC cipher
suites. This hardens the library in case stack memory leaks through a
memory disclosure vulnerabilty, which could formerly have allowed a
man-in-the-middle to inject fake ciphertext into a DTLS connection.

View file

@ -32,6 +32,7 @@
#else #else
#include MBEDTLS_CONFIG_FILE #include MBEDTLS_CONFIG_FILE
#endif #endif
#include "mbedtls/platform_util.h"
/** The selected feature is not available. */ /** The selected feature is not available. */
#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 #define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080
@ -210,6 +211,7 @@ int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_
* failure. * failure.
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure. * \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
*/ */
MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ); int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac );
/** /**
@ -231,6 +233,7 @@ int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_inf
* \return \c 0 on success. * \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure. * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure.
*/ */
MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_clone( mbedtls_md_context_t *dst, int mbedtls_md_clone( mbedtls_md_context_t *dst,
const mbedtls_md_context_t *src ); const mbedtls_md_context_t *src );
@ -280,6 +283,7 @@ const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info );
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure. * failure.
*/ */
MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_starts( mbedtls_md_context_t *ctx ); int mbedtls_md_starts( mbedtls_md_context_t *ctx );
/** /**
@ -298,6 +302,7 @@ int mbedtls_md_starts( mbedtls_md_context_t *ctx );
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure. * failure.
*/ */
MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ); int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen );
/** /**
@ -318,6 +323,7 @@ int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, si
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure. * failure.
*/ */
MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ); int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output );
/** /**
@ -338,6 +344,7 @@ int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output );
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure. * failure.
*/ */
MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
unsigned char *output ); unsigned char *output );
@ -359,6 +366,7 @@ int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, si
* the file pointed by \p path. * the file pointed by \p path.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL. * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL.
*/ */
MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path,
unsigned char *output ); unsigned char *output );
#endif /* MBEDTLS_FS_IO */ #endif /* MBEDTLS_FS_IO */
@ -381,6 +389,7 @@ int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path,
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure. * failure.
*/ */
MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
size_t keylen ); size_t keylen );
@ -403,6 +412,7 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure. * failure.
*/ */
MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input,
size_t ilen ); size_t ilen );
@ -424,6 +434,7 @@ int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *inpu
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure. * failure.
*/ */
MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output); int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output);
/** /**
@ -441,6 +452,7 @@ int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output);
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure. * failure.
*/ */
MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ); int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx );
/** /**
@ -465,11 +477,13 @@ int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx );
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification * \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure. * failure.
*/ */
MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen, int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen, const unsigned char *input, size_t ilen,
unsigned char *output ); unsigned char *output );
/* Internal use */ /* Internal use */
MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ); int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data );
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -474,17 +474,18 @@ static void ssl_extract_add_data_from_record( unsigned char* add_data,
/* /*
* SSLv3.0 MAC functions * SSLv3.0 MAC functions
*/ */
static void ssl_mac( mbedtls_md_context_t *md_ctx, static int ssl_mac( mbedtls_md_context_t *md_ctx,
const unsigned char *secret, const unsigned char *secret,
const unsigned char *buf, size_t len, const unsigned char *buf, size_t len,
const unsigned char *ctr, int type, const unsigned char *ctr, int type,
unsigned char out[SSL3_MAC_MAX_BYTES] ) unsigned char out[SSL3_MAC_MAX_BYTES] )
{ {
unsigned char header[11]; unsigned char header[11];
unsigned char padding[48]; unsigned char padding[48];
int padlen; int padlen;
int md_size = mbedtls_md_get_size( md_ctx->md_info ); int md_size = mbedtls_md_get_size( md_ctx->md_info );
int md_type = mbedtls_md_get_type( md_ctx->md_info ); int md_type = mbedtls_md_get_type( md_ctx->md_info );
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* Only MD5 and SHA-1 supported */ /* Only MD5 and SHA-1 supported */
if( md_type == MBEDTLS_MD_MD5 ) if( md_type == MBEDTLS_MD_MD5 )
@ -497,19 +498,43 @@ static void ssl_mac( mbedtls_md_context_t *md_ctx,
MBEDTLS_PUT_UINT16_BE( len, header, 9); MBEDTLS_PUT_UINT16_BE( len, header, 9);
memset( padding, 0x36, padlen ); memset( padding, 0x36, padlen );
mbedtls_md_starts( md_ctx ); ret = mbedtls_md_starts( md_ctx );
mbedtls_md_update( md_ctx, secret, md_size ); if( ret != 0 )
mbedtls_md_update( md_ctx, padding, padlen ); return( ret );
mbedtls_md_update( md_ctx, header, 11 ); ret = mbedtls_md_update( md_ctx, secret, md_size );
mbedtls_md_update( md_ctx, buf, len ); if( ret != 0 )
mbedtls_md_finish( md_ctx, out ); return( ret );
ret = mbedtls_md_update( md_ctx, padding, padlen );
if( ret != 0 )
return( ret );
ret = mbedtls_md_update( md_ctx, header, 11 );
if( ret != 0 )
return( ret );
ret = mbedtls_md_update( md_ctx, buf, len );
if( ret != 0 )
return( ret );
ret = mbedtls_md_finish( md_ctx, out );
if( ret != 0 )
return( ret );
memset( padding, 0x5C, padlen ); memset( padding, 0x5C, padlen );
mbedtls_md_starts( md_ctx ); ret = mbedtls_md_starts( md_ctx );
mbedtls_md_update( md_ctx, secret, md_size ); if( ret != 0 )
mbedtls_md_update( md_ctx, padding, padlen ); return( ret );
mbedtls_md_update( md_ctx, out, md_size ); ret = mbedtls_md_update( md_ctx, secret, md_size );
mbedtls_md_finish( md_ctx, out ); if( ret != 0 )
return( ret );
ret = mbedtls_md_update( md_ctx, padding, padlen );
if( ret != 0 )
return( ret );
ret = mbedtls_md_update( md_ctx, out, md_size );
if( ret != 0 )
return( ret );
ret = mbedtls_md_finish( md_ctx, out );
if( ret != 0 )
return( ret );
return( 0 );
} }
#endif /* MBEDTLS_SSL_PROTO_SSL3 */ #endif /* MBEDTLS_SSL_PROTO_SSL3 */
@ -714,9 +739,17 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
{ {
unsigned char mac[SSL3_MAC_MAX_BYTES]; unsigned char mac[SSL3_MAC_MAX_BYTES];
ssl_mac( &transform->md_ctx_enc, transform->mac_enc, int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
data, rec->data_len, rec->ctr, rec->type, mac ); ret = ssl_mac( &transform->md_ctx_enc, transform->mac_enc,
memcpy( data + rec->data_len, mac, transform->maclen ); data, rec->data_len, rec->ctr, rec->type, mac );
if( ret == 0 )
memcpy( data + rec->data_len, mac, transform->maclen );
mbedtls_platform_zeroize( mac, transform->maclen );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_mac", ret );
return( ret );
}
} }
else else
#endif #endif
@ -725,18 +758,35 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
{ {
unsigned char mac[MBEDTLS_SSL_MAC_ADD]; unsigned char mac[MBEDTLS_SSL_MAC_ADD];
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ssl_extract_add_data_from_record( add_data, &add_data_len, rec, ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
transform->minor_ver ); transform->minor_ver );
mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data, ret = mbedtls_md_hmac_update( &transform->md_ctx_enc,
add_data_len ); add_data, add_data_len );
mbedtls_md_hmac_update( &transform->md_ctx_enc, if( ret != 0 )
data, rec->data_len ); goto hmac_failed_etm_disabled;
mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac ); ret = mbedtls_md_hmac_update( &transform->md_ctx_enc,
mbedtls_md_hmac_reset( &transform->md_ctx_enc ); data, rec->data_len );
if( ret != 0 )
goto hmac_failed_etm_disabled;
ret = mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac );
if( ret != 0 )
goto hmac_failed_etm_disabled;
ret = mbedtls_md_hmac_reset( &transform->md_ctx_enc );
if( ret != 0 )
goto hmac_failed_etm_disabled;
memcpy( data + rec->data_len, mac, transform->maclen ); memcpy( data + rec->data_len, mac, transform->maclen );
hmac_failed_etm_disabled:
mbedtls_platform_zeroize( mac, transform->maclen );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_hmac_xxx", ret );
return( ret );
}
} }
else else
#endif #endif
@ -1009,18 +1059,34 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data, MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
add_data_len ); add_data_len );
mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data, ret = mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data,
add_data_len ); add_data_len );
mbedtls_md_hmac_update( &transform->md_ctx_enc, if( ret != 0 )
data, rec->data_len ); goto hmac_failed_etm_enabled;
mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac ); ret = mbedtls_md_hmac_update( &transform->md_ctx_enc,
mbedtls_md_hmac_reset( &transform->md_ctx_enc ); data, rec->data_len );
if( ret != 0 )
goto hmac_failed_etm_enabled;
ret = mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac );
if( ret != 0 )
goto hmac_failed_etm_enabled;
ret = mbedtls_md_hmac_reset( &transform->md_ctx_enc );
if( ret != 0 )
goto hmac_failed_etm_enabled;
memcpy( data + rec->data_len, mac, transform->maclen ); memcpy( data + rec->data_len, mac, transform->maclen );
rec->data_len += transform->maclen; rec->data_len += transform->maclen;
post_avail -= transform->maclen; post_avail -= transform->maclen;
auth_done++; auth_done++;
hmac_failed_etm_enabled:
mbedtls_platform_zeroize( mac, transform->maclen );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "HMAC calculation failed", ret );
return( ret );
}
} }
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
} }
@ -1292,12 +1358,20 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
/* Calculate expected MAC. */ /* Calculate expected MAC. */
MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data, MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
add_data_len ); add_data_len );
mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data, ret = mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data,
add_data_len ); add_data_len );
mbedtls_md_hmac_update( &transform->md_ctx_dec, if( ret != 0 )
goto hmac_failed_etm_enabled;
ret = mbedtls_md_hmac_update( &transform->md_ctx_dec,
data, rec->data_len ); data, rec->data_len );
mbedtls_md_hmac_finish( &transform->md_ctx_dec, mac_expect ); if( ret != 0 )
mbedtls_md_hmac_reset( &transform->md_ctx_dec ); goto hmac_failed_etm_enabled;
ret = mbedtls_md_hmac_finish( &transform->md_ctx_dec, mac_expect );
if( ret != 0 )
goto hmac_failed_etm_enabled;
ret = mbedtls_md_hmac_reset( &transform->md_ctx_dec );
if( ret != 0 )
goto hmac_failed_etm_enabled;
MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", data + rec->data_len, MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", data + rec->data_len,
transform->maclen ); transform->maclen );
@ -1309,9 +1383,19 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
transform->maclen ) != 0 ) transform->maclen ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
return( MBEDTLS_ERR_SSL_INVALID_MAC ); ret = MBEDTLS_ERR_SSL_INVALID_MAC;
goto hmac_failed_etm_enabled;
} }
auth_done++; auth_done++;
hmac_failed_etm_enabled:
mbedtls_platform_zeroize( mac_expect, transform->maclen );
if( ret != 0 )
{
if( ret != MBEDTLS_ERR_SSL_INVALID_MAC )
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_hmac_xxx", ret );
return( ret );
}
} }
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
@ -1529,11 +1613,16 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
#if defined(MBEDTLS_SSL_PROTO_SSL3) #if defined(MBEDTLS_SSL_PROTO_SSL3)
if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
{ {
ssl_mac( &transform->md_ctx_dec, ret = ssl_mac( &transform->md_ctx_dec,
transform->mac_dec, transform->mac_dec,
data, rec->data_len, data, rec->data_len,
rec->ctr, rec->type, rec->ctr, rec->type,
mac_expect ); mac_expect );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_mac", ret );
goto hmac_failed_etm_disabled;
}
memcpy( mac_peer, data + rec->data_len, transform->maclen ); memcpy( mac_peer, data + rec->data_len, transform->maclen );
} }
else else
@ -1562,7 +1651,7 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
if( ret != 0 ) if( ret != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ct_hmac", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ct_hmac", ret );
return( ret ); goto hmac_failed_etm_disabled;
} }
mbedtls_ct_memcpy_offset( mac_peer, data, mbedtls_ct_memcpy_offset( mac_peer, data,
@ -1592,6 +1681,12 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
correct = 0; correct = 0;
} }
auth_done++; auth_done++;
hmac_failed_etm_disabled:
mbedtls_platform_zeroize( mac_peer, transform->maclen );
mbedtls_platform_zeroize( mac_expect, transform->maclen );
if( ret != 0 )
return( ret );
} }
/* /*

View file

@ -442,19 +442,37 @@ static int tls1_prf( const unsigned char *secret, size_t slen,
goto exit; goto exit;
} }
mbedtls_md_hmac_starts( &md_ctx, S1, hs ); ret = mbedtls_md_hmac_starts( &md_ctx, S1, hs );
mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb ); if( ret != 0 )
mbedtls_md_hmac_finish( &md_ctx, 4 + tmp ); goto exit;
ret = mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb );
if( ret != 0 )
goto exit;
ret = mbedtls_md_hmac_finish( &md_ctx, 4 + tmp );
if( ret != 0 )
goto exit;
for( i = 0; i < dlen; i += 16 ) for( i = 0; i < dlen; i += 16 )
{ {
mbedtls_md_hmac_reset ( &md_ctx ); ret = mbedtls_md_hmac_reset ( &md_ctx );
mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 + nb ); if( ret != 0 )
mbedtls_md_hmac_finish( &md_ctx, h_i ); goto exit;
ret = mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 + nb );
if( ret != 0 )
goto exit;
ret = mbedtls_md_hmac_finish( &md_ctx, h_i );
if( ret != 0 )
goto exit;
mbedtls_md_hmac_reset ( &md_ctx ); ret = mbedtls_md_hmac_reset ( &md_ctx );
mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 ); if( ret != 0 )
mbedtls_md_hmac_finish( &md_ctx, 4 + tmp ); goto exit;
ret = mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 );
if( ret != 0 )
goto exit;
ret = mbedtls_md_hmac_finish( &md_ctx, 4 + tmp );
if( ret != 0 )
goto exit;
k = ( i + 16 > dlen ) ? dlen % 16 : 16; k = ( i + 16 > dlen ) ? dlen % 16 : 16;
@ -478,19 +496,37 @@ static int tls1_prf( const unsigned char *secret, size_t slen,
goto exit; goto exit;
} }
mbedtls_md_hmac_starts( &md_ctx, S2, hs ); ret = mbedtls_md_hmac_starts( &md_ctx, S2, hs );
mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb ); if( ret != 0 )
mbedtls_md_hmac_finish( &md_ctx, tmp ); goto exit;
ret = mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb );
if( ret != 0 )
goto exit;
ret = mbedtls_md_hmac_finish( &md_ctx, tmp );
if( ret != 0 )
goto exit;
for( i = 0; i < dlen; i += 20 ) for( i = 0; i < dlen; i += 20 )
{ {
mbedtls_md_hmac_reset ( &md_ctx ); ret = mbedtls_md_hmac_reset ( &md_ctx );
mbedtls_md_hmac_update( &md_ctx, tmp, 20 + nb ); if( ret != 0 )
mbedtls_md_hmac_finish( &md_ctx, h_i ); goto exit;
ret = mbedtls_md_hmac_update( &md_ctx, tmp, 20 + nb );
if( ret != 0 )
goto exit;
ret = mbedtls_md_hmac_finish( &md_ctx, h_i );
if( ret != 0 )
goto exit;
mbedtls_md_hmac_reset ( &md_ctx ); ret = mbedtls_md_hmac_reset ( &md_ctx );
mbedtls_md_hmac_update( &md_ctx, tmp, 20 ); if( ret != 0 )
mbedtls_md_hmac_finish( &md_ctx, tmp ); goto exit;
ret = mbedtls_md_hmac_update( &md_ctx, tmp, 20 );
if( ret != 0 )
goto exit;
ret = mbedtls_md_hmac_finish( &md_ctx, tmp );
if( ret != 0 )
goto exit;
k = ( i + 20 > dlen ) ? dlen % 20 : 20; k = ( i + 20 > dlen ) ? dlen % 20 : 20;
@ -680,19 +716,37 @@ static int tls_prf_generic( mbedtls_md_type_t md_type,
if ( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) if ( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
goto exit; goto exit;
mbedtls_md_hmac_starts( &md_ctx, secret, slen ); ret = mbedtls_md_hmac_starts( &md_ctx, secret, slen );
mbedtls_md_hmac_update( &md_ctx, tmp + md_len, nb ); if( ret != 0 )
mbedtls_md_hmac_finish( &md_ctx, tmp ); goto exit;
ret = mbedtls_md_hmac_update( &md_ctx, tmp + md_len, nb );
if( ret != 0 )
goto exit;
ret = mbedtls_md_hmac_finish( &md_ctx, tmp );
if( ret != 0 )
goto exit;
for( i = 0; i < dlen; i += md_len ) for( i = 0; i < dlen; i += md_len )
{ {
mbedtls_md_hmac_reset ( &md_ctx ); ret = mbedtls_md_hmac_reset ( &md_ctx );
mbedtls_md_hmac_update( &md_ctx, tmp, md_len + nb ); if( ret != 0 )
mbedtls_md_hmac_finish( &md_ctx, h_i ); goto exit;
ret = mbedtls_md_hmac_update( &md_ctx, tmp, md_len + nb );
if( ret != 0 )
goto exit;
ret = mbedtls_md_hmac_finish( &md_ctx, h_i );
if( ret != 0 )
goto exit;
mbedtls_md_hmac_reset ( &md_ctx ); ret = mbedtls_md_hmac_reset ( &md_ctx );
mbedtls_md_hmac_update( &md_ctx, tmp, md_len ); if( ret != 0 )
mbedtls_md_hmac_finish( &md_ctx, tmp ); goto exit;
ret = mbedtls_md_hmac_update( &md_ctx, tmp, md_len );
if( ret != 0 )
goto exit;
ret = mbedtls_md_hmac_finish( &md_ctx, tmp );
if( ret != 0 )
goto exit;
k = ( i + md_len > dlen ) ? dlen % md_len : md_len; k = ( i + md_len > dlen ) ? dlen % md_len : md_len;
@ -1232,8 +1286,14 @@ static int ssl_populate_transform( mbedtls_ssl_transform *transform,
For AEAD-based ciphersuites, there is nothing to do here. */ For AEAD-based ciphersuites, there is nothing to do here. */
if( mac_key_len != 0 ) if( mac_key_len != 0 )
{ {
mbedtls_md_hmac_starts( &transform->md_ctx_enc, mac_enc, mac_key_len ); ret = mbedtls_md_hmac_starts( &transform->md_ctx_enc,
mbedtls_md_hmac_starts( &transform->md_ctx_dec, mac_dec, mac_key_len ); mac_enc, mac_key_len );
if( ret != 0 )
goto end;
ret = mbedtls_md_hmac_starts( &transform->md_ctx_dec,
mac_dec, mac_key_len );
if( ret != 0 )
goto end;
} }
} }
else else