From 9681ec0f9cc81282251be21a7d8309d8e468034e Mon Sep 17 00:00:00 2001 From: Ashish Sharma Date: Thu, 15 Jan 2026 16:17:54 +0800 Subject: [PATCH] fix: fixes failing dynamic buffer tests --- .../port/dynamic/esp_mbedtls_dynamic_impl.c | 14 ++++++++++- components/mbedtls/port/dynamic/esp_ssl_cli.c | 24 +++++++++++++++---- components/mbedtls/port/dynamic/esp_ssl_tls.c | 10 ++------ .../main/esp_http_client_example.c | 2 ++ .../esp_http_client/pytest_esp_http_client.py | 2 +- 5 files changed, 37 insertions(+), 15 deletions(-) diff --git a/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.c b/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.c index c2aff10532..4084a9015c 100644 --- a/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.c +++ b/components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -407,6 +407,18 @@ int esp_mbedtls_add_rx_buffer(mbedtls_ssl_context *ssl) in_msglen = ssl->MBEDTLS_PRIVATE(in_msglen); buffer_len = tx_buffer_len(ssl, in_msglen); +#if defined(MBEDTLS_SSL_PROTO_TLS1_3) + /* For TLS 1.3 ENCRYPTED_EXTENSIONS state, allocate max size buffer. + * This is needed because ChangeCipherSpec (1 byte) arrives first, + * followed immediately by EncryptedExtensions (potentially large). + * Since mbedtls processes both in the same read loop without returning + * to the wrapper, we need to allocate sufficient space upfront. */ + if (ssl->MBEDTLS_PRIVATE(state) == MBEDTLS_SSL_ENCRYPTED_EXTENSIONS) { + buffer_len = tx_buffer_len(ssl, MBEDTLS_SSL_IN_CONTENT_LEN); + ESP_LOGV(TAG, "TLS 1.3 ENCRYPTED_EXTENSIONS: allocating max buffer %d bytes", buffer_len); + } +#endif + ESP_LOGV(TAG, "message length is %d RX buffer length should be %d left is %d", (int)in_msglen, (int)buffer_len, (int)ssl->MBEDTLS_PRIVATE(in_left)); diff --git a/components/mbedtls/port/dynamic/esp_ssl_cli.c b/components/mbedtls/port/dynamic/esp_ssl_cli.c index 376f104780..7c34b8a47d 100644 --- a/components/mbedtls/port/dynamic/esp_ssl_cli.c +++ b/components/mbedtls/port/dynamic/esp_ssl_cli.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,7 +19,11 @@ static const char *TAG = "SSL client"; static int manage_resource(mbedtls_ssl_context *ssl, bool add) { - int state = add ? ssl->MBEDTLS_PRIVATE(state) : ssl->MBEDTLS_PRIVATE(state) - 1; + static _Thread_local int last_state = 0; + int state = add ? ssl->MBEDTLS_PRIVATE(state) : last_state; + if (add) { + last_state = state; + } if (mbedtls_ssl_is_handshake_over(ssl) || ssl->MBEDTLS_PRIVATE(handshake) == NULL) { return 0; @@ -66,14 +70,20 @@ static int manage_resource(mbedtls_ssl_context *ssl, bool add) if (add) { CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); } else { - CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + /* Don't free RX buffer - TLS 1.3 may have multiple messages in the same record */ + if (!ssl->MBEDTLS_PRIVATE(keep_current_message)) { + CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + } } break; case MBEDTLS_SSL_SERVER_CERTIFICATE: if (add) { CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); } else { - CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + /* Don't free RX buffer - TLS 1.3 may have multiple messages in the same record */ + if (!ssl->MBEDTLS_PRIVATE(keep_current_message)) { + CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + } #ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT esp_mbedtls_free_cacert(ssl); @@ -149,8 +159,12 @@ static int manage_resource(mbedtls_ssl_context *ssl, bool add) case MBEDTLS_SSL_CERTIFICATE_VERIFY: if (add) { size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN; - CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); +#ifdef CONFIG_MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE + if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) { + CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); + } +#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */ } else { #ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA esp_mbedtls_free_dhm(ssl); diff --git a/components/mbedtls/port/dynamic/esp_ssl_tls.c b/components/mbedtls/port/dynamic/esp_ssl_tls.c index c153ab03f1..6a9537651f 100644 --- a/components/mbedtls/port/dynamic/esp_ssl_tls.c +++ b/components/mbedtls/port/dynamic/esp_ssl_tls.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -383,15 +383,9 @@ int __wrap_mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t * and prepare for the next read. So we have to update the msglen * by ourselves and free the rx buffer if no more data is available. */ - if (ssl->MBEDTLS_PRIVATE(in_hslen) < ssl->MBEDTLS_PRIVATE(in_msglen)) { + if (ssl->MBEDTLS_PRIVATE(in_hslen) == ssl->MBEDTLS_PRIVATE(in_msglen)) { ssl->MBEDTLS_PRIVATE(in_msglen) -= ssl->MBEDTLS_PRIVATE(in_hslen); - memmove(ssl->MBEDTLS_PRIVATE(in_msg), ssl->MBEDTLS_PRIVATE(in_msg) + ssl->MBEDTLS_PRIVATE(in_hslen), - ssl->MBEDTLS_PRIVATE(in_msglen)); - MBEDTLS_PUT_UINT16_BE(ssl->MBEDTLS_PRIVATE(in_msglen), ssl->in_len, 0); - } else { - ssl->MBEDTLS_PRIVATE(in_msglen) = 0; } - ssl->MBEDTLS_PRIVATE(in_hslen) = 0; } } #endif // CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 diff --git a/examples/protocols/esp_http_client/main/esp_http_client_example.c b/examples/protocols/esp_http_client/main/esp_http_client_example.c index 3d753effb7..dafdc05e70 100644 --- a/examples/protocols/esp_http_client/main/esp_http_client_example.c +++ b/examples/protocols/esp_http_client/main/esp_http_client_example.c @@ -426,6 +426,7 @@ static void https_with_url(void) .url = "https://www.howsmyssl.com", .event_handler = _http_event_handler, .crt_bundle_attach = esp_crt_bundle_attach, + .timeout_ms = 5000, }; ESP_LOGI(TAG, "HTTPS request with url =>"); esp_http_client_handle_t client = esp_http_client_init(&config); @@ -450,6 +451,7 @@ static void https_with_hostname_path(void) .transport_type = HTTP_TRANSPORT_OVER_SSL, .event_handler = _http_event_handler, .cert_pem = howsmyssl_com_root_cert_pem_start, + .timeout_ms = 5000, }; ESP_LOGI(TAG, "HTTPS request with hostname and path =>"); esp_http_client_handle_t client = esp_http_client_init(&config); diff --git a/examples/protocols/esp_http_client/pytest_esp_http_client.py b/examples/protocols/esp_http_client/pytest_esp_http_client.py index a7fa5a55d8..c89c10f25f 100644 --- a/examples/protocols/esp_http_client/pytest_esp_http_client.py +++ b/examples/protocols/esp_http_client/pytest_esp_http_client.py @@ -64,7 +64,7 @@ def test_examples_protocol_esp_http_client(dut: Dut) -> None: ], indirect=True, ) -@idf_parametrize('target', ['esp32'], indirect=['target']) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_examples_protocol_esp_http_client_dynamic_buffer(dut: Dut) -> None: # test mbedtls dynamic resource # check and log bin size