xref: /optee_os/lib/libmbedtls/mbedtls/library/ssl_tls12_client.c (revision 32b3180828fa15a49ccc86ecb4be9d274c140c89)
1*32b31808SJens Wiklander /*
2*32b31808SJens Wiklander  *  TLS client-side functions
3*32b31808SJens Wiklander  *
4*32b31808SJens Wiklander  *  Copyright The Mbed TLS Contributors
5*32b31808SJens Wiklander  *  SPDX-License-Identifier: Apache-2.0
6*32b31808SJens Wiklander  *
7*32b31808SJens Wiklander  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
8*32b31808SJens Wiklander  *  not use this file except in compliance with the License.
9*32b31808SJens Wiklander  *  You may obtain a copy of the License at
10*32b31808SJens Wiklander  *
11*32b31808SJens Wiklander  *  http://www.apache.org/licenses/LICENSE-2.0
12*32b31808SJens Wiklander  *
13*32b31808SJens Wiklander  *  Unless required by applicable law or agreed to in writing, software
14*32b31808SJens Wiklander  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15*32b31808SJens Wiklander  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*32b31808SJens Wiklander  *  See the License for the specific language governing permissions and
17*32b31808SJens Wiklander  *  limitations under the License.
18*32b31808SJens Wiklander  */
19*32b31808SJens Wiklander 
20*32b31808SJens Wiklander #include "common.h"
21*32b31808SJens Wiklander 
22*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_2)
23*32b31808SJens Wiklander 
24*32b31808SJens Wiklander #include "mbedtls/platform.h"
25*32b31808SJens Wiklander 
26*32b31808SJens Wiklander #include "mbedtls/ssl.h"
27*32b31808SJens Wiklander #include "ssl_client.h"
28*32b31808SJens Wiklander #include "ssl_misc.h"
29*32b31808SJens Wiklander #include "mbedtls/debug.h"
30*32b31808SJens Wiklander #include "mbedtls/error.h"
31*32b31808SJens Wiklander #include "mbedtls/constant_time.h"
32*32b31808SJens Wiklander 
33*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
34*32b31808SJens Wiklander #include "mbedtls/psa_util.h"
35*32b31808SJens Wiklander #include "psa/crypto.h"
36*32b31808SJens Wiklander #define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status,   \
37*32b31808SJens Wiklander                                                            psa_to_ssl_errors,             \
38*32b31808SJens Wiklander                                                            psa_generic_status_to_mbedtls)
39*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
40*32b31808SJens Wiklander 
41*32b31808SJens Wiklander #include <string.h>
42*32b31808SJens Wiklander 
43*32b31808SJens Wiklander #include <stdint.h>
44*32b31808SJens Wiklander 
45*32b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME)
46*32b31808SJens Wiklander #include "mbedtls/platform_time.h"
47*32b31808SJens Wiklander #endif
48*32b31808SJens Wiklander 
49*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
50*32b31808SJens Wiklander #include "mbedtls/platform_util.h"
51*32b31808SJens Wiklander #endif
52*32b31808SJens Wiklander 
53*32b31808SJens Wiklander #include "hash_info.h"
54*32b31808SJens Wiklander 
55*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
56*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
57*32b31808SJens Wiklander static int ssl_write_renegotiation_ext(mbedtls_ssl_context *ssl,
58*32b31808SJens Wiklander                                        unsigned char *buf,
59*32b31808SJens Wiklander                                        const unsigned char *end,
60*32b31808SJens Wiklander                                        size_t *olen)
61*32b31808SJens Wiklander {
62*32b31808SJens Wiklander     unsigned char *p = buf;
63*32b31808SJens Wiklander 
64*32b31808SJens Wiklander     *olen = 0;
65*32b31808SJens Wiklander 
66*32b31808SJens Wiklander     /* We're always including a TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the
67*32b31808SJens Wiklander      * initial ClientHello, in which case also adding the renegotiation
68*32b31808SJens Wiklander      * info extension is NOT RECOMMENDED as per RFC 5746 Section 3.4. */
69*32b31808SJens Wiklander     if (ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
70*32b31808SJens Wiklander         return 0;
71*32b31808SJens Wiklander     }
72*32b31808SJens Wiklander 
73*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
74*32b31808SJens Wiklander                           ("client hello, adding renegotiation extension"));
75*32b31808SJens Wiklander 
76*32b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 5 + ssl->verify_data_len);
77*32b31808SJens Wiklander 
78*32b31808SJens Wiklander     /*
79*32b31808SJens Wiklander      * Secure renegotiation
80*32b31808SJens Wiklander      */
81*32b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_RENEGOTIATION_INFO, p, 0);
82*32b31808SJens Wiklander     p += 2;
83*32b31808SJens Wiklander 
84*32b31808SJens Wiklander     *p++ = 0x00;
85*32b31808SJens Wiklander     *p++ = MBEDTLS_BYTE_0(ssl->verify_data_len + 1);
86*32b31808SJens Wiklander     *p++ = MBEDTLS_BYTE_0(ssl->verify_data_len);
87*32b31808SJens Wiklander 
88*32b31808SJens Wiklander     memcpy(p, ssl->own_verify_data, ssl->verify_data_len);
89*32b31808SJens Wiklander 
90*32b31808SJens Wiklander     *olen = 5 + ssl->verify_data_len;
91*32b31808SJens Wiklander 
92*32b31808SJens Wiklander     return 0;
93*32b31808SJens Wiklander }
94*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */
95*32b31808SJens Wiklander 
96*32b31808SJens Wiklander #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
97*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
98*32b31808SJens Wiklander 
99*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
100*32b31808SJens Wiklander static int ssl_write_supported_point_formats_ext(mbedtls_ssl_context *ssl,
101*32b31808SJens Wiklander                                                  unsigned char *buf,
102*32b31808SJens Wiklander                                                  const unsigned char *end,
103*32b31808SJens Wiklander                                                  size_t *olen)
104*32b31808SJens Wiklander {
105*32b31808SJens Wiklander     unsigned char *p = buf;
106*32b31808SJens Wiklander     (void) ssl; /* ssl used for debugging only */
107*32b31808SJens Wiklander 
108*32b31808SJens Wiklander     *olen = 0;
109*32b31808SJens Wiklander 
110*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
111*32b31808SJens Wiklander                           ("client hello, adding supported_point_formats extension"));
112*32b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6);
113*32b31808SJens Wiklander 
114*32b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, p, 0);
115*32b31808SJens Wiklander     p += 2;
116*32b31808SJens Wiklander 
117*32b31808SJens Wiklander     *p++ = 0x00;
118*32b31808SJens Wiklander     *p++ = 2;
119*32b31808SJens Wiklander 
120*32b31808SJens Wiklander     *p++ = 1;
121*32b31808SJens Wiklander     *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED;
122*32b31808SJens Wiklander 
123*32b31808SJens Wiklander     *olen = 6;
124*32b31808SJens Wiklander 
125*32b31808SJens Wiklander     return 0;
126*32b31808SJens Wiklander }
127*32b31808SJens Wiklander #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
128*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
129*32b31808SJens Wiklander 
130*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
131*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
132*32b31808SJens Wiklander static int ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl,
133*32b31808SJens Wiklander                                       unsigned char *buf,
134*32b31808SJens Wiklander                                       const unsigned char *end,
135*32b31808SJens Wiklander                                       size_t *olen)
136*32b31808SJens Wiklander {
137*32b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
138*32b31808SJens Wiklander     unsigned char *p = buf;
139*32b31808SJens Wiklander     size_t kkpp_len = 0;
140*32b31808SJens Wiklander 
141*32b31808SJens Wiklander     *olen = 0;
142*32b31808SJens Wiklander 
143*32b31808SJens Wiklander     /* Skip costly extension if we can't use EC J-PAKE anyway */
144*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
145*32b31808SJens Wiklander     if (ssl->handshake->psa_pake_ctx_is_ok != 1) {
146*32b31808SJens Wiklander         return 0;
147*32b31808SJens Wiklander     }
148*32b31808SJens Wiklander #else
149*32b31808SJens Wiklander     if (mbedtls_ecjpake_check(&ssl->handshake->ecjpake_ctx) != 0) {
150*32b31808SJens Wiklander         return 0;
151*32b31808SJens Wiklander     }
152*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
153*32b31808SJens Wiklander 
154*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
155*32b31808SJens Wiklander                           ("client hello, adding ecjpake_kkpp extension"));
156*32b31808SJens Wiklander 
157*32b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4);
158*32b31808SJens Wiklander 
159*32b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0);
160*32b31808SJens Wiklander     p += 2;
161*32b31808SJens Wiklander 
162*32b31808SJens Wiklander     /*
163*32b31808SJens Wiklander      * We may need to send ClientHello multiple times for Hello verification.
164*32b31808SJens Wiklander      * We don't want to compute fresh values every time (both for performance
165*32b31808SJens Wiklander      * and consistency reasons), so cache the extension content.
166*32b31808SJens Wiklander      */
167*32b31808SJens Wiklander     if (ssl->handshake->ecjpake_cache == NULL ||
168*32b31808SJens Wiklander         ssl->handshake->ecjpake_cache_len == 0) {
169*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("generating new ecjpake parameters"));
170*32b31808SJens Wiklander 
171*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
172*32b31808SJens Wiklander         ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx,
173*32b31808SJens Wiklander                                               p + 2, end - p - 2, &kkpp_len,
174*32b31808SJens Wiklander                                               MBEDTLS_ECJPAKE_ROUND_ONE);
175*32b31808SJens Wiklander         if (ret != 0) {
176*32b31808SJens Wiklander             psa_destroy_key(ssl->handshake->psa_pake_password);
177*32b31808SJens Wiklander             psa_pake_abort(&ssl->handshake->psa_pake_ctx);
178*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret);
179*32b31808SJens Wiklander             return ret;
180*32b31808SJens Wiklander         }
181*32b31808SJens Wiklander #else
182*32b31808SJens Wiklander         ret = mbedtls_ecjpake_write_round_one(&ssl->handshake->ecjpake_ctx,
183*32b31808SJens Wiklander                                               p + 2, end - p - 2, &kkpp_len,
184*32b31808SJens Wiklander                                               ssl->conf->f_rng, ssl->conf->p_rng);
185*32b31808SJens Wiklander         if (ret != 0) {
186*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1,
187*32b31808SJens Wiklander                                   "mbedtls_ecjpake_write_round_one", ret);
188*32b31808SJens Wiklander             return ret;
189*32b31808SJens Wiklander         }
190*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
191*32b31808SJens Wiklander 
192*32b31808SJens Wiklander         ssl->handshake->ecjpake_cache = mbedtls_calloc(1, kkpp_len);
193*32b31808SJens Wiklander         if (ssl->handshake->ecjpake_cache == NULL) {
194*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("allocation failed"));
195*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ALLOC_FAILED;
196*32b31808SJens Wiklander         }
197*32b31808SJens Wiklander 
198*32b31808SJens Wiklander         memcpy(ssl->handshake->ecjpake_cache, p + 2, kkpp_len);
199*32b31808SJens Wiklander         ssl->handshake->ecjpake_cache_len = kkpp_len;
200*32b31808SJens Wiklander     } else {
201*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("re-using cached ecjpake parameters"));
202*32b31808SJens Wiklander 
203*32b31808SJens Wiklander         kkpp_len = ssl->handshake->ecjpake_cache_len;
204*32b31808SJens Wiklander         MBEDTLS_SSL_CHK_BUF_PTR(p + 2, end, kkpp_len);
205*32b31808SJens Wiklander 
206*32b31808SJens Wiklander         memcpy(p + 2, ssl->handshake->ecjpake_cache, kkpp_len);
207*32b31808SJens Wiklander     }
208*32b31808SJens Wiklander 
209*32b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(kkpp_len, p, 0);
210*32b31808SJens Wiklander     p += 2;
211*32b31808SJens Wiklander 
212*32b31808SJens Wiklander     *olen = kkpp_len + 4;
213*32b31808SJens Wiklander 
214*32b31808SJens Wiklander     return 0;
215*32b31808SJens Wiklander }
216*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
217*32b31808SJens Wiklander 
218*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
219*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
220*32b31808SJens Wiklander static int ssl_write_cid_ext(mbedtls_ssl_context *ssl,
221*32b31808SJens Wiklander                              unsigned char *buf,
222*32b31808SJens Wiklander                              const unsigned char *end,
223*32b31808SJens Wiklander                              size_t *olen)
224*32b31808SJens Wiklander {
225*32b31808SJens Wiklander     unsigned char *p = buf;
226*32b31808SJens Wiklander     size_t ext_len;
227*32b31808SJens Wiklander 
228*32b31808SJens Wiklander     /*
229*32b31808SJens Wiklander      *   struct {
230*32b31808SJens Wiklander      *      opaque cid<0..2^8-1>;
231*32b31808SJens Wiklander      *   } ConnectionId;
232*32b31808SJens Wiklander      */
233*32b31808SJens Wiklander 
234*32b31808SJens Wiklander     *olen = 0;
235*32b31808SJens Wiklander     if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
236*32b31808SJens Wiklander         ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED) {
237*32b31808SJens Wiklander         return 0;
238*32b31808SJens Wiklander     }
239*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding CID extension"));
240*32b31808SJens Wiklander 
241*32b31808SJens Wiklander     /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX
242*32b31808SJens Wiklander      * which is at most 255, so the increment cannot overflow. */
243*32b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, (unsigned) (ssl->own_cid_len + 5));
244*32b31808SJens Wiklander 
245*32b31808SJens Wiklander     /* Add extension ID + size */
246*32b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_CID, p, 0);
247*32b31808SJens Wiklander     p += 2;
248*32b31808SJens Wiklander     ext_len = (size_t) ssl->own_cid_len + 1;
249*32b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(ext_len, p, 0);
250*32b31808SJens Wiklander     p += 2;
251*32b31808SJens Wiklander 
252*32b31808SJens Wiklander     *p++ = (uint8_t) ssl->own_cid_len;
253*32b31808SJens Wiklander     memcpy(p, ssl->own_cid, ssl->own_cid_len);
254*32b31808SJens Wiklander 
255*32b31808SJens Wiklander     *olen = ssl->own_cid_len + 5;
256*32b31808SJens Wiklander 
257*32b31808SJens Wiklander     return 0;
258*32b31808SJens Wiklander }
259*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
260*32b31808SJens Wiklander 
261*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
262*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
263*32b31808SJens Wiklander static int ssl_write_max_fragment_length_ext(mbedtls_ssl_context *ssl,
264*32b31808SJens Wiklander                                              unsigned char *buf,
265*32b31808SJens Wiklander                                              const unsigned char *end,
266*32b31808SJens Wiklander                                              size_t *olen)
267*32b31808SJens Wiklander {
268*32b31808SJens Wiklander     unsigned char *p = buf;
269*32b31808SJens Wiklander 
270*32b31808SJens Wiklander     *olen = 0;
271*32b31808SJens Wiklander 
272*32b31808SJens Wiklander     if (ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE) {
273*32b31808SJens Wiklander         return 0;
274*32b31808SJens Wiklander     }
275*32b31808SJens Wiklander 
276*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
277*32b31808SJens Wiklander                           ("client hello, adding max_fragment_length extension"));
278*32b31808SJens Wiklander 
279*32b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 5);
280*32b31808SJens Wiklander 
281*32b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, p, 0);
282*32b31808SJens Wiklander     p += 2;
283*32b31808SJens Wiklander 
284*32b31808SJens Wiklander     *p++ = 0x00;
285*32b31808SJens Wiklander     *p++ = 1;
286*32b31808SJens Wiklander 
287*32b31808SJens Wiklander     *p++ = ssl->conf->mfl_code;
288*32b31808SJens Wiklander 
289*32b31808SJens Wiklander     *olen = 5;
290*32b31808SJens Wiklander 
291*32b31808SJens Wiklander     return 0;
292*32b31808SJens Wiklander }
293*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
294*32b31808SJens Wiklander 
295*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
296*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
297*32b31808SJens Wiklander static int ssl_write_encrypt_then_mac_ext(mbedtls_ssl_context *ssl,
298*32b31808SJens Wiklander                                           unsigned char *buf,
299*32b31808SJens Wiklander                                           const unsigned char *end,
300*32b31808SJens Wiklander                                           size_t *olen)
301*32b31808SJens Wiklander {
302*32b31808SJens Wiklander     unsigned char *p = buf;
303*32b31808SJens Wiklander 
304*32b31808SJens Wiklander     *olen = 0;
305*32b31808SJens Wiklander 
306*32b31808SJens Wiklander     if (ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED) {
307*32b31808SJens Wiklander         return 0;
308*32b31808SJens Wiklander     }
309*32b31808SJens Wiklander 
310*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
311*32b31808SJens Wiklander                           ("client hello, adding encrypt_then_mac extension"));
312*32b31808SJens Wiklander 
313*32b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4);
314*32b31808SJens Wiklander 
315*32b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, p, 0);
316*32b31808SJens Wiklander     p += 2;
317*32b31808SJens Wiklander 
318*32b31808SJens Wiklander     *p++ = 0x00;
319*32b31808SJens Wiklander     *p++ = 0x00;
320*32b31808SJens Wiklander 
321*32b31808SJens Wiklander     *olen = 4;
322*32b31808SJens Wiklander 
323*32b31808SJens Wiklander     return 0;
324*32b31808SJens Wiklander }
325*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
326*32b31808SJens Wiklander 
327*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
328*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
329*32b31808SJens Wiklander static int ssl_write_extended_ms_ext(mbedtls_ssl_context *ssl,
330*32b31808SJens Wiklander                                      unsigned char *buf,
331*32b31808SJens Wiklander                                      const unsigned char *end,
332*32b31808SJens Wiklander                                      size_t *olen)
333*32b31808SJens Wiklander {
334*32b31808SJens Wiklander     unsigned char *p = buf;
335*32b31808SJens Wiklander 
336*32b31808SJens Wiklander     *olen = 0;
337*32b31808SJens Wiklander 
338*32b31808SJens Wiklander     if (ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED) {
339*32b31808SJens Wiklander         return 0;
340*32b31808SJens Wiklander     }
341*32b31808SJens Wiklander 
342*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
343*32b31808SJens Wiklander                           ("client hello, adding extended_master_secret extension"));
344*32b31808SJens Wiklander 
345*32b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4);
346*32b31808SJens Wiklander 
347*32b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, p, 0);
348*32b31808SJens Wiklander     p += 2;
349*32b31808SJens Wiklander 
350*32b31808SJens Wiklander     *p++ = 0x00;
351*32b31808SJens Wiklander     *p++ = 0x00;
352*32b31808SJens Wiklander 
353*32b31808SJens Wiklander     *olen = 4;
354*32b31808SJens Wiklander 
355*32b31808SJens Wiklander     return 0;
356*32b31808SJens Wiklander }
357*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
358*32b31808SJens Wiklander 
359*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
360*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
361*32b31808SJens Wiklander static int ssl_write_session_ticket_ext(mbedtls_ssl_context *ssl,
362*32b31808SJens Wiklander                                         unsigned char *buf,
363*32b31808SJens Wiklander                                         const unsigned char *end,
364*32b31808SJens Wiklander                                         size_t *olen)
365*32b31808SJens Wiklander {
366*32b31808SJens Wiklander     unsigned char *p = buf;
367*32b31808SJens Wiklander     size_t tlen = ssl->session_negotiate->ticket_len;
368*32b31808SJens Wiklander 
369*32b31808SJens Wiklander     *olen = 0;
370*32b31808SJens Wiklander 
371*32b31808SJens Wiklander     if (ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED) {
372*32b31808SJens Wiklander         return 0;
373*32b31808SJens Wiklander     }
374*32b31808SJens Wiklander 
375*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
376*32b31808SJens Wiklander                           ("client hello, adding session ticket extension"));
377*32b31808SJens Wiklander 
378*32b31808SJens Wiklander     /* The addition is safe here since the ticket length is 16 bit. */
379*32b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4 + tlen);
380*32b31808SJens Wiklander 
381*32b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SESSION_TICKET, p, 0);
382*32b31808SJens Wiklander     p += 2;
383*32b31808SJens Wiklander 
384*32b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(tlen, p, 0);
385*32b31808SJens Wiklander     p += 2;
386*32b31808SJens Wiklander 
387*32b31808SJens Wiklander     *olen = 4;
388*32b31808SJens Wiklander 
389*32b31808SJens Wiklander     if (ssl->session_negotiate->ticket == NULL || tlen == 0) {
390*32b31808SJens Wiklander         return 0;
391*32b31808SJens Wiklander     }
392*32b31808SJens Wiklander 
393*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
394*32b31808SJens Wiklander                           ("sending session ticket of length %" MBEDTLS_PRINTF_SIZET, tlen));
395*32b31808SJens Wiklander 
396*32b31808SJens Wiklander     memcpy(p, ssl->session_negotiate->ticket, tlen);
397*32b31808SJens Wiklander 
398*32b31808SJens Wiklander     *olen += tlen;
399*32b31808SJens Wiklander 
400*32b31808SJens Wiklander     return 0;
401*32b31808SJens Wiklander }
402*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
403*32b31808SJens Wiklander 
404*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP)
405*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
406*32b31808SJens Wiklander static int ssl_write_use_srtp_ext(mbedtls_ssl_context *ssl,
407*32b31808SJens Wiklander                                   unsigned char *buf,
408*32b31808SJens Wiklander                                   const unsigned char *end,
409*32b31808SJens Wiklander                                   size_t *olen)
410*32b31808SJens Wiklander {
411*32b31808SJens Wiklander     unsigned char *p = buf;
412*32b31808SJens Wiklander     size_t protection_profiles_index = 0, ext_len = 0;
413*32b31808SJens Wiklander     uint16_t mki_len = 0, profile_value = 0;
414*32b31808SJens Wiklander 
415*32b31808SJens Wiklander     *olen = 0;
416*32b31808SJens Wiklander 
417*32b31808SJens Wiklander     if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) ||
418*32b31808SJens Wiklander         (ssl->conf->dtls_srtp_profile_list == NULL) ||
419*32b31808SJens Wiklander         (ssl->conf->dtls_srtp_profile_list_len == 0)) {
420*32b31808SJens Wiklander         return 0;
421*32b31808SJens Wiklander     }
422*32b31808SJens Wiklander 
423*32b31808SJens Wiklander     /* RFC 5764 section 4.1.1
424*32b31808SJens Wiklander      * uint8 SRTPProtectionProfile[2];
425*32b31808SJens Wiklander      *
426*32b31808SJens Wiklander      * struct {
427*32b31808SJens Wiklander      *   SRTPProtectionProfiles SRTPProtectionProfiles;
428*32b31808SJens Wiklander      *   opaque srtp_mki<0..255>;
429*32b31808SJens Wiklander      * } UseSRTPData;
430*32b31808SJens Wiklander      * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
431*32b31808SJens Wiklander      */
432*32b31808SJens Wiklander     if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED) {
433*32b31808SJens Wiklander         mki_len = ssl->dtls_srtp_info.mki_len;
434*32b31808SJens Wiklander     }
435*32b31808SJens Wiklander     /* Extension length = 2 bytes for profiles length,
436*32b31808SJens Wiklander      *                    ssl->conf->dtls_srtp_profile_list_len * 2 (each profile is 2 bytes length ),
437*32b31808SJens Wiklander      *                    1 byte for srtp_mki vector length and the mki_len value
438*32b31808SJens Wiklander      */
439*32b31808SJens Wiklander     ext_len = 2 + 2 * (ssl->conf->dtls_srtp_profile_list_len) + 1 + mki_len;
440*32b31808SJens Wiklander 
441*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding use_srtp extension"));
442*32b31808SJens Wiklander 
443*32b31808SJens Wiklander     /* Check there is room in the buffer for the extension + 4 bytes
444*32b31808SJens Wiklander      * - the extension tag (2 bytes)
445*32b31808SJens Wiklander      * - the extension length (2 bytes)
446*32b31808SJens Wiklander      */
447*32b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, ext_len + 4);
448*32b31808SJens Wiklander 
449*32b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_USE_SRTP, p, 0);
450*32b31808SJens Wiklander     p += 2;
451*32b31808SJens Wiklander 
452*32b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(ext_len, p, 0);
453*32b31808SJens Wiklander     p += 2;
454*32b31808SJens Wiklander 
455*32b31808SJens Wiklander     /* protection profile length: 2*(ssl->conf->dtls_srtp_profile_list_len) */
456*32b31808SJens Wiklander     /* micro-optimization:
457*32b31808SJens Wiklander      * the list size is limited to MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH
458*32b31808SJens Wiklander      * which is lower than 127, so the upper byte of the length is always 0
459*32b31808SJens Wiklander      * For the documentation, the more generic code is left in comments
460*32b31808SJens Wiklander      * *p++ = (unsigned char)( ( ( 2 * ssl->conf->dtls_srtp_profile_list_len )
461*32b31808SJens Wiklander      *                        >> 8 ) & 0xFF );
462*32b31808SJens Wiklander      */
463*32b31808SJens Wiklander     *p++ = 0;
464*32b31808SJens Wiklander     *p++ = MBEDTLS_BYTE_0(2 * ssl->conf->dtls_srtp_profile_list_len);
465*32b31808SJens Wiklander 
466*32b31808SJens Wiklander     for (protection_profiles_index = 0;
467*32b31808SJens Wiklander          protection_profiles_index < ssl->conf->dtls_srtp_profile_list_len;
468*32b31808SJens Wiklander          protection_profiles_index++) {
469*32b31808SJens Wiklander         profile_value = mbedtls_ssl_check_srtp_profile_value
470*32b31808SJens Wiklander                             (ssl->conf->dtls_srtp_profile_list[protection_profiles_index]);
471*32b31808SJens Wiklander         if (profile_value != MBEDTLS_TLS_SRTP_UNSET) {
472*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_write_use_srtp_ext, add profile: %04x",
473*32b31808SJens Wiklander                                       profile_value));
474*32b31808SJens Wiklander             MBEDTLS_PUT_UINT16_BE(profile_value, p, 0);
475*32b31808SJens Wiklander             p += 2;
476*32b31808SJens Wiklander         } else {
477*32b31808SJens Wiklander             /*
478*32b31808SJens Wiklander              * Note: we shall never arrive here as protection profiles
479*32b31808SJens Wiklander              * is checked by mbedtls_ssl_conf_dtls_srtp_protection_profiles function
480*32b31808SJens Wiklander              */
481*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3,
482*32b31808SJens Wiklander                                   ("client hello, "
483*32b31808SJens Wiklander                                    "illegal DTLS-SRTP protection profile %d",
484*32b31808SJens Wiklander                                    ssl->conf->dtls_srtp_profile_list[protection_profiles_index]
485*32b31808SJens Wiklander                                   ));
486*32b31808SJens Wiklander             return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
487*32b31808SJens Wiklander         }
488*32b31808SJens Wiklander     }
489*32b31808SJens Wiklander 
490*32b31808SJens Wiklander     *p++ = mki_len & 0xFF;
491*32b31808SJens Wiklander 
492*32b31808SJens Wiklander     if (mki_len != 0) {
493*32b31808SJens Wiklander         memcpy(p, ssl->dtls_srtp_info.mki_value, mki_len);
494*32b31808SJens Wiklander         /*
495*32b31808SJens Wiklander          * Increment p to point to the current position.
496*32b31808SJens Wiklander          */
497*32b31808SJens Wiklander         p += mki_len;
498*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "sending mki",  ssl->dtls_srtp_info.mki_value,
499*32b31808SJens Wiklander                               ssl->dtls_srtp_info.mki_len);
500*32b31808SJens Wiklander     }
501*32b31808SJens Wiklander 
502*32b31808SJens Wiklander     /*
503*32b31808SJens Wiklander      * total extension length: extension type (2 bytes)
504*32b31808SJens Wiklander      *                         + extension length (2 bytes)
505*32b31808SJens Wiklander      *                         + protection profile length (2 bytes)
506*32b31808SJens Wiklander      *                         + 2 * number of protection profiles
507*32b31808SJens Wiklander      *                         + srtp_mki vector length(1 byte)
508*32b31808SJens Wiklander      *                         + mki value
509*32b31808SJens Wiklander      */
510*32b31808SJens Wiklander     *olen = p - buf;
511*32b31808SJens Wiklander 
512*32b31808SJens Wiklander     return 0;
513*32b31808SJens Wiklander }
514*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_SRTP */
515*32b31808SJens Wiklander 
516*32b31808SJens Wiklander int mbedtls_ssl_tls12_write_client_hello_exts(mbedtls_ssl_context *ssl,
517*32b31808SJens Wiklander                                               unsigned char *buf,
518*32b31808SJens Wiklander                                               const unsigned char *end,
519*32b31808SJens Wiklander                                               int uses_ec,
520*32b31808SJens Wiklander                                               size_t *out_len)
521*32b31808SJens Wiklander {
522*32b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
523*32b31808SJens Wiklander     unsigned char *p = buf;
524*32b31808SJens Wiklander     size_t ext_len = 0;
525*32b31808SJens Wiklander 
526*32b31808SJens Wiklander     (void) ssl;
527*32b31808SJens Wiklander     (void) end;
528*32b31808SJens Wiklander     (void) uses_ec;
529*32b31808SJens Wiklander     (void) ret;
530*32b31808SJens Wiklander     (void) ext_len;
531*32b31808SJens Wiklander 
532*32b31808SJens Wiklander     *out_len = 0;
533*32b31808SJens Wiklander 
534*32b31808SJens Wiklander     /* Note that TLS_EMPTY_RENEGOTIATION_INFO_SCSV is always added
535*32b31808SJens Wiklander      * even if MBEDTLS_SSL_RENEGOTIATION is not defined. */
536*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
537*32b31808SJens Wiklander     if ((ret = ssl_write_renegotiation_ext(ssl, p, end, &ext_len)) != 0) {
538*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_renegotiation_ext", ret);
539*32b31808SJens Wiklander         return ret;
540*32b31808SJens Wiklander     }
541*32b31808SJens Wiklander     p += ext_len;
542*32b31808SJens Wiklander #endif
543*32b31808SJens Wiklander 
544*32b31808SJens Wiklander #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
545*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
546*32b31808SJens Wiklander     if (uses_ec) {
547*32b31808SJens Wiklander         if ((ret = ssl_write_supported_point_formats_ext(ssl, p, end,
548*32b31808SJens Wiklander                                                          &ext_len)) != 0) {
549*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_supported_point_formats_ext", ret);
550*32b31808SJens Wiklander             return ret;
551*32b31808SJens Wiklander         }
552*32b31808SJens Wiklander         p += ext_len;
553*32b31808SJens Wiklander     }
554*32b31808SJens Wiklander #endif
555*32b31808SJens Wiklander 
556*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
557*32b31808SJens Wiklander     if ((ret = ssl_write_ecjpake_kkpp_ext(ssl, p, end, &ext_len)) != 0) {
558*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_ecjpake_kkpp_ext", ret);
559*32b31808SJens Wiklander         return ret;
560*32b31808SJens Wiklander     }
561*32b31808SJens Wiklander     p += ext_len;
562*32b31808SJens Wiklander #endif
563*32b31808SJens Wiklander 
564*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
565*32b31808SJens Wiklander     if ((ret = ssl_write_cid_ext(ssl, p, end, &ext_len)) != 0) {
566*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_cid_ext", ret);
567*32b31808SJens Wiklander         return ret;
568*32b31808SJens Wiklander     }
569*32b31808SJens Wiklander     p += ext_len;
570*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
571*32b31808SJens Wiklander 
572*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
573*32b31808SJens Wiklander     if ((ret = ssl_write_max_fragment_length_ext(ssl, p, end,
574*32b31808SJens Wiklander                                                  &ext_len)) != 0) {
575*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_max_fragment_length_ext", ret);
576*32b31808SJens Wiklander         return ret;
577*32b31808SJens Wiklander     }
578*32b31808SJens Wiklander     p += ext_len;
579*32b31808SJens Wiklander #endif
580*32b31808SJens Wiklander 
581*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
582*32b31808SJens Wiklander     if ((ret = ssl_write_encrypt_then_mac_ext(ssl, p, end, &ext_len)) != 0) {
583*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_encrypt_then_mac_ext", ret);
584*32b31808SJens Wiklander         return ret;
585*32b31808SJens Wiklander     }
586*32b31808SJens Wiklander     p += ext_len;
587*32b31808SJens Wiklander #endif
588*32b31808SJens Wiklander 
589*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
590*32b31808SJens Wiklander     if ((ret = ssl_write_extended_ms_ext(ssl, p, end, &ext_len)) != 0) {
591*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_extended_ms_ext", ret);
592*32b31808SJens Wiklander         return ret;
593*32b31808SJens Wiklander     }
594*32b31808SJens Wiklander     p += ext_len;
595*32b31808SJens Wiklander #endif
596*32b31808SJens Wiklander 
597*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP)
598*32b31808SJens Wiklander     if ((ret = ssl_write_use_srtp_ext(ssl, p, end, &ext_len)) != 0) {
599*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_use_srtp_ext", ret);
600*32b31808SJens Wiklander         return ret;
601*32b31808SJens Wiklander     }
602*32b31808SJens Wiklander     p += ext_len;
603*32b31808SJens Wiklander #endif
604*32b31808SJens Wiklander 
605*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
606*32b31808SJens Wiklander     if ((ret = ssl_write_session_ticket_ext(ssl, p, end, &ext_len)) != 0) {
607*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_session_ticket_ext", ret);
608*32b31808SJens Wiklander         return ret;
609*32b31808SJens Wiklander     }
610*32b31808SJens Wiklander     p += ext_len;
611*32b31808SJens Wiklander #endif
612*32b31808SJens Wiklander 
613*32b31808SJens Wiklander     *out_len = p - buf;
614*32b31808SJens Wiklander 
615*32b31808SJens Wiklander     return 0;
616*32b31808SJens Wiklander }
617*32b31808SJens Wiklander 
618*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
619*32b31808SJens Wiklander static int ssl_parse_renegotiation_info(mbedtls_ssl_context *ssl,
620*32b31808SJens Wiklander                                         const unsigned char *buf,
621*32b31808SJens Wiklander                                         size_t len)
622*32b31808SJens Wiklander {
623*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
624*32b31808SJens Wiklander     if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
625*32b31808SJens Wiklander         /* Check verify-data in constant-time. The length OTOH is no secret */
626*32b31808SJens Wiklander         if (len    != 1 + ssl->verify_data_len * 2 ||
627*32b31808SJens Wiklander             buf[0] !=     ssl->verify_data_len * 2 ||
628*32b31808SJens Wiklander             mbedtls_ct_memcmp(buf + 1,
629*32b31808SJens Wiklander                               ssl->own_verify_data, ssl->verify_data_len) != 0 ||
630*32b31808SJens Wiklander             mbedtls_ct_memcmp(buf + 1 + ssl->verify_data_len,
631*32b31808SJens Wiklander                               ssl->peer_verify_data, ssl->verify_data_len) != 0) {
632*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("non-matching renegotiation info"));
633*32b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
634*32b31808SJens Wiklander                 ssl,
635*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
636*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
637*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
638*32b31808SJens Wiklander         }
639*32b31808SJens Wiklander     } else
640*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */
641*32b31808SJens Wiklander     {
642*32b31808SJens Wiklander         if (len != 1 || buf[0] != 0x00) {
643*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1,
644*32b31808SJens Wiklander                                   ("non-zero length renegotiation info"));
645*32b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
646*32b31808SJens Wiklander                 ssl,
647*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
648*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
649*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
650*32b31808SJens Wiklander         }
651*32b31808SJens Wiklander 
652*32b31808SJens Wiklander         ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
653*32b31808SJens Wiklander     }
654*32b31808SJens Wiklander 
655*32b31808SJens Wiklander     return 0;
656*32b31808SJens Wiklander }
657*32b31808SJens Wiklander 
658*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
659*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
660*32b31808SJens Wiklander static int ssl_parse_max_fragment_length_ext(mbedtls_ssl_context *ssl,
661*32b31808SJens Wiklander                                              const unsigned char *buf,
662*32b31808SJens Wiklander                                              size_t len)
663*32b31808SJens Wiklander {
664*32b31808SJens Wiklander     /*
665*32b31808SJens Wiklander      * server should use the extension only if we did,
666*32b31808SJens Wiklander      * and if so the server's value should match ours (and len is always 1)
667*32b31808SJens Wiklander      */
668*32b31808SJens Wiklander     if (ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ||
669*32b31808SJens Wiklander         len != 1 ||
670*32b31808SJens Wiklander         buf[0] != ssl->conf->mfl_code) {
671*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
672*32b31808SJens Wiklander                               ("non-matching max fragment length extension"));
673*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
674*32b31808SJens Wiklander             ssl,
675*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
676*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
677*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
678*32b31808SJens Wiklander     }
679*32b31808SJens Wiklander 
680*32b31808SJens Wiklander     return 0;
681*32b31808SJens Wiklander }
682*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
683*32b31808SJens Wiklander 
684*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
685*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
686*32b31808SJens Wiklander static int ssl_parse_cid_ext(mbedtls_ssl_context *ssl,
687*32b31808SJens Wiklander                              const unsigned char *buf,
688*32b31808SJens Wiklander                              size_t len)
689*32b31808SJens Wiklander {
690*32b31808SJens Wiklander     size_t peer_cid_len;
691*32b31808SJens Wiklander 
692*32b31808SJens Wiklander     if ( /* CID extension only makes sense in DTLS */
693*32b31808SJens Wiklander         ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
694*32b31808SJens Wiklander         /* The server must only send the CID extension if we have offered it. */
695*32b31808SJens Wiklander         ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED) {
696*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension unexpected"));
697*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
698*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT);
699*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION;
700*32b31808SJens Wiklander     }
701*32b31808SJens Wiklander 
702*32b31808SJens Wiklander     if (len == 0) {
703*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension invalid"));
704*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
705*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
706*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
707*32b31808SJens Wiklander     }
708*32b31808SJens Wiklander 
709*32b31808SJens Wiklander     peer_cid_len = *buf++;
710*32b31808SJens Wiklander     len--;
711*32b31808SJens Wiklander 
712*32b31808SJens Wiklander     if (peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX) {
713*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension invalid"));
714*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
715*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
716*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
717*32b31808SJens Wiklander     }
718*32b31808SJens Wiklander 
719*32b31808SJens Wiklander     if (len != peer_cid_len) {
720*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension invalid"));
721*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
722*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
723*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
724*32b31808SJens Wiklander     }
725*32b31808SJens Wiklander 
726*32b31808SJens Wiklander     ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED;
727*32b31808SJens Wiklander     ssl->handshake->peer_cid_len = (uint8_t) peer_cid_len;
728*32b31808SJens Wiklander     memcpy(ssl->handshake->peer_cid, buf, peer_cid_len);
729*32b31808SJens Wiklander 
730*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("Use of CID extension negotiated"));
731*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "Server CID", buf, peer_cid_len);
732*32b31808SJens Wiklander 
733*32b31808SJens Wiklander     return 0;
734*32b31808SJens Wiklander }
735*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
736*32b31808SJens Wiklander 
737*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
738*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
739*32b31808SJens Wiklander static int ssl_parse_encrypt_then_mac_ext(mbedtls_ssl_context *ssl,
740*32b31808SJens Wiklander                                           const unsigned char *buf,
741*32b31808SJens Wiklander                                           size_t len)
742*32b31808SJens Wiklander {
743*32b31808SJens Wiklander     if (ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
744*32b31808SJens Wiklander         len != 0) {
745*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
746*32b31808SJens Wiklander                               ("non-matching encrypt-then-MAC extension"));
747*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
748*32b31808SJens Wiklander             ssl,
749*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
750*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT);
751*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION;
752*32b31808SJens Wiklander     }
753*32b31808SJens Wiklander 
754*32b31808SJens Wiklander     ((void) buf);
755*32b31808SJens Wiklander 
756*32b31808SJens Wiklander     ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
757*32b31808SJens Wiklander 
758*32b31808SJens Wiklander     return 0;
759*32b31808SJens Wiklander }
760*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
761*32b31808SJens Wiklander 
762*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
763*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
764*32b31808SJens Wiklander static int ssl_parse_extended_ms_ext(mbedtls_ssl_context *ssl,
765*32b31808SJens Wiklander                                      const unsigned char *buf,
766*32b31808SJens Wiklander                                      size_t len)
767*32b31808SJens Wiklander {
768*32b31808SJens Wiklander     if (ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
769*32b31808SJens Wiklander         len != 0) {
770*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
771*32b31808SJens Wiklander                               ("non-matching extended master secret extension"));
772*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
773*32b31808SJens Wiklander             ssl,
774*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
775*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT);
776*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION;
777*32b31808SJens Wiklander     }
778*32b31808SJens Wiklander 
779*32b31808SJens Wiklander     ((void) buf);
780*32b31808SJens Wiklander 
781*32b31808SJens Wiklander     ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
782*32b31808SJens Wiklander 
783*32b31808SJens Wiklander     return 0;
784*32b31808SJens Wiklander }
785*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
786*32b31808SJens Wiklander 
787*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
788*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
789*32b31808SJens Wiklander static int ssl_parse_session_ticket_ext(mbedtls_ssl_context *ssl,
790*32b31808SJens Wiklander                                         const unsigned char *buf,
791*32b31808SJens Wiklander                                         size_t len)
792*32b31808SJens Wiklander {
793*32b31808SJens Wiklander     if (ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ||
794*32b31808SJens Wiklander         len != 0) {
795*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
796*32b31808SJens Wiklander                               ("non-matching session ticket extension"));
797*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
798*32b31808SJens Wiklander             ssl,
799*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
800*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT);
801*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION;
802*32b31808SJens Wiklander     }
803*32b31808SJens Wiklander 
804*32b31808SJens Wiklander     ((void) buf);
805*32b31808SJens Wiklander 
806*32b31808SJens Wiklander     ssl->handshake->new_session_ticket = 1;
807*32b31808SJens Wiklander 
808*32b31808SJens Wiklander     return 0;
809*32b31808SJens Wiklander }
810*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
811*32b31808SJens Wiklander 
812*32b31808SJens Wiklander #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
813*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
814*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
815*32b31808SJens Wiklander static int ssl_parse_supported_point_formats_ext(mbedtls_ssl_context *ssl,
816*32b31808SJens Wiklander                                                  const unsigned char *buf,
817*32b31808SJens Wiklander                                                  size_t len)
818*32b31808SJens Wiklander {
819*32b31808SJens Wiklander     size_t list_size;
820*32b31808SJens Wiklander     const unsigned char *p;
821*32b31808SJens Wiklander 
822*32b31808SJens Wiklander     if (len == 0 || (size_t) (buf[0] + 1) != len) {
823*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
824*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
825*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
826*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
827*32b31808SJens Wiklander     }
828*32b31808SJens Wiklander     list_size = buf[0];
829*32b31808SJens Wiklander 
830*32b31808SJens Wiklander     p = buf + 1;
831*32b31808SJens Wiklander     while (list_size > 0) {
832*32b31808SJens Wiklander         if (p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
833*32b31808SJens Wiklander             p[0] == MBEDTLS_ECP_PF_COMPRESSED) {
834*32b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO) &&                             \
835*32b31808SJens Wiklander             (defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C))
836*32b31808SJens Wiklander             ssl->handshake->ecdh_ctx.point_format = p[0];
837*32b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO &&
838*32b31808SJens Wiklander           ( MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ) */
839*32b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO) &&                             \
840*32b31808SJens Wiklander             defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
841*32b31808SJens Wiklander             mbedtls_ecjpake_set_point_format(&ssl->handshake->ecjpake_ctx,
842*32b31808SJens Wiklander                                              p[0]);
843*32b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
844*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(4, ("point format selected: %d", p[0]));
845*32b31808SJens Wiklander             return 0;
846*32b31808SJens Wiklander         }
847*32b31808SJens Wiklander 
848*32b31808SJens Wiklander         list_size--;
849*32b31808SJens Wiklander         p++;
850*32b31808SJens Wiklander     }
851*32b31808SJens Wiklander 
852*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(1, ("no point format in common"));
853*32b31808SJens Wiklander     mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
854*32b31808SJens Wiklander                                    MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
855*32b31808SJens Wiklander     return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
856*32b31808SJens Wiklander }
857*32b31808SJens Wiklander #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
858*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
859*32b31808SJens Wiklander 
860*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
861*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
862*32b31808SJens Wiklander static int ssl_parse_ecjpake_kkpp(mbedtls_ssl_context *ssl,
863*32b31808SJens Wiklander                                   const unsigned char *buf,
864*32b31808SJens Wiklander                                   size_t len)
865*32b31808SJens Wiklander {
866*32b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
867*32b31808SJens Wiklander 
868*32b31808SJens Wiklander     if (ssl->handshake->ciphersuite_info->key_exchange !=
869*32b31808SJens Wiklander         MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
870*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("skip ecjpake kkpp extension"));
871*32b31808SJens Wiklander         return 0;
872*32b31808SJens Wiklander     }
873*32b31808SJens Wiklander 
874*32b31808SJens Wiklander     /* If we got here, we no longer need our cached extension */
875*32b31808SJens Wiklander     mbedtls_free(ssl->handshake->ecjpake_cache);
876*32b31808SJens Wiklander     ssl->handshake->ecjpake_cache = NULL;
877*32b31808SJens Wiklander     ssl->handshake->ecjpake_cache_len = 0;
878*32b31808SJens Wiklander 
879*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
880*32b31808SJens Wiklander     if ((ret = mbedtls_psa_ecjpake_read_round(
881*32b31808SJens Wiklander              &ssl->handshake->psa_pake_ctx, buf, len,
882*32b31808SJens Wiklander              MBEDTLS_ECJPAKE_ROUND_ONE)) != 0) {
883*32b31808SJens Wiklander         psa_destroy_key(ssl->handshake->psa_pake_password);
884*32b31808SJens Wiklander         psa_pake_abort(&ssl->handshake->psa_pake_ctx);
885*32b31808SJens Wiklander 
886*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round one", ret);
887*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
888*32b31808SJens Wiklander             ssl,
889*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
890*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
891*32b31808SJens Wiklander         return ret;
892*32b31808SJens Wiklander     }
893*32b31808SJens Wiklander 
894*32b31808SJens Wiklander     return 0;
895*32b31808SJens Wiklander #else
896*32b31808SJens Wiklander     if ((ret = mbedtls_ecjpake_read_round_one(&ssl->handshake->ecjpake_ctx,
897*32b31808SJens Wiklander                                               buf, len)) != 0) {
898*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_one", ret);
899*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
900*32b31808SJens Wiklander             ssl,
901*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
902*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
903*32b31808SJens Wiklander         return ret;
904*32b31808SJens Wiklander     }
905*32b31808SJens Wiklander 
906*32b31808SJens Wiklander     return 0;
907*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
908*32b31808SJens Wiklander }
909*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
910*32b31808SJens Wiklander 
911*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ALPN)
912*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
913*32b31808SJens Wiklander static int ssl_parse_alpn_ext(mbedtls_ssl_context *ssl,
914*32b31808SJens Wiklander                               const unsigned char *buf, size_t len)
915*32b31808SJens Wiklander {
916*32b31808SJens Wiklander     size_t list_len, name_len;
917*32b31808SJens Wiklander     const char **p;
918*32b31808SJens Wiklander 
919*32b31808SJens Wiklander     /* If we didn't send it, the server shouldn't send it */
920*32b31808SJens Wiklander     if (ssl->conf->alpn_list == NULL) {
921*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("non-matching ALPN extension"));
922*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
923*32b31808SJens Wiklander             ssl,
924*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
925*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT);
926*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION;
927*32b31808SJens Wiklander     }
928*32b31808SJens Wiklander 
929*32b31808SJens Wiklander     /*
930*32b31808SJens Wiklander      * opaque ProtocolName<1..2^8-1>;
931*32b31808SJens Wiklander      *
932*32b31808SJens Wiklander      * struct {
933*32b31808SJens Wiklander      *     ProtocolName protocol_name_list<2..2^16-1>
934*32b31808SJens Wiklander      * } ProtocolNameList;
935*32b31808SJens Wiklander      *
936*32b31808SJens Wiklander      * the "ProtocolNameList" MUST contain exactly one "ProtocolName"
937*32b31808SJens Wiklander      */
938*32b31808SJens Wiklander 
939*32b31808SJens Wiklander     /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
940*32b31808SJens Wiklander     if (len < 4) {
941*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
942*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
943*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
944*32b31808SJens Wiklander     }
945*32b31808SJens Wiklander 
946*32b31808SJens Wiklander     list_len = (buf[0] << 8) | buf[1];
947*32b31808SJens Wiklander     if (list_len != len - 2) {
948*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
949*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
950*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
951*32b31808SJens Wiklander     }
952*32b31808SJens Wiklander 
953*32b31808SJens Wiklander     name_len = buf[2];
954*32b31808SJens Wiklander     if (name_len != list_len - 1) {
955*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
956*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
957*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
958*32b31808SJens Wiklander     }
959*32b31808SJens Wiklander 
960*32b31808SJens Wiklander     /* Check that the server chosen protocol was in our list and save it */
961*32b31808SJens Wiklander     for (p = ssl->conf->alpn_list; *p != NULL; p++) {
962*32b31808SJens Wiklander         if (name_len == strlen(*p) &&
963*32b31808SJens Wiklander             memcmp(buf + 3, *p, name_len) == 0) {
964*32b31808SJens Wiklander             ssl->alpn_chosen = *p;
965*32b31808SJens Wiklander             return 0;
966*32b31808SJens Wiklander         }
967*32b31808SJens Wiklander     }
968*32b31808SJens Wiklander 
969*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(1, ("ALPN extension: no matching protocol"));
970*32b31808SJens Wiklander     mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
971*32b31808SJens Wiklander                                    MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
972*32b31808SJens Wiklander     return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
973*32b31808SJens Wiklander }
974*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_ALPN */
975*32b31808SJens Wiklander 
976*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP)
977*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
978*32b31808SJens Wiklander static int ssl_parse_use_srtp_ext(mbedtls_ssl_context *ssl,
979*32b31808SJens Wiklander                                   const unsigned char *buf,
980*32b31808SJens Wiklander                                   size_t len)
981*32b31808SJens Wiklander {
982*32b31808SJens Wiklander     mbedtls_ssl_srtp_profile server_protection = MBEDTLS_TLS_SRTP_UNSET;
983*32b31808SJens Wiklander     size_t i, mki_len = 0;
984*32b31808SJens Wiklander     uint16_t server_protection_profile_value = 0;
985*32b31808SJens Wiklander 
986*32b31808SJens Wiklander     /* If use_srtp is not configured, just ignore the extension */
987*32b31808SJens Wiklander     if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) ||
988*32b31808SJens Wiklander         (ssl->conf->dtls_srtp_profile_list == NULL) ||
989*32b31808SJens Wiklander         (ssl->conf->dtls_srtp_profile_list_len == 0)) {
990*32b31808SJens Wiklander         return 0;
991*32b31808SJens Wiklander     }
992*32b31808SJens Wiklander 
993*32b31808SJens Wiklander     /* RFC 5764 section 4.1.1
994*32b31808SJens Wiklander      * uint8 SRTPProtectionProfile[2];
995*32b31808SJens Wiklander      *
996*32b31808SJens Wiklander      * struct {
997*32b31808SJens Wiklander      *   SRTPProtectionProfiles SRTPProtectionProfiles;
998*32b31808SJens Wiklander      *   opaque srtp_mki<0..255>;
999*32b31808SJens Wiklander      * } UseSRTPData;
1000*32b31808SJens Wiklander 
1001*32b31808SJens Wiklander      * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
1002*32b31808SJens Wiklander      *
1003*32b31808SJens Wiklander      */
1004*32b31808SJens Wiklander     if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED) {
1005*32b31808SJens Wiklander         mki_len = ssl->dtls_srtp_info.mki_len;
1006*32b31808SJens Wiklander     }
1007*32b31808SJens Wiklander 
1008*32b31808SJens Wiklander     /*
1009*32b31808SJens Wiklander      * Length is 5 + optional mki_value : one protection profile length (2 bytes)
1010*32b31808SJens Wiklander      *                                      + protection profile (2 bytes)
1011*32b31808SJens Wiklander      *                                      + mki_len(1 byte)
1012*32b31808SJens Wiklander      *                                      and optional srtp_mki
1013*32b31808SJens Wiklander      */
1014*32b31808SJens Wiklander     if ((len < 5) || (len != (buf[4] + 5u))) {
1015*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
1016*32b31808SJens Wiklander     }
1017*32b31808SJens Wiklander 
1018*32b31808SJens Wiklander     /*
1019*32b31808SJens Wiklander      * get the server protection profile
1020*32b31808SJens Wiklander      */
1021*32b31808SJens Wiklander 
1022*32b31808SJens Wiklander     /*
1023*32b31808SJens Wiklander      * protection profile length must be 0x0002 as we must have only
1024*32b31808SJens Wiklander      * one protection profile in server Hello
1025*32b31808SJens Wiklander      */
1026*32b31808SJens Wiklander     if ((buf[0] != 0) || (buf[1] != 2)) {
1027*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
1028*32b31808SJens Wiklander     }
1029*32b31808SJens Wiklander 
1030*32b31808SJens Wiklander     server_protection_profile_value = (buf[2] << 8) | buf[3];
1031*32b31808SJens Wiklander     server_protection = mbedtls_ssl_check_srtp_profile_value(
1032*32b31808SJens Wiklander         server_protection_profile_value);
1033*32b31808SJens Wiklander     if (server_protection != MBEDTLS_TLS_SRTP_UNSET) {
1034*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("found srtp profile: %s",
1035*32b31808SJens Wiklander                                   mbedtls_ssl_get_srtp_profile_as_string(
1036*32b31808SJens Wiklander                                       server_protection)));
1037*32b31808SJens Wiklander     }
1038*32b31808SJens Wiklander 
1039*32b31808SJens Wiklander     ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET;
1040*32b31808SJens Wiklander 
1041*32b31808SJens Wiklander     /*
1042*32b31808SJens Wiklander      * Check we have the server profile in our list
1043*32b31808SJens Wiklander      */
1044*32b31808SJens Wiklander     for (i = 0; i < ssl->conf->dtls_srtp_profile_list_len; i++) {
1045*32b31808SJens Wiklander         if (server_protection == ssl->conf->dtls_srtp_profile_list[i]) {
1046*32b31808SJens Wiklander             ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
1047*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3, ("selected srtp profile: %s",
1048*32b31808SJens Wiklander                                       mbedtls_ssl_get_srtp_profile_as_string(
1049*32b31808SJens Wiklander                                           server_protection)));
1050*32b31808SJens Wiklander             break;
1051*32b31808SJens Wiklander         }
1052*32b31808SJens Wiklander     }
1053*32b31808SJens Wiklander 
1054*32b31808SJens Wiklander     /* If no match was found : server problem, it shall never answer with incompatible profile */
1055*32b31808SJens Wiklander     if (ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET) {
1056*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1057*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
1058*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
1059*32b31808SJens Wiklander     }
1060*32b31808SJens Wiklander 
1061*32b31808SJens Wiklander     /* If server does not use mki in its reply, make sure the client won't keep
1062*32b31808SJens Wiklander      * one as negotiated */
1063*32b31808SJens Wiklander     if (len == 5) {
1064*32b31808SJens Wiklander         ssl->dtls_srtp_info.mki_len = 0;
1065*32b31808SJens Wiklander     }
1066*32b31808SJens Wiklander 
1067*32b31808SJens Wiklander     /*
1068*32b31808SJens Wiklander      * RFC5764:
1069*32b31808SJens Wiklander      *  If the client detects a nonzero-length MKI in the server's response
1070*32b31808SJens Wiklander      *  that is different than the one the client offered, then the client
1071*32b31808SJens Wiklander      *  MUST abort the handshake and SHOULD send an invalid_parameter alert.
1072*32b31808SJens Wiklander      */
1073*32b31808SJens Wiklander     if (len > 5  && (buf[4] != mki_len ||
1074*32b31808SJens Wiklander                      (memcmp(ssl->dtls_srtp_info.mki_value, &buf[5], mki_len)))) {
1075*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1076*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
1077*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
1078*32b31808SJens Wiklander     }
1079*32b31808SJens Wiklander #if defined(MBEDTLS_DEBUG_C)
1080*32b31808SJens Wiklander     if (len > 5) {
1081*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "received mki", ssl->dtls_srtp_info.mki_value,
1082*32b31808SJens Wiklander                               ssl->dtls_srtp_info.mki_len);
1083*32b31808SJens Wiklander     }
1084*32b31808SJens Wiklander #endif
1085*32b31808SJens Wiklander     return 0;
1086*32b31808SJens Wiklander }
1087*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_SRTP */
1088*32b31808SJens Wiklander 
1089*32b31808SJens Wiklander /*
1090*32b31808SJens Wiklander  * Parse HelloVerifyRequest.  Only called after verifying the HS type.
1091*32b31808SJens Wiklander  */
1092*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
1093*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
1094*32b31808SJens Wiklander static int ssl_parse_hello_verify_request(mbedtls_ssl_context *ssl)
1095*32b31808SJens Wiklander {
1096*32b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
1097*32b31808SJens Wiklander     const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl);
1098*32b31808SJens Wiklander     uint16_t dtls_legacy_version;
1099*32b31808SJens Wiklander 
1100*32b31808SJens Wiklander #if !defined(MBEDTLS_SSL_PROTO_TLS1_3)
1101*32b31808SJens Wiklander     uint8_t cookie_len;
1102*32b31808SJens Wiklander #else
1103*32b31808SJens Wiklander     uint16_t cookie_len;
1104*32b31808SJens Wiklander #endif
1105*32b31808SJens Wiklander 
1106*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse hello verify request"));
1107*32b31808SJens Wiklander 
1108*32b31808SJens Wiklander     /* Check that there is enough room for:
1109*32b31808SJens Wiklander      * - 2 bytes of version
1110*32b31808SJens Wiklander      * - 1 byte of cookie_len
1111*32b31808SJens Wiklander      */
1112*32b31808SJens Wiklander     if (mbedtls_ssl_hs_hdr_len(ssl) + 3 > ssl->in_msglen) {
1113*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
1114*32b31808SJens Wiklander                               ("incoming HelloVerifyRequest message is too short"));
1115*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1116*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
1117*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
1118*32b31808SJens Wiklander     }
1119*32b31808SJens Wiklander 
1120*32b31808SJens Wiklander     /*
1121*32b31808SJens Wiklander      * struct {
1122*32b31808SJens Wiklander      *   ProtocolVersion server_version;
1123*32b31808SJens Wiklander      *   opaque cookie<0..2^8-1>;
1124*32b31808SJens Wiklander      * } HelloVerifyRequest;
1125*32b31808SJens Wiklander      */
1126*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "server version", p, 2);
1127*32b31808SJens Wiklander     dtls_legacy_version = MBEDTLS_GET_UINT16_BE(p, 0);
1128*32b31808SJens Wiklander     p += 2;
1129*32b31808SJens Wiklander 
1130*32b31808SJens Wiklander     /*
1131*32b31808SJens Wiklander      * Since the RFC is not clear on this point, accept DTLS 1.0 (0xfeff)
1132*32b31808SJens Wiklander      * The DTLS 1.3 (current draft) renames ProtocolVersion server_version to
1133*32b31808SJens Wiklander      * legacy_version and locks the value of legacy_version to 0xfefd (DTLS 1.2)
1134*32b31808SJens Wiklander      */
1135*32b31808SJens Wiklander     if (dtls_legacy_version != 0xfefd && dtls_legacy_version != 0xfeff) {
1136*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server version"));
1137*32b31808SJens Wiklander 
1138*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1139*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION);
1140*32b31808SJens Wiklander 
1141*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
1142*32b31808SJens Wiklander     }
1143*32b31808SJens Wiklander 
1144*32b31808SJens Wiklander     cookie_len = *p++;
1145*32b31808SJens Wiklander     if ((ssl->in_msg + ssl->in_msglen) - p < cookie_len) {
1146*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
1147*32b31808SJens Wiklander                               ("cookie length does not match incoming message size"));
1148*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1149*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
1150*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
1151*32b31808SJens Wiklander     }
1152*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "cookie", p, cookie_len);
1153*32b31808SJens Wiklander 
1154*32b31808SJens Wiklander     mbedtls_free(ssl->handshake->cookie);
1155*32b31808SJens Wiklander 
1156*32b31808SJens Wiklander     ssl->handshake->cookie = mbedtls_calloc(1, cookie_len);
1157*32b31808SJens Wiklander     if (ssl->handshake->cookie  == NULL) {
1158*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("alloc failed (%d bytes)", cookie_len));
1159*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ALLOC_FAILED;
1160*32b31808SJens Wiklander     }
1161*32b31808SJens Wiklander 
1162*32b31808SJens Wiklander     memcpy(ssl->handshake->cookie, p, cookie_len);
1163*32b31808SJens Wiklander     ssl->handshake->cookie_len = cookie_len;
1164*32b31808SJens Wiklander 
1165*32b31808SJens Wiklander     /* Start over at ClientHello */
1166*32b31808SJens Wiklander     ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
1167*32b31808SJens Wiklander     ret = mbedtls_ssl_reset_checksum(ssl);
1168*32b31808SJens Wiklander     if (0 != ret) {
1169*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_reset_checksum"), ret);
1170*32b31808SJens Wiklander         return ret;
1171*32b31808SJens Wiklander     }
1172*32b31808SJens Wiklander 
1173*32b31808SJens Wiklander     mbedtls_ssl_recv_flight_completed(ssl);
1174*32b31808SJens Wiklander 
1175*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse hello verify request"));
1176*32b31808SJens Wiklander 
1177*32b31808SJens Wiklander     return 0;
1178*32b31808SJens Wiklander }
1179*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */
1180*32b31808SJens Wiklander 
1181*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
1182*32b31808SJens Wiklander static int ssl_parse_server_hello(mbedtls_ssl_context *ssl)
1183*32b31808SJens Wiklander {
1184*32b31808SJens Wiklander     int ret, i;
1185*32b31808SJens Wiklander     size_t n;
1186*32b31808SJens Wiklander     size_t ext_len;
1187*32b31808SJens Wiklander     unsigned char *buf, *ext;
1188*32b31808SJens Wiklander     unsigned char comp;
1189*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
1190*32b31808SJens Wiklander     int renegotiation_info_seen = 0;
1191*32b31808SJens Wiklander #endif
1192*32b31808SJens Wiklander     int handshake_failure = 0;
1193*32b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *suite_info;
1194*32b31808SJens Wiklander 
1195*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse server hello"));
1196*32b31808SJens Wiklander 
1197*32b31808SJens Wiklander     if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
1198*32b31808SJens Wiklander         /* No alert on a read error. */
1199*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
1200*32b31808SJens Wiklander         return ret;
1201*32b31808SJens Wiklander     }
1202*32b31808SJens Wiklander 
1203*32b31808SJens Wiklander     buf = ssl->in_msg;
1204*32b31808SJens Wiklander 
1205*32b31808SJens Wiklander     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
1206*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
1207*32b31808SJens Wiklander         if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
1208*32b31808SJens Wiklander             ssl->renego_records_seen++;
1209*32b31808SJens Wiklander 
1210*32b31808SJens Wiklander             if (ssl->conf->renego_max_records >= 0 &&
1211*32b31808SJens Wiklander                 ssl->renego_records_seen > ssl->conf->renego_max_records) {
1212*32b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1,
1213*32b31808SJens Wiklander                                       ("renegotiation requested, but not honored by server"));
1214*32b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
1215*32b31808SJens Wiklander             }
1216*32b31808SJens Wiklander 
1217*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1,
1218*32b31808SJens Wiklander                                   ("non-handshake message during renegotiation"));
1219*32b31808SJens Wiklander 
1220*32b31808SJens Wiklander             ssl->keep_current_message = 1;
1221*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO;
1222*32b31808SJens Wiklander         }
1223*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */
1224*32b31808SJens Wiklander 
1225*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
1226*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
1227*32b31808SJens Wiklander             ssl,
1228*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1229*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE);
1230*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
1231*32b31808SJens Wiklander     }
1232*32b31808SJens Wiklander 
1233*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
1234*32b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
1235*32b31808SJens Wiklander         if (buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST) {
1236*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2, ("received hello verify request"));
1237*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server hello"));
1238*32b31808SJens Wiklander             return ssl_parse_hello_verify_request(ssl);
1239*32b31808SJens Wiklander         } else {
1240*32b31808SJens Wiklander             /* We made it through the verification process */
1241*32b31808SJens Wiklander             mbedtls_free(ssl->handshake->cookie);
1242*32b31808SJens Wiklander             ssl->handshake->cookie = NULL;
1243*32b31808SJens Wiklander             ssl->handshake->cookie_len = 0;
1244*32b31808SJens Wiklander         }
1245*32b31808SJens Wiklander     }
1246*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */
1247*32b31808SJens Wiklander 
1248*32b31808SJens Wiklander     if (ssl->in_hslen < 38 + mbedtls_ssl_hs_hdr_len(ssl) ||
1249*32b31808SJens Wiklander         buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO) {
1250*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
1251*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1252*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
1253*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
1254*32b31808SJens Wiklander     }
1255*32b31808SJens Wiklander 
1256*32b31808SJens Wiklander     /*
1257*32b31808SJens Wiklander      *  0   .  1    server_version
1258*32b31808SJens Wiklander      *  2   . 33    random (maybe including 4 bytes of Unix time)
1259*32b31808SJens Wiklander      * 34   . 34    session_id length = n
1260*32b31808SJens Wiklander      * 35   . 34+n  session_id
1261*32b31808SJens Wiklander      * 35+n . 36+n  cipher_suite
1262*32b31808SJens Wiklander      * 37+n . 37+n  compression_method
1263*32b31808SJens Wiklander      *
1264*32b31808SJens Wiklander      * 38+n . 39+n  extensions length (optional)
1265*32b31808SJens Wiklander      * 40+n .  ..   extensions
1266*32b31808SJens Wiklander      */
1267*32b31808SJens Wiklander     buf += mbedtls_ssl_hs_hdr_len(ssl);
1268*32b31808SJens Wiklander 
1269*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "server hello, version", buf, 2);
1270*32b31808SJens Wiklander     ssl->tls_version = mbedtls_ssl_read_version(buf, ssl->conf->transport);
1271*32b31808SJens Wiklander     ssl->session_negotiate->tls_version = ssl->tls_version;
1272*32b31808SJens Wiklander 
1273*32b31808SJens Wiklander     if (ssl->tls_version < ssl->conf->min_tls_version ||
1274*32b31808SJens Wiklander         ssl->tls_version > ssl->conf->max_tls_version) {
1275*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
1276*32b31808SJens Wiklander                               (
1277*32b31808SJens Wiklander                                   "server version out of bounds -  min: [0x%x], server: [0x%x], max: [0x%x]",
1278*32b31808SJens Wiklander                                   (unsigned) ssl->conf->min_tls_version,
1279*32b31808SJens Wiklander                                   (unsigned) ssl->tls_version,
1280*32b31808SJens Wiklander                                   (unsigned) ssl->conf->max_tls_version));
1281*32b31808SJens Wiklander 
1282*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1283*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION);
1284*32b31808SJens Wiklander 
1285*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
1286*32b31808SJens Wiklander     }
1287*32b31808SJens Wiklander 
1288*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, current time: %lu",
1289*32b31808SJens Wiklander                               ((unsigned long) buf[2] << 24) |
1290*32b31808SJens Wiklander                               ((unsigned long) buf[3] << 16) |
1291*32b31808SJens Wiklander                               ((unsigned long) buf[4] <<  8) |
1292*32b31808SJens Wiklander                               ((unsigned long) buf[5])));
1293*32b31808SJens Wiklander 
1294*32b31808SJens Wiklander     memcpy(ssl->handshake->randbytes + 32, buf + 2, 32);
1295*32b31808SJens Wiklander 
1296*32b31808SJens Wiklander     n = buf[34];
1297*32b31808SJens Wiklander 
1298*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3,   "server hello, random bytes", buf + 2, 32);
1299*32b31808SJens Wiklander 
1300*32b31808SJens Wiklander     if (n > 32) {
1301*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
1302*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1303*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
1304*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
1305*32b31808SJens Wiklander     }
1306*32b31808SJens Wiklander 
1307*32b31808SJens Wiklander     if (ssl->in_hslen > mbedtls_ssl_hs_hdr_len(ssl) + 39 + n) {
1308*32b31808SJens Wiklander         ext_len = ((buf[38 + n] <<  8)
1309*32b31808SJens Wiklander                    | (buf[39 + n]));
1310*32b31808SJens Wiklander 
1311*32b31808SJens Wiklander         if ((ext_len > 0 && ext_len < 4) ||
1312*32b31808SJens Wiklander             ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl) + 40 + n + ext_len) {
1313*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
1314*32b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
1315*32b31808SJens Wiklander                 ssl,
1316*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1317*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
1318*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
1319*32b31808SJens Wiklander         }
1320*32b31808SJens Wiklander     } else if (ssl->in_hslen == mbedtls_ssl_hs_hdr_len(ssl) + 38 + n) {
1321*32b31808SJens Wiklander         ext_len = 0;
1322*32b31808SJens Wiklander     } else {
1323*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
1324*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1325*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
1326*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
1327*32b31808SJens Wiklander     }
1328*32b31808SJens Wiklander 
1329*32b31808SJens Wiklander     /* ciphersuite (used later) */
1330*32b31808SJens Wiklander     i = (buf[35 + n] << 8) | buf[36 + n];
1331*32b31808SJens Wiklander 
1332*32b31808SJens Wiklander     /*
1333*32b31808SJens Wiklander      * Read and check compression
1334*32b31808SJens Wiklander      */
1335*32b31808SJens Wiklander     comp = buf[37 + n];
1336*32b31808SJens Wiklander 
1337*32b31808SJens Wiklander     if (comp != MBEDTLS_SSL_COMPRESS_NULL) {
1338*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
1339*32b31808SJens Wiklander                               ("server hello, bad compression: %d", comp));
1340*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
1341*32b31808SJens Wiklander             ssl,
1342*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1343*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
1344*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
1345*32b31808SJens Wiklander     }
1346*32b31808SJens Wiklander 
1347*32b31808SJens Wiklander     /*
1348*32b31808SJens Wiklander      * Initialize update checksum functions
1349*32b31808SJens Wiklander      */
1350*32b31808SJens Wiklander     ssl->handshake->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(i);
1351*32b31808SJens Wiklander     if (ssl->handshake->ciphersuite_info == NULL) {
1352*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
1353*32b31808SJens Wiklander                               ("ciphersuite info for %04x not found", (unsigned int) i));
1354*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1355*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
1356*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
1357*32b31808SJens Wiklander     }
1358*32b31808SJens Wiklander 
1359*32b31808SJens Wiklander     mbedtls_ssl_optimize_checksum(ssl, ssl->handshake->ciphersuite_info);
1360*32b31808SJens Wiklander 
1361*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, session id len.: %" MBEDTLS_PRINTF_SIZET, n));
1362*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3,   "server hello, session id", buf + 35, n);
1363*32b31808SJens Wiklander 
1364*32b31808SJens Wiklander     /*
1365*32b31808SJens Wiklander      * Check if the session can be resumed
1366*32b31808SJens Wiklander      */
1367*32b31808SJens Wiklander     if (ssl->handshake->resume == 0 || n == 0 ||
1368*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
1369*32b31808SJens Wiklander         ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ||
1370*32b31808SJens Wiklander #endif
1371*32b31808SJens Wiklander         ssl->session_negotiate->ciphersuite != i ||
1372*32b31808SJens Wiklander         ssl->session_negotiate->id_len != n ||
1373*32b31808SJens Wiklander         memcmp(ssl->session_negotiate->id, buf + 35, n) != 0) {
1374*32b31808SJens Wiklander         ssl->state++;
1375*32b31808SJens Wiklander         ssl->handshake->resume = 0;
1376*32b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME)
1377*32b31808SJens Wiklander         ssl->session_negotiate->start = mbedtls_time(NULL);
1378*32b31808SJens Wiklander #endif
1379*32b31808SJens Wiklander         ssl->session_negotiate->ciphersuite = i;
1380*32b31808SJens Wiklander         ssl->session_negotiate->id_len = n;
1381*32b31808SJens Wiklander         memcpy(ssl->session_negotiate->id, buf + 35, n);
1382*32b31808SJens Wiklander     } else {
1383*32b31808SJens Wiklander         ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
1384*32b31808SJens Wiklander     }
1385*32b31808SJens Wiklander 
1386*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("%s session has been resumed",
1387*32b31808SJens Wiklander                               ssl->handshake->resume ? "a" : "no"));
1388*32b31808SJens Wiklander 
1389*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen ciphersuite: %04x", (unsigned) i));
1390*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, compress alg.: %d",
1391*32b31808SJens Wiklander                               buf[37 + n]));
1392*32b31808SJens Wiklander 
1393*32b31808SJens Wiklander     /*
1394*32b31808SJens Wiklander      * Perform cipher suite validation in same way as in ssl_write_client_hello.
1395*32b31808SJens Wiklander      */
1396*32b31808SJens Wiklander     i = 0;
1397*32b31808SJens Wiklander     while (1) {
1398*32b31808SJens Wiklander         if (ssl->conf->ciphersuite_list[i] == 0) {
1399*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
1400*32b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
1401*32b31808SJens Wiklander                 ssl,
1402*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1403*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
1404*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
1405*32b31808SJens Wiklander         }
1406*32b31808SJens Wiklander 
1407*32b31808SJens Wiklander         if (ssl->conf->ciphersuite_list[i++] ==
1408*32b31808SJens Wiklander             ssl->session_negotiate->ciphersuite) {
1409*32b31808SJens Wiklander             break;
1410*32b31808SJens Wiklander         }
1411*32b31808SJens Wiklander     }
1412*32b31808SJens Wiklander 
1413*32b31808SJens Wiklander     suite_info = mbedtls_ssl_ciphersuite_from_id(
1414*32b31808SJens Wiklander         ssl->session_negotiate->ciphersuite);
1415*32b31808SJens Wiklander     if (mbedtls_ssl_validate_ciphersuite(ssl, suite_info, ssl->tls_version,
1416*32b31808SJens Wiklander                                          ssl->tls_version) != 0) {
1417*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
1418*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
1419*32b31808SJens Wiklander             ssl,
1420*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1421*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
1422*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
1423*32b31808SJens Wiklander     }
1424*32b31808SJens Wiklander 
1425*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
1426*32b31808SJens Wiklander                           ("server hello, chosen ciphersuite: %s", suite_info->name));
1427*32b31808SJens Wiklander 
1428*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
1429*32b31808SJens Wiklander     if (suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA &&
1430*32b31808SJens Wiklander         ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2) {
1431*32b31808SJens Wiklander         ssl->handshake->ecrs_enabled = 1;
1432*32b31808SJens Wiklander     }
1433*32b31808SJens Wiklander #endif
1434*32b31808SJens Wiklander 
1435*32b31808SJens Wiklander     if (comp != MBEDTLS_SSL_COMPRESS_NULL) {
1436*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
1437*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
1438*32b31808SJens Wiklander             ssl,
1439*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1440*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
1441*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
1442*32b31808SJens Wiklander     }
1443*32b31808SJens Wiklander 
1444*32b31808SJens Wiklander     ext = buf + 40 + n;
1445*32b31808SJens Wiklander 
1446*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2,
1447*32b31808SJens Wiklander                           ("server hello, total extension length: %" MBEDTLS_PRINTF_SIZET,
1448*32b31808SJens Wiklander                            ext_len));
1449*32b31808SJens Wiklander 
1450*32b31808SJens Wiklander     while (ext_len) {
1451*32b31808SJens Wiklander         unsigned int ext_id   = ((ext[0] <<  8)
1452*32b31808SJens Wiklander                                  | (ext[1]));
1453*32b31808SJens Wiklander         unsigned int ext_size = ((ext[2] <<  8)
1454*32b31808SJens Wiklander                                  | (ext[3]));
1455*32b31808SJens Wiklander 
1456*32b31808SJens Wiklander         if (ext_size + 4 > ext_len) {
1457*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
1458*32b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
1459*32b31808SJens Wiklander                 ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1460*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
1461*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
1462*32b31808SJens Wiklander         }
1463*32b31808SJens Wiklander 
1464*32b31808SJens Wiklander         switch (ext_id) {
1465*32b31808SJens Wiklander             case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
1466*32b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found renegotiation extension"));
1467*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
1468*32b31808SJens Wiklander                 renegotiation_info_seen = 1;
1469*32b31808SJens Wiklander #endif
1470*32b31808SJens Wiklander 
1471*32b31808SJens Wiklander                 if ((ret = ssl_parse_renegotiation_info(ssl, ext + 4,
1472*32b31808SJens Wiklander                                                         ext_size)) != 0) {
1473*32b31808SJens Wiklander                     return ret;
1474*32b31808SJens Wiklander                 }
1475*32b31808SJens Wiklander 
1476*32b31808SJens Wiklander                 break;
1477*32b31808SJens Wiklander 
1478*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
1479*32b31808SJens Wiklander             case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
1480*32b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3,
1481*32b31808SJens Wiklander                                       ("found max_fragment_length extension"));
1482*32b31808SJens Wiklander 
1483*32b31808SJens Wiklander                 if ((ret = ssl_parse_max_fragment_length_ext(ssl,
1484*32b31808SJens Wiklander                                                              ext + 4, ext_size)) != 0) {
1485*32b31808SJens Wiklander                     return ret;
1486*32b31808SJens Wiklander                 }
1487*32b31808SJens Wiklander 
1488*32b31808SJens Wiklander                 break;
1489*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
1490*32b31808SJens Wiklander 
1491*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
1492*32b31808SJens Wiklander             case MBEDTLS_TLS_EXT_CID:
1493*32b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found CID extension"));
1494*32b31808SJens Wiklander 
1495*32b31808SJens Wiklander                 if ((ret = ssl_parse_cid_ext(ssl,
1496*32b31808SJens Wiklander                                              ext + 4,
1497*32b31808SJens Wiklander                                              ext_size)) != 0) {
1498*32b31808SJens Wiklander                     return ret;
1499*32b31808SJens Wiklander                 }
1500*32b31808SJens Wiklander 
1501*32b31808SJens Wiklander                 break;
1502*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
1503*32b31808SJens Wiklander 
1504*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
1505*32b31808SJens Wiklander             case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
1506*32b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found encrypt_then_mac extension"));
1507*32b31808SJens Wiklander 
1508*32b31808SJens Wiklander                 if ((ret = ssl_parse_encrypt_then_mac_ext(ssl,
1509*32b31808SJens Wiklander                                                           ext + 4, ext_size)) != 0) {
1510*32b31808SJens Wiklander                     return ret;
1511*32b31808SJens Wiklander                 }
1512*32b31808SJens Wiklander 
1513*32b31808SJens Wiklander                 break;
1514*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
1515*32b31808SJens Wiklander 
1516*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
1517*32b31808SJens Wiklander             case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
1518*32b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3,
1519*32b31808SJens Wiklander                                       ("found extended_master_secret extension"));
1520*32b31808SJens Wiklander 
1521*32b31808SJens Wiklander                 if ((ret = ssl_parse_extended_ms_ext(ssl,
1522*32b31808SJens Wiklander                                                      ext + 4, ext_size)) != 0) {
1523*32b31808SJens Wiklander                     return ret;
1524*32b31808SJens Wiklander                 }
1525*32b31808SJens Wiklander 
1526*32b31808SJens Wiklander                 break;
1527*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
1528*32b31808SJens Wiklander 
1529*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
1530*32b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SESSION_TICKET:
1531*32b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found session_ticket extension"));
1532*32b31808SJens Wiklander 
1533*32b31808SJens Wiklander                 if ((ret = ssl_parse_session_ticket_ext(ssl,
1534*32b31808SJens Wiklander                                                         ext + 4, ext_size)) != 0) {
1535*32b31808SJens Wiklander                     return ret;
1536*32b31808SJens Wiklander                 }
1537*32b31808SJens Wiklander 
1538*32b31808SJens Wiklander                 break;
1539*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
1540*32b31808SJens Wiklander 
1541*32b31808SJens Wiklander #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
1542*32b31808SJens Wiklander                 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
1543*32b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
1544*32b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3,
1545*32b31808SJens Wiklander                                       ("found supported_point_formats extension"));
1546*32b31808SJens Wiklander 
1547*32b31808SJens Wiklander                 if ((ret = ssl_parse_supported_point_formats_ext(ssl,
1548*32b31808SJens Wiklander                                                                  ext + 4, ext_size)) != 0) {
1549*32b31808SJens Wiklander                     return ret;
1550*32b31808SJens Wiklander                 }
1551*32b31808SJens Wiklander 
1552*32b31808SJens Wiklander                 break;
1553*32b31808SJens Wiklander #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
1554*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1555*32b31808SJens Wiklander 
1556*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
1557*32b31808SJens Wiklander             case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
1558*32b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found ecjpake_kkpp extension"));
1559*32b31808SJens Wiklander 
1560*32b31808SJens Wiklander                 if ((ret = ssl_parse_ecjpake_kkpp(ssl,
1561*32b31808SJens Wiklander                                                   ext + 4, ext_size)) != 0) {
1562*32b31808SJens Wiklander                     return ret;
1563*32b31808SJens Wiklander                 }
1564*32b31808SJens Wiklander 
1565*32b31808SJens Wiklander                 break;
1566*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1567*32b31808SJens Wiklander 
1568*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ALPN)
1569*32b31808SJens Wiklander             case MBEDTLS_TLS_EXT_ALPN:
1570*32b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found alpn extension"));
1571*32b31808SJens Wiklander 
1572*32b31808SJens Wiklander                 if ((ret = ssl_parse_alpn_ext(ssl, ext + 4, ext_size)) != 0) {
1573*32b31808SJens Wiklander                     return ret;
1574*32b31808SJens Wiklander                 }
1575*32b31808SJens Wiklander 
1576*32b31808SJens Wiklander                 break;
1577*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_ALPN */
1578*32b31808SJens Wiklander 
1579*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP)
1580*32b31808SJens Wiklander             case MBEDTLS_TLS_EXT_USE_SRTP:
1581*32b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found use_srtp extension"));
1582*32b31808SJens Wiklander 
1583*32b31808SJens Wiklander                 if ((ret = ssl_parse_use_srtp_ext(ssl, ext + 4, ext_size)) != 0) {
1584*32b31808SJens Wiklander                     return ret;
1585*32b31808SJens Wiklander                 }
1586*32b31808SJens Wiklander 
1587*32b31808SJens Wiklander                 break;
1588*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_SRTP */
1589*32b31808SJens Wiklander 
1590*32b31808SJens Wiklander             default:
1591*32b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3,
1592*32b31808SJens Wiklander                                       ("unknown extension found: %u (ignoring)", ext_id));
1593*32b31808SJens Wiklander         }
1594*32b31808SJens Wiklander 
1595*32b31808SJens Wiklander         ext_len -= 4 + ext_size;
1596*32b31808SJens Wiklander         ext += 4 + ext_size;
1597*32b31808SJens Wiklander 
1598*32b31808SJens Wiklander         if (ext_len > 0 && ext_len < 4) {
1599*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
1600*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
1601*32b31808SJens Wiklander         }
1602*32b31808SJens Wiklander     }
1603*32b31808SJens Wiklander 
1604*32b31808SJens Wiklander     /*
1605*32b31808SJens Wiklander      * mbedtls_ssl_derive_keys() has to be called after the parsing of the
1606*32b31808SJens Wiklander      * extensions. It sets the transform data for the resumed session which in
1607*32b31808SJens Wiklander      * case of DTLS includes the server CID extracted from the CID extension.
1608*32b31808SJens Wiklander      */
1609*32b31808SJens Wiklander     if (ssl->handshake->resume) {
1610*32b31808SJens Wiklander         if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) {
1611*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret);
1612*32b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
1613*32b31808SJens Wiklander                 ssl,
1614*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1615*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
1616*32b31808SJens Wiklander             return ret;
1617*32b31808SJens Wiklander         }
1618*32b31808SJens Wiklander     }
1619*32b31808SJens Wiklander 
1620*32b31808SJens Wiklander     /*
1621*32b31808SJens Wiklander      * Renegotiation security checks
1622*32b31808SJens Wiklander      */
1623*32b31808SJens Wiklander     if (ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
1624*32b31808SJens Wiklander         ssl->conf->allow_legacy_renegotiation ==
1625*32b31808SJens Wiklander         MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE) {
1626*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
1627*32b31808SJens Wiklander                               ("legacy renegotiation, breaking off handshake"));
1628*32b31808SJens Wiklander         handshake_failure = 1;
1629*32b31808SJens Wiklander     }
1630*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
1631*32b31808SJens Wiklander     else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1632*32b31808SJens Wiklander              ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION &&
1633*32b31808SJens Wiklander              renegotiation_info_seen == 0) {
1634*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
1635*32b31808SJens Wiklander                               ("renegotiation_info extension missing (secure)"));
1636*32b31808SJens Wiklander         handshake_failure = 1;
1637*32b31808SJens Wiklander     } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1638*32b31808SJens Wiklander                ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
1639*32b31808SJens Wiklander                ssl->conf->allow_legacy_renegotiation ==
1640*32b31808SJens Wiklander                MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION) {
1641*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("legacy renegotiation not allowed"));
1642*32b31808SJens Wiklander         handshake_failure = 1;
1643*32b31808SJens Wiklander     } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1644*32b31808SJens Wiklander                ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
1645*32b31808SJens Wiklander                renegotiation_info_seen == 1) {
1646*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
1647*32b31808SJens Wiklander                               ("renegotiation_info extension present (legacy)"));
1648*32b31808SJens Wiklander         handshake_failure = 1;
1649*32b31808SJens Wiklander     }
1650*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */
1651*32b31808SJens Wiklander 
1652*32b31808SJens Wiklander     if (handshake_failure == 1) {
1653*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
1654*32b31808SJens Wiklander             ssl,
1655*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1656*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
1657*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
1658*32b31808SJens Wiklander     }
1659*32b31808SJens Wiklander 
1660*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server hello"));
1661*32b31808SJens Wiklander 
1662*32b31808SJens Wiklander     return 0;
1663*32b31808SJens Wiklander }
1664*32b31808SJens Wiklander 
1665*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
1666*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
1667*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
1668*32b31808SJens Wiklander static int ssl_parse_server_dh_params(mbedtls_ssl_context *ssl,
1669*32b31808SJens Wiklander                                       unsigned char **p,
1670*32b31808SJens Wiklander                                       unsigned char *end)
1671*32b31808SJens Wiklander {
1672*32b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
1673*32b31808SJens Wiklander     size_t dhm_actual_bitlen;
1674*32b31808SJens Wiklander 
1675*32b31808SJens Wiklander     /*
1676*32b31808SJens Wiklander      * Ephemeral DH parameters:
1677*32b31808SJens Wiklander      *
1678*32b31808SJens Wiklander      * struct {
1679*32b31808SJens Wiklander      *     opaque dh_p<1..2^16-1>;
1680*32b31808SJens Wiklander      *     opaque dh_g<1..2^16-1>;
1681*32b31808SJens Wiklander      *     opaque dh_Ys<1..2^16-1>;
1682*32b31808SJens Wiklander      * } ServerDHParams;
1683*32b31808SJens Wiklander      */
1684*32b31808SJens Wiklander     if ((ret = mbedtls_dhm_read_params(&ssl->handshake->dhm_ctx,
1685*32b31808SJens Wiklander                                        p, end)) != 0) {
1686*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(2, ("mbedtls_dhm_read_params"), ret);
1687*32b31808SJens Wiklander         return ret;
1688*32b31808SJens Wiklander     }
1689*32b31808SJens Wiklander 
1690*32b31808SJens Wiklander     dhm_actual_bitlen = mbedtls_dhm_get_bitlen(&ssl->handshake->dhm_ctx);
1691*32b31808SJens Wiklander     if (dhm_actual_bitlen < ssl->conf->dhm_min_bitlen) {
1692*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("DHM prime too short: %" MBEDTLS_PRINTF_SIZET " < %u",
1693*32b31808SJens Wiklander                                   dhm_actual_bitlen,
1694*32b31808SJens Wiklander                                   ssl->conf->dhm_min_bitlen));
1695*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
1696*32b31808SJens Wiklander     }
1697*32b31808SJens Wiklander 
1698*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MPI(3, "DHM: P ", &ssl->handshake->dhm_ctx.P);
1699*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MPI(3, "DHM: G ", &ssl->handshake->dhm_ctx.G);
1700*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GY", &ssl->handshake->dhm_ctx.GY);
1701*32b31808SJens Wiklander 
1702*32b31808SJens Wiklander     return ret;
1703*32b31808SJens Wiklander }
1704*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
1705*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
1706*32b31808SJens Wiklander 
1707*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
1708*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)   ||   \
1709*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)   ||   \
1710*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
1711*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
1712*32b31808SJens Wiklander static int ssl_parse_server_ecdh_params(mbedtls_ssl_context *ssl,
1713*32b31808SJens Wiklander                                         unsigned char **p,
1714*32b31808SJens Wiklander                                         unsigned char *end)
1715*32b31808SJens Wiklander {
1716*32b31808SJens Wiklander     uint16_t tls_id;
1717*32b31808SJens Wiklander     uint8_t ecpoint_len;
1718*32b31808SJens Wiklander     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
1719*32b31808SJens Wiklander     psa_ecc_family_t ec_psa_family = 0;
1720*32b31808SJens Wiklander     size_t ec_bits = 0;
1721*32b31808SJens Wiklander 
1722*32b31808SJens Wiklander     /*
1723*32b31808SJens Wiklander      * struct {
1724*32b31808SJens Wiklander      *     ECParameters curve_params;
1725*32b31808SJens Wiklander      *     ECPoint      public;
1726*32b31808SJens Wiklander      * } ServerECDHParams;
1727*32b31808SJens Wiklander      *
1728*32b31808SJens Wiklander      *  1       curve_type (must be "named_curve")
1729*32b31808SJens Wiklander      *  2..3    NamedCurve
1730*32b31808SJens Wiklander      *  4       ECPoint.len
1731*32b31808SJens Wiklander      *  5+      ECPoint contents
1732*32b31808SJens Wiklander      */
1733*32b31808SJens Wiklander     if (end - *p < 4) {
1734*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
1735*32b31808SJens Wiklander     }
1736*32b31808SJens Wiklander 
1737*32b31808SJens Wiklander     /* First byte is curve_type; only named_curve is handled */
1738*32b31808SJens Wiklander     if (*(*p)++ != MBEDTLS_ECP_TLS_NAMED_CURVE) {
1739*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
1740*32b31808SJens Wiklander     }
1741*32b31808SJens Wiklander 
1742*32b31808SJens Wiklander     /* Next two bytes are the namedcurve value */
1743*32b31808SJens Wiklander     tls_id = *(*p)++;
1744*32b31808SJens Wiklander     tls_id <<= 8;
1745*32b31808SJens Wiklander     tls_id |= *(*p)++;
1746*32b31808SJens Wiklander 
1747*32b31808SJens Wiklander     /* Check it's a curve we offered */
1748*32b31808SJens Wiklander     if (mbedtls_ssl_check_curve_tls_id(ssl, tls_id) != 0) {
1749*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2,
1750*32b31808SJens Wiklander                               ("bad server key exchange message (ECDHE curve): %u",
1751*32b31808SJens Wiklander                                (unsigned) tls_id));
1752*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
1753*32b31808SJens Wiklander     }
1754*32b31808SJens Wiklander 
1755*32b31808SJens Wiklander     /* Convert EC's TLS ID to PSA key type. */
1756*32b31808SJens Wiklander     if (mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id, &ec_psa_family,
1757*32b31808SJens Wiklander                                                    &ec_bits) == PSA_ERROR_NOT_SUPPORTED) {
1758*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
1759*32b31808SJens Wiklander     }
1760*32b31808SJens Wiklander     handshake->ecdh_psa_type = PSA_KEY_TYPE_ECC_KEY_PAIR(ec_psa_family);
1761*32b31808SJens Wiklander     handshake->ecdh_bits = ec_bits;
1762*32b31808SJens Wiklander 
1763*32b31808SJens Wiklander     /* Keep a copy of the peer's public key */
1764*32b31808SJens Wiklander     ecpoint_len = *(*p)++;
1765*32b31808SJens Wiklander     if ((size_t) (end - *p) < ecpoint_len) {
1766*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
1767*32b31808SJens Wiklander     }
1768*32b31808SJens Wiklander 
1769*32b31808SJens Wiklander     if (ecpoint_len > sizeof(handshake->ecdh_psa_peerkey)) {
1770*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
1771*32b31808SJens Wiklander     }
1772*32b31808SJens Wiklander 
1773*32b31808SJens Wiklander     memcpy(handshake->ecdh_psa_peerkey, *p, ecpoint_len);
1774*32b31808SJens Wiklander     handshake->ecdh_psa_peerkey_len = ecpoint_len;
1775*32b31808SJens Wiklander     *p += ecpoint_len;
1776*32b31808SJens Wiklander 
1777*32b31808SJens Wiklander     return 0;
1778*32b31808SJens Wiklander }
1779*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED   ||
1780*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED   ||
1781*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
1782*32b31808SJens Wiklander #else
1783*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)   ||   \
1784*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)    ||   \
1785*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)   ||   \
1786*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||   \
1787*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
1788*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
1789*32b31808SJens Wiklander static int ssl_check_server_ecdh_params(const mbedtls_ssl_context *ssl)
1790*32b31808SJens Wiklander {
1791*32b31808SJens Wiklander     uint16_t tls_id;
1792*32b31808SJens Wiklander     mbedtls_ecp_group_id grp_id;
1793*32b31808SJens Wiklander #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
1794*32b31808SJens Wiklander     grp_id = ssl->handshake->ecdh_ctx.grp.id;
1795*32b31808SJens Wiklander #else
1796*32b31808SJens Wiklander     grp_id = ssl->handshake->ecdh_ctx.grp_id;
1797*32b31808SJens Wiklander #endif
1798*32b31808SJens Wiklander 
1799*32b31808SJens Wiklander     tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id);
1800*32b31808SJens Wiklander     if (tls_id == 0) {
1801*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1802*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1803*32b31808SJens Wiklander     }
1804*32b31808SJens Wiklander 
1805*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("ECDH curve: %s",
1806*32b31808SJens Wiklander                               mbedtls_ssl_get_curve_name_from_tls_id(tls_id)));
1807*32b31808SJens Wiklander 
1808*32b31808SJens Wiklander     if (mbedtls_ssl_check_curve(ssl, grp_id) != 0) {
1809*32b31808SJens Wiklander         return -1;
1810*32b31808SJens Wiklander     }
1811*32b31808SJens Wiklander 
1812*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
1813*32b31808SJens Wiklander                            MBEDTLS_DEBUG_ECDH_QP);
1814*32b31808SJens Wiklander 
1815*32b31808SJens Wiklander     return 0;
1816*32b31808SJens Wiklander }
1817*32b31808SJens Wiklander 
1818*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED   ||
1819*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED    ||
1820*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED   ||
1821*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
1822*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
1823*32b31808SJens Wiklander 
1824*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||     \
1825*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||     \
1826*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
1827*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
1828*32b31808SJens Wiklander static int ssl_parse_server_ecdh_params(mbedtls_ssl_context *ssl,
1829*32b31808SJens Wiklander                                         unsigned char **p,
1830*32b31808SJens Wiklander                                         unsigned char *end)
1831*32b31808SJens Wiklander {
1832*32b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
1833*32b31808SJens Wiklander 
1834*32b31808SJens Wiklander     /*
1835*32b31808SJens Wiklander      * Ephemeral ECDH parameters:
1836*32b31808SJens Wiklander      *
1837*32b31808SJens Wiklander      * struct {
1838*32b31808SJens Wiklander      *     ECParameters curve_params;
1839*32b31808SJens Wiklander      *     ECPoint      public;
1840*32b31808SJens Wiklander      * } ServerECDHParams;
1841*32b31808SJens Wiklander      */
1842*32b31808SJens Wiklander     if ((ret = mbedtls_ecdh_read_params(&ssl->handshake->ecdh_ctx,
1843*32b31808SJens Wiklander                                         (const unsigned char **) p, end)) != 0) {
1844*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_read_params"), ret);
1845*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
1846*32b31808SJens Wiklander         if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
1847*32b31808SJens Wiklander             ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
1848*32b31808SJens Wiklander         }
1849*32b31808SJens Wiklander #endif
1850*32b31808SJens Wiklander         return ret;
1851*32b31808SJens Wiklander     }
1852*32b31808SJens Wiklander 
1853*32b31808SJens Wiklander     if (ssl_check_server_ecdh_params(ssl) != 0) {
1854*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
1855*32b31808SJens Wiklander                               ("bad server key exchange message (ECDHE curve)"));
1856*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
1857*32b31808SJens Wiklander     }
1858*32b31808SJens Wiklander 
1859*32b31808SJens Wiklander     return ret;
1860*32b31808SJens Wiklander }
1861*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || \
1862*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || \
1863*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
1864*32b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO */
1865*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
1866*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
1867*32b31808SJens Wiklander static int ssl_parse_server_psk_hint(mbedtls_ssl_context *ssl,
1868*32b31808SJens Wiklander                                      unsigned char **p,
1869*32b31808SJens Wiklander                                      unsigned char *end)
1870*32b31808SJens Wiklander {
1871*32b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
1872*32b31808SJens Wiklander     uint16_t  len;
1873*32b31808SJens Wiklander     ((void) ssl);
1874*32b31808SJens Wiklander 
1875*32b31808SJens Wiklander     /*
1876*32b31808SJens Wiklander      * PSK parameters:
1877*32b31808SJens Wiklander      *
1878*32b31808SJens Wiklander      * opaque psk_identity_hint<0..2^16-1>;
1879*32b31808SJens Wiklander      */
1880*32b31808SJens Wiklander     if (end - (*p) < 2) {
1881*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
1882*32b31808SJens Wiklander                               ("bad server key exchange message (psk_identity_hint length)"));
1883*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
1884*32b31808SJens Wiklander     }
1885*32b31808SJens Wiklander     len = (*p)[0] << 8 | (*p)[1];
1886*32b31808SJens Wiklander     *p += 2;
1887*32b31808SJens Wiklander 
1888*32b31808SJens Wiklander     if (end - (*p) < len) {
1889*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
1890*32b31808SJens Wiklander                               ("bad server key exchange message (psk_identity_hint length)"));
1891*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
1892*32b31808SJens Wiklander     }
1893*32b31808SJens Wiklander 
1894*32b31808SJens Wiklander     /*
1895*32b31808SJens Wiklander      * Note: we currently ignore the PSK identity hint, as we only allow one
1896*32b31808SJens Wiklander      * PSK to be provisioned on the client. This could be changed later if
1897*32b31808SJens Wiklander      * someone needs that feature.
1898*32b31808SJens Wiklander      */
1899*32b31808SJens Wiklander     *p += len;
1900*32b31808SJens Wiklander     ret = 0;
1901*32b31808SJens Wiklander 
1902*32b31808SJens Wiklander     return ret;
1903*32b31808SJens Wiklander }
1904*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
1905*32b31808SJens Wiklander 
1906*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) ||                           \
1907*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
1908*32b31808SJens Wiklander /*
1909*32b31808SJens Wiklander  * Generate a pre-master secret and encrypt it with the server's RSA key
1910*32b31808SJens Wiklander  */
1911*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
1912*32b31808SJens Wiklander static int ssl_write_encrypted_pms(mbedtls_ssl_context *ssl,
1913*32b31808SJens Wiklander                                    size_t offset, size_t *olen,
1914*32b31808SJens Wiklander                                    size_t pms_offset)
1915*32b31808SJens Wiklander {
1916*32b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1917*32b31808SJens Wiklander     size_t len_bytes = 2;
1918*32b31808SJens Wiklander     unsigned char *p = ssl->handshake->premaster + pms_offset;
1919*32b31808SJens Wiklander     mbedtls_pk_context *peer_pk;
1920*32b31808SJens Wiklander 
1921*32b31808SJens Wiklander     if (offset + len_bytes > MBEDTLS_SSL_OUT_CONTENT_LEN) {
1922*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small for encrypted pms"));
1923*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
1924*32b31808SJens Wiklander     }
1925*32b31808SJens Wiklander 
1926*32b31808SJens Wiklander     /*
1927*32b31808SJens Wiklander      * Generate (part of) the pre-master as
1928*32b31808SJens Wiklander      *  struct {
1929*32b31808SJens Wiklander      *      ProtocolVersion client_version;
1930*32b31808SJens Wiklander      *      opaque random[46];
1931*32b31808SJens Wiklander      *  } PreMasterSecret;
1932*32b31808SJens Wiklander      */
1933*32b31808SJens Wiklander     mbedtls_ssl_write_version(p, ssl->conf->transport,
1934*32b31808SJens Wiklander                               MBEDTLS_SSL_VERSION_TLS1_2);
1935*32b31808SJens Wiklander 
1936*32b31808SJens Wiklander     if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p + 2, 46)) != 0) {
1937*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "f_rng", ret);
1938*32b31808SJens Wiklander         return ret;
1939*32b31808SJens Wiklander     }
1940*32b31808SJens Wiklander 
1941*32b31808SJens Wiklander     ssl->handshake->pmslen = 48;
1942*32b31808SJens Wiklander 
1943*32b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
1944*32b31808SJens Wiklander     peer_pk = &ssl->handshake->peer_pubkey;
1945*32b31808SJens Wiklander #else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
1946*32b31808SJens Wiklander     if (ssl->session_negotiate->peer_cert == NULL) {
1947*32b31808SJens Wiklander         /* Should never happen */
1948*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1949*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1950*32b31808SJens Wiklander     }
1951*32b31808SJens Wiklander     peer_pk = &ssl->session_negotiate->peer_cert->pk;
1952*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
1953*32b31808SJens Wiklander 
1954*32b31808SJens Wiklander     /*
1955*32b31808SJens Wiklander      * Now write it out, encrypted
1956*32b31808SJens Wiklander      */
1957*32b31808SJens Wiklander     if (!mbedtls_pk_can_do(peer_pk, MBEDTLS_PK_RSA)) {
1958*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("certificate key type mismatch"));
1959*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
1960*32b31808SJens Wiklander     }
1961*32b31808SJens Wiklander 
1962*32b31808SJens Wiklander     if ((ret = mbedtls_pk_encrypt(peer_pk,
1963*32b31808SJens Wiklander                                   p, ssl->handshake->pmslen,
1964*32b31808SJens Wiklander                                   ssl->out_msg + offset + len_bytes, olen,
1965*32b31808SJens Wiklander                                   MBEDTLS_SSL_OUT_CONTENT_LEN - offset - len_bytes,
1966*32b31808SJens Wiklander                                   ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
1967*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_rsa_pkcs1_encrypt", ret);
1968*32b31808SJens Wiklander         return ret;
1969*32b31808SJens Wiklander     }
1970*32b31808SJens Wiklander 
1971*32b31808SJens Wiklander     if (len_bytes == 2) {
1972*32b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(*olen, ssl->out_msg, offset);
1973*32b31808SJens Wiklander         *olen += 2;
1974*32b31808SJens Wiklander     }
1975*32b31808SJens Wiklander 
1976*32b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
1977*32b31808SJens Wiklander     /* We don't need the peer's public key anymore. Free it. */
1978*32b31808SJens Wiklander     mbedtls_pk_free(peer_pk);
1979*32b31808SJens Wiklander #endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
1980*32b31808SJens Wiklander     return 0;
1981*32b31808SJens Wiklander }
1982*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
1983*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
1984*32b31808SJens Wiklander 
1985*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
1986*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
1987*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
1988*32b31808SJens Wiklander static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
1989*32b31808SJens Wiklander {
1990*32b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1991*32b31808SJens Wiklander     const mbedtls_ecp_keypair *peer_key;
1992*32b31808SJens Wiklander     mbedtls_pk_context *peer_pk;
1993*32b31808SJens Wiklander 
1994*32b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
1995*32b31808SJens Wiklander     peer_pk = &ssl->handshake->peer_pubkey;
1996*32b31808SJens Wiklander #else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
1997*32b31808SJens Wiklander     if (ssl->session_negotiate->peer_cert == NULL) {
1998*32b31808SJens Wiklander         /* Should never happen */
1999*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2000*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2001*32b31808SJens Wiklander     }
2002*32b31808SJens Wiklander     peer_pk = &ssl->session_negotiate->peer_cert->pk;
2003*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
2004*32b31808SJens Wiklander 
2005*32b31808SJens Wiklander     /* This is a public key, so it can't be opaque, so can_do() is a good
2006*32b31808SJens Wiklander      * enough check to ensure pk_ec() is safe to use below. */
2007*32b31808SJens Wiklander     if (!mbedtls_pk_can_do(peer_pk, MBEDTLS_PK_ECKEY)) {
2008*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("server key not ECDH capable"));
2009*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
2010*32b31808SJens Wiklander     }
2011*32b31808SJens Wiklander 
2012*32b31808SJens Wiklander     peer_key = mbedtls_pk_ec(*peer_pk);
2013*32b31808SJens Wiklander 
2014*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
2015*32b31808SJens Wiklander     size_t olen = 0;
2016*32b31808SJens Wiklander     uint16_t tls_id = 0;
2017*32b31808SJens Wiklander     psa_ecc_family_t ecc_family;
2018*32b31808SJens Wiklander 
2019*32b31808SJens Wiklander     if (mbedtls_ssl_check_curve(ssl, peer_key->grp.id) != 0) {
2020*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server certificate (ECDH curve)"));
2021*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
2022*32b31808SJens Wiklander     }
2023*32b31808SJens Wiklander 
2024*32b31808SJens Wiklander     tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(peer_key->grp.id);
2025*32b31808SJens Wiklander     if (tls_id == 0) {
2026*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("ECC group %u not suported",
2027*32b31808SJens Wiklander                                   peer_key->grp.id));
2028*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
2029*32b31808SJens Wiklander     }
2030*32b31808SJens Wiklander 
2031*32b31808SJens Wiklander     /* If the above conversion to TLS ID was fine, then also this one will be,
2032*32b31808SJens Wiklander        so there is no need to check the return value here */
2033*32b31808SJens Wiklander     mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id, &ecc_family,
2034*32b31808SJens Wiklander                                                &ssl->handshake->ecdh_bits);
2035*32b31808SJens Wiklander 
2036*32b31808SJens Wiklander     ssl->handshake->ecdh_psa_type = PSA_KEY_TYPE_ECC_KEY_PAIR(ecc_family);
2037*32b31808SJens Wiklander 
2038*32b31808SJens Wiklander     /* Store peer's public key in psa format. */
2039*32b31808SJens Wiklander     ret = mbedtls_ecp_point_write_binary(&peer_key->grp, &peer_key->Q,
2040*32b31808SJens Wiklander                                          MBEDTLS_ECP_PF_UNCOMPRESSED, &olen,
2041*32b31808SJens Wiklander                                          ssl->handshake->ecdh_psa_peerkey,
2042*32b31808SJens Wiklander                                          MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH);
2043*32b31808SJens Wiklander 
2044*32b31808SJens Wiklander     if (ret != 0) {
2045*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecp_point_write_binary"), ret);
2046*32b31808SJens Wiklander         return ret;
2047*32b31808SJens Wiklander     }
2048*32b31808SJens Wiklander 
2049*32b31808SJens Wiklander     ssl->handshake->ecdh_psa_peerkey_len = olen;
2050*32b31808SJens Wiklander #else
2051*32b31808SJens Wiklander     if ((ret = mbedtls_ecdh_get_params(&ssl->handshake->ecdh_ctx, peer_key,
2052*32b31808SJens Wiklander                                        MBEDTLS_ECDH_THEIRS)) != 0) {
2053*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_get_params"), ret);
2054*32b31808SJens Wiklander         return ret;
2055*32b31808SJens Wiklander     }
2056*32b31808SJens Wiklander 
2057*32b31808SJens Wiklander     if (ssl_check_server_ecdh_params(ssl) != 0) {
2058*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server certificate (ECDH curve)"));
2059*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
2060*32b31808SJens Wiklander     }
2061*32b31808SJens Wiklander #endif
2062*32b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
2063*32b31808SJens Wiklander     /* We don't need the peer's public key anymore. Free it,
2064*32b31808SJens Wiklander      * so that more RAM is available for upcoming expensive
2065*32b31808SJens Wiklander      * operations like ECDHE. */
2066*32b31808SJens Wiklander     mbedtls_pk_free(peer_pk);
2067*32b31808SJens Wiklander #endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
2068*32b31808SJens Wiklander 
2069*32b31808SJens Wiklander     return ret;
2070*32b31808SJens Wiklander }
2071*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
2072*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
2073*32b31808SJens Wiklander 
2074*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
2075*32b31808SJens Wiklander static int ssl_parse_server_key_exchange(mbedtls_ssl_context *ssl)
2076*32b31808SJens Wiklander {
2077*32b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2078*32b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
2079*32b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
2080*32b31808SJens Wiklander     unsigned char *p = NULL, *end = NULL;
2081*32b31808SJens Wiklander 
2082*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse server key exchange"));
2083*32b31808SJens Wiklander 
2084*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
2085*32b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) {
2086*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse server key exchange"));
2087*32b31808SJens Wiklander         ssl->state++;
2088*32b31808SJens Wiklander         return 0;
2089*32b31808SJens Wiklander     }
2090*32b31808SJens Wiklander     ((void) p);
2091*32b31808SJens Wiklander     ((void) end);
2092*32b31808SJens Wiklander #endif
2093*32b31808SJens Wiklander 
2094*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
2095*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
2096*32b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
2097*32b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA) {
2098*32b31808SJens Wiklander         if ((ret = ssl_get_ecdh_params_from_cert(ssl)) != 0) {
2099*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "ssl_get_ecdh_params_from_cert", ret);
2100*32b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
2101*32b31808SJens Wiklander                 ssl,
2102*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2103*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
2104*32b31808SJens Wiklander             return ret;
2105*32b31808SJens Wiklander         }
2106*32b31808SJens Wiklander 
2107*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse server key exchange"));
2108*32b31808SJens Wiklander         ssl->state++;
2109*32b31808SJens Wiklander         return 0;
2110*32b31808SJens Wiklander     }
2111*32b31808SJens Wiklander     ((void) p);
2112*32b31808SJens Wiklander     ((void) end);
2113*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
2114*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
2115*32b31808SJens Wiklander 
2116*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
2117*32b31808SJens Wiklander     if (ssl->handshake->ecrs_enabled &&
2118*32b31808SJens Wiklander         ssl->handshake->ecrs_state == ssl_ecrs_ske_start_processing) {
2119*32b31808SJens Wiklander         goto start_processing;
2120*32b31808SJens Wiklander     }
2121*32b31808SJens Wiklander #endif
2122*32b31808SJens Wiklander 
2123*32b31808SJens Wiklander     if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
2124*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
2125*32b31808SJens Wiklander         return ret;
2126*32b31808SJens Wiklander     }
2127*32b31808SJens Wiklander 
2128*32b31808SJens Wiklander     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
2129*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message"));
2130*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
2131*32b31808SJens Wiklander             ssl,
2132*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2133*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE);
2134*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
2135*32b31808SJens Wiklander     }
2136*32b31808SJens Wiklander 
2137*32b31808SJens Wiklander     /*
2138*32b31808SJens Wiklander      * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server
2139*32b31808SJens Wiklander      * doesn't use a psk_identity_hint
2140*32b31808SJens Wiklander      */
2141*32b31808SJens Wiklander     if (ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE) {
2142*32b31808SJens Wiklander         if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2143*32b31808SJens Wiklander             ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) {
2144*32b31808SJens Wiklander             /* Current message is probably either
2145*32b31808SJens Wiklander              * CertificateRequest or ServerHelloDone */
2146*32b31808SJens Wiklander             ssl->keep_current_message = 1;
2147*32b31808SJens Wiklander             goto exit;
2148*32b31808SJens Wiklander         }
2149*32b31808SJens Wiklander 
2150*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
2151*32b31808SJens Wiklander                               ("server key exchange message must not be skipped"));
2152*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
2153*32b31808SJens Wiklander             ssl,
2154*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2155*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE);
2156*32b31808SJens Wiklander 
2157*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
2158*32b31808SJens Wiklander     }
2159*32b31808SJens Wiklander 
2160*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
2161*32b31808SJens Wiklander     if (ssl->handshake->ecrs_enabled) {
2162*32b31808SJens Wiklander         ssl->handshake->ecrs_state = ssl_ecrs_ske_start_processing;
2163*32b31808SJens Wiklander     }
2164*32b31808SJens Wiklander 
2165*32b31808SJens Wiklander start_processing:
2166*32b31808SJens Wiklander #endif
2167*32b31808SJens Wiklander     p   = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl);
2168*32b31808SJens Wiklander     end = ssl->in_msg + ssl->in_hslen;
2169*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3,   "server key exchange", p, end - p);
2170*32b31808SJens Wiklander 
2171*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
2172*32b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2173*32b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
2174*32b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
2175*32b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) {
2176*32b31808SJens Wiklander         if (ssl_parse_server_psk_hint(ssl, &p, end) != 0) {
2177*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message"));
2178*32b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
2179*32b31808SJens Wiklander                 ssl,
2180*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2181*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2182*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
2183*32b31808SJens Wiklander         }
2184*32b31808SJens Wiklander     } /* FALLTHROUGH */
2185*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
2186*32b31808SJens Wiklander 
2187*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) ||                       \
2188*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
2189*32b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
2190*32b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) {
2191*32b31808SJens Wiklander         ; /* nothing more to do */
2192*32b31808SJens Wiklander     } else
2193*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED ||
2194*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
2195*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
2196*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
2197*32b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
2198*32b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK) {
2199*32b31808SJens Wiklander         if (ssl_parse_server_dh_params(ssl, &p, end) != 0) {
2200*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message"));
2201*32b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
2202*32b31808SJens Wiklander                 ssl,
2203*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2204*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
2205*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
2206*32b31808SJens Wiklander         }
2207*32b31808SJens Wiklander     } else
2208*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
2209*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
2210*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||     \
2211*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||     \
2212*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
2213*32b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
2214*32b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
2215*32b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA) {
2216*32b31808SJens Wiklander         if (ssl_parse_server_ecdh_params(ssl, &p, end) != 0) {
2217*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message"));
2218*32b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
2219*32b31808SJens Wiklander                 ssl,
2220*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2221*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
2222*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
2223*32b31808SJens Wiklander         }
2224*32b31808SJens Wiklander     } else
2225*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2226*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
2227*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
2228*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
2229*32b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
2230*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
2231*32b31808SJens Wiklander         /*
2232*32b31808SJens Wiklander          * The first 3 bytes are:
2233*32b31808SJens Wiklander          * [0] MBEDTLS_ECP_TLS_NAMED_CURVE
2234*32b31808SJens Wiklander          * [1, 2] elliptic curve's TLS ID
2235*32b31808SJens Wiklander          *
2236*32b31808SJens Wiklander          * However since we only support secp256r1 for now, we check only
2237*32b31808SJens Wiklander          * that TLS ID here
2238*32b31808SJens Wiklander          */
2239*32b31808SJens Wiklander         uint16_t read_tls_id = MBEDTLS_GET_UINT16_BE(p, 1);
2240*32b31808SJens Wiklander         uint16_t exp_tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(
2241*32b31808SJens Wiklander             MBEDTLS_ECP_DP_SECP256R1);
2242*32b31808SJens Wiklander 
2243*32b31808SJens Wiklander         if (exp_tls_id == 0) {
2244*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
2245*32b31808SJens Wiklander         }
2246*32b31808SJens Wiklander 
2247*32b31808SJens Wiklander         if ((*p != MBEDTLS_ECP_TLS_NAMED_CURVE) ||
2248*32b31808SJens Wiklander             (read_tls_id != exp_tls_id)) {
2249*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
2250*32b31808SJens Wiklander         }
2251*32b31808SJens Wiklander 
2252*32b31808SJens Wiklander         p += 3;
2253*32b31808SJens Wiklander 
2254*32b31808SJens Wiklander         if ((ret = mbedtls_psa_ecjpake_read_round(
2255*32b31808SJens Wiklander                  &ssl->handshake->psa_pake_ctx, p, end - p,
2256*32b31808SJens Wiklander                  MBEDTLS_ECJPAKE_ROUND_TWO)) != 0) {
2257*32b31808SJens Wiklander             psa_destroy_key(ssl->handshake->psa_pake_password);
2258*32b31808SJens Wiklander             psa_pake_abort(&ssl->handshake->psa_pake_ctx);
2259*32b31808SJens Wiklander 
2260*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round two", ret);
2261*32b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
2262*32b31808SJens Wiklander                 ssl,
2263*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2264*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
2265*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
2266*32b31808SJens Wiklander         }
2267*32b31808SJens Wiklander #else
2268*32b31808SJens Wiklander         ret = mbedtls_ecjpake_read_round_two(&ssl->handshake->ecjpake_ctx,
2269*32b31808SJens Wiklander                                              p, end - p);
2270*32b31808SJens Wiklander         if (ret != 0) {
2271*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_two", ret);
2272*32b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
2273*32b31808SJens Wiklander                 ssl,
2274*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2275*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
2276*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
2277*32b31808SJens Wiklander         }
2278*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
2279*32b31808SJens Wiklander     } else
2280*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
2281*32b31808SJens Wiklander     {
2282*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2283*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2284*32b31808SJens Wiklander     }
2285*32b31808SJens Wiklander 
2286*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
2287*32b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_uses_server_signature(ciphersuite_info)) {
2288*32b31808SJens Wiklander         size_t sig_len, hashlen;
2289*32b31808SJens Wiklander         unsigned char hash[MBEDTLS_HASH_MAX_SIZE];
2290*32b31808SJens Wiklander 
2291*32b31808SJens Wiklander         mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
2292*32b31808SJens Wiklander         mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
2293*32b31808SJens Wiklander         unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl);
2294*32b31808SJens Wiklander         size_t params_len = p - params;
2295*32b31808SJens Wiklander         void *rs_ctx = NULL;
2296*32b31808SJens Wiklander         uint16_t sig_alg;
2297*32b31808SJens Wiklander 
2298*32b31808SJens Wiklander         mbedtls_pk_context *peer_pk;
2299*32b31808SJens Wiklander 
2300*32b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
2301*32b31808SJens Wiklander         peer_pk = &ssl->handshake->peer_pubkey;
2302*32b31808SJens Wiklander #else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
2303*32b31808SJens Wiklander         if (ssl->session_negotiate->peer_cert == NULL) {
2304*32b31808SJens Wiklander             /* Should never happen */
2305*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2306*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2307*32b31808SJens Wiklander         }
2308*32b31808SJens Wiklander         peer_pk = &ssl->session_negotiate->peer_cert->pk;
2309*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
2310*32b31808SJens Wiklander 
2311*32b31808SJens Wiklander         /*
2312*32b31808SJens Wiklander          * Handle the digitally-signed structure
2313*32b31808SJens Wiklander          */
2314*32b31808SJens Wiklander         MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
2315*32b31808SJens Wiklander         sig_alg = MBEDTLS_GET_UINT16_BE(p, 0);
2316*32b31808SJens Wiklander         if (mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg(
2317*32b31808SJens Wiklander                 sig_alg, &pk_alg, &md_alg) != 0 &&
2318*32b31808SJens Wiklander             !mbedtls_ssl_sig_alg_is_offered(ssl, sig_alg) &&
2319*32b31808SJens Wiklander             !mbedtls_ssl_sig_alg_is_supported(ssl, sig_alg)) {
2320*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1,
2321*32b31808SJens Wiklander                                   ("bad server key exchange message"));
2322*32b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
2323*32b31808SJens Wiklander                 ssl,
2324*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2325*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
2326*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
2327*32b31808SJens Wiklander         }
2328*32b31808SJens Wiklander         p += 2;
2329*32b31808SJens Wiklander 
2330*32b31808SJens Wiklander         if (!mbedtls_pk_can_do(peer_pk, pk_alg)) {
2331*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1,
2332*32b31808SJens Wiklander                                   ("bad server key exchange message"));
2333*32b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
2334*32b31808SJens Wiklander                 ssl,
2335*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2336*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
2337*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
2338*32b31808SJens Wiklander         }
2339*32b31808SJens Wiklander 
2340*32b31808SJens Wiklander         /*
2341*32b31808SJens Wiklander          * Read signature
2342*32b31808SJens Wiklander          */
2343*32b31808SJens Wiklander 
2344*32b31808SJens Wiklander         if (p > end - 2) {
2345*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message"));
2346*32b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
2347*32b31808SJens Wiklander                 ssl,
2348*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2349*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2350*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
2351*32b31808SJens Wiklander         }
2352*32b31808SJens Wiklander         sig_len = (p[0] << 8) | p[1];
2353*32b31808SJens Wiklander         p += 2;
2354*32b31808SJens Wiklander 
2355*32b31808SJens Wiklander         if (p != end - sig_len) {
2356*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message"));
2357*32b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
2358*32b31808SJens Wiklander                 ssl,
2359*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2360*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2361*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
2362*32b31808SJens Wiklander         }
2363*32b31808SJens Wiklander 
2364*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "signature", p, sig_len);
2365*32b31808SJens Wiklander 
2366*32b31808SJens Wiklander         /*
2367*32b31808SJens Wiklander          * Compute the hash that has been signed
2368*32b31808SJens Wiklander          */
2369*32b31808SJens Wiklander         if (md_alg != MBEDTLS_MD_NONE) {
2370*32b31808SJens Wiklander             ret = mbedtls_ssl_get_key_exchange_md_tls1_2(ssl, hash, &hashlen,
2371*32b31808SJens Wiklander                                                          params, params_len,
2372*32b31808SJens Wiklander                                                          md_alg);
2373*32b31808SJens Wiklander             if (ret != 0) {
2374*32b31808SJens Wiklander                 return ret;
2375*32b31808SJens Wiklander             }
2376*32b31808SJens Wiklander         } else {
2377*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2378*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2379*32b31808SJens Wiklander         }
2380*32b31808SJens Wiklander 
2381*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "parameters hash", hash, hashlen);
2382*32b31808SJens Wiklander 
2383*32b31808SJens Wiklander         /*
2384*32b31808SJens Wiklander          * Verify signature
2385*32b31808SJens Wiklander          */
2386*32b31808SJens Wiklander         if (!mbedtls_pk_can_do(peer_pk, pk_alg)) {
2387*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message"));
2388*32b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
2389*32b31808SJens Wiklander                 ssl,
2390*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2391*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
2392*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
2393*32b31808SJens Wiklander         }
2394*32b31808SJens Wiklander 
2395*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
2396*32b31808SJens Wiklander         if (ssl->handshake->ecrs_enabled) {
2397*32b31808SJens Wiklander             rs_ctx = &ssl->handshake->ecrs_ctx.pk;
2398*32b31808SJens Wiklander         }
2399*32b31808SJens Wiklander #endif
2400*32b31808SJens Wiklander 
2401*32b31808SJens Wiklander #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
2402*32b31808SJens Wiklander         if (pk_alg == MBEDTLS_PK_RSASSA_PSS) {
2403*32b31808SJens Wiklander             mbedtls_pk_rsassa_pss_options rsassa_pss_options;
2404*32b31808SJens Wiklander             rsassa_pss_options.mgf1_hash_id = md_alg;
2405*32b31808SJens Wiklander             rsassa_pss_options.expected_salt_len =
2406*32b31808SJens Wiklander                 mbedtls_hash_info_get_size(md_alg);
2407*32b31808SJens Wiklander             if (rsassa_pss_options.expected_salt_len == 0) {
2408*32b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2409*32b31808SJens Wiklander             }
2410*32b31808SJens Wiklander 
2411*32b31808SJens Wiklander             ret = mbedtls_pk_verify_ext(pk_alg, &rsassa_pss_options,
2412*32b31808SJens Wiklander                                         peer_pk,
2413*32b31808SJens Wiklander                                         md_alg, hash, hashlen,
2414*32b31808SJens Wiklander                                         p, sig_len);
2415*32b31808SJens Wiklander         } else
2416*32b31808SJens Wiklander #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
2417*32b31808SJens Wiklander         ret = mbedtls_pk_verify_restartable(peer_pk,
2418*32b31808SJens Wiklander                                             md_alg, hash, hashlen, p, sig_len, rs_ctx);
2419*32b31808SJens Wiklander 
2420*32b31808SJens Wiklander         if (ret != 0) {
2421*32b31808SJens Wiklander             int send_alert_msg = 1;
2422*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
2423*32b31808SJens Wiklander             send_alert_msg = (ret != MBEDTLS_ERR_ECP_IN_PROGRESS);
2424*32b31808SJens Wiklander #endif
2425*32b31808SJens Wiklander             if (send_alert_msg) {
2426*32b31808SJens Wiklander                 mbedtls_ssl_send_alert_message(
2427*32b31808SJens Wiklander                     ssl,
2428*32b31808SJens Wiklander                     MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2429*32b31808SJens Wiklander                     MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR);
2430*32b31808SJens Wiklander             }
2431*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_verify", ret);
2432*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
2433*32b31808SJens Wiklander             if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
2434*32b31808SJens Wiklander                 ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
2435*32b31808SJens Wiklander             }
2436*32b31808SJens Wiklander #endif
2437*32b31808SJens Wiklander             return ret;
2438*32b31808SJens Wiklander         }
2439*32b31808SJens Wiklander 
2440*32b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
2441*32b31808SJens Wiklander         /* We don't need the peer's public key anymore. Free it,
2442*32b31808SJens Wiklander          * so that more RAM is available for upcoming expensive
2443*32b31808SJens Wiklander          * operations like ECDHE. */
2444*32b31808SJens Wiklander         mbedtls_pk_free(peer_pk);
2445*32b31808SJens Wiklander #endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
2446*32b31808SJens Wiklander     }
2447*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
2448*32b31808SJens Wiklander 
2449*32b31808SJens Wiklander exit:
2450*32b31808SJens Wiklander     ssl->state++;
2451*32b31808SJens Wiklander 
2452*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server key exchange"));
2453*32b31808SJens Wiklander 
2454*32b31808SJens Wiklander     return 0;
2455*32b31808SJens Wiklander }
2456*32b31808SJens Wiklander 
2457*32b31808SJens Wiklander #if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
2458*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
2459*32b31808SJens Wiklander static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl)
2460*32b31808SJens Wiklander {
2461*32b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
2462*32b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
2463*32b31808SJens Wiklander 
2464*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate request"));
2465*32b31808SJens Wiklander 
2466*32b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
2467*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate request"));
2468*32b31808SJens Wiklander         ssl->state++;
2469*32b31808SJens Wiklander         return 0;
2470*32b31808SJens Wiklander     }
2471*32b31808SJens Wiklander 
2472*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2473*32b31808SJens Wiklander     return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2474*32b31808SJens Wiklander }
2475*32b31808SJens Wiklander #else /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
2476*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
2477*32b31808SJens Wiklander static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl)
2478*32b31808SJens Wiklander {
2479*32b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2480*32b31808SJens Wiklander     unsigned char *buf;
2481*32b31808SJens Wiklander     size_t n = 0;
2482*32b31808SJens Wiklander     size_t cert_type_len = 0, dn_len = 0;
2483*32b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
2484*32b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
2485*32b31808SJens Wiklander     size_t sig_alg_len;
2486*32b31808SJens Wiklander #if defined(MBEDTLS_DEBUG_C)
2487*32b31808SJens Wiklander     unsigned char *sig_alg;
2488*32b31808SJens Wiklander     unsigned char *dn;
2489*32b31808SJens Wiklander #endif
2490*32b31808SJens Wiklander 
2491*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate request"));
2492*32b31808SJens Wiklander 
2493*32b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
2494*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate request"));
2495*32b31808SJens Wiklander         ssl->state++;
2496*32b31808SJens Wiklander         return 0;
2497*32b31808SJens Wiklander     }
2498*32b31808SJens Wiklander 
2499*32b31808SJens Wiklander     if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
2500*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
2501*32b31808SJens Wiklander         return ret;
2502*32b31808SJens Wiklander     }
2503*32b31808SJens Wiklander 
2504*32b31808SJens Wiklander     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
2505*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message"));
2506*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
2507*32b31808SJens Wiklander             ssl,
2508*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2509*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE);
2510*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
2511*32b31808SJens Wiklander     }
2512*32b31808SJens Wiklander 
2513*32b31808SJens Wiklander     ssl->state++;
2514*32b31808SJens Wiklander     ssl->handshake->client_auth =
2515*32b31808SJens Wiklander         (ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST);
2516*32b31808SJens Wiklander 
2517*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("got %s certificate request",
2518*32b31808SJens Wiklander                               ssl->handshake->client_auth ? "a" : "no"));
2519*32b31808SJens Wiklander 
2520*32b31808SJens Wiklander     if (ssl->handshake->client_auth == 0) {
2521*32b31808SJens Wiklander         /* Current message is probably the ServerHelloDone */
2522*32b31808SJens Wiklander         ssl->keep_current_message = 1;
2523*32b31808SJens Wiklander         goto exit;
2524*32b31808SJens Wiklander     }
2525*32b31808SJens Wiklander 
2526*32b31808SJens Wiklander     /*
2527*32b31808SJens Wiklander      *  struct {
2528*32b31808SJens Wiklander      *      ClientCertificateType certificate_types<1..2^8-1>;
2529*32b31808SJens Wiklander      *      SignatureAndHashAlgorithm
2530*32b31808SJens Wiklander      *        supported_signature_algorithms<2^16-1>; -- TLS 1.2 only
2531*32b31808SJens Wiklander      *      DistinguishedName certificate_authorities<0..2^16-1>;
2532*32b31808SJens Wiklander      *  } CertificateRequest;
2533*32b31808SJens Wiklander      *
2534*32b31808SJens Wiklander      *  Since we only support a single certificate on clients, let's just
2535*32b31808SJens Wiklander      *  ignore all the information that's supposed to help us pick a
2536*32b31808SJens Wiklander      *  certificate.
2537*32b31808SJens Wiklander      *
2538*32b31808SJens Wiklander      *  We could check that our certificate matches the request, and bail out
2539*32b31808SJens Wiklander      *  if it doesn't, but it's simpler to just send the certificate anyway,
2540*32b31808SJens Wiklander      *  and give the server the opportunity to decide if it should terminate
2541*32b31808SJens Wiklander      *  the connection when it doesn't like our certificate.
2542*32b31808SJens Wiklander      *
2543*32b31808SJens Wiklander      *  Same goes for the hash in TLS 1.2's signature_algorithms: at this
2544*32b31808SJens Wiklander      *  point we only have one hash available (see comments in
2545*32b31808SJens Wiklander      *  write_certificate_verify), so let's just use what we have.
2546*32b31808SJens Wiklander      *
2547*32b31808SJens Wiklander      *  However, we still minimally parse the message to check it is at least
2548*32b31808SJens Wiklander      *  superficially sane.
2549*32b31808SJens Wiklander      */
2550*32b31808SJens Wiklander     buf = ssl->in_msg;
2551*32b31808SJens Wiklander 
2552*32b31808SJens Wiklander     /* certificate_types */
2553*32b31808SJens Wiklander     if (ssl->in_hslen <= mbedtls_ssl_hs_hdr_len(ssl)) {
2554*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message"));
2555*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2556*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2557*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
2558*32b31808SJens Wiklander     }
2559*32b31808SJens Wiklander     cert_type_len = buf[mbedtls_ssl_hs_hdr_len(ssl)];
2560*32b31808SJens Wiklander     n = cert_type_len;
2561*32b31808SJens Wiklander 
2562*32b31808SJens Wiklander     /*
2563*32b31808SJens Wiklander      * In the subsequent code there are two paths that read from buf:
2564*32b31808SJens Wiklander      *     * the length of the signature algorithms field (if minor version of
2565*32b31808SJens Wiklander      *       SSL is 3),
2566*32b31808SJens Wiklander      *     * distinguished name length otherwise.
2567*32b31808SJens Wiklander      * Both reach at most the index:
2568*32b31808SJens Wiklander      *    ...hdr_len + 2 + n,
2569*32b31808SJens Wiklander      * therefore the buffer length at this point must be greater than that
2570*32b31808SJens Wiklander      * regardless of the actual code path.
2571*32b31808SJens Wiklander      */
2572*32b31808SJens Wiklander     if (ssl->in_hslen <= mbedtls_ssl_hs_hdr_len(ssl) + 2 + n) {
2573*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message"));
2574*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2575*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2576*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
2577*32b31808SJens Wiklander     }
2578*32b31808SJens Wiklander 
2579*32b31808SJens Wiklander     /* supported_signature_algorithms */
2580*32b31808SJens Wiklander     sig_alg_len = ((buf[mbedtls_ssl_hs_hdr_len(ssl) + 1 + n] <<  8)
2581*32b31808SJens Wiklander                    | (buf[mbedtls_ssl_hs_hdr_len(ssl) + 2 + n]));
2582*32b31808SJens Wiklander 
2583*32b31808SJens Wiklander     /*
2584*32b31808SJens Wiklander      * The furthest access in buf is in the loop few lines below:
2585*32b31808SJens Wiklander      *     sig_alg[i + 1],
2586*32b31808SJens Wiklander      * where:
2587*32b31808SJens Wiklander      *     sig_alg = buf + ...hdr_len + 3 + n,
2588*32b31808SJens Wiklander      *     max(i) = sig_alg_len - 1.
2589*32b31808SJens Wiklander      * Therefore the furthest access is:
2590*32b31808SJens Wiklander      *     buf[...hdr_len + 3 + n + sig_alg_len - 1 + 1],
2591*32b31808SJens Wiklander      * which reduces to:
2592*32b31808SJens Wiklander      *     buf[...hdr_len + 3 + n + sig_alg_len],
2593*32b31808SJens Wiklander      * which is one less than we need the buf to be.
2594*32b31808SJens Wiklander      */
2595*32b31808SJens Wiklander     if (ssl->in_hslen <= mbedtls_ssl_hs_hdr_len(ssl) + 3 + n + sig_alg_len) {
2596*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message"));
2597*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
2598*32b31808SJens Wiklander             ssl,
2599*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2600*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2601*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
2602*32b31808SJens Wiklander     }
2603*32b31808SJens Wiklander 
2604*32b31808SJens Wiklander #if defined(MBEDTLS_DEBUG_C)
2605*32b31808SJens Wiklander     sig_alg = buf + mbedtls_ssl_hs_hdr_len(ssl) + 3 + n;
2606*32b31808SJens Wiklander     for (size_t i = 0; i < sig_alg_len; i += 2) {
2607*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3,
2608*32b31808SJens Wiklander                               ("Supported Signature Algorithm found: %02x %02x",
2609*32b31808SJens Wiklander                                sig_alg[i], sig_alg[i + 1]));
2610*32b31808SJens Wiklander     }
2611*32b31808SJens Wiklander #endif
2612*32b31808SJens Wiklander 
2613*32b31808SJens Wiklander     n += 2 + sig_alg_len;
2614*32b31808SJens Wiklander 
2615*32b31808SJens Wiklander     /* certificate_authorities */
2616*32b31808SJens Wiklander     dn_len = ((buf[mbedtls_ssl_hs_hdr_len(ssl) + 1 + n] <<  8)
2617*32b31808SJens Wiklander               | (buf[mbedtls_ssl_hs_hdr_len(ssl) + 2 + n]));
2618*32b31808SJens Wiklander 
2619*32b31808SJens Wiklander     n += dn_len;
2620*32b31808SJens Wiklander     if (ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl) + 3 + n) {
2621*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message"));
2622*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2623*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2624*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
2625*32b31808SJens Wiklander     }
2626*32b31808SJens Wiklander 
2627*32b31808SJens Wiklander #if defined(MBEDTLS_DEBUG_C)
2628*32b31808SJens Wiklander     dn = buf + mbedtls_ssl_hs_hdr_len(ssl) + 3 + n - dn_len;
2629*32b31808SJens Wiklander     for (size_t i = 0, dni_len = 0; i < dn_len; i += 2 + dni_len) {
2630*32b31808SJens Wiklander         unsigned char *p = dn + i + 2;
2631*32b31808SJens Wiklander         mbedtls_x509_name name;
2632*32b31808SJens Wiklander         size_t asn1_len;
2633*32b31808SJens Wiklander         char s[MBEDTLS_X509_MAX_DN_NAME_SIZE];
2634*32b31808SJens Wiklander         memset(&name, 0, sizeof(name));
2635*32b31808SJens Wiklander         dni_len = MBEDTLS_GET_UINT16_BE(dn + i, 0);
2636*32b31808SJens Wiklander         if (dni_len > dn_len - i - 2 ||
2637*32b31808SJens Wiklander             mbedtls_asn1_get_tag(&p, p + dni_len, &asn1_len,
2638*32b31808SJens Wiklander                                  MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0 ||
2639*32b31808SJens Wiklander             mbedtls_x509_get_name(&p, p + asn1_len, &name) != 0) {
2640*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message"));
2641*32b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
2642*32b31808SJens Wiklander                 ssl,
2643*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2644*32b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2645*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
2646*32b31808SJens Wiklander         }
2647*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3,
2648*32b31808SJens Wiklander                               ("DN hint: %.*s",
2649*32b31808SJens Wiklander                                mbedtls_x509_dn_gets(s, sizeof(s), &name), s));
2650*32b31808SJens Wiklander         mbedtls_asn1_free_named_data_list_shallow(name.next);
2651*32b31808SJens Wiklander     }
2652*32b31808SJens Wiklander #endif
2653*32b31808SJens Wiklander 
2654*32b31808SJens Wiklander exit:
2655*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate request"));
2656*32b31808SJens Wiklander 
2657*32b31808SJens Wiklander     return 0;
2658*32b31808SJens Wiklander }
2659*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
2660*32b31808SJens Wiklander 
2661*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
2662*32b31808SJens Wiklander static int ssl_parse_server_hello_done(mbedtls_ssl_context *ssl)
2663*32b31808SJens Wiklander {
2664*32b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2665*32b31808SJens Wiklander 
2666*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse server hello done"));
2667*32b31808SJens Wiklander 
2668*32b31808SJens Wiklander     if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
2669*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
2670*32b31808SJens Wiklander         return ret;
2671*32b31808SJens Wiklander     }
2672*32b31808SJens Wiklander 
2673*32b31808SJens Wiklander     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
2674*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello done message"));
2675*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
2676*32b31808SJens Wiklander     }
2677*32b31808SJens Wiklander 
2678*32b31808SJens Wiklander     if (ssl->in_hslen  != mbedtls_ssl_hs_hdr_len(ssl) ||
2679*32b31808SJens Wiklander         ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE) {
2680*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello done message"));
2681*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
2682*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
2683*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
2684*32b31808SJens Wiklander     }
2685*32b31808SJens Wiklander 
2686*32b31808SJens Wiklander     ssl->state++;
2687*32b31808SJens Wiklander 
2688*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
2689*32b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
2690*32b31808SJens Wiklander         mbedtls_ssl_recv_flight_completed(ssl);
2691*32b31808SJens Wiklander     }
2692*32b31808SJens Wiklander #endif
2693*32b31808SJens Wiklander 
2694*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server hello done"));
2695*32b31808SJens Wiklander 
2696*32b31808SJens Wiklander     return 0;
2697*32b31808SJens Wiklander }
2698*32b31808SJens Wiklander 
2699*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
2700*32b31808SJens Wiklander static int ssl_write_client_key_exchange(mbedtls_ssl_context *ssl)
2701*32b31808SJens Wiklander {
2702*32b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2703*32b31808SJens Wiklander 
2704*32b31808SJens Wiklander     size_t header_len;
2705*32b31808SJens Wiklander     size_t content_len;
2706*32b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
2707*32b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
2708*32b31808SJens Wiklander 
2709*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write client key exchange"));
2710*32b31808SJens Wiklander 
2711*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
2712*32b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA) {
2713*32b31808SJens Wiklander         /*
2714*32b31808SJens Wiklander          * DHM key exchange -- send G^X mod P
2715*32b31808SJens Wiklander          */
2716*32b31808SJens Wiklander         content_len = mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx);
2717*32b31808SJens Wiklander 
2718*32b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(content_len, ssl->out_msg, 4);
2719*32b31808SJens Wiklander         header_len = 6;
2720*32b31808SJens Wiklander 
2721*32b31808SJens Wiklander         ret = mbedtls_dhm_make_public(&ssl->handshake->dhm_ctx,
2722*32b31808SJens Wiklander                                       (int) mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx),
2723*32b31808SJens Wiklander                                       &ssl->out_msg[header_len], content_len,
2724*32b31808SJens Wiklander                                       ssl->conf->f_rng, ssl->conf->p_rng);
2725*32b31808SJens Wiklander         if (ret != 0) {
2726*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_make_public", ret);
2727*32b31808SJens Wiklander             return ret;
2728*32b31808SJens Wiklander         }
2729*32b31808SJens Wiklander 
2730*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: X ", &ssl->handshake->dhm_ctx.X);
2731*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GX", &ssl->handshake->dhm_ctx.GX);
2732*32b31808SJens Wiklander 
2733*32b31808SJens Wiklander         if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx,
2734*32b31808SJens Wiklander                                            ssl->handshake->premaster,
2735*32b31808SJens Wiklander                                            MBEDTLS_PREMASTER_SIZE,
2736*32b31808SJens Wiklander                                            &ssl->handshake->pmslen,
2737*32b31808SJens Wiklander                                            ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
2738*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret);
2739*32b31808SJens Wiklander             return ret;
2740*32b31808SJens Wiklander         }
2741*32b31808SJens Wiklander 
2742*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K);
2743*32b31808SJens Wiklander     } else
2744*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
2745*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
2746*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
2747*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
2748*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
2749*32b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
2750*32b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
2751*32b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
2752*32b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA) {
2753*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
2754*32b31808SJens Wiklander         psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2755*32b31808SJens Wiklander         psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED;
2756*32b31808SJens Wiklander         psa_key_attributes_t key_attributes;
2757*32b31808SJens Wiklander 
2758*32b31808SJens Wiklander         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
2759*32b31808SJens Wiklander 
2760*32b31808SJens Wiklander         header_len = 4;
2761*32b31808SJens Wiklander 
2762*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("Perform PSA-based ECDH computation."));
2763*32b31808SJens Wiklander 
2764*32b31808SJens Wiklander         /*
2765*32b31808SJens Wiklander          * Generate EC private key for ECDHE exchange.
2766*32b31808SJens Wiklander          */
2767*32b31808SJens Wiklander 
2768*32b31808SJens Wiklander         /* The master secret is obtained from the shared ECDH secret by
2769*32b31808SJens Wiklander          * applying the TLS 1.2 PRF with a specific salt and label. While
2770*32b31808SJens Wiklander          * the PSA Crypto API encourages combining key agreement schemes
2771*32b31808SJens Wiklander          * such as ECDH with fixed KDFs such as TLS 1.2 PRF, it does not
2772*32b31808SJens Wiklander          * yet support the provisioning of salt + label to the KDF.
2773*32b31808SJens Wiklander          * For the time being, we therefore need to split the computation
2774*32b31808SJens Wiklander          * of the ECDH secret and the application of the TLS 1.2 PRF. */
2775*32b31808SJens Wiklander         key_attributes = psa_key_attributes_init();
2776*32b31808SJens Wiklander         psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
2777*32b31808SJens Wiklander         psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
2778*32b31808SJens Wiklander         psa_set_key_type(&key_attributes, handshake->ecdh_psa_type);
2779*32b31808SJens Wiklander         psa_set_key_bits(&key_attributes, handshake->ecdh_bits);
2780*32b31808SJens Wiklander 
2781*32b31808SJens Wiklander         /* Generate ECDH private key. */
2782*32b31808SJens Wiklander         status = psa_generate_key(&key_attributes,
2783*32b31808SJens Wiklander                                   &handshake->ecdh_psa_privkey);
2784*32b31808SJens Wiklander         if (status != PSA_SUCCESS) {
2785*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
2786*32b31808SJens Wiklander         }
2787*32b31808SJens Wiklander 
2788*32b31808SJens Wiklander         /* Export the public part of the ECDH private key from PSA.
2789*32b31808SJens Wiklander          * The export format is an ECPoint structure as expected by TLS,
2790*32b31808SJens Wiklander          * but we just need to add a length byte before that. */
2791*32b31808SJens Wiklander         unsigned char *own_pubkey = ssl->out_msg + header_len + 1;
2792*32b31808SJens Wiklander         unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
2793*32b31808SJens Wiklander         size_t own_pubkey_max_len = (size_t) (end - own_pubkey);
2794*32b31808SJens Wiklander         size_t own_pubkey_len;
2795*32b31808SJens Wiklander 
2796*32b31808SJens Wiklander         status = psa_export_public_key(handshake->ecdh_psa_privkey,
2797*32b31808SJens Wiklander                                        own_pubkey, own_pubkey_max_len,
2798*32b31808SJens Wiklander                                        &own_pubkey_len);
2799*32b31808SJens Wiklander         if (status != PSA_SUCCESS) {
2800*32b31808SJens Wiklander             psa_destroy_key(handshake->ecdh_psa_privkey);
2801*32b31808SJens Wiklander             handshake->ecdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
2802*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
2803*32b31808SJens Wiklander         }
2804*32b31808SJens Wiklander 
2805*32b31808SJens Wiklander         ssl->out_msg[header_len] = (unsigned char) own_pubkey_len;
2806*32b31808SJens Wiklander         content_len = own_pubkey_len + 1;
2807*32b31808SJens Wiklander 
2808*32b31808SJens Wiklander         /* The ECDH secret is the premaster secret used for key derivation. */
2809*32b31808SJens Wiklander 
2810*32b31808SJens Wiklander         /* Compute ECDH shared secret. */
2811*32b31808SJens Wiklander         status = psa_raw_key_agreement(PSA_ALG_ECDH,
2812*32b31808SJens Wiklander                                        handshake->ecdh_psa_privkey,
2813*32b31808SJens Wiklander                                        handshake->ecdh_psa_peerkey,
2814*32b31808SJens Wiklander                                        handshake->ecdh_psa_peerkey_len,
2815*32b31808SJens Wiklander                                        ssl->handshake->premaster,
2816*32b31808SJens Wiklander                                        sizeof(ssl->handshake->premaster),
2817*32b31808SJens Wiklander                                        &ssl->handshake->pmslen);
2818*32b31808SJens Wiklander 
2819*32b31808SJens Wiklander         destruction_status = psa_destroy_key(handshake->ecdh_psa_privkey);
2820*32b31808SJens Wiklander         handshake->ecdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
2821*32b31808SJens Wiklander 
2822*32b31808SJens Wiklander         if (status != PSA_SUCCESS || destruction_status != PSA_SUCCESS) {
2823*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
2824*32b31808SJens Wiklander         }
2825*32b31808SJens Wiklander #else
2826*32b31808SJens Wiklander         /*
2827*32b31808SJens Wiklander          * ECDH key exchange -- send client public value
2828*32b31808SJens Wiklander          */
2829*32b31808SJens Wiklander         header_len = 4;
2830*32b31808SJens Wiklander 
2831*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
2832*32b31808SJens Wiklander         if (ssl->handshake->ecrs_enabled) {
2833*32b31808SJens Wiklander             if (ssl->handshake->ecrs_state == ssl_ecrs_cke_ecdh_calc_secret) {
2834*32b31808SJens Wiklander                 goto ecdh_calc_secret;
2835*32b31808SJens Wiklander             }
2836*32b31808SJens Wiklander 
2837*32b31808SJens Wiklander             mbedtls_ecdh_enable_restart(&ssl->handshake->ecdh_ctx);
2838*32b31808SJens Wiklander         }
2839*32b31808SJens Wiklander #endif
2840*32b31808SJens Wiklander 
2841*32b31808SJens Wiklander         ret = mbedtls_ecdh_make_public(&ssl->handshake->ecdh_ctx,
2842*32b31808SJens Wiklander                                        &content_len,
2843*32b31808SJens Wiklander                                        &ssl->out_msg[header_len], 1000,
2844*32b31808SJens Wiklander                                        ssl->conf->f_rng, ssl->conf->p_rng);
2845*32b31808SJens Wiklander         if (ret != 0) {
2846*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_make_public", ret);
2847*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
2848*32b31808SJens Wiklander             if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
2849*32b31808SJens Wiklander                 ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
2850*32b31808SJens Wiklander             }
2851*32b31808SJens Wiklander #endif
2852*32b31808SJens Wiklander             return ret;
2853*32b31808SJens Wiklander         }
2854*32b31808SJens Wiklander 
2855*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
2856*32b31808SJens Wiklander                                MBEDTLS_DEBUG_ECDH_Q);
2857*32b31808SJens Wiklander 
2858*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
2859*32b31808SJens Wiklander         if (ssl->handshake->ecrs_enabled) {
2860*32b31808SJens Wiklander             ssl->handshake->ecrs_n = content_len;
2861*32b31808SJens Wiklander             ssl->handshake->ecrs_state = ssl_ecrs_cke_ecdh_calc_secret;
2862*32b31808SJens Wiklander         }
2863*32b31808SJens Wiklander 
2864*32b31808SJens Wiklander ecdh_calc_secret:
2865*32b31808SJens Wiklander         if (ssl->handshake->ecrs_enabled) {
2866*32b31808SJens Wiklander             content_len = ssl->handshake->ecrs_n;
2867*32b31808SJens Wiklander         }
2868*32b31808SJens Wiklander #endif
2869*32b31808SJens Wiklander         if ((ret = mbedtls_ecdh_calc_secret(&ssl->handshake->ecdh_ctx,
2870*32b31808SJens Wiklander                                             &ssl->handshake->pmslen,
2871*32b31808SJens Wiklander                                             ssl->handshake->premaster,
2872*32b31808SJens Wiklander                                             MBEDTLS_MPI_MAX_SIZE,
2873*32b31808SJens Wiklander                                             ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
2874*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_calc_secret", ret);
2875*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
2876*32b31808SJens Wiklander             if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
2877*32b31808SJens Wiklander                 ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
2878*32b31808SJens Wiklander             }
2879*32b31808SJens Wiklander #endif
2880*32b31808SJens Wiklander             return ret;
2881*32b31808SJens Wiklander         }
2882*32b31808SJens Wiklander 
2883*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
2884*32b31808SJens Wiklander                                MBEDTLS_DEBUG_ECDH_Z);
2885*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
2886*32b31808SJens Wiklander     } else
2887*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
2888*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
2889*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
2890*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
2891*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) &&                           \
2892*32b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
2893*32b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) {
2894*32b31808SJens Wiklander         psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2895*32b31808SJens Wiklander         psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED;
2896*32b31808SJens Wiklander         psa_key_attributes_t key_attributes;
2897*32b31808SJens Wiklander 
2898*32b31808SJens Wiklander         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
2899*32b31808SJens Wiklander 
2900*32b31808SJens Wiklander         /*
2901*32b31808SJens Wiklander          * opaque psk_identity<0..2^16-1>;
2902*32b31808SJens Wiklander          */
2903*32b31808SJens Wiklander         if (mbedtls_ssl_conf_has_static_psk(ssl->conf) == 0) {
2904*32b31808SJens Wiklander             /* We don't offer PSK suites if we don't have a PSK,
2905*32b31808SJens Wiklander              * and we check that the server's choice is among the
2906*32b31808SJens Wiklander              * ciphersuites we offered, so this should never happen. */
2907*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2908*32b31808SJens Wiklander         }
2909*32b31808SJens Wiklander 
2910*32b31808SJens Wiklander         /* uint16 to store content length */
2911*32b31808SJens Wiklander         const size_t content_len_size = 2;
2912*32b31808SJens Wiklander 
2913*32b31808SJens Wiklander         header_len = 4;
2914*32b31808SJens Wiklander 
2915*32b31808SJens Wiklander         if (header_len + content_len_size + ssl->conf->psk_identity_len
2916*32b31808SJens Wiklander             > MBEDTLS_SSL_OUT_CONTENT_LEN) {
2917*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1,
2918*32b31808SJens Wiklander                                   ("psk identity too long or SSL buffer too short"));
2919*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
2920*32b31808SJens Wiklander         }
2921*32b31808SJens Wiklander 
2922*32b31808SJens Wiklander         unsigned char *p = ssl->out_msg + header_len;
2923*32b31808SJens Wiklander 
2924*32b31808SJens Wiklander         *p++ = MBEDTLS_BYTE_1(ssl->conf->psk_identity_len);
2925*32b31808SJens Wiklander         *p++ = MBEDTLS_BYTE_0(ssl->conf->psk_identity_len);
2926*32b31808SJens Wiklander         header_len += content_len_size;
2927*32b31808SJens Wiklander 
2928*32b31808SJens Wiklander         memcpy(p, ssl->conf->psk_identity,
2929*32b31808SJens Wiklander                ssl->conf->psk_identity_len);
2930*32b31808SJens Wiklander         p += ssl->conf->psk_identity_len;
2931*32b31808SJens Wiklander 
2932*32b31808SJens Wiklander         header_len += ssl->conf->psk_identity_len;
2933*32b31808SJens Wiklander 
2934*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("Perform PSA-based ECDH computation."));
2935*32b31808SJens Wiklander 
2936*32b31808SJens Wiklander         /*
2937*32b31808SJens Wiklander          * Generate EC private key for ECDHE exchange.
2938*32b31808SJens Wiklander          */
2939*32b31808SJens Wiklander 
2940*32b31808SJens Wiklander         /* The master secret is obtained from the shared ECDH secret by
2941*32b31808SJens Wiklander          * applying the TLS 1.2 PRF with a specific salt and label. While
2942*32b31808SJens Wiklander          * the PSA Crypto API encourages combining key agreement schemes
2943*32b31808SJens Wiklander          * such as ECDH with fixed KDFs such as TLS 1.2 PRF, it does not
2944*32b31808SJens Wiklander          * yet support the provisioning of salt + label to the KDF.
2945*32b31808SJens Wiklander          * For the time being, we therefore need to split the computation
2946*32b31808SJens Wiklander          * of the ECDH secret and the application of the TLS 1.2 PRF. */
2947*32b31808SJens Wiklander         key_attributes = psa_key_attributes_init();
2948*32b31808SJens Wiklander         psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
2949*32b31808SJens Wiklander         psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
2950*32b31808SJens Wiklander         psa_set_key_type(&key_attributes, handshake->ecdh_psa_type);
2951*32b31808SJens Wiklander         psa_set_key_bits(&key_attributes, handshake->ecdh_bits);
2952*32b31808SJens Wiklander 
2953*32b31808SJens Wiklander         /* Generate ECDH private key. */
2954*32b31808SJens Wiklander         status = psa_generate_key(&key_attributes,
2955*32b31808SJens Wiklander                                   &handshake->ecdh_psa_privkey);
2956*32b31808SJens Wiklander         if (status != PSA_SUCCESS) {
2957*32b31808SJens Wiklander             return PSA_TO_MBEDTLS_ERR(status);
2958*32b31808SJens Wiklander         }
2959*32b31808SJens Wiklander 
2960*32b31808SJens Wiklander         /* Export the public part of the ECDH private key from PSA.
2961*32b31808SJens Wiklander          * The export format is an ECPoint structure as expected by TLS,
2962*32b31808SJens Wiklander          * but we just need to add a length byte before that. */
2963*32b31808SJens Wiklander         unsigned char *own_pubkey = p + 1;
2964*32b31808SJens Wiklander         unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
2965*32b31808SJens Wiklander         size_t own_pubkey_max_len = (size_t) (end - own_pubkey);
2966*32b31808SJens Wiklander         size_t own_pubkey_len = 0;
2967*32b31808SJens Wiklander 
2968*32b31808SJens Wiklander         status = psa_export_public_key(handshake->ecdh_psa_privkey,
2969*32b31808SJens Wiklander                                        own_pubkey, own_pubkey_max_len,
2970*32b31808SJens Wiklander                                        &own_pubkey_len);
2971*32b31808SJens Wiklander         if (status != PSA_SUCCESS) {
2972*32b31808SJens Wiklander             psa_destroy_key(handshake->ecdh_psa_privkey);
2973*32b31808SJens Wiklander             handshake->ecdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
2974*32b31808SJens Wiklander             return PSA_TO_MBEDTLS_ERR(status);
2975*32b31808SJens Wiklander         }
2976*32b31808SJens Wiklander 
2977*32b31808SJens Wiklander         *p = (unsigned char) own_pubkey_len;
2978*32b31808SJens Wiklander         content_len = own_pubkey_len + 1;
2979*32b31808SJens Wiklander 
2980*32b31808SJens Wiklander         /* As RFC 5489 section 2, the premaster secret is formed as follows:
2981*32b31808SJens Wiklander          * - a uint16 containing the length (in octets) of the ECDH computation
2982*32b31808SJens Wiklander          * - the octet string produced by the ECDH computation
2983*32b31808SJens Wiklander          * - a uint16 containing the length (in octets) of the PSK
2984*32b31808SJens Wiklander          * - the PSK itself
2985*32b31808SJens Wiklander          */
2986*32b31808SJens Wiklander         unsigned char *pms = ssl->handshake->premaster;
2987*32b31808SJens Wiklander         const unsigned char * const pms_end = pms +
2988*32b31808SJens Wiklander                                               sizeof(ssl->handshake->premaster);
2989*32b31808SJens Wiklander         /* uint16 to store length (in octets) of the ECDH computation */
2990*32b31808SJens Wiklander         const size_t zlen_size = 2;
2991*32b31808SJens Wiklander         size_t zlen = 0;
2992*32b31808SJens Wiklander 
2993*32b31808SJens Wiklander         /* Perform ECDH computation after the uint16 reserved for the length */
2994*32b31808SJens Wiklander         status = psa_raw_key_agreement(PSA_ALG_ECDH,
2995*32b31808SJens Wiklander                                        handshake->ecdh_psa_privkey,
2996*32b31808SJens Wiklander                                        handshake->ecdh_psa_peerkey,
2997*32b31808SJens Wiklander                                        handshake->ecdh_psa_peerkey_len,
2998*32b31808SJens Wiklander                                        pms + zlen_size,
2999*32b31808SJens Wiklander                                        pms_end - (pms + zlen_size),
3000*32b31808SJens Wiklander                                        &zlen);
3001*32b31808SJens Wiklander 
3002*32b31808SJens Wiklander         destruction_status = psa_destroy_key(handshake->ecdh_psa_privkey);
3003*32b31808SJens Wiklander         handshake->ecdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
3004*32b31808SJens Wiklander 
3005*32b31808SJens Wiklander         if (status != PSA_SUCCESS) {
3006*32b31808SJens Wiklander             return PSA_TO_MBEDTLS_ERR(status);
3007*32b31808SJens Wiklander         } else if (destruction_status != PSA_SUCCESS) {
3008*32b31808SJens Wiklander             return PSA_TO_MBEDTLS_ERR(destruction_status);
3009*32b31808SJens Wiklander         }
3010*32b31808SJens Wiklander 
3011*32b31808SJens Wiklander         /* Write the ECDH computation length before the ECDH computation */
3012*32b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(zlen, pms, 0);
3013*32b31808SJens Wiklander         pms += zlen_size + zlen;
3014*32b31808SJens Wiklander     } else
3015*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO &&
3016*32b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
3017*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
3018*32b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_uses_psk(ciphersuite_info)) {
3019*32b31808SJens Wiklander         /*
3020*32b31808SJens Wiklander          * opaque psk_identity<0..2^16-1>;
3021*32b31808SJens Wiklander          */
3022*32b31808SJens Wiklander         if (mbedtls_ssl_conf_has_static_psk(ssl->conf) == 0) {
3023*32b31808SJens Wiklander             /* We don't offer PSK suites if we don't have a PSK,
3024*32b31808SJens Wiklander              * and we check that the server's choice is among the
3025*32b31808SJens Wiklander              * ciphersuites we offered, so this should never happen. */
3026*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
3027*32b31808SJens Wiklander         }
3028*32b31808SJens Wiklander 
3029*32b31808SJens Wiklander         header_len = 4;
3030*32b31808SJens Wiklander         content_len = ssl->conf->psk_identity_len;
3031*32b31808SJens Wiklander 
3032*32b31808SJens Wiklander         if (header_len + 2 + content_len > MBEDTLS_SSL_OUT_CONTENT_LEN) {
3033*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1,
3034*32b31808SJens Wiklander                                   ("psk identity too long or SSL buffer too short"));
3035*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
3036*32b31808SJens Wiklander         }
3037*32b31808SJens Wiklander 
3038*32b31808SJens Wiklander         ssl->out_msg[header_len++] = MBEDTLS_BYTE_1(content_len);
3039*32b31808SJens Wiklander         ssl->out_msg[header_len++] = MBEDTLS_BYTE_0(content_len);
3040*32b31808SJens Wiklander 
3041*32b31808SJens Wiklander         memcpy(ssl->out_msg + header_len,
3042*32b31808SJens Wiklander                ssl->conf->psk_identity,
3043*32b31808SJens Wiklander                ssl->conf->psk_identity_len);
3044*32b31808SJens Wiklander         header_len += ssl->conf->psk_identity_len;
3045*32b31808SJens Wiklander 
3046*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
3047*32b31808SJens Wiklander         if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK) {
3048*32b31808SJens Wiklander             content_len = 0;
3049*32b31808SJens Wiklander         } else
3050*32b31808SJens Wiklander #endif
3051*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
3052*32b31808SJens Wiklander         if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) {
3053*32b31808SJens Wiklander             if ((ret = ssl_write_encrypted_pms(ssl, header_len,
3054*32b31808SJens Wiklander                                                &content_len, 2)) != 0) {
3055*32b31808SJens Wiklander                 return ret;
3056*32b31808SJens Wiklander             }
3057*32b31808SJens Wiklander         } else
3058*32b31808SJens Wiklander #endif
3059*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
3060*32b31808SJens Wiklander         if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK) {
3061*32b31808SJens Wiklander             /*
3062*32b31808SJens Wiklander              * ClientDiffieHellmanPublic public (DHM send G^X mod P)
3063*32b31808SJens Wiklander              */
3064*32b31808SJens Wiklander             content_len = mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx);
3065*32b31808SJens Wiklander 
3066*32b31808SJens Wiklander             if (header_len + 2 + content_len >
3067*32b31808SJens Wiklander                 MBEDTLS_SSL_OUT_CONTENT_LEN) {
3068*32b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1,
3069*32b31808SJens Wiklander                                       ("psk identity or DHM size too long or SSL buffer too short"));
3070*32b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
3071*32b31808SJens Wiklander             }
3072*32b31808SJens Wiklander 
3073*32b31808SJens Wiklander             ssl->out_msg[header_len++] = MBEDTLS_BYTE_1(content_len);
3074*32b31808SJens Wiklander             ssl->out_msg[header_len++] = MBEDTLS_BYTE_0(content_len);
3075*32b31808SJens Wiklander 
3076*32b31808SJens Wiklander             ret = mbedtls_dhm_make_public(&ssl->handshake->dhm_ctx,
3077*32b31808SJens Wiklander                                           (int) mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx),
3078*32b31808SJens Wiklander                                           &ssl->out_msg[header_len], content_len,
3079*32b31808SJens Wiklander                                           ssl->conf->f_rng, ssl->conf->p_rng);
3080*32b31808SJens Wiklander             if (ret != 0) {
3081*32b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_make_public", ret);
3082*32b31808SJens Wiklander                 return ret;
3083*32b31808SJens Wiklander             }
3084*32b31808SJens Wiklander 
3085*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
3086*32b31808SJens Wiklander             unsigned char *pms = ssl->handshake->premaster;
3087*32b31808SJens Wiklander             unsigned char *pms_end = pms + sizeof(ssl->handshake->premaster);
3088*32b31808SJens Wiklander             size_t pms_len;
3089*32b31808SJens Wiklander 
3090*32b31808SJens Wiklander             /* Write length only when we know the actual value */
3091*32b31808SJens Wiklander             if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx,
3092*32b31808SJens Wiklander                                                pms + 2, pms_end - (pms + 2), &pms_len,
3093*32b31808SJens Wiklander                                                ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
3094*32b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret);
3095*32b31808SJens Wiklander                 return ret;
3096*32b31808SJens Wiklander             }
3097*32b31808SJens Wiklander             MBEDTLS_PUT_UINT16_BE(pms_len, pms, 0);
3098*32b31808SJens Wiklander             pms += 2 + pms_len;
3099*32b31808SJens Wiklander 
3100*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K);
3101*32b31808SJens Wiklander #endif
3102*32b31808SJens Wiklander         } else
3103*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
3104*32b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO) &&                             \
3105*32b31808SJens Wiklander         defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
3106*32b31808SJens Wiklander         if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) {
3107*32b31808SJens Wiklander             /*
3108*32b31808SJens Wiklander              * ClientECDiffieHellmanPublic public;
3109*32b31808SJens Wiklander              */
3110*32b31808SJens Wiklander             ret = mbedtls_ecdh_make_public(&ssl->handshake->ecdh_ctx,
3111*32b31808SJens Wiklander                                            &content_len,
3112*32b31808SJens Wiklander                                            &ssl->out_msg[header_len],
3113*32b31808SJens Wiklander                                            MBEDTLS_SSL_OUT_CONTENT_LEN - header_len,
3114*32b31808SJens Wiklander                                            ssl->conf->f_rng, ssl->conf->p_rng);
3115*32b31808SJens Wiklander             if (ret != 0) {
3116*32b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_make_public", ret);
3117*32b31808SJens Wiklander                 return ret;
3118*32b31808SJens Wiklander             }
3119*32b31808SJens Wiklander 
3120*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
3121*32b31808SJens Wiklander                                    MBEDTLS_DEBUG_ECDH_Q);
3122*32b31808SJens Wiklander         } else
3123*32b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
3124*32b31808SJens Wiklander         {
3125*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
3126*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
3127*32b31808SJens Wiklander         }
3128*32b31808SJens Wiklander 
3129*32b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO)
3130*32b31808SJens Wiklander         if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
3131*32b31808SJens Wiklander                                                     ciphersuite_info->key_exchange)) != 0) {
3132*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1,
3133*32b31808SJens Wiklander                                   "mbedtls_ssl_psk_derive_premaster", ret);
3134*32b31808SJens Wiklander             return ret;
3135*32b31808SJens Wiklander         }
3136*32b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO */
3137*32b31808SJens Wiklander     } else
3138*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
3139*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
3140*32b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) {
3141*32b31808SJens Wiklander         header_len = 4;
3142*32b31808SJens Wiklander         if ((ret = ssl_write_encrypted_pms(ssl, header_len,
3143*32b31808SJens Wiklander                                            &content_len, 0)) != 0) {
3144*32b31808SJens Wiklander             return ret;
3145*32b31808SJens Wiklander         }
3146*32b31808SJens Wiklander     } else
3147*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
3148*32b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
3149*32b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
3150*32b31808SJens Wiklander         header_len = 4;
3151*32b31808SJens Wiklander 
3152*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
3153*32b31808SJens Wiklander         unsigned char *out_p = ssl->out_msg + header_len;
3154*32b31808SJens Wiklander         unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN -
3155*32b31808SJens Wiklander                                header_len;
3156*32b31808SJens Wiklander         ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx,
3157*32b31808SJens Wiklander                                               out_p, end_p - out_p, &content_len,
3158*32b31808SJens Wiklander                                               MBEDTLS_ECJPAKE_ROUND_TWO);
3159*32b31808SJens Wiklander         if (ret != 0) {
3160*32b31808SJens Wiklander             psa_destroy_key(ssl->handshake->psa_pake_password);
3161*32b31808SJens Wiklander             psa_pake_abort(&ssl->handshake->psa_pake_ctx);
3162*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret);
3163*32b31808SJens Wiklander             return ret;
3164*32b31808SJens Wiklander         }
3165*32b31808SJens Wiklander #else
3166*32b31808SJens Wiklander         ret = mbedtls_ecjpake_write_round_two(&ssl->handshake->ecjpake_ctx,
3167*32b31808SJens Wiklander                                               ssl->out_msg + header_len,
3168*32b31808SJens Wiklander                                               MBEDTLS_SSL_OUT_CONTENT_LEN - header_len,
3169*32b31808SJens Wiklander                                               &content_len,
3170*32b31808SJens Wiklander                                               ssl->conf->f_rng, ssl->conf->p_rng);
3171*32b31808SJens Wiklander         if (ret != 0) {
3172*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_two", ret);
3173*32b31808SJens Wiklander             return ret;
3174*32b31808SJens Wiklander         }
3175*32b31808SJens Wiklander 
3176*32b31808SJens Wiklander         ret = mbedtls_ecjpake_derive_secret(&ssl->handshake->ecjpake_ctx,
3177*32b31808SJens Wiklander                                             ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
3178*32b31808SJens Wiklander                                             ssl->conf->f_rng, ssl->conf->p_rng);
3179*32b31808SJens Wiklander         if (ret != 0) {
3180*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_derive_secret", ret);
3181*32b31808SJens Wiklander             return ret;
3182*32b31808SJens Wiklander         }
3183*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
3184*32b31808SJens Wiklander     } else
3185*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
3186*32b31808SJens Wiklander     {
3187*32b31808SJens Wiklander         ((void) ciphersuite_info);
3188*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
3189*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
3190*32b31808SJens Wiklander     }
3191*32b31808SJens Wiklander 
3192*32b31808SJens Wiklander     ssl->out_msglen  = header_len + content_len;
3193*32b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
3194*32b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE;
3195*32b31808SJens Wiklander 
3196*32b31808SJens Wiklander     ssl->state++;
3197*32b31808SJens Wiklander 
3198*32b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
3199*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
3200*32b31808SJens Wiklander         return ret;
3201*32b31808SJens Wiklander     }
3202*32b31808SJens Wiklander 
3203*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write client key exchange"));
3204*32b31808SJens Wiklander 
3205*32b31808SJens Wiklander     return 0;
3206*32b31808SJens Wiklander }
3207*32b31808SJens Wiklander 
3208*32b31808SJens Wiklander #if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
3209*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
3210*32b31808SJens Wiklander static int ssl_write_certificate_verify(mbedtls_ssl_context *ssl)
3211*32b31808SJens Wiklander {
3212*32b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
3213*32b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
3214*32b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3215*32b31808SJens Wiklander 
3216*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate verify"));
3217*32b31808SJens Wiklander 
3218*32b31808SJens Wiklander     if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) {
3219*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret);
3220*32b31808SJens Wiklander         return ret;
3221*32b31808SJens Wiklander     }
3222*32b31808SJens Wiklander 
3223*32b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
3224*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify"));
3225*32b31808SJens Wiklander         ssl->state++;
3226*32b31808SJens Wiklander         return 0;
3227*32b31808SJens Wiklander     }
3228*32b31808SJens Wiklander 
3229*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
3230*32b31808SJens Wiklander     return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
3231*32b31808SJens Wiklander }
3232*32b31808SJens Wiklander #else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
3233*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
3234*32b31808SJens Wiklander static int ssl_write_certificate_verify(mbedtls_ssl_context *ssl)
3235*32b31808SJens Wiklander {
3236*32b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
3237*32b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
3238*32b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
3239*32b31808SJens Wiklander     size_t n = 0, offset = 0;
3240*32b31808SJens Wiklander     unsigned char hash[48];
3241*32b31808SJens Wiklander     unsigned char *hash_start = hash;
3242*32b31808SJens Wiklander     mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
3243*32b31808SJens Wiklander     size_t hashlen;
3244*32b31808SJens Wiklander     void *rs_ctx = NULL;
3245*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
3246*32b31808SJens Wiklander     size_t out_buf_len = ssl->out_buf_len - (ssl->out_msg - ssl->out_buf);
3247*32b31808SJens Wiklander #else
3248*32b31808SJens Wiklander     size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - (ssl->out_msg - ssl->out_buf);
3249*32b31808SJens Wiklander #endif
3250*32b31808SJens Wiklander 
3251*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate verify"));
3252*32b31808SJens Wiklander 
3253*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
3254*32b31808SJens Wiklander     if (ssl->handshake->ecrs_enabled &&
3255*32b31808SJens Wiklander         ssl->handshake->ecrs_state == ssl_ecrs_crt_vrfy_sign) {
3256*32b31808SJens Wiklander         goto sign;
3257*32b31808SJens Wiklander     }
3258*32b31808SJens Wiklander #endif
3259*32b31808SJens Wiklander 
3260*32b31808SJens Wiklander     if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) {
3261*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret);
3262*32b31808SJens Wiklander         return ret;
3263*32b31808SJens Wiklander     }
3264*32b31808SJens Wiklander 
3265*32b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
3266*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify"));
3267*32b31808SJens Wiklander         ssl->state++;
3268*32b31808SJens Wiklander         return 0;
3269*32b31808SJens Wiklander     }
3270*32b31808SJens Wiklander 
3271*32b31808SJens Wiklander     if (ssl->handshake->client_auth == 0 ||
3272*32b31808SJens Wiklander         mbedtls_ssl_own_cert(ssl) == NULL) {
3273*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify"));
3274*32b31808SJens Wiklander         ssl->state++;
3275*32b31808SJens Wiklander         return 0;
3276*32b31808SJens Wiklander     }
3277*32b31808SJens Wiklander 
3278*32b31808SJens Wiklander     if (mbedtls_ssl_own_key(ssl) == NULL) {
3279*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got no private key for certificate"));
3280*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED;
3281*32b31808SJens Wiklander     }
3282*32b31808SJens Wiklander 
3283*32b31808SJens Wiklander     /*
3284*32b31808SJens Wiklander      * Make a signature of the handshake digests
3285*32b31808SJens Wiklander      */
3286*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
3287*32b31808SJens Wiklander     if (ssl->handshake->ecrs_enabled) {
3288*32b31808SJens Wiklander         ssl->handshake->ecrs_state = ssl_ecrs_crt_vrfy_sign;
3289*32b31808SJens Wiklander     }
3290*32b31808SJens Wiklander 
3291*32b31808SJens Wiklander sign:
3292*32b31808SJens Wiklander #endif
3293*32b31808SJens Wiklander 
3294*32b31808SJens Wiklander     ret = ssl->handshake->calc_verify(ssl, hash, &hashlen);
3295*32b31808SJens Wiklander     if (0 != ret) {
3296*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("calc_verify"), ret);
3297*32b31808SJens Wiklander         return ret;
3298*32b31808SJens Wiklander     }
3299*32b31808SJens Wiklander 
3300*32b31808SJens Wiklander     /*
3301*32b31808SJens Wiklander      * digitally-signed struct {
3302*32b31808SJens Wiklander      *     opaque handshake_messages[handshake_messages_length];
3303*32b31808SJens Wiklander      * };
3304*32b31808SJens Wiklander      *
3305*32b31808SJens Wiklander      * Taking shortcut here. We assume that the server always allows the
3306*32b31808SJens Wiklander      * PRF Hash function and has sent it in the allowed signature
3307*32b31808SJens Wiklander      * algorithms list received in the Certificate Request message.
3308*32b31808SJens Wiklander      *
3309*32b31808SJens Wiklander      * Until we encounter a server that does not, we will take this
3310*32b31808SJens Wiklander      * shortcut.
3311*32b31808SJens Wiklander      *
3312*32b31808SJens Wiklander      * Reason: Otherwise we should have running hashes for SHA512 and
3313*32b31808SJens Wiklander      *         SHA224 in order to satisfy 'weird' needs from the server
3314*32b31808SJens Wiklander      *         side.
3315*32b31808SJens Wiklander      */
3316*32b31808SJens Wiklander     if (ssl->handshake->ciphersuite_info->mac == MBEDTLS_MD_SHA384) {
3317*32b31808SJens Wiklander         md_alg = MBEDTLS_MD_SHA384;
3318*32b31808SJens Wiklander         ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384;
3319*32b31808SJens Wiklander     } else {
3320*32b31808SJens Wiklander         md_alg = MBEDTLS_MD_SHA256;
3321*32b31808SJens Wiklander         ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA256;
3322*32b31808SJens Wiklander     }
3323*32b31808SJens Wiklander     ssl->out_msg[5] = mbedtls_ssl_sig_from_pk(mbedtls_ssl_own_key(ssl));
3324*32b31808SJens Wiklander 
3325*32b31808SJens Wiklander     /* Info from md_alg will be used instead */
3326*32b31808SJens Wiklander     hashlen = 0;
3327*32b31808SJens Wiklander     offset = 2;
3328*32b31808SJens Wiklander 
3329*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
3330*32b31808SJens Wiklander     if (ssl->handshake->ecrs_enabled) {
3331*32b31808SJens Wiklander         rs_ctx = &ssl->handshake->ecrs_ctx.pk;
3332*32b31808SJens Wiklander     }
3333*32b31808SJens Wiklander #endif
3334*32b31808SJens Wiklander 
3335*32b31808SJens Wiklander     if ((ret = mbedtls_pk_sign_restartable(mbedtls_ssl_own_key(ssl),
3336*32b31808SJens Wiklander                                            md_alg, hash_start, hashlen,
3337*32b31808SJens Wiklander                                            ssl->out_msg + 6 + offset,
3338*32b31808SJens Wiklander                                            out_buf_len - 6 - offset,
3339*32b31808SJens Wiklander                                            &n,
3340*32b31808SJens Wiklander                                            ssl->conf->f_rng, ssl->conf->p_rng, rs_ctx)) != 0) {
3341*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_sign", ret);
3342*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
3343*32b31808SJens Wiklander         if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
3344*32b31808SJens Wiklander             ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
3345*32b31808SJens Wiklander         }
3346*32b31808SJens Wiklander #endif
3347*32b31808SJens Wiklander         return ret;
3348*32b31808SJens Wiklander     }
3349*32b31808SJens Wiklander 
3350*32b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(n, ssl->out_msg, offset + 4);
3351*32b31808SJens Wiklander 
3352*32b31808SJens Wiklander     ssl->out_msglen  = 6 + n + offset;
3353*32b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
3354*32b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY;
3355*32b31808SJens Wiklander 
3356*32b31808SJens Wiklander     ssl->state++;
3357*32b31808SJens Wiklander 
3358*32b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
3359*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
3360*32b31808SJens Wiklander         return ret;
3361*32b31808SJens Wiklander     }
3362*32b31808SJens Wiklander 
3363*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write certificate verify"));
3364*32b31808SJens Wiklander 
3365*32b31808SJens Wiklander     return ret;
3366*32b31808SJens Wiklander }
3367*32b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
3368*32b31808SJens Wiklander 
3369*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
3370*32b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
3371*32b31808SJens Wiklander static int ssl_parse_new_session_ticket(mbedtls_ssl_context *ssl)
3372*32b31808SJens Wiklander {
3373*32b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3374*32b31808SJens Wiklander     uint32_t lifetime;
3375*32b31808SJens Wiklander     size_t ticket_len;
3376*32b31808SJens Wiklander     unsigned char *ticket;
3377*32b31808SJens Wiklander     const unsigned char *msg;
3378*32b31808SJens Wiklander 
3379*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse new session ticket"));
3380*32b31808SJens Wiklander 
3381*32b31808SJens Wiklander     if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
3382*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
3383*32b31808SJens Wiklander         return ret;
3384*32b31808SJens Wiklander     }
3385*32b31808SJens Wiklander 
3386*32b31808SJens Wiklander     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
3387*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad new session ticket message"));
3388*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
3389*32b31808SJens Wiklander             ssl,
3390*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
3391*32b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE);
3392*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
3393*32b31808SJens Wiklander     }
3394*32b31808SJens Wiklander 
3395*32b31808SJens Wiklander     /*
3396*32b31808SJens Wiklander      * struct {
3397*32b31808SJens Wiklander      *     uint32 ticket_lifetime_hint;
3398*32b31808SJens Wiklander      *     opaque ticket<0..2^16-1>;
3399*32b31808SJens Wiklander      * } NewSessionTicket;
3400*32b31808SJens Wiklander      *
3401*32b31808SJens Wiklander      * 0  .  3   ticket_lifetime_hint
3402*32b31808SJens Wiklander      * 4  .  5   ticket_len (n)
3403*32b31808SJens Wiklander      * 6  .  5+n ticket content
3404*32b31808SJens Wiklander      */
3405*32b31808SJens Wiklander     if (ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET ||
3406*32b31808SJens Wiklander         ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len(ssl)) {
3407*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad new session ticket message"));
3408*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
3409*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
3410*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
3411*32b31808SJens Wiklander     }
3412*32b31808SJens Wiklander 
3413*32b31808SJens Wiklander     msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl);
3414*32b31808SJens Wiklander 
3415*32b31808SJens Wiklander     lifetime = (((uint32_t) msg[0]) << 24) | (msg[1] << 16) |
3416*32b31808SJens Wiklander                (msg[2] << 8) | (msg[3]);
3417*32b31808SJens Wiklander 
3418*32b31808SJens Wiklander     ticket_len = (msg[4] << 8) | (msg[5]);
3419*32b31808SJens Wiklander 
3420*32b31808SJens Wiklander     if (ticket_len + 6 + mbedtls_ssl_hs_hdr_len(ssl) != ssl->in_hslen) {
3421*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad new session ticket message"));
3422*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
3423*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
3424*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
3425*32b31808SJens Wiklander     }
3426*32b31808SJens Wiklander 
3427*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("ticket length: %" MBEDTLS_PRINTF_SIZET, ticket_len));
3428*32b31808SJens Wiklander 
3429*32b31808SJens Wiklander     /* We're not waiting for a NewSessionTicket message any more */
3430*32b31808SJens Wiklander     ssl->handshake->new_session_ticket = 0;
3431*32b31808SJens Wiklander     ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
3432*32b31808SJens Wiklander 
3433*32b31808SJens Wiklander     /*
3434*32b31808SJens Wiklander      * Zero-length ticket means the server changed his mind and doesn't want
3435*32b31808SJens Wiklander      * to send a ticket after all, so just forget it
3436*32b31808SJens Wiklander      */
3437*32b31808SJens Wiklander     if (ticket_len == 0) {
3438*32b31808SJens Wiklander         return 0;
3439*32b31808SJens Wiklander     }
3440*32b31808SJens Wiklander 
3441*32b31808SJens Wiklander     if (ssl->session != NULL && ssl->session->ticket != NULL) {
3442*32b31808SJens Wiklander         mbedtls_platform_zeroize(ssl->session->ticket,
3443*32b31808SJens Wiklander                                  ssl->session->ticket_len);
3444*32b31808SJens Wiklander         mbedtls_free(ssl->session->ticket);
3445*32b31808SJens Wiklander         ssl->session->ticket = NULL;
3446*32b31808SJens Wiklander         ssl->session->ticket_len = 0;
3447*32b31808SJens Wiklander     }
3448*32b31808SJens Wiklander 
3449*32b31808SJens Wiklander     mbedtls_platform_zeroize(ssl->session_negotiate->ticket,
3450*32b31808SJens Wiklander                              ssl->session_negotiate->ticket_len);
3451*32b31808SJens Wiklander     mbedtls_free(ssl->session_negotiate->ticket);
3452*32b31808SJens Wiklander     ssl->session_negotiate->ticket = NULL;
3453*32b31808SJens Wiklander     ssl->session_negotiate->ticket_len = 0;
3454*32b31808SJens Wiklander 
3455*32b31808SJens Wiklander     if ((ticket = mbedtls_calloc(1, ticket_len)) == NULL) {
3456*32b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("ticket alloc failed"));
3457*32b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
3458*32b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
3459*32b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ALLOC_FAILED;
3460*32b31808SJens Wiklander     }
3461*32b31808SJens Wiklander 
3462*32b31808SJens Wiklander     memcpy(ticket, msg + 6, ticket_len);
3463*32b31808SJens Wiklander 
3464*32b31808SJens Wiklander     ssl->session_negotiate->ticket = ticket;
3465*32b31808SJens Wiklander     ssl->session_negotiate->ticket_len = ticket_len;
3466*32b31808SJens Wiklander     ssl->session_negotiate->ticket_lifetime = lifetime;
3467*32b31808SJens Wiklander 
3468*32b31808SJens Wiklander     /*
3469*32b31808SJens Wiklander      * RFC 5077 section 3.4:
3470*32b31808SJens Wiklander      * "If the client receives a session ticket from the server, then it
3471*32b31808SJens Wiklander      * discards any Session ID that was sent in the ServerHello."
3472*32b31808SJens Wiklander      */
3473*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("ticket in use, discarding session id"));
3474*32b31808SJens Wiklander     ssl->session_negotiate->id_len = 0;
3475*32b31808SJens Wiklander 
3476*32b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse new session ticket"));
3477*32b31808SJens Wiklander 
3478*32b31808SJens Wiklander     return 0;
3479*32b31808SJens Wiklander }
3480*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
3481*32b31808SJens Wiklander 
3482*32b31808SJens Wiklander /*
3483*32b31808SJens Wiklander  * SSL handshake -- client side -- single step
3484*32b31808SJens Wiklander  */
3485*32b31808SJens Wiklander int mbedtls_ssl_handshake_client_step(mbedtls_ssl_context *ssl)
3486*32b31808SJens Wiklander {
3487*32b31808SJens Wiklander     int ret = 0;
3488*32b31808SJens Wiklander 
3489*32b31808SJens Wiklander     /* Change state now, so that it is right in mbedtls_ssl_read_record(), used
3490*32b31808SJens Wiklander      * by DTLS for dropping out-of-sequence ChangeCipherSpec records */
3491*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
3492*32b31808SJens Wiklander     if (ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC &&
3493*32b31808SJens Wiklander         ssl->handshake->new_session_ticket != 0) {
3494*32b31808SJens Wiklander         ssl->state = MBEDTLS_SSL_NEW_SESSION_TICKET;
3495*32b31808SJens Wiklander     }
3496*32b31808SJens Wiklander #endif
3497*32b31808SJens Wiklander 
3498*32b31808SJens Wiklander     switch (ssl->state) {
3499*32b31808SJens Wiklander         case MBEDTLS_SSL_HELLO_REQUEST:
3500*32b31808SJens Wiklander             ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
3501*32b31808SJens Wiklander             break;
3502*32b31808SJens Wiklander 
3503*32b31808SJens Wiklander         /*
3504*32b31808SJens Wiklander          *  ==>   ClientHello
3505*32b31808SJens Wiklander          */
3506*32b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_HELLO:
3507*32b31808SJens Wiklander             ret = mbedtls_ssl_write_client_hello(ssl);
3508*32b31808SJens Wiklander             break;
3509*32b31808SJens Wiklander 
3510*32b31808SJens Wiklander         /*
3511*32b31808SJens Wiklander          *  <==   ServerHello
3512*32b31808SJens Wiklander          *        Certificate
3513*32b31808SJens Wiklander          *      ( ServerKeyExchange  )
3514*32b31808SJens Wiklander          *      ( CertificateRequest )
3515*32b31808SJens Wiklander          *        ServerHelloDone
3516*32b31808SJens Wiklander          */
3517*32b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_HELLO:
3518*32b31808SJens Wiklander             ret = ssl_parse_server_hello(ssl);
3519*32b31808SJens Wiklander             break;
3520*32b31808SJens Wiklander 
3521*32b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_CERTIFICATE:
3522*32b31808SJens Wiklander             ret = mbedtls_ssl_parse_certificate(ssl);
3523*32b31808SJens Wiklander             break;
3524*32b31808SJens Wiklander 
3525*32b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
3526*32b31808SJens Wiklander             ret = ssl_parse_server_key_exchange(ssl);
3527*32b31808SJens Wiklander             break;
3528*32b31808SJens Wiklander 
3529*32b31808SJens Wiklander         case MBEDTLS_SSL_CERTIFICATE_REQUEST:
3530*32b31808SJens Wiklander             ret = ssl_parse_certificate_request(ssl);
3531*32b31808SJens Wiklander             break;
3532*32b31808SJens Wiklander 
3533*32b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_HELLO_DONE:
3534*32b31808SJens Wiklander             ret = ssl_parse_server_hello_done(ssl);
3535*32b31808SJens Wiklander             break;
3536*32b31808SJens Wiklander 
3537*32b31808SJens Wiklander         /*
3538*32b31808SJens Wiklander          *  ==> ( Certificate/Alert  )
3539*32b31808SJens Wiklander          *        ClientKeyExchange
3540*32b31808SJens Wiklander          *      ( CertificateVerify  )
3541*32b31808SJens Wiklander          *        ChangeCipherSpec
3542*32b31808SJens Wiklander          *        Finished
3543*32b31808SJens Wiklander          */
3544*32b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_CERTIFICATE:
3545*32b31808SJens Wiklander             ret = mbedtls_ssl_write_certificate(ssl);
3546*32b31808SJens Wiklander             break;
3547*32b31808SJens Wiklander 
3548*32b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
3549*32b31808SJens Wiklander             ret = ssl_write_client_key_exchange(ssl);
3550*32b31808SJens Wiklander             break;
3551*32b31808SJens Wiklander 
3552*32b31808SJens Wiklander         case MBEDTLS_SSL_CERTIFICATE_VERIFY:
3553*32b31808SJens Wiklander             ret = ssl_write_certificate_verify(ssl);
3554*32b31808SJens Wiklander             break;
3555*32b31808SJens Wiklander 
3556*32b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
3557*32b31808SJens Wiklander             ret = mbedtls_ssl_write_change_cipher_spec(ssl);
3558*32b31808SJens Wiklander             break;
3559*32b31808SJens Wiklander 
3560*32b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_FINISHED:
3561*32b31808SJens Wiklander             ret = mbedtls_ssl_write_finished(ssl);
3562*32b31808SJens Wiklander             break;
3563*32b31808SJens Wiklander 
3564*32b31808SJens Wiklander             /*
3565*32b31808SJens Wiklander              *  <==   ( NewSessionTicket )
3566*32b31808SJens Wiklander              *        ChangeCipherSpec
3567*32b31808SJens Wiklander              *        Finished
3568*32b31808SJens Wiklander              */
3569*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
3570*32b31808SJens Wiklander         case MBEDTLS_SSL_NEW_SESSION_TICKET:
3571*32b31808SJens Wiklander             ret = ssl_parse_new_session_ticket(ssl);
3572*32b31808SJens Wiklander             break;
3573*32b31808SJens Wiklander #endif
3574*32b31808SJens Wiklander 
3575*32b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
3576*32b31808SJens Wiklander             ret = mbedtls_ssl_parse_change_cipher_spec(ssl);
3577*32b31808SJens Wiklander             break;
3578*32b31808SJens Wiklander 
3579*32b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_FINISHED:
3580*32b31808SJens Wiklander             ret = mbedtls_ssl_parse_finished(ssl);
3581*32b31808SJens Wiklander             break;
3582*32b31808SJens Wiklander 
3583*32b31808SJens Wiklander         case MBEDTLS_SSL_FLUSH_BUFFERS:
3584*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done"));
3585*32b31808SJens Wiklander             ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
3586*32b31808SJens Wiklander             break;
3587*32b31808SJens Wiklander 
3588*32b31808SJens Wiklander         case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
3589*32b31808SJens Wiklander             mbedtls_ssl_handshake_wrapup(ssl);
3590*32b31808SJens Wiklander             break;
3591*32b31808SJens Wiklander 
3592*32b31808SJens Wiklander         default:
3593*32b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("invalid state %d", ssl->state));
3594*32b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
3595*32b31808SJens Wiklander     }
3596*32b31808SJens Wiklander 
3597*32b31808SJens Wiklander     return ret;
3598*32b31808SJens Wiklander }
3599*32b31808SJens Wiklander 
3600*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_PROTO_TLS1_2 */
3601