blob: eabdc75ac7dfaaf7b77c8e3b642381800bc36a8c [file] [log] [blame]
Ronald Cron3d580bf2022-02-18 17:24:56 +01001/*
2 * TLS 1.2 and 1.3 client-side functions
3 *
4 * Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Ronald Cron3d580bf2022-02-18 17:24:56 +01006 *
Gilles Peskinee820c0a2023-08-03 17:45:20 +02007 * This file is part of Mbed TLS ( https://tls.mbed.org )
Ronald Cron3d580bf2022-02-18 17:24:56 +01008 */
9
10#include "common.h"
11
12#if defined(MBEDTLS_SSL_CLI_C)
13#if defined(MBEDTLS_SSL_PROTO_TLS1_3) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
14
15#include <string.h>
16
17#include "mbedtls/debug.h"
18#include "mbedtls/error.h"
Jerry Yu141bbe72022-12-01 20:30:41 +080019#include "mbedtls/platform.h"
Ronald Cron3d580bf2022-02-18 17:24:56 +010020
21#include "ssl_client.h"
22#include "ssl_misc.h"
Ronald Cron3d580bf2022-02-18 17:24:56 +010023#include "ssl_tls13_keys.h"
24#include "ssl_debug_helpers.h"
25
Ronald Cronfbd9f992022-03-17 15:22:07 +010026#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
Manuel Pégourié-Gonnarda3115dc2022-06-17 10:52:54 +020027MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine449bd832023-01-11 14:50:10 +010028static int ssl_write_hostname_ext(mbedtls_ssl_context *ssl,
29 unsigned char *buf,
30 const unsigned char *end,
31 size_t *olen)
Ronald Cronfbd9f992022-03-17 15:22:07 +010032{
33 unsigned char *p = buf;
34 size_t hostname_len;
35
36 *olen = 0;
37
Gilles Peskine449bd832023-01-11 14:50:10 +010038 if (ssl->hostname == NULL) {
39 return 0;
40 }
Ronald Cronfbd9f992022-03-17 15:22:07 +010041
Gilles Peskine449bd832023-01-11 14:50:10 +010042 MBEDTLS_SSL_DEBUG_MSG(3,
43 ("client hello, adding server name extension: %s",
44 ssl->hostname));
Ronald Cronfbd9f992022-03-17 15:22:07 +010045
Gilles Peskine449bd832023-01-11 14:50:10 +010046 hostname_len = strlen(ssl->hostname);
Ronald Cronfbd9f992022-03-17 15:22:07 +010047
Gilles Peskine449bd832023-01-11 14:50:10 +010048 MBEDTLS_SSL_CHK_BUF_PTR(p, end, hostname_len + 9);
Ronald Cronfbd9f992022-03-17 15:22:07 +010049
50 /*
51 * Sect. 3, RFC 6066 (TLS Extensions Definitions)
52 *
53 * In order to provide any of the server names, clients MAY include an
54 * extension of type "server_name" in the (extended) client hello. The
55 * "extension_data" field of this extension SHALL contain
56 * "ServerNameList" where:
57 *
58 * struct {
59 * NameType name_type;
60 * select (name_type) {
61 * case host_name: HostName;
62 * } name;
63 * } ServerName;
64 *
65 * enum {
66 * host_name(0), (255)
67 * } NameType;
68 *
69 * opaque HostName<1..2^16-1>;
70 *
71 * struct {
72 * ServerName server_name_list<1..2^16-1>
73 * } ServerNameList;
74 *
75 */
Gilles Peskine449bd832023-01-11 14:50:10 +010076 MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SERVERNAME, p, 0);
Ronald Cronfbd9f992022-03-17 15:22:07 +010077 p += 2;
78
Gilles Peskine449bd832023-01-11 14:50:10 +010079 MBEDTLS_PUT_UINT16_BE(hostname_len + 5, p, 0);
Ronald Cronfbd9f992022-03-17 15:22:07 +010080 p += 2;
81
Gilles Peskine449bd832023-01-11 14:50:10 +010082 MBEDTLS_PUT_UINT16_BE(hostname_len + 3, p, 0);
Ronald Cronfbd9f992022-03-17 15:22:07 +010083 p += 2;
84
Gilles Peskine449bd832023-01-11 14:50:10 +010085 *p++ = MBEDTLS_BYTE_0(MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME);
Ronald Cronfbd9f992022-03-17 15:22:07 +010086
Gilles Peskine449bd832023-01-11 14:50:10 +010087 MBEDTLS_PUT_UINT16_BE(hostname_len, p, 0);
Ronald Cronfbd9f992022-03-17 15:22:07 +010088 p += 2;
89
Gilles Peskine449bd832023-01-11 14:50:10 +010090 memcpy(p, ssl->hostname, hostname_len);
Ronald Cronfbd9f992022-03-17 15:22:07 +010091
92 *olen = hostname_len + 9;
93
Jerry Yu0c354a22022-08-29 15:25:36 +080094#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
Gilles Peskine449bd832023-01-11 14:50:10 +010095 mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_SERVERNAME);
Jerry Yu0c354a22022-08-29 15:25:36 +080096#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
Gilles Peskine449bd832023-01-11 14:50:10 +010097 return 0;
Ronald Cronfbd9f992022-03-17 15:22:07 +010098}
99#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
100
Ronald Cron3d580bf2022-02-18 17:24:56 +0100101#if defined(MBEDTLS_SSL_ALPN)
102/*
Ronald Cron71c23322022-02-18 17:29:39 +0100103 * ssl_write_alpn_ext()
Ronald Cron3d580bf2022-02-18 17:24:56 +0100104 *
105 * Structure of the application_layer_protocol_negotiation extension in
106 * ClientHello:
107 *
108 * opaque ProtocolName<1..2^8-1>;
109 *
110 * struct {
111 * ProtocolName protocol_name_list<2..2^16-1>
112 * } ProtocolNameList;
113 *
114 */
Manuel Pégourié-Gonnarda3115dc2022-06-17 10:52:54 +0200115MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine449bd832023-01-11 14:50:10 +0100116static int ssl_write_alpn_ext(mbedtls_ssl_context *ssl,
117 unsigned char *buf,
118 const unsigned char *end,
119 size_t *out_len)
Ronald Cron3d580bf2022-02-18 17:24:56 +0100120{
121 unsigned char *p = buf;
122
123 *out_len = 0;
124
Gilles Peskine449bd832023-01-11 14:50:10 +0100125 if (ssl->conf->alpn_list == NULL) {
126 return 0;
127 }
Ronald Cron3d580bf2022-02-18 17:24:56 +0100128
Gilles Peskine449bd832023-01-11 14:50:10 +0100129 MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding alpn extension"));
Ronald Cron3d580bf2022-02-18 17:24:56 +0100130
131
132 /* Check we have enough space for the extension type (2 bytes), the
133 * extension length (2 bytes) and the protocol_name_list length (2 bytes).
134 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100135 MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6);
136 MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ALPN, p, 0);
Ronald Cron3d580bf2022-02-18 17:24:56 +0100137 /* Skip writing extension and list length for now */
138 p += 6;
139
140 /*
141 * opaque ProtocolName<1..2^8-1>;
142 *
143 * struct {
144 * ProtocolName protocol_name_list<2..2^16-1>
145 * } ProtocolNameList;
146 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100147 for (const char **cur = ssl->conf->alpn_list; *cur != NULL; cur++) {
Ronald Cron3d580bf2022-02-18 17:24:56 +0100148 /*
149 * mbedtls_ssl_conf_set_alpn_protocols() checked that the length of
150 * protocol names is less than 255.
151 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100152 size_t protocol_name_len = strlen(*cur);
Ronald Cron3d580bf2022-02-18 17:24:56 +0100153
Gilles Peskine449bd832023-01-11 14:50:10 +0100154 MBEDTLS_SSL_CHK_BUF_PTR(p, end, 1 + protocol_name_len);
155 *p++ = (unsigned char) protocol_name_len;
156 memcpy(p, *cur, protocol_name_len);
Ronald Cron3d580bf2022-02-18 17:24:56 +0100157 p += protocol_name_len;
158 }
159
160 *out_len = p - buf;
161
162 /* List length = *out_len - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100163 MBEDTLS_PUT_UINT16_BE(*out_len - 6, buf, 4);
Ronald Cron3d580bf2022-02-18 17:24:56 +0100164
165 /* Extension length = *out_len - 2 (ext_type) - 2 (ext_len) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100166 MBEDTLS_PUT_UINT16_BE(*out_len - 4, buf, 2);
Ronald Cron3d580bf2022-02-18 17:24:56 +0100167
Jerry Yu0c354a22022-08-29 15:25:36 +0800168#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
Gilles Peskine449bd832023-01-11 14:50:10 +0100169 mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_ALPN);
Jerry Yu0c354a22022-08-29 15:25:36 +0800170#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100171 return 0;
Ronald Cron3d580bf2022-02-18 17:24:56 +0100172}
173#endif /* MBEDTLS_SSL_ALPN */
174
Przemek Stekiel98d79332023-06-26 12:44:33 +0200175#if defined(MBEDTLS_SSL_TLS1_2_SOME_ECC) || \
176 defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
Ronald Cronfbd9f992022-03-17 15:22:07 +0100177/*
178 * Function for writing a supported groups (TLS 1.3) or supported elliptic
179 * curves (TLS 1.2) extension.
180 *
181 * The "extension_data" field of a supported groups extension contains a
182 * "NamedGroupList" value (TLS 1.3 RFC8446):
183 * enum {
184 * secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019),
185 * x25519(0x001D), x448(0x001E),
186 * ffdhe2048(0x0100), ffdhe3072(0x0101), ffdhe4096(0x0102),
187 * ffdhe6144(0x0103), ffdhe8192(0x0104),
188 * ffdhe_private_use(0x01FC..0x01FF),
189 * ecdhe_private_use(0xFE00..0xFEFF),
190 * (0xFFFF)
191 * } NamedGroup;
192 * struct {
193 * NamedGroup named_group_list<2..2^16-1>;
194 * } NamedGroupList;
195 *
196 * The "extension_data" field of a supported elliptic curves extension contains
197 * a "NamedCurveList" value (TLS 1.2 RFC 8422):
198 * enum {
199 * deprecated(1..22),
200 * secp256r1 (23), secp384r1 (24), secp521r1 (25),
201 * x25519(29), x448(30),
202 * reserved (0xFE00..0xFEFF),
203 * deprecated(0xFF01..0xFF02),
204 * (0xFFFF)
205 * } NamedCurve;
206 * struct {
207 * NamedCurve named_curve_list<2..2^16-1>
208 * } NamedCurveList;
209 *
210 * The TLS 1.3 supported groups extension was defined to be a compatible
211 * generalization of the TLS 1.2 supported elliptic curves extension. They both
212 * share the same extension identifier.
213 *
Ronald Cronfbd9f992022-03-17 15:22:07 +0100214 */
Ronald Cron1ffa4502023-06-30 14:56:38 +0200215#define SSL_WRITE_SUPPORTED_GROUPS_EXT_TLS1_2_FLAG 1
216#define SSL_WRITE_SUPPORTED_GROUPS_EXT_TLS1_3_FLAG 2
217
Manuel Pégourié-Gonnarda3115dc2022-06-17 10:52:54 +0200218MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine449bd832023-01-11 14:50:10 +0100219static int ssl_write_supported_groups_ext(mbedtls_ssl_context *ssl,
220 unsigned char *buf,
221 const unsigned char *end,
Ronald Cron1ffa4502023-06-30 14:56:38 +0200222 int flags,
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 size_t *out_len)
Ronald Cronfbd9f992022-03-17 15:22:07 +0100224{
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 unsigned char *p = buf;
Ronald Cronfbd9f992022-03-17 15:22:07 +0100226 unsigned char *named_group_list; /* Start of named_group_list */
227 size_t named_group_list_len; /* Length of named_group_list */
Gilles Peskine449bd832023-01-11 14:50:10 +0100228 const uint16_t *group_list = mbedtls_ssl_get_groups(ssl);
Ronald Cronfbd9f992022-03-17 15:22:07 +0100229
230 *out_len = 0;
231
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding supported_groups extension"));
Ronald Cronfbd9f992022-03-17 15:22:07 +0100233
234 /* Check if we have space for header and length fields:
235 * - extension_type (2 bytes)
236 * - extension_data_length (2 bytes)
237 * - named_group_list_length (2 bytes)
238 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6);
Ronald Cronfbd9f992022-03-17 15:22:07 +0100240 p += 6;
241
242 named_group_list = p;
243
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 if (group_list == NULL) {
245 return MBEDTLS_ERR_SSL_BAD_CONFIG;
246 }
Ronald Cronfbd9f992022-03-17 15:22:07 +0100247
Gilles Peskine449bd832023-01-11 14:50:10 +0100248 for (; *group_list != 0; group_list++) {
Ronald Cron1ffa4502023-06-30 14:56:38 +0200249 int propose_group = 0;
250
mcagriaksoyd9f22802023-09-13 22:42:19 +0200251 MBEDTLS_SSL_DEBUG_MSG(3, ("got supported group(%04x)", *group_list));
Ronald Cronfbd9f992022-03-17 15:22:07 +0100252
Ronald Cron1ffa4502023-06-30 14:56:38 +0200253#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
254 if (flags & SSL_WRITE_SUPPORTED_GROUPS_EXT_TLS1_3_FLAG) {
255#if defined(PSA_WANT_ALG_ECDH)
256 if (mbedtls_ssl_tls13_named_group_is_ecdhe(*group_list) &&
257 (mbedtls_ssl_get_ecp_group_id_from_tls_id(*group_list) !=
258 MBEDTLS_ECP_DP_NONE)) {
259 propose_group = 1;
Valerio Setti18c9fed2022-12-30 17:44:24 +0100260 }
Ronald Cron1ffa4502023-06-30 14:56:38 +0200261#endif
262#if defined(PSA_WANT_ALG_FFDH)
Przemek Stekiele80bbf42023-07-05 10:34:40 +0200263 if (mbedtls_ssl_tls13_named_group_is_ffdh(*group_list)) {
Ronald Cron1ffa4502023-06-30 14:56:38 +0200264 propose_group = 1;
265 }
266#endif
267 }
268#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */
269
270#if defined(MBEDTLS_SSL_TLS1_2_SOME_ECC)
271 if ((flags & SSL_WRITE_SUPPORTED_GROUPS_EXT_TLS1_2_FLAG) &&
272 mbedtls_ssl_tls12_named_group_is_ecdhe(*group_list) &&
273 (mbedtls_ssl_get_ecp_group_id_from_tls_id(*group_list) !=
274 MBEDTLS_ECP_DP_NONE)) {
275 propose_group = 1;
276 }
277#endif /* MBEDTLS_SSL_TLS1_2_SOME_ECC */
278
279 if (propose_group) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100280 MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2);
281 MBEDTLS_PUT_UINT16_BE(*group_list, p, 0);
Ronald Cronfbd9f992022-03-17 15:22:07 +0100282 p += 2;
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 MBEDTLS_SSL_DEBUG_MSG(3, ("NamedGroup: %s ( %x )",
Ronald Cron1ffa4502023-06-30 14:56:38 +0200284 mbedtls_ssl_named_group_to_str(*group_list),
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 *group_list));
Ronald Cronfbd9f992022-03-17 15:22:07 +0100286 }
Ronald Cronfbd9f992022-03-17 15:22:07 +0100287 }
288
289 /* Length of named_group_list */
290 named_group_list_len = p - named_group_list;
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 if (named_group_list_len == 0) {
292 MBEDTLS_SSL_DEBUG_MSG(1, ("No group available."));
293 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
Ronald Cronfbd9f992022-03-17 15:22:07 +0100294 }
295
296 /* Write extension_type */
Gilles Peskine449bd832023-01-11 14:50:10 +0100297 MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SUPPORTED_GROUPS, buf, 0);
Ronald Cronfbd9f992022-03-17 15:22:07 +0100298 /* Write extension_data_length */
Gilles Peskine449bd832023-01-11 14:50:10 +0100299 MBEDTLS_PUT_UINT16_BE(named_group_list_len + 2, buf, 2);
Ronald Cronfbd9f992022-03-17 15:22:07 +0100300 /* Write length of named_group_list */
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 MBEDTLS_PUT_UINT16_BE(named_group_list_len, buf, 4);
Ronald Cronfbd9f992022-03-17 15:22:07 +0100302
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 MBEDTLS_SSL_DEBUG_BUF(3, "Supported groups extension",
304 buf + 4, named_group_list_len + 2);
Ronald Cronfbd9f992022-03-17 15:22:07 +0100305
306 *out_len = p - buf;
307
308#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
Jerry Yu4b8f2f72022-10-31 13:31:22 +0800309 mbedtls_ssl_tls13_set_hs_sent_ext_mask(
Gilles Peskine449bd832023-01-11 14:50:10 +0100310 ssl, MBEDTLS_TLS_EXT_SUPPORTED_GROUPS);
Ronald Cronfbd9f992022-03-17 15:22:07 +0100311#endif /* MBEDTLS_SSL_PROTO_TLS1_3 */
312
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 return 0;
Ronald Cronfbd9f992022-03-17 15:22:07 +0100314}
Przemek Stekiel98d79332023-06-26 12:44:33 +0200315#endif /* MBEDTLS_SSL_TLS1_2_SOME_ECC ||
316 MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */
Ronald Cronfbd9f992022-03-17 15:22:07 +0100317
Manuel Pégourié-Gonnarda3115dc2022-06-17 10:52:54 +0200318MBEDTLS_CHECK_RETURN_CRITICAL
Ronald Cron71c23322022-02-18 17:29:39 +0100319static int ssl_write_client_hello_cipher_suites(
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 mbedtls_ssl_context *ssl,
321 unsigned char *buf,
322 unsigned char *end,
323 int *tls12_uses_ec,
324 size_t *out_len)
Ronald Cron3d580bf2022-02-18 17:24:56 +0100325{
326 unsigned char *p = buf;
327 const int *ciphersuite_list;
328 unsigned char *cipher_suites; /* Start of the cipher_suites list */
329 size_t cipher_suites_len;
330
Ronald Crond491c2d2022-02-19 18:30:46 +0100331 *tls12_uses_ec = 0;
332 *out_len = 0;
Ronald Cron3d580bf2022-02-18 17:24:56 +0100333
334 /*
335 * Ciphersuite list
336 *
337 * This is a list of the symmetric cipher options supported by
338 * the client, specifically the record protection algorithm
339 * ( including secret key length ) and a hash to be used with
340 * HKDF, in descending order of client preference.
341 */
342 ciphersuite_list = ssl->conf->ciphersuite_list;
343
344 /* Check there is space for the cipher suite list length (2 bytes). */
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2);
Ronald Cron3d580bf2022-02-18 17:24:56 +0100346 p += 2;
347
Ronald Cron64767262022-03-31 14:13:57 +0200348 /* Write cipher_suites
349 * CipherSuite cipher_suites<2..2^16-2>;
350 */
Ronald Cron3d580bf2022-02-18 17:24:56 +0100351 cipher_suites = p;
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 for (size_t i = 0; ciphersuite_list[i] != 0; i++) {
Ronald Cron3d580bf2022-02-18 17:24:56 +0100353 int cipher_suite = ciphersuite_list[i];
354 const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
355
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(cipher_suite);
Ronald Crond491c2d2022-02-19 18:30:46 +0100357
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 if (mbedtls_ssl_validate_ciphersuite(ssl, ciphersuite_info,
359 ssl->handshake->min_tls_version,
360 ssl->tls_version) != 0) {
Ronald Cron3d580bf2022-02-18 17:24:56 +0100361 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 }
Ronald Crond491c2d2022-02-19 18:30:46 +0100363
364#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
Valerio Setti7aeec542023-07-05 18:57:21 +0200365 (defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
Valerio Settie9646ec2023-08-02 20:02:28 +0200366 defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED))
368 *tls12_uses_ec |= mbedtls_ssl_ciphersuite_uses_ec(ciphersuite_info);
Ronald Crond491c2d2022-02-19 18:30:46 +0100369#endif
Ronald Cron3d580bf2022-02-18 17:24:56 +0100370
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, add ciphersuite: %04x, %s",
372 (unsigned int) cipher_suite,
373 ciphersuite_info->name));
Ronald Cron3d580bf2022-02-18 17:24:56 +0100374
375 /* Check there is space for the cipher suite identifier (2 bytes). */
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2);
377 MBEDTLS_PUT_UINT16_BE(cipher_suite, p, 0);
Ronald Cron3d580bf2022-02-18 17:24:56 +0100378 p += 2;
379 }
380
Ronald Crond491c2d2022-02-19 18:30:46 +0100381 /*
382 * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV
383 */
David Horstmann4a285632022-10-06 18:30:10 +0100384 int renegotiating = 0;
Ronald Crond491c2d2022-02-19 18:30:46 +0100385#if defined(MBEDTLS_SSL_RENEGOTIATION)
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 renegotiating = (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE);
Ronald Crond491c2d2022-02-19 18:30:46 +0100387#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 if (!renegotiating) {
389 MBEDTLS_SSL_DEBUG_MSG(3, ("adding EMPTY_RENEGOTIATION_INFO_SCSV"));
390 MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2);
391 MBEDTLS_PUT_UINT16_BE(MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO, p, 0);
Ronald Crond491c2d2022-02-19 18:30:46 +0100392 p += 2;
393 }
394
Ronald Cron3d580bf2022-02-18 17:24:56 +0100395 /* Write the cipher_suites length in number of bytes */
396 cipher_suites_len = p - cipher_suites;
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 MBEDTLS_PUT_UINT16_BE(cipher_suites_len, buf, 0);
398 MBEDTLS_SSL_DEBUG_MSG(3,
399 ("client hello, got %" MBEDTLS_PRINTF_SIZET " cipher suites",
400 cipher_suites_len/2));
Ronald Cron3d580bf2022-02-18 17:24:56 +0100401
402 /* Output the total length of cipher_suites field. */
403 *out_len = p - buf;
404
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 return 0;
Ronald Cron3d580bf2022-02-18 17:24:56 +0100406}
407
408/*
Ronald Cron5456a7f2022-02-18 17:38:42 +0100409 * Structure of the TLS 1.3 ClientHello message:
Ronald Cron3d580bf2022-02-18 17:24:56 +0100410 *
411 * struct {
412 * ProtocolVersion legacy_version = 0x0303; // TLS v1.2
413 * Random random;
414 * opaque legacy_session_id<0..32>;
415 * CipherSuite cipher_suites<2..2^16-2>;
416 * opaque legacy_compression_methods<1..2^8-1>;
417 * Extension extensions<8..2^16-1>;
418 * } ClientHello;
Ronald Cron5456a7f2022-02-18 17:38:42 +0100419 *
420 * Structure of the (D)TLS 1.2 ClientHello message:
421 *
422 * struct {
423 * ProtocolVersion client_version;
424 * Random random;
425 * SessionID session_id;
426 * opaque cookie<0..2^8-1>; // DTLS 1.2 ONLY
427 * CipherSuite cipher_suites<2..2^16-2>;
428 * CompressionMethod compression_methods<1..2^8-1>;
429 * select (extensions_present) {
430 * case false:
431 * struct {};
432 * case true:
433 * Extension extensions<0..2^16-1>;
434 * };
435 * } ClientHello;
Ronald Cron3d580bf2022-02-18 17:24:56 +0100436 */
Manuel Pégourié-Gonnarda3115dc2022-06-17 10:52:54 +0200437MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine449bd832023-01-11 14:50:10 +0100438static int ssl_write_client_hello_body(mbedtls_ssl_context *ssl,
439 unsigned char *buf,
440 unsigned char *end,
441 size_t *out_len,
442 size_t *binders_len)
Ronald Cron3d580bf2022-02-18 17:24:56 +0100443{
Ronald Cron3d580bf2022-02-18 17:24:56 +0100444 int ret;
Ronald Cron4079abc2022-02-20 10:35:26 +0100445 mbedtls_ssl_handshake_params *handshake = ssl->handshake;
Ronald Cron4079abc2022-02-20 10:35:26 +0100446 unsigned char *p = buf;
Ronald Cron3d580bf2022-02-18 17:24:56 +0100447 unsigned char *p_extensions_len; /* Pointer to extensions length */
448 size_t output_len; /* Length of buffer used by function */
449 size_t extensions_len; /* Length of the list of extensions*/
Ronald Cron4079abc2022-02-20 10:35:26 +0100450 int tls12_uses_ec = 0;
Ronald Cron3d580bf2022-02-18 17:24:56 +0100451
Ronald Cron3d580bf2022-02-18 17:24:56 +0100452 *out_len = 0;
XiaokangQianeb69aee2022-07-05 08:21:43 +0000453 *binders_len = 0;
Ronald Cron3d580bf2022-02-18 17:24:56 +0100454
Ronald Cron4079abc2022-02-20 10:35:26 +0100455#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Ronald Cron150d5792022-03-30 20:24:51 +0200456 unsigned char propose_tls12 =
Gilles Peskine449bd832023-01-11 14:50:10 +0100457 (handshake->min_tls_version <= MBEDTLS_SSL_VERSION_TLS1_2)
Ronald Cron150d5792022-03-30 20:24:51 +0200458 &&
Gilles Peskine449bd832023-01-11 14:50:10 +0100459 (MBEDTLS_SSL_VERSION_TLS1_2 <= ssl->tls_version);
Ronald Cron4079abc2022-02-20 10:35:26 +0100460#endif
461#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
Ronald Cron150d5792022-03-30 20:24:51 +0200462 unsigned char propose_tls13 =
Gilles Peskine449bd832023-01-11 14:50:10 +0100463 (handshake->min_tls_version <= MBEDTLS_SSL_VERSION_TLS1_3)
Ronald Cron150d5792022-03-30 20:24:51 +0200464 &&
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 (MBEDTLS_SSL_VERSION_TLS1_3 <= ssl->tls_version);
Ronald Cron4079abc2022-02-20 10:35:26 +0100466#endif
467
Ronald Cron3d580bf2022-02-18 17:24:56 +0100468 /*
Ronald Cron1614eb62022-02-18 17:53:01 +0100469 * Write client_version (TLS 1.2) or legacy_version (TLS 1.3)
Ronald Cron3d580bf2022-02-18 17:24:56 +0100470 *
Ronald Cron1614eb62022-02-18 17:53:01 +0100471 * In all cases this is the TLS 1.2 version.
Ronald Cron3d580bf2022-02-18 17:24:56 +0100472 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2);
474 mbedtls_ssl_write_version(p, ssl->conf->transport,
475 MBEDTLS_SSL_VERSION_TLS1_2);
Ronald Cron3d580bf2022-02-18 17:24:56 +0100476 p += 2;
477
Ronald Cron58b80382022-02-18 18:41:08 +0100478 /* ...
479 * Random random;
480 * ...
481 *
Ronald Cron58b80382022-02-18 18:41:08 +0100482 * The random bytes have been prepared by ssl_prepare_client_hello() into
Ronald Cron4079abc2022-02-20 10:35:26 +0100483 * the handshake->randbytes buffer and are copied here into the output
484 * buffer.
Ronald Cron58b80382022-02-18 18:41:08 +0100485 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 MBEDTLS_SSL_CHK_BUF_PTR(p, end, MBEDTLS_CLIENT_HELLO_RANDOM_LEN);
487 memcpy(p, handshake->randbytes, MBEDTLS_CLIENT_HELLO_RANDOM_LEN);
488 MBEDTLS_SSL_DEBUG_BUF(3, "client hello, random bytes",
489 p, MBEDTLS_CLIENT_HELLO_RANDOM_LEN);
Ronald Cron3d580bf2022-02-18 17:24:56 +0100490 p += MBEDTLS_CLIENT_HELLO_RANDOM_LEN;
491
Ronald Cron021b1782022-02-19 17:32:53 +0100492 /* TLS 1.2:
493 * ...
494 * SessionID session_id;
495 * ...
496 * with
497 * opaque SessionID<0..32>;
Ronald Cron3d580bf2022-02-18 17:24:56 +0100498 *
Ronald Cron021b1782022-02-19 17:32:53 +0100499 * TLS 1.3:
500 * ...
501 * opaque legacy_session_id<0..32>;
502 * ...
503 *
Ronald Cronda41b382022-03-30 09:57:11 +0200504 * The (legacy) session identifier bytes have been prepared by
Ronald Cron021b1782022-02-19 17:32:53 +0100505 * ssl_prepare_client_hello() into the ssl->session_negotiate->id buffer
506 * and are copied here into the output buffer.
Ronald Cron3d580bf2022-02-18 17:24:56 +0100507 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 MBEDTLS_SSL_CHK_BUF_PTR(p, end, ssl->session_negotiate->id_len + 1);
509 *p++ = (unsigned char) ssl->session_negotiate->id_len;
510 memcpy(p, ssl->session_negotiate->id, ssl->session_negotiate->id_len);
Ronald Cron3d580bf2022-02-18 17:24:56 +0100511 p += ssl->session_negotiate->id_len;
512
Gilles Peskine449bd832023-01-11 14:50:10 +0100513 MBEDTLS_SSL_DEBUG_BUF(3, "session id", ssl->session_negotiate->id,
514 ssl->session_negotiate->id_len);
Ronald Cron3d580bf2022-02-18 17:24:56 +0100515
Ronald Crona874aa82022-02-19 18:11:26 +0100516 /* DTLS 1.2 ONLY
517 * ...
518 * opaque cookie<0..2^8-1>;
519 * ...
520 */
521#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Jerry Yue01304f2022-04-07 10:51:55 +0800523#if !defined(MBEDTLS_SSL_PROTO_TLS1_3)
524 uint8_t cookie_len = 0;
525#else
526 uint16_t cookie_len = 0;
527#endif /* !MBEDTLS_SSL_PROTO_TLS1_3 */
Ronald Crona874aa82022-02-19 18:11:26 +0100528
Gilles Peskine449bd832023-01-11 14:50:10 +0100529 if (handshake->cookie != NULL) {
530 MBEDTLS_SSL_DEBUG_BUF(3, "client hello, cookie",
531 handshake->cookie,
532 handshake->cookie_len);
Jerry Yuac5ca5a2022-03-04 12:50:46 +0800533 cookie_len = handshake->cookie_len;
Ronald Crona874aa82022-02-19 18:11:26 +0100534 }
535
Gilles Peskine449bd832023-01-11 14:50:10 +0100536 MBEDTLS_SSL_CHK_BUF_PTR(p, end, cookie_len + 1);
537 *p++ = (unsigned char) cookie_len;
538 if (cookie_len > 0) {
539 memcpy(p, handshake->cookie, cookie_len);
Ronald Crona874aa82022-02-19 18:11:26 +0100540 p += cookie_len;
541 }
542 }
543#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_SSL_PROTO_DTLS */
544
Ronald Cron3d580bf2022-02-18 17:24:56 +0100545 /* Write cipher_suites */
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 ret = ssl_write_client_hello_cipher_suites(ssl, p, end,
547 &tls12_uses_ec,
548 &output_len);
549 if (ret != 0) {
550 return ret;
551 }
Ronald Cron3d580bf2022-02-18 17:24:56 +0100552 p += output_len;
553
Ronald Cron42c1cbf2022-02-20 10:24:39 +0100554 /* Write legacy_compression_methods (TLS 1.3) or
555 * compression_methods (TLS 1.2)
Ronald Cron3d580bf2022-02-18 17:24:56 +0100556 *
557 * For every TLS 1.3 ClientHello, this vector MUST contain exactly
558 * one byte set to zero, which corresponds to the 'null' compression
559 * method in prior versions of TLS.
Ronald Cron42c1cbf2022-02-20 10:24:39 +0100560 *
561 * For TLS 1.2 ClientHello, for security reasons we do not support
562 * compression anymore, thus also just the 'null' compression method.
Ronald Cron3d580bf2022-02-18 17:24:56 +0100563 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2);
Ronald Cron3d580bf2022-02-18 17:24:56 +0100565 *p++ = 1;
566 *p++ = MBEDTLS_SSL_COMPRESS_NULL;
567
568 /* Write extensions */
569
570#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
571 /* Keeping track of the included extensions */
Jerry Yu63a459c2022-10-31 13:38:40 +0800572 handshake->sent_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
Ronald Cron3d580bf2022-02-18 17:24:56 +0100573#endif
574
575 /* First write extensions, then the total length */
Gilles Peskine449bd832023-01-11 14:50:10 +0100576 MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2);
Ronald Cron3d580bf2022-02-18 17:24:56 +0100577 p_extensions_len = p;
578 p += 2;
579
Ronald Crondf823bf2022-03-29 18:57:54 +0200580#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
581 /* Write server name extension */
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 ret = ssl_write_hostname_ext(ssl, p, end, &output_len);
583 if (ret != 0) {
584 return ret;
585 }
Ronald Cron3d580bf2022-02-18 17:24:56 +0100586 p += output_len;
Ronald Crondf823bf2022-03-29 18:57:54 +0200587#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
Ronald Cron3d580bf2022-02-18 17:24:56 +0100588
589#if defined(MBEDTLS_SSL_ALPN)
Gilles Peskine449bd832023-01-11 14:50:10 +0100590 ret = ssl_write_alpn_ext(ssl, p, end, &output_len);
591 if (ret != 0) {
592 return ret;
593 }
Ronald Cron3d580bf2022-02-18 17:24:56 +0100594 p += output_len;
595#endif /* MBEDTLS_SSL_ALPN */
596
597#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 if (propose_tls13) {
599 ret = mbedtls_ssl_tls13_write_client_hello_exts(ssl, p, end,
600 &output_len);
601 if (ret != 0) {
602 return ret;
603 }
Ronald Cron4079abc2022-02-20 10:35:26 +0100604 p += output_len;
605 }
Ronald Crondf823bf2022-03-29 18:57:54 +0200606#endif
607
Przemek Stekiel76669452023-06-26 17:34:36 +0200608#if defined(MBEDTLS_SSL_TLS1_2_SOME_ECC) || \
609 defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
Ronald Cron1ffa4502023-06-30 14:56:38 +0200610 {
611 int ssl_write_supported_groups_ext_flags = 0;
612
613#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
614 if (propose_tls13 && mbedtls_ssl_conf_tls13_some_ephemeral_enabled(ssl)) {
615 ssl_write_supported_groups_ext_flags |=
616 SSL_WRITE_SUPPORTED_GROUPS_EXT_TLS1_3_FLAG;
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 }
Ronald Cron1ffa4502023-06-30 14:56:38 +0200618#endif
619#if defined(MBEDTLS_SSL_TLS1_2_SOME_ECC)
620 if (propose_tls12 && tls12_uses_ec) {
621 ssl_write_supported_groups_ext_flags |=
622 SSL_WRITE_SUPPORTED_GROUPS_EXT_TLS1_2_FLAG;
623 }
624#endif
625 if (ssl_write_supported_groups_ext_flags != 0) {
626 ret = ssl_write_supported_groups_ext(ssl, p, end,
627 ssl_write_supported_groups_ext_flags,
628 &output_len);
629 if (ret != 0) {
630 return ret;
631 }
632 p += output_len;
633 }
Ronald Cron3d580bf2022-02-18 17:24:56 +0100634 }
Przemek Stekiel76669452023-06-26 17:34:36 +0200635#endif /* MBEDTLS_SSL_TLS1_2_SOME_ECC ||
636 MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */
Ronald Cron3d580bf2022-02-18 17:24:56 +0100637
Ronald Crone68ab4f2022-10-05 12:46:29 +0200638#if defined(MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED)
Dave Rodgmane99b24d2023-09-14 15:45:03 +0100639 int write_sig_alg_ext = 0;
Ronald Cron4079abc2022-02-20 10:35:26 +0100640#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
Dave Rodgmana11eac42023-09-14 16:16:04 +0100641 write_sig_alg_ext = write_sig_alg_ext ||
642 (propose_tls13 && mbedtls_ssl_conf_tls13_ephemeral_enabled(ssl));
Ronald Cron4079abc2022-02-20 10:35:26 +0100643#endif
644#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Dave Rodgmane99b24d2023-09-14 15:45:03 +0100645 write_sig_alg_ext = write_sig_alg_ext || propose_tls12;
Ronald Cron4079abc2022-02-20 10:35:26 +0100646#endif
Dave Rodgmane99b24d2023-09-14 15:45:03 +0100647
648 if (write_sig_alg_ext) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 ret = mbedtls_ssl_write_sig_alg_ext(ssl, p, end, &output_len);
650 if (ret != 0) {
651 return ret;
652 }
Ronald Cron3d580bf2022-02-18 17:24:56 +0100653 p += output_len;
654 }
Ronald Crone68ab4f2022-10-05 12:46:29 +0200655#endif /* MBEDTLS_SSL_HANDSHAKE_WITH_CERT_ENABLED */
Ronald Cron3d580bf2022-02-18 17:24:56 +0100656
Ronald Cron4079abc2022-02-20 10:35:26 +0100657#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 if (propose_tls12) {
659 ret = mbedtls_ssl_tls12_write_client_hello_exts(ssl, p, end,
660 tls12_uses_ec,
661 &output_len);
662 if (ret != 0) {
663 return ret;
664 }
Ronald Cron4079abc2022-02-20 10:35:26 +0100665 p += output_len;
666 }
667#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
Ronald Cron3d580bf2022-02-18 17:24:56 +0100668
Ronald Cron41a443a2022-10-04 16:38:25 +0200669#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
XiaokangQian86981952022-07-19 09:51:50 +0000670 /* The "pre_shared_key" extension (RFC 8446 Section 4.2.11)
671 * MUST be the last extension in the ClientHello.
672 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100673 if (propose_tls13 && mbedtls_ssl_conf_tls13_some_psk_enabled(ssl)) {
XiaokangQian3ad67bf2022-07-21 02:26:21 +0000674 ret = mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext(
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 ssl, p, end, &output_len, binders_len);
676 if (ret != 0) {
677 return ret;
678 }
XiaokangQianeb69aee2022-07-05 08:21:43 +0000679 p += output_len;
680 }
Ronald Cron41a443a2022-10-04 16:38:25 +0200681#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
XiaokangQianeb69aee2022-07-05 08:21:43 +0000682
Ronald Cron3d580bf2022-02-18 17:24:56 +0100683 /* Write the length of the list of extensions. */
684 extensions_len = p - p_extensions_len - 2;
Ronald Cron4079abc2022-02-20 10:35:26 +0100685
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 if (extensions_len == 0) {
687 p = p_extensions_len;
688 } else {
689 MBEDTLS_PUT_UINT16_BE(extensions_len, p_extensions_len, 0);
690 MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, total extension length: %" \
691 MBEDTLS_PRINTF_SIZET, extensions_len));
692 MBEDTLS_SSL_DEBUG_BUF(3, "client hello extensions",
693 p_extensions_len, extensions_len);
Ronald Cron4079abc2022-02-20 10:35:26 +0100694 }
Ronald Cron3d580bf2022-02-18 17:24:56 +0100695
Jerry Yu4b8f2f72022-10-31 13:31:22 +0800696#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
Jerry Yu7de2ff02022-11-08 21:43:46 +0800697 MBEDTLS_SSL_PRINT_EXTS(
Gilles Peskine449bd832023-01-11 14:50:10 +0100698 3, MBEDTLS_SSL_HS_CLIENT_HELLO, handshake->sent_extensions);
Jerry Yu4b8f2f72022-10-31 13:31:22 +0800699#endif
700
Ronald Cron3d580bf2022-02-18 17:24:56 +0100701 *out_len = p - buf;
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 return 0;
Ronald Cron3d580bf2022-02-18 17:24:56 +0100703}
704
Manuel Pégourié-Gonnarda3115dc2022-06-17 10:52:54 +0200705MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine449bd832023-01-11 14:50:10 +0100706static int ssl_generate_random(mbedtls_ssl_context *ssl)
Ronald Cron58b80382022-02-18 18:41:08 +0100707{
708 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
709 unsigned char *randbytes = ssl->handshake->randbytes;
710 size_t gmt_unix_time_len = 0;
711
712 /*
713 * Generate the random bytes
714 *
715 * TLS 1.2 case:
716 * struct {
717 * uint32 gmt_unix_time;
718 * opaque random_bytes[28];
719 * } Random;
720 *
721 * TLS 1.3 case:
722 * opaque Random[32];
723 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2) {
Ronald Cron58b80382022-02-18 18:41:08 +0100725#if defined(MBEDTLS_HAVE_TIME)
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 mbedtls_time_t gmt_unix_time = mbedtls_time(NULL);
727 MBEDTLS_PUT_UINT32_BE(gmt_unix_time, randbytes, 0);
Ronald Cron58b80382022-02-18 18:41:08 +0100728 gmt_unix_time_len = 4;
729
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 MBEDTLS_SSL_DEBUG_MSG(3,
731 ("client hello, current time: %" MBEDTLS_PRINTF_LONGLONG,
732 (long long) gmt_unix_time));
Ronald Cron58b80382022-02-18 18:41:08 +0100733#endif /* MBEDTLS_HAVE_TIME */
734 }
735
Gilles Peskine449bd832023-01-11 14:50:10 +0100736 ret = ssl->conf->f_rng(ssl->conf->p_rng,
737 randbytes + gmt_unix_time_len,
738 MBEDTLS_CLIENT_HELLO_RANDOM_LEN - gmt_unix_time_len);
739 return ret;
Ronald Cron58b80382022-02-18 18:41:08 +0100740}
Xiaokang Qian2f9efd32022-10-10 11:24:08 +0000741
Manuel Pégourié-Gonnarda3115dc2022-06-17 10:52:54 +0200742MBEDTLS_CHECK_RETURN_CRITICAL
Gilles Peskine449bd832023-01-11 14:50:10 +0100743static int ssl_prepare_client_hello(mbedtls_ssl_context *ssl)
Ronald Cron3d580bf2022-02-18 17:24:56 +0100744{
745 int ret;
Ronald Cron021b1782022-02-19 17:32:53 +0100746 size_t session_id_len;
Jerry Yu22c18c12022-10-11 15:58:51 +0800747 mbedtls_ssl_session *session_negotiate = ssl->session_negotiate;
748
Gilles Peskine449bd832023-01-11 14:50:10 +0100749 if (session_negotiate == NULL) {
750 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
751 }
Ronald Cron3d580bf2022-02-18 17:24:56 +0100752
Jerry Yu4f77ecf2022-10-10 22:10:08 +0800753#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
754 defined(MBEDTLS_SSL_SESSION_TICKETS) && \
755 defined(MBEDTLS_HAVE_TIME)
Jerry Yu22c18c12022-10-11 15:58:51 +0800756
Jerry Yu4f77ecf2022-10-10 22:10:08 +0800757 /* Check if a tls13 ticket has been configured. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 if (ssl->handshake->resume != 0 &&
Jerry Yu22c18c12022-10-11 15:58:51 +0800759 session_negotiate->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 session_negotiate->ticket != NULL) {
761 mbedtls_time_t now = mbedtls_time(NULL);
762 uint64_t age = (uint64_t) (now - session_negotiate->ticket_received);
763 if (session_negotiate->ticket_received > now ||
764 age > session_negotiate->ticket_lifetime) {
Jerry Yu4f77ecf2022-10-10 22:10:08 +0800765 /* Without valid ticket, disable session resumption.*/
766 MBEDTLS_SSL_DEBUG_MSG(
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 3, ("Ticket expired, disable session resumption"));
Jerry Yu4f77ecf2022-10-10 22:10:08 +0800768 ssl->handshake->resume = 0;
769 }
770 }
771#endif /* MBEDTLS_SSL_PROTO_TLS1_3 &&
772 MBEDTLS_SSL_SESSION_TICKETS &&
773 MBEDTLS_HAVE_TIME */
774
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 if (ssl->conf->f_rng == NULL) {
776 MBEDTLS_SSL_DEBUG_MSG(1, ("no RNG provided"));
777 return MBEDTLS_ERR_SSL_NO_RNG;
Ronald Cron3d580bf2022-02-18 17:24:56 +0100778 }
779
Ronald Cron86a477f2022-02-18 17:45:10 +0100780 /* Bet on the highest configured version if we are not in a TLS 1.2
781 * renegotiation or session resumption.
782 */
783#if defined(MBEDTLS_SSL_RENEGOTIATION)
Gilles Peskine449bd832023-01-11 14:50:10 +0100784 if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
Glenn Strausscd78df62022-04-07 19:07:11 -0400785 ssl->handshake->min_tls_version = ssl->tls_version;
Gilles Peskine449bd832023-01-11 14:50:10 +0100786 } else
Ronald Cron86a477f2022-02-18 17:45:10 +0100787#endif
788 {
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 if (ssl->handshake->resume) {
790 ssl->tls_version = session_negotiate->tls_version;
791 ssl->handshake->min_tls_version = ssl->tls_version;
792 } else {
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 ssl->handshake->min_tls_version = ssl->conf->min_tls_version;
Ronald Cron86a477f2022-02-18 17:45:10 +0100794 }
795 }
796
Ronald Cron58b80382022-02-18 18:41:08 +0100797 /*
Ronald Cronda41b382022-03-30 09:57:11 +0200798 * Generate the random bytes, except when responding to a verify request
Tom Cosgrove1797b052022-12-04 17:19:59 +0000799 * where we MUST reuse the previously generated random bytes
Ronald Cronda41b382022-03-30 09:57:11 +0200800 * (RFC 6347 4.2.1).
Ronald Cron58b80382022-02-18 18:41:08 +0100801 */
802#if defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) ||
804 (ssl->handshake->cookie == NULL))
Ronald Cron58b80382022-02-18 18:41:08 +0100805#endif
Ronald Cron3d580bf2022-02-18 17:24:56 +0100806 {
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 ret = ssl_generate_random(ssl);
808 if (ret != 0) {
809 MBEDTLS_SSL_DEBUG_RET(1, "Random bytes generation failed", ret);
810 return ret;
Ronald Cron58b80382022-02-18 18:41:08 +0100811 }
Ronald Cron3d580bf2022-02-18 17:24:56 +0100812 }
813
Ronald Cron3d580bf2022-02-18 17:24:56 +0100814 /*
Ronald Cronda41b382022-03-30 09:57:11 +0200815 * Prepare session identifier. At that point, the length of the session
816 * identifier in the SSL context `ssl->session_negotiate->id_len` is equal
817 * to zero, except in the case of a TLS 1.2 session renegotiation or
818 * session resumption.
Ronald Cron3d580bf2022-02-18 17:24:56 +0100819 */
Jerry Yu22c18c12022-10-11 15:58:51 +0800820 session_id_len = session_negotiate->id_len;
Ronald Cron021b1782022-02-19 17:32:53 +0100821
822#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
Gilles Peskine449bd832023-01-11 14:50:10 +0100823 if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2) {
824 if (session_id_len < 16 || session_id_len > 32 ||
Ronald Cron021b1782022-02-19 17:32:53 +0100825#if defined(MBEDTLS_SSL_RENEGOTIATION)
826 ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ||
827#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 ssl->handshake->resume == 0) {
Ronald Cron021b1782022-02-19 17:32:53 +0100829 session_id_len = 0;
Ronald Cron3d580bf2022-02-18 17:24:56 +0100830 }
Ronald Cron021b1782022-02-19 17:32:53 +0100831
832#if defined(MBEDTLS_SSL_SESSION_TICKETS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100833 /*
834 * RFC 5077 section 3.4: "When presenting a ticket, the client MAY
835 * generate and include a Session ID in the TLS ClientHello."
836 */
David Horstmann4a285632022-10-06 18:30:10 +0100837 int renegotiating = 0;
Ronald Cron021b1782022-02-19 17:32:53 +0100838#if defined(MBEDTLS_SSL_RENEGOTIATION)
Gilles Peskine449bd832023-01-11 14:50:10 +0100839 if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
David Horstmann7aee0ec2022-10-25 10:38:25 +0100840 renegotiating = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 }
Ronald Cron021b1782022-02-19 17:32:53 +0100842#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100843 if (!renegotiating) {
844 if ((session_negotiate->ticket != NULL) &&
845 (session_negotiate->ticket_len != 0)) {
Ronald Cron021b1782022-02-19 17:32:53 +0100846 session_id_len = 32;
847 }
848 }
849#endif /* MBEDTLS_SSL_SESSION_TICKETS */
850 }
851#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
852
853#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100854 if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3) {
Ronald Cron021b1782022-02-19 17:32:53 +0100855 /*
856 * Create a legacy session identifier for the purpose of middlebox
857 * compatibility only if one has not been created already, which is
858 * the case if we are here for the TLS 1.3 second ClientHello.
859 *
860 * Versions of TLS before TLS 1.3 supported a "session resumption"
861 * feature which has been merged with pre-shared keys in TLS 1.3
862 * version. A client which has a cached session ID set by a pre-TLS 1.3
863 * server SHOULD set this field to that value. In compatibility mode,
864 * this field MUST be non-empty, so a client not offering a pre-TLS 1.3
865 * session MUST generate a new 32-byte value. This value need not be
866 * random but SHOULD be unpredictable to avoid implementations fixating
867 * on a specific value (also known as ossification). Otherwise, it MUST
868 * be set as a zero-length vector ( i.e., a zero-valued single byte
869 * length field ).
870 */
871 session_id_len = 32;
Ronald Cron3d580bf2022-02-18 17:24:56 +0100872 }
873#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
874
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 if (session_id_len != session_negotiate->id_len) {
Jerry Yu22c18c12022-10-11 15:58:51 +0800876 session_negotiate->id_len = session_id_len;
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 if (session_id_len > 0) {
878 ret = ssl->conf->f_rng(ssl->conf->p_rng,
879 session_negotiate->id,
880 session_id_len);
881 if (ret != 0) {
882 MBEDTLS_SSL_DEBUG_RET(1, "creating session id failed", ret);
883 return ret;
Ronald Cron021b1782022-02-19 17:32:53 +0100884 }
885 }
886 }
887
Xiaokang Qianbc663a02022-10-09 11:14:39 +0000888#if defined(MBEDTLS_SSL_PROTO_TLS1_3) && \
Xiaokang Qian03409292022-10-12 02:49:52 +0000889 defined(MBEDTLS_SSL_SESSION_TICKETS) && \
Xiaokang Qianbc663a02022-10-09 11:14:39 +0000890 defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 if (ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
892 ssl->handshake->resume) {
Xiaokang Qiand7adc372022-10-11 09:05:11 +0000893 int hostname_mismatch = ssl->hostname != NULL ||
Xiaokang Qian307a7302022-10-12 11:14:32 +0000894 session_negotiate->hostname != NULL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100895 if (ssl->hostname != NULL && session_negotiate->hostname != NULL) {
Xiaokang Qiand7adc372022-10-11 09:05:11 +0000896 hostname_mismatch = strcmp(
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 ssl->hostname, session_negotiate->hostname) != 0;
Xiaokang Qianed3afcd2022-10-12 08:31:11 +0000898 }
Xiaokang Qiana3b451f2022-10-11 06:20:56 +0000899
Gilles Peskine449bd832023-01-11 14:50:10 +0100900 if (hostname_mismatch) {
Xiaokang Qianed0620c2022-10-12 06:58:13 +0000901 MBEDTLS_SSL_DEBUG_MSG(
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 1, ("Hostname mismatch the session ticket, "
903 "disable session resumption."));
904 return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
Xiaokang Qianbc663a02022-10-09 11:14:39 +0000905 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 } else {
907 return mbedtls_ssl_session_set_hostname(session_negotiate,
908 ssl->hostname);
Xiaokang Qian03409292022-10-12 02:49:52 +0000909 }
Xiaokang Qianbc663a02022-10-09 11:14:39 +0000910#endif /* MBEDTLS_SSL_PROTO_TLS1_3 &&
Xiaokang Qian03409292022-10-12 02:49:52 +0000911 MBEDTLS_SSL_SESSION_TICKETS &&
Xiaokang Qianbc663a02022-10-09 11:14:39 +0000912 MBEDTLS_SSL_SERVER_NAME_INDICATION */
913
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 return 0;
Ronald Cron3d580bf2022-02-18 17:24:56 +0100915}
Ronald Cron3d580bf2022-02-18 17:24:56 +0100916/*
917 * Write ClientHello handshake message.
918 * Handler for MBEDTLS_SSL_CLIENT_HELLO
919 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100920int mbedtls_ssl_write_client_hello(mbedtls_ssl_context *ssl)
Ronald Cron3d580bf2022-02-18 17:24:56 +0100921{
922 int ret = 0;
923 unsigned char *buf;
XiaokangQianeb69aee2022-07-05 08:21:43 +0000924 size_t buf_len, msg_len, binders_len;
Ronald Cron3d580bf2022-02-18 17:24:56 +0100925
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 MBEDTLS_SSL_DEBUG_MSG(2, ("=> write client hello"));
Ronald Cron3d580bf2022-02-18 17:24:56 +0100927
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 MBEDTLS_SSL_PROC_CHK(ssl_prepare_client_hello(ssl));
Ronald Cron3d580bf2022-02-18 17:24:56 +0100929
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(
931 ssl, MBEDTLS_SSL_HS_CLIENT_HELLO,
932 &buf, &buf_len));
Ronald Cron3d580bf2022-02-18 17:24:56 +0100933
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 MBEDTLS_SSL_PROC_CHK(ssl_write_client_hello_body(ssl, buf,
935 buf + buf_len,
936 &msg_len,
937 &binders_len));
Ronald Cron3d580bf2022-02-18 17:24:56 +0100938
Ronald Cron5f4e9122022-02-21 09:50:36 +0100939#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && defined(MBEDTLS_SSL_PROTO_DTLS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
Ronald Cron5f4e9122022-02-21 09:50:36 +0100941 ssl->out_msglen = msg_len + 4;
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 mbedtls_ssl_send_flight_completed(ssl);
Ronald Cron3d580bf2022-02-18 17:24:56 +0100943
Ronald Cron8ecd9932022-03-29 12:26:54 +0200944 /*
945 * The two functions below may try to send data on the network and
946 * can return with the MBEDTLS_ERR_SSL_WANT_READ error code when they
947 * fail to do so and the transmission has to be retried later. In that
Ronald Cronda41b382022-03-30 09:57:11 +0200948 * case as in fatal error cases, we return immediately. But we must have
Ronald Cron8ecd9932022-03-29 12:26:54 +0200949 * set the handshake state to the next state at that point to ensure
950 * that we will not write and send again a ClientHello when we
951 * eventually succeed in sending the pending data.
952 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO);
Ronald Cron8ecd9932022-03-29 12:26:54 +0200954
Gilles Peskine449bd832023-01-11 14:50:10 +0100955 if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
956 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
957 return ret;
Ronald Cron5f4e9122022-02-21 09:50:36 +0100958 }
959
Gilles Peskine449bd832023-01-11 14:50:10 +0100960 if ((ret = mbedtls_ssl_flight_transmit(ssl)) != 0) {
961 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flight_transmit", ret);
962 return ret;
Ronald Cron5f4e9122022-02-21 09:50:36 +0100963 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100964 } else
Ronald Cron5f4e9122022-02-21 09:50:36 +0100965#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_SSL_PROTO_DTLS */
966 {
XiaokangQianeb69aee2022-07-05 08:21:43 +0000967
Manuel Pégourié-Gonnardb8b07aa2023-02-06 00:34:21 +0100968 ret = mbedtls_ssl_add_hs_hdr_to_checksum(ssl,
969 MBEDTLS_SSL_HS_CLIENT_HELLO,
970 msg_len);
971 if (ret != 0) {
972 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_add_hs_hdr_to_checksum", ret);
973 return ret;
974 }
975 ret = ssl->handshake->update_checksum(ssl, buf, msg_len - binders_len);
976 if (ret != 0) {
977 MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret);
978 return ret;
979 }
Ronald Cron41a443a2022-10-04 16:38:25 +0200980#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
Gilles Peskine449bd832023-01-11 14:50:10 +0100981 if (binders_len > 0) {
XiaokangQianeb69aee2022-07-05 08:21:43 +0000982 MBEDTLS_SSL_PROC_CHK(
XiaokangQian86981952022-07-19 09:51:50 +0000983 mbedtls_ssl_tls13_write_binders_of_pre_shared_key_ext(
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 ssl, buf + msg_len - binders_len, buf + msg_len));
Manuel Pégourié-Gonnardb8b07aa2023-02-06 00:34:21 +0100985 ret = ssl->handshake->update_checksum(ssl, buf + msg_len - binders_len,
Manuel Pégourié-Gonnard43cc1272023-02-06 11:48:19 +0100986 binders_len);
Manuel Pégourié-Gonnardb8b07aa2023-02-06 00:34:21 +0100987 if (ret != 0) {
988 MBEDTLS_SSL_DEBUG_RET(1, "update_checksum", ret);
989 return ret;
990 }
XiaokangQianeb69aee2022-07-05 08:21:43 +0000991 }
Ronald Cron41a443a2022-10-04 16:38:25 +0200992#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
XiaokangQianeb69aee2022-07-05 08:21:43 +0000993
Gilles Peskine449bd832023-01-11 14:50:10 +0100994 MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_finish_handshake_msg(ssl,
995 buf_len,
996 msg_len));
Ronald Cron3d580bf2022-02-18 17:24:56 +0100997
Xiaokang Qian44051f62023-02-02 06:57:26 +0000998 /*
999 * Set next state. Note that if TLS 1.3 is proposed, this may be
Xiaokang Qian934ce6f2023-02-06 10:23:04 +00001000 * overwritten by mbedtls_ssl_tls13_finalize_client_hello().
Xiaokang Qian44051f62023-02-02 06:57:26 +00001001 */
1002 mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO);
Xiaokang Qiandf6f52e2022-12-15 14:42:45 +00001003
Xiaokang Qian44051f62023-02-02 06:57:26 +00001004#if defined(MBEDTLS_SSL_PROTO_TLS1_3)
1005 if (ssl->handshake->min_tls_version <= MBEDTLS_SSL_VERSION_TLS1_3 &&
1006 MBEDTLS_SSL_VERSION_TLS1_3 <= ssl->tls_version) {
Xiaokang Qian934ce6f2023-02-06 10:23:04 +00001007 ret = mbedtls_ssl_tls13_finalize_client_hello(ssl);
Xiaokang Qian44051f62023-02-02 06:57:26 +00001008 }
1009#endif
Xiaokang Qiandf6f52e2022-12-15 14:42:45 +00001010 }
Ronald Cron3d580bf2022-02-18 17:24:56 +01001011
1012cleanup:
1013
Gilles Peskine449bd832023-01-11 14:50:10 +01001014 MBEDTLS_SSL_DEBUG_MSG(2, ("<= write client hello"));
Ronald Cron3d580bf2022-02-18 17:24:56 +01001015 return ret;
1016}
1017
1018#endif /* MBEDTLS_SSL_PROTO_TLS1_3 || MBEDTLS_SSL_PROTO_TLS1_2 */
1019#endif /* MBEDTLS_SSL_CLI_C */