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