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 "esp_mbedtls_dynamic_impl.h"
8 
9 int __real_mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl);
10 
11 int __wrap_mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl);
12 
13 static const char *TAG = "SSL Server";
14 
15 #ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA
16 /**
17  * Check if ciphersuite uses rsa key exchange methods.
18  */
ssl_ciphersuite_uses_rsa_key_ex(mbedtls_ssl_context * ssl)19 static bool ssl_ciphersuite_uses_rsa_key_ex(mbedtls_ssl_context *ssl)
20 {
21     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
22         ssl->MBEDTLS_PRIVATE(handshake)->ciphersuite_info;
23 
24     if (ciphersuite_info->MBEDTLS_PRIVATE(key_exchange) == MBEDTLS_KEY_EXCHANGE_RSA ||
25         ciphersuite_info->MBEDTLS_PRIVATE(key_exchange) == MBEDTLS_KEY_EXCHANGE_RSA_PSK) {
26         return true;
27     } else {
28         return false;
29     }
30 }
31 #endif
32 
manage_resource(mbedtls_ssl_context * ssl,bool add)33 static int manage_resource(mbedtls_ssl_context *ssl, bool add)
34 {
35     int state = add ? ssl->MBEDTLS_PRIVATE(state) : ssl->MBEDTLS_PRIVATE(state) - 1;
36 
37     if (mbedtls_ssl_is_handshake_over(ssl) || ssl->MBEDTLS_PRIVATE(handshake) == NULL) {
38         return 0;
39     }
40 
41     if (!add) {
42         if (!ssl->MBEDTLS_PRIVATE(out_left)) {
43             CHECK_OK(esp_mbedtls_free_tx_buffer(ssl));
44         }
45     }
46 
47     switch (state) {
48         case MBEDTLS_SSL_HELLO_REQUEST:
49             break;
50         case MBEDTLS_SSL_CLIENT_HELLO:
51             if (add) {
52                 CHECK_OK(esp_mbedtls_add_rx_buffer(ssl));
53             } else {
54                 CHECK_OK(esp_mbedtls_free_rx_buffer(ssl));
55             }
56             break;
57 
58 
59         case MBEDTLS_SSL_SERVER_HELLO:
60             if (add) {
61                 size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
62 
63                 CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len));
64             }
65             break;
66         case MBEDTLS_SSL_SERVER_CERTIFICATE:
67             if (add) {
68                 size_t buffer_len = 3;
69 
70                 const mbedtls_ssl_config *conf = mbedtls_ssl_context_get_config(ssl);
71                 mbedtls_ssl_key_cert *key_cert = conf->MBEDTLS_PRIVATE(key_cert);
72 
73                 while (key_cert && key_cert->cert) {
74                     size_t num;
75 
76                     buffer_len += esp_mbedtls_get_crt_size(key_cert->cert, &num);
77                     buffer_len += num * 3;
78 
79                     key_cert = key_cert->next;
80                 }
81 
82                 buffer_len = MAX(buffer_len, MBEDTLS_SSL_OUT_BUFFER_LEN);
83 
84                 CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len));
85             } else {
86 #ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA
87                 /**
88                  * Not free keycert->cert until MBEDTLS_SSL_CLIENT_KEY_EXCHANGE for rsa key exchange methods.
89                  * For ssl server will use keycert->cert to parse client key exchange.
90                  */
91                 if (!ssl_ciphersuite_uses_rsa_key_ex(ssl)) {
92                     esp_mbedtls_free_keycert_cert(ssl);
93                 }
94 #endif
95             }
96             break;
97         case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
98             if (add) {
99                 size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
100 
101                 CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len));
102             } else {
103 #ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA
104                 esp_mbedtls_free_dhm(ssl);
105                 /**
106                  * Not free keycert->key and keycert until MBEDTLS_SSL_CLIENT_KEY_EXCHANGE for rsa key exchange methods.
107                  * For ssl server will use keycert->key to parse client key exchange.
108                  */
109                 if (!ssl_ciphersuite_uses_rsa_key_ex(ssl)) {
110                     esp_mbedtls_free_keycert_key(ssl);
111                     esp_mbedtls_free_keycert(ssl);
112                 }
113 #endif
114             }
115             break;
116         case MBEDTLS_SSL_CERTIFICATE_REQUEST:
117             if (add) {
118                 size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
119 
120                 CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len));
121             }
122             break;
123         case MBEDTLS_SSL_SERVER_HELLO_DONE:
124             if (add) {
125                 size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
126 
127                 CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len));
128             }
129             break;
130 
131 
132         case MBEDTLS_SSL_CLIENT_CERTIFICATE:
133             if (add) {
134                 CHECK_OK(esp_mbedtls_add_rx_buffer(ssl));
135             } else {
136                 CHECK_OK(esp_mbedtls_free_rx_buffer(ssl));
137 
138 #ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT
139                 esp_mbedtls_free_cacert(ssl);
140 #endif
141             }
142             break;
143         case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
144             if (add) {
145                 CHECK_OK(esp_mbedtls_add_rx_buffer(ssl));
146             } else {
147                 CHECK_OK(esp_mbedtls_free_rx_buffer(ssl));
148 
149 #ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA
150                 /**
151                  * Free keycert after MBEDTLS_SSL_CLIENT_KEY_EXCHANGE for rsa key exchange methods.
152                  * For ssl server will use keycert->cert and keycert->key to parse client key exchange.
153                  */
154                 if (ssl_ciphersuite_uses_rsa_key_ex(ssl)) {
155                     esp_mbedtls_free_keycert_cert(ssl);
156                     esp_mbedtls_free_keycert_key(ssl);
157                     esp_mbedtls_free_keycert(ssl);
158                 }
159 #endif
160             }
161             break;
162         case MBEDTLS_SSL_CERTIFICATE_VERIFY:
163             if (add) {
164                 CHECK_OK(esp_mbedtls_add_rx_buffer(ssl));
165             } else {
166                 CHECK_OK(esp_mbedtls_free_rx_buffer(ssl));
167             }
168             break;
169         case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
170             if (add) {
171                 CHECK_OK(esp_mbedtls_add_rx_buffer(ssl));
172             } else {
173                 CHECK_OK(esp_mbedtls_free_rx_buffer(ssl));
174             }
175             break;
176         case MBEDTLS_SSL_CLIENT_FINISHED:
177             if (add) {
178                 CHECK_OK(esp_mbedtls_add_rx_buffer(ssl));
179             } else {
180                 CHECK_OK(esp_mbedtls_free_rx_buffer(ssl));
181             }
182             break;
183 
184 
185         case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
186             if (add) {
187                 size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
188 
189                 CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len));
190             }
191             break;
192         case MBEDTLS_SSL_SERVER_FINISHED:
193             if (add) {
194                 size_t buffer_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
195 
196                 CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len));
197             }
198             break;
199         case MBEDTLS_SSL_FLUSH_BUFFERS:
200             break;
201         case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
202             break;
203         default:
204             break;
205     }
206 
207     return 0;
208 }
209 
__wrap_mbedtls_ssl_handshake_server_step(mbedtls_ssl_context * ssl)210 int __wrap_mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl)
211 {
212     CHECK_OK(manage_resource(ssl, true));
213 
214     CHECK_OK(__real_mbedtls_ssl_handshake_server_step(ssl));
215 
216     CHECK_OK(manage_resource(ssl, false));
217 
218     return 0;
219 }
220