diff options
author | Andrzej Kurek <andrzej.kurek@arm.com> | 2020-07-06 15:27:34 -0400 |
---|---|---|
committer | Andrzej Kurek <andrzej.kurek@arm.com> | 2020-07-06 15:27:34 -0400 |
commit | 84bde419e134a318becb61537459d7365af7f4bd (patch) | |
tree | 2b887ea4df13526366334e6ba88266ffd19b3ff9 | |
parent | 74f7d0f03de292474ed16500575aee45758fa491 (diff) | |
download | mbed-tls-84bde419e134a318becb61537459d7365af7f4bd.tar.gz |
Add FI countermeasures to the ssl module
This commit adds mainly buffer pointer and length duplication and checks,
but also some hamming distance and return values checking improvements.
Signed-off-by: Andrzej Kurek <andrzej.kurek@arm.com>
-rw-r--r-- | library/ssl_cli.c | 10 | ||||
-rw-r--r-- | library/ssl_srv.c | 21 | ||||
-rw-r--r-- | library/ssl_tls.c | 156 |
3 files changed, 153 insertions, 34 deletions
diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 24c73b534..5b47c0a9b 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -3587,7 +3587,10 @@ static int ssl_out_client_key_exchange_write( mbedtls_ssl_context *ssl, { int ret; unsigned char *p, *end; + volatile unsigned char *buf_dup = buf; + volatile size_t buflen_dup = buflen; size_t n; + mbedtls_ssl_ciphersuite_handle_t ciphersuite_info = mbedtls_ssl_handshake_get_ciphersuite( ssl->handshake ); @@ -3870,7 +3873,12 @@ static int ssl_out_client_key_exchange_write( mbedtls_ssl_context *ssl, } *olen = p - buf; - return( 0 ); + /* Secure against buffer substitution */ + if( buf_dup == buf && buflen_dup == buflen ) + { + return( 0 ); + } + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); } static int ssl_out_client_key_exchange_postprocess( mbedtls_ssl_context *ssl ) diff --git a/library/ssl_srv.c b/library/ssl_srv.c index d560d3516..7094a89a1 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -3269,13 +3269,19 @@ static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl, - sig_start ); int ret = ssl->conf->f_async_resume( ssl, sig_start, signature_len, sig_max_len ); + volatile size_t *signature_len_dup = signature_len; if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) { ssl->handshake->async_in_progress = 0; mbedtls_ssl_set_async_operation_data( ssl, NULL ); } MBEDTLS_SSL_DEBUG_RET( 2, "ssl_resume_server_key_exchange", ret ); - return( ret ); + /* Secure against buffer substitution */ + if( signature_len_dup == signature_len ) + { + return( ret ); + } + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); } #endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && defined(MBEDTLS_SSL_ASYNC_PRIVATE) */ @@ -3678,7 +3684,7 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, { return( 0 ); } - return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); } /* Prepare the ServerKeyExchange message and send it. For ciphersuites @@ -3826,6 +3832,8 @@ static int ssl_parse_client_dh_public( mbedtls_ssl_context *ssl, unsigned char * const unsigned char *end ) { int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; + unsigned char ** volatile p_dup = p; + volatile const unsigned char *end_dup = end; size_t n; /* @@ -3856,7 +3864,12 @@ static int ssl_parse_client_dh_public( mbedtls_ssl_context *ssl, unsigned char * MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY ); - return( ret ); + /* Secure against buffer substitution */ + if( p_dup == p && end_dup == end ) + { + return( ret ); + } + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); } #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ @@ -4423,7 +4436,7 @@ static int ssl_in_client_key_exchange_parse( mbedtls_ssl_context *ssl, { return( ret ); } - return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); } /* Update the handshake state */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index ad2dc9809..cfb871783 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -232,7 +232,7 @@ exit: if( buf_dup != buf || buflen_dup != buflen ) { - return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); } MBEDTLS_SSL_DEBUG_MSG( 1, ( "<= mbedtls_ssl_check_record" ) ); return( ret ); @@ -288,6 +288,9 @@ int mbedtls_ssl_set_cid( mbedtls_ssl_context *ssl, unsigned char const *own_cid, size_t own_cid_len ) { + volatile unsigned char const *own_cid_dup = own_cid; + volatile size_t own_cid_len_dup = own_cid_len; + if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); @@ -314,7 +317,12 @@ int mbedtls_ssl_set_cid( mbedtls_ssl_context *ssl, * MBEDTLS_SSL_CID_IN_LEN_MAX at most 255. */ ssl->own_cid_len = (uint8_t) own_cid_len; - return( 0 ); + /* Secure against buffer substitution */ + if( own_cid_dup == own_cid && own_cid_len_dup == own_cid_len ) + { + return( 0 ); + } + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); } int mbedtls_ssl_get_peer_cid( mbedtls_ssl_context *ssl, @@ -611,7 +619,13 @@ MBEDTLS_NO_INLINE static int ssl3_prf( const unsigned char *secret, size_t slen, mbedtls_sha1_context sha1; unsigned char padding[16]; unsigned char sha1sum[20]; - ((void)label); + volatile const unsigned char *secret_dup = secret; + volatile size_t slen_dup = slen; + volatile const char *label_dup = label; + volatile const unsigned char *random_dup = random; + volatile size_t rlen_dup = rlen; + volatile unsigned char *dstbuf_dup = dstbuf; + volatile size_t dlen_dup = dlen; mbedtls_md5_init( &md5 ); mbedtls_sha1_init( &sha1 ); @@ -656,7 +670,14 @@ exit: mbedtls_platform_zeroize( padding, sizeof( padding ) ); mbedtls_platform_zeroize( sha1sum, sizeof( sha1sum ) ); - return( ret ); + /* Secure against buffer substitution */ + if( secret_dup == secret && slen_dup == slen && label_dup == label && + random_dup == random && rlen_dup == rlen && dstbuf_dup == dstbuf && + dlen_dup == dlen ) + { + return( ret ); + } + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); } #endif /* MBEDTLS_SSL_PROTO_SSL3 */ @@ -674,6 +695,13 @@ MBEDTLS_NO_INLINE static int tls1_prf( const unsigned char *secret, size_t slen, mbedtls_md_handle_t md_info; mbedtls_md_context_t md_ctx; int ret; + volatile const unsigned char *secret_dup = secret; + volatile size_t slen_dup = slen; + volatile const char *label_dup = label; + volatile const unsigned char *random_dup = random; + volatile size_t rlen_dup = rlen; + volatile unsigned char *dstbuf_dup = dstbuf; + volatile size_t dlen_dup = dlen; mbedtls_md_init( &md_ctx ); @@ -760,7 +788,14 @@ MBEDTLS_NO_INLINE static int tls1_prf( const unsigned char *secret, size_t slen, mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); mbedtls_platform_zeroize( h_i, sizeof( h_i ) ); - return( 0 ); + /* Secure against buffer substitution */ + if( secret_dup == secret && slen_dup == slen && label_dup == label && + random_dup == random && rlen_dup == rlen && dstbuf_dup == dstbuf && + dlen_dup == dlen ) + { + return( 0 ); + } + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); } #endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */ @@ -783,6 +818,13 @@ int tls_prf_generic( mbedtls_md_type_t md_type, mbedtls_md_handle_t md_info; mbedtls_md_context_t md_ctx; int ret; + volatile const unsigned char *secret_dup = secret; + volatile size_t slen_dup = slen; + volatile const char *label_dup = label; + volatile const unsigned char *random_dup = random; + volatile size_t rlen_dup = rlen; + volatile unsigned char *dstbuf_dup = dstbuf; + volatile size_t dlen_dup = dlen; mbedtls_md_init( &md_ctx ); @@ -842,7 +884,14 @@ int tls_prf_generic( mbedtls_md_type_t md_type, (void)mbedtls_platform_zeroize( tmp, sizeof( tmp ) ); (void)mbedtls_platform_zeroize( h_i, sizeof( h_i ) ); - return( 0 ); + /* Secure against buffer substitution */ + if( secret_dup == secret && slen_dup == slen && label_dup == label && + random_dup == random && rlen_dup == rlen && dstbuf_dup == dstbuf && + dlen_dup == dlen ) + { + return( 0 ); + } + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); } #if defined(MBEDTLS_SHA256_C) @@ -1834,6 +1883,7 @@ static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake, const mbedtls_ssl_context *ssl ) { int ret; + volatile unsigned char *master_dup = master; /* #if !defined(MBEDTLS_DEBUG_C) && !defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) */ /* ssl = NULL; /\* make sure we don't use it except for debug and EMS *\/ */ @@ -1894,8 +1944,12 @@ static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake, mbedtls_platform_zeroize( handshake->premaster, sizeof(handshake->premaster) ); - - return( 0 ); + /* Secure against buffer substitution */ + if( master_dup == master ) + { + return( 0 ); + } + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); } int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) @@ -2412,22 +2466,33 @@ static int ssl_cid_build_inner_plaintext( unsigned char *content, size_t pad = ( MBEDTLS_SSL_CID_PADDING_GRANULARITY - ( len + 1 ) % MBEDTLS_SSL_CID_PADDING_GRANULARITY ) % MBEDTLS_SSL_CID_PADDING_GRANULARITY; + volatile unsigned char *content_dup = content; + volatile size_t *content_size_dup = content_size; + volatile size_t remaining_dup = remaining; + /* Write real content type */ if( remaining == 0 ) - return( -1 ); + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); content[ len ] = rec_type; len++; remaining--; if( remaining < pad ) - return( -1 ); + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); mbedtls_platform_memset( content + len, 0, pad ); len += pad; remaining -= pad; *content_size = len; - return( 0 ); + + /* Secure against buffer substitution */ + if( content_dup == content && content_size_dup == content_size && + ( remaining_dup - 1 - pad ) == remaining ) + { + return( 0 ); + } + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); } /* This function parses a DTLSInnerPlaintext structure. @@ -2572,6 +2637,7 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, if( rec->cid_len != 0 ) { + int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED; /* * Wrap plaintext into DTLSInnerPlaintext structure. * See ssl_cid_build_inner_plaintext() for more information. @@ -2579,12 +2645,12 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, * Note that this changes `rec->data_len`, and hence * `post_avail` needs to be recalculated afterwards. */ - if( ssl_cid_build_inner_plaintext( data, - &rec->data_len, - post_avail, - rec->type ) != 0 ) + if( ( ret = ssl_cid_build_inner_plaintext( data, + &rec->data_len, + post_avail, + rec->type ) ) != 0 ) { - return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + return( ret ); } rec->type = MBEDTLS_SSL_MSG_CID; @@ -4831,13 +4897,13 @@ static int ssl_bitmask_check( unsigned char *mask, size_t len ) for( i = 0; i < len / 8; i++ ) if( mask[i] != 0xFF ) - return( -1 ); + return( 0x75555555 ); for( i = 0; i < len % 8; i++ ) if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 ) - return( -1 ); + return( 0x75555555 ); - return( 0 ); + return( 0 ); } /* msg_len does not include the handshake header */ @@ -7070,10 +7136,10 @@ static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl, mbedtls_x509_crt const * const peer_crt = ssl->session->peer_cert; if( peer_crt == NULL ) - return( -1 ); + return( 0x75555555 ); if( peer_crt->raw.len != crt_buf_len ) - return( -1 ); + return( 0x75555555 ); return( mbedtls_platform_memcmp( peer_crt->raw.p, crt_buf, crt_buf_len ) ); } @@ -7095,16 +7161,16 @@ static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl, if( peer_cert_digest == NULL || digest_info == MBEDTLS_MD_INVALID_HANDLE ) { - return( -1 ); + return( 0x75555555 ); } digest_len = mbedtls_md_get_size( digest_info ); if( digest_len > MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN ) - return( -1 ); + return( 0x75555555 ); ret = mbedtls_md( digest_info, crt_buf, crt_buf_len, tmp_digest ); if( ret != 0 ) - return( -1 ); + return( 0x75555555 ); return( mbedtls_platform_memcmp( tmp_digest, peer_cert_digest, digest_len ) ); } @@ -10869,6 +10935,8 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) { int ret; size_t n; + volatile unsigned char *buf_dup = buf; + volatile size_t len_dup = len; if( ssl == NULL || ssl->conf == NULL ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); @@ -11182,7 +11250,12 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) ); - return( (int) n ); + /* Secure against buffer substitution */ + if( buf_dup == buf && len_dup == len ) + { + return( (int) n ); + } + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); } /* @@ -11202,6 +11275,8 @@ static int ssl_write_real( mbedtls_ssl_context *ssl, { int ret = mbedtls_ssl_get_max_out_record_payload( ssl ); const size_t max_len = (size_t) ret; + volatile const unsigned char *buf_dup = buf; + volatile size_t len_dup = len; if( ret < 0 ) { @@ -11224,6 +11299,7 @@ static int ssl_write_real( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_SSL_PROTO_TLS) { len = max_len; + len_dup = len; } #endif } @@ -11259,8 +11335,12 @@ static int ssl_write_real( mbedtls_ssl_context *ssl, return( ret ); } } - - return( (int) len ); + /* Secure against buffer substitution */ + if( buf_dup == buf && len_dup == len ) + { + return( (int) len ); + } + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); } /* @@ -11309,6 +11389,8 @@ static int ssl_write_split( mbedtls_ssl_context *ssl, int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) { int ret; + volatile const unsigned char *buf_dup = buf; + volatile size_t len_dup = len; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) ); @@ -11340,7 +11422,12 @@ int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) ); - return( ret ); + /* Secure against buffer substitution */ + if( buf_dup == buf && len_dup == len ) + { + return( ret ); + } + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); } /* @@ -12924,6 +13011,11 @@ int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl, { int ret = 0; mbedtls_md_context_t ctx; + volatile unsigned char* hash_dup = hash; + volatile size_t *hashlen_dup = hashlen; + volatile unsigned char* data_dup = data; + volatile size_t data_len_dup = data_len; + mbedtls_md_handle_t md_info = mbedtls_md_info_from_type( md_alg ); *hashlen = mbedtls_md_get_size( md_info ); @@ -12969,7 +13061,13 @@ exit: mbedtls_ssl_pend_fatal_alert( ssl, MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); - return( ret ); + /* Secure against buffer substitution */ + if( hash_dup == hash && hashlen_dup == hashlen && + data_dup == data && data_len_dup == data_len ) + { + return( ret ); + } + return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED ); } #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ MBEDTLS_SSL_PROTO_TLS1_2 */ |