mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2026-09-21 17:47:24 +00:00
Merge pull request #1609 from minosgalanakis/security/mlfbyt4c_tls13_policy_bypass_3.6
Backport 3.6: TLS1.3 client HRR policy bypass[ARM-MLFBYT4C]
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
Security
|
||||
* Fix TLS 1.3 clients to reject a HelloRetryRequest whose selected group was
|
||||
not advertised in the original ClientHello. Reported by
|
||||
Din Asotić / Xiangdong Li, Beijing University of Posts and
|
||||
Telecommunications (BUPT)
|
||||
@@ -210,6 +210,10 @@ static int ssl_write_alpn_ext(mbedtls_ssl_context *ssl,
|
||||
* generalization of the TLS 1.2 supported elliptic curves extension. They both
|
||||
* share the same extension identifier.
|
||||
*
|
||||
* If the TLS 1.3 logic for selecting proposed groups changes, the TLS 1.3
|
||||
* group filtering in the function `ssl_tls13_parse_hrr_key_share_ext()` must
|
||||
* be updated accordingly.
|
||||
*
|
||||
*/
|
||||
#define SSL_WRITE_SUPPORTED_GROUPS_EXT_TLS1_2_FLAG 1
|
||||
#define SSL_WRITE_SUPPORTED_GROUPS_EXT_TLS1_3_FLAG 2
|
||||
@@ -253,8 +257,8 @@ static int ssl_write_supported_groups_ext(mbedtls_ssl_context *ssl,
|
||||
if (flags & SSL_WRITE_SUPPORTED_GROUPS_EXT_TLS1_3_FLAG) {
|
||||
#if defined(PSA_WANT_ALG_ECDH)
|
||||
if (mbedtls_ssl_tls13_named_group_is_ecdhe(*group_list) &&
|
||||
(mbedtls_ssl_get_ecp_group_id_from_tls_id(*group_list) !=
|
||||
MBEDTLS_ECP_DP_NONE)) {
|
||||
mbedtls_ssl_get_psa_curve_info_from_tls_id(
|
||||
*group_list, NULL, NULL) == PSA_SUCCESS) {
|
||||
propose_group = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -405,14 +405,18 @@ static int ssl_tls13_parse_hrr_key_share_ext(mbedtls_ssl_context *ssl,
|
||||
* then the client MUST abort the handshake with an "illegal_parameter" alert.
|
||||
*/
|
||||
for (; *group_list != 0; group_list++) {
|
||||
if (*group_list != selected_group) {
|
||||
continue;
|
||||
}
|
||||
#if defined(PSA_WANT_ALG_ECDH)
|
||||
if (mbedtls_ssl_tls13_named_group_is_ecdhe(*group_list)) {
|
||||
if ((mbedtls_ssl_get_psa_curve_info_from_tls_id(
|
||||
*group_list, NULL, NULL) == PSA_ERROR_NOT_SUPPORTED) ||
|
||||
*group_list != selected_group) {
|
||||
found = 1;
|
||||
break;
|
||||
if (mbedtls_ssl_get_psa_curve_info_from_tls_id(
|
||||
*group_list, NULL, NULL) == PSA_ERROR_NOT_SUPPORTED) {
|
||||
continue;
|
||||
}
|
||||
/* Found only if psa_curve is supported and group_list == selected_group */
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
#endif /* PSA_WANT_ALG_ECDH */
|
||||
#if defined(PSA_WANT_ALG_FFDH)
|
||||
|
||||
@@ -3347,6 +3347,9 @@ cookie_parsing:"16fefd0000000000000000002F010000de000000000000011efefd7b72727272
|
||||
TLS 1.3 srv Certificate msg - wrong vector lengths
|
||||
tls13_server_certificate_msg_invalid_vector_len
|
||||
|
||||
TLS 1.3 cli rejects HRR selecting an un-offered group
|
||||
reject_hrr_selecting_unoffered_group
|
||||
|
||||
EC-JPAKE set password
|
||||
depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
|
||||
ssl_ecjpake_set_password:0
|
||||
|
||||
@@ -3968,6 +3968,118 @@ exit:
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_SSL_PROTO_TLS1_3:MBEDTLS_SSL_CLI_C:MBEDTLS_SSL_SRV_C:MBEDTLS_TEST_AT_LEAST_ONE_TLS1_3_CIPHERSUITE:MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED:PSA_WANT_ALG_SHA_256:PSA_WANT_ALG_ECDH:MBEDTLS_PK_CAN_ECDSA_SIGN:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ECC_SECP_R1_384 */
|
||||
void reject_hrr_selecting_unoffered_group(void)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
mbedtls_test_ssl_endpoint client_ep, server_ep;
|
||||
mbedtls_test_handshake_test_options client_options, server_options;
|
||||
#if defined(MBEDTLS_DEBUG_C)
|
||||
mbedtls_test_ssl_log_pattern cli_pattern = { .pattern = "Invalid key share in HRR" };
|
||||
#endif /* MBEDTLS_DEBUG_C */
|
||||
|
||||
/* Group order is intentional: client offers secp256r1 first, while server only
|
||||
* accepts secp384r1. This prevents immediate group agreement and forces HRR. */
|
||||
uint16_t client_group_list[] = {
|
||||
MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1,
|
||||
MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1,
|
||||
MBEDTLS_SSL_IANA_TLS_GROUP_NONE
|
||||
};
|
||||
uint16_t server_group_list[] = { MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1,
|
||||
MBEDTLS_SSL_IANA_TLS_GROUP_NONE };
|
||||
|
||||
memset(&client_ep, 0, sizeof(client_ep));
|
||||
memset(&server_ep, 0, sizeof(server_ep));
|
||||
|
||||
mbedtls_test_init_handshake_options(&client_options);
|
||||
mbedtls_test_init_handshake_options(&server_options);
|
||||
MD_OR_USE_PSA_INIT();
|
||||
|
||||
client_options.pk_alg = MBEDTLS_PK_ECDSA;
|
||||
client_options.client_min_version = MBEDTLS_SSL_VERSION_TLS1_3;
|
||||
client_options.client_max_version = MBEDTLS_SSL_VERSION_TLS1_3;
|
||||
client_options.group_list = client_group_list;
|
||||
#if defined(MBEDTLS_DEBUG_C)
|
||||
client_options.cli_log_obj = &cli_pattern;
|
||||
client_options.cli_log_fun = mbedtls_test_ssl_log_analyzer;
|
||||
mbedtls_debug_set_threshold(1);
|
||||
#endif /* MBEDTLS_DEBUG_C */
|
||||
|
||||
server_options.pk_alg = MBEDTLS_PK_ECDSA;
|
||||
server_options.server_min_version = MBEDTLS_SSL_VERSION_TLS1_3;
|
||||
server_options.server_max_version = MBEDTLS_SSL_VERSION_TLS1_3;
|
||||
server_options.group_list = server_group_list;
|
||||
|
||||
for (int round = 0; round < 2; round++) {
|
||||
int select_unoffered_group = (round != 0);
|
||||
TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&client_ep,
|
||||
MBEDTLS_SSL_IS_CLIENT,
|
||||
&client_options, NULL, NULL,
|
||||
NULL), 0);
|
||||
|
||||
TEST_EQUAL(mbedtls_test_ssl_endpoint_init(&server_ep,
|
||||
MBEDTLS_SSL_IS_SERVER,
|
||||
&server_options, NULL, NULL,
|
||||
NULL), 0);
|
||||
|
||||
TEST_EQUAL(mbedtls_test_mock_socket_connect(&(client_ep.socket),
|
||||
&(server_ep.socket), 4096), 0);
|
||||
|
||||
ret = mbedtls_test_move_handshake_to_state(
|
||||
&(server_ep.ssl), &(client_ep.ssl),
|
||||
MBEDTLS_SSL_HELLO_RETRY_REQUEST);
|
||||
TEST_EQUAL(ret, 0);
|
||||
TEST_EQUAL(client_ep.ssl.handshake->offered_group_id,
|
||||
MBEDTLS_SSL_IANA_TLS_GROUP_SECP256R1);
|
||||
|
||||
if (!select_unoffered_group) {
|
||||
TEST_EQUAL(server_ep.ssl.handshake->hrr_selected_group,
|
||||
MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1);
|
||||
} else {
|
||||
server_ep.ssl.handshake->hrr_selected_group = MBEDTLS_SSL_IANA_TLS_GROUP_X25519;
|
||||
}
|
||||
|
||||
/* Write and send the HRR */
|
||||
TEST_EQUAL(mbedtls_ssl_handshake_step(&(server_ep.ssl)), 0);
|
||||
TEST_EQUAL(mbedtls_ssl_flush_output(&(server_ep.ssl)), 0);
|
||||
|
||||
if (!select_unoffered_group) {
|
||||
/* Valid HRR, the client accepts the group MBEDTLS_SSL_IANA_TLS_GROUP_SECP384R1
|
||||
* and goes ahead with the handshake.
|
||||
*/
|
||||
TEST_EQUAL(mbedtls_ssl_handshake_step(&(client_ep.ssl)), 0);
|
||||
TEST_ASSERT(client_ep.ssl.state != MBEDTLS_SSL_SERVER_HELLO);
|
||||
#if defined(MBEDTLS_DEBUG_C)
|
||||
TEST_EQUAL(cli_pattern.counter, 0);
|
||||
#endif /* MBEDTLS_DEBUG_C */
|
||||
} else {
|
||||
/* Invalid HRR selecting MBEDTLS_SSL_IANA_TLS_GROUP_X25519 group.
|
||||
* The client rejects it and aborts the handshake.
|
||||
*/
|
||||
TEST_EQUAL(mbedtls_ssl_handshake_step(&(client_ep.ssl)),
|
||||
MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
|
||||
TEST_EQUAL(client_ep.ssl.state, MBEDTLS_SSL_SERVER_HELLO);
|
||||
#if defined(MBEDTLS_DEBUG_C)
|
||||
TEST_EQUAL(cli_pattern.counter, 1);
|
||||
#endif /* MBEDTLS_DEBUG_C */
|
||||
}
|
||||
mbedtls_test_ssl_endpoint_free(&client_ep, NULL);
|
||||
mbedtls_test_ssl_endpoint_free(&server_ep, NULL);
|
||||
}
|
||||
|
||||
exit:
|
||||
mbedtls_test_ssl_endpoint_free(&client_ep, NULL);
|
||||
mbedtls_test_ssl_endpoint_free(&server_ep, NULL);
|
||||
mbedtls_test_free_handshake_options(&client_options);
|
||||
mbedtls_test_free_handshake_options(&server_options);
|
||||
#if defined(MBEDTLS_DEBUG_C)
|
||||
mbedtls_debug_set_threshold(0);
|
||||
#endif /* MBEDTLS_DEBUG_C */
|
||||
MD_OR_USE_PSA_DONE();
|
||||
}
|
||||
/* END_CASE */
|
||||
|
||||
/* BEGIN_CASE depends_on:MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
|
||||
void ssl_ecjpake_set_password(int use_opaque_arg)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user