diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index b3b5d47f8..7893edd13 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -169,6 +169,15 @@ /** Invalid value in SSL config */ #define MBEDTLS_ERR_SSL_BAD_CONFIG -0x5E80 +/* + * Constants from RFC 8446 for TLS 1.3 PSK modes + * + * Those are used in the Pre-Shared Key Exchange Modes extension. + * See Section 4.2.9 in RFC 8446. + */ +#define MBEDTLS_SSL_TLS1_3_PSK_MODE_PURE 0 /* Pure PSK-based exchange */ +#define MBEDTLS_SSL_TLS1_3_PSK_MODE_ECDHE 1 /* PSK+ECDHE-based exchange */ + /* * TLS 1.3 NamedGroup values * diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c index 7d99433a9..7c28c578c 100644 --- a/library/ssl_tls13_server.c +++ b/library/ssl_tls13_server.c @@ -45,6 +45,60 @@ #include "ssl_tls13_keys.h" #include "ssl_debug_helpers.h" +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) +/* From RFC 8446: + * + * enum { psk_ke(0), psk_dhe_ke(1), (255) } PskKeyExchangeMode; + * struct { + * PskKeyExchangeMode ke_modes<1..255>; + * } PskKeyExchangeModes; + */ +static int ssl_tls13_parse_key_exchange_modes_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + const unsigned char *end ) +{ + const unsigned char *p = buf; + size_t ke_modes_len; + int ke_modes = 0; + + /* Read ke_modes length (1 Byte) */ + MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, 1 ); + ke_modes_len = *p++; + /* Currently, there are only two PSK modes, so even without looking + * at the content, something's wrong if the list has more than 2 items. */ + if( ke_modes_len > 2 ) + { + MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, + MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER ); + return( MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE ); + } + + MBEDTLS_SSL_CHK_BUF_READ_PTR( p, end, ke_modes_len ); + + while( ke_modes_len-- != 0 ) + { + switch( *p++ ) + { + case MBEDTLS_SSL_TLS1_3_PSK_MODE_PURE: + ke_modes |= MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK; + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Found PSK KEX MODE" ) ); + break; + case MBEDTLS_SSL_TLS1_3_PSK_MODE_ECDHE: + ke_modes |= MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL; + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Found PSK_EPHEMERAL KEX MODE" ) ); + break; + default: + MBEDTLS_SSL_PEND_FATAL_ALERT( MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER, + MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER ); + return( MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER ); + } + } + + ssl->handshake->tls13_kex_modes = ke_modes; + return( 0 ); +} +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ + /* From RFC 8446: * struct { * ProtocolVersion versions<2..254>; @@ -754,6 +808,23 @@ static int ssl_tls13_parse_client_hello( mbedtls_ssl_context *ssl, ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_SUPPORTED_VERSIONS; break; +#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) + case MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found psk key exchange modes extension" ) ); + + ret = ssl_tls13_parse_key_exchange_modes_ext( + ssl, p, extension_data_end ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( + 1, "ssl_tls13_parse_key_exchange_modes_ext", ret ); + return( ret ); + } + + ssl->handshake->extensions_present |= MBEDTLS_SSL_EXT_PSK_KEY_EXCHANGE_MODES; + break; +#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ + #if defined(MBEDTLS_SSL_ALPN) case MBEDTLS_TLS_EXT_ALPN: MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) ); diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 80b7806e7..68a2d778b 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -878,7 +878,9 @@ wait_client_done() { CLI_EXIT=$? kill $DOG_PID >/dev/null 2>&1 - wait $DOG_PID + # For Ubuntu 22.04, `Terminated` message is outputed by wait command. + # To remove it from stdout, redirect stdout/stderr to CLI_OUT + wait $DOG_PID >> $CLI_OUT 2>&1 echo "EXIT: $CLI_EXIT" >> $CLI_OUT @@ -2229,41 +2231,86 @@ run_test "SHA-256 allowed by default in client certificate" \ # ssl_client2/ssl_server2 example programs works. requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_config_enabled MBEDTLS_SSL_SRV_C run_test "TLS 1.3: key exchange mode parameter passing: PSK only" \ "$P_SRV tls13_kex_modes=psk debug_level=4" \ "$P_CLI tls13_kex_modes=psk debug_level=4" \ 0 + requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_config_enabled MBEDTLS_SSL_SRV_C 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_2 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_config_enabled MBEDTLS_SSL_SRV_C 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_2 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_config_enabled MBEDTLS_SSL_SRV_C 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_2 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_config_enabled MBEDTLS_SSL_SRV_C 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_2 requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_SSL_CLI_C +requires_config_enabled MBEDTLS_SSL_SRV_C run_test "TLS 1.3: key exchange mode parameter passing: All" \ "$P_SRV tls13_kex_modes=all" \ "$P_CLI tls13_kex_modes=all" \ 0 +requires_openssl_tls1_3 +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_enabled MBEDTLS_DEBUG_C +run_test "TLS 1.3: psk_key_exchange_modes: basic check, O->m" \ + "$P_SRV force_version=tls13 debug_level=5" \ + "$O_NEXT_CLI -tls1_3 -psk 6162636465666768696a6b6c6d6e6f70 -allow_no_dhe_kex" \ + 0 \ + -s "found psk key exchange modes extension" \ + -s "Found PSK_EPHEMERAL KEX MODE" \ + -s "Found PSK KEX MODE" + +requires_gnutls_tls1_3 +requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3 +requires_config_enabled MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE +requires_config_enabled MBEDTLS_SSL_SRV_C +requires_config_enabled MBEDTLS_DEBUG_C +run_test "TLS 1.3: psk_key_exchange_modes: basic check, G->m" \ + "$P_SRV force_version=tls13 debug_level=5" \ + "$G_NEXT_CLI --priority NORMAL:-VERS-ALL:+VERS-TLS1.3 \ + --pskusername Client_identity --pskkey=6162636465666768696a6b6c6d6e6f70 \ + localhost" \ + 0 \ + -s "found psk key exchange modes extension" \ + -s "Found PSK_EPHEMERAL KEX MODE" \ + -s "Found PSK KEX MODE" + # Tests for datagram packing requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2 run_test "DTLS: multiple records in same datagram, client and server" \