xref: /aosp_15_r20/external/mbedtls/library/ssl_tls12_server.c (revision 62c56f9862f102b96d72393aff6076c951fb8148)
1*62c56f98SSadaf Ebrahimi /*
2*62c56f98SSadaf Ebrahimi  *  TLS server-side functions
3*62c56f98SSadaf Ebrahimi  *
4*62c56f98SSadaf Ebrahimi  *  Copyright The Mbed TLS Contributors
5*62c56f98SSadaf Ebrahimi  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6*62c56f98SSadaf Ebrahimi  */
7*62c56f98SSadaf Ebrahimi 
8*62c56f98SSadaf Ebrahimi #include "common.h"
9*62c56f98SSadaf Ebrahimi 
10*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_2)
11*62c56f98SSadaf Ebrahimi 
12*62c56f98SSadaf Ebrahimi #include "mbedtls/platform.h"
13*62c56f98SSadaf Ebrahimi 
14*62c56f98SSadaf Ebrahimi #include "mbedtls/ssl.h"
15*62c56f98SSadaf Ebrahimi #include "ssl_misc.h"
16*62c56f98SSadaf Ebrahimi #include "mbedtls/debug.h"
17*62c56f98SSadaf Ebrahimi #include "mbedtls/error.h"
18*62c56f98SSadaf Ebrahimi #include "mbedtls/platform_util.h"
19*62c56f98SSadaf Ebrahimi #include "constant_time_internal.h"
20*62c56f98SSadaf Ebrahimi #include "mbedtls/constant_time.h"
21*62c56f98SSadaf Ebrahimi 
22*62c56f98SSadaf Ebrahimi #include <string.h>
23*62c56f98SSadaf Ebrahimi 
24*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
25*62c56f98SSadaf Ebrahimi /* Define a local translating function to save code size by not using too many
26*62c56f98SSadaf Ebrahimi  * arguments in each translating place. */
27*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED) || \
28*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED)
local_err_translation(psa_status_t status)29*62c56f98SSadaf Ebrahimi static int local_err_translation(psa_status_t status)
30*62c56f98SSadaf Ebrahimi {
31*62c56f98SSadaf Ebrahimi     return psa_status_to_mbedtls(status, psa_to_ssl_errors,
32*62c56f98SSadaf Ebrahimi                                  ARRAY_LENGTH(psa_to_ssl_errors),
33*62c56f98SSadaf Ebrahimi                                  psa_generic_status_to_mbedtls);
34*62c56f98SSadaf Ebrahimi }
35*62c56f98SSadaf Ebrahimi #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)
36*62c56f98SSadaf Ebrahimi #endif
37*62c56f98SSadaf Ebrahimi #endif
38*62c56f98SSadaf Ebrahimi 
39*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_ECP_C)
40*62c56f98SSadaf Ebrahimi #include "mbedtls/ecp.h"
41*62c56f98SSadaf Ebrahimi #endif
42*62c56f98SSadaf Ebrahimi 
43*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_HAVE_TIME)
44*62c56f98SSadaf Ebrahimi #include "mbedtls/platform_time.h"
45*62c56f98SSadaf Ebrahimi #endif
46*62c56f98SSadaf Ebrahimi 
47*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
mbedtls_ssl_set_client_transport_id(mbedtls_ssl_context * ssl,const unsigned char * info,size_t ilen)48*62c56f98SSadaf Ebrahimi int mbedtls_ssl_set_client_transport_id(mbedtls_ssl_context *ssl,
49*62c56f98SSadaf Ebrahimi                                         const unsigned char *info,
50*62c56f98SSadaf Ebrahimi                                         size_t ilen)
51*62c56f98SSadaf Ebrahimi {
52*62c56f98SSadaf Ebrahimi     if (ssl->conf->endpoint != MBEDTLS_SSL_IS_SERVER) {
53*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
54*62c56f98SSadaf Ebrahimi     }
55*62c56f98SSadaf Ebrahimi 
56*62c56f98SSadaf Ebrahimi     mbedtls_free(ssl->cli_id);
57*62c56f98SSadaf Ebrahimi 
58*62c56f98SSadaf Ebrahimi     if ((ssl->cli_id = mbedtls_calloc(1, ilen)) == NULL) {
59*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_ALLOC_FAILED;
60*62c56f98SSadaf Ebrahimi     }
61*62c56f98SSadaf Ebrahimi 
62*62c56f98SSadaf Ebrahimi     memcpy(ssl->cli_id, info, ilen);
63*62c56f98SSadaf Ebrahimi     ssl->cli_id_len = ilen;
64*62c56f98SSadaf Ebrahimi 
65*62c56f98SSadaf Ebrahimi     return 0;
66*62c56f98SSadaf Ebrahimi }
67*62c56f98SSadaf Ebrahimi 
mbedtls_ssl_conf_dtls_cookies(mbedtls_ssl_config * conf,mbedtls_ssl_cookie_write_t * f_cookie_write,mbedtls_ssl_cookie_check_t * f_cookie_check,void * p_cookie)68*62c56f98SSadaf Ebrahimi void mbedtls_ssl_conf_dtls_cookies(mbedtls_ssl_config *conf,
69*62c56f98SSadaf Ebrahimi                                    mbedtls_ssl_cookie_write_t *f_cookie_write,
70*62c56f98SSadaf Ebrahimi                                    mbedtls_ssl_cookie_check_t *f_cookie_check,
71*62c56f98SSadaf Ebrahimi                                    void *p_cookie)
72*62c56f98SSadaf Ebrahimi {
73*62c56f98SSadaf Ebrahimi     conf->f_cookie_write = f_cookie_write;
74*62c56f98SSadaf Ebrahimi     conf->f_cookie_check = f_cookie_check;
75*62c56f98SSadaf Ebrahimi     conf->p_cookie       = p_cookie;
76*62c56f98SSadaf Ebrahimi }
77*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
78*62c56f98SSadaf Ebrahimi 
79*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
80*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_conf_has_psk_or_cb(mbedtls_ssl_config const * conf)81*62c56f98SSadaf Ebrahimi static int ssl_conf_has_psk_or_cb(mbedtls_ssl_config const *conf)
82*62c56f98SSadaf Ebrahimi {
83*62c56f98SSadaf Ebrahimi     if (conf->f_psk != NULL) {
84*62c56f98SSadaf Ebrahimi         return 1;
85*62c56f98SSadaf Ebrahimi     }
86*62c56f98SSadaf Ebrahimi 
87*62c56f98SSadaf Ebrahimi     if (conf->psk_identity_len == 0 || conf->psk_identity == NULL) {
88*62c56f98SSadaf Ebrahimi         return 0;
89*62c56f98SSadaf Ebrahimi     }
90*62c56f98SSadaf Ebrahimi 
91*62c56f98SSadaf Ebrahimi 
92*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
93*62c56f98SSadaf Ebrahimi     if (!mbedtls_svc_key_id_is_null(conf->psk_opaque)) {
94*62c56f98SSadaf Ebrahimi         return 1;
95*62c56f98SSadaf Ebrahimi     }
96*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_USE_PSA_CRYPTO */
97*62c56f98SSadaf Ebrahimi 
98*62c56f98SSadaf Ebrahimi     if (conf->psk != NULL && conf->psk_len != 0) {
99*62c56f98SSadaf Ebrahimi         return 1;
100*62c56f98SSadaf Ebrahimi     }
101*62c56f98SSadaf Ebrahimi 
102*62c56f98SSadaf Ebrahimi     return 0;
103*62c56f98SSadaf Ebrahimi }
104*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
105*62c56f98SSadaf Ebrahimi 
106*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_renegotiation_info(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)107*62c56f98SSadaf Ebrahimi static int ssl_parse_renegotiation_info(mbedtls_ssl_context *ssl,
108*62c56f98SSadaf Ebrahimi                                         const unsigned char *buf,
109*62c56f98SSadaf Ebrahimi                                         size_t len)
110*62c56f98SSadaf Ebrahimi {
111*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_RENEGOTIATION)
112*62c56f98SSadaf Ebrahimi     if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
113*62c56f98SSadaf Ebrahimi         /* Check verify-data in constant-time. The length OTOH is no secret */
114*62c56f98SSadaf Ebrahimi         if (len    != 1 + ssl->verify_data_len ||
115*62c56f98SSadaf Ebrahimi             buf[0] !=     ssl->verify_data_len ||
116*62c56f98SSadaf Ebrahimi             mbedtls_ct_memcmp(buf + 1, ssl->peer_verify_data,
117*62c56f98SSadaf Ebrahimi                               ssl->verify_data_len) != 0) {
118*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("non-matching renegotiation info"));
119*62c56f98SSadaf Ebrahimi             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
120*62c56f98SSadaf Ebrahimi                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
121*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
122*62c56f98SSadaf Ebrahimi         }
123*62c56f98SSadaf Ebrahimi     } else
124*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_RENEGOTIATION */
125*62c56f98SSadaf Ebrahimi     {
126*62c56f98SSadaf Ebrahimi         if (len != 1 || buf[0] != 0x0) {
127*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("non-zero length renegotiation info"));
128*62c56f98SSadaf Ebrahimi             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
129*62c56f98SSadaf Ebrahimi                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
130*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
131*62c56f98SSadaf Ebrahimi         }
132*62c56f98SSadaf Ebrahimi 
133*62c56f98SSadaf Ebrahimi         ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
134*62c56f98SSadaf Ebrahimi     }
135*62c56f98SSadaf Ebrahimi 
136*62c56f98SSadaf Ebrahimi     return 0;
137*62c56f98SSadaf Ebrahimi }
138*62c56f98SSadaf Ebrahimi 
139*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
140*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
141*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
142*62c56f98SSadaf Ebrahimi /*
143*62c56f98SSadaf Ebrahimi  * Function for parsing a supported groups (TLS 1.3) or supported elliptic
144*62c56f98SSadaf Ebrahimi  * curves (TLS 1.2) extension.
145*62c56f98SSadaf Ebrahimi  *
146*62c56f98SSadaf Ebrahimi  * The "extension_data" field of a supported groups extension contains a
147*62c56f98SSadaf Ebrahimi  * "NamedGroupList" value (TLS 1.3 RFC8446):
148*62c56f98SSadaf Ebrahimi  *      enum {
149*62c56f98SSadaf Ebrahimi  *          secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019),
150*62c56f98SSadaf Ebrahimi  *          x25519(0x001D), x448(0x001E),
151*62c56f98SSadaf Ebrahimi  *          ffdhe2048(0x0100), ffdhe3072(0x0101), ffdhe4096(0x0102),
152*62c56f98SSadaf Ebrahimi  *          ffdhe6144(0x0103), ffdhe8192(0x0104),
153*62c56f98SSadaf Ebrahimi  *          ffdhe_private_use(0x01FC..0x01FF),
154*62c56f98SSadaf Ebrahimi  *          ecdhe_private_use(0xFE00..0xFEFF),
155*62c56f98SSadaf Ebrahimi  *          (0xFFFF)
156*62c56f98SSadaf Ebrahimi  *      } NamedGroup;
157*62c56f98SSadaf Ebrahimi  *      struct {
158*62c56f98SSadaf Ebrahimi  *          NamedGroup named_group_list<2..2^16-1>;
159*62c56f98SSadaf Ebrahimi  *      } NamedGroupList;
160*62c56f98SSadaf Ebrahimi  *
161*62c56f98SSadaf Ebrahimi  * The "extension_data" field of a supported elliptic curves extension contains
162*62c56f98SSadaf Ebrahimi  * a "NamedCurveList" value (TLS 1.2 RFC 8422):
163*62c56f98SSadaf Ebrahimi  * enum {
164*62c56f98SSadaf Ebrahimi  *      deprecated(1..22),
165*62c56f98SSadaf Ebrahimi  *      secp256r1 (23), secp384r1 (24), secp521r1 (25),
166*62c56f98SSadaf Ebrahimi  *      x25519(29), x448(30),
167*62c56f98SSadaf Ebrahimi  *      reserved (0xFE00..0xFEFF),
168*62c56f98SSadaf Ebrahimi  *      deprecated(0xFF01..0xFF02),
169*62c56f98SSadaf Ebrahimi  *      (0xFFFF)
170*62c56f98SSadaf Ebrahimi  *  } NamedCurve;
171*62c56f98SSadaf Ebrahimi  * struct {
172*62c56f98SSadaf Ebrahimi  *      NamedCurve named_curve_list<2..2^16-1>
173*62c56f98SSadaf Ebrahimi  *  } NamedCurveList;
174*62c56f98SSadaf Ebrahimi  *
175*62c56f98SSadaf Ebrahimi  * The TLS 1.3 supported groups extension was defined to be a compatible
176*62c56f98SSadaf Ebrahimi  * generalization of the TLS 1.2 supported elliptic curves extension. They both
177*62c56f98SSadaf Ebrahimi  * share the same extension identifier.
178*62c56f98SSadaf Ebrahimi  *
179*62c56f98SSadaf Ebrahimi  */
180*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_supported_groups_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)181*62c56f98SSadaf Ebrahimi static int ssl_parse_supported_groups_ext(mbedtls_ssl_context *ssl,
182*62c56f98SSadaf Ebrahimi                                           const unsigned char *buf,
183*62c56f98SSadaf Ebrahimi                                           size_t len)
184*62c56f98SSadaf Ebrahimi {
185*62c56f98SSadaf Ebrahimi     size_t list_size, our_size;
186*62c56f98SSadaf Ebrahimi     const unsigned char *p;
187*62c56f98SSadaf Ebrahimi     uint16_t *curves_tls_id;
188*62c56f98SSadaf Ebrahimi 
189*62c56f98SSadaf Ebrahimi     if (len < 2) {
190*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
191*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
192*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
193*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
194*62c56f98SSadaf Ebrahimi     }
195*62c56f98SSadaf Ebrahimi     list_size = ((buf[0] << 8) | (buf[1]));
196*62c56f98SSadaf Ebrahimi     if (list_size + 2 != len ||
197*62c56f98SSadaf Ebrahimi         list_size % 2 != 0) {
198*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
199*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
200*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
201*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
202*62c56f98SSadaf Ebrahimi     }
203*62c56f98SSadaf Ebrahimi 
204*62c56f98SSadaf Ebrahimi     /* Should never happen unless client duplicates the extension */
205*62c56f98SSadaf Ebrahimi     if (ssl->handshake->curves_tls_id != NULL) {
206*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
207*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
208*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
209*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
210*62c56f98SSadaf Ebrahimi     }
211*62c56f98SSadaf Ebrahimi 
212*62c56f98SSadaf Ebrahimi     /* Don't allow our peer to make us allocate too much memory,
213*62c56f98SSadaf Ebrahimi      * and leave room for a final 0 */
214*62c56f98SSadaf Ebrahimi     our_size = list_size / 2 + 1;
215*62c56f98SSadaf Ebrahimi     if (our_size > MBEDTLS_ECP_DP_MAX) {
216*62c56f98SSadaf Ebrahimi         our_size = MBEDTLS_ECP_DP_MAX;
217*62c56f98SSadaf Ebrahimi     }
218*62c56f98SSadaf Ebrahimi 
219*62c56f98SSadaf Ebrahimi     if ((curves_tls_id = mbedtls_calloc(our_size,
220*62c56f98SSadaf Ebrahimi                                         sizeof(*curves_tls_id))) == NULL) {
221*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
222*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
223*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_ALLOC_FAILED;
224*62c56f98SSadaf Ebrahimi     }
225*62c56f98SSadaf Ebrahimi 
226*62c56f98SSadaf Ebrahimi     ssl->handshake->curves_tls_id = curves_tls_id;
227*62c56f98SSadaf Ebrahimi 
228*62c56f98SSadaf Ebrahimi     p = buf + 2;
229*62c56f98SSadaf Ebrahimi     while (list_size > 0 && our_size > 1) {
230*62c56f98SSadaf Ebrahimi         uint16_t curr_tls_id = MBEDTLS_GET_UINT16_BE(p, 0);
231*62c56f98SSadaf Ebrahimi 
232*62c56f98SSadaf Ebrahimi         if (mbedtls_ssl_get_ecp_group_id_from_tls_id(curr_tls_id) !=
233*62c56f98SSadaf Ebrahimi             MBEDTLS_ECP_DP_NONE) {
234*62c56f98SSadaf Ebrahimi             *curves_tls_id++ = curr_tls_id;
235*62c56f98SSadaf Ebrahimi             our_size--;
236*62c56f98SSadaf Ebrahimi         }
237*62c56f98SSadaf Ebrahimi 
238*62c56f98SSadaf Ebrahimi         list_size -= 2;
239*62c56f98SSadaf Ebrahimi         p += 2;
240*62c56f98SSadaf Ebrahimi     }
241*62c56f98SSadaf Ebrahimi 
242*62c56f98SSadaf Ebrahimi     return 0;
243*62c56f98SSadaf Ebrahimi }
244*62c56f98SSadaf Ebrahimi 
245*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_supported_point_formats(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)246*62c56f98SSadaf Ebrahimi static int ssl_parse_supported_point_formats(mbedtls_ssl_context *ssl,
247*62c56f98SSadaf Ebrahimi                                              const unsigned char *buf,
248*62c56f98SSadaf Ebrahimi                                              size_t len)
249*62c56f98SSadaf Ebrahimi {
250*62c56f98SSadaf Ebrahimi     size_t list_size;
251*62c56f98SSadaf Ebrahimi     const unsigned char *p;
252*62c56f98SSadaf Ebrahimi 
253*62c56f98SSadaf Ebrahimi     if (len == 0 || (size_t) (buf[0] + 1) != len) {
254*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
255*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
256*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
257*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
258*62c56f98SSadaf Ebrahimi     }
259*62c56f98SSadaf Ebrahimi     list_size = buf[0];
260*62c56f98SSadaf Ebrahimi 
261*62c56f98SSadaf Ebrahimi     p = buf + 1;
262*62c56f98SSadaf Ebrahimi     while (list_size > 0) {
263*62c56f98SSadaf Ebrahimi         if (p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
264*62c56f98SSadaf Ebrahimi             p[0] == MBEDTLS_ECP_PF_COMPRESSED) {
265*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_USE_PSA_CRYPTO) && \
266*62c56f98SSadaf Ebrahimi             defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED)
267*62c56f98SSadaf Ebrahimi             ssl->handshake->ecdh_ctx.point_format = p[0];
268*62c56f98SSadaf Ebrahimi #endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED */
269*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_USE_PSA_CRYPTO) &&                             \
270*62c56f98SSadaf Ebrahimi             defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
271*62c56f98SSadaf Ebrahimi             mbedtls_ecjpake_set_point_format(&ssl->handshake->ecjpake_ctx,
272*62c56f98SSadaf Ebrahimi                                              p[0]);
273*62c56f98SSadaf Ebrahimi #endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
274*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(4, ("point format selected: %d", p[0]));
275*62c56f98SSadaf Ebrahimi             return 0;
276*62c56f98SSadaf Ebrahimi         }
277*62c56f98SSadaf Ebrahimi 
278*62c56f98SSadaf Ebrahimi         list_size--;
279*62c56f98SSadaf Ebrahimi         p++;
280*62c56f98SSadaf Ebrahimi     }
281*62c56f98SSadaf Ebrahimi 
282*62c56f98SSadaf Ebrahimi     return 0;
283*62c56f98SSadaf Ebrahimi }
284*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED ||
285*62c56f98SSadaf Ebrahimi           MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED ||
286*62c56f98SSadaf Ebrahimi           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
287*62c56f98SSadaf Ebrahimi 
288*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
289*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_ecjpake_kkpp(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)290*62c56f98SSadaf Ebrahimi static int ssl_parse_ecjpake_kkpp(mbedtls_ssl_context *ssl,
291*62c56f98SSadaf Ebrahimi                                   const unsigned char *buf,
292*62c56f98SSadaf Ebrahimi                                   size_t len)
293*62c56f98SSadaf Ebrahimi {
294*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
295*62c56f98SSadaf Ebrahimi 
296*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
297*62c56f98SSadaf Ebrahimi     if (ssl->handshake->psa_pake_ctx_is_ok != 1)
298*62c56f98SSadaf Ebrahimi #else
299*62c56f98SSadaf Ebrahimi     if (mbedtls_ecjpake_check(&ssl->handshake->ecjpake_ctx) != 0)
300*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_USE_PSA_CRYPTO */
301*62c56f98SSadaf Ebrahimi     {
302*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(3, ("skip ecjpake kkpp extension"));
303*62c56f98SSadaf Ebrahimi         return 0;
304*62c56f98SSadaf Ebrahimi     }
305*62c56f98SSadaf Ebrahimi 
306*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
307*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_psa_ecjpake_read_round(
308*62c56f98SSadaf Ebrahimi              &ssl->handshake->psa_pake_ctx, buf, len,
309*62c56f98SSadaf Ebrahimi              MBEDTLS_ECJPAKE_ROUND_ONE)) != 0) {
310*62c56f98SSadaf Ebrahimi         psa_destroy_key(ssl->handshake->psa_pake_password);
311*62c56f98SSadaf Ebrahimi         psa_pake_abort(&ssl->handshake->psa_pake_ctx);
312*62c56f98SSadaf Ebrahimi 
313*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round one", ret);
314*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(
315*62c56f98SSadaf Ebrahimi             ssl,
316*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
317*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
318*62c56f98SSadaf Ebrahimi 
319*62c56f98SSadaf Ebrahimi         return ret;
320*62c56f98SSadaf Ebrahimi     }
321*62c56f98SSadaf Ebrahimi #else
322*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_ecjpake_read_round_one(&ssl->handshake->ecjpake_ctx,
323*62c56f98SSadaf Ebrahimi                                               buf, len)) != 0) {
324*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_one", ret);
325*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
326*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
327*62c56f98SSadaf Ebrahimi         return ret;
328*62c56f98SSadaf Ebrahimi     }
329*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_USE_PSA_CRYPTO */
330*62c56f98SSadaf Ebrahimi 
331*62c56f98SSadaf Ebrahimi     /* Only mark the extension as OK when we're sure it is */
332*62c56f98SSadaf Ebrahimi     ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK;
333*62c56f98SSadaf Ebrahimi 
334*62c56f98SSadaf Ebrahimi     return 0;
335*62c56f98SSadaf Ebrahimi }
336*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
337*62c56f98SSadaf Ebrahimi 
338*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
339*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_max_fragment_length_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)340*62c56f98SSadaf Ebrahimi static int ssl_parse_max_fragment_length_ext(mbedtls_ssl_context *ssl,
341*62c56f98SSadaf Ebrahimi                                              const unsigned char *buf,
342*62c56f98SSadaf Ebrahimi                                              size_t len)
343*62c56f98SSadaf Ebrahimi {
344*62c56f98SSadaf Ebrahimi     if (len != 1 || buf[0] >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID) {
345*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
346*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
347*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
348*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
349*62c56f98SSadaf Ebrahimi     }
350*62c56f98SSadaf Ebrahimi 
351*62c56f98SSadaf Ebrahimi     ssl->session_negotiate->mfl_code = buf[0];
352*62c56f98SSadaf Ebrahimi 
353*62c56f98SSadaf Ebrahimi     return 0;
354*62c56f98SSadaf Ebrahimi }
355*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
356*62c56f98SSadaf Ebrahimi 
357*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
358*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_cid_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)359*62c56f98SSadaf Ebrahimi static int ssl_parse_cid_ext(mbedtls_ssl_context *ssl,
360*62c56f98SSadaf Ebrahimi                              const unsigned char *buf,
361*62c56f98SSadaf Ebrahimi                              size_t len)
362*62c56f98SSadaf Ebrahimi {
363*62c56f98SSadaf Ebrahimi     size_t peer_cid_len;
364*62c56f98SSadaf Ebrahimi 
365*62c56f98SSadaf Ebrahimi     /* CID extension only makes sense in DTLS */
366*62c56f98SSadaf Ebrahimi     if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
367*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
368*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
369*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
370*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
371*62c56f98SSadaf Ebrahimi     }
372*62c56f98SSadaf Ebrahimi 
373*62c56f98SSadaf Ebrahimi     /*
374*62c56f98SSadaf Ebrahimi      *   struct {
375*62c56f98SSadaf Ebrahimi      *      opaque cid<0..2^8-1>;
376*62c56f98SSadaf Ebrahimi      *   } ConnectionId;
377*62c56f98SSadaf Ebrahimi      */
378*62c56f98SSadaf Ebrahimi 
379*62c56f98SSadaf Ebrahimi     if (len < 1) {
380*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
381*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
382*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
383*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
384*62c56f98SSadaf Ebrahimi     }
385*62c56f98SSadaf Ebrahimi 
386*62c56f98SSadaf Ebrahimi     peer_cid_len = *buf++;
387*62c56f98SSadaf Ebrahimi     len--;
388*62c56f98SSadaf Ebrahimi 
389*62c56f98SSadaf Ebrahimi     if (len != peer_cid_len) {
390*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
391*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
392*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
393*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
394*62c56f98SSadaf Ebrahimi     }
395*62c56f98SSadaf Ebrahimi 
396*62c56f98SSadaf Ebrahimi     /* Ignore CID if the user has disabled its use. */
397*62c56f98SSadaf Ebrahimi     if (ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED) {
398*62c56f98SSadaf Ebrahimi         /* Leave ssl->handshake->cid_in_use in its default
399*62c56f98SSadaf Ebrahimi          * value of MBEDTLS_SSL_CID_DISABLED. */
400*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(3, ("Client sent CID extension, but CID disabled"));
401*62c56f98SSadaf Ebrahimi         return 0;
402*62c56f98SSadaf Ebrahimi     }
403*62c56f98SSadaf Ebrahimi 
404*62c56f98SSadaf Ebrahimi     if (peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX) {
405*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
406*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
407*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
408*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
409*62c56f98SSadaf Ebrahimi     }
410*62c56f98SSadaf Ebrahimi 
411*62c56f98SSadaf Ebrahimi     ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED;
412*62c56f98SSadaf Ebrahimi     ssl->handshake->peer_cid_len = (uint8_t) peer_cid_len;
413*62c56f98SSadaf Ebrahimi     memcpy(ssl->handshake->peer_cid, buf, peer_cid_len);
414*62c56f98SSadaf Ebrahimi 
415*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("Use of CID extension negotiated"));
416*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_BUF(3, "Client CID", buf, peer_cid_len);
417*62c56f98SSadaf Ebrahimi 
418*62c56f98SSadaf Ebrahimi     return 0;
419*62c56f98SSadaf Ebrahimi }
420*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
421*62c56f98SSadaf Ebrahimi 
422*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
423*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_encrypt_then_mac_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)424*62c56f98SSadaf Ebrahimi static int ssl_parse_encrypt_then_mac_ext(mbedtls_ssl_context *ssl,
425*62c56f98SSadaf Ebrahimi                                           const unsigned char *buf,
426*62c56f98SSadaf Ebrahimi                                           size_t len)
427*62c56f98SSadaf Ebrahimi {
428*62c56f98SSadaf Ebrahimi     if (len != 0) {
429*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
430*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
431*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
432*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
433*62c56f98SSadaf Ebrahimi     }
434*62c56f98SSadaf Ebrahimi 
435*62c56f98SSadaf Ebrahimi     ((void) buf);
436*62c56f98SSadaf Ebrahimi 
437*62c56f98SSadaf Ebrahimi     if (ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED) {
438*62c56f98SSadaf Ebrahimi         ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
439*62c56f98SSadaf Ebrahimi     }
440*62c56f98SSadaf Ebrahimi 
441*62c56f98SSadaf Ebrahimi     return 0;
442*62c56f98SSadaf Ebrahimi }
443*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
444*62c56f98SSadaf Ebrahimi 
445*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
446*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_extended_ms_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)447*62c56f98SSadaf Ebrahimi static int ssl_parse_extended_ms_ext(mbedtls_ssl_context *ssl,
448*62c56f98SSadaf Ebrahimi                                      const unsigned char *buf,
449*62c56f98SSadaf Ebrahimi                                      size_t len)
450*62c56f98SSadaf Ebrahimi {
451*62c56f98SSadaf Ebrahimi     if (len != 0) {
452*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
453*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
454*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
455*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
456*62c56f98SSadaf Ebrahimi     }
457*62c56f98SSadaf Ebrahimi 
458*62c56f98SSadaf Ebrahimi     ((void) buf);
459*62c56f98SSadaf Ebrahimi 
460*62c56f98SSadaf Ebrahimi     if (ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED) {
461*62c56f98SSadaf Ebrahimi         ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
462*62c56f98SSadaf Ebrahimi     }
463*62c56f98SSadaf Ebrahimi 
464*62c56f98SSadaf Ebrahimi     return 0;
465*62c56f98SSadaf Ebrahimi }
466*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
467*62c56f98SSadaf Ebrahimi 
468*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_SESSION_TICKETS)
469*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_session_ticket_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t len)470*62c56f98SSadaf Ebrahimi static int ssl_parse_session_ticket_ext(mbedtls_ssl_context *ssl,
471*62c56f98SSadaf Ebrahimi                                         unsigned char *buf,
472*62c56f98SSadaf Ebrahimi                                         size_t len)
473*62c56f98SSadaf Ebrahimi {
474*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
475*62c56f98SSadaf Ebrahimi     mbedtls_ssl_session session;
476*62c56f98SSadaf Ebrahimi 
477*62c56f98SSadaf Ebrahimi     mbedtls_ssl_session_init(&session);
478*62c56f98SSadaf Ebrahimi 
479*62c56f98SSadaf Ebrahimi     if (ssl->conf->f_ticket_parse == NULL ||
480*62c56f98SSadaf Ebrahimi         ssl->conf->f_ticket_write == NULL) {
481*62c56f98SSadaf Ebrahimi         return 0;
482*62c56f98SSadaf Ebrahimi     }
483*62c56f98SSadaf Ebrahimi 
484*62c56f98SSadaf Ebrahimi     /* Remember the client asked us to send a new ticket */
485*62c56f98SSadaf Ebrahimi     ssl->handshake->new_session_ticket = 1;
486*62c56f98SSadaf Ebrahimi 
487*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("ticket length: %" MBEDTLS_PRINTF_SIZET, len));
488*62c56f98SSadaf Ebrahimi 
489*62c56f98SSadaf Ebrahimi     if (len == 0) {
490*62c56f98SSadaf Ebrahimi         return 0;
491*62c56f98SSadaf Ebrahimi     }
492*62c56f98SSadaf Ebrahimi 
493*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_RENEGOTIATION)
494*62c56f98SSadaf Ebrahimi     if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
495*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(3, ("ticket rejected: renegotiating"));
496*62c56f98SSadaf Ebrahimi         return 0;
497*62c56f98SSadaf Ebrahimi     }
498*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_RENEGOTIATION */
499*62c56f98SSadaf Ebrahimi 
500*62c56f98SSadaf Ebrahimi     /*
501*62c56f98SSadaf Ebrahimi      * Failures are ok: just ignore the ticket and proceed.
502*62c56f98SSadaf Ebrahimi      */
503*62c56f98SSadaf Ebrahimi     if ((ret = ssl->conf->f_ticket_parse(ssl->conf->p_ticket, &session,
504*62c56f98SSadaf Ebrahimi                                          buf, len)) != 0) {
505*62c56f98SSadaf Ebrahimi         mbedtls_ssl_session_free(&session);
506*62c56f98SSadaf Ebrahimi 
507*62c56f98SSadaf Ebrahimi         if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) {
508*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is not authentic"));
509*62c56f98SSadaf Ebrahimi         } else if (ret == MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) {
510*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is expired"));
511*62c56f98SSadaf Ebrahimi         } else {
512*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_ticket_parse", ret);
513*62c56f98SSadaf Ebrahimi         }
514*62c56f98SSadaf Ebrahimi 
515*62c56f98SSadaf Ebrahimi         return 0;
516*62c56f98SSadaf Ebrahimi     }
517*62c56f98SSadaf Ebrahimi 
518*62c56f98SSadaf Ebrahimi     /*
519*62c56f98SSadaf Ebrahimi      * Keep the session ID sent by the client, since we MUST send it back to
520*62c56f98SSadaf Ebrahimi      * inform them we're accepting the ticket  (RFC 5077 section 3.4)
521*62c56f98SSadaf Ebrahimi      */
522*62c56f98SSadaf Ebrahimi     session.id_len = ssl->session_negotiate->id_len;
523*62c56f98SSadaf Ebrahimi     memcpy(&session.id, ssl->session_negotiate->id, session.id_len);
524*62c56f98SSadaf Ebrahimi 
525*62c56f98SSadaf Ebrahimi     mbedtls_ssl_session_free(ssl->session_negotiate);
526*62c56f98SSadaf Ebrahimi     memcpy(ssl->session_negotiate, &session, sizeof(mbedtls_ssl_session));
527*62c56f98SSadaf Ebrahimi 
528*62c56f98SSadaf Ebrahimi     /* Zeroize instead of free as we copied the content */
529*62c56f98SSadaf Ebrahimi     mbedtls_platform_zeroize(&session, sizeof(mbedtls_ssl_session));
530*62c56f98SSadaf Ebrahimi 
531*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("session successfully restored from ticket"));
532*62c56f98SSadaf Ebrahimi 
533*62c56f98SSadaf Ebrahimi     ssl->handshake->resume = 1;
534*62c56f98SSadaf Ebrahimi 
535*62c56f98SSadaf Ebrahimi     /* Don't send a new ticket after all, this one is OK */
536*62c56f98SSadaf Ebrahimi     ssl->handshake->new_session_ticket = 0;
537*62c56f98SSadaf Ebrahimi 
538*62c56f98SSadaf Ebrahimi     return 0;
539*62c56f98SSadaf Ebrahimi }
540*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_SESSION_TICKETS */
541*62c56f98SSadaf Ebrahimi 
542*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_DTLS_SRTP)
543*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_use_srtp_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)544*62c56f98SSadaf Ebrahimi static int ssl_parse_use_srtp_ext(mbedtls_ssl_context *ssl,
545*62c56f98SSadaf Ebrahimi                                   const unsigned char *buf,
546*62c56f98SSadaf Ebrahimi                                   size_t len)
547*62c56f98SSadaf Ebrahimi {
548*62c56f98SSadaf Ebrahimi     mbedtls_ssl_srtp_profile client_protection = MBEDTLS_TLS_SRTP_UNSET;
549*62c56f98SSadaf Ebrahimi     size_t i, j;
550*62c56f98SSadaf Ebrahimi     size_t profile_length;
551*62c56f98SSadaf Ebrahimi     uint16_t mki_length;
552*62c56f98SSadaf Ebrahimi     /*! 2 bytes for profile length and 1 byte for mki len */
553*62c56f98SSadaf Ebrahimi     const size_t size_of_lengths = 3;
554*62c56f98SSadaf Ebrahimi 
555*62c56f98SSadaf Ebrahimi     /* If use_srtp is not configured, just ignore the extension */
556*62c56f98SSadaf Ebrahimi     if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) ||
557*62c56f98SSadaf Ebrahimi         (ssl->conf->dtls_srtp_profile_list == NULL) ||
558*62c56f98SSadaf Ebrahimi         (ssl->conf->dtls_srtp_profile_list_len == 0)) {
559*62c56f98SSadaf Ebrahimi         return 0;
560*62c56f98SSadaf Ebrahimi     }
561*62c56f98SSadaf Ebrahimi 
562*62c56f98SSadaf Ebrahimi     /* RFC5764 section 4.1.1
563*62c56f98SSadaf Ebrahimi      * uint8 SRTPProtectionProfile[2];
564*62c56f98SSadaf Ebrahimi      *
565*62c56f98SSadaf Ebrahimi      * struct {
566*62c56f98SSadaf Ebrahimi      *   SRTPProtectionProfiles SRTPProtectionProfiles;
567*62c56f98SSadaf Ebrahimi      *   opaque srtp_mki<0..255>;
568*62c56f98SSadaf Ebrahimi      * } UseSRTPData;
569*62c56f98SSadaf Ebrahimi 
570*62c56f98SSadaf Ebrahimi      * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
571*62c56f98SSadaf Ebrahimi      */
572*62c56f98SSadaf Ebrahimi 
573*62c56f98SSadaf Ebrahimi     /*
574*62c56f98SSadaf Ebrahimi      * Min length is 5: at least one protection profile(2 bytes)
575*62c56f98SSadaf Ebrahimi      *                  and length(2 bytes) + srtp_mki length(1 byte)
576*62c56f98SSadaf Ebrahimi      * Check here that we have at least 2 bytes of protection profiles length
577*62c56f98SSadaf Ebrahimi      * and one of srtp_mki length
578*62c56f98SSadaf Ebrahimi      */
579*62c56f98SSadaf Ebrahimi     if (len < size_of_lengths) {
580*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
581*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
582*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
583*62c56f98SSadaf Ebrahimi     }
584*62c56f98SSadaf Ebrahimi 
585*62c56f98SSadaf Ebrahimi     ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET;
586*62c56f98SSadaf Ebrahimi 
587*62c56f98SSadaf Ebrahimi     /* first 2 bytes are protection profile length(in bytes) */
588*62c56f98SSadaf Ebrahimi     profile_length = (buf[0] << 8) | buf[1];
589*62c56f98SSadaf Ebrahimi     buf += 2;
590*62c56f98SSadaf Ebrahimi 
591*62c56f98SSadaf Ebrahimi     /* The profile length cannot be bigger than input buffer size - lengths fields */
592*62c56f98SSadaf Ebrahimi     if (profile_length > len - size_of_lengths ||
593*62c56f98SSadaf Ebrahimi         profile_length % 2 != 0) { /* profiles are 2 bytes long, so the length must be even */
594*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
595*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
596*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
597*62c56f98SSadaf Ebrahimi     }
598*62c56f98SSadaf Ebrahimi     /*
599*62c56f98SSadaf Ebrahimi      * parse the extension list values are defined in
600*62c56f98SSadaf Ebrahimi      * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
601*62c56f98SSadaf Ebrahimi      */
602*62c56f98SSadaf Ebrahimi     for (j = 0; j < profile_length; j += 2) {
603*62c56f98SSadaf Ebrahimi         uint16_t protection_profile_value = buf[j] << 8 | buf[j + 1];
604*62c56f98SSadaf Ebrahimi         client_protection = mbedtls_ssl_check_srtp_profile_value(protection_profile_value);
605*62c56f98SSadaf Ebrahimi 
606*62c56f98SSadaf Ebrahimi         if (client_protection != MBEDTLS_TLS_SRTP_UNSET) {
607*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(3, ("found srtp profile: %s",
608*62c56f98SSadaf Ebrahimi                                       mbedtls_ssl_get_srtp_profile_as_string(
609*62c56f98SSadaf Ebrahimi                                           client_protection)));
610*62c56f98SSadaf Ebrahimi         } else {
611*62c56f98SSadaf Ebrahimi             continue;
612*62c56f98SSadaf Ebrahimi         }
613*62c56f98SSadaf Ebrahimi         /* check if suggested profile is in our list */
614*62c56f98SSadaf Ebrahimi         for (i = 0; i < ssl->conf->dtls_srtp_profile_list_len; i++) {
615*62c56f98SSadaf Ebrahimi             if (client_protection == ssl->conf->dtls_srtp_profile_list[i]) {
616*62c56f98SSadaf Ebrahimi                 ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
617*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(3, ("selected srtp profile: %s",
618*62c56f98SSadaf Ebrahimi                                           mbedtls_ssl_get_srtp_profile_as_string(
619*62c56f98SSadaf Ebrahimi                                               client_protection)));
620*62c56f98SSadaf Ebrahimi                 break;
621*62c56f98SSadaf Ebrahimi             }
622*62c56f98SSadaf Ebrahimi         }
623*62c56f98SSadaf Ebrahimi         if (ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_TLS_SRTP_UNSET) {
624*62c56f98SSadaf Ebrahimi             break;
625*62c56f98SSadaf Ebrahimi         }
626*62c56f98SSadaf Ebrahimi     }
627*62c56f98SSadaf Ebrahimi     buf += profile_length; /* buf points to the mki length */
628*62c56f98SSadaf Ebrahimi     mki_length = *buf;
629*62c56f98SSadaf Ebrahimi     buf++;
630*62c56f98SSadaf Ebrahimi 
631*62c56f98SSadaf Ebrahimi     if (mki_length > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH ||
632*62c56f98SSadaf Ebrahimi         mki_length + profile_length + size_of_lengths != len) {
633*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
634*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
635*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
636*62c56f98SSadaf Ebrahimi     }
637*62c56f98SSadaf Ebrahimi 
638*62c56f98SSadaf Ebrahimi     /* Parse the mki only if present and mki is supported locally */
639*62c56f98SSadaf Ebrahimi     if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED &&
640*62c56f98SSadaf Ebrahimi         mki_length > 0) {
641*62c56f98SSadaf Ebrahimi         ssl->dtls_srtp_info.mki_len = mki_length;
642*62c56f98SSadaf Ebrahimi 
643*62c56f98SSadaf Ebrahimi         memcpy(ssl->dtls_srtp_info.mki_value, buf, mki_length);
644*62c56f98SSadaf Ebrahimi 
645*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_BUF(3, "using mki",  ssl->dtls_srtp_info.mki_value,
646*62c56f98SSadaf Ebrahimi                               ssl->dtls_srtp_info.mki_len);
647*62c56f98SSadaf Ebrahimi     }
648*62c56f98SSadaf Ebrahimi 
649*62c56f98SSadaf Ebrahimi     return 0;
650*62c56f98SSadaf Ebrahimi }
651*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_DTLS_SRTP */
652*62c56f98SSadaf Ebrahimi 
653*62c56f98SSadaf Ebrahimi /*
654*62c56f98SSadaf Ebrahimi  * Auxiliary functions for ServerHello parsing and related actions
655*62c56f98SSadaf Ebrahimi  */
656*62c56f98SSadaf Ebrahimi 
657*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_X509_CRT_PARSE_C)
658*62c56f98SSadaf Ebrahimi /*
659*62c56f98SSadaf Ebrahimi  * Return 0 if the given key uses one of the acceptable curves, -1 otherwise
660*62c56f98SSadaf Ebrahimi  */
661*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
662*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_check_key_curve(mbedtls_pk_context * pk,uint16_t * curves_tls_id)663*62c56f98SSadaf Ebrahimi static int ssl_check_key_curve(mbedtls_pk_context *pk,
664*62c56f98SSadaf Ebrahimi                                uint16_t *curves_tls_id)
665*62c56f98SSadaf Ebrahimi {
666*62c56f98SSadaf Ebrahimi     uint16_t *curr_tls_id = curves_tls_id;
667*62c56f98SSadaf Ebrahimi     mbedtls_ecp_group_id grp_id = mbedtls_pk_ec_ro(*pk)->grp.id;
668*62c56f98SSadaf Ebrahimi     mbedtls_ecp_group_id curr_grp_id;
669*62c56f98SSadaf Ebrahimi 
670*62c56f98SSadaf Ebrahimi     while (*curr_tls_id != 0) {
671*62c56f98SSadaf Ebrahimi         curr_grp_id = mbedtls_ssl_get_ecp_group_id_from_tls_id(*curr_tls_id);
672*62c56f98SSadaf Ebrahimi         if (curr_grp_id == grp_id) {
673*62c56f98SSadaf Ebrahimi             return 0;
674*62c56f98SSadaf Ebrahimi         }
675*62c56f98SSadaf Ebrahimi         curr_tls_id++;
676*62c56f98SSadaf Ebrahimi     }
677*62c56f98SSadaf Ebrahimi 
678*62c56f98SSadaf Ebrahimi     return -1;
679*62c56f98SSadaf Ebrahimi }
680*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED */
681*62c56f98SSadaf Ebrahimi 
682*62c56f98SSadaf Ebrahimi /*
683*62c56f98SSadaf Ebrahimi  * Try picking a certificate for this ciphersuite,
684*62c56f98SSadaf Ebrahimi  * return 0 on success and -1 on failure.
685*62c56f98SSadaf Ebrahimi  */
686*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_pick_cert(mbedtls_ssl_context * ssl,const mbedtls_ssl_ciphersuite_t * ciphersuite_info)687*62c56f98SSadaf Ebrahimi static int ssl_pick_cert(mbedtls_ssl_context *ssl,
688*62c56f98SSadaf Ebrahimi                          const mbedtls_ssl_ciphersuite_t *ciphersuite_info)
689*62c56f98SSadaf Ebrahimi {
690*62c56f98SSadaf Ebrahimi     mbedtls_ssl_key_cert *cur, *list;
691*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
692*62c56f98SSadaf Ebrahimi     psa_algorithm_t pk_alg =
693*62c56f98SSadaf Ebrahimi         mbedtls_ssl_get_ciphersuite_sig_pk_psa_alg(ciphersuite_info);
694*62c56f98SSadaf Ebrahimi     psa_key_usage_t pk_usage =
695*62c56f98SSadaf Ebrahimi         mbedtls_ssl_get_ciphersuite_sig_pk_psa_usage(ciphersuite_info);
696*62c56f98SSadaf Ebrahimi #else
697*62c56f98SSadaf Ebrahimi     mbedtls_pk_type_t pk_alg =
698*62c56f98SSadaf Ebrahimi         mbedtls_ssl_get_ciphersuite_sig_pk_alg(ciphersuite_info);
699*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_USE_PSA_CRYPTO */
700*62c56f98SSadaf Ebrahimi     uint32_t flags;
701*62c56f98SSadaf Ebrahimi 
702*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
703*62c56f98SSadaf Ebrahimi     if (ssl->handshake->sni_key_cert != NULL) {
704*62c56f98SSadaf Ebrahimi         list = ssl->handshake->sni_key_cert;
705*62c56f98SSadaf Ebrahimi     } else
706*62c56f98SSadaf Ebrahimi #endif
707*62c56f98SSadaf Ebrahimi     list = ssl->conf->key_cert;
708*62c56f98SSadaf Ebrahimi 
709*62c56f98SSadaf Ebrahimi     int pk_alg_is_none = 0;
710*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
711*62c56f98SSadaf Ebrahimi     pk_alg_is_none = (pk_alg == PSA_ALG_NONE);
712*62c56f98SSadaf Ebrahimi #else
713*62c56f98SSadaf Ebrahimi     pk_alg_is_none = (pk_alg == MBEDTLS_PK_NONE);
714*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_USE_PSA_CRYPTO */
715*62c56f98SSadaf Ebrahimi     if (pk_alg_is_none) {
716*62c56f98SSadaf Ebrahimi         return 0;
717*62c56f98SSadaf Ebrahimi     }
718*62c56f98SSadaf Ebrahimi 
719*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite requires certificate"));
720*62c56f98SSadaf Ebrahimi 
721*62c56f98SSadaf Ebrahimi     if (list == NULL) {
722*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(3, ("server has no certificate"));
723*62c56f98SSadaf Ebrahimi         return -1;
724*62c56f98SSadaf Ebrahimi     }
725*62c56f98SSadaf Ebrahimi 
726*62c56f98SSadaf Ebrahimi     for (cur = list; cur != NULL; cur = cur->next) {
727*62c56f98SSadaf Ebrahimi         flags = 0;
728*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_CRT(3, "candidate certificate chain, certificate",
729*62c56f98SSadaf Ebrahimi                               cur->cert);
730*62c56f98SSadaf Ebrahimi 
731*62c56f98SSadaf Ebrahimi         int key_type_matches = 0;
732*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
733*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
734*62c56f98SSadaf Ebrahimi         key_type_matches = ((ssl->conf->f_async_sign_start != NULL ||
735*62c56f98SSadaf Ebrahimi                              ssl->conf->f_async_decrypt_start != NULL ||
736*62c56f98SSadaf Ebrahimi                              mbedtls_pk_can_do_ext(cur->key, pk_alg, pk_usage)) &&
737*62c56f98SSadaf Ebrahimi                             mbedtls_pk_can_do_ext(&cur->cert->pk, pk_alg, pk_usage));
738*62c56f98SSadaf Ebrahimi #else
739*62c56f98SSadaf Ebrahimi         key_type_matches = (
740*62c56f98SSadaf Ebrahimi             mbedtls_pk_can_do_ext(cur->key, pk_alg, pk_usage));
741*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
742*62c56f98SSadaf Ebrahimi #else
743*62c56f98SSadaf Ebrahimi         key_type_matches = mbedtls_pk_can_do(&cur->cert->pk, pk_alg);
744*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_USE_PSA_CRYPTO */
745*62c56f98SSadaf Ebrahimi         if (!key_type_matches) {
746*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: key type"));
747*62c56f98SSadaf Ebrahimi             continue;
748*62c56f98SSadaf Ebrahimi         }
749*62c56f98SSadaf Ebrahimi 
750*62c56f98SSadaf Ebrahimi         /*
751*62c56f98SSadaf Ebrahimi          * This avoids sending the client a cert it'll reject based on
752*62c56f98SSadaf Ebrahimi          * keyUsage or other extensions.
753*62c56f98SSadaf Ebrahimi          *
754*62c56f98SSadaf Ebrahimi          * It also allows the user to provision different certificates for
755*62c56f98SSadaf Ebrahimi          * different uses based on keyUsage, eg if they want to avoid signing
756*62c56f98SSadaf Ebrahimi          * and decrypting with the same RSA key.
757*62c56f98SSadaf Ebrahimi          */
758*62c56f98SSadaf Ebrahimi         if (mbedtls_ssl_check_cert_usage(cur->cert, ciphersuite_info,
759*62c56f98SSadaf Ebrahimi                                          MBEDTLS_SSL_IS_SERVER, &flags) != 0) {
760*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: "
761*62c56f98SSadaf Ebrahimi                                       "(extended) key usage extension"));
762*62c56f98SSadaf Ebrahimi             continue;
763*62c56f98SSadaf Ebrahimi         }
764*62c56f98SSadaf Ebrahimi 
765*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
766*62c56f98SSadaf Ebrahimi         if (pk_alg == MBEDTLS_PK_ECDSA &&
767*62c56f98SSadaf Ebrahimi             ssl_check_key_curve(&cur->cert->pk,
768*62c56f98SSadaf Ebrahimi                                 ssl->handshake->curves_tls_id) != 0) {
769*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: elliptic curve"));
770*62c56f98SSadaf Ebrahimi             continue;
771*62c56f98SSadaf Ebrahimi         }
772*62c56f98SSadaf Ebrahimi #endif
773*62c56f98SSadaf Ebrahimi 
774*62c56f98SSadaf Ebrahimi         /* If we get there, we got a winner */
775*62c56f98SSadaf Ebrahimi         break;
776*62c56f98SSadaf Ebrahimi     }
777*62c56f98SSadaf Ebrahimi 
778*62c56f98SSadaf Ebrahimi     /* Do not update ssl->handshake->key_cert unless there is a match */
779*62c56f98SSadaf Ebrahimi     if (cur != NULL) {
780*62c56f98SSadaf Ebrahimi         ssl->handshake->key_cert = cur;
781*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_CRT(3, "selected certificate chain, certificate",
782*62c56f98SSadaf Ebrahimi                               ssl->handshake->key_cert->cert);
783*62c56f98SSadaf Ebrahimi         return 0;
784*62c56f98SSadaf Ebrahimi     }
785*62c56f98SSadaf Ebrahimi 
786*62c56f98SSadaf Ebrahimi     return -1;
787*62c56f98SSadaf Ebrahimi }
788*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_X509_CRT_PARSE_C */
789*62c56f98SSadaf Ebrahimi 
790*62c56f98SSadaf Ebrahimi /*
791*62c56f98SSadaf Ebrahimi  * Check if a given ciphersuite is suitable for use with our config/keys/etc
792*62c56f98SSadaf Ebrahimi  * Sets ciphersuite_info only if the suite matches.
793*62c56f98SSadaf Ebrahimi  */
794*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_ciphersuite_match(mbedtls_ssl_context * ssl,int suite_id,const mbedtls_ssl_ciphersuite_t ** ciphersuite_info)795*62c56f98SSadaf Ebrahimi static int ssl_ciphersuite_match(mbedtls_ssl_context *ssl, int suite_id,
796*62c56f98SSadaf Ebrahimi                                  const mbedtls_ssl_ciphersuite_t **ciphersuite_info)
797*62c56f98SSadaf Ebrahimi {
798*62c56f98SSadaf Ebrahimi     const mbedtls_ssl_ciphersuite_t *suite_info;
799*62c56f98SSadaf Ebrahimi 
800*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
801*62c56f98SSadaf Ebrahimi     mbedtls_pk_type_t sig_type;
802*62c56f98SSadaf Ebrahimi #endif
803*62c56f98SSadaf Ebrahimi 
804*62c56f98SSadaf Ebrahimi     suite_info = mbedtls_ssl_ciphersuite_from_id(suite_id);
805*62c56f98SSadaf Ebrahimi     if (suite_info == NULL) {
806*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
807*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
808*62c56f98SSadaf Ebrahimi     }
809*62c56f98SSadaf Ebrahimi 
810*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("trying ciphersuite: %#04x (%s)",
811*62c56f98SSadaf Ebrahimi                               (unsigned int) suite_id, suite_info->name));
812*62c56f98SSadaf Ebrahimi 
813*62c56f98SSadaf Ebrahimi     if (suite_info->min_tls_version > ssl->tls_version ||
814*62c56f98SSadaf Ebrahimi         suite_info->max_tls_version < ssl->tls_version) {
815*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: version"));
816*62c56f98SSadaf Ebrahimi         return 0;
817*62c56f98SSadaf Ebrahimi     }
818*62c56f98SSadaf Ebrahimi 
819*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
820*62c56f98SSadaf Ebrahimi     if (suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
821*62c56f98SSadaf Ebrahimi         (ssl->handshake->cli_exts & MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK) == 0) {
822*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: ecjpake "
823*62c56f98SSadaf Ebrahimi                                   "not configured or ext missing"));
824*62c56f98SSadaf Ebrahimi         return 0;
825*62c56f98SSadaf Ebrahimi     }
826*62c56f98SSadaf Ebrahimi #endif
827*62c56f98SSadaf Ebrahimi 
828*62c56f98SSadaf Ebrahimi 
829*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
830*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
831*62c56f98SSadaf Ebrahimi     if (mbedtls_ssl_ciphersuite_uses_ec(suite_info) &&
832*62c56f98SSadaf Ebrahimi         (ssl->handshake->curves_tls_id == NULL ||
833*62c56f98SSadaf Ebrahimi          ssl->handshake->curves_tls_id[0] == 0)) {
834*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: "
835*62c56f98SSadaf Ebrahimi                                   "no common elliptic curve"));
836*62c56f98SSadaf Ebrahimi         return 0;
837*62c56f98SSadaf Ebrahimi     }
838*62c56f98SSadaf Ebrahimi #endif
839*62c56f98SSadaf Ebrahimi 
840*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
841*62c56f98SSadaf Ebrahimi     /* If the ciphersuite requires a pre-shared key and we don't
842*62c56f98SSadaf Ebrahimi      * have one, skip it now rather than failing later */
843*62c56f98SSadaf Ebrahimi     if (mbedtls_ssl_ciphersuite_uses_psk(suite_info) &&
844*62c56f98SSadaf Ebrahimi         ssl_conf_has_psk_or_cb(ssl->conf) == 0) {
845*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: no pre-shared key"));
846*62c56f98SSadaf Ebrahimi         return 0;
847*62c56f98SSadaf Ebrahimi     }
848*62c56f98SSadaf Ebrahimi #endif
849*62c56f98SSadaf Ebrahimi 
850*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_X509_CRT_PARSE_C)
851*62c56f98SSadaf Ebrahimi     /*
852*62c56f98SSadaf Ebrahimi      * Final check: if ciphersuite requires us to have a
853*62c56f98SSadaf Ebrahimi      * certificate/key of a particular type:
854*62c56f98SSadaf Ebrahimi      * - select the appropriate certificate if we have one, or
855*62c56f98SSadaf Ebrahimi      * - try the next ciphersuite if we don't
856*62c56f98SSadaf Ebrahimi      * This must be done last since we modify the key_cert list.
857*62c56f98SSadaf Ebrahimi      */
858*62c56f98SSadaf Ebrahimi     if (ssl_pick_cert(ssl, suite_info) != 0) {
859*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: "
860*62c56f98SSadaf Ebrahimi                                   "no suitable certificate"));
861*62c56f98SSadaf Ebrahimi         return 0;
862*62c56f98SSadaf Ebrahimi     }
863*62c56f98SSadaf Ebrahimi #endif
864*62c56f98SSadaf Ebrahimi 
865*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
866*62c56f98SSadaf Ebrahimi     /* If the ciphersuite requires signing, check whether
867*62c56f98SSadaf Ebrahimi      * a suitable hash algorithm is present. */
868*62c56f98SSadaf Ebrahimi     sig_type = mbedtls_ssl_get_ciphersuite_sig_alg(suite_info);
869*62c56f98SSadaf Ebrahimi     if (sig_type != MBEDTLS_PK_NONE &&
870*62c56f98SSadaf Ebrahimi         mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
871*62c56f98SSadaf Ebrahimi             ssl, mbedtls_ssl_sig_from_pk_alg(sig_type)) == MBEDTLS_SSL_HASH_NONE) {
872*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: no suitable hash algorithm "
873*62c56f98SSadaf Ebrahimi                                   "for signature algorithm %u", (unsigned) sig_type));
874*62c56f98SSadaf Ebrahimi         return 0;
875*62c56f98SSadaf Ebrahimi     }
876*62c56f98SSadaf Ebrahimi 
877*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
878*62c56f98SSadaf Ebrahimi 
879*62c56f98SSadaf Ebrahimi     *ciphersuite_info = suite_info;
880*62c56f98SSadaf Ebrahimi     return 0;
881*62c56f98SSadaf Ebrahimi }
882*62c56f98SSadaf Ebrahimi 
883*62c56f98SSadaf Ebrahimi /* This function doesn't alert on errors that happen early during
884*62c56f98SSadaf Ebrahimi    ClientHello parsing because they might indicate that the client is
885*62c56f98SSadaf Ebrahimi    not talking SSL/TLS at all and would not understand our alert. */
886*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_client_hello(mbedtls_ssl_context * ssl)887*62c56f98SSadaf Ebrahimi static int ssl_parse_client_hello(mbedtls_ssl_context *ssl)
888*62c56f98SSadaf Ebrahimi {
889*62c56f98SSadaf Ebrahimi     int ret, got_common_suite;
890*62c56f98SSadaf Ebrahimi     size_t i, j;
891*62c56f98SSadaf Ebrahimi     size_t ciph_offset, comp_offset, ext_offset;
892*62c56f98SSadaf Ebrahimi     size_t msg_len, ciph_len, sess_len, comp_len, ext_len;
893*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_PROTO_DTLS)
894*62c56f98SSadaf Ebrahimi     size_t cookie_offset, cookie_len;
895*62c56f98SSadaf Ebrahimi #endif
896*62c56f98SSadaf Ebrahimi     unsigned char *buf, *p, *ext;
897*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_RENEGOTIATION)
898*62c56f98SSadaf Ebrahimi     int renegotiation_info_seen = 0;
899*62c56f98SSadaf Ebrahimi #endif
900*62c56f98SSadaf Ebrahimi     int handshake_failure = 0;
901*62c56f98SSadaf Ebrahimi     const int *ciphersuites;
902*62c56f98SSadaf Ebrahimi     const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
903*62c56f98SSadaf Ebrahimi 
904*62c56f98SSadaf Ebrahimi     /* If there is no signature-algorithm extension present,
905*62c56f98SSadaf Ebrahimi      * we need to fall back to the default values for allowed
906*62c56f98SSadaf Ebrahimi      * signature-hash pairs. */
907*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
908*62c56f98SSadaf Ebrahimi     int sig_hash_alg_ext_present = 0;
909*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
910*62c56f98SSadaf Ebrahimi 
911*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse client hello"));
912*62c56f98SSadaf Ebrahimi 
913*62c56f98SSadaf Ebrahimi     int renegotiating;
914*62c56f98SSadaf Ebrahimi 
915*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
916*62c56f98SSadaf Ebrahimi read_record_header:
917*62c56f98SSadaf Ebrahimi #endif
918*62c56f98SSadaf Ebrahimi     /*
919*62c56f98SSadaf Ebrahimi      * If renegotiating, then the input was read with mbedtls_ssl_read_record(),
920*62c56f98SSadaf Ebrahimi      * otherwise read it ourselves manually in order to support SSLv2
921*62c56f98SSadaf Ebrahimi      * ClientHello, which doesn't use the same record layer format.
922*62c56f98SSadaf Ebrahimi      * Otherwise in a scenario of TLS 1.3/TLS 1.2 version negotiation, the
923*62c56f98SSadaf Ebrahimi      * ClientHello has been already fully fetched by the TLS 1.3 code and the
924*62c56f98SSadaf Ebrahimi      * flag ssl->keep_current_message is raised.
925*62c56f98SSadaf Ebrahimi      */
926*62c56f98SSadaf Ebrahimi     renegotiating = 0;
927*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_RENEGOTIATION)
928*62c56f98SSadaf Ebrahimi     renegotiating = (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE);
929*62c56f98SSadaf Ebrahimi #endif
930*62c56f98SSadaf Ebrahimi     if (!renegotiating && !ssl->keep_current_message) {
931*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_ssl_fetch_input(ssl, 5)) != 0) {
932*62c56f98SSadaf Ebrahimi             /* No alert on a read error. */
933*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
934*62c56f98SSadaf Ebrahimi             return ret;
935*62c56f98SSadaf Ebrahimi         }
936*62c56f98SSadaf Ebrahimi     }
937*62c56f98SSadaf Ebrahimi 
938*62c56f98SSadaf Ebrahimi     buf = ssl->in_hdr;
939*62c56f98SSadaf Ebrahimi 
940*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_BUF(4, "record header", buf, mbedtls_ssl_in_hdr_len(ssl));
941*62c56f98SSadaf Ebrahimi 
942*62c56f98SSadaf Ebrahimi     /*
943*62c56f98SSadaf Ebrahimi      * TLS Client Hello
944*62c56f98SSadaf Ebrahimi      *
945*62c56f98SSadaf Ebrahimi      * Record layer:
946*62c56f98SSadaf Ebrahimi      *     0  .   0   message type
947*62c56f98SSadaf Ebrahimi      *     1  .   2   protocol version
948*62c56f98SSadaf Ebrahimi      *     3  .   11  DTLS: epoch + record sequence number
949*62c56f98SSadaf Ebrahimi      *     3  .   4   message length
950*62c56f98SSadaf Ebrahimi      */
951*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, message type: %d",
952*62c56f98SSadaf Ebrahimi                               buf[0]));
953*62c56f98SSadaf Ebrahimi 
954*62c56f98SSadaf Ebrahimi     if (buf[0] != MBEDTLS_SSL_MSG_HANDSHAKE) {
955*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
956*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
957*62c56f98SSadaf Ebrahimi     }
958*62c56f98SSadaf Ebrahimi 
959*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, message len.: %d",
960*62c56f98SSadaf Ebrahimi                               (ssl->in_len[0] << 8) | ssl->in_len[1]));
961*62c56f98SSadaf Ebrahimi 
962*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, protocol version: [%d:%d]",
963*62c56f98SSadaf Ebrahimi                               buf[1], buf[2]));
964*62c56f98SSadaf Ebrahimi 
965*62c56f98SSadaf Ebrahimi     /* For DTLS if this is the initial handshake, remember the client sequence
966*62c56f98SSadaf Ebrahimi      * number to use it in our next message (RFC 6347 4.2.1) */
967*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_PROTO_DTLS)
968*62c56f98SSadaf Ebrahimi     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM
969*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_RENEGOTIATION)
970*62c56f98SSadaf Ebrahimi         && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE
971*62c56f98SSadaf Ebrahimi #endif
972*62c56f98SSadaf Ebrahimi         ) {
973*62c56f98SSadaf Ebrahimi         /* Epoch should be 0 for initial handshakes */
974*62c56f98SSadaf Ebrahimi         if (ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0) {
975*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
976*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
977*62c56f98SSadaf Ebrahimi         }
978*62c56f98SSadaf Ebrahimi 
979*62c56f98SSadaf Ebrahimi         memcpy(&ssl->cur_out_ctr[2], ssl->in_ctr + 2,
980*62c56f98SSadaf Ebrahimi                sizeof(ssl->cur_out_ctr) - 2);
981*62c56f98SSadaf Ebrahimi 
982*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
983*62c56f98SSadaf Ebrahimi         if (mbedtls_ssl_dtls_replay_check(ssl) != 0) {
984*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("replayed record, discarding"));
985*62c56f98SSadaf Ebrahimi             ssl->next_record_offset = 0;
986*62c56f98SSadaf Ebrahimi             ssl->in_left = 0;
987*62c56f98SSadaf Ebrahimi             goto read_record_header;
988*62c56f98SSadaf Ebrahimi         }
989*62c56f98SSadaf Ebrahimi 
990*62c56f98SSadaf Ebrahimi         /* No MAC to check yet, so we can update right now */
991*62c56f98SSadaf Ebrahimi         mbedtls_ssl_dtls_replay_update(ssl);
992*62c56f98SSadaf Ebrahimi #endif
993*62c56f98SSadaf Ebrahimi     }
994*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_PROTO_DTLS */
995*62c56f98SSadaf Ebrahimi 
996*62c56f98SSadaf Ebrahimi     msg_len = (ssl->in_len[0] << 8) | ssl->in_len[1];
997*62c56f98SSadaf Ebrahimi 
998*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_RENEGOTIATION)
999*62c56f98SSadaf Ebrahimi     if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
1000*62c56f98SSadaf Ebrahimi         /* Set by mbedtls_ssl_read_record() */
1001*62c56f98SSadaf Ebrahimi         msg_len = ssl->in_hslen;
1002*62c56f98SSadaf Ebrahimi     } else
1003*62c56f98SSadaf Ebrahimi #endif
1004*62c56f98SSadaf Ebrahimi     {
1005*62c56f98SSadaf Ebrahimi         if (ssl->keep_current_message) {
1006*62c56f98SSadaf Ebrahimi             ssl->keep_current_message = 0;
1007*62c56f98SSadaf Ebrahimi         } else {
1008*62c56f98SSadaf Ebrahimi             if (msg_len > MBEDTLS_SSL_IN_CONTENT_LEN) {
1009*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
1010*62c56f98SSadaf Ebrahimi                 return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
1011*62c56f98SSadaf Ebrahimi             }
1012*62c56f98SSadaf Ebrahimi 
1013*62c56f98SSadaf Ebrahimi             if ((ret = mbedtls_ssl_fetch_input(ssl,
1014*62c56f98SSadaf Ebrahimi                                                mbedtls_ssl_in_hdr_len(ssl) + msg_len)) != 0) {
1015*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
1016*62c56f98SSadaf Ebrahimi                 return ret;
1017*62c56f98SSadaf Ebrahimi             }
1018*62c56f98SSadaf Ebrahimi 
1019*62c56f98SSadaf Ebrahimi             /* Done reading this record, get ready for the next one */
1020*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_PROTO_DTLS)
1021*62c56f98SSadaf Ebrahimi             if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
1022*62c56f98SSadaf Ebrahimi                 ssl->next_record_offset = msg_len + mbedtls_ssl_in_hdr_len(ssl);
1023*62c56f98SSadaf Ebrahimi             } else
1024*62c56f98SSadaf Ebrahimi #endif
1025*62c56f98SSadaf Ebrahimi             ssl->in_left = 0;
1026*62c56f98SSadaf Ebrahimi         }
1027*62c56f98SSadaf Ebrahimi     }
1028*62c56f98SSadaf Ebrahimi 
1029*62c56f98SSadaf Ebrahimi     buf = ssl->in_msg;
1030*62c56f98SSadaf Ebrahimi 
1031*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_BUF(4, "record contents", buf, msg_len);
1032*62c56f98SSadaf Ebrahimi 
1033*62c56f98SSadaf Ebrahimi     ret = ssl->handshake->update_checksum(ssl, buf, msg_len);
1034*62c56f98SSadaf Ebrahimi     if (0 != ret) {
1035*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret);
1036*62c56f98SSadaf Ebrahimi         return ret;
1037*62c56f98SSadaf Ebrahimi     }
1038*62c56f98SSadaf Ebrahimi 
1039*62c56f98SSadaf Ebrahimi     /*
1040*62c56f98SSadaf Ebrahimi      * Handshake layer:
1041*62c56f98SSadaf Ebrahimi      *     0  .   0   handshake type
1042*62c56f98SSadaf Ebrahimi      *     1  .   3   handshake length
1043*62c56f98SSadaf Ebrahimi      *     4  .   5   DTLS only: message sequence number
1044*62c56f98SSadaf Ebrahimi      *     6  .   8   DTLS only: fragment offset
1045*62c56f98SSadaf Ebrahimi      *     9  .  11   DTLS only: fragment length
1046*62c56f98SSadaf Ebrahimi      */
1047*62c56f98SSadaf Ebrahimi     if (msg_len < mbedtls_ssl_hs_hdr_len(ssl)) {
1048*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
1049*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
1050*62c56f98SSadaf Ebrahimi     }
1051*62c56f98SSadaf Ebrahimi 
1052*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello v3, handshake type: %d", buf[0]));
1053*62c56f98SSadaf Ebrahimi 
1054*62c56f98SSadaf Ebrahimi     if (buf[0] != MBEDTLS_SSL_HS_CLIENT_HELLO) {
1055*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
1056*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
1057*62c56f98SSadaf Ebrahimi     }
1058*62c56f98SSadaf Ebrahimi     {
1059*62c56f98SSadaf Ebrahimi         size_t handshake_len = MBEDTLS_GET_UINT24_BE(buf, 1);
1060*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(3, ("client hello v3, handshake len.: %u",
1061*62c56f98SSadaf Ebrahimi                                   (unsigned) handshake_len));
1062*62c56f98SSadaf Ebrahimi 
1063*62c56f98SSadaf Ebrahimi         /* The record layer has a record size limit of 2^14 - 1 and
1064*62c56f98SSadaf Ebrahimi          * fragmentation is not supported, so buf[1] should be zero. */
1065*62c56f98SSadaf Ebrahimi         if (buf[1] != 0) {
1066*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message: %u != 0",
1067*62c56f98SSadaf Ebrahimi                                       (unsigned) buf[1]));
1068*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_DECODE_ERROR;
1069*62c56f98SSadaf Ebrahimi         }
1070*62c56f98SSadaf Ebrahimi 
1071*62c56f98SSadaf Ebrahimi         /* We don't support fragmentation of ClientHello (yet?) */
1072*62c56f98SSadaf Ebrahimi         if (msg_len != mbedtls_ssl_hs_hdr_len(ssl) + handshake_len) {
1073*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message: %u != %u + %u",
1074*62c56f98SSadaf Ebrahimi                                       (unsigned) msg_len,
1075*62c56f98SSadaf Ebrahimi                                       (unsigned) mbedtls_ssl_hs_hdr_len(ssl),
1076*62c56f98SSadaf Ebrahimi                                       (unsigned) handshake_len));
1077*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_DECODE_ERROR;
1078*62c56f98SSadaf Ebrahimi         }
1079*62c56f98SSadaf Ebrahimi     }
1080*62c56f98SSadaf Ebrahimi 
1081*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_PROTO_DTLS)
1082*62c56f98SSadaf Ebrahimi     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
1083*62c56f98SSadaf Ebrahimi         /*
1084*62c56f98SSadaf Ebrahimi          * Copy the client's handshake message_seq on initial handshakes,
1085*62c56f98SSadaf Ebrahimi          * check sequence number on renego.
1086*62c56f98SSadaf Ebrahimi          */
1087*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_RENEGOTIATION)
1088*62c56f98SSadaf Ebrahimi         if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
1089*62c56f98SSadaf Ebrahimi             /* This couldn't be done in ssl_prepare_handshake_record() */
1090*62c56f98SSadaf Ebrahimi             unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
1091*62c56f98SSadaf Ebrahimi             if (cli_msg_seq != ssl->handshake->in_msg_seq) {
1092*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message_seq: "
1093*62c56f98SSadaf Ebrahimi                                           "%u (expected %u)", cli_msg_seq,
1094*62c56f98SSadaf Ebrahimi                                           ssl->handshake->in_msg_seq));
1095*62c56f98SSadaf Ebrahimi                 return MBEDTLS_ERR_SSL_DECODE_ERROR;
1096*62c56f98SSadaf Ebrahimi             }
1097*62c56f98SSadaf Ebrahimi 
1098*62c56f98SSadaf Ebrahimi             ssl->handshake->in_msg_seq++;
1099*62c56f98SSadaf Ebrahimi         } else
1100*62c56f98SSadaf Ebrahimi #endif
1101*62c56f98SSadaf Ebrahimi         {
1102*62c56f98SSadaf Ebrahimi             unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
1103*62c56f98SSadaf Ebrahimi             ssl->handshake->out_msg_seq = cli_msg_seq;
1104*62c56f98SSadaf Ebrahimi             ssl->handshake->in_msg_seq  = cli_msg_seq + 1;
1105*62c56f98SSadaf Ebrahimi         }
1106*62c56f98SSadaf Ebrahimi         {
1107*62c56f98SSadaf Ebrahimi             /*
1108*62c56f98SSadaf Ebrahimi              * For now we don't support fragmentation, so make sure
1109*62c56f98SSadaf Ebrahimi              * fragment_offset == 0 and fragment_length == length
1110*62c56f98SSadaf Ebrahimi              */
1111*62c56f98SSadaf Ebrahimi             size_t fragment_offset, fragment_length, length;
1112*62c56f98SSadaf Ebrahimi             fragment_offset = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 6);
1113*62c56f98SSadaf Ebrahimi             fragment_length = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 9);
1114*62c56f98SSadaf Ebrahimi             length = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 1);
1115*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(
1116*62c56f98SSadaf Ebrahimi                 4, ("fragment_offset=%u fragment_length=%u length=%u",
1117*62c56f98SSadaf Ebrahimi                     (unsigned) fragment_offset, (unsigned) fragment_length,
1118*62c56f98SSadaf Ebrahimi                     (unsigned) length));
1119*62c56f98SSadaf Ebrahimi             if (fragment_offset != 0 || length != fragment_length) {
1120*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(1, ("ClientHello fragmentation not supported"));
1121*62c56f98SSadaf Ebrahimi                 return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
1122*62c56f98SSadaf Ebrahimi             }
1123*62c56f98SSadaf Ebrahimi         }
1124*62c56f98SSadaf Ebrahimi     }
1125*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_PROTO_DTLS */
1126*62c56f98SSadaf Ebrahimi 
1127*62c56f98SSadaf Ebrahimi     buf += mbedtls_ssl_hs_hdr_len(ssl);
1128*62c56f98SSadaf Ebrahimi     msg_len -= mbedtls_ssl_hs_hdr_len(ssl);
1129*62c56f98SSadaf Ebrahimi 
1130*62c56f98SSadaf Ebrahimi     /*
1131*62c56f98SSadaf Ebrahimi      * ClientHello layer:
1132*62c56f98SSadaf Ebrahimi      *     0  .   1   protocol version
1133*62c56f98SSadaf Ebrahimi      *     2  .  33   random bytes (starting with 4 bytes of Unix time)
1134*62c56f98SSadaf Ebrahimi      *    34  .  35   session id length (1 byte)
1135*62c56f98SSadaf Ebrahimi      *    35  . 34+x  session id
1136*62c56f98SSadaf Ebrahimi      *   35+x . 35+x  DTLS only: cookie length (1 byte)
1137*62c56f98SSadaf Ebrahimi      *   36+x .  ..   DTLS only: cookie
1138*62c56f98SSadaf Ebrahimi      *    ..  .  ..   ciphersuite list length (2 bytes)
1139*62c56f98SSadaf Ebrahimi      *    ..  .  ..   ciphersuite list
1140*62c56f98SSadaf Ebrahimi      *    ..  .  ..   compression alg. list length (1 byte)
1141*62c56f98SSadaf Ebrahimi      *    ..  .  ..   compression alg. list
1142*62c56f98SSadaf Ebrahimi      *    ..  .  ..   extensions length (2 bytes, optional)
1143*62c56f98SSadaf Ebrahimi      *    ..  .  ..   extensions (optional)
1144*62c56f98SSadaf Ebrahimi      */
1145*62c56f98SSadaf Ebrahimi 
1146*62c56f98SSadaf Ebrahimi     /*
1147*62c56f98SSadaf Ebrahimi      * Minimal length (with everything empty and extensions omitted) is
1148*62c56f98SSadaf Ebrahimi      * 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can
1149*62c56f98SSadaf Ebrahimi      * read at least up to session id length without worrying.
1150*62c56f98SSadaf Ebrahimi      */
1151*62c56f98SSadaf Ebrahimi     if (msg_len < 38) {
1152*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
1153*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
1154*62c56f98SSadaf Ebrahimi     }
1155*62c56f98SSadaf Ebrahimi 
1156*62c56f98SSadaf Ebrahimi     /*
1157*62c56f98SSadaf Ebrahimi      * Check and save the protocol version
1158*62c56f98SSadaf Ebrahimi      */
1159*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, version", buf, 2);
1160*62c56f98SSadaf Ebrahimi 
1161*62c56f98SSadaf Ebrahimi     ssl->tls_version = (mbedtls_ssl_protocol_version) mbedtls_ssl_read_version(buf,
1162*62c56f98SSadaf Ebrahimi                                                                                ssl->conf->transport);
1163*62c56f98SSadaf Ebrahimi     ssl->session_negotiate->tls_version = ssl->tls_version;
1164*62c56f98SSadaf Ebrahimi 
1165*62c56f98SSadaf Ebrahimi     if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_2) {
1166*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("server only supports TLS 1.2"));
1167*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1168*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION);
1169*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
1170*62c56f98SSadaf Ebrahimi     }
1171*62c56f98SSadaf Ebrahimi 
1172*62c56f98SSadaf Ebrahimi     /*
1173*62c56f98SSadaf Ebrahimi      * Save client random (inc. Unix time)
1174*62c56f98SSadaf Ebrahimi      */
1175*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, random bytes", buf + 2, 32);
1176*62c56f98SSadaf Ebrahimi 
1177*62c56f98SSadaf Ebrahimi     memcpy(ssl->handshake->randbytes, buf + 2, 32);
1178*62c56f98SSadaf Ebrahimi 
1179*62c56f98SSadaf Ebrahimi     /*
1180*62c56f98SSadaf Ebrahimi      * Check the session ID length and save session ID
1181*62c56f98SSadaf Ebrahimi      */
1182*62c56f98SSadaf Ebrahimi     sess_len = buf[34];
1183*62c56f98SSadaf Ebrahimi 
1184*62c56f98SSadaf Ebrahimi     if (sess_len > sizeof(ssl->session_negotiate->id) ||
1185*62c56f98SSadaf Ebrahimi         sess_len + 34 + 2 > msg_len) { /* 2 for cipherlist length field */
1186*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
1187*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1188*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
1189*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
1190*62c56f98SSadaf Ebrahimi     }
1191*62c56f98SSadaf Ebrahimi 
1192*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, session id", buf + 35, sess_len);
1193*62c56f98SSadaf Ebrahimi 
1194*62c56f98SSadaf Ebrahimi     ssl->session_negotiate->id_len = sess_len;
1195*62c56f98SSadaf Ebrahimi     memset(ssl->session_negotiate->id, 0,
1196*62c56f98SSadaf Ebrahimi            sizeof(ssl->session_negotiate->id));
1197*62c56f98SSadaf Ebrahimi     memcpy(ssl->session_negotiate->id, buf + 35,
1198*62c56f98SSadaf Ebrahimi            ssl->session_negotiate->id_len);
1199*62c56f98SSadaf Ebrahimi 
1200*62c56f98SSadaf Ebrahimi     /*
1201*62c56f98SSadaf Ebrahimi      * Check the cookie length and content
1202*62c56f98SSadaf Ebrahimi      */
1203*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_PROTO_DTLS)
1204*62c56f98SSadaf Ebrahimi     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
1205*62c56f98SSadaf Ebrahimi         cookie_offset = 35 + sess_len;
1206*62c56f98SSadaf Ebrahimi         cookie_len = buf[cookie_offset];
1207*62c56f98SSadaf Ebrahimi 
1208*62c56f98SSadaf Ebrahimi         if (cookie_offset + 1 + cookie_len + 2 > msg_len) {
1209*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
1210*62c56f98SSadaf Ebrahimi             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1211*62c56f98SSadaf Ebrahimi                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
1212*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_DECODE_ERROR;
1213*62c56f98SSadaf Ebrahimi         }
1214*62c56f98SSadaf Ebrahimi 
1215*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_BUF(3, "client hello, cookie",
1216*62c56f98SSadaf Ebrahimi                               buf + cookie_offset + 1, cookie_len);
1217*62c56f98SSadaf Ebrahimi 
1218*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
1219*62c56f98SSadaf Ebrahimi         if (ssl->conf->f_cookie_check != NULL
1220*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_RENEGOTIATION)
1221*62c56f98SSadaf Ebrahimi             && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE
1222*62c56f98SSadaf Ebrahimi #endif
1223*62c56f98SSadaf Ebrahimi             ) {
1224*62c56f98SSadaf Ebrahimi             if (ssl->conf->f_cookie_check(ssl->conf->p_cookie,
1225*62c56f98SSadaf Ebrahimi                                           buf + cookie_offset + 1, cookie_len,
1226*62c56f98SSadaf Ebrahimi                                           ssl->cli_id, ssl->cli_id_len) != 0) {
1227*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(2, ("cookie verification failed"));
1228*62c56f98SSadaf Ebrahimi                 ssl->handshake->cookie_verify_result = 1;
1229*62c56f98SSadaf Ebrahimi             } else {
1230*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(2, ("cookie verification passed"));
1231*62c56f98SSadaf Ebrahimi                 ssl->handshake->cookie_verify_result = 0;
1232*62c56f98SSadaf Ebrahimi             }
1233*62c56f98SSadaf Ebrahimi         } else
1234*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
1235*62c56f98SSadaf Ebrahimi         {
1236*62c56f98SSadaf Ebrahimi             /* We know we didn't send a cookie, so it should be empty */
1237*62c56f98SSadaf Ebrahimi             if (cookie_len != 0) {
1238*62c56f98SSadaf Ebrahimi                 /* This may be an attacker's probe, so don't send an alert */
1239*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
1240*62c56f98SSadaf Ebrahimi                 return MBEDTLS_ERR_SSL_DECODE_ERROR;
1241*62c56f98SSadaf Ebrahimi             }
1242*62c56f98SSadaf Ebrahimi 
1243*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(2, ("cookie verification skipped"));
1244*62c56f98SSadaf Ebrahimi         }
1245*62c56f98SSadaf Ebrahimi 
1246*62c56f98SSadaf Ebrahimi         /*
1247*62c56f98SSadaf Ebrahimi          * Check the ciphersuitelist length (will be parsed later)
1248*62c56f98SSadaf Ebrahimi          */
1249*62c56f98SSadaf Ebrahimi         ciph_offset = cookie_offset + 1 + cookie_len;
1250*62c56f98SSadaf Ebrahimi     } else
1251*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_PROTO_DTLS */
1252*62c56f98SSadaf Ebrahimi     ciph_offset = 35 + sess_len;
1253*62c56f98SSadaf Ebrahimi 
1254*62c56f98SSadaf Ebrahimi     ciph_len = (buf[ciph_offset + 0] << 8)
1255*62c56f98SSadaf Ebrahimi                | (buf[ciph_offset + 1]);
1256*62c56f98SSadaf Ebrahimi 
1257*62c56f98SSadaf Ebrahimi     if (ciph_len < 2 ||
1258*62c56f98SSadaf Ebrahimi         ciph_len + 2 + ciph_offset + 1 > msg_len || /* 1 for comp. alg. len */
1259*62c56f98SSadaf Ebrahimi         (ciph_len % 2) != 0) {
1260*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
1261*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1262*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
1263*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
1264*62c56f98SSadaf Ebrahimi     }
1265*62c56f98SSadaf Ebrahimi 
1266*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, ciphersuitelist",
1267*62c56f98SSadaf Ebrahimi                           buf + ciph_offset + 2,  ciph_len);
1268*62c56f98SSadaf Ebrahimi 
1269*62c56f98SSadaf Ebrahimi     /*
1270*62c56f98SSadaf Ebrahimi      * Check the compression algorithm's length.
1271*62c56f98SSadaf Ebrahimi      * The list contents are ignored because implementing
1272*62c56f98SSadaf Ebrahimi      * MBEDTLS_SSL_COMPRESS_NULL is mandatory and is the only
1273*62c56f98SSadaf Ebrahimi      * option supported by Mbed TLS.
1274*62c56f98SSadaf Ebrahimi      */
1275*62c56f98SSadaf Ebrahimi     comp_offset = ciph_offset + 2 + ciph_len;
1276*62c56f98SSadaf Ebrahimi 
1277*62c56f98SSadaf Ebrahimi     comp_len = buf[comp_offset];
1278*62c56f98SSadaf Ebrahimi 
1279*62c56f98SSadaf Ebrahimi     if (comp_len < 1 ||
1280*62c56f98SSadaf Ebrahimi         comp_len > 16 ||
1281*62c56f98SSadaf Ebrahimi         comp_len + comp_offset + 1 > msg_len) {
1282*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
1283*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1284*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
1285*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
1286*62c56f98SSadaf Ebrahimi     }
1287*62c56f98SSadaf Ebrahimi 
1288*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, compression",
1289*62c56f98SSadaf Ebrahimi                           buf + comp_offset + 1, comp_len);
1290*62c56f98SSadaf Ebrahimi 
1291*62c56f98SSadaf Ebrahimi     /*
1292*62c56f98SSadaf Ebrahimi      * Check the extension length
1293*62c56f98SSadaf Ebrahimi      */
1294*62c56f98SSadaf Ebrahimi     ext_offset = comp_offset + 1 + comp_len;
1295*62c56f98SSadaf Ebrahimi     if (msg_len > ext_offset) {
1296*62c56f98SSadaf Ebrahimi         if (msg_len < ext_offset + 2) {
1297*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
1298*62c56f98SSadaf Ebrahimi             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1299*62c56f98SSadaf Ebrahimi                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
1300*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_DECODE_ERROR;
1301*62c56f98SSadaf Ebrahimi         }
1302*62c56f98SSadaf Ebrahimi 
1303*62c56f98SSadaf Ebrahimi         ext_len = (buf[ext_offset + 0] << 8)
1304*62c56f98SSadaf Ebrahimi                   | (buf[ext_offset + 1]);
1305*62c56f98SSadaf Ebrahimi 
1306*62c56f98SSadaf Ebrahimi         if (msg_len != ext_offset + 2 + ext_len) {
1307*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
1308*62c56f98SSadaf Ebrahimi             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1309*62c56f98SSadaf Ebrahimi                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
1310*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_DECODE_ERROR;
1311*62c56f98SSadaf Ebrahimi         }
1312*62c56f98SSadaf Ebrahimi     } else {
1313*62c56f98SSadaf Ebrahimi         ext_len = 0;
1314*62c56f98SSadaf Ebrahimi     }
1315*62c56f98SSadaf Ebrahimi 
1316*62c56f98SSadaf Ebrahimi     ext = buf + ext_offset + 2;
1317*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_BUF(3, "client hello extensions", ext, ext_len);
1318*62c56f98SSadaf Ebrahimi 
1319*62c56f98SSadaf Ebrahimi     while (ext_len != 0) {
1320*62c56f98SSadaf Ebrahimi         unsigned int ext_id;
1321*62c56f98SSadaf Ebrahimi         unsigned int ext_size;
1322*62c56f98SSadaf Ebrahimi         if (ext_len < 4) {
1323*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
1324*62c56f98SSadaf Ebrahimi             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1325*62c56f98SSadaf Ebrahimi                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
1326*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_DECODE_ERROR;
1327*62c56f98SSadaf Ebrahimi         }
1328*62c56f98SSadaf Ebrahimi         ext_id   = ((ext[0] <<  8) | (ext[1]));
1329*62c56f98SSadaf Ebrahimi         ext_size = ((ext[2] <<  8) | (ext[3]));
1330*62c56f98SSadaf Ebrahimi 
1331*62c56f98SSadaf Ebrahimi         if (ext_size + 4 > ext_len) {
1332*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
1333*62c56f98SSadaf Ebrahimi             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1334*62c56f98SSadaf Ebrahimi                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
1335*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_DECODE_ERROR;
1336*62c56f98SSadaf Ebrahimi         }
1337*62c56f98SSadaf Ebrahimi         switch (ext_id) {
1338*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
1339*62c56f98SSadaf Ebrahimi             case MBEDTLS_TLS_EXT_SERVERNAME:
1340*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(3, ("found ServerName extension"));
1341*62c56f98SSadaf Ebrahimi                 ret = mbedtls_ssl_parse_server_name_ext(ssl, ext + 4,
1342*62c56f98SSadaf Ebrahimi                                                         ext + 4 + ext_size);
1343*62c56f98SSadaf Ebrahimi                 if (ret != 0) {
1344*62c56f98SSadaf Ebrahimi                     return ret;
1345*62c56f98SSadaf Ebrahimi                 }
1346*62c56f98SSadaf Ebrahimi                 break;
1347*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
1348*62c56f98SSadaf Ebrahimi 
1349*62c56f98SSadaf Ebrahimi             case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
1350*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(3, ("found renegotiation extension"));
1351*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_RENEGOTIATION)
1352*62c56f98SSadaf Ebrahimi                 renegotiation_info_seen = 1;
1353*62c56f98SSadaf Ebrahimi #endif
1354*62c56f98SSadaf Ebrahimi 
1355*62c56f98SSadaf Ebrahimi                 ret = ssl_parse_renegotiation_info(ssl, ext + 4, ext_size);
1356*62c56f98SSadaf Ebrahimi                 if (ret != 0) {
1357*62c56f98SSadaf Ebrahimi                     return ret;
1358*62c56f98SSadaf Ebrahimi                 }
1359*62c56f98SSadaf Ebrahimi                 break;
1360*62c56f98SSadaf Ebrahimi 
1361*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
1362*62c56f98SSadaf Ebrahimi             case MBEDTLS_TLS_EXT_SIG_ALG:
1363*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(3, ("found signature_algorithms extension"));
1364*62c56f98SSadaf Ebrahimi 
1365*62c56f98SSadaf Ebrahimi                 ret = mbedtls_ssl_parse_sig_alg_ext(ssl, ext + 4, ext + 4 + ext_size);
1366*62c56f98SSadaf Ebrahimi                 if (ret != 0) {
1367*62c56f98SSadaf Ebrahimi                     return ret;
1368*62c56f98SSadaf Ebrahimi                 }
1369*62c56f98SSadaf Ebrahimi 
1370*62c56f98SSadaf Ebrahimi                 sig_hash_alg_ext_present = 1;
1371*62c56f98SSadaf Ebrahimi                 break;
1372*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
1373*62c56f98SSadaf Ebrahimi 
1374*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
1375*62c56f98SSadaf Ebrahimi                 defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
1376*62c56f98SSadaf Ebrahimi                 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
1377*62c56f98SSadaf Ebrahimi             case MBEDTLS_TLS_EXT_SUPPORTED_GROUPS:
1378*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(3, ("found supported elliptic curves extension"));
1379*62c56f98SSadaf Ebrahimi 
1380*62c56f98SSadaf Ebrahimi                 ret = ssl_parse_supported_groups_ext(ssl, ext + 4, ext_size);
1381*62c56f98SSadaf Ebrahimi                 if (ret != 0) {
1382*62c56f98SSadaf Ebrahimi                     return ret;
1383*62c56f98SSadaf Ebrahimi                 }
1384*62c56f98SSadaf Ebrahimi                 break;
1385*62c56f98SSadaf Ebrahimi 
1386*62c56f98SSadaf Ebrahimi             case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
1387*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(3, ("found supported point formats extension"));
1388*62c56f98SSadaf Ebrahimi                 ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT;
1389*62c56f98SSadaf Ebrahimi 
1390*62c56f98SSadaf Ebrahimi                 ret = ssl_parse_supported_point_formats(ssl, ext + 4, ext_size);
1391*62c56f98SSadaf Ebrahimi                 if (ret != 0) {
1392*62c56f98SSadaf Ebrahimi                     return ret;
1393*62c56f98SSadaf Ebrahimi                 }
1394*62c56f98SSadaf Ebrahimi                 break;
1395*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || \
1396*62c56f98SSadaf Ebrahimi           MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED ||
1397*62c56f98SSadaf Ebrahimi           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1398*62c56f98SSadaf Ebrahimi 
1399*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
1400*62c56f98SSadaf Ebrahimi             case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
1401*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(3, ("found ecjpake kkpp extension"));
1402*62c56f98SSadaf Ebrahimi 
1403*62c56f98SSadaf Ebrahimi                 ret = ssl_parse_ecjpake_kkpp(ssl, ext + 4, ext_size);
1404*62c56f98SSadaf Ebrahimi                 if (ret != 0) {
1405*62c56f98SSadaf Ebrahimi                     return ret;
1406*62c56f98SSadaf Ebrahimi                 }
1407*62c56f98SSadaf Ebrahimi                 break;
1408*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1409*62c56f98SSadaf Ebrahimi 
1410*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
1411*62c56f98SSadaf Ebrahimi             case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
1412*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(3, ("found max fragment length extension"));
1413*62c56f98SSadaf Ebrahimi 
1414*62c56f98SSadaf Ebrahimi                 ret = ssl_parse_max_fragment_length_ext(ssl, ext + 4, ext_size);
1415*62c56f98SSadaf Ebrahimi                 if (ret != 0) {
1416*62c56f98SSadaf Ebrahimi                     return ret;
1417*62c56f98SSadaf Ebrahimi                 }
1418*62c56f98SSadaf Ebrahimi                 break;
1419*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
1420*62c56f98SSadaf Ebrahimi 
1421*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
1422*62c56f98SSadaf Ebrahimi             case MBEDTLS_TLS_EXT_CID:
1423*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(3, ("found CID extension"));
1424*62c56f98SSadaf Ebrahimi 
1425*62c56f98SSadaf Ebrahimi                 ret = ssl_parse_cid_ext(ssl, ext + 4, ext_size);
1426*62c56f98SSadaf Ebrahimi                 if (ret != 0) {
1427*62c56f98SSadaf Ebrahimi                     return ret;
1428*62c56f98SSadaf Ebrahimi                 }
1429*62c56f98SSadaf Ebrahimi                 break;
1430*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
1431*62c56f98SSadaf Ebrahimi 
1432*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
1433*62c56f98SSadaf Ebrahimi             case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
1434*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(3, ("found encrypt then mac extension"));
1435*62c56f98SSadaf Ebrahimi 
1436*62c56f98SSadaf Ebrahimi                 ret = ssl_parse_encrypt_then_mac_ext(ssl, ext + 4, ext_size);
1437*62c56f98SSadaf Ebrahimi                 if (ret != 0) {
1438*62c56f98SSadaf Ebrahimi                     return ret;
1439*62c56f98SSadaf Ebrahimi                 }
1440*62c56f98SSadaf Ebrahimi                 break;
1441*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
1442*62c56f98SSadaf Ebrahimi 
1443*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
1444*62c56f98SSadaf Ebrahimi             case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
1445*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(3, ("found extended master secret extension"));
1446*62c56f98SSadaf Ebrahimi 
1447*62c56f98SSadaf Ebrahimi                 ret = ssl_parse_extended_ms_ext(ssl, ext + 4, ext_size);
1448*62c56f98SSadaf Ebrahimi                 if (ret != 0) {
1449*62c56f98SSadaf Ebrahimi                     return ret;
1450*62c56f98SSadaf Ebrahimi                 }
1451*62c56f98SSadaf Ebrahimi                 break;
1452*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
1453*62c56f98SSadaf Ebrahimi 
1454*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_SESSION_TICKETS)
1455*62c56f98SSadaf Ebrahimi             case MBEDTLS_TLS_EXT_SESSION_TICKET:
1456*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(3, ("found session ticket extension"));
1457*62c56f98SSadaf Ebrahimi 
1458*62c56f98SSadaf Ebrahimi                 ret = ssl_parse_session_ticket_ext(ssl, ext + 4, ext_size);
1459*62c56f98SSadaf Ebrahimi                 if (ret != 0) {
1460*62c56f98SSadaf Ebrahimi                     return ret;
1461*62c56f98SSadaf Ebrahimi                 }
1462*62c56f98SSadaf Ebrahimi                 break;
1463*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_SESSION_TICKETS */
1464*62c56f98SSadaf Ebrahimi 
1465*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_ALPN)
1466*62c56f98SSadaf Ebrahimi             case MBEDTLS_TLS_EXT_ALPN:
1467*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(3, ("found alpn extension"));
1468*62c56f98SSadaf Ebrahimi 
1469*62c56f98SSadaf Ebrahimi                 ret = mbedtls_ssl_parse_alpn_ext(ssl, ext + 4,
1470*62c56f98SSadaf Ebrahimi                                                  ext + 4 + ext_size);
1471*62c56f98SSadaf Ebrahimi                 if (ret != 0) {
1472*62c56f98SSadaf Ebrahimi                     return ret;
1473*62c56f98SSadaf Ebrahimi                 }
1474*62c56f98SSadaf Ebrahimi                 break;
1475*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_SESSION_TICKETS */
1476*62c56f98SSadaf Ebrahimi 
1477*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_DTLS_SRTP)
1478*62c56f98SSadaf Ebrahimi             case MBEDTLS_TLS_EXT_USE_SRTP:
1479*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(3, ("found use_srtp extension"));
1480*62c56f98SSadaf Ebrahimi 
1481*62c56f98SSadaf Ebrahimi                 ret = ssl_parse_use_srtp_ext(ssl, ext + 4, ext_size);
1482*62c56f98SSadaf Ebrahimi                 if (ret != 0) {
1483*62c56f98SSadaf Ebrahimi                     return ret;
1484*62c56f98SSadaf Ebrahimi                 }
1485*62c56f98SSadaf Ebrahimi                 break;
1486*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_DTLS_SRTP */
1487*62c56f98SSadaf Ebrahimi 
1488*62c56f98SSadaf Ebrahimi             default:
1489*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(3, ("unknown extension found: %u (ignoring)",
1490*62c56f98SSadaf Ebrahimi                                           ext_id));
1491*62c56f98SSadaf Ebrahimi         }
1492*62c56f98SSadaf Ebrahimi 
1493*62c56f98SSadaf Ebrahimi         ext_len -= 4 + ext_size;
1494*62c56f98SSadaf Ebrahimi         ext += 4 + ext_size;
1495*62c56f98SSadaf Ebrahimi     }
1496*62c56f98SSadaf Ebrahimi 
1497*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
1498*62c56f98SSadaf Ebrahimi 
1499*62c56f98SSadaf Ebrahimi     /*
1500*62c56f98SSadaf Ebrahimi      * Try to fall back to default hash SHA1 if the client
1501*62c56f98SSadaf Ebrahimi      * hasn't provided any preferred signature-hash combinations.
1502*62c56f98SSadaf Ebrahimi      */
1503*62c56f98SSadaf Ebrahimi     if (!sig_hash_alg_ext_present) {
1504*62c56f98SSadaf Ebrahimi         uint16_t *received_sig_algs = ssl->handshake->received_sig_algs;
1505*62c56f98SSadaf Ebrahimi         const uint16_t default_sig_algs[] = {
1506*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
1507*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA,
1508*62c56f98SSadaf Ebrahimi                                                MBEDTLS_SSL_HASH_SHA1),
1509*62c56f98SSadaf Ebrahimi #endif
1510*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_RSA_C)
1511*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA,
1512*62c56f98SSadaf Ebrahimi                                                MBEDTLS_SSL_HASH_SHA1),
1513*62c56f98SSadaf Ebrahimi #endif
1514*62c56f98SSadaf Ebrahimi             MBEDTLS_TLS_SIG_NONE
1515*62c56f98SSadaf Ebrahimi         };
1516*62c56f98SSadaf Ebrahimi 
1517*62c56f98SSadaf Ebrahimi         MBEDTLS_STATIC_ASSERT(sizeof(default_sig_algs) / sizeof(default_sig_algs[0])
1518*62c56f98SSadaf Ebrahimi                               <= MBEDTLS_RECEIVED_SIG_ALGS_SIZE,
1519*62c56f98SSadaf Ebrahimi                               "default_sig_algs is too big");
1520*62c56f98SSadaf Ebrahimi 
1521*62c56f98SSadaf Ebrahimi         memcpy(received_sig_algs, default_sig_algs, sizeof(default_sig_algs));
1522*62c56f98SSadaf Ebrahimi     }
1523*62c56f98SSadaf Ebrahimi 
1524*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
1525*62c56f98SSadaf Ebrahimi 
1526*62c56f98SSadaf Ebrahimi     /*
1527*62c56f98SSadaf Ebrahimi      * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
1528*62c56f98SSadaf Ebrahimi      */
1529*62c56f98SSadaf Ebrahimi     for (i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2) {
1530*62c56f98SSadaf Ebrahimi         if (p[0] == 0 && p[1] == MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO) {
1531*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(3, ("received TLS_EMPTY_RENEGOTIATION_INFO "));
1532*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_RENEGOTIATION)
1533*62c56f98SSadaf Ebrahimi             if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
1534*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(1, ("received RENEGOTIATION SCSV "
1535*62c56f98SSadaf Ebrahimi                                           "during renegotiation"));
1536*62c56f98SSadaf Ebrahimi                 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1537*62c56f98SSadaf Ebrahimi                                                MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
1538*62c56f98SSadaf Ebrahimi                 return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
1539*62c56f98SSadaf Ebrahimi             }
1540*62c56f98SSadaf Ebrahimi #endif
1541*62c56f98SSadaf Ebrahimi             ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
1542*62c56f98SSadaf Ebrahimi             break;
1543*62c56f98SSadaf Ebrahimi         }
1544*62c56f98SSadaf Ebrahimi     }
1545*62c56f98SSadaf Ebrahimi 
1546*62c56f98SSadaf Ebrahimi     /*
1547*62c56f98SSadaf Ebrahimi      * Renegotiation security checks
1548*62c56f98SSadaf Ebrahimi      */
1549*62c56f98SSadaf Ebrahimi     if (ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION &&
1550*62c56f98SSadaf Ebrahimi         ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE) {
1551*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("legacy renegotiation, breaking off handshake"));
1552*62c56f98SSadaf Ebrahimi         handshake_failure = 1;
1553*62c56f98SSadaf Ebrahimi     }
1554*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_RENEGOTIATION)
1555*62c56f98SSadaf Ebrahimi     else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1556*62c56f98SSadaf Ebrahimi              ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION &&
1557*62c56f98SSadaf Ebrahimi              renegotiation_info_seen == 0) {
1558*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("renegotiation_info extension missing (secure)"));
1559*62c56f98SSadaf Ebrahimi         handshake_failure = 1;
1560*62c56f98SSadaf Ebrahimi     } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1561*62c56f98SSadaf Ebrahimi                ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
1562*62c56f98SSadaf Ebrahimi                ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION) {
1563*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("legacy renegotiation not allowed"));
1564*62c56f98SSadaf Ebrahimi         handshake_failure = 1;
1565*62c56f98SSadaf Ebrahimi     } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
1566*62c56f98SSadaf Ebrahimi                ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
1567*62c56f98SSadaf Ebrahimi                renegotiation_info_seen == 1) {
1568*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("renegotiation_info extension present (legacy)"));
1569*62c56f98SSadaf Ebrahimi         handshake_failure = 1;
1570*62c56f98SSadaf Ebrahimi     }
1571*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_RENEGOTIATION */
1572*62c56f98SSadaf Ebrahimi 
1573*62c56f98SSadaf Ebrahimi     if (handshake_failure == 1) {
1574*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1575*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
1576*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
1577*62c56f98SSadaf Ebrahimi     }
1578*62c56f98SSadaf Ebrahimi 
1579*62c56f98SSadaf Ebrahimi     /*
1580*62c56f98SSadaf Ebrahimi      * Server certification selection (after processing TLS extensions)
1581*62c56f98SSadaf Ebrahimi      */
1582*62c56f98SSadaf Ebrahimi     if (ssl->conf->f_cert_cb && (ret = ssl->conf->f_cert_cb(ssl)) != 0) {
1583*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, "f_cert_cb", ret);
1584*62c56f98SSadaf Ebrahimi         return ret;
1585*62c56f98SSadaf Ebrahimi     }
1586*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
1587*62c56f98SSadaf Ebrahimi     ssl->handshake->sni_name = NULL;
1588*62c56f98SSadaf Ebrahimi     ssl->handshake->sni_name_len = 0;
1589*62c56f98SSadaf Ebrahimi #endif
1590*62c56f98SSadaf Ebrahimi 
1591*62c56f98SSadaf Ebrahimi     /*
1592*62c56f98SSadaf Ebrahimi      * Search for a matching ciphersuite
1593*62c56f98SSadaf Ebrahimi      * (At the end because we need information from the EC-based extensions
1594*62c56f98SSadaf Ebrahimi      * and certificate from the SNI callback triggered by the SNI extension
1595*62c56f98SSadaf Ebrahimi      * or certificate from server certificate selection callback.)
1596*62c56f98SSadaf Ebrahimi      */
1597*62c56f98SSadaf Ebrahimi     got_common_suite = 0;
1598*62c56f98SSadaf Ebrahimi     ciphersuites = ssl->conf->ciphersuite_list;
1599*62c56f98SSadaf Ebrahimi     ciphersuite_info = NULL;
1600*62c56f98SSadaf Ebrahimi 
1601*62c56f98SSadaf Ebrahimi     if (ssl->conf->respect_cli_pref == MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT) {
1602*62c56f98SSadaf Ebrahimi         for (j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2) {
1603*62c56f98SSadaf Ebrahimi             for (i = 0; ciphersuites[i] != 0; i++) {
1604*62c56f98SSadaf Ebrahimi                 if (MBEDTLS_GET_UINT16_BE(p, 0) != ciphersuites[i]) {
1605*62c56f98SSadaf Ebrahimi                     continue;
1606*62c56f98SSadaf Ebrahimi                 }
1607*62c56f98SSadaf Ebrahimi 
1608*62c56f98SSadaf Ebrahimi                 got_common_suite = 1;
1609*62c56f98SSadaf Ebrahimi 
1610*62c56f98SSadaf Ebrahimi                 if ((ret = ssl_ciphersuite_match(ssl, ciphersuites[i],
1611*62c56f98SSadaf Ebrahimi                                                  &ciphersuite_info)) != 0) {
1612*62c56f98SSadaf Ebrahimi                     return ret;
1613*62c56f98SSadaf Ebrahimi                 }
1614*62c56f98SSadaf Ebrahimi 
1615*62c56f98SSadaf Ebrahimi                 if (ciphersuite_info != NULL) {
1616*62c56f98SSadaf Ebrahimi                     goto have_ciphersuite;
1617*62c56f98SSadaf Ebrahimi                 }
1618*62c56f98SSadaf Ebrahimi             }
1619*62c56f98SSadaf Ebrahimi         }
1620*62c56f98SSadaf Ebrahimi     } else {
1621*62c56f98SSadaf Ebrahimi         for (i = 0; ciphersuites[i] != 0; i++) {
1622*62c56f98SSadaf Ebrahimi             for (j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2) {
1623*62c56f98SSadaf Ebrahimi                 if (MBEDTLS_GET_UINT16_BE(p, 0) != ciphersuites[i]) {
1624*62c56f98SSadaf Ebrahimi                     continue;
1625*62c56f98SSadaf Ebrahimi                 }
1626*62c56f98SSadaf Ebrahimi 
1627*62c56f98SSadaf Ebrahimi                 got_common_suite = 1;
1628*62c56f98SSadaf Ebrahimi 
1629*62c56f98SSadaf Ebrahimi                 if ((ret = ssl_ciphersuite_match(ssl, ciphersuites[i],
1630*62c56f98SSadaf Ebrahimi                                                  &ciphersuite_info)) != 0) {
1631*62c56f98SSadaf Ebrahimi                     return ret;
1632*62c56f98SSadaf Ebrahimi                 }
1633*62c56f98SSadaf Ebrahimi 
1634*62c56f98SSadaf Ebrahimi                 if (ciphersuite_info != NULL) {
1635*62c56f98SSadaf Ebrahimi                     goto have_ciphersuite;
1636*62c56f98SSadaf Ebrahimi                 }
1637*62c56f98SSadaf Ebrahimi             }
1638*62c56f98SSadaf Ebrahimi         }
1639*62c56f98SSadaf Ebrahimi     }
1640*62c56f98SSadaf Ebrahimi 
1641*62c56f98SSadaf Ebrahimi     if (got_common_suite) {
1642*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("got ciphersuites in common, "
1643*62c56f98SSadaf Ebrahimi                                   "but none of them usable"));
1644*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1645*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
1646*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
1647*62c56f98SSadaf Ebrahimi     } else {
1648*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("got no ciphersuites in common"));
1649*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
1650*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
1651*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
1652*62c56f98SSadaf Ebrahimi     }
1653*62c56f98SSadaf Ebrahimi 
1654*62c56f98SSadaf Ebrahimi have_ciphersuite:
1655*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("selected ciphersuite: %s", ciphersuite_info->name));
1656*62c56f98SSadaf Ebrahimi 
1657*62c56f98SSadaf Ebrahimi     ssl->session_negotiate->ciphersuite = ciphersuites[i];
1658*62c56f98SSadaf Ebrahimi     ssl->handshake->ciphersuite_info = ciphersuite_info;
1659*62c56f98SSadaf Ebrahimi 
1660*62c56f98SSadaf Ebrahimi     ssl->state++;
1661*62c56f98SSadaf Ebrahimi 
1662*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_PROTO_DTLS)
1663*62c56f98SSadaf Ebrahimi     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
1664*62c56f98SSadaf Ebrahimi         mbedtls_ssl_recv_flight_completed(ssl);
1665*62c56f98SSadaf Ebrahimi     }
1666*62c56f98SSadaf Ebrahimi #endif
1667*62c56f98SSadaf Ebrahimi 
1668*62c56f98SSadaf Ebrahimi     /* Debugging-only output for testsuite */
1669*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_DEBUG_C)                         && \
1670*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
1671*62c56f98SSadaf Ebrahimi     mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_alg(ciphersuite_info);
1672*62c56f98SSadaf Ebrahimi     if (sig_alg != MBEDTLS_PK_NONE) {
1673*62c56f98SSadaf Ebrahimi         unsigned int sig_hash = mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
1674*62c56f98SSadaf Ebrahimi             ssl, mbedtls_ssl_sig_from_pk_alg(sig_alg));
1675*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(3, ("client hello v3, signature_algorithm ext: %u",
1676*62c56f98SSadaf Ebrahimi                                   sig_hash));
1677*62c56f98SSadaf Ebrahimi     } else {
1678*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(3, ("no hash algorithm for signature algorithm "
1679*62c56f98SSadaf Ebrahimi                                   "%u - should not happen", (unsigned) sig_alg));
1680*62c56f98SSadaf Ebrahimi     }
1681*62c56f98SSadaf Ebrahimi #endif
1682*62c56f98SSadaf Ebrahimi 
1683*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse client hello"));
1684*62c56f98SSadaf Ebrahimi 
1685*62c56f98SSadaf Ebrahimi     return 0;
1686*62c56f98SSadaf Ebrahimi }
1687*62c56f98SSadaf Ebrahimi 
1688*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
ssl_write_cid_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t * olen)1689*62c56f98SSadaf Ebrahimi static void ssl_write_cid_ext(mbedtls_ssl_context *ssl,
1690*62c56f98SSadaf Ebrahimi                               unsigned char *buf,
1691*62c56f98SSadaf Ebrahimi                               size_t *olen)
1692*62c56f98SSadaf Ebrahimi {
1693*62c56f98SSadaf Ebrahimi     unsigned char *p = buf;
1694*62c56f98SSadaf Ebrahimi     size_t ext_len;
1695*62c56f98SSadaf Ebrahimi     const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
1696*62c56f98SSadaf Ebrahimi 
1697*62c56f98SSadaf Ebrahimi     *olen = 0;
1698*62c56f98SSadaf Ebrahimi 
1699*62c56f98SSadaf Ebrahimi     /* Skip writing the extension if we don't want to use it or if
1700*62c56f98SSadaf Ebrahimi      * the client hasn't offered it. */
1701*62c56f98SSadaf Ebrahimi     if (ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_DISABLED) {
1702*62c56f98SSadaf Ebrahimi         return;
1703*62c56f98SSadaf Ebrahimi     }
1704*62c56f98SSadaf Ebrahimi 
1705*62c56f98SSadaf Ebrahimi     /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX
1706*62c56f98SSadaf Ebrahimi      * which is at most 255, so the increment cannot overflow. */
1707*62c56f98SSadaf Ebrahimi     if (end < p || (size_t) (end - p) < (unsigned) (ssl->own_cid_len + 5)) {
1708*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small"));
1709*62c56f98SSadaf Ebrahimi         return;
1710*62c56f98SSadaf Ebrahimi     }
1711*62c56f98SSadaf Ebrahimi 
1712*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding CID extension"));
1713*62c56f98SSadaf Ebrahimi 
1714*62c56f98SSadaf Ebrahimi     /*
1715*62c56f98SSadaf Ebrahimi      *   struct {
1716*62c56f98SSadaf Ebrahimi      *      opaque cid<0..2^8-1>;
1717*62c56f98SSadaf Ebrahimi      *   } ConnectionId;
1718*62c56f98SSadaf Ebrahimi      */
1719*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_CID, p, 0);
1720*62c56f98SSadaf Ebrahimi     p += 2;
1721*62c56f98SSadaf Ebrahimi     ext_len = (size_t) ssl->own_cid_len + 1;
1722*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT16_BE(ext_len, p, 0);
1723*62c56f98SSadaf Ebrahimi     p += 2;
1724*62c56f98SSadaf Ebrahimi 
1725*62c56f98SSadaf Ebrahimi     *p++ = (uint8_t) ssl->own_cid_len;
1726*62c56f98SSadaf Ebrahimi     memcpy(p, ssl->own_cid, ssl->own_cid_len);
1727*62c56f98SSadaf Ebrahimi 
1728*62c56f98SSadaf Ebrahimi     *olen = ssl->own_cid_len + 5;
1729*62c56f98SSadaf Ebrahimi }
1730*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
1731*62c56f98SSadaf Ebrahimi 
1732*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM)
ssl_write_encrypt_then_mac_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t * olen)1733*62c56f98SSadaf Ebrahimi static void ssl_write_encrypt_then_mac_ext(mbedtls_ssl_context *ssl,
1734*62c56f98SSadaf Ebrahimi                                            unsigned char *buf,
1735*62c56f98SSadaf Ebrahimi                                            size_t *olen)
1736*62c56f98SSadaf Ebrahimi {
1737*62c56f98SSadaf Ebrahimi     unsigned char *p = buf;
1738*62c56f98SSadaf Ebrahimi     const mbedtls_ssl_ciphersuite_t *suite = NULL;
1739*62c56f98SSadaf Ebrahimi 
1740*62c56f98SSadaf Ebrahimi     /*
1741*62c56f98SSadaf Ebrahimi      * RFC 7366: "If a server receives an encrypt-then-MAC request extension
1742*62c56f98SSadaf Ebrahimi      * from a client and then selects a stream or Authenticated Encryption
1743*62c56f98SSadaf Ebrahimi      * with Associated Data (AEAD) ciphersuite, it MUST NOT send an
1744*62c56f98SSadaf Ebrahimi      * encrypt-then-MAC response extension back to the client."
1745*62c56f98SSadaf Ebrahimi      */
1746*62c56f98SSadaf Ebrahimi     suite = mbedtls_ssl_ciphersuite_from_id(
1747*62c56f98SSadaf Ebrahimi         ssl->session_negotiate->ciphersuite);
1748*62c56f98SSadaf Ebrahimi     if (suite == NULL) {
1749*62c56f98SSadaf Ebrahimi         ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_DISABLED;
1750*62c56f98SSadaf Ebrahimi     } else {
1751*62c56f98SSadaf Ebrahimi         mbedtls_ssl_mode_t ssl_mode =
1752*62c56f98SSadaf Ebrahimi             mbedtls_ssl_get_mode_from_ciphersuite(
1753*62c56f98SSadaf Ebrahimi                 ssl->session_negotiate->encrypt_then_mac,
1754*62c56f98SSadaf Ebrahimi                 suite);
1755*62c56f98SSadaf Ebrahimi 
1756*62c56f98SSadaf Ebrahimi         if (ssl_mode != MBEDTLS_SSL_MODE_CBC_ETM) {
1757*62c56f98SSadaf Ebrahimi             ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_DISABLED;
1758*62c56f98SSadaf Ebrahimi         }
1759*62c56f98SSadaf Ebrahimi     }
1760*62c56f98SSadaf Ebrahimi 
1761*62c56f98SSadaf Ebrahimi     if (ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED) {
1762*62c56f98SSadaf Ebrahimi         *olen = 0;
1763*62c56f98SSadaf Ebrahimi         return;
1764*62c56f98SSadaf Ebrahimi     }
1765*62c56f98SSadaf Ebrahimi 
1766*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding encrypt then mac extension"));
1767*62c56f98SSadaf Ebrahimi 
1768*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, p, 0);
1769*62c56f98SSadaf Ebrahimi     p += 2;
1770*62c56f98SSadaf Ebrahimi 
1771*62c56f98SSadaf Ebrahimi     *p++ = 0x00;
1772*62c56f98SSadaf Ebrahimi     *p++ = 0x00;
1773*62c56f98SSadaf Ebrahimi 
1774*62c56f98SSadaf Ebrahimi     *olen = 4;
1775*62c56f98SSadaf Ebrahimi }
1776*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */
1777*62c56f98SSadaf Ebrahimi 
1778*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
ssl_write_extended_ms_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t * olen)1779*62c56f98SSadaf Ebrahimi static void ssl_write_extended_ms_ext(mbedtls_ssl_context *ssl,
1780*62c56f98SSadaf Ebrahimi                                       unsigned char *buf,
1781*62c56f98SSadaf Ebrahimi                                       size_t *olen)
1782*62c56f98SSadaf Ebrahimi {
1783*62c56f98SSadaf Ebrahimi     unsigned char *p = buf;
1784*62c56f98SSadaf Ebrahimi 
1785*62c56f98SSadaf Ebrahimi     if (ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED) {
1786*62c56f98SSadaf Ebrahimi         *olen = 0;
1787*62c56f98SSadaf Ebrahimi         return;
1788*62c56f98SSadaf Ebrahimi     }
1789*62c56f98SSadaf Ebrahimi 
1790*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding extended master secret "
1791*62c56f98SSadaf Ebrahimi                               "extension"));
1792*62c56f98SSadaf Ebrahimi 
1793*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, p, 0);
1794*62c56f98SSadaf Ebrahimi     p += 2;
1795*62c56f98SSadaf Ebrahimi 
1796*62c56f98SSadaf Ebrahimi     *p++ = 0x00;
1797*62c56f98SSadaf Ebrahimi     *p++ = 0x00;
1798*62c56f98SSadaf Ebrahimi 
1799*62c56f98SSadaf Ebrahimi     *olen = 4;
1800*62c56f98SSadaf Ebrahimi }
1801*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
1802*62c56f98SSadaf Ebrahimi 
1803*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_SESSION_TICKETS)
ssl_write_session_ticket_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t * olen)1804*62c56f98SSadaf Ebrahimi static void ssl_write_session_ticket_ext(mbedtls_ssl_context *ssl,
1805*62c56f98SSadaf Ebrahimi                                          unsigned char *buf,
1806*62c56f98SSadaf Ebrahimi                                          size_t *olen)
1807*62c56f98SSadaf Ebrahimi {
1808*62c56f98SSadaf Ebrahimi     unsigned char *p = buf;
1809*62c56f98SSadaf Ebrahimi 
1810*62c56f98SSadaf Ebrahimi     if (ssl->handshake->new_session_ticket == 0) {
1811*62c56f98SSadaf Ebrahimi         *olen = 0;
1812*62c56f98SSadaf Ebrahimi         return;
1813*62c56f98SSadaf Ebrahimi     }
1814*62c56f98SSadaf Ebrahimi 
1815*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding session ticket extension"));
1816*62c56f98SSadaf Ebrahimi 
1817*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SESSION_TICKET, p, 0);
1818*62c56f98SSadaf Ebrahimi     p += 2;
1819*62c56f98SSadaf Ebrahimi 
1820*62c56f98SSadaf Ebrahimi     *p++ = 0x00;
1821*62c56f98SSadaf Ebrahimi     *p++ = 0x00;
1822*62c56f98SSadaf Ebrahimi 
1823*62c56f98SSadaf Ebrahimi     *olen = 4;
1824*62c56f98SSadaf Ebrahimi }
1825*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_SESSION_TICKETS */
1826*62c56f98SSadaf Ebrahimi 
ssl_write_renegotiation_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t * olen)1827*62c56f98SSadaf Ebrahimi static void ssl_write_renegotiation_ext(mbedtls_ssl_context *ssl,
1828*62c56f98SSadaf Ebrahimi                                         unsigned char *buf,
1829*62c56f98SSadaf Ebrahimi                                         size_t *olen)
1830*62c56f98SSadaf Ebrahimi {
1831*62c56f98SSadaf Ebrahimi     unsigned char *p = buf;
1832*62c56f98SSadaf Ebrahimi 
1833*62c56f98SSadaf Ebrahimi     if (ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION) {
1834*62c56f98SSadaf Ebrahimi         *olen = 0;
1835*62c56f98SSadaf Ebrahimi         return;
1836*62c56f98SSadaf Ebrahimi     }
1837*62c56f98SSadaf Ebrahimi 
1838*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, secure renegotiation extension"));
1839*62c56f98SSadaf Ebrahimi 
1840*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_RENEGOTIATION_INFO, p, 0);
1841*62c56f98SSadaf Ebrahimi     p += 2;
1842*62c56f98SSadaf Ebrahimi 
1843*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_RENEGOTIATION)
1844*62c56f98SSadaf Ebrahimi     if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
1845*62c56f98SSadaf Ebrahimi         *p++ = 0x00;
1846*62c56f98SSadaf Ebrahimi         *p++ = (ssl->verify_data_len * 2 + 1) & 0xFF;
1847*62c56f98SSadaf Ebrahimi         *p++ = ssl->verify_data_len * 2 & 0xFF;
1848*62c56f98SSadaf Ebrahimi 
1849*62c56f98SSadaf Ebrahimi         memcpy(p, ssl->peer_verify_data, ssl->verify_data_len);
1850*62c56f98SSadaf Ebrahimi         p += ssl->verify_data_len;
1851*62c56f98SSadaf Ebrahimi         memcpy(p, ssl->own_verify_data, ssl->verify_data_len);
1852*62c56f98SSadaf Ebrahimi         p += ssl->verify_data_len;
1853*62c56f98SSadaf Ebrahimi     } else
1854*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_RENEGOTIATION */
1855*62c56f98SSadaf Ebrahimi     {
1856*62c56f98SSadaf Ebrahimi         *p++ = 0x00;
1857*62c56f98SSadaf Ebrahimi         *p++ = 0x01;
1858*62c56f98SSadaf Ebrahimi         *p++ = 0x00;
1859*62c56f98SSadaf Ebrahimi     }
1860*62c56f98SSadaf Ebrahimi 
1861*62c56f98SSadaf Ebrahimi     *olen = p - buf;
1862*62c56f98SSadaf Ebrahimi }
1863*62c56f98SSadaf Ebrahimi 
1864*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
ssl_write_max_fragment_length_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t * olen)1865*62c56f98SSadaf Ebrahimi static void ssl_write_max_fragment_length_ext(mbedtls_ssl_context *ssl,
1866*62c56f98SSadaf Ebrahimi                                               unsigned char *buf,
1867*62c56f98SSadaf Ebrahimi                                               size_t *olen)
1868*62c56f98SSadaf Ebrahimi {
1869*62c56f98SSadaf Ebrahimi     unsigned char *p = buf;
1870*62c56f98SSadaf Ebrahimi 
1871*62c56f98SSadaf Ebrahimi     if (ssl->session_negotiate->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE) {
1872*62c56f98SSadaf Ebrahimi         *olen = 0;
1873*62c56f98SSadaf Ebrahimi         return;
1874*62c56f98SSadaf Ebrahimi     }
1875*62c56f98SSadaf Ebrahimi 
1876*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, max_fragment_length extension"));
1877*62c56f98SSadaf Ebrahimi 
1878*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, p, 0);
1879*62c56f98SSadaf Ebrahimi     p += 2;
1880*62c56f98SSadaf Ebrahimi 
1881*62c56f98SSadaf Ebrahimi     *p++ = 0x00;
1882*62c56f98SSadaf Ebrahimi     *p++ = 1;
1883*62c56f98SSadaf Ebrahimi 
1884*62c56f98SSadaf Ebrahimi     *p++ = ssl->session_negotiate->mfl_code;
1885*62c56f98SSadaf Ebrahimi 
1886*62c56f98SSadaf Ebrahimi     *olen = 5;
1887*62c56f98SSadaf Ebrahimi }
1888*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
1889*62c56f98SSadaf Ebrahimi 
1890*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
1891*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
1892*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ssl_write_supported_point_formats_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t * olen)1893*62c56f98SSadaf Ebrahimi static void ssl_write_supported_point_formats_ext(mbedtls_ssl_context *ssl,
1894*62c56f98SSadaf Ebrahimi                                                   unsigned char *buf,
1895*62c56f98SSadaf Ebrahimi                                                   size_t *olen)
1896*62c56f98SSadaf Ebrahimi {
1897*62c56f98SSadaf Ebrahimi     unsigned char *p = buf;
1898*62c56f98SSadaf Ebrahimi     ((void) ssl);
1899*62c56f98SSadaf Ebrahimi 
1900*62c56f98SSadaf Ebrahimi     if ((ssl->handshake->cli_exts &
1901*62c56f98SSadaf Ebrahimi          MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT) == 0) {
1902*62c56f98SSadaf Ebrahimi         *olen = 0;
1903*62c56f98SSadaf Ebrahimi         return;
1904*62c56f98SSadaf Ebrahimi     }
1905*62c56f98SSadaf Ebrahimi 
1906*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, supported_point_formats extension"));
1907*62c56f98SSadaf Ebrahimi 
1908*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, p, 0);
1909*62c56f98SSadaf Ebrahimi     p += 2;
1910*62c56f98SSadaf Ebrahimi 
1911*62c56f98SSadaf Ebrahimi     *p++ = 0x00;
1912*62c56f98SSadaf Ebrahimi     *p++ = 2;
1913*62c56f98SSadaf Ebrahimi 
1914*62c56f98SSadaf Ebrahimi     *p++ = 1;
1915*62c56f98SSadaf Ebrahimi     *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED;
1916*62c56f98SSadaf Ebrahimi 
1917*62c56f98SSadaf Ebrahimi     *olen = 6;
1918*62c56f98SSadaf Ebrahimi }
1919*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED ||
1920*62c56f98SSadaf Ebrahimi           MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED ||
1921*62c56f98SSadaf Ebrahimi           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1922*62c56f98SSadaf Ebrahimi 
1923*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t * olen)1924*62c56f98SSadaf Ebrahimi static void ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl,
1925*62c56f98SSadaf Ebrahimi                                        unsigned char *buf,
1926*62c56f98SSadaf Ebrahimi                                        size_t *olen)
1927*62c56f98SSadaf Ebrahimi {
1928*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1929*62c56f98SSadaf Ebrahimi     unsigned char *p = buf;
1930*62c56f98SSadaf Ebrahimi     const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
1931*62c56f98SSadaf Ebrahimi     size_t kkpp_len;
1932*62c56f98SSadaf Ebrahimi 
1933*62c56f98SSadaf Ebrahimi     *olen = 0;
1934*62c56f98SSadaf Ebrahimi 
1935*62c56f98SSadaf Ebrahimi     /* Skip costly computation if not needed */
1936*62c56f98SSadaf Ebrahimi     if (ssl->handshake->ciphersuite_info->key_exchange !=
1937*62c56f98SSadaf Ebrahimi         MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
1938*62c56f98SSadaf Ebrahimi         return;
1939*62c56f98SSadaf Ebrahimi     }
1940*62c56f98SSadaf Ebrahimi 
1941*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, ecjpake kkpp extension"));
1942*62c56f98SSadaf Ebrahimi 
1943*62c56f98SSadaf Ebrahimi     if (end - p < 4) {
1944*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small"));
1945*62c56f98SSadaf Ebrahimi         return;
1946*62c56f98SSadaf Ebrahimi     }
1947*62c56f98SSadaf Ebrahimi 
1948*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0);
1949*62c56f98SSadaf Ebrahimi     p += 2;
1950*62c56f98SSadaf Ebrahimi 
1951*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
1952*62c56f98SSadaf Ebrahimi     ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx,
1953*62c56f98SSadaf Ebrahimi                                           p + 2, end - p - 2, &kkpp_len,
1954*62c56f98SSadaf Ebrahimi                                           MBEDTLS_ECJPAKE_ROUND_ONE);
1955*62c56f98SSadaf Ebrahimi     if (ret != 0) {
1956*62c56f98SSadaf Ebrahimi         psa_destroy_key(ssl->handshake->psa_pake_password);
1957*62c56f98SSadaf Ebrahimi         psa_pake_abort(&ssl->handshake->psa_pake_ctx);
1958*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret);
1959*62c56f98SSadaf Ebrahimi         return;
1960*62c56f98SSadaf Ebrahimi     }
1961*62c56f98SSadaf Ebrahimi #else
1962*62c56f98SSadaf Ebrahimi     ret = mbedtls_ecjpake_write_round_one(&ssl->handshake->ecjpake_ctx,
1963*62c56f98SSadaf Ebrahimi                                           p + 2, end - p - 2, &kkpp_len,
1964*62c56f98SSadaf Ebrahimi                                           ssl->conf->f_rng, ssl->conf->p_rng);
1965*62c56f98SSadaf Ebrahimi     if (ret != 0) {
1966*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_one", ret);
1967*62c56f98SSadaf Ebrahimi         return;
1968*62c56f98SSadaf Ebrahimi     }
1969*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_USE_PSA_CRYPTO */
1970*62c56f98SSadaf Ebrahimi 
1971*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT16_BE(kkpp_len, p, 0);
1972*62c56f98SSadaf Ebrahimi     p += 2;
1973*62c56f98SSadaf Ebrahimi 
1974*62c56f98SSadaf Ebrahimi     *olen = kkpp_len + 4;
1975*62c56f98SSadaf Ebrahimi }
1976*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
1977*62c56f98SSadaf Ebrahimi 
1978*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_DTLS_SRTP) && defined(MBEDTLS_SSL_PROTO_DTLS)
ssl_write_use_srtp_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t * olen)1979*62c56f98SSadaf Ebrahimi static void ssl_write_use_srtp_ext(mbedtls_ssl_context *ssl,
1980*62c56f98SSadaf Ebrahimi                                    unsigned char *buf,
1981*62c56f98SSadaf Ebrahimi                                    size_t *olen)
1982*62c56f98SSadaf Ebrahimi {
1983*62c56f98SSadaf Ebrahimi     size_t mki_len = 0, ext_len = 0;
1984*62c56f98SSadaf Ebrahimi     uint16_t profile_value = 0;
1985*62c56f98SSadaf Ebrahimi     const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
1986*62c56f98SSadaf Ebrahimi 
1987*62c56f98SSadaf Ebrahimi     *olen = 0;
1988*62c56f98SSadaf Ebrahimi 
1989*62c56f98SSadaf Ebrahimi     if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) ||
1990*62c56f98SSadaf Ebrahimi         (ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET)) {
1991*62c56f98SSadaf Ebrahimi         return;
1992*62c56f98SSadaf Ebrahimi     }
1993*62c56f98SSadaf Ebrahimi 
1994*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding use_srtp extension"));
1995*62c56f98SSadaf Ebrahimi 
1996*62c56f98SSadaf Ebrahimi     if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED) {
1997*62c56f98SSadaf Ebrahimi         mki_len = ssl->dtls_srtp_info.mki_len;
1998*62c56f98SSadaf Ebrahimi     }
1999*62c56f98SSadaf Ebrahimi 
2000*62c56f98SSadaf Ebrahimi     /* The extension total size is 9 bytes :
2001*62c56f98SSadaf Ebrahimi      * - 2 bytes for the extension tag
2002*62c56f98SSadaf Ebrahimi      * - 2 bytes for the total size
2003*62c56f98SSadaf Ebrahimi      * - 2 bytes for the protection profile length
2004*62c56f98SSadaf Ebrahimi      * - 2 bytes for the protection profile
2005*62c56f98SSadaf Ebrahimi      * - 1 byte for the mki length
2006*62c56f98SSadaf Ebrahimi      * +  the actual mki length
2007*62c56f98SSadaf Ebrahimi      * Check we have enough room in the output buffer */
2008*62c56f98SSadaf Ebrahimi     if ((size_t) (end - buf) < mki_len + 9) {
2009*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small"));
2010*62c56f98SSadaf Ebrahimi         return;
2011*62c56f98SSadaf Ebrahimi     }
2012*62c56f98SSadaf Ebrahimi 
2013*62c56f98SSadaf Ebrahimi     /* extension */
2014*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_USE_SRTP, buf, 0);
2015*62c56f98SSadaf Ebrahimi     /*
2016*62c56f98SSadaf Ebrahimi      * total length 5 and mki value: only one profile(2 bytes)
2017*62c56f98SSadaf Ebrahimi      *              and length(2 bytes) and srtp_mki  )
2018*62c56f98SSadaf Ebrahimi      */
2019*62c56f98SSadaf Ebrahimi     ext_len = 5 + mki_len;
2020*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT16_BE(ext_len, buf, 2);
2021*62c56f98SSadaf Ebrahimi 
2022*62c56f98SSadaf Ebrahimi     /* protection profile length: 2 */
2023*62c56f98SSadaf Ebrahimi     buf[4] = 0x00;
2024*62c56f98SSadaf Ebrahimi     buf[5] = 0x02;
2025*62c56f98SSadaf Ebrahimi     profile_value = mbedtls_ssl_check_srtp_profile_value(
2026*62c56f98SSadaf Ebrahimi         ssl->dtls_srtp_info.chosen_dtls_srtp_profile);
2027*62c56f98SSadaf Ebrahimi     if (profile_value != MBEDTLS_TLS_SRTP_UNSET) {
2028*62c56f98SSadaf Ebrahimi         MBEDTLS_PUT_UINT16_BE(profile_value, buf, 6);
2029*62c56f98SSadaf Ebrahimi     } else {
2030*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("use_srtp extension invalid profile"));
2031*62c56f98SSadaf Ebrahimi         return;
2032*62c56f98SSadaf Ebrahimi     }
2033*62c56f98SSadaf Ebrahimi 
2034*62c56f98SSadaf Ebrahimi     buf[8] = mki_len & 0xFF;
2035*62c56f98SSadaf Ebrahimi     memcpy(&buf[9], ssl->dtls_srtp_info.mki_value, mki_len);
2036*62c56f98SSadaf Ebrahimi 
2037*62c56f98SSadaf Ebrahimi     *olen = 9 + mki_len;
2038*62c56f98SSadaf Ebrahimi }
2039*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_DTLS_SRTP */
2040*62c56f98SSadaf Ebrahimi 
2041*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
2042*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_write_hello_verify_request(mbedtls_ssl_context * ssl)2043*62c56f98SSadaf Ebrahimi static int ssl_write_hello_verify_request(mbedtls_ssl_context *ssl)
2044*62c56f98SSadaf Ebrahimi {
2045*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2046*62c56f98SSadaf Ebrahimi     unsigned char *p = ssl->out_msg + 4;
2047*62c56f98SSadaf Ebrahimi     unsigned char *cookie_len_byte;
2048*62c56f98SSadaf Ebrahimi 
2049*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write hello verify request"));
2050*62c56f98SSadaf Ebrahimi 
2051*62c56f98SSadaf Ebrahimi     /*
2052*62c56f98SSadaf Ebrahimi      * struct {
2053*62c56f98SSadaf Ebrahimi      *   ProtocolVersion server_version;
2054*62c56f98SSadaf Ebrahimi      *   opaque cookie<0..2^8-1>;
2055*62c56f98SSadaf Ebrahimi      * } HelloVerifyRequest;
2056*62c56f98SSadaf Ebrahimi      */
2057*62c56f98SSadaf Ebrahimi 
2058*62c56f98SSadaf Ebrahimi     /* The RFC is not clear on this point, but sending the actual negotiated
2059*62c56f98SSadaf Ebrahimi      * version looks like the most interoperable thing to do. */
2060*62c56f98SSadaf Ebrahimi     mbedtls_ssl_write_version(p, ssl->conf->transport, ssl->tls_version);
2061*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_BUF(3, "server version", p, 2);
2062*62c56f98SSadaf Ebrahimi     p += 2;
2063*62c56f98SSadaf Ebrahimi 
2064*62c56f98SSadaf Ebrahimi     /* If we get here, f_cookie_check is not null */
2065*62c56f98SSadaf Ebrahimi     if (ssl->conf->f_cookie_write == NULL) {
2066*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("inconsistent cookie callbacks"));
2067*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2068*62c56f98SSadaf Ebrahimi     }
2069*62c56f98SSadaf Ebrahimi 
2070*62c56f98SSadaf Ebrahimi     /* Skip length byte until we know the length */
2071*62c56f98SSadaf Ebrahimi     cookie_len_byte = p++;
2072*62c56f98SSadaf Ebrahimi 
2073*62c56f98SSadaf Ebrahimi     if ((ret = ssl->conf->f_cookie_write(ssl->conf->p_cookie,
2074*62c56f98SSadaf Ebrahimi                                          &p, ssl->out_buf + MBEDTLS_SSL_OUT_BUFFER_LEN,
2075*62c56f98SSadaf Ebrahimi                                          ssl->cli_id, ssl->cli_id_len)) != 0) {
2076*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, "f_cookie_write", ret);
2077*62c56f98SSadaf Ebrahimi         return ret;
2078*62c56f98SSadaf Ebrahimi     }
2079*62c56f98SSadaf Ebrahimi 
2080*62c56f98SSadaf Ebrahimi     *cookie_len_byte = (unsigned char) (p - (cookie_len_byte + 1));
2081*62c56f98SSadaf Ebrahimi 
2082*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_BUF(3, "cookie sent", cookie_len_byte + 1, *cookie_len_byte);
2083*62c56f98SSadaf Ebrahimi 
2084*62c56f98SSadaf Ebrahimi     ssl->out_msglen  = p - ssl->out_msg;
2085*62c56f98SSadaf Ebrahimi     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
2086*62c56f98SSadaf Ebrahimi     ssl->out_msg[0]  = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
2087*62c56f98SSadaf Ebrahimi 
2088*62c56f98SSadaf Ebrahimi     ssl->state = MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT;
2089*62c56f98SSadaf Ebrahimi 
2090*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
2091*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
2092*62c56f98SSadaf Ebrahimi         return ret;
2093*62c56f98SSadaf Ebrahimi     }
2094*62c56f98SSadaf Ebrahimi 
2095*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_PROTO_DTLS)
2096*62c56f98SSadaf Ebrahimi     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
2097*62c56f98SSadaf Ebrahimi         (ret = mbedtls_ssl_flight_transmit(ssl)) != 0) {
2098*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flight_transmit", ret);
2099*62c56f98SSadaf Ebrahimi         return ret;
2100*62c56f98SSadaf Ebrahimi     }
2101*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_PROTO_DTLS */
2102*62c56f98SSadaf Ebrahimi 
2103*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write hello verify request"));
2104*62c56f98SSadaf Ebrahimi 
2105*62c56f98SSadaf Ebrahimi     return 0;
2106*62c56f98SSadaf Ebrahimi }
2107*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
2108*62c56f98SSadaf Ebrahimi 
ssl_handle_id_based_session_resumption(mbedtls_ssl_context * ssl)2109*62c56f98SSadaf Ebrahimi static void ssl_handle_id_based_session_resumption(mbedtls_ssl_context *ssl)
2110*62c56f98SSadaf Ebrahimi {
2111*62c56f98SSadaf Ebrahimi     int ret;
2112*62c56f98SSadaf Ebrahimi     mbedtls_ssl_session session_tmp;
2113*62c56f98SSadaf Ebrahimi     mbedtls_ssl_session * const session = ssl->session_negotiate;
2114*62c56f98SSadaf Ebrahimi 
2115*62c56f98SSadaf Ebrahimi     /* Resume is 0  by default, see ssl_handshake_init().
2116*62c56f98SSadaf Ebrahimi      * It may be already set to 1 by ssl_parse_session_ticket_ext(). */
2117*62c56f98SSadaf Ebrahimi     if (ssl->handshake->resume == 1) {
2118*62c56f98SSadaf Ebrahimi         return;
2119*62c56f98SSadaf Ebrahimi     }
2120*62c56f98SSadaf Ebrahimi     if (session->id_len == 0) {
2121*62c56f98SSadaf Ebrahimi         return;
2122*62c56f98SSadaf Ebrahimi     }
2123*62c56f98SSadaf Ebrahimi     if (ssl->conf->f_get_cache == NULL) {
2124*62c56f98SSadaf Ebrahimi         return;
2125*62c56f98SSadaf Ebrahimi     }
2126*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_RENEGOTIATION)
2127*62c56f98SSadaf Ebrahimi     if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
2128*62c56f98SSadaf Ebrahimi         return;
2129*62c56f98SSadaf Ebrahimi     }
2130*62c56f98SSadaf Ebrahimi #endif
2131*62c56f98SSadaf Ebrahimi 
2132*62c56f98SSadaf Ebrahimi     mbedtls_ssl_session_init(&session_tmp);
2133*62c56f98SSadaf Ebrahimi 
2134*62c56f98SSadaf Ebrahimi     ret = ssl->conf->f_get_cache(ssl->conf->p_cache,
2135*62c56f98SSadaf Ebrahimi                                  session->id,
2136*62c56f98SSadaf Ebrahimi                                  session->id_len,
2137*62c56f98SSadaf Ebrahimi                                  &session_tmp);
2138*62c56f98SSadaf Ebrahimi     if (ret != 0) {
2139*62c56f98SSadaf Ebrahimi         goto exit;
2140*62c56f98SSadaf Ebrahimi     }
2141*62c56f98SSadaf Ebrahimi 
2142*62c56f98SSadaf Ebrahimi     if (session->ciphersuite != session_tmp.ciphersuite) {
2143*62c56f98SSadaf Ebrahimi         /* Mismatch between cached and negotiated session */
2144*62c56f98SSadaf Ebrahimi         goto exit;
2145*62c56f98SSadaf Ebrahimi     }
2146*62c56f98SSadaf Ebrahimi 
2147*62c56f98SSadaf Ebrahimi     /* Move semantics */
2148*62c56f98SSadaf Ebrahimi     mbedtls_ssl_session_free(session);
2149*62c56f98SSadaf Ebrahimi     *session = session_tmp;
2150*62c56f98SSadaf Ebrahimi     memset(&session_tmp, 0, sizeof(session_tmp));
2151*62c56f98SSadaf Ebrahimi 
2152*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("session successfully restored from cache"));
2153*62c56f98SSadaf Ebrahimi     ssl->handshake->resume = 1;
2154*62c56f98SSadaf Ebrahimi 
2155*62c56f98SSadaf Ebrahimi exit:
2156*62c56f98SSadaf Ebrahimi 
2157*62c56f98SSadaf Ebrahimi     mbedtls_ssl_session_free(&session_tmp);
2158*62c56f98SSadaf Ebrahimi }
2159*62c56f98SSadaf Ebrahimi 
2160*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_write_server_hello(mbedtls_ssl_context * ssl)2161*62c56f98SSadaf Ebrahimi static int ssl_write_server_hello(mbedtls_ssl_context *ssl)
2162*62c56f98SSadaf Ebrahimi {
2163*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_HAVE_TIME)
2164*62c56f98SSadaf Ebrahimi     mbedtls_time_t t;
2165*62c56f98SSadaf Ebrahimi #endif
2166*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2167*62c56f98SSadaf Ebrahimi     size_t olen, ext_len = 0, n;
2168*62c56f98SSadaf Ebrahimi     unsigned char *buf, *p;
2169*62c56f98SSadaf Ebrahimi 
2170*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server hello"));
2171*62c56f98SSadaf Ebrahimi 
2172*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
2173*62c56f98SSadaf Ebrahimi     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
2174*62c56f98SSadaf Ebrahimi         ssl->handshake->cookie_verify_result != 0) {
2175*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(2, ("client hello was not authenticated"));
2176*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello"));
2177*62c56f98SSadaf Ebrahimi 
2178*62c56f98SSadaf Ebrahimi         return ssl_write_hello_verify_request(ssl);
2179*62c56f98SSadaf Ebrahimi     }
2180*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
2181*62c56f98SSadaf Ebrahimi 
2182*62c56f98SSadaf Ebrahimi     if (ssl->conf->f_rng == NULL) {
2183*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided"));
2184*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_NO_RNG;
2185*62c56f98SSadaf Ebrahimi     }
2186*62c56f98SSadaf Ebrahimi 
2187*62c56f98SSadaf Ebrahimi     /*
2188*62c56f98SSadaf Ebrahimi      *     0  .   0   handshake type
2189*62c56f98SSadaf Ebrahimi      *     1  .   3   handshake length
2190*62c56f98SSadaf Ebrahimi      *     4  .   5   protocol version
2191*62c56f98SSadaf Ebrahimi      *     6  .   9   UNIX time()
2192*62c56f98SSadaf Ebrahimi      *    10  .  37   random bytes
2193*62c56f98SSadaf Ebrahimi      */
2194*62c56f98SSadaf Ebrahimi     buf = ssl->out_msg;
2195*62c56f98SSadaf Ebrahimi     p = buf + 4;
2196*62c56f98SSadaf Ebrahimi 
2197*62c56f98SSadaf Ebrahimi     mbedtls_ssl_write_version(p, ssl->conf->transport, ssl->tls_version);
2198*62c56f98SSadaf Ebrahimi     p += 2;
2199*62c56f98SSadaf Ebrahimi 
2200*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen version: [%d:%d]",
2201*62c56f98SSadaf Ebrahimi                               buf[4], buf[5]));
2202*62c56f98SSadaf Ebrahimi 
2203*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_HAVE_TIME)
2204*62c56f98SSadaf Ebrahimi     t = mbedtls_time(NULL);
2205*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT32_BE(t, p, 0);
2206*62c56f98SSadaf Ebrahimi     p += 4;
2207*62c56f98SSadaf Ebrahimi 
2208*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, current time: %" MBEDTLS_PRINTF_LONGLONG,
2209*62c56f98SSadaf Ebrahimi                               (long long) t));
2210*62c56f98SSadaf Ebrahimi #else
2211*62c56f98SSadaf Ebrahimi     if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 4)) != 0) {
2212*62c56f98SSadaf Ebrahimi         return ret;
2213*62c56f98SSadaf Ebrahimi     }
2214*62c56f98SSadaf Ebrahimi 
2215*62c56f98SSadaf Ebrahimi     p += 4;
2216*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_HAVE_TIME */
2217*62c56f98SSadaf Ebrahimi 
2218*62c56f98SSadaf Ebrahimi     if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 20)) != 0) {
2219*62c56f98SSadaf Ebrahimi         return ret;
2220*62c56f98SSadaf Ebrahimi     }
2221*62c56f98SSadaf Ebrahimi     p += 20;
2222*62c56f98SSadaf Ebrahimi 
2223*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
2224*62c56f98SSadaf Ebrahimi     /*
2225*62c56f98SSadaf Ebrahimi      * RFC 8446
2226*62c56f98SSadaf Ebrahimi      * TLS 1.3 has a downgrade protection mechanism embedded in the server's
2227*62c56f98SSadaf Ebrahimi      * random value. TLS 1.3 servers which negotiate TLS 1.2 or below in
2228*62c56f98SSadaf Ebrahimi      * response to a ClientHello MUST set the last 8 bytes of their Random
2229*62c56f98SSadaf Ebrahimi      * value specially in their ServerHello.
2230*62c56f98SSadaf Ebrahimi      */
2231*62c56f98SSadaf Ebrahimi     if (mbedtls_ssl_conf_is_tls13_enabled(ssl->conf)) {
2232*62c56f98SSadaf Ebrahimi         static const unsigned char magic_tls12_downgrade_string[] =
2233*62c56f98SSadaf Ebrahimi         { 'D', 'O', 'W', 'N', 'G', 'R', 'D', 1 };
2234*62c56f98SSadaf Ebrahimi 
2235*62c56f98SSadaf Ebrahimi         MBEDTLS_STATIC_ASSERT(
2236*62c56f98SSadaf Ebrahimi             sizeof(magic_tls12_downgrade_string) == 8,
2237*62c56f98SSadaf Ebrahimi             "magic_tls12_downgrade_string does not have the expected size");
2238*62c56f98SSadaf Ebrahimi 
2239*62c56f98SSadaf Ebrahimi         memcpy(p, magic_tls12_downgrade_string,
2240*62c56f98SSadaf Ebrahimi                sizeof(magic_tls12_downgrade_string));
2241*62c56f98SSadaf Ebrahimi     } else
2242*62c56f98SSadaf Ebrahimi #endif
2243*62c56f98SSadaf Ebrahimi     {
2244*62c56f98SSadaf Ebrahimi         if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 8)) != 0) {
2245*62c56f98SSadaf Ebrahimi             return ret;
2246*62c56f98SSadaf Ebrahimi         }
2247*62c56f98SSadaf Ebrahimi     }
2248*62c56f98SSadaf Ebrahimi     p += 8;
2249*62c56f98SSadaf Ebrahimi 
2250*62c56f98SSadaf Ebrahimi     memcpy(ssl->handshake->randbytes + 32, buf + 6, 32);
2251*62c56f98SSadaf Ebrahimi 
2252*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_BUF(3, "server hello, random bytes", buf + 6, 32);
2253*62c56f98SSadaf Ebrahimi 
2254*62c56f98SSadaf Ebrahimi     ssl_handle_id_based_session_resumption(ssl);
2255*62c56f98SSadaf Ebrahimi 
2256*62c56f98SSadaf Ebrahimi     if (ssl->handshake->resume == 0) {
2257*62c56f98SSadaf Ebrahimi         /*
2258*62c56f98SSadaf Ebrahimi          * New session, create a new session id,
2259*62c56f98SSadaf Ebrahimi          * unless we're about to issue a session ticket
2260*62c56f98SSadaf Ebrahimi          */
2261*62c56f98SSadaf Ebrahimi         ssl->state++;
2262*62c56f98SSadaf Ebrahimi 
2263*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_HAVE_TIME)
2264*62c56f98SSadaf Ebrahimi         ssl->session_negotiate->start = mbedtls_time(NULL);
2265*62c56f98SSadaf Ebrahimi #endif
2266*62c56f98SSadaf Ebrahimi 
2267*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_SESSION_TICKETS)
2268*62c56f98SSadaf Ebrahimi         if (ssl->handshake->new_session_ticket != 0) {
2269*62c56f98SSadaf Ebrahimi             ssl->session_negotiate->id_len = n = 0;
2270*62c56f98SSadaf Ebrahimi             memset(ssl->session_negotiate->id, 0, 32);
2271*62c56f98SSadaf Ebrahimi         } else
2272*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_SESSION_TICKETS */
2273*62c56f98SSadaf Ebrahimi         {
2274*62c56f98SSadaf Ebrahimi             ssl->session_negotiate->id_len = n = 32;
2275*62c56f98SSadaf Ebrahimi             if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, ssl->session_negotiate->id,
2276*62c56f98SSadaf Ebrahimi                                         n)) != 0) {
2277*62c56f98SSadaf Ebrahimi                 return ret;
2278*62c56f98SSadaf Ebrahimi             }
2279*62c56f98SSadaf Ebrahimi         }
2280*62c56f98SSadaf Ebrahimi     } else {
2281*62c56f98SSadaf Ebrahimi         /*
2282*62c56f98SSadaf Ebrahimi          * Resuming a session
2283*62c56f98SSadaf Ebrahimi          */
2284*62c56f98SSadaf Ebrahimi         n = ssl->session_negotiate->id_len;
2285*62c56f98SSadaf Ebrahimi         ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
2286*62c56f98SSadaf Ebrahimi 
2287*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) {
2288*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret);
2289*62c56f98SSadaf Ebrahimi             return ret;
2290*62c56f98SSadaf Ebrahimi         }
2291*62c56f98SSadaf Ebrahimi     }
2292*62c56f98SSadaf Ebrahimi 
2293*62c56f98SSadaf Ebrahimi     /*
2294*62c56f98SSadaf Ebrahimi      *    38  .  38     session id length
2295*62c56f98SSadaf Ebrahimi      *    39  . 38+n    session id
2296*62c56f98SSadaf Ebrahimi      *   39+n . 40+n    chosen ciphersuite
2297*62c56f98SSadaf Ebrahimi      *   41+n . 41+n    chosen compression alg.
2298*62c56f98SSadaf Ebrahimi      *   42+n . 43+n    extensions length
2299*62c56f98SSadaf Ebrahimi      *   44+n . 43+n+m  extensions
2300*62c56f98SSadaf Ebrahimi      */
2301*62c56f98SSadaf Ebrahimi     *p++ = (unsigned char) ssl->session_negotiate->id_len;
2302*62c56f98SSadaf Ebrahimi     memcpy(p, ssl->session_negotiate->id, ssl->session_negotiate->id_len);
2303*62c56f98SSadaf Ebrahimi     p += ssl->session_negotiate->id_len;
2304*62c56f98SSadaf Ebrahimi 
2305*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, session id len.: %" MBEDTLS_PRINTF_SIZET, n));
2306*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_BUF(3,   "server hello, session id", buf + 39, n);
2307*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("%s session has been resumed",
2308*62c56f98SSadaf Ebrahimi                               ssl->handshake->resume ? "a" : "no"));
2309*62c56f98SSadaf Ebrahimi 
2310*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT16_BE(ssl->session_negotiate->ciphersuite, p, 0);
2311*62c56f98SSadaf Ebrahimi     p += 2;
2312*62c56f98SSadaf Ebrahimi     *p++ = MBEDTLS_BYTE_0(MBEDTLS_SSL_COMPRESS_NULL);
2313*62c56f98SSadaf Ebrahimi 
2314*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen ciphersuite: %s",
2315*62c56f98SSadaf Ebrahimi                               mbedtls_ssl_get_ciphersuite_name(ssl->session_negotiate->ciphersuite)));
2316*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, compress alg.: 0x%02X",
2317*62c56f98SSadaf Ebrahimi                               (unsigned int) MBEDTLS_SSL_COMPRESS_NULL));
2318*62c56f98SSadaf Ebrahimi 
2319*62c56f98SSadaf Ebrahimi     /*
2320*62c56f98SSadaf Ebrahimi      *  First write extensions, then the total length
2321*62c56f98SSadaf Ebrahimi      */
2322*62c56f98SSadaf Ebrahimi     ssl_write_renegotiation_ext(ssl, p + 2 + ext_len, &olen);
2323*62c56f98SSadaf Ebrahimi     ext_len += olen;
2324*62c56f98SSadaf Ebrahimi 
2325*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
2326*62c56f98SSadaf Ebrahimi     ssl_write_max_fragment_length_ext(ssl, p + 2 + ext_len, &olen);
2327*62c56f98SSadaf Ebrahimi     ext_len += olen;
2328*62c56f98SSadaf Ebrahimi #endif
2329*62c56f98SSadaf Ebrahimi 
2330*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
2331*62c56f98SSadaf Ebrahimi     ssl_write_cid_ext(ssl, p + 2 + ext_len, &olen);
2332*62c56f98SSadaf Ebrahimi     ext_len += olen;
2333*62c56f98SSadaf Ebrahimi #endif
2334*62c56f98SSadaf Ebrahimi 
2335*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM)
2336*62c56f98SSadaf Ebrahimi     ssl_write_encrypt_then_mac_ext(ssl, p + 2 + ext_len, &olen);
2337*62c56f98SSadaf Ebrahimi     ext_len += olen;
2338*62c56f98SSadaf Ebrahimi #endif
2339*62c56f98SSadaf Ebrahimi 
2340*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
2341*62c56f98SSadaf Ebrahimi     ssl_write_extended_ms_ext(ssl, p + 2 + ext_len, &olen);
2342*62c56f98SSadaf Ebrahimi     ext_len += olen;
2343*62c56f98SSadaf Ebrahimi #endif
2344*62c56f98SSadaf Ebrahimi 
2345*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_SESSION_TICKETS)
2346*62c56f98SSadaf Ebrahimi     ssl_write_session_ticket_ext(ssl, p + 2 + ext_len, &olen);
2347*62c56f98SSadaf Ebrahimi     ext_len += olen;
2348*62c56f98SSadaf Ebrahimi #endif
2349*62c56f98SSadaf Ebrahimi 
2350*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
2351*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
2352*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
2353*62c56f98SSadaf Ebrahimi     const mbedtls_ssl_ciphersuite_t *suite =
2354*62c56f98SSadaf Ebrahimi         mbedtls_ssl_ciphersuite_from_id(ssl->session_negotiate->ciphersuite);
2355*62c56f98SSadaf Ebrahimi     if (suite != NULL && mbedtls_ssl_ciphersuite_uses_ec(suite)) {
2356*62c56f98SSadaf Ebrahimi         ssl_write_supported_point_formats_ext(ssl, p + 2 + ext_len, &olen);
2357*62c56f98SSadaf Ebrahimi         ext_len += olen;
2358*62c56f98SSadaf Ebrahimi     }
2359*62c56f98SSadaf Ebrahimi #endif
2360*62c56f98SSadaf Ebrahimi 
2361*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
2362*62c56f98SSadaf Ebrahimi     ssl_write_ecjpake_kkpp_ext(ssl, p + 2 + ext_len, &olen);
2363*62c56f98SSadaf Ebrahimi     ext_len += olen;
2364*62c56f98SSadaf Ebrahimi #endif
2365*62c56f98SSadaf Ebrahimi 
2366*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_ALPN)
2367*62c56f98SSadaf Ebrahimi     unsigned char *end = buf + MBEDTLS_SSL_OUT_CONTENT_LEN - 4;
2368*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_ssl_write_alpn_ext(ssl, p + 2 + ext_len, end, &olen))
2369*62c56f98SSadaf Ebrahimi         != 0) {
2370*62c56f98SSadaf Ebrahimi         return ret;
2371*62c56f98SSadaf Ebrahimi     }
2372*62c56f98SSadaf Ebrahimi 
2373*62c56f98SSadaf Ebrahimi     ext_len += olen;
2374*62c56f98SSadaf Ebrahimi #endif
2375*62c56f98SSadaf Ebrahimi 
2376*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_DTLS_SRTP)
2377*62c56f98SSadaf Ebrahimi     ssl_write_use_srtp_ext(ssl, p + 2 + ext_len, &olen);
2378*62c56f98SSadaf Ebrahimi     ext_len += olen;
2379*62c56f98SSadaf Ebrahimi #endif
2380*62c56f98SSadaf Ebrahimi 
2381*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, total extension length: %" MBEDTLS_PRINTF_SIZET,
2382*62c56f98SSadaf Ebrahimi                               ext_len));
2383*62c56f98SSadaf Ebrahimi 
2384*62c56f98SSadaf Ebrahimi     if (ext_len > 0) {
2385*62c56f98SSadaf Ebrahimi         MBEDTLS_PUT_UINT16_BE(ext_len, p, 0);
2386*62c56f98SSadaf Ebrahimi         p += 2 + ext_len;
2387*62c56f98SSadaf Ebrahimi     }
2388*62c56f98SSadaf Ebrahimi 
2389*62c56f98SSadaf Ebrahimi     ssl->out_msglen  = p - buf;
2390*62c56f98SSadaf Ebrahimi     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
2391*62c56f98SSadaf Ebrahimi     ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_HELLO;
2392*62c56f98SSadaf Ebrahimi 
2393*62c56f98SSadaf Ebrahimi     ret = mbedtls_ssl_write_handshake_msg(ssl);
2394*62c56f98SSadaf Ebrahimi 
2395*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello"));
2396*62c56f98SSadaf Ebrahimi 
2397*62c56f98SSadaf Ebrahimi     return ret;
2398*62c56f98SSadaf Ebrahimi }
2399*62c56f98SSadaf Ebrahimi 
2400*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
2401*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_write_certificate_request(mbedtls_ssl_context * ssl)2402*62c56f98SSadaf Ebrahimi static int ssl_write_certificate_request(mbedtls_ssl_context *ssl)
2403*62c56f98SSadaf Ebrahimi {
2404*62c56f98SSadaf Ebrahimi     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
2405*62c56f98SSadaf Ebrahimi         ssl->handshake->ciphersuite_info;
2406*62c56f98SSadaf Ebrahimi 
2407*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate request"));
2408*62c56f98SSadaf Ebrahimi 
2409*62c56f98SSadaf Ebrahimi     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
2410*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate request"));
2411*62c56f98SSadaf Ebrahimi         ssl->state++;
2412*62c56f98SSadaf Ebrahimi         return 0;
2413*62c56f98SSadaf Ebrahimi     }
2414*62c56f98SSadaf Ebrahimi 
2415*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2416*62c56f98SSadaf Ebrahimi     return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2417*62c56f98SSadaf Ebrahimi }
2418*62c56f98SSadaf Ebrahimi #else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
2419*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_write_certificate_request(mbedtls_ssl_context * ssl)2420*62c56f98SSadaf Ebrahimi static int ssl_write_certificate_request(mbedtls_ssl_context *ssl)
2421*62c56f98SSadaf Ebrahimi {
2422*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
2423*62c56f98SSadaf Ebrahimi     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
2424*62c56f98SSadaf Ebrahimi         ssl->handshake->ciphersuite_info;
2425*62c56f98SSadaf Ebrahimi     uint16_t dn_size, total_dn_size; /* excluding length bytes */
2426*62c56f98SSadaf Ebrahimi     size_t ct_len, sa_len; /* including length bytes */
2427*62c56f98SSadaf Ebrahimi     unsigned char *buf, *p;
2428*62c56f98SSadaf Ebrahimi     const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
2429*62c56f98SSadaf Ebrahimi     const mbedtls_x509_crt *crt;
2430*62c56f98SSadaf Ebrahimi     int authmode;
2431*62c56f98SSadaf Ebrahimi 
2432*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate request"));
2433*62c56f98SSadaf Ebrahimi 
2434*62c56f98SSadaf Ebrahimi     ssl->state++;
2435*62c56f98SSadaf Ebrahimi 
2436*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
2437*62c56f98SSadaf Ebrahimi     if (ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET) {
2438*62c56f98SSadaf Ebrahimi         authmode = ssl->handshake->sni_authmode;
2439*62c56f98SSadaf Ebrahimi     } else
2440*62c56f98SSadaf Ebrahimi #endif
2441*62c56f98SSadaf Ebrahimi     authmode = ssl->conf->authmode;
2442*62c56f98SSadaf Ebrahimi 
2443*62c56f98SSadaf Ebrahimi     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info) ||
2444*62c56f98SSadaf Ebrahimi         authmode == MBEDTLS_SSL_VERIFY_NONE) {
2445*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate request"));
2446*62c56f98SSadaf Ebrahimi         return 0;
2447*62c56f98SSadaf Ebrahimi     }
2448*62c56f98SSadaf Ebrahimi 
2449*62c56f98SSadaf Ebrahimi     /*
2450*62c56f98SSadaf Ebrahimi      *     0  .   0   handshake type
2451*62c56f98SSadaf Ebrahimi      *     1  .   3   handshake length
2452*62c56f98SSadaf Ebrahimi      *     4  .   4   cert type count
2453*62c56f98SSadaf Ebrahimi      *     5  .. m-1  cert types
2454*62c56f98SSadaf Ebrahimi      *     m  .. m+1  sig alg length (TLS 1.2 only)
2455*62c56f98SSadaf Ebrahimi      *    m+1 .. n-1  SignatureAndHashAlgorithms (TLS 1.2 only)
2456*62c56f98SSadaf Ebrahimi      *     n  .. n+1  length of all DNs
2457*62c56f98SSadaf Ebrahimi      *    n+2 .. n+3  length of DN 1
2458*62c56f98SSadaf Ebrahimi      *    n+4 .. ...  Distinguished Name #1
2459*62c56f98SSadaf Ebrahimi      *    ... .. ...  length of DN 2, etc.
2460*62c56f98SSadaf Ebrahimi      */
2461*62c56f98SSadaf Ebrahimi     buf = ssl->out_msg;
2462*62c56f98SSadaf Ebrahimi     p = buf + 4;
2463*62c56f98SSadaf Ebrahimi 
2464*62c56f98SSadaf Ebrahimi     /*
2465*62c56f98SSadaf Ebrahimi      * Supported certificate types
2466*62c56f98SSadaf Ebrahimi      *
2467*62c56f98SSadaf Ebrahimi      *     ClientCertificateType certificate_types<1..2^8-1>;
2468*62c56f98SSadaf Ebrahimi      *     enum { (255) } ClientCertificateType;
2469*62c56f98SSadaf Ebrahimi      */
2470*62c56f98SSadaf Ebrahimi     ct_len = 0;
2471*62c56f98SSadaf Ebrahimi 
2472*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_RSA_C)
2473*62c56f98SSadaf Ebrahimi     p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN;
2474*62c56f98SSadaf Ebrahimi #endif
2475*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
2476*62c56f98SSadaf Ebrahimi     p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN;
2477*62c56f98SSadaf Ebrahimi #endif
2478*62c56f98SSadaf Ebrahimi 
2479*62c56f98SSadaf Ebrahimi     p[0] = (unsigned char) ct_len++;
2480*62c56f98SSadaf Ebrahimi     p += ct_len;
2481*62c56f98SSadaf Ebrahimi 
2482*62c56f98SSadaf Ebrahimi     sa_len = 0;
2483*62c56f98SSadaf Ebrahimi 
2484*62c56f98SSadaf Ebrahimi     /*
2485*62c56f98SSadaf Ebrahimi      * Add signature_algorithms for verify (TLS 1.2)
2486*62c56f98SSadaf Ebrahimi      *
2487*62c56f98SSadaf Ebrahimi      *     SignatureAndHashAlgorithm supported_signature_algorithms<2..2^16-2>;
2488*62c56f98SSadaf Ebrahimi      *
2489*62c56f98SSadaf Ebrahimi      *     struct {
2490*62c56f98SSadaf Ebrahimi      *           HashAlgorithm hash;
2491*62c56f98SSadaf Ebrahimi      *           SignatureAlgorithm signature;
2492*62c56f98SSadaf Ebrahimi      *     } SignatureAndHashAlgorithm;
2493*62c56f98SSadaf Ebrahimi      *
2494*62c56f98SSadaf Ebrahimi      *     enum { (255) } HashAlgorithm;
2495*62c56f98SSadaf Ebrahimi      *     enum { (255) } SignatureAlgorithm;
2496*62c56f98SSadaf Ebrahimi      */
2497*62c56f98SSadaf Ebrahimi     const uint16_t *sig_alg = mbedtls_ssl_get_sig_algs(ssl);
2498*62c56f98SSadaf Ebrahimi     if (sig_alg == NULL) {
2499*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_BAD_CONFIG;
2500*62c56f98SSadaf Ebrahimi     }
2501*62c56f98SSadaf Ebrahimi 
2502*62c56f98SSadaf Ebrahimi     for (; *sig_alg != MBEDTLS_TLS_SIG_NONE; sig_alg++) {
2503*62c56f98SSadaf Ebrahimi         unsigned char hash = MBEDTLS_BYTE_1(*sig_alg);
2504*62c56f98SSadaf Ebrahimi 
2505*62c56f98SSadaf Ebrahimi         if (mbedtls_ssl_set_calc_verify_md(ssl, hash)) {
2506*62c56f98SSadaf Ebrahimi             continue;
2507*62c56f98SSadaf Ebrahimi         }
2508*62c56f98SSadaf Ebrahimi         if (!mbedtls_ssl_sig_alg_is_supported(ssl, *sig_alg)) {
2509*62c56f98SSadaf Ebrahimi             continue;
2510*62c56f98SSadaf Ebrahimi         }
2511*62c56f98SSadaf Ebrahimi 
2512*62c56f98SSadaf Ebrahimi         /* Write elements at offsets starting from 1 (offset 0 is for the
2513*62c56f98SSadaf Ebrahimi          * length). Thus the offset of each element is the length of the
2514*62c56f98SSadaf Ebrahimi          * partial list including that element. */
2515*62c56f98SSadaf Ebrahimi         sa_len += 2;
2516*62c56f98SSadaf Ebrahimi         MBEDTLS_PUT_UINT16_BE(*sig_alg, p, sa_len);
2517*62c56f98SSadaf Ebrahimi 
2518*62c56f98SSadaf Ebrahimi     }
2519*62c56f98SSadaf Ebrahimi 
2520*62c56f98SSadaf Ebrahimi     /* Fill in list length. */
2521*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT16_BE(sa_len, p, 0);
2522*62c56f98SSadaf Ebrahimi     sa_len += 2;
2523*62c56f98SSadaf Ebrahimi     p += sa_len;
2524*62c56f98SSadaf Ebrahimi 
2525*62c56f98SSadaf Ebrahimi     /*
2526*62c56f98SSadaf Ebrahimi      * DistinguishedName certificate_authorities<0..2^16-1>;
2527*62c56f98SSadaf Ebrahimi      * opaque DistinguishedName<1..2^16-1>;
2528*62c56f98SSadaf Ebrahimi      */
2529*62c56f98SSadaf Ebrahimi     p += 2;
2530*62c56f98SSadaf Ebrahimi 
2531*62c56f98SSadaf Ebrahimi     total_dn_size = 0;
2532*62c56f98SSadaf Ebrahimi 
2533*62c56f98SSadaf Ebrahimi     if (ssl->conf->cert_req_ca_list ==  MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED) {
2534*62c56f98SSadaf Ebrahimi         /* NOTE: If trusted certificates are provisioned
2535*62c56f98SSadaf Ebrahimi          *       via a CA callback (configured through
2536*62c56f98SSadaf Ebrahimi          *       `mbedtls_ssl_conf_ca_cb()`, then the
2537*62c56f98SSadaf Ebrahimi          *       CertificateRequest is currently left empty. */
2538*62c56f98SSadaf Ebrahimi 
2539*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
2540*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
2541*62c56f98SSadaf Ebrahimi         if (ssl->handshake->dn_hints != NULL) {
2542*62c56f98SSadaf Ebrahimi             crt = ssl->handshake->dn_hints;
2543*62c56f98SSadaf Ebrahimi         } else
2544*62c56f98SSadaf Ebrahimi #endif
2545*62c56f98SSadaf Ebrahimi         if (ssl->conf->dn_hints != NULL) {
2546*62c56f98SSadaf Ebrahimi             crt = ssl->conf->dn_hints;
2547*62c56f98SSadaf Ebrahimi         } else
2548*62c56f98SSadaf Ebrahimi #endif
2549*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
2550*62c56f98SSadaf Ebrahimi         if (ssl->handshake->sni_ca_chain != NULL) {
2551*62c56f98SSadaf Ebrahimi             crt = ssl->handshake->sni_ca_chain;
2552*62c56f98SSadaf Ebrahimi         } else
2553*62c56f98SSadaf Ebrahimi #endif
2554*62c56f98SSadaf Ebrahimi         crt = ssl->conf->ca_chain;
2555*62c56f98SSadaf Ebrahimi 
2556*62c56f98SSadaf Ebrahimi         while (crt != NULL && crt->version != 0) {
2557*62c56f98SSadaf Ebrahimi             /* It follows from RFC 5280 A.1 that this length
2558*62c56f98SSadaf Ebrahimi              * can be represented in at most 11 bits. */
2559*62c56f98SSadaf Ebrahimi             dn_size = (uint16_t) crt->subject_raw.len;
2560*62c56f98SSadaf Ebrahimi 
2561*62c56f98SSadaf Ebrahimi             if (end < p || (size_t) (end - p) < 2 + (size_t) dn_size) {
2562*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_MSG(1, ("skipping CAs: buffer too short"));
2563*62c56f98SSadaf Ebrahimi                 break;
2564*62c56f98SSadaf Ebrahimi             }
2565*62c56f98SSadaf Ebrahimi 
2566*62c56f98SSadaf Ebrahimi             MBEDTLS_PUT_UINT16_BE(dn_size, p, 0);
2567*62c56f98SSadaf Ebrahimi             p += 2;
2568*62c56f98SSadaf Ebrahimi             memcpy(p, crt->subject_raw.p, dn_size);
2569*62c56f98SSadaf Ebrahimi             p += dn_size;
2570*62c56f98SSadaf Ebrahimi 
2571*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_BUF(3, "requested DN", p - dn_size, dn_size);
2572*62c56f98SSadaf Ebrahimi 
2573*62c56f98SSadaf Ebrahimi             total_dn_size += 2 + dn_size;
2574*62c56f98SSadaf Ebrahimi             crt = crt->next;
2575*62c56f98SSadaf Ebrahimi         }
2576*62c56f98SSadaf Ebrahimi     }
2577*62c56f98SSadaf Ebrahimi 
2578*62c56f98SSadaf Ebrahimi     ssl->out_msglen  = p - buf;
2579*62c56f98SSadaf Ebrahimi     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
2580*62c56f98SSadaf Ebrahimi     ssl->out_msg[0]  = MBEDTLS_SSL_HS_CERTIFICATE_REQUEST;
2581*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT16_BE(total_dn_size, ssl->out_msg, 4 + ct_len + sa_len);
2582*62c56f98SSadaf Ebrahimi 
2583*62c56f98SSadaf Ebrahimi     ret = mbedtls_ssl_write_handshake_msg(ssl);
2584*62c56f98SSadaf Ebrahimi 
2585*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write certificate request"));
2586*62c56f98SSadaf Ebrahimi 
2587*62c56f98SSadaf Ebrahimi     return ret;
2588*62c56f98SSadaf Ebrahimi }
2589*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
2590*62c56f98SSadaf Ebrahimi 
2591*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO) &&                      \
2592*62c56f98SSadaf Ebrahimi     (defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
2593*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED))
2594*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_get_ecdh_params_from_cert(mbedtls_ssl_context * ssl)2595*62c56f98SSadaf Ebrahimi static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
2596*62c56f98SSadaf Ebrahimi {
2597*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2598*62c56f98SSadaf Ebrahimi     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
2599*62c56f98SSadaf Ebrahimi     mbedtls_pk_context *pk;
2600*62c56f98SSadaf Ebrahimi     mbedtls_pk_type_t pk_type;
2601*62c56f98SSadaf Ebrahimi     psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
2602*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
2603*62c56f98SSadaf Ebrahimi     uint16_t tls_id = 0;
2604*62c56f98SSadaf Ebrahimi     psa_key_type_t key_type = PSA_KEY_TYPE_NONE;
2605*62c56f98SSadaf Ebrahimi     size_t key_len;
2606*62c56f98SSadaf Ebrahimi     mbedtls_ecp_group_id grp_id;
2607*62c56f98SSadaf Ebrahimi     unsigned char buf[PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
2608*62c56f98SSadaf Ebrahimi     mbedtls_ecp_keypair *key;
2609*62c56f98SSadaf Ebrahimi #endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
2610*62c56f98SSadaf Ebrahimi 
2611*62c56f98SSadaf Ebrahimi     pk = mbedtls_ssl_own_key(ssl);
2612*62c56f98SSadaf Ebrahimi 
2613*62c56f98SSadaf Ebrahimi     if (pk == NULL) {
2614*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
2615*62c56f98SSadaf Ebrahimi     }
2616*62c56f98SSadaf Ebrahimi 
2617*62c56f98SSadaf Ebrahimi     pk_type = mbedtls_pk_get_type(pk);
2618*62c56f98SSadaf Ebrahimi 
2619*62c56f98SSadaf Ebrahimi     switch (pk_type) {
2620*62c56f98SSadaf Ebrahimi         case MBEDTLS_PK_OPAQUE:
2621*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
2622*62c56f98SSadaf Ebrahimi         case MBEDTLS_PK_ECKEY:
2623*62c56f98SSadaf Ebrahimi         case MBEDTLS_PK_ECKEY_DH:
2624*62c56f98SSadaf Ebrahimi         case MBEDTLS_PK_ECDSA:
2625*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
2626*62c56f98SSadaf Ebrahimi             if (!mbedtls_pk_can_do(pk, MBEDTLS_PK_ECKEY)) {
2627*62c56f98SSadaf Ebrahimi                 return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
2628*62c56f98SSadaf Ebrahimi             }
2629*62c56f98SSadaf Ebrahimi 
2630*62c56f98SSadaf Ebrahimi             ssl->handshake->xxdh_psa_privkey = pk->priv_id;
2631*62c56f98SSadaf Ebrahimi 
2632*62c56f98SSadaf Ebrahimi             /* Key should not be destroyed in the TLS library */
2633*62c56f98SSadaf Ebrahimi             ssl->handshake->xxdh_psa_privkey_is_external = 1;
2634*62c56f98SSadaf Ebrahimi 
2635*62c56f98SSadaf Ebrahimi             status = psa_get_key_attributes(ssl->handshake->xxdh_psa_privkey,
2636*62c56f98SSadaf Ebrahimi                                             &key_attributes);
2637*62c56f98SSadaf Ebrahimi             if (status != PSA_SUCCESS) {
2638*62c56f98SSadaf Ebrahimi                 ssl->handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
2639*62c56f98SSadaf Ebrahimi                 return PSA_TO_MBEDTLS_ERR(status);
2640*62c56f98SSadaf Ebrahimi             }
2641*62c56f98SSadaf Ebrahimi 
2642*62c56f98SSadaf Ebrahimi             ssl->handshake->xxdh_psa_type = psa_get_key_type(&key_attributes);
2643*62c56f98SSadaf Ebrahimi             ssl->handshake->xxdh_psa_bits = psa_get_key_bits(&key_attributes);
2644*62c56f98SSadaf Ebrahimi 
2645*62c56f98SSadaf Ebrahimi             psa_reset_key_attributes(&key_attributes);
2646*62c56f98SSadaf Ebrahimi 
2647*62c56f98SSadaf Ebrahimi             ret = 0;
2648*62c56f98SSadaf Ebrahimi             break;
2649*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
2650*62c56f98SSadaf Ebrahimi         case MBEDTLS_PK_ECKEY:
2651*62c56f98SSadaf Ebrahimi         case MBEDTLS_PK_ECKEY_DH:
2652*62c56f98SSadaf Ebrahimi         case MBEDTLS_PK_ECDSA:
2653*62c56f98SSadaf Ebrahimi             key = mbedtls_pk_ec_rw(*pk);
2654*62c56f98SSadaf Ebrahimi             grp_id = mbedtls_pk_get_group_id(pk);
2655*62c56f98SSadaf Ebrahimi             if (grp_id == MBEDTLS_ECP_DP_NONE) {
2656*62c56f98SSadaf Ebrahimi                 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
2657*62c56f98SSadaf Ebrahimi             }
2658*62c56f98SSadaf Ebrahimi             tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id);
2659*62c56f98SSadaf Ebrahimi             if (tls_id == 0) {
2660*62c56f98SSadaf Ebrahimi                 /* This elliptic curve is not supported */
2661*62c56f98SSadaf Ebrahimi                 return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
2662*62c56f98SSadaf Ebrahimi             }
2663*62c56f98SSadaf Ebrahimi 
2664*62c56f98SSadaf Ebrahimi             /* If the above conversion to TLS ID was fine, then also this one will
2665*62c56f98SSadaf Ebrahimi                be, so there is no need to check the return value here */
2666*62c56f98SSadaf Ebrahimi             mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id, &key_type,
2667*62c56f98SSadaf Ebrahimi                                                        &ssl->handshake->xxdh_psa_bits);
2668*62c56f98SSadaf Ebrahimi 
2669*62c56f98SSadaf Ebrahimi             ssl->handshake->xxdh_psa_type = key_type;
2670*62c56f98SSadaf Ebrahimi 
2671*62c56f98SSadaf Ebrahimi             key_attributes = psa_key_attributes_init();
2672*62c56f98SSadaf Ebrahimi             psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
2673*62c56f98SSadaf Ebrahimi             psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
2674*62c56f98SSadaf Ebrahimi             psa_set_key_type(&key_attributes,
2675*62c56f98SSadaf Ebrahimi                              PSA_KEY_TYPE_ECC_KEY_PAIR(ssl->handshake->xxdh_psa_type));
2676*62c56f98SSadaf Ebrahimi             psa_set_key_bits(&key_attributes, ssl->handshake->xxdh_psa_bits);
2677*62c56f98SSadaf Ebrahimi 
2678*62c56f98SSadaf Ebrahimi             key_len = PSA_BITS_TO_BYTES(key->grp.pbits);
2679*62c56f98SSadaf Ebrahimi             ret = mbedtls_ecp_write_key(key, buf, key_len);
2680*62c56f98SSadaf Ebrahimi             if (ret != 0) {
2681*62c56f98SSadaf Ebrahimi                 mbedtls_platform_zeroize(buf, sizeof(buf));
2682*62c56f98SSadaf Ebrahimi                 break;
2683*62c56f98SSadaf Ebrahimi             }
2684*62c56f98SSadaf Ebrahimi 
2685*62c56f98SSadaf Ebrahimi             status = psa_import_key(&key_attributes, buf, key_len,
2686*62c56f98SSadaf Ebrahimi                                     &ssl->handshake->xxdh_psa_privkey);
2687*62c56f98SSadaf Ebrahimi             if (status != PSA_SUCCESS) {
2688*62c56f98SSadaf Ebrahimi                 ret = PSA_TO_MBEDTLS_ERR(status);
2689*62c56f98SSadaf Ebrahimi                 mbedtls_platform_zeroize(buf, sizeof(buf));
2690*62c56f98SSadaf Ebrahimi                 break;
2691*62c56f98SSadaf Ebrahimi             }
2692*62c56f98SSadaf Ebrahimi 
2693*62c56f98SSadaf Ebrahimi             mbedtls_platform_zeroize(buf, sizeof(buf));
2694*62c56f98SSadaf Ebrahimi             ret = 0;
2695*62c56f98SSadaf Ebrahimi             break;
2696*62c56f98SSadaf Ebrahimi #endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
2697*62c56f98SSadaf Ebrahimi         default:
2698*62c56f98SSadaf Ebrahimi             ret = MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
2699*62c56f98SSadaf Ebrahimi     }
2700*62c56f98SSadaf Ebrahimi 
2701*62c56f98SSadaf Ebrahimi     return ret;
2702*62c56f98SSadaf Ebrahimi }
2703*62c56f98SSadaf Ebrahimi #elif defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
2704*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
2705*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_get_ecdh_params_from_cert(mbedtls_ssl_context * ssl)2706*62c56f98SSadaf Ebrahimi static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
2707*62c56f98SSadaf Ebrahimi {
2708*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2709*62c56f98SSadaf Ebrahimi 
2710*62c56f98SSadaf Ebrahimi     const mbedtls_pk_context *private_key = mbedtls_ssl_own_key(ssl);
2711*62c56f98SSadaf Ebrahimi     if (private_key == NULL) {
2712*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("got no server private key"));
2713*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED;
2714*62c56f98SSadaf Ebrahimi     }
2715*62c56f98SSadaf Ebrahimi 
2716*62c56f98SSadaf Ebrahimi     if (!mbedtls_pk_can_do(private_key, MBEDTLS_PK_ECKEY)) {
2717*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("server key not ECDH capable"));
2718*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
2719*62c56f98SSadaf Ebrahimi     }
2720*62c56f98SSadaf Ebrahimi 
2721*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_ecdh_get_params(&ssl->handshake->ecdh_ctx,
2722*62c56f98SSadaf Ebrahimi                                        mbedtls_pk_ec_ro(*mbedtls_ssl_own_key(ssl)),
2723*62c56f98SSadaf Ebrahimi                                        MBEDTLS_ECDH_OURS)) != 0) {
2724*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_get_params"), ret);
2725*62c56f98SSadaf Ebrahimi         return ret;
2726*62c56f98SSadaf Ebrahimi     }
2727*62c56f98SSadaf Ebrahimi 
2728*62c56f98SSadaf Ebrahimi     return 0;
2729*62c56f98SSadaf Ebrahimi }
2730*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
2731*62c56f98SSadaf Ebrahimi           MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
2732*62c56f98SSadaf Ebrahimi 
2733*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \
2734*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_SSL_ASYNC_PRIVATE)
2735*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_resume_server_key_exchange(mbedtls_ssl_context * ssl,size_t * signature_len)2736*62c56f98SSadaf Ebrahimi static int ssl_resume_server_key_exchange(mbedtls_ssl_context *ssl,
2737*62c56f98SSadaf Ebrahimi                                           size_t *signature_len)
2738*62c56f98SSadaf Ebrahimi {
2739*62c56f98SSadaf Ebrahimi     /* Append the signature to ssl->out_msg, leaving 2 bytes for the
2740*62c56f98SSadaf Ebrahimi      * signature length which will be added in ssl_write_server_key_exchange
2741*62c56f98SSadaf Ebrahimi      * after the call to ssl_prepare_server_key_exchange.
2742*62c56f98SSadaf Ebrahimi      * ssl_write_server_key_exchange also takes care of incrementing
2743*62c56f98SSadaf Ebrahimi      * ssl->out_msglen. */
2744*62c56f98SSadaf Ebrahimi     unsigned char *sig_start = ssl->out_msg + ssl->out_msglen + 2;
2745*62c56f98SSadaf Ebrahimi     size_t sig_max_len = (ssl->out_buf + MBEDTLS_SSL_OUT_CONTENT_LEN
2746*62c56f98SSadaf Ebrahimi                           - sig_start);
2747*62c56f98SSadaf Ebrahimi     int ret = ssl->conf->f_async_resume(ssl,
2748*62c56f98SSadaf Ebrahimi                                         sig_start, signature_len, sig_max_len);
2749*62c56f98SSadaf Ebrahimi     if (ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
2750*62c56f98SSadaf Ebrahimi         ssl->handshake->async_in_progress = 0;
2751*62c56f98SSadaf Ebrahimi         mbedtls_ssl_set_async_operation_data(ssl, NULL);
2752*62c56f98SSadaf Ebrahimi     }
2753*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_RET(2, "ssl_resume_server_key_exchange", ret);
2754*62c56f98SSadaf Ebrahimi     return ret;
2755*62c56f98SSadaf Ebrahimi }
2756*62c56f98SSadaf Ebrahimi #endif /* defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) &&
2757*62c56f98SSadaf Ebrahimi           defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
2758*62c56f98SSadaf Ebrahimi 
2759*62c56f98SSadaf Ebrahimi /* Prepare the ServerKeyExchange message, up to and including
2760*62c56f98SSadaf Ebrahimi  * calculating the signature if any, but excluding formatting the
2761*62c56f98SSadaf Ebrahimi  * signature and sending the message. */
2762*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_prepare_server_key_exchange(mbedtls_ssl_context * ssl,size_t * signature_len)2763*62c56f98SSadaf Ebrahimi static int ssl_prepare_server_key_exchange(mbedtls_ssl_context *ssl,
2764*62c56f98SSadaf Ebrahimi                                            size_t *signature_len)
2765*62c56f98SSadaf Ebrahimi {
2766*62c56f98SSadaf Ebrahimi     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
2767*62c56f98SSadaf Ebrahimi         ssl->handshake->ciphersuite_info;
2768*62c56f98SSadaf Ebrahimi 
2769*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED)
2770*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
2771*62c56f98SSadaf Ebrahimi     unsigned char *dig_signed = NULL;
2772*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
2773*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED */
2774*62c56f98SSadaf Ebrahimi 
2775*62c56f98SSadaf Ebrahimi     (void) ciphersuite_info; /* unused in some configurations */
2776*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
2777*62c56f98SSadaf Ebrahimi     (void) signature_len;
2778*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
2779*62c56f98SSadaf Ebrahimi 
2780*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
2781*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
2782*62c56f98SSadaf Ebrahimi     size_t out_buf_len = ssl->out_buf_len - (ssl->out_msg - ssl->out_buf);
2783*62c56f98SSadaf Ebrahimi #else
2784*62c56f98SSadaf Ebrahimi     size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - (ssl->out_msg - ssl->out_buf);
2785*62c56f98SSadaf Ebrahimi #endif
2786*62c56f98SSadaf Ebrahimi #endif
2787*62c56f98SSadaf Ebrahimi 
2788*62c56f98SSadaf Ebrahimi     ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */
2789*62c56f98SSadaf Ebrahimi 
2790*62c56f98SSadaf Ebrahimi     /*
2791*62c56f98SSadaf Ebrahimi      *
2792*62c56f98SSadaf Ebrahimi      * Part 1: Provide key exchange parameters for chosen ciphersuite.
2793*62c56f98SSadaf Ebrahimi      *
2794*62c56f98SSadaf Ebrahimi      */
2795*62c56f98SSadaf Ebrahimi 
2796*62c56f98SSadaf Ebrahimi     /*
2797*62c56f98SSadaf Ebrahimi      * - ECJPAKE key exchanges
2798*62c56f98SSadaf Ebrahimi      */
2799*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
2800*62c56f98SSadaf Ebrahimi     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
2801*62c56f98SSadaf Ebrahimi         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2802*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
2803*62c56f98SSadaf Ebrahimi         unsigned char *out_p = ssl->out_msg + ssl->out_msglen;
2804*62c56f98SSadaf Ebrahimi         unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN -
2805*62c56f98SSadaf Ebrahimi                                ssl->out_msglen;
2806*62c56f98SSadaf Ebrahimi         size_t output_offset = 0;
2807*62c56f98SSadaf Ebrahimi         size_t output_len = 0;
2808*62c56f98SSadaf Ebrahimi 
2809*62c56f98SSadaf Ebrahimi         /*
2810*62c56f98SSadaf Ebrahimi          * The first 3 bytes are:
2811*62c56f98SSadaf Ebrahimi          * [0] MBEDTLS_ECP_TLS_NAMED_CURVE
2812*62c56f98SSadaf Ebrahimi          * [1, 2] elliptic curve's TLS ID
2813*62c56f98SSadaf Ebrahimi          *
2814*62c56f98SSadaf Ebrahimi          * However since we only support secp256r1 for now, we hardcode its
2815*62c56f98SSadaf Ebrahimi          * TLS ID here
2816*62c56f98SSadaf Ebrahimi          */
2817*62c56f98SSadaf Ebrahimi         uint16_t tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(
2818*62c56f98SSadaf Ebrahimi             MBEDTLS_ECP_DP_SECP256R1);
2819*62c56f98SSadaf Ebrahimi         if (tls_id == 0) {
2820*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
2821*62c56f98SSadaf Ebrahimi         }
2822*62c56f98SSadaf Ebrahimi         *out_p = MBEDTLS_ECP_TLS_NAMED_CURVE;
2823*62c56f98SSadaf Ebrahimi         MBEDTLS_PUT_UINT16_BE(tls_id, out_p, 1);
2824*62c56f98SSadaf Ebrahimi         output_offset += 3;
2825*62c56f98SSadaf Ebrahimi 
2826*62c56f98SSadaf Ebrahimi         ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx,
2827*62c56f98SSadaf Ebrahimi                                               out_p + output_offset,
2828*62c56f98SSadaf Ebrahimi                                               end_p - out_p - output_offset, &output_len,
2829*62c56f98SSadaf Ebrahimi                                               MBEDTLS_ECJPAKE_ROUND_TWO);
2830*62c56f98SSadaf Ebrahimi         if (ret != 0) {
2831*62c56f98SSadaf Ebrahimi             psa_destroy_key(ssl->handshake->psa_pake_password);
2832*62c56f98SSadaf Ebrahimi             psa_pake_abort(&ssl->handshake->psa_pake_ctx);
2833*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret);
2834*62c56f98SSadaf Ebrahimi             return ret;
2835*62c56f98SSadaf Ebrahimi         }
2836*62c56f98SSadaf Ebrahimi 
2837*62c56f98SSadaf Ebrahimi         output_offset += output_len;
2838*62c56f98SSadaf Ebrahimi         ssl->out_msglen += output_offset;
2839*62c56f98SSadaf Ebrahimi #else
2840*62c56f98SSadaf Ebrahimi         size_t len = 0;
2841*62c56f98SSadaf Ebrahimi 
2842*62c56f98SSadaf Ebrahimi         ret = mbedtls_ecjpake_write_round_two(
2843*62c56f98SSadaf Ebrahimi             &ssl->handshake->ecjpake_ctx,
2844*62c56f98SSadaf Ebrahimi             ssl->out_msg + ssl->out_msglen,
2845*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, &len,
2846*62c56f98SSadaf Ebrahimi             ssl->conf->f_rng, ssl->conf->p_rng);
2847*62c56f98SSadaf Ebrahimi         if (ret != 0) {
2848*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_two", ret);
2849*62c56f98SSadaf Ebrahimi             return ret;
2850*62c56f98SSadaf Ebrahimi         }
2851*62c56f98SSadaf Ebrahimi 
2852*62c56f98SSadaf Ebrahimi         ssl->out_msglen += len;
2853*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_USE_PSA_CRYPTO */
2854*62c56f98SSadaf Ebrahimi     }
2855*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
2856*62c56f98SSadaf Ebrahimi 
2857*62c56f98SSadaf Ebrahimi     /*
2858*62c56f98SSadaf Ebrahimi      * For (EC)DHE key exchanges with PSK, parameters are prefixed by support
2859*62c56f98SSadaf Ebrahimi      * identity hint (RFC 4279, Sec. 3). Until someone needs this feature,
2860*62c56f98SSadaf Ebrahimi      * we use empty support identity hints here.
2861*62c56f98SSadaf Ebrahimi      **/
2862*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)   || \
2863*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
2864*62c56f98SSadaf Ebrahimi     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
2865*62c56f98SSadaf Ebrahimi         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) {
2866*62c56f98SSadaf Ebrahimi         ssl->out_msg[ssl->out_msglen++] = 0x00;
2867*62c56f98SSadaf Ebrahimi         ssl->out_msg[ssl->out_msglen++] = 0x00;
2868*62c56f98SSadaf Ebrahimi     }
2869*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED ||
2870*62c56f98SSadaf Ebrahimi           MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
2871*62c56f98SSadaf Ebrahimi 
2872*62c56f98SSadaf Ebrahimi     /*
2873*62c56f98SSadaf Ebrahimi      * - DHE key exchanges
2874*62c56f98SSadaf Ebrahimi      */
2875*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED)
2876*62c56f98SSadaf Ebrahimi     if (mbedtls_ssl_ciphersuite_uses_dhe(ciphersuite_info)) {
2877*62c56f98SSadaf Ebrahimi         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2878*62c56f98SSadaf Ebrahimi         size_t len = 0;
2879*62c56f98SSadaf Ebrahimi 
2880*62c56f98SSadaf Ebrahimi         if (ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL) {
2881*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("no DH parameters set"));
2882*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
2883*62c56f98SSadaf Ebrahimi         }
2884*62c56f98SSadaf Ebrahimi 
2885*62c56f98SSadaf Ebrahimi         /*
2886*62c56f98SSadaf Ebrahimi          * Ephemeral DH parameters:
2887*62c56f98SSadaf Ebrahimi          *
2888*62c56f98SSadaf Ebrahimi          * struct {
2889*62c56f98SSadaf Ebrahimi          *     opaque dh_p<1..2^16-1>;
2890*62c56f98SSadaf Ebrahimi          *     opaque dh_g<1..2^16-1>;
2891*62c56f98SSadaf Ebrahimi          *     opaque dh_Ys<1..2^16-1>;
2892*62c56f98SSadaf Ebrahimi          * } ServerDHParams;
2893*62c56f98SSadaf Ebrahimi          */
2894*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_dhm_set_group(&ssl->handshake->dhm_ctx,
2895*62c56f98SSadaf Ebrahimi                                          &ssl->conf->dhm_P,
2896*62c56f98SSadaf Ebrahimi                                          &ssl->conf->dhm_G)) != 0) {
2897*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_set_group", ret);
2898*62c56f98SSadaf Ebrahimi             return ret;
2899*62c56f98SSadaf Ebrahimi         }
2900*62c56f98SSadaf Ebrahimi 
2901*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_dhm_make_params(
2902*62c56f98SSadaf Ebrahimi                  &ssl->handshake->dhm_ctx,
2903*62c56f98SSadaf Ebrahimi                  (int) mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx),
2904*62c56f98SSadaf Ebrahimi                  ssl->out_msg + ssl->out_msglen, &len,
2905*62c56f98SSadaf Ebrahimi                  ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
2906*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_make_params", ret);
2907*62c56f98SSadaf Ebrahimi             return ret;
2908*62c56f98SSadaf Ebrahimi         }
2909*62c56f98SSadaf Ebrahimi 
2910*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
2911*62c56f98SSadaf Ebrahimi         dig_signed = ssl->out_msg + ssl->out_msglen;
2912*62c56f98SSadaf Ebrahimi #endif
2913*62c56f98SSadaf Ebrahimi 
2914*62c56f98SSadaf Ebrahimi         ssl->out_msglen += len;
2915*62c56f98SSadaf Ebrahimi 
2916*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: X ", &ssl->handshake->dhm_ctx.X);
2917*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: P ", &ssl->handshake->dhm_ctx.P);
2918*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: G ", &ssl->handshake->dhm_ctx.G);
2919*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GX", &ssl->handshake->dhm_ctx.GX);
2920*62c56f98SSadaf Ebrahimi     }
2921*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED */
2922*62c56f98SSadaf Ebrahimi 
2923*62c56f98SSadaf Ebrahimi     /*
2924*62c56f98SSadaf Ebrahimi      * - ECDHE key exchanges
2925*62c56f98SSadaf Ebrahimi      */
2926*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED)
2927*62c56f98SSadaf Ebrahimi     if (mbedtls_ssl_ciphersuite_uses_ecdhe(ciphersuite_info)) {
2928*62c56f98SSadaf Ebrahimi         /*
2929*62c56f98SSadaf Ebrahimi          * Ephemeral ECDH parameters:
2930*62c56f98SSadaf Ebrahimi          *
2931*62c56f98SSadaf Ebrahimi          * struct {
2932*62c56f98SSadaf Ebrahimi          *     ECParameters curve_params;
2933*62c56f98SSadaf Ebrahimi          *     ECPoint      public;
2934*62c56f98SSadaf Ebrahimi          * } ServerECDHParams;
2935*62c56f98SSadaf Ebrahimi          */
2936*62c56f98SSadaf Ebrahimi         uint16_t *curr_tls_id = ssl->handshake->curves_tls_id;
2937*62c56f98SSadaf Ebrahimi         const uint16_t *group_list = mbedtls_ssl_get_groups(ssl);
2938*62c56f98SSadaf Ebrahimi         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2939*62c56f98SSadaf Ebrahimi         size_t len = 0;
2940*62c56f98SSadaf Ebrahimi 
2941*62c56f98SSadaf Ebrahimi         /* Match our preference list against the offered curves */
2942*62c56f98SSadaf Ebrahimi         if ((group_list == NULL) || (curr_tls_id == NULL)) {
2943*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_BAD_CONFIG;
2944*62c56f98SSadaf Ebrahimi         }
2945*62c56f98SSadaf Ebrahimi         for (; *group_list != 0; group_list++) {
2946*62c56f98SSadaf Ebrahimi             for (curr_tls_id = ssl->handshake->curves_tls_id;
2947*62c56f98SSadaf Ebrahimi                  *curr_tls_id != 0; curr_tls_id++) {
2948*62c56f98SSadaf Ebrahimi                 if (*curr_tls_id == *group_list) {
2949*62c56f98SSadaf Ebrahimi                     goto curve_matching_done;
2950*62c56f98SSadaf Ebrahimi                 }
2951*62c56f98SSadaf Ebrahimi             }
2952*62c56f98SSadaf Ebrahimi         }
2953*62c56f98SSadaf Ebrahimi 
2954*62c56f98SSadaf Ebrahimi curve_matching_done:
2955*62c56f98SSadaf Ebrahimi         if (*curr_tls_id == 0) {
2956*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("no matching curve for ECDHE"));
2957*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
2958*62c56f98SSadaf Ebrahimi         }
2959*62c56f98SSadaf Ebrahimi 
2960*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(2, ("ECDHE curve: %s",
2961*62c56f98SSadaf Ebrahimi                                   mbedtls_ssl_get_curve_name_from_tls_id(*curr_tls_id)));
2962*62c56f98SSadaf Ebrahimi 
2963*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
2964*62c56f98SSadaf Ebrahimi         psa_status_t status = PSA_ERROR_GENERIC_ERROR;
2965*62c56f98SSadaf Ebrahimi         psa_key_attributes_t key_attributes;
2966*62c56f98SSadaf Ebrahimi         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
2967*62c56f98SSadaf Ebrahimi         uint8_t *p = ssl->out_msg + ssl->out_msglen;
2968*62c56f98SSadaf Ebrahimi         const size_t header_size = 4; // curve_type(1), namedcurve(2),
2969*62c56f98SSadaf Ebrahimi                                       // data length(1)
2970*62c56f98SSadaf Ebrahimi         const size_t data_length_size = 1;
2971*62c56f98SSadaf Ebrahimi         psa_key_type_t key_type = PSA_KEY_TYPE_NONE;
2972*62c56f98SSadaf Ebrahimi         size_t ec_bits = 0;
2973*62c56f98SSadaf Ebrahimi 
2974*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("Perform PSA-based ECDH computation."));
2975*62c56f98SSadaf Ebrahimi 
2976*62c56f98SSadaf Ebrahimi         /* Convert EC's TLS ID to PSA key type. */
2977*62c56f98SSadaf Ebrahimi         if (mbedtls_ssl_get_psa_curve_info_from_tls_id(*curr_tls_id,
2978*62c56f98SSadaf Ebrahimi                                                        &key_type,
2979*62c56f98SSadaf Ebrahimi                                                        &ec_bits) == PSA_ERROR_NOT_SUPPORTED) {
2980*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid ecc group parse."));
2981*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
2982*62c56f98SSadaf Ebrahimi         }
2983*62c56f98SSadaf Ebrahimi         handshake->xxdh_psa_type = key_type;
2984*62c56f98SSadaf Ebrahimi         handshake->xxdh_psa_bits = ec_bits;
2985*62c56f98SSadaf Ebrahimi 
2986*62c56f98SSadaf Ebrahimi         key_attributes = psa_key_attributes_init();
2987*62c56f98SSadaf Ebrahimi         psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
2988*62c56f98SSadaf Ebrahimi         psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
2989*62c56f98SSadaf Ebrahimi         psa_set_key_type(&key_attributes, handshake->xxdh_psa_type);
2990*62c56f98SSadaf Ebrahimi         psa_set_key_bits(&key_attributes, handshake->xxdh_psa_bits);
2991*62c56f98SSadaf Ebrahimi 
2992*62c56f98SSadaf Ebrahimi         /*
2993*62c56f98SSadaf Ebrahimi          * ECParameters curve_params
2994*62c56f98SSadaf Ebrahimi          *
2995*62c56f98SSadaf Ebrahimi          * First byte is curve_type, always named_curve
2996*62c56f98SSadaf Ebrahimi          */
2997*62c56f98SSadaf Ebrahimi         *p++ = MBEDTLS_ECP_TLS_NAMED_CURVE;
2998*62c56f98SSadaf Ebrahimi 
2999*62c56f98SSadaf Ebrahimi         /*
3000*62c56f98SSadaf Ebrahimi          * Next two bytes are the namedcurve value
3001*62c56f98SSadaf Ebrahimi          */
3002*62c56f98SSadaf Ebrahimi         MBEDTLS_PUT_UINT16_BE(*curr_tls_id, p, 0);
3003*62c56f98SSadaf Ebrahimi         p += 2;
3004*62c56f98SSadaf Ebrahimi 
3005*62c56f98SSadaf Ebrahimi         /* Generate ECDH private key. */
3006*62c56f98SSadaf Ebrahimi         status = psa_generate_key(&key_attributes,
3007*62c56f98SSadaf Ebrahimi                                   &handshake->xxdh_psa_privkey);
3008*62c56f98SSadaf Ebrahimi         if (status != PSA_SUCCESS) {
3009*62c56f98SSadaf Ebrahimi             ret = PSA_TO_MBEDTLS_ERR(status);
3010*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "psa_generate_key", ret);
3011*62c56f98SSadaf Ebrahimi             return ret;
3012*62c56f98SSadaf Ebrahimi         }
3013*62c56f98SSadaf Ebrahimi 
3014*62c56f98SSadaf Ebrahimi         /*
3015*62c56f98SSadaf Ebrahimi          * ECPoint  public
3016*62c56f98SSadaf Ebrahimi          *
3017*62c56f98SSadaf Ebrahimi          * First byte is data length.
3018*62c56f98SSadaf Ebrahimi          * It will be filled later. p holds now the data length location.
3019*62c56f98SSadaf Ebrahimi          */
3020*62c56f98SSadaf Ebrahimi 
3021*62c56f98SSadaf Ebrahimi         /* Export the public part of the ECDH private key from PSA.
3022*62c56f98SSadaf Ebrahimi          * Make one byte space for the length.
3023*62c56f98SSadaf Ebrahimi          */
3024*62c56f98SSadaf Ebrahimi         unsigned char *own_pubkey = p + data_length_size;
3025*62c56f98SSadaf Ebrahimi 
3026*62c56f98SSadaf Ebrahimi         size_t own_pubkey_max_len = (size_t) (MBEDTLS_SSL_OUT_CONTENT_LEN
3027*62c56f98SSadaf Ebrahimi                                               - (own_pubkey - ssl->out_msg));
3028*62c56f98SSadaf Ebrahimi 
3029*62c56f98SSadaf Ebrahimi         status = psa_export_public_key(handshake->xxdh_psa_privkey,
3030*62c56f98SSadaf Ebrahimi                                        own_pubkey, own_pubkey_max_len,
3031*62c56f98SSadaf Ebrahimi                                        &len);
3032*62c56f98SSadaf Ebrahimi         if (status != PSA_SUCCESS) {
3033*62c56f98SSadaf Ebrahimi             ret = PSA_TO_MBEDTLS_ERR(status);
3034*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "psa_export_public_key", ret);
3035*62c56f98SSadaf Ebrahimi             (void) psa_destroy_key(handshake->xxdh_psa_privkey);
3036*62c56f98SSadaf Ebrahimi             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
3037*62c56f98SSadaf Ebrahimi             return ret;
3038*62c56f98SSadaf Ebrahimi         }
3039*62c56f98SSadaf Ebrahimi 
3040*62c56f98SSadaf Ebrahimi         /* Store the length of the exported public key. */
3041*62c56f98SSadaf Ebrahimi         *p = (uint8_t) len;
3042*62c56f98SSadaf Ebrahimi 
3043*62c56f98SSadaf Ebrahimi         /* Determine full message length. */
3044*62c56f98SSadaf Ebrahimi         len += header_size;
3045*62c56f98SSadaf Ebrahimi #else
3046*62c56f98SSadaf Ebrahimi         mbedtls_ecp_group_id curr_grp_id =
3047*62c56f98SSadaf Ebrahimi             mbedtls_ssl_get_ecp_group_id_from_tls_id(*curr_tls_id);
3048*62c56f98SSadaf Ebrahimi 
3049*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_ecdh_setup(&ssl->handshake->ecdh_ctx,
3050*62c56f98SSadaf Ebrahimi                                       curr_grp_id)) != 0) {
3051*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecp_group_load", ret);
3052*62c56f98SSadaf Ebrahimi             return ret;
3053*62c56f98SSadaf Ebrahimi         }
3054*62c56f98SSadaf Ebrahimi 
3055*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_ecdh_make_params(
3056*62c56f98SSadaf Ebrahimi                  &ssl->handshake->ecdh_ctx, &len,
3057*62c56f98SSadaf Ebrahimi                  ssl->out_msg + ssl->out_msglen,
3058*62c56f98SSadaf Ebrahimi                  MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen,
3059*62c56f98SSadaf Ebrahimi                  ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
3060*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_make_params", ret);
3061*62c56f98SSadaf Ebrahimi             return ret;
3062*62c56f98SSadaf Ebrahimi         }
3063*62c56f98SSadaf Ebrahimi 
3064*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
3065*62c56f98SSadaf Ebrahimi                                MBEDTLS_DEBUG_ECDH_Q);
3066*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_USE_PSA_CRYPTO */
3067*62c56f98SSadaf Ebrahimi 
3068*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
3069*62c56f98SSadaf Ebrahimi         dig_signed = ssl->out_msg + ssl->out_msglen;
3070*62c56f98SSadaf Ebrahimi #endif
3071*62c56f98SSadaf Ebrahimi 
3072*62c56f98SSadaf Ebrahimi         ssl->out_msglen += len;
3073*62c56f98SSadaf Ebrahimi     }
3074*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED */
3075*62c56f98SSadaf Ebrahimi 
3076*62c56f98SSadaf Ebrahimi     /*
3077*62c56f98SSadaf Ebrahimi      *
3078*62c56f98SSadaf Ebrahimi      * Part 2: For key exchanges involving the server signing the
3079*62c56f98SSadaf Ebrahimi      *         exchange parameters, compute and add the signature here.
3080*62c56f98SSadaf Ebrahimi      *
3081*62c56f98SSadaf Ebrahimi      */
3082*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
3083*62c56f98SSadaf Ebrahimi     if (mbedtls_ssl_ciphersuite_uses_server_signature(ciphersuite_info)) {
3084*62c56f98SSadaf Ebrahimi         if (dig_signed == NULL) {
3085*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
3086*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
3087*62c56f98SSadaf Ebrahimi         }
3088*62c56f98SSadaf Ebrahimi 
3089*62c56f98SSadaf Ebrahimi         size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed;
3090*62c56f98SSadaf Ebrahimi         size_t hashlen = 0;
3091*62c56f98SSadaf Ebrahimi         unsigned char hash[MBEDTLS_MD_MAX_SIZE];
3092*62c56f98SSadaf Ebrahimi 
3093*62c56f98SSadaf Ebrahimi         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3094*62c56f98SSadaf Ebrahimi 
3095*62c56f98SSadaf Ebrahimi         /*
3096*62c56f98SSadaf Ebrahimi          * 2.1: Choose hash algorithm:
3097*62c56f98SSadaf Ebrahimi          *      For TLS 1.2, obey signature-hash-algorithm extension
3098*62c56f98SSadaf Ebrahimi          *      to choose appropriate hash.
3099*62c56f98SSadaf Ebrahimi          */
3100*62c56f98SSadaf Ebrahimi 
3101*62c56f98SSadaf Ebrahimi         mbedtls_pk_type_t sig_alg =
3102*62c56f98SSadaf Ebrahimi             mbedtls_ssl_get_ciphersuite_sig_pk_alg(ciphersuite_info);
3103*62c56f98SSadaf Ebrahimi 
3104*62c56f98SSadaf Ebrahimi         unsigned int sig_hash =
3105*62c56f98SSadaf Ebrahimi             mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
3106*62c56f98SSadaf Ebrahimi                 ssl, mbedtls_ssl_sig_from_pk_alg(sig_alg));
3107*62c56f98SSadaf Ebrahimi 
3108*62c56f98SSadaf Ebrahimi         mbedtls_md_type_t md_alg = mbedtls_ssl_md_alg_from_hash(sig_hash);
3109*62c56f98SSadaf Ebrahimi 
3110*62c56f98SSadaf Ebrahimi         /*    For TLS 1.2, obey signature-hash-algorithm extension
3111*62c56f98SSadaf Ebrahimi          *    (RFC 5246, Sec. 7.4.1.4.1). */
3112*62c56f98SSadaf Ebrahimi         if (sig_alg == MBEDTLS_PK_NONE || md_alg == MBEDTLS_MD_NONE) {
3113*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
3114*62c56f98SSadaf Ebrahimi             /* (... because we choose a cipher suite
3115*62c56f98SSadaf Ebrahimi              *      only if there is a matching hash.) */
3116*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
3117*62c56f98SSadaf Ebrahimi         }
3118*62c56f98SSadaf Ebrahimi 
3119*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(3, ("pick hash algorithm %u for signing", (unsigned) md_alg));
3120*62c56f98SSadaf Ebrahimi 
3121*62c56f98SSadaf Ebrahimi         /*
3122*62c56f98SSadaf Ebrahimi          * 2.2: Compute the hash to be signed
3123*62c56f98SSadaf Ebrahimi          */
3124*62c56f98SSadaf Ebrahimi         if (md_alg != MBEDTLS_MD_NONE) {
3125*62c56f98SSadaf Ebrahimi             ret = mbedtls_ssl_get_key_exchange_md_tls1_2(ssl, hash, &hashlen,
3126*62c56f98SSadaf Ebrahimi                                                          dig_signed,
3127*62c56f98SSadaf Ebrahimi                                                          dig_signed_len,
3128*62c56f98SSadaf Ebrahimi                                                          md_alg);
3129*62c56f98SSadaf Ebrahimi             if (ret != 0) {
3130*62c56f98SSadaf Ebrahimi                 return ret;
3131*62c56f98SSadaf Ebrahimi             }
3132*62c56f98SSadaf Ebrahimi         } else {
3133*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
3134*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
3135*62c56f98SSadaf Ebrahimi         }
3136*62c56f98SSadaf Ebrahimi 
3137*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_BUF(3, "parameters hash", hash, hashlen);
3138*62c56f98SSadaf Ebrahimi 
3139*62c56f98SSadaf Ebrahimi         /*
3140*62c56f98SSadaf Ebrahimi          * 2.3: Compute and add the signature
3141*62c56f98SSadaf Ebrahimi          */
3142*62c56f98SSadaf Ebrahimi         /*
3143*62c56f98SSadaf Ebrahimi          * We need to specify signature and hash algorithm explicitly through
3144*62c56f98SSadaf Ebrahimi          * a prefix to the signature.
3145*62c56f98SSadaf Ebrahimi          *
3146*62c56f98SSadaf Ebrahimi          * struct {
3147*62c56f98SSadaf Ebrahimi          *    HashAlgorithm hash;
3148*62c56f98SSadaf Ebrahimi          *    SignatureAlgorithm signature;
3149*62c56f98SSadaf Ebrahimi          * } SignatureAndHashAlgorithm;
3150*62c56f98SSadaf Ebrahimi          *
3151*62c56f98SSadaf Ebrahimi          * struct {
3152*62c56f98SSadaf Ebrahimi          *    SignatureAndHashAlgorithm algorithm;
3153*62c56f98SSadaf Ebrahimi          *    opaque signature<0..2^16-1>;
3154*62c56f98SSadaf Ebrahimi          * } DigitallySigned;
3155*62c56f98SSadaf Ebrahimi          *
3156*62c56f98SSadaf Ebrahimi          */
3157*62c56f98SSadaf Ebrahimi 
3158*62c56f98SSadaf Ebrahimi         ssl->out_msg[ssl->out_msglen++] = mbedtls_ssl_hash_from_md_alg(md_alg);
3159*62c56f98SSadaf Ebrahimi         ssl->out_msg[ssl->out_msglen++] = mbedtls_ssl_sig_from_pk_alg(sig_alg);
3160*62c56f98SSadaf Ebrahimi 
3161*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
3162*62c56f98SSadaf Ebrahimi         if (ssl->conf->f_async_sign_start != NULL) {
3163*62c56f98SSadaf Ebrahimi             ret = ssl->conf->f_async_sign_start(ssl,
3164*62c56f98SSadaf Ebrahimi                                                 mbedtls_ssl_own_cert(ssl),
3165*62c56f98SSadaf Ebrahimi                                                 md_alg, hash, hashlen);
3166*62c56f98SSadaf Ebrahimi             switch (ret) {
3167*62c56f98SSadaf Ebrahimi                 case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH:
3168*62c56f98SSadaf Ebrahimi                     /* act as if f_async_sign was null */
3169*62c56f98SSadaf Ebrahimi                     break;
3170*62c56f98SSadaf Ebrahimi                 case 0:
3171*62c56f98SSadaf Ebrahimi                     ssl->handshake->async_in_progress = 1;
3172*62c56f98SSadaf Ebrahimi                     return ssl_resume_server_key_exchange(ssl, signature_len);
3173*62c56f98SSadaf Ebrahimi                 case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
3174*62c56f98SSadaf Ebrahimi                     ssl->handshake->async_in_progress = 1;
3175*62c56f98SSadaf Ebrahimi                     return MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS;
3176*62c56f98SSadaf Ebrahimi                 default:
3177*62c56f98SSadaf Ebrahimi                     MBEDTLS_SSL_DEBUG_RET(1, "f_async_sign_start", ret);
3178*62c56f98SSadaf Ebrahimi                     return ret;
3179*62c56f98SSadaf Ebrahimi             }
3180*62c56f98SSadaf Ebrahimi         }
3181*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
3182*62c56f98SSadaf Ebrahimi 
3183*62c56f98SSadaf Ebrahimi         if (mbedtls_ssl_own_key(ssl) == NULL) {
3184*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("got no private key"));
3185*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED;
3186*62c56f98SSadaf Ebrahimi         }
3187*62c56f98SSadaf Ebrahimi 
3188*62c56f98SSadaf Ebrahimi         /* Append the signature to ssl->out_msg, leaving 2 bytes for the
3189*62c56f98SSadaf Ebrahimi          * signature length which will be added in ssl_write_server_key_exchange
3190*62c56f98SSadaf Ebrahimi          * after the call to ssl_prepare_server_key_exchange.
3191*62c56f98SSadaf Ebrahimi          * ssl_write_server_key_exchange also takes care of incrementing
3192*62c56f98SSadaf Ebrahimi          * ssl->out_msglen. */
3193*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_pk_sign(mbedtls_ssl_own_key(ssl),
3194*62c56f98SSadaf Ebrahimi                                    md_alg, hash, hashlen,
3195*62c56f98SSadaf Ebrahimi                                    ssl->out_msg + ssl->out_msglen + 2,
3196*62c56f98SSadaf Ebrahimi                                    out_buf_len - ssl->out_msglen - 2,
3197*62c56f98SSadaf Ebrahimi                                    signature_len,
3198*62c56f98SSadaf Ebrahimi                                    ssl->conf->f_rng,
3199*62c56f98SSadaf Ebrahimi                                    ssl->conf->p_rng)) != 0) {
3200*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_sign", ret);
3201*62c56f98SSadaf Ebrahimi             return ret;
3202*62c56f98SSadaf Ebrahimi         }
3203*62c56f98SSadaf Ebrahimi     }
3204*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
3205*62c56f98SSadaf Ebrahimi 
3206*62c56f98SSadaf Ebrahimi     return 0;
3207*62c56f98SSadaf Ebrahimi }
3208*62c56f98SSadaf Ebrahimi 
3209*62c56f98SSadaf Ebrahimi /* Prepare the ServerKeyExchange message and send it. For ciphersuites
3210*62c56f98SSadaf Ebrahimi  * that do not include a ServerKeyExchange message, do nothing. Either
3211*62c56f98SSadaf Ebrahimi  * way, if successful, move on to the next step in the SSL state
3212*62c56f98SSadaf Ebrahimi  * machine. */
3213*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_write_server_key_exchange(mbedtls_ssl_context * ssl)3214*62c56f98SSadaf Ebrahimi static int ssl_write_server_key_exchange(mbedtls_ssl_context *ssl)
3215*62c56f98SSadaf Ebrahimi {
3216*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3217*62c56f98SSadaf Ebrahimi     size_t signature_len = 0;
3218*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED)
3219*62c56f98SSadaf Ebrahimi     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
3220*62c56f98SSadaf Ebrahimi         ssl->handshake->ciphersuite_info;
3221*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */
3222*62c56f98SSadaf Ebrahimi 
3223*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server key exchange"));
3224*62c56f98SSadaf Ebrahimi 
3225*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED)
3226*62c56f98SSadaf Ebrahimi     /* Extract static ECDH parameters and abort if ServerKeyExchange
3227*62c56f98SSadaf Ebrahimi      * is not needed. */
3228*62c56f98SSadaf Ebrahimi     if (mbedtls_ssl_ciphersuite_no_pfs(ciphersuite_info)) {
3229*62c56f98SSadaf Ebrahimi         /* For suites involving ECDH, extract DH parameters
3230*62c56f98SSadaf Ebrahimi          * from certificate at this point. */
3231*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED)
3232*62c56f98SSadaf Ebrahimi         if (mbedtls_ssl_ciphersuite_uses_ecdh(ciphersuite_info)) {
3233*62c56f98SSadaf Ebrahimi             ret = ssl_get_ecdh_params_from_cert(ssl);
3234*62c56f98SSadaf Ebrahimi             if (ret != 0) {
3235*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_RET(1, "ssl_get_ecdh_params_from_cert", ret);
3236*62c56f98SSadaf Ebrahimi                 return ret;
3237*62c56f98SSadaf Ebrahimi             }
3238*62c56f98SSadaf Ebrahimi         }
3239*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */
3240*62c56f98SSadaf Ebrahimi 
3241*62c56f98SSadaf Ebrahimi         /* Key exchanges not involving ephemeral keys don't use
3242*62c56f98SSadaf Ebrahimi          * ServerKeyExchange, so end here. */
3243*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write server key exchange"));
3244*62c56f98SSadaf Ebrahimi         ssl->state++;
3245*62c56f98SSadaf Ebrahimi         return 0;
3246*62c56f98SSadaf Ebrahimi     }
3247*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */
3248*62c56f98SSadaf Ebrahimi 
3249*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \
3250*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_SSL_ASYNC_PRIVATE)
3251*62c56f98SSadaf Ebrahimi     /* If we have already prepared the message and there is an ongoing
3252*62c56f98SSadaf Ebrahimi      * signature operation, resume signing. */
3253*62c56f98SSadaf Ebrahimi     if (ssl->handshake->async_in_progress != 0) {
3254*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(2, ("resuming signature operation"));
3255*62c56f98SSadaf Ebrahimi         ret = ssl_resume_server_key_exchange(ssl, &signature_len);
3256*62c56f98SSadaf Ebrahimi     } else
3257*62c56f98SSadaf Ebrahimi #endif /* defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) &&
3258*62c56f98SSadaf Ebrahimi           defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
3259*62c56f98SSadaf Ebrahimi     {
3260*62c56f98SSadaf Ebrahimi         /* ServerKeyExchange is needed. Prepare the message. */
3261*62c56f98SSadaf Ebrahimi         ret = ssl_prepare_server_key_exchange(ssl, &signature_len);
3262*62c56f98SSadaf Ebrahimi     }
3263*62c56f98SSadaf Ebrahimi 
3264*62c56f98SSadaf Ebrahimi     if (ret != 0) {
3265*62c56f98SSadaf Ebrahimi         /* If we're starting to write a new message, set ssl->out_msglen
3266*62c56f98SSadaf Ebrahimi          * to 0. But if we're resuming after an asynchronous message,
3267*62c56f98SSadaf Ebrahimi          * out_msglen is the amount of data written so far and mst be
3268*62c56f98SSadaf Ebrahimi          * preserved. */
3269*62c56f98SSadaf Ebrahimi         if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
3270*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server key exchange (pending)"));
3271*62c56f98SSadaf Ebrahimi         } else {
3272*62c56f98SSadaf Ebrahimi             ssl->out_msglen = 0;
3273*62c56f98SSadaf Ebrahimi         }
3274*62c56f98SSadaf Ebrahimi         return ret;
3275*62c56f98SSadaf Ebrahimi     }
3276*62c56f98SSadaf Ebrahimi 
3277*62c56f98SSadaf Ebrahimi     /* If there is a signature, write its length.
3278*62c56f98SSadaf Ebrahimi      * ssl_prepare_server_key_exchange already wrote the signature
3279*62c56f98SSadaf Ebrahimi      * itself at its proper place in the output buffer. */
3280*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
3281*62c56f98SSadaf Ebrahimi     if (signature_len != 0) {
3282*62c56f98SSadaf Ebrahimi         ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_1(signature_len);
3283*62c56f98SSadaf Ebrahimi         ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_0(signature_len);
3284*62c56f98SSadaf Ebrahimi 
3285*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_BUF(3, "my signature",
3286*62c56f98SSadaf Ebrahimi                               ssl->out_msg + ssl->out_msglen,
3287*62c56f98SSadaf Ebrahimi                               signature_len);
3288*62c56f98SSadaf Ebrahimi 
3289*62c56f98SSadaf Ebrahimi         /* Skip over the already-written signature */
3290*62c56f98SSadaf Ebrahimi         ssl->out_msglen += signature_len;
3291*62c56f98SSadaf Ebrahimi     }
3292*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
3293*62c56f98SSadaf Ebrahimi 
3294*62c56f98SSadaf Ebrahimi     /* Add header and send. */
3295*62c56f98SSadaf Ebrahimi     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
3296*62c56f98SSadaf Ebrahimi     ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE;
3297*62c56f98SSadaf Ebrahimi 
3298*62c56f98SSadaf Ebrahimi     ssl->state++;
3299*62c56f98SSadaf Ebrahimi 
3300*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
3301*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
3302*62c56f98SSadaf Ebrahimi         return ret;
3303*62c56f98SSadaf Ebrahimi     }
3304*62c56f98SSadaf Ebrahimi 
3305*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server key exchange"));
3306*62c56f98SSadaf Ebrahimi     return 0;
3307*62c56f98SSadaf Ebrahimi }
3308*62c56f98SSadaf Ebrahimi 
3309*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_write_server_hello_done(mbedtls_ssl_context * ssl)3310*62c56f98SSadaf Ebrahimi static int ssl_write_server_hello_done(mbedtls_ssl_context *ssl)
3311*62c56f98SSadaf Ebrahimi {
3312*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3313*62c56f98SSadaf Ebrahimi 
3314*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server hello done"));
3315*62c56f98SSadaf Ebrahimi 
3316*62c56f98SSadaf Ebrahimi     ssl->out_msglen  = 4;
3317*62c56f98SSadaf Ebrahimi     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
3318*62c56f98SSadaf Ebrahimi     ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_HELLO_DONE;
3319*62c56f98SSadaf Ebrahimi 
3320*62c56f98SSadaf Ebrahimi     ssl->state++;
3321*62c56f98SSadaf Ebrahimi 
3322*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_PROTO_DTLS)
3323*62c56f98SSadaf Ebrahimi     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
3324*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_flight_completed(ssl);
3325*62c56f98SSadaf Ebrahimi     }
3326*62c56f98SSadaf Ebrahimi #endif
3327*62c56f98SSadaf Ebrahimi 
3328*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
3329*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
3330*62c56f98SSadaf Ebrahimi         return ret;
3331*62c56f98SSadaf Ebrahimi     }
3332*62c56f98SSadaf Ebrahimi 
3333*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_PROTO_DTLS)
3334*62c56f98SSadaf Ebrahimi     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
3335*62c56f98SSadaf Ebrahimi         (ret = mbedtls_ssl_flight_transmit(ssl)) != 0) {
3336*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flight_transmit", ret);
3337*62c56f98SSadaf Ebrahimi         return ret;
3338*62c56f98SSadaf Ebrahimi     }
3339*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_PROTO_DTLS */
3340*62c56f98SSadaf Ebrahimi 
3341*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello done"));
3342*62c56f98SSadaf Ebrahimi 
3343*62c56f98SSadaf Ebrahimi     return 0;
3344*62c56f98SSadaf Ebrahimi }
3345*62c56f98SSadaf Ebrahimi 
3346*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
3347*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
3348*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_client_dh_public(mbedtls_ssl_context * ssl,unsigned char ** p,const unsigned char * end)3349*62c56f98SSadaf Ebrahimi static int ssl_parse_client_dh_public(mbedtls_ssl_context *ssl, unsigned char **p,
3350*62c56f98SSadaf Ebrahimi                                       const unsigned char *end)
3351*62c56f98SSadaf Ebrahimi {
3352*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
3353*62c56f98SSadaf Ebrahimi     size_t n;
3354*62c56f98SSadaf Ebrahimi 
3355*62c56f98SSadaf Ebrahimi     /*
3356*62c56f98SSadaf Ebrahimi      * Receive G^Y mod P, premaster = (G^Y)^X mod P
3357*62c56f98SSadaf Ebrahimi      */
3358*62c56f98SSadaf Ebrahimi     if (*p + 2 > end) {
3359*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
3360*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
3361*62c56f98SSadaf Ebrahimi     }
3362*62c56f98SSadaf Ebrahimi 
3363*62c56f98SSadaf Ebrahimi     n = ((*p)[0] << 8) | (*p)[1];
3364*62c56f98SSadaf Ebrahimi     *p += 2;
3365*62c56f98SSadaf Ebrahimi 
3366*62c56f98SSadaf Ebrahimi     if (*p + n > end) {
3367*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
3368*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
3369*62c56f98SSadaf Ebrahimi     }
3370*62c56f98SSadaf Ebrahimi 
3371*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_dhm_read_public(&ssl->handshake->dhm_ctx, *p, n)) != 0) {
3372*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_read_public", ret);
3373*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
3374*62c56f98SSadaf Ebrahimi     }
3375*62c56f98SSadaf Ebrahimi 
3376*62c56f98SSadaf Ebrahimi     *p += n;
3377*62c56f98SSadaf Ebrahimi 
3378*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GY", &ssl->handshake->dhm_ctx.GY);
3379*62c56f98SSadaf Ebrahimi 
3380*62c56f98SSadaf Ebrahimi     return ret;
3381*62c56f98SSadaf Ebrahimi }
3382*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
3383*62c56f98SSadaf Ebrahimi           MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
3384*62c56f98SSadaf Ebrahimi 
3385*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) ||                           \
3386*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
3387*62c56f98SSadaf Ebrahimi 
3388*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
3389*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_resume_decrypt_pms(mbedtls_ssl_context * ssl,unsigned char * peer_pms,size_t * peer_pmslen,size_t peer_pmssize)3390*62c56f98SSadaf Ebrahimi static int ssl_resume_decrypt_pms(mbedtls_ssl_context *ssl,
3391*62c56f98SSadaf Ebrahimi                                   unsigned char *peer_pms,
3392*62c56f98SSadaf Ebrahimi                                   size_t *peer_pmslen,
3393*62c56f98SSadaf Ebrahimi                                   size_t peer_pmssize)
3394*62c56f98SSadaf Ebrahimi {
3395*62c56f98SSadaf Ebrahimi     int ret = ssl->conf->f_async_resume(ssl,
3396*62c56f98SSadaf Ebrahimi                                         peer_pms, peer_pmslen, peer_pmssize);
3397*62c56f98SSadaf Ebrahimi     if (ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
3398*62c56f98SSadaf Ebrahimi         ssl->handshake->async_in_progress = 0;
3399*62c56f98SSadaf Ebrahimi         mbedtls_ssl_set_async_operation_data(ssl, NULL);
3400*62c56f98SSadaf Ebrahimi     }
3401*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_RET(2, "ssl_decrypt_encrypted_pms", ret);
3402*62c56f98SSadaf Ebrahimi     return ret;
3403*62c56f98SSadaf Ebrahimi }
3404*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
3405*62c56f98SSadaf Ebrahimi 
3406*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_decrypt_encrypted_pms(mbedtls_ssl_context * ssl,const unsigned char * p,const unsigned char * end,unsigned char * peer_pms,size_t * peer_pmslen,size_t peer_pmssize)3407*62c56f98SSadaf Ebrahimi static int ssl_decrypt_encrypted_pms(mbedtls_ssl_context *ssl,
3408*62c56f98SSadaf Ebrahimi                                      const unsigned char *p,
3409*62c56f98SSadaf Ebrahimi                                      const unsigned char *end,
3410*62c56f98SSadaf Ebrahimi                                      unsigned char *peer_pms,
3411*62c56f98SSadaf Ebrahimi                                      size_t *peer_pmslen,
3412*62c56f98SSadaf Ebrahimi                                      size_t peer_pmssize)
3413*62c56f98SSadaf Ebrahimi {
3414*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3415*62c56f98SSadaf Ebrahimi 
3416*62c56f98SSadaf Ebrahimi     mbedtls_x509_crt *own_cert = mbedtls_ssl_own_cert(ssl);
3417*62c56f98SSadaf Ebrahimi     if (own_cert == NULL) {
3418*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("got no local certificate"));
3419*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE;
3420*62c56f98SSadaf Ebrahimi     }
3421*62c56f98SSadaf Ebrahimi     mbedtls_pk_context *public_key = &own_cert->pk;
3422*62c56f98SSadaf Ebrahimi     mbedtls_pk_context *private_key = mbedtls_ssl_own_key(ssl);
3423*62c56f98SSadaf Ebrahimi     size_t len = mbedtls_pk_get_len(public_key);
3424*62c56f98SSadaf Ebrahimi 
3425*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
3426*62c56f98SSadaf Ebrahimi     /* If we have already started decoding the message and there is an ongoing
3427*62c56f98SSadaf Ebrahimi      * decryption operation, resume signing. */
3428*62c56f98SSadaf Ebrahimi     if (ssl->handshake->async_in_progress != 0) {
3429*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(2, ("resuming decryption operation"));
3430*62c56f98SSadaf Ebrahimi         return ssl_resume_decrypt_pms(ssl,
3431*62c56f98SSadaf Ebrahimi                                       peer_pms, peer_pmslen, peer_pmssize);
3432*62c56f98SSadaf Ebrahimi     }
3433*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
3434*62c56f98SSadaf Ebrahimi 
3435*62c56f98SSadaf Ebrahimi     /*
3436*62c56f98SSadaf Ebrahimi      * Prepare to decrypt the premaster using own private RSA key
3437*62c56f98SSadaf Ebrahimi      */
3438*62c56f98SSadaf Ebrahimi     if (p + 2 > end) {
3439*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
3440*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
3441*62c56f98SSadaf Ebrahimi     }
3442*62c56f98SSadaf Ebrahimi     if (*p++ != MBEDTLS_BYTE_1(len) ||
3443*62c56f98SSadaf Ebrahimi         *p++ != MBEDTLS_BYTE_0(len)) {
3444*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
3445*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
3446*62c56f98SSadaf Ebrahimi     }
3447*62c56f98SSadaf Ebrahimi 
3448*62c56f98SSadaf Ebrahimi     if (p + len != end) {
3449*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
3450*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
3451*62c56f98SSadaf Ebrahimi     }
3452*62c56f98SSadaf Ebrahimi 
3453*62c56f98SSadaf Ebrahimi     /*
3454*62c56f98SSadaf Ebrahimi      * Decrypt the premaster secret
3455*62c56f98SSadaf Ebrahimi      */
3456*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
3457*62c56f98SSadaf Ebrahimi     if (ssl->conf->f_async_decrypt_start != NULL) {
3458*62c56f98SSadaf Ebrahimi         ret = ssl->conf->f_async_decrypt_start(ssl,
3459*62c56f98SSadaf Ebrahimi                                                mbedtls_ssl_own_cert(ssl),
3460*62c56f98SSadaf Ebrahimi                                                p, len);
3461*62c56f98SSadaf Ebrahimi         switch (ret) {
3462*62c56f98SSadaf Ebrahimi             case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH:
3463*62c56f98SSadaf Ebrahimi                 /* act as if f_async_decrypt_start was null */
3464*62c56f98SSadaf Ebrahimi                 break;
3465*62c56f98SSadaf Ebrahimi             case 0:
3466*62c56f98SSadaf Ebrahimi                 ssl->handshake->async_in_progress = 1;
3467*62c56f98SSadaf Ebrahimi                 return ssl_resume_decrypt_pms(ssl,
3468*62c56f98SSadaf Ebrahimi                                               peer_pms,
3469*62c56f98SSadaf Ebrahimi                                               peer_pmslen,
3470*62c56f98SSadaf Ebrahimi                                               peer_pmssize);
3471*62c56f98SSadaf Ebrahimi             case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
3472*62c56f98SSadaf Ebrahimi                 ssl->handshake->async_in_progress = 1;
3473*62c56f98SSadaf Ebrahimi                 return MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS;
3474*62c56f98SSadaf Ebrahimi             default:
3475*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_RET(1, "f_async_decrypt_start", ret);
3476*62c56f98SSadaf Ebrahimi                 return ret;
3477*62c56f98SSadaf Ebrahimi         }
3478*62c56f98SSadaf Ebrahimi     }
3479*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
3480*62c56f98SSadaf Ebrahimi 
3481*62c56f98SSadaf Ebrahimi     if (!mbedtls_pk_can_do(private_key, MBEDTLS_PK_RSA)) {
3482*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("got no RSA private key"));
3483*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED;
3484*62c56f98SSadaf Ebrahimi     }
3485*62c56f98SSadaf Ebrahimi 
3486*62c56f98SSadaf Ebrahimi     ret = mbedtls_pk_decrypt(private_key, p, len,
3487*62c56f98SSadaf Ebrahimi                              peer_pms, peer_pmslen, peer_pmssize,
3488*62c56f98SSadaf Ebrahimi                              ssl->conf->f_rng, ssl->conf->p_rng);
3489*62c56f98SSadaf Ebrahimi     return ret;
3490*62c56f98SSadaf Ebrahimi }
3491*62c56f98SSadaf Ebrahimi 
3492*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_encrypted_pms(mbedtls_ssl_context * ssl,const unsigned char * p,const unsigned char * end,size_t pms_offset)3493*62c56f98SSadaf Ebrahimi static int ssl_parse_encrypted_pms(mbedtls_ssl_context *ssl,
3494*62c56f98SSadaf Ebrahimi                                    const unsigned char *p,
3495*62c56f98SSadaf Ebrahimi                                    const unsigned char *end,
3496*62c56f98SSadaf Ebrahimi                                    size_t pms_offset)
3497*62c56f98SSadaf Ebrahimi {
3498*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3499*62c56f98SSadaf Ebrahimi     unsigned char *pms = ssl->handshake->premaster + pms_offset;
3500*62c56f98SSadaf Ebrahimi     unsigned char ver[2];
3501*62c56f98SSadaf Ebrahimi     unsigned char fake_pms[48], peer_pms[48];
3502*62c56f98SSadaf Ebrahimi     size_t peer_pmslen;
3503*62c56f98SSadaf Ebrahimi     mbedtls_ct_condition_t diff;
3504*62c56f98SSadaf Ebrahimi 
3505*62c56f98SSadaf Ebrahimi     /* In case of a failure in decryption, the decryption may write less than
3506*62c56f98SSadaf Ebrahimi      * 2 bytes of output, but we always read the first two bytes. It doesn't
3507*62c56f98SSadaf Ebrahimi      * matter in the end because diff will be nonzero in that case due to
3508*62c56f98SSadaf Ebrahimi      * ret being nonzero, and we only care whether diff is 0.
3509*62c56f98SSadaf Ebrahimi      * But do initialize peer_pms and peer_pmslen for robustness anyway. This
3510*62c56f98SSadaf Ebrahimi      * also makes memory analyzers happy (don't access uninitialized memory,
3511*62c56f98SSadaf Ebrahimi      * even if it's an unsigned char). */
3512*62c56f98SSadaf Ebrahimi     peer_pms[0] = peer_pms[1] = ~0;
3513*62c56f98SSadaf Ebrahimi     peer_pmslen = 0;
3514*62c56f98SSadaf Ebrahimi 
3515*62c56f98SSadaf Ebrahimi     ret = ssl_decrypt_encrypted_pms(ssl, p, end,
3516*62c56f98SSadaf Ebrahimi                                     peer_pms,
3517*62c56f98SSadaf Ebrahimi                                     &peer_pmslen,
3518*62c56f98SSadaf Ebrahimi                                     sizeof(peer_pms));
3519*62c56f98SSadaf Ebrahimi 
3520*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
3521*62c56f98SSadaf Ebrahimi     if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
3522*62c56f98SSadaf Ebrahimi         return ret;
3523*62c56f98SSadaf Ebrahimi     }
3524*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
3525*62c56f98SSadaf Ebrahimi 
3526*62c56f98SSadaf Ebrahimi     mbedtls_ssl_write_version(ver, ssl->conf->transport,
3527*62c56f98SSadaf Ebrahimi                               ssl->session_negotiate->tls_version);
3528*62c56f98SSadaf Ebrahimi 
3529*62c56f98SSadaf Ebrahimi     /* Avoid data-dependent branches while checking for invalid
3530*62c56f98SSadaf Ebrahimi      * padding, to protect against timing-based Bleichenbacher-type
3531*62c56f98SSadaf Ebrahimi      * attacks. */
3532*62c56f98SSadaf Ebrahimi     diff = mbedtls_ct_bool(ret);
3533*62c56f98SSadaf Ebrahimi     diff = mbedtls_ct_bool_or(diff, mbedtls_ct_uint_ne(peer_pmslen, 48));
3534*62c56f98SSadaf Ebrahimi     diff = mbedtls_ct_bool_or(diff, mbedtls_ct_uint_ne(peer_pms[0], ver[0]));
3535*62c56f98SSadaf Ebrahimi     diff = mbedtls_ct_bool_or(diff, mbedtls_ct_uint_ne(peer_pms[1], ver[1]));
3536*62c56f98SSadaf Ebrahimi 
3537*62c56f98SSadaf Ebrahimi     /*
3538*62c56f98SSadaf Ebrahimi      * Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding
3539*62c56f98SSadaf Ebrahimi      * must not cause the connection to end immediately; instead, send a
3540*62c56f98SSadaf Ebrahimi      * bad_record_mac later in the handshake.
3541*62c56f98SSadaf Ebrahimi      * To protect against timing-based variants of the attack, we must
3542*62c56f98SSadaf Ebrahimi      * not have any branch that depends on whether the decryption was
3543*62c56f98SSadaf Ebrahimi      * successful. In particular, always generate the fake premaster secret,
3544*62c56f98SSadaf Ebrahimi      * regardless of whether it will ultimately influence the output or not.
3545*62c56f98SSadaf Ebrahimi      */
3546*62c56f98SSadaf Ebrahimi     ret = ssl->conf->f_rng(ssl->conf->p_rng, fake_pms, sizeof(fake_pms));
3547*62c56f98SSadaf Ebrahimi     if (ret != 0) {
3548*62c56f98SSadaf Ebrahimi         /* It's ok to abort on an RNG failure, since this does not reveal
3549*62c56f98SSadaf Ebrahimi          * anything about the RSA decryption. */
3550*62c56f98SSadaf Ebrahimi         return ret;
3551*62c56f98SSadaf Ebrahimi     }
3552*62c56f98SSadaf Ebrahimi 
3553*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_DEBUG_ALL)
3554*62c56f98SSadaf Ebrahimi     if (diff != MBEDTLS_CT_FALSE) {
3555*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
3556*62c56f98SSadaf Ebrahimi     }
3557*62c56f98SSadaf Ebrahimi #endif
3558*62c56f98SSadaf Ebrahimi 
3559*62c56f98SSadaf Ebrahimi     if (sizeof(ssl->handshake->premaster) < pms_offset ||
3560*62c56f98SSadaf Ebrahimi         sizeof(ssl->handshake->premaster) - pms_offset < 48) {
3561*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
3562*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
3563*62c56f98SSadaf Ebrahimi     }
3564*62c56f98SSadaf Ebrahimi     ssl->handshake->pmslen = 48;
3565*62c56f98SSadaf Ebrahimi 
3566*62c56f98SSadaf Ebrahimi     /* Set pms to either the true or the fake PMS, without
3567*62c56f98SSadaf Ebrahimi      * data-dependent branches. */
3568*62c56f98SSadaf Ebrahimi     mbedtls_ct_memcpy_if(diff, pms, fake_pms, peer_pms, ssl->handshake->pmslen);
3569*62c56f98SSadaf Ebrahimi 
3570*62c56f98SSadaf Ebrahimi     return 0;
3571*62c56f98SSadaf Ebrahimi }
3572*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
3573*62c56f98SSadaf Ebrahimi           MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
3574*62c56f98SSadaf Ebrahimi 
3575*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
3576*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_client_psk_identity(mbedtls_ssl_context * ssl,unsigned char ** p,const unsigned char * end)3577*62c56f98SSadaf Ebrahimi static int ssl_parse_client_psk_identity(mbedtls_ssl_context *ssl, unsigned char **p,
3578*62c56f98SSadaf Ebrahimi                                          const unsigned char *end)
3579*62c56f98SSadaf Ebrahimi {
3580*62c56f98SSadaf Ebrahimi     int ret = 0;
3581*62c56f98SSadaf Ebrahimi     uint16_t n;
3582*62c56f98SSadaf Ebrahimi 
3583*62c56f98SSadaf Ebrahimi     if (ssl_conf_has_psk_or_cb(ssl->conf) == 0) {
3584*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("got no pre-shared key"));
3585*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED;
3586*62c56f98SSadaf Ebrahimi     }
3587*62c56f98SSadaf Ebrahimi 
3588*62c56f98SSadaf Ebrahimi     /*
3589*62c56f98SSadaf Ebrahimi      * Receive client pre-shared key identity name
3590*62c56f98SSadaf Ebrahimi      */
3591*62c56f98SSadaf Ebrahimi     if (end - *p < 2) {
3592*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
3593*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
3594*62c56f98SSadaf Ebrahimi     }
3595*62c56f98SSadaf Ebrahimi 
3596*62c56f98SSadaf Ebrahimi     n = ((*p)[0] << 8) | (*p)[1];
3597*62c56f98SSadaf Ebrahimi     *p += 2;
3598*62c56f98SSadaf Ebrahimi 
3599*62c56f98SSadaf Ebrahimi     if (n == 0 || n > end - *p) {
3600*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
3601*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
3602*62c56f98SSadaf Ebrahimi     }
3603*62c56f98SSadaf Ebrahimi 
3604*62c56f98SSadaf Ebrahimi     if (ssl->conf->f_psk != NULL) {
3605*62c56f98SSadaf Ebrahimi         if (ssl->conf->f_psk(ssl->conf->p_psk, ssl, *p, n) != 0) {
3606*62c56f98SSadaf Ebrahimi             ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
3607*62c56f98SSadaf Ebrahimi         }
3608*62c56f98SSadaf Ebrahimi     } else {
3609*62c56f98SSadaf Ebrahimi         /* Identity is not a big secret since clients send it in the clear,
3610*62c56f98SSadaf Ebrahimi          * but treat it carefully anyway, just in case */
3611*62c56f98SSadaf Ebrahimi         if (n != ssl->conf->psk_identity_len ||
3612*62c56f98SSadaf Ebrahimi             mbedtls_ct_memcmp(ssl->conf->psk_identity, *p, n) != 0) {
3613*62c56f98SSadaf Ebrahimi             ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
3614*62c56f98SSadaf Ebrahimi         }
3615*62c56f98SSadaf Ebrahimi     }
3616*62c56f98SSadaf Ebrahimi 
3617*62c56f98SSadaf Ebrahimi     if (ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) {
3618*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_BUF(3, "Unknown PSK identity", *p, n);
3619*62c56f98SSadaf Ebrahimi         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
3620*62c56f98SSadaf Ebrahimi                                        MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY);
3621*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
3622*62c56f98SSadaf Ebrahimi     }
3623*62c56f98SSadaf Ebrahimi 
3624*62c56f98SSadaf Ebrahimi     *p += n;
3625*62c56f98SSadaf Ebrahimi 
3626*62c56f98SSadaf Ebrahimi     return 0;
3627*62c56f98SSadaf Ebrahimi }
3628*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
3629*62c56f98SSadaf Ebrahimi 
3630*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_client_key_exchange(mbedtls_ssl_context * ssl)3631*62c56f98SSadaf Ebrahimi static int ssl_parse_client_key_exchange(mbedtls_ssl_context *ssl)
3632*62c56f98SSadaf Ebrahimi {
3633*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3634*62c56f98SSadaf Ebrahimi     const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
3635*62c56f98SSadaf Ebrahimi     unsigned char *p, *end;
3636*62c56f98SSadaf Ebrahimi 
3637*62c56f98SSadaf Ebrahimi     ciphersuite_info = ssl->handshake->ciphersuite_info;
3638*62c56f98SSadaf Ebrahimi 
3639*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse client key exchange"));
3640*62c56f98SSadaf Ebrahimi 
3641*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_ASYNC_PRIVATE) && \
3642*62c56f98SSadaf Ebrahimi     (defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
3643*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED))
3644*62c56f98SSadaf Ebrahimi     if ((ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
3645*62c56f98SSadaf Ebrahimi          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) &&
3646*62c56f98SSadaf Ebrahimi         (ssl->handshake->async_in_progress != 0)) {
3647*62c56f98SSadaf Ebrahimi         /* We've already read a record and there is an asynchronous
3648*62c56f98SSadaf Ebrahimi          * operation in progress to decrypt it. So skip reading the
3649*62c56f98SSadaf Ebrahimi          * record. */
3650*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(3, ("will resume decryption of previously-read record"));
3651*62c56f98SSadaf Ebrahimi     } else
3652*62c56f98SSadaf Ebrahimi #endif
3653*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
3654*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
3655*62c56f98SSadaf Ebrahimi         return ret;
3656*62c56f98SSadaf Ebrahimi     }
3657*62c56f98SSadaf Ebrahimi 
3658*62c56f98SSadaf Ebrahimi     p = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl);
3659*62c56f98SSadaf Ebrahimi     end = ssl->in_msg + ssl->in_hslen;
3660*62c56f98SSadaf Ebrahimi 
3661*62c56f98SSadaf Ebrahimi     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
3662*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
3663*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
3664*62c56f98SSadaf Ebrahimi     }
3665*62c56f98SSadaf Ebrahimi 
3666*62c56f98SSadaf Ebrahimi     if (ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE) {
3667*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
3668*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
3669*62c56f98SSadaf Ebrahimi     }
3670*62c56f98SSadaf Ebrahimi 
3671*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
3672*62c56f98SSadaf Ebrahimi     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA) {
3673*62c56f98SSadaf Ebrahimi         if ((ret = ssl_parse_client_dh_public(ssl, &p, end)) != 0) {
3674*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_dh_public"), ret);
3675*62c56f98SSadaf Ebrahimi             return ret;
3676*62c56f98SSadaf Ebrahimi         }
3677*62c56f98SSadaf Ebrahimi 
3678*62c56f98SSadaf Ebrahimi         if (p != end) {
3679*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange"));
3680*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_DECODE_ERROR;
3681*62c56f98SSadaf Ebrahimi         }
3682*62c56f98SSadaf Ebrahimi 
3683*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx,
3684*62c56f98SSadaf Ebrahimi                                            ssl->handshake->premaster,
3685*62c56f98SSadaf Ebrahimi                                            MBEDTLS_PREMASTER_SIZE,
3686*62c56f98SSadaf Ebrahimi                                            &ssl->handshake->pmslen,
3687*62c56f98SSadaf Ebrahimi                                            ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
3688*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret);
3689*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_DECODE_ERROR;
3690*62c56f98SSadaf Ebrahimi         }
3691*62c56f98SSadaf Ebrahimi 
3692*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K);
3693*62c56f98SSadaf Ebrahimi     } else
3694*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
3695*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
3696*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
3697*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
3698*62c56f98SSadaf Ebrahimi     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
3699*62c56f98SSadaf Ebrahimi     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
3700*62c56f98SSadaf Ebrahimi         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
3701*62c56f98SSadaf Ebrahimi         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
3702*62c56f98SSadaf Ebrahimi         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA) {
3703*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
3704*62c56f98SSadaf Ebrahimi         size_t data_len = (size_t) (*p++);
3705*62c56f98SSadaf Ebrahimi         size_t buf_len = (size_t) (end - p);
3706*62c56f98SSadaf Ebrahimi         psa_status_t status = PSA_ERROR_GENERIC_ERROR;
3707*62c56f98SSadaf Ebrahimi         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
3708*62c56f98SSadaf Ebrahimi 
3709*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(3, ("Read the peer's public key."));
3710*62c56f98SSadaf Ebrahimi 
3711*62c56f98SSadaf Ebrahimi         /*
3712*62c56f98SSadaf Ebrahimi          * We must have at least two bytes (1 for length, at least 1 for data)
3713*62c56f98SSadaf Ebrahimi          */
3714*62c56f98SSadaf Ebrahimi         if (buf_len < 2) {
3715*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid buffer length: %" MBEDTLS_PRINTF_SIZET,
3716*62c56f98SSadaf Ebrahimi                                       buf_len));
3717*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
3718*62c56f98SSadaf Ebrahimi         }
3719*62c56f98SSadaf Ebrahimi 
3720*62c56f98SSadaf Ebrahimi         if (data_len < 1 || data_len > buf_len) {
3721*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid data length: %" MBEDTLS_PRINTF_SIZET
3722*62c56f98SSadaf Ebrahimi                                       " > %" MBEDTLS_PRINTF_SIZET,
3723*62c56f98SSadaf Ebrahimi                                       data_len, buf_len));
3724*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
3725*62c56f98SSadaf Ebrahimi         }
3726*62c56f98SSadaf Ebrahimi 
3727*62c56f98SSadaf Ebrahimi         /* Store peer's ECDH public key. */
3728*62c56f98SSadaf Ebrahimi         if (data_len > sizeof(handshake->xxdh_psa_peerkey)) {
3729*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid public key length: %" MBEDTLS_PRINTF_SIZET
3730*62c56f98SSadaf Ebrahimi                                       " > %" MBEDTLS_PRINTF_SIZET,
3731*62c56f98SSadaf Ebrahimi                                       data_len,
3732*62c56f98SSadaf Ebrahimi                                       sizeof(handshake->xxdh_psa_peerkey)));
3733*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
3734*62c56f98SSadaf Ebrahimi         }
3735*62c56f98SSadaf Ebrahimi         memcpy(handshake->xxdh_psa_peerkey, p, data_len);
3736*62c56f98SSadaf Ebrahimi         handshake->xxdh_psa_peerkey_len = data_len;
3737*62c56f98SSadaf Ebrahimi 
3738*62c56f98SSadaf Ebrahimi         /* Compute ECDH shared secret. */
3739*62c56f98SSadaf Ebrahimi         status = psa_raw_key_agreement(
3740*62c56f98SSadaf Ebrahimi             PSA_ALG_ECDH, handshake->xxdh_psa_privkey,
3741*62c56f98SSadaf Ebrahimi             handshake->xxdh_psa_peerkey, handshake->xxdh_psa_peerkey_len,
3742*62c56f98SSadaf Ebrahimi             handshake->premaster, sizeof(handshake->premaster),
3743*62c56f98SSadaf Ebrahimi             &handshake->pmslen);
3744*62c56f98SSadaf Ebrahimi         if (status != PSA_SUCCESS) {
3745*62c56f98SSadaf Ebrahimi             ret = PSA_TO_MBEDTLS_ERR(status);
3746*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "psa_raw_key_agreement", ret);
3747*62c56f98SSadaf Ebrahimi             if (handshake->xxdh_psa_privkey_is_external == 0) {
3748*62c56f98SSadaf Ebrahimi                 (void) psa_destroy_key(handshake->xxdh_psa_privkey);
3749*62c56f98SSadaf Ebrahimi             }
3750*62c56f98SSadaf Ebrahimi             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
3751*62c56f98SSadaf Ebrahimi             return ret;
3752*62c56f98SSadaf Ebrahimi         }
3753*62c56f98SSadaf Ebrahimi 
3754*62c56f98SSadaf Ebrahimi         if (handshake->xxdh_psa_privkey_is_external == 0) {
3755*62c56f98SSadaf Ebrahimi             status = psa_destroy_key(handshake->xxdh_psa_privkey);
3756*62c56f98SSadaf Ebrahimi 
3757*62c56f98SSadaf Ebrahimi             if (status != PSA_SUCCESS) {
3758*62c56f98SSadaf Ebrahimi                 ret = PSA_TO_MBEDTLS_ERR(status);
3759*62c56f98SSadaf Ebrahimi                 MBEDTLS_SSL_DEBUG_RET(1, "psa_destroy_key", ret);
3760*62c56f98SSadaf Ebrahimi                 return ret;
3761*62c56f98SSadaf Ebrahimi             }
3762*62c56f98SSadaf Ebrahimi         }
3763*62c56f98SSadaf Ebrahimi         handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
3764*62c56f98SSadaf Ebrahimi #else
3765*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_ecdh_read_public(&ssl->handshake->ecdh_ctx,
3766*62c56f98SSadaf Ebrahimi                                             p, end - p)) != 0) {
3767*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_read_public", ret);
3768*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_DECODE_ERROR;
3769*62c56f98SSadaf Ebrahimi         }
3770*62c56f98SSadaf Ebrahimi 
3771*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
3772*62c56f98SSadaf Ebrahimi                                MBEDTLS_DEBUG_ECDH_QP);
3773*62c56f98SSadaf Ebrahimi 
3774*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_ecdh_calc_secret(&ssl->handshake->ecdh_ctx,
3775*62c56f98SSadaf Ebrahimi                                             &ssl->handshake->pmslen,
3776*62c56f98SSadaf Ebrahimi                                             ssl->handshake->premaster,
3777*62c56f98SSadaf Ebrahimi                                             MBEDTLS_MPI_MAX_SIZE,
3778*62c56f98SSadaf Ebrahimi                                             ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
3779*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_calc_secret", ret);
3780*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_DECODE_ERROR;
3781*62c56f98SSadaf Ebrahimi         }
3782*62c56f98SSadaf Ebrahimi 
3783*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
3784*62c56f98SSadaf Ebrahimi                                MBEDTLS_DEBUG_ECDH_Z);
3785*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_USE_PSA_CRYPTO */
3786*62c56f98SSadaf Ebrahimi     } else
3787*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
3788*62c56f98SSadaf Ebrahimi           MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
3789*62c56f98SSadaf Ebrahimi           MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
3790*62c56f98SSadaf Ebrahimi           MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
3791*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
3792*62c56f98SSadaf Ebrahimi     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK) {
3793*62c56f98SSadaf Ebrahimi         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
3794*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
3795*62c56f98SSadaf Ebrahimi             return ret;
3796*62c56f98SSadaf Ebrahimi         }
3797*62c56f98SSadaf Ebrahimi 
3798*62c56f98SSadaf Ebrahimi         if (p != end) {
3799*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange"));
3800*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_DECODE_ERROR;
3801*62c56f98SSadaf Ebrahimi         }
3802*62c56f98SSadaf Ebrahimi 
3803*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_USE_PSA_CRYPTO)
3804*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
3805*62c56f98SSadaf Ebrahimi                                                     (mbedtls_key_exchange_type_t) ciphersuite_info->
3806*62c56f98SSadaf Ebrahimi                                                     key_exchange)) != 0) {
3807*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret);
3808*62c56f98SSadaf Ebrahimi             return ret;
3809*62c56f98SSadaf Ebrahimi         }
3810*62c56f98SSadaf Ebrahimi #endif /* !MBEDTLS_USE_PSA_CRYPTO */
3811*62c56f98SSadaf Ebrahimi     } else
3812*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
3813*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
3814*62c56f98SSadaf Ebrahimi     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) {
3815*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
3816*62c56f98SSadaf Ebrahimi         if (ssl->handshake->async_in_progress != 0) {
3817*62c56f98SSadaf Ebrahimi             /* There is an asynchronous operation in progress to
3818*62c56f98SSadaf Ebrahimi              * decrypt the encrypted premaster secret, so skip
3819*62c56f98SSadaf Ebrahimi              * directly to resuming this operation. */
3820*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(3, ("PSK identity already parsed"));
3821*62c56f98SSadaf Ebrahimi             /* Update p to skip the PSK identity. ssl_parse_encrypted_pms
3822*62c56f98SSadaf Ebrahimi              * won't actually use it, but maintain p anyway for robustness. */
3823*62c56f98SSadaf Ebrahimi             p += ssl->conf->psk_identity_len + 2;
3824*62c56f98SSadaf Ebrahimi         } else
3825*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
3826*62c56f98SSadaf Ebrahimi         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
3827*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
3828*62c56f98SSadaf Ebrahimi             return ret;
3829*62c56f98SSadaf Ebrahimi         }
3830*62c56f98SSadaf Ebrahimi 
3831*62c56f98SSadaf Ebrahimi         if ((ret = ssl_parse_encrypted_pms(ssl, p, end, 2)) != 0) {
3832*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_encrypted_pms"), ret);
3833*62c56f98SSadaf Ebrahimi             return ret;
3834*62c56f98SSadaf Ebrahimi         }
3835*62c56f98SSadaf Ebrahimi 
3836*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_USE_PSA_CRYPTO)
3837*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
3838*62c56f98SSadaf Ebrahimi                                                     (mbedtls_key_exchange_type_t) ciphersuite_info->
3839*62c56f98SSadaf Ebrahimi                                                     key_exchange)) != 0) {
3840*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret);
3841*62c56f98SSadaf Ebrahimi             return ret;
3842*62c56f98SSadaf Ebrahimi         }
3843*62c56f98SSadaf Ebrahimi #endif /* !MBEDTLS_USE_PSA_CRYPTO */
3844*62c56f98SSadaf Ebrahimi     } else
3845*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
3846*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
3847*62c56f98SSadaf Ebrahimi     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK) {
3848*62c56f98SSadaf Ebrahimi         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
3849*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
3850*62c56f98SSadaf Ebrahimi             return ret;
3851*62c56f98SSadaf Ebrahimi         }
3852*62c56f98SSadaf Ebrahimi         if ((ret = ssl_parse_client_dh_public(ssl, &p, end)) != 0) {
3853*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_dh_public"), ret);
3854*62c56f98SSadaf Ebrahimi             return ret;
3855*62c56f98SSadaf Ebrahimi         }
3856*62c56f98SSadaf Ebrahimi 
3857*62c56f98SSadaf Ebrahimi         if (p != end) {
3858*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange"));
3859*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_DECODE_ERROR;
3860*62c56f98SSadaf Ebrahimi         }
3861*62c56f98SSadaf Ebrahimi 
3862*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
3863*62c56f98SSadaf Ebrahimi         unsigned char *pms = ssl->handshake->premaster;
3864*62c56f98SSadaf Ebrahimi         unsigned char *pms_end = pms + sizeof(ssl->handshake->premaster);
3865*62c56f98SSadaf Ebrahimi         size_t pms_len;
3866*62c56f98SSadaf Ebrahimi 
3867*62c56f98SSadaf Ebrahimi         /* Write length only when we know the actual value */
3868*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx,
3869*62c56f98SSadaf Ebrahimi                                            pms + 2, pms_end - (pms + 2), &pms_len,
3870*62c56f98SSadaf Ebrahimi                                            ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
3871*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret);
3872*62c56f98SSadaf Ebrahimi             return ret;
3873*62c56f98SSadaf Ebrahimi         }
3874*62c56f98SSadaf Ebrahimi         MBEDTLS_PUT_UINT16_BE(pms_len, pms, 0);
3875*62c56f98SSadaf Ebrahimi         pms += 2 + pms_len;
3876*62c56f98SSadaf Ebrahimi 
3877*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K);
3878*62c56f98SSadaf Ebrahimi #else
3879*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
3880*62c56f98SSadaf Ebrahimi                                                     (mbedtls_key_exchange_type_t) ciphersuite_info->
3881*62c56f98SSadaf Ebrahimi                                                     key_exchange)) != 0) {
3882*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret);
3883*62c56f98SSadaf Ebrahimi             return ret;
3884*62c56f98SSadaf Ebrahimi         }
3885*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_USE_PSA_CRYPTO */
3886*62c56f98SSadaf Ebrahimi     } else
3887*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
3888*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
3889*62c56f98SSadaf Ebrahimi     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) {
3890*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
3891*62c56f98SSadaf Ebrahimi         psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
3892*62c56f98SSadaf Ebrahimi         psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED;
3893*62c56f98SSadaf Ebrahimi         uint8_t ecpoint_len;
3894*62c56f98SSadaf Ebrahimi 
3895*62c56f98SSadaf Ebrahimi         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
3896*62c56f98SSadaf Ebrahimi 
3897*62c56f98SSadaf Ebrahimi         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
3898*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
3899*62c56f98SSadaf Ebrahimi             psa_destroy_key(handshake->xxdh_psa_privkey);
3900*62c56f98SSadaf Ebrahimi             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
3901*62c56f98SSadaf Ebrahimi             return ret;
3902*62c56f98SSadaf Ebrahimi         }
3903*62c56f98SSadaf Ebrahimi 
3904*62c56f98SSadaf Ebrahimi         /* Keep a copy of the peer's public key */
3905*62c56f98SSadaf Ebrahimi         if (p >= end) {
3906*62c56f98SSadaf Ebrahimi             psa_destroy_key(handshake->xxdh_psa_privkey);
3907*62c56f98SSadaf Ebrahimi             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
3908*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_DECODE_ERROR;
3909*62c56f98SSadaf Ebrahimi         }
3910*62c56f98SSadaf Ebrahimi 
3911*62c56f98SSadaf Ebrahimi         ecpoint_len = *(p++);
3912*62c56f98SSadaf Ebrahimi         if ((size_t) (end - p) < ecpoint_len) {
3913*62c56f98SSadaf Ebrahimi             psa_destroy_key(handshake->xxdh_psa_privkey);
3914*62c56f98SSadaf Ebrahimi             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
3915*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_DECODE_ERROR;
3916*62c56f98SSadaf Ebrahimi         }
3917*62c56f98SSadaf Ebrahimi 
3918*62c56f98SSadaf Ebrahimi         /* When FFDH is enabled, the array handshake->xxdh_psa_peer_key size takes into account
3919*62c56f98SSadaf Ebrahimi            the sizes of the FFDH keys which are at least 2048 bits.
3920*62c56f98SSadaf Ebrahimi            The size of the array is thus greater than 256 bytes which is greater than any
3921*62c56f98SSadaf Ebrahimi            possible value of ecpoint_len (type uint8_t) and the check below can be skipped.*/
3922*62c56f98SSadaf Ebrahimi #if !defined(PSA_WANT_ALG_FFDH)
3923*62c56f98SSadaf Ebrahimi         if (ecpoint_len > sizeof(handshake->xxdh_psa_peerkey)) {
3924*62c56f98SSadaf Ebrahimi             psa_destroy_key(handshake->xxdh_psa_privkey);
3925*62c56f98SSadaf Ebrahimi             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
3926*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
3927*62c56f98SSadaf Ebrahimi         }
3928*62c56f98SSadaf Ebrahimi #else
3929*62c56f98SSadaf Ebrahimi         MBEDTLS_STATIC_ASSERT(sizeof(handshake->xxdh_psa_peerkey) >= UINT8_MAX,
3930*62c56f98SSadaf Ebrahimi                               "peer key buffer too small");
3931*62c56f98SSadaf Ebrahimi #endif
3932*62c56f98SSadaf Ebrahimi 
3933*62c56f98SSadaf Ebrahimi         memcpy(handshake->xxdh_psa_peerkey, p, ecpoint_len);
3934*62c56f98SSadaf Ebrahimi         handshake->xxdh_psa_peerkey_len = ecpoint_len;
3935*62c56f98SSadaf Ebrahimi         p += ecpoint_len;
3936*62c56f98SSadaf Ebrahimi 
3937*62c56f98SSadaf Ebrahimi         /* As RFC 5489 section 2, the premaster secret is formed as follows:
3938*62c56f98SSadaf Ebrahimi          * - a uint16 containing the length (in octets) of the ECDH computation
3939*62c56f98SSadaf Ebrahimi          * - the octet string produced by the ECDH computation
3940*62c56f98SSadaf Ebrahimi          * - a uint16 containing the length (in octets) of the PSK
3941*62c56f98SSadaf Ebrahimi          * - the PSK itself
3942*62c56f98SSadaf Ebrahimi          */
3943*62c56f98SSadaf Ebrahimi         unsigned char *psm = ssl->handshake->premaster;
3944*62c56f98SSadaf Ebrahimi         const unsigned char * const psm_end =
3945*62c56f98SSadaf Ebrahimi             psm + sizeof(ssl->handshake->premaster);
3946*62c56f98SSadaf Ebrahimi         /* uint16 to store length (in octets) of the ECDH computation */
3947*62c56f98SSadaf Ebrahimi         const size_t zlen_size = 2;
3948*62c56f98SSadaf Ebrahimi         size_t zlen = 0;
3949*62c56f98SSadaf Ebrahimi 
3950*62c56f98SSadaf Ebrahimi         /* Compute ECDH shared secret. */
3951*62c56f98SSadaf Ebrahimi         status = psa_raw_key_agreement(PSA_ALG_ECDH,
3952*62c56f98SSadaf Ebrahimi                                        handshake->xxdh_psa_privkey,
3953*62c56f98SSadaf Ebrahimi                                        handshake->xxdh_psa_peerkey,
3954*62c56f98SSadaf Ebrahimi                                        handshake->xxdh_psa_peerkey_len,
3955*62c56f98SSadaf Ebrahimi                                        psm + zlen_size,
3956*62c56f98SSadaf Ebrahimi                                        psm_end - (psm + zlen_size),
3957*62c56f98SSadaf Ebrahimi                                        &zlen);
3958*62c56f98SSadaf Ebrahimi 
3959*62c56f98SSadaf Ebrahimi         destruction_status = psa_destroy_key(handshake->xxdh_psa_privkey);
3960*62c56f98SSadaf Ebrahimi         handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
3961*62c56f98SSadaf Ebrahimi 
3962*62c56f98SSadaf Ebrahimi         if (status != PSA_SUCCESS) {
3963*62c56f98SSadaf Ebrahimi             return PSA_TO_MBEDTLS_ERR(status);
3964*62c56f98SSadaf Ebrahimi         } else if (destruction_status != PSA_SUCCESS) {
3965*62c56f98SSadaf Ebrahimi             return PSA_TO_MBEDTLS_ERR(destruction_status);
3966*62c56f98SSadaf Ebrahimi         }
3967*62c56f98SSadaf Ebrahimi 
3968*62c56f98SSadaf Ebrahimi         /* Write the ECDH computation length before the ECDH computation */
3969*62c56f98SSadaf Ebrahimi         MBEDTLS_PUT_UINT16_BE(zlen, psm, 0);
3970*62c56f98SSadaf Ebrahimi         psm += zlen_size + zlen;
3971*62c56f98SSadaf Ebrahimi 
3972*62c56f98SSadaf Ebrahimi #else /* MBEDTLS_USE_PSA_CRYPTO */
3973*62c56f98SSadaf Ebrahimi         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
3974*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
3975*62c56f98SSadaf Ebrahimi             return ret;
3976*62c56f98SSadaf Ebrahimi         }
3977*62c56f98SSadaf Ebrahimi 
3978*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_ecdh_read_public(&ssl->handshake->ecdh_ctx,
3979*62c56f98SSadaf Ebrahimi                                             p, end - p)) != 0) {
3980*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_read_public", ret);
3981*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_DECODE_ERROR;
3982*62c56f98SSadaf Ebrahimi         }
3983*62c56f98SSadaf Ebrahimi 
3984*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
3985*62c56f98SSadaf Ebrahimi                                MBEDTLS_DEBUG_ECDH_QP);
3986*62c56f98SSadaf Ebrahimi 
3987*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
3988*62c56f98SSadaf Ebrahimi                                                     (mbedtls_key_exchange_type_t) ciphersuite_info->
3989*62c56f98SSadaf Ebrahimi                                                     key_exchange)) != 0) {
3990*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret);
3991*62c56f98SSadaf Ebrahimi             return ret;
3992*62c56f98SSadaf Ebrahimi         }
3993*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_USE_PSA_CRYPTO */
3994*62c56f98SSadaf Ebrahimi     } else
3995*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
3996*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
3997*62c56f98SSadaf Ebrahimi     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) {
3998*62c56f98SSadaf Ebrahimi         if ((ret = ssl_parse_encrypted_pms(ssl, p, end, 0)) != 0) {
3999*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_parse_encrypted_pms_secret"), ret);
4000*62c56f98SSadaf Ebrahimi             return ret;
4001*62c56f98SSadaf Ebrahimi         }
4002*62c56f98SSadaf Ebrahimi     } else
4003*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
4004*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
4005*62c56f98SSadaf Ebrahimi     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
4006*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_USE_PSA_CRYPTO)
4007*62c56f98SSadaf Ebrahimi         if ((ret = mbedtls_psa_ecjpake_read_round(
4008*62c56f98SSadaf Ebrahimi                  &ssl->handshake->psa_pake_ctx, p, end - p,
4009*62c56f98SSadaf Ebrahimi                  MBEDTLS_ECJPAKE_ROUND_TWO)) != 0) {
4010*62c56f98SSadaf Ebrahimi             psa_destroy_key(ssl->handshake->psa_pake_password);
4011*62c56f98SSadaf Ebrahimi             psa_pake_abort(&ssl->handshake->psa_pake_ctx);
4012*62c56f98SSadaf Ebrahimi 
4013*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round two", ret);
4014*62c56f98SSadaf Ebrahimi             return ret;
4015*62c56f98SSadaf Ebrahimi         }
4016*62c56f98SSadaf Ebrahimi #else
4017*62c56f98SSadaf Ebrahimi         ret = mbedtls_ecjpake_read_round_two(&ssl->handshake->ecjpake_ctx,
4018*62c56f98SSadaf Ebrahimi                                              p, end - p);
4019*62c56f98SSadaf Ebrahimi         if (ret != 0) {
4020*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_two", ret);
4021*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
4022*62c56f98SSadaf Ebrahimi         }
4023*62c56f98SSadaf Ebrahimi 
4024*62c56f98SSadaf Ebrahimi         ret = mbedtls_ecjpake_derive_secret(&ssl->handshake->ecjpake_ctx,
4025*62c56f98SSadaf Ebrahimi                                             ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
4026*62c56f98SSadaf Ebrahimi                                             ssl->conf->f_rng, ssl->conf->p_rng);
4027*62c56f98SSadaf Ebrahimi         if (ret != 0) {
4028*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_derive_secret", ret);
4029*62c56f98SSadaf Ebrahimi             return ret;
4030*62c56f98SSadaf Ebrahimi         }
4031*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_USE_PSA_CRYPTO */
4032*62c56f98SSadaf Ebrahimi     } else
4033*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
4034*62c56f98SSadaf Ebrahimi     {
4035*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
4036*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
4037*62c56f98SSadaf Ebrahimi     }
4038*62c56f98SSadaf Ebrahimi 
4039*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) {
4040*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret);
4041*62c56f98SSadaf Ebrahimi         return ret;
4042*62c56f98SSadaf Ebrahimi     }
4043*62c56f98SSadaf Ebrahimi 
4044*62c56f98SSadaf Ebrahimi     ssl->state++;
4045*62c56f98SSadaf Ebrahimi 
4046*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse client key exchange"));
4047*62c56f98SSadaf Ebrahimi 
4048*62c56f98SSadaf Ebrahimi     return 0;
4049*62c56f98SSadaf Ebrahimi }
4050*62c56f98SSadaf Ebrahimi 
4051*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
4052*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_certificate_verify(mbedtls_ssl_context * ssl)4053*62c56f98SSadaf Ebrahimi static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl)
4054*62c56f98SSadaf Ebrahimi {
4055*62c56f98SSadaf Ebrahimi     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
4056*62c56f98SSadaf Ebrahimi         ssl->handshake->ciphersuite_info;
4057*62c56f98SSadaf Ebrahimi 
4058*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate verify"));
4059*62c56f98SSadaf Ebrahimi 
4060*62c56f98SSadaf Ebrahimi     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
4061*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
4062*62c56f98SSadaf Ebrahimi         ssl->state++;
4063*62c56f98SSadaf Ebrahimi         return 0;
4064*62c56f98SSadaf Ebrahimi     }
4065*62c56f98SSadaf Ebrahimi 
4066*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
4067*62c56f98SSadaf Ebrahimi     return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
4068*62c56f98SSadaf Ebrahimi }
4069*62c56f98SSadaf Ebrahimi #else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
4070*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_certificate_verify(mbedtls_ssl_context * ssl)4071*62c56f98SSadaf Ebrahimi static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl)
4072*62c56f98SSadaf Ebrahimi {
4073*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
4074*62c56f98SSadaf Ebrahimi     size_t i, sig_len;
4075*62c56f98SSadaf Ebrahimi     unsigned char hash[48];
4076*62c56f98SSadaf Ebrahimi     unsigned char *hash_start = hash;
4077*62c56f98SSadaf Ebrahimi     size_t hashlen;
4078*62c56f98SSadaf Ebrahimi     mbedtls_pk_type_t pk_alg;
4079*62c56f98SSadaf Ebrahimi     mbedtls_md_type_t md_alg;
4080*62c56f98SSadaf Ebrahimi     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
4081*62c56f98SSadaf Ebrahimi         ssl->handshake->ciphersuite_info;
4082*62c56f98SSadaf Ebrahimi     mbedtls_pk_context *peer_pk;
4083*62c56f98SSadaf Ebrahimi 
4084*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate verify"));
4085*62c56f98SSadaf Ebrahimi 
4086*62c56f98SSadaf Ebrahimi     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
4087*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
4088*62c56f98SSadaf Ebrahimi         ssl->state++;
4089*62c56f98SSadaf Ebrahimi         return 0;
4090*62c56f98SSadaf Ebrahimi     }
4091*62c56f98SSadaf Ebrahimi 
4092*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
4093*62c56f98SSadaf Ebrahimi     if (ssl->session_negotiate->peer_cert == NULL) {
4094*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
4095*62c56f98SSadaf Ebrahimi         ssl->state++;
4096*62c56f98SSadaf Ebrahimi         return 0;
4097*62c56f98SSadaf Ebrahimi     }
4098*62c56f98SSadaf Ebrahimi #else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
4099*62c56f98SSadaf Ebrahimi     if (ssl->session_negotiate->peer_cert_digest == NULL) {
4100*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
4101*62c56f98SSadaf Ebrahimi         ssl->state++;
4102*62c56f98SSadaf Ebrahimi         return 0;
4103*62c56f98SSadaf Ebrahimi     }
4104*62c56f98SSadaf Ebrahimi #endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
4105*62c56f98SSadaf Ebrahimi 
4106*62c56f98SSadaf Ebrahimi     /* Read the message without adding it to the checksum */
4107*62c56f98SSadaf Ebrahimi     ret = mbedtls_ssl_read_record(ssl, 0 /* no checksum update */);
4108*62c56f98SSadaf Ebrahimi     if (0 != ret) {
4109*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_read_record"), ret);
4110*62c56f98SSadaf Ebrahimi         return ret;
4111*62c56f98SSadaf Ebrahimi     }
4112*62c56f98SSadaf Ebrahimi 
4113*62c56f98SSadaf Ebrahimi     ssl->state++;
4114*62c56f98SSadaf Ebrahimi 
4115*62c56f98SSadaf Ebrahimi     /* Process the message contents */
4116*62c56f98SSadaf Ebrahimi     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ||
4117*62c56f98SSadaf Ebrahimi         ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY) {
4118*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message"));
4119*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
4120*62c56f98SSadaf Ebrahimi     }
4121*62c56f98SSadaf Ebrahimi 
4122*62c56f98SSadaf Ebrahimi     i = mbedtls_ssl_hs_hdr_len(ssl);
4123*62c56f98SSadaf Ebrahimi 
4124*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
4125*62c56f98SSadaf Ebrahimi     peer_pk = &ssl->handshake->peer_pubkey;
4126*62c56f98SSadaf Ebrahimi #else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
4127*62c56f98SSadaf Ebrahimi     if (ssl->session_negotiate->peer_cert == NULL) {
4128*62c56f98SSadaf Ebrahimi         /* Should never happen */
4129*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
4130*62c56f98SSadaf Ebrahimi     }
4131*62c56f98SSadaf Ebrahimi     peer_pk = &ssl->session_negotiate->peer_cert->pk;
4132*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
4133*62c56f98SSadaf Ebrahimi 
4134*62c56f98SSadaf Ebrahimi     /*
4135*62c56f98SSadaf Ebrahimi      *  struct {
4136*62c56f98SSadaf Ebrahimi      *     SignatureAndHashAlgorithm algorithm; -- TLS 1.2 only
4137*62c56f98SSadaf Ebrahimi      *     opaque signature<0..2^16-1>;
4138*62c56f98SSadaf Ebrahimi      *  } DigitallySigned;
4139*62c56f98SSadaf Ebrahimi      */
4140*62c56f98SSadaf Ebrahimi     if (i + 2 > ssl->in_hslen) {
4141*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message"));
4142*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
4143*62c56f98SSadaf Ebrahimi     }
4144*62c56f98SSadaf Ebrahimi 
4145*62c56f98SSadaf Ebrahimi     /*
4146*62c56f98SSadaf Ebrahimi      * Hash
4147*62c56f98SSadaf Ebrahimi      */
4148*62c56f98SSadaf Ebrahimi     md_alg = mbedtls_ssl_md_alg_from_hash(ssl->in_msg[i]);
4149*62c56f98SSadaf Ebrahimi 
4150*62c56f98SSadaf Ebrahimi     if (md_alg == MBEDTLS_MD_NONE || mbedtls_ssl_set_calc_verify_md(ssl, ssl->in_msg[i])) {
4151*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("peer not adhering to requested sig_alg"
4152*62c56f98SSadaf Ebrahimi                                   " for verify message"));
4153*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
4154*62c56f98SSadaf Ebrahimi     }
4155*62c56f98SSadaf Ebrahimi 
4156*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_MD_SHA1)
4157*62c56f98SSadaf Ebrahimi     if (MBEDTLS_MD_SHA1 == md_alg) {
4158*62c56f98SSadaf Ebrahimi         hash_start += 16;
4159*62c56f98SSadaf Ebrahimi     }
4160*62c56f98SSadaf Ebrahimi #endif
4161*62c56f98SSadaf Ebrahimi 
4162*62c56f98SSadaf Ebrahimi     /* Info from md_alg will be used instead */
4163*62c56f98SSadaf Ebrahimi     hashlen = 0;
4164*62c56f98SSadaf Ebrahimi 
4165*62c56f98SSadaf Ebrahimi     i++;
4166*62c56f98SSadaf Ebrahimi 
4167*62c56f98SSadaf Ebrahimi     /*
4168*62c56f98SSadaf Ebrahimi      * Signature
4169*62c56f98SSadaf Ebrahimi      */
4170*62c56f98SSadaf Ebrahimi     if ((pk_alg = mbedtls_ssl_pk_alg_from_sig(ssl->in_msg[i]))
4171*62c56f98SSadaf Ebrahimi         == MBEDTLS_PK_NONE) {
4172*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("peer not adhering to requested sig_alg"
4173*62c56f98SSadaf Ebrahimi                                   " for verify message"));
4174*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
4175*62c56f98SSadaf Ebrahimi     }
4176*62c56f98SSadaf Ebrahimi 
4177*62c56f98SSadaf Ebrahimi     /*
4178*62c56f98SSadaf Ebrahimi      * Check the certificate's key type matches the signature alg
4179*62c56f98SSadaf Ebrahimi      */
4180*62c56f98SSadaf Ebrahimi     if (!mbedtls_pk_can_do(peer_pk, pk_alg)) {
4181*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("sig_alg doesn't match cert key"));
4182*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
4183*62c56f98SSadaf Ebrahimi     }
4184*62c56f98SSadaf Ebrahimi 
4185*62c56f98SSadaf Ebrahimi     i++;
4186*62c56f98SSadaf Ebrahimi 
4187*62c56f98SSadaf Ebrahimi     if (i + 2 > ssl->in_hslen) {
4188*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message"));
4189*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
4190*62c56f98SSadaf Ebrahimi     }
4191*62c56f98SSadaf Ebrahimi 
4192*62c56f98SSadaf Ebrahimi     sig_len = (ssl->in_msg[i] << 8) | ssl->in_msg[i+1];
4193*62c56f98SSadaf Ebrahimi     i += 2;
4194*62c56f98SSadaf Ebrahimi 
4195*62c56f98SSadaf Ebrahimi     if (i + sig_len != ssl->in_hslen) {
4196*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message"));
4197*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_SSL_DECODE_ERROR;
4198*62c56f98SSadaf Ebrahimi     }
4199*62c56f98SSadaf Ebrahimi 
4200*62c56f98SSadaf Ebrahimi     /* Calculate hash and verify signature */
4201*62c56f98SSadaf Ebrahimi     {
4202*62c56f98SSadaf Ebrahimi         size_t dummy_hlen;
4203*62c56f98SSadaf Ebrahimi         ret = ssl->handshake->calc_verify(ssl, hash, &dummy_hlen);
4204*62c56f98SSadaf Ebrahimi         if (0 != ret) {
4205*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_RET(1, ("calc_verify"), ret);
4206*62c56f98SSadaf Ebrahimi             return ret;
4207*62c56f98SSadaf Ebrahimi         }
4208*62c56f98SSadaf Ebrahimi     }
4209*62c56f98SSadaf Ebrahimi 
4210*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_pk_verify(peer_pk,
4211*62c56f98SSadaf Ebrahimi                                  md_alg, hash_start, hashlen,
4212*62c56f98SSadaf Ebrahimi                                  ssl->in_msg + i, sig_len)) != 0) {
4213*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_verify", ret);
4214*62c56f98SSadaf Ebrahimi         return ret;
4215*62c56f98SSadaf Ebrahimi     }
4216*62c56f98SSadaf Ebrahimi 
4217*62c56f98SSadaf Ebrahimi     ret = mbedtls_ssl_update_handshake_status(ssl);
4218*62c56f98SSadaf Ebrahimi     if (0 != ret) {
4219*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_update_handshake_status"), ret);
4220*62c56f98SSadaf Ebrahimi         return ret;
4221*62c56f98SSadaf Ebrahimi     }
4222*62c56f98SSadaf Ebrahimi 
4223*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate verify"));
4224*62c56f98SSadaf Ebrahimi 
4225*62c56f98SSadaf Ebrahimi     return ret;
4226*62c56f98SSadaf Ebrahimi }
4227*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
4228*62c56f98SSadaf Ebrahimi 
4229*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_SESSION_TICKETS)
4230*62c56f98SSadaf Ebrahimi MBEDTLS_CHECK_RETURN_CRITICAL
ssl_write_new_session_ticket(mbedtls_ssl_context * ssl)4231*62c56f98SSadaf Ebrahimi static int ssl_write_new_session_ticket(mbedtls_ssl_context *ssl)
4232*62c56f98SSadaf Ebrahimi {
4233*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
4234*62c56f98SSadaf Ebrahimi     size_t tlen;
4235*62c56f98SSadaf Ebrahimi     uint32_t lifetime;
4236*62c56f98SSadaf Ebrahimi 
4237*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write new session ticket"));
4238*62c56f98SSadaf Ebrahimi 
4239*62c56f98SSadaf Ebrahimi     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
4240*62c56f98SSadaf Ebrahimi     ssl->out_msg[0]  = MBEDTLS_SSL_HS_NEW_SESSION_TICKET;
4241*62c56f98SSadaf Ebrahimi 
4242*62c56f98SSadaf Ebrahimi     /*
4243*62c56f98SSadaf Ebrahimi      * struct {
4244*62c56f98SSadaf Ebrahimi      *     uint32 ticket_lifetime_hint;
4245*62c56f98SSadaf Ebrahimi      *     opaque ticket<0..2^16-1>;
4246*62c56f98SSadaf Ebrahimi      * } NewSessionTicket;
4247*62c56f98SSadaf Ebrahimi      *
4248*62c56f98SSadaf Ebrahimi      * 4  .  7   ticket_lifetime_hint (0 = unspecified)
4249*62c56f98SSadaf Ebrahimi      * 8  .  9   ticket_len (n)
4250*62c56f98SSadaf Ebrahimi      * 10 .  9+n ticket content
4251*62c56f98SSadaf Ebrahimi      */
4252*62c56f98SSadaf Ebrahimi 
4253*62c56f98SSadaf Ebrahimi     if ((ret = ssl->conf->f_ticket_write(ssl->conf->p_ticket,
4254*62c56f98SSadaf Ebrahimi                                          ssl->session_negotiate,
4255*62c56f98SSadaf Ebrahimi                                          ssl->out_msg + 10,
4256*62c56f98SSadaf Ebrahimi                                          ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN,
4257*62c56f98SSadaf Ebrahimi                                          &tlen, &lifetime)) != 0) {
4258*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_ticket_write", ret);
4259*62c56f98SSadaf Ebrahimi         tlen = 0;
4260*62c56f98SSadaf Ebrahimi     }
4261*62c56f98SSadaf Ebrahimi 
4262*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT32_BE(lifetime, ssl->out_msg, 4);
4263*62c56f98SSadaf Ebrahimi     MBEDTLS_PUT_UINT16_BE(tlen, ssl->out_msg, 8);
4264*62c56f98SSadaf Ebrahimi     ssl->out_msglen = 10 + tlen;
4265*62c56f98SSadaf Ebrahimi 
4266*62c56f98SSadaf Ebrahimi     /*
4267*62c56f98SSadaf Ebrahimi      * Morally equivalent to updating ssl->state, but NewSessionTicket and
4268*62c56f98SSadaf Ebrahimi      * ChangeCipherSpec share the same state.
4269*62c56f98SSadaf Ebrahimi      */
4270*62c56f98SSadaf Ebrahimi     ssl->handshake->new_session_ticket = 0;
4271*62c56f98SSadaf Ebrahimi 
4272*62c56f98SSadaf Ebrahimi     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
4273*62c56f98SSadaf Ebrahimi         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
4274*62c56f98SSadaf Ebrahimi         return ret;
4275*62c56f98SSadaf Ebrahimi     }
4276*62c56f98SSadaf Ebrahimi 
4277*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write new session ticket"));
4278*62c56f98SSadaf Ebrahimi 
4279*62c56f98SSadaf Ebrahimi     return 0;
4280*62c56f98SSadaf Ebrahimi }
4281*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_SESSION_TICKETS */
4282*62c56f98SSadaf Ebrahimi 
4283*62c56f98SSadaf Ebrahimi /*
4284*62c56f98SSadaf Ebrahimi  * SSL handshake -- server side -- single step
4285*62c56f98SSadaf Ebrahimi  */
mbedtls_ssl_handshake_server_step(mbedtls_ssl_context * ssl)4286*62c56f98SSadaf Ebrahimi int mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl)
4287*62c56f98SSadaf Ebrahimi {
4288*62c56f98SSadaf Ebrahimi     int ret = 0;
4289*62c56f98SSadaf Ebrahimi 
4290*62c56f98SSadaf Ebrahimi     MBEDTLS_SSL_DEBUG_MSG(2, ("server state: %d", ssl->state));
4291*62c56f98SSadaf Ebrahimi 
4292*62c56f98SSadaf Ebrahimi     switch (ssl->state) {
4293*62c56f98SSadaf Ebrahimi         case MBEDTLS_SSL_HELLO_REQUEST:
4294*62c56f98SSadaf Ebrahimi             ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
4295*62c56f98SSadaf Ebrahimi             break;
4296*62c56f98SSadaf Ebrahimi 
4297*62c56f98SSadaf Ebrahimi         /*
4298*62c56f98SSadaf Ebrahimi          *  <==   ClientHello
4299*62c56f98SSadaf Ebrahimi          */
4300*62c56f98SSadaf Ebrahimi         case MBEDTLS_SSL_CLIENT_HELLO:
4301*62c56f98SSadaf Ebrahimi             ret = ssl_parse_client_hello(ssl);
4302*62c56f98SSadaf Ebrahimi             break;
4303*62c56f98SSadaf Ebrahimi 
4304*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_PROTO_DTLS)
4305*62c56f98SSadaf Ebrahimi         case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT:
4306*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED;
4307*62c56f98SSadaf Ebrahimi #endif
4308*62c56f98SSadaf Ebrahimi 
4309*62c56f98SSadaf Ebrahimi         /*
4310*62c56f98SSadaf Ebrahimi          *  ==>   ServerHello
4311*62c56f98SSadaf Ebrahimi          *        Certificate
4312*62c56f98SSadaf Ebrahimi          *      ( ServerKeyExchange  )
4313*62c56f98SSadaf Ebrahimi          *      ( CertificateRequest )
4314*62c56f98SSadaf Ebrahimi          *        ServerHelloDone
4315*62c56f98SSadaf Ebrahimi          */
4316*62c56f98SSadaf Ebrahimi         case MBEDTLS_SSL_SERVER_HELLO:
4317*62c56f98SSadaf Ebrahimi             ret = ssl_write_server_hello(ssl);
4318*62c56f98SSadaf Ebrahimi             break;
4319*62c56f98SSadaf Ebrahimi 
4320*62c56f98SSadaf Ebrahimi         case MBEDTLS_SSL_SERVER_CERTIFICATE:
4321*62c56f98SSadaf Ebrahimi             ret = mbedtls_ssl_write_certificate(ssl);
4322*62c56f98SSadaf Ebrahimi             break;
4323*62c56f98SSadaf Ebrahimi 
4324*62c56f98SSadaf Ebrahimi         case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
4325*62c56f98SSadaf Ebrahimi             ret = ssl_write_server_key_exchange(ssl);
4326*62c56f98SSadaf Ebrahimi             break;
4327*62c56f98SSadaf Ebrahimi 
4328*62c56f98SSadaf Ebrahimi         case MBEDTLS_SSL_CERTIFICATE_REQUEST:
4329*62c56f98SSadaf Ebrahimi             ret = ssl_write_certificate_request(ssl);
4330*62c56f98SSadaf Ebrahimi             break;
4331*62c56f98SSadaf Ebrahimi 
4332*62c56f98SSadaf Ebrahimi         case MBEDTLS_SSL_SERVER_HELLO_DONE:
4333*62c56f98SSadaf Ebrahimi             ret = ssl_write_server_hello_done(ssl);
4334*62c56f98SSadaf Ebrahimi             break;
4335*62c56f98SSadaf Ebrahimi 
4336*62c56f98SSadaf Ebrahimi         /*
4337*62c56f98SSadaf Ebrahimi          *  <== ( Certificate/Alert  )
4338*62c56f98SSadaf Ebrahimi          *        ClientKeyExchange
4339*62c56f98SSadaf Ebrahimi          *      ( CertificateVerify  )
4340*62c56f98SSadaf Ebrahimi          *        ChangeCipherSpec
4341*62c56f98SSadaf Ebrahimi          *        Finished
4342*62c56f98SSadaf Ebrahimi          */
4343*62c56f98SSadaf Ebrahimi         case MBEDTLS_SSL_CLIENT_CERTIFICATE:
4344*62c56f98SSadaf Ebrahimi             ret = mbedtls_ssl_parse_certificate(ssl);
4345*62c56f98SSadaf Ebrahimi             break;
4346*62c56f98SSadaf Ebrahimi 
4347*62c56f98SSadaf Ebrahimi         case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
4348*62c56f98SSadaf Ebrahimi             ret = ssl_parse_client_key_exchange(ssl);
4349*62c56f98SSadaf Ebrahimi             break;
4350*62c56f98SSadaf Ebrahimi 
4351*62c56f98SSadaf Ebrahimi         case MBEDTLS_SSL_CERTIFICATE_VERIFY:
4352*62c56f98SSadaf Ebrahimi             ret = ssl_parse_certificate_verify(ssl);
4353*62c56f98SSadaf Ebrahimi             break;
4354*62c56f98SSadaf Ebrahimi 
4355*62c56f98SSadaf Ebrahimi         case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
4356*62c56f98SSadaf Ebrahimi             ret = mbedtls_ssl_parse_change_cipher_spec(ssl);
4357*62c56f98SSadaf Ebrahimi             break;
4358*62c56f98SSadaf Ebrahimi 
4359*62c56f98SSadaf Ebrahimi         case MBEDTLS_SSL_CLIENT_FINISHED:
4360*62c56f98SSadaf Ebrahimi             ret = mbedtls_ssl_parse_finished(ssl);
4361*62c56f98SSadaf Ebrahimi             break;
4362*62c56f98SSadaf Ebrahimi 
4363*62c56f98SSadaf Ebrahimi         /*
4364*62c56f98SSadaf Ebrahimi          *  ==> ( NewSessionTicket )
4365*62c56f98SSadaf Ebrahimi          *        ChangeCipherSpec
4366*62c56f98SSadaf Ebrahimi          *        Finished
4367*62c56f98SSadaf Ebrahimi          */
4368*62c56f98SSadaf Ebrahimi         case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
4369*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SSL_SESSION_TICKETS)
4370*62c56f98SSadaf Ebrahimi             if (ssl->handshake->new_session_ticket != 0) {
4371*62c56f98SSadaf Ebrahimi                 ret = ssl_write_new_session_ticket(ssl);
4372*62c56f98SSadaf Ebrahimi             } else
4373*62c56f98SSadaf Ebrahimi #endif
4374*62c56f98SSadaf Ebrahimi             ret = mbedtls_ssl_write_change_cipher_spec(ssl);
4375*62c56f98SSadaf Ebrahimi             break;
4376*62c56f98SSadaf Ebrahimi 
4377*62c56f98SSadaf Ebrahimi         case MBEDTLS_SSL_SERVER_FINISHED:
4378*62c56f98SSadaf Ebrahimi             ret = mbedtls_ssl_write_finished(ssl);
4379*62c56f98SSadaf Ebrahimi             break;
4380*62c56f98SSadaf Ebrahimi 
4381*62c56f98SSadaf Ebrahimi         case MBEDTLS_SSL_FLUSH_BUFFERS:
4382*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done"));
4383*62c56f98SSadaf Ebrahimi             ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
4384*62c56f98SSadaf Ebrahimi             break;
4385*62c56f98SSadaf Ebrahimi 
4386*62c56f98SSadaf Ebrahimi         case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
4387*62c56f98SSadaf Ebrahimi             mbedtls_ssl_handshake_wrapup(ssl);
4388*62c56f98SSadaf Ebrahimi             break;
4389*62c56f98SSadaf Ebrahimi 
4390*62c56f98SSadaf Ebrahimi         default:
4391*62c56f98SSadaf Ebrahimi             MBEDTLS_SSL_DEBUG_MSG(1, ("invalid state %d", ssl->state));
4392*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
4393*62c56f98SSadaf Ebrahimi     }
4394*62c56f98SSadaf Ebrahimi 
4395*62c56f98SSadaf Ebrahimi     return ret;
4396*62c56f98SSadaf Ebrahimi }
4397*62c56f98SSadaf Ebrahimi 
mbedtls_ssl_conf_preference_order(mbedtls_ssl_config * conf,int order)4398*62c56f98SSadaf Ebrahimi void mbedtls_ssl_conf_preference_order(mbedtls_ssl_config *conf, int order)
4399*62c56f98SSadaf Ebrahimi {
4400*62c56f98SSadaf Ebrahimi     conf->respect_cli_pref = order;
4401*62c56f98SSadaf Ebrahimi }
4402*62c56f98SSadaf Ebrahimi 
4403*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_PROTO_TLS1_2 */
4404