Skip to content

Commit a8bf745

Browse files
committed
Merge branch 'feat/adding_different_strategy_to_perform_tls_using_dynamic_feature' into 'master'
Add configuration to control dynamic buffer strategy in mbedtls Closes IDF-12591 See merge request espressif/esp-idf!39469
2 parents dd89395 + 5928a87 commit a8bf745

File tree

14 files changed

+217
-6
lines changed

14 files changed

+217
-6
lines changed

components/esp-tls/esp_tls.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -91,6 +91,12 @@ typedef enum {
9191
ESP_TLS_VER_TLS_MAX, /* to indicate max */
9292
} esp_tls_proto_ver_t;
9393

94+
typedef enum {
95+
ESP_TLS_DYN_BUF_RX_STATIC = 1, /*!< Strategy to disable dynamic RX buffer allocations and convert to static allocation post-handshake, reducing memory fragmentation */
96+
ESP_TLS_DYN_BUF_STRATEGY_MAX, /*!< to indicate max */
97+
} esp_tls_dyn_buf_strategy_t;
98+
99+
94100
/**
95101
* @brief ESP-TLS configuration parameters
96102
*
@@ -213,6 +219,11 @@ typedef struct esp_tls_cfg {
213219
const int *ciphersuites_list; /*!< Pointer to a zero-terminated array of IANA identifiers of TLS ciphersuites.
214220
Please check the list validity by esp_tls_get_ciphersuites_list() API */
215221
esp_tls_proto_ver_t tls_version; /*!< TLS protocol version of the connection, e.g., TLS 1.2, TLS 1.3 (default - no preference) */
222+
223+
#if CONFIG_MBEDTLS_DYNAMIC_BUFFER
224+
esp_tls_dyn_buf_strategy_t esp_tls_dyn_buf_strategy; /*!< ESP-TLS dynamic buffer strategy */
225+
#endif
226+
216227
} esp_tls_cfg_t;
217228

218229
#if defined(CONFIG_ESP_TLS_SERVER_SESSION_TICKETS)

