1 /*
2  * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <string.h>
8 #include "esp_mbedtls_dynamic_impl.h"
9 #include "sdkconfig.h"
10 
11 #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
12 #include "esp_crt_bundle.h"
13 #endif
14 
15 #define COUNTER_SIZE (8)
16 #define CACHE_IV_SIZE (16)
17 #define CACHE_BUFFER_SIZE (CACHE_IV_SIZE + COUNTER_SIZE)
18 
19 #define TX_IDLE_BUFFER_SIZE (MBEDTLS_SSL_HEADER_LEN + CACHE_BUFFER_SIZE)
20 
21 static const char *TAG = "Dynamic Impl";
22 
esp_mbedtls_set_buf_state(unsigned char * buf,esp_mbedtls_ssl_buf_states state)23 static void esp_mbedtls_set_buf_state(unsigned char *buf, esp_mbedtls_ssl_buf_states state)
24 {
25     struct esp_mbedtls_ssl_buf *temp = __containerof(buf, struct esp_mbedtls_ssl_buf, buf[0]);
26     temp->state = state;
27 }
28 
esp_mbedtls_get_buf_state(unsigned char * buf)29 static esp_mbedtls_ssl_buf_states esp_mbedtls_get_buf_state(unsigned char *buf)
30 {
31     struct esp_mbedtls_ssl_buf *temp = __containerof(buf, struct esp_mbedtls_ssl_buf, buf[0]);
32     return temp->state;
33 }
34 
esp_mbedtls_free_buf(unsigned char * buf)35 void esp_mbedtls_free_buf(unsigned char *buf)
36 {
37     struct esp_mbedtls_ssl_buf *temp = __containerof(buf, struct esp_mbedtls_ssl_buf, buf[0]);
38     ESP_LOGV(TAG, "free buffer @ %p", temp);
39     mbedtls_free(temp);
40 }
41 
esp_mbedtls_init_ssl_buf(struct esp_mbedtls_ssl_buf * buf,unsigned int len)42 static void esp_mbedtls_init_ssl_buf(struct esp_mbedtls_ssl_buf *buf, unsigned int len)
43 {
44     if (buf) {
45         buf->state = ESP_MBEDTLS_SSL_BUF_CACHED;
46         buf->len = len;
47     }
48 }
49 
esp_mbedtls_parse_record_header(mbedtls_ssl_context * ssl)50 static void esp_mbedtls_parse_record_header(mbedtls_ssl_context *ssl)
51 {
52     ssl->MBEDTLS_PRIVATE(in_msgtype) =  ssl->MBEDTLS_PRIVATE(in_hdr)[0];
53     ssl->MBEDTLS_PRIVATE(in_msglen) = (ssl->MBEDTLS_PRIVATE(in_len)[0] << 8) | ssl->MBEDTLS_PRIVATE(in_len)[1];
54 }
55 
tx_buffer_len(mbedtls_ssl_context * ssl,int len)56 static int tx_buffer_len(mbedtls_ssl_context *ssl, int len)
57 {
58     (void)ssl;
59 
60     if (!len) {
61         return MBEDTLS_SSL_OUT_BUFFER_LEN;
62     } else {
63         return len + MBEDTLS_SSL_HEADER_LEN
64                    + MBEDTLS_MAX_IV_LENGTH
65                    + MBEDTLS_SSL_MAC_ADD
66                    + MBEDTLS_SSL_PADDING_ADD
67                    + MBEDTLS_SSL_MAX_CID_EXPANSION;
68     }
69 }
70 
init_tx_buffer(mbedtls_ssl_context * ssl,unsigned char * buf)71 static void init_tx_buffer(mbedtls_ssl_context *ssl, unsigned char *buf)
72 {
73     /**
74      * In mbedtls, ssl->MBEDTLS_PRIVATE(out_msg) = ssl->MBEDTLS_PRIVATE(out_buf) + offset;
75      */
76     if (!buf) {
77         int out_msg_off = (int)ssl->MBEDTLS_PRIVATE(out_msg) - (int)ssl->MBEDTLS_PRIVATE(out_buf);
78 
79         if (!out_msg_off) {
80             out_msg_off = MBEDTLS_SSL_HEADER_LEN;
81         }
82 
83         ssl->MBEDTLS_PRIVATE(out_buf) = NULL;
84         ssl->MBEDTLS_PRIVATE(out_ctr) = NULL;
85         ssl->MBEDTLS_PRIVATE(out_hdr) = NULL;
86         ssl->MBEDTLS_PRIVATE(out_len) = NULL;
87         ssl->MBEDTLS_PRIVATE(out_iv)  = NULL;
88         ssl->MBEDTLS_PRIVATE(out_msg) = (unsigned char *)out_msg_off;
89     } else {
90         int out_msg_off = (int)ssl->MBEDTLS_PRIVATE(out_msg);
91 
92         ssl->MBEDTLS_PRIVATE(out_buf) = buf;
93         ssl->MBEDTLS_PRIVATE(out_ctr) = ssl->MBEDTLS_PRIVATE(out_buf);
94         ssl->MBEDTLS_PRIVATE(out_hdr) = ssl->MBEDTLS_PRIVATE(out_buf) +  8;
95         ssl->MBEDTLS_PRIVATE(out_len) = ssl->MBEDTLS_PRIVATE(out_buf) + 11;
96         ssl->MBEDTLS_PRIVATE(out_iv)  = ssl->MBEDTLS_PRIVATE(out_buf) + MBEDTLS_SSL_HEADER_LEN;
97         ssl->MBEDTLS_PRIVATE(out_msg) = ssl->MBEDTLS_PRIVATE(out_buf) + out_msg_off;
98 
99         ESP_LOGV(TAG, "out msg offset is %d", out_msg_off);
100     }
101 
102     ssl->MBEDTLS_PRIVATE(out_msgtype) = 0;
103     ssl->MBEDTLS_PRIVATE(out_msglen) = 0;
104     ssl->MBEDTLS_PRIVATE(out_left) = 0;
105 }
106 
init_rx_buffer(mbedtls_ssl_context * ssl,unsigned char * buf)107 static void init_rx_buffer(mbedtls_ssl_context *ssl, unsigned char *buf)
108 {
109     /**
110      * In mbedtls, ssl->MBEDTLS_PRIVATE(in_msg) = ssl->MBEDTLS_PRIVATE(in_buf) + offset;
111      */
112     if (!buf) {
113         int in_msg_off = (int)ssl->MBEDTLS_PRIVATE(in_msg) - (int)ssl->MBEDTLS_PRIVATE(in_buf);
114 
115         if (!in_msg_off) {
116             in_msg_off = MBEDTLS_SSL_HEADER_LEN;
117         }
118 
119         ssl->MBEDTLS_PRIVATE(in_buf) = NULL;
120         ssl->MBEDTLS_PRIVATE(in_ctr) = NULL;
121         ssl->MBEDTLS_PRIVATE(in_hdr) = NULL;
122         ssl->MBEDTLS_PRIVATE(in_len) = NULL;
123         ssl->MBEDTLS_PRIVATE(in_iv)  = NULL;
124         ssl->MBEDTLS_PRIVATE(in_msg) = (unsigned char *)in_msg_off;
125     } else {
126         int in_msg_off = (int)ssl->MBEDTLS_PRIVATE(in_msg);
127 
128         ssl->MBEDTLS_PRIVATE(in_buf) = buf;
129         ssl->MBEDTLS_PRIVATE(in_ctr) = ssl->MBEDTLS_PRIVATE(in_buf);
130         ssl->MBEDTLS_PRIVATE(in_hdr) = ssl->MBEDTLS_PRIVATE(in_buf) +  8;
131         ssl->MBEDTLS_PRIVATE(in_len) = ssl->MBEDTLS_PRIVATE(in_buf) + 11;
132         ssl->MBEDTLS_PRIVATE(in_iv)  = ssl->MBEDTLS_PRIVATE(in_buf) + MBEDTLS_SSL_HEADER_LEN;
133         ssl->MBEDTLS_PRIVATE(in_msg) = ssl->MBEDTLS_PRIVATE(in_buf) + in_msg_off;
134 
135         ESP_LOGV(TAG, "in msg offset is %d", in_msg_off);
136     }
137 
138     ssl->MBEDTLS_PRIVATE(in_msgtype) = 0;
139     ssl->MBEDTLS_PRIVATE(in_msglen) = 0;
140     ssl->MBEDTLS_PRIVATE(in_left) = 0;
141 }
142 
esp_mbedtls_alloc_tx_buf(mbedtls_ssl_context * ssl,int len)143 static int esp_mbedtls_alloc_tx_buf(mbedtls_ssl_context *ssl, int len)
144 {
145     struct esp_mbedtls_ssl_buf *esp_buf;
146 
147     if (ssl->MBEDTLS_PRIVATE(out_buf)) {
148         esp_mbedtls_free_buf(ssl->MBEDTLS_PRIVATE(out_buf));
149         ssl->MBEDTLS_PRIVATE(out_buf) = NULL;
150     }
151 
152     esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + len);
153     if (!esp_buf) {
154         ESP_LOGE(TAG, "alloc(%d bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + len);
155         return MBEDTLS_ERR_SSL_ALLOC_FAILED;
156     }
157 
158     ESP_LOGV(TAG, "add out buffer %d bytes @ %p", len, esp_buf->buf);
159 
160     esp_mbedtls_init_ssl_buf(esp_buf, len);
161     /**
162      * Mark the out_msg offset from ssl->MBEDTLS_PRIVATE(out_buf).
163      *
164      * In mbedtls, ssl->MBEDTLS_PRIVATE(out_msg) = ssl->MBEDTLS_PRIVATE(out_buf) + offset;
165      */
166     ssl->MBEDTLS_PRIVATE(out_msg) = (unsigned char *)MBEDTLS_SSL_HEADER_LEN;
167 
168     init_tx_buffer(ssl, esp_buf->buf);
169 
170     return 0;
171 }
172 
esp_mbedtls_setup_tx_buffer(mbedtls_ssl_context * ssl)173 int esp_mbedtls_setup_tx_buffer(mbedtls_ssl_context *ssl)
174 {
175     CHECK_OK(esp_mbedtls_alloc_tx_buf(ssl, TX_IDLE_BUFFER_SIZE));
176 
177     /* mark the out buffer has no data cached */
178     esp_mbedtls_set_buf_state(ssl->MBEDTLS_PRIVATE(out_buf), ESP_MBEDTLS_SSL_BUF_NO_CACHED);
179 
180     return 0;
181 }
182 
esp_mbedtls_setup_rx_buffer(mbedtls_ssl_context * ssl)183 void esp_mbedtls_setup_rx_buffer(mbedtls_ssl_context *ssl)
184 {
185     ssl->MBEDTLS_PRIVATE(in_msg) = ssl->MBEDTLS_PRIVATE(in_buf) = NULL;
186     init_rx_buffer(ssl, NULL);
187 }
188 
esp_mbedtls_reset_add_tx_buffer(mbedtls_ssl_context * ssl)189 int esp_mbedtls_reset_add_tx_buffer(mbedtls_ssl_context *ssl)
190 {
191     return esp_mbedtls_alloc_tx_buf(ssl, MBEDTLS_SSL_OUT_BUFFER_LEN);
192 }
193 
esp_mbedtls_reset_free_tx_buffer(mbedtls_ssl_context * ssl)194 int esp_mbedtls_reset_free_tx_buffer(mbedtls_ssl_context *ssl)
195 {
196     esp_mbedtls_free_buf(ssl->MBEDTLS_PRIVATE(out_buf));
197     init_tx_buffer(ssl, NULL);
198 
199     CHECK_OK(esp_mbedtls_setup_tx_buffer(ssl));
200 
201     return 0;
202 }
203 
esp_mbedtls_reset_add_rx_buffer(mbedtls_ssl_context * ssl)204 int esp_mbedtls_reset_add_rx_buffer(mbedtls_ssl_context *ssl)
205 {
206     struct esp_mbedtls_ssl_buf *esp_buf;
207 
208     if (ssl->MBEDTLS_PRIVATE(in_buf)) {
209         esp_mbedtls_free_buf(ssl->MBEDTLS_PRIVATE(in_buf));
210         ssl->MBEDTLS_PRIVATE(in_buf) = NULL;
211     }
212 
213     esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + MBEDTLS_SSL_IN_BUFFER_LEN);
214     if (!esp_buf) {
215         ESP_LOGE(TAG, "alloc(%d bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + MBEDTLS_SSL_IN_BUFFER_LEN);
216         return MBEDTLS_ERR_SSL_ALLOC_FAILED;
217     }
218 
219     ESP_LOGV(TAG, "add in buffer %d bytes @ %p", MBEDTLS_SSL_IN_BUFFER_LEN, esp_buf->buf);
220 
221     esp_mbedtls_init_ssl_buf(esp_buf, MBEDTLS_SSL_IN_BUFFER_LEN);
222     /**
223      * Mark the in_msg offset from ssl->MBEDTLS_PRIVATE(in_buf).
224      *
225      * In mbedtls, ssl->MBEDTLS_PRIVATE(in_msg) = ssl->MBEDTLS_PRIVATE(in_buf) + offset;
226      */
227     ssl->MBEDTLS_PRIVATE(in_msg) = (unsigned char *)MBEDTLS_SSL_HEADER_LEN;
228 
229     init_rx_buffer(ssl, esp_buf->buf);
230 
231     return 0;
232 }
233 
esp_mbedtls_reset_free_rx_buffer(mbedtls_ssl_context * ssl)234 void esp_mbedtls_reset_free_rx_buffer(mbedtls_ssl_context *ssl)
235 {
236     esp_mbedtls_free_buf(ssl->MBEDTLS_PRIVATE(in_buf));
237     init_rx_buffer(ssl, NULL);
238 }
239 
esp_mbedtls_add_tx_buffer(mbedtls_ssl_context * ssl,size_t buffer_len)240 int esp_mbedtls_add_tx_buffer(mbedtls_ssl_context *ssl, size_t buffer_len)
241 {
242     int ret = 0;
243     int cached = 0;
244     struct esp_mbedtls_ssl_buf *esp_buf;
245     unsigned char cache_buf[CACHE_BUFFER_SIZE];
246 
247     ESP_LOGV(TAG, "--> add out");
248 
249     if (ssl->MBEDTLS_PRIVATE(out_buf)) {
250         if (esp_mbedtls_get_buf_state(ssl->MBEDTLS_PRIVATE(out_buf)) == ESP_MBEDTLS_SSL_BUF_CACHED) {
251             ESP_LOGV(TAG, "out buffer is not empty");
252             ret = 0;
253             goto exit;
254         } else {
255             memcpy(cache_buf, ssl->MBEDTLS_PRIVATE(out_buf), CACHE_BUFFER_SIZE);
256             esp_mbedtls_free_buf(ssl->MBEDTLS_PRIVATE(out_buf));
257             init_tx_buffer(ssl, NULL);
258             cached = 1;
259         }
260     }
261 
262     buffer_len = tx_buffer_len(ssl, buffer_len);
263 
264     esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + buffer_len);
265     if (!esp_buf) {
266         ESP_LOGE(TAG, "alloc(%zu bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + buffer_len);
267         ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
268         goto exit;
269     }
270 
271     ESP_LOGV(TAG, "add out buffer %zu bytes @ %p", buffer_len, esp_buf->buf);
272 
273     esp_mbedtls_init_ssl_buf(esp_buf, buffer_len);
274     init_tx_buffer(ssl, esp_buf->buf);
275 
276     if (cached) {
277         memcpy(ssl->MBEDTLS_PRIVATE(out_ctr), cache_buf, COUNTER_SIZE);
278         memcpy(ssl->MBEDTLS_PRIVATE(out_iv), cache_buf + COUNTER_SIZE, CACHE_IV_SIZE);
279     }
280 
281     ESP_LOGV(TAG, "ssl->MBEDTLS_PRIVATE(out_buf)=%p ssl->MBEDTLS_PRIVATE(out_msg)=%p", ssl->MBEDTLS_PRIVATE(out_buf), ssl->MBEDTLS_PRIVATE(out_msg));
282 
283 exit:
284     ESP_LOGV(TAG, "<-- add out");
285 
286     return ret;
287 }
288 
289 
esp_mbedtls_free_tx_buffer(mbedtls_ssl_context * ssl)290 int esp_mbedtls_free_tx_buffer(mbedtls_ssl_context *ssl)
291 {
292     int ret = 0;
293     unsigned char buf[CACHE_BUFFER_SIZE];
294     struct esp_mbedtls_ssl_buf *esp_buf;
295 
296     ESP_LOGV(TAG, "--> free out");
297 
298     if (!ssl->MBEDTLS_PRIVATE(out_buf) || (ssl->MBEDTLS_PRIVATE(out_buf) && (esp_mbedtls_get_buf_state(ssl->MBEDTLS_PRIVATE(out_buf)) == ESP_MBEDTLS_SSL_BUF_NO_CACHED))) {
299         ret = 0;
300         goto exit;
301     }
302 
303     memcpy(buf, ssl->MBEDTLS_PRIVATE(out_ctr), COUNTER_SIZE);
304     memcpy(buf + COUNTER_SIZE, ssl->MBEDTLS_PRIVATE(out_iv), CACHE_IV_SIZE);
305 
306     esp_mbedtls_free_buf(ssl->MBEDTLS_PRIVATE(out_buf));
307     init_tx_buffer(ssl, NULL);
308 
309     esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + TX_IDLE_BUFFER_SIZE);
310     if (!esp_buf) {
311         ESP_LOGE(TAG, "alloc(%d bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + TX_IDLE_BUFFER_SIZE);
312         return MBEDTLS_ERR_SSL_ALLOC_FAILED;
313     }
314 
315     esp_mbedtls_init_ssl_buf(esp_buf, TX_IDLE_BUFFER_SIZE);
316     memcpy(esp_buf->buf, buf, CACHE_BUFFER_SIZE);
317     init_tx_buffer(ssl, esp_buf->buf);
318     esp_mbedtls_set_buf_state(ssl->MBEDTLS_PRIVATE(out_buf), ESP_MBEDTLS_SSL_BUF_NO_CACHED);
319 exit:
320     ESP_LOGV(TAG, "<-- free out");
321 
322     return ret;
323 }
324 
esp_mbedtls_add_rx_buffer(mbedtls_ssl_context * ssl)325 int esp_mbedtls_add_rx_buffer(mbedtls_ssl_context *ssl)
326 {
327     int cached = 0;
328     int ret = 0;
329     int buffer_len;
330     struct esp_mbedtls_ssl_buf *esp_buf;
331     unsigned char cache_buf[16];
332     unsigned char msg_head[5];
333     size_t in_msglen, in_left;
334 
335     ESP_LOGV(TAG, "--> add rx");
336 
337     if (ssl->MBEDTLS_PRIVATE(in_buf)) {
338         if (esp_mbedtls_get_buf_state(ssl->MBEDTLS_PRIVATE(in_buf)) == ESP_MBEDTLS_SSL_BUF_CACHED) {
339             ESP_LOGV(TAG, "in buffer is not empty");
340             ret = 0;
341             goto exit;
342         } else {
343             cached = 1;
344         }
345     }
346 
347     ssl->MBEDTLS_PRIVATE(in_hdr) = msg_head;
348     ssl->MBEDTLS_PRIVATE(in_len) = msg_head + 3;
349 
350     if ((ret = mbedtls_ssl_fetch_input(ssl, mbedtls_ssl_in_hdr_len(ssl))) != 0) {
351         if (ret == MBEDTLS_ERR_SSL_TIMEOUT) {
352             ESP_LOGD(TAG, "mbedtls_ssl_fetch_input reads data times out");
353         } else if (ret == MBEDTLS_ERR_SSL_WANT_READ) {
354             ESP_LOGD(TAG, "mbedtls_ssl_fetch_input wants to read more data");
355         } else {
356             ESP_LOGE(TAG, "mbedtls_ssl_fetch_input error=%d", -ret);
357         }
358 
359         goto exit;
360     }
361 
362     esp_mbedtls_parse_record_header(ssl);
363 
364     in_left = ssl->MBEDTLS_PRIVATE(in_left);
365     in_msglen = ssl->MBEDTLS_PRIVATE(in_msglen);
366     buffer_len = tx_buffer_len(ssl, in_msglen);
367 
368     ESP_LOGV(TAG, "message length is %d RX buffer length should be %d left is %d",
369                 (int)in_msglen, (int)buffer_len, (int)ssl->MBEDTLS_PRIVATE(in_left));
370 
371     if (cached) {
372         memcpy(cache_buf, ssl->MBEDTLS_PRIVATE(in_buf), 16);
373         esp_mbedtls_free_buf(ssl->MBEDTLS_PRIVATE(in_buf));
374         init_rx_buffer(ssl, NULL);
375     }
376 
377     esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + buffer_len);
378     if (!esp_buf) {
379         ESP_LOGE(TAG, "alloc(%d bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + buffer_len);
380         ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
381         goto exit;
382     }
383 
384     ESP_LOGV(TAG, "add in buffer %d bytes @ %p", buffer_len, esp_buf->buf);
385 
386     esp_mbedtls_init_ssl_buf(esp_buf, buffer_len);
387     init_rx_buffer(ssl, esp_buf->buf);
388 
389     if (cached) {
390         memcpy(ssl->MBEDTLS_PRIVATE(in_ctr), cache_buf, 8);
391         memcpy(ssl->MBEDTLS_PRIVATE(in_iv), cache_buf + 8, 8);
392     }
393 
394     memcpy(ssl->MBEDTLS_PRIVATE(in_hdr), msg_head, in_left);
395     ssl->MBEDTLS_PRIVATE(in_left) = in_left;
396     ssl->MBEDTLS_PRIVATE(in_msglen) = 0;
397 
398 exit:
399     ESP_LOGV(TAG, "<-- add rx");
400 
401     return ret;
402 }
403 
esp_mbedtls_free_rx_buffer(mbedtls_ssl_context * ssl)404 int esp_mbedtls_free_rx_buffer(mbedtls_ssl_context *ssl)
405 {
406     int ret = 0;
407     unsigned char buf[16];
408     struct esp_mbedtls_ssl_buf *esp_buf;
409 
410     ESP_LOGV(TAG, "--> free rx");
411 
412     /**
413      * When have read multi messages once, can't free the input buffer directly.
414      */
415     if (!ssl->MBEDTLS_PRIVATE(in_buf) || (ssl->MBEDTLS_PRIVATE(in_hslen) && (ssl->MBEDTLS_PRIVATE(in_hslen) < ssl->MBEDTLS_PRIVATE(in_msglen))) ||
416         (ssl->MBEDTLS_PRIVATE(in_buf) && (esp_mbedtls_get_buf_state(ssl->MBEDTLS_PRIVATE(in_buf)) == ESP_MBEDTLS_SSL_BUF_NO_CACHED))) {
417         ret = 0;
418         goto exit;
419     }
420 
421     /**
422      * The previous processing is just skipped, so "ssl->MBEDTLS_PRIVATE(in_msglen) = 0"
423      */
424     if (!ssl->MBEDTLS_PRIVATE(in_msgtype)
425 #if defined(MBEDTLS_SSL_SRV_C)
426         /**
427          * The ssl server read ClientHello manually without mbedtls_ssl_read_record(), so in_msgtype is not set and is zero.
428          * ClientHello has been processed and rx buffer should be freed.
429          * After processing ClientHello, the ssl state has been changed to MBEDTLS_SSL_SERVER_HELLO.
430          */
431         && !(ssl->MBEDTLS_PRIVATE(conf)->MBEDTLS_PRIVATE(endpoint) == MBEDTLS_SSL_IS_SERVER && ssl->MBEDTLS_PRIVATE(state) == MBEDTLS_SSL_SERVER_HELLO)
432 #endif
433     ) {
434         goto exit;
435     }
436 
437     memcpy(buf, ssl->MBEDTLS_PRIVATE(in_ctr), 8);
438     memcpy(buf + 8, ssl->MBEDTLS_PRIVATE(in_iv), 8);
439 
440     esp_mbedtls_free_buf(ssl->MBEDTLS_PRIVATE(in_buf));
441     init_rx_buffer(ssl, NULL);
442 
443     esp_buf = mbedtls_calloc(1, SSL_BUF_HEAD_OFFSET_SIZE + 16);
444     if (!esp_buf) {
445         ESP_LOGE(TAG, "alloc(%d bytes) failed", SSL_BUF_HEAD_OFFSET_SIZE + 16);
446         ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
447         goto exit;
448     }
449 
450     esp_mbedtls_init_ssl_buf(esp_buf, 16);
451     memcpy(esp_buf->buf, buf, 16);
452     init_rx_buffer(ssl, esp_buf->buf);
453     esp_mbedtls_set_buf_state(ssl->MBEDTLS_PRIVATE(in_buf), ESP_MBEDTLS_SSL_BUF_NO_CACHED);
454 exit:
455     ESP_LOGV(TAG, "<-- free rx");
456 
457     return ret;
458 }
459 
esp_mbedtls_get_crt_size(mbedtls_x509_crt * cert,size_t * num)460 size_t esp_mbedtls_get_crt_size(mbedtls_x509_crt *cert, size_t *num)
461 {
462     size_t n = 0;
463     size_t bytes = 0;
464 
465     while (cert) {
466         bytes += cert->raw.len;
467         n++;
468 
469         cert = cert->next;
470     }
471 
472     *num = n;
473 
474     return bytes;
475 }
476 
477 #ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA
esp_mbedtls_free_dhm(mbedtls_ssl_context * ssl)478 void esp_mbedtls_free_dhm(mbedtls_ssl_context *ssl)
479 {
480 #ifdef CONFIG_MBEDTLS_DHM_C
481     const mbedtls_ssl_config *conf = mbedtls_ssl_context_get_config(ssl);
482     mbedtls_mpi_free((mbedtls_mpi *)&conf->MBEDTLS_PRIVATE(dhm_P));
483     mbedtls_mpi_free((mbedtls_mpi *)&conf->MBEDTLS_PRIVATE(dhm_G));
484 #endif /* CONFIG_MBEDTLS_DHM_C */
485 }
486 
esp_mbedtls_free_keycert(mbedtls_ssl_context * ssl)487 void esp_mbedtls_free_keycert(mbedtls_ssl_context *ssl)
488 {
489     mbedtls_ssl_config *conf = (mbedtls_ssl_config * )mbedtls_ssl_context_get_config(ssl);
490     mbedtls_ssl_key_cert *keycert = conf->MBEDTLS_PRIVATE(key_cert), *next;
491 
492     while (keycert) {
493         next = keycert->next;
494 
495         if (keycert) {
496             mbedtls_free(keycert);
497         }
498 
499         keycert = next;
500     }
501 
502     conf->MBEDTLS_PRIVATE(key_cert) = NULL;
503 }
504 
esp_mbedtls_free_keycert_key(mbedtls_ssl_context * ssl)505 void esp_mbedtls_free_keycert_key(mbedtls_ssl_context *ssl)
506 {
507     const mbedtls_ssl_config *conf = mbedtls_ssl_context_get_config(ssl);
508     mbedtls_ssl_key_cert *keycert = conf->MBEDTLS_PRIVATE(key_cert);
509 
510     while (keycert) {
511         if (keycert->key) {
512             mbedtls_pk_free(keycert->key);
513             keycert->key = NULL;
514         }
515         keycert = keycert->next;
516     }
517 }
518 
esp_mbedtls_free_keycert_cert(mbedtls_ssl_context * ssl)519 void esp_mbedtls_free_keycert_cert(mbedtls_ssl_context *ssl)
520 {
521     const mbedtls_ssl_config *conf = mbedtls_ssl_context_get_config(ssl);
522     mbedtls_ssl_key_cert *keycert = conf->MBEDTLS_PRIVATE(key_cert);
523 
524     while (keycert) {
525         if (keycert->cert) {
526             mbedtls_x509_crt_free(keycert->cert);
527             keycert->cert = NULL;
528         }
529         keycert = keycert->next;
530     }
531 }
532 #endif /* CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA */
533 
534 #ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT
esp_mbedtls_free_cacert(mbedtls_ssl_context * ssl)535 void esp_mbedtls_free_cacert(mbedtls_ssl_context *ssl)
536 {
537     if (ssl->MBEDTLS_PRIVATE(conf)->MBEDTLS_PRIVATE(ca_chain)) {
538         mbedtls_ssl_config *conf = (mbedtls_ssl_config * )mbedtls_ssl_context_get_config(ssl);
539 
540 #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
541         /* In case of mbedtls certificate bundle, we attach a "static const"
542          * dummy cert, thus we need to avoid the write operations (memset())
543          * performed by `mbedtls_x509_crt_free()`
544          */
545         if (!esp_crt_bundle_in_use(conf->MBEDTLS_PRIVATE(ca_chain))) {
546             mbedtls_x509_crt_free(conf->MBEDTLS_PRIVATE(ca_chain));
547         }
548 #else
549         mbedtls_x509_crt_free(conf->MBEDTLS_PRIVATE(ca_chain));
550 #endif
551 
552         conf->MBEDTLS_PRIVATE(ca_chain) = NULL;
553     }
554 }
555 #endif /* CONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT */
556