xref: /optee_os/lib/libmbedtls/mbedtls/library/ssl_tls13_client.c (revision c3deb3d6f3b13d0e17fc9efe5880aec039e47594)
132b31808SJens Wiklander /*
232b31808SJens Wiklander  *  TLS 1.3 client-side functions
332b31808SJens Wiklander  *
432b31808SJens Wiklander  *  Copyright The Mbed TLS Contributors
5b0563631STom Van Eyck  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
632b31808SJens Wiklander  */
732b31808SJens Wiklander 
832b31808SJens Wiklander #include "common.h"
932b31808SJens Wiklander 
1032b31808SJens Wiklander #if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_PROTO_TLS1_3)
1132b31808SJens Wiklander 
1232b31808SJens Wiklander #include <string.h>
1332b31808SJens Wiklander 
14b0563631STom Van Eyck #include "debug_internal.h"
1532b31808SJens Wiklander #include "mbedtls/error.h"
1632b31808SJens Wiklander #include "mbedtls/platform.h"
1732b31808SJens Wiklander 
1832b31808SJens Wiklander #include "ssl_misc.h"
1932b31808SJens Wiklander #include "ssl_client.h"
2032b31808SJens Wiklander #include "ssl_tls13_keys.h"
2132b31808SJens Wiklander #include "ssl_debug_helpers.h"
22b0563631STom Van Eyck #include "mbedtls/psa_util.h"
2332b31808SJens Wiklander 
24b0563631STom Van Eyck #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
25b0563631STom Van Eyck /* Define a local translating function to save code size by not using too many
26b0563631STom Van Eyck  * arguments in each translating place. */
local_err_translation(psa_status_t status)27b0563631STom Van Eyck static int local_err_translation(psa_status_t status)
28b0563631STom Van Eyck {
29b0563631STom Van Eyck     return psa_status_to_mbedtls(status, psa_to_ssl_errors,
30b0563631STom Van Eyck                                  ARRAY_LENGTH(psa_to_ssl_errors),
31b0563631STom Van Eyck                                  psa_generic_status_to_mbedtls);
32b0563631STom Van Eyck }
33b0563631STom Van Eyck #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)
34b0563631STom Van Eyck #endif
3532b31808SJens Wiklander 
3632b31808SJens Wiklander /* Write extensions */
3732b31808SJens Wiklander 
3832b31808SJens Wiklander /*
3932b31808SJens Wiklander  * ssl_tls13_write_supported_versions_ext():
4032b31808SJens Wiklander  *
4132b31808SJens Wiklander  * struct {
4232b31808SJens Wiklander  *      ProtocolVersion versions<2..254>;
4332b31808SJens Wiklander  * } SupportedVersions;
4432b31808SJens Wiklander  */
4532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_write_supported_versions_ext(mbedtls_ssl_context * ssl,unsigned char * buf,unsigned char * end,size_t * out_len)4632b31808SJens Wiklander static int ssl_tls13_write_supported_versions_ext(mbedtls_ssl_context *ssl,
4732b31808SJens Wiklander                                                   unsigned char *buf,
4832b31808SJens Wiklander                                                   unsigned char *end,
4932b31808SJens Wiklander                                                   size_t *out_len)
5032b31808SJens Wiklander {
5132b31808SJens Wiklander     unsigned char *p = buf;
5232b31808SJens Wiklander     unsigned char versions_len = (ssl->handshake->min_tls_version <=
5332b31808SJens Wiklander                                   MBEDTLS_SSL_VERSION_TLS1_2) ? 4 : 2;
5432b31808SJens Wiklander 
5532b31808SJens Wiklander     *out_len = 0;
5632b31808SJens Wiklander 
5732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding supported versions extension"));
5832b31808SJens Wiklander 
5932b31808SJens Wiklander     /* Check if we have space to write the extension:
6032b31808SJens Wiklander      * - extension_type         (2 bytes)
6132b31808SJens Wiklander      * - extension_data_length  (2 bytes)
6232b31808SJens Wiklander      * - versions_length        (1 byte )
6332b31808SJens Wiklander      * - versions               (2 or 4 bytes)
6432b31808SJens Wiklander      */
6532b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 5 + versions_len);
6632b31808SJens Wiklander 
6732b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS, p, 0);
6832b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(versions_len + 1, p, 2);
6932b31808SJens Wiklander     p += 4;
7032b31808SJens Wiklander 
7132b31808SJens Wiklander     /* Length of versions */
7232b31808SJens Wiklander     *p++ = versions_len;
7332b31808SJens Wiklander 
7432b31808SJens Wiklander     /* Write values of supported versions.
7532b31808SJens Wiklander      * They are defined by the configuration.
7632b31808SJens Wiklander      * Currently, we advertise only TLS 1.3 or both TLS 1.3 and TLS 1.2.
7732b31808SJens Wiklander      */
7832b31808SJens Wiklander     mbedtls_ssl_write_version(p, MBEDTLS_SSL_TRANSPORT_STREAM,
7932b31808SJens Wiklander                               MBEDTLS_SSL_VERSION_TLS1_3);
8032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("supported version: [3:4]"));
8132b31808SJens Wiklander 
8232b31808SJens Wiklander 
8332b31808SJens Wiklander     if (ssl->handshake->min_tls_version <= MBEDTLS_SSL_VERSION_TLS1_2) {
8432b31808SJens Wiklander         mbedtls_ssl_write_version(p + 2, MBEDTLS_SSL_TRANSPORT_STREAM,
8532b31808SJens Wiklander                                   MBEDTLS_SSL_VERSION_TLS1_2);
8632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("supported version: [3:3]"));
8732b31808SJens Wiklander     }
8832b31808SJens Wiklander 
8932b31808SJens Wiklander     *out_len = 5 + versions_len;
9032b31808SJens Wiklander 
9132b31808SJens Wiklander     mbedtls_ssl_tls13_set_hs_sent_ext_mask(
9232b31808SJens Wiklander         ssl, MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS);
9332b31808SJens Wiklander 
9432b31808SJens Wiklander     return 0;
9532b31808SJens Wiklander }
9632b31808SJens Wiklander 
9732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_parse_supported_versions_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,const unsigned char * end)9832b31808SJens Wiklander static int ssl_tls13_parse_supported_versions_ext(mbedtls_ssl_context *ssl,
9932b31808SJens Wiklander                                                   const unsigned char *buf,
10032b31808SJens Wiklander                                                   const unsigned char *end)
10132b31808SJens Wiklander {
10232b31808SJens Wiklander     ((void) ssl);
10332b31808SJens Wiklander 
10432b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(buf, end, 2);
10532b31808SJens Wiklander     if (mbedtls_ssl_read_version(buf, ssl->conf->transport) !=
10632b31808SJens Wiklander         MBEDTLS_SSL_VERSION_TLS1_3) {
10732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("unexpected version"));
10832b31808SJens Wiklander 
10932b31808SJens Wiklander         MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
11032b31808SJens Wiklander                                      MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
11132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
11232b31808SJens Wiklander     }
11332b31808SJens Wiklander 
11432b31808SJens Wiklander     if (&buf[2] != end) {
115b0563631STom Van Eyck         MBEDTLS_SSL_DEBUG_MSG(
116b0563631STom Van Eyck             1, ("supported_versions ext data length incorrect"));
11732b31808SJens Wiklander         MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
11832b31808SJens Wiklander                                      MBEDTLS_ERR_SSL_DECODE_ERROR);
11932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
12032b31808SJens Wiklander     }
12132b31808SJens Wiklander 
12232b31808SJens Wiklander     return 0;
12332b31808SJens Wiklander }
12432b31808SJens Wiklander 
12532b31808SJens Wiklander #if defined(MBEDTLS_SSL_ALPN)
12632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_parse_alpn_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)12732b31808SJens Wiklander static int ssl_tls13_parse_alpn_ext(mbedtls_ssl_context *ssl,
12832b31808SJens Wiklander                                     const unsigned char *buf, size_t len)
12932b31808SJens Wiklander {
13032b31808SJens Wiklander     const unsigned char *p = buf;
13132b31808SJens Wiklander     const unsigned char *end = buf + len;
13232b31808SJens Wiklander     size_t protocol_name_list_len, protocol_name_len;
13332b31808SJens Wiklander     const unsigned char *protocol_name_list_end;
13432b31808SJens Wiklander 
13532b31808SJens Wiklander     /* If we didn't send it, the server shouldn't send it */
13632b31808SJens Wiklander     if (ssl->conf->alpn_list == NULL) {
13732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
13832b31808SJens Wiklander     }
13932b31808SJens Wiklander 
14032b31808SJens Wiklander     /*
14132b31808SJens Wiklander      * opaque ProtocolName<1..2^8-1>;
14232b31808SJens Wiklander      *
14332b31808SJens Wiklander      * struct {
14432b31808SJens Wiklander      *     ProtocolName protocol_name_list<2..2^16-1>
14532b31808SJens Wiklander      * } ProtocolNameList;
14632b31808SJens Wiklander      *
14732b31808SJens Wiklander      * the "ProtocolNameList" MUST contain exactly one "ProtocolName"
14832b31808SJens Wiklander      */
14932b31808SJens Wiklander 
15032b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
15132b31808SJens Wiklander     protocol_name_list_len = MBEDTLS_GET_UINT16_BE(p, 0);
15232b31808SJens Wiklander     p += 2;
15332b31808SJens Wiklander 
15432b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, protocol_name_list_len);
15532b31808SJens Wiklander     protocol_name_list_end = p + protocol_name_list_len;
15632b31808SJens Wiklander 
15732b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, protocol_name_list_end, 1);
15832b31808SJens Wiklander     protocol_name_len = *p++;
15932b31808SJens Wiklander 
16032b31808SJens Wiklander     /* Check that the server chosen protocol was in our list and save it */
16132b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, protocol_name_list_end, protocol_name_len);
16232b31808SJens Wiklander     for (const char **alpn = ssl->conf->alpn_list; *alpn != NULL; alpn++) {
16332b31808SJens Wiklander         if (protocol_name_len == strlen(*alpn) &&
16432b31808SJens Wiklander             memcmp(p, *alpn, protocol_name_len) == 0) {
16532b31808SJens Wiklander             ssl->alpn_chosen = *alpn;
16632b31808SJens Wiklander             return 0;
16732b31808SJens Wiklander         }
16832b31808SJens Wiklander     }
16932b31808SJens Wiklander 
17032b31808SJens Wiklander     return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
17132b31808SJens Wiklander }
17232b31808SJens Wiklander #endif /* MBEDTLS_SSL_ALPN */
17332b31808SJens Wiklander 
17432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_reset_key_share(mbedtls_ssl_context * ssl)17532b31808SJens Wiklander static int ssl_tls13_reset_key_share(mbedtls_ssl_context *ssl)
17632b31808SJens Wiklander {
17732b31808SJens Wiklander     uint16_t group_id = ssl->handshake->offered_group_id;
17832b31808SJens Wiklander 
17932b31808SJens Wiklander     if (group_id == 0) {
18032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
18132b31808SJens Wiklander     }
18232b31808SJens Wiklander 
183b0563631STom Van Eyck #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
184b0563631STom Van Eyck     if (mbedtls_ssl_tls13_named_group_is_ecdhe(group_id) ||
185b0563631STom Van Eyck         mbedtls_ssl_tls13_named_group_is_ffdh(group_id)) {
18632b31808SJens Wiklander         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
18732b31808SJens Wiklander         psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
18832b31808SJens Wiklander 
18932b31808SJens Wiklander         /* Destroy generated private key. */
190b0563631STom Van Eyck         status = psa_destroy_key(ssl->handshake->xxdh_psa_privkey);
19132b31808SJens Wiklander         if (status != PSA_SUCCESS) {
19232b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
19332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_destroy_key", ret);
19432b31808SJens Wiklander             return ret;
19532b31808SJens Wiklander         }
19632b31808SJens Wiklander 
197b0563631STom Van Eyck         ssl->handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
19832b31808SJens Wiklander         return 0;
19932b31808SJens Wiklander     } else
200b0563631STom Van Eyck #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */
20132b31808SJens Wiklander     if (0 /* other KEMs? */) {
20232b31808SJens Wiklander         /* Do something */
20332b31808SJens Wiklander     }
20432b31808SJens Wiklander 
20532b31808SJens Wiklander     return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
20632b31808SJens Wiklander }
20732b31808SJens Wiklander 
20832b31808SJens Wiklander /*
20932b31808SJens Wiklander  * Functions for writing key_share extension.
21032b31808SJens Wiklander  */
21132b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
21232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_get_default_group_id(mbedtls_ssl_context * ssl,uint16_t * group_id)21332b31808SJens Wiklander static int ssl_tls13_get_default_group_id(mbedtls_ssl_context *ssl,
21432b31808SJens Wiklander                                           uint16_t *group_id)
21532b31808SJens Wiklander {
21632b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
21732b31808SJens Wiklander 
21832b31808SJens Wiklander 
219b0563631STom Van Eyck #if defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)
22032b31808SJens Wiklander     const uint16_t *group_list = mbedtls_ssl_get_groups(ssl);
22132b31808SJens Wiklander     /* Pick first available ECDHE group compatible with TLS 1.3 */
22232b31808SJens Wiklander     if (group_list == NULL) {
22332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_CONFIG;
22432b31808SJens Wiklander     }
22532b31808SJens Wiklander 
22632b31808SJens Wiklander     for (; *group_list != 0; group_list++) {
227b0563631STom Van Eyck #if defined(PSA_WANT_ALG_ECDH)
228b0563631STom Van Eyck         if ((mbedtls_ssl_get_psa_curve_info_from_tls_id(
229b0563631STom Van Eyck                  *group_list, NULL, NULL) == PSA_SUCCESS) &&
23032b31808SJens Wiklander             mbedtls_ssl_tls13_named_group_is_ecdhe(*group_list)) {
23132b31808SJens Wiklander             *group_id = *group_list;
23232b31808SJens Wiklander             return 0;
23332b31808SJens Wiklander         }
234b0563631STom Van Eyck #endif
235b0563631STom Van Eyck #if defined(PSA_WANT_ALG_FFDH)
236b0563631STom Van Eyck         if (mbedtls_ssl_tls13_named_group_is_ffdh(*group_list)) {
237b0563631STom Van Eyck             *group_id = *group_list;
238b0563631STom Van Eyck             return 0;
239b0563631STom Van Eyck         }
240b0563631STom Van Eyck #endif
24132b31808SJens Wiklander     }
24232b31808SJens Wiklander #else
24332b31808SJens Wiklander     ((void) ssl);
24432b31808SJens Wiklander     ((void) group_id);
245b0563631STom Van Eyck #endif /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */
24632b31808SJens Wiklander 
24732b31808SJens Wiklander     return ret;
24832b31808SJens Wiklander }
24932b31808SJens Wiklander 
25032b31808SJens Wiklander /*
25132b31808SJens Wiklander  * ssl_tls13_write_key_share_ext
25232b31808SJens Wiklander  *
25332b31808SJens Wiklander  * Structure of key_share extension in ClientHello:
25432b31808SJens Wiklander  *
25532b31808SJens Wiklander  *  struct {
25632b31808SJens Wiklander  *          NamedGroup group;
25732b31808SJens Wiklander  *          opaque key_exchange<1..2^16-1>;
25832b31808SJens Wiklander  *      } KeyShareEntry;
25932b31808SJens Wiklander  *  struct {
26032b31808SJens Wiklander  *          KeyShareEntry client_shares<0..2^16-1>;
26132b31808SJens Wiklander  *      } KeyShareClientHello;
26232b31808SJens Wiklander  */
26332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_write_key_share_ext(mbedtls_ssl_context * ssl,unsigned char * buf,unsigned char * end,size_t * out_len)26432b31808SJens Wiklander static int ssl_tls13_write_key_share_ext(mbedtls_ssl_context *ssl,
26532b31808SJens Wiklander                                          unsigned char *buf,
26632b31808SJens Wiklander                                          unsigned char *end,
26732b31808SJens Wiklander                                          size_t *out_len)
26832b31808SJens Wiklander {
26932b31808SJens Wiklander     unsigned char *p = buf;
27032b31808SJens Wiklander     unsigned char *client_shares; /* Start of client_shares */
27132b31808SJens Wiklander     size_t client_shares_len;     /* Length of client_shares */
27232b31808SJens Wiklander     uint16_t group_id;
27332b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
27432b31808SJens Wiklander 
27532b31808SJens Wiklander     *out_len = 0;
27632b31808SJens Wiklander 
27732b31808SJens Wiklander     /* Check if we have space for header and length fields:
27832b31808SJens Wiklander      * - extension_type         (2 bytes)
27932b31808SJens Wiklander      * - extension_data_length  (2 bytes)
28032b31808SJens Wiklander      * - client_shares_length   (2 bytes)
28132b31808SJens Wiklander      */
28232b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6);
28332b31808SJens Wiklander     p += 6;
28432b31808SJens Wiklander 
28532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello: adding key share extension"));
28632b31808SJens Wiklander 
28732b31808SJens Wiklander     /* HRR could already have requested something else. */
28832b31808SJens Wiklander     group_id = ssl->handshake->offered_group_id;
28932b31808SJens Wiklander     if (!mbedtls_ssl_tls13_named_group_is_ecdhe(group_id) &&
290b0563631STom Van Eyck         !mbedtls_ssl_tls13_named_group_is_ffdh(group_id)) {
29132b31808SJens Wiklander         MBEDTLS_SSL_PROC_CHK(ssl_tls13_get_default_group_id(ssl,
29232b31808SJens Wiklander                                                             &group_id));
29332b31808SJens Wiklander     }
29432b31808SJens Wiklander 
29532b31808SJens Wiklander     /*
29632b31808SJens Wiklander      * Dispatch to type-specific key generation function.
29732b31808SJens Wiklander      *
29832b31808SJens Wiklander      * So far, we're only supporting ECDHE. With the introduction
29932b31808SJens Wiklander      * of PQC KEMs, we'll want to have multiple branches, one per
30032b31808SJens Wiklander      * type of KEM, and dispatch to the corresponding crypto. And
30132b31808SJens Wiklander      * only one key share entry is allowed.
30232b31808SJens Wiklander      */
30332b31808SJens Wiklander     client_shares = p;
304b0563631STom Van Eyck #if defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)
305b0563631STom Van Eyck     if (mbedtls_ssl_tls13_named_group_is_ecdhe(group_id) ||
306b0563631STom Van Eyck         mbedtls_ssl_tls13_named_group_is_ffdh(group_id)) {
30732b31808SJens Wiklander         /* Pointer to group */
30832b31808SJens Wiklander         unsigned char *group = p;
30932b31808SJens Wiklander         /* Length of key_exchange */
31032b31808SJens Wiklander         size_t key_exchange_len = 0;
31132b31808SJens Wiklander 
31232b31808SJens Wiklander         /* Check there is space for header of KeyShareEntry
31332b31808SJens Wiklander          * - group                  (2 bytes)
31432b31808SJens Wiklander          * - key_exchange_length    (2 bytes)
31532b31808SJens Wiklander          */
31632b31808SJens Wiklander         MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4);
31732b31808SJens Wiklander         p += 4;
318b0563631STom Van Eyck         ret = mbedtls_ssl_tls13_generate_and_write_xxdh_key_exchange(
31932b31808SJens Wiklander             ssl, group_id, p, end, &key_exchange_len);
32032b31808SJens Wiklander         p += key_exchange_len;
32132b31808SJens Wiklander         if (ret != 0) {
322*c3deb3d6SEtienne Carriere             MBEDTLS_SSL_DEBUG_MSG(1, ("client hello: failed generating xxdh key exchange"));
32332b31808SJens Wiklander             return ret;
32432b31808SJens Wiklander         }
32532b31808SJens Wiklander 
32632b31808SJens Wiklander         /* Write group */
32732b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(group_id, group, 0);
32832b31808SJens Wiklander         /* Write key_exchange_length */
32932b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(key_exchange_len, group, 2);
33032b31808SJens Wiklander     } else
331b0563631STom Van Eyck #endif /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */
33232b31808SJens Wiklander     if (0 /* other KEMs? */) {
33332b31808SJens Wiklander         /* Do something */
33432b31808SJens Wiklander     } else {
33532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
33632b31808SJens Wiklander     }
33732b31808SJens Wiklander 
33832b31808SJens Wiklander     /* Length of client_shares */
33932b31808SJens Wiklander     client_shares_len = p - client_shares;
34032b31808SJens Wiklander     if (client_shares_len == 0) {
34132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("No key share defined."));
34232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
34332b31808SJens Wiklander     }
34432b31808SJens Wiklander     /* Write extension_type */
34532b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_KEY_SHARE, buf, 0);
34632b31808SJens Wiklander     /* Write extension_data_length */
34732b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(client_shares_len + 2, buf, 2);
34832b31808SJens Wiklander     /* Write client_shares_length */
34932b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(client_shares_len, buf, 4);
35032b31808SJens Wiklander 
35132b31808SJens Wiklander     /* Update offered_group_id field */
35232b31808SJens Wiklander     ssl->handshake->offered_group_id = group_id;
35332b31808SJens Wiklander 
35432b31808SJens Wiklander     /* Output the total length of key_share extension. */
35532b31808SJens Wiklander     *out_len = p - buf;
35632b31808SJens Wiklander 
357b0563631STom Van Eyck     MBEDTLS_SSL_DEBUG_BUF(
358b0563631STom Van Eyck         3, "client hello, key_share extension", buf, *out_len);
35932b31808SJens Wiklander 
36032b31808SJens Wiklander     mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_KEY_SHARE);
36132b31808SJens Wiklander 
36232b31808SJens Wiklander cleanup:
36332b31808SJens Wiklander 
36432b31808SJens Wiklander     return ret;
36532b31808SJens Wiklander }
36632b31808SJens Wiklander #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */
36732b31808SJens Wiklander 
36832b31808SJens Wiklander /*
36932b31808SJens Wiklander  * ssl_tls13_parse_hrr_key_share_ext()
37032b31808SJens Wiklander  *      Parse key_share extension in Hello Retry Request
37132b31808SJens Wiklander  *
37232b31808SJens Wiklander  * struct {
37332b31808SJens Wiklander  *        NamedGroup selected_group;
37432b31808SJens Wiklander  * } KeyShareHelloRetryRequest;
37532b31808SJens Wiklander  */
37632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_parse_hrr_key_share_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,const unsigned char * end)37732b31808SJens Wiklander static int ssl_tls13_parse_hrr_key_share_ext(mbedtls_ssl_context *ssl,
37832b31808SJens Wiklander                                              const unsigned char *buf,
37932b31808SJens Wiklander                                              const unsigned char *end)
38032b31808SJens Wiklander {
381b0563631STom Van Eyck #if defined(PSA_WANT_ALG_ECDH) || defined(PSA_WANT_ALG_FFDH)
38232b31808SJens Wiklander     const unsigned char *p = buf;
38332b31808SJens Wiklander     int selected_group;
38432b31808SJens Wiklander     int found = 0;
38532b31808SJens Wiklander 
38632b31808SJens Wiklander     const uint16_t *group_list = mbedtls_ssl_get_groups(ssl);
38732b31808SJens Wiklander     if (group_list == NULL) {
38832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_CONFIG;
38932b31808SJens Wiklander     }
39032b31808SJens Wiklander 
39132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "key_share extension", p, end - buf);
39232b31808SJens Wiklander 
39332b31808SJens Wiklander     /* Read selected_group */
39432b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
39532b31808SJens Wiklander     selected_group = MBEDTLS_GET_UINT16_BE(p, 0);
39632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("selected_group ( %d )", selected_group));
39732b31808SJens Wiklander 
39832b31808SJens Wiklander     /* Upon receipt of this extension in a HelloRetryRequest, the client
39932b31808SJens Wiklander      * MUST first verify that the selected_group field corresponds to a
40032b31808SJens Wiklander      * group which was provided in the "supported_groups" extension in the
40132b31808SJens Wiklander      * original ClientHello.
40232b31808SJens Wiklander      * The supported_group was based on the info in ssl->conf->group_list.
40332b31808SJens Wiklander      *
40432b31808SJens Wiklander      * If the server provided a key share that was not sent in the ClientHello
40532b31808SJens Wiklander      * then the client MUST abort the handshake with an "illegal_parameter" alert.
40632b31808SJens Wiklander      */
40732b31808SJens Wiklander     for (; *group_list != 0; group_list++) {
408b0563631STom Van Eyck #if defined(PSA_WANT_ALG_ECDH)
409b0563631STom Van Eyck         if (mbedtls_ssl_tls13_named_group_is_ecdhe(*group_list)) {
410b0563631STom Van Eyck             if ((mbedtls_ssl_get_psa_curve_info_from_tls_id(
411b0563631STom Van Eyck                      *group_list, NULL, NULL) == PSA_ERROR_NOT_SUPPORTED) ||
41232b31808SJens Wiklander                 *group_list != selected_group) {
41332b31808SJens Wiklander                 found = 1;
41432b31808SJens Wiklander                 break;
41532b31808SJens Wiklander             }
416b0563631STom Van Eyck         }
417b0563631STom Van Eyck #endif /* PSA_WANT_ALG_ECDH */
418b0563631STom Van Eyck #if defined(PSA_WANT_ALG_FFDH)
419b0563631STom Van Eyck         if (mbedtls_ssl_tls13_named_group_is_ffdh(*group_list)) {
420b0563631STom Van Eyck             found = 1;
421b0563631STom Van Eyck             break;
422b0563631STom Van Eyck         }
423b0563631STom Van Eyck #endif /* PSA_WANT_ALG_FFDH */
424b0563631STom Van Eyck     }
42532b31808SJens Wiklander 
42632b31808SJens Wiklander     /* Client MUST verify that the selected_group field does not
42732b31808SJens Wiklander      * correspond to a group which was provided in the "key_share"
42832b31808SJens Wiklander      * extension in the original ClientHello. If the server sent an
42932b31808SJens Wiklander      * HRR message with a key share already provided in the
43032b31808SJens Wiklander      * ClientHello then the client MUST abort the handshake with
43132b31808SJens Wiklander      * an "illegal_parameter" alert.
43232b31808SJens Wiklander      */
43332b31808SJens Wiklander     if (found == 0 || selected_group == ssl->handshake->offered_group_id) {
43432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid key share in HRR"));
43532b31808SJens Wiklander         MBEDTLS_SSL_PEND_FATAL_ALERT(
43632b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
43732b31808SJens Wiklander             MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
43832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
43932b31808SJens Wiklander     }
44032b31808SJens Wiklander 
44132b31808SJens Wiklander     /* Remember server's preference for next ClientHello */
44232b31808SJens Wiklander     ssl->handshake->offered_group_id = selected_group;
44332b31808SJens Wiklander 
44432b31808SJens Wiklander     return 0;
445b0563631STom Van Eyck #else /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */
44632b31808SJens Wiklander     (void) ssl;
44732b31808SJens Wiklander     (void) buf;
44832b31808SJens Wiklander     (void) end;
44932b31808SJens Wiklander     return MBEDTLS_ERR_SSL_BAD_CONFIG;
450b0563631STom Van Eyck #endif /* PSA_WANT_ALG_ECDH || PSA_WANT_ALG_FFDH */
45132b31808SJens Wiklander }
45232b31808SJens Wiklander 
45332b31808SJens Wiklander /*
45432b31808SJens Wiklander  * ssl_tls13_parse_key_share_ext()
45532b31808SJens Wiklander  *      Parse key_share extension in Server Hello
45632b31808SJens Wiklander  *
45732b31808SJens Wiklander  * struct {
45832b31808SJens Wiklander  *        KeyShareEntry server_share;
45932b31808SJens Wiklander  * } KeyShareServerHello;
46032b31808SJens Wiklander  * struct {
46132b31808SJens Wiklander  *        NamedGroup group;
46232b31808SJens Wiklander  *        opaque key_exchange<1..2^16-1>;
46332b31808SJens Wiklander  * } KeyShareEntry;
46432b31808SJens Wiklander  */
46532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_parse_key_share_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,const unsigned char * end)46632b31808SJens Wiklander static int ssl_tls13_parse_key_share_ext(mbedtls_ssl_context *ssl,
46732b31808SJens Wiklander                                          const unsigned char *buf,
46832b31808SJens Wiklander                                          const unsigned char *end)
46932b31808SJens Wiklander {
47032b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
47132b31808SJens Wiklander     const unsigned char *p = buf;
47232b31808SJens Wiklander     uint16_t group, offered_group;
47332b31808SJens Wiklander 
47432b31808SJens Wiklander     /* ...
47532b31808SJens Wiklander      * NamedGroup group; (2 bytes)
47632b31808SJens Wiklander      * ...
47732b31808SJens Wiklander      */
47832b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
47932b31808SJens Wiklander     group = MBEDTLS_GET_UINT16_BE(p, 0);
48032b31808SJens Wiklander     p += 2;
48132b31808SJens Wiklander 
48232b31808SJens Wiklander     /* Check that the chosen group matches the one we offered. */
48332b31808SJens Wiklander     offered_group = ssl->handshake->offered_group_id;
48432b31808SJens Wiklander     if (offered_group != group) {
485b0563631STom Van Eyck         MBEDTLS_SSL_DEBUG_MSG(
486b0563631STom Van Eyck             1, ("Invalid server key share, our group %u, their group %u",
48732b31808SJens Wiklander                 (unsigned) offered_group, (unsigned) group));
48832b31808SJens Wiklander         MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
48932b31808SJens Wiklander                                      MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
49032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
49132b31808SJens Wiklander     }
49232b31808SJens Wiklander 
493b0563631STom Van Eyck #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
494b0563631STom Van Eyck     if (mbedtls_ssl_tls13_named_group_is_ecdhe(group) ||
495b0563631STom Van Eyck         mbedtls_ssl_tls13_named_group_is_ffdh(group)) {
496b0563631STom Van Eyck         MBEDTLS_SSL_DEBUG_MSG(2,
497b0563631STom Van Eyck                               ("DHE group name: %s", mbedtls_ssl_named_group_to_str(group)));
498b0563631STom Van Eyck         ret = mbedtls_ssl_tls13_read_public_xxdhe_share(ssl, p, end - p);
49932b31808SJens Wiklander         if (ret != 0) {
50032b31808SJens Wiklander             return ret;
50132b31808SJens Wiklander         }
50232b31808SJens Wiklander     } else
503b0563631STom Van Eyck #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED */
50432b31808SJens Wiklander     if (0 /* other KEMs? */) {
50532b31808SJens Wiklander         /* Do something */
50632b31808SJens Wiklander     } else {
50732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
50832b31808SJens Wiklander     }
50932b31808SJens Wiklander 
51032b31808SJens Wiklander     return ret;
51132b31808SJens Wiklander }
51232b31808SJens Wiklander 
51332b31808SJens Wiklander /*
51432b31808SJens Wiklander  * ssl_tls13_parse_cookie_ext()
51532b31808SJens Wiklander  *      Parse cookie extension in Hello Retry Request
51632b31808SJens Wiklander  *
51732b31808SJens Wiklander  * struct {
51832b31808SJens Wiklander  *        opaque cookie<1..2^16-1>;
51932b31808SJens Wiklander  * } Cookie;
52032b31808SJens Wiklander  *
52132b31808SJens Wiklander  * When sending a HelloRetryRequest, the server MAY provide a "cookie"
52232b31808SJens Wiklander  * extension to the client (this is an exception to the usual rule that
52332b31808SJens Wiklander  * the only extensions that may be sent are those that appear in the
52432b31808SJens Wiklander  * ClientHello).  When sending the new ClientHello, the client MUST copy
52532b31808SJens Wiklander  * the contents of the extension received in the HelloRetryRequest into
52632b31808SJens Wiklander  * a "cookie" extension in the new ClientHello.  Clients MUST NOT use
52732b31808SJens Wiklander  * cookies in their initial ClientHello in subsequent connections.
52832b31808SJens Wiklander  */
52932b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_parse_cookie_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,const unsigned char * end)53032b31808SJens Wiklander static int ssl_tls13_parse_cookie_ext(mbedtls_ssl_context *ssl,
53132b31808SJens Wiklander                                       const unsigned char *buf,
53232b31808SJens Wiklander                                       const unsigned char *end)
53332b31808SJens Wiklander {
53432b31808SJens Wiklander     uint16_t cookie_len;
53532b31808SJens Wiklander     const unsigned char *p = buf;
53632b31808SJens Wiklander     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
53732b31808SJens Wiklander 
53832b31808SJens Wiklander     /* Retrieve length field of cookie */
53932b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
54032b31808SJens Wiklander     cookie_len = MBEDTLS_GET_UINT16_BE(p, 0);
54132b31808SJens Wiklander     p += 2;
54232b31808SJens Wiklander 
54332b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, cookie_len);
54432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "cookie extension", p, cookie_len);
54532b31808SJens Wiklander 
54632b31808SJens Wiklander     mbedtls_free(handshake->cookie);
54732b31808SJens Wiklander     handshake->cookie_len = 0;
54832b31808SJens Wiklander     handshake->cookie = mbedtls_calloc(1, cookie_len);
54932b31808SJens Wiklander     if (handshake->cookie == NULL) {
55032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
55132b31808SJens Wiklander                               ("alloc failed ( %ud bytes )",
55232b31808SJens Wiklander                                cookie_len));
55332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ALLOC_FAILED;
55432b31808SJens Wiklander     }
55532b31808SJens Wiklander 
55632b31808SJens Wiklander     memcpy(handshake->cookie, p, cookie_len);
55732b31808SJens Wiklander     handshake->cookie_len = cookie_len;
55832b31808SJens Wiklander 
55932b31808SJens Wiklander     return 0;
56032b31808SJens Wiklander }
56132b31808SJens Wiklander 
56232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_write_cookie_ext(mbedtls_ssl_context * ssl,unsigned char * buf,unsigned char * end,size_t * out_len)56332b31808SJens Wiklander static int ssl_tls13_write_cookie_ext(mbedtls_ssl_context *ssl,
56432b31808SJens Wiklander                                       unsigned char *buf,
56532b31808SJens Wiklander                                       unsigned char *end,
56632b31808SJens Wiklander                                       size_t *out_len)
56732b31808SJens Wiklander {
56832b31808SJens Wiklander     unsigned char *p = buf;
56932b31808SJens Wiklander     *out_len = 0;
57032b31808SJens Wiklander     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
57132b31808SJens Wiklander 
57232b31808SJens Wiklander     if (handshake->cookie == NULL) {
57332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("no cookie to send; skip extension"));
57432b31808SJens Wiklander         return 0;
57532b31808SJens Wiklander     }
57632b31808SJens Wiklander 
57732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, cookie",
57832b31808SJens Wiklander                           handshake->cookie,
57932b31808SJens Wiklander                           handshake->cookie_len);
58032b31808SJens Wiklander 
58132b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, handshake->cookie_len + 6);
58232b31808SJens Wiklander 
58332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding cookie extension"));
58432b31808SJens Wiklander 
58532b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_COOKIE, p, 0);
58632b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(handshake->cookie_len + 2, p, 2);
58732b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(handshake->cookie_len, p, 4);
58832b31808SJens Wiklander     p += 6;
58932b31808SJens Wiklander 
59032b31808SJens Wiklander     /* Cookie */
59132b31808SJens Wiklander     memcpy(p, handshake->cookie, handshake->cookie_len);
59232b31808SJens Wiklander 
59332b31808SJens Wiklander     *out_len = handshake->cookie_len + 6;
59432b31808SJens Wiklander 
59532b31808SJens Wiklander     mbedtls_ssl_tls13_set_hs_sent_ext_mask(ssl, MBEDTLS_TLS_EXT_COOKIE);
59632b31808SJens Wiklander 
59732b31808SJens Wiklander     return 0;
59832b31808SJens Wiklander }
59932b31808SJens Wiklander 
60032b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
60132b31808SJens Wiklander /*
60232b31808SJens Wiklander  * ssl_tls13_write_psk_key_exchange_modes_ext() structure:
60332b31808SJens Wiklander  *
60432b31808SJens Wiklander  * enum { psk_ke( 0 ), psk_dhe_ke( 1 ), ( 255 ) } PskKeyExchangeMode;
60532b31808SJens Wiklander  *
60632b31808SJens Wiklander  * struct {
60732b31808SJens Wiklander  *     PskKeyExchangeMode ke_modes<1..255>;
60832b31808SJens Wiklander  * } PskKeyExchangeModes;
60932b31808SJens Wiklander  */
61032b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_write_psk_key_exchange_modes_ext(mbedtls_ssl_context * ssl,unsigned char * buf,unsigned char * end,size_t * out_len)61132b31808SJens Wiklander static int ssl_tls13_write_psk_key_exchange_modes_ext(mbedtls_ssl_context *ssl,
61232b31808SJens Wiklander                                                       unsigned char *buf,
61332b31808SJens Wiklander                                                       unsigned char *end,
61432b31808SJens Wiklander                                                       size_t *out_len)
61532b31808SJens Wiklander {
61632b31808SJens Wiklander     unsigned char *p = buf;
61732b31808SJens Wiklander     int ke_modes_len = 0;
61832b31808SJens Wiklander 
61932b31808SJens Wiklander     ((void) ke_modes_len);
62032b31808SJens Wiklander     *out_len = 0;
62132b31808SJens Wiklander 
62232b31808SJens Wiklander     /* Skip writing extension if no PSK key exchange mode
62332b31808SJens Wiklander      * is enabled in the config.
62432b31808SJens Wiklander      */
625b0563631STom Van Eyck     if (!mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl)) {
62632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("skip psk_key_exchange_modes extension"));
62732b31808SJens Wiklander         return 0;
62832b31808SJens Wiklander     }
62932b31808SJens Wiklander 
63032b31808SJens Wiklander     /* Require 7 bytes of data, otherwise fail,
63132b31808SJens Wiklander      * even if extension might be shorter.
63232b31808SJens Wiklander      */
63332b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 7);
63432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(
63532b31808SJens Wiklander         3, ("client hello, adding psk_key_exchange_modes extension"));
63632b31808SJens Wiklander 
63732b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES, p, 0);
63832b31808SJens Wiklander 
63932b31808SJens Wiklander     /* Skip extension length (2 bytes) and
64032b31808SJens Wiklander      * ke_modes length (1 byte) for now.
64132b31808SJens Wiklander      */
64232b31808SJens Wiklander     p += 5;
64332b31808SJens Wiklander 
644b0563631STom Van Eyck     if (mbedtls_ssl_conf_tls13_is_psk_ephemeral_enabled(ssl)) {
64532b31808SJens Wiklander         *p++ = MBEDTLS_SSL_TLS1_3_PSK_MODE_ECDHE;
64632b31808SJens Wiklander         ke_modes_len++;
64732b31808SJens Wiklander 
64832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(4, ("Adding PSK-ECDHE key exchange mode"));
64932b31808SJens Wiklander     }
65032b31808SJens Wiklander 
651b0563631STom Van Eyck     if (mbedtls_ssl_conf_tls13_is_psk_enabled(ssl)) {
65232b31808SJens Wiklander         *p++ = MBEDTLS_SSL_TLS1_3_PSK_MODE_PURE;
65332b31808SJens Wiklander         ke_modes_len++;
65432b31808SJens Wiklander 
65532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(4, ("Adding pure PSK key exchange mode"));
65632b31808SJens Wiklander     }
65732b31808SJens Wiklander 
65832b31808SJens Wiklander     /* Now write the extension and ke_modes length */
65932b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(ke_modes_len + 1, buf, 2);
66032b31808SJens Wiklander     buf[4] = ke_modes_len;
66132b31808SJens Wiklander 
66232b31808SJens Wiklander     *out_len = p - buf;
66332b31808SJens Wiklander 
66432b31808SJens Wiklander     mbedtls_ssl_tls13_set_hs_sent_ext_mask(
66532b31808SJens Wiklander         ssl, MBEDTLS_TLS_EXT_PSK_KEY_EXCHANGE_MODES);
66632b31808SJens Wiklander 
66732b31808SJens Wiklander     return 0;
66832b31808SJens Wiklander }
66932b31808SJens Wiklander 
670cb034002SJerome Forissier #if defined(MBEDTLS_SSL_SESSION_TICKETS)
ssl_tls13_get_ciphersuite_hash_alg(int ciphersuite)67132b31808SJens Wiklander static psa_algorithm_t ssl_tls13_get_ciphersuite_hash_alg(int ciphersuite)
67232b31808SJens Wiklander {
67332b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info = NULL;
67432b31808SJens Wiklander     ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(ciphersuite);
67532b31808SJens Wiklander 
67632b31808SJens Wiklander     if (ciphersuite_info != NULL) {
677b0563631STom Van Eyck         return mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac);
67832b31808SJens Wiklander     }
67932b31808SJens Wiklander 
68032b31808SJens Wiklander     return PSA_ALG_NONE;
68132b31808SJens Wiklander }
68232b31808SJens Wiklander 
ssl_tls13_has_configured_ticket(mbedtls_ssl_context * ssl)68332b31808SJens Wiklander static int ssl_tls13_has_configured_ticket(mbedtls_ssl_context *ssl)
68432b31808SJens Wiklander {
68532b31808SJens Wiklander     mbedtls_ssl_session *session = ssl->session_negotiate;
68632b31808SJens Wiklander     return ssl->handshake->resume &&
68732b31808SJens Wiklander            session != NULL && session->ticket != NULL &&
688b0563631STom Van Eyck            mbedtls_ssl_conf_tls13_is_kex_mode_enabled(
689b0563631STom Van Eyck         ssl, mbedtls_ssl_tls13_session_get_ticket_flags(
69032b31808SJens Wiklander             session, MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL));
69132b31808SJens Wiklander }
69232b31808SJens Wiklander 
69332b31808SJens Wiklander #if defined(MBEDTLS_SSL_EARLY_DATA)
ssl_tls13_early_data_has_valid_ticket(mbedtls_ssl_context * ssl)69432b31808SJens Wiklander static int ssl_tls13_early_data_has_valid_ticket(mbedtls_ssl_context *ssl)
69532b31808SJens Wiklander {
69632b31808SJens Wiklander     mbedtls_ssl_session *session = ssl->session_negotiate;
69732b31808SJens Wiklander     return ssl->handshake->resume &&
69832b31808SJens Wiklander            session->tls_version == MBEDTLS_SSL_VERSION_TLS1_3 &&
699b0563631STom Van Eyck            mbedtls_ssl_tls13_session_ticket_allow_early_data(session) &&
700b0563631STom Van Eyck            mbedtls_ssl_tls13_cipher_suite_is_offered(ssl, session->ciphersuite);
70132b31808SJens Wiklander }
70232b31808SJens Wiklander #endif
70332b31808SJens Wiklander 
70432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_ticket_get_identity(mbedtls_ssl_context * ssl,psa_algorithm_t * hash_alg,const unsigned char ** identity,size_t * identity_len)70532b31808SJens Wiklander static int ssl_tls13_ticket_get_identity(mbedtls_ssl_context *ssl,
70632b31808SJens Wiklander                                          psa_algorithm_t *hash_alg,
70732b31808SJens Wiklander                                          const unsigned char **identity,
70832b31808SJens Wiklander                                          size_t *identity_len)
70932b31808SJens Wiklander {
71032b31808SJens Wiklander     mbedtls_ssl_session *session = ssl->session_negotiate;
71132b31808SJens Wiklander 
71232b31808SJens Wiklander     if (!ssl_tls13_has_configured_ticket(ssl)) {
71332b31808SJens Wiklander         return -1;
71432b31808SJens Wiklander     }
71532b31808SJens Wiklander 
71632b31808SJens Wiklander     *hash_alg = ssl_tls13_get_ciphersuite_hash_alg(session->ciphersuite);
71732b31808SJens Wiklander     *identity = session->ticket;
71832b31808SJens Wiklander     *identity_len = session->ticket_len;
71932b31808SJens Wiklander     return 0;
72032b31808SJens Wiklander }
72132b31808SJens Wiklander 
72232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_ticket_get_psk(mbedtls_ssl_context * ssl,psa_algorithm_t * hash_alg,const unsigned char ** psk,size_t * psk_len)72332b31808SJens Wiklander static int ssl_tls13_ticket_get_psk(mbedtls_ssl_context *ssl,
72432b31808SJens Wiklander                                     psa_algorithm_t *hash_alg,
72532b31808SJens Wiklander                                     const unsigned char **psk,
72632b31808SJens Wiklander                                     size_t *psk_len)
72732b31808SJens Wiklander {
72832b31808SJens Wiklander 
72932b31808SJens Wiklander     mbedtls_ssl_session *session = ssl->session_negotiate;
73032b31808SJens Wiklander 
73132b31808SJens Wiklander     if (!ssl_tls13_has_configured_ticket(ssl)) {
73232b31808SJens Wiklander         return -1;
73332b31808SJens Wiklander     }
73432b31808SJens Wiklander 
73532b31808SJens Wiklander     *hash_alg = ssl_tls13_get_ciphersuite_hash_alg(session->ciphersuite);
73632b31808SJens Wiklander     *psk = session->resumption_key;
73732b31808SJens Wiklander     *psk_len = session->resumption_key_len;
73832b31808SJens Wiklander 
73932b31808SJens Wiklander     return 0;
74032b31808SJens Wiklander }
74132b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
74232b31808SJens Wiklander 
74332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_psk_get_identity(mbedtls_ssl_context * ssl,psa_algorithm_t * hash_alg,const unsigned char ** identity,size_t * identity_len)74432b31808SJens Wiklander static int ssl_tls13_psk_get_identity(mbedtls_ssl_context *ssl,
74532b31808SJens Wiklander                                       psa_algorithm_t *hash_alg,
74632b31808SJens Wiklander                                       const unsigned char **identity,
74732b31808SJens Wiklander                                       size_t *identity_len)
74832b31808SJens Wiklander {
74932b31808SJens Wiklander 
75032b31808SJens Wiklander     if (!mbedtls_ssl_conf_has_static_psk(ssl->conf)) {
75132b31808SJens Wiklander         return -1;
75232b31808SJens Wiklander     }
75332b31808SJens Wiklander 
75432b31808SJens Wiklander     *hash_alg = PSA_ALG_SHA_256;
75532b31808SJens Wiklander     *identity = ssl->conf->psk_identity;
75632b31808SJens Wiklander     *identity_len = ssl->conf->psk_identity_len;
75732b31808SJens Wiklander     return 0;
75832b31808SJens Wiklander }
75932b31808SJens Wiklander 
76032b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_psk_get_psk(mbedtls_ssl_context * ssl,psa_algorithm_t * hash_alg,const unsigned char ** psk,size_t * psk_len)76132b31808SJens Wiklander static int ssl_tls13_psk_get_psk(mbedtls_ssl_context *ssl,
76232b31808SJens Wiklander                                  psa_algorithm_t *hash_alg,
76332b31808SJens Wiklander                                  const unsigned char **psk,
76432b31808SJens Wiklander                                  size_t *psk_len)
76532b31808SJens Wiklander {
76632b31808SJens Wiklander 
76732b31808SJens Wiklander     if (!mbedtls_ssl_conf_has_static_psk(ssl->conf)) {
76832b31808SJens Wiklander         return -1;
76932b31808SJens Wiklander     }
77032b31808SJens Wiklander 
77132b31808SJens Wiklander     *hash_alg = PSA_ALG_SHA_256;
77232b31808SJens Wiklander     *psk = ssl->conf->psk;
77332b31808SJens Wiklander     *psk_len = ssl->conf->psk_len;
77432b31808SJens Wiklander     return 0;
77532b31808SJens Wiklander }
77632b31808SJens Wiklander 
ssl_tls13_get_configured_psk_count(mbedtls_ssl_context * ssl)77732b31808SJens Wiklander static int ssl_tls13_get_configured_psk_count(mbedtls_ssl_context *ssl)
77832b31808SJens Wiklander {
77932b31808SJens Wiklander     int configured_psk_count = 0;
78032b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
78132b31808SJens Wiklander     if (ssl_tls13_has_configured_ticket(ssl)) {
78232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("Ticket is configured"));
78332b31808SJens Wiklander         configured_psk_count++;
78432b31808SJens Wiklander     }
78532b31808SJens Wiklander #endif
78632b31808SJens Wiklander     if (mbedtls_ssl_conf_has_static_psk(ssl->conf)) {
78732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("PSK is configured"));
78832b31808SJens Wiklander         configured_psk_count++;
78932b31808SJens Wiklander     }
79032b31808SJens Wiklander     return configured_psk_count;
79132b31808SJens Wiklander }
79232b31808SJens Wiklander 
79332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_write_identity(mbedtls_ssl_context * ssl,unsigned char * buf,unsigned char * end,const unsigned char * identity,size_t identity_len,uint32_t obfuscated_ticket_age,size_t * out_len)79432b31808SJens Wiklander static int ssl_tls13_write_identity(mbedtls_ssl_context *ssl,
79532b31808SJens Wiklander                                     unsigned char *buf,
79632b31808SJens Wiklander                                     unsigned char *end,
79732b31808SJens Wiklander                                     const unsigned char *identity,
79832b31808SJens Wiklander                                     size_t identity_len,
79932b31808SJens Wiklander                                     uint32_t obfuscated_ticket_age,
80032b31808SJens Wiklander                                     size_t *out_len)
80132b31808SJens Wiklander {
80232b31808SJens Wiklander     ((void) ssl);
80332b31808SJens Wiklander     *out_len = 0;
80432b31808SJens Wiklander 
80532b31808SJens Wiklander     /*
80632b31808SJens Wiklander      * - identity_len           (2 bytes)
80732b31808SJens Wiklander      * - identity               (psk_identity_len bytes)
80832b31808SJens Wiklander      * - obfuscated_ticket_age  (4 bytes)
80932b31808SJens Wiklander      */
81032b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(buf, end, 6 + identity_len);
81132b31808SJens Wiklander 
81232b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(identity_len, buf, 0);
81332b31808SJens Wiklander     memcpy(buf + 2, identity, identity_len);
81432b31808SJens Wiklander     MBEDTLS_PUT_UINT32_BE(obfuscated_ticket_age, buf, 2 + identity_len);
81532b31808SJens Wiklander 
81632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(4, "write identity", buf, 6 + identity_len);
81732b31808SJens Wiklander 
81832b31808SJens Wiklander     *out_len = 6 + identity_len;
81932b31808SJens Wiklander 
82032b31808SJens Wiklander     return 0;
82132b31808SJens Wiklander }
82232b31808SJens Wiklander 
82332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_write_binder(mbedtls_ssl_context * ssl,unsigned char * buf,unsigned char * end,int psk_type,psa_algorithm_t hash_alg,const unsigned char * psk,size_t psk_len,size_t * out_len)82432b31808SJens Wiklander static int ssl_tls13_write_binder(mbedtls_ssl_context *ssl,
82532b31808SJens Wiklander                                   unsigned char *buf,
82632b31808SJens Wiklander                                   unsigned char *end,
82732b31808SJens Wiklander                                   int psk_type,
82832b31808SJens Wiklander                                   psa_algorithm_t hash_alg,
82932b31808SJens Wiklander                                   const unsigned char *psk,
83032b31808SJens Wiklander                                   size_t psk_len,
83132b31808SJens Wiklander                                   size_t *out_len)
83232b31808SJens Wiklander {
83332b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
83432b31808SJens Wiklander     unsigned char binder_len;
83532b31808SJens Wiklander     unsigned char transcript[MBEDTLS_TLS1_3_MD_MAX_SIZE];
83632b31808SJens Wiklander     size_t transcript_len = 0;
83732b31808SJens Wiklander 
83832b31808SJens Wiklander     *out_len = 0;
83932b31808SJens Wiklander 
84032b31808SJens Wiklander     binder_len = PSA_HASH_LENGTH(hash_alg);
84132b31808SJens Wiklander 
84232b31808SJens Wiklander     /*
84332b31808SJens Wiklander      * - binder_len           (1 bytes)
84432b31808SJens Wiklander      * - binder               (binder_len bytes)
84532b31808SJens Wiklander      */
84632b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(buf, end, 1 + binder_len);
84732b31808SJens Wiklander 
84832b31808SJens Wiklander     buf[0] = binder_len;
84932b31808SJens Wiklander 
85032b31808SJens Wiklander     /* Get current state of handshake transcript. */
85132b31808SJens Wiklander     ret = mbedtls_ssl_get_handshake_transcript(
852b0563631STom Van Eyck         ssl, mbedtls_md_type_from_psa_alg(hash_alg),
85332b31808SJens Wiklander         transcript, sizeof(transcript), &transcript_len);
85432b31808SJens Wiklander     if (ret != 0) {
85532b31808SJens Wiklander         return ret;
85632b31808SJens Wiklander     }
85732b31808SJens Wiklander 
85832b31808SJens Wiklander     ret = mbedtls_ssl_tls13_create_psk_binder(ssl, hash_alg,
85932b31808SJens Wiklander                                               psk, psk_len, psk_type,
86032b31808SJens Wiklander                                               transcript, buf + 1);
86132b31808SJens Wiklander     if (ret != 0) {
86232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_tls13_create_psk_binder", ret);
86332b31808SJens Wiklander         return ret;
86432b31808SJens Wiklander     }
86532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(4, "write binder", buf, 1 + binder_len);
86632b31808SJens Wiklander 
86732b31808SJens Wiklander     *out_len = 1 + binder_len;
86832b31808SJens Wiklander 
86932b31808SJens Wiklander     return 0;
87032b31808SJens Wiklander }
87132b31808SJens Wiklander 
87232b31808SJens Wiklander /*
87332b31808SJens Wiklander  * mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext() structure:
87432b31808SJens Wiklander  *
87532b31808SJens Wiklander  * struct {
87632b31808SJens Wiklander  *   opaque identity<1..2^16-1>;
87732b31808SJens Wiklander  *   uint32 obfuscated_ticket_age;
87832b31808SJens Wiklander  * } PskIdentity;
87932b31808SJens Wiklander  *
88032b31808SJens Wiklander  * opaque PskBinderEntry<32..255>;
88132b31808SJens Wiklander  *
88232b31808SJens Wiklander  * struct {
88332b31808SJens Wiklander  *   PskIdentity identities<7..2^16-1>;
88432b31808SJens Wiklander  *   PskBinderEntry binders<33..2^16-1>;
88532b31808SJens Wiklander  * } OfferedPsks;
88632b31808SJens Wiklander  *
88732b31808SJens Wiklander  * struct {
88832b31808SJens Wiklander  *   select (Handshake.msg_type) {
88932b31808SJens Wiklander  *      case client_hello: OfferedPsks;
89032b31808SJens Wiklander  *      ...
89132b31808SJens Wiklander  *   };
89232b31808SJens Wiklander  * } PreSharedKeyExtension;
89332b31808SJens Wiklander  *
89432b31808SJens Wiklander  */
mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext(mbedtls_ssl_context * ssl,unsigned char * buf,unsigned char * end,size_t * out_len,size_t * binders_len)89532b31808SJens Wiklander int mbedtls_ssl_tls13_write_identities_of_pre_shared_key_ext(
89632b31808SJens Wiklander     mbedtls_ssl_context *ssl, unsigned char *buf, unsigned char *end,
89732b31808SJens Wiklander     size_t *out_len, size_t *binders_len)
89832b31808SJens Wiklander {
89932b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
90032b31808SJens Wiklander     int configured_psk_count = 0;
90132b31808SJens Wiklander     unsigned char *p = buf;
90232b31808SJens Wiklander     psa_algorithm_t hash_alg = PSA_ALG_NONE;
90332b31808SJens Wiklander     const unsigned char *identity;
90432b31808SJens Wiklander     size_t identity_len;
90532b31808SJens Wiklander     size_t l_binders_len = 0;
90632b31808SJens Wiklander     size_t output_len;
90732b31808SJens Wiklander 
90832b31808SJens Wiklander     *out_len = 0;
90932b31808SJens Wiklander     *binders_len = 0;
91032b31808SJens Wiklander 
91132b31808SJens Wiklander     /* Check if we have any PSKs to offer. If no, skip pre_shared_key */
91232b31808SJens Wiklander     configured_psk_count = ssl_tls13_get_configured_psk_count(ssl);
91332b31808SJens Wiklander     if (configured_psk_count == 0) {
91432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("skip pre_shared_key extensions"));
91532b31808SJens Wiklander         return 0;
91632b31808SJens Wiklander     }
91732b31808SJens Wiklander 
91832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(4, ("Pre-configured PSK number = %d",
91932b31808SJens Wiklander                               configured_psk_count));
92032b31808SJens Wiklander 
92132b31808SJens Wiklander     /* Check if we have space to write the extension, binders included.
92232b31808SJens Wiklander      * - extension_type         (2 bytes)
92332b31808SJens Wiklander      * - extension_data_len     (2 bytes)
92432b31808SJens Wiklander      * - identities_len         (2 bytes)
92532b31808SJens Wiklander      */
92632b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6);
92732b31808SJens Wiklander     p += 6;
92832b31808SJens Wiklander 
92932b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
93032b31808SJens Wiklander     if (ssl_tls13_ticket_get_identity(
93132b31808SJens Wiklander             ssl, &hash_alg, &identity, &identity_len) == 0) {
93232b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME)
933b0563631STom Van Eyck         mbedtls_ms_time_t now = mbedtls_ms_time();
93432b31808SJens Wiklander         mbedtls_ssl_session *session = ssl->session_negotiate;
935b0563631STom Van Eyck         /* The ticket age has been checked to be smaller than the
936b0563631STom Van Eyck          * `ticket_lifetime` in ssl_prepare_client_hello() which is smaller than
937b0563631STom Van Eyck          * 7 days (enforced in ssl_tls13_parse_new_session_ticket()) . Thus the
938b0563631STom Van Eyck          * cast to `uint32_t` of the ticket age is safe. */
93932b31808SJens Wiklander         uint32_t obfuscated_ticket_age =
940b0563631STom Van Eyck             (uint32_t) (now - session->ticket_reception_time);
94132b31808SJens Wiklander         obfuscated_ticket_age += session->ticket_age_add;
94232b31808SJens Wiklander 
94332b31808SJens Wiklander         ret = ssl_tls13_write_identity(ssl, p, end,
94432b31808SJens Wiklander                                        identity, identity_len,
94532b31808SJens Wiklander                                        obfuscated_ticket_age,
94632b31808SJens Wiklander                                        &output_len);
94732b31808SJens Wiklander #else
94832b31808SJens Wiklander         ret = ssl_tls13_write_identity(ssl, p, end, identity, identity_len,
94932b31808SJens Wiklander                                        0, &output_len);
95032b31808SJens Wiklander #endif /* MBEDTLS_HAVE_TIME */
95132b31808SJens Wiklander         if (ret != 0) {
95232b31808SJens Wiklander             return ret;
95332b31808SJens Wiklander         }
95432b31808SJens Wiklander 
95532b31808SJens Wiklander         p += output_len;
95632b31808SJens Wiklander         l_binders_len += 1 + PSA_HASH_LENGTH(hash_alg);
95732b31808SJens Wiklander     }
95832b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
95932b31808SJens Wiklander 
96032b31808SJens Wiklander     if (ssl_tls13_psk_get_identity(
96132b31808SJens Wiklander             ssl, &hash_alg, &identity, &identity_len) == 0) {
96232b31808SJens Wiklander 
96332b31808SJens Wiklander         ret = ssl_tls13_write_identity(ssl, p, end, identity, identity_len, 0,
96432b31808SJens Wiklander                                        &output_len);
96532b31808SJens Wiklander         if (ret != 0) {
96632b31808SJens Wiklander             return ret;
96732b31808SJens Wiklander         }
96832b31808SJens Wiklander 
96932b31808SJens Wiklander         p += output_len;
97032b31808SJens Wiklander         l_binders_len += 1 + PSA_HASH_LENGTH(hash_alg);
97132b31808SJens Wiklander     }
97232b31808SJens Wiklander 
97332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
97432b31808SJens Wiklander                           ("client hello, adding pre_shared_key extension, "
97532b31808SJens Wiklander                            "omitting PSK binder list"));
97632b31808SJens Wiklander 
97732b31808SJens Wiklander     /* Take into account the two bytes for the length of the binders. */
97832b31808SJens Wiklander     l_binders_len += 2;
97932b31808SJens Wiklander     /* Check if there is enough space for binders */
98032b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, l_binders_len);
98132b31808SJens Wiklander 
98232b31808SJens Wiklander     /*
98332b31808SJens Wiklander      * - extension_type         (2 bytes)
98432b31808SJens Wiklander      * - extension_data_len     (2 bytes)
98532b31808SJens Wiklander      * - identities_len         (2 bytes)
98632b31808SJens Wiklander      */
98732b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_PRE_SHARED_KEY, buf, 0);
98832b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(p - buf - 4 + l_binders_len, buf, 2);
98932b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(p - buf - 6, buf, 4);
99032b31808SJens Wiklander 
99132b31808SJens Wiklander     *out_len = (p - buf) + l_binders_len;
99232b31808SJens Wiklander     *binders_len = l_binders_len;
99332b31808SJens Wiklander 
99432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "pre_shared_key identities", buf, p - buf);
99532b31808SJens Wiklander 
99632b31808SJens Wiklander     return 0;
99732b31808SJens Wiklander }
99832b31808SJens Wiklander 
mbedtls_ssl_tls13_write_binders_of_pre_shared_key_ext(mbedtls_ssl_context * ssl,unsigned char * buf,unsigned char * end)99932b31808SJens Wiklander int mbedtls_ssl_tls13_write_binders_of_pre_shared_key_ext(
100032b31808SJens Wiklander     mbedtls_ssl_context *ssl, unsigned char *buf, unsigned char *end)
100132b31808SJens Wiklander {
100232b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
100332b31808SJens Wiklander     unsigned char *p = buf;
100432b31808SJens Wiklander     psa_algorithm_t hash_alg = PSA_ALG_NONE;
100532b31808SJens Wiklander     const unsigned char *psk;
100632b31808SJens Wiklander     size_t psk_len;
100732b31808SJens Wiklander     size_t output_len;
100832b31808SJens Wiklander 
100932b31808SJens Wiklander     /* Check if we have space to write binders_len.
101032b31808SJens Wiklander      * - binders_len         (2 bytes)
101132b31808SJens Wiklander      */
101232b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 2);
101332b31808SJens Wiklander     p += 2;
101432b31808SJens Wiklander 
101532b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
101632b31808SJens Wiklander     if (ssl_tls13_ticket_get_psk(ssl, &hash_alg, &psk, &psk_len) == 0) {
101732b31808SJens Wiklander 
101832b31808SJens Wiklander         ret = ssl_tls13_write_binder(ssl, p, end,
101932b31808SJens Wiklander                                      MBEDTLS_SSL_TLS1_3_PSK_RESUMPTION,
102032b31808SJens Wiklander                                      hash_alg, psk, psk_len,
102132b31808SJens Wiklander                                      &output_len);
102232b31808SJens Wiklander         if (ret != 0) {
102332b31808SJens Wiklander             return ret;
102432b31808SJens Wiklander         }
102532b31808SJens Wiklander         p += output_len;
102632b31808SJens Wiklander     }
102732b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
102832b31808SJens Wiklander 
102932b31808SJens Wiklander     if (ssl_tls13_psk_get_psk(ssl, &hash_alg, &psk, &psk_len) == 0) {
103032b31808SJens Wiklander 
103132b31808SJens Wiklander         ret = ssl_tls13_write_binder(ssl, p, end,
103232b31808SJens Wiklander                                      MBEDTLS_SSL_TLS1_3_PSK_EXTERNAL,
103332b31808SJens Wiklander                                      hash_alg, psk, psk_len,
103432b31808SJens Wiklander                                      &output_len);
103532b31808SJens Wiklander         if (ret != 0) {
103632b31808SJens Wiklander             return ret;
103732b31808SJens Wiklander         }
103832b31808SJens Wiklander         p += output_len;
103932b31808SJens Wiklander     }
104032b31808SJens Wiklander 
104132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding PSK binder list."));
104232b31808SJens Wiklander 
104332b31808SJens Wiklander     /*
104432b31808SJens Wiklander      * - binders_len         (2 bytes)
104532b31808SJens Wiklander      */
104632b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(p - buf - 2, buf, 0);
104732b31808SJens Wiklander 
104832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "pre_shared_key binders", buf, p - buf);
104932b31808SJens Wiklander 
105032b31808SJens Wiklander     mbedtls_ssl_tls13_set_hs_sent_ext_mask(
105132b31808SJens Wiklander         ssl, MBEDTLS_TLS_EXT_PRE_SHARED_KEY);
105232b31808SJens Wiklander 
105332b31808SJens Wiklander     return 0;
105432b31808SJens Wiklander }
105532b31808SJens Wiklander 
105632b31808SJens Wiklander /*
105732b31808SJens Wiklander  * struct {
105832b31808SJens Wiklander  *   opaque identity<1..2^16-1>;
105932b31808SJens Wiklander  *   uint32 obfuscated_ticket_age;
106032b31808SJens Wiklander  * } PskIdentity;
106132b31808SJens Wiklander  *
106232b31808SJens Wiklander  * opaque PskBinderEntry<32..255>;
106332b31808SJens Wiklander  *
106432b31808SJens Wiklander  * struct {
106532b31808SJens Wiklander  *
106632b31808SJens Wiklander  *   select (Handshake.msg_type) {
106732b31808SJens Wiklander  *         ...
106832b31808SJens Wiklander  *         case server_hello: uint16 selected_identity;
106932b31808SJens Wiklander  *   };
107032b31808SJens Wiklander  *
107132b31808SJens Wiklander  * } PreSharedKeyExtension;
107232b31808SJens Wiklander  *
107332b31808SJens Wiklander  */
107432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_parse_server_pre_shared_key_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,const unsigned char * end)107532b31808SJens Wiklander static int ssl_tls13_parse_server_pre_shared_key_ext(mbedtls_ssl_context *ssl,
107632b31808SJens Wiklander                                                      const unsigned char *buf,
107732b31808SJens Wiklander                                                      const unsigned char *end)
107832b31808SJens Wiklander {
107932b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
108032b31808SJens Wiklander     int selected_identity;
108132b31808SJens Wiklander     const unsigned char *psk;
108232b31808SJens Wiklander     size_t psk_len;
108332b31808SJens Wiklander     psa_algorithm_t hash_alg;
108432b31808SJens Wiklander 
108532b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(buf, end, 2);
108632b31808SJens Wiklander     selected_identity = MBEDTLS_GET_UINT16_BE(buf, 0);
108732b31808SJens Wiklander     ssl->handshake->selected_identity = (uint16_t) selected_identity;
108832b31808SJens Wiklander 
108932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("selected_identity = %d", selected_identity));
109032b31808SJens Wiklander 
109132b31808SJens Wiklander     if (selected_identity >= ssl_tls13_get_configured_psk_count(ssl)) {
109232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid PSK identity."));
109332b31808SJens Wiklander 
109432b31808SJens Wiklander         MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
109532b31808SJens Wiklander                                      MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
109632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
109732b31808SJens Wiklander     }
109832b31808SJens Wiklander 
109932b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
110032b31808SJens Wiklander     if (selected_identity == 0 && ssl_tls13_has_configured_ticket(ssl)) {
110132b31808SJens Wiklander         ret = ssl_tls13_ticket_get_psk(ssl, &hash_alg, &psk, &psk_len);
110232b31808SJens Wiklander     } else
110332b31808SJens Wiklander #endif
110432b31808SJens Wiklander     if (mbedtls_ssl_conf_has_static_psk(ssl->conf)) {
110532b31808SJens Wiklander         ret = ssl_tls13_psk_get_psk(ssl, &hash_alg, &psk, &psk_len);
110632b31808SJens Wiklander     } else {
110732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
110832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
110932b31808SJens Wiklander     }
111032b31808SJens Wiklander     if (ret != 0) {
111132b31808SJens Wiklander         return ret;
111232b31808SJens Wiklander     }
111332b31808SJens Wiklander 
1114b0563631STom Van Eyck     if (mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ssl->handshake->ciphersuite_info->mac)
111532b31808SJens Wiklander         != hash_alg) {
111632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(
111732b31808SJens Wiklander             1, ("Invalid ciphersuite for external psk."));
111832b31808SJens Wiklander 
111932b31808SJens Wiklander         MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
112032b31808SJens Wiklander                                      MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
112132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
112232b31808SJens Wiklander     }
112332b31808SJens Wiklander 
112432b31808SJens Wiklander     ret = mbedtls_ssl_set_hs_psk(ssl, psk, psk_len);
112532b31808SJens Wiklander     if (ret != 0) {
112632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_set_hs_psk", ret);
112732b31808SJens Wiklander         return ret;
112832b31808SJens Wiklander     }
112932b31808SJens Wiklander 
113032b31808SJens Wiklander     return 0;
113132b31808SJens Wiklander }
113232b31808SJens Wiklander #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED */
113332b31808SJens Wiklander 
mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context * ssl,unsigned char * buf,unsigned char * end,size_t * out_len)113432b31808SJens Wiklander int mbedtls_ssl_tls13_write_client_hello_exts(mbedtls_ssl_context *ssl,
113532b31808SJens Wiklander                                               unsigned char *buf,
113632b31808SJens Wiklander                                               unsigned char *end,
113732b31808SJens Wiklander                                               size_t *out_len)
113832b31808SJens Wiklander {
113932b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
114032b31808SJens Wiklander     unsigned char *p = buf;
114132b31808SJens Wiklander     size_t ext_len;
114232b31808SJens Wiklander 
114332b31808SJens Wiklander     *out_len = 0;
114432b31808SJens Wiklander 
1145cb034002SJerome Forissier     ret = mbedtls_ssl_tls13_crypto_init(ssl);
1146cb034002SJerome Forissier     if (ret != 0) {
1147cb034002SJerome Forissier         return ret;
1148cb034002SJerome Forissier     }
1149cb034002SJerome Forissier 
115032b31808SJens Wiklander     /* Write supported_versions extension
115132b31808SJens Wiklander      *
115232b31808SJens Wiklander      * Supported Versions Extension is mandatory with TLS 1.3.
115332b31808SJens Wiklander      */
115432b31808SJens Wiklander     ret = ssl_tls13_write_supported_versions_ext(ssl, p, end, &ext_len);
115532b31808SJens Wiklander     if (ret != 0) {
115632b31808SJens Wiklander         return ret;
115732b31808SJens Wiklander     }
115832b31808SJens Wiklander     p += ext_len;
115932b31808SJens Wiklander 
116032b31808SJens Wiklander     /* Echo the cookie if the server provided one in its preceding
116132b31808SJens Wiklander      * HelloRetryRequest message.
116232b31808SJens Wiklander      */
116332b31808SJens Wiklander     ret = ssl_tls13_write_cookie_ext(ssl, p, end, &ext_len);
116432b31808SJens Wiklander     if (ret != 0) {
116532b31808SJens Wiklander         return ret;
116632b31808SJens Wiklander     }
116732b31808SJens Wiklander     p += ext_len;
116832b31808SJens Wiklander 
1169b0563631STom Van Eyck #if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
1170b0563631STom Van Eyck     ret = mbedtls_ssl_tls13_write_record_size_limit_ext(
1171b0563631STom Van Eyck         ssl, p, end, &ext_len);
1172b0563631STom Van Eyck     if (ret != 0) {
1173b0563631STom Van Eyck         return ret;
1174b0563631STom Van Eyck     }
1175b0563631STom Van Eyck     p += ext_len;
1176b0563631STom Van Eyck #endif
1177b0563631STom Van Eyck 
117832b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_EPHEMERAL_ENABLED)
1179b0563631STom Van Eyck     if (mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(ssl)) {
118032b31808SJens Wiklander         ret = ssl_tls13_write_key_share_ext(ssl, p, end, &ext_len);
118132b31808SJens Wiklander         if (ret != 0) {
118232b31808SJens Wiklander             return ret;
118332b31808SJens Wiklander         }
118432b31808SJens Wiklander         p += ext_len;
118532b31808SJens Wiklander     }
118632b31808SJens Wiklander #endif
118732b31808SJens Wiklander 
118832b31808SJens Wiklander #if defined(MBEDTLS_SSL_EARLY_DATA)
1189b0563631STom Van Eyck     /* In the first ClientHello, write the early data indication extension if
1190b0563631STom Van Eyck      * necessary and update the early data state.
1191b0563631STom Van Eyck      * If an HRR has been received and thus we are currently writing the
1192b0563631STom Van Eyck      * second ClientHello, the second ClientHello must not contain an early
1193b0563631STom Van Eyck      * data extension and the early data state must stay as it is:
1194b0563631STom Van Eyck      * MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT or
1195b0563631STom Van Eyck      * MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED.
1196b0563631STom Van Eyck      */
1197b0563631STom Van Eyck     if (!ssl->handshake->hello_retry_request_flag) {
1198b0563631STom Van Eyck         if (mbedtls_ssl_conf_tls13_is_some_psk_enabled(ssl) &&
119932b31808SJens Wiklander             ssl_tls13_early_data_has_valid_ticket(ssl) &&
120032b31808SJens Wiklander             ssl->conf->early_data_enabled == MBEDTLS_SSL_EARLY_DATA_ENABLED) {
1201b0563631STom Van Eyck             ret = mbedtls_ssl_tls13_write_early_data_ext(
1202b0563631STom Van Eyck                 ssl, 0, p, end, &ext_len);
120332b31808SJens Wiklander             if (ret != 0) {
120432b31808SJens Wiklander                 return ret;
120532b31808SJens Wiklander             }
120632b31808SJens Wiklander             p += ext_len;
120732b31808SJens Wiklander 
1208b0563631STom Van Eyck             ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT;
120932b31808SJens Wiklander         } else {
1210b0563631STom Van Eyck             ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT;
1211b0563631STom Van Eyck         }
121232b31808SJens Wiklander     }
121332b31808SJens Wiklander #endif /* MBEDTLS_SSL_EARLY_DATA */
121432b31808SJens Wiklander 
121532b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
121632b31808SJens Wiklander     /* For PSK-based key exchange we need the pre_shared_key extension
121732b31808SJens Wiklander      * and the psk_key_exchange_modes extension.
121832b31808SJens Wiklander      *
121932b31808SJens Wiklander      * The pre_shared_key extension MUST be the last extension in the
122032b31808SJens Wiklander      * ClientHello. Servers MUST check that it is the last extension and
122132b31808SJens Wiklander      * otherwise fail the handshake with an "illegal_parameter" alert.
122232b31808SJens Wiklander      *
122332b31808SJens Wiklander      * Add the psk_key_exchange_modes extension.
122432b31808SJens Wiklander      */
122532b31808SJens Wiklander     ret = ssl_tls13_write_psk_key_exchange_modes_ext(ssl, p, end, &ext_len);
122632b31808SJens Wiklander     if (ret != 0) {
122732b31808SJens Wiklander         return ret;
122832b31808SJens Wiklander     }
122932b31808SJens Wiklander     p += ext_len;
123032b31808SJens Wiklander #endif
123132b31808SJens Wiklander 
123232b31808SJens Wiklander     *out_len = p - buf;
123332b31808SJens Wiklander 
123432b31808SJens Wiklander     return 0;
123532b31808SJens Wiklander }
123632b31808SJens Wiklander 
mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context * ssl)123732b31808SJens Wiklander int mbedtls_ssl_tls13_finalize_client_hello(mbedtls_ssl_context *ssl)
123832b31808SJens Wiklander {
123932b31808SJens Wiklander     ((void) ssl);
124032b31808SJens Wiklander 
124132b31808SJens Wiklander #if defined(MBEDTLS_SSL_EARLY_DATA)
124232b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
124332b31808SJens Wiklander     psa_algorithm_t hash_alg = PSA_ALG_NONE;
124432b31808SJens Wiklander     const unsigned char *psk;
124532b31808SJens Wiklander     size_t psk_len;
124632b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
124732b31808SJens Wiklander 
1248b0563631STom Van Eyck     if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_IND_SENT) {
124932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(
125032b31808SJens Wiklander             1, ("Set hs psk for early data when writing the first psk"));
125132b31808SJens Wiklander 
125232b31808SJens Wiklander         ret = ssl_tls13_ticket_get_psk(ssl, &hash_alg, &psk, &psk_len);
125332b31808SJens Wiklander         if (ret != 0) {
125432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(
125532b31808SJens Wiklander                 1, "ssl_tls13_ticket_get_psk", ret);
125632b31808SJens Wiklander             return ret;
125732b31808SJens Wiklander         }
125832b31808SJens Wiklander 
125932b31808SJens Wiklander         ret = mbedtls_ssl_set_hs_psk(ssl, psk, psk_len);
126032b31808SJens Wiklander         if (ret  != 0) {
126132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_set_hs_psk", ret);
126232b31808SJens Wiklander             return ret;
126332b31808SJens Wiklander         }
126432b31808SJens Wiklander 
126532b31808SJens Wiklander         /*
126632b31808SJens Wiklander          * Early data are going to be encrypted using the ciphersuite
126732b31808SJens Wiklander          * associated with the pre-shared key used for the handshake.
126832b31808SJens Wiklander          * Note that if the server rejects early data, the handshake
126932b31808SJens Wiklander          * based on the pre-shared key may complete successfully
127032b31808SJens Wiklander          * with a selected ciphersuite different from the ciphersuite
127132b31808SJens Wiklander          * associated with the pre-shared key. Only the hashes of the
127232b31808SJens Wiklander          * two ciphersuites have to be the same. In that case, the
127332b31808SJens Wiklander          * encrypted handshake data and application data are
127432b31808SJens Wiklander          * encrypted using a different ciphersuite than the one used for
127532b31808SJens Wiklander          * the rejected early data.
127632b31808SJens Wiklander          */
127732b31808SJens Wiklander         ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(
127832b31808SJens Wiklander             ssl->session_negotiate->ciphersuite);
127932b31808SJens Wiklander         ssl->handshake->ciphersuite_info = ciphersuite_info;
128032b31808SJens Wiklander 
128132b31808SJens Wiklander         /* Enable psk and psk_ephemeral to make stage early happy */
128232b31808SJens Wiklander         ssl->handshake->key_exchange_mode =
128332b31808SJens Wiklander             MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ALL;
128432b31808SJens Wiklander 
128532b31808SJens Wiklander         /* Start the TLS 1.3 key schedule:
128632b31808SJens Wiklander          *     Set the PSK and derive early secret.
128732b31808SJens Wiklander          */
128832b31808SJens Wiklander         ret = mbedtls_ssl_tls13_key_schedule_stage_early(ssl);
128932b31808SJens Wiklander         if (ret != 0) {
129032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(
129132b31808SJens Wiklander                 1, "mbedtls_ssl_tls13_key_schedule_stage_early", ret);
129232b31808SJens Wiklander             return ret;
129332b31808SJens Wiklander         }
129432b31808SJens Wiklander 
129532b31808SJens Wiklander         /* Derive early data key material */
129632b31808SJens Wiklander         ret = mbedtls_ssl_tls13_compute_early_transform(ssl);
129732b31808SJens Wiklander         if (ret != 0) {
129832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(
129932b31808SJens Wiklander                 1, "mbedtls_ssl_tls13_compute_early_transform", ret);
130032b31808SJens Wiklander             return ret;
130132b31808SJens Wiklander         }
130232b31808SJens Wiklander 
1303b0563631STom Van Eyck #if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
1304b0563631STom Van Eyck         mbedtls_ssl_handshake_set_state(
1305b0563631STom Van Eyck             ssl, MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO);
1306b0563631STom Van Eyck #else
1307b0563631STom Van Eyck         MBEDTLS_SSL_DEBUG_MSG(
1308b0563631STom Van Eyck             1, ("Switch to early data keys for outbound traffic"));
1309b0563631STom Van Eyck         mbedtls_ssl_set_outbound_transform(
1310b0563631STom Van Eyck             ssl, ssl->handshake->transform_earlydata);
1311b0563631STom Van Eyck         ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE;
1312b0563631STom Van Eyck #endif
131332b31808SJens Wiklander     }
131432b31808SJens Wiklander #endif /* MBEDTLS_SSL_EARLY_DATA */
131532b31808SJens Wiklander     return 0;
131632b31808SJens Wiklander }
131732b31808SJens Wiklander /*
131832b31808SJens Wiklander  * Functions for parsing and processing Server Hello
131932b31808SJens Wiklander  */
132032b31808SJens Wiklander 
132132b31808SJens Wiklander /**
132232b31808SJens Wiklander  * \brief Detect if the ServerHello contains a supported_versions extension
132332b31808SJens Wiklander  *        or not.
132432b31808SJens Wiklander  *
132532b31808SJens Wiklander  * \param[in] ssl  SSL context
132632b31808SJens Wiklander  * \param[in] buf  Buffer containing the ServerHello message
132732b31808SJens Wiklander  * \param[in] end  End of the buffer containing the ServerHello message
132832b31808SJens Wiklander  *
132932b31808SJens Wiklander  * \return 0 if the ServerHello does not contain a supported_versions extension
133032b31808SJens Wiklander  * \return 1 if the ServerHello contains a supported_versions extension
133132b31808SJens Wiklander  * \return A negative value if an error occurred while parsing the ServerHello.
133232b31808SJens Wiklander  */
133332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_is_supported_versions_ext_present(mbedtls_ssl_context * ssl,const unsigned char * buf,const unsigned char * end)133432b31808SJens Wiklander static int ssl_tls13_is_supported_versions_ext_present(
133532b31808SJens Wiklander     mbedtls_ssl_context *ssl,
133632b31808SJens Wiklander     const unsigned char *buf,
133732b31808SJens Wiklander     const unsigned char *end)
133832b31808SJens Wiklander {
133932b31808SJens Wiklander     const unsigned char *p = buf;
134032b31808SJens Wiklander     size_t legacy_session_id_echo_len;
1341b0563631STom Van Eyck     const unsigned char *supported_versions_data;
1342b0563631STom Van Eyck     const unsigned char *supported_versions_data_end;
134332b31808SJens Wiklander 
134432b31808SJens Wiklander     /*
134532b31808SJens Wiklander      * Check there is enough data to access the legacy_session_id_echo vector
134632b31808SJens Wiklander      * length:
134732b31808SJens Wiklander      * - legacy_version                 2 bytes
134832b31808SJens Wiklander      * - random                         MBEDTLS_SERVER_HELLO_RANDOM_LEN bytes
134932b31808SJens Wiklander      * - legacy_session_id_echo length  1 byte
135032b31808SJens Wiklander      */
135132b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, MBEDTLS_SERVER_HELLO_RANDOM_LEN + 3);
135232b31808SJens Wiklander     p += MBEDTLS_SERVER_HELLO_RANDOM_LEN + 2;
135332b31808SJens Wiklander     legacy_session_id_echo_len = *p;
135432b31808SJens Wiklander 
135532b31808SJens Wiklander     /*
135632b31808SJens Wiklander      * Jump to the extensions, jumping over:
135732b31808SJens Wiklander      * - legacy_session_id_echo     (legacy_session_id_echo_len + 1) bytes
135832b31808SJens Wiklander      * - cipher_suite               2 bytes
135932b31808SJens Wiklander      * - legacy_compression_method  1 byte
136032b31808SJens Wiklander      */
136132b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, legacy_session_id_echo_len + 4);
136232b31808SJens Wiklander     p += legacy_session_id_echo_len + 4;
136332b31808SJens Wiklander 
1364b0563631STom Van Eyck     return mbedtls_ssl_tls13_is_supported_versions_ext_present_in_exts(
1365b0563631STom Van Eyck         ssl, p, end,
1366b0563631STom Van Eyck         &supported_versions_data, &supported_versions_data_end);
136732b31808SJens Wiklander }
136832b31808SJens Wiklander 
136932b31808SJens Wiklander /* Returns a negative value on failure, and otherwise
137032b31808SJens Wiklander  * - 1 if the last eight bytes of the ServerHello random bytes indicate that
137132b31808SJens Wiklander  *     the server is TLS 1.3 capable but negotiating TLS 1.2 or below.
137232b31808SJens Wiklander  * - 0 otherwise
137332b31808SJens Wiklander  */
137432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_is_downgrade_negotiation(mbedtls_ssl_context * ssl,const unsigned char * buf,const unsigned char * end)137532b31808SJens Wiklander static int ssl_tls13_is_downgrade_negotiation(mbedtls_ssl_context *ssl,
137632b31808SJens Wiklander                                               const unsigned char *buf,
137732b31808SJens Wiklander                                               const unsigned char *end)
137832b31808SJens Wiklander {
137932b31808SJens Wiklander     /* First seven bytes of the magic downgrade strings, see RFC 8446 4.1.3 */
138032b31808SJens Wiklander     static const unsigned char magic_downgrade_string[] =
138132b31808SJens Wiklander     { 0x44, 0x4F, 0x57, 0x4E, 0x47, 0x52, 0x44 };
138232b31808SJens Wiklander     const unsigned char *last_eight_bytes_of_random;
138332b31808SJens Wiklander     unsigned char last_byte_of_random;
138432b31808SJens Wiklander 
138532b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(buf, end, MBEDTLS_SERVER_HELLO_RANDOM_LEN + 2);
138632b31808SJens Wiklander     last_eight_bytes_of_random = buf + 2 + MBEDTLS_SERVER_HELLO_RANDOM_LEN - 8;
138732b31808SJens Wiklander 
138832b31808SJens Wiklander     if (memcmp(last_eight_bytes_of_random,
138932b31808SJens Wiklander                magic_downgrade_string,
139032b31808SJens Wiklander                sizeof(magic_downgrade_string)) == 0) {
139132b31808SJens Wiklander         last_byte_of_random = last_eight_bytes_of_random[7];
139232b31808SJens Wiklander         return last_byte_of_random == 0 ||
139332b31808SJens Wiklander                last_byte_of_random == 1;
139432b31808SJens Wiklander     }
139532b31808SJens Wiklander 
139632b31808SJens Wiklander     return 0;
139732b31808SJens Wiklander }
139832b31808SJens Wiklander 
139932b31808SJens Wiklander /* Returns a negative value on failure, and otherwise
140032b31808SJens Wiklander  * - SSL_SERVER_HELLO or
140132b31808SJens Wiklander  * - SSL_SERVER_HELLO_HRR
140232b31808SJens Wiklander  * to indicate which message is expected and to be parsed next.
140332b31808SJens Wiklander  */
140432b31808SJens Wiklander #define SSL_SERVER_HELLO 0
140532b31808SJens Wiklander #define SSL_SERVER_HELLO_HRR 1
140632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_server_hello_is_hrr(mbedtls_ssl_context * ssl,const unsigned char * buf,const unsigned char * end)140732b31808SJens Wiklander static int ssl_server_hello_is_hrr(mbedtls_ssl_context *ssl,
140832b31808SJens Wiklander                                    const unsigned char *buf,
140932b31808SJens Wiklander                                    const unsigned char *end)
141032b31808SJens Wiklander {
141132b31808SJens Wiklander 
141232b31808SJens Wiklander     /* Check whether this message is a HelloRetryRequest ( HRR ) message.
141332b31808SJens Wiklander      *
141432b31808SJens Wiklander      * Server Hello and HRR are only distinguished by Random set to the
141532b31808SJens Wiklander      * special value of the SHA-256 of "HelloRetryRequest".
141632b31808SJens Wiklander      *
141732b31808SJens Wiklander      * struct {
141832b31808SJens Wiklander      *    ProtocolVersion legacy_version = 0x0303;
141932b31808SJens Wiklander      *    Random random;
142032b31808SJens Wiklander      *    opaque legacy_session_id_echo<0..32>;
142132b31808SJens Wiklander      *    CipherSuite cipher_suite;
142232b31808SJens Wiklander      *    uint8 legacy_compression_method = 0;
142332b31808SJens Wiklander      *    Extension extensions<6..2^16-1>;
142432b31808SJens Wiklander      * } ServerHello;
142532b31808SJens Wiklander      *
142632b31808SJens Wiklander      */
1427b0563631STom Van Eyck     MBEDTLS_SSL_CHK_BUF_READ_PTR(
1428b0563631STom Van Eyck         buf, end, 2 + sizeof(mbedtls_ssl_tls13_hello_retry_request_magic));
142932b31808SJens Wiklander 
143032b31808SJens Wiklander     if (memcmp(buf + 2, mbedtls_ssl_tls13_hello_retry_request_magic,
143132b31808SJens Wiklander                sizeof(mbedtls_ssl_tls13_hello_retry_request_magic)) == 0) {
143232b31808SJens Wiklander         return SSL_SERVER_HELLO_HRR;
143332b31808SJens Wiklander     }
143432b31808SJens Wiklander 
143532b31808SJens Wiklander     return SSL_SERVER_HELLO;
143632b31808SJens Wiklander }
143732b31808SJens Wiklander 
143832b31808SJens Wiklander /*
143932b31808SJens Wiklander  * Returns a negative value on failure, and otherwise
144032b31808SJens Wiklander  * - SSL_SERVER_HELLO or
144132b31808SJens Wiklander  * - SSL_SERVER_HELLO_HRR or
144232b31808SJens Wiklander  * - SSL_SERVER_HELLO_TLS1_2
144332b31808SJens Wiklander  */
144432b31808SJens Wiklander #define SSL_SERVER_HELLO_TLS1_2 2
144532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_preprocess_server_hello(mbedtls_ssl_context * ssl,const unsigned char * buf,const unsigned char * end)144632b31808SJens Wiklander static int ssl_tls13_preprocess_server_hello(mbedtls_ssl_context *ssl,
144732b31808SJens Wiklander                                              const unsigned char *buf,
144832b31808SJens Wiklander                                              const unsigned char *end)
144932b31808SJens Wiklander {
145032b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
145132b31808SJens Wiklander     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
145232b31808SJens Wiklander 
145332b31808SJens Wiklander     MBEDTLS_SSL_PROC_CHK_NEG(ssl_tls13_is_supported_versions_ext_present(
145432b31808SJens Wiklander                                  ssl, buf, end));
145532b31808SJens Wiklander 
145632b31808SJens Wiklander     if (ret == 0) {
145732b31808SJens Wiklander         MBEDTLS_SSL_PROC_CHK_NEG(
145832b31808SJens Wiklander             ssl_tls13_is_downgrade_negotiation(ssl, buf, end));
145932b31808SJens Wiklander 
146032b31808SJens Wiklander         /* If the server is negotiating TLS 1.2 or below and:
146132b31808SJens Wiklander          * . we did not propose TLS 1.2 or
146232b31808SJens Wiklander          * . the server responded it is TLS 1.3 capable but negotiating a lower
146332b31808SJens Wiklander          *   version of the protocol and thus we are under downgrade attack
146432b31808SJens Wiklander          * abort the handshake with an "illegal parameter" alert.
146532b31808SJens Wiklander          */
146632b31808SJens Wiklander         if (handshake->min_tls_version > MBEDTLS_SSL_VERSION_TLS1_2 || ret) {
146732b31808SJens Wiklander             MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
146832b31808SJens Wiklander                                          MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
146932b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
147032b31808SJens Wiklander         }
147132b31808SJens Wiklander 
1472b0563631STom Van Eyck         /*
1473b0563631STom Van Eyck          * Version 1.2 of the protocol has been negotiated, set the
1474b0563631STom Van Eyck          * ssl->keep_current_message flag for the ServerHello to be kept and
1475b0563631STom Van Eyck          * parsed as a TLS 1.2 ServerHello. We also change ssl->tls_version to
1476b0563631STom Van Eyck          * MBEDTLS_SSL_VERSION_TLS1_2 thus from now on mbedtls_ssl_handshake_step()
1477b0563631STom Van Eyck          * will dispatch to the TLS 1.2 state machine.
1478b0563631STom Van Eyck          */
147932b31808SJens Wiklander         ssl->keep_current_message = 1;
148032b31808SJens Wiklander         ssl->tls_version = MBEDTLS_SSL_VERSION_TLS1_2;
1481b0563631STom Van Eyck         MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
1482b0563631STom Van Eyck                                  ssl, MBEDTLS_SSL_HS_SERVER_HELLO,
148332b31808SJens Wiklander                                  buf, (size_t) (end - buf)));
148432b31808SJens Wiklander 
1485b0563631STom Van Eyck         if (mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(ssl)) {
148632b31808SJens Wiklander             ret = ssl_tls13_reset_key_share(ssl);
148732b31808SJens Wiklander             if (ret != 0) {
148832b31808SJens Wiklander                 return ret;
148932b31808SJens Wiklander             }
149032b31808SJens Wiklander         }
149132b31808SJens Wiklander 
149232b31808SJens Wiklander         return SSL_SERVER_HELLO_TLS1_2;
149332b31808SJens Wiklander     }
149432b31808SJens Wiklander 
149532b31808SJens Wiklander     ssl->session_negotiate->tls_version = ssl->tls_version;
1496b0563631STom Van Eyck     ssl->session_negotiate->endpoint = ssl->conf->endpoint;
149732b31808SJens Wiklander 
149832b31808SJens Wiklander     handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
149932b31808SJens Wiklander 
150032b31808SJens Wiklander     ret = ssl_server_hello_is_hrr(ssl, buf, end);
150132b31808SJens Wiklander     switch (ret) {
150232b31808SJens Wiklander         case SSL_SERVER_HELLO:
150332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2, ("received ServerHello message"));
150432b31808SJens Wiklander             break;
150532b31808SJens Wiklander         case SSL_SERVER_HELLO_HRR:
150632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2, ("received HelloRetryRequest message"));
1507b0563631STom Van Eyck             /* If a client receives a second HelloRetryRequest in the same
1508b0563631STom Van Eyck              * connection (i.e., where the ClientHello was itself in response
1509b0563631STom Van Eyck              * to a HelloRetryRequest), it MUST abort the handshake with an
1510b0563631STom Van Eyck              * "unexpected_message" alert.
151132b31808SJens Wiklander              */
1512b0563631STom Van Eyck             if (handshake->hello_retry_request_flag) {
151332b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1, ("Multiple HRRs received"));
1514b0563631STom Van Eyck                 MBEDTLS_SSL_PEND_FATAL_ALERT(
1515b0563631STom Van Eyck                     MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE,
151632b31808SJens Wiklander                     MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE);
151732b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
151832b31808SJens Wiklander             }
151932b31808SJens Wiklander             /*
152032b31808SJens Wiklander              * Clients must abort the handshake with an "illegal_parameter"
152132b31808SJens Wiklander              * alert if the HelloRetryRequest would not result in any change
152232b31808SJens Wiklander              * in the ClientHello.
152332b31808SJens Wiklander              * In a PSK only key exchange that what we expect.
152432b31808SJens Wiklander              */
1525b0563631STom Van Eyck             if (!mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(ssl)) {
152632b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1,
152732b31808SJens Wiklander                                       ("Unexpected HRR in pure PSK key exchange."));
152832b31808SJens Wiklander                 MBEDTLS_SSL_PEND_FATAL_ALERT(
152932b31808SJens Wiklander                     MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
153032b31808SJens Wiklander                     MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
153132b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
153232b31808SJens Wiklander             }
153332b31808SJens Wiklander 
1534b0563631STom Van Eyck             handshake->hello_retry_request_flag = 1;
153532b31808SJens Wiklander 
153632b31808SJens Wiklander             break;
153732b31808SJens Wiklander     }
153832b31808SJens Wiklander 
153932b31808SJens Wiklander cleanup:
154032b31808SJens Wiklander 
154132b31808SJens Wiklander     return ret;
154232b31808SJens Wiklander }
154332b31808SJens Wiklander 
154432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_check_server_hello_session_id_echo(mbedtls_ssl_context * ssl,const unsigned char ** buf,const unsigned char * end)154532b31808SJens Wiklander static int ssl_tls13_check_server_hello_session_id_echo(mbedtls_ssl_context *ssl,
154632b31808SJens Wiklander                                                         const unsigned char **buf,
154732b31808SJens Wiklander                                                         const unsigned char *end)
154832b31808SJens Wiklander {
154932b31808SJens Wiklander     const unsigned char *p = *buf;
155032b31808SJens Wiklander     size_t legacy_session_id_echo_len;
155132b31808SJens Wiklander 
155232b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 1);
155332b31808SJens Wiklander     legacy_session_id_echo_len = *p++;
155432b31808SJens Wiklander 
155532b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, legacy_session_id_echo_len);
155632b31808SJens Wiklander 
155732b31808SJens Wiklander     /* legacy_session_id_echo */
155832b31808SJens Wiklander     if (ssl->session_negotiate->id_len != legacy_session_id_echo_len ||
155932b31808SJens Wiklander         memcmp(ssl->session_negotiate->id, p, legacy_session_id_echo_len) != 0) {
156032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "Expected Session ID",
156132b31808SJens Wiklander                               ssl->session_negotiate->id,
156232b31808SJens Wiklander                               ssl->session_negotiate->id_len);
156332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "Received Session ID", p,
156432b31808SJens Wiklander                               legacy_session_id_echo_len);
156532b31808SJens Wiklander 
156632b31808SJens Wiklander         MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
156732b31808SJens Wiklander                                      MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
156832b31808SJens Wiklander 
156932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
157032b31808SJens Wiklander     }
157132b31808SJens Wiklander 
157232b31808SJens Wiklander     p += legacy_session_id_echo_len;
157332b31808SJens Wiklander     *buf = p;
157432b31808SJens Wiklander 
157532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "Session ID", ssl->session_negotiate->id,
157632b31808SJens Wiklander                           ssl->session_negotiate->id_len);
157732b31808SJens Wiklander     return 0;
157832b31808SJens Wiklander }
157932b31808SJens Wiklander 
158032b31808SJens Wiklander /* Parse ServerHello message and configure context
158132b31808SJens Wiklander  *
158232b31808SJens Wiklander  * struct {
158332b31808SJens Wiklander  *    ProtocolVersion legacy_version = 0x0303; // TLS 1.2
158432b31808SJens Wiklander  *    Random random;
158532b31808SJens Wiklander  *    opaque legacy_session_id_echo<0..32>;
158632b31808SJens Wiklander  *    CipherSuite cipher_suite;
158732b31808SJens Wiklander  *    uint8 legacy_compression_method = 0;
158832b31808SJens Wiklander  *    Extension extensions<6..2^16-1>;
158932b31808SJens Wiklander  * } ServerHello;
159032b31808SJens Wiklander  */
159132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_parse_server_hello(mbedtls_ssl_context * ssl,const unsigned char * buf,const unsigned char * end,int is_hrr)159232b31808SJens Wiklander static int ssl_tls13_parse_server_hello(mbedtls_ssl_context *ssl,
159332b31808SJens Wiklander                                         const unsigned char *buf,
159432b31808SJens Wiklander                                         const unsigned char *end,
159532b31808SJens Wiklander                                         int is_hrr)
159632b31808SJens Wiklander {
159732b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
159832b31808SJens Wiklander     const unsigned char *p = buf;
159932b31808SJens Wiklander     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
160032b31808SJens Wiklander     size_t extensions_len;
160132b31808SJens Wiklander     const unsigned char *extensions_end;
160232b31808SJens Wiklander     uint16_t cipher_suite;
160332b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
160432b31808SJens Wiklander     int fatal_alert = 0;
160532b31808SJens Wiklander     uint32_t allowed_extensions_mask;
160632b31808SJens Wiklander     int hs_msg_type = is_hrr ? MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST :
160732b31808SJens Wiklander                       MBEDTLS_SSL_HS_SERVER_HELLO;
160832b31808SJens Wiklander 
160932b31808SJens Wiklander     /*
161032b31808SJens Wiklander      * Check there is space for minimal fields
161132b31808SJens Wiklander      *
161232b31808SJens Wiklander      * - legacy_version             ( 2 bytes)
161332b31808SJens Wiklander      * - random                     (MBEDTLS_SERVER_HELLO_RANDOM_LEN bytes)
161432b31808SJens Wiklander      * - legacy_session_id_echo     ( 1 byte ), minimum size
161532b31808SJens Wiklander      * - cipher_suite               ( 2 bytes)
161632b31808SJens Wiklander      * - legacy_compression_method  ( 1 byte )
161732b31808SJens Wiklander      */
161832b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, MBEDTLS_SERVER_HELLO_RANDOM_LEN + 6);
161932b31808SJens Wiklander 
162032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(4, "server hello", p, end - p);
162132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "server hello, version", p, 2);
162232b31808SJens Wiklander 
162332b31808SJens Wiklander     /* ...
162432b31808SJens Wiklander      * ProtocolVersion legacy_version = 0x0303; // TLS 1.2
162532b31808SJens Wiklander      * ...
162632b31808SJens Wiklander      * with ProtocolVersion defined as:
162732b31808SJens Wiklander      * uint16 ProtocolVersion;
162832b31808SJens Wiklander      */
162932b31808SJens Wiklander     if (mbedtls_ssl_read_version(p, ssl->conf->transport) !=
163032b31808SJens Wiklander         MBEDTLS_SSL_VERSION_TLS1_2) {
163132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("Unsupported version of TLS."));
163232b31808SJens Wiklander         MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION,
163332b31808SJens Wiklander                                      MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION);
163432b31808SJens Wiklander         ret = MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
163532b31808SJens Wiklander         goto cleanup;
163632b31808SJens Wiklander     }
163732b31808SJens Wiklander     p += 2;
163832b31808SJens Wiklander 
163932b31808SJens Wiklander     /* ...
164032b31808SJens Wiklander      * Random random;
164132b31808SJens Wiklander      * ...
164232b31808SJens Wiklander      * with Random defined as:
164332b31808SJens Wiklander      * opaque Random[MBEDTLS_SERVER_HELLO_RANDOM_LEN];
164432b31808SJens Wiklander      */
164532b31808SJens Wiklander     if (!is_hrr) {
164632b31808SJens Wiklander         memcpy(&handshake->randbytes[MBEDTLS_CLIENT_HELLO_RANDOM_LEN], p,
164732b31808SJens Wiklander                MBEDTLS_SERVER_HELLO_RANDOM_LEN);
164832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "server hello, random bytes",
164932b31808SJens Wiklander                               p, MBEDTLS_SERVER_HELLO_RANDOM_LEN);
165032b31808SJens Wiklander     }
165132b31808SJens Wiklander     p += MBEDTLS_SERVER_HELLO_RANDOM_LEN;
165232b31808SJens Wiklander 
165332b31808SJens Wiklander     /* ...
165432b31808SJens Wiklander      * opaque legacy_session_id_echo<0..32>;
165532b31808SJens Wiklander      * ...
165632b31808SJens Wiklander      */
165732b31808SJens Wiklander     if (ssl_tls13_check_server_hello_session_id_echo(ssl, &p, end) != 0) {
165832b31808SJens Wiklander         fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
165932b31808SJens Wiklander         goto cleanup;
166032b31808SJens Wiklander     }
166132b31808SJens Wiklander 
166232b31808SJens Wiklander     /* ...
166332b31808SJens Wiklander      * CipherSuite cipher_suite;
166432b31808SJens Wiklander      * ...
166532b31808SJens Wiklander      * with CipherSuite defined as:
166632b31808SJens Wiklander      * uint8 CipherSuite[2];
166732b31808SJens Wiklander      */
166832b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
166932b31808SJens Wiklander     cipher_suite = MBEDTLS_GET_UINT16_BE(p, 0);
167032b31808SJens Wiklander     p += 2;
167132b31808SJens Wiklander 
167232b31808SJens Wiklander 
167332b31808SJens Wiklander     ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(cipher_suite);
167432b31808SJens Wiklander     /*
167532b31808SJens Wiklander      * Check whether this ciphersuite is valid and offered.
167632b31808SJens Wiklander      */
167732b31808SJens Wiklander     if ((mbedtls_ssl_validate_ciphersuite(ssl, ciphersuite_info,
167832b31808SJens Wiklander                                           ssl->tls_version,
167932b31808SJens Wiklander                                           ssl->tls_version) != 0) ||
168032b31808SJens Wiklander         !mbedtls_ssl_tls13_cipher_suite_is_offered(ssl, cipher_suite)) {
168132b31808SJens Wiklander         fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
168232b31808SJens Wiklander     }
168332b31808SJens Wiklander     /*
168432b31808SJens Wiklander      * If we received an HRR before and that the proposed selected
168532b31808SJens Wiklander      * ciphersuite in this server hello is not the same as the one
168632b31808SJens Wiklander      * proposed in the HRR, we abort the handshake and send an
168732b31808SJens Wiklander      * "illegal_parameter" alert.
168832b31808SJens Wiklander      */
1689b0563631STom Van Eyck     else if ((!is_hrr) && handshake->hello_retry_request_flag &&
169032b31808SJens Wiklander              (cipher_suite != ssl->session_negotiate->ciphersuite)) {
169132b31808SJens Wiklander         fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
169232b31808SJens Wiklander     }
169332b31808SJens Wiklander 
169432b31808SJens Wiklander     if (fatal_alert == MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER) {
169532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("invalid ciphersuite(%04x) parameter",
169632b31808SJens Wiklander                                   cipher_suite));
169732b31808SJens Wiklander         goto cleanup;
169832b31808SJens Wiklander     }
169932b31808SJens Wiklander 
170032b31808SJens Wiklander     /* Configure ciphersuites */
170132b31808SJens Wiklander     mbedtls_ssl_optimize_checksum(ssl, ciphersuite_info);
170232b31808SJens Wiklander 
170332b31808SJens Wiklander     handshake->ciphersuite_info = ciphersuite_info;
170432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen ciphersuite: ( %04x ) - %s",
170532b31808SJens Wiklander                               cipher_suite, ciphersuite_info->name));
170632b31808SJens Wiklander 
170732b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME)
1708b0563631STom Van Eyck     ssl->session_negotiate->start = mbedtls_time(NULL);
170932b31808SJens Wiklander #endif /* MBEDTLS_HAVE_TIME */
171032b31808SJens Wiklander 
171132b31808SJens Wiklander     /* ...
171232b31808SJens Wiklander      * uint8 legacy_compression_method = 0;
171332b31808SJens Wiklander      * ...
171432b31808SJens Wiklander      */
171532b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 1);
171632b31808SJens Wiklander     if (p[0] != MBEDTLS_SSL_COMPRESS_NULL) {
171732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad legacy compression method"));
171832b31808SJens Wiklander         fatal_alert = MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER;
171932b31808SJens Wiklander         goto cleanup;
172032b31808SJens Wiklander     }
172132b31808SJens Wiklander     p++;
172232b31808SJens Wiklander 
172332b31808SJens Wiklander     /* ...
172432b31808SJens Wiklander      * Extension extensions<6..2^16-1>;
172532b31808SJens Wiklander      * ...
172632b31808SJens Wiklander      * struct {
172732b31808SJens Wiklander      *      ExtensionType extension_type; (2 bytes)
172832b31808SJens Wiklander      *      opaque extension_data<0..2^16-1>;
172932b31808SJens Wiklander      * } Extension;
173032b31808SJens Wiklander      */
173132b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
173232b31808SJens Wiklander     extensions_len = MBEDTLS_GET_UINT16_BE(p, 0);
173332b31808SJens Wiklander     p += 2;
173432b31808SJens Wiklander 
173532b31808SJens Wiklander     /* Check extensions do not go beyond the buffer of data. */
173632b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extensions_len);
173732b31808SJens Wiklander     extensions_end = p + extensions_len;
173832b31808SJens Wiklander 
173932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "server hello extensions", p, extensions_len);
174032b31808SJens Wiklander 
174132b31808SJens Wiklander     handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
174232b31808SJens Wiklander     allowed_extensions_mask = is_hrr ?
174332b31808SJens Wiklander                               MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_HRR :
174432b31808SJens Wiklander                               MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_SH;
174532b31808SJens Wiklander 
174632b31808SJens Wiklander     while (p < extensions_end) {
174732b31808SJens Wiklander         unsigned int extension_type;
174832b31808SJens Wiklander         size_t extension_data_len;
174932b31808SJens Wiklander         const unsigned char *extension_data_end;
175032b31808SJens Wiklander 
175132b31808SJens Wiklander         MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, 4);
175232b31808SJens Wiklander         extension_type = MBEDTLS_GET_UINT16_BE(p, 0);
175332b31808SJens Wiklander         extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2);
175432b31808SJens Wiklander         p += 4;
175532b31808SJens Wiklander 
175632b31808SJens Wiklander         MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, extension_data_len);
175732b31808SJens Wiklander         extension_data_end = p + extension_data_len;
175832b31808SJens Wiklander 
175932b31808SJens Wiklander         ret = mbedtls_ssl_tls13_check_received_extension(
176032b31808SJens Wiklander             ssl, hs_msg_type, extension_type, allowed_extensions_mask);
176132b31808SJens Wiklander         if (ret != 0) {
176232b31808SJens Wiklander             return ret;
176332b31808SJens Wiklander         }
176432b31808SJens Wiklander 
176532b31808SJens Wiklander         switch (extension_type) {
176632b31808SJens Wiklander             case MBEDTLS_TLS_EXT_COOKIE:
176732b31808SJens Wiklander 
176832b31808SJens Wiklander                 ret = ssl_tls13_parse_cookie_ext(ssl,
176932b31808SJens Wiklander                                                  p, extension_data_end);
177032b31808SJens Wiklander                 if (ret != 0) {
177132b31808SJens Wiklander                     MBEDTLS_SSL_DEBUG_RET(1,
177232b31808SJens Wiklander                                           "ssl_tls13_parse_cookie_ext",
177332b31808SJens Wiklander                                           ret);
177432b31808SJens Wiklander                     goto cleanup;
177532b31808SJens Wiklander                 }
177632b31808SJens Wiklander                 break;
177732b31808SJens Wiklander 
177832b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SUPPORTED_VERSIONS:
177932b31808SJens Wiklander                 ret = ssl_tls13_parse_supported_versions_ext(ssl,
178032b31808SJens Wiklander                                                              p,
178132b31808SJens Wiklander                                                              extension_data_end);
178232b31808SJens Wiklander                 if (ret != 0) {
178332b31808SJens Wiklander                     goto cleanup;
178432b31808SJens Wiklander                 }
178532b31808SJens Wiklander                 break;
178632b31808SJens Wiklander 
178732b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_SOME_PSK_ENABLED)
178832b31808SJens Wiklander             case MBEDTLS_TLS_EXT_PRE_SHARED_KEY:
178932b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found pre_shared_key extension"));
179032b31808SJens Wiklander 
179132b31808SJens Wiklander                 if ((ret = ssl_tls13_parse_server_pre_shared_key_ext(
179232b31808SJens Wiklander                          ssl, p, extension_data_end)) != 0) {
179332b31808SJens Wiklander                     MBEDTLS_SSL_DEBUG_RET(
179432b31808SJens Wiklander                         1, ("ssl_tls13_parse_server_pre_shared_key_ext"), ret);
179532b31808SJens Wiklander                     return ret;
179632b31808SJens Wiklander                 }
179732b31808SJens Wiklander                 break;
179832b31808SJens Wiklander #endif
179932b31808SJens Wiklander 
180032b31808SJens Wiklander             case MBEDTLS_TLS_EXT_KEY_SHARE:
180132b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found key_shares extension"));
1802b0563631STom Van Eyck                 if (!mbedtls_ssl_conf_tls13_is_some_ephemeral_enabled(ssl)) {
180332b31808SJens Wiklander                     fatal_alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT;
180432b31808SJens Wiklander                     goto cleanup;
180532b31808SJens Wiklander                 }
180632b31808SJens Wiklander 
180732b31808SJens Wiklander                 if (is_hrr) {
180832b31808SJens Wiklander                     ret = ssl_tls13_parse_hrr_key_share_ext(ssl,
180932b31808SJens Wiklander                                                             p, extension_data_end);
181032b31808SJens Wiklander                 } else {
181132b31808SJens Wiklander                     ret = ssl_tls13_parse_key_share_ext(ssl,
181232b31808SJens Wiklander                                                         p, extension_data_end);
181332b31808SJens Wiklander                 }
181432b31808SJens Wiklander                 if (ret != 0) {
181532b31808SJens Wiklander                     MBEDTLS_SSL_DEBUG_RET(1,
181632b31808SJens Wiklander                                           "ssl_tls13_parse_key_share_ext",
181732b31808SJens Wiklander                                           ret);
181832b31808SJens Wiklander                     goto cleanup;
181932b31808SJens Wiklander                 }
182032b31808SJens Wiklander                 break;
182132b31808SJens Wiklander 
182232b31808SJens Wiklander             default:
182332b31808SJens Wiklander                 ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
182432b31808SJens Wiklander                 goto cleanup;
182532b31808SJens Wiklander         }
182632b31808SJens Wiklander 
182732b31808SJens Wiklander         p += extension_data_len;
182832b31808SJens Wiklander     }
182932b31808SJens Wiklander 
183032b31808SJens Wiklander     MBEDTLS_SSL_PRINT_EXTS(3, hs_msg_type, handshake->received_extensions);
183132b31808SJens Wiklander 
183232b31808SJens Wiklander cleanup:
183332b31808SJens Wiklander 
183432b31808SJens Wiklander     if (fatal_alert == MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT) {
183532b31808SJens Wiklander         MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT,
183632b31808SJens Wiklander                                      MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION);
183732b31808SJens Wiklander         ret = MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION;
183832b31808SJens Wiklander     } else if (fatal_alert == MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER) {
183932b31808SJens Wiklander         MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
184032b31808SJens Wiklander                                      MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
184132b31808SJens Wiklander         ret = MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
184232b31808SJens Wiklander     }
184332b31808SJens Wiklander     return ret;
184432b31808SJens Wiklander }
184532b31808SJens Wiklander 
184632b31808SJens Wiklander #if defined(MBEDTLS_DEBUG_C)
ssl_tls13_get_kex_mode_str(int mode)184732b31808SJens Wiklander static const char *ssl_tls13_get_kex_mode_str(int mode)
184832b31808SJens Wiklander {
184932b31808SJens Wiklander     switch (mode) {
185032b31808SJens Wiklander         case MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK:
185132b31808SJens Wiklander             return "psk";
185232b31808SJens Wiklander         case MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL:
185332b31808SJens Wiklander             return "ephemeral";
185432b31808SJens Wiklander         case MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL:
185532b31808SJens Wiklander             return "psk_ephemeral";
185632b31808SJens Wiklander         default:
185732b31808SJens Wiklander             return "unknown mode";
185832b31808SJens Wiklander     }
185932b31808SJens Wiklander }
186032b31808SJens Wiklander #endif /* MBEDTLS_DEBUG_C */
186132b31808SJens Wiklander 
186232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_postprocess_server_hello(mbedtls_ssl_context * ssl)186332b31808SJens Wiklander static int ssl_tls13_postprocess_server_hello(mbedtls_ssl_context *ssl)
186432b31808SJens Wiklander {
186532b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
186632b31808SJens Wiklander     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
186732b31808SJens Wiklander 
186832b31808SJens Wiklander     /* Determine the key exchange mode:
186932b31808SJens Wiklander      * 1) If both the pre_shared_key and key_share extensions were received
187032b31808SJens Wiklander      *    then the key exchange mode is PSK with EPHEMERAL.
187132b31808SJens Wiklander      * 2) If only the pre_shared_key extension was received then the key
187232b31808SJens Wiklander      *    exchange mode is PSK-only.
187332b31808SJens Wiklander      * 3) If only the key_share extension was received then the key
187432b31808SJens Wiklander      *    exchange mode is EPHEMERAL-only.
187532b31808SJens Wiklander      */
187632b31808SJens Wiklander     switch (handshake->received_extensions &
1877b0563631STom Van Eyck             (MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY) |
1878b0563631STom Van Eyck              MBEDTLS_SSL_EXT_MASK(KEY_SHARE))) {
187932b31808SJens Wiklander         /* Only the pre_shared_key extension was received */
188032b31808SJens Wiklander         case MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY):
1881b0563631STom Van Eyck             handshake->key_exchange_mode =
1882b0563631STom Van Eyck                 MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK;
188332b31808SJens Wiklander             break;
188432b31808SJens Wiklander 
188532b31808SJens Wiklander         /* Only the key_share extension was received */
188632b31808SJens Wiklander         case MBEDTLS_SSL_EXT_MASK(KEY_SHARE):
1887b0563631STom Van Eyck             handshake->key_exchange_mode =
1888b0563631STom Van Eyck                 MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL;
188932b31808SJens Wiklander             break;
189032b31808SJens Wiklander 
189132b31808SJens Wiklander         /* Both the pre_shared_key and key_share extensions were received */
1892b0563631STom Van Eyck         case (MBEDTLS_SSL_EXT_MASK(PRE_SHARED_KEY) |
1893b0563631STom Van Eyck               MBEDTLS_SSL_EXT_MASK(KEY_SHARE)):
1894b0563631STom Van Eyck             handshake->key_exchange_mode =
1895b0563631STom Van Eyck                 MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL;
189632b31808SJens Wiklander             break;
189732b31808SJens Wiklander 
189832b31808SJens Wiklander         /* Neither pre_shared_key nor key_share extension was received */
189932b31808SJens Wiklander         default:
190032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("Unknown key exchange."));
190132b31808SJens Wiklander             ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
190232b31808SJens Wiklander             goto cleanup;
190332b31808SJens Wiklander     }
190432b31808SJens Wiklander 
1905b0563631STom Van Eyck     if (!mbedtls_ssl_conf_tls13_is_kex_mode_enabled(
190632b31808SJens Wiklander             ssl, handshake->key_exchange_mode)) {
190732b31808SJens Wiklander         ret = MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
1908b0563631STom Van Eyck         MBEDTLS_SSL_DEBUG_MSG(
1909b0563631STom Van Eyck             2, ("Key exchange mode(%s) is not supported.",
191032b31808SJens Wiklander                 ssl_tls13_get_kex_mode_str(handshake->key_exchange_mode)));
191132b31808SJens Wiklander         goto cleanup;
191232b31808SJens Wiklander     }
191332b31808SJens Wiklander 
1914b0563631STom Van Eyck     MBEDTLS_SSL_DEBUG_MSG(
1915b0563631STom Van Eyck         3, ("Selected key exchange mode: %s",
191632b31808SJens Wiklander             ssl_tls13_get_kex_mode_str(handshake->key_exchange_mode)));
191732b31808SJens Wiklander 
191832b31808SJens Wiklander     /* Start the TLS 1.3 key scheduling if not already done.
191932b31808SJens Wiklander      *
192032b31808SJens Wiklander      * If we proposed early data then we have already derived an
192132b31808SJens Wiklander      * early secret using the selected PSK and its associated hash.
192232b31808SJens Wiklander      * It means that if the negotiated key exchange mode is psk or
192332b31808SJens Wiklander      * psk_ephemeral, we have already correctly computed the
192432b31808SJens Wiklander      * early secret and thus we do not do it again. In all other
192532b31808SJens Wiklander      * cases we compute it here.
192632b31808SJens Wiklander      */
192732b31808SJens Wiklander #if defined(MBEDTLS_SSL_EARLY_DATA)
1928b0563631STom Van Eyck     if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT ||
192932b31808SJens Wiklander         handshake->key_exchange_mode ==
193032b31808SJens Wiklander         MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL)
193132b31808SJens Wiklander #endif
193232b31808SJens Wiklander     {
193332b31808SJens Wiklander         ret = mbedtls_ssl_tls13_key_schedule_stage_early(ssl);
193432b31808SJens Wiklander         if (ret != 0) {
193532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(
193632b31808SJens Wiklander                 1, "mbedtls_ssl_tls13_key_schedule_stage_early", ret);
193732b31808SJens Wiklander             goto cleanup;
193832b31808SJens Wiklander         }
193932b31808SJens Wiklander     }
194032b31808SJens Wiklander 
194132b31808SJens Wiklander     ret = mbedtls_ssl_tls13_compute_handshake_transform(ssl);
194232b31808SJens Wiklander     if (ret != 0) {
194332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1,
194432b31808SJens Wiklander                               "mbedtls_ssl_tls13_compute_handshake_transform",
194532b31808SJens Wiklander                               ret);
194632b31808SJens Wiklander         goto cleanup;
194732b31808SJens Wiklander     }
194832b31808SJens Wiklander 
194932b31808SJens Wiklander     mbedtls_ssl_set_inbound_transform(ssl, handshake->transform_handshake);
195032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(1, ("Switch to handshake keys for inbound traffic"));
195132b31808SJens Wiklander     ssl->session_in = ssl->session_negotiate;
195232b31808SJens Wiklander 
195332b31808SJens Wiklander cleanup:
195432b31808SJens Wiklander     if (ret != 0) {
195532b31808SJens Wiklander         MBEDTLS_SSL_PEND_FATAL_ALERT(
195632b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
195732b31808SJens Wiklander             MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
195832b31808SJens Wiklander     }
195932b31808SJens Wiklander 
196032b31808SJens Wiklander     return ret;
196132b31808SJens Wiklander }
196232b31808SJens Wiklander 
196332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_postprocess_hrr(mbedtls_ssl_context * ssl)196432b31808SJens Wiklander static int ssl_tls13_postprocess_hrr(mbedtls_ssl_context *ssl)
196532b31808SJens Wiklander {
196632b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
196732b31808SJens Wiklander 
196832b31808SJens Wiklander     mbedtls_ssl_session_reset_msg_layer(ssl, 0);
196932b31808SJens Wiklander 
197032b31808SJens Wiklander     /*
197132b31808SJens Wiklander      * We are going to re-generate a shared secret corresponding to the group
197232b31808SJens Wiklander      * selected by the server, which is different from the group for which we
197332b31808SJens Wiklander      * generated a shared secret in the first client hello.
197432b31808SJens Wiklander      * Thus, reset the shared secret.
197532b31808SJens Wiklander      */
197632b31808SJens Wiklander     ret = ssl_tls13_reset_key_share(ssl);
197732b31808SJens Wiklander     if (ret != 0) {
197832b31808SJens Wiklander         return ret;
197932b31808SJens Wiklander     }
198032b31808SJens Wiklander 
198132b31808SJens Wiklander     ssl->session_negotiate->ciphersuite = ssl->handshake->ciphersuite_info->id;
1982b0563631STom Van Eyck 
1983b0563631STom Van Eyck #if defined(MBEDTLS_SSL_EARLY_DATA)
1984b0563631STom Van Eyck     if (ssl->early_data_state != MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT) {
1985b0563631STom Van Eyck         ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED;
1986b0563631STom Van Eyck     }
1987b0563631STom Van Eyck #endif
1988b0563631STom Van Eyck 
198932b31808SJens Wiklander     return 0;
199032b31808SJens Wiklander }
199132b31808SJens Wiklander 
199232b31808SJens Wiklander /*
199332b31808SJens Wiklander  * Wait and parse ServerHello handshake message.
199432b31808SJens Wiklander  * Handler for MBEDTLS_SSL_SERVER_HELLO
199532b31808SJens Wiklander  */
199632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_process_server_hello(mbedtls_ssl_context * ssl)199732b31808SJens Wiklander static int ssl_tls13_process_server_hello(mbedtls_ssl_context *ssl)
199832b31808SJens Wiklander {
199932b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
200032b31808SJens Wiklander     unsigned char *buf = NULL;
200132b31808SJens Wiklander     size_t buf_len = 0;
200232b31808SJens Wiklander     int is_hrr = 0;
200332b31808SJens Wiklander 
200432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> %s", __func__));
200532b31808SJens Wiklander 
2006b0563631STom Van Eyck     MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(
2007b0563631STom Van Eyck                              ssl, MBEDTLS_SSL_HS_SERVER_HELLO, &buf, &buf_len));
200832b31808SJens Wiklander 
200932b31808SJens Wiklander     ret = ssl_tls13_preprocess_server_hello(ssl, buf, buf + buf_len);
201032b31808SJens Wiklander     if (ret < 0) {
201132b31808SJens Wiklander         goto cleanup;
201232b31808SJens Wiklander     } else {
201332b31808SJens Wiklander         is_hrr = (ret == SSL_SERVER_HELLO_HRR);
201432b31808SJens Wiklander     }
201532b31808SJens Wiklander 
201632b31808SJens Wiklander     if (ret == SSL_SERVER_HELLO_TLS1_2) {
201732b31808SJens Wiklander         ret = 0;
201832b31808SJens Wiklander         goto cleanup;
201932b31808SJens Wiklander     }
202032b31808SJens Wiklander 
202132b31808SJens Wiklander     MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_server_hello(ssl, buf,
202232b31808SJens Wiklander                                                       buf + buf_len,
202332b31808SJens Wiklander                                                       is_hrr));
202432b31808SJens Wiklander     if (is_hrr) {
202532b31808SJens Wiklander         MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_reset_transcript_for_hrr(ssl));
202632b31808SJens Wiklander     }
202732b31808SJens Wiklander 
2028b0563631STom Van Eyck     MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
2029b0563631STom Van Eyck                              ssl, MBEDTLS_SSL_HS_SERVER_HELLO, buf, buf_len));
203032b31808SJens Wiklander 
203132b31808SJens Wiklander     if (is_hrr) {
203232b31808SJens Wiklander         MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_hrr(ssl));
203332b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
203432b31808SJens Wiklander         /* If not offering early data, the client sends a dummy CCS record
203532b31808SJens Wiklander          * immediately before its second flight. This may either be before
203632b31808SJens Wiklander          * its second ClientHello or before its encrypted handshake flight.
203732b31808SJens Wiklander          */
2038b0563631STom Van Eyck         mbedtls_ssl_handshake_set_state(
2039b0563631STom Van Eyck             ssl, MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO);
204032b31808SJens Wiklander #else
204132b31808SJens Wiklander         mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
204232b31808SJens Wiklander #endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
204332b31808SJens Wiklander     } else {
204432b31808SJens Wiklander         MBEDTLS_SSL_PROC_CHK(ssl_tls13_postprocess_server_hello(ssl));
204532b31808SJens Wiklander         mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_ENCRYPTED_EXTENSIONS);
204632b31808SJens Wiklander     }
204732b31808SJens Wiklander 
204832b31808SJens Wiklander cleanup:
204932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= %s ( %s )", __func__,
205032b31808SJens Wiklander                               is_hrr ? "HelloRetryRequest" : "ServerHello"));
205132b31808SJens Wiklander     return ret;
205232b31808SJens Wiklander }
205332b31808SJens Wiklander 
205432b31808SJens Wiklander /*
205532b31808SJens Wiklander  *
205632b31808SJens Wiklander  * Handler for MBEDTLS_SSL_ENCRYPTED_EXTENSIONS
205732b31808SJens Wiklander  *
205832b31808SJens Wiklander  * The EncryptedExtensions message contains any extensions which
205932b31808SJens Wiklander  * should be protected, i.e., any which are not needed to establish
206032b31808SJens Wiklander  * the cryptographic context.
206132b31808SJens Wiklander  */
206232b31808SJens Wiklander 
206332b31808SJens Wiklander /* Parse EncryptedExtensions message
206432b31808SJens Wiklander  * struct {
206532b31808SJens Wiklander  *     Extension extensions<0..2^16-1>;
206632b31808SJens Wiklander  * } EncryptedExtensions;
206732b31808SJens Wiklander  */
206832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_parse_encrypted_extensions(mbedtls_ssl_context * ssl,const unsigned char * buf,const unsigned char * end)206932b31808SJens Wiklander static int ssl_tls13_parse_encrypted_extensions(mbedtls_ssl_context *ssl,
207032b31808SJens Wiklander                                                 const unsigned char *buf,
207132b31808SJens Wiklander                                                 const unsigned char *end)
207232b31808SJens Wiklander {
207332b31808SJens Wiklander     int ret = 0;
207432b31808SJens Wiklander     size_t extensions_len;
207532b31808SJens Wiklander     const unsigned char *p = buf;
207632b31808SJens Wiklander     const unsigned char *extensions_end;
207732b31808SJens Wiklander     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
207832b31808SJens Wiklander 
207932b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
208032b31808SJens Wiklander     extensions_len = MBEDTLS_GET_UINT16_BE(p, 0);
208132b31808SJens Wiklander     p += 2;
208232b31808SJens Wiklander 
208332b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extensions_len);
208432b31808SJens Wiklander     extensions_end = p + extensions_len;
208532b31808SJens Wiklander 
208632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "encrypted extensions", p, extensions_len);
208732b31808SJens Wiklander 
208832b31808SJens Wiklander     handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
208932b31808SJens Wiklander 
209032b31808SJens Wiklander     while (p < extensions_end) {
209132b31808SJens Wiklander         unsigned int extension_type;
209232b31808SJens Wiklander         size_t extension_data_len;
209332b31808SJens Wiklander 
209432b31808SJens Wiklander         /*
209532b31808SJens Wiklander          * struct {
209632b31808SJens Wiklander          *     ExtensionType extension_type; (2 bytes)
209732b31808SJens Wiklander          *     opaque extension_data<0..2^16-1>;
209832b31808SJens Wiklander          * } Extension;
209932b31808SJens Wiklander          */
210032b31808SJens Wiklander         MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, 4);
210132b31808SJens Wiklander         extension_type = MBEDTLS_GET_UINT16_BE(p, 0);
210232b31808SJens Wiklander         extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2);
210332b31808SJens Wiklander         p += 4;
210432b31808SJens Wiklander 
210532b31808SJens Wiklander         MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, extension_data_len);
210632b31808SJens Wiklander 
210732b31808SJens Wiklander         ret = mbedtls_ssl_tls13_check_received_extension(
210832b31808SJens Wiklander             ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS, extension_type,
210932b31808SJens Wiklander             MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_EE);
211032b31808SJens Wiklander         if (ret != 0) {
211132b31808SJens Wiklander             return ret;
211232b31808SJens Wiklander         }
211332b31808SJens Wiklander 
211432b31808SJens Wiklander         switch (extension_type) {
211532b31808SJens Wiklander #if defined(MBEDTLS_SSL_ALPN)
211632b31808SJens Wiklander             case MBEDTLS_TLS_EXT_ALPN:
211732b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found alpn extension"));
211832b31808SJens Wiklander 
2119b0563631STom Van Eyck                 if ((ret = ssl_tls13_parse_alpn_ext(
2120b0563631STom Van Eyck                          ssl, p, (size_t) extension_data_len)) != 0) {
212132b31808SJens Wiklander                     return ret;
212232b31808SJens Wiklander                 }
212332b31808SJens Wiklander 
212432b31808SJens Wiklander                 break;
212532b31808SJens Wiklander #endif /* MBEDTLS_SSL_ALPN */
212632b31808SJens Wiklander 
212732b31808SJens Wiklander #if defined(MBEDTLS_SSL_EARLY_DATA)
212832b31808SJens Wiklander             case MBEDTLS_TLS_EXT_EARLY_DATA:
212932b31808SJens Wiklander 
213032b31808SJens Wiklander                 if (extension_data_len != 0) {
213132b31808SJens Wiklander                     /* The message must be empty. */
213232b31808SJens Wiklander                     MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
213332b31808SJens Wiklander                                                  MBEDTLS_ERR_SSL_DECODE_ERROR);
213432b31808SJens Wiklander                     return MBEDTLS_ERR_SSL_DECODE_ERROR;
213532b31808SJens Wiklander                 }
213632b31808SJens Wiklander 
213732b31808SJens Wiklander                 break;
213832b31808SJens Wiklander #endif /* MBEDTLS_SSL_EARLY_DATA */
213932b31808SJens Wiklander 
214032b31808SJens Wiklander #if defined(MBEDTLS_SSL_RECORD_SIZE_LIMIT)
214132b31808SJens Wiklander             case MBEDTLS_TLS_EXT_RECORD_SIZE_LIMIT:
214232b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found record_size_limit extension"));
214332b31808SJens Wiklander 
2144b0563631STom Van Eyck                 ret = mbedtls_ssl_tls13_parse_record_size_limit_ext(
2145b0563631STom Van Eyck                     ssl, p, p + extension_data_len);
2146b0563631STom Van Eyck                 if (ret != 0) {
2147b0563631STom Van Eyck                     MBEDTLS_SSL_DEBUG_RET(
2148b0563631STom Van Eyck                         1, ("mbedtls_ssl_tls13_parse_record_size_limit_ext"), ret);
214932b31808SJens Wiklander                     return ret;
2150b0563631STom Van Eyck                 }
215132b31808SJens Wiklander                 break;
215232b31808SJens Wiklander #endif /* MBEDTLS_SSL_RECORD_SIZE_LIMIT */
215332b31808SJens Wiklander 
215432b31808SJens Wiklander             default:
215532b31808SJens Wiklander                 MBEDTLS_SSL_PRINT_EXT(
215632b31808SJens Wiklander                     3, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
215732b31808SJens Wiklander                     extension_type, "( ignored )");
215832b31808SJens Wiklander                 break;
215932b31808SJens Wiklander         }
216032b31808SJens Wiklander 
216132b31808SJens Wiklander         p += extension_data_len;
216232b31808SJens Wiklander     }
216332b31808SJens Wiklander 
2164b0563631STom Van Eyck     if ((handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(RECORD_SIZE_LIMIT)) &&
2165b0563631STom Van Eyck         (handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(MAX_FRAGMENT_LENGTH))) {
2166b0563631STom Van Eyck         MBEDTLS_SSL_DEBUG_MSG(3,
2167b0563631STom Van Eyck                               (
2168b0563631STom Van Eyck                                   "Record size limit extension cannot be used with max fragment length extension"));
2169b0563631STom Van Eyck         MBEDTLS_SSL_PEND_FATAL_ALERT(
2170b0563631STom Van Eyck             MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
2171b0563631STom Van Eyck             MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
2172b0563631STom Van Eyck         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
2173b0563631STom Van Eyck     }
2174b0563631STom Van Eyck 
217532b31808SJens Wiklander     MBEDTLS_SSL_PRINT_EXTS(3, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
217632b31808SJens Wiklander                            handshake->received_extensions);
217732b31808SJens Wiklander 
217832b31808SJens Wiklander     /* Check that we consumed all the message. */
217932b31808SJens Wiklander     if (p != end) {
218032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("EncryptedExtension lengths misaligned"));
218132b31808SJens Wiklander         MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
218232b31808SJens Wiklander                                      MBEDTLS_ERR_SSL_DECODE_ERROR);
218332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
218432b31808SJens Wiklander     }
218532b31808SJens Wiklander 
218632b31808SJens Wiklander     return ret;
218732b31808SJens Wiklander }
218832b31808SJens Wiklander 
218932b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context * ssl)219032b31808SJens Wiklander static int ssl_tls13_process_encrypted_extensions(mbedtls_ssl_context *ssl)
219132b31808SJens Wiklander {
219232b31808SJens Wiklander     int ret;
219332b31808SJens Wiklander     unsigned char *buf;
219432b31808SJens Wiklander     size_t buf_len;
2195b0563631STom Van Eyck     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
219632b31808SJens Wiklander 
219732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse encrypted extensions"));
219832b31808SJens Wiklander 
2199b0563631STom Van Eyck     MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(
2200b0563631STom Van Eyck                              ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
220132b31808SJens Wiklander                              &buf, &buf_len));
220232b31808SJens Wiklander 
220332b31808SJens Wiklander     /* Process the message contents */
220432b31808SJens Wiklander     MBEDTLS_SSL_PROC_CHK(
220532b31808SJens Wiklander         ssl_tls13_parse_encrypted_extensions(ssl, buf, buf + buf_len));
220632b31808SJens Wiklander 
220732b31808SJens Wiklander #if defined(MBEDTLS_SSL_EARLY_DATA)
2208b0563631STom Van Eyck     if (handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(EARLY_DATA)) {
2209b0563631STom Van Eyck         /* RFC8446 4.2.11
2210b0563631STom Van Eyck          * If the server supplies an "early_data" extension, the
2211b0563631STom Van Eyck          * client MUST verify that the server's selected_identity
2212b0563631STom Van Eyck          * is 0. If any other value is returned, the client MUST
2213b0563631STom Van Eyck          * abort the handshake with an "illegal_parameter" alert.
2214b0563631STom Van Eyck          *
2215b0563631STom Van Eyck          * RFC 8446 4.2.10
2216b0563631STom Van Eyck          * In order to accept early data, the server MUST have accepted a PSK
2217b0563631STom Van Eyck          * cipher suite and selected the first key offered in the client's
2218b0563631STom Van Eyck          * "pre_shared_key" extension. In addition, it MUST verify that the
2219b0563631STom Van Eyck          * following values are the same as those associated with the
2220b0563631STom Van Eyck          * selected PSK:
2221b0563631STom Van Eyck          * - The TLS version number
2222b0563631STom Van Eyck          * - The selected cipher suite
2223b0563631STom Van Eyck          * - The selected ALPN [RFC7301] protocol, if any
2224b0563631STom Van Eyck          *
2225b0563631STom Van Eyck          * The server has sent an early data extension in its Encrypted
2226b0563631STom Van Eyck          * Extension message thus accepted to receive early data. We
2227b0563631STom Van Eyck          * check here that the additional constraints on the handshake
2228b0563631STom Van Eyck          * parameters, when early data are exchanged, are met,
2229b0563631STom Van Eyck          * namely:
2230b0563631STom Van Eyck          * - a PSK has been selected for the handshake
2231b0563631STom Van Eyck          * - the selected PSK for the handshake was the first one proposed
2232b0563631STom Van Eyck          *   by the client.
2233b0563631STom Van Eyck          * - the selected ciphersuite for the handshake is the ciphersuite
2234b0563631STom Van Eyck          *   associated with the selected PSK.
2235b0563631STom Van Eyck          */
2236b0563631STom Van Eyck         if ((!mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) ||
2237b0563631STom Van Eyck             handshake->selected_identity != 0 ||
2238b0563631STom Van Eyck             handshake->ciphersuite_info->id !=
2239b0563631STom Van Eyck             ssl->session_negotiate->ciphersuite) {
2240b0563631STom Van Eyck 
2241b0563631STom Van Eyck             MBEDTLS_SSL_PEND_FATAL_ALERT(
2242b0563631STom Van Eyck                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER,
2243b0563631STom Van Eyck                 MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER);
2244b0563631STom Van Eyck             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
2245b0563631STom Van Eyck         }
2246b0563631STom Van Eyck 
2247b0563631STom Van Eyck         ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED;
2248b0563631STom Van Eyck     } else if (ssl->early_data_state !=
2249b0563631STom Van Eyck                MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT) {
2250b0563631STom Van Eyck         ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED;
225132b31808SJens Wiklander     }
225232b31808SJens Wiklander #endif
225332b31808SJens Wiklander 
2254b0563631STom Van Eyck     /*
2255b0563631STom Van Eyck      * In case the client has proposed a PSK associated with a ticket,
2256b0563631STom Van Eyck      * `ssl->session_negotiate->ciphersuite` still contains at this point the
2257b0563631STom Van Eyck      * identifier of the ciphersuite associated with the ticket. This is that
2258b0563631STom Van Eyck      * way because, if an exchange of early data is agreed upon, we need
2259b0563631STom Van Eyck      * it to check that the ciphersuite selected for the handshake is the
2260b0563631STom Van Eyck      * ticket ciphersuite (see above). This information is not needed
2261b0563631STom Van Eyck      * anymore thus we can now set it to the identifier of the ciphersuite
2262b0563631STom Van Eyck      * used in this session under negotiation.
2263b0563631STom Van Eyck      */
2264b0563631STom Van Eyck     ssl->session_negotiate->ciphersuite = handshake->ciphersuite_info->id;
2265b0563631STom Van Eyck 
2266b0563631STom Van Eyck     MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
2267b0563631STom Van Eyck                              ssl, MBEDTLS_SSL_HS_ENCRYPTED_EXTENSIONS,
226832b31808SJens Wiklander                              buf, buf_len));
226932b31808SJens Wiklander 
227032b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
227132b31808SJens Wiklander     if (mbedtls_ssl_tls13_key_exchange_mode_with_psk(ssl)) {
227232b31808SJens Wiklander         mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_FINISHED);
227332b31808SJens Wiklander     } else {
227432b31808SJens Wiklander         mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CERTIFICATE_REQUEST);
227532b31808SJens Wiklander     }
227632b31808SJens Wiklander #else
227732b31808SJens Wiklander     ((void) ssl);
227832b31808SJens Wiklander     mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_FINISHED);
227932b31808SJens Wiklander #endif
228032b31808SJens Wiklander 
228132b31808SJens Wiklander cleanup:
228232b31808SJens Wiklander 
228332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse encrypted extensions"));
228432b31808SJens Wiklander     return ret;
228532b31808SJens Wiklander 
228632b31808SJens Wiklander }
228732b31808SJens Wiklander 
2288b0563631STom Van Eyck #if defined(MBEDTLS_SSL_EARLY_DATA)
228932b31808SJens Wiklander /*
229032b31808SJens Wiklander  * Handler for MBEDTLS_SSL_END_OF_EARLY_DATA
229132b31808SJens Wiklander  *
229232b31808SJens Wiklander  * RFC 8446 section 4.5
229332b31808SJens Wiklander  *
229432b31808SJens Wiklander  * struct {} EndOfEarlyData;
229532b31808SJens Wiklander  *
229632b31808SJens Wiklander  * If the server sent an "early_data" extension in EncryptedExtensions, the
229732b31808SJens Wiklander  * client MUST send an EndOfEarlyData message after receiving the server
229832b31808SJens Wiklander  * Finished. Otherwise, the client MUST NOT send an EndOfEarlyData message.
229932b31808SJens Wiklander  */
230032b31808SJens Wiklander 
230132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_write_end_of_early_data(mbedtls_ssl_context * ssl)230232b31808SJens Wiklander static int ssl_tls13_write_end_of_early_data(mbedtls_ssl_context *ssl)
230332b31808SJens Wiklander {
230432b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
230532b31808SJens Wiklander     unsigned char *buf = NULL;
230632b31808SJens Wiklander     size_t buf_len;
230732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write EndOfEarlyData"));
230832b31808SJens Wiklander 
230932b31808SJens Wiklander     MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_start_handshake_msg(
231032b31808SJens Wiklander                              ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA,
231132b31808SJens Wiklander                              &buf, &buf_len));
231232b31808SJens Wiklander 
231332b31808SJens Wiklander     MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_hdr_to_checksum(
231432b31808SJens Wiklander                              ssl, MBEDTLS_SSL_HS_END_OF_EARLY_DATA, 0));
231532b31808SJens Wiklander 
231632b31808SJens Wiklander     MBEDTLS_SSL_PROC_CHK(
231732b31808SJens Wiklander         mbedtls_ssl_finish_handshake_msg(ssl, buf_len, 0));
231832b31808SJens Wiklander 
231932b31808SJens Wiklander     mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
232032b31808SJens Wiklander 
232132b31808SJens Wiklander cleanup:
232232b31808SJens Wiklander 
232332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write EndOfEarlyData"));
232432b31808SJens Wiklander     return ret;
232532b31808SJens Wiklander }
232632b31808SJens Wiklander 
mbedtls_ssl_get_early_data_status(mbedtls_ssl_context * ssl)2327b0563631STom Van Eyck int mbedtls_ssl_get_early_data_status(mbedtls_ssl_context *ssl)
2328b0563631STom Van Eyck {
2329b0563631STom Van Eyck     if ((ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT) ||
2330b0563631STom Van Eyck         (!mbedtls_ssl_is_handshake_over(ssl))) {
2331b0563631STom Van Eyck         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
2332b0563631STom Van Eyck     }
2333b0563631STom Van Eyck 
2334b0563631STom Van Eyck     switch (ssl->early_data_state) {
2335b0563631STom Van Eyck         case MBEDTLS_SSL_EARLY_DATA_STATE_NO_IND_SENT:
2336b0563631STom Van Eyck             return MBEDTLS_SSL_EARLY_DATA_STATUS_NOT_INDICATED;
2337b0563631STom Van Eyck             break;
2338b0563631STom Van Eyck 
2339b0563631STom Van Eyck         case MBEDTLS_SSL_EARLY_DATA_STATE_REJECTED:
2340b0563631STom Van Eyck             return MBEDTLS_SSL_EARLY_DATA_STATUS_REJECTED;
2341b0563631STom Van Eyck             break;
2342b0563631STom Van Eyck 
2343b0563631STom Van Eyck         case MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED:
2344b0563631STom Van Eyck             return MBEDTLS_SSL_EARLY_DATA_STATUS_ACCEPTED;
2345b0563631STom Van Eyck             break;
2346b0563631STom Van Eyck 
2347b0563631STom Van Eyck         default:
2348b0563631STom Van Eyck             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
2349b0563631STom Van Eyck     }
2350b0563631STom Van Eyck }
2351b0563631STom Van Eyck #endif /* MBEDTLS_SSL_EARLY_DATA */
2352b0563631STom Van Eyck 
235332b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
235432b31808SJens Wiklander /*
235532b31808SJens Wiklander  * STATE HANDLING: CertificateRequest
235632b31808SJens Wiklander  *
235732b31808SJens Wiklander  */
235832b31808SJens Wiklander #define SSL_CERTIFICATE_REQUEST_EXPECT_REQUEST 0
235932b31808SJens Wiklander #define SSL_CERTIFICATE_REQUEST_SKIP           1
236032b31808SJens Wiklander /* Coordination:
236132b31808SJens Wiklander  * Deals with the ambiguity of not knowing if a CertificateRequest
236232b31808SJens Wiklander  * will be sent. Returns a negative code on failure, or
236332b31808SJens Wiklander  * - SSL_CERTIFICATE_REQUEST_EXPECT_REQUEST
236432b31808SJens Wiklander  * - SSL_CERTIFICATE_REQUEST_SKIP
236532b31808SJens Wiklander  * indicating if a Certificate Request is expected or not.
236632b31808SJens Wiklander  */
236732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_certificate_request_coordinate(mbedtls_ssl_context * ssl)236832b31808SJens Wiklander static int ssl_tls13_certificate_request_coordinate(mbedtls_ssl_context *ssl)
236932b31808SJens Wiklander {
237032b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
237132b31808SJens Wiklander 
237232b31808SJens Wiklander     if ((ret = mbedtls_ssl_read_record(ssl, 0)) != 0) {
237332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
237432b31808SJens Wiklander         return ret;
237532b31808SJens Wiklander     }
237632b31808SJens Wiklander     ssl->keep_current_message = 1;
237732b31808SJens Wiklander 
237832b31808SJens Wiklander     if ((ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE) &&
237932b31808SJens Wiklander         (ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST)) {
238032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("got a certificate request"));
238132b31808SJens Wiklander         return SSL_CERTIFICATE_REQUEST_EXPECT_REQUEST;
238232b31808SJens Wiklander     }
238332b31808SJens Wiklander 
238432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("got no certificate request"));
238532b31808SJens Wiklander 
238632b31808SJens Wiklander     return SSL_CERTIFICATE_REQUEST_SKIP;
238732b31808SJens Wiklander }
238832b31808SJens Wiklander 
238932b31808SJens Wiklander /*
239032b31808SJens Wiklander  * ssl_tls13_parse_certificate_request()
239132b31808SJens Wiklander  *     Parse certificate request
239232b31808SJens Wiklander  * struct {
239332b31808SJens Wiklander  *   opaque certificate_request_context<0..2^8-1>;
239432b31808SJens Wiklander  *   Extension extensions<2..2^16-1>;
239532b31808SJens Wiklander  * } CertificateRequest;
239632b31808SJens Wiklander  */
239732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_parse_certificate_request(mbedtls_ssl_context * ssl,const unsigned char * buf,const unsigned char * end)239832b31808SJens Wiklander static int ssl_tls13_parse_certificate_request(mbedtls_ssl_context *ssl,
239932b31808SJens Wiklander                                                const unsigned char *buf,
240032b31808SJens Wiklander                                                const unsigned char *end)
240132b31808SJens Wiklander {
240232b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
240332b31808SJens Wiklander     const unsigned char *p = buf;
240432b31808SJens Wiklander     size_t certificate_request_context_len = 0;
240532b31808SJens Wiklander     size_t extensions_len = 0;
240632b31808SJens Wiklander     const unsigned char *extensions_end;
240732b31808SJens Wiklander     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
240832b31808SJens Wiklander 
240932b31808SJens Wiklander     /* ...
241032b31808SJens Wiklander      * opaque certificate_request_context<0..2^8-1>
241132b31808SJens Wiklander      * ...
241232b31808SJens Wiklander      */
241332b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 1);
241432b31808SJens Wiklander     certificate_request_context_len = (size_t) p[0];
241532b31808SJens Wiklander     p += 1;
241632b31808SJens Wiklander 
241732b31808SJens Wiklander     if (certificate_request_context_len > 0) {
241832b31808SJens Wiklander         MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, certificate_request_context_len);
241932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "Certificate Request Context",
242032b31808SJens Wiklander                               p, certificate_request_context_len);
242132b31808SJens Wiklander 
242232b31808SJens Wiklander         handshake->certificate_request_context =
242332b31808SJens Wiklander             mbedtls_calloc(1, certificate_request_context_len);
242432b31808SJens Wiklander         if (handshake->certificate_request_context == NULL) {
242532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small"));
242632b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ALLOC_FAILED;
242732b31808SJens Wiklander         }
242832b31808SJens Wiklander         memcpy(handshake->certificate_request_context, p,
242932b31808SJens Wiklander                certificate_request_context_len);
243032b31808SJens Wiklander         p += certificate_request_context_len;
243132b31808SJens Wiklander     }
243232b31808SJens Wiklander 
243332b31808SJens Wiklander     /* ...
243432b31808SJens Wiklander      * Extension extensions<2..2^16-1>;
243532b31808SJens Wiklander      * ...
243632b31808SJens Wiklander      */
243732b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
243832b31808SJens Wiklander     extensions_len = MBEDTLS_GET_UINT16_BE(p, 0);
243932b31808SJens Wiklander     p += 2;
244032b31808SJens Wiklander 
244132b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extensions_len);
244232b31808SJens Wiklander     extensions_end = p + extensions_len;
244332b31808SJens Wiklander 
244432b31808SJens Wiklander     handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
244532b31808SJens Wiklander 
244632b31808SJens Wiklander     while (p < extensions_end) {
244732b31808SJens Wiklander         unsigned int extension_type;
244832b31808SJens Wiklander         size_t extension_data_len;
244932b31808SJens Wiklander 
245032b31808SJens Wiklander         MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, 4);
245132b31808SJens Wiklander         extension_type = MBEDTLS_GET_UINT16_BE(p, 0);
245232b31808SJens Wiklander         extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2);
245332b31808SJens Wiklander         p += 4;
245432b31808SJens Wiklander 
245532b31808SJens Wiklander         MBEDTLS_SSL_CHK_BUF_READ_PTR(p, extensions_end, extension_data_len);
245632b31808SJens Wiklander 
245732b31808SJens Wiklander         ret = mbedtls_ssl_tls13_check_received_extension(
245832b31808SJens Wiklander             ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST, extension_type,
245932b31808SJens Wiklander             MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_CR);
246032b31808SJens Wiklander         if (ret != 0) {
246132b31808SJens Wiklander             return ret;
246232b31808SJens Wiklander         }
246332b31808SJens Wiklander 
246432b31808SJens Wiklander         switch (extension_type) {
246532b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SIG_ALG:
246632b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3,
246732b31808SJens Wiklander                                       ("found signature algorithms extension"));
246832b31808SJens Wiklander                 ret = mbedtls_ssl_parse_sig_alg_ext(ssl, p,
246932b31808SJens Wiklander                                                     p + extension_data_len);
247032b31808SJens Wiklander                 if (ret != 0) {
247132b31808SJens Wiklander                     return ret;
247232b31808SJens Wiklander                 }
247332b31808SJens Wiklander 
247432b31808SJens Wiklander                 break;
247532b31808SJens Wiklander 
247632b31808SJens Wiklander             default:
247732b31808SJens Wiklander                 MBEDTLS_SSL_PRINT_EXT(
247832b31808SJens Wiklander                     3, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
247932b31808SJens Wiklander                     extension_type, "( ignored )");
248032b31808SJens Wiklander                 break;
248132b31808SJens Wiklander         }
248232b31808SJens Wiklander 
248332b31808SJens Wiklander         p += extension_data_len;
248432b31808SJens Wiklander     }
248532b31808SJens Wiklander 
248632b31808SJens Wiklander     MBEDTLS_SSL_PRINT_EXTS(3, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
248732b31808SJens Wiklander                            handshake->received_extensions);
248832b31808SJens Wiklander 
248932b31808SJens Wiklander     /* Check that we consumed all the message. */
249032b31808SJens Wiklander     if (p != end) {
249132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
249232b31808SJens Wiklander                               ("CertificateRequest misaligned"));
249332b31808SJens Wiklander         goto decode_error;
249432b31808SJens Wiklander     }
249532b31808SJens Wiklander 
249632b31808SJens Wiklander     /* RFC 8446 section 4.3.2
249732b31808SJens Wiklander      *
249832b31808SJens Wiklander      * The "signature_algorithms" extension MUST be specified
249932b31808SJens Wiklander      */
250032b31808SJens Wiklander     if ((handshake->received_extensions & MBEDTLS_SSL_EXT_MASK(SIG_ALG)) == 0) {
250132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3,
250232b31808SJens Wiklander                               ("no signature algorithms extension found"));
250332b31808SJens Wiklander         goto decode_error;
250432b31808SJens Wiklander     }
250532b31808SJens Wiklander 
250632b31808SJens Wiklander     ssl->handshake->client_auth = 1;
250732b31808SJens Wiklander     return 0;
250832b31808SJens Wiklander 
250932b31808SJens Wiklander decode_error:
251032b31808SJens Wiklander     MBEDTLS_SSL_PEND_FATAL_ALERT(MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR,
251132b31808SJens Wiklander                                  MBEDTLS_ERR_SSL_DECODE_ERROR);
251232b31808SJens Wiklander     return MBEDTLS_ERR_SSL_DECODE_ERROR;
251332b31808SJens Wiklander }
251432b31808SJens Wiklander 
251532b31808SJens Wiklander /*
251632b31808SJens Wiklander  * Handler for  MBEDTLS_SSL_CERTIFICATE_REQUEST
251732b31808SJens Wiklander  */
251832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_process_certificate_request(mbedtls_ssl_context * ssl)251932b31808SJens Wiklander static int ssl_tls13_process_certificate_request(mbedtls_ssl_context *ssl)
252032b31808SJens Wiklander {
252132b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
252232b31808SJens Wiklander 
252332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate request"));
252432b31808SJens Wiklander 
252532b31808SJens Wiklander     MBEDTLS_SSL_PROC_CHK_NEG(ssl_tls13_certificate_request_coordinate(ssl));
252632b31808SJens Wiklander 
252732b31808SJens Wiklander     if (ret == SSL_CERTIFICATE_REQUEST_EXPECT_REQUEST) {
252832b31808SJens Wiklander         unsigned char *buf;
252932b31808SJens Wiklander         size_t buf_len;
253032b31808SJens Wiklander 
2531b0563631STom Van Eyck         MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(
2532b0563631STom Van Eyck                                  ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
253332b31808SJens Wiklander                                  &buf, &buf_len));
253432b31808SJens Wiklander 
2535b0563631STom Van Eyck         MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_certificate_request(
2536b0563631STom Van Eyck                                  ssl, buf, buf + buf_len));
253732b31808SJens Wiklander 
2538b0563631STom Van Eyck         MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_add_hs_msg_to_checksum(
2539b0563631STom Van Eyck                                  ssl, MBEDTLS_SSL_HS_CERTIFICATE_REQUEST,
254032b31808SJens Wiklander                                  buf, buf_len));
254132b31808SJens Wiklander     } else if (ret == SSL_CERTIFICATE_REQUEST_SKIP) {
254232b31808SJens Wiklander         ret = 0;
254332b31808SJens Wiklander     } else {
254432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
254532b31808SJens Wiklander         ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
254632b31808SJens Wiklander         goto cleanup;
254732b31808SJens Wiklander     }
254832b31808SJens Wiklander 
254932b31808SJens Wiklander     mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_CERTIFICATE);
255032b31808SJens Wiklander 
255132b31808SJens Wiklander cleanup:
255232b31808SJens Wiklander 
255332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate request"));
255432b31808SJens Wiklander     return ret;
255532b31808SJens Wiklander }
255632b31808SJens Wiklander 
255732b31808SJens Wiklander /*
255832b31808SJens Wiklander  * Handler for MBEDTLS_SSL_SERVER_CERTIFICATE
255932b31808SJens Wiklander  */
256032b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_process_server_certificate(mbedtls_ssl_context * ssl)256132b31808SJens Wiklander static int ssl_tls13_process_server_certificate(mbedtls_ssl_context *ssl)
256232b31808SJens Wiklander {
256332b31808SJens Wiklander     int ret;
256432b31808SJens Wiklander 
256532b31808SJens Wiklander     ret = mbedtls_ssl_tls13_process_certificate(ssl);
256632b31808SJens Wiklander     if (ret != 0) {
256732b31808SJens Wiklander         return ret;
256832b31808SJens Wiklander     }
256932b31808SJens Wiklander 
257032b31808SJens Wiklander     mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CERTIFICATE_VERIFY);
257132b31808SJens Wiklander     return 0;
257232b31808SJens Wiklander }
257332b31808SJens Wiklander 
257432b31808SJens Wiklander /*
257532b31808SJens Wiklander  * Handler for MBEDTLS_SSL_CERTIFICATE_VERIFY
257632b31808SJens Wiklander  */
257732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_process_certificate_verify(mbedtls_ssl_context * ssl)257832b31808SJens Wiklander static int ssl_tls13_process_certificate_verify(mbedtls_ssl_context *ssl)
257932b31808SJens Wiklander {
258032b31808SJens Wiklander     int ret;
258132b31808SJens Wiklander 
258232b31808SJens Wiklander     ret = mbedtls_ssl_tls13_process_certificate_verify(ssl);
258332b31808SJens Wiklander     if (ret != 0) {
258432b31808SJens Wiklander         return ret;
258532b31808SJens Wiklander     }
258632b31808SJens Wiklander 
258732b31808SJens Wiklander     mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_FINISHED);
258832b31808SJens Wiklander     return 0;
258932b31808SJens Wiklander }
259032b31808SJens Wiklander #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
259132b31808SJens Wiklander 
259232b31808SJens Wiklander /*
259332b31808SJens Wiklander  * Handler for MBEDTLS_SSL_SERVER_FINISHED
259432b31808SJens Wiklander  */
259532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_process_server_finished(mbedtls_ssl_context * ssl)259632b31808SJens Wiklander static int ssl_tls13_process_server_finished(mbedtls_ssl_context *ssl)
259732b31808SJens Wiklander {
259832b31808SJens Wiklander     int ret;
259932b31808SJens Wiklander 
260032b31808SJens Wiklander     ret = mbedtls_ssl_tls13_process_finished_message(ssl);
260132b31808SJens Wiklander     if (ret != 0) {
260232b31808SJens Wiklander         return ret;
260332b31808SJens Wiklander     }
260432b31808SJens Wiklander 
260532b31808SJens Wiklander     ret = mbedtls_ssl_tls13_compute_application_transform(ssl);
260632b31808SJens Wiklander     if (ret != 0) {
260732b31808SJens Wiklander         MBEDTLS_SSL_PEND_FATAL_ALERT(
260832b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE,
260932b31808SJens Wiklander             MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE);
261032b31808SJens Wiklander         return ret;
261132b31808SJens Wiklander     }
261232b31808SJens Wiklander 
261332b31808SJens Wiklander #if defined(MBEDTLS_SSL_EARLY_DATA)
2614b0563631STom Van Eyck     if (ssl->early_data_state == MBEDTLS_SSL_EARLY_DATA_STATE_ACCEPTED) {
2615b0563631STom Van Eyck         ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_SERVER_FINISHED_RECEIVED;
261632b31808SJens Wiklander         mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_END_OF_EARLY_DATA);
261732b31808SJens Wiklander     } else
261832b31808SJens Wiklander #endif /* MBEDTLS_SSL_EARLY_DATA */
261932b31808SJens Wiklander     {
262032b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
262132b31808SJens Wiklander         mbedtls_ssl_handshake_set_state(
262232b31808SJens Wiklander             ssl, MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED);
262332b31808SJens Wiklander #else
262432b31808SJens Wiklander         mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
262532b31808SJens Wiklander #endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
262632b31808SJens Wiklander     }
262732b31808SJens Wiklander 
262832b31808SJens Wiklander     return 0;
262932b31808SJens Wiklander }
263032b31808SJens Wiklander 
263132b31808SJens Wiklander /*
263232b31808SJens Wiklander  * Handler for MBEDTLS_SSL_CLIENT_CERTIFICATE
263332b31808SJens Wiklander  */
263432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_write_client_certificate(mbedtls_ssl_context * ssl)263532b31808SJens Wiklander static int ssl_tls13_write_client_certificate(mbedtls_ssl_context *ssl)
263632b31808SJens Wiklander {
263732b31808SJens Wiklander     int non_empty_certificate_msg = 0;
263832b31808SJens Wiklander 
263932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(1,
264032b31808SJens Wiklander                           ("Switch to handshake traffic keys for outbound traffic"));
264132b31808SJens Wiklander     mbedtls_ssl_set_outbound_transform(ssl, ssl->handshake->transform_handshake);
264232b31808SJens Wiklander 
264332b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
264432b31808SJens Wiklander     if (ssl->handshake->client_auth) {
264532b31808SJens Wiklander         int ret = mbedtls_ssl_tls13_write_certificate(ssl);
264632b31808SJens Wiklander         if (ret != 0) {
264732b31808SJens Wiklander             return ret;
264832b31808SJens Wiklander         }
264932b31808SJens Wiklander 
265032b31808SJens Wiklander         if (mbedtls_ssl_own_cert(ssl) != NULL) {
265132b31808SJens Wiklander             non_empty_certificate_msg = 1;
265232b31808SJens Wiklander         }
265332b31808SJens Wiklander     } else {
265432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("skip write certificate"));
265532b31808SJens Wiklander     }
265632b31808SJens Wiklander #endif
265732b31808SJens Wiklander 
265832b31808SJens Wiklander     if (non_empty_certificate_msg) {
265932b31808SJens Wiklander         mbedtls_ssl_handshake_set_state(ssl,
266032b31808SJens Wiklander                                         MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY);
266132b31808SJens Wiklander     } else {
266232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("skip write certificate verify"));
266332b31808SJens Wiklander         mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_FINISHED);
266432b31808SJens Wiklander     }
266532b31808SJens Wiklander 
266632b31808SJens Wiklander     return 0;
266732b31808SJens Wiklander }
266832b31808SJens Wiklander 
266932b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
267032b31808SJens Wiklander /*
267132b31808SJens Wiklander  * Handler for MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY
267232b31808SJens Wiklander  */
267332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_write_client_certificate_verify(mbedtls_ssl_context * ssl)267432b31808SJens Wiklander static int ssl_tls13_write_client_certificate_verify(mbedtls_ssl_context *ssl)
267532b31808SJens Wiklander {
267632b31808SJens Wiklander     int ret = mbedtls_ssl_tls13_write_certificate_verify(ssl);
267732b31808SJens Wiklander 
267832b31808SJens Wiklander     if (ret == 0) {
267932b31808SJens Wiklander         mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_FINISHED);
268032b31808SJens Wiklander     }
268132b31808SJens Wiklander 
268232b31808SJens Wiklander     return ret;
268332b31808SJens Wiklander }
268432b31808SJens Wiklander #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
268532b31808SJens Wiklander 
268632b31808SJens Wiklander /*
268732b31808SJens Wiklander  * Handler for MBEDTLS_SSL_CLIENT_FINISHED
268832b31808SJens Wiklander  */
268932b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_write_client_finished(mbedtls_ssl_context * ssl)269032b31808SJens Wiklander static int ssl_tls13_write_client_finished(mbedtls_ssl_context *ssl)
269132b31808SJens Wiklander {
269232b31808SJens Wiklander     int ret;
269332b31808SJens Wiklander 
269432b31808SJens Wiklander     ret = mbedtls_ssl_tls13_write_finished_message(ssl);
269532b31808SJens Wiklander     if (ret != 0) {
269632b31808SJens Wiklander         return ret;
269732b31808SJens Wiklander     }
269832b31808SJens Wiklander 
269932b31808SJens Wiklander     ret = mbedtls_ssl_tls13_compute_resumption_master_secret(ssl);
270032b31808SJens Wiklander     if (ret != 0) {
2701b0563631STom Van Eyck         MBEDTLS_SSL_DEBUG_RET(
2702b0563631STom Van Eyck             1, "mbedtls_ssl_tls13_compute_resumption_master_secret ", ret);
270332b31808SJens Wiklander         return ret;
270432b31808SJens Wiklander     }
270532b31808SJens Wiklander 
270632b31808SJens Wiklander     mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_FLUSH_BUFFERS);
270732b31808SJens Wiklander     return 0;
270832b31808SJens Wiklander }
270932b31808SJens Wiklander 
271032b31808SJens Wiklander /*
271132b31808SJens Wiklander  * Handler for MBEDTLS_SSL_FLUSH_BUFFERS
271232b31808SJens Wiklander  */
271332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_flush_buffers(mbedtls_ssl_context * ssl)271432b31808SJens Wiklander static int ssl_tls13_flush_buffers(mbedtls_ssl_context *ssl)
271532b31808SJens Wiklander {
271632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done"));
271732b31808SJens Wiklander     mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP);
271832b31808SJens Wiklander     return 0;
271932b31808SJens Wiklander }
272032b31808SJens Wiklander 
272132b31808SJens Wiklander /*
272232b31808SJens Wiklander  * Handler for MBEDTLS_SSL_HANDSHAKE_WRAPUP
272332b31808SJens Wiklander  */
272432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_handshake_wrapup(mbedtls_ssl_context * ssl)272532b31808SJens Wiklander static int ssl_tls13_handshake_wrapup(mbedtls_ssl_context *ssl)
272632b31808SJens Wiklander {
272732b31808SJens Wiklander 
272832b31808SJens Wiklander     mbedtls_ssl_tls13_handshake_wrapup(ssl);
272932b31808SJens Wiklander 
273032b31808SJens Wiklander     mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER);
273132b31808SJens Wiklander     return 0;
273232b31808SJens Wiklander }
273332b31808SJens Wiklander 
273432b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
273532b31808SJens Wiklander 
2736b0563631STom Van Eyck #if defined(MBEDTLS_SSL_EARLY_DATA)
2737b0563631STom Van Eyck /* From RFC 8446 section 4.2.10
2738b0563631STom Van Eyck  *
2739b0563631STom Van Eyck  * struct {
2740b0563631STom Van Eyck  *     select (Handshake.msg_type) {
2741b0563631STom Van Eyck  *         case new_session_ticket:   uint32 max_early_data_size;
2742b0563631STom Van Eyck  *         ...
2743b0563631STom Van Eyck  *     };
2744b0563631STom Van Eyck  * } EarlyDataIndication;
2745b0563631STom Van Eyck  */
2746b0563631STom Van Eyck MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_parse_new_session_ticket_early_data_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,const unsigned char * end)2747b0563631STom Van Eyck static int ssl_tls13_parse_new_session_ticket_early_data_ext(
2748b0563631STom Van Eyck     mbedtls_ssl_context *ssl,
2749b0563631STom Van Eyck     const unsigned char *buf,
2750b0563631STom Van Eyck     const unsigned char *end)
2751b0563631STom Van Eyck {
2752b0563631STom Van Eyck     mbedtls_ssl_session *session = ssl->session;
2753b0563631STom Van Eyck 
2754b0563631STom Van Eyck     MBEDTLS_SSL_CHK_BUF_READ_PTR(buf, end, 4);
2755b0563631STom Van Eyck 
2756b0563631STom Van Eyck     session->max_early_data_size = MBEDTLS_GET_UINT32_BE(buf, 0);
2757b0563631STom Van Eyck     mbedtls_ssl_tls13_session_set_ticket_flags(
2758b0563631STom Van Eyck         session, MBEDTLS_SSL_TLS1_3_TICKET_ALLOW_EARLY_DATA);
2759b0563631STom Van Eyck     MBEDTLS_SSL_DEBUG_MSG(
2760b0563631STom Van Eyck         3, ("received max_early_data_size: %u",
2761b0563631STom Van Eyck             (unsigned int) session->max_early_data_size));
2762b0563631STom Van Eyck 
2763b0563631STom Van Eyck     return 0;
2764b0563631STom Van Eyck }
2765b0563631STom Van Eyck #endif /* MBEDTLS_SSL_EARLY_DATA */
2766b0563631STom Van Eyck 
276732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_parse_new_session_ticket_exts(mbedtls_ssl_context * ssl,const unsigned char * buf,const unsigned char * end)276832b31808SJens Wiklander static int ssl_tls13_parse_new_session_ticket_exts(mbedtls_ssl_context *ssl,
276932b31808SJens Wiklander                                                    const unsigned char *buf,
277032b31808SJens Wiklander                                                    const unsigned char *end)
277132b31808SJens Wiklander {
277232b31808SJens Wiklander     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
277332b31808SJens Wiklander     const unsigned char *p = buf;
277432b31808SJens Wiklander 
277532b31808SJens Wiklander 
277632b31808SJens Wiklander     handshake->received_extensions = MBEDTLS_SSL_EXT_MASK_NONE;
277732b31808SJens Wiklander 
277832b31808SJens Wiklander     while (p < end) {
277932b31808SJens Wiklander         unsigned int extension_type;
278032b31808SJens Wiklander         size_t extension_data_len;
278132b31808SJens Wiklander         int ret;
278232b31808SJens Wiklander 
278332b31808SJens Wiklander         MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 4);
278432b31808SJens Wiklander         extension_type = MBEDTLS_GET_UINT16_BE(p, 0);
278532b31808SJens Wiklander         extension_data_len = MBEDTLS_GET_UINT16_BE(p, 2);
278632b31808SJens Wiklander         p += 4;
278732b31808SJens Wiklander 
278832b31808SJens Wiklander         MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extension_data_len);
278932b31808SJens Wiklander 
279032b31808SJens Wiklander         ret = mbedtls_ssl_tls13_check_received_extension(
279132b31808SJens Wiklander             ssl, MBEDTLS_SSL_HS_NEW_SESSION_TICKET, extension_type,
279232b31808SJens Wiklander             MBEDTLS_SSL_TLS1_3_ALLOWED_EXTS_OF_NST);
279332b31808SJens Wiklander         if (ret != 0) {
279432b31808SJens Wiklander             return ret;
279532b31808SJens Wiklander         }
279632b31808SJens Wiklander 
279732b31808SJens Wiklander         switch (extension_type) {
279832b31808SJens Wiklander #if defined(MBEDTLS_SSL_EARLY_DATA)
279932b31808SJens Wiklander             case MBEDTLS_TLS_EXT_EARLY_DATA:
2800b0563631STom Van Eyck                 ret = ssl_tls13_parse_new_session_ticket_early_data_ext(
2801b0563631STom Van Eyck                     ssl, p, p + extension_data_len);
2802b0563631STom Van Eyck                 if (ret != 0) {
2803b0563631STom Van Eyck                     MBEDTLS_SSL_DEBUG_RET(
2804b0563631STom Van Eyck                         1, "ssl_tls13_parse_new_session_ticket_early_data_ext",
2805b0563631STom Van Eyck                         ret);
280632b31808SJens Wiklander                 }
280732b31808SJens Wiklander                 break;
280832b31808SJens Wiklander #endif /* MBEDTLS_SSL_EARLY_DATA */
280932b31808SJens Wiklander 
281032b31808SJens Wiklander             default:
281132b31808SJens Wiklander                 MBEDTLS_SSL_PRINT_EXT(
281232b31808SJens Wiklander                     3, MBEDTLS_SSL_HS_NEW_SESSION_TICKET,
281332b31808SJens Wiklander                     extension_type, "( ignored )");
281432b31808SJens Wiklander                 break;
281532b31808SJens Wiklander         }
281632b31808SJens Wiklander 
281732b31808SJens Wiklander         p +=  extension_data_len;
281832b31808SJens Wiklander     }
281932b31808SJens Wiklander 
282032b31808SJens Wiklander     MBEDTLS_SSL_PRINT_EXTS(3, MBEDTLS_SSL_HS_NEW_SESSION_TICKET,
282132b31808SJens Wiklander                            handshake->received_extensions);
282232b31808SJens Wiklander 
282332b31808SJens Wiklander     return 0;
282432b31808SJens Wiklander }
282532b31808SJens Wiklander 
282632b31808SJens Wiklander /*
282732b31808SJens Wiklander  * From RFC8446, page 74
282832b31808SJens Wiklander  *
282932b31808SJens Wiklander  * struct {
283032b31808SJens Wiklander  *    uint32 ticket_lifetime;
283132b31808SJens Wiklander  *    uint32 ticket_age_add;
283232b31808SJens Wiklander  *    opaque ticket_nonce<0..255>;
283332b31808SJens Wiklander  *    opaque ticket<1..2^16-1>;
283432b31808SJens Wiklander  *    Extension extensions<0..2^16-2>;
283532b31808SJens Wiklander  * } NewSessionTicket;
283632b31808SJens Wiklander  *
283732b31808SJens Wiklander  */
283832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_parse_new_session_ticket(mbedtls_ssl_context * ssl,unsigned char * buf,unsigned char * end,unsigned char ** ticket_nonce,size_t * ticket_nonce_len)283932b31808SJens Wiklander static int ssl_tls13_parse_new_session_ticket(mbedtls_ssl_context *ssl,
284032b31808SJens Wiklander                                               unsigned char *buf,
284132b31808SJens Wiklander                                               unsigned char *end,
284232b31808SJens Wiklander                                               unsigned char **ticket_nonce,
284332b31808SJens Wiklander                                               size_t *ticket_nonce_len)
284432b31808SJens Wiklander {
284532b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
284632b31808SJens Wiklander     unsigned char *p = buf;
284732b31808SJens Wiklander     mbedtls_ssl_session *session = ssl->session;
284832b31808SJens Wiklander     size_t ticket_len;
284932b31808SJens Wiklander     unsigned char *ticket;
285032b31808SJens Wiklander     size_t extensions_len;
285132b31808SJens Wiklander 
285232b31808SJens Wiklander     *ticket_nonce = NULL;
285332b31808SJens Wiklander     *ticket_nonce_len = 0;
285432b31808SJens Wiklander     /*
285532b31808SJens Wiklander      *    ticket_lifetime   4 bytes
285632b31808SJens Wiklander      *    ticket_age_add    4 bytes
285732b31808SJens Wiklander      *    ticket_nonce_len  1 byte
285832b31808SJens Wiklander      */
285932b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 9);
286032b31808SJens Wiklander 
286132b31808SJens Wiklander     session->ticket_lifetime = MBEDTLS_GET_UINT32_BE(p, 0);
286232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
286332b31808SJens Wiklander                           ("ticket_lifetime: %u",
286432b31808SJens Wiklander                            (unsigned int) session->ticket_lifetime));
2865b0563631STom Van Eyck     if (session->ticket_lifetime >
2866b0563631STom Van Eyck         MBEDTLS_SSL_TLS1_3_MAX_ALLOWED_TICKET_LIFETIME) {
2867b0563631STom Van Eyck         MBEDTLS_SSL_DEBUG_MSG(3, ("ticket_lifetime exceeds 7 days."));
2868b0563631STom Van Eyck         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
2869b0563631STom Van Eyck     }
287032b31808SJens Wiklander 
287132b31808SJens Wiklander     session->ticket_age_add = MBEDTLS_GET_UINT32_BE(p, 4);
287232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
287332b31808SJens Wiklander                           ("ticket_age_add: %u",
287432b31808SJens Wiklander                            (unsigned int) session->ticket_age_add));
287532b31808SJens Wiklander 
287632b31808SJens Wiklander     *ticket_nonce_len = p[8];
287732b31808SJens Wiklander     p += 9;
287832b31808SJens Wiklander 
287932b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, *ticket_nonce_len);
288032b31808SJens Wiklander     *ticket_nonce = p;
288132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "ticket_nonce:", *ticket_nonce, *ticket_nonce_len);
288232b31808SJens Wiklander     p += *ticket_nonce_len;
288332b31808SJens Wiklander 
288432b31808SJens Wiklander     /* Ticket */
288532b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
288632b31808SJens Wiklander     ticket_len = MBEDTLS_GET_UINT16_BE(p, 0);
288732b31808SJens Wiklander     p += 2;
288832b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, ticket_len);
288932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "received ticket", p, ticket_len);
289032b31808SJens Wiklander 
289132b31808SJens Wiklander     /* Check if we previously received a ticket already. */
289232b31808SJens Wiklander     if (session->ticket != NULL || session->ticket_len > 0) {
289332b31808SJens Wiklander         mbedtls_free(session->ticket);
289432b31808SJens Wiklander         session->ticket = NULL;
289532b31808SJens Wiklander         session->ticket_len = 0;
289632b31808SJens Wiklander     }
289732b31808SJens Wiklander 
289832b31808SJens Wiklander     if ((ticket = mbedtls_calloc(1, ticket_len)) == NULL) {
289932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("ticket alloc failed"));
290032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ALLOC_FAILED;
290132b31808SJens Wiklander     }
290232b31808SJens Wiklander     memcpy(ticket, p, ticket_len);
290332b31808SJens Wiklander     p += ticket_len;
290432b31808SJens Wiklander     session->ticket = ticket;
290532b31808SJens Wiklander     session->ticket_len = ticket_len;
290632b31808SJens Wiklander 
290732b31808SJens Wiklander     /* Clear all flags in ticket_flags */
2908b0563631STom Van Eyck     mbedtls_ssl_tls13_session_clear_ticket_flags(
290932b31808SJens Wiklander         session, MBEDTLS_SSL_TLS1_3_TICKET_FLAGS_MASK);
291032b31808SJens Wiklander 
291132b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
291232b31808SJens Wiklander     extensions_len = MBEDTLS_GET_UINT16_BE(p, 0);
291332b31808SJens Wiklander     p += 2;
291432b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, extensions_len);
291532b31808SJens Wiklander 
291632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "ticket extension", p, extensions_len);
291732b31808SJens Wiklander 
291832b31808SJens Wiklander     ret = ssl_tls13_parse_new_session_ticket_exts(ssl, p, p + extensions_len);
291932b31808SJens Wiklander     if (ret != 0) {
292032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1,
292132b31808SJens Wiklander                               "ssl_tls13_parse_new_session_ticket_exts",
292232b31808SJens Wiklander                               ret);
292332b31808SJens Wiklander         return ret;
292432b31808SJens Wiklander     }
292532b31808SJens Wiklander 
292632b31808SJens Wiklander     return 0;
292732b31808SJens Wiklander }
292832b31808SJens Wiklander 
2929b0563631STom Van Eyck /* Non negative return values for ssl_tls13_postprocess_new_session_ticket().
2930b0563631STom Van Eyck  * - POSTPROCESS_NEW_SESSION_TICKET_SIGNAL, all good, we have to signal the
2931b0563631STom Van Eyck  *   application that a valid ticket has been received.
2932b0563631STom Van Eyck  * - POSTPROCESS_NEW_SESSION_TICKET_DISCARD, no fatal error, we keep the
2933b0563631STom Van Eyck  *   connection alive but we do not signal the ticket to the application.
2934b0563631STom Van Eyck  */
2935b0563631STom Van Eyck #define POSTPROCESS_NEW_SESSION_TICKET_SIGNAL 0
2936b0563631STom Van Eyck #define POSTPROCESS_NEW_SESSION_TICKET_DISCARD 1
293732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_postprocess_new_session_ticket(mbedtls_ssl_context * ssl,unsigned char * ticket_nonce,size_t ticket_nonce_len)293832b31808SJens Wiklander static int ssl_tls13_postprocess_new_session_ticket(mbedtls_ssl_context *ssl,
293932b31808SJens Wiklander                                                     unsigned char *ticket_nonce,
294032b31808SJens Wiklander                                                     size_t ticket_nonce_len)
294132b31808SJens Wiklander {
294232b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
294332b31808SJens Wiklander     mbedtls_ssl_session *session = ssl->session;
294432b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
294532b31808SJens Wiklander     psa_algorithm_t psa_hash_alg;
294632b31808SJens Wiklander     int hash_length;
294732b31808SJens Wiklander 
2948b0563631STom Van Eyck     if (session->ticket_lifetime == 0) {
2949b0563631STom Van Eyck         return POSTPROCESS_NEW_SESSION_TICKET_DISCARD;
2950b0563631STom Van Eyck     }
2951b0563631STom Van Eyck 
295232b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME)
295332b31808SJens Wiklander     /* Store ticket creation time */
2954b0563631STom Van Eyck     session->ticket_reception_time = mbedtls_ms_time();
295532b31808SJens Wiklander #endif
295632b31808SJens Wiklander 
295732b31808SJens Wiklander     ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(session->ciphersuite);
295832b31808SJens Wiklander     if (ciphersuite_info == NULL) {
295932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
296032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
296132b31808SJens Wiklander     }
296232b31808SJens Wiklander 
2963b0563631STom Van Eyck     psa_hash_alg = mbedtls_md_psa_alg_from_type((mbedtls_md_type_t) ciphersuite_info->mac);
296432b31808SJens Wiklander     hash_length = PSA_HASH_LENGTH(psa_hash_alg);
296532b31808SJens Wiklander     if (hash_length == -1 ||
296632b31808SJens Wiklander         (size_t) hash_length > sizeof(session->resumption_key)) {
296732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
296832b31808SJens Wiklander     }
296932b31808SJens Wiklander 
297032b31808SJens Wiklander 
297132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "resumption_master_secret",
297232b31808SJens Wiklander                           session->app_secrets.resumption_master_secret,
297332b31808SJens Wiklander                           hash_length);
297432b31808SJens Wiklander 
297532b31808SJens Wiklander     /* Compute resumption key
297632b31808SJens Wiklander      *
297732b31808SJens Wiklander      *  HKDF-Expand-Label( resumption_master_secret,
297832b31808SJens Wiklander      *                    "resumption", ticket_nonce, Hash.length )
297932b31808SJens Wiklander      */
298032b31808SJens Wiklander     ret = mbedtls_ssl_tls13_hkdf_expand_label(
298132b31808SJens Wiklander         psa_hash_alg,
298232b31808SJens Wiklander         session->app_secrets.resumption_master_secret,
298332b31808SJens Wiklander         hash_length,
298432b31808SJens Wiklander         MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN(resumption),
298532b31808SJens Wiklander         ticket_nonce,
298632b31808SJens Wiklander         ticket_nonce_len,
298732b31808SJens Wiklander         session->resumption_key,
298832b31808SJens Wiklander         hash_length);
298932b31808SJens Wiklander 
299032b31808SJens Wiklander     if (ret != 0) {
299132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(2,
299232b31808SJens Wiklander                               "Creating the ticket-resumed PSK failed",
299332b31808SJens Wiklander                               ret);
299432b31808SJens Wiklander         return ret;
299532b31808SJens Wiklander     }
299632b31808SJens Wiklander 
299732b31808SJens Wiklander     session->resumption_key_len = hash_length;
299832b31808SJens Wiklander 
299932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "Ticket-resumed PSK",
300032b31808SJens Wiklander                           session->resumption_key,
300132b31808SJens Wiklander                           session->resumption_key_len);
300232b31808SJens Wiklander 
300332b31808SJens Wiklander     /* Set ticket_flags depends on the selected key exchange modes */
3004b0563631STom Van Eyck     mbedtls_ssl_tls13_session_set_ticket_flags(
300532b31808SJens Wiklander         session, ssl->conf->tls13_kex_modes);
300632b31808SJens Wiklander     MBEDTLS_SSL_PRINT_TICKET_FLAGS(4, session->ticket_flags);
300732b31808SJens Wiklander 
3008b0563631STom Van Eyck     return POSTPROCESS_NEW_SESSION_TICKET_SIGNAL;
300932b31808SJens Wiklander }
301032b31808SJens Wiklander 
301132b31808SJens Wiklander /*
301232b31808SJens Wiklander  * Handler for MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET
301332b31808SJens Wiklander  */
301432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_tls13_process_new_session_ticket(mbedtls_ssl_context * ssl)301532b31808SJens Wiklander static int ssl_tls13_process_new_session_ticket(mbedtls_ssl_context *ssl)
301632b31808SJens Wiklander {
301732b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
301832b31808SJens Wiklander     unsigned char *buf;
301932b31808SJens Wiklander     size_t buf_len;
302032b31808SJens Wiklander     unsigned char *ticket_nonce;
302132b31808SJens Wiklander     size_t ticket_nonce_len;
302232b31808SJens Wiklander 
302332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse new session ticket"));
302432b31808SJens Wiklander 
302532b31808SJens Wiklander     MBEDTLS_SSL_PROC_CHK(mbedtls_ssl_tls13_fetch_handshake_msg(
302632b31808SJens Wiklander                              ssl, MBEDTLS_SSL_HS_NEW_SESSION_TICKET,
302732b31808SJens Wiklander                              &buf, &buf_len));
302832b31808SJens Wiklander 
3029b0563631STom Van Eyck     /*
3030b0563631STom Van Eyck      * We are about to update (maybe only partially) ticket data thus block
3031b0563631STom Van Eyck      * any session export for the time being.
3032b0563631STom Van Eyck      */
3033b0563631STom Van Eyck     ssl->session->exported = 1;
3034b0563631STom Van Eyck 
303532b31808SJens Wiklander     MBEDTLS_SSL_PROC_CHK(ssl_tls13_parse_new_session_ticket(
303632b31808SJens Wiklander                              ssl, buf, buf + buf_len,
303732b31808SJens Wiklander                              &ticket_nonce, &ticket_nonce_len));
303832b31808SJens Wiklander 
3039b0563631STom Van Eyck     MBEDTLS_SSL_PROC_CHK_NEG(ssl_tls13_postprocess_new_session_ticket(
304032b31808SJens Wiklander                                  ssl, ticket_nonce, ticket_nonce_len));
304132b31808SJens Wiklander 
3042b0563631STom Van Eyck     switch (ret) {
3043b0563631STom Van Eyck         case POSTPROCESS_NEW_SESSION_TICKET_SIGNAL:
3044b0563631STom Van Eyck             /*
3045b0563631STom Van Eyck              * All good, we have received a new valid ticket, session data can
3046b0563631STom Van Eyck              * be exported now and we signal the ticket to the application.
3047b0563631STom Van Eyck              */
3048b0563631STom Van Eyck             ssl->session->exported = 0;
3049b0563631STom Van Eyck             ret = MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET;
3050b0563631STom Van Eyck             break;
3051b0563631STom Van Eyck 
3052b0563631STom Van Eyck         case POSTPROCESS_NEW_SESSION_TICKET_DISCARD:
3053b0563631STom Van Eyck             ret = 0;
3054b0563631STom Van Eyck             MBEDTLS_SSL_DEBUG_MSG(2, ("Discard new session ticket"));
3055b0563631STom Van Eyck             break;
3056b0563631STom Van Eyck 
3057b0563631STom Van Eyck         default:
3058b0563631STom Van Eyck             ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
3059b0563631STom Van Eyck     }
3060b0563631STom Van Eyck 
306132b31808SJens Wiklander     mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_OVER);
306232b31808SJens Wiklander 
306332b31808SJens Wiklander cleanup:
306432b31808SJens Wiklander 
306532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse new session ticket"));
306632b31808SJens Wiklander     return ret;
306732b31808SJens Wiklander }
306832b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
306932b31808SJens Wiklander 
mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context * ssl)307032b31808SJens Wiklander int mbedtls_ssl_tls13_handshake_client_step(mbedtls_ssl_context *ssl)
307132b31808SJens Wiklander {
307232b31808SJens Wiklander     int ret = 0;
307332b31808SJens Wiklander 
307432b31808SJens Wiklander     switch (ssl->state) {
307532b31808SJens Wiklander         case MBEDTLS_SSL_HELLO_REQUEST:
307632b31808SJens Wiklander             mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
307732b31808SJens Wiklander             break;
307832b31808SJens Wiklander 
307932b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_HELLO:
308032b31808SJens Wiklander             ret = mbedtls_ssl_write_client_hello(ssl);
308132b31808SJens Wiklander             break;
308232b31808SJens Wiklander 
308332b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_HELLO:
308432b31808SJens Wiklander             ret = ssl_tls13_process_server_hello(ssl);
308532b31808SJens Wiklander             break;
308632b31808SJens Wiklander 
308732b31808SJens Wiklander         case MBEDTLS_SSL_ENCRYPTED_EXTENSIONS:
308832b31808SJens Wiklander             ret = ssl_tls13_process_encrypted_extensions(ssl);
308932b31808SJens Wiklander             break;
309032b31808SJens Wiklander 
309132b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
309232b31808SJens Wiklander         case MBEDTLS_SSL_CERTIFICATE_REQUEST:
309332b31808SJens Wiklander             ret = ssl_tls13_process_certificate_request(ssl);
309432b31808SJens Wiklander             break;
309532b31808SJens Wiklander 
309632b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_CERTIFICATE:
309732b31808SJens Wiklander             ret = ssl_tls13_process_server_certificate(ssl);
309832b31808SJens Wiklander             break;
309932b31808SJens Wiklander 
310032b31808SJens Wiklander         case MBEDTLS_SSL_CERTIFICATE_VERIFY:
310132b31808SJens Wiklander             ret = ssl_tls13_process_certificate_verify(ssl);
310232b31808SJens Wiklander             break;
310332b31808SJens Wiklander #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
310432b31808SJens Wiklander 
310532b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_FINISHED:
310632b31808SJens Wiklander             ret = ssl_tls13_process_server_finished(ssl);
310732b31808SJens Wiklander             break;
310832b31808SJens Wiklander 
3109b0563631STom Van Eyck #if defined(MBEDTLS_SSL_EARLY_DATA)
311032b31808SJens Wiklander         case MBEDTLS_SSL_END_OF_EARLY_DATA:
311132b31808SJens Wiklander             ret = ssl_tls13_write_end_of_early_data(ssl);
311232b31808SJens Wiklander             break;
3113b0563631STom Van Eyck #endif
311432b31808SJens Wiklander 
311532b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_CERTIFICATE:
311632b31808SJens Wiklander             ret = ssl_tls13_write_client_certificate(ssl);
311732b31808SJens Wiklander             break;
311832b31808SJens Wiklander 
311932b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED)
312032b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_CERTIFICATE_VERIFY:
312132b31808SJens Wiklander             ret = ssl_tls13_write_client_certificate_verify(ssl);
312232b31808SJens Wiklander             break;
312332b31808SJens Wiklander #endif /* MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED */
312432b31808SJens Wiklander 
312532b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_FINISHED:
312632b31808SJens Wiklander             ret = ssl_tls13_write_client_finished(ssl);
312732b31808SJens Wiklander             break;
312832b31808SJens Wiklander 
312932b31808SJens Wiklander         case MBEDTLS_SSL_FLUSH_BUFFERS:
313032b31808SJens Wiklander             ret = ssl_tls13_flush_buffers(ssl);
313132b31808SJens Wiklander             break;
313232b31808SJens Wiklander 
313332b31808SJens Wiklander         case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
313432b31808SJens Wiklander             ret = ssl_tls13_handshake_wrapup(ssl);
313532b31808SJens Wiklander             break;
313632b31808SJens Wiklander 
313732b31808SJens Wiklander             /*
313832b31808SJens Wiklander              * Injection of dummy-CCS's for middlebox compatibility
313932b31808SJens Wiklander              */
314032b31808SJens Wiklander #if defined(MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE)
314132b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_CCS_BEFORE_2ND_CLIENT_HELLO:
314232b31808SJens Wiklander             ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
3143b0563631STom Van Eyck             if (ret != 0) {
3144b0563631STom Van Eyck                 break;
314532b31808SJens Wiklander             }
3146b0563631STom Van Eyck             mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
314732b31808SJens Wiklander             break;
314832b31808SJens Wiklander 
314932b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_CCS_AFTER_SERVER_FINISHED:
315032b31808SJens Wiklander             ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
3151b0563631STom Van Eyck             if (ret != 0) {
3152b0563631STom Van Eyck                 break;
315332b31808SJens Wiklander             }
3154b0563631STom Van Eyck             mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_CERTIFICATE);
315532b31808SJens Wiklander             break;
315632b31808SJens Wiklander 
3157b0563631STom Van Eyck #if defined(MBEDTLS_SSL_EARLY_DATA)
315832b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_CCS_AFTER_CLIENT_HELLO:
315932b31808SJens Wiklander             ret = mbedtls_ssl_tls13_write_change_cipher_spec(ssl);
316032b31808SJens Wiklander             if (ret == 0) {
316132b31808SJens Wiklander                 mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO);
316232b31808SJens Wiklander 
316332b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(
316432b31808SJens Wiklander                     1, ("Switch to early data keys for outbound traffic"));
316532b31808SJens Wiklander                 mbedtls_ssl_set_outbound_transform(
316632b31808SJens Wiklander                     ssl, ssl->handshake->transform_earlydata);
3167b0563631STom Van Eyck                 ssl->early_data_state = MBEDTLS_SSL_EARLY_DATA_STATE_CAN_WRITE;
316832b31808SJens Wiklander             }
316932b31808SJens Wiklander             break;
3170b0563631STom Van Eyck #endif /* MBEDTLS_SSL_EARLY_DATA */
317132b31808SJens Wiklander #endif /* MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE */
317232b31808SJens Wiklander 
317332b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
317432b31808SJens Wiklander         case MBEDTLS_SSL_TLS1_3_NEW_SESSION_TICKET:
317532b31808SJens Wiklander             ret = ssl_tls13_process_new_session_ticket(ssl);
317632b31808SJens Wiklander             break;
317732b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
317832b31808SJens Wiklander 
317932b31808SJens Wiklander         default:
318032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("invalid state %d", ssl->state));
318132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
318232b31808SJens Wiklander     }
318332b31808SJens Wiklander 
318432b31808SJens Wiklander     return ret;
318532b31808SJens Wiklander }
318632b31808SJens Wiklander 
318732b31808SJens Wiklander #endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_PROTO_TLS1_3 */
3188