diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 1e5b68ef96..8c65061e59 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1239,10 +1239,8 @@ struct mbedtls_ssl_config * so that elements tend to be in the 128-element direct access window * on Arm Thumb, which reduces the code size. */ - unsigned char MBEDTLS_PRIVATE(max_major_ver); /*!< max. major version used */ - unsigned char MBEDTLS_PRIVATE(max_minor_ver); /*!< max. minor version used */ - unsigned char MBEDTLS_PRIVATE(min_major_ver); /*!< min. major version used */ - unsigned char MBEDTLS_PRIVATE(min_minor_ver); /*!< min. minor version used */ + uint16_t MBEDTLS_PRIVATE(max_tls_version); /*!< max. TLS version used */ + uint16_t MBEDTLS_PRIVATE(min_tls_version); /*!< min. TLS version used */ /* * Flags (could be bit-fields to save RAM, but separate bytes make @@ -3847,6 +3845,24 @@ void mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ss */ void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor ); +/** + * \brief Set the maximum supported version sent from the client side + * and/or accepted at the server side. + * + * \note After the handshake, you can call + * mbedtls_ssl_get_version_number() to see what version was + * negotiated. + * + * \param conf SSL configuration + * \param tls_version TLS protocol version number (\p mbedtls_ssl_protocol_version) + * (#MBEDTLS_SSL_VERSION_UNKNOWN is not valid) + */ +static inline void mbedtls_ssl_conf_max_tls_version( mbedtls_ssl_config *conf, + mbedtls_ssl_protocol_version tls_version ) +{ + conf->MBEDTLS_PRIVATE(max_tls_version) = tls_version; +} + /** * \brief Set the minimum accepted SSL/TLS protocol version * @@ -3880,6 +3896,24 @@ void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int mino */ void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor ); +/** + * \brief Set the minimum supported version sent from the client side + * and/or accepted at the server side. + * + * \note After the handshake, you can call + * mbedtls_ssl_get_version_number() to see what version was + * negotiated. + * + * \param conf SSL configuration + * \param tls_version TLS protocol version number (\p mbedtls_ssl_protocol_version) + * (#MBEDTLS_SSL_VERSION_UNKNOWN is not valid) + */ +static inline void mbedtls_ssl_conf_min_tls_version( mbedtls_ssl_config *conf, + mbedtls_ssl_protocol_version tls_version ) +{ + conf->MBEDTLS_PRIVATE(min_tls_version) = tls_version; +} + #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) /** * \brief Enable or disable Encrypt-then-MAC diff --git a/library/ssl_client.c b/library/ssl_client.c index 39b65e8413..6177906d72 100644 --- a/library/ssl_client.c +++ b/library/ssl_client.c @@ -864,8 +864,8 @@ static int ssl_prepare_client_hello( mbedtls_ssl_context *ssl ) } else { - ssl->minor_ver = ssl->conf->max_minor_ver; - ssl->handshake->min_minor_ver = ssl->conf->min_minor_ver; + ssl->minor_ver = ssl->conf->max_tls_version & 0xFF; + ssl->handshake->min_minor_ver = ssl->conf->min_tls_version & 0xFF; } } diff --git a/library/ssl_misc.h b/library/ssl_misc.h index af3aa5d8bc..1abe8eb831 100644 --- a/library/ssl_misc.h +++ b/library/ssl_misc.h @@ -1601,14 +1601,8 @@ void mbedtls_ssl_flight_free( mbedtls_ssl_flight_item *flight ); #if defined(MBEDTLS_SSL_PROTO_TLS1_3) static inline int mbedtls_ssl_conf_is_tls13_only( const mbedtls_ssl_config *conf ) { - if( conf->min_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 && - conf->max_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 && - conf->min_minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 && - conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 ) - { - return( 1 ); - } - return( 0 ); + return( conf->min_tls_version == MBEDTLS_SSL_VERSION_TLS1_3 && + conf->max_tls_version == MBEDTLS_SSL_VERSION_TLS1_3 ); } #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ @@ -1616,14 +1610,8 @@ static inline int mbedtls_ssl_conf_is_tls13_only( const mbedtls_ssl_config *conf #if defined(MBEDTLS_SSL_PROTO_TLS1_2) static inline int mbedtls_ssl_conf_is_tls12_only( const mbedtls_ssl_config *conf ) { - if( conf->min_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 && - conf->max_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 && - conf->min_minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 && - conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) - { - return( 1 ); - } - return( 0 ); + return( conf->min_tls_version == MBEDTLS_SSL_VERSION_TLS1_2 && + conf->max_tls_version == MBEDTLS_SSL_VERSION_TLS1_2 ); } #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ @@ -1631,14 +1619,8 @@ static inline int mbedtls_ssl_conf_is_tls12_only( const mbedtls_ssl_config *conf static inline int mbedtls_ssl_conf_is_tls13_enabled( const mbedtls_ssl_config *conf ) { #if defined(MBEDTLS_SSL_PROTO_TLS1_3) - if( conf->min_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 && - conf->max_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 && - conf->min_minor_ver <= MBEDTLS_SSL_MINOR_VERSION_4 && - conf->max_minor_ver >= MBEDTLS_SSL_MINOR_VERSION_4 ) - { - return( 1 ); - } - return( 0 ); + return( conf->min_tls_version <= MBEDTLS_SSL_VERSION_TLS1_3 && + conf->max_tls_version >= MBEDTLS_SSL_VERSION_TLS1_3 ); #else ((void) conf); return( 0 ); @@ -1648,14 +1630,8 @@ static inline int mbedtls_ssl_conf_is_tls13_enabled( const mbedtls_ssl_config *c static inline int mbedtls_ssl_conf_is_tls12_enabled( const mbedtls_ssl_config *conf ) { #if defined(MBEDTLS_SSL_PROTO_TLS1_2) - if( conf->min_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 && - conf->max_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 && - conf->min_minor_ver <= MBEDTLS_SSL_MINOR_VERSION_3 && - conf->max_minor_ver >= MBEDTLS_SSL_MINOR_VERSION_3 ) - { - return( 1 ); - } - return( 0 ); + return( conf->min_tls_version <= MBEDTLS_SSL_VERSION_TLS1_2 && + conf->max_tls_version >= MBEDTLS_SSL_VERSION_TLS1_2 ); #else ((void) conf); return( 0 ); @@ -1665,14 +1641,8 @@ static inline int mbedtls_ssl_conf_is_tls12_enabled( const mbedtls_ssl_config *c #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_TLS1_3) static inline int mbedtls_ssl_conf_is_hybrid_tls12_tls13( const mbedtls_ssl_config *conf ) { - if( conf->min_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 && - conf->max_major_ver == MBEDTLS_SSL_MAJOR_VERSION_3 && - conf->min_minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 && - conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 ) - { - return( 1 ); - } - return( 0 ); + return( conf->min_tls_version == MBEDTLS_SSL_VERSION_TLS1_2 && + conf->max_tls_version == MBEDTLS_SSL_VERSION_TLS1_3 ); } #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_SSL_PROTO_TLS1_3 */ diff --git a/library/ssl_msg.c b/library/ssl_msg.c index 8053e7613b..c79fcfa6ff 100644 --- a/library/ssl_msg.c +++ b/library/ssl_msg.c @@ -3541,7 +3541,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context const *ssl, return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } - if( minor_ver > ssl->conf->max_minor_ver ) + if( minor_ver > ( ssl->conf->max_tls_version & 0xFF ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); diff --git a/library/ssl_tls.c b/library/ssl_tls.c index fa6220dbe9..b3f132d6f4 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -2155,14 +2155,12 @@ void mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ss void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor ) { - conf->max_major_ver = major; - conf->max_minor_ver = minor; + conf->max_tls_version = (major << 8) | minor; } void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor ) { - conf->min_major_ver = major; - conf->min_minor_ver = minor; + conf->min_tls_version = (major << 8) | minor; } #if defined(MBEDTLS_SSL_SRV_C) @@ -3577,10 +3575,8 @@ static int ssl_context_load( mbedtls_ssl_context *ssl, * least check it matches the requirements for serializing. */ if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM || - ssl->conf->max_major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 || - ssl->conf->min_major_ver > MBEDTLS_SSL_MAJOR_VERSION_3 || - ssl->conf->max_minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 || - ssl->conf->min_minor_ver > MBEDTLS_SSL_MINOR_VERSION_3 || + ssl->conf->max_tls_version < MBEDTLS_SSL_VERSION_TLS1_2 || + ssl->conf->min_tls_version > MBEDTLS_SSL_VERSION_TLS1_2 || #if defined(MBEDTLS_SSL_RENEGOTIATION) ssl->conf->disable_renegotiation != MBEDTLS_SSL_RENEGOTIATION_DISABLED || #endif @@ -4250,6 +4246,32 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, conf->tls13_kex_modes = MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_ALL; #endif /* MBEDTLS_SSL_PROTO_TLS1_3 */ + if( ( endpoint == MBEDTLS_SSL_IS_SERVER ) || + ( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ) + { +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + conf->min_tls_version = MBEDTLS_SSL_VERSION_TLS1_2; + conf->max_tls_version = MBEDTLS_SSL_VERSION_TLS1_2; +#else + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); +#endif + } + else + { +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_TLS1_3) + conf->min_tls_version = MBEDTLS_SSL_VERSION_TLS1_2; + conf->max_tls_version = MBEDTLS_SSL_VERSION_TLS1_3; +#elif defined(MBEDTLS_SSL_PROTO_TLS1_3) + conf->min_tls_version = MBEDTLS_SSL_VERSION_TLS1_3; + conf->max_tls_version = MBEDTLS_SSL_VERSION_TLS1_3; +#elif defined(MBEDTLS_SSL_PROTO_TLS1_2) + conf->min_tls_version = MBEDTLS_SSL_VERSION_TLS1_2; + conf->max_tls_version = MBEDTLS_SSL_VERSION_TLS1_2; +#else + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); +#endif + } + /* * Preset-specific defaults */ @@ -4259,30 +4281,7 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, * NSA Suite B */ case MBEDTLS_SSL_PRESET_SUITEB: - conf->min_major_ver = MBEDTLS_SSL_MIN_MAJOR_VERSION; - conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION; - if( ( endpoint == MBEDTLS_SSL_IS_SERVER ) || - ( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ) -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - { - conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; - conf->max_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; - } -#else - { - conf->min_major_ver = 0; - conf->max_major_ver = 0; - conf->min_minor_ver = 0; - conf->max_minor_ver = 0; - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); - } -#endif - else - { - conf->min_minor_ver = MBEDTLS_SSL_MIN_MINOR_VERSION; - conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION; - } conf->ciphersuite_list = ssl_preset_suiteb_ciphersuites; #if defined(MBEDTLS_X509_CRT_PARSE_C) @@ -4311,30 +4310,6 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, * Default */ default: - conf->min_major_ver = MBEDTLS_SSL_MIN_MAJOR_VERSION; - conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION; - - if( ( endpoint == MBEDTLS_SSL_IS_SERVER ) || - ( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ) -#if defined(MBEDTLS_SSL_PROTO_TLS1_2) - { - conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; - conf->max_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; - } -#else - { - conf->min_major_ver = 0; - conf->max_major_ver = 0; - conf->min_minor_ver = 0; - conf->max_minor_ver = 0; - return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); - } -#endif - else - { - conf->min_minor_ver = MBEDTLS_SSL_MIN_MINOR_VERSION; - conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION; - } conf->ciphersuite_list = mbedtls_ssl_list_ciphersuites(); diff --git a/library/ssl_tls12_client.c b/library/ssl_tls12_client.c index f0a58db742..1607a8b65d 100644 --- a/library/ssl_tls12_client.c +++ b/library/ssl_tls12_client.c @@ -1155,8 +1155,7 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl ) */ if( major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 || minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 || - major_ver > ssl->conf->max_major_ver || - minor_ver > ssl->conf->max_minor_ver ) + ( ( major_ver << 8 ) | minor_ver ) > ssl->conf->max_tls_version ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server version" ) ); @@ -1302,18 +1301,16 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) ssl->conf->transport, buf + 0 ); ssl->session_negotiate->tls_version = 0x0300 | ssl->minor_ver; - if( ssl->major_ver < ssl->conf->min_major_ver || - ssl->minor_ver < ssl->conf->min_minor_ver || - ssl->major_ver > ssl->conf->max_major_ver || - ssl->minor_ver > ssl->conf->max_minor_ver ) + if( ( ( ssl->major_ver << 8 ) | ssl->minor_ver ) + < ssl->conf->min_tls_version || + ( ( ssl->major_ver << 8 ) | ssl->minor_ver ) + > ssl->conf->max_tls_version ) { MBEDTLS_SSL_DEBUG_MSG( 1, - ( "server version out of bounds - min: [%d:%d], server: [%d:%d], max: [%d:%d]", - ssl->conf->min_major_ver, - ssl->conf->min_minor_ver, - ssl->major_ver, ssl->minor_ver, - ssl->conf->max_major_ver, - ssl->conf->max_minor_ver ) ); + ( "server version out of bounds - min: [0x%x], server: [0x%x], max: [0x%x]", + (unsigned)ssl->conf->min_tls_version, + (unsigned)( ( ssl->major_ver << 8 ) | ssl->minor_ver ), + (unsigned)ssl->conf->max_tls_version ) ); mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function index da42cd977c..c730704a58 100644 --- a/tests/suites/test_suite_ssl.function +++ b/tests/suites/test_suite_ssl.function @@ -1179,16 +1179,16 @@ void set_ciphersuite( mbedtls_ssl_config *conf, const char *cipher, mbedtls_ssl_ciphersuite_from_id( forced_ciphersuite[0] ); TEST_ASSERT( ciphersuite_info != NULL ); - TEST_ASSERT( ciphersuite_info->min_minor_ver <= conf->max_minor_ver ); - TEST_ASSERT( ciphersuite_info->max_minor_ver >= conf->min_minor_ver ); + TEST_ASSERT( ciphersuite_info->min_minor_ver <= ( conf->max_tls_version & 0xFF ) ); + TEST_ASSERT( ciphersuite_info->max_minor_ver >= ( conf->min_tls_version & 0xFF ) ); - if( conf->max_minor_ver > ciphersuite_info->max_minor_ver ) + if( conf->max_tls_version > ( 0x0300 | ciphersuite_info->max_minor_ver ) ) { - conf->max_minor_ver = ciphersuite_info->max_minor_ver; + conf->max_tls_version = 0x0300 | ciphersuite_info->max_minor_ver; } - if( conf->min_minor_ver < ciphersuite_info->min_minor_ver ) + if( conf->min_tls_version < ( 0x0300 | ciphersuite_info->min_minor_ver ) ) { - conf->min_minor_ver = ciphersuite_info->min_minor_ver; + conf->min_tls_version = 0x0300 | ciphersuite_info->min_minor_ver; } mbedtls_ssl_conf_ciphersuites( conf, forced_ciphersuite );