1 /*
2  * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <sys/param.h>
7 #include "mbedtls/error.h"
8 #include "esp_mbedtls_dynamic_impl.h"
9 
10 int __real_mbedtls_ssl_write(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len);
11 int __real_mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len);
12 void __real_mbedtls_ssl_free(mbedtls_ssl_context *ssl);
13 int __real_mbedtls_ssl_session_reset(mbedtls_ssl_context *ssl);
14 int __real_mbedtls_ssl_setup(mbedtls_ssl_context *ssl, const mbedtls_ssl_config *conf);
15 int __real_mbedtls_ssl_send_alert_message(mbedtls_ssl_context *ssl, unsigned char level, unsigned char message);
16 int __real_mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl);
17 
18 int __wrap_mbedtls_ssl_write(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len);
19 int __wrap_mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len);
20 void __wrap_mbedtls_ssl_free(mbedtls_ssl_context *ssl);
21 int __wrap_mbedtls_ssl_session_reset(mbedtls_ssl_context *ssl);
22 int __wrap_mbedtls_ssl_setup(mbedtls_ssl_context *ssl, const mbedtls_ssl_config *conf);
23 int __wrap_mbedtls_ssl_send_alert_message(mbedtls_ssl_context *ssl, unsigned char level, unsigned char message);
24 int __wrap_mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl);
25 
26 static const char *TAG = "SSL TLS";
27 
tx_done(mbedtls_ssl_context * ssl)28 static int tx_done(mbedtls_ssl_context *ssl)
29 {
30     if (!ssl->MBEDTLS_PRIVATE(out_left))
31         return 1;
32 
33     return 0;
34 }
35 
rx_done(mbedtls_ssl_context * ssl)36 static int rx_done(mbedtls_ssl_context *ssl)
37 {
38     if (!ssl->MBEDTLS_PRIVATE(in_msglen)) {
39         return 1;
40     }
41 
42     ESP_LOGD(TAG, "RX left %zu bytes", ssl->MBEDTLS_PRIVATE(in_msglen));
43     return 0;
44 }
45 
ssl_update_checksum_start(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)46 static int ssl_update_checksum_start( mbedtls_ssl_context *ssl,
47                                        const unsigned char *buf, size_t len )
48 {
49     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
50 #if defined(MBEDTLS_SHA256_C)
51     ret = mbedtls_md_update( &ssl->handshake->fin_sha256, buf, len );
52 #endif
53 #if defined(MBEDTLS_SHA512_C)
54     ret = mbedtls_md_update( &ssl->handshake->fin_sha384, buf, len );
55 #endif
56     return ret;
57 }
58 
ssl_handshake_params_init(mbedtls_ssl_handshake_params * handshake)59 static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake )
60 {
61     memset( handshake, 0, sizeof( mbedtls_ssl_handshake_params ) );
62 
63 #if defined(MBEDTLS_SHA256_C)
64     mbedtls_md_init( &handshake->fin_sha256 );
65     mbedtls_md_setup( &handshake->fin_sha256,
66                     mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
67                     0 );
68     mbedtls_md_starts( &handshake->fin_sha256 );
69 #endif
70 #if defined(MBEDTLS_SHA512_C)
71     mbedtls_md_init( &handshake->fin_sha384 );
72     mbedtls_md_setup( &handshake->fin_sha384,
73                     mbedtls_md_info_from_type(MBEDTLS_MD_SHA384),
74                     0 );
75     mbedtls_md_starts( &handshake->fin_sha384 );
76 #endif
77 
78     handshake->update_checksum = ssl_update_checksum_start;
79 
80 #if defined(MBEDTLS_DHM_C)
81     mbedtls_dhm_init( &handshake->dhm_ctx );
82 #endif
83 #if defined(MBEDTLS_ECDH_C)
84     mbedtls_ecdh_init( &handshake->ecdh_ctx );
85 #endif
86 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
87     mbedtls_ecjpake_init( &handshake->ecjpake_ctx );
88 #if defined(MBEDTLS_SSL_CLI_C)
89     handshake->ecjpake_cache = NULL;
90     handshake->ecjpake_cache_len = 0;
91 #endif
92 #endif
93 
94 #if defined(MBEDTLS_SSL_ECP_RESTARTABLE)
95     mbedtls_x509_crt_restart_init( &handshake->ecrs_ctx );
96 #endif
97 
98 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
99     handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET;
100 #endif
101 
102 #if defined(MBEDTLS_X509_CRT_PARSE_C) && \
103     !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
104     mbedtls_pk_init( &handshake->peer_pubkey );
105 #endif
106 }
107 
ssl_handshake_init(mbedtls_ssl_context * ssl)108 static int ssl_handshake_init( mbedtls_ssl_context *ssl )
109 {
110     /* Clear old handshake information if present */
111     if( ssl->transform_negotiate )
112         mbedtls_ssl_transform_free( ssl->transform_negotiate );
113     if( ssl->session_negotiate )
114         mbedtls_ssl_session_free( ssl->session_negotiate );
115     if( ssl->handshake )
116         mbedtls_ssl_handshake_free( ssl );
117 
118     /*
119      * Either the pointers are now NULL or cleared properly and can be freed.
120      * Now allocate missing structures.
121      */
122     if( ssl->transform_negotiate == NULL )
123     {
124         ssl->transform_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_transform) );
125     }
126 
127     if( ssl->session_negotiate == NULL )
128     {
129         ssl->session_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_session) );
130     }
131 
132     if( ssl->handshake == NULL )
133     {
134         ssl->handshake = mbedtls_calloc( 1, sizeof(mbedtls_ssl_handshake_params) );
135     }
136 #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
137     /* If the buffers are too small - reallocate */
138 
139     handle_buffer_resizing( ssl, 0, MBEDTLS_SSL_IN_BUFFER_LEN,
140                                     MBEDTLS_SSL_OUT_BUFFER_LEN );
141 #endif
142 
143     /* All pointers should exist and can be directly freed without issue */
144     if( ssl->handshake == NULL ||
145         ssl->transform_negotiate == NULL ||
146         ssl->session_negotiate == NULL )
147     {
148         ESP_LOGD(TAG, "alloc() of ssl sub-contexts failed");
149 
150         mbedtls_free( ssl->handshake );
151         mbedtls_free( ssl->transform_negotiate );
152         mbedtls_free( ssl->session_negotiate );
153 
154         ssl->handshake = NULL;
155         ssl->transform_negotiate = NULL;
156         ssl->session_negotiate = NULL;
157 
158         return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
159     }
160 
161     /* Initialize structures */
162     mbedtls_ssl_session_init( ssl->session_negotiate );
163     mbedtls_ssl_transform_init( ssl->transform_negotiate );
164     ssl_handshake_params_init( ssl->handshake );
165 
166 /*
167  * curve_list is translated to IANA TLS group identifiers here because
168  * mbedtls_ssl_conf_curves returns void and so can't return
169  * any error codes.
170  */
171 #if defined(MBEDTLS_ECP_C)
172 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
173     /* Heap allocate and translate curve_list from internal to IANA group ids */
174     if ( ssl->conf->curve_list != NULL )
175     {
176         size_t length;
177         const mbedtls_ecp_group_id *curve_list = ssl->conf->curve_list;
178 
179         for( length = 0;  ( curve_list[length] != MBEDTLS_ECP_DP_NONE ) &&
180                           ( length < MBEDTLS_ECP_DP_MAX ); length++ ) {}
181 
182         /* Leave room for zero termination */
183         uint16_t *group_list = mbedtls_calloc( length + 1, sizeof(uint16_t) );
184         if ( group_list == NULL )
185             return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
186 
187         for( size_t i = 0; i < length; i++ )
188         {
189             const mbedtls_ecp_curve_info *info =
190                         mbedtls_ecp_curve_info_from_grp_id( curve_list[i] );
191             if ( info == NULL )
192             {
193                 mbedtls_free( group_list );
194                 return( MBEDTLS_ERR_SSL_BAD_CONFIG );
195             }
196             group_list[i] = info->tls_id;
197         }
198 
199         group_list[length] = 0;
200 
201         ssl->handshake->group_list = group_list;
202         ssl->handshake->group_list_heap_allocated = 1;
203     }
204     else
205     {
206         ssl->handshake->group_list = ssl->conf->group_list;
207         ssl->handshake->group_list_heap_allocated = 0;
208     }
209 #endif /* MBEDTLS_DEPRECATED_REMOVED */
210 #endif /* MBEDTLS_ECP_C */
211 
212 #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
213 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
214 #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
215     /* Heap allocate and translate sig_hashes from internal hash identifiers to
216        signature algorithms IANA identifiers.  */
217     if ( mbedtls_ssl_conf_is_tls12_only( ssl->conf ) &&
218          ssl->conf->sig_hashes != NULL )
219     {
220         const int *md;
221         const int *sig_hashes = ssl->conf->sig_hashes;
222         size_t sig_algs_len = 0;
223         uint16_t *p;
224 
225 #if defined(static_assert)
226         static_assert( MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN
227                        <= ( SIZE_MAX - ( 2 * sizeof(uint16_t) ) ),
228                        "MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN too big" );
229 #endif
230 
231         for( md = sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
232         {
233             if( mbedtls_ssl_hash_from_md_alg( *md ) == MBEDTLS_SSL_HASH_NONE )
234                 continue;
235 #if defined(MBEDTLS_ECDSA_C)
236             sig_algs_len += sizeof( uint16_t );
237 #endif
238 
239 #if defined(MBEDTLS_RSA_C)
240             sig_algs_len += sizeof( uint16_t );
241 #endif
242             if( sig_algs_len > MBEDTLS_SSL_MAX_SIG_ALG_LIST_LEN )
243                 return( MBEDTLS_ERR_SSL_BAD_CONFIG );
244         }
245 
246         if( sig_algs_len < MBEDTLS_SSL_MIN_SIG_ALG_LIST_LEN )
247             return( MBEDTLS_ERR_SSL_BAD_CONFIG );
248 
249         ssl->handshake->sig_algs = mbedtls_calloc( 1, sig_algs_len +
250                                                       sizeof( uint16_t ));
251         if( ssl->handshake->sig_algs == NULL )
252             return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
253 
254         p = (uint16_t *)ssl->handshake->sig_algs;
255         for( md = sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
256         {
257             unsigned char hash = mbedtls_ssl_hash_from_md_alg( *md );
258             if( hash == MBEDTLS_SSL_HASH_NONE )
259                 continue;
260 #if defined(MBEDTLS_ECDSA_C)
261             *p = (( hash << 8 ) | MBEDTLS_SSL_SIG_ECDSA);
262             p++;
263 #endif
264 #if defined(MBEDTLS_RSA_C)
265             *p = (( hash << 8 ) | MBEDTLS_SSL_SIG_RSA);
266             p++;
267 #endif
268         }
269         *p = MBEDTLS_TLS_SIG_NONE;
270         ssl->handshake->sig_algs_heap_allocated = 1;
271     }
272     else
273 #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
274     {
275         ssl->handshake->sig_algs_heap_allocated = 0;
276     }
277 #endif /* !MBEDTLS_DEPRECATED_REMOVED */
278 #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
279 
280     return( 0 );
281 }
282 
__wrap_mbedtls_ssl_setup(mbedtls_ssl_context * ssl,const mbedtls_ssl_config * conf)283 int __wrap_mbedtls_ssl_setup(mbedtls_ssl_context *ssl, const mbedtls_ssl_config *conf)
284 {
285     ssl->conf = conf;
286     ssl->tls_version = ssl->conf->max_tls_version;
287 
288     CHECK_OK(ssl_handshake_init(ssl));
289 
290     mbedtls_free(ssl->MBEDTLS_PRIVATE(out_buf));
291     ssl->MBEDTLS_PRIVATE(out_buf) = NULL;
292     CHECK_OK(esp_mbedtls_setup_tx_buffer(ssl));
293 
294     mbedtls_free(ssl->MBEDTLS_PRIVATE(in_buf));
295     ssl->MBEDTLS_PRIVATE(in_buf) = NULL;
296     esp_mbedtls_setup_rx_buffer(ssl);
297 
298     return 0;
299 }
300 
__wrap_mbedtls_ssl_write(mbedtls_ssl_context * ssl,unsigned char * buf,size_t len)301 int __wrap_mbedtls_ssl_write(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
302 {
303     int ret;
304 
305     CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, 0));
306 
307     ret = __real_mbedtls_ssl_write(ssl, buf, len);
308 
309     if (tx_done(ssl)) {
310         CHECK_OK(esp_mbedtls_free_tx_buffer(ssl));
311     }
312 
313     return ret;
314 }
315 
__wrap_mbedtls_ssl_read(mbedtls_ssl_context * ssl,unsigned char * buf,size_t len)316 int __wrap_mbedtls_ssl_read(mbedtls_ssl_context *ssl, unsigned char *buf, size_t len)
317 {
318     int ret;
319 
320     ESP_LOGD(TAG, "add mbedtls RX buffer");
321     ret = esp_mbedtls_add_rx_buffer(ssl);
322     if (ret == MBEDTLS_ERR_SSL_CONN_EOF) {
323         ESP_LOGD(TAG, "fail, the connection indicated an EOF");
324         return 0;
325     } else if (ret < 0) {
326         ESP_LOGD(TAG, "fail, error=%d", -ret);
327         return ret;
328     }
329     ESP_LOGD(TAG, "end");
330 
331     ret = __real_mbedtls_ssl_read(ssl, buf, len);
332 
333     if (rx_done(ssl)) {
334         CHECK_OK(esp_mbedtls_free_rx_buffer(ssl));
335     }
336 
337     return ret;
338 }
339 
__wrap_mbedtls_ssl_free(mbedtls_ssl_context * ssl)340 void __wrap_mbedtls_ssl_free(mbedtls_ssl_context *ssl)
341 {
342     if (ssl->MBEDTLS_PRIVATE(out_buf)) {
343         esp_mbedtls_free_buf(ssl->MBEDTLS_PRIVATE(out_buf));
344         ssl->MBEDTLS_PRIVATE(out_buf) = NULL;
345     }
346 
347     if (ssl->MBEDTLS_PRIVATE(in_buf)) {
348         esp_mbedtls_free_buf(ssl->MBEDTLS_PRIVATE(in_buf));
349         ssl->MBEDTLS_PRIVATE(in_buf) = NULL;
350     }
351 
352     __real_mbedtls_ssl_free(ssl);
353 }
354 
__wrap_mbedtls_ssl_session_reset(mbedtls_ssl_context * ssl)355 int __wrap_mbedtls_ssl_session_reset(mbedtls_ssl_context *ssl)
356 {
357     CHECK_OK(esp_mbedtls_reset_add_tx_buffer(ssl));
358 
359     CHECK_OK(esp_mbedtls_reset_add_rx_buffer(ssl));
360 
361     CHECK_OK(__real_mbedtls_ssl_session_reset(ssl));
362 
363     CHECK_OK(esp_mbedtls_reset_free_tx_buffer(ssl));
364 
365     esp_mbedtls_reset_free_rx_buffer(ssl);
366 
367     return 0;
368 }
369 
__wrap_mbedtls_ssl_send_alert_message(mbedtls_ssl_context * ssl,unsigned char level,unsigned char message)370 int __wrap_mbedtls_ssl_send_alert_message(mbedtls_ssl_context *ssl, unsigned char level, unsigned char message)
371 {
372     int ret;
373 
374     CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, 0));
375 
376     ret = __real_mbedtls_ssl_send_alert_message(ssl, level, message);
377 
378     if (tx_done(ssl)) {
379         CHECK_OK(esp_mbedtls_free_tx_buffer(ssl));
380     }
381 
382     return ret;
383 }
384 
__wrap_mbedtls_ssl_close_notify(mbedtls_ssl_context * ssl)385 int __wrap_mbedtls_ssl_close_notify(mbedtls_ssl_context *ssl)
386 {
387     int ret;
388 
389     CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, 0));
390 
391     ret = __real_mbedtls_ssl_close_notify(ssl);
392 
393     if (tx_done(ssl)) {
394         CHECK_OK(esp_mbedtls_free_tx_buffer(ssl));
395     }
396 
397     return ret;
398 }
399