1a8e1175bSopenharmony_ci/*
2a8e1175bSopenharmony_ci *  TLS 1.3 client-side functions
3a8e1175bSopenharmony_ci *
4a8e1175bSopenharmony_ci *  Copyright The Mbed TLS Contributors
5a8e1175bSopenharmony_ci *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6a8e1175bSopenharmony_ci */
7a8e1175bSopenharmony_ci
8a8e1175bSopenharmony_ci#include "common.h"
9a8e1175bSopenharmony_ci
10a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
11a8e1175bSopenharmony_ci
12a8e1175bSopenharmony_ci#include <string.h>
13a8e1175bSopenharmony_ci
14a8e1175bSopenharmony_ci#include "debug_internal.h"
15a8e1175bSopenharmony_ci#include "mbedtls/error.h"
16a8e1175bSopenharmony_ci#include "mbedtls/platform.h"
17a8e1175bSopenharmony_ci
18a8e1175bSopenharmony_ci#include "ssl_misc.h"
19a8e1175bSopenharmony_ci#include "ssl_client.h"
20a8e1175bSopenharmony_ci#include "ssl_tls13_keys.h"
21a8e1175bSopenharmony_ci#include "ssl_debug_helpers.h"
22a8e1175bSopenharmony_ci#include "mbedtls/psa_util.h"
23a8e1175bSopenharmony_ci
24a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
25a8e1175bSopenharmony_ci/* Define a local translating function to save code size by not using too many
26a8e1175bSopenharmony_ci * arguments in each translating place. */
27a8e1175bSopenharmony_cistatic int local_err_translation(psa_status_t status)
28a8e1175bSopenharmony_ci{
29a8e1175bSopenharmony_ci    return psa_status_to_mbedtls(status, psa_to_ssl_errors,
30a8e1175bSopenharmony_ci                                 ARRAY_LENGTH(psa_to_ssl_errors),
31a8e1175bSopenharmony_ci                                 psa_generic_status_to_mbedtls);
32a8e1175bSopenharmony_ci}
33a8e1175bSopenharmony_ci#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)
34a8e1175bSopenharmony_ci#endif
35a8e1175bSopenharmony_ci
36a8e1175bSopenharmony_ci/* Write extensions */
37a8e1175bSopenharmony_ci
38a8e1175bSopenharmony_ci/*
39a8e1175bSopenharmony_ci * ssl_tls13_write_supported_versions_ext():
40a8e1175bSopenharmony_ci *
41a8e1175bSopenharmony_ci * struct {
42a8e1175bSopenharmony_ci *      ProtocolVersion versions<2..254>;
43a8e1175bSopenharmony_ci * } SupportedVersions;
44a8e1175bSopenharmony_ci */
45a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
46a8e1175bSopenharmony_cistatic int ssl_tls13_write_supported_versions_ext(mbedtls_ssl_context *ssl,
47a8e1175bSopenharmony_ci                                                  unsigned char *buf,
48a8e1175bSopenharmony_ci                                                  unsigned char *end,
49a8e1175bSopenharmony_ci                                                  size_t *out_len)
50a8e1175bSopenharmony_ci{
51a8e1175bSopenharmony_ci    unsigned char *p = buf;
52a8e1175bSopenharmony_ci    unsigned char versions_len = (ssl->handshake->min_tls_version <=
53a8e1175bSopenharmony_ci                                  MBEDTLS_SSL_VERSION_TLS1_2) ? 4 : 2;
54a8e1175bSopenharmony_ci
55a8e1175bSopenharmony_ci    *out_len = 0;
56a8e1175bSopenharmony_ci
57a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding supported versions extension"));
58a8e1175bSopenharmony_ci
59a8e1175bSopenharmony_ci    /* Check if we have space to write the extension:
60a8e1175bSopenharmony_ci     * - extension_type         (2 bytes)
61a8e1175bSopenharmony_ci     * - extension_data_length  (2 bytes)
62a8e1175bSopenharmony_ci     * - versions_length        (1 byte )
63a8e1175bSopenharmony_ci     * - versions               (2 or 4 bytes)
64a8e1175bSopenharmony_ci     */
65a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_PTR(p, end, 5 + versions_len);
66a8e1175bSopenharmony_ci
67a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS, p, 0);
68a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT16_BE(versions_len + 1, p, 2);
69a8e1175bSopenharmony_ci    p += 4;
70a8e1175bSopenharmony_ci
71a8e1175bSopenharmony_ci    /* Length of versions */
72a8e1175bSopenharmony_ci    *p++ = versions_len;
73a8e1175bSopenharmony_ci
74a8e1175bSopenharmony_ci    /* Write values of supported versions.
75a8e1175bSopenharmony_ci     * They are defined by the configuration.
76a8e1175bSopenharmony_ci     * Currently, we advertise only TLS 1.3 or both TLS 1.3 and TLS 1.2.
77a8e1175bSopenharmony_ci     */
78a8e1175bSopenharmony_ci    mbedtls_ssl_write_version(p, MBEDTLS_SSL_TRANSPORT_STREAM,
79a8e1175bSopenharmony_ci                              MBEDTLS_SSL_VERSION_TLS1_3);
80a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("supported version: [3:4]"));
81a8e1175bSopenharmony_ci
82a8e1175bSopenharmony_ci
83a8e1175bSopenharmony_ci    if (ssl->handshake->min_tls_version <= MBEDTLS_SSL_VERSION_TLS1_2) {
84a8e1175bSopenharmony_ci        mbedtls_ssl_write_version(p + 2, MBEDTLS_SSL_TRANSPORT_STREAM,
85a8e1175bSopenharmony_ci                                  MBEDTLS_SSL_VERSION_TLS1_2);
86a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3, ("supported version: [3:3]"));
87a8e1175bSopenharmony_ci    }
88a8e1175bSopenharmony_ci
89a8e1175bSopenharmony_ci    *out_len = 5 + versions_len;
90a8e1175bSopenharmony_ci
91a8e1175bSopenharmony_ci    mbedtls_ssl_tls13_set_hs_sent_ext_mask(
92a8e1175bSopenharmony_ci        ssl, MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS);
93a8e1175bSopenharmony_ci
94a8e1175bSopenharmony_ci    return 0;
95a8e1175bSopenharmony_ci}
96a8e1175bSopenharmony_ci
97a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
98a8e1175bSopenharmony_cistatic int ssl_tls13_parse_supported_versions_ext(mbedtls_ssl_context *ssl,
99a8e1175bSopenharmony_ci                                                  const unsigned char *buf,
100a8e1175bSopenharmony_ci                                                  const unsigned char *end)
101a8e1175bSopenharmony_ci{
102a8e1175bSopenharmony_ci    ((void) ssl);
103a8e1175bSopenharmony_ci
104a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(buf, end, 2);
105a8e1175bSopenharmony_ci    if (mbedtls_ssl_read_version(buf, ssl->conf->transport) !=
106a8e1175bSopenharmony_ci        MBEDTLS_SSL_VERSION_TLS1_3) {
107a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("unexpected version"));
108a8e1175bSopenharmony_ci
109a8e1175bSopenharmony_ci        MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
110a8e1175bSopenharmony_ci                                     MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
111a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
112a8e1175bSopenharmony_ci    }
113a8e1175bSopenharmony_ci
114a8e1175bSopenharmony_ci    if (&buf[2] != end) {
115a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(
116a8e1175bSopenharmony_ci            1, ("supported_versions ext data length incorrect"));
117a8e1175bSopenharmony_ci        MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
118a8e1175bSopenharmony_ci                                     MBEDTLS_ERR_SSL_DECODE_ERROR);
119a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_DECODE_ERROR;
120a8e1175bSopenharmony_ci    }
121a8e1175bSopenharmony_ci
122a8e1175bSopenharmony_ci    return 0;
123a8e1175bSopenharmony_ci}
124a8e1175bSopenharmony_ci
125a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ALPN)
126a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
127a8e1175bSopenharmony_cistatic int ssl_tls13_parse_alpn_ext(mbedtls_ssl_context *ssl,
128a8e1175bSopenharmony_ci                                    const unsigned char *buf, size_t len)
129a8e1175bSopenharmony_ci{
130a8e1175bSopenharmony_ci    const unsigned char *p = buf;
131a8e1175bSopenharmony_ci    const unsigned char *end = buf + len;
132a8e1175bSopenharmony_ci    size_t protocol_name_list_len, protocol_name_len;
133a8e1175bSopenharmony_ci    const unsigned char *protocol_name_list_end;
134a8e1175bSopenharmony_ci
135a8e1175bSopenharmony_ci    /* If we didn't send it, the server shouldn't send it */
136a8e1175bSopenharmony_ci    if (ssl->conf->alpn_list == NULL) {
137a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
138a8e1175bSopenharmony_ci    }
139a8e1175bSopenharmony_ci
140a8e1175bSopenharmony_ci    /*
141a8e1175bSopenharmony_ci     * opaque ProtocolName<1..2^8-1>;
142a8e1175bSopenharmony_ci     *
143a8e1175bSopenharmony_ci     * struct {
144a8e1175bSopenharmony_ci     *     ProtocolName protocol_name_list<2..2^16-1>
145a8e1175bSopenharmony_ci     * } ProtocolNameList;
146a8e1175bSopenharmony_ci     *
147a8e1175bSopenharmony_ci     * the "ProtocolNameList" MUST contain exactly one "ProtocolName"
148a8e1175bSopenharmony_ci     */
149a8e1175bSopenharmony_ci
150a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
151a8e1175bSopenharmony_ci    protocol_name_list_len = MBEDTLS_GET_UINT16_BE(p, 0);
152a8e1175bSopenharmony_ci    p += 2;
153a8e1175bSopenharmony_ci
154a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, protocol_name_list_len);
155a8e1175bSopenharmony_ci    protocol_name_list_end = p + protocol_name_list_len;
156a8e1175bSopenharmony_ci
157a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, protocol_name_list_end, 1);
158a8e1175bSopenharmony_ci    protocol_name_len = *p++;
159a8e1175bSopenharmony_ci
160a8e1175bSopenharmony_ci    /* Check that the server chosen protocol was in our list and save it */
161a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, protocol_name_list_end, protocol_name_len);
162a8e1175bSopenharmony_ci    for (const char **alpn = ssl->conf->alpn_list; *alpn != NULL; alpn++) {
163a8e1175bSopenharmony_ci        if (protocol_name_len == strlen(*alpn) &&
164a8e1175bSopenharmony_ci            memcmp(p, *alpn, protocol_name_len) == 0) {
165a8e1175bSopenharmony_ci            ssl->alpn_chosen = *alpn;
166a8e1175bSopenharmony_ci            return 0;
167a8e1175bSopenharmony_ci        }
168a8e1175bSopenharmony_ci    }
169a8e1175bSopenharmony_ci
170a8e1175bSopenharmony_ci    return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
171a8e1175bSopenharmony_ci}
172a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ALPN */
173a8e1175bSopenharmony_ci
174a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
175a8e1175bSopenharmony_cistatic int ssl_tls13_reset_key_share(mbedtls_ssl_context *ssl)
176a8e1175bSopenharmony_ci{
177a8e1175bSopenharmony_ci    uint16_t group_id = ssl->handshake->offered_group_id;
178a8e1175bSopenharmony_ci
179a8e1175bSopenharmony_ci    if (group_id == 0) {
180a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
181a8e1175bSopenharmony_ci    }
182a8e1175bSopenharmony_ci
183a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
184a8e1175bSopenharmony_ci    if (mbedtls_ssl_tls13_named_group_is_ecdhe(group_id) ||
185a8e1175bSopenharmony_ci        mbedtls_ssl_tls13_named_group_is_ffdh(group_id)) {
186a8e1175bSopenharmony_ci        int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
187a8e1175bSopenharmony_ci        psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
188a8e1175bSopenharmony_ci
189a8e1175bSopenharmony_ci        /* Destroy generated private key. */
190a8e1175bSopenharmony_ci        status = psa_destroy_key(ssl->handshake->xxdh_psa_privkey);
191a8e1175bSopenharmony_ci        if (status != PSA_SUCCESS) {
192a8e1175bSopenharmony_ci            ret = PSA_TO_MBEDTLS_ERR(status);
193a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "psa_destroy_key", ret);
194a8e1175bSopenharmony_ci            return ret;
195a8e1175bSopenharmony_ci        }
196a8e1175bSopenharmony_ci
197a8e1175bSopenharmony_ci        ssl->handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
198a8e1175bSopenharmony_ci        return 0;
199a8e1175bSopenharmony_ci    } else
200a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */
201a8e1175bSopenharmony_ci    if (0 /* other KEMs? */) {
202a8e1175bSopenharmony_ci        /* Do something */
203a8e1175bSopenharmony_ci    }
204a8e1175bSopenharmony_ci
205a8e1175bSopenharmony_ci    return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
206a8e1175bSopenharmony_ci}
207a8e1175bSopenharmony_ci
208a8e1175bSopenharmony_ci/*
209a8e1175bSopenharmony_ci * Functions for writing key_share extension.
210a8e1175bSopenharmony_ci */
211a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
212a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
213a8e1175bSopenharmony_cistatic int ssl_tls13_get_default_group_id(mbedtls_ssl_context *ssl,
214a8e1175bSopenharmony_ci                                          uint16_t *group_id)
215a8e1175bSopenharmony_ci{
216a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
217a8e1175bSopenharmony_ci
218a8e1175bSopenharmony_ci
219a8e1175bSopenharmony_ci#if defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)
220a8e1175bSopenharmony_ci    const uint16_t *group_list = mbedtls_ssl_get_groups(ssl);
221a8e1175bSopenharmony_ci    /* Pick first available ECDHE group compatible with TLS 1.3 */
222a8e1175bSopenharmony_ci    if (group_list == NULL) {
223a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_BAD_CONFIG;
224a8e1175bSopenharmony_ci    }
225a8e1175bSopenharmony_ci
226a8e1175bSopenharmony_ci    for (; *group_list != 0; group_list++) {
227a8e1175bSopenharmony_ci#if defined(PSA_WANT_ALG_ECDH)
228a8e1175bSopenharmony_ci        if ((mbedtls_ssl_get_psa_curve_info_from_tls_id(
229a8e1175bSopenharmony_ci                 *group_list, NULL, NULL) == PSA_SUCCESS) &&
230a8e1175bSopenharmony_ci            mbedtls_ssl_tls13_named_group_is_ecdhe(*group_list)) {
231a8e1175bSopenharmony_ci            *group_id = *group_list;
232a8e1175bSopenharmony_ci            return 0;
233a8e1175bSopenharmony_ci        }
234a8e1175bSopenharmony_ci#endif
235a8e1175bSopenharmony_ci#if defined(PSA_WANT_ALG_FFDH)
236a8e1175bSopenharmony_ci        if (mbedtls_ssl_tls13_named_group_is_ffdh(*group_list)) {
237a8e1175bSopenharmony_ci            *group_id = *group_list;
238a8e1175bSopenharmony_ci            return 0;
239a8e1175bSopenharmony_ci        }
240a8e1175bSopenharmony_ci#endif
241a8e1175bSopenharmony_ci    }
242a8e1175bSopenharmony_ci#else
243a8e1175bSopenharmony_ci    ((void) ssl);
244a8e1175bSopenharmony_ci    ((void) group_id);
245a8e1175bSopenharmony_ci#endif /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */
246a8e1175bSopenharmony_ci
247a8e1175bSopenharmony_ci    return ret;
248a8e1175bSopenharmony_ci}
249a8e1175bSopenharmony_ci
250a8e1175bSopenharmony_ci/*
251a8e1175bSopenharmony_ci * ssl_tls13_write_key_share_ext
252a8e1175bSopenharmony_ci *
253a8e1175bSopenharmony_ci * Structure of key_share extension in ClientHello:
254a8e1175bSopenharmony_ci *
255a8e1175bSopenharmony_ci *  struct {
256a8e1175bSopenharmony_ci *          NamedGroup group;
257a8e1175bSopenharmony_ci *          opaque key_exchange<1..2^16-1>;
258a8e1175bSopenharmony_ci *      } KeyShareEntry;
259a8e1175bSopenharmony_ci *  struct {
260a8e1175bSopenharmony_ci *          KeyShareEntry client_shares<0..2^16-1>;
261a8e1175bSopenharmony_ci *      } KeyShareClientHello;
262a8e1175bSopenharmony_ci */
263a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
264a8e1175bSopenharmony_cistatic int ssl_tls13_write_key_share_ext(mbedtls_ssl_context *ssl,
265a8e1175bSopenharmony_ci                                         unsigned char *buf,
266a8e1175bSopenharmony_ci                                         unsigned char *end,
267a8e1175bSopenharmony_ci                                         size_t *out_len)
268a8e1175bSopenharmony_ci{
269a8e1175bSopenharmony_ci    unsigned char *p = buf;
270a8e1175bSopenharmony_ci    unsigned char *client_shares; /* Start of client_shares */
271a8e1175bSopenharmony_ci    size_t client_shares_len;     /* Length of client_shares */
272a8e1175bSopenharmony_ci    uint16_t group_id;
273a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
274a8e1175bSopenharmony_ci
275a8e1175bSopenharmony_ci    *out_len = 0;
276a8e1175bSopenharmony_ci
277a8e1175bSopenharmony_ci    /* Check if we have space for header and length fields:
278a8e1175bSopenharmony_ci     * - extension_type         (2 bytes)
279a8e1175bSopenharmony_ci     * - extension_data_length  (2 bytes)
280a8e1175bSopenharmony_ci     * - client_shares_length   (2 bytes)
281a8e1175bSopenharmony_ci     */
282a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6);
283a8e1175bSopenharmony_ci    p += 6;
284a8e1175bSopenharmony_ci
285a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("client hello: adding key share extension"));
286a8e1175bSopenharmony_ci
287a8e1175bSopenharmony_ci    /* HRR could already have requested something else. */
288a8e1175bSopenharmony_ci    group_id = ssl->handshake->offered_group_id;
289a8e1175bSopenharmony_ci    if (!mbedtls_ssl_tls13_named_group_is_ecdhe(group_id) &&
290a8e1175bSopenharmony_ci        !mbedtls_ssl_tls13_named_group_is_ffdh(group_id)) {
291a8e1175bSopenharmony_ci        MBEDTLS_SSL_PROC_CHK(ssl_tls13_get_default_group_id(ssl,
292a8e1175bSopenharmony_ci                                                            &group_id));
293a8e1175bSopenharmony_ci    }
294a8e1175bSopenharmony_ci
295a8e1175bSopenharmony_ci    /*
296a8e1175bSopenharmony_ci     * Dispatch to type-specific key generation function.
297a8e1175bSopenharmony_ci     *
298a8e1175bSopenharmony_ci     * So far, we're only supporting ECDHE. With the introduction
299a8e1175bSopenharmony_ci     * of PQC KEMs, we'll want to have multiple branches, one per
300a8e1175bSopenharmony_ci     * type of KEM, and dispatch to the corresponding crypto. And
301a8e1175bSopenharmony_ci     * only one key share entry is allowed.
302a8e1175bSopenharmony_ci     */
303a8e1175bSopenharmony_ci    client_shares = p;
304a8e1175bSopenharmony_ci#if defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)
305a8e1175bSopenharmony_ci    if (mbedtls_ssl_tls13_named_group_is_ecdhe(group_id) ||
306a8e1175bSopenharmony_ci        mbedtls_ssl_tls13_named_group_is_ffdh(group_id)) {
307a8e1175bSopenharmony_ci        /* Pointer to group */
308a8e1175bSopenharmony_ci        unsigned char *group = p;
309a8e1175bSopenharmony_ci        /* Length of key_exchange */
310a8e1175bSopenharmony_ci        size_t key_exchange_len = 0;
311a8e1175bSopenharmony_ci
312a8e1175bSopenharmony_ci        /* Check there is space for header of KeyShareEntry
313a8e1175bSopenharmony_ci         * - group                  (2 bytes)
314a8e1175bSopenharmony_ci         * - key_exchange_length    (2 bytes)
315a8e1175bSopenharmony_ci         */
316a8e1175bSopenharmony_ci        MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4);
317a8e1175bSopenharmony_ci        p += 4;
318a8e1175bSopenharmony_ci        ret = mbedtls_ssl_tls13_generate_and_write_xxdh_key_exchange(
319a8e1175bSopenharmony_ci            ssl, group_id, p, end, &key_exchange_len);
320a8e1175bSopenharmony_ci        p += key_exchange_len;
321a8e1175bSopenharmony_ci        if (ret != 0) {
322a8e1175bSopenharmony_ci            return ret;
323a8e1175bSopenharmony_ci        }
324a8e1175bSopenharmony_ci
325a8e1175bSopenharmony_ci        /* Write group */
326a8e1175bSopenharmony_ci        MBEDTLS_PUT_UINT16_BE(group_id, group, 0);
327a8e1175bSopenharmony_ci        /* Write key_exchange_length */
328a8e1175bSopenharmony_ci        MBEDTLS_PUT_UINT16_BE(key_exchange_len, group, 2);
329a8e1175bSopenharmony_ci    } else
330a8e1175bSopenharmony_ci#endif /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */
331a8e1175bSopenharmony_ci    if (0 /* other KEMs? */) {
332a8e1175bSopenharmony_ci        /* Do something */
333a8e1175bSopenharmony_ci    } else {
334a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
335a8e1175bSopenharmony_ci    }
336a8e1175bSopenharmony_ci
337a8e1175bSopenharmony_ci    /* Length of client_shares */
338a8e1175bSopenharmony_ci    client_shares_len = p - client_shares;
339a8e1175bSopenharmony_ci    if (client_shares_len == 0) {
340a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("No key share defined."));
341a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
342a8e1175bSopenharmony_ci    }
343a8e1175bSopenharmony_ci    /* Write extension_type */
344a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_KEY_SHARE, buf, 0);
345a8e1175bSopenharmony_ci    /* Write extension_data_length */
346a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT16_BE(client_shares_len + 2, buf, 2);
347a8e1175bSopenharmony_ci    /* Write client_shares_length */
348a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT16_BE(client_shares_len, buf, 4);
349a8e1175bSopenharmony_ci
350a8e1175bSopenharmony_ci    /* Update offered_group_id field */
351a8e1175bSopenharmony_ci    ssl->handshake->offered_group_id = group_id;
352a8e1175bSopenharmony_ci
353a8e1175bSopenharmony_ci    /* Output the total length of key_share extension. */
354a8e1175bSopenharmony_ci    *out_len = p - buf;
355a8e1175bSopenharmony_ci
356a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(
357a8e1175bSopenharmony_ci        3, "client hello, key_share extension", buf, *out_len);
358a8e1175bSopenharmony_ci
359a8e1175bSopenharmony_ci    mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_KEY_SHARE);
360a8e1175bSopenharmony_ci
361a8e1175bSopenharmony_cicleanup:
362a8e1175bSopenharmony_ci
363a8e1175bSopenharmony_ci    return ret;
364a8e1175bSopenharmony_ci}
365a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */
366a8e1175bSopenharmony_ci
367a8e1175bSopenharmony_ci/*
368a8e1175bSopenharmony_ci * ssl_tls13_parse_hrr_key_share_ext()
369a8e1175bSopenharmony_ci *      Parse key_share extension in Hello Retry Request
370a8e1175bSopenharmony_ci *
371a8e1175bSopenharmony_ci * struct {
372a8e1175bSopenharmony_ci *        NamedGroup selected_group;
373a8e1175bSopenharmony_ci * } KeyShareHelloRetryRequest;
374a8e1175bSopenharmony_ci */
375a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
376a8e1175bSopenharmony_cistatic int ssl_tls13_parse_hrr_key_share_ext(mbedtls_ssl_context *ssl,
377a8e1175bSopenharmony_ci                                             const unsigned char *buf,
378a8e1175bSopenharmony_ci                                             const unsigned char *end)
379a8e1175bSopenharmony_ci{
380a8e1175bSopenharmony_ci#if defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)
381a8e1175bSopenharmony_ci    const unsigned char *p = buf;
382a8e1175bSopenharmony_ci    int selected_group;
383a8e1175bSopenharmony_ci    int found = 0;
384a8e1175bSopenharmony_ci
385a8e1175bSopenharmony_ci    const uint16_t *group_list = mbedtls_ssl_get_groups(ssl);
386a8e1175bSopenharmony_ci    if (group_list == NULL) {
387a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_BAD_CONFIG;
388a8e1175bSopenharmony_ci    }
389a8e1175bSopenharmony_ci
390a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(3, "key_share extension", p, end - buf);
391a8e1175bSopenharmony_ci
392a8e1175bSopenharmony_ci    /* Read selected_group */
393a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
394a8e1175bSopenharmony_ci    selected_group = MBEDTLS_GET_UINT16_BE(p, 0);
395a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("selected_group ( %d )", selected_group));
396a8e1175bSopenharmony_ci
397a8e1175bSopenharmony_ci    /* Upon receipt of this extension in a HelloRetryRequest, the client
398a8e1175bSopenharmony_ci     * MUST first verify that the selected_group field corresponds to a
399a8e1175bSopenharmony_ci     * group which was provided in the "supported_groups" extension in the
400a8e1175bSopenharmony_ci     * original ClientHello.
401a8e1175bSopenharmony_ci     * The supported_group was based on the info in ssl->conf->group_list.
402a8e1175bSopenharmony_ci     *
403a8e1175bSopenharmony_ci     * If the server provided a key share that was not sent in the ClientHello
404a8e1175bSopenharmony_ci     * then the client MUST abort the handshake with an "illegal_parameter" alert.
405a8e1175bSopenharmony_ci     */
406a8e1175bSopenharmony_ci    for (; *group_list != 0; group_list++) {
407a8e1175bSopenharmony_ci#if defined(PSA_WANT_ALG_ECDH)
408a8e1175bSopenharmony_ci        if (mbedtls_ssl_tls13_named_group_is_ecdhe(*group_list)) {
409a8e1175bSopenharmony_ci            if ((mbedtls_ssl_get_psa_curve_info_from_tls_id(
410a8e1175bSopenharmony_ci                     *group_list, NULL, NULL) == PSA_ERROR_NOT_SUPPORTED) ||
411a8e1175bSopenharmony_ci                *group_list != selected_group) {
412a8e1175bSopenharmony_ci                found = 1;
413a8e1175bSopenharmony_ci                break;
414a8e1175bSopenharmony_ci            }
415a8e1175bSopenharmony_ci        }
416a8e1175bSopenharmony_ci#endif /* PSA_WANT_ALG_ECDH */
417a8e1175bSopenharmony_ci#if defined(PSA_WANT_ALG_FFDH)
418a8e1175bSopenharmony_ci        if (mbedtls_ssl_tls13_named_group_is_ffdh(*group_list)) {
419a8e1175bSopenharmony_ci            found = 1;
420a8e1175bSopenharmony_ci            break;
421a8e1175bSopenharmony_ci        }
422a8e1175bSopenharmony_ci#endif /* PSA_WANT_ALG_FFDH */
423a8e1175bSopenharmony_ci    }
424a8e1175bSopenharmony_ci
425a8e1175bSopenharmony_ci    /* Client MUST verify that the selected_group field does not
426a8e1175bSopenharmony_ci     * correspond to a group which was provided in the "key_share"
427a8e1175bSopenharmony_ci     * extension in the original ClientHello. If the server sent an
428a8e1175bSopenharmony_ci     * HRR message with a key share already provided in the
429a8e1175bSopenharmony_ci     * ClientHello then the client MUST abort the handshake with
430a8e1175bSopenharmony_ci     * an "illegal_parameter" alert.
431a8e1175bSopenharmony_ci     */
432a8e1175bSopenharmony_ci    if (found == 0 || selected_group == ssl->handshake->offered_group_id) {
433a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid key share in HRR"));
434a8e1175bSopenharmony_ci        MBEDTLS_SSL_PEND_FATAL_ALERT(
435a8e1175bSopenharmony_ci            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
436a8e1175bSopenharmony_ci            MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
437a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
438a8e1175bSopenharmony_ci    }
439a8e1175bSopenharmony_ci
440a8e1175bSopenharmony_ci    /* Remember server's preference for next ClientHello */
441a8e1175bSopenharmony_ci    ssl->handshake->offered_group_id = selected_group;
442a8e1175bSopenharmony_ci
443a8e1175bSopenharmony_ci    return 0;
444a8e1175bSopenharmony_ci#else /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */
445a8e1175bSopenharmony_ci    (void) ssl;
446a8e1175bSopenharmony_ci    (void) buf;
447a8e1175bSopenharmony_ci    (void) end;
448a8e1175bSopenharmony_ci    return MBEDTLS_ERR_SSL_BAD_CONFIG;
449a8e1175bSopenharmony_ci#endif /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */
450a8e1175bSopenharmony_ci}
451a8e1175bSopenharmony_ci
452a8e1175bSopenharmony_ci/*
453a8e1175bSopenharmony_ci * ssl_tls13_parse_key_share_ext()
454a8e1175bSopenharmony_ci *      Parse key_share extension in Server Hello
455a8e1175bSopenharmony_ci *
456a8e1175bSopenharmony_ci * struct {
457a8e1175bSopenharmony_ci *        KeyShareEntry server_share;
458a8e1175bSopenharmony_ci * } KeyShareServerHello;
459a8e1175bSopenharmony_ci * struct {
460a8e1175bSopenharmony_ci *        NamedGroup group;
461a8e1175bSopenharmony_ci *        opaque key_exchange<1..2^16-1>;
462a8e1175bSopenharmony_ci * } KeyShareEntry;
463a8e1175bSopenharmony_ci */
464a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
465a8e1175bSopenharmony_cistatic int ssl_tls13_parse_key_share_ext(mbedtls_ssl_context *ssl,
466a8e1175bSopenharmony_ci                                         const unsigned char *buf,
467a8e1175bSopenharmony_ci                                         const unsigned char *end)
468a8e1175bSopenharmony_ci{
469a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
470a8e1175bSopenharmony_ci    const unsigned char *p = buf;
471a8e1175bSopenharmony_ci    uint16_t group, offered_group;
472a8e1175bSopenharmony_ci
473a8e1175bSopenharmony_ci    /* ...
474a8e1175bSopenharmony_ci     * NamedGroup group; (2 bytes)
475a8e1175bSopenharmony_ci     * ...
476a8e1175bSopenharmony_ci     */
477a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
478a8e1175bSopenharmony_ci    group = MBEDTLS_GET_UINT16_BE(p, 0);
479a8e1175bSopenharmony_ci    p += 2;
480a8e1175bSopenharmony_ci
481a8e1175bSopenharmony_ci    /* Check that the chosen group matches the one we offered. */
482a8e1175bSopenharmony_ci    offered_group = ssl->handshake->offered_group_id;
483a8e1175bSopenharmony_ci    if (offered_group != group) {
484a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(
485a8e1175bSopenharmony_ci            1, ("Invalid server key share, our group %u, their group %u",
486a8e1175bSopenharmony_ci                (unsigned) offered_group, (unsigned) group));
487a8e1175bSopenharmony_ci        MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
488a8e1175bSopenharmony_ci                                     MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
489a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
490a8e1175bSopenharmony_ci    }
491a8e1175bSopenharmony_ci
492a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
493a8e1175bSopenharmony_ci    if (mbedtls_ssl_tls13_named_group_is_ecdhe(group) ||
494a8e1175bSopenharmony_ci        mbedtls_ssl_tls13_named_group_is_ffdh(group)) {
495a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(2,
496a8e1175bSopenharmony_ci                              ("DHE group name: %s", mbedtls_ssl_named_group_to_str(group)));
497a8e1175bSopenharmony_ci        ret = mbedtls_ssl_tls13_read_public_xxdhe_share(ssl, p, end - p);
498a8e1175bSopenharmony_ci        if (ret != 0) {
499a8e1175bSopenharmony_ci            return ret;
500a8e1175bSopenharmony_ci        }
501a8e1175bSopenharmony_ci    } else
502a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */
503a8e1175bSopenharmony_ci    if (0 /* other KEMs? */) {
504a8e1175bSopenharmony_ci        /* Do something */
505a8e1175bSopenharmony_ci    } else {
506a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
507a8e1175bSopenharmony_ci    }
508a8e1175bSopenharmony_ci
509a8e1175bSopenharmony_ci    return ret;
510a8e1175bSopenharmony_ci}
511a8e1175bSopenharmony_ci
512a8e1175bSopenharmony_ci/*
513a8e1175bSopenharmony_ci * ssl_tls13_parse_cookie_ext()
514a8e1175bSopenharmony_ci *      Parse cookie extension in Hello Retry Request
515a8e1175bSopenharmony_ci *
516a8e1175bSopenharmony_ci * struct {
517a8e1175bSopenharmony_ci *        opaque cookie<1..2^16-1>;
518a8e1175bSopenharmony_ci * } Cookie;
519a8e1175bSopenharmony_ci *
520a8e1175bSopenharmony_ci * When sending a HelloRetryRequest, the server MAY provide a "cookie"
521a8e1175bSopenharmony_ci * extension to the client (this is an exception to the usual rule that
522a8e1175bSopenharmony_ci * the only extensions that may be sent are those that appear in the
523a8e1175bSopenharmony_ci * ClientHello).  When sending the new ClientHello, the client MUST copy
524a8e1175bSopenharmony_ci * the contents of the extension received in the HelloRetryRequest into
525a8e1175bSopenharmony_ci * a "cookie" extension in the new ClientHello.  Clients MUST NOT use
526a8e1175bSopenharmony_ci * cookies in their initial ClientHello in subsequent connections.
527a8e1175bSopenharmony_ci */
528a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
529a8e1175bSopenharmony_cistatic int ssl_tls13_parse_cookie_ext(mbedtls_ssl_context *ssl,
530a8e1175bSopenharmony_ci                                      const unsigned char *buf,
531a8e1175bSopenharmony_ci                                      const unsigned char *end)
532a8e1175bSopenharmony_ci{
533a8e1175bSopenharmony_ci    uint16_t cookie_len;
534a8e1175bSopenharmony_ci    const unsigned char *p = buf;
535a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
536a8e1175bSopenharmony_ci
537a8e1175bSopenharmony_ci    /* Retrieve length field of cookie */
538a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
539a8e1175bSopenharmony_ci    cookie_len = MBEDTLS_GET_UINT16_BE(p, 0);
540a8e1175bSopenharmony_ci    p += 2;
541a8e1175bSopenharmony_ci
542a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, cookie_len);
543a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(3, "cookie extension", p, cookie_len);
544a8e1175bSopenharmony_ci
545a8e1175bSopenharmony_ci    mbedtls_free(handshake->cookie);
546a8e1175bSopenharmony_ci    handshake->cookie_len = 0;
547a8e1175bSopenharmony_ci    handshake->cookie = mbedtls_calloc(1, cookie_len);
548a8e1175bSopenharmony_ci    if (handshake->cookie == NULL) {
549a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1,
550a8e1175bSopenharmony_ci                              ("alloc failed ( %ud bytes )",
551a8e1175bSopenharmony_ci                               cookie_len));
552a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_ALLOC_FAILED;
553a8e1175bSopenharmony_ci    }
554a8e1175bSopenharmony_ci
555a8e1175bSopenharmony_ci    memcpy(handshake->cookie, p, cookie_len);
556a8e1175bSopenharmony_ci    handshake->cookie_len = cookie_len;
557a8e1175bSopenharmony_ci
558a8e1175bSopenharmony_ci    return 0;
559a8e1175bSopenharmony_ci}
560a8e1175bSopenharmony_ci
561a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
562a8e1175bSopenharmony_cistatic int ssl_tls13_write_cookie_ext(mbedtls_ssl_context *ssl,
563a8e1175bSopenharmony_ci                                      unsigned char *buf,
564a8e1175bSopenharmony_ci                                      unsigned char *end,
565a8e1175bSopenharmony_ci                                      size_t *out_len)
566a8e1175bSopenharmony_ci{
567a8e1175bSopenharmony_ci    unsigned char *p = buf;
568a8e1175bSopenharmony_ci    *out_len = 0;
569a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
570a8e1175bSopenharmony_ci
571a8e1175bSopenharmony_ci    if (handshake->cookie == NULL) {
572a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3, ("no cookie to send; skip extension"));
573a8e1175bSopenharmony_ci        return 0;
574a8e1175bSopenharmony_ci    }
575a8e1175bSopenharmony_ci
576a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(3, "client hello, cookie",
577a8e1175bSopenharmony_ci                          handshake->cookie,
578a8e1175bSopenharmony_ci                          handshake->cookie_len);
579a8e1175bSopenharmony_ci
580a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_PTR(p, end, handshake->cookie_len + 6);
581a8e1175bSopenharmony_ci
582a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding cookie extension"));
583a8e1175bSopenharmony_ci
584a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_COOKIE, p, 0);
585a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT16_BE(handshake->cookie_len + 2, p, 2);
586a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT16_BE(handshake->cookie_len, p, 4);
587a8e1175bSopenharmony_ci    p += 6;
588a8e1175bSopenharmony_ci
589a8e1175bSopenharmony_ci    /* Cookie */
590a8e1175bSopenharmony_ci    memcpy(p, handshake->cookie, handshake->cookie_len);
591a8e1175bSopenharmony_ci
592a8e1175bSopenharmony_ci    *out_len = handshake->cookie_len + 6;
593a8e1175bSopenharmony_ci
594a8e1175bSopenharmony_ci    mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_COOKIE);
595a8e1175bSopenharmony_ci
596a8e1175bSopenharmony_ci    return 0;
597a8e1175bSopenharmony_ci}
598a8e1175bSopenharmony_ci
599a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
600a8e1175bSopenharmony_ci/*
601a8e1175bSopenharmony_ci * ssl_tls13_write_psk_key_exchange_modes_ext() structure:
602a8e1175bSopenharmony_ci *
603a8e1175bSopenharmony_ci * enum { psk_ke( 0 ), psk_dhe_ke( 1 ), ( 255 ) } PskKeyExchangeMode;
604a8e1175bSopenharmony_ci *
605a8e1175bSopenharmony_ci * struct {
606a8e1175bSopenharmony_ci *     PskKeyExchangeMode ke_modes<1..255>;
607a8e1175bSopenharmony_ci * } PskKeyExchangeModes;
608a8e1175bSopenharmony_ci */
609a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
610a8e1175bSopenharmony_cistatic int ssl_tls13_write_psk_key_exchange_modes_ext(mbedtls_ssl_context *ssl,
611a8e1175bSopenharmony_ci                                                      unsigned char *buf,
612a8e1175bSopenharmony_ci                                                      unsigned char *end,
613a8e1175bSopenharmony_ci                                                      size_t *out_len)
614a8e1175bSopenharmony_ci{
615a8e1175bSopenharmony_ci    unsigned char *p = buf;
616a8e1175bSopenharmony_ci    int ke_modes_len = 0;
617a8e1175bSopenharmony_ci
618a8e1175bSopenharmony_ci    ((void) ke_modes_len);
619a8e1175bSopenharmony_ci    *out_len = 0;
620a8e1175bSopenharmony_ci
621a8e1175bSopenharmony_ci    /* Skip writing extension if no PSK key exchange mode
622a8e1175bSopenharmony_ci     * is enabled in the config.
623a8e1175bSopenharmony_ci     */
624a8e1175bSopenharmony_ci    if (!mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl)) {
625a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3, ("skip psk_key_exchange_modes extension"));
626a8e1175bSopenharmony_ci        return 0;
627a8e1175bSopenharmony_ci    }
628a8e1175bSopenharmony_ci
629a8e1175bSopenharmony_ci    /* Require 7 bytes of data, otherwise fail,
630a8e1175bSopenharmony_ci     * even if extension might be shorter.
631a8e1175bSopenharmony_ci     */
632a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_PTR(p, end, 7);
633a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(
634a8e1175bSopenharmony_ci        3, ("client hello, adding psk_key_exchange_modes extension"));
635a8e1175bSopenharmony_ci
636a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES, p, 0);
637a8e1175bSopenharmony_ci
638a8e1175bSopenharmony_ci    /* Skip extension length (2 bytes) and
639a8e1175bSopenharmony_ci     * ke_modes length (1 byte) for now.
640a8e1175bSopenharmony_ci     */
641a8e1175bSopenharmony_ci    p += 5;
642a8e1175bSopenharmony_ci
643a8e1175bSopenharmony_ci    if (mbedtls_ssl_conf_tls13_is_psk_ephemeral_enabled(ssl)) {
644a8e1175bSopenharmony_ci        *p++ = MBEDTLS_SSL_TLS1_3_PSK_MODE_ECDHE;
645a8e1175bSopenharmony_ci        ke_modes_len++;
646a8e1175bSopenharmony_ci
647a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(4, ("Adding PSK-ECDHE key exchange mode"));
648a8e1175bSopenharmony_ci    }
649a8e1175bSopenharmony_ci
650a8e1175bSopenharmony_ci    if (mbedtls_ssl_conf_tls13_is_psk_enabled(ssl)) {
651a8e1175bSopenharmony_ci        *p++ = MBEDTLS_SSL_TLS1_3_PSK_MODE_PURE;
652a8e1175bSopenharmony_ci        ke_modes_len++;
653a8e1175bSopenharmony_ci
654a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(4, ("Adding pure PSK key exchange mode"));
655a8e1175bSopenharmony_ci    }
656a8e1175bSopenharmony_ci
657a8e1175bSopenharmony_ci    /* Now write the extension and ke_modes length */
658a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT16_BE(ke_modes_len + 1, buf, 2);
659a8e1175bSopenharmony_ci    buf[4] = ke_modes_len;
660a8e1175bSopenharmony_ci
661a8e1175bSopenharmony_ci    *out_len = p - buf;
662a8e1175bSopenharmony_ci
663a8e1175bSopenharmony_ci    mbedtls_ssl_tls13_set_hs_sent_ext_mask(
664a8e1175bSopenharmony_ci        ssl, MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES);
665a8e1175bSopenharmony_ci
666a8e1175bSopenharmony_ci    return 0;
667a8e1175bSopenharmony_ci}
668a8e1175bSopenharmony_ci
669a8e1175bSopenharmony_cistatic psa_algorithm_t ssl_tls13_get_ciphersuite_hash_alg(int ciphersuite)
670a8e1175bSopenharmony_ci{
671a8e1175bSopenharmony_ci    const mbedtls_ssl_ciphersuite_t *ciphersuite_info = NULL;
672a8e1175bSopenharmony_ci    ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(ciphersuite);
673a8e1175bSopenharmony_ci
674a8e1175bSopenharmony_ci    if (ciphersuite_info != NULL) {
675a8e1175bSopenharmony_ci        return mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac);
676a8e1175bSopenharmony_ci    }
677a8e1175bSopenharmony_ci
678a8e1175bSopenharmony_ci    return PSA_ALG_NONE;
679a8e1175bSopenharmony_ci}
680a8e1175bSopenharmony_ci
681a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS)
682a8e1175bSopenharmony_cistatic int ssl_tls13_has_configured_ticket(mbedtls_ssl_context *ssl)
683a8e1175bSopenharmony_ci{
684a8e1175bSopenharmony_ci    mbedtls_ssl_session *session = ssl->session_negotiate;
685a8e1175bSopenharmony_ci    return ssl->handshake->resume &&
686a8e1175bSopenharmony_ci           session != NULL && session->ticket != NULL &&
687a8e1175bSopenharmony_ci           mbedtls_ssl_conf_tls13_is_kex_mode_enabled(
688a8e1175bSopenharmony_ci        ssl, mbedtls_ssl_tls13_session_get_ticket_flags(
689a8e1175bSopenharmony_ci            session, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL));
690a8e1175bSopenharmony_ci}
691a8e1175bSopenharmony_ci
692a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
693a8e1175bSopenharmony_cistatic int ssl_tls13_early_data_has_valid_ticket(mbedtls_ssl_context *ssl)
694a8e1175bSopenharmony_ci{
695a8e1175bSopenharmony_ci    mbedtls_ssl_session *session = ssl->session_negotiate;
696a8e1175bSopenharmony_ci    return ssl->handshake->resume &&
697a8e1175bSopenharmony_ci           session->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
698a8e1175bSopenharmony_ci           mbedtls_ssl_tls13_session_ticket_allow_early_data(session) &&
699a8e1175bSopenharmony_ci           mbedtls_ssl_tls13_cipher_suite_is_offered(ssl, session->ciphersuite);
700a8e1175bSopenharmony_ci}
701a8e1175bSopenharmony_ci#endif
702a8e1175bSopenharmony_ci
703a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
704a8e1175bSopenharmony_cistatic int ssl_tls13_ticket_get_identity(mbedtls_ssl_context *ssl,
705a8e1175bSopenharmony_ci                                         psa_algorithm_t *hash_alg,
706a8e1175bSopenharmony_ci                                         const unsigned char **identity,
707a8e1175bSopenharmony_ci                                         size_t *identity_len)
708a8e1175bSopenharmony_ci{
709a8e1175bSopenharmony_ci    mbedtls_ssl_session *session = ssl->session_negotiate;
710a8e1175bSopenharmony_ci
711a8e1175bSopenharmony_ci    if (!ssl_tls13_has_configured_ticket(ssl)) {
712a8e1175bSopenharmony_ci        return -1;
713a8e1175bSopenharmony_ci    }
714a8e1175bSopenharmony_ci
715a8e1175bSopenharmony_ci    *hash_alg = ssl_tls13_get_ciphersuite_hash_alg(session->ciphersuite);
716a8e1175bSopenharmony_ci    *identity = session->ticket;
717a8e1175bSopenharmony_ci    *identity_len = session->ticket_len;
718a8e1175bSopenharmony_ci    return 0;
719a8e1175bSopenharmony_ci}
720a8e1175bSopenharmony_ci
721a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
722a8e1175bSopenharmony_cistatic int ssl_tls13_ticket_get_psk(mbedtls_ssl_context *ssl,
723a8e1175bSopenharmony_ci                                    psa_algorithm_t *hash_alg,
724a8e1175bSopenharmony_ci                                    const unsigned char **psk,
725a8e1175bSopenharmony_ci                                    size_t *psk_len)
726a8e1175bSopenharmony_ci{
727a8e1175bSopenharmony_ci
728a8e1175bSopenharmony_ci    mbedtls_ssl_session *session = ssl->session_negotiate;
729a8e1175bSopenharmony_ci
730a8e1175bSopenharmony_ci    if (!ssl_tls13_has_configured_ticket(ssl)) {
731a8e1175bSopenharmony_ci        return -1;
732a8e1175bSopenharmony_ci    }
733a8e1175bSopenharmony_ci
734a8e1175bSopenharmony_ci    *hash_alg = ssl_tls13_get_ciphersuite_hash_alg(session->ciphersuite);
735a8e1175bSopenharmony_ci    *psk = session->resumption_key;
736a8e1175bSopenharmony_ci    *psk_len = session->resumption_key_len;
737a8e1175bSopenharmony_ci
738a8e1175bSopenharmony_ci    return 0;
739a8e1175bSopenharmony_ci}
740a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS */
741a8e1175bSopenharmony_ci
742a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
743a8e1175bSopenharmony_cistatic int ssl_tls13_psk_get_identity(mbedtls_ssl_context *ssl,
744a8e1175bSopenharmony_ci                                      psa_algorithm_t *hash_alg,
745a8e1175bSopenharmony_ci                                      const unsigned char **identity,
746a8e1175bSopenharmony_ci                                      size_t *identity_len)
747a8e1175bSopenharmony_ci{
748a8e1175bSopenharmony_ci
749a8e1175bSopenharmony_ci    if (!mbedtls_ssl_conf_has_static_psk(ssl->conf)) {
750a8e1175bSopenharmony_ci        return -1;
751a8e1175bSopenharmony_ci    }
752a8e1175bSopenharmony_ci
753a8e1175bSopenharmony_ci    *hash_alg = PSA_ALG_SHA_256;
754a8e1175bSopenharmony_ci    *identity = ssl->conf->psk_identity;
755a8e1175bSopenharmony_ci    *identity_len = ssl->conf->psk_identity_len;
756a8e1175bSopenharmony_ci    return 0;
757a8e1175bSopenharmony_ci}
758a8e1175bSopenharmony_ci
759a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
760a8e1175bSopenharmony_cistatic int ssl_tls13_psk_get_psk(mbedtls_ssl_context *ssl,
761a8e1175bSopenharmony_ci                                 psa_algorithm_t *hash_alg,
762a8e1175bSopenharmony_ci                                 const unsigned char **psk,
763a8e1175bSopenharmony_ci                                 size_t *psk_len)
764a8e1175bSopenharmony_ci{
765a8e1175bSopenharmony_ci
766a8e1175bSopenharmony_ci    if (!mbedtls_ssl_conf_has_static_psk(ssl->conf)) {
767a8e1175bSopenharmony_ci        return -1;
768a8e1175bSopenharmony_ci    }
769a8e1175bSopenharmony_ci
770a8e1175bSopenharmony_ci    *hash_alg = PSA_ALG_SHA_256;
771a8e1175bSopenharmony_ci    *psk = ssl->conf->psk;
772a8e1175bSopenharmony_ci    *psk_len = ssl->conf->psk_len;
773a8e1175bSopenharmony_ci    return 0;
774a8e1175bSopenharmony_ci}
775a8e1175bSopenharmony_ci
776a8e1175bSopenharmony_cistatic int ssl_tls13_get_configured_psk_count(mbedtls_ssl_context *ssl)
777a8e1175bSopenharmony_ci{
778a8e1175bSopenharmony_ci    int configured_psk_count = 0;
779a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS)
780a8e1175bSopenharmony_ci    if (ssl_tls13_has_configured_ticket(ssl)) {
781a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3, ("Ticket is configured"));
782a8e1175bSopenharmony_ci        configured_psk_count++;
783a8e1175bSopenharmony_ci    }
784a8e1175bSopenharmony_ci#endif
785a8e1175bSopenharmony_ci    if (mbedtls_ssl_conf_has_static_psk(ssl->conf)) {
786a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3, ("PSK is configured"));
787a8e1175bSopenharmony_ci        configured_psk_count++;
788a8e1175bSopenharmony_ci    }
789a8e1175bSopenharmony_ci    return configured_psk_count;
790a8e1175bSopenharmony_ci}
791a8e1175bSopenharmony_ci
792a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
793a8e1175bSopenharmony_cistatic int ssl_tls13_write_identity(mbedtls_ssl_context *ssl,
794a8e1175bSopenharmony_ci                                    unsigned char *buf,
795a8e1175bSopenharmony_ci                                    unsigned char *end,
796a8e1175bSopenharmony_ci                                    const unsigned char *identity,
797a8e1175bSopenharmony_ci                                    size_t identity_len,
798a8e1175bSopenharmony_ci                                    uint32_t obfuscated_ticket_age,
799a8e1175bSopenharmony_ci                                    size_t *out_len)
800a8e1175bSopenharmony_ci{
801a8e1175bSopenharmony_ci    ((void) ssl);
802a8e1175bSopenharmony_ci    *out_len = 0;
803a8e1175bSopenharmony_ci
804a8e1175bSopenharmony_ci    /*
805a8e1175bSopenharmony_ci     * - identity_len           (2 bytes)
806a8e1175bSopenharmony_ci     * - identity               (psk_identity_len bytes)
807a8e1175bSopenharmony_ci     * - obfuscated_ticket_age  (4 bytes)
808a8e1175bSopenharmony_ci     */
809a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_PTR(buf, end, 6 + identity_len);
810a8e1175bSopenharmony_ci
811a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT16_BE(identity_len, buf, 0);
812a8e1175bSopenharmony_ci    memcpy(buf + 2, identity, identity_len);
813a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT32_BE(obfuscated_ticket_age, buf, 2 + identity_len);
814a8e1175bSopenharmony_ci
815a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(4, "write identity", buf, 6 + identity_len);
816a8e1175bSopenharmony_ci
817a8e1175bSopenharmony_ci    *out_len = 6 + identity_len;
818a8e1175bSopenharmony_ci
819a8e1175bSopenharmony_ci    return 0;
820a8e1175bSopenharmony_ci}
821a8e1175bSopenharmony_ci
822a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
823a8e1175bSopenharmony_cistatic int ssl_tls13_write_binder(mbedtls_ssl_context *ssl,
824a8e1175bSopenharmony_ci                                  unsigned char *buf,
825a8e1175bSopenharmony_ci                                  unsigned char *end,
826a8e1175bSopenharmony_ci                                  int psk_type,
827a8e1175bSopenharmony_ci                                  psa_algorithm_t hash_alg,
828a8e1175bSopenharmony_ci                                  const unsigned char *psk,
829a8e1175bSopenharmony_ci                                  size_t psk_len,
830a8e1175bSopenharmony_ci                                  size_t *out_len)
831a8e1175bSopenharmony_ci{
832a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
833a8e1175bSopenharmony_ci    unsigned char binder_len;
834a8e1175bSopenharmony_ci    unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
835a8e1175bSopenharmony_ci    size_t transcript_len = 0;
836a8e1175bSopenharmony_ci
837a8e1175bSopenharmony_ci    *out_len = 0;
838a8e1175bSopenharmony_ci
839a8e1175bSopenharmony_ci    binder_len = PSA_HASH_LENGTH(hash_alg);
840a8e1175bSopenharmony_ci
841a8e1175bSopenharmony_ci    /*
842a8e1175bSopenharmony_ci     * - binder_len           (1 bytes)
843a8e1175bSopenharmony_ci     * - binder               (binder_len bytes)
844a8e1175bSopenharmony_ci     */
845a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_PTR(buf, end, 1 + binder_len);
846a8e1175bSopenharmony_ci
847a8e1175bSopenharmony_ci    buf[0] = binder_len;
848a8e1175bSopenharmony_ci
849a8e1175bSopenharmony_ci    /* Get current state of handshake transcript. */
850a8e1175bSopenharmony_ci    ret = mbedtls_ssl_get_handshake_transcript(
851a8e1175bSopenharmony_ci        ssl, mbedtls_md_type_from_psa_alg(hash_alg),
852a8e1175bSopenharmony_ci        transcript, sizeof(transcript), &transcript_len);
853a8e1175bSopenharmony_ci    if (ret != 0) {
854a8e1175bSopenharmony_ci        return ret;
855a8e1175bSopenharmony_ci    }
856a8e1175bSopenharmony_ci
857a8e1175bSopenharmony_ci    ret = mbedtls_ssl_tls13_create_psk_binder(ssl, hash_alg,
858a8e1175bSopenharmony_ci                                              psk, psk_len, psk_type,
859a8e1175bSopenharmony_ci                                              transcript, buf + 1);
860a8e1175bSopenharmony_ci    if (ret != 0) {
861a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_create_psk_binder", ret);
862a8e1175bSopenharmony_ci        return ret;
863a8e1175bSopenharmony_ci    }
864a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(4, "write binder", buf, 1 + binder_len);
865a8e1175bSopenharmony_ci
866a8e1175bSopenharmony_ci    *out_len = 1 + binder_len;
867a8e1175bSopenharmony_ci
868a8e1175bSopenharmony_ci    return 0;
869a8e1175bSopenharmony_ci}
870a8e1175bSopenharmony_ci
871a8e1175bSopenharmony_ci/*
872a8e1175bSopenharmony_ci * mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext() structure:
873a8e1175bSopenharmony_ci *
874a8e1175bSopenharmony_ci * struct {
875a8e1175bSopenharmony_ci *   opaque identity<1..2^16-1>;
876a8e1175bSopenharmony_ci *   uint32 obfuscated_ticket_age;
877a8e1175bSopenharmony_ci * } PskIdentity;
878a8e1175bSopenharmony_ci *
879a8e1175bSopenharmony_ci * opaque PskBinderEntry<32..255>;
880a8e1175bSopenharmony_ci *
881a8e1175bSopenharmony_ci * struct {
882a8e1175bSopenharmony_ci *   PskIdentity identities<7..2^16-1>;
883a8e1175bSopenharmony_ci *   PskBinderEntry binders<33..2^16-1>;
884a8e1175bSopenharmony_ci * } OfferedPsks;
885a8e1175bSopenharmony_ci *
886a8e1175bSopenharmony_ci * struct {
887a8e1175bSopenharmony_ci *   select (Handshake.msg_type) {
888a8e1175bSopenharmony_ci *      case client_hello: OfferedPsks;
889a8e1175bSopenharmony_ci *      ...
890a8e1175bSopenharmony_ci *   };
891a8e1175bSopenharmony_ci * } PreSharedKeyExtension;
892a8e1175bSopenharmony_ci *
893a8e1175bSopenharmony_ci */
894a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext(
895a8e1175bSopenharmony_ci    mbedtls_ssl_context *ssl, unsigned char *buf, unsigned char *end,
896a8e1175bSopenharmony_ci    size_t *out_len, size_t *binders_len)
897a8e1175bSopenharmony_ci{
898a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
899a8e1175bSopenharmony_ci    int configured_psk_count = 0;
900a8e1175bSopenharmony_ci    unsigned char *p = buf;
901a8e1175bSopenharmony_ci    psa_algorithm_t hash_alg = PSA_ALG_NONE;
902a8e1175bSopenharmony_ci    const unsigned char *identity;
903a8e1175bSopenharmony_ci    size_t identity_len;
904a8e1175bSopenharmony_ci    size_t l_binders_len = 0;
905a8e1175bSopenharmony_ci    size_t output_len;
906a8e1175bSopenharmony_ci
907a8e1175bSopenharmony_ci    *out_len = 0;
908a8e1175bSopenharmony_ci    *binders_len = 0;
909a8e1175bSopenharmony_ci
910a8e1175bSopenharmony_ci    /* Check if we have any PSKs to offer. If no, skip pre_shared_key */
911a8e1175bSopenharmony_ci    configured_psk_count = ssl_tls13_get_configured_psk_count(ssl);
912a8e1175bSopenharmony_ci    if (configured_psk_count == 0) {
913a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3, ("skip pre_shared_key extensions"));
914a8e1175bSopenharmony_ci        return 0;
915a8e1175bSopenharmony_ci    }
916a8e1175bSopenharmony_ci
917a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(4, ("Pre-configured PSK number = %d",
918a8e1175bSopenharmony_ci                              configured_psk_count));
919a8e1175bSopenharmony_ci
920a8e1175bSopenharmony_ci    /* Check if we have space to write the extension, binders included.
921a8e1175bSopenharmony_ci     * - extension_type         (2 bytes)
922a8e1175bSopenharmony_ci     * - extension_data_len     (2 bytes)
923a8e1175bSopenharmony_ci     * - identities_len         (2 bytes)
924a8e1175bSopenharmony_ci     */
925a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6);
926a8e1175bSopenharmony_ci    p += 6;
927a8e1175bSopenharmony_ci
928a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS)
929a8e1175bSopenharmony_ci    if (ssl_tls13_ticket_get_identity(
930a8e1175bSopenharmony_ci            ssl, &hash_alg, &identity, &identity_len) == 0) {
931a8e1175bSopenharmony_ci#if defined(MBEDTLS_HAVE_TIME)
932a8e1175bSopenharmony_ci        mbedtls_ms_time_t now = mbedtls_ms_time();
933a8e1175bSopenharmony_ci        mbedtls_ssl_session *session = ssl->session_negotiate;
934a8e1175bSopenharmony_ci        /* The ticket age has been checked to be smaller than the
935a8e1175bSopenharmony_ci         * `ticket_lifetime` in ssl_prepare_client_hello() which is smaller than
936a8e1175bSopenharmony_ci         * 7 days (enforced in ssl_tls13_parse_new_session_ticket()) . Thus the
937a8e1175bSopenharmony_ci         * cast to `uint32_t` of the ticket age is safe. */
938a8e1175bSopenharmony_ci        uint32_t obfuscated_ticket_age =
939a8e1175bSopenharmony_ci            (uint32_t) (now - session->ticket_reception_time);
940a8e1175bSopenharmony_ci        obfuscated_ticket_age += session->ticket_age_add;
941a8e1175bSopenharmony_ci
942a8e1175bSopenharmony_ci        ret = ssl_tls13_write_identity(ssl, p, end,
943a8e1175bSopenharmony_ci                                       identity, identity_len,
944a8e1175bSopenharmony_ci                                       obfuscated_ticket_age,
945a8e1175bSopenharmony_ci                                       &output_len);
946a8e1175bSopenharmony_ci#else
947a8e1175bSopenharmony_ci        ret = ssl_tls13_write_identity(ssl, p, end, identity, identity_len,
948a8e1175bSopenharmony_ci                                       0, &output_len);
949a8e1175bSopenharmony_ci#endif /* MBEDTLS_HAVE_TIME */
950a8e1175bSopenharmony_ci        if (ret != 0) {
951a8e1175bSopenharmony_ci            return ret;
952a8e1175bSopenharmony_ci        }
953a8e1175bSopenharmony_ci
954a8e1175bSopenharmony_ci        p += output_len;
955a8e1175bSopenharmony_ci        l_binders_len += 1 + PSA_HASH_LENGTH(hash_alg);
956a8e1175bSopenharmony_ci    }
957a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS */
958a8e1175bSopenharmony_ci
959a8e1175bSopenharmony_ci    if (ssl_tls13_psk_get_identity(
960a8e1175bSopenharmony_ci            ssl, &hash_alg, &identity, &identity_len) == 0) {
961a8e1175bSopenharmony_ci
962a8e1175bSopenharmony_ci        ret = ssl_tls13_write_identity(ssl, p, end, identity, identity_len, 0,
963a8e1175bSopenharmony_ci                                       &output_len);
964a8e1175bSopenharmony_ci        if (ret != 0) {
965a8e1175bSopenharmony_ci            return ret;
966a8e1175bSopenharmony_ci        }
967a8e1175bSopenharmony_ci
968a8e1175bSopenharmony_ci        p += output_len;
969a8e1175bSopenharmony_ci        l_binders_len += 1 + PSA_HASH_LENGTH(hash_alg);
970a8e1175bSopenharmony_ci    }
971a8e1175bSopenharmony_ci
972a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3,
973a8e1175bSopenharmony_ci                          ("client hello, adding pre_shared_key extension, "
974a8e1175bSopenharmony_ci                           "omitting PSK binder list"));
975a8e1175bSopenharmony_ci
976a8e1175bSopenharmony_ci    /* Take into account the two bytes for the length of the binders. */
977a8e1175bSopenharmony_ci    l_binders_len += 2;
978a8e1175bSopenharmony_ci    /* Check if there is enough space for binders */
979a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_PTR(p, end, l_binders_len);
980a8e1175bSopenharmony_ci
981a8e1175bSopenharmony_ci    /*
982a8e1175bSopenharmony_ci     * - extension_type         (2 bytes)
983a8e1175bSopenharmony_ci     * - extension_data_len     (2 bytes)
984a8e1175bSopenharmony_ci     * - identities_len         (2 bytes)
985a8e1175bSopenharmony_ci     */
986a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_PRE_SHARED_KEY, buf, 0);
987a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT16_BE(p - buf - 4 + l_binders_len, buf, 2);
988a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT16_BE(p - buf - 6, buf, 4);
989a8e1175bSopenharmony_ci
990a8e1175bSopenharmony_ci    *out_len = (p - buf) + l_binders_len;
991a8e1175bSopenharmony_ci    *binders_len = l_binders_len;
992a8e1175bSopenharmony_ci
993a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(3, "pre_shared_key identities", buf, p - buf);
994a8e1175bSopenharmony_ci
995a8e1175bSopenharmony_ci    return 0;
996a8e1175bSopenharmony_ci}
997a8e1175bSopenharmony_ci
998a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_write_binders_of_pre_shared_key_ext(
999a8e1175bSopenharmony_ci    mbedtls_ssl_context *ssl, unsigned char *buf, unsigned char *end)
1000a8e1175bSopenharmony_ci{
1001a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1002a8e1175bSopenharmony_ci    unsigned char *p = buf;
1003a8e1175bSopenharmony_ci    psa_algorithm_t hash_alg = PSA_ALG_NONE;
1004a8e1175bSopenharmony_ci    const unsigned char *psk;
1005a8e1175bSopenharmony_ci    size_t psk_len;
1006a8e1175bSopenharmony_ci    size_t output_len;
1007a8e1175bSopenharmony_ci
1008a8e1175bSopenharmony_ci    /* Check if we have space to write binders_len.
1009a8e1175bSopenharmony_ci     * - binders_len         (2 bytes)
1010a8e1175bSopenharmony_ci     */
1011a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2);
1012a8e1175bSopenharmony_ci    p += 2;
1013a8e1175bSopenharmony_ci
1014a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS)
1015a8e1175bSopenharmony_ci    if (ssl_tls13_ticket_get_psk(ssl, &hash_alg, &psk, &psk_len) == 0) {
1016a8e1175bSopenharmony_ci
1017a8e1175bSopenharmony_ci        ret = ssl_tls13_write_binder(ssl, p, end,
1018a8e1175bSopenharmony_ci                                     MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION,
1019a8e1175bSopenharmony_ci                                     hash_alg, psk, psk_len,
1020a8e1175bSopenharmony_ci                                     &output_len);
1021a8e1175bSopenharmony_ci        if (ret != 0) {
1022a8e1175bSopenharmony_ci            return ret;
1023a8e1175bSopenharmony_ci        }
1024a8e1175bSopenharmony_ci        p += output_len;
1025a8e1175bSopenharmony_ci    }
1026a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS */
1027a8e1175bSopenharmony_ci
1028a8e1175bSopenharmony_ci    if (ssl_tls13_psk_get_psk(ssl, &hash_alg, &psk, &psk_len) == 0) {
1029a8e1175bSopenharmony_ci
1030a8e1175bSopenharmony_ci        ret = ssl_tls13_write_binder(ssl, p, end,
1031a8e1175bSopenharmony_ci                                     MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL,
1032a8e1175bSopenharmony_ci                                     hash_alg, psk, psk_len,
1033a8e1175bSopenharmony_ci                                     &output_len);
1034a8e1175bSopenharmony_ci        if (ret != 0) {
1035a8e1175bSopenharmony_ci            return ret;
1036a8e1175bSopenharmony_ci        }
1037a8e1175bSopenharmony_ci        p += output_len;
1038a8e1175bSopenharmony_ci    }
1039a8e1175bSopenharmony_ci
1040a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding PSK binder list."));
1041a8e1175bSopenharmony_ci
1042a8e1175bSopenharmony_ci    /*
1043a8e1175bSopenharmony_ci     * - binders_len         (2 bytes)
1044a8e1175bSopenharmony_ci     */
1045a8e1175bSopenharmony_ci    MBEDTLS_PUT_UINT16_BE(p - buf - 2, buf, 0);
1046a8e1175bSopenharmony_ci
1047a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(3, "pre_shared_key binders", buf, p - buf);
1048a8e1175bSopenharmony_ci
1049a8e1175bSopenharmony_ci    mbedtls_ssl_tls13_set_hs_sent_ext_mask(
1050a8e1175bSopenharmony_ci        ssl, MBEDTLS_TLS_EXT_PRE_SHARED_KEY);
1051a8e1175bSopenharmony_ci
1052a8e1175bSopenharmony_ci    return 0;
1053a8e1175bSopenharmony_ci}
1054a8e1175bSopenharmony_ci
1055a8e1175bSopenharmony_ci/*
1056a8e1175bSopenharmony_ci * struct {
1057a8e1175bSopenharmony_ci *   opaque identity<1..2^16-1>;
1058a8e1175bSopenharmony_ci *   uint32 obfuscated_ticket_age;
1059a8e1175bSopenharmony_ci * } PskIdentity;
1060a8e1175bSopenharmony_ci *
1061a8e1175bSopenharmony_ci * opaque PskBinderEntry<32..255>;
1062a8e1175bSopenharmony_ci *
1063a8e1175bSopenharmony_ci * struct {
1064a8e1175bSopenharmony_ci *
1065a8e1175bSopenharmony_ci *   select (Handshake.msg_type) {
1066a8e1175bSopenharmony_ci *         ...
1067a8e1175bSopenharmony_ci *         case server_hello: uint16 selected_identity;
1068a8e1175bSopenharmony_ci *   };
1069a8e1175bSopenharmony_ci *
1070a8e1175bSopenharmony_ci * } PreSharedKeyExtension;
1071a8e1175bSopenharmony_ci *
1072a8e1175bSopenharmony_ci */
1073a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
1074a8e1175bSopenharmony_cistatic int ssl_tls13_parse_server_pre_shared_key_ext(mbedtls_ssl_context *ssl,
1075a8e1175bSopenharmony_ci                                                     const unsigned char *buf,
1076a8e1175bSopenharmony_ci                                                     const unsigned char *end)
1077a8e1175bSopenharmony_ci{
1078a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1079a8e1175bSopenharmony_ci    int selected_identity;
1080a8e1175bSopenharmony_ci    const unsigned char *psk;
1081a8e1175bSopenharmony_ci    size_t psk_len;
1082a8e1175bSopenharmony_ci    psa_algorithm_t hash_alg;
1083a8e1175bSopenharmony_ci
1084a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(buf, end, 2);
1085a8e1175bSopenharmony_ci    selected_identity = MBEDTLS_GET_UINT16_BE(buf, 0);
1086a8e1175bSopenharmony_ci    ssl->handshake->selected_identity = (uint16_t) selected_identity;
1087a8e1175bSopenharmony_ci
1088a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("selected_identity = %d", selected_identity));
1089a8e1175bSopenharmony_ci
1090a8e1175bSopenharmony_ci    if (selected_identity >= ssl_tls13_get_configured_psk_count(ssl)) {
1091a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid PSK identity."));
1092a8e1175bSopenharmony_ci
1093a8e1175bSopenharmony_ci        MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
1094a8e1175bSopenharmony_ci                                     MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
1095a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
1096a8e1175bSopenharmony_ci    }
1097a8e1175bSopenharmony_ci
1098a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS)
1099a8e1175bSopenharmony_ci    if (selected_identity == 0 && ssl_tls13_has_configured_ticket(ssl)) {
1100a8e1175bSopenharmony_ci        ret = ssl_tls13_ticket_get_psk(ssl, &hash_alg, &psk, &psk_len);
1101a8e1175bSopenharmony_ci    } else
1102a8e1175bSopenharmony_ci#endif
1103a8e1175bSopenharmony_ci    if (mbedtls_ssl_conf_has_static_psk(ssl->conf)) {
1104a8e1175bSopenharmony_ci        ret = ssl_tls13_psk_get_psk(ssl, &hash_alg, &psk, &psk_len);
1105a8e1175bSopenharmony_ci    } else {
1106a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
1107a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1108a8e1175bSopenharmony_ci    }
1109a8e1175bSopenharmony_ci    if (ret != 0) {
1110a8e1175bSopenharmony_ci        return ret;
1111a8e1175bSopenharmony_ci    }
1112a8e1175bSopenharmony_ci
1113a8e1175bSopenharmony_ci    if (mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ssl->handshake->ciphersuite_info->mac)
1114a8e1175bSopenharmony_ci        != hash_alg) {
1115a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(
1116a8e1175bSopenharmony_ci            1, ("Invalid ciphersuite for external psk."));
1117a8e1175bSopenharmony_ci
1118a8e1175bSopenharmony_ci        MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
1119a8e1175bSopenharmony_ci                                     MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
1120a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
1121a8e1175bSopenharmony_ci    }
1122a8e1175bSopenharmony_ci
1123a8e1175bSopenharmony_ci    ret = mbedtls_ssl_set_hs_psk(ssl, psk, psk_len);
1124a8e1175bSopenharmony_ci    if (ret != 0) {
1125a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_set_hs_psk", ret);
1126a8e1175bSopenharmony_ci        return ret;
1127a8e1175bSopenharmony_ci    }
1128a8e1175bSopenharmony_ci
1129a8e1175bSopenharmony_ci    return 0;
1130a8e1175bSopenharmony_ci}
1131a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
1132a8e1175bSopenharmony_ci
1133a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl,
1134a8e1175bSopenharmony_ci                                              unsigned char *buf,
1135a8e1175bSopenharmony_ci                                              unsigned char *end,
1136a8e1175bSopenharmony_ci                                              size_t *out_len)
1137a8e1175bSopenharmony_ci{
1138a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1139a8e1175bSopenharmony_ci    unsigned char *p = buf;
1140a8e1175bSopenharmony_ci    size_t ext_len;
1141a8e1175bSopenharmony_ci
1142a8e1175bSopenharmony_ci    *out_len = 0;
1143a8e1175bSopenharmony_ci
1144a8e1175bSopenharmony_ci    /* Write supported_versions extension
1145a8e1175bSopenharmony_ci     *
1146a8e1175bSopenharmony_ci     * Supported Versions Extension is mandatory with TLS 1.3.
1147a8e1175bSopenharmony_ci     */
1148a8e1175bSopenharmony_ci    ret = ssl_tls13_write_supported_versions_ext(ssl, p, end, &ext_len);
1149a8e1175bSopenharmony_ci    if (ret != 0) {
1150a8e1175bSopenharmony_ci        return ret;
1151a8e1175bSopenharmony_ci    }
1152a8e1175bSopenharmony_ci    p += ext_len;
1153a8e1175bSopenharmony_ci
1154a8e1175bSopenharmony_ci    /* Echo the cookie if the server provided one in its preceding
1155a8e1175bSopenharmony_ci     * HelloRetryRequest message.
1156a8e1175bSopenharmony_ci     */
1157a8e1175bSopenharmony_ci    ret = ssl_tls13_write_cookie_ext(ssl, p, end, &ext_len);
1158a8e1175bSopenharmony_ci    if (ret != 0) {
1159a8e1175bSopenharmony_ci        return ret;
1160a8e1175bSopenharmony_ci    }
1161a8e1175bSopenharmony_ci    p += ext_len;
1162a8e1175bSopenharmony_ci
1163a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
1164a8e1175bSopenharmony_ci    ret = mbedtls_ssl_tls13_write_record_size_limit_ext(
1165a8e1175bSopenharmony_ci        ssl, p, end, &ext_len);
1166a8e1175bSopenharmony_ci    if (ret != 0) {
1167a8e1175bSopenharmony_ci        return ret;
1168a8e1175bSopenharmony_ci    }
1169a8e1175bSopenharmony_ci    p += ext_len;
1170a8e1175bSopenharmony_ci#endif
1171a8e1175bSopenharmony_ci
1172a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
1173a8e1175bSopenharmony_ci    if (mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(ssl)) {
1174a8e1175bSopenharmony_ci        ret = ssl_tls13_write_key_share_ext(ssl, p, end, &ext_len);
1175a8e1175bSopenharmony_ci        if (ret != 0) {
1176a8e1175bSopenharmony_ci            return ret;
1177a8e1175bSopenharmony_ci        }
1178a8e1175bSopenharmony_ci        p += ext_len;
1179a8e1175bSopenharmony_ci    }
1180a8e1175bSopenharmony_ci#endif
1181a8e1175bSopenharmony_ci
1182a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
1183a8e1175bSopenharmony_ci    /* In the first ClientHello, write the early data indication extension if
1184a8e1175bSopenharmony_ci     * necessary and update the early data state.
1185a8e1175bSopenharmony_ci     * If an HRR has been received and thus we are currently writing the
1186a8e1175bSopenharmony_ci     * second ClientHello, the second ClientHello must not contain an early
1187a8e1175bSopenharmony_ci     * data extension and the early data state must stay as it is:
1188a8e1175bSopenharmony_ci     * MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT or
1189a8e1175bSopenharmony_ci     * MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED.
1190a8e1175bSopenharmony_ci     */
1191a8e1175bSopenharmony_ci    if (!ssl->handshake->hello_retry_request_flag) {
1192a8e1175bSopenharmony_ci        if (mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl) &&
1193a8e1175bSopenharmony_ci            ssl_tls13_early_data_has_valid_ticket(ssl) &&
1194a8e1175bSopenharmony_ci            ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED) {
1195a8e1175bSopenharmony_ci            ret = mbedtls_ssl_tls13_write_early_data_ext(
1196a8e1175bSopenharmony_ci                ssl, 0, p, end, &ext_len);
1197a8e1175bSopenharmony_ci            if (ret != 0) {
1198a8e1175bSopenharmony_ci                return ret;
1199a8e1175bSopenharmony_ci            }
1200a8e1175bSopenharmony_ci            p += ext_len;
1201a8e1175bSopenharmony_ci
1202a8e1175bSopenharmony_ci            ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT;
1203a8e1175bSopenharmony_ci        } else {
1204a8e1175bSopenharmony_ci            ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT;
1205a8e1175bSopenharmony_ci        }
1206a8e1175bSopenharmony_ci    }
1207a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EARLY_DATA */
1208a8e1175bSopenharmony_ci
1209a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
1210a8e1175bSopenharmony_ci    /* For PSK-based key exchange we need the pre_shared_key extension
1211a8e1175bSopenharmony_ci     * and the psk_key_exchange_modes extension.
1212a8e1175bSopenharmony_ci     *
1213a8e1175bSopenharmony_ci     * The pre_shared_key extension MUST be the last extension in the
1214a8e1175bSopenharmony_ci     * ClientHello. Servers MUST check that it is the last extension and
1215a8e1175bSopenharmony_ci     * otherwise fail the handshake with an "illegal_parameter" alert.
1216a8e1175bSopenharmony_ci     *
1217a8e1175bSopenharmony_ci     * Add the psk_key_exchange_modes extension.
1218a8e1175bSopenharmony_ci     */
1219a8e1175bSopenharmony_ci    ret = ssl_tls13_write_psk_key_exchange_modes_ext(ssl, p, end, &ext_len);
1220a8e1175bSopenharmony_ci    if (ret != 0) {
1221a8e1175bSopenharmony_ci        return ret;
1222a8e1175bSopenharmony_ci    }
1223a8e1175bSopenharmony_ci    p += ext_len;
1224a8e1175bSopenharmony_ci#endif
1225a8e1175bSopenharmony_ci
1226a8e1175bSopenharmony_ci    *out_len = p - buf;
1227a8e1175bSopenharmony_ci
1228a8e1175bSopenharmony_ci    return 0;
1229a8e1175bSopenharmony_ci}
1230a8e1175bSopenharmony_ci
1231a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl)
1232a8e1175bSopenharmony_ci{
1233a8e1175bSopenharmony_ci    ((void) ssl);
1234a8e1175bSopenharmony_ci
1235a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
1236a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1237a8e1175bSopenharmony_ci    psa_algorithm_t hash_alg = PSA_ALG_NONE;
1238a8e1175bSopenharmony_ci    const unsigned char *psk;
1239a8e1175bSopenharmony_ci    size_t psk_len;
1240a8e1175bSopenharmony_ci    const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
1241a8e1175bSopenharmony_ci
1242a8e1175bSopenharmony_ci    if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT) {
1243a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(
1244a8e1175bSopenharmony_ci            1, ("Set hs psk for early data when writing the first psk"));
1245a8e1175bSopenharmony_ci
1246a8e1175bSopenharmony_ci        ret = ssl_tls13_ticket_get_psk(ssl, &hash_alg, &psk, &psk_len);
1247a8e1175bSopenharmony_ci        if (ret != 0) {
1248a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(
1249a8e1175bSopenharmony_ci                1, "ssl_tls13_ticket_get_psk", ret);
1250a8e1175bSopenharmony_ci            return ret;
1251a8e1175bSopenharmony_ci        }
1252a8e1175bSopenharmony_ci
1253a8e1175bSopenharmony_ci        ret = mbedtls_ssl_set_hs_psk(ssl, psk, psk_len);
1254a8e1175bSopenharmony_ci        if (ret  != 0) {
1255a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_set_hs_psk", ret);
1256a8e1175bSopenharmony_ci            return ret;
1257a8e1175bSopenharmony_ci        }
1258a8e1175bSopenharmony_ci
1259a8e1175bSopenharmony_ci        /*
1260a8e1175bSopenharmony_ci         * Early data are going to be encrypted using the ciphersuite
1261a8e1175bSopenharmony_ci         * associated with the pre-shared key used for the handshake.
1262a8e1175bSopenharmony_ci         * Note that if the server rejects early data, the handshake
1263a8e1175bSopenharmony_ci         * based on the pre-shared key may complete successfully
1264a8e1175bSopenharmony_ci         * with a selected ciphersuite different from the ciphersuite
1265a8e1175bSopenharmony_ci         * associated with the pre-shared key. Only the hashes of the
1266a8e1175bSopenharmony_ci         * two ciphersuites have to be the same. In that case, the
1267a8e1175bSopenharmony_ci         * encrypted handshake data and application data are
1268a8e1175bSopenharmony_ci         * encrypted using a different ciphersuite than the one used for
1269a8e1175bSopenharmony_ci         * the rejected early data.
1270a8e1175bSopenharmony_ci         */
1271a8e1175bSopenharmony_ci        ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(
1272a8e1175bSopenharmony_ci            ssl->session_negotiate->ciphersuite);
1273a8e1175bSopenharmony_ci        ssl->handshake->ciphersuite_info = ciphersuite_info;
1274a8e1175bSopenharmony_ci
1275a8e1175bSopenharmony_ci        /* Enable psk and psk_ephemeral to make stage early happy */
1276a8e1175bSopenharmony_ci        ssl->handshake->key_exchange_mode =
1277a8e1175bSopenharmony_ci            MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL;
1278a8e1175bSopenharmony_ci
1279a8e1175bSopenharmony_ci        /* Start the TLS 1.3 key schedule:
1280a8e1175bSopenharmony_ci         *     Set the PSK and derive early secret.
1281a8e1175bSopenharmony_ci         */
1282a8e1175bSopenharmony_ci        ret = mbedtls_ssl_tls13_key_schedule_stage_early(ssl);
1283a8e1175bSopenharmony_ci        if (ret != 0) {
1284a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(
1285a8e1175bSopenharmony_ci                1, "mbedtls_ssl_tls13_key_schedule_stage_early", ret);
1286a8e1175bSopenharmony_ci            return ret;
1287a8e1175bSopenharmony_ci        }
1288a8e1175bSopenharmony_ci
1289a8e1175bSopenharmony_ci        /* Derive early data key material */
1290a8e1175bSopenharmony_ci        ret = mbedtls_ssl_tls13_compute_early_transform(ssl);
1291a8e1175bSopenharmony_ci        if (ret != 0) {
1292a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(
1293a8e1175bSopenharmony_ci                1, "mbedtls_ssl_tls13_compute_early_transform", ret);
1294a8e1175bSopenharmony_ci            return ret;
1295a8e1175bSopenharmony_ci        }
1296a8e1175bSopenharmony_ci
1297a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
1298a8e1175bSopenharmony_ci        mbedtls_ssl_handshake_set_state(
1299a8e1175bSopenharmony_ci            ssl, MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO);
1300a8e1175bSopenharmony_ci#else
1301a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(
1302a8e1175bSopenharmony_ci            1, ("Switch to early data keys for outbound traffic"));
1303a8e1175bSopenharmony_ci        mbedtls_ssl_set_outbound_transform(
1304a8e1175bSopenharmony_ci            ssl, ssl->handshake->transform_earlydata);
1305a8e1175bSopenharmony_ci        ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE;
1306a8e1175bSopenharmony_ci#endif
1307a8e1175bSopenharmony_ci    }
1308a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EARLY_DATA */
1309a8e1175bSopenharmony_ci    return 0;
1310a8e1175bSopenharmony_ci}
1311a8e1175bSopenharmony_ci/*
1312a8e1175bSopenharmony_ci * Functions for parsing and processing Server Hello
1313a8e1175bSopenharmony_ci */
1314a8e1175bSopenharmony_ci
1315a8e1175bSopenharmony_ci/**
1316a8e1175bSopenharmony_ci * \brief Detect if the ServerHello contains a supported_versions extension
1317a8e1175bSopenharmony_ci *        or not.
1318a8e1175bSopenharmony_ci *
1319a8e1175bSopenharmony_ci * \param[in] ssl  SSL context
1320a8e1175bSopenharmony_ci * \param[in] buf  Buffer containing the ServerHello message
1321a8e1175bSopenharmony_ci * \param[in] end  End of the buffer containing the ServerHello message
1322a8e1175bSopenharmony_ci *
1323a8e1175bSopenharmony_ci * \return 0 if the ServerHello does not contain a supported_versions extension
1324a8e1175bSopenharmony_ci * \return 1 if the ServerHello contains a supported_versions extension
1325a8e1175bSopenharmony_ci * \return A negative value if an error occurred while parsing the ServerHello.
1326a8e1175bSopenharmony_ci */
1327a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
1328a8e1175bSopenharmony_cistatic int ssl_tls13_is_supported_versions_ext_present(
1329a8e1175bSopenharmony_ci    mbedtls_ssl_context *ssl,
1330a8e1175bSopenharmony_ci    const unsigned char *buf,
1331a8e1175bSopenharmony_ci    const unsigned char *end)
1332a8e1175bSopenharmony_ci{
1333a8e1175bSopenharmony_ci    const unsigned char *p = buf;
1334a8e1175bSopenharmony_ci    size_t legacy_session_id_echo_len;
1335a8e1175bSopenharmony_ci    const unsigned char *supported_versions_data;
1336a8e1175bSopenharmony_ci    const unsigned char *supported_versions_data_end;
1337a8e1175bSopenharmony_ci
1338a8e1175bSopenharmony_ci    /*
1339a8e1175bSopenharmony_ci     * Check there is enough data to access the legacy_session_id_echo vector
1340a8e1175bSopenharmony_ci     * length:
1341a8e1175bSopenharmony_ci     * - legacy_version                 2 bytes
1342a8e1175bSopenharmony_ci     * - random                         MBEDTLS_SERVER_HELLO_RANDOM_LEN bytes
1343a8e1175bSopenharmony_ci     * - legacy_session_id_echo length  1 byte
1344a8e1175bSopenharmony_ci     */
1345a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, MBEDTLS_SERVER_HELLO_RANDOM_LEN + 3);
1346a8e1175bSopenharmony_ci    p += MBEDTLS_SERVER_HELLO_RANDOM_LEN + 2;
1347a8e1175bSopenharmony_ci    legacy_session_id_echo_len = *p;
1348a8e1175bSopenharmony_ci
1349a8e1175bSopenharmony_ci    /*
1350a8e1175bSopenharmony_ci     * Jump to the extensions, jumping over:
1351a8e1175bSopenharmony_ci     * - legacy_session_id_echo     (legacy_session_id_echo_len + 1) bytes
1352a8e1175bSopenharmony_ci     * - cipher_suite               2 bytes
1353a8e1175bSopenharmony_ci     * - legacy_compression_method  1 byte
1354a8e1175bSopenharmony_ci     */
1355a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, legacy_session_id_echo_len + 4);
1356a8e1175bSopenharmony_ci    p += legacy_session_id_echo_len + 4;
1357a8e1175bSopenharmony_ci
1358a8e1175bSopenharmony_ci    return mbedtls_ssl_tls13_is_supported_versions_ext_present_in_exts(
1359a8e1175bSopenharmony_ci        ssl, p, end,
1360a8e1175bSopenharmony_ci        &supported_versions_data, &supported_versions_data_end);
1361a8e1175bSopenharmony_ci}
1362a8e1175bSopenharmony_ci
1363a8e1175bSopenharmony_ci/* Returns a negative value on failure, and otherwise
1364a8e1175bSopenharmony_ci * - 1 if the last eight bytes of the ServerHello random bytes indicate that
1365a8e1175bSopenharmony_ci *     the server is TLS 1.3 capable but negotiating TLS 1.2 or below.
1366a8e1175bSopenharmony_ci * - 0 otherwise
1367a8e1175bSopenharmony_ci */
1368a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
1369a8e1175bSopenharmony_cistatic int ssl_tls13_is_downgrade_negotiation(mbedtls_ssl_context *ssl,
1370a8e1175bSopenharmony_ci                                              const unsigned char *buf,
1371a8e1175bSopenharmony_ci                                              const unsigned char *end)
1372a8e1175bSopenharmony_ci{
1373a8e1175bSopenharmony_ci    /* First seven bytes of the magic downgrade strings, see RFC 8446 4.1.3 */
1374a8e1175bSopenharmony_ci    static const unsigned char magic_downgrade_string[] =
1375a8e1175bSopenharmony_ci    { 0x44, 0x4F, 0x57, 0x4E, 0x47, 0x52, 0x44 };
1376a8e1175bSopenharmony_ci    const unsigned char *last_eight_bytes_of_random;
1377a8e1175bSopenharmony_ci    unsigned char last_byte_of_random;
1378a8e1175bSopenharmony_ci
1379a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(buf, end, MBEDTLS_SERVER_HELLO_RANDOM_LEN + 2);
1380a8e1175bSopenharmony_ci    last_eight_bytes_of_random = buf + 2 + MBEDTLS_SERVER_HELLO_RANDOM_LEN - 8;
1381a8e1175bSopenharmony_ci
1382a8e1175bSopenharmony_ci    if (memcmp(last_eight_bytes_of_random,
1383a8e1175bSopenharmony_ci               magic_downgrade_string,
1384a8e1175bSopenharmony_ci               sizeof(magic_downgrade_string)) == 0) {
1385a8e1175bSopenharmony_ci        last_byte_of_random = last_eight_bytes_of_random[7];
1386a8e1175bSopenharmony_ci        return last_byte_of_random == 0 ||
1387a8e1175bSopenharmony_ci               last_byte_of_random == 1;
1388a8e1175bSopenharmony_ci    }
1389a8e1175bSopenharmony_ci
1390a8e1175bSopenharmony_ci    return 0;
1391a8e1175bSopenharmony_ci}
1392a8e1175bSopenharmony_ci
1393a8e1175bSopenharmony_ci/* Returns a negative value on failure, and otherwise
1394a8e1175bSopenharmony_ci * - SSL_SERVER_HELLO or
1395a8e1175bSopenharmony_ci * - SSL_SERVER_HELLO_HRR
1396a8e1175bSopenharmony_ci * to indicate which message is expected and to be parsed next.
1397a8e1175bSopenharmony_ci */
1398a8e1175bSopenharmony_ci#define SSL_SERVER_HELLO 0
1399a8e1175bSopenharmony_ci#define SSL_SERVER_HELLO_HRR 1
1400a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
1401a8e1175bSopenharmony_cistatic int ssl_server_hello_is_hrr(mbedtls_ssl_context *ssl,
1402a8e1175bSopenharmony_ci                                   const unsigned char *buf,
1403a8e1175bSopenharmony_ci                                   const unsigned char *end)
1404a8e1175bSopenharmony_ci{
1405a8e1175bSopenharmony_ci
1406a8e1175bSopenharmony_ci    /* Check whether this message is a HelloRetryRequest ( HRR ) message.
1407a8e1175bSopenharmony_ci     *
1408a8e1175bSopenharmony_ci     * Server Hello and HRR are only distinguished by Random set to the
1409a8e1175bSopenharmony_ci     * special value of the SHA-256 of "HelloRetryRequest".
1410a8e1175bSopenharmony_ci     *
1411a8e1175bSopenharmony_ci     * struct {
1412a8e1175bSopenharmony_ci     *    ProtocolVersion legacy_version = 0x0303;
1413a8e1175bSopenharmony_ci     *    Random random;
1414a8e1175bSopenharmony_ci     *    opaque legacy_session_id_echo<0..32>;
1415a8e1175bSopenharmony_ci     *    CipherSuite cipher_suite;
1416a8e1175bSopenharmony_ci     *    uint8 legacy_compression_method = 0;
1417a8e1175bSopenharmony_ci     *    Extension extensions<6..2^16-1>;
1418a8e1175bSopenharmony_ci     * } ServerHello;
1419a8e1175bSopenharmony_ci     *
1420a8e1175bSopenharmony_ci     */
1421a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(
1422a8e1175bSopenharmony_ci        buf, end, 2 + sizeof(mbedtls_ssl_tls13_hello_retry_request_magic));
1423a8e1175bSopenharmony_ci
1424a8e1175bSopenharmony_ci    if (memcmp(buf + 2, mbedtls_ssl_tls13_hello_retry_request_magic,
1425a8e1175bSopenharmony_ci               sizeof(mbedtls_ssl_tls13_hello_retry_request_magic)) == 0) {
1426a8e1175bSopenharmony_ci        return SSL_SERVER_HELLO_HRR;
1427a8e1175bSopenharmony_ci    }
1428a8e1175bSopenharmony_ci
1429a8e1175bSopenharmony_ci    return SSL_SERVER_HELLO;
1430a8e1175bSopenharmony_ci}
1431a8e1175bSopenharmony_ci
1432a8e1175bSopenharmony_ci/*
1433a8e1175bSopenharmony_ci * Returns a negative value on failure, and otherwise
1434a8e1175bSopenharmony_ci * - SSL_SERVER_HELLO or
1435a8e1175bSopenharmony_ci * - SSL_SERVER_HELLO_HRR or
1436a8e1175bSopenharmony_ci * - SSL_SERVER_HELLO_TLS1_2
1437a8e1175bSopenharmony_ci */
1438a8e1175bSopenharmony_ci#define SSL_SERVER_HELLO_TLS1_2 2
1439a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
1440a8e1175bSopenharmony_cistatic int ssl_tls13_preprocess_server_hello(mbedtls_ssl_context *ssl,
1441a8e1175bSopenharmony_ci                                             const unsigned char *buf,
1442a8e1175bSopenharmony_ci                                             const unsigned char *end)
1443a8e1175bSopenharmony_ci{
1444a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1445a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
1446a8e1175bSopenharmony_ci
1447a8e1175bSopenharmony_ci    MBEDTLS_SSL_PROC_CHK_NEG(ssl_tls13_is_supported_versions_ext_present(
1448a8e1175bSopenharmony_ci                                 ssl, buf, end));
1449a8e1175bSopenharmony_ci
1450a8e1175bSopenharmony_ci    if (ret == 0) {
1451a8e1175bSopenharmony_ci        MBEDTLS_SSL_PROC_CHK_NEG(
1452a8e1175bSopenharmony_ci            ssl_tls13_is_downgrade_negotiation(ssl, buf, end));
1453a8e1175bSopenharmony_ci
1454a8e1175bSopenharmony_ci        /* If the server is negotiating TLS 1.2 or below and:
1455a8e1175bSopenharmony_ci         * . we did not propose TLS 1.2 or
1456a8e1175bSopenharmony_ci         * . the server responded it is TLS 1.3 capable but negotiating a lower
1457a8e1175bSopenharmony_ci         *   version of the protocol and thus we are under downgrade attack
1458a8e1175bSopenharmony_ci         * abort the handshake with an "illegal parameter" alert.
1459a8e1175bSopenharmony_ci         */
1460a8e1175bSopenharmony_ci        if (handshake->min_tls_version > MBEDTLS_SSL_VERSION_TLS1_2 || ret) {
1461a8e1175bSopenharmony_ci            MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
1462a8e1175bSopenharmony_ci                                         MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
1463a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
1464a8e1175bSopenharmony_ci        }
1465a8e1175bSopenharmony_ci
1466a8e1175bSopenharmony_ci        /*
1467a8e1175bSopenharmony_ci         * Version 1.2 of the protocol has been negotiated, set the
1468a8e1175bSopenharmony_ci         * ssl->keep_current_message flag for the ServerHello to be kept and
1469a8e1175bSopenharmony_ci         * parsed as a TLS 1.2 ServerHello. We also change ssl->tls_version to
1470a8e1175bSopenharmony_ci         * MBEDTLS_SSL_VERSION_TLS1_2 thus from now on mbedtls_ssl_handshake_step()
1471a8e1175bSopenharmony_ci         * will dispatch to the TLS 1.2 state machine.
1472a8e1175bSopenharmony_ci         */
1473a8e1175bSopenharmony_ci        ssl->keep_current_message = 1;
1474a8e1175bSopenharmony_ci        ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_2;
1475a8e1175bSopenharmony_ci        MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
1476a8e1175bSopenharmony_ci                                 ssl, MBEDTLS_SSL_HS_SERVER_HELLO,
1477a8e1175bSopenharmony_ci                                 buf, (size_t) (end - buf)));
1478a8e1175bSopenharmony_ci
1479a8e1175bSopenharmony_ci        if (mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(ssl)) {
1480a8e1175bSopenharmony_ci            ret = ssl_tls13_reset_key_share(ssl);
1481a8e1175bSopenharmony_ci            if (ret != 0) {
1482a8e1175bSopenharmony_ci                return ret;
1483a8e1175bSopenharmony_ci            }
1484a8e1175bSopenharmony_ci        }
1485a8e1175bSopenharmony_ci
1486a8e1175bSopenharmony_ci        return SSL_SERVER_HELLO_TLS1_2;
1487a8e1175bSopenharmony_ci    }
1488a8e1175bSopenharmony_ci
1489a8e1175bSopenharmony_ci    ssl->session_negotiate->tls_version = ssl->tls_version;
1490a8e1175bSopenharmony_ci    ssl->session_negotiate->endpoint = ssl->conf->endpoint;
1491a8e1175bSopenharmony_ci
1492a8e1175bSopenharmony_ci    handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
1493a8e1175bSopenharmony_ci
1494a8e1175bSopenharmony_ci    ret = ssl_server_hello_is_hrr(ssl, buf, end);
1495a8e1175bSopenharmony_ci    switch (ret) {
1496a8e1175bSopenharmony_ci        case SSL_SERVER_HELLO:
1497a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(2, ("received ServerHello message"));
1498a8e1175bSopenharmony_ci            break;
1499a8e1175bSopenharmony_ci        case SSL_SERVER_HELLO_HRR:
1500a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(2, ("received HelloRetryRequest message"));
1501a8e1175bSopenharmony_ci            /* If a client receives a second HelloRetryRequest in the same
1502a8e1175bSopenharmony_ci             * connection (i.e., where the ClientHello was itself in response
1503a8e1175bSopenharmony_ci             * to a HelloRetryRequest), it MUST abort the handshake with an
1504a8e1175bSopenharmony_ci             * "unexpected_message" alert.
1505a8e1175bSopenharmony_ci             */
1506a8e1175bSopenharmony_ci            if (handshake->hello_retry_request_flag) {
1507a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1, ("Multiple HRRs received"));
1508a8e1175bSopenharmony_ci                MBEDTLS_SSL_PEND_FATAL_ALERT(
1509a8e1175bSopenharmony_ci                    MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
1510a8e1175bSopenharmony_ci                    MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
1511a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
1512a8e1175bSopenharmony_ci            }
1513a8e1175bSopenharmony_ci            /*
1514a8e1175bSopenharmony_ci             * Clients must abort the handshake with an "illegal_parameter"
1515a8e1175bSopenharmony_ci             * alert if the HelloRetryRequest would not result in any change
1516a8e1175bSopenharmony_ci             * in the ClientHello.
1517a8e1175bSopenharmony_ci             * In a PSK only key exchange that what we expect.
1518a8e1175bSopenharmony_ci             */
1519a8e1175bSopenharmony_ci            if (!mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(ssl)) {
1520a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(1,
1521a8e1175bSopenharmony_ci                                      ("Unexpected HRR in pure PSK key exchange."));
1522a8e1175bSopenharmony_ci                MBEDTLS_SSL_PEND_FATAL_ALERT(
1523a8e1175bSopenharmony_ci                    MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
1524a8e1175bSopenharmony_ci                    MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
1525a8e1175bSopenharmony_ci                return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
1526a8e1175bSopenharmony_ci            }
1527a8e1175bSopenharmony_ci
1528a8e1175bSopenharmony_ci            handshake->hello_retry_request_flag = 1;
1529a8e1175bSopenharmony_ci
1530a8e1175bSopenharmony_ci            break;
1531a8e1175bSopenharmony_ci    }
1532a8e1175bSopenharmony_ci
1533a8e1175bSopenharmony_cicleanup:
1534a8e1175bSopenharmony_ci
1535a8e1175bSopenharmony_ci    return ret;
1536a8e1175bSopenharmony_ci}
1537a8e1175bSopenharmony_ci
1538a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
1539a8e1175bSopenharmony_cistatic int ssl_tls13_check_server_hello_session_id_echo(mbedtls_ssl_context *ssl,
1540a8e1175bSopenharmony_ci                                                        const unsigned char **buf,
1541a8e1175bSopenharmony_ci                                                        const unsigned char *end)
1542a8e1175bSopenharmony_ci{
1543a8e1175bSopenharmony_ci    const unsigned char *p = *buf;
1544a8e1175bSopenharmony_ci    size_t legacy_session_id_echo_len;
1545a8e1175bSopenharmony_ci
1546a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 1);
1547a8e1175bSopenharmony_ci    legacy_session_id_echo_len = *p++;
1548a8e1175bSopenharmony_ci
1549a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, legacy_session_id_echo_len);
1550a8e1175bSopenharmony_ci
1551a8e1175bSopenharmony_ci    /* legacy_session_id_echo */
1552a8e1175bSopenharmony_ci    if (ssl->session_negotiate->id_len != legacy_session_id_echo_len ||
1553a8e1175bSopenharmony_ci        memcmp(ssl->session_negotiate->id, p, legacy_session_id_echo_len) != 0) {
1554a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_BUF(3, "Expected Session ID",
1555a8e1175bSopenharmony_ci                              ssl->session_negotiate->id,
1556a8e1175bSopenharmony_ci                              ssl->session_negotiate->id_len);
1557a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_BUF(3, "Received Session ID", p,
1558a8e1175bSopenharmony_ci                              legacy_session_id_echo_len);
1559a8e1175bSopenharmony_ci
1560a8e1175bSopenharmony_ci        MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
1561a8e1175bSopenharmony_ci                                     MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
1562a8e1175bSopenharmony_ci
1563a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
1564a8e1175bSopenharmony_ci    }
1565a8e1175bSopenharmony_ci
1566a8e1175bSopenharmony_ci    p += legacy_session_id_echo_len;
1567a8e1175bSopenharmony_ci    *buf = p;
1568a8e1175bSopenharmony_ci
1569a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(3, "Session ID", ssl->session_negotiate->id,
1570a8e1175bSopenharmony_ci                          ssl->session_negotiate->id_len);
1571a8e1175bSopenharmony_ci    return 0;
1572a8e1175bSopenharmony_ci}
1573a8e1175bSopenharmony_ci
1574a8e1175bSopenharmony_ci/* Parse ServerHello message and configure context
1575a8e1175bSopenharmony_ci *
1576a8e1175bSopenharmony_ci * struct {
1577a8e1175bSopenharmony_ci *    ProtocolVersion legacy_version = 0x0303; // TLS 1.2
1578a8e1175bSopenharmony_ci *    Random random;
1579a8e1175bSopenharmony_ci *    opaque legacy_session_id_echo<0..32>;
1580a8e1175bSopenharmony_ci *    CipherSuite cipher_suite;
1581a8e1175bSopenharmony_ci *    uint8 legacy_compression_method = 0;
1582a8e1175bSopenharmony_ci *    Extension extensions<6..2^16-1>;
1583a8e1175bSopenharmony_ci * } ServerHello;
1584a8e1175bSopenharmony_ci */
1585a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
1586a8e1175bSopenharmony_cistatic int ssl_tls13_parse_server_hello(mbedtls_ssl_context *ssl,
1587a8e1175bSopenharmony_ci                                        const unsigned char *buf,
1588a8e1175bSopenharmony_ci                                        const unsigned char *end,
1589a8e1175bSopenharmony_ci                                        int is_hrr)
1590a8e1175bSopenharmony_ci{
1591a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1592a8e1175bSopenharmony_ci    const unsigned char *p = buf;
1593a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
1594a8e1175bSopenharmony_ci    size_t extensions_len;
1595a8e1175bSopenharmony_ci    const unsigned char *extensions_end;
1596a8e1175bSopenharmony_ci    uint16_t cipher_suite;
1597a8e1175bSopenharmony_ci    const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
1598a8e1175bSopenharmony_ci    int fatal_alert = 0;
1599a8e1175bSopenharmony_ci    uint32_t allowed_extensions_mask;
1600a8e1175bSopenharmony_ci    int hs_msg_type = is_hrr ? MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST :
1601a8e1175bSopenharmony_ci                      MBEDTLS_SSL_HS_SERVER_HELLO;
1602a8e1175bSopenharmony_ci
1603a8e1175bSopenharmony_ci    /*
1604a8e1175bSopenharmony_ci     * Check there is space for minimal fields
1605a8e1175bSopenharmony_ci     *
1606a8e1175bSopenharmony_ci     * - legacy_version             ( 2 bytes)
1607a8e1175bSopenharmony_ci     * - random                     (MBEDTLS_SERVER_HELLO_RANDOM_LEN bytes)
1608a8e1175bSopenharmony_ci     * - legacy_session_id_echo     ( 1 byte ), minimum size
1609a8e1175bSopenharmony_ci     * - cipher_suite               ( 2 bytes)
1610a8e1175bSopenharmony_ci     * - legacy_compression_method  ( 1 byte )
1611a8e1175bSopenharmony_ci     */
1612a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, MBEDTLS_SERVER_HELLO_RANDOM_LEN + 6);
1613a8e1175bSopenharmony_ci
1614a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(4, "server hello", p, end - p);
1615a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(3, "server hello, version", p, 2);
1616a8e1175bSopenharmony_ci
1617a8e1175bSopenharmony_ci    /* ...
1618a8e1175bSopenharmony_ci     * ProtocolVersion legacy_version = 0x0303; // TLS 1.2
1619a8e1175bSopenharmony_ci     * ...
1620a8e1175bSopenharmony_ci     * with ProtocolVersion defined as:
1621a8e1175bSopenharmony_ci     * uint16 ProtocolVersion;
1622a8e1175bSopenharmony_ci     */
1623a8e1175bSopenharmony_ci    if (mbedtls_ssl_read_version(p, ssl->conf->transport) !=
1624a8e1175bSopenharmony_ci        MBEDTLS_SSL_VERSION_TLS1_2) {
1625a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("Unsupported version of TLS."));
1626a8e1175bSopenharmony_ci        MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION,
1627a8e1175bSopenharmony_ci                                     MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION);
1628a8e1175bSopenharmony_ci        ret = MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
1629a8e1175bSopenharmony_ci        goto cleanup;
1630a8e1175bSopenharmony_ci    }
1631a8e1175bSopenharmony_ci    p += 2;
1632a8e1175bSopenharmony_ci
1633a8e1175bSopenharmony_ci    /* ...
1634a8e1175bSopenharmony_ci     * Random random;
1635a8e1175bSopenharmony_ci     * ...
1636a8e1175bSopenharmony_ci     * with Random defined as:
1637a8e1175bSopenharmony_ci     * opaque Random[MBEDTLS_SERVER_HELLO_RANDOM_LEN];
1638a8e1175bSopenharmony_ci     */
1639a8e1175bSopenharmony_ci    if (!is_hrr) {
1640a8e1175bSopenharmony_ci        memcpy(&handshake->randbytes[MBEDTLS_CLIENT_HELLO_RANDOM_LEN], p,
1641a8e1175bSopenharmony_ci               MBEDTLS_SERVER_HELLO_RANDOM_LEN);
1642a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_BUF(3, "server hello, random bytes",
1643a8e1175bSopenharmony_ci                              p, MBEDTLS_SERVER_HELLO_RANDOM_LEN);
1644a8e1175bSopenharmony_ci    }
1645a8e1175bSopenharmony_ci    p += MBEDTLS_SERVER_HELLO_RANDOM_LEN;
1646a8e1175bSopenharmony_ci
1647a8e1175bSopenharmony_ci    /* ...
1648a8e1175bSopenharmony_ci     * opaque legacy_session_id_echo<0..32>;
1649a8e1175bSopenharmony_ci     * ...
1650a8e1175bSopenharmony_ci     */
1651a8e1175bSopenharmony_ci    if (ssl_tls13_check_server_hello_session_id_echo(ssl, &p, end) != 0) {
1652a8e1175bSopenharmony_ci        fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
1653a8e1175bSopenharmony_ci        goto cleanup;
1654a8e1175bSopenharmony_ci    }
1655a8e1175bSopenharmony_ci
1656a8e1175bSopenharmony_ci    /* ...
1657a8e1175bSopenharmony_ci     * CipherSuite cipher_suite;
1658a8e1175bSopenharmony_ci     * ...
1659a8e1175bSopenharmony_ci     * with CipherSuite defined as:
1660a8e1175bSopenharmony_ci     * uint8 CipherSuite[2];
1661a8e1175bSopenharmony_ci     */
1662a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
1663a8e1175bSopenharmony_ci    cipher_suite = MBEDTLS_GET_UINT16_BE(p, 0);
1664a8e1175bSopenharmony_ci    p += 2;
1665a8e1175bSopenharmony_ci
1666a8e1175bSopenharmony_ci
1667a8e1175bSopenharmony_ci    ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(cipher_suite);
1668a8e1175bSopenharmony_ci    /*
1669a8e1175bSopenharmony_ci     * Check whether this ciphersuite is valid and offered.
1670a8e1175bSopenharmony_ci     */
1671a8e1175bSopenharmony_ci    if ((mbedtls_ssl_validate_ciphersuite(ssl, ciphersuite_info,
1672a8e1175bSopenharmony_ci                                          ssl->tls_version,
1673a8e1175bSopenharmony_ci                                          ssl->tls_version) != 0) ||
1674a8e1175bSopenharmony_ci        !mbedtls_ssl_tls13_cipher_suite_is_offered(ssl, cipher_suite)) {
1675a8e1175bSopenharmony_ci        fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
1676a8e1175bSopenharmony_ci    }
1677a8e1175bSopenharmony_ci    /*
1678a8e1175bSopenharmony_ci     * If we received an HRR before and that the proposed selected
1679a8e1175bSopenharmony_ci     * ciphersuite in this server hello is not the same as the one
1680a8e1175bSopenharmony_ci     * proposed in the HRR, we abort the handshake and send an
1681a8e1175bSopenharmony_ci     * "illegal_parameter" alert.
1682a8e1175bSopenharmony_ci     */
1683a8e1175bSopenharmony_ci    else if ((!is_hrr) && handshake->hello_retry_request_flag &&
1684a8e1175bSopenharmony_ci             (cipher_suite != ssl->session_negotiate->ciphersuite)) {
1685a8e1175bSopenharmony_ci        fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
1686a8e1175bSopenharmony_ci    }
1687a8e1175bSopenharmony_ci
1688a8e1175bSopenharmony_ci    if (fatal_alert == MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER) {
1689a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("invalid ciphersuite(%04x) parameter",
1690a8e1175bSopenharmony_ci                                  cipher_suite));
1691a8e1175bSopenharmony_ci        goto cleanup;
1692a8e1175bSopenharmony_ci    }
1693a8e1175bSopenharmony_ci
1694a8e1175bSopenharmony_ci    /* Configure ciphersuites */
1695a8e1175bSopenharmony_ci    mbedtls_ssl_optimize_checksum(ssl, ciphersuite_info);
1696a8e1175bSopenharmony_ci
1697a8e1175bSopenharmony_ci    handshake->ciphersuite_info = ciphersuite_info;
1698a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen ciphersuite: ( %04x ) - %s",
1699a8e1175bSopenharmony_ci                              cipher_suite, ciphersuite_info->name));
1700a8e1175bSopenharmony_ci
1701a8e1175bSopenharmony_ci#if defined(MBEDTLS_HAVE_TIME)
1702a8e1175bSopenharmony_ci    ssl->session_negotiate->start = mbedtls_time(NULL);
1703a8e1175bSopenharmony_ci#endif /* MBEDTLS_HAVE_TIME */
1704a8e1175bSopenharmony_ci
1705a8e1175bSopenharmony_ci    /* ...
1706a8e1175bSopenharmony_ci     * uint8 legacy_compression_method = 0;
1707a8e1175bSopenharmony_ci     * ...
1708a8e1175bSopenharmony_ci     */
1709a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 1);
1710a8e1175bSopenharmony_ci    if (p[0] != MBEDTLS_SSL_COMPRESS_NULL) {
1711a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("bad legacy compression method"));
1712a8e1175bSopenharmony_ci        fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
1713a8e1175bSopenharmony_ci        goto cleanup;
1714a8e1175bSopenharmony_ci    }
1715a8e1175bSopenharmony_ci    p++;
1716a8e1175bSopenharmony_ci
1717a8e1175bSopenharmony_ci    /* ...
1718a8e1175bSopenharmony_ci     * Extension extensions<6..2^16-1>;
1719a8e1175bSopenharmony_ci     * ...
1720a8e1175bSopenharmony_ci     * struct {
1721a8e1175bSopenharmony_ci     *      ExtensionType extension_type; (2 bytes)
1722a8e1175bSopenharmony_ci     *      opaque extension_data<0..2^16-1>;
1723a8e1175bSopenharmony_ci     * } Extension;
1724a8e1175bSopenharmony_ci     */
1725a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
1726a8e1175bSopenharmony_ci    extensions_len = MBEDTLS_GET_UINT16_BE(p, 0);
1727a8e1175bSopenharmony_ci    p += 2;
1728a8e1175bSopenharmony_ci
1729a8e1175bSopenharmony_ci    /* Check extensions do not go beyond the buffer of data. */
1730a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extensions_len);
1731a8e1175bSopenharmony_ci    extensions_end = p + extensions_len;
1732a8e1175bSopenharmony_ci
1733a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(3, "server hello extensions", p, extensions_len);
1734a8e1175bSopenharmony_ci
1735a8e1175bSopenharmony_ci    handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
1736a8e1175bSopenharmony_ci    allowed_extensions_mask = is_hrr ?
1737a8e1175bSopenharmony_ci                              MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_HRR :
1738a8e1175bSopenharmony_ci                              MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_SH;
1739a8e1175bSopenharmony_ci
1740a8e1175bSopenharmony_ci    while (p < extensions_end) {
1741a8e1175bSopenharmony_ci        unsigned int extension_type;
1742a8e1175bSopenharmony_ci        size_t extension_data_len;
1743a8e1175bSopenharmony_ci        const unsigned char *extension_data_end;
1744a8e1175bSopenharmony_ci
1745a8e1175bSopenharmony_ci        MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, 4);
1746a8e1175bSopenharmony_ci        extension_type = MBEDTLS_GET_UINT16_BE(p, 0);
1747a8e1175bSopenharmony_ci        extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2);
1748a8e1175bSopenharmony_ci        p += 4;
1749a8e1175bSopenharmony_ci
1750a8e1175bSopenharmony_ci        MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, extension_data_len);
1751a8e1175bSopenharmony_ci        extension_data_end = p + extension_data_len;
1752a8e1175bSopenharmony_ci
1753a8e1175bSopenharmony_ci        ret = mbedtls_ssl_tls13_check_received_extension(
1754a8e1175bSopenharmony_ci            ssl, hs_msg_type, extension_type, allowed_extensions_mask);
1755a8e1175bSopenharmony_ci        if (ret != 0) {
1756a8e1175bSopenharmony_ci            return ret;
1757a8e1175bSopenharmony_ci        }
1758a8e1175bSopenharmony_ci
1759a8e1175bSopenharmony_ci        switch (extension_type) {
1760a8e1175bSopenharmony_ci            case MBEDTLS_TLS_EXT_COOKIE:
1761a8e1175bSopenharmony_ci
1762a8e1175bSopenharmony_ci                ret = ssl_tls13_parse_cookie_ext(ssl,
1763a8e1175bSopenharmony_ci                                                 p, extension_data_end);
1764a8e1175bSopenharmony_ci                if (ret != 0) {
1765a8e1175bSopenharmony_ci                    MBEDTLS_SSL_DEBUG_RET(1,
1766a8e1175bSopenharmony_ci                                          "ssl_tls13_parse_cookie_ext",
1767a8e1175bSopenharmony_ci                                          ret);
1768a8e1175bSopenharmony_ci                    goto cleanup;
1769a8e1175bSopenharmony_ci                }
1770a8e1175bSopenharmony_ci                break;
1771a8e1175bSopenharmony_ci
1772a8e1175bSopenharmony_ci            case MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS:
1773a8e1175bSopenharmony_ci                ret = ssl_tls13_parse_supported_versions_ext(ssl,
1774a8e1175bSopenharmony_ci                                                             p,
1775a8e1175bSopenharmony_ci                                                             extension_data_end);
1776a8e1175bSopenharmony_ci                if (ret != 0) {
1777a8e1175bSopenharmony_ci                    goto cleanup;
1778a8e1175bSopenharmony_ci                }
1779a8e1175bSopenharmony_ci                break;
1780a8e1175bSopenharmony_ci
1781a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
1782a8e1175bSopenharmony_ci            case MBEDTLS_TLS_EXT_PRE_SHARED_KEY:
1783a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(3, ("found pre_shared_key extension"));
1784a8e1175bSopenharmony_ci
1785a8e1175bSopenharmony_ci                if ((ret = ssl_tls13_parse_server_pre_shared_key_ext(
1786a8e1175bSopenharmony_ci                         ssl, p, extension_data_end)) != 0) {
1787a8e1175bSopenharmony_ci                    MBEDTLS_SSL_DEBUG_RET(
1788a8e1175bSopenharmony_ci                        1, ("ssl_tls13_parse_server_pre_shared_key_ext"), ret);
1789a8e1175bSopenharmony_ci                    return ret;
1790a8e1175bSopenharmony_ci                }
1791a8e1175bSopenharmony_ci                break;
1792a8e1175bSopenharmony_ci#endif
1793a8e1175bSopenharmony_ci
1794a8e1175bSopenharmony_ci            case MBEDTLS_TLS_EXT_KEY_SHARE:
1795a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(3, ("found key_shares extension"));
1796a8e1175bSopenharmony_ci                if (!mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(ssl)) {
1797a8e1175bSopenharmony_ci                    fatal_alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT;
1798a8e1175bSopenharmony_ci                    goto cleanup;
1799a8e1175bSopenharmony_ci                }
1800a8e1175bSopenharmony_ci
1801a8e1175bSopenharmony_ci                if (is_hrr) {
1802a8e1175bSopenharmony_ci                    ret = ssl_tls13_parse_hrr_key_share_ext(ssl,
1803a8e1175bSopenharmony_ci                                                            p, extension_data_end);
1804a8e1175bSopenharmony_ci                } else {
1805a8e1175bSopenharmony_ci                    ret = ssl_tls13_parse_key_share_ext(ssl,
1806a8e1175bSopenharmony_ci                                                        p, extension_data_end);
1807a8e1175bSopenharmony_ci                }
1808a8e1175bSopenharmony_ci                if (ret != 0) {
1809a8e1175bSopenharmony_ci                    MBEDTLS_SSL_DEBUG_RET(1,
1810a8e1175bSopenharmony_ci                                          "ssl_tls13_parse_key_share_ext",
1811a8e1175bSopenharmony_ci                                          ret);
1812a8e1175bSopenharmony_ci                    goto cleanup;
1813a8e1175bSopenharmony_ci                }
1814a8e1175bSopenharmony_ci                break;
1815a8e1175bSopenharmony_ci
1816a8e1175bSopenharmony_ci            default:
1817a8e1175bSopenharmony_ci                ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
1818a8e1175bSopenharmony_ci                goto cleanup;
1819a8e1175bSopenharmony_ci        }
1820a8e1175bSopenharmony_ci
1821a8e1175bSopenharmony_ci        p += extension_data_len;
1822a8e1175bSopenharmony_ci    }
1823a8e1175bSopenharmony_ci
1824a8e1175bSopenharmony_ci    MBEDTLS_SSL_PRINT_EXTS(3, hs_msg_type, handshake->received_extensions);
1825a8e1175bSopenharmony_ci
1826a8e1175bSopenharmony_cicleanup:
1827a8e1175bSopenharmony_ci
1828a8e1175bSopenharmony_ci    if (fatal_alert == MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT) {
1829a8e1175bSopenharmony_ci        MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT,
1830a8e1175bSopenharmony_ci                                     MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION);
1831a8e1175bSopenharmony_ci        ret = MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION;
1832a8e1175bSopenharmony_ci    } else if (fatal_alert == MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER) {
1833a8e1175bSopenharmony_ci        MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
1834a8e1175bSopenharmony_ci                                     MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
1835a8e1175bSopenharmony_ci        ret = MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
1836a8e1175bSopenharmony_ci    }
1837a8e1175bSopenharmony_ci    return ret;
1838a8e1175bSopenharmony_ci}
1839a8e1175bSopenharmony_ci
1840a8e1175bSopenharmony_ci#if defined(MBEDTLS_DEBUG_C)
1841a8e1175bSopenharmony_cistatic const char *ssl_tls13_get_kex_mode_str(int mode)
1842a8e1175bSopenharmony_ci{
1843a8e1175bSopenharmony_ci    switch (mode) {
1844a8e1175bSopenharmony_ci        case MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK:
1845a8e1175bSopenharmony_ci            return "psk";
1846a8e1175bSopenharmony_ci        case MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL:
1847a8e1175bSopenharmony_ci            return "ephemeral";
1848a8e1175bSopenharmony_ci        case MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL:
1849a8e1175bSopenharmony_ci            return "psk_ephemeral";
1850a8e1175bSopenharmony_ci        default:
1851a8e1175bSopenharmony_ci            return "unknown mode";
1852a8e1175bSopenharmony_ci    }
1853a8e1175bSopenharmony_ci}
1854a8e1175bSopenharmony_ci#endif /* MBEDTLS_DEBUG_C */
1855a8e1175bSopenharmony_ci
1856a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
1857a8e1175bSopenharmony_cistatic int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl)
1858a8e1175bSopenharmony_ci{
1859a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1860a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
1861a8e1175bSopenharmony_ci
1862a8e1175bSopenharmony_ci    /* Determine the key exchange mode:
1863a8e1175bSopenharmony_ci     * 1) If both the pre_shared_key and key_share extensions were received
1864a8e1175bSopenharmony_ci     *    then the key exchange mode is PSK with EPHEMERAL.
1865a8e1175bSopenharmony_ci     * 2) If only the pre_shared_key extension was received then the key
1866a8e1175bSopenharmony_ci     *    exchange mode is PSK-only.
1867a8e1175bSopenharmony_ci     * 3) If only the key_share extension was received then the key
1868a8e1175bSopenharmony_ci     *    exchange mode is EPHEMERAL-only.
1869a8e1175bSopenharmony_ci     */
1870a8e1175bSopenharmony_ci    switch (handshake->received_extensions &
1871a8e1175bSopenharmony_ci            (MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY) |
1872a8e1175bSopenharmony_ci             MBEDTLS_SSL_EXT_MASK(KEY_SHARE))) {
1873a8e1175bSopenharmony_ci        /* Only the pre_shared_key extension was received */
1874a8e1175bSopenharmony_ci        case MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY):
1875a8e1175bSopenharmony_ci            handshake->key_exchange_mode =
1876a8e1175bSopenharmony_ci                MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
1877a8e1175bSopenharmony_ci            break;
1878a8e1175bSopenharmony_ci
1879a8e1175bSopenharmony_ci        /* Only the key_share extension was received */
1880a8e1175bSopenharmony_ci        case MBEDTLS_SSL_EXT_MASK(KEY_SHARE):
1881a8e1175bSopenharmony_ci            handshake->key_exchange_mode =
1882a8e1175bSopenharmony_ci                MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL;
1883a8e1175bSopenharmony_ci            break;
1884a8e1175bSopenharmony_ci
1885a8e1175bSopenharmony_ci        /* Both the pre_shared_key and key_share extensions were received */
1886a8e1175bSopenharmony_ci        case (MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY) |
1887a8e1175bSopenharmony_ci              MBEDTLS_SSL_EXT_MASK(KEY_SHARE)):
1888a8e1175bSopenharmony_ci            handshake->key_exchange_mode =
1889a8e1175bSopenharmony_ci                MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
1890a8e1175bSopenharmony_ci            break;
1891a8e1175bSopenharmony_ci
1892a8e1175bSopenharmony_ci        /* Neither pre_shared_key nor key_share extension was received */
1893a8e1175bSopenharmony_ci        default:
1894a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("Unknown key exchange."));
1895a8e1175bSopenharmony_ci            ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
1896a8e1175bSopenharmony_ci            goto cleanup;
1897a8e1175bSopenharmony_ci    }
1898a8e1175bSopenharmony_ci
1899a8e1175bSopenharmony_ci    if (!mbedtls_ssl_conf_tls13_is_kex_mode_enabled(
1900a8e1175bSopenharmony_ci            ssl, handshake->key_exchange_mode)) {
1901a8e1175bSopenharmony_ci        ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
1902a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(
1903a8e1175bSopenharmony_ci            2, ("Key exchange mode(%s) is not supported.",
1904a8e1175bSopenharmony_ci                ssl_tls13_get_kex_mode_str(handshake->key_exchange_mode)));
1905a8e1175bSopenharmony_ci        goto cleanup;
1906a8e1175bSopenharmony_ci    }
1907a8e1175bSopenharmony_ci
1908a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(
1909a8e1175bSopenharmony_ci        3, ("Selected key exchange mode: %s",
1910a8e1175bSopenharmony_ci            ssl_tls13_get_kex_mode_str(handshake->key_exchange_mode)));
1911a8e1175bSopenharmony_ci
1912a8e1175bSopenharmony_ci    /* Start the TLS 1.3 key scheduling if not already done.
1913a8e1175bSopenharmony_ci     *
1914a8e1175bSopenharmony_ci     * If we proposed early data then we have already derived an
1915a8e1175bSopenharmony_ci     * early secret using the selected PSK and its associated hash.
1916a8e1175bSopenharmony_ci     * It means that if the negotiated key exchange mode is psk or
1917a8e1175bSopenharmony_ci     * psk_ephemeral, we have already correctly computed the
1918a8e1175bSopenharmony_ci     * early secret and thus we do not do it again. In all other
1919a8e1175bSopenharmony_ci     * cases we compute it here.
1920a8e1175bSopenharmony_ci     */
1921a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
1922a8e1175bSopenharmony_ci    if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT ||
1923a8e1175bSopenharmony_ci        handshake->key_exchange_mode ==
1924a8e1175bSopenharmony_ci        MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL)
1925a8e1175bSopenharmony_ci#endif
1926a8e1175bSopenharmony_ci    {
1927a8e1175bSopenharmony_ci        ret = mbedtls_ssl_tls13_key_schedule_stage_early(ssl);
1928a8e1175bSopenharmony_ci        if (ret != 0) {
1929a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_RET(
1930a8e1175bSopenharmony_ci                1, "mbedtls_ssl_tls13_key_schedule_stage_early", ret);
1931a8e1175bSopenharmony_ci            goto cleanup;
1932a8e1175bSopenharmony_ci        }
1933a8e1175bSopenharmony_ci    }
1934a8e1175bSopenharmony_ci
1935a8e1175bSopenharmony_ci    ret = mbedtls_ssl_tls13_compute_handshake_transform(ssl);
1936a8e1175bSopenharmony_ci    if (ret != 0) {
1937a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_RET(1,
1938a8e1175bSopenharmony_ci                              "mbedtls_ssl_tls13_compute_handshake_transform",
1939a8e1175bSopenharmony_ci                              ret);
1940a8e1175bSopenharmony_ci        goto cleanup;
1941a8e1175bSopenharmony_ci    }
1942a8e1175bSopenharmony_ci
1943a8e1175bSopenharmony_ci    mbedtls_ssl_set_inbound_transform(ssl, handshake->transform_handshake);
1944a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(1, ("Switch to handshake keys for inbound traffic"));
1945a8e1175bSopenharmony_ci    ssl->session_in = ssl->session_negotiate;
1946a8e1175bSopenharmony_ci
1947a8e1175bSopenharmony_cicleanup:
1948a8e1175bSopenharmony_ci    if (ret != 0) {
1949a8e1175bSopenharmony_ci        MBEDTLS_SSL_PEND_FATAL_ALERT(
1950a8e1175bSopenharmony_ci            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
1951a8e1175bSopenharmony_ci            MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
1952a8e1175bSopenharmony_ci    }
1953a8e1175bSopenharmony_ci
1954a8e1175bSopenharmony_ci    return ret;
1955a8e1175bSopenharmony_ci}
1956a8e1175bSopenharmony_ci
1957a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
1958a8e1175bSopenharmony_cistatic int ssl_tls13_postprocess_hrr(mbedtls_ssl_context *ssl)
1959a8e1175bSopenharmony_ci{
1960a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1961a8e1175bSopenharmony_ci
1962a8e1175bSopenharmony_ci    mbedtls_ssl_session_reset_msg_layer(ssl, 0);
1963a8e1175bSopenharmony_ci
1964a8e1175bSopenharmony_ci    /*
1965a8e1175bSopenharmony_ci     * We are going to re-generate a shared secret corresponding to the group
1966a8e1175bSopenharmony_ci     * selected by the server, which is different from the group for which we
1967a8e1175bSopenharmony_ci     * generated a shared secret in the first client hello.
1968a8e1175bSopenharmony_ci     * Thus, reset the shared secret.
1969a8e1175bSopenharmony_ci     */
1970a8e1175bSopenharmony_ci    ret = ssl_tls13_reset_key_share(ssl);
1971a8e1175bSopenharmony_ci    if (ret != 0) {
1972a8e1175bSopenharmony_ci        return ret;
1973a8e1175bSopenharmony_ci    }
1974a8e1175bSopenharmony_ci
1975a8e1175bSopenharmony_ci    ssl->session_negotiate->ciphersuite = ssl->handshake->ciphersuite_info->id;
1976a8e1175bSopenharmony_ci
1977a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
1978a8e1175bSopenharmony_ci    if (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT) {
1979a8e1175bSopenharmony_ci        ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED;
1980a8e1175bSopenharmony_ci    }
1981a8e1175bSopenharmony_ci#endif
1982a8e1175bSopenharmony_ci
1983a8e1175bSopenharmony_ci    return 0;
1984a8e1175bSopenharmony_ci}
1985a8e1175bSopenharmony_ci
1986a8e1175bSopenharmony_ci/*
1987a8e1175bSopenharmony_ci * Wait and parse ServerHello handshake message.
1988a8e1175bSopenharmony_ci * Handler for MBEDTLS_SSL_SERVER_HELLO
1989a8e1175bSopenharmony_ci */
1990a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
1991a8e1175bSopenharmony_cistatic int ssl_tls13_process_server_hello(mbedtls_ssl_context *ssl)
1992a8e1175bSopenharmony_ci{
1993a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1994a8e1175bSopenharmony_ci    unsigned char *buf = NULL;
1995a8e1175bSopenharmony_ci    size_t buf_len = 0;
1996a8e1175bSopenharmony_ci    int is_hrr = 0;
1997a8e1175bSopenharmony_ci
1998a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> %s", __func__));
1999a8e1175bSopenharmony_ci
2000a8e1175bSopenharmony_ci    MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(
2001a8e1175bSopenharmony_ci                             ssl, MBEDTLS_SSL_HS_SERVER_HELLO, &buf, &buf_len));
2002a8e1175bSopenharmony_ci
2003a8e1175bSopenharmony_ci    ret = ssl_tls13_preprocess_server_hello(ssl, buf, buf + buf_len);
2004a8e1175bSopenharmony_ci    if (ret < 0) {
2005a8e1175bSopenharmony_ci        goto cleanup;
2006a8e1175bSopenharmony_ci    } else {
2007a8e1175bSopenharmony_ci        is_hrr = (ret == SSL_SERVER_HELLO_HRR);
2008a8e1175bSopenharmony_ci    }
2009a8e1175bSopenharmony_ci
2010a8e1175bSopenharmony_ci    if (ret == SSL_SERVER_HELLO_TLS1_2) {
2011a8e1175bSopenharmony_ci        ret = 0;
2012a8e1175bSopenharmony_ci        goto cleanup;
2013a8e1175bSopenharmony_ci    }
2014a8e1175bSopenharmony_ci
2015a8e1175bSopenharmony_ci    MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_server_hello(ssl, buf,
2016a8e1175bSopenharmony_ci                                                      buf + buf_len,
2017a8e1175bSopenharmony_ci                                                      is_hrr));
2018a8e1175bSopenharmony_ci    if (is_hrr) {
2019a8e1175bSopenharmony_ci        MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_reset_transcript_for_hrr(ssl));
2020a8e1175bSopenharmony_ci    }
2021a8e1175bSopenharmony_ci
2022a8e1175bSopenharmony_ci    MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
2023a8e1175bSopenharmony_ci                             ssl, MBEDTLS_SSL_HS_SERVER_HELLO, buf, buf_len));
2024a8e1175bSopenharmony_ci
2025a8e1175bSopenharmony_ci    if (is_hrr) {
2026a8e1175bSopenharmony_ci        MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_hrr(ssl));
2027a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
2028a8e1175bSopenharmony_ci        /* If not offering early data, the client sends a dummy CCS record
2029a8e1175bSopenharmony_ci         * immediately before its second flight. This may either be before
2030a8e1175bSopenharmony_ci         * its second ClientHello or before its encrypted handshake flight.
2031a8e1175bSopenharmony_ci         */
2032a8e1175bSopenharmony_ci        mbedtls_ssl_handshake_set_state(
2033a8e1175bSopenharmony_ci            ssl, MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO);
2034a8e1175bSopenharmony_ci#else
2035a8e1175bSopenharmony_ci        mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
2036a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
2037a8e1175bSopenharmony_ci    } else {
2038a8e1175bSopenharmony_ci        MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_server_hello(ssl));
2039a8e1175bSopenharmony_ci        mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS);
2040a8e1175bSopenharmony_ci    }
2041a8e1175bSopenharmony_ci
2042a8e1175bSopenharmony_cicleanup:
2043a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= %s ( %s )", __func__,
2044a8e1175bSopenharmony_ci                              is_hrr ? "HelloRetryRequest" : "ServerHello"));
2045a8e1175bSopenharmony_ci    return ret;
2046a8e1175bSopenharmony_ci}
2047a8e1175bSopenharmony_ci
2048a8e1175bSopenharmony_ci/*
2049a8e1175bSopenharmony_ci *
2050a8e1175bSopenharmony_ci * Handler for MBEDTLS_SSL_ENCRYPTED_EXTENSIONS
2051a8e1175bSopenharmony_ci *
2052a8e1175bSopenharmony_ci * The EncryptedExtensions message contains any extensions which
2053a8e1175bSopenharmony_ci * should be protected, i.e., any which are not needed to establish
2054a8e1175bSopenharmony_ci * the cryptographic context.
2055a8e1175bSopenharmony_ci */
2056a8e1175bSopenharmony_ci
2057a8e1175bSopenharmony_ci/* Parse EncryptedExtensions message
2058a8e1175bSopenharmony_ci * struct {
2059a8e1175bSopenharmony_ci *     Extension extensions<0..2^16-1>;
2060a8e1175bSopenharmony_ci * } EncryptedExtensions;
2061a8e1175bSopenharmony_ci */
2062a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2063a8e1175bSopenharmony_cistatic int ssl_tls13_parse_encrypted_extensions(mbedtls_ssl_context *ssl,
2064a8e1175bSopenharmony_ci                                                const unsigned char *buf,
2065a8e1175bSopenharmony_ci                                                const unsigned char *end)
2066a8e1175bSopenharmony_ci{
2067a8e1175bSopenharmony_ci    int ret = 0;
2068a8e1175bSopenharmony_ci    size_t extensions_len;
2069a8e1175bSopenharmony_ci    const unsigned char *p = buf;
2070a8e1175bSopenharmony_ci    const unsigned char *extensions_end;
2071a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
2072a8e1175bSopenharmony_ci
2073a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
2074a8e1175bSopenharmony_ci    extensions_len = MBEDTLS_GET_UINT16_BE(p, 0);
2075a8e1175bSopenharmony_ci    p += 2;
2076a8e1175bSopenharmony_ci
2077a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extensions_len);
2078a8e1175bSopenharmony_ci    extensions_end = p + extensions_len;
2079a8e1175bSopenharmony_ci
2080a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(3, "encrypted extensions", p, extensions_len);
2081a8e1175bSopenharmony_ci
2082a8e1175bSopenharmony_ci    handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
2083a8e1175bSopenharmony_ci
2084a8e1175bSopenharmony_ci    while (p < extensions_end) {
2085a8e1175bSopenharmony_ci        unsigned int extension_type;
2086a8e1175bSopenharmony_ci        size_t extension_data_len;
2087a8e1175bSopenharmony_ci
2088a8e1175bSopenharmony_ci        /*
2089a8e1175bSopenharmony_ci         * struct {
2090a8e1175bSopenharmony_ci         *     ExtensionType extension_type; (2 bytes)
2091a8e1175bSopenharmony_ci         *     opaque extension_data<0..2^16-1>;
2092a8e1175bSopenharmony_ci         * } Extension;
2093a8e1175bSopenharmony_ci         */
2094a8e1175bSopenharmony_ci        MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, 4);
2095a8e1175bSopenharmony_ci        extension_type = MBEDTLS_GET_UINT16_BE(p, 0);
2096a8e1175bSopenharmony_ci        extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2);
2097a8e1175bSopenharmony_ci        p += 4;
2098a8e1175bSopenharmony_ci
2099a8e1175bSopenharmony_ci        MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, extension_data_len);
2100a8e1175bSopenharmony_ci
2101a8e1175bSopenharmony_ci        ret = mbedtls_ssl_tls13_check_received_extension(
2102a8e1175bSopenharmony_ci            ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, extension_type,
2103a8e1175bSopenharmony_ci            MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_EE);
2104a8e1175bSopenharmony_ci        if (ret != 0) {
2105a8e1175bSopenharmony_ci            return ret;
2106a8e1175bSopenharmony_ci        }
2107a8e1175bSopenharmony_ci
2108a8e1175bSopenharmony_ci        switch (extension_type) {
2109a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ALPN)
2110a8e1175bSopenharmony_ci            case MBEDTLS_TLS_EXT_ALPN:
2111a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(3, ("found alpn extension"));
2112a8e1175bSopenharmony_ci
2113a8e1175bSopenharmony_ci                if ((ret = ssl_tls13_parse_alpn_ext(
2114a8e1175bSopenharmony_ci                         ssl, p, (size_t) extension_data_len)) != 0) {
2115a8e1175bSopenharmony_ci                    return ret;
2116a8e1175bSopenharmony_ci                }
2117a8e1175bSopenharmony_ci
2118a8e1175bSopenharmony_ci                break;
2119a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ALPN */
2120a8e1175bSopenharmony_ci
2121a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
2122a8e1175bSopenharmony_ci            case MBEDTLS_TLS_EXT_EARLY_DATA:
2123a8e1175bSopenharmony_ci
2124a8e1175bSopenharmony_ci                if (extension_data_len != 0) {
2125a8e1175bSopenharmony_ci                    /* The message must be empty. */
2126a8e1175bSopenharmony_ci                    MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
2127a8e1175bSopenharmony_ci                                                 MBEDTLS_ERR_SSL_DECODE_ERROR);
2128a8e1175bSopenharmony_ci                    return MBEDTLS_ERR_SSL_DECODE_ERROR;
2129a8e1175bSopenharmony_ci                }
2130a8e1175bSopenharmony_ci
2131a8e1175bSopenharmony_ci                break;
2132a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EARLY_DATA */
2133a8e1175bSopenharmony_ci
2134a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
2135a8e1175bSopenharmony_ci            case MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT:
2136a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(3, ("found record_size_limit extension"));
2137a8e1175bSopenharmony_ci
2138a8e1175bSopenharmony_ci                ret = mbedtls_ssl_tls13_parse_record_size_limit_ext(
2139a8e1175bSopenharmony_ci                    ssl, p, p + extension_data_len);
2140a8e1175bSopenharmony_ci                if (ret != 0) {
2141a8e1175bSopenharmony_ci                    MBEDTLS_SSL_DEBUG_RET(
2142a8e1175bSopenharmony_ci                        1, ("mbedtls_ssl_tls13_parse_record_size_limit_ext"), ret);
2143a8e1175bSopenharmony_ci                    return ret;
2144a8e1175bSopenharmony_ci                }
2145a8e1175bSopenharmony_ci                break;
2146a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
2147a8e1175bSopenharmony_ci
2148a8e1175bSopenharmony_ci            default:
2149a8e1175bSopenharmony_ci                MBEDTLS_SSL_PRINT_EXT(
2150a8e1175bSopenharmony_ci                    3, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
2151a8e1175bSopenharmony_ci                    extension_type, "( ignored )");
2152a8e1175bSopenharmony_ci                break;
2153a8e1175bSopenharmony_ci        }
2154a8e1175bSopenharmony_ci
2155a8e1175bSopenharmony_ci        p += extension_data_len;
2156a8e1175bSopenharmony_ci    }
2157a8e1175bSopenharmony_ci
2158a8e1175bSopenharmony_ci    if ((handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(RECORD_SIZE_LIMIT)) &&
2159a8e1175bSopenharmony_ci        (handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(MAX_FRAGMENT_LENGTH))) {
2160a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3,
2161a8e1175bSopenharmony_ci                              (
2162a8e1175bSopenharmony_ci                                  "Record size limit extension cannot be used with max fragment length extension"));
2163a8e1175bSopenharmony_ci        MBEDTLS_SSL_PEND_FATAL_ALERT(
2164a8e1175bSopenharmony_ci            MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
2165a8e1175bSopenharmony_ci            MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
2166a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
2167a8e1175bSopenharmony_ci    }
2168a8e1175bSopenharmony_ci
2169a8e1175bSopenharmony_ci    MBEDTLS_SSL_PRINT_EXTS(3, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
2170a8e1175bSopenharmony_ci                           handshake->received_extensions);
2171a8e1175bSopenharmony_ci
2172a8e1175bSopenharmony_ci    /* Check that we consumed all the message. */
2173a8e1175bSopenharmony_ci    if (p != end) {
2174a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("EncryptedExtension lengths misaligned"));
2175a8e1175bSopenharmony_ci        MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
2176a8e1175bSopenharmony_ci                                     MBEDTLS_ERR_SSL_DECODE_ERROR);
2177a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_DECODE_ERROR;
2178a8e1175bSopenharmony_ci    }
2179a8e1175bSopenharmony_ci
2180a8e1175bSopenharmony_ci    return ret;
2181a8e1175bSopenharmony_ci}
2182a8e1175bSopenharmony_ci
2183a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2184a8e1175bSopenharmony_cistatic int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl)
2185a8e1175bSopenharmony_ci{
2186a8e1175bSopenharmony_ci    int ret;
2187a8e1175bSopenharmony_ci    unsigned char *buf;
2188a8e1175bSopenharmony_ci    size_t buf_len;
2189a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
2190a8e1175bSopenharmony_ci
2191a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse encrypted extensions"));
2192a8e1175bSopenharmony_ci
2193a8e1175bSopenharmony_ci    MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(
2194a8e1175bSopenharmony_ci                             ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
2195a8e1175bSopenharmony_ci                             &buf, &buf_len));
2196a8e1175bSopenharmony_ci
2197a8e1175bSopenharmony_ci    /* Process the message contents */
2198a8e1175bSopenharmony_ci    MBEDTLS_SSL_PROC_CHK(
2199a8e1175bSopenharmony_ci        ssl_tls13_parse_encrypted_extensions(ssl, buf, buf + buf_len));
2200a8e1175bSopenharmony_ci
2201a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
2202a8e1175bSopenharmony_ci    if (handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(EARLY_DATA)) {
2203a8e1175bSopenharmony_ci        /* RFC8446 4.2.11
2204a8e1175bSopenharmony_ci         * If the server supplies an "early_data" extension, the
2205a8e1175bSopenharmony_ci         * client MUST verify that the server's selected_identity
2206a8e1175bSopenharmony_ci         * is 0. If any other value is returned, the client MUST
2207a8e1175bSopenharmony_ci         * abort the handshake with an "illegal_parameter" alert.
2208a8e1175bSopenharmony_ci         *
2209a8e1175bSopenharmony_ci         * RFC 8446 4.2.10
2210a8e1175bSopenharmony_ci         * In order to accept early data, the server MUST have accepted a PSK
2211a8e1175bSopenharmony_ci         * cipher suite and selected the first key offered in the client's
2212a8e1175bSopenharmony_ci         * "pre_shared_key" extension. In addition, it MUST verify that the
2213a8e1175bSopenharmony_ci         * following values are the same as those associated with the
2214a8e1175bSopenharmony_ci         * selected PSK:
2215a8e1175bSopenharmony_ci         * - The TLS version number
2216a8e1175bSopenharmony_ci         * - The selected cipher suite
2217a8e1175bSopenharmony_ci         * - The selected ALPN [RFC7301] protocol, if any
2218a8e1175bSopenharmony_ci         *
2219a8e1175bSopenharmony_ci         * The server has sent an early data extension in its Encrypted
2220a8e1175bSopenharmony_ci         * Extension message thus accepted to receive early data. We
2221a8e1175bSopenharmony_ci         * check here that the additional constraints on the handshake
2222a8e1175bSopenharmony_ci         * parameters, when early data are exchanged, are met,
2223a8e1175bSopenharmony_ci         * namely:
2224a8e1175bSopenharmony_ci         * - a PSK has been selected for the handshake
2225a8e1175bSopenharmony_ci         * - the selected PSK for the handshake was the first one proposed
2226a8e1175bSopenharmony_ci         *   by the client.
2227a8e1175bSopenharmony_ci         * - the selected ciphersuite for the handshake is the ciphersuite
2228a8e1175bSopenharmony_ci         *   associated with the selected PSK.
2229a8e1175bSopenharmony_ci         */
2230a8e1175bSopenharmony_ci        if ((!mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) ||
2231a8e1175bSopenharmony_ci            handshake->selected_identity != 0 ||
2232a8e1175bSopenharmony_ci            handshake->ciphersuite_info->id !=
2233a8e1175bSopenharmony_ci            ssl->session_negotiate->ciphersuite) {
2234a8e1175bSopenharmony_ci
2235a8e1175bSopenharmony_ci            MBEDTLS_SSL_PEND_FATAL_ALERT(
2236a8e1175bSopenharmony_ci                MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
2237a8e1175bSopenharmony_ci                MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
2238a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
2239a8e1175bSopenharmony_ci        }
2240a8e1175bSopenharmony_ci
2241a8e1175bSopenharmony_ci        ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED;
2242a8e1175bSopenharmony_ci    } else if (ssl->early_data_state !=
2243a8e1175bSopenharmony_ci               MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT) {
2244a8e1175bSopenharmony_ci        ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED;
2245a8e1175bSopenharmony_ci    }
2246a8e1175bSopenharmony_ci#endif
2247a8e1175bSopenharmony_ci
2248a8e1175bSopenharmony_ci    /*
2249a8e1175bSopenharmony_ci     * In case the client has proposed a PSK associated with a ticket,
2250a8e1175bSopenharmony_ci     * `ssl->session_negotiate->ciphersuite` still contains at this point the
2251a8e1175bSopenharmony_ci     * identifier of the ciphersuite associated with the ticket. This is that
2252a8e1175bSopenharmony_ci     * way because, if an exchange of early data is agreed upon, we need
2253a8e1175bSopenharmony_ci     * it to check that the ciphersuite selected for the handshake is the
2254a8e1175bSopenharmony_ci     * ticket ciphersuite (see above). This information is not needed
2255a8e1175bSopenharmony_ci     * anymore thus we can now set it to the identifier of the ciphersuite
2256a8e1175bSopenharmony_ci     * used in this session under negotiation.
2257a8e1175bSopenharmony_ci     */
2258a8e1175bSopenharmony_ci    ssl->session_negotiate->ciphersuite = handshake->ciphersuite_info->id;
2259a8e1175bSopenharmony_ci
2260a8e1175bSopenharmony_ci    MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
2261a8e1175bSopenharmony_ci                             ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
2262a8e1175bSopenharmony_ci                             buf, buf_len));
2263a8e1175bSopenharmony_ci
2264a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
2265a8e1175bSopenharmony_ci    if (mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) {
2266a8e1175bSopenharmony_ci        mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_FINISHED);
2267a8e1175bSopenharmony_ci    } else {
2268a8e1175bSopenharmony_ci        mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CERTIFICATE_REQUEST);
2269a8e1175bSopenharmony_ci    }
2270a8e1175bSopenharmony_ci#else
2271a8e1175bSopenharmony_ci    ((void) ssl);
2272a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_FINISHED);
2273a8e1175bSopenharmony_ci#endif
2274a8e1175bSopenharmony_ci
2275a8e1175bSopenharmony_cicleanup:
2276a8e1175bSopenharmony_ci
2277a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse encrypted extensions"));
2278a8e1175bSopenharmony_ci    return ret;
2279a8e1175bSopenharmony_ci
2280a8e1175bSopenharmony_ci}
2281a8e1175bSopenharmony_ci
2282a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
2283a8e1175bSopenharmony_ci/*
2284a8e1175bSopenharmony_ci * Handler for MBEDTLS_SSL_END_OF_EARLY_DATA
2285a8e1175bSopenharmony_ci *
2286a8e1175bSopenharmony_ci * RFC 8446 section 4.5
2287a8e1175bSopenharmony_ci *
2288a8e1175bSopenharmony_ci * struct {} EndOfEarlyData;
2289a8e1175bSopenharmony_ci *
2290a8e1175bSopenharmony_ci * If the server sent an "early_data" extension in EncryptedExtensions, the
2291a8e1175bSopenharmony_ci * client MUST send an EndOfEarlyData message after receiving the server
2292a8e1175bSopenharmony_ci * Finished. Otherwise, the client MUST NOT send an EndOfEarlyData message.
2293a8e1175bSopenharmony_ci */
2294a8e1175bSopenharmony_ci
2295a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2296a8e1175bSopenharmony_cistatic int ssl_tls13_write_end_of_early_data(mbedtls_ssl_context *ssl)
2297a8e1175bSopenharmony_ci{
2298a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2299a8e1175bSopenharmony_ci    unsigned char *buf = NULL;
2300a8e1175bSopenharmony_ci    size_t buf_len;
2301a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> write EndOfEarlyData"));
2302a8e1175bSopenharmony_ci
2303a8e1175bSopenharmony_ci    MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(
2304a8e1175bSopenharmony_ci                             ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA,
2305a8e1175bSopenharmony_ci                             &buf, &buf_len));
2306a8e1175bSopenharmony_ci
2307a8e1175bSopenharmony_ci    MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_hdr_to_checksum(
2308a8e1175bSopenharmony_ci                             ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA, 0));
2309a8e1175bSopenharmony_ci
2310a8e1175bSopenharmony_ci    MBEDTLS_SSL_PROC_CHK(
2311a8e1175bSopenharmony_ci        mbedtls_ssl_finish_handshake_msg(ssl, buf_len, 0));
2312a8e1175bSopenharmony_ci
2313a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
2314a8e1175bSopenharmony_ci
2315a8e1175bSopenharmony_cicleanup:
2316a8e1175bSopenharmony_ci
2317a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= write EndOfEarlyData"));
2318a8e1175bSopenharmony_ci    return ret;
2319a8e1175bSopenharmony_ci}
2320a8e1175bSopenharmony_ci
2321a8e1175bSopenharmony_ciint mbedtls_ssl_get_early_data_status(mbedtls_ssl_context *ssl)
2322a8e1175bSopenharmony_ci{
2323a8e1175bSopenharmony_ci    if ((ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT) ||
2324a8e1175bSopenharmony_ci        (!mbedtls_ssl_is_handshake_over(ssl))) {
2325a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
2326a8e1175bSopenharmony_ci    }
2327a8e1175bSopenharmony_ci
2328a8e1175bSopenharmony_ci    switch (ssl->early_data_state) {
2329a8e1175bSopenharmony_ci        case MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT:
2330a8e1175bSopenharmony_ci            return MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_INDICATED;
2331a8e1175bSopenharmony_ci            break;
2332a8e1175bSopenharmony_ci
2333a8e1175bSopenharmony_ci        case MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED:
2334a8e1175bSopenharmony_ci            return MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
2335a8e1175bSopenharmony_ci            break;
2336a8e1175bSopenharmony_ci
2337a8e1175bSopenharmony_ci        case MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED:
2338a8e1175bSopenharmony_ci            return MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;
2339a8e1175bSopenharmony_ci            break;
2340a8e1175bSopenharmony_ci
2341a8e1175bSopenharmony_ci        default:
2342a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2343a8e1175bSopenharmony_ci    }
2344a8e1175bSopenharmony_ci}
2345a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EARLY_DATA */
2346a8e1175bSopenharmony_ci
2347a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
2348a8e1175bSopenharmony_ci/*
2349a8e1175bSopenharmony_ci * STATE HANDLING: CertificateRequest
2350a8e1175bSopenharmony_ci *
2351a8e1175bSopenharmony_ci */
2352a8e1175bSopenharmony_ci#define SSL_CERTIFICATE_REQUEST_EXPECT_REQUEST 0
2353a8e1175bSopenharmony_ci#define SSL_CERTIFICATE_REQUEST_SKIP           1
2354a8e1175bSopenharmony_ci/* Coordination:
2355a8e1175bSopenharmony_ci * Deals with the ambiguity of not knowing if a CertificateRequest
2356a8e1175bSopenharmony_ci * will be sent. Returns a negative code on failure, or
2357a8e1175bSopenharmony_ci * - SSL_CERTIFICATE_REQUEST_EXPECT_REQUEST
2358a8e1175bSopenharmony_ci * - SSL_CERTIFICATE_REQUEST_SKIP
2359a8e1175bSopenharmony_ci * indicating if a Certificate Request is expected or not.
2360a8e1175bSopenharmony_ci */
2361a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2362a8e1175bSopenharmony_cistatic int ssl_tls13_certificate_request_coordinate(mbedtls_ssl_context *ssl)
2363a8e1175bSopenharmony_ci{
2364a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2365a8e1175bSopenharmony_ci
2366a8e1175bSopenharmony_ci    if ((ret = mbedtls_ssl_read_record(ssl, 0)) != 0) {
2367a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
2368a8e1175bSopenharmony_ci        return ret;
2369a8e1175bSopenharmony_ci    }
2370a8e1175bSopenharmony_ci    ssl->keep_current_message = 1;
2371a8e1175bSopenharmony_ci
2372a8e1175bSopenharmony_ci    if ((ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) &&
2373a8e1175bSopenharmony_ci        (ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST)) {
2374a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3, ("got a certificate request"));
2375a8e1175bSopenharmony_ci        return SSL_CERTIFICATE_REQUEST_EXPECT_REQUEST;
2376a8e1175bSopenharmony_ci    }
2377a8e1175bSopenharmony_ci
2378a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3, ("got no certificate request"));
2379a8e1175bSopenharmony_ci
2380a8e1175bSopenharmony_ci    return SSL_CERTIFICATE_REQUEST_SKIP;
2381a8e1175bSopenharmony_ci}
2382a8e1175bSopenharmony_ci
2383a8e1175bSopenharmony_ci/*
2384a8e1175bSopenharmony_ci * ssl_tls13_parse_certificate_request()
2385a8e1175bSopenharmony_ci *     Parse certificate request
2386a8e1175bSopenharmony_ci * struct {
2387a8e1175bSopenharmony_ci *   opaque certificate_request_context<0..2^8-1>;
2388a8e1175bSopenharmony_ci *   Extension extensions<2..2^16-1>;
2389a8e1175bSopenharmony_ci * } CertificateRequest;
2390a8e1175bSopenharmony_ci */
2391a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2392a8e1175bSopenharmony_cistatic int ssl_tls13_parse_certificate_request(mbedtls_ssl_context *ssl,
2393a8e1175bSopenharmony_ci                                               const unsigned char *buf,
2394a8e1175bSopenharmony_ci                                               const unsigned char *end)
2395a8e1175bSopenharmony_ci{
2396a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2397a8e1175bSopenharmony_ci    const unsigned char *p = buf;
2398a8e1175bSopenharmony_ci    size_t certificate_request_context_len = 0;
2399a8e1175bSopenharmony_ci    size_t extensions_len = 0;
2400a8e1175bSopenharmony_ci    const unsigned char *extensions_end;
2401a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
2402a8e1175bSopenharmony_ci
2403a8e1175bSopenharmony_ci    /* ...
2404a8e1175bSopenharmony_ci     * opaque certificate_request_context<0..2^8-1>
2405a8e1175bSopenharmony_ci     * ...
2406a8e1175bSopenharmony_ci     */
2407a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 1);
2408a8e1175bSopenharmony_ci    certificate_request_context_len = (size_t) p[0];
2409a8e1175bSopenharmony_ci    p += 1;
2410a8e1175bSopenharmony_ci
2411a8e1175bSopenharmony_ci    if (certificate_request_context_len > 0) {
2412a8e1175bSopenharmony_ci        MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, certificate_request_context_len);
2413a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_BUF(3, "Certificate Request Context",
2414a8e1175bSopenharmony_ci                              p, certificate_request_context_len);
2415a8e1175bSopenharmony_ci
2416a8e1175bSopenharmony_ci        handshake->certificate_request_context =
2417a8e1175bSopenharmony_ci            mbedtls_calloc(1, certificate_request_context_len);
2418a8e1175bSopenharmony_ci        if (handshake->certificate_request_context == NULL) {
2419a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small"));
2420a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_ALLOC_FAILED;
2421a8e1175bSopenharmony_ci        }
2422a8e1175bSopenharmony_ci        memcpy(handshake->certificate_request_context, p,
2423a8e1175bSopenharmony_ci               certificate_request_context_len);
2424a8e1175bSopenharmony_ci        p += certificate_request_context_len;
2425a8e1175bSopenharmony_ci    }
2426a8e1175bSopenharmony_ci
2427a8e1175bSopenharmony_ci    /* ...
2428a8e1175bSopenharmony_ci     * Extension extensions<2..2^16-1>;
2429a8e1175bSopenharmony_ci     * ...
2430a8e1175bSopenharmony_ci     */
2431a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
2432a8e1175bSopenharmony_ci    extensions_len = MBEDTLS_GET_UINT16_BE(p, 0);
2433a8e1175bSopenharmony_ci    p += 2;
2434a8e1175bSopenharmony_ci
2435a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extensions_len);
2436a8e1175bSopenharmony_ci    extensions_end = p + extensions_len;
2437a8e1175bSopenharmony_ci
2438a8e1175bSopenharmony_ci    handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
2439a8e1175bSopenharmony_ci
2440a8e1175bSopenharmony_ci    while (p < extensions_end) {
2441a8e1175bSopenharmony_ci        unsigned int extension_type;
2442a8e1175bSopenharmony_ci        size_t extension_data_len;
2443a8e1175bSopenharmony_ci
2444a8e1175bSopenharmony_ci        MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, 4);
2445a8e1175bSopenharmony_ci        extension_type = MBEDTLS_GET_UINT16_BE(p, 0);
2446a8e1175bSopenharmony_ci        extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2);
2447a8e1175bSopenharmony_ci        p += 4;
2448a8e1175bSopenharmony_ci
2449a8e1175bSopenharmony_ci        MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, extension_data_len);
2450a8e1175bSopenharmony_ci
2451a8e1175bSopenharmony_ci        ret = mbedtls_ssl_tls13_check_received_extension(
2452a8e1175bSopenharmony_ci            ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, extension_type,
2453a8e1175bSopenharmony_ci            MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CR);
2454a8e1175bSopenharmony_ci        if (ret != 0) {
2455a8e1175bSopenharmony_ci            return ret;
2456a8e1175bSopenharmony_ci        }
2457a8e1175bSopenharmony_ci
2458a8e1175bSopenharmony_ci        switch (extension_type) {
2459a8e1175bSopenharmony_ci            case MBEDTLS_TLS_EXT_SIG_ALG:
2460a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(3,
2461a8e1175bSopenharmony_ci                                      ("found signature algorithms extension"));
2462a8e1175bSopenharmony_ci                ret = mbedtls_ssl_parse_sig_alg_ext(ssl, p,
2463a8e1175bSopenharmony_ci                                                    p + extension_data_len);
2464a8e1175bSopenharmony_ci                if (ret != 0) {
2465a8e1175bSopenharmony_ci                    return ret;
2466a8e1175bSopenharmony_ci                }
2467a8e1175bSopenharmony_ci
2468a8e1175bSopenharmony_ci                break;
2469a8e1175bSopenharmony_ci
2470a8e1175bSopenharmony_ci            default:
2471a8e1175bSopenharmony_ci                MBEDTLS_SSL_PRINT_EXT(
2472a8e1175bSopenharmony_ci                    3, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
2473a8e1175bSopenharmony_ci                    extension_type, "( ignored )");
2474a8e1175bSopenharmony_ci                break;
2475a8e1175bSopenharmony_ci        }
2476a8e1175bSopenharmony_ci
2477a8e1175bSopenharmony_ci        p += extension_data_len;
2478a8e1175bSopenharmony_ci    }
2479a8e1175bSopenharmony_ci
2480a8e1175bSopenharmony_ci    MBEDTLS_SSL_PRINT_EXTS(3, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
2481a8e1175bSopenharmony_ci                           handshake->received_extensions);
2482a8e1175bSopenharmony_ci
2483a8e1175bSopenharmony_ci    /* Check that we consumed all the message. */
2484a8e1175bSopenharmony_ci    if (p != end) {
2485a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1,
2486a8e1175bSopenharmony_ci                              ("CertificateRequest misaligned"));
2487a8e1175bSopenharmony_ci        goto decode_error;
2488a8e1175bSopenharmony_ci    }
2489a8e1175bSopenharmony_ci
2490a8e1175bSopenharmony_ci    /* RFC 8446 section 4.3.2
2491a8e1175bSopenharmony_ci     *
2492a8e1175bSopenharmony_ci     * The "signature_algorithms" extension MUST be specified
2493a8e1175bSopenharmony_ci     */
2494a8e1175bSopenharmony_ci    if ((handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(SIG_ALG)) == 0) {
2495a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3,
2496a8e1175bSopenharmony_ci                              ("no signature algorithms extension found"));
2497a8e1175bSopenharmony_ci        goto decode_error;
2498a8e1175bSopenharmony_ci    }
2499a8e1175bSopenharmony_ci
2500a8e1175bSopenharmony_ci    ssl->handshake->client_auth = 1;
2501a8e1175bSopenharmony_ci    return 0;
2502a8e1175bSopenharmony_ci
2503a8e1175bSopenharmony_cidecode_error:
2504a8e1175bSopenharmony_ci    MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
2505a8e1175bSopenharmony_ci                                 MBEDTLS_ERR_SSL_DECODE_ERROR);
2506a8e1175bSopenharmony_ci    return MBEDTLS_ERR_SSL_DECODE_ERROR;
2507a8e1175bSopenharmony_ci}
2508a8e1175bSopenharmony_ci
2509a8e1175bSopenharmony_ci/*
2510a8e1175bSopenharmony_ci * Handler for  MBEDTLS_SSL_CERTIFICATE_REQUEST
2511a8e1175bSopenharmony_ci */
2512a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2513a8e1175bSopenharmony_cistatic int ssl_tls13_process_certificate_request(mbedtls_ssl_context *ssl)
2514a8e1175bSopenharmony_ci{
2515a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2516a8e1175bSopenharmony_ci
2517a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate request"));
2518a8e1175bSopenharmony_ci
2519a8e1175bSopenharmony_ci    MBEDTLS_SSL_PROC_CHK_NEG(ssl_tls13_certificate_request_coordinate(ssl));
2520a8e1175bSopenharmony_ci
2521a8e1175bSopenharmony_ci    if (ret == SSL_CERTIFICATE_REQUEST_EXPECT_REQUEST) {
2522a8e1175bSopenharmony_ci        unsigned char *buf;
2523a8e1175bSopenharmony_ci        size_t buf_len;
2524a8e1175bSopenharmony_ci
2525a8e1175bSopenharmony_ci        MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(
2526a8e1175bSopenharmony_ci                                 ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
2527a8e1175bSopenharmony_ci                                 &buf, &buf_len));
2528a8e1175bSopenharmony_ci
2529a8e1175bSopenharmony_ci        MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_certificate_request(
2530a8e1175bSopenharmony_ci                                 ssl, buf, buf + buf_len));
2531a8e1175bSopenharmony_ci
2532a8e1175bSopenharmony_ci        MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
2533a8e1175bSopenharmony_ci                                 ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
2534a8e1175bSopenharmony_ci                                 buf, buf_len));
2535a8e1175bSopenharmony_ci    } else if (ret == SSL_CERTIFICATE_REQUEST_SKIP) {
2536a8e1175bSopenharmony_ci        ret = 0;
2537a8e1175bSopenharmony_ci    } else {
2538a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2539a8e1175bSopenharmony_ci        ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2540a8e1175bSopenharmony_ci        goto cleanup;
2541a8e1175bSopenharmony_ci    }
2542a8e1175bSopenharmony_ci
2543a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_CERTIFICATE);
2544a8e1175bSopenharmony_ci
2545a8e1175bSopenharmony_cicleanup:
2546a8e1175bSopenharmony_ci
2547a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate request"));
2548a8e1175bSopenharmony_ci    return ret;
2549a8e1175bSopenharmony_ci}
2550a8e1175bSopenharmony_ci
2551a8e1175bSopenharmony_ci/*
2552a8e1175bSopenharmony_ci * Handler for MBEDTLS_SSL_SERVER_CERTIFICATE
2553a8e1175bSopenharmony_ci */
2554a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2555a8e1175bSopenharmony_cistatic int ssl_tls13_process_server_certificate(mbedtls_ssl_context *ssl)
2556a8e1175bSopenharmony_ci{
2557a8e1175bSopenharmony_ci    int ret;
2558a8e1175bSopenharmony_ci
2559a8e1175bSopenharmony_ci    ret = mbedtls_ssl_tls13_process_certificate(ssl);
2560a8e1175bSopenharmony_ci    if (ret != 0) {
2561a8e1175bSopenharmony_ci        return ret;
2562a8e1175bSopenharmony_ci    }
2563a8e1175bSopenharmony_ci
2564a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CERTIFICATE_VERIFY);
2565a8e1175bSopenharmony_ci    return 0;
2566a8e1175bSopenharmony_ci}
2567a8e1175bSopenharmony_ci
2568a8e1175bSopenharmony_ci/*
2569a8e1175bSopenharmony_ci * Handler for MBEDTLS_SSL_CERTIFICATE_VERIFY
2570a8e1175bSopenharmony_ci */
2571a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2572a8e1175bSopenharmony_cistatic int ssl_tls13_process_certificate_verify(mbedtls_ssl_context *ssl)
2573a8e1175bSopenharmony_ci{
2574a8e1175bSopenharmony_ci    int ret;
2575a8e1175bSopenharmony_ci
2576a8e1175bSopenharmony_ci    ret = mbedtls_ssl_tls13_process_certificate_verify(ssl);
2577a8e1175bSopenharmony_ci    if (ret != 0) {
2578a8e1175bSopenharmony_ci        return ret;
2579a8e1175bSopenharmony_ci    }
2580a8e1175bSopenharmony_ci
2581a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_FINISHED);
2582a8e1175bSopenharmony_ci    return 0;
2583a8e1175bSopenharmony_ci}
2584a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
2585a8e1175bSopenharmony_ci
2586a8e1175bSopenharmony_ci/*
2587a8e1175bSopenharmony_ci * Handler for MBEDTLS_SSL_SERVER_FINISHED
2588a8e1175bSopenharmony_ci */
2589a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2590a8e1175bSopenharmony_cistatic int ssl_tls13_process_server_finished(mbedtls_ssl_context *ssl)
2591a8e1175bSopenharmony_ci{
2592a8e1175bSopenharmony_ci    int ret;
2593a8e1175bSopenharmony_ci
2594a8e1175bSopenharmony_ci    ret = mbedtls_ssl_tls13_process_finished_message(ssl);
2595a8e1175bSopenharmony_ci    if (ret != 0) {
2596a8e1175bSopenharmony_ci        return ret;
2597a8e1175bSopenharmony_ci    }
2598a8e1175bSopenharmony_ci
2599a8e1175bSopenharmony_ci    ret = mbedtls_ssl_tls13_compute_application_transform(ssl);
2600a8e1175bSopenharmony_ci    if (ret != 0) {
2601a8e1175bSopenharmony_ci        MBEDTLS_SSL_PEND_FATAL_ALERT(
2602a8e1175bSopenharmony_ci            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
2603a8e1175bSopenharmony_ci            MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
2604a8e1175bSopenharmony_ci        return ret;
2605a8e1175bSopenharmony_ci    }
2606a8e1175bSopenharmony_ci
2607a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
2608a8e1175bSopenharmony_ci    if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED) {
2609a8e1175bSopenharmony_ci        ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED;
2610a8e1175bSopenharmony_ci        mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_END_OF_EARLY_DATA);
2611a8e1175bSopenharmony_ci    } else
2612a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EARLY_DATA */
2613a8e1175bSopenharmony_ci    {
2614a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
2615a8e1175bSopenharmony_ci        mbedtls_ssl_handshake_set_state(
2616a8e1175bSopenharmony_ci            ssl, MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED);
2617a8e1175bSopenharmony_ci#else
2618a8e1175bSopenharmony_ci        mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
2619a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
2620a8e1175bSopenharmony_ci    }
2621a8e1175bSopenharmony_ci
2622a8e1175bSopenharmony_ci    return 0;
2623a8e1175bSopenharmony_ci}
2624a8e1175bSopenharmony_ci
2625a8e1175bSopenharmony_ci/*
2626a8e1175bSopenharmony_ci * Handler for MBEDTLS_SSL_CLIENT_CERTIFICATE
2627a8e1175bSopenharmony_ci */
2628a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2629a8e1175bSopenharmony_cistatic int ssl_tls13_write_client_certificate(mbedtls_ssl_context *ssl)
2630a8e1175bSopenharmony_ci{
2631a8e1175bSopenharmony_ci    int non_empty_certificate_msg = 0;
2632a8e1175bSopenharmony_ci
2633a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(1,
2634a8e1175bSopenharmony_ci                          ("Switch to handshake traffic keys for outbound traffic"));
2635a8e1175bSopenharmony_ci    mbedtls_ssl_set_outbound_transform(ssl, ssl->handshake->transform_handshake);
2636a8e1175bSopenharmony_ci
2637a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
2638a8e1175bSopenharmony_ci    if (ssl->handshake->client_auth) {
2639a8e1175bSopenharmony_ci        int ret = mbedtls_ssl_tls13_write_certificate(ssl);
2640a8e1175bSopenharmony_ci        if (ret != 0) {
2641a8e1175bSopenharmony_ci            return ret;
2642a8e1175bSopenharmony_ci        }
2643a8e1175bSopenharmony_ci
2644a8e1175bSopenharmony_ci        if (mbedtls_ssl_own_cert(ssl) != NULL) {
2645a8e1175bSopenharmony_ci            non_empty_certificate_msg = 1;
2646a8e1175bSopenharmony_ci        }
2647a8e1175bSopenharmony_ci    } else {
2648a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(2, ("skip write certificate"));
2649a8e1175bSopenharmony_ci    }
2650a8e1175bSopenharmony_ci#endif
2651a8e1175bSopenharmony_ci
2652a8e1175bSopenharmony_ci    if (non_empty_certificate_msg) {
2653a8e1175bSopenharmony_ci        mbedtls_ssl_handshake_set_state(ssl,
2654a8e1175bSopenharmony_ci                                        MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY);
2655a8e1175bSopenharmony_ci    } else {
2656a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(2, ("skip write certificate verify"));
2657a8e1175bSopenharmony_ci        mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_FINISHED);
2658a8e1175bSopenharmony_ci    }
2659a8e1175bSopenharmony_ci
2660a8e1175bSopenharmony_ci    return 0;
2661a8e1175bSopenharmony_ci}
2662a8e1175bSopenharmony_ci
2663a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
2664a8e1175bSopenharmony_ci/*
2665a8e1175bSopenharmony_ci * Handler for MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY
2666a8e1175bSopenharmony_ci */
2667a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2668a8e1175bSopenharmony_cistatic int ssl_tls13_write_client_certificate_verify(mbedtls_ssl_context *ssl)
2669a8e1175bSopenharmony_ci{
2670a8e1175bSopenharmony_ci    int ret = mbedtls_ssl_tls13_write_certificate_verify(ssl);
2671a8e1175bSopenharmony_ci
2672a8e1175bSopenharmony_ci    if (ret == 0) {
2673a8e1175bSopenharmony_ci        mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_FINISHED);
2674a8e1175bSopenharmony_ci    }
2675a8e1175bSopenharmony_ci
2676a8e1175bSopenharmony_ci    return ret;
2677a8e1175bSopenharmony_ci}
2678a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
2679a8e1175bSopenharmony_ci
2680a8e1175bSopenharmony_ci/*
2681a8e1175bSopenharmony_ci * Handler for MBEDTLS_SSL_CLIENT_FINISHED
2682a8e1175bSopenharmony_ci */
2683a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2684a8e1175bSopenharmony_cistatic int ssl_tls13_write_client_finished(mbedtls_ssl_context *ssl)
2685a8e1175bSopenharmony_ci{
2686a8e1175bSopenharmony_ci    int ret;
2687a8e1175bSopenharmony_ci
2688a8e1175bSopenharmony_ci    ret = mbedtls_ssl_tls13_write_finished_message(ssl);
2689a8e1175bSopenharmony_ci    if (ret != 0) {
2690a8e1175bSopenharmony_ci        return ret;
2691a8e1175bSopenharmony_ci    }
2692a8e1175bSopenharmony_ci
2693a8e1175bSopenharmony_ci    ret = mbedtls_ssl_tls13_compute_resumption_master_secret(ssl);
2694a8e1175bSopenharmony_ci    if (ret != 0) {
2695a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_RET(
2696a8e1175bSopenharmony_ci            1, "mbedtls_ssl_tls13_compute_resumption_master_secret ", ret);
2697a8e1175bSopenharmony_ci        return ret;
2698a8e1175bSopenharmony_ci    }
2699a8e1175bSopenharmony_ci
2700a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_FLUSH_BUFFERS);
2701a8e1175bSopenharmony_ci    return 0;
2702a8e1175bSopenharmony_ci}
2703a8e1175bSopenharmony_ci
2704a8e1175bSopenharmony_ci/*
2705a8e1175bSopenharmony_ci * Handler for MBEDTLS_SSL_FLUSH_BUFFERS
2706a8e1175bSopenharmony_ci */
2707a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2708a8e1175bSopenharmony_cistatic int ssl_tls13_flush_buffers(mbedtls_ssl_context *ssl)
2709a8e1175bSopenharmony_ci{
2710a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done"));
2711a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP);
2712a8e1175bSopenharmony_ci    return 0;
2713a8e1175bSopenharmony_ci}
2714a8e1175bSopenharmony_ci
2715a8e1175bSopenharmony_ci/*
2716a8e1175bSopenharmony_ci * Handler for MBEDTLS_SSL_HANDSHAKE_WRAPUP
2717a8e1175bSopenharmony_ci */
2718a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2719a8e1175bSopenharmony_cistatic int ssl_tls13_handshake_wrapup(mbedtls_ssl_context *ssl)
2720a8e1175bSopenharmony_ci{
2721a8e1175bSopenharmony_ci
2722a8e1175bSopenharmony_ci    mbedtls_ssl_tls13_handshake_wrapup(ssl);
2723a8e1175bSopenharmony_ci
2724a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER);
2725a8e1175bSopenharmony_ci    return 0;
2726a8e1175bSopenharmony_ci}
2727a8e1175bSopenharmony_ci
2728a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS)
2729a8e1175bSopenharmony_ci
2730a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
2731a8e1175bSopenharmony_ci/* From RFC 8446 section 4.2.10
2732a8e1175bSopenharmony_ci *
2733a8e1175bSopenharmony_ci * struct {
2734a8e1175bSopenharmony_ci *     select (Handshake.msg_type) {
2735a8e1175bSopenharmony_ci *         case new_session_ticket:   uint32 max_early_data_size;
2736a8e1175bSopenharmony_ci *         ...
2737a8e1175bSopenharmony_ci *     };
2738a8e1175bSopenharmony_ci * } EarlyDataIndication;
2739a8e1175bSopenharmony_ci */
2740a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2741a8e1175bSopenharmony_cistatic int ssl_tls13_parse_new_session_ticket_early_data_ext(
2742a8e1175bSopenharmony_ci    mbedtls_ssl_context *ssl,
2743a8e1175bSopenharmony_ci    const unsigned char *buf,
2744a8e1175bSopenharmony_ci    const unsigned char *end)
2745a8e1175bSopenharmony_ci{
2746a8e1175bSopenharmony_ci    mbedtls_ssl_session *session = ssl->session;
2747a8e1175bSopenharmony_ci
2748a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(buf, end, 4);
2749a8e1175bSopenharmony_ci
2750a8e1175bSopenharmony_ci    session->max_early_data_size = MBEDTLS_GET_UINT32_BE(buf, 0);
2751a8e1175bSopenharmony_ci    mbedtls_ssl_tls13_session_set_ticket_flags(
2752a8e1175bSopenharmony_ci        session, MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA);
2753a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(
2754a8e1175bSopenharmony_ci        3, ("received max_early_data_size: %u",
2755a8e1175bSopenharmony_ci            (unsigned int) session->max_early_data_size));
2756a8e1175bSopenharmony_ci
2757a8e1175bSopenharmony_ci    return 0;
2758a8e1175bSopenharmony_ci}
2759a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EARLY_DATA */
2760a8e1175bSopenharmony_ci
2761a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2762a8e1175bSopenharmony_cistatic int ssl_tls13_parse_new_session_ticket_exts(mbedtls_ssl_context *ssl,
2763a8e1175bSopenharmony_ci                                                   const unsigned char *buf,
2764a8e1175bSopenharmony_ci                                                   const unsigned char *end)
2765a8e1175bSopenharmony_ci{
2766a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_params *handshake = ssl->handshake;
2767a8e1175bSopenharmony_ci    const unsigned char *p = buf;
2768a8e1175bSopenharmony_ci
2769a8e1175bSopenharmony_ci
2770a8e1175bSopenharmony_ci    handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
2771a8e1175bSopenharmony_ci
2772a8e1175bSopenharmony_ci    while (p < end) {
2773a8e1175bSopenharmony_ci        unsigned int extension_type;
2774a8e1175bSopenharmony_ci        size_t extension_data_len;
2775a8e1175bSopenharmony_ci        int ret;
2776a8e1175bSopenharmony_ci
2777a8e1175bSopenharmony_ci        MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 4);
2778a8e1175bSopenharmony_ci        extension_type = MBEDTLS_GET_UINT16_BE(p, 0);
2779a8e1175bSopenharmony_ci        extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2);
2780a8e1175bSopenharmony_ci        p += 4;
2781a8e1175bSopenharmony_ci
2782a8e1175bSopenharmony_ci        MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extension_data_len);
2783a8e1175bSopenharmony_ci
2784a8e1175bSopenharmony_ci        ret = mbedtls_ssl_tls13_check_received_extension(
2785a8e1175bSopenharmony_ci            ssl, MBEDTLS_SSL_HS_NEW_SESSION_TICKET, extension_type,
2786a8e1175bSopenharmony_ci            MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_NST);
2787a8e1175bSopenharmony_ci        if (ret != 0) {
2788a8e1175bSopenharmony_ci            return ret;
2789a8e1175bSopenharmony_ci        }
2790a8e1175bSopenharmony_ci
2791a8e1175bSopenharmony_ci        switch (extension_type) {
2792a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
2793a8e1175bSopenharmony_ci            case MBEDTLS_TLS_EXT_EARLY_DATA:
2794a8e1175bSopenharmony_ci                ret = ssl_tls13_parse_new_session_ticket_early_data_ext(
2795a8e1175bSopenharmony_ci                    ssl, p, p + extension_data_len);
2796a8e1175bSopenharmony_ci                if (ret != 0) {
2797a8e1175bSopenharmony_ci                    MBEDTLS_SSL_DEBUG_RET(
2798a8e1175bSopenharmony_ci                        1, "ssl_tls13_parse_new_session_ticket_early_data_ext",
2799a8e1175bSopenharmony_ci                        ret);
2800a8e1175bSopenharmony_ci                }
2801a8e1175bSopenharmony_ci                break;
2802a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EARLY_DATA */
2803a8e1175bSopenharmony_ci
2804a8e1175bSopenharmony_ci            default:
2805a8e1175bSopenharmony_ci                MBEDTLS_SSL_PRINT_EXT(
2806a8e1175bSopenharmony_ci                    3, MBEDTLS_SSL_HS_NEW_SESSION_TICKET,
2807a8e1175bSopenharmony_ci                    extension_type, "( ignored )");
2808a8e1175bSopenharmony_ci                break;
2809a8e1175bSopenharmony_ci        }
2810a8e1175bSopenharmony_ci
2811a8e1175bSopenharmony_ci        p +=  extension_data_len;
2812a8e1175bSopenharmony_ci    }
2813a8e1175bSopenharmony_ci
2814a8e1175bSopenharmony_ci    MBEDTLS_SSL_PRINT_EXTS(3, MBEDTLS_SSL_HS_NEW_SESSION_TICKET,
2815a8e1175bSopenharmony_ci                           handshake->received_extensions);
2816a8e1175bSopenharmony_ci
2817a8e1175bSopenharmony_ci    return 0;
2818a8e1175bSopenharmony_ci}
2819a8e1175bSopenharmony_ci
2820a8e1175bSopenharmony_ci/*
2821a8e1175bSopenharmony_ci * From RFC8446, page 74
2822a8e1175bSopenharmony_ci *
2823a8e1175bSopenharmony_ci * struct {
2824a8e1175bSopenharmony_ci *    uint32 ticket_lifetime;
2825a8e1175bSopenharmony_ci *    uint32 ticket_age_add;
2826a8e1175bSopenharmony_ci *    opaque ticket_nonce<0..255>;
2827a8e1175bSopenharmony_ci *    opaque ticket<1..2^16-1>;
2828a8e1175bSopenharmony_ci *    Extension extensions<0..2^16-2>;
2829a8e1175bSopenharmony_ci * } NewSessionTicket;
2830a8e1175bSopenharmony_ci *
2831a8e1175bSopenharmony_ci */
2832a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2833a8e1175bSopenharmony_cistatic int ssl_tls13_parse_new_session_ticket(mbedtls_ssl_context *ssl,
2834a8e1175bSopenharmony_ci                                              unsigned char *buf,
2835a8e1175bSopenharmony_ci                                              unsigned char *end,
2836a8e1175bSopenharmony_ci                                              unsigned char **ticket_nonce,
2837a8e1175bSopenharmony_ci                                              size_t *ticket_nonce_len)
2838a8e1175bSopenharmony_ci{
2839a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2840a8e1175bSopenharmony_ci    unsigned char *p = buf;
2841a8e1175bSopenharmony_ci    mbedtls_ssl_session *session = ssl->session;
2842a8e1175bSopenharmony_ci    size_t ticket_len;
2843a8e1175bSopenharmony_ci    unsigned char *ticket;
2844a8e1175bSopenharmony_ci    size_t extensions_len;
2845a8e1175bSopenharmony_ci
2846a8e1175bSopenharmony_ci    *ticket_nonce = NULL;
2847a8e1175bSopenharmony_ci    *ticket_nonce_len = 0;
2848a8e1175bSopenharmony_ci    /*
2849a8e1175bSopenharmony_ci     *    ticket_lifetime   4 bytes
2850a8e1175bSopenharmony_ci     *    ticket_age_add    4 bytes
2851a8e1175bSopenharmony_ci     *    ticket_nonce_len  1 byte
2852a8e1175bSopenharmony_ci     */
2853a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 9);
2854a8e1175bSopenharmony_ci
2855a8e1175bSopenharmony_ci    session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0);
2856a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3,
2857a8e1175bSopenharmony_ci                          ("ticket_lifetime: %u",
2858a8e1175bSopenharmony_ci                           (unsigned int) session->ticket_lifetime));
2859a8e1175bSopenharmony_ci    if (session->ticket_lifetime >
2860a8e1175bSopenharmony_ci        MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME) {
2861a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(3, ("ticket_lifetime exceeds 7 days."));
2862a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
2863a8e1175bSopenharmony_ci    }
2864a8e1175bSopenharmony_ci
2865a8e1175bSopenharmony_ci    session->ticket_age_add = MBEDTLS_GET_UINT32_BE(p, 4);
2866a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(3,
2867a8e1175bSopenharmony_ci                          ("ticket_age_add: %u",
2868a8e1175bSopenharmony_ci                           (unsigned int) session->ticket_age_add));
2869a8e1175bSopenharmony_ci
2870a8e1175bSopenharmony_ci    *ticket_nonce_len = p[8];
2871a8e1175bSopenharmony_ci    p += 9;
2872a8e1175bSopenharmony_ci
2873a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, *ticket_nonce_len);
2874a8e1175bSopenharmony_ci    *ticket_nonce = p;
2875a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(3, "ticket_nonce:", *ticket_nonce, *ticket_nonce_len);
2876a8e1175bSopenharmony_ci    p += *ticket_nonce_len;
2877a8e1175bSopenharmony_ci
2878a8e1175bSopenharmony_ci    /* Ticket */
2879a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
2880a8e1175bSopenharmony_ci    ticket_len = MBEDTLS_GET_UINT16_BE(p, 0);
2881a8e1175bSopenharmony_ci    p += 2;
2882a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, ticket_len);
2883a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(3, "received ticket", p, ticket_len);
2884a8e1175bSopenharmony_ci
2885a8e1175bSopenharmony_ci    /* Check if we previously received a ticket already. */
2886a8e1175bSopenharmony_ci    if (session->ticket != NULL || session->ticket_len > 0) {
2887a8e1175bSopenharmony_ci        mbedtls_free(session->ticket);
2888a8e1175bSopenharmony_ci        session->ticket = NULL;
2889a8e1175bSopenharmony_ci        session->ticket_len = 0;
2890a8e1175bSopenharmony_ci    }
2891a8e1175bSopenharmony_ci
2892a8e1175bSopenharmony_ci    if ((ticket = mbedtls_calloc(1, ticket_len)) == NULL) {
2893a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("ticket alloc failed"));
2894a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_ALLOC_FAILED;
2895a8e1175bSopenharmony_ci    }
2896a8e1175bSopenharmony_ci    memcpy(ticket, p, ticket_len);
2897a8e1175bSopenharmony_ci    p += ticket_len;
2898a8e1175bSopenharmony_ci    session->ticket = ticket;
2899a8e1175bSopenharmony_ci    session->ticket_len = ticket_len;
2900a8e1175bSopenharmony_ci
2901a8e1175bSopenharmony_ci    /* Clear all flags in ticket_flags */
2902a8e1175bSopenharmony_ci    mbedtls_ssl_tls13_session_clear_ticket_flags(
2903a8e1175bSopenharmony_ci        session, MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
2904a8e1175bSopenharmony_ci
2905a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
2906a8e1175bSopenharmony_ci    extensions_len = MBEDTLS_GET_UINT16_BE(p, 0);
2907a8e1175bSopenharmony_ci    p += 2;
2908a8e1175bSopenharmony_ci    MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extensions_len);
2909a8e1175bSopenharmony_ci
2910a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(3, "ticket extension", p, extensions_len);
2911a8e1175bSopenharmony_ci
2912a8e1175bSopenharmony_ci    ret = ssl_tls13_parse_new_session_ticket_exts(ssl, p, p + extensions_len);
2913a8e1175bSopenharmony_ci    if (ret != 0) {
2914a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_RET(1,
2915a8e1175bSopenharmony_ci                              "ssl_tls13_parse_new_session_ticket_exts",
2916a8e1175bSopenharmony_ci                              ret);
2917a8e1175bSopenharmony_ci        return ret;
2918a8e1175bSopenharmony_ci    }
2919a8e1175bSopenharmony_ci
2920a8e1175bSopenharmony_ci    return 0;
2921a8e1175bSopenharmony_ci}
2922a8e1175bSopenharmony_ci
2923a8e1175bSopenharmony_ci/* Non negative return values for ssl_tls13_postprocess_new_session_ticket().
2924a8e1175bSopenharmony_ci * - POSTPROCESS_NEW_SESSION_TICKET_SIGNAL, all good, we have to signal the
2925a8e1175bSopenharmony_ci *   application that a valid ticket has been received.
2926a8e1175bSopenharmony_ci * - POSTPROCESS_NEW_SESSION_TICKET_DISCARD, no fatal error, we keep the
2927a8e1175bSopenharmony_ci *   connection alive but we do not signal the ticket to the application.
2928a8e1175bSopenharmony_ci */
2929a8e1175bSopenharmony_ci#define POSTPROCESS_NEW_SESSION_TICKET_SIGNAL 0
2930a8e1175bSopenharmony_ci#define POSTPROCESS_NEW_SESSION_TICKET_DISCARD 1
2931a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
2932a8e1175bSopenharmony_cistatic int ssl_tls13_postprocess_new_session_ticket(mbedtls_ssl_context *ssl,
2933a8e1175bSopenharmony_ci                                                    unsigned char *ticket_nonce,
2934a8e1175bSopenharmony_ci                                                    size_t ticket_nonce_len)
2935a8e1175bSopenharmony_ci{
2936a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2937a8e1175bSopenharmony_ci    mbedtls_ssl_session *session = ssl->session;
2938a8e1175bSopenharmony_ci    const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
2939a8e1175bSopenharmony_ci    psa_algorithm_t psa_hash_alg;
2940a8e1175bSopenharmony_ci    int hash_length;
2941a8e1175bSopenharmony_ci
2942a8e1175bSopenharmony_ci    if (session->ticket_lifetime == 0) {
2943a8e1175bSopenharmony_ci        return POSTPROCESS_NEW_SESSION_TICKET_DISCARD;
2944a8e1175bSopenharmony_ci    }
2945a8e1175bSopenharmony_ci
2946a8e1175bSopenharmony_ci#if defined(MBEDTLS_HAVE_TIME)
2947a8e1175bSopenharmony_ci    /* Store ticket creation time */
2948a8e1175bSopenharmony_ci    session->ticket_reception_time = mbedtls_ms_time();
2949a8e1175bSopenharmony_ci#endif
2950a8e1175bSopenharmony_ci
2951a8e1175bSopenharmony_ci    ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(session->ciphersuite);
2952a8e1175bSopenharmony_ci    if (ciphersuite_info == NULL) {
2953a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
2954a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2955a8e1175bSopenharmony_ci    }
2956a8e1175bSopenharmony_ci
2957a8e1175bSopenharmony_ci    psa_hash_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac);
2958a8e1175bSopenharmony_ci    hash_length = PSA_HASH_LENGTH(psa_hash_alg);
2959a8e1175bSopenharmony_ci    if (hash_length == -1 ||
2960a8e1175bSopenharmony_ci        (size_t) hash_length > sizeof(session->resumption_key)) {
2961a8e1175bSopenharmony_ci        return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2962a8e1175bSopenharmony_ci    }
2963a8e1175bSopenharmony_ci
2964a8e1175bSopenharmony_ci
2965a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(3, "resumption_master_secret",
2966a8e1175bSopenharmony_ci                          session->app_secrets.resumption_master_secret,
2967a8e1175bSopenharmony_ci                          hash_length);
2968a8e1175bSopenharmony_ci
2969a8e1175bSopenharmony_ci    /* Compute resumption key
2970a8e1175bSopenharmony_ci     *
2971a8e1175bSopenharmony_ci     *  HKDF-Expand-Label( resumption_master_secret,
2972a8e1175bSopenharmony_ci     *                    "resumption", ticket_nonce, Hash.length )
2973a8e1175bSopenharmony_ci     */
2974a8e1175bSopenharmony_ci    ret = mbedtls_ssl_tls13_hkdf_expand_label(
2975a8e1175bSopenharmony_ci        psa_hash_alg,
2976a8e1175bSopenharmony_ci        session->app_secrets.resumption_master_secret,
2977a8e1175bSopenharmony_ci        hash_length,
2978a8e1175bSopenharmony_ci        MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(resumption),
2979a8e1175bSopenharmony_ci        ticket_nonce,
2980a8e1175bSopenharmony_ci        ticket_nonce_len,
2981a8e1175bSopenharmony_ci        session->resumption_key,
2982a8e1175bSopenharmony_ci        hash_length);
2983a8e1175bSopenharmony_ci
2984a8e1175bSopenharmony_ci    if (ret != 0) {
2985a8e1175bSopenharmony_ci        MBEDTLS_SSL_DEBUG_RET(2,
2986a8e1175bSopenharmony_ci                              "Creating the ticket-resumed PSK failed",
2987a8e1175bSopenharmony_ci                              ret);
2988a8e1175bSopenharmony_ci        return ret;
2989a8e1175bSopenharmony_ci    }
2990a8e1175bSopenharmony_ci
2991a8e1175bSopenharmony_ci    session->resumption_key_len = hash_length;
2992a8e1175bSopenharmony_ci
2993a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_BUF(3, "Ticket-resumed PSK",
2994a8e1175bSopenharmony_ci                          session->resumption_key,
2995a8e1175bSopenharmony_ci                          session->resumption_key_len);
2996a8e1175bSopenharmony_ci
2997a8e1175bSopenharmony_ci    /* Set ticket_flags depends on the selected key exchange modes */
2998a8e1175bSopenharmony_ci    mbedtls_ssl_tls13_session_set_ticket_flags(
2999a8e1175bSopenharmony_ci        session, ssl->conf->tls13_kex_modes);
3000a8e1175bSopenharmony_ci    MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags);
3001a8e1175bSopenharmony_ci
3002a8e1175bSopenharmony_ci    return POSTPROCESS_NEW_SESSION_TICKET_SIGNAL;
3003a8e1175bSopenharmony_ci}
3004a8e1175bSopenharmony_ci
3005a8e1175bSopenharmony_ci/*
3006a8e1175bSopenharmony_ci * Handler for MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET
3007a8e1175bSopenharmony_ci */
3008a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL
3009a8e1175bSopenharmony_cistatic int ssl_tls13_process_new_session_ticket(mbedtls_ssl_context *ssl)
3010a8e1175bSopenharmony_ci{
3011a8e1175bSopenharmony_ci    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
3012a8e1175bSopenharmony_ci    unsigned char *buf;
3013a8e1175bSopenharmony_ci    size_t buf_len;
3014a8e1175bSopenharmony_ci    unsigned char *ticket_nonce;
3015a8e1175bSopenharmony_ci    size_t ticket_nonce_len;
3016a8e1175bSopenharmony_ci
3017a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse new session ticket"));
3018a8e1175bSopenharmony_ci
3019a8e1175bSopenharmony_ci    MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(
3020a8e1175bSopenharmony_ci                             ssl, MBEDTLS_SSL_HS_NEW_SESSION_TICKET,
3021a8e1175bSopenharmony_ci                             &buf, &buf_len));
3022a8e1175bSopenharmony_ci
3023a8e1175bSopenharmony_ci    /*
3024a8e1175bSopenharmony_ci     * We are about to update (maybe only partially) ticket data thus block
3025a8e1175bSopenharmony_ci     * any session export for the time being.
3026a8e1175bSopenharmony_ci     */
3027a8e1175bSopenharmony_ci    ssl->session->exported = 1;
3028a8e1175bSopenharmony_ci
3029a8e1175bSopenharmony_ci    MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_new_session_ticket(
3030a8e1175bSopenharmony_ci                             ssl, buf, buf + buf_len,
3031a8e1175bSopenharmony_ci                             &ticket_nonce, &ticket_nonce_len));
3032a8e1175bSopenharmony_ci
3033a8e1175bSopenharmony_ci    MBEDTLS_SSL_PROC_CHK_NEG(ssl_tls13_postprocess_new_session_ticket(
3034a8e1175bSopenharmony_ci                                 ssl, ticket_nonce, ticket_nonce_len));
3035a8e1175bSopenharmony_ci
3036a8e1175bSopenharmony_ci    switch (ret) {
3037a8e1175bSopenharmony_ci        case POSTPROCESS_NEW_SESSION_TICKET_SIGNAL:
3038a8e1175bSopenharmony_ci            /*
3039a8e1175bSopenharmony_ci             * All good, we have received a new valid ticket, session data can
3040a8e1175bSopenharmony_ci             * be exported now and we signal the ticket to the application.
3041a8e1175bSopenharmony_ci             */
3042a8e1175bSopenharmony_ci            ssl->session->exported = 0;
3043a8e1175bSopenharmony_ci            ret = MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET;
3044a8e1175bSopenharmony_ci            break;
3045a8e1175bSopenharmony_ci
3046a8e1175bSopenharmony_ci        case POSTPROCESS_NEW_SESSION_TICKET_DISCARD:
3047a8e1175bSopenharmony_ci            ret = 0;
3048a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(2, ("Discard new session ticket"));
3049a8e1175bSopenharmony_ci            break;
3050a8e1175bSopenharmony_ci
3051a8e1175bSopenharmony_ci        default:
3052a8e1175bSopenharmony_ci            ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
3053a8e1175bSopenharmony_ci    }
3054a8e1175bSopenharmony_ci
3055a8e1175bSopenharmony_ci    mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER);
3056a8e1175bSopenharmony_ci
3057a8e1175bSopenharmony_cicleanup:
3058a8e1175bSopenharmony_ci
3059a8e1175bSopenharmony_ci    MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse new session ticket"));
3060a8e1175bSopenharmony_ci    return ret;
3061a8e1175bSopenharmony_ci}
3062a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS */
3063a8e1175bSopenharmony_ci
3064a8e1175bSopenharmony_ciint mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl)
3065a8e1175bSopenharmony_ci{
3066a8e1175bSopenharmony_ci    int ret = 0;
3067a8e1175bSopenharmony_ci
3068a8e1175bSopenharmony_ci    switch (ssl->state) {
3069a8e1175bSopenharmony_ci        case MBEDTLS_SSL_HELLO_REQUEST:
3070a8e1175bSopenharmony_ci            mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
3071a8e1175bSopenharmony_ci            break;
3072a8e1175bSopenharmony_ci
3073a8e1175bSopenharmony_ci        case MBEDTLS_SSL_CLIENT_HELLO:
3074a8e1175bSopenharmony_ci            ret = mbedtls_ssl_write_client_hello(ssl);
3075a8e1175bSopenharmony_ci            break;
3076a8e1175bSopenharmony_ci
3077a8e1175bSopenharmony_ci        case MBEDTLS_SSL_SERVER_HELLO:
3078a8e1175bSopenharmony_ci            ret = ssl_tls13_process_server_hello(ssl);
3079a8e1175bSopenharmony_ci            break;
3080a8e1175bSopenharmony_ci
3081a8e1175bSopenharmony_ci        case MBEDTLS_SSL_ENCRYPTED_EXTENSIONS:
3082a8e1175bSopenharmony_ci            ret = ssl_tls13_process_encrypted_extensions(ssl);
3083a8e1175bSopenharmony_ci            break;
3084a8e1175bSopenharmony_ci
3085a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
3086a8e1175bSopenharmony_ci        case MBEDTLS_SSL_CERTIFICATE_REQUEST:
3087a8e1175bSopenharmony_ci            ret = ssl_tls13_process_certificate_request(ssl);
3088a8e1175bSopenharmony_ci            break;
3089a8e1175bSopenharmony_ci
3090a8e1175bSopenharmony_ci        case MBEDTLS_SSL_SERVER_CERTIFICATE:
3091a8e1175bSopenharmony_ci            ret = ssl_tls13_process_server_certificate(ssl);
3092a8e1175bSopenharmony_ci            break;
3093a8e1175bSopenharmony_ci
3094a8e1175bSopenharmony_ci        case MBEDTLS_SSL_CERTIFICATE_VERIFY:
3095a8e1175bSopenharmony_ci            ret = ssl_tls13_process_certificate_verify(ssl);
3096a8e1175bSopenharmony_ci            break;
3097a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
3098a8e1175bSopenharmony_ci
3099a8e1175bSopenharmony_ci        case MBEDTLS_SSL_SERVER_FINISHED:
3100a8e1175bSopenharmony_ci            ret = ssl_tls13_process_server_finished(ssl);
3101a8e1175bSopenharmony_ci            break;
3102a8e1175bSopenharmony_ci
3103a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
3104a8e1175bSopenharmony_ci        case MBEDTLS_SSL_END_OF_EARLY_DATA:
3105a8e1175bSopenharmony_ci            ret = ssl_tls13_write_end_of_early_data(ssl);
3106a8e1175bSopenharmony_ci            break;
3107a8e1175bSopenharmony_ci#endif
3108a8e1175bSopenharmony_ci
3109a8e1175bSopenharmony_ci        case MBEDTLS_SSL_CLIENT_CERTIFICATE:
3110a8e1175bSopenharmony_ci            ret = ssl_tls13_write_client_certificate(ssl);
3111a8e1175bSopenharmony_ci            break;
3112a8e1175bSopenharmony_ci
3113a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
3114a8e1175bSopenharmony_ci        case MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY:
3115a8e1175bSopenharmony_ci            ret = ssl_tls13_write_client_certificate_verify(ssl);
3116a8e1175bSopenharmony_ci            break;
3117a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
3118a8e1175bSopenharmony_ci
3119a8e1175bSopenharmony_ci        case MBEDTLS_SSL_CLIENT_FINISHED:
3120a8e1175bSopenharmony_ci            ret = ssl_tls13_write_client_finished(ssl);
3121a8e1175bSopenharmony_ci            break;
3122a8e1175bSopenharmony_ci
3123a8e1175bSopenharmony_ci        case MBEDTLS_SSL_FLUSH_BUFFERS:
3124a8e1175bSopenharmony_ci            ret = ssl_tls13_flush_buffers(ssl);
3125a8e1175bSopenharmony_ci            break;
3126a8e1175bSopenharmony_ci
3127a8e1175bSopenharmony_ci        case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
3128a8e1175bSopenharmony_ci            ret = ssl_tls13_handshake_wrapup(ssl);
3129a8e1175bSopenharmony_ci            break;
3130a8e1175bSopenharmony_ci
3131a8e1175bSopenharmony_ci            /*
3132a8e1175bSopenharmony_ci             * Injection of dummy-CCS's for middlebox compatibility
3133a8e1175bSopenharmony_ci             */
3134a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
3135a8e1175bSopenharmony_ci        case MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO:
3136a8e1175bSopenharmony_ci            ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
3137a8e1175bSopenharmony_ci            if (ret != 0) {
3138a8e1175bSopenharmony_ci                break;
3139a8e1175bSopenharmony_ci            }
3140a8e1175bSopenharmony_ci            mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
3141a8e1175bSopenharmony_ci            break;
3142a8e1175bSopenharmony_ci
3143a8e1175bSopenharmony_ci        case MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED:
3144a8e1175bSopenharmony_ci            ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
3145a8e1175bSopenharmony_ci            if (ret != 0) {
3146a8e1175bSopenharmony_ci                break;
3147a8e1175bSopenharmony_ci            }
3148a8e1175bSopenharmony_ci            mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
3149a8e1175bSopenharmony_ci            break;
3150a8e1175bSopenharmony_ci
3151a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EARLY_DATA)
3152a8e1175bSopenharmony_ci        case MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO:
3153a8e1175bSopenharmony_ci            ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
3154a8e1175bSopenharmony_ci            if (ret == 0) {
3155a8e1175bSopenharmony_ci                mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO);
3156a8e1175bSopenharmony_ci
3157a8e1175bSopenharmony_ci                MBEDTLS_SSL_DEBUG_MSG(
3158a8e1175bSopenharmony_ci                    1, ("Switch to early data keys for outbound traffic"));
3159a8e1175bSopenharmony_ci                mbedtls_ssl_set_outbound_transform(
3160a8e1175bSopenharmony_ci                    ssl, ssl->handshake->transform_earlydata);
3161a8e1175bSopenharmony_ci                ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE;
3162a8e1175bSopenharmony_ci            }
3163a8e1175bSopenharmony_ci            break;
3164a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EARLY_DATA */
3165a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
3166a8e1175bSopenharmony_ci
3167a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS)
3168a8e1175bSopenharmony_ci        case MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET:
3169a8e1175bSopenharmony_ci            ret = ssl_tls13_process_new_session_ticket(ssl);
3170a8e1175bSopenharmony_ci            break;
3171a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS */
3172a8e1175bSopenharmony_ci
3173a8e1175bSopenharmony_ci        default:
3174a8e1175bSopenharmony_ci            MBEDTLS_SSL_DEBUG_MSG(1, ("invalid state %d", ssl->state));
3175a8e1175bSopenharmony_ci            return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
3176a8e1175bSopenharmony_ci    }
3177a8e1175bSopenharmony_ci
3178a8e1175bSopenharmony_ci    return ret;
3179a8e1175bSopenharmony_ci}
3180a8e1175bSopenharmony_ci
3181a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_PROTO_TLS1_3 */
3182