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