diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 3cb896cb4c..2909dc8e5b 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -169,6 +169,35 @@ /** Invalid value in SSL config */ #define MBEDTLS_ERR_SSL_BAD_CONFIG -0x5E80 +/* + * TLS 1.3 Key Exchange Modes + * + * Mbed TLS internal identifiers for use with the SSL configuration API + * mbedtls_ssl_conf_tls13_key_exchange_modes(). + */ + +#define MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK ( 1u << 0 ) /*!< Pure-PSK TLS 1.3 key exchange, + * encompassing both externally agreed PSKs + * as well as resumption PSKs. */ +#define MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL ( 1u << 1 ) /*!< Pure-Ephemeral TLS 1.3 key exchanges, + * including for example ECDHE and DHE + * key exchanges. */ +#define MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_EPHEMERAL ( 1u << 2 ) /*!< PSK-Ephemeral TLS 1.3 key exchanges, + * using both a PSK and an ephemeral + * key exchange. */ + +/* Convenience macros for sets of key exchanges. */ +#define MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_ALL \ + ( MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK | \ + MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_EPHEMERAL | \ + MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL ) /*!< All TLS 1.3 key exchanges */ +#define MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_ALL \ + ( MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK | \ + MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_EPHEMERAL ) /*!< All PSK-based TLS 1.3 key exchanges */ +#define MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL_ALL \ + ( MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL | \ + MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_EPHEMERAL ) /*!< All ephemeral TLS 1.3 key exchanges */ + /* * Various constants */ @@ -1111,6 +1140,11 @@ struct mbedtls_ssl_config /** Allowed ciphersuites for (D)TLS 1.2 (0-terminated) */ const int *MBEDTLS_PRIVATE(ciphersuite_list); +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + /** Allowed TLS 1.3 key exchange modes. */ + int MBEDTLS_PRIVATE(tls13_kex_modes); +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + /** Callback for printing debug output */ void (*MBEDTLS_PRIVATE(f_dbg))(void *, int, const char *, int, const char *); void *MBEDTLS_PRIVATE(p_dbg); /*!< context for the debug function */ @@ -2579,23 +2613,93 @@ int mbedtls_ssl_session_save( const mbedtls_ssl_session *session, /** * \brief Set the list of allowed ciphersuites and the preference * order. First in the list has the highest preference. - * (Overrides all version-specific lists) * - * The ciphersuites array is not copied, and must remain - * valid for the lifetime of the ssl_config. + * For TLS 1.2, the notion of ciphersuite determines both + * the key exchange mechanism and the suite of symmetric + * algorithms to be used during and after the handshake. * - * Note: By default, the server chooses its preferred + * For TLS 1.3 (in development), the notion of ciphersuite + * only determines the suite of symmetric algorithms to be + * used during and after the handshake, while key exchange + * mechanisms are configured separately. + * + * In Mbed TLS, ciphersuites for both TLS 1.2 and TLS 1.3 + * are configured via this function. For users of TLS 1.3, + * there will be separate API for the configuration of key + * exchange mechanisms. + * + * The list of ciphersuites passed to this function may + * contain a mixture of TLS 1.2 and TLS 1.3 ciphersuite + * identifiers. This is useful if negotiation of TLS 1.3 + * should be attempted, but a fallback to TLS 1.2 would + * be tolerated. + * + * \note By default, the server chooses its preferred * ciphersuite among those that the client supports. If * mbedtls_ssl_conf_preference_order() is called to prefer * the client's preferences, the server instead chooses * the client's preferred ciphersuite among those that * the server supports. * - * \param conf SSL configuration - * \param ciphersuites 0-terminated list of allowed ciphersuites + * \warning The ciphersuites array \p ciphersuites is not copied. + * It must remain valid for the lifetime of the SSL + * configuration \p conf. + * + * \param conf The SSL configuration to modify. + * \param ciphersuites A 0-terminated list of IANA identifiers of supported + * ciphersuites, accessible through \c MBEDTLS_TLS_XXX + * and \c MBEDTLS_TLS1_3_XXX macros defined in + * ssl_ciphersuites.h. */ void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf, - const int *ciphersuites ); + const int *ciphersuites ); + +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) +/** + * \brief Set the supported key exchange modes for TLS 1.3 connections. + * + * In contrast to TLS 1.2, the ciphersuite concept in TLS 1.3 does not + * include the choice of key exchange mechanism. It is therefore not + * covered by the API mbedtls_ssl_conf_ciphersuites(). See the + * documentation of mbedtls_ssl_conf_ciphersuites() for more + * information on the ciphersuite concept in TLS 1.2 and TLS 1.3. + * + * The present function is specific to TLS 1.3 and allows users to + * configure the set of supported key exchange mechanisms in TLS 1.3. + * + * \param conf The SSL configuration the change should apply to. + * \param kex_modes A bitwise combination of one or more of the following: + * - MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK + * This flag enables pure-PSK key exchanges. + * - MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_EPHEMERAL + * This flag enables combined PSK-ephemeral key exchanges. + * - MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL + * This flag enables pure-ephemeral key exchanges. + * For convenience, the following pre-defined macros are + * available for combinations of the above: + * - MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_ALL + * Includes all of pure-PSK, PSK-ephemeral and pure-ephemeral. + * - MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_ALL + * Includes both pure-PSK and combined PSK-ephemeral + * key exchanges, but excludes pure-ephemeral key exchanges. + * - MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL_ALL + * Includes both pure-ephemeral and combined PSK-ephemeral + * key exchanges. + * + * \note If a PSK-based key exchange mode shall be supported, applications + * must also use the APIs mbedtls_ssl_conf_psk() or + * mbedtls_ssl_conf_psk_cb() or mbedtls_ssl_conf_psk_opaque() + * to configure the PSKs to be used. + * + * \note If a pure-ephemeral key exchange mode shall be supported, + * server-side applications must also provide a certificate via + * mbedtls_ssl_conf_own_cert(). + * + */ + +void mbedtls_ssl_conf_tls13_key_exchange_modes( mbedtls_ssl_config* conf, + const int kex_modes ); +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) #define MBEDTLS_SSL_UNEXPECTED_CID_IGNORE 0 diff --git a/include/mbedtls/ssl_ciphersuites.h b/include/mbedtls/ssl_ciphersuites.h index 812560c8a1..18e7c98767 100644 --- a/include/mbedtls/ssl_ciphersuites.h +++ b/include/mbedtls/ssl_ciphersuites.h @@ -256,6 +256,13 @@ extern "C" { #define MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAD /**< TLS 1.2 */ #define MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAE /**< TLS 1.2 */ +/* RFC 8446, Appendix B.4 */ +#define MBEDTLS_TLS1_3_AES_128_GCM_SHA256 0x1301 /**< TLS 1.3 */ +#define MBEDTLS_TLS1_3_AES_256_GCM_SHA384 0x1302 /**< TLS 1.3 */ +#define MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256 0x1303 /**< TLS 1.3 */ +#define MBEDTLS_TLS1_3_AES_128_CCM_SHA256 0x1304 /**< TLS 1.3 */ +#define MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256 0x1305 /**< TLS 1.3 */ + /* Reminder: update mbedtls_ssl_premaster_secret when adding a new key exchange. * Reminder: update MBEDTLS_KEY_EXCHANGE__xxx below */ diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c index a3ee157d50..b10a9634ef 100644 --- a/library/ssl_ciphersuites.c +++ b/library/ssl_ciphersuites.c @@ -52,6 +52,15 @@ static const int ciphersuite_preference[] = #if defined(MBEDTLS_SSL_CIPHERSUITES) MBEDTLS_SSL_CIPHERSUITES, #else +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + /* TLS 1.3 ciphersuites */ + MBEDTLS_TLS1_3_AES_128_GCM_SHA256, + MBEDTLS_TLS1_3_AES_256_GCM_SHA384, + MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256, + MBEDTLS_TLS1_3_AES_128_CCM_SHA256, + MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256, +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + /* Chacha-Poly ephemeral suites */ MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, @@ -283,6 +292,52 @@ static const int ciphersuite_preference[] = static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] = { +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA384_C) + { MBEDTLS_TLS1_3_AES_256_GCM_SHA384, "TLS1-3-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, + MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */ + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4, + 0 }, +#endif /* MBEDTLS_SHA384_C */ +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS1_3_AES_128_GCM_SHA256, "TLS1-3-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, + MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */ + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4, + 0 }, +#endif /* MBEDTLS_SHA256_C */ +#endif /* MBEDTLS_GCM_C */ +#if defined(MBEDTLS_CCM_C) && defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS1_3_AES_128_CCM_SHA256, "TLS1-3-AES-128-CCM-SHA256", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, + MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */ + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4, + 0 }, + { MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256, "TLS1-3-AES-128-CCM-8-SHA256", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, + MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */ + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, +#endif /* MBEDTLS_SHA256_C && MBEDTLS_CCM_C */ +#endif /* MBEDTLS_AES_C */ +#if defined(MBEDTLS_CHACHAPOLY_C) && defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256, + "TLS1-3-CHACHA20-POLY1305-SHA256", + MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, + MBEDTLS_KEY_EXCHANGE_NONE, /* Key exchange not part of ciphersuite in TLS 1.3 */ + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_4, + 0 }, +#endif /* MBEDTLS_CHACHAPOLY_C && MBEDTLS_SHA256_C */ +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + #if defined(MBEDTLS_CHACHAPOLY_C) && \ defined(MBEDTLS_SHA256_C) && \ defined(MBEDTLS_SSL_PROTO_TLS1_2) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 5cd47e6ce5..07b51003ab 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -3550,6 +3550,14 @@ void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf, conf->ciphersuite_list = ciphersuites; } +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) +void mbedtls_ssl_conf_tls13_key_exchange_modes( mbedtls_ssl_config *conf, + const int kex_modes ) +{ + conf->tls13_kex_modes = kex_modes & MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_ALL; +} +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + #if defined(MBEDTLS_X509_CRT_PARSE_C) void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf, const mbedtls_x509_crt_profile *profile ) @@ -6393,22 +6401,29 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, #endif #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) - if( endpoint == MBEDTLS_SSL_IS_SERVER ) - { - const unsigned char dhm_p[] = - MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN; - const unsigned char dhm_g[] = - MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN; + if( endpoint == MBEDTLS_SSL_IS_SERVER ) + { + const unsigned char dhm_p[] = + MBEDTLS_DHM_RFC3526_MODP_2048_P_BIN; + const unsigned char dhm_g[] = + MBEDTLS_DHM_RFC3526_MODP_2048_G_BIN; - if ( ( ret = mbedtls_ssl_conf_dh_param_bin( conf, - dhm_p, sizeof( dhm_p ), - dhm_g, sizeof( dhm_g ) ) ) != 0 ) - { - return( ret ); - } - } + if ( ( ret = mbedtls_ssl_conf_dh_param_bin( conf, + dhm_p, sizeof( dhm_p ), + dhm_g, sizeof( dhm_g ) ) ) != 0 ) + { + return( ret ); + } + } #endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + /* + * Allow all TLS 1.3 key exchange modes by default. + */ + conf->tls13_kex_modes = MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_ALL; +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + /* * Preset-specific defaults */ diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 1400961b8c..a970503c87 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -65,6 +65,7 @@ int main( void ) #define DFL_ECJPAKE_PW NULL #define DFL_EC_MAX_OPS -1 #define DFL_FORCE_CIPHER 0 +#define DFL_TLS13_KEX_MODES MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_ALL #define DFL_RENEGOTIATION MBEDTLS_SSL_RENEGOTIATION_DISABLED #define DFL_ALLOW_LEGACY -2 #define DFL_RENEGOTIATE 0 @@ -345,6 +346,14 @@ int main( void ) #define USAGE_SERIALIZATION "" #endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) +#define USAGE_TLS13_KEY_EXCHANGE_MODES \ + " tls13_kex_modes=%%s default: all\n" \ + " options: psk, psk_ephemeral, ephemeral, ephemeral_all, psk_all, all\n" +#else +#define USAGE_TLS13_KEY_EXCHANGE_MODES "" +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + /* USAGE is arbitrarily split to stay under the portable string literal * length limit: 4095 bytes in C99. */ #define USAGE1 \ @@ -414,18 +423,19 @@ int main( void ) #endif /* !MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ #define USAGE4 \ - " allow_sha1=%%d default: 0\n" \ - " min_version=%%s default: (library default: tls1_2)\n" \ - " max_version=%%s default: (library default: tls1_2)\n" \ - " force_version=%%s default: \"\" (none)\n" \ + " allow_sha1=%%d default: 0\n" \ + " min_version=%%s default: (library default: tls1_2)\n" \ + " max_version=%%s default: (library default: tls1_2)\n" \ + " force_version=%%s default: \"\" (none)\n" \ " options: tls1_2, dtls1_2" TLS1_3_VERSION_OPTIONS \ - "\n\n" \ - " force_ciphersuite= default: all enabled\n"\ - " query_config= return 0 if the specified\n" \ + "\n\n" \ + " force_ciphersuite= default: all enabled\n" \ + USAGE_TLS13_KEY_EXCHANGE_MODES \ + " query_config= return 0 if the specified\n" \ " configuration macro is defined and 1\n" \ " otherwise. The expansion of the macro\n" \ - " is printed if it is defined\n" \ - USAGE_SERIALIZATION \ + " is printed if it is defined\n" \ + USAGE_SERIALIZATION \ " acceptable ciphersuite names:\n" #define ALPN_LIST_SIZE 10 @@ -464,6 +474,9 @@ struct options const char *ecjpake_pw; /* the EC J-PAKE password */ int ec_max_ops; /* EC consecutive operations limit */ int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + int tls13_kex_modes; /* supported TLS 1.3 key exchange modes */ +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ int renegotiation; /* enable / disable renegotiation */ int allow_legacy; /* allow legacy renegotiation */ int renegotiate; /* attempt renegotiation? */ @@ -832,6 +845,9 @@ int main( int argc, char *argv[] ) opt.ecjpake_pw = DFL_ECJPAKE_PW; opt.ec_max_ops = DFL_EC_MAX_OPS; opt.force_ciphersuite[0]= DFL_FORCE_CIPHER; +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + opt.tls13_kex_modes = DFL_TLS13_KEX_MODES; +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ opt.renegotiation = DFL_RENEGOTIATION; opt.allow_legacy = DFL_ALLOW_LEGACY; opt.renegotiate = DFL_RENEGOTIATE; @@ -1097,6 +1113,24 @@ int main( int argc, char *argv[] ) default: goto usage; } } +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + else if( strcmp( p, "tls13_kex_modes" ) == 0 ) + { + if( strcmp( q, "psk" ) == 0 ) + opt.tls13_kex_modes = MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK; + else if( strcmp(q, "psk_ephemeral" ) == 0 ) + opt.tls13_kex_modes = MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_EPHEMERAL; + else if( strcmp(q, "ephemeral" ) == 0 ) + opt.tls13_kex_modes = MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL; + else if( strcmp(q, "ephemeral_all" ) == 0 ) + opt.tls13_kex_modes = MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL_ALL; + else if( strcmp( q, "psk_all" ) == 0 ) + opt.tls13_kex_modes = MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_ALL; + else if( strcmp( q, "all" ) == 0 ) + opt.tls13_kex_modes = MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_ALL; + else goto usage; + } +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ else if( strcmp( p, "min_version" ) == 0 ) { if( strcmp( q, "tls1_2" ) == 0 || @@ -1827,6 +1861,10 @@ int main( int argc, char *argv[] ) if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER ) mbedtls_ssl_conf_ciphersuites( &conf, opt.force_ciphersuite ); +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + mbedtls_ssl_conf_tls13_key_exchange_modes( &conf, opt.tls13_kex_modes ); +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + if( opt.allow_legacy != DFL_ALLOW_LEGACY ) mbedtls_ssl_conf_legacy_renegotiation( &conf, opt.allow_legacy ); #if defined(MBEDTLS_SSL_RENEGOTIATION) diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index b9a789e729..e8e4ed8aea 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -95,6 +95,7 @@ int main( void ) #define DFL_ECJPAKE_PW NULL #define DFL_PSK_LIST NULL #define DFL_FORCE_CIPHER 0 +#define DFL_TLS13_KEX_MODES MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_ALL #define DFL_RENEGOTIATION MBEDTLS_SSL_RENEGOTIATION_DISABLED #define DFL_ALLOW_LEGACY -2 #define DFL_RENEGOTIATE 0 @@ -442,6 +443,15 @@ int main( void ) #define USAGE_SERIALIZATION "" #endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) +#define USAGE_TLS13_KEY_EXCHANGE_MODES \ + " tls13_kex_modes=%%s default: all\n" \ + " options: psk, psk_ephemeral, ephemeral, ephemeral_all, psk_all, all\n" +#else +#define USAGE_TLS13_KEY_EXCHANGE_MODES "" +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + + /* USAGE is arbitrarily split to stay under the portable string literal * length limit: 4095 bytes in C99. */ #define USAGE1 \ @@ -506,18 +516,19 @@ int main( void ) #define USAGE4 \ USAGE_SSL_ASYNC \ USAGE_SNI \ - " allow_sha1=%%d default: 0\n" \ - " min_version=%%s default: (library default: tls1_2)\n" \ - " max_version=%%s default: (library default: tls1_2)\n" \ - " force_version=%%s default: \"\" (none)\n" \ + " allow_sha1=%%d default: 0\n" \ + " min_version=%%s default: (library default: tls1_2)\n" \ + " max_version=%%s default: (library default: tls1_2)\n" \ + " force_version=%%s default: \"\" (none)\n" \ " options: tls1_2, dtls1_2" TLS1_3_VERSION_OPTIONS \ - "\n\n" \ - " force_ciphersuite= default: all enabled\n" \ - " query_config= return 0 if the specified\n" \ + "\n\n" \ + " force_ciphersuite= default: all enabled\n" \ + USAGE_TLS13_KEY_EXCHANGE_MODES \ + " query_config= return 0 if the specified\n" \ " configuration macro is defined and 1\n" \ " otherwise. The expansion of the macro\n" \ - " is printed if it is defined\n" \ - USAGE_SERIALIZATION \ + " is printed if it is defined\n" \ + USAGE_SERIALIZATION \ " acceptable ciphersuite names:\n" #define ALPN_LIST_SIZE 10 @@ -576,6 +587,9 @@ struct options char *psk_list; /* list of PSK id/key pairs for callback */ const char *ecjpake_pw; /* the EC J-PAKE password */ int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + int tls13_kex_modes; /* supported TLS 1.3 key exchange modes */ +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ int renegotiation; /* enable / disable renegotiation */ int allow_legacy; /* allow legacy renegotiation */ int renegotiate; /* attempt renegotiation? */ @@ -1497,6 +1511,9 @@ int main( int argc, char *argv[] ) opt.psk_list = DFL_PSK_LIST; opt.ecjpake_pw = DFL_ECJPAKE_PW; opt.force_ciphersuite[0]= DFL_FORCE_CIPHER; +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + opt.tls13_kex_modes = DFL_TLS13_KEX_MODES; +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ opt.renegotiation = DFL_RENEGOTIATION; opt.allow_legacy = DFL_ALLOW_LEGACY; opt.renegotiate = DFL_RENEGOTIATE; @@ -1740,6 +1757,25 @@ int main( int argc, char *argv[] ) if( opt.exchanges < 0 ) goto usage; } +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + else if( strcmp( p, "tls13_kex_modes" ) == 0 ) + { + if( strcmp( q, "psk" ) == 0 ) + opt.tls13_kex_modes = MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK; + else if( strcmp(q, "psk_ephemeral" ) == 0 ) + opt.tls13_kex_modes = MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_EPHEMERAL; + else if( strcmp(q, "ephemeral" ) == 0 ) + opt.tls13_kex_modes = MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL; + else if( strcmp(q, "ephemeral_all" ) == 0 ) + opt.tls13_kex_modes = MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_EPHEMERAL_ALL; + else if( strcmp( q, "psk_all" ) == 0 ) + opt.tls13_kex_modes = MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_PSK_ALL; + else if( strcmp( q, "all" ) == 0 ) + opt.tls13_kex_modes = MBEDTLS_SSL_TLS13_KEY_EXCHANGE_MODE_ALL; + else goto usage; + } +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + else if( strcmp( p, "min_version" ) == 0 ) { if( strcmp( q, "tls1_2" ) == 0 || @@ -2690,6 +2726,10 @@ int main( int argc, char *argv[] ) if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER ) mbedtls_ssl_conf_ciphersuites( &conf, opt.force_ciphersuite ); +#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) + mbedtls_ssl_conf_tls13_key_exchange_modes( &conf, opt.tls13_kex_modes ); +#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */ + if( opt.allow_legacy != DFL_ALLOW_LEGACY ) mbedtls_ssl_conf_legacy_renegotiation( &conf, opt.allow_legacy ); #if defined(MBEDTLS_SSL_RENEGOTIATION) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index af05dd9418..a664df219e 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -2474,6 +2474,8 @@ component_test_tls13_experimental_with_padding () { make msg "test: default config with MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL enabled, with padding" make test + msg "ssl-opt.sh (TLS 1.3 experimental)" + if_build_succeeded tests/ssl-opt.sh } component_build_mingw () { diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 9ee6b761db..ad925f0f0c 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -1512,6 +1512,40 @@ run_test "SHA-256 allowed by default in client certificate" \ "$P_CLI key_file=data_files/cli-rsa.key crt_file=data_files/cli-rsa-sha256.crt" \ 0 +# Dummy TLS 1.3 test +# Currently only checking that passing TLS 1.3 key exchange modes to +# ssl_client2/ssl_server2 example programs works. +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL +run_test "TLS 1.3, key exchange mode parameter passing: PSK only" \ + "$P_SRV tls13_kex_modes=psk" \ + "$P_CLI tls13_kex_modes=psk" \ + 0 +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL +run_test "TLS 1.3, key exchange mode parameter passing: PSK-ephemeral only" \ + "$P_SRV tls13_kex_modes=psk_ephemeral" \ + "$P_CLI tls13_kex_modes=psk_ephemeral" \ + 0 +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL +run_test "TLS 1.3, key exchange mode parameter passing: Pure-ephemeral only" \ + "$P_SRV tls13_kex_modes=ephemeral" \ + "$P_CLI tls13_kex_modes=ephemeral" \ + 0 +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL +run_test "TLS 1.3, key exchange mode parameter passing: All ephemeral" \ + "$P_SRV tls13_kex_modes=ephemeral_all" \ + "$P_CLI tls13_kex_modes=ephemeral_all" \ + 0 +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL +run_test "TLS 1.3, key exchange mode parameter passing: All PSK" \ + "$P_SRV tls13_kex_modes=psk_all" \ + "$P_CLI tls13_kex_modes=psk_all" \ + 0 +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL +run_test "TLS 1.3, key exchange mode parameter passing: All" \ + "$P_SRV tls13_kex_modes=all" \ + "$P_CLI tls13_kex_modes=all" \ + 0 + # Tests for datagram packing run_test "DTLS: multiple records in same datagram, client and server" \ "$P_SRV dtls=1 dgram_packing=1 debug_level=2" \