components/esp-tls/esp_tls_mbedtls.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include <errno.h>
2121
#include "esp_log.h"
2222
#include "esp_check.h"
23-
23+
#include "mbedtls/esp_mbedtls_dynamic.h"
2424
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
2525
#include "ecdsa/ecdsa_alt.h"
2626
#endif
@@ -115,6 +115,10 @@ esp_err_t esp_create_mbedtls_handle(const char *hostname, size_t hostlen, const
115115

116116
mbedtls_ssl_conf_rng(&tls->conf, mbedtls_ctr_drbg_random, &tls->ctr_drbg);
117117

118+
#if CONFIG_MBEDTLS_DYNAMIC_BUFFER
119+
tls->esp_tls_dyn_buf_strategy = ((esp_tls_cfg_t *)cfg)->esp_tls_dyn_buf_strategy;
120+
#endif
121+
118122
if (tls->role == ESP_TLS_CLIENT) {
119123
esp_ret = set_client_config(hostname, hostlen, (esp_tls_cfg_t *)cfg, tls);
120124
if (esp_ret != ESP_OK) {
@@ -256,6 +260,15 @@ int esp_mbedtls_handshake(esp_tls_t *tls, const esp_tls_cfg_t *cfg)
256260
#endif
257261
ret = mbedtls_ssl_handshake(&tls->ssl);
258262
if (ret == 0) {
263+
#if CONFIG_MBEDTLS_DYNAMIC_BUFFER
264+
if (tls->esp_tls_dyn_buf_strategy != 0) {
265+
ret = esp_mbedtls_dynamic_set_rx_buf_static(&tls->ssl);
266+
if (ret != 0) {
267+
ESP_LOGE(TAG, "esp_mbedtls_dynamic_set_rx_buf_static returned -0x%04X", -ret);
268+
return ret;
269+
}
270+
}
271+
#endif
259272
tls->conn_state = ESP_TLS_DONE;
260273

261274
#ifdef CONFIG_ESP_TLS_USE_DS_PERIPHERAL

components/esp-tls/private_include/esp_tls_private.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ struct esp_tls {
9898

9999
esp_tls_error_handle_t error_handle; /*!< handle to error descriptor */
100100

101+
#if CONFIG_MBEDTLS_DYNAMIC_BUFFER
102+
esp_tls_dyn_buf_strategy_t esp_tls_dyn_buf_strategy; /*!< ESP-TLS dynamic buffer strategy */
103+
#endif
104+
101105
};
102106

103107
// Function pointer for the server configuration API

components/esp_http_client/esp_http_client.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ static const char *TAG = "HTTP_CLIENT";
3434

3535
ESP_STATIC_ASSERT((int)ESP_HTTP_CLIENT_TLS_VER_ANY == (int)ESP_TLS_VER_ANY, "Enum mismatch in esp_http_client and esp-tls");
3636
ESP_STATIC_ASSERT((int)ESP_HTTP_CLIENT_TLS_VER_MAX <= (int)ESP_TLS_VER_TLS_MAX, "HTTP client supported TLS is not supported in esp-tls");
37+
ESP_STATIC_ASSERT((int)HTTP_TLS_DYN_BUF_RX_STATIC == (int)ESP_TLS_DYN_BUF_RX_STATIC, "Enum mismatch in esp_http_client and esp-tls");
38+
ESP_STATIC_ASSERT((int)HTTP_TLS_DYN_BUF_STRATEGY_MAX <= (int)ESP_TLS_DYN_BUF_STRATEGY_MAX, "HTTP client supported TLS is not supported in esp-tls");
3739

3840
#if CONFIG_ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT == -1
3941
#define ESP_HTTP_CLIENT_EVENT_POST_TIMEOUT portMAX_DELAY
@@ -844,6 +846,14 @@ esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *co
844846
}
845847
esp_transport_ssl_set_tls_version(ssl, config->tls_version);
846848

849+
#if CONFIG_MBEDTLS_DYNAMIC_BUFFER
850+
/* When tls_dyn_buf_strategy is 0, mbedTLS dynamic buffer allocation uses default behavior.
851+
* No need to call esp_transport_ssl_set_esp_tls_dyn_buf_strategy() in this case */
852+
if (config->tls_dyn_buf_strategy != 0 && config->tls_dyn_buf_strategy < HTTP_TLS_DYN_BUF_STRATEGY_MAX) {
853+
esp_transport_ssl_set_esp_tls_dyn_buf_strategy(ssl, config->tls_dyn_buf_strategy);
854+
}
855+
#endif
856+
847857
#if CONFIG_ESP_TLS_USE_SECURE_ELEMENT
848858
if (config->use_secure_element) {
849859
esp_transport_ssl_use_secure_element(ssl);

components/esp_http_client/include/esp_http_client.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ typedef enum {
139139
HTTP_ADDR_TYPE_INET6 = AF_INET6, /**< IPv6 address family. */
140140
} esp_http_client_addr_type_t;
141141

142+
typedef enum {
143+
HTTP_TLS_DYN_BUF_RX_STATIC = 1, /*!< Strategy to disable dynamic RX buffer allocations and convert to static allocation post-handshake, reducing memory fragmentation */
144+
HTTP_TLS_DYN_BUF_STRATEGY_MAX, /*!< to indicate max */
145+
} esp_http_client_tls_dyn_buf_strategy_t;
146+
142147
/**
143148
* @brief HTTP configuration
144149
*/
@@ -215,6 +220,10 @@ typedef struct {
215220
struct esp_transport_item_t *transport;
216221
#endif
217222
esp_http_client_addr_type_t addr_type; /*!< Address type used in http client configurations */
223+
224+
#if CONFIG_MBEDTLS_DYNAMIC_BUFFER
225+
esp_http_client_tls_dyn_buf_strategy_t tls_dyn_buf_strategy; /*!< TLS dynamic buffer strategy */
226+
#endif
218227
} esp_http_client_config_t;
219228

220229
/**

components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,17 @@
1818

1919
#define TX_IDLE_BUFFER_SIZE (MBEDTLS_SSL_HEADER_LEN + CACHE_BUFFER_SIZE)
2020

21+
#define ESP_MBEDTLS_RETURN_IF_RX_BUF_STATIC(ssl) \
22+
do { \
23+
if (ssl->MBEDTLS_PRIVATE(in_buf)) { \
24+
esp_mbedtls_ssl_buf_states state = esp_mbedtls_get_buf_state(ssl->MBEDTLS_PRIVATE(in_buf)); \
25+
if (state == ESP_MBEDTLS_SSL_BUF_STATIC) { \
26+
return 0; \
27+
} \
28+
} \
29+
} while(0)
30+
31+
2132
static const char *TAG = "Dynamic Impl";
2233

2334
static void esp_mbedtls_set_buf_state(unsigned char *buf, esp_mbedtls_ssl_buf_states state)
@@ -140,6 +151,29 @@ static void init_rx_buffer(mbedtls_ssl_context *ssl, unsigned char *buf)
140151
ssl->MBEDTLS_PRIVATE(in_left) = 0;
141152
}
142153

154+
esp_err_t esp_mbedtls_dynamic_set_rx_buf_static(mbedtls_ssl_context *ssl)
155+
{
156+
unsigned char cache_buf[16];
157+
memcpy(cache_buf, ssl->MBEDTLS_PRIVATE(in_buf), 16);
158+
esp_mbedtls_reset_free_rx_buffer(ssl);
159+
160+
struct esp_mbedtls_ssl_buf *esp_buf;
161+
int buffer_len = tx_buffer_len(ssl, MBEDTLS_SSL_IN_BUFFER_LEN);
162+
esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + buffer_len);
163+
if (!esp_buf) {
164+
ESP_LOGE(TAG, "rx buf alloc(%d bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + buffer_len);
165+
return ESP_ERR_NO_MEM;
166+
}
167+
esp_mbedtls_init_ssl_buf(esp_buf, buffer_len);
168+
init_rx_buffer(ssl, esp_buf->buf);
169+
170+
memcpy(ssl->MBEDTLS_PRIVATE(in_ctr), cache_buf, 8);
171+
memcpy(ssl->MBEDTLS_PRIVATE(in_iv), cache_buf + 8, 8);
172+
esp_mbedtls_set_buf_state(ssl->MBEDTLS_PRIVATE(in_buf), ESP_MBEDTLS_SSL_BUF_STATIC);
173+
return ESP_OK;
174+
175+
}
176+
143177
static int esp_mbedtls_alloc_tx_buf(mbedtls_ssl_context *ssl, int len)
144178
{
145179
struct esp_mbedtls_ssl_buf *esp_buf;
@@ -324,6 +358,12 @@ int esp_mbedtls_free_tx_buffer(mbedtls_ssl_context *ssl)
324358

325359
int esp_mbedtls_add_rx_buffer(mbedtls_ssl_context *ssl)
326360
{
361+
/*
362+
* If RX buffer is set to static mode, this macro will return early
363+
* and skip dynamic buffer allocation logic below
364+
*/
365+
ESP_MBEDTLS_RETURN_IF_RX_BUF_STATIC(ssl);
366+
327367
int cached = 0;
328368
int ret = 0;
329369
int buffer_len;
@@ -405,6 +445,12 @@ int esp_mbedtls_add_rx_buffer(mbedtls_ssl_context *ssl)
405445

406446
int esp_mbedtls_free_rx_buffer(mbedtls_ssl_context *ssl)
407447
{
448+
/*
449+
* If RX buffer is set to static mode, this macro will return early
450+
* and skip dynamic buffer free logic below
451+
*/
452+
ESP_MBEDTLS_RETURN_IF_RX_BUF_STATIC(ssl);
453+
408454
int ret = 0;
409455
unsigned char buf[16];
410456
struct esp_mbedtls_ssl_buf *esp_buf;

components/mbedtls/port/dynamic/esp_mbedtls_dynamic_impl.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -26,6 +26,8 @@
2626
#include "esp_log.h"
2727
#include "sdkconfig.h"
2828

29+
#include "mbedtls/esp_mbedtls_dynamic.h"
30+
2931
#define TRACE_CHECK(_fn, _state) \
3032
({ \
3133
ESP_LOGV(TAG, "%d " _state " to do \"%s\"", __LINE__, # _fn); \
@@ -48,8 +50,9 @@
4850
})
4951

5052
typedef enum {
51-
ESP_MBEDTLS_SSL_BUF_CACHED,
53+
ESP_MBEDTLS_SSL_BUF_CACHED = 0,
5254
ESP_MBEDTLS_SSL_BUF_NO_CACHED,
55+
ESP_MBEDTLS_SSL_BUF_STATIC,
5356
} esp_mbedtls_ssl_buf_states;
5457

5558
struct esp_mbedtls_ssl_buf {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#include "mbedtls/ssl.h"
10+
#include "esp_err.h"
11+
12+
#ifdef __cplusplus
13+
extern "C" {
14+
#endif
15+
16+
/**
17+
* @brief Set the dynamic buffer rx statically after the handshake. This is to avoid frequent allocation and deallocation of dynamic buffer.
18+
*
19+
* @param ssl mbedtls ssl context
20+
* @return esp_err_t
21+
* - ESP_OK: Successfully set the rx buffer to static
22+
* - ESP_ERR_NO_MEM: Failed to allocate memory for the rx buffer
23+
*/
24+
esp_err_t esp_mbedtls_dynamic_set_rx_buf_static(mbedtls_ssl_context *ssl);
25+
26+
#ifdef __cplusplus
27+
}
28+
#endif

components/tcp_transport/include/esp_transport_ssl.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -61,6 +61,15 @@ void esp_transport_ssl_crt_bundle_attach(esp_transport_handle_t t, esp_err_t ((*
6161
*/
6262
void esp_transport_ssl_enable_global_ca_store(esp_transport_handle_t t);
6363

64+
#if CONFIG_MBEDTLS_DYNAMIC_BUFFER
65+
/**
66+
* @brief Set ESP-TLS dynamic buffer strategy for ESP-TLS connection
67+
*
68+
* @param t ssl transport
69+
* @param[in] strategy ESP-TLS dynamic buffer strategy
70+
*/
71+
void esp_transport_ssl_set_esp_tls_dyn_buf_strategy(esp_transport_handle_t t, esp_tls_dyn_buf_strategy_t strategy);
72+
#endif
6473
/**
6574
* @brief Set TLS protocol version for ESP-TLS connection
6675
*

components/tcp_transport/transport_ssl.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -365,6 +365,14 @@ void esp_transport_ssl_enable_global_ca_store(esp_transport_handle_t t)
365365
ssl->cfg.use_global_ca_store = true;
366366
}
367367

368+
#if CONFIG_MBEDTLS_DYNAMIC_BUFFER
369+
void esp_transport_ssl_set_esp_tls_dyn_buf_strategy(esp_transport_handle_t t, esp_tls_dyn_buf_strategy_t strategy)
370+
{
371+
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);
372+
ssl->cfg.esp_tls_dyn_buf_strategy = strategy;
373+
}
374+
#endif
375+
368376
void esp_transport_ssl_set_tls_version(esp_transport_handle_t t, esp_tls_proto_ver_t tls_version)
369377
{
370378
GET_SSL_FROM_TRANSPORT_OR_RETURN(ssl, t);

0 commit comments

Comments
 (0)