Merge pull request #7887 from ronald-cron-arm/fix-hrr-in-psk-kem
tls13: server: Fix spurious HRR
diff --git a/ChangeLog.d/fix-hrr-in-psk-kem.txt b/ChangeLog.d/fix-hrr-in-psk-kem.txt
new file mode 100644
index 0000000..0377711
--- /dev/null
+++ b/ChangeLog.d/fix-hrr-in-psk-kem.txt
@@ -0,0 +1,5 @@
+Bugfix
+ * In TLS 1.3, fix handshake failure when a client in its ClientHello
+ proposes an handshake based on PSK only key exchange mode or at least
+ one of the key exchange modes using ephemeral keys to a server that
+ supports only the PSK key exchange mode.
diff --git a/library/ssl_tls13_server.c b/library/ssl_tls13_server.c
index 196d09a..5aeb358 100644
--- a/library/ssl_tls13_server.c
+++ b/library/ssl_tls13_server.c
@@ -1262,6 +1262,7 @@
const unsigned char *supported_versions_data_end;
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
int hrr_required = 0;
+ int no_usable_share_for_key_agreement = 0;
#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
const unsigned char *pre_shared_key_ext = NULL;
@@ -1577,8 +1578,8 @@
ret = ssl_tls13_parse_key_shares_ext(
ssl, p, extension_data_end);
if (ret == SSL_TLS1_3_PARSE_KEY_SHARES_EXT_NO_MATCH) {
- MBEDTLS_SSL_DEBUG_MSG(2, ("HRR needed "));
- hrr_required = 1;
+ MBEDTLS_SSL_DEBUG_MSG(2, ("No usable share for key agreement."));
+ no_usable_share_for_key_agreement = 1;
}
if (ret < 0) {
@@ -1736,6 +1737,11 @@
return ret;
}
+ if (ssl->handshake->key_exchange_mode !=
+ MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK) {
+ hrr_required = (no_usable_share_for_key_agreement != 0);
+ }
+
mbedtls_ssl_optimize_checksum(ssl, handshake->ciphersuite_info);
return hrr_required ? SSL_CLIENT_HELLO_HRR_REQUIRED : SSL_CLIENT_HELLO_OK;
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index 1e52dbe..cc1695d 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -13362,6 +13362,19 @@
-c "Verifying peer X.509 certificate... ok" \
-C "received HelloRetryRequest message"
+requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_3
+requires_config_enabled MBEDTLS_SSL_SRV_C
+requires_config_enabled MBEDTLS_SSL_CLI_C
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED
+requires_config_enabled MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED
+run_test "TLS 1.3: no HRR in case of PSK key exchange mode" \
+ "$P_SRV nbio=2 psk=010203 psk_identity=0a0b0c tls13_kex_modes=psk curves=none" \
+ "$P_CLI nbio=2 debug_level=3 psk=010203 psk_identity=0a0b0c tls13_kex_modes=all" \
+ 0 \
+ -C "received HelloRetryRequest message" \
+ -c "Selected key exchange mode: psk$" \
+ -c "HTTP/1.0 200 OK"
+
# Test heap memory usage after handshake
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
requires_config_enabled MBEDTLS_MEMORY_DEBUG