xref: /optee_os/lib/libmbedtls/mbedtls/library/ssl_tls12_client.c (revision c3deb3d6f3b13d0e17fc9efe5880aec039e47594)
132b31808SJens Wiklander /*
232b31808SJens Wiklander  *  TLS 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_2)
1132b31808SJens Wiklander 
1232b31808SJens Wiklander #include "mbedtls/platform.h"
1332b31808SJens Wiklander 
1432b31808SJens Wiklander #include "mbedtls/ssl.h"
1532b31808SJens Wiklander #include "ssl_client.h"
1632b31808SJens Wiklander #include "ssl_misc.h"
17b0563631STom Van Eyck #include "debug_internal.h"
1832b31808SJens Wiklander #include "mbedtls/error.h"
1932b31808SJens Wiklander #include "mbedtls/constant_time.h"
2032b31808SJens Wiklander 
2132b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
22b0563631STom Van Eyck #include "psa_util_internal.h"
2332b31808SJens Wiklander #include "psa/crypto.h"
24b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_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. */
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 /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
3532b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
3632b31808SJens Wiklander 
3732b31808SJens Wiklander #include <string.h>
3832b31808SJens Wiklander 
3932b31808SJens Wiklander #include <stdint.h>
4032b31808SJens Wiklander 
4132b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME)
4232b31808SJens Wiklander #include "mbedtls/platform_time.h"
4332b31808SJens Wiklander #endif
4432b31808SJens Wiklander 
4532b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
4632b31808SJens Wiklander #include "mbedtls/platform_util.h"
4732b31808SJens Wiklander #endif
4832b31808SJens Wiklander 
4932b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
5032b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
5132b31808SJens Wiklander static int ssl_write_renegotiation_ext(mbedtls_ssl_context *ssl,
5232b31808SJens Wiklander                                        unsigned char *buf,
5332b31808SJens Wiklander                                        const unsigned char *end,
5432b31808SJens Wiklander                                        size_t *olen)
5532b31808SJens Wiklander {
5632b31808SJens Wiklander     unsigned char *p = buf;
5732b31808SJens Wiklander 
5832b31808SJens Wiklander     *olen = 0;
5932b31808SJens Wiklander 
6032b31808SJens Wiklander     /* We're always including a TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the
6132b31808SJens Wiklander      * initial ClientHello, in which case also adding the renegotiation
6232b31808SJens Wiklander      * info extension is NOT RECOMMENDED as per RFC 5746 Section 3.4. */
6332b31808SJens Wiklander     if (ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
6432b31808SJens Wiklander         return 0;
6532b31808SJens Wiklander     }
6632b31808SJens Wiklander 
6732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
6832b31808SJens Wiklander                           ("client hello, adding renegotiation extension"));
6932b31808SJens Wiklander 
7032b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 5 + ssl->verify_data_len);
7132b31808SJens Wiklander 
7232b31808SJens Wiklander     /*
7332b31808SJens Wiklander      * Secure renegotiation
7432b31808SJens Wiklander      */
7532b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_RENEGOTIATION_INFO, p, 0);
7632b31808SJens Wiklander     p += 2;
7732b31808SJens Wiklander 
7832b31808SJens Wiklander     *p++ = 0x00;
7932b31808SJens Wiklander     *p++ = MBEDTLS_BYTE_0(ssl->verify_data_len + 1);
8032b31808SJens Wiklander     *p++ = MBEDTLS_BYTE_0(ssl->verify_data_len);
8132b31808SJens Wiklander 
8232b31808SJens Wiklander     memcpy(p, ssl->own_verify_data, ssl->verify_data_len);
8332b31808SJens Wiklander 
8432b31808SJens Wiklander     *olen = 5 + ssl->verify_data_len;
8532b31808SJens Wiklander 
8632b31808SJens Wiklander     return 0;
8732b31808SJens Wiklander }
8832b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */
8932b31808SJens Wiklander 
90b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
91b0563631STom Van Eyck     defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
9232b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
9332b31808SJens Wiklander 
9432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
9532b31808SJens Wiklander static int ssl_write_supported_point_formats_ext(mbedtls_ssl_context *ssl,
9632b31808SJens Wiklander                                                  unsigned char *buf,
9732b31808SJens Wiklander                                                  const unsigned char *end,
9832b31808SJens Wiklander                                                  size_t *olen)
9932b31808SJens Wiklander {
10032b31808SJens Wiklander     unsigned char *p = buf;
10132b31808SJens Wiklander     (void) ssl; /* ssl used for debugging only */
10232b31808SJens Wiklander 
10332b31808SJens Wiklander     *olen = 0;
10432b31808SJens Wiklander 
10532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
10632b31808SJens Wiklander                           ("client hello, adding supported_point_formats extension"));
10732b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6);
10832b31808SJens Wiklander 
10932b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, p, 0);
11032b31808SJens Wiklander     p += 2;
11132b31808SJens Wiklander 
11232b31808SJens Wiklander     *p++ = 0x00;
11332b31808SJens Wiklander     *p++ = 2;
11432b31808SJens Wiklander 
11532b31808SJens Wiklander     *p++ = 1;
11632b31808SJens Wiklander     *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED;
11732b31808SJens Wiklander 
11832b31808SJens Wiklander     *olen = 6;
11932b31808SJens Wiklander 
12032b31808SJens Wiklander     return 0;
12132b31808SJens Wiklander }
122b0563631STom Van Eyck #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED ||
123b0563631STom Van Eyck           MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED ||
12432b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
12532b31808SJens Wiklander 
12632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
12732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
12832b31808SJens Wiklander static int ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl,
12932b31808SJens Wiklander                                       unsigned char *buf,
13032b31808SJens Wiklander                                       const unsigned char *end,
13132b31808SJens Wiklander                                       size_t *olen)
13232b31808SJens Wiklander {
13332b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
13432b31808SJens Wiklander     unsigned char *p = buf;
13532b31808SJens Wiklander     size_t kkpp_len = 0;
13632b31808SJens Wiklander 
13732b31808SJens Wiklander     *olen = 0;
13832b31808SJens Wiklander 
13932b31808SJens Wiklander     /* Skip costly extension if we can't use EC J-PAKE anyway */
14032b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
14132b31808SJens Wiklander     if (ssl->handshake->psa_pake_ctx_is_ok != 1) {
14232b31808SJens Wiklander         return 0;
14332b31808SJens Wiklander     }
14432b31808SJens Wiklander #else
14532b31808SJens Wiklander     if (mbedtls_ecjpake_check(&ssl->handshake->ecjpake_ctx) != 0) {
14632b31808SJens Wiklander         return 0;
14732b31808SJens Wiklander     }
14832b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
14932b31808SJens Wiklander 
15032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
15132b31808SJens Wiklander                           ("client hello, adding ecjpake_kkpp extension"));
15232b31808SJens Wiklander 
15332b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4);
15432b31808SJens Wiklander 
15532b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0);
15632b31808SJens Wiklander     p += 2;
15732b31808SJens Wiklander 
15832b31808SJens Wiklander     /*
15932b31808SJens Wiklander      * We may need to send ClientHello multiple times for Hello verification.
16032b31808SJens Wiklander      * We don't want to compute fresh values every time (both for performance
16132b31808SJens Wiklander      * and consistency reasons), so cache the extension content.
16232b31808SJens Wiklander      */
16332b31808SJens Wiklander     if (ssl->handshake->ecjpake_cache == NULL ||
16432b31808SJens Wiklander         ssl->handshake->ecjpake_cache_len == 0) {
16532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("generating new ecjpake parameters"));
16632b31808SJens Wiklander 
16732b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
16832b31808SJens Wiklander         ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx,
16932b31808SJens Wiklander                                               p + 2, end - p - 2, &kkpp_len,
17032b31808SJens Wiklander                                               MBEDTLS_ECJPAKE_ROUND_ONE);
17132b31808SJens Wiklander         if (ret != 0) {
17232b31808SJens Wiklander             psa_destroy_key(ssl->handshake->psa_pake_password);
17332b31808SJens Wiklander             psa_pake_abort(&ssl->handshake->psa_pake_ctx);
17432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret);
17532b31808SJens Wiklander             return ret;
17632b31808SJens Wiklander         }
17732b31808SJens Wiklander #else
17832b31808SJens Wiklander         ret = mbedtls_ecjpake_write_round_one(&ssl->handshake->ecjpake_ctx,
17932b31808SJens Wiklander                                               p + 2, end - p - 2, &kkpp_len,
18032b31808SJens Wiklander                                               ssl->conf->f_rng, ssl->conf->p_rng);
18132b31808SJens Wiklander         if (ret != 0) {
18232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1,
18332b31808SJens Wiklander                                   "mbedtls_ecjpake_write_round_one", ret);
18432b31808SJens Wiklander             return ret;
18532b31808SJens Wiklander         }
18632b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
18732b31808SJens Wiklander 
18832b31808SJens Wiklander         ssl->handshake->ecjpake_cache = mbedtls_calloc(1, kkpp_len);
18932b31808SJens Wiklander         if (ssl->handshake->ecjpake_cache == NULL) {
19032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("allocation failed"));
19132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ALLOC_FAILED;
19232b31808SJens Wiklander         }
19332b31808SJens Wiklander 
19432b31808SJens Wiklander         memcpy(ssl->handshake->ecjpake_cache, p + 2, kkpp_len);
19532b31808SJens Wiklander         ssl->handshake->ecjpake_cache_len = kkpp_len;
19632b31808SJens Wiklander     } else {
19732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("re-using cached ecjpake parameters"));
19832b31808SJens Wiklander 
19932b31808SJens Wiklander         kkpp_len = ssl->handshake->ecjpake_cache_len;
20032b31808SJens Wiklander         MBEDTLS_SSL_CHK_BUF_PTR(p + 2, end, kkpp_len);
20132b31808SJens Wiklander 
20232b31808SJens Wiklander         memcpy(p + 2, ssl->handshake->ecjpake_cache, kkpp_len);
20332b31808SJens Wiklander     }
20432b31808SJens Wiklander 
20532b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(kkpp_len, p, 0);
20632b31808SJens Wiklander     p += 2;
20732b31808SJens Wiklander 
20832b31808SJens Wiklander     *olen = kkpp_len + 4;
20932b31808SJens Wiklander 
21032b31808SJens Wiklander     return 0;
21132b31808SJens Wiklander }
21232b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
21332b31808SJens Wiklander 
21432b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
21532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
21632b31808SJens Wiklander static int ssl_write_cid_ext(mbedtls_ssl_context *ssl,
21732b31808SJens Wiklander                              unsigned char *buf,
21832b31808SJens Wiklander                              const unsigned char *end,
21932b31808SJens Wiklander                              size_t *olen)
22032b31808SJens Wiklander {
22132b31808SJens Wiklander     unsigned char *p = buf;
22232b31808SJens Wiklander     size_t ext_len;
22332b31808SJens Wiklander 
22432b31808SJens Wiklander     /*
22532b31808SJens Wiklander      *   struct {
22632b31808SJens Wiklander      *      opaque cid<0..2^8-1>;
22732b31808SJens Wiklander      *   } ConnectionId;
22832b31808SJens Wiklander      */
22932b31808SJens Wiklander 
23032b31808SJens Wiklander     *olen = 0;
23132b31808SJens Wiklander     if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
23232b31808SJens Wiklander         ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED) {
23332b31808SJens Wiklander         return 0;
23432b31808SJens Wiklander     }
23532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding CID extension"));
23632b31808SJens Wiklander 
23732b31808SJens Wiklander     /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX
23832b31808SJens Wiklander      * which is at most 255, so the increment cannot overflow. */
23932b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, (unsigned) (ssl->own_cid_len + 5));
24032b31808SJens Wiklander 
24132b31808SJens Wiklander     /* Add extension ID + size */
24232b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_CID, p, 0);
24332b31808SJens Wiklander     p += 2;
24432b31808SJens Wiklander     ext_len = (size_t) ssl->own_cid_len + 1;
24532b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(ext_len, p, 0);
24632b31808SJens Wiklander     p += 2;
24732b31808SJens Wiklander 
24832b31808SJens Wiklander     *p++ = (uint8_t) ssl->own_cid_len;
24932b31808SJens Wiklander     memcpy(p, ssl->own_cid, ssl->own_cid_len);
25032b31808SJens Wiklander 
25132b31808SJens Wiklander     *olen = ssl->own_cid_len + 5;
25232b31808SJens Wiklander 
25332b31808SJens Wiklander     return 0;
25432b31808SJens Wiklander }
25532b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
25632b31808SJens Wiklander 
25732b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
25832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
25932b31808SJens Wiklander static int ssl_write_max_fragment_length_ext(mbedtls_ssl_context *ssl,
26032b31808SJens Wiklander                                              unsigned char *buf,
26132b31808SJens Wiklander                                              const unsigned char *end,
26232b31808SJens Wiklander                                              size_t *olen)
26332b31808SJens Wiklander {
26432b31808SJens Wiklander     unsigned char *p = buf;
26532b31808SJens Wiklander 
26632b31808SJens Wiklander     *olen = 0;
26732b31808SJens Wiklander 
26832b31808SJens Wiklander     if (ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE) {
26932b31808SJens Wiklander         return 0;
27032b31808SJens Wiklander     }
27132b31808SJens Wiklander 
27232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
27332b31808SJens Wiklander                           ("client hello, adding max_fragment_length extension"));
27432b31808SJens Wiklander 
27532b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 5);
27632b31808SJens Wiklander 
27732b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, p, 0);
27832b31808SJens Wiklander     p += 2;
27932b31808SJens Wiklander 
28032b31808SJens Wiklander     *p++ = 0x00;
28132b31808SJens Wiklander     *p++ = 1;
28232b31808SJens Wiklander 
28332b31808SJens Wiklander     *p++ = ssl->conf->mfl_code;
28432b31808SJens Wiklander 
28532b31808SJens Wiklander     *olen = 5;
28632b31808SJens Wiklander 
28732b31808SJens Wiklander     return 0;
28832b31808SJens Wiklander }
28932b31808SJens Wiklander #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
29032b31808SJens Wiklander 
29132b31808SJens Wiklander #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
29232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
29332b31808SJens Wiklander static int ssl_write_encrypt_then_mac_ext(mbedtls_ssl_context *ssl,
29432b31808SJens Wiklander                                           unsigned char *buf,
29532b31808SJens Wiklander                                           const unsigned char *end,
29632b31808SJens Wiklander                                           size_t *olen)
29732b31808SJens Wiklander {
29832b31808SJens Wiklander     unsigned char *p = buf;
29932b31808SJens Wiklander 
30032b31808SJens Wiklander     *olen = 0;
30132b31808SJens Wiklander 
30232b31808SJens Wiklander     if (ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED) {
30332b31808SJens Wiklander         return 0;
30432b31808SJens Wiklander     }
30532b31808SJens Wiklander 
30632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
30732b31808SJens Wiklander                           ("client hello, adding encrypt_then_mac extension"));
30832b31808SJens Wiklander 
30932b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4);
31032b31808SJens Wiklander 
31132b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, p, 0);
31232b31808SJens Wiklander     p += 2;
31332b31808SJens Wiklander 
31432b31808SJens Wiklander     *p++ = 0x00;
31532b31808SJens Wiklander     *p++ = 0x00;
31632b31808SJens Wiklander 
31732b31808SJens Wiklander     *olen = 4;
31832b31808SJens Wiklander 
31932b31808SJens Wiklander     return 0;
32032b31808SJens Wiklander }
32132b31808SJens Wiklander #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
32232b31808SJens Wiklander 
32332b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
32432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
32532b31808SJens Wiklander static int ssl_write_extended_ms_ext(mbedtls_ssl_context *ssl,
32632b31808SJens Wiklander                                      unsigned char *buf,
32732b31808SJens Wiklander                                      const unsigned char *end,
32832b31808SJens Wiklander                                      size_t *olen)
32932b31808SJens Wiklander {
33032b31808SJens Wiklander     unsigned char *p = buf;
33132b31808SJens Wiklander 
33232b31808SJens Wiklander     *olen = 0;
33332b31808SJens Wiklander 
33432b31808SJens Wiklander     if (ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED) {
33532b31808SJens Wiklander         return 0;
33632b31808SJens Wiklander     }
33732b31808SJens Wiklander 
33832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
33932b31808SJens Wiklander                           ("client hello, adding extended_master_secret extension"));
34032b31808SJens Wiklander 
34132b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4);
34232b31808SJens Wiklander 
34332b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, p, 0);
34432b31808SJens Wiklander     p += 2;
34532b31808SJens Wiklander 
34632b31808SJens Wiklander     *p++ = 0x00;
34732b31808SJens Wiklander     *p++ = 0x00;
34832b31808SJens Wiklander 
34932b31808SJens Wiklander     *olen = 4;
35032b31808SJens Wiklander 
35132b31808SJens Wiklander     return 0;
35232b31808SJens Wiklander }
35332b31808SJens Wiklander #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
35432b31808SJens Wiklander 
35532b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
35632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
35732b31808SJens Wiklander static int ssl_write_session_ticket_ext(mbedtls_ssl_context *ssl,
35832b31808SJens Wiklander                                         unsigned char *buf,
35932b31808SJens Wiklander                                         const unsigned char *end,
36032b31808SJens Wiklander                                         size_t *olen)
36132b31808SJens Wiklander {
36232b31808SJens Wiklander     unsigned char *p = buf;
36332b31808SJens Wiklander     size_t tlen = ssl->session_negotiate->ticket_len;
36432b31808SJens Wiklander 
36532b31808SJens Wiklander     *olen = 0;
36632b31808SJens Wiklander 
367cb034002SJerome Forissier     if (mbedtls_ssl_conf_get_session_tickets(ssl->conf) ==
368cb034002SJerome Forissier         MBEDTLS_SSL_SESSION_TICKETS_DISABLED) {
36932b31808SJens Wiklander         return 0;
37032b31808SJens Wiklander     }
37132b31808SJens Wiklander 
37232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
37332b31808SJens Wiklander                           ("client hello, adding session ticket extension"));
37432b31808SJens Wiklander 
37532b31808SJens Wiklander     /* The addition is safe here since the ticket length is 16 bit. */
37632b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4 + tlen);
37732b31808SJens Wiklander 
37832b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SESSION_TICKET, p, 0);
37932b31808SJens Wiklander     p += 2;
38032b31808SJens Wiklander 
38132b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(tlen, p, 0);
38232b31808SJens Wiklander     p += 2;
38332b31808SJens Wiklander 
38432b31808SJens Wiklander     *olen = 4;
38532b31808SJens Wiklander 
38632b31808SJens Wiklander     if (ssl->session_negotiate->ticket == NULL || tlen == 0) {
38732b31808SJens Wiklander         return 0;
38832b31808SJens Wiklander     }
38932b31808SJens Wiklander 
39032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
39132b31808SJens Wiklander                           ("sending session ticket of length %" MBEDTLS_PRINTF_SIZET, tlen));
39232b31808SJens Wiklander 
39332b31808SJens Wiklander     memcpy(p, ssl->session_negotiate->ticket, tlen);
39432b31808SJens Wiklander 
39532b31808SJens Wiklander     *olen += tlen;
39632b31808SJens Wiklander 
39732b31808SJens Wiklander     return 0;
39832b31808SJens Wiklander }
39932b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
40032b31808SJens Wiklander 
40132b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP)
40232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
40332b31808SJens Wiklander static int ssl_write_use_srtp_ext(mbedtls_ssl_context *ssl,
40432b31808SJens Wiklander                                   unsigned char *buf,
40532b31808SJens Wiklander                                   const unsigned char *end,
40632b31808SJens Wiklander                                   size_t *olen)
40732b31808SJens Wiklander {
40832b31808SJens Wiklander     unsigned char *p = buf;
40932b31808SJens Wiklander     size_t protection_profiles_index = 0, ext_len = 0;
41032b31808SJens Wiklander     uint16_t mki_len = 0, profile_value = 0;
41132b31808SJens Wiklander 
41232b31808SJens Wiklander     *olen = 0;
41332b31808SJens Wiklander 
41432b31808SJens Wiklander     if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) ||
41532b31808SJens Wiklander         (ssl->conf->dtls_srtp_profile_list == NULL) ||
41632b31808SJens Wiklander         (ssl->conf->dtls_srtp_profile_list_len == 0)) {
41732b31808SJens Wiklander         return 0;
41832b31808SJens Wiklander     }
41932b31808SJens Wiklander 
42032b31808SJens Wiklander     /* RFC 5764 section 4.1.1
42132b31808SJens Wiklander      * uint8 SRTPProtectionProfile[2];
42232b31808SJens Wiklander      *
42332b31808SJens Wiklander      * struct {
42432b31808SJens Wiklander      *   SRTPProtectionProfiles SRTPProtectionProfiles;
42532b31808SJens Wiklander      *   opaque srtp_mki<0..255>;
42632b31808SJens Wiklander      * } UseSRTPData;
42732b31808SJens Wiklander      * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
42832b31808SJens Wiklander      */
42932b31808SJens Wiklander     if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED) {
43032b31808SJens Wiklander         mki_len = ssl->dtls_srtp_info.mki_len;
43132b31808SJens Wiklander     }
43232b31808SJens Wiklander     /* Extension length = 2 bytes for profiles length,
43332b31808SJens Wiklander      *                    ssl->conf->dtls_srtp_profile_list_len * 2 (each profile is 2 bytes length ),
43432b31808SJens Wiklander      *                    1 byte for srtp_mki vector length and the mki_len value
43532b31808SJens Wiklander      */
43632b31808SJens Wiklander     ext_len = 2 + 2 * (ssl->conf->dtls_srtp_profile_list_len) + 1 + mki_len;
43732b31808SJens Wiklander 
43832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding use_srtp extension"));
43932b31808SJens Wiklander 
44032b31808SJens Wiklander     /* Check there is room in the buffer for the extension + 4 bytes
44132b31808SJens Wiklander      * - the extension tag (2 bytes)
44232b31808SJens Wiklander      * - the extension length (2 bytes)
44332b31808SJens Wiklander      */
44432b31808SJens Wiklander     MBEDTLS_SSL_CHK_BUF_PTR(p, end, ext_len + 4);
44532b31808SJens Wiklander 
44632b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_USE_SRTP, p, 0);
44732b31808SJens Wiklander     p += 2;
44832b31808SJens Wiklander 
44932b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(ext_len, p, 0);
45032b31808SJens Wiklander     p += 2;
45132b31808SJens Wiklander 
45232b31808SJens Wiklander     /* protection profile length: 2*(ssl->conf->dtls_srtp_profile_list_len) */
45332b31808SJens Wiklander     /* micro-optimization:
45432b31808SJens Wiklander      * the list size is limited to MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH
45532b31808SJens Wiklander      * which is lower than 127, so the upper byte of the length is always 0
45632b31808SJens Wiklander      * For the documentation, the more generic code is left in comments
45732b31808SJens Wiklander      * *p++ = (unsigned char)( ( ( 2 * ssl->conf->dtls_srtp_profile_list_len )
45832b31808SJens Wiklander      *                        >> 8 ) & 0xFF );
45932b31808SJens Wiklander      */
46032b31808SJens Wiklander     *p++ = 0;
46132b31808SJens Wiklander     *p++ = MBEDTLS_BYTE_0(2 * ssl->conf->dtls_srtp_profile_list_len);
46232b31808SJens Wiklander 
46332b31808SJens Wiklander     for (protection_profiles_index = 0;
46432b31808SJens Wiklander          protection_profiles_index < ssl->conf->dtls_srtp_profile_list_len;
46532b31808SJens Wiklander          protection_profiles_index++) {
46632b31808SJens Wiklander         profile_value = mbedtls_ssl_check_srtp_profile_value
46732b31808SJens Wiklander                             (ssl->conf->dtls_srtp_profile_list[protection_profiles_index]);
46832b31808SJens Wiklander         if (profile_value != MBEDTLS_TLS_SRTP_UNSET) {
46932b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_write_use_srtp_ext, add profile: %04x",
47032b31808SJens Wiklander                                       profile_value));
47132b31808SJens Wiklander             MBEDTLS_PUT_UINT16_BE(profile_value, p, 0);
47232b31808SJens Wiklander             p += 2;
47332b31808SJens Wiklander         } else {
47432b31808SJens Wiklander             /*
47532b31808SJens Wiklander              * Note: we shall never arrive here as protection profiles
47632b31808SJens Wiklander              * is checked by mbedtls_ssl_conf_dtls_srtp_protection_profiles function
47732b31808SJens Wiklander              */
47832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3,
47932b31808SJens Wiklander                                   ("client hello, "
48032b31808SJens Wiklander                                    "illegal DTLS-SRTP protection profile %d",
48132b31808SJens Wiklander                                    ssl->conf->dtls_srtp_profile_list[protection_profiles_index]
48232b31808SJens Wiklander                                   ));
48332b31808SJens Wiklander             return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
48432b31808SJens Wiklander         }
48532b31808SJens Wiklander     }
48632b31808SJens Wiklander 
48732b31808SJens Wiklander     *p++ = mki_len & 0xFF;
48832b31808SJens Wiklander 
48932b31808SJens Wiklander     if (mki_len != 0) {
49032b31808SJens Wiklander         memcpy(p, ssl->dtls_srtp_info.mki_value, mki_len);
49132b31808SJens Wiklander         /*
49232b31808SJens Wiklander          * Increment p to point to the current position.
49332b31808SJens Wiklander          */
49432b31808SJens Wiklander         p += mki_len;
49532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "sending mki",  ssl->dtls_srtp_info.mki_value,
49632b31808SJens Wiklander                               ssl->dtls_srtp_info.mki_len);
49732b31808SJens Wiklander     }
49832b31808SJens Wiklander 
49932b31808SJens Wiklander     /*
50032b31808SJens Wiklander      * total extension length: extension type (2 bytes)
50132b31808SJens Wiklander      *                         + extension length (2 bytes)
50232b31808SJens Wiklander      *                         + protection profile length (2 bytes)
50332b31808SJens Wiklander      *                         + 2 * number of protection profiles
50432b31808SJens Wiklander      *                         + srtp_mki vector length(1 byte)
50532b31808SJens Wiklander      *                         + mki value
50632b31808SJens Wiklander      */
50732b31808SJens Wiklander     *olen = p - buf;
50832b31808SJens Wiklander 
50932b31808SJens Wiklander     return 0;
51032b31808SJens Wiklander }
51132b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_SRTP */
51232b31808SJens Wiklander 
51332b31808SJens Wiklander int mbedtls_ssl_tls12_write_client_hello_exts(mbedtls_ssl_context *ssl,
51432b31808SJens Wiklander                                               unsigned char *buf,
51532b31808SJens Wiklander                                               const unsigned char *end,
51632b31808SJens Wiklander                                               int uses_ec,
51732b31808SJens Wiklander                                               size_t *out_len)
51832b31808SJens Wiklander {
51932b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
52032b31808SJens Wiklander     unsigned char *p = buf;
52132b31808SJens Wiklander     size_t ext_len = 0;
52232b31808SJens Wiklander 
52332b31808SJens Wiklander     (void) ssl;
52432b31808SJens Wiklander     (void) end;
52532b31808SJens Wiklander     (void) uses_ec;
52632b31808SJens Wiklander     (void) ret;
52732b31808SJens Wiklander     (void) ext_len;
52832b31808SJens Wiklander 
52932b31808SJens Wiklander     *out_len = 0;
53032b31808SJens Wiklander 
53132b31808SJens Wiklander     /* Note that TLS_EMPTY_RENEGOTIATION_INFO_SCSV is always added
53232b31808SJens Wiklander      * even if MBEDTLS_SSL_RENEGOTIATION is not defined. */
53332b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
53432b31808SJens Wiklander     if ((ret = ssl_write_renegotiation_ext(ssl, p, end, &ext_len)) != 0) {
53532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_renegotiation_ext", ret);
53632b31808SJens Wiklander         return ret;
53732b31808SJens Wiklander     }
53832b31808SJens Wiklander     p += ext_len;
53932b31808SJens Wiklander #endif
54032b31808SJens Wiklander 
541b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
542b0563631STom Van Eyck     defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
54332b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
54432b31808SJens Wiklander     if (uses_ec) {
54532b31808SJens Wiklander         if ((ret = ssl_write_supported_point_formats_ext(ssl, p, end,
54632b31808SJens Wiklander                                                          &ext_len)) != 0) {
54732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_supported_point_formats_ext", ret);
54832b31808SJens Wiklander             return ret;
54932b31808SJens Wiklander         }
55032b31808SJens Wiklander         p += ext_len;
55132b31808SJens Wiklander     }
55232b31808SJens Wiklander #endif
55332b31808SJens Wiklander 
55432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
55532b31808SJens Wiklander     if ((ret = ssl_write_ecjpake_kkpp_ext(ssl, p, end, &ext_len)) != 0) {
55632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_ecjpake_kkpp_ext", ret);
55732b31808SJens Wiklander         return ret;
55832b31808SJens Wiklander     }
55932b31808SJens Wiklander     p += ext_len;
56032b31808SJens Wiklander #endif
56132b31808SJens Wiklander 
56232b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
56332b31808SJens Wiklander     if ((ret = ssl_write_cid_ext(ssl, p, end, &ext_len)) != 0) {
56432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_cid_ext", ret);
56532b31808SJens Wiklander         return ret;
56632b31808SJens Wiklander     }
56732b31808SJens Wiklander     p += ext_len;
56832b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
56932b31808SJens Wiklander 
57032b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
57132b31808SJens Wiklander     if ((ret = ssl_write_max_fragment_length_ext(ssl, p, end,
57232b31808SJens Wiklander                                                  &ext_len)) != 0) {
57332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_max_fragment_length_ext", ret);
57432b31808SJens Wiklander         return ret;
57532b31808SJens Wiklander     }
57632b31808SJens Wiklander     p += ext_len;
57732b31808SJens Wiklander #endif
57832b31808SJens Wiklander 
57932b31808SJens Wiklander #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
58032b31808SJens Wiklander     if ((ret = ssl_write_encrypt_then_mac_ext(ssl, p, end, &ext_len)) != 0) {
58132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_encrypt_then_mac_ext", ret);
58232b31808SJens Wiklander         return ret;
58332b31808SJens Wiklander     }
58432b31808SJens Wiklander     p += ext_len;
58532b31808SJens Wiklander #endif
58632b31808SJens Wiklander 
58732b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
58832b31808SJens Wiklander     if ((ret = ssl_write_extended_ms_ext(ssl, p, end, &ext_len)) != 0) {
58932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_extended_ms_ext", ret);
59032b31808SJens Wiklander         return ret;
59132b31808SJens Wiklander     }
59232b31808SJens Wiklander     p += ext_len;
59332b31808SJens Wiklander #endif
59432b31808SJens Wiklander 
59532b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP)
59632b31808SJens Wiklander     if ((ret = ssl_write_use_srtp_ext(ssl, p, end, &ext_len)) != 0) {
59732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_use_srtp_ext", ret);
59832b31808SJens Wiklander         return ret;
59932b31808SJens Wiklander     }
60032b31808SJens Wiklander     p += ext_len;
60132b31808SJens Wiklander #endif
60232b31808SJens Wiklander 
60332b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
60432b31808SJens Wiklander     if ((ret = ssl_write_session_ticket_ext(ssl, p, end, &ext_len)) != 0) {
60532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_session_ticket_ext", ret);
60632b31808SJens Wiklander         return ret;
60732b31808SJens Wiklander     }
60832b31808SJens Wiklander     p += ext_len;
60932b31808SJens Wiklander #endif
61032b31808SJens Wiklander 
611b0563631STom Van Eyck     *out_len = (size_t) (p - buf);
61232b31808SJens Wiklander 
61332b31808SJens Wiklander     return 0;
61432b31808SJens Wiklander }
61532b31808SJens Wiklander 
61632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
61732b31808SJens Wiklander static int ssl_parse_renegotiation_info(mbedtls_ssl_context *ssl,
61832b31808SJens Wiklander                                         const unsigned char *buf,
61932b31808SJens Wiklander                                         size_t len)
62032b31808SJens Wiklander {
62132b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
62232b31808SJens Wiklander     if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
62332b31808SJens Wiklander         /* Check verify-data in constant-time. The length OTOH is no secret */
62432b31808SJens Wiklander         if (len    != 1 + ssl->verify_data_len * 2 ||
62532b31808SJens Wiklander             buf[0] !=     ssl->verify_data_len * 2 ||
62632b31808SJens Wiklander             mbedtls_ct_memcmp(buf + 1,
62732b31808SJens Wiklander                               ssl->own_verify_data, ssl->verify_data_len) != 0 ||
62832b31808SJens Wiklander             mbedtls_ct_memcmp(buf + 1 + ssl->verify_data_len,
62932b31808SJens Wiklander                               ssl->peer_verify_data, ssl->verify_data_len) != 0) {
63032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("non-matching renegotiation info"));
63132b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
63232b31808SJens Wiklander                 ssl,
63332b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
63432b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
63532b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
63632b31808SJens Wiklander         }
63732b31808SJens Wiklander     } else
63832b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */
63932b31808SJens Wiklander     {
64032b31808SJens Wiklander         if (len != 1 || buf[0] != 0x00) {
64132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1,
64232b31808SJens Wiklander                                   ("non-zero length renegotiation info"));
64332b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
64432b31808SJens Wiklander                 ssl,
64532b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
64632b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
64732b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
64832b31808SJens Wiklander         }
64932b31808SJens Wiklander 
65032b31808SJens Wiklander         ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
65132b31808SJens Wiklander     }
65232b31808SJens Wiklander 
65332b31808SJens Wiklander     return 0;
65432b31808SJens Wiklander }
65532b31808SJens Wiklander 
65632b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
65732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
65832b31808SJens Wiklander static int ssl_parse_max_fragment_length_ext(mbedtls_ssl_context *ssl,
65932b31808SJens Wiklander                                              const unsigned char *buf,
66032b31808SJens Wiklander                                              size_t len)
66132b31808SJens Wiklander {
66232b31808SJens Wiklander     /*
66332b31808SJens Wiklander      * server should use the extension only if we did,
66432b31808SJens Wiklander      * and if so the server's value should match ours (and len is always 1)
66532b31808SJens Wiklander      */
66632b31808SJens Wiklander     if (ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ||
66732b31808SJens Wiklander         len != 1 ||
66832b31808SJens Wiklander         buf[0] != ssl->conf->mfl_code) {
66932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
67032b31808SJens Wiklander                               ("non-matching max fragment length extension"));
67132b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
67232b31808SJens Wiklander             ssl,
67332b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
67432b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
67532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
67632b31808SJens Wiklander     }
67732b31808SJens Wiklander 
67832b31808SJens Wiklander     return 0;
67932b31808SJens Wiklander }
68032b31808SJens Wiklander #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
68132b31808SJens Wiklander 
68232b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
68332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
68432b31808SJens Wiklander static int ssl_parse_cid_ext(mbedtls_ssl_context *ssl,
68532b31808SJens Wiklander                              const unsigned char *buf,
68632b31808SJens Wiklander                              size_t len)
68732b31808SJens Wiklander {
68832b31808SJens Wiklander     size_t peer_cid_len;
68932b31808SJens Wiklander 
69032b31808SJens Wiklander     if ( /* CID extension only makes sense in DTLS */
69132b31808SJens Wiklander         ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
69232b31808SJens Wiklander         /* The server must only send the CID extension if we have offered it. */
69332b31808SJens Wiklander         ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED) {
69432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension unexpected"));
69532b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
69632b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT);
69732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION;
69832b31808SJens Wiklander     }
69932b31808SJens Wiklander 
70032b31808SJens Wiklander     if (len == 0) {
70132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension invalid"));
70232b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
70332b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
70432b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
70532b31808SJens Wiklander     }
70632b31808SJens Wiklander 
70732b31808SJens Wiklander     peer_cid_len = *buf++;
70832b31808SJens Wiklander     len--;
70932b31808SJens Wiklander 
71032b31808SJens Wiklander     if (peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX) {
71132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension invalid"));
71232b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
71332b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
71432b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
71532b31808SJens Wiklander     }
71632b31808SJens Wiklander 
71732b31808SJens Wiklander     if (len != peer_cid_len) {
71832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension invalid"));
71932b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
72032b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
72132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
72232b31808SJens Wiklander     }
72332b31808SJens Wiklander 
72432b31808SJens Wiklander     ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED;
72532b31808SJens Wiklander     ssl->handshake->peer_cid_len = (uint8_t) peer_cid_len;
72632b31808SJens Wiklander     memcpy(ssl->handshake->peer_cid, buf, peer_cid_len);
72732b31808SJens Wiklander 
72832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("Use of CID extension negotiated"));
72932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "Server CID", buf, peer_cid_len);
73032b31808SJens Wiklander 
73132b31808SJens Wiklander     return 0;
73232b31808SJens Wiklander }
73332b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
73432b31808SJens Wiklander 
73532b31808SJens Wiklander #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
73632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
73732b31808SJens Wiklander static int ssl_parse_encrypt_then_mac_ext(mbedtls_ssl_context *ssl,
73832b31808SJens Wiklander                                           const unsigned char *buf,
73932b31808SJens Wiklander                                           size_t len)
74032b31808SJens Wiklander {
74132b31808SJens Wiklander     if (ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
74232b31808SJens Wiklander         len != 0) {
74332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
74432b31808SJens Wiklander                               ("non-matching encrypt-then-MAC extension"));
74532b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
74632b31808SJens Wiklander             ssl,
74732b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
74832b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT);
74932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION;
75032b31808SJens Wiklander     }
75132b31808SJens Wiklander 
75232b31808SJens Wiklander     ((void) buf);
75332b31808SJens Wiklander 
75432b31808SJens Wiklander     ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
75532b31808SJens Wiklander 
75632b31808SJens Wiklander     return 0;
75732b31808SJens Wiklander }
75832b31808SJens Wiklander #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
75932b31808SJens Wiklander 
76032b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
76132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
76232b31808SJens Wiklander static int ssl_parse_extended_ms_ext(mbedtls_ssl_context *ssl,
76332b31808SJens Wiklander                                      const unsigned char *buf,
76432b31808SJens Wiklander                                      size_t len)
76532b31808SJens Wiklander {
76632b31808SJens Wiklander     if (ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
76732b31808SJens Wiklander         len != 0) {
76832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
76932b31808SJens Wiklander                               ("non-matching extended master secret extension"));
77032b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
77132b31808SJens Wiklander             ssl,
77232b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
77332b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT);
77432b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION;
77532b31808SJens Wiklander     }
77632b31808SJens Wiklander 
77732b31808SJens Wiklander     ((void) buf);
77832b31808SJens Wiklander 
77932b31808SJens Wiklander     ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
78032b31808SJens Wiklander 
78132b31808SJens Wiklander     return 0;
78232b31808SJens Wiklander }
78332b31808SJens Wiklander #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
78432b31808SJens Wiklander 
78532b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
78632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
78732b31808SJens Wiklander static int ssl_parse_session_ticket_ext(mbedtls_ssl_context *ssl,
78832b31808SJens Wiklander                                         const unsigned char *buf,
78932b31808SJens Wiklander                                         size_t len)
79032b31808SJens Wiklander {
791cb034002SJerome Forissier     if ((mbedtls_ssl_conf_get_session_tickets(ssl->conf) ==
792cb034002SJerome Forissier          MBEDTLS_SSL_SESSION_TICKETS_DISABLED) ||
79332b31808SJens Wiklander         len != 0) {
79432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
79532b31808SJens Wiklander                               ("non-matching session ticket extension"));
79632b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
79732b31808SJens Wiklander             ssl,
79832b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
79932b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT);
80032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION;
80132b31808SJens Wiklander     }
80232b31808SJens Wiklander 
80332b31808SJens Wiklander     ((void) buf);
80432b31808SJens Wiklander 
80532b31808SJens Wiklander     ssl->handshake->new_session_ticket = 1;
80632b31808SJens Wiklander 
80732b31808SJens Wiklander     return 0;
80832b31808SJens Wiklander }
80932b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
81032b31808SJens Wiklander 
811b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
812b0563631STom Van Eyck     defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
81332b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
81432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
81532b31808SJens Wiklander static int ssl_parse_supported_point_formats_ext(mbedtls_ssl_context *ssl,
81632b31808SJens Wiklander                                                  const unsigned char *buf,
81732b31808SJens Wiklander                                                  size_t len)
81832b31808SJens Wiklander {
81932b31808SJens Wiklander     size_t list_size;
82032b31808SJens Wiklander     const unsigned char *p;
82132b31808SJens Wiklander 
82232b31808SJens Wiklander     if (len == 0 || (size_t) (buf[0] + 1) != len) {
82332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
82432b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
82532b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
82632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
82732b31808SJens Wiklander     }
82832b31808SJens Wiklander     list_size = buf[0];
82932b31808SJens Wiklander 
83032b31808SJens Wiklander     p = buf + 1;
83132b31808SJens Wiklander     while (list_size > 0) {
83232b31808SJens Wiklander         if (p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
83332b31808SJens Wiklander             p[0] == MBEDTLS_ECP_PF_COMPRESSED) {
83432b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO) && \
835b0563631STom Van Eyck             defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED)
83632b31808SJens Wiklander             ssl->handshake->ecdh_ctx.point_format = p[0];
837b0563631STom Van Eyck #endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED */
83832b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO) &&                             \
83932b31808SJens Wiklander             defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
84032b31808SJens Wiklander             mbedtls_ecjpake_set_point_format(&ssl->handshake->ecjpake_ctx,
84132b31808SJens Wiklander                                              p[0]);
84232b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
84332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(4, ("point format selected: %d", p[0]));
84432b31808SJens Wiklander             return 0;
84532b31808SJens Wiklander         }
84632b31808SJens Wiklander 
84732b31808SJens Wiklander         list_size--;
84832b31808SJens Wiklander         p++;
84932b31808SJens Wiklander     }
85032b31808SJens Wiklander 
85132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(1, ("no point format in common"));
85232b31808SJens Wiklander     mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
85332b31808SJens Wiklander                                    MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
85432b31808SJens Wiklander     return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
85532b31808SJens Wiklander }
856b0563631STom Van Eyck #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED ||
857b0563631STom Van Eyck           MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED ||
85832b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
85932b31808SJens Wiklander 
86032b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
86132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
86232b31808SJens Wiklander static int ssl_parse_ecjpake_kkpp(mbedtls_ssl_context *ssl,
86332b31808SJens Wiklander                                   const unsigned char *buf,
86432b31808SJens Wiklander                                   size_t len)
86532b31808SJens Wiklander {
86632b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
86732b31808SJens Wiklander 
86832b31808SJens Wiklander     if (ssl->handshake->ciphersuite_info->key_exchange !=
86932b31808SJens Wiklander         MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
87032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("skip ecjpake kkpp extension"));
87132b31808SJens Wiklander         return 0;
87232b31808SJens Wiklander     }
87332b31808SJens Wiklander 
87432b31808SJens Wiklander     /* If we got here, we no longer need our cached extension */
87532b31808SJens Wiklander     mbedtls_free(ssl->handshake->ecjpake_cache);
87632b31808SJens Wiklander     ssl->handshake->ecjpake_cache = NULL;
87732b31808SJens Wiklander     ssl->handshake->ecjpake_cache_len = 0;
87832b31808SJens Wiklander 
87932b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
88032b31808SJens Wiklander     if ((ret = mbedtls_psa_ecjpake_read_round(
88132b31808SJens Wiklander              &ssl->handshake->psa_pake_ctx, buf, len,
88232b31808SJens Wiklander              MBEDTLS_ECJPAKE_ROUND_ONE)) != 0) {
88332b31808SJens Wiklander         psa_destroy_key(ssl->handshake->psa_pake_password);
88432b31808SJens Wiklander         psa_pake_abort(&ssl->handshake->psa_pake_ctx);
88532b31808SJens Wiklander 
88632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round one", ret);
88732b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
88832b31808SJens Wiklander             ssl,
88932b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
89032b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
89132b31808SJens Wiklander         return ret;
89232b31808SJens Wiklander     }
89332b31808SJens Wiklander 
89432b31808SJens Wiklander     return 0;
89532b31808SJens Wiklander #else
89632b31808SJens Wiklander     if ((ret = mbedtls_ecjpake_read_round_one(&ssl->handshake->ecjpake_ctx,
89732b31808SJens Wiklander                                               buf, len)) != 0) {
89832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_one", ret);
89932b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
90032b31808SJens Wiklander             ssl,
90132b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
90232b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
90332b31808SJens Wiklander         return ret;
90432b31808SJens Wiklander     }
90532b31808SJens Wiklander 
90632b31808SJens Wiklander     return 0;
90732b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
90832b31808SJens Wiklander }
90932b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
91032b31808SJens Wiklander 
91132b31808SJens Wiklander #if defined(MBEDTLS_SSL_ALPN)
91232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
91332b31808SJens Wiklander static int ssl_parse_alpn_ext(mbedtls_ssl_context *ssl,
91432b31808SJens Wiklander                               const unsigned char *buf, size_t len)
91532b31808SJens Wiklander {
91632b31808SJens Wiklander     size_t list_len, name_len;
91732b31808SJens Wiklander     const char **p;
91832b31808SJens Wiklander 
91932b31808SJens Wiklander     /* If we didn't send it, the server shouldn't send it */
92032b31808SJens Wiklander     if (ssl->conf->alpn_list == NULL) {
92132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("non-matching ALPN extension"));
92232b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
92332b31808SJens Wiklander             ssl,
92432b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
92532b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT);
92632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION;
92732b31808SJens Wiklander     }
92832b31808SJens Wiklander 
92932b31808SJens Wiklander     /*
93032b31808SJens Wiklander      * opaque ProtocolName<1..2^8-1>;
93132b31808SJens Wiklander      *
93232b31808SJens Wiklander      * struct {
93332b31808SJens Wiklander      *     ProtocolName protocol_name_list<2..2^16-1>
93432b31808SJens Wiklander      * } ProtocolNameList;
93532b31808SJens Wiklander      *
93632b31808SJens Wiklander      * the "ProtocolNameList" MUST contain exactly one "ProtocolName"
93732b31808SJens Wiklander      */
93832b31808SJens Wiklander 
93932b31808SJens Wiklander     /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */
94032b31808SJens Wiklander     if (len < 4) {
94132b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
94232b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
94332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
94432b31808SJens Wiklander     }
94532b31808SJens Wiklander 
946b0563631STom Van Eyck     list_len = MBEDTLS_GET_UINT16_BE(buf, 0);
94732b31808SJens Wiklander     if (list_len != len - 2) {
94832b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
94932b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
95032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
95132b31808SJens Wiklander     }
95232b31808SJens Wiklander 
95332b31808SJens Wiklander     name_len = buf[2];
95432b31808SJens Wiklander     if (name_len != list_len - 1) {
95532b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
95632b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
95732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
95832b31808SJens Wiklander     }
95932b31808SJens Wiklander 
96032b31808SJens Wiklander     /* Check that the server chosen protocol was in our list and save it */
96132b31808SJens Wiklander     for (p = ssl->conf->alpn_list; *p != NULL; p++) {
96232b31808SJens Wiklander         if (name_len == strlen(*p) &&
96332b31808SJens Wiklander             memcmp(buf + 3, *p, name_len) == 0) {
96432b31808SJens Wiklander             ssl->alpn_chosen = *p;
96532b31808SJens Wiklander             return 0;
96632b31808SJens Wiklander         }
96732b31808SJens Wiklander     }
96832b31808SJens Wiklander 
96932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(1, ("ALPN extension: no matching protocol"));
97032b31808SJens Wiklander     mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
97132b31808SJens Wiklander                                    MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
97232b31808SJens Wiklander     return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
97332b31808SJens Wiklander }
97432b31808SJens Wiklander #endif /* MBEDTLS_SSL_ALPN */
97532b31808SJens Wiklander 
97632b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP)
97732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
97832b31808SJens Wiklander static int ssl_parse_use_srtp_ext(mbedtls_ssl_context *ssl,
97932b31808SJens Wiklander                                   const unsigned char *buf,
98032b31808SJens Wiklander                                   size_t len)
98132b31808SJens Wiklander {
98232b31808SJens Wiklander     mbedtls_ssl_srtp_profile server_protection = MBEDTLS_TLS_SRTP_UNSET;
98332b31808SJens Wiklander     size_t i, mki_len = 0;
98432b31808SJens Wiklander     uint16_t server_protection_profile_value = 0;
98532b31808SJens Wiklander 
98632b31808SJens Wiklander     /* If use_srtp is not configured, just ignore the extension */
98732b31808SJens Wiklander     if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) ||
98832b31808SJens Wiklander         (ssl->conf->dtls_srtp_profile_list == NULL) ||
98932b31808SJens Wiklander         (ssl->conf->dtls_srtp_profile_list_len == 0)) {
99032b31808SJens Wiklander         return 0;
99132b31808SJens Wiklander     }
99232b31808SJens Wiklander 
99332b31808SJens Wiklander     /* RFC 5764 section 4.1.1
99432b31808SJens Wiklander      * uint8 SRTPProtectionProfile[2];
99532b31808SJens Wiklander      *
99632b31808SJens Wiklander      * struct {
99732b31808SJens Wiklander      *   SRTPProtectionProfiles SRTPProtectionProfiles;
99832b31808SJens Wiklander      *   opaque srtp_mki<0..255>;
99932b31808SJens Wiklander      * } UseSRTPData;
100032b31808SJens Wiklander 
100132b31808SJens Wiklander      * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
100232b31808SJens Wiklander      *
100332b31808SJens Wiklander      */
100432b31808SJens Wiklander     if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED) {
100532b31808SJens Wiklander         mki_len = ssl->dtls_srtp_info.mki_len;
100632b31808SJens Wiklander     }
100732b31808SJens Wiklander 
100832b31808SJens Wiklander     /*
100932b31808SJens Wiklander      * Length is 5 + optional mki_value : one protection profile length (2 bytes)
101032b31808SJens Wiklander      *                                      + protection profile (2 bytes)
101132b31808SJens Wiklander      *                                      + mki_len(1 byte)
101232b31808SJens Wiklander      *                                      and optional srtp_mki
101332b31808SJens Wiklander      */
101432b31808SJens Wiklander     if ((len < 5) || (len != (buf[4] + 5u))) {
101532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
101632b31808SJens Wiklander     }
101732b31808SJens Wiklander 
101832b31808SJens Wiklander     /*
101932b31808SJens Wiklander      * get the server protection profile
102032b31808SJens Wiklander      */
102132b31808SJens Wiklander 
102232b31808SJens Wiklander     /*
102332b31808SJens Wiklander      * protection profile length must be 0x0002 as we must have only
102432b31808SJens Wiklander      * one protection profile in server Hello
102532b31808SJens Wiklander      */
102632b31808SJens Wiklander     if ((buf[0] != 0) || (buf[1] != 2)) {
102732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
102832b31808SJens Wiklander     }
102932b31808SJens Wiklander 
103032b31808SJens Wiklander     server_protection_profile_value = (buf[2] << 8) | buf[3];
103132b31808SJens Wiklander     server_protection = mbedtls_ssl_check_srtp_profile_value(
103232b31808SJens Wiklander         server_protection_profile_value);
103332b31808SJens Wiklander     if (server_protection != MBEDTLS_TLS_SRTP_UNSET) {
103432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("found srtp profile: %s",
103532b31808SJens Wiklander                                   mbedtls_ssl_get_srtp_profile_as_string(
103632b31808SJens Wiklander                                       server_protection)));
103732b31808SJens Wiklander     }
103832b31808SJens Wiklander 
103932b31808SJens Wiklander     ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET;
104032b31808SJens Wiklander 
104132b31808SJens Wiklander     /*
104232b31808SJens Wiklander      * Check we have the server profile in our list
104332b31808SJens Wiklander      */
104432b31808SJens Wiklander     for (i = 0; i < ssl->conf->dtls_srtp_profile_list_len; i++) {
104532b31808SJens Wiklander         if (server_protection == ssl->conf->dtls_srtp_profile_list[i]) {
104632b31808SJens Wiklander             ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
104732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3, ("selected srtp profile: %s",
104832b31808SJens Wiklander                                       mbedtls_ssl_get_srtp_profile_as_string(
104932b31808SJens Wiklander                                           server_protection)));
105032b31808SJens Wiklander             break;
105132b31808SJens Wiklander         }
105232b31808SJens Wiklander     }
105332b31808SJens Wiklander 
105432b31808SJens Wiklander     /* If no match was found : server problem, it shall never answer with incompatible profile */
105532b31808SJens Wiklander     if (ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET) {
105632b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
105732b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
105832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
105932b31808SJens Wiklander     }
106032b31808SJens Wiklander 
106132b31808SJens Wiklander     /* If server does not use mki in its reply, make sure the client won't keep
106232b31808SJens Wiklander      * one as negotiated */
106332b31808SJens Wiklander     if (len == 5) {
106432b31808SJens Wiklander         ssl->dtls_srtp_info.mki_len = 0;
106532b31808SJens Wiklander     }
106632b31808SJens Wiklander 
106732b31808SJens Wiklander     /*
106832b31808SJens Wiklander      * RFC5764:
106932b31808SJens Wiklander      *  If the client detects a nonzero-length MKI in the server's response
107032b31808SJens Wiklander      *  that is different than the one the client offered, then the client
107132b31808SJens Wiklander      *  MUST abort the handshake and SHOULD send an invalid_parameter alert.
107232b31808SJens Wiklander      */
107332b31808SJens Wiklander     if (len > 5  && (buf[4] != mki_len ||
107432b31808SJens Wiklander                      (memcmp(ssl->dtls_srtp_info.mki_value, &buf[5], mki_len)))) {
107532b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
107632b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
107732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
107832b31808SJens Wiklander     }
107932b31808SJens Wiklander #if defined(MBEDTLS_DEBUG_C)
108032b31808SJens Wiklander     if (len > 5) {
108132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "received mki", ssl->dtls_srtp_info.mki_value,
108232b31808SJens Wiklander                               ssl->dtls_srtp_info.mki_len);
108332b31808SJens Wiklander     }
108432b31808SJens Wiklander #endif
108532b31808SJens Wiklander     return 0;
108632b31808SJens Wiklander }
108732b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_SRTP */
108832b31808SJens Wiklander 
108932b31808SJens Wiklander /*
109032b31808SJens Wiklander  * Parse HelloVerifyRequest.  Only called after verifying the HS type.
109132b31808SJens Wiklander  */
109232b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
109332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
109432b31808SJens Wiklander static int ssl_parse_hello_verify_request(mbedtls_ssl_context *ssl)
109532b31808SJens Wiklander {
109632b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
109732b31808SJens Wiklander     const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl);
109832b31808SJens Wiklander     uint16_t dtls_legacy_version;
109932b31808SJens Wiklander 
110032b31808SJens Wiklander #if !defined(MBEDTLS_SSL_PROTO_TLS1_3)
110132b31808SJens Wiklander     uint8_t cookie_len;
110232b31808SJens Wiklander #else
110332b31808SJens Wiklander     uint16_t cookie_len;
110432b31808SJens Wiklander #endif
110532b31808SJens Wiklander 
110632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse hello verify request"));
110732b31808SJens Wiklander 
110832b31808SJens Wiklander     /* Check that there is enough room for:
110932b31808SJens Wiklander      * - 2 bytes of version
111032b31808SJens Wiklander      * - 1 byte of cookie_len
111132b31808SJens Wiklander      */
111232b31808SJens Wiklander     if (mbedtls_ssl_hs_hdr_len(ssl) + 3 > ssl->in_msglen) {
111332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
111432b31808SJens Wiklander                               ("incoming HelloVerifyRequest message is too short"));
111532b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
111632b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
111732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
111832b31808SJens Wiklander     }
111932b31808SJens Wiklander 
112032b31808SJens Wiklander     /*
112132b31808SJens Wiklander      * struct {
112232b31808SJens Wiklander      *   ProtocolVersion server_version;
112332b31808SJens Wiklander      *   opaque cookie<0..2^8-1>;
112432b31808SJens Wiklander      * } HelloVerifyRequest;
112532b31808SJens Wiklander      */
112632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "server version", p, 2);
112732b31808SJens Wiklander     dtls_legacy_version = MBEDTLS_GET_UINT16_BE(p, 0);
112832b31808SJens Wiklander     p += 2;
112932b31808SJens Wiklander 
113032b31808SJens Wiklander     /*
113132b31808SJens Wiklander      * Since the RFC is not clear on this point, accept DTLS 1.0 (0xfeff)
113232b31808SJens Wiklander      * The DTLS 1.3 (current draft) renames ProtocolVersion server_version to
113332b31808SJens Wiklander      * legacy_version and locks the value of legacy_version to 0xfefd (DTLS 1.2)
113432b31808SJens Wiklander      */
113532b31808SJens Wiklander     if (dtls_legacy_version != 0xfefd && dtls_legacy_version != 0xfeff) {
113632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server version"));
113732b31808SJens Wiklander 
113832b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
113932b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION);
114032b31808SJens Wiklander 
114132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
114232b31808SJens Wiklander     }
114332b31808SJens Wiklander 
114432b31808SJens Wiklander     cookie_len = *p++;
114532b31808SJens Wiklander     if ((ssl->in_msg + ssl->in_msglen) - p < cookie_len) {
114632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
114732b31808SJens Wiklander                               ("cookie length does not match incoming message size"));
114832b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
114932b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
115032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
115132b31808SJens Wiklander     }
115232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "cookie", p, cookie_len);
115332b31808SJens Wiklander 
115432b31808SJens Wiklander     mbedtls_free(ssl->handshake->cookie);
115532b31808SJens Wiklander 
115632b31808SJens Wiklander     ssl->handshake->cookie = mbedtls_calloc(1, cookie_len);
115732b31808SJens Wiklander     if (ssl->handshake->cookie  == NULL) {
115832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("alloc failed (%d bytes)", cookie_len));
115932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ALLOC_FAILED;
116032b31808SJens Wiklander     }
116132b31808SJens Wiklander 
116232b31808SJens Wiklander     memcpy(ssl->handshake->cookie, p, cookie_len);
116332b31808SJens Wiklander     ssl->handshake->cookie_len = cookie_len;
116432b31808SJens Wiklander 
116532b31808SJens Wiklander     /* Start over at ClientHello */
116632b31808SJens Wiklander     ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
116732b31808SJens Wiklander     ret = mbedtls_ssl_reset_checksum(ssl);
116832b31808SJens Wiklander     if (0 != ret) {
116932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_reset_checksum"), ret);
117032b31808SJens Wiklander         return ret;
117132b31808SJens Wiklander     }
117232b31808SJens Wiklander 
117332b31808SJens Wiklander     mbedtls_ssl_recv_flight_completed(ssl);
117432b31808SJens Wiklander 
117532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse hello verify request"));
117632b31808SJens Wiklander 
117732b31808SJens Wiklander     return 0;
117832b31808SJens Wiklander }
117932b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */
118032b31808SJens Wiklander 
118132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
118232b31808SJens Wiklander static int ssl_parse_server_hello(mbedtls_ssl_context *ssl)
118332b31808SJens Wiklander {
118432b31808SJens Wiklander     int ret, i;
118532b31808SJens Wiklander     size_t n;
118632b31808SJens Wiklander     size_t ext_len;
118732b31808SJens Wiklander     unsigned char *buf, *ext;
118832b31808SJens Wiklander     unsigned char comp;
118932b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
119032b31808SJens Wiklander     int renegotiation_info_seen = 0;
119132b31808SJens Wiklander #endif
119232b31808SJens Wiklander     int handshake_failure = 0;
119332b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *suite_info;
119432b31808SJens Wiklander 
119532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse server hello"));
119632b31808SJens Wiklander 
119732b31808SJens Wiklander     if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
119832b31808SJens Wiklander         /* No alert on a read error. */
119932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
120032b31808SJens Wiklander         return ret;
120132b31808SJens Wiklander     }
120232b31808SJens Wiklander 
120332b31808SJens Wiklander     buf = ssl->in_msg;
120432b31808SJens Wiklander 
120532b31808SJens Wiklander     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
120632b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
120732b31808SJens Wiklander         if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
120832b31808SJens Wiklander             ssl->renego_records_seen++;
120932b31808SJens Wiklander 
121032b31808SJens Wiklander             if (ssl->conf->renego_max_records >= 0 &&
121132b31808SJens Wiklander                 ssl->renego_records_seen > ssl->conf->renego_max_records) {
121232b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1,
121332b31808SJens Wiklander                                       ("renegotiation requested, but not honored by server"));
121432b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
121532b31808SJens Wiklander             }
121632b31808SJens Wiklander 
121732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1,
121832b31808SJens Wiklander                                   ("non-handshake message during renegotiation"));
121932b31808SJens Wiklander 
122032b31808SJens Wiklander             ssl->keep_current_message = 1;
122132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO;
122232b31808SJens Wiklander         }
122332b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */
122432b31808SJens Wiklander 
122532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
122632b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
122732b31808SJens Wiklander             ssl,
122832b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
122932b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE);
123032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
123132b31808SJens Wiklander     }
123232b31808SJens Wiklander 
123332b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
123432b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
123532b31808SJens Wiklander         if (buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST) {
123632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2, ("received hello verify request"));
123732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server hello"));
123832b31808SJens Wiklander             return ssl_parse_hello_verify_request(ssl);
123932b31808SJens Wiklander         } else {
124032b31808SJens Wiklander             /* We made it through the verification process */
124132b31808SJens Wiklander             mbedtls_free(ssl->handshake->cookie);
124232b31808SJens Wiklander             ssl->handshake->cookie = NULL;
124332b31808SJens Wiklander             ssl->handshake->cookie_len = 0;
124432b31808SJens Wiklander         }
124532b31808SJens Wiklander     }
124632b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */
124732b31808SJens Wiklander 
124832b31808SJens Wiklander     if (ssl->in_hslen < 38 + mbedtls_ssl_hs_hdr_len(ssl) ||
124932b31808SJens Wiklander         buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO) {
125032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
125132b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
125232b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
125332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
125432b31808SJens Wiklander     }
125532b31808SJens Wiklander 
125632b31808SJens Wiklander     /*
125732b31808SJens Wiklander      *  0   .  1    server_version
125832b31808SJens Wiklander      *  2   . 33    random (maybe including 4 bytes of Unix time)
125932b31808SJens Wiklander      * 34   . 34    session_id length = n
126032b31808SJens Wiklander      * 35   . 34+n  session_id
126132b31808SJens Wiklander      * 35+n . 36+n  cipher_suite
126232b31808SJens Wiklander      * 37+n . 37+n  compression_method
126332b31808SJens Wiklander      *
126432b31808SJens Wiklander      * 38+n . 39+n  extensions length (optional)
126532b31808SJens Wiklander      * 40+n .  ..   extensions
126632b31808SJens Wiklander      */
126732b31808SJens Wiklander     buf += mbedtls_ssl_hs_hdr_len(ssl);
126832b31808SJens Wiklander 
126932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "server hello, version", buf, 2);
1270b0563631STom Van Eyck     ssl->tls_version = (mbedtls_ssl_protocol_version) mbedtls_ssl_read_version(buf,
1271b0563631STom Van Eyck                                                                                ssl->conf->transport);
127232b31808SJens Wiklander     ssl->session_negotiate->tls_version = ssl->tls_version;
1273b0563631STom Van Eyck     ssl->session_negotiate->endpoint = ssl->conf->endpoint;
127432b31808SJens Wiklander 
127532b31808SJens Wiklander     if (ssl->tls_version < ssl->conf->min_tls_version ||
127632b31808SJens Wiklander         ssl->tls_version > ssl->conf->max_tls_version) {
127732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
127832b31808SJens Wiklander                               (
127932b31808SJens Wiklander                                   "server version out of bounds -  min: [0x%x], server: [0x%x], max: [0x%x]",
128032b31808SJens Wiklander                                   (unsigned) ssl->conf->min_tls_version,
128132b31808SJens Wiklander                                   (unsigned) ssl->tls_version,
128232b31808SJens Wiklander                                   (unsigned) ssl->conf->max_tls_version));
128332b31808SJens Wiklander 
128432b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
128532b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION);
128632b31808SJens Wiklander 
128732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
128832b31808SJens Wiklander     }
128932b31808SJens Wiklander 
129032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, current time: %lu",
129132b31808SJens Wiklander                               ((unsigned long) buf[2] << 24) |
129232b31808SJens Wiklander                               ((unsigned long) buf[3] << 16) |
129332b31808SJens Wiklander                               ((unsigned long) buf[4] <<  8) |
129432b31808SJens Wiklander                               ((unsigned long) buf[5])));
129532b31808SJens Wiklander 
129632b31808SJens Wiklander     memcpy(ssl->handshake->randbytes + 32, buf + 2, 32);
129732b31808SJens Wiklander 
129832b31808SJens Wiklander     n = buf[34];
129932b31808SJens Wiklander 
130032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3,   "server hello, random bytes", buf + 2, 32);
130132b31808SJens Wiklander 
130232b31808SJens Wiklander     if (n > 32) {
130332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
130432b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
130532b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
130632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
130732b31808SJens Wiklander     }
130832b31808SJens Wiklander 
130932b31808SJens Wiklander     if (ssl->in_hslen > mbedtls_ssl_hs_hdr_len(ssl) + 39 + n) {
1310b0563631STom Van Eyck         ext_len = MBEDTLS_GET_UINT16_BE(buf, 38 + n);
131132b31808SJens Wiklander 
131232b31808SJens Wiklander         if ((ext_len > 0 && ext_len < 4) ||
131332b31808SJens Wiklander             ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl) + 40 + n + ext_len) {
131432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
131532b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
131632b31808SJens Wiklander                 ssl,
131732b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
131832b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
131932b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
132032b31808SJens Wiklander         }
132132b31808SJens Wiklander     } else if (ssl->in_hslen == mbedtls_ssl_hs_hdr_len(ssl) + 38 + n) {
132232b31808SJens Wiklander         ext_len = 0;
132332b31808SJens Wiklander     } else {
132432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
132532b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
132632b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
132732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
132832b31808SJens Wiklander     }
132932b31808SJens Wiklander 
133032b31808SJens Wiklander     /* ciphersuite (used later) */
1331b0563631STom Van Eyck     i = (int) MBEDTLS_GET_UINT16_BE(buf, n + 35);
133232b31808SJens Wiklander 
133332b31808SJens Wiklander     /*
133432b31808SJens Wiklander      * Read and check compression
133532b31808SJens Wiklander      */
133632b31808SJens Wiklander     comp = buf[37 + n];
133732b31808SJens Wiklander 
133832b31808SJens Wiklander     if (comp != MBEDTLS_SSL_COMPRESS_NULL) {
133932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
134032b31808SJens Wiklander                               ("server hello, bad compression: %d", comp));
134132b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
134232b31808SJens Wiklander             ssl,
134332b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
134432b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
134532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
134632b31808SJens Wiklander     }
134732b31808SJens Wiklander 
134832b31808SJens Wiklander     /*
134932b31808SJens Wiklander      * Initialize update checksum functions
135032b31808SJens Wiklander      */
135132b31808SJens Wiklander     ssl->handshake->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(i);
135232b31808SJens Wiklander     if (ssl->handshake->ciphersuite_info == NULL) {
135332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
135432b31808SJens Wiklander                               ("ciphersuite info for %04x not found", (unsigned int) i));
135532b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
135632b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
135732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
135832b31808SJens Wiklander     }
135932b31808SJens Wiklander 
136032b31808SJens Wiklander     mbedtls_ssl_optimize_checksum(ssl, ssl->handshake->ciphersuite_info);
136132b31808SJens Wiklander 
136232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, session id len.: %" MBEDTLS_PRINTF_SIZET, n));
136332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3,   "server hello, session id", buf + 35, n);
136432b31808SJens Wiklander 
136532b31808SJens Wiklander     /*
136632b31808SJens Wiklander      * Check if the session can be resumed
136732b31808SJens Wiklander      */
136832b31808SJens Wiklander     if (ssl->handshake->resume == 0 || n == 0 ||
136932b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
137032b31808SJens Wiklander         ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ||
137132b31808SJens Wiklander #endif
137232b31808SJens Wiklander         ssl->session_negotiate->ciphersuite != i ||
137332b31808SJens Wiklander         ssl->session_negotiate->id_len != n ||
137432b31808SJens Wiklander         memcmp(ssl->session_negotiate->id, buf + 35, n) != 0) {
137532b31808SJens Wiklander         ssl->state++;
137632b31808SJens Wiklander         ssl->handshake->resume = 0;
137732b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME)
137832b31808SJens Wiklander         ssl->session_negotiate->start = mbedtls_time(NULL);
137932b31808SJens Wiklander #endif
138032b31808SJens Wiklander         ssl->session_negotiate->ciphersuite = i;
138132b31808SJens Wiklander         ssl->session_negotiate->id_len = n;
138232b31808SJens Wiklander         memcpy(ssl->session_negotiate->id, buf + 35, n);
138332b31808SJens Wiklander     } else {
138432b31808SJens Wiklander         ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
138532b31808SJens Wiklander     }
138632b31808SJens Wiklander 
138732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("%s session has been resumed",
138832b31808SJens Wiklander                               ssl->handshake->resume ? "a" : "no"));
138932b31808SJens Wiklander 
139032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen ciphersuite: %04x", (unsigned) i));
139132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, compress alg.: %d",
139232b31808SJens Wiklander                               buf[37 + n]));
139332b31808SJens Wiklander 
139432b31808SJens Wiklander     /*
139532b31808SJens Wiklander      * Perform cipher suite validation in same way as in ssl_write_client_hello.
139632b31808SJens Wiklander      */
139732b31808SJens Wiklander     i = 0;
139832b31808SJens Wiklander     while (1) {
139932b31808SJens Wiklander         if (ssl->conf->ciphersuite_list[i] == 0) {
140032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
140132b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
140232b31808SJens Wiklander                 ssl,
140332b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
140432b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
140532b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
140632b31808SJens Wiklander         }
140732b31808SJens Wiklander 
140832b31808SJens Wiklander         if (ssl->conf->ciphersuite_list[i++] ==
140932b31808SJens Wiklander             ssl->session_negotiate->ciphersuite) {
141032b31808SJens Wiklander             break;
141132b31808SJens Wiklander         }
141232b31808SJens Wiklander     }
141332b31808SJens Wiklander 
141432b31808SJens Wiklander     suite_info = mbedtls_ssl_ciphersuite_from_id(
141532b31808SJens Wiklander         ssl->session_negotiate->ciphersuite);
141632b31808SJens Wiklander     if (mbedtls_ssl_validate_ciphersuite(ssl, suite_info, ssl->tls_version,
141732b31808SJens Wiklander                                          ssl->tls_version) != 0) {
141832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
141932b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
142032b31808SJens Wiklander             ssl,
142132b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
142232b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
142332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
142432b31808SJens Wiklander     }
142532b31808SJens Wiklander 
142632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3,
142732b31808SJens Wiklander                           ("server hello, chosen ciphersuite: %s", suite_info->name));
142832b31808SJens Wiklander 
142932b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
143032b31808SJens Wiklander     if (suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA &&
143132b31808SJens Wiklander         ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2) {
143232b31808SJens Wiklander         ssl->handshake->ecrs_enabled = 1;
143332b31808SJens Wiklander     }
143432b31808SJens Wiklander #endif
143532b31808SJens Wiklander 
143632b31808SJens Wiklander     if (comp != MBEDTLS_SSL_COMPRESS_NULL) {
143732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
143832b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
143932b31808SJens Wiklander             ssl,
144032b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
144132b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
144232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
144332b31808SJens Wiklander     }
144432b31808SJens Wiklander 
144532b31808SJens Wiklander     ext = buf + 40 + n;
144632b31808SJens Wiklander 
144732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2,
144832b31808SJens Wiklander                           ("server hello, total extension length: %" MBEDTLS_PRINTF_SIZET,
144932b31808SJens Wiklander                            ext_len));
145032b31808SJens Wiklander 
145132b31808SJens Wiklander     while (ext_len) {
1452b0563631STom Van Eyck         unsigned int ext_id   = MBEDTLS_GET_UINT16_BE(ext, 0);
1453b0563631STom Van Eyck         unsigned int ext_size = MBEDTLS_GET_UINT16_BE(ext, 2);
145432b31808SJens Wiklander 
145532b31808SJens Wiklander         if (ext_size + 4 > ext_len) {
145632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
145732b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
145832b31808SJens Wiklander                 ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
145932b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
146032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
146132b31808SJens Wiklander         }
146232b31808SJens Wiklander 
146332b31808SJens Wiklander         switch (ext_id) {
146432b31808SJens Wiklander             case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
146532b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found renegotiation extension"));
146632b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
146732b31808SJens Wiklander                 renegotiation_info_seen = 1;
146832b31808SJens Wiklander #endif
146932b31808SJens Wiklander 
147032b31808SJens Wiklander                 if ((ret = ssl_parse_renegotiation_info(ssl, ext + 4,
147132b31808SJens Wiklander                                                         ext_size)) != 0) {
147232b31808SJens Wiklander                     return ret;
147332b31808SJens Wiklander                 }
147432b31808SJens Wiklander 
147532b31808SJens Wiklander                 break;
147632b31808SJens Wiklander 
147732b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
147832b31808SJens Wiklander             case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
147932b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3,
148032b31808SJens Wiklander                                       ("found max_fragment_length extension"));
148132b31808SJens Wiklander 
148232b31808SJens Wiklander                 if ((ret = ssl_parse_max_fragment_length_ext(ssl,
148332b31808SJens Wiklander                                                              ext + 4, ext_size)) != 0) {
148432b31808SJens Wiklander                     return ret;
148532b31808SJens Wiklander                 }
148632b31808SJens Wiklander 
148732b31808SJens Wiklander                 break;
148832b31808SJens Wiklander #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
148932b31808SJens Wiklander 
149032b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
149132b31808SJens Wiklander             case MBEDTLS_TLS_EXT_CID:
149232b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found CID extension"));
149332b31808SJens Wiklander 
149432b31808SJens Wiklander                 if ((ret = ssl_parse_cid_ext(ssl,
149532b31808SJens Wiklander                                              ext + 4,
149632b31808SJens Wiklander                                              ext_size)) != 0) {
149732b31808SJens Wiklander                     return ret;
149832b31808SJens Wiklander                 }
149932b31808SJens Wiklander 
150032b31808SJens Wiklander                 break;
150132b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
150232b31808SJens Wiklander 
150332b31808SJens Wiklander #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
150432b31808SJens Wiklander             case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
150532b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found encrypt_then_mac extension"));
150632b31808SJens Wiklander 
150732b31808SJens Wiklander                 if ((ret = ssl_parse_encrypt_then_mac_ext(ssl,
150832b31808SJens Wiklander                                                           ext + 4, ext_size)) != 0) {
150932b31808SJens Wiklander                     return ret;
151032b31808SJens Wiklander                 }
151132b31808SJens Wiklander 
151232b31808SJens Wiklander                 break;
151332b31808SJens Wiklander #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
151432b31808SJens Wiklander 
151532b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
151632b31808SJens Wiklander             case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
151732b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3,
151832b31808SJens Wiklander                                       ("found extended_master_secret extension"));
151932b31808SJens Wiklander 
152032b31808SJens Wiklander                 if ((ret = ssl_parse_extended_ms_ext(ssl,
152132b31808SJens Wiklander                                                      ext + 4, ext_size)) != 0) {
152232b31808SJens Wiklander                     return ret;
152332b31808SJens Wiklander                 }
152432b31808SJens Wiklander 
152532b31808SJens Wiklander                 break;
152632b31808SJens Wiklander #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
152732b31808SJens Wiklander 
152832b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
152932b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SESSION_TICKET:
153032b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found session_ticket extension"));
153132b31808SJens Wiklander 
153232b31808SJens Wiklander                 if ((ret = ssl_parse_session_ticket_ext(ssl,
153332b31808SJens Wiklander                                                         ext + 4, ext_size)) != 0) {
153432b31808SJens Wiklander                     return ret;
153532b31808SJens Wiklander                 }
153632b31808SJens Wiklander 
153732b31808SJens Wiklander                 break;
153832b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
153932b31808SJens Wiklander 
1540b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
1541b0563631STom Van Eyck                 defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
154232b31808SJens Wiklander                 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
154332b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
154432b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3,
154532b31808SJens Wiklander                                       ("found supported_point_formats extension"));
154632b31808SJens Wiklander 
154732b31808SJens Wiklander                 if ((ret = ssl_parse_supported_point_formats_ext(ssl,
154832b31808SJens Wiklander                                                                  ext + 4, ext_size)) != 0) {
154932b31808SJens Wiklander                     return ret;
155032b31808SJens Wiklander                 }
155132b31808SJens Wiklander 
155232b31808SJens Wiklander                 break;
1553b0563631STom Van Eyck #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED ||
1554b0563631STom Van Eyck           MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED ||
155532b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
155632b31808SJens Wiklander 
155732b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
155832b31808SJens Wiklander             case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
155932b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found ecjpake_kkpp extension"));
156032b31808SJens Wiklander 
156132b31808SJens Wiklander                 if ((ret = ssl_parse_ecjpake_kkpp(ssl,
156232b31808SJens Wiklander                                                   ext + 4, ext_size)) != 0) {
156332b31808SJens Wiklander                     return ret;
156432b31808SJens Wiklander                 }
156532b31808SJens Wiklander 
156632b31808SJens Wiklander                 break;
156732b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
156832b31808SJens Wiklander 
156932b31808SJens Wiklander #if defined(MBEDTLS_SSL_ALPN)
157032b31808SJens Wiklander             case MBEDTLS_TLS_EXT_ALPN:
157132b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found alpn extension"));
157232b31808SJens Wiklander 
157332b31808SJens Wiklander                 if ((ret = ssl_parse_alpn_ext(ssl, ext + 4, ext_size)) != 0) {
157432b31808SJens Wiklander                     return ret;
157532b31808SJens Wiklander                 }
157632b31808SJens Wiklander 
157732b31808SJens Wiklander                 break;
157832b31808SJens Wiklander #endif /* MBEDTLS_SSL_ALPN */
157932b31808SJens Wiklander 
158032b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP)
158132b31808SJens Wiklander             case MBEDTLS_TLS_EXT_USE_SRTP:
158232b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found use_srtp extension"));
158332b31808SJens Wiklander 
158432b31808SJens Wiklander                 if ((ret = ssl_parse_use_srtp_ext(ssl, ext + 4, ext_size)) != 0) {
158532b31808SJens Wiklander                     return ret;
158632b31808SJens Wiklander                 }
158732b31808SJens Wiklander 
158832b31808SJens Wiklander                 break;
158932b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_SRTP */
159032b31808SJens Wiklander 
159132b31808SJens Wiklander             default:
159232b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3,
159332b31808SJens Wiklander                                       ("unknown extension found: %u (ignoring)", ext_id));
159432b31808SJens Wiklander         }
159532b31808SJens Wiklander 
159632b31808SJens Wiklander         ext_len -= 4 + ext_size;
159732b31808SJens Wiklander         ext += 4 + ext_size;
159832b31808SJens Wiklander 
159932b31808SJens Wiklander         if (ext_len > 0 && ext_len < 4) {
160032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message"));
160132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
160232b31808SJens Wiklander         }
160332b31808SJens Wiklander     }
160432b31808SJens Wiklander 
160532b31808SJens Wiklander     /*
160632b31808SJens Wiklander      * mbedtls_ssl_derive_keys() has to be called after the parsing of the
160732b31808SJens Wiklander      * extensions. It sets the transform data for the resumed session which in
160832b31808SJens Wiklander      * case of DTLS includes the server CID extracted from the CID extension.
160932b31808SJens Wiklander      */
161032b31808SJens Wiklander     if (ssl->handshake->resume) {
161132b31808SJens Wiklander         if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) {
161232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret);
161332b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
161432b31808SJens Wiklander                 ssl,
161532b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
161632b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
161732b31808SJens Wiklander             return ret;
161832b31808SJens Wiklander         }
161932b31808SJens Wiklander     }
162032b31808SJens Wiklander 
162132b31808SJens Wiklander     /*
162232b31808SJens Wiklander      * Renegotiation security checks
162332b31808SJens Wiklander      */
162432b31808SJens Wiklander     if (ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
162532b31808SJens Wiklander         ssl->conf->allow_legacy_renegotiation ==
162632b31808SJens Wiklander         MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE) {
162732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
162832b31808SJens Wiklander                               ("legacy renegotiation, breaking off handshake"));
162932b31808SJens Wiklander         handshake_failure = 1;
163032b31808SJens Wiklander     }
163132b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
163232b31808SJens Wiklander     else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
163332b31808SJens Wiklander              ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION &&
163432b31808SJens Wiklander              renegotiation_info_seen == 0) {
163532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
163632b31808SJens Wiklander                               ("renegotiation_info extension missing (secure)"));
163732b31808SJens Wiklander         handshake_failure = 1;
163832b31808SJens Wiklander     } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
163932b31808SJens Wiklander                ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
164032b31808SJens Wiklander                ssl->conf->allow_legacy_renegotiation ==
164132b31808SJens Wiklander                MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION) {
164232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("legacy renegotiation not allowed"));
164332b31808SJens Wiklander         handshake_failure = 1;
164432b31808SJens Wiklander     } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
164532b31808SJens Wiklander                ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
164632b31808SJens Wiklander                renegotiation_info_seen == 1) {
164732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
164832b31808SJens Wiklander                               ("renegotiation_info extension present (legacy)"));
164932b31808SJens Wiklander         handshake_failure = 1;
165032b31808SJens Wiklander     }
165132b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */
165232b31808SJens Wiklander 
165332b31808SJens Wiklander     if (handshake_failure == 1) {
165432b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
165532b31808SJens Wiklander             ssl,
165632b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
165732b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
165832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
165932b31808SJens Wiklander     }
166032b31808SJens Wiklander 
166132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server hello"));
166232b31808SJens Wiklander 
166332b31808SJens Wiklander     return 0;
166432b31808SJens Wiklander }
166532b31808SJens Wiklander 
166632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
166732b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
166832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
166932b31808SJens Wiklander static int ssl_parse_server_dh_params(mbedtls_ssl_context *ssl,
167032b31808SJens Wiklander                                       unsigned char **p,
167132b31808SJens Wiklander                                       unsigned char *end)
167232b31808SJens Wiklander {
167332b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
167432b31808SJens Wiklander     size_t dhm_actual_bitlen;
167532b31808SJens Wiklander 
167632b31808SJens Wiklander     /*
167732b31808SJens Wiklander      * Ephemeral DH parameters:
167832b31808SJens Wiklander      *
167932b31808SJens Wiklander      * struct {
168032b31808SJens Wiklander      *     opaque dh_p<1..2^16-1>;
168132b31808SJens Wiklander      *     opaque dh_g<1..2^16-1>;
168232b31808SJens Wiklander      *     opaque dh_Ys<1..2^16-1>;
168332b31808SJens Wiklander      * } ServerDHParams;
168432b31808SJens Wiklander      */
168532b31808SJens Wiklander     if ((ret = mbedtls_dhm_read_params(&ssl->handshake->dhm_ctx,
168632b31808SJens Wiklander                                        p, end)) != 0) {
168732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(2, ("mbedtls_dhm_read_params"), ret);
168832b31808SJens Wiklander         return ret;
168932b31808SJens Wiklander     }
169032b31808SJens Wiklander 
169132b31808SJens Wiklander     dhm_actual_bitlen = mbedtls_dhm_get_bitlen(&ssl->handshake->dhm_ctx);
169232b31808SJens Wiklander     if (dhm_actual_bitlen < ssl->conf->dhm_min_bitlen) {
169332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("DHM prime too short: %" MBEDTLS_PRINTF_SIZET " < %u",
169432b31808SJens Wiklander                                   dhm_actual_bitlen,
169532b31808SJens Wiklander                                   ssl->conf->dhm_min_bitlen));
169632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
169732b31808SJens Wiklander     }
169832b31808SJens Wiklander 
169932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MPI(3, "DHM: P ", &ssl->handshake->dhm_ctx.P);
170032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MPI(3, "DHM: G ", &ssl->handshake->dhm_ctx.G);
170132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GY", &ssl->handshake->dhm_ctx.GY);
170232b31808SJens Wiklander 
170332b31808SJens Wiklander     return ret;
170432b31808SJens Wiklander }
170532b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
170632b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
170732b31808SJens Wiklander 
170832b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
170932b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)   ||   \
171032b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)   ||   \
171132b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
171232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
171332b31808SJens Wiklander static int ssl_parse_server_ecdh_params(mbedtls_ssl_context *ssl,
171432b31808SJens Wiklander                                         unsigned char **p,
171532b31808SJens Wiklander                                         unsigned char *end)
171632b31808SJens Wiklander {
171732b31808SJens Wiklander     uint16_t tls_id;
1718b0563631STom Van Eyck     size_t ecpoint_len;
171932b31808SJens Wiklander     mbedtls_ssl_handshake_params *handshake = ssl->handshake;
1720b0563631STom Van Eyck     psa_key_type_t key_type = PSA_KEY_TYPE_NONE;
172132b31808SJens Wiklander     size_t ec_bits = 0;
172232b31808SJens Wiklander 
172332b31808SJens Wiklander     /*
172432b31808SJens Wiklander      * struct {
172532b31808SJens Wiklander      *     ECParameters curve_params;
172632b31808SJens Wiklander      *     ECPoint      public;
172732b31808SJens Wiklander      * } ServerECDHParams;
172832b31808SJens Wiklander      *
172932b31808SJens Wiklander      *  1       curve_type (must be "named_curve")
173032b31808SJens Wiklander      *  2..3    NamedCurve
173132b31808SJens Wiklander      *  4       ECPoint.len
173232b31808SJens Wiklander      *  5+      ECPoint contents
173332b31808SJens Wiklander      */
173432b31808SJens Wiklander     if (end - *p < 4) {
173532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
173632b31808SJens Wiklander     }
173732b31808SJens Wiklander 
173832b31808SJens Wiklander     /* First byte is curve_type; only named_curve is handled */
173932b31808SJens Wiklander     if (*(*p)++ != MBEDTLS_ECP_TLS_NAMED_CURVE) {
174032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
174132b31808SJens Wiklander     }
174232b31808SJens Wiklander 
174332b31808SJens Wiklander     /* Next two bytes are the namedcurve value */
1744b0563631STom Van Eyck     tls_id = MBEDTLS_GET_UINT16_BE(*p, 0);
1745b0563631STom Van Eyck     *p += 2;
174632b31808SJens Wiklander 
174732b31808SJens Wiklander     /* Check it's a curve we offered */
174832b31808SJens Wiklander     if (mbedtls_ssl_check_curve_tls_id(ssl, tls_id) != 0) {
174932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2,
175032b31808SJens Wiklander                               ("bad server key exchange message (ECDHE curve): %u",
175132b31808SJens Wiklander                                (unsigned) tls_id));
175232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
175332b31808SJens Wiklander     }
175432b31808SJens Wiklander 
175532b31808SJens Wiklander     /* Convert EC's TLS ID to PSA key type. */
1756b0563631STom Van Eyck     if (mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id, &key_type,
175732b31808SJens Wiklander                                                    &ec_bits) == PSA_ERROR_NOT_SUPPORTED) {
175832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
175932b31808SJens Wiklander     }
1760b0563631STom Van Eyck     handshake->xxdh_psa_type = key_type;
1761b0563631STom Van Eyck     handshake->xxdh_psa_bits = ec_bits;
176232b31808SJens Wiklander 
176332b31808SJens Wiklander     /* Keep a copy of the peer's public key */
176432b31808SJens Wiklander     ecpoint_len = *(*p)++;
176532b31808SJens Wiklander     if ((size_t) (end - *p) < ecpoint_len) {
176632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
176732b31808SJens Wiklander     }
176832b31808SJens Wiklander 
1769b0563631STom Van Eyck     if (ecpoint_len > sizeof(handshake->xxdh_psa_peerkey)) {
177032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
177132b31808SJens Wiklander     }
177232b31808SJens Wiklander 
1773b0563631STom Van Eyck     memcpy(handshake->xxdh_psa_peerkey, *p, ecpoint_len);
1774b0563631STom Van Eyck     handshake->xxdh_psa_peerkey_len = ecpoint_len;
177532b31808SJens Wiklander     *p += ecpoint_len;
177632b31808SJens Wiklander 
177732b31808SJens Wiklander     return 0;
177832b31808SJens Wiklander }
177932b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED   ||
178032b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED   ||
178132b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
178232b31808SJens Wiklander #else
178332b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)   ||   \
178432b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)    ||   \
178532b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)   ||   \
178632b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||   \
178732b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
178832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
178932b31808SJens Wiklander static int ssl_check_server_ecdh_params(const mbedtls_ssl_context *ssl)
179032b31808SJens Wiklander {
179132b31808SJens Wiklander     uint16_t tls_id;
179232b31808SJens Wiklander     mbedtls_ecp_group_id grp_id;
179332b31808SJens Wiklander #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
179432b31808SJens Wiklander     grp_id = ssl->handshake->ecdh_ctx.grp.id;
179532b31808SJens Wiklander #else
179632b31808SJens Wiklander     grp_id = ssl->handshake->ecdh_ctx.grp_id;
179732b31808SJens Wiklander #endif
179832b31808SJens Wiklander 
179932b31808SJens Wiklander     tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id);
180032b31808SJens Wiklander     if (tls_id == 0) {
180132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
180232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
180332b31808SJens Wiklander     }
180432b31808SJens Wiklander 
180532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("ECDH curve: %s",
180632b31808SJens Wiklander                               mbedtls_ssl_get_curve_name_from_tls_id(tls_id)));
180732b31808SJens Wiklander 
180832b31808SJens Wiklander     if (mbedtls_ssl_check_curve(ssl, grp_id) != 0) {
180932b31808SJens Wiklander         return -1;
181032b31808SJens Wiklander     }
181132b31808SJens Wiklander 
181232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
181332b31808SJens Wiklander                            MBEDTLS_DEBUG_ECDH_QP);
181432b31808SJens Wiklander 
181532b31808SJens Wiklander     return 0;
181632b31808SJens Wiklander }
181732b31808SJens Wiklander 
181832b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED   ||
181932b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED    ||
182032b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED   ||
182132b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
182232b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
182332b31808SJens Wiklander 
182432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||     \
182532b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||     \
182632b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
182732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
182832b31808SJens Wiklander static int ssl_parse_server_ecdh_params(mbedtls_ssl_context *ssl,
182932b31808SJens Wiklander                                         unsigned char **p,
183032b31808SJens Wiklander                                         unsigned char *end)
183132b31808SJens Wiklander {
183232b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
183332b31808SJens Wiklander 
183432b31808SJens Wiklander     /*
183532b31808SJens Wiklander      * Ephemeral ECDH parameters:
183632b31808SJens Wiklander      *
183732b31808SJens Wiklander      * struct {
183832b31808SJens Wiklander      *     ECParameters curve_params;
183932b31808SJens Wiklander      *     ECPoint      public;
184032b31808SJens Wiklander      * } ServerECDHParams;
184132b31808SJens Wiklander      */
184232b31808SJens Wiklander     if ((ret = mbedtls_ecdh_read_params(&ssl->handshake->ecdh_ctx,
184332b31808SJens Wiklander                                         (const unsigned char **) p, end)) != 0) {
184432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_read_params"), ret);
184532b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
184632b31808SJens Wiklander         if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
184732b31808SJens Wiklander             ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
184832b31808SJens Wiklander         }
184932b31808SJens Wiklander #endif
185032b31808SJens Wiklander         return ret;
185132b31808SJens Wiklander     }
185232b31808SJens Wiklander 
185332b31808SJens Wiklander     if (ssl_check_server_ecdh_params(ssl) != 0) {
185432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
185532b31808SJens Wiklander                               ("bad server key exchange message (ECDHE curve)"));
185632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
185732b31808SJens Wiklander     }
185832b31808SJens Wiklander 
185932b31808SJens Wiklander     return ret;
186032b31808SJens Wiklander }
186132b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || \
186232b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || \
186332b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
186432b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO */
186532b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
186632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
186732b31808SJens Wiklander static int ssl_parse_server_psk_hint(mbedtls_ssl_context *ssl,
186832b31808SJens Wiklander                                      unsigned char **p,
186932b31808SJens Wiklander                                      unsigned char *end)
187032b31808SJens Wiklander {
187132b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
187232b31808SJens Wiklander     uint16_t  len;
187332b31808SJens Wiklander     ((void) ssl);
187432b31808SJens Wiklander 
187532b31808SJens Wiklander     /*
187632b31808SJens Wiklander      * PSK parameters:
187732b31808SJens Wiklander      *
187832b31808SJens Wiklander      * opaque psk_identity_hint<0..2^16-1>;
187932b31808SJens Wiklander      */
188032b31808SJens Wiklander     if (end - (*p) < 2) {
188132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
188232b31808SJens Wiklander                               ("bad server key exchange message (psk_identity_hint length)"));
188332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
188432b31808SJens Wiklander     }
1885b0563631STom Van Eyck     len = MBEDTLS_GET_UINT16_BE(*p, 0);
188632b31808SJens Wiklander     *p += 2;
188732b31808SJens Wiklander 
188832b31808SJens Wiklander     if (end - (*p) < len) {
188932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
189032b31808SJens Wiklander                               ("bad server key exchange message (psk_identity_hint length)"));
189132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
189232b31808SJens Wiklander     }
189332b31808SJens Wiklander 
189432b31808SJens Wiklander     /*
189532b31808SJens Wiklander      * Note: we currently ignore the PSK identity hint, as we only allow one
189632b31808SJens Wiklander      * PSK to be provisioned on the client. This could be changed later if
189732b31808SJens Wiklander      * someone needs that feature.
189832b31808SJens Wiklander      */
189932b31808SJens Wiklander     *p += len;
190032b31808SJens Wiklander     ret = 0;
190132b31808SJens Wiklander 
190232b31808SJens Wiklander     return ret;
190332b31808SJens Wiklander }
190432b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
190532b31808SJens Wiklander 
190632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) ||                           \
190732b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
190832b31808SJens Wiklander /*
190932b31808SJens Wiklander  * Generate a pre-master secret and encrypt it with the server's RSA key
191032b31808SJens Wiklander  */
191132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
191232b31808SJens Wiklander static int ssl_write_encrypted_pms(mbedtls_ssl_context *ssl,
191332b31808SJens Wiklander                                    size_t offset, size_t *olen,
191432b31808SJens Wiklander                                    size_t pms_offset)
191532b31808SJens Wiklander {
191632b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
191732b31808SJens Wiklander     size_t len_bytes = 2;
191832b31808SJens Wiklander     unsigned char *p = ssl->handshake->premaster + pms_offset;
191932b31808SJens Wiklander     mbedtls_pk_context *peer_pk;
192032b31808SJens Wiklander 
192132b31808SJens Wiklander     if (offset + len_bytes > MBEDTLS_SSL_OUT_CONTENT_LEN) {
192232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small for encrypted pms"));
192332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
192432b31808SJens Wiklander     }
192532b31808SJens Wiklander 
192632b31808SJens Wiklander     /*
192732b31808SJens Wiklander      * Generate (part of) the pre-master as
192832b31808SJens Wiklander      *  struct {
192932b31808SJens Wiklander      *      ProtocolVersion client_version;
193032b31808SJens Wiklander      *      opaque random[46];
193132b31808SJens Wiklander      *  } PreMasterSecret;
193232b31808SJens Wiklander      */
193332b31808SJens Wiklander     mbedtls_ssl_write_version(p, ssl->conf->transport,
193432b31808SJens Wiklander                               MBEDTLS_SSL_VERSION_TLS1_2);
193532b31808SJens Wiklander 
193632b31808SJens Wiklander     if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p + 2, 46)) != 0) {
193732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "f_rng", ret);
193832b31808SJens Wiklander         return ret;
193932b31808SJens Wiklander     }
194032b31808SJens Wiklander 
194132b31808SJens Wiklander     ssl->handshake->pmslen = 48;
194232b31808SJens Wiklander 
194332b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
194432b31808SJens Wiklander     peer_pk = &ssl->handshake->peer_pubkey;
194532b31808SJens Wiklander #else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
194632b31808SJens Wiklander     if (ssl->session_negotiate->peer_cert == NULL) {
194732b31808SJens Wiklander         /* Should never happen */
194832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
194932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
195032b31808SJens Wiklander     }
195132b31808SJens Wiklander     peer_pk = &ssl->session_negotiate->peer_cert->pk;
195232b31808SJens Wiklander #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
195332b31808SJens Wiklander 
195432b31808SJens Wiklander     /*
195532b31808SJens Wiklander      * Now write it out, encrypted
195632b31808SJens Wiklander      */
195732b31808SJens Wiklander     if (!mbedtls_pk_can_do(peer_pk, MBEDTLS_PK_RSA)) {
195832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("certificate key type mismatch"));
195932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
196032b31808SJens Wiklander     }
196132b31808SJens Wiklander 
196232b31808SJens Wiklander     if ((ret = mbedtls_pk_encrypt(peer_pk,
196332b31808SJens Wiklander                                   p, ssl->handshake->pmslen,
196432b31808SJens Wiklander                                   ssl->out_msg + offset + len_bytes, olen,
196532b31808SJens Wiklander                                   MBEDTLS_SSL_OUT_CONTENT_LEN - offset - len_bytes,
196632b31808SJens Wiklander                                   ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
1967*c3deb3d6SEtienne Carriere         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_encrypt", ret);
196832b31808SJens Wiklander         return ret;
196932b31808SJens Wiklander     }
197032b31808SJens Wiklander 
197132b31808SJens Wiklander     if (len_bytes == 2) {
197232b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(*olen, ssl->out_msg, offset);
197332b31808SJens Wiklander         *olen += 2;
197432b31808SJens Wiklander     }
197532b31808SJens Wiklander 
197632b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
197732b31808SJens Wiklander     /* We don't need the peer's public key anymore. Free it. */
197832b31808SJens Wiklander     mbedtls_pk_free(peer_pk);
197932b31808SJens Wiklander #endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
198032b31808SJens Wiklander     return 0;
198132b31808SJens Wiklander }
198232b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
198332b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
198432b31808SJens Wiklander 
198532b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
198632b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
198732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
198832b31808SJens Wiklander static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
198932b31808SJens Wiklander {
199032b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
199132b31808SJens Wiklander     mbedtls_pk_context *peer_pk;
199232b31808SJens Wiklander 
199332b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
199432b31808SJens Wiklander     peer_pk = &ssl->handshake->peer_pubkey;
199532b31808SJens Wiklander #else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
199632b31808SJens Wiklander     if (ssl->session_negotiate->peer_cert == NULL) {
199732b31808SJens Wiklander         /* Should never happen */
199832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
199932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
200032b31808SJens Wiklander     }
200132b31808SJens Wiklander     peer_pk = &ssl->session_negotiate->peer_cert->pk;
200232b31808SJens Wiklander #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
200332b31808SJens Wiklander 
200432b31808SJens Wiklander     /* This is a public key, so it can't be opaque, so can_do() is a good
200532b31808SJens Wiklander      * enough check to ensure pk_ec() is safe to use below. */
200632b31808SJens Wiklander     if (!mbedtls_pk_can_do(peer_pk, MBEDTLS_PK_ECKEY)) {
200732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("server key not ECDH capable"));
200832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
200932b31808SJens Wiklander     }
201032b31808SJens Wiklander 
2011b0563631STom Van Eyck #if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
2012b0563631STom Van Eyck     const mbedtls_ecp_keypair *peer_key = mbedtls_pk_ec_ro(*peer_pk);
2013b0563631STom Van Eyck #endif /* !defined(MBEDTLS_PK_USE_PSA_EC_DATA) */
201432b31808SJens Wiklander 
201532b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
201632b31808SJens Wiklander     uint16_t tls_id = 0;
2017b0563631STom Van Eyck     psa_key_type_t key_type = PSA_KEY_TYPE_NONE;
2018b0563631STom Van Eyck     mbedtls_ecp_group_id grp_id = mbedtls_pk_get_ec_group_id(peer_pk);
201932b31808SJens Wiklander 
2020b0563631STom Van Eyck     if (mbedtls_ssl_check_curve(ssl, grp_id) != 0) {
202132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server certificate (ECDH curve)"));
202232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
202332b31808SJens Wiklander     }
202432b31808SJens Wiklander 
2025b0563631STom Van Eyck     tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id);
202632b31808SJens Wiklander     if (tls_id == 0) {
202732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("ECC group %u not suported",
2028b0563631STom Van Eyck                                   grp_id));
202932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
203032b31808SJens Wiklander     }
203132b31808SJens Wiklander 
203232b31808SJens Wiklander     /* If the above conversion to TLS ID was fine, then also this one will be,
203332b31808SJens Wiklander        so there is no need to check the return value here */
2034b0563631STom Van Eyck     mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id, &key_type,
2035b0563631STom Van Eyck                                                &ssl->handshake->xxdh_psa_bits);
203632b31808SJens Wiklander 
2037b0563631STom Van Eyck     ssl->handshake->xxdh_psa_type = key_type;
203832b31808SJens Wiklander 
203932b31808SJens Wiklander     /* Store peer's public key in psa format. */
2040b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
2041b0563631STom Van Eyck     memcpy(ssl->handshake->xxdh_psa_peerkey, peer_pk->pub_raw, peer_pk->pub_raw_len);
2042b0563631STom Van Eyck     ssl->handshake->xxdh_psa_peerkey_len = peer_pk->pub_raw_len;
2043b0563631STom Van Eyck     ret = 0;
2044b0563631STom Van Eyck #else /* MBEDTLS_PK_USE_PSA_EC_DATA */
2045b0563631STom Van Eyck     size_t olen = 0;
204632b31808SJens Wiklander     ret = mbedtls_ecp_point_write_binary(&peer_key->grp, &peer_key->Q,
204732b31808SJens Wiklander                                          MBEDTLS_ECP_PF_UNCOMPRESSED, &olen,
2048b0563631STom Van Eyck                                          ssl->handshake->xxdh_psa_peerkey,
2049b0563631STom Van Eyck                                          sizeof(ssl->handshake->xxdh_psa_peerkey));
205032b31808SJens Wiklander 
205132b31808SJens Wiklander     if (ret != 0) {
205232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecp_point_write_binary"), ret);
205332b31808SJens Wiklander         return ret;
205432b31808SJens Wiklander     }
2055b0563631STom Van Eyck     ssl->handshake->xxdh_psa_peerkey_len = olen;
2056b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
2057b0563631STom Van Eyck #else /* MBEDTLS_USE_PSA_CRYPTO */
205832b31808SJens Wiklander     if ((ret = mbedtls_ecdh_get_params(&ssl->handshake->ecdh_ctx, peer_key,
205932b31808SJens Wiklander                                        MBEDTLS_ECDH_THEIRS)) != 0) {
206032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_get_params"), ret);
206132b31808SJens Wiklander         return ret;
206232b31808SJens Wiklander     }
206332b31808SJens Wiklander 
206432b31808SJens Wiklander     if (ssl_check_server_ecdh_params(ssl) != 0) {
206532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server certificate (ECDH curve)"));
206632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_CERTIFICATE;
206732b31808SJens Wiklander     }
2068b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */
206932b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
207032b31808SJens Wiklander     /* We don't need the peer's public key anymore. Free it,
207132b31808SJens Wiklander      * so that more RAM is available for upcoming expensive
207232b31808SJens Wiklander      * operations like ECDHE. */
207332b31808SJens Wiklander     mbedtls_pk_free(peer_pk);
207432b31808SJens Wiklander #endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
207532b31808SJens Wiklander 
207632b31808SJens Wiklander     return ret;
207732b31808SJens Wiklander }
207832b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
207932b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
208032b31808SJens Wiklander 
208132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
208232b31808SJens Wiklander static int ssl_parse_server_key_exchange(mbedtls_ssl_context *ssl)
208332b31808SJens Wiklander {
208432b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
208532b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
208632b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
208732b31808SJens Wiklander     unsigned char *p = NULL, *end = NULL;
208832b31808SJens Wiklander 
208932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse server key exchange"));
209032b31808SJens Wiklander 
209132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
209232b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) {
209332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse server key exchange"));
209432b31808SJens Wiklander         ssl->state++;
209532b31808SJens Wiklander         return 0;
209632b31808SJens Wiklander     }
209732b31808SJens Wiklander     ((void) p);
209832b31808SJens Wiklander     ((void) end);
209932b31808SJens Wiklander #endif
210032b31808SJens Wiklander 
210132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
210232b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
210332b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
210432b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA) {
210532b31808SJens Wiklander         if ((ret = ssl_get_ecdh_params_from_cert(ssl)) != 0) {
210632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "ssl_get_ecdh_params_from_cert", ret);
210732b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
210832b31808SJens Wiklander                 ssl,
210932b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
211032b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
211132b31808SJens Wiklander             return ret;
211232b31808SJens Wiklander         }
211332b31808SJens Wiklander 
211432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse server key exchange"));
211532b31808SJens Wiklander         ssl->state++;
211632b31808SJens Wiklander         return 0;
211732b31808SJens Wiklander     }
211832b31808SJens Wiklander     ((void) p);
211932b31808SJens Wiklander     ((void) end);
212032b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
212132b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
212232b31808SJens Wiklander 
212332b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
212432b31808SJens Wiklander     if (ssl->handshake->ecrs_enabled &&
212532b31808SJens Wiklander         ssl->handshake->ecrs_state == ssl_ecrs_ske_start_processing) {
212632b31808SJens Wiklander         goto start_processing;
212732b31808SJens Wiklander     }
212832b31808SJens Wiklander #endif
212932b31808SJens Wiklander 
213032b31808SJens Wiklander     if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
213132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
213232b31808SJens Wiklander         return ret;
213332b31808SJens Wiklander     }
213432b31808SJens Wiklander 
213532b31808SJens Wiklander     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
213632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message"));
213732b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
213832b31808SJens Wiklander             ssl,
213932b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
214032b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE);
214132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
214232b31808SJens Wiklander     }
214332b31808SJens Wiklander 
214432b31808SJens Wiklander     /*
214532b31808SJens Wiklander      * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server
214632b31808SJens Wiklander      * doesn't use a psk_identity_hint
214732b31808SJens Wiklander      */
214832b31808SJens Wiklander     if (ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE) {
214932b31808SJens Wiklander         if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
215032b31808SJens Wiklander             ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) {
215132b31808SJens Wiklander             /* Current message is probably either
215232b31808SJens Wiklander              * CertificateRequest or ServerHelloDone */
215332b31808SJens Wiklander             ssl->keep_current_message = 1;
215432b31808SJens Wiklander             goto exit;
215532b31808SJens Wiklander         }
215632b31808SJens Wiklander 
215732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1,
215832b31808SJens Wiklander                               ("server key exchange message must not be skipped"));
215932b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
216032b31808SJens Wiklander             ssl,
216132b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
216232b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE);
216332b31808SJens Wiklander 
216432b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
216532b31808SJens Wiklander     }
216632b31808SJens Wiklander 
216732b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
216832b31808SJens Wiklander     if (ssl->handshake->ecrs_enabled) {
216932b31808SJens Wiklander         ssl->handshake->ecrs_state = ssl_ecrs_ske_start_processing;
217032b31808SJens Wiklander     }
217132b31808SJens Wiklander 
217232b31808SJens Wiklander start_processing:
217332b31808SJens Wiklander #endif
217432b31808SJens Wiklander     p   = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl);
217532b31808SJens Wiklander     end = ssl->in_msg + ssl->in_hslen;
2176b0563631STom Van Eyck     MBEDTLS_SSL_DEBUG_BUF(3,   "server key exchange", p, (size_t) (end - p));
217732b31808SJens Wiklander 
217832b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
217932b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
218032b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
218132b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
218232b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) {
218332b31808SJens Wiklander         if (ssl_parse_server_psk_hint(ssl, &p, end) != 0) {
218432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message"));
218532b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
218632b31808SJens Wiklander                 ssl,
218732b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
218832b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
218932b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
219032b31808SJens Wiklander         }
219132b31808SJens Wiklander     } /* FALLTHROUGH */
219232b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
219332b31808SJens Wiklander 
219432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) ||                       \
219532b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
219632b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
219732b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) {
219832b31808SJens Wiklander         ; /* nothing more to do */
219932b31808SJens Wiklander     } else
220032b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED ||
220132b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
220232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
220332b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
220432b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ||
220532b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK) {
220632b31808SJens Wiklander         if (ssl_parse_server_dh_params(ssl, &p, end) != 0) {
220732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message"));
220832b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
220932b31808SJens Wiklander                 ssl,
221032b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
221132b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
221232b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
221332b31808SJens Wiklander         }
221432b31808SJens Wiklander     } else
221532b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
221632b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
221732b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||     \
221832b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||     \
221932b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
222032b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
222132b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
222232b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA) {
222332b31808SJens Wiklander         if (ssl_parse_server_ecdh_params(ssl, &p, end) != 0) {
222432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message"));
222532b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
222632b31808SJens Wiklander                 ssl,
222732b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
222832b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
222932b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
223032b31808SJens Wiklander         }
223132b31808SJens Wiklander     } else
223232b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
223332b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
223432b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
223532b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
223632b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
223732b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
223832b31808SJens Wiklander         /*
223932b31808SJens Wiklander          * The first 3 bytes are:
224032b31808SJens Wiklander          * [0] MBEDTLS_ECP_TLS_NAMED_CURVE
224132b31808SJens Wiklander          * [1, 2] elliptic curve's TLS ID
224232b31808SJens Wiklander          *
224332b31808SJens Wiklander          * However since we only support secp256r1 for now, we check only
224432b31808SJens Wiklander          * that TLS ID here
224532b31808SJens Wiklander          */
224632b31808SJens Wiklander         uint16_t read_tls_id = MBEDTLS_GET_UINT16_BE(p, 1);
224732b31808SJens Wiklander         uint16_t exp_tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(
224832b31808SJens Wiklander             MBEDTLS_ECP_DP_SECP256R1);
224932b31808SJens Wiklander 
225032b31808SJens Wiklander         if (exp_tls_id == 0) {
225132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
225232b31808SJens Wiklander         }
225332b31808SJens Wiklander 
225432b31808SJens Wiklander         if ((*p != MBEDTLS_ECP_TLS_NAMED_CURVE) ||
225532b31808SJens Wiklander             (read_tls_id != exp_tls_id)) {
225632b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
225732b31808SJens Wiklander         }
225832b31808SJens Wiklander 
225932b31808SJens Wiklander         p += 3;
226032b31808SJens Wiklander 
226132b31808SJens Wiklander         if ((ret = mbedtls_psa_ecjpake_read_round(
226232b31808SJens Wiklander                  &ssl->handshake->psa_pake_ctx, p, end - p,
226332b31808SJens Wiklander                  MBEDTLS_ECJPAKE_ROUND_TWO)) != 0) {
226432b31808SJens Wiklander             psa_destroy_key(ssl->handshake->psa_pake_password);
226532b31808SJens Wiklander             psa_pake_abort(&ssl->handshake->psa_pake_ctx);
226632b31808SJens Wiklander 
226732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round two", ret);
226832b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
226932b31808SJens Wiklander                 ssl,
227032b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
227132b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
227232b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
227332b31808SJens Wiklander         }
227432b31808SJens Wiklander #else
227532b31808SJens Wiklander         ret = mbedtls_ecjpake_read_round_two(&ssl->handshake->ecjpake_ctx,
227632b31808SJens Wiklander                                              p, end - p);
227732b31808SJens Wiklander         if (ret != 0) {
227832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_two", ret);
227932b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
228032b31808SJens Wiklander                 ssl,
228132b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
228232b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
228332b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
228432b31808SJens Wiklander         }
228532b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
228632b31808SJens Wiklander     } else
228732b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
228832b31808SJens Wiklander     {
228932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
229032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
229132b31808SJens Wiklander     }
229232b31808SJens Wiklander 
229332b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
229432b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_uses_server_signature(ciphersuite_info)) {
229532b31808SJens Wiklander         size_t sig_len, hashlen;
2296b0563631STom Van Eyck         unsigned char hash[MBEDTLS_MD_MAX_SIZE];
229732b31808SJens Wiklander 
229832b31808SJens Wiklander         mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
229932b31808SJens Wiklander         mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
230032b31808SJens Wiklander         unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl);
2301b0563631STom Van Eyck         size_t params_len = (size_t) (p - params);
230232b31808SJens Wiklander         void *rs_ctx = NULL;
230332b31808SJens Wiklander         uint16_t sig_alg;
230432b31808SJens Wiklander 
230532b31808SJens Wiklander         mbedtls_pk_context *peer_pk;
230632b31808SJens Wiklander 
230732b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
230832b31808SJens Wiklander         peer_pk = &ssl->handshake->peer_pubkey;
230932b31808SJens Wiklander #else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
231032b31808SJens Wiklander         if (ssl->session_negotiate->peer_cert == NULL) {
231132b31808SJens Wiklander             /* Should never happen */
231232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
231332b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
231432b31808SJens Wiklander         }
231532b31808SJens Wiklander         peer_pk = &ssl->session_negotiate->peer_cert->pk;
231632b31808SJens Wiklander #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
231732b31808SJens Wiklander 
231832b31808SJens Wiklander         /*
231932b31808SJens Wiklander          * Handle the digitally-signed structure
232032b31808SJens Wiklander          */
232132b31808SJens Wiklander         MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2);
232232b31808SJens Wiklander         sig_alg = MBEDTLS_GET_UINT16_BE(p, 0);
232332b31808SJens Wiklander         if (mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg(
232432b31808SJens Wiklander                 sig_alg, &pk_alg, &md_alg) != 0 &&
232532b31808SJens Wiklander             !mbedtls_ssl_sig_alg_is_offered(ssl, sig_alg) &&
232632b31808SJens Wiklander             !mbedtls_ssl_sig_alg_is_supported(ssl, sig_alg)) {
232732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1,
232832b31808SJens Wiklander                                   ("bad server key exchange message"));
232932b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
233032b31808SJens Wiklander                 ssl,
233132b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
233232b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
233332b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
233432b31808SJens Wiklander         }
233532b31808SJens Wiklander         p += 2;
233632b31808SJens Wiklander 
233732b31808SJens Wiklander         if (!mbedtls_pk_can_do(peer_pk, pk_alg)) {
233832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1,
233932b31808SJens Wiklander                                   ("bad server key exchange message"));
234032b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
234132b31808SJens Wiklander                 ssl,
234232b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
234332b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
234432b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
234532b31808SJens Wiklander         }
234632b31808SJens Wiklander 
234732b31808SJens Wiklander         /*
234832b31808SJens Wiklander          * Read signature
234932b31808SJens Wiklander          */
235032b31808SJens Wiklander 
235132b31808SJens Wiklander         if (p > end - 2) {
235232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message"));
235332b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
235432b31808SJens Wiklander                 ssl,
235532b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
235632b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
235732b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
235832b31808SJens Wiklander         }
2359b0563631STom Van Eyck         sig_len = MBEDTLS_GET_UINT16_BE(p, 0);
236032b31808SJens Wiklander         p += 2;
236132b31808SJens Wiklander 
236232b31808SJens Wiklander         if (p != end - sig_len) {
236332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message"));
236432b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
236532b31808SJens Wiklander                 ssl,
236632b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
236732b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
236832b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
236932b31808SJens Wiklander         }
237032b31808SJens Wiklander 
237132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "signature", p, sig_len);
237232b31808SJens Wiklander 
237332b31808SJens Wiklander         /*
237432b31808SJens Wiklander          * Compute the hash that has been signed
237532b31808SJens Wiklander          */
237632b31808SJens Wiklander         if (md_alg != MBEDTLS_MD_NONE) {
237732b31808SJens Wiklander             ret = mbedtls_ssl_get_key_exchange_md_tls1_2(ssl, hash, &hashlen,
237832b31808SJens Wiklander                                                          params, params_len,
237932b31808SJens Wiklander                                                          md_alg);
238032b31808SJens Wiklander             if (ret != 0) {
238132b31808SJens Wiklander                 return ret;
238232b31808SJens Wiklander             }
238332b31808SJens Wiklander         } else {
238432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
238532b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
238632b31808SJens Wiklander         }
238732b31808SJens Wiklander 
238832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "parameters hash", hash, hashlen);
238932b31808SJens Wiklander 
239032b31808SJens Wiklander         /*
239132b31808SJens Wiklander          * Verify signature
239232b31808SJens Wiklander          */
239332b31808SJens Wiklander         if (!mbedtls_pk_can_do(peer_pk, pk_alg)) {
239432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message"));
239532b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
239632b31808SJens Wiklander                 ssl,
239732b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
239832b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
239932b31808SJens Wiklander             return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
240032b31808SJens Wiklander         }
240132b31808SJens Wiklander 
240232b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
240332b31808SJens Wiklander         if (ssl->handshake->ecrs_enabled) {
240432b31808SJens Wiklander             rs_ctx = &ssl->handshake->ecrs_ctx.pk;
240532b31808SJens Wiklander         }
240632b31808SJens Wiklander #endif
240732b31808SJens Wiklander 
240832b31808SJens Wiklander #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
240932b31808SJens Wiklander         if (pk_alg == MBEDTLS_PK_RSASSA_PSS) {
241032b31808SJens Wiklander             mbedtls_pk_rsassa_pss_options rsassa_pss_options;
241132b31808SJens Wiklander             rsassa_pss_options.mgf1_hash_id = md_alg;
241232b31808SJens Wiklander             rsassa_pss_options.expected_salt_len =
2413b0563631STom Van Eyck                 mbedtls_md_get_size_from_type(md_alg);
241432b31808SJens Wiklander             if (rsassa_pss_options.expected_salt_len == 0) {
241532b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
241632b31808SJens Wiklander             }
241732b31808SJens Wiklander 
241832b31808SJens Wiklander             ret = mbedtls_pk_verify_ext(pk_alg, &rsassa_pss_options,
241932b31808SJens Wiklander                                         peer_pk,
242032b31808SJens Wiklander                                         md_alg, hash, hashlen,
242132b31808SJens Wiklander                                         p, sig_len);
242232b31808SJens Wiklander         } else
242332b31808SJens Wiklander #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
242432b31808SJens Wiklander         ret = mbedtls_pk_verify_restartable(peer_pk,
242532b31808SJens Wiklander                                             md_alg, hash, hashlen, p, sig_len, rs_ctx);
242632b31808SJens Wiklander 
242732b31808SJens Wiklander         if (ret != 0) {
242832b31808SJens Wiklander             int send_alert_msg = 1;
242932b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
243032b31808SJens Wiklander             send_alert_msg = (ret != MBEDTLS_ERR_ECP_IN_PROGRESS);
243132b31808SJens Wiklander #endif
243232b31808SJens Wiklander             if (send_alert_msg) {
243332b31808SJens Wiklander                 mbedtls_ssl_send_alert_message(
243432b31808SJens Wiklander                     ssl,
243532b31808SJens Wiklander                     MBEDTLS_SSL_ALERT_LEVEL_FATAL,
243632b31808SJens Wiklander                     MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR);
243732b31808SJens Wiklander             }
243832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_verify", ret);
243932b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
244032b31808SJens Wiklander             if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
244132b31808SJens Wiklander                 ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
244232b31808SJens Wiklander             }
244332b31808SJens Wiklander #endif
244432b31808SJens Wiklander             return ret;
244532b31808SJens Wiklander         }
244632b31808SJens Wiklander 
244732b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
244832b31808SJens Wiklander         /* We don't need the peer's public key anymore. Free it,
244932b31808SJens Wiklander          * so that more RAM is available for upcoming expensive
245032b31808SJens Wiklander          * operations like ECDHE. */
245132b31808SJens Wiklander         mbedtls_pk_free(peer_pk);
245232b31808SJens Wiklander #endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
245332b31808SJens Wiklander     }
245432b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
245532b31808SJens Wiklander 
245632b31808SJens Wiklander exit:
245732b31808SJens Wiklander     ssl->state++;
245832b31808SJens Wiklander 
245932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server key exchange"));
246032b31808SJens Wiklander 
246132b31808SJens Wiklander     return 0;
246232b31808SJens Wiklander }
246332b31808SJens Wiklander 
246432b31808SJens Wiklander #if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
246532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
246632b31808SJens Wiklander static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl)
246732b31808SJens Wiklander {
246832b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
246932b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
247032b31808SJens Wiklander 
247132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate request"));
247232b31808SJens Wiklander 
247332b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
247432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate request"));
247532b31808SJens Wiklander         ssl->state++;
247632b31808SJens Wiklander         return 0;
247732b31808SJens Wiklander     }
247832b31808SJens Wiklander 
247932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
248032b31808SJens Wiklander     return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
248132b31808SJens Wiklander }
248232b31808SJens Wiklander #else /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
248332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
248432b31808SJens Wiklander static int ssl_parse_certificate_request(mbedtls_ssl_context *ssl)
248532b31808SJens Wiklander {
248632b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
248732b31808SJens Wiklander     unsigned char *buf;
248832b31808SJens Wiklander     size_t n = 0;
248932b31808SJens Wiklander     size_t cert_type_len = 0, dn_len = 0;
249032b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
249132b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
249232b31808SJens Wiklander     size_t sig_alg_len;
249332b31808SJens Wiklander #if defined(MBEDTLS_DEBUG_C)
249432b31808SJens Wiklander     unsigned char *sig_alg;
249532b31808SJens Wiklander     unsigned char *dn;
249632b31808SJens Wiklander #endif
249732b31808SJens Wiklander 
249832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate request"));
249932b31808SJens Wiklander 
250032b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
250132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate request"));
250232b31808SJens Wiklander         ssl->state++;
250332b31808SJens Wiklander         return 0;
250432b31808SJens Wiklander     }
250532b31808SJens Wiklander 
250632b31808SJens Wiklander     if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
250732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
250832b31808SJens Wiklander         return ret;
250932b31808SJens Wiklander     }
251032b31808SJens Wiklander 
251132b31808SJens Wiklander     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
251232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message"));
251332b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
251432b31808SJens Wiklander             ssl,
251532b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
251632b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE);
251732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
251832b31808SJens Wiklander     }
251932b31808SJens Wiklander 
252032b31808SJens Wiklander     ssl->state++;
252132b31808SJens Wiklander     ssl->handshake->client_auth =
252232b31808SJens Wiklander         (ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST);
252332b31808SJens Wiklander 
252432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("got %s certificate request",
252532b31808SJens Wiklander                               ssl->handshake->client_auth ? "a" : "no"));
252632b31808SJens Wiklander 
252732b31808SJens Wiklander     if (ssl->handshake->client_auth == 0) {
252832b31808SJens Wiklander         /* Current message is probably the ServerHelloDone */
252932b31808SJens Wiklander         ssl->keep_current_message = 1;
253032b31808SJens Wiklander         goto exit;
253132b31808SJens Wiklander     }
253232b31808SJens Wiklander 
253332b31808SJens Wiklander     /*
253432b31808SJens Wiklander      *  struct {
253532b31808SJens Wiklander      *      ClientCertificateType certificate_types<1..2^8-1>;
253632b31808SJens Wiklander      *      SignatureAndHashAlgorithm
253732b31808SJens Wiklander      *        supported_signature_algorithms<2^16-1>; -- TLS 1.2 only
253832b31808SJens Wiklander      *      DistinguishedName certificate_authorities<0..2^16-1>;
253932b31808SJens Wiklander      *  } CertificateRequest;
254032b31808SJens Wiklander      *
254132b31808SJens Wiklander      *  Since we only support a single certificate on clients, let's just
254232b31808SJens Wiklander      *  ignore all the information that's supposed to help us pick a
254332b31808SJens Wiklander      *  certificate.
254432b31808SJens Wiklander      *
254532b31808SJens Wiklander      *  We could check that our certificate matches the request, and bail out
254632b31808SJens Wiklander      *  if it doesn't, but it's simpler to just send the certificate anyway,
254732b31808SJens Wiklander      *  and give the server the opportunity to decide if it should terminate
254832b31808SJens Wiklander      *  the connection when it doesn't like our certificate.
254932b31808SJens Wiklander      *
255032b31808SJens Wiklander      *  Same goes for the hash in TLS 1.2's signature_algorithms: at this
255132b31808SJens Wiklander      *  point we only have one hash available (see comments in
255232b31808SJens Wiklander      *  write_certificate_verify), so let's just use what we have.
255332b31808SJens Wiklander      *
255432b31808SJens Wiklander      *  However, we still minimally parse the message to check it is at least
255532b31808SJens Wiklander      *  superficially sane.
255632b31808SJens Wiklander      */
255732b31808SJens Wiklander     buf = ssl->in_msg;
255832b31808SJens Wiklander 
255932b31808SJens Wiklander     /* certificate_types */
256032b31808SJens Wiklander     if (ssl->in_hslen <= mbedtls_ssl_hs_hdr_len(ssl)) {
256132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message"));
256232b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
256332b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
256432b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
256532b31808SJens Wiklander     }
256632b31808SJens Wiklander     cert_type_len = buf[mbedtls_ssl_hs_hdr_len(ssl)];
256732b31808SJens Wiklander     n = cert_type_len;
256832b31808SJens Wiklander 
256932b31808SJens Wiklander     /*
257032b31808SJens Wiklander      * In the subsequent code there are two paths that read from buf:
257132b31808SJens Wiklander      *     * the length of the signature algorithms field (if minor version of
257232b31808SJens Wiklander      *       SSL is 3),
257332b31808SJens Wiklander      *     * distinguished name length otherwise.
257432b31808SJens Wiklander      * Both reach at most the index:
257532b31808SJens Wiklander      *    ...hdr_len + 2 + n,
257632b31808SJens Wiklander      * therefore the buffer length at this point must be greater than that
257732b31808SJens Wiklander      * regardless of the actual code path.
257832b31808SJens Wiklander      */
257932b31808SJens Wiklander     if (ssl->in_hslen <= mbedtls_ssl_hs_hdr_len(ssl) + 2 + n) {
258032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message"));
258132b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
258232b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
258332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
258432b31808SJens Wiklander     }
258532b31808SJens Wiklander 
258632b31808SJens Wiklander     /* supported_signature_algorithms */
2587b0563631STom Van Eyck     sig_alg_len = MBEDTLS_GET_UINT16_BE(buf, mbedtls_ssl_hs_hdr_len(ssl) + 1 + n);
258832b31808SJens Wiklander 
258932b31808SJens Wiklander     /*
259032b31808SJens Wiklander      * The furthest access in buf is in the loop few lines below:
259132b31808SJens Wiklander      *     sig_alg[i + 1],
259232b31808SJens Wiklander      * where:
259332b31808SJens Wiklander      *     sig_alg = buf + ...hdr_len + 3 + n,
259432b31808SJens Wiklander      *     max(i) = sig_alg_len - 1.
259532b31808SJens Wiklander      * Therefore the furthest access is:
259632b31808SJens Wiklander      *     buf[...hdr_len + 3 + n + sig_alg_len - 1 + 1],
259732b31808SJens Wiklander      * which reduces to:
259832b31808SJens Wiklander      *     buf[...hdr_len + 3 + n + sig_alg_len],
259932b31808SJens Wiklander      * which is one less than we need the buf to be.
260032b31808SJens Wiklander      */
260132b31808SJens Wiklander     if (ssl->in_hslen <= mbedtls_ssl_hs_hdr_len(ssl) + 3 + n + sig_alg_len) {
260232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message"));
260332b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
260432b31808SJens Wiklander             ssl,
260532b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
260632b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
260732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
260832b31808SJens Wiklander     }
260932b31808SJens Wiklander 
261032b31808SJens Wiklander #if defined(MBEDTLS_DEBUG_C)
261132b31808SJens Wiklander     sig_alg = buf + mbedtls_ssl_hs_hdr_len(ssl) + 3 + n;
261232b31808SJens Wiklander     for (size_t i = 0; i < sig_alg_len; i += 2) {
261332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3,
261432b31808SJens Wiklander                               ("Supported Signature Algorithm found: %02x %02x",
261532b31808SJens Wiklander                                sig_alg[i], sig_alg[i + 1]));
261632b31808SJens Wiklander     }
261732b31808SJens Wiklander #endif
261832b31808SJens Wiklander 
261932b31808SJens Wiklander     n += 2 + sig_alg_len;
262032b31808SJens Wiklander 
262132b31808SJens Wiklander     /* certificate_authorities */
2622b0563631STom Van Eyck     dn_len = MBEDTLS_GET_UINT16_BE(buf, mbedtls_ssl_hs_hdr_len(ssl) + 1 + n);
262332b31808SJens Wiklander 
262432b31808SJens Wiklander     n += dn_len;
262532b31808SJens Wiklander     if (ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl) + 3 + n) {
262632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message"));
262732b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
262832b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
262932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
263032b31808SJens Wiklander     }
263132b31808SJens Wiklander 
263232b31808SJens Wiklander #if defined(MBEDTLS_DEBUG_C)
263332b31808SJens Wiklander     dn = buf + mbedtls_ssl_hs_hdr_len(ssl) + 3 + n - dn_len;
263432b31808SJens Wiklander     for (size_t i = 0, dni_len = 0; i < dn_len; i += 2 + dni_len) {
263532b31808SJens Wiklander         unsigned char *p = dn + i + 2;
263632b31808SJens Wiklander         mbedtls_x509_name name;
263732b31808SJens Wiklander         size_t asn1_len;
263832b31808SJens Wiklander         char s[MBEDTLS_X509_MAX_DN_NAME_SIZE];
263932b31808SJens Wiklander         memset(&name, 0, sizeof(name));
264032b31808SJens Wiklander         dni_len = MBEDTLS_GET_UINT16_BE(dn + i, 0);
264132b31808SJens Wiklander         if (dni_len > dn_len - i - 2 ||
264232b31808SJens Wiklander             mbedtls_asn1_get_tag(&p, p + dni_len, &asn1_len,
264332b31808SJens Wiklander                                  MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0 ||
264432b31808SJens Wiklander             mbedtls_x509_get_name(&p, p + asn1_len, &name) != 0) {
264532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message"));
264632b31808SJens Wiklander             mbedtls_ssl_send_alert_message(
264732b31808SJens Wiklander                 ssl,
264832b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_LEVEL_FATAL,
264932b31808SJens Wiklander                 MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
265032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
265132b31808SJens Wiklander         }
265232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3,
265332b31808SJens Wiklander                               ("DN hint: %.*s",
265432b31808SJens Wiklander                                mbedtls_x509_dn_gets(s, sizeof(s), &name), s));
265532b31808SJens Wiklander         mbedtls_asn1_free_named_data_list_shallow(name.next);
265632b31808SJens Wiklander     }
265732b31808SJens Wiklander #endif
265832b31808SJens Wiklander 
265932b31808SJens Wiklander exit:
266032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate request"));
266132b31808SJens Wiklander 
266232b31808SJens Wiklander     return 0;
266332b31808SJens Wiklander }
266432b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
266532b31808SJens Wiklander 
266632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
266732b31808SJens Wiklander static int ssl_parse_server_hello_done(mbedtls_ssl_context *ssl)
266832b31808SJens Wiklander {
266932b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
267032b31808SJens Wiklander 
267132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse server hello done"));
267232b31808SJens Wiklander 
267332b31808SJens Wiklander     if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
267432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
267532b31808SJens Wiklander         return ret;
267632b31808SJens Wiklander     }
267732b31808SJens Wiklander 
267832b31808SJens Wiklander     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
267932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello done message"));
268032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
268132b31808SJens Wiklander     }
268232b31808SJens Wiklander 
268332b31808SJens Wiklander     if (ssl->in_hslen  != mbedtls_ssl_hs_hdr_len(ssl) ||
268432b31808SJens Wiklander         ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE) {
268532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello done message"));
268632b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
268732b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
268832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
268932b31808SJens Wiklander     }
269032b31808SJens Wiklander 
269132b31808SJens Wiklander     ssl->state++;
269232b31808SJens Wiklander 
269332b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
269432b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
269532b31808SJens Wiklander         mbedtls_ssl_recv_flight_completed(ssl);
269632b31808SJens Wiklander     }
269732b31808SJens Wiklander #endif
269832b31808SJens Wiklander 
269932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server hello done"));
270032b31808SJens Wiklander 
270132b31808SJens Wiklander     return 0;
270232b31808SJens Wiklander }
270332b31808SJens Wiklander 
270432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
270532b31808SJens Wiklander static int ssl_write_client_key_exchange(mbedtls_ssl_context *ssl)
270632b31808SJens Wiklander {
270732b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
270832b31808SJens Wiklander 
270932b31808SJens Wiklander     size_t header_len;
271032b31808SJens Wiklander     size_t content_len;
271132b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
271232b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
271332b31808SJens Wiklander 
271432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write client key exchange"));
271532b31808SJens Wiklander 
271632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
271732b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA) {
271832b31808SJens Wiklander         /*
271932b31808SJens Wiklander          * DHM key exchange -- send G^X mod P
272032b31808SJens Wiklander          */
272132b31808SJens Wiklander         content_len = mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx);
272232b31808SJens Wiklander 
272332b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(content_len, ssl->out_msg, 4);
272432b31808SJens Wiklander         header_len = 6;
272532b31808SJens Wiklander 
272632b31808SJens Wiklander         ret = mbedtls_dhm_make_public(&ssl->handshake->dhm_ctx,
272732b31808SJens Wiklander                                       (int) mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx),
272832b31808SJens Wiklander                                       &ssl->out_msg[header_len], content_len,
272932b31808SJens Wiklander                                       ssl->conf->f_rng, ssl->conf->p_rng);
273032b31808SJens Wiklander         if (ret != 0) {
273132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_make_public", ret);
273232b31808SJens Wiklander             return ret;
273332b31808SJens Wiklander         }
273432b31808SJens Wiklander 
273532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: X ", &ssl->handshake->dhm_ctx.X);
273632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GX", &ssl->handshake->dhm_ctx.GX);
273732b31808SJens Wiklander 
273832b31808SJens Wiklander         if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx,
273932b31808SJens Wiklander                                            ssl->handshake->premaster,
274032b31808SJens Wiklander                                            MBEDTLS_PREMASTER_SIZE,
274132b31808SJens Wiklander                                            &ssl->handshake->pmslen,
274232b31808SJens Wiklander                                            ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
274332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret);
274432b31808SJens Wiklander             return ret;
274532b31808SJens Wiklander         }
274632b31808SJens Wiklander 
274732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K);
274832b31808SJens Wiklander     } else
274932b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
275032b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
275132b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
275232b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
275332b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
275432b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
275532b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
275632b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
275732b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA) {
275832b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
275932b31808SJens Wiklander         psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
276032b31808SJens Wiklander         psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED;
276132b31808SJens Wiklander         psa_key_attributes_t key_attributes;
276232b31808SJens Wiklander 
276332b31808SJens Wiklander         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
276432b31808SJens Wiklander 
276532b31808SJens Wiklander         header_len = 4;
276632b31808SJens Wiklander 
276732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("Perform PSA-based ECDH computation."));
276832b31808SJens Wiklander 
276932b31808SJens Wiklander         /*
277032b31808SJens Wiklander          * Generate EC private key for ECDHE exchange.
277132b31808SJens Wiklander          */
277232b31808SJens Wiklander 
277332b31808SJens Wiklander         /* The master secret is obtained from the shared ECDH secret by
277432b31808SJens Wiklander          * applying the TLS 1.2 PRF with a specific salt and label. While
277532b31808SJens Wiklander          * the PSA Crypto API encourages combining key agreement schemes
277632b31808SJens Wiklander          * such as ECDH with fixed KDFs such as TLS 1.2 PRF, it does not
277732b31808SJens Wiklander          * yet support the provisioning of salt + label to the KDF.
277832b31808SJens Wiklander          * For the time being, we therefore need to split the computation
277932b31808SJens Wiklander          * of the ECDH secret and the application of the TLS 1.2 PRF. */
278032b31808SJens Wiklander         key_attributes = psa_key_attributes_init();
278132b31808SJens Wiklander         psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
278232b31808SJens Wiklander         psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
2783b0563631STom Van Eyck         psa_set_key_type(&key_attributes, handshake->xxdh_psa_type);
2784b0563631STom Van Eyck         psa_set_key_bits(&key_attributes, handshake->xxdh_psa_bits);
278532b31808SJens Wiklander 
278632b31808SJens Wiklander         /* Generate ECDH private key. */
278732b31808SJens Wiklander         status = psa_generate_key(&key_attributes,
2788b0563631STom Van Eyck                                   &handshake->xxdh_psa_privkey);
278932b31808SJens Wiklander         if (status != PSA_SUCCESS) {
279032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
279132b31808SJens Wiklander         }
279232b31808SJens Wiklander 
279332b31808SJens Wiklander         /* Export the public part of the ECDH private key from PSA.
279432b31808SJens Wiklander          * The export format is an ECPoint structure as expected by TLS,
279532b31808SJens Wiklander          * but we just need to add a length byte before that. */
279632b31808SJens Wiklander         unsigned char *own_pubkey = ssl->out_msg + header_len + 1;
279732b31808SJens Wiklander         unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
279832b31808SJens Wiklander         size_t own_pubkey_max_len = (size_t) (end - own_pubkey);
279932b31808SJens Wiklander         size_t own_pubkey_len;
280032b31808SJens Wiklander 
2801b0563631STom Van Eyck         status = psa_export_public_key(handshake->xxdh_psa_privkey,
280232b31808SJens Wiklander                                        own_pubkey, own_pubkey_max_len,
280332b31808SJens Wiklander                                        &own_pubkey_len);
280432b31808SJens Wiklander         if (status != PSA_SUCCESS) {
2805b0563631STom Van Eyck             psa_destroy_key(handshake->xxdh_psa_privkey);
2806b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
280732b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
280832b31808SJens Wiklander         }
280932b31808SJens Wiklander 
281032b31808SJens Wiklander         ssl->out_msg[header_len] = (unsigned char) own_pubkey_len;
281132b31808SJens Wiklander         content_len = own_pubkey_len + 1;
281232b31808SJens Wiklander 
281332b31808SJens Wiklander         /* The ECDH secret is the premaster secret used for key derivation. */
281432b31808SJens Wiklander 
281532b31808SJens Wiklander         /* Compute ECDH shared secret. */
281632b31808SJens Wiklander         status = psa_raw_key_agreement(PSA_ALG_ECDH,
2817b0563631STom Van Eyck                                        handshake->xxdh_psa_privkey,
2818b0563631STom Van Eyck                                        handshake->xxdh_psa_peerkey,
2819b0563631STom Van Eyck                                        handshake->xxdh_psa_peerkey_len,
282032b31808SJens Wiklander                                        ssl->handshake->premaster,
282132b31808SJens Wiklander                                        sizeof(ssl->handshake->premaster),
282232b31808SJens Wiklander                                        &ssl->handshake->pmslen);
282332b31808SJens Wiklander 
2824b0563631STom Van Eyck         destruction_status = psa_destroy_key(handshake->xxdh_psa_privkey);
2825b0563631STom Van Eyck         handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
282632b31808SJens Wiklander 
282732b31808SJens Wiklander         if (status != PSA_SUCCESS || destruction_status != PSA_SUCCESS) {
282832b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
282932b31808SJens Wiklander         }
283032b31808SJens Wiklander #else
283132b31808SJens Wiklander         /*
283232b31808SJens Wiklander          * ECDH key exchange -- send client public value
283332b31808SJens Wiklander          */
283432b31808SJens Wiklander         header_len = 4;
283532b31808SJens Wiklander 
283632b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
283732b31808SJens Wiklander         if (ssl->handshake->ecrs_enabled) {
283832b31808SJens Wiklander             if (ssl->handshake->ecrs_state == ssl_ecrs_cke_ecdh_calc_secret) {
283932b31808SJens Wiklander                 goto ecdh_calc_secret;
284032b31808SJens Wiklander             }
284132b31808SJens Wiklander 
284232b31808SJens Wiklander             mbedtls_ecdh_enable_restart(&ssl->handshake->ecdh_ctx);
284332b31808SJens Wiklander         }
284432b31808SJens Wiklander #endif
284532b31808SJens Wiklander 
284632b31808SJens Wiklander         ret = mbedtls_ecdh_make_public(&ssl->handshake->ecdh_ctx,
284732b31808SJens Wiklander                                        &content_len,
284832b31808SJens Wiklander                                        &ssl->out_msg[header_len], 1000,
284932b31808SJens Wiklander                                        ssl->conf->f_rng, ssl->conf->p_rng);
285032b31808SJens Wiklander         if (ret != 0) {
285132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_make_public", ret);
285232b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
285332b31808SJens Wiklander             if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
285432b31808SJens Wiklander                 ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
285532b31808SJens Wiklander             }
285632b31808SJens Wiklander #endif
285732b31808SJens Wiklander             return ret;
285832b31808SJens Wiklander         }
285932b31808SJens Wiklander 
286032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
286132b31808SJens Wiklander                                MBEDTLS_DEBUG_ECDH_Q);
286232b31808SJens Wiklander 
286332b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
286432b31808SJens Wiklander         if (ssl->handshake->ecrs_enabled) {
286532b31808SJens Wiklander             ssl->handshake->ecrs_n = content_len;
286632b31808SJens Wiklander             ssl->handshake->ecrs_state = ssl_ecrs_cke_ecdh_calc_secret;
286732b31808SJens Wiklander         }
286832b31808SJens Wiklander 
286932b31808SJens Wiklander ecdh_calc_secret:
287032b31808SJens Wiklander         if (ssl->handshake->ecrs_enabled) {
287132b31808SJens Wiklander             content_len = ssl->handshake->ecrs_n;
287232b31808SJens Wiklander         }
287332b31808SJens Wiklander #endif
287432b31808SJens Wiklander         if ((ret = mbedtls_ecdh_calc_secret(&ssl->handshake->ecdh_ctx,
287532b31808SJens Wiklander                                             &ssl->handshake->pmslen,
287632b31808SJens Wiklander                                             ssl->handshake->premaster,
287732b31808SJens Wiklander                                             MBEDTLS_MPI_MAX_SIZE,
287832b31808SJens Wiklander                                             ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
287932b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_calc_secret", ret);
288032b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
288132b31808SJens Wiklander             if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
288232b31808SJens Wiklander                 ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
288332b31808SJens Wiklander             }
288432b31808SJens Wiklander #endif
288532b31808SJens Wiklander             return ret;
288632b31808SJens Wiklander         }
288732b31808SJens Wiklander 
288832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
288932b31808SJens Wiklander                                MBEDTLS_DEBUG_ECDH_Z);
289032b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
289132b31808SJens Wiklander     } else
289232b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
289332b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
289432b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
289532b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
289632b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO) &&                           \
289732b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
289832b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) {
289932b31808SJens Wiklander         psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
290032b31808SJens Wiklander         psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED;
290132b31808SJens Wiklander         psa_key_attributes_t key_attributes;
290232b31808SJens Wiklander 
290332b31808SJens Wiklander         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
290432b31808SJens Wiklander 
290532b31808SJens Wiklander         /*
290632b31808SJens Wiklander          * opaque psk_identity<0..2^16-1>;
290732b31808SJens Wiklander          */
290832b31808SJens Wiklander         if (mbedtls_ssl_conf_has_static_psk(ssl->conf) == 0) {
290932b31808SJens Wiklander             /* We don't offer PSK suites if we don't have a PSK,
291032b31808SJens Wiklander              * and we check that the server's choice is among the
291132b31808SJens Wiklander              * ciphersuites we offered, so this should never happen. */
291232b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
291332b31808SJens Wiklander         }
291432b31808SJens Wiklander 
291532b31808SJens Wiklander         /* uint16 to store content length */
291632b31808SJens Wiklander         const size_t content_len_size = 2;
291732b31808SJens Wiklander 
291832b31808SJens Wiklander         header_len = 4;
291932b31808SJens Wiklander 
292032b31808SJens Wiklander         if (header_len + content_len_size + ssl->conf->psk_identity_len
292132b31808SJens Wiklander             > MBEDTLS_SSL_OUT_CONTENT_LEN) {
292232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1,
292332b31808SJens Wiklander                                   ("psk identity too long or SSL buffer too short"));
292432b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
292532b31808SJens Wiklander         }
292632b31808SJens Wiklander 
292732b31808SJens Wiklander         unsigned char *p = ssl->out_msg + header_len;
292832b31808SJens Wiklander 
292932b31808SJens Wiklander         *p++ = MBEDTLS_BYTE_1(ssl->conf->psk_identity_len);
293032b31808SJens Wiklander         *p++ = MBEDTLS_BYTE_0(ssl->conf->psk_identity_len);
293132b31808SJens Wiklander         header_len += content_len_size;
293232b31808SJens Wiklander 
293332b31808SJens Wiklander         memcpy(p, ssl->conf->psk_identity,
293432b31808SJens Wiklander                ssl->conf->psk_identity_len);
293532b31808SJens Wiklander         p += ssl->conf->psk_identity_len;
293632b31808SJens Wiklander 
293732b31808SJens Wiklander         header_len += ssl->conf->psk_identity_len;
293832b31808SJens Wiklander 
293932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("Perform PSA-based ECDH computation."));
294032b31808SJens Wiklander 
294132b31808SJens Wiklander         /*
294232b31808SJens Wiklander          * Generate EC private key for ECDHE exchange.
294332b31808SJens Wiklander          */
294432b31808SJens Wiklander 
294532b31808SJens Wiklander         /* The master secret is obtained from the shared ECDH secret by
294632b31808SJens Wiklander          * applying the TLS 1.2 PRF with a specific salt and label. While
294732b31808SJens Wiklander          * the PSA Crypto API encourages combining key agreement schemes
294832b31808SJens Wiklander          * such as ECDH with fixed KDFs such as TLS 1.2 PRF, it does not
294932b31808SJens Wiklander          * yet support the provisioning of salt + label to the KDF.
295032b31808SJens Wiklander          * For the time being, we therefore need to split the computation
295132b31808SJens Wiklander          * of the ECDH secret and the application of the TLS 1.2 PRF. */
295232b31808SJens Wiklander         key_attributes = psa_key_attributes_init();
295332b31808SJens Wiklander         psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
295432b31808SJens Wiklander         psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
2955b0563631STom Van Eyck         psa_set_key_type(&key_attributes, handshake->xxdh_psa_type);
2956b0563631STom Van Eyck         psa_set_key_bits(&key_attributes, handshake->xxdh_psa_bits);
295732b31808SJens Wiklander 
295832b31808SJens Wiklander         /* Generate ECDH private key. */
295932b31808SJens Wiklander         status = psa_generate_key(&key_attributes,
2960b0563631STom Van Eyck                                   &handshake->xxdh_psa_privkey);
296132b31808SJens Wiklander         if (status != PSA_SUCCESS) {
296232b31808SJens Wiklander             return PSA_TO_MBEDTLS_ERR(status);
296332b31808SJens Wiklander         }
296432b31808SJens Wiklander 
296532b31808SJens Wiklander         /* Export the public part of the ECDH private key from PSA.
296632b31808SJens Wiklander          * The export format is an ECPoint structure as expected by TLS,
296732b31808SJens Wiklander          * but we just need to add a length byte before that. */
296832b31808SJens Wiklander         unsigned char *own_pubkey = p + 1;
296932b31808SJens Wiklander         unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
297032b31808SJens Wiklander         size_t own_pubkey_max_len = (size_t) (end - own_pubkey);
297132b31808SJens Wiklander         size_t own_pubkey_len = 0;
297232b31808SJens Wiklander 
2973b0563631STom Van Eyck         status = psa_export_public_key(handshake->xxdh_psa_privkey,
297432b31808SJens Wiklander                                        own_pubkey, own_pubkey_max_len,
297532b31808SJens Wiklander                                        &own_pubkey_len);
297632b31808SJens Wiklander         if (status != PSA_SUCCESS) {
2977b0563631STom Van Eyck             psa_destroy_key(handshake->xxdh_psa_privkey);
2978b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
297932b31808SJens Wiklander             return PSA_TO_MBEDTLS_ERR(status);
298032b31808SJens Wiklander         }
298132b31808SJens Wiklander 
298232b31808SJens Wiklander         *p = (unsigned char) own_pubkey_len;
298332b31808SJens Wiklander         content_len = own_pubkey_len + 1;
298432b31808SJens Wiklander 
298532b31808SJens Wiklander         /* As RFC 5489 section 2, the premaster secret is formed as follows:
298632b31808SJens Wiklander          * - a uint16 containing the length (in octets) of the ECDH computation
298732b31808SJens Wiklander          * - the octet string produced by the ECDH computation
298832b31808SJens Wiklander          * - a uint16 containing the length (in octets) of the PSK
298932b31808SJens Wiklander          * - the PSK itself
299032b31808SJens Wiklander          */
299132b31808SJens Wiklander         unsigned char *pms = ssl->handshake->premaster;
299232b31808SJens Wiklander         const unsigned char * const pms_end = pms +
299332b31808SJens Wiklander                                               sizeof(ssl->handshake->premaster);
299432b31808SJens Wiklander         /* uint16 to store length (in octets) of the ECDH computation */
299532b31808SJens Wiklander         const size_t zlen_size = 2;
299632b31808SJens Wiklander         size_t zlen = 0;
299732b31808SJens Wiklander 
299832b31808SJens Wiklander         /* Perform ECDH computation after the uint16 reserved for the length */
299932b31808SJens Wiklander         status = psa_raw_key_agreement(PSA_ALG_ECDH,
3000b0563631STom Van Eyck                                        handshake->xxdh_psa_privkey,
3001b0563631STom Van Eyck                                        handshake->xxdh_psa_peerkey,
3002b0563631STom Van Eyck                                        handshake->xxdh_psa_peerkey_len,
300332b31808SJens Wiklander                                        pms + zlen_size,
300432b31808SJens Wiklander                                        pms_end - (pms + zlen_size),
300532b31808SJens Wiklander                                        &zlen);
300632b31808SJens Wiklander 
3007b0563631STom Van Eyck         destruction_status = psa_destroy_key(handshake->xxdh_psa_privkey);
3008b0563631STom Van Eyck         handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
300932b31808SJens Wiklander 
301032b31808SJens Wiklander         if (status != PSA_SUCCESS) {
301132b31808SJens Wiklander             return PSA_TO_MBEDTLS_ERR(status);
301232b31808SJens Wiklander         } else if (destruction_status != PSA_SUCCESS) {
301332b31808SJens Wiklander             return PSA_TO_MBEDTLS_ERR(destruction_status);
301432b31808SJens Wiklander         }
301532b31808SJens Wiklander 
301632b31808SJens Wiklander         /* Write the ECDH computation length before the ECDH computation */
301732b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(zlen, pms, 0);
301832b31808SJens Wiklander         pms += zlen_size + zlen;
301932b31808SJens Wiklander     } else
302032b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO &&
302132b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
302232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
302332b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_uses_psk(ciphersuite_info)) {
302432b31808SJens Wiklander         /*
302532b31808SJens Wiklander          * opaque psk_identity<0..2^16-1>;
302632b31808SJens Wiklander          */
302732b31808SJens Wiklander         if (mbedtls_ssl_conf_has_static_psk(ssl->conf) == 0) {
302832b31808SJens Wiklander             /* We don't offer PSK suites if we don't have a PSK,
302932b31808SJens Wiklander              * and we check that the server's choice is among the
303032b31808SJens Wiklander              * ciphersuites we offered, so this should never happen. */
303132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
303232b31808SJens Wiklander         }
303332b31808SJens Wiklander 
303432b31808SJens Wiklander         header_len = 4;
303532b31808SJens Wiklander         content_len = ssl->conf->psk_identity_len;
303632b31808SJens Wiklander 
303732b31808SJens Wiklander         if (header_len + 2 + content_len > MBEDTLS_SSL_OUT_CONTENT_LEN) {
303832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1,
303932b31808SJens Wiklander                                   ("psk identity too long or SSL buffer too short"));
304032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
304132b31808SJens Wiklander         }
304232b31808SJens Wiklander 
304332b31808SJens Wiklander         ssl->out_msg[header_len++] = MBEDTLS_BYTE_1(content_len);
304432b31808SJens Wiklander         ssl->out_msg[header_len++] = MBEDTLS_BYTE_0(content_len);
304532b31808SJens Wiklander 
304632b31808SJens Wiklander         memcpy(ssl->out_msg + header_len,
304732b31808SJens Wiklander                ssl->conf->psk_identity,
304832b31808SJens Wiklander                ssl->conf->psk_identity_len);
304932b31808SJens Wiklander         header_len += ssl->conf->psk_identity_len;
305032b31808SJens Wiklander 
305132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
305232b31808SJens Wiklander         if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK) {
305332b31808SJens Wiklander             content_len = 0;
305432b31808SJens Wiklander         } else
305532b31808SJens Wiklander #endif
305632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
305732b31808SJens Wiklander         if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) {
305832b31808SJens Wiklander             if ((ret = ssl_write_encrypted_pms(ssl, header_len,
305932b31808SJens Wiklander                                                &content_len, 2)) != 0) {
306032b31808SJens Wiklander                 return ret;
306132b31808SJens Wiklander             }
306232b31808SJens Wiklander         } else
306332b31808SJens Wiklander #endif
306432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
306532b31808SJens Wiklander         if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK) {
306632b31808SJens Wiklander             /*
306732b31808SJens Wiklander              * ClientDiffieHellmanPublic public (DHM send G^X mod P)
306832b31808SJens Wiklander              */
306932b31808SJens Wiklander             content_len = mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx);
307032b31808SJens Wiklander 
307132b31808SJens Wiklander             if (header_len + 2 + content_len >
307232b31808SJens Wiklander                 MBEDTLS_SSL_OUT_CONTENT_LEN) {
307332b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1,
307432b31808SJens Wiklander                                       ("psk identity or DHM size too long or SSL buffer too short"));
307532b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
307632b31808SJens Wiklander             }
307732b31808SJens Wiklander 
307832b31808SJens Wiklander             ssl->out_msg[header_len++] = MBEDTLS_BYTE_1(content_len);
307932b31808SJens Wiklander             ssl->out_msg[header_len++] = MBEDTLS_BYTE_0(content_len);
308032b31808SJens Wiklander 
308132b31808SJens Wiklander             ret = mbedtls_dhm_make_public(&ssl->handshake->dhm_ctx,
308232b31808SJens Wiklander                                           (int) mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx),
308332b31808SJens Wiklander                                           &ssl->out_msg[header_len], content_len,
308432b31808SJens Wiklander                                           ssl->conf->f_rng, ssl->conf->p_rng);
308532b31808SJens Wiklander             if (ret != 0) {
308632b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_make_public", ret);
308732b31808SJens Wiklander                 return ret;
308832b31808SJens Wiklander             }
308932b31808SJens Wiklander 
309032b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
309132b31808SJens Wiklander             unsigned char *pms = ssl->handshake->premaster;
309232b31808SJens Wiklander             unsigned char *pms_end = pms + sizeof(ssl->handshake->premaster);
309332b31808SJens Wiklander             size_t pms_len;
309432b31808SJens Wiklander 
309532b31808SJens Wiklander             /* Write length only when we know the actual value */
309632b31808SJens Wiklander             if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx,
309732b31808SJens Wiklander                                                pms + 2, pms_end - (pms + 2), &pms_len,
309832b31808SJens Wiklander                                                ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
309932b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret);
310032b31808SJens Wiklander                 return ret;
310132b31808SJens Wiklander             }
310232b31808SJens Wiklander             MBEDTLS_PUT_UINT16_BE(pms_len, pms, 0);
310332b31808SJens Wiklander             pms += 2 + pms_len;
310432b31808SJens Wiklander 
310532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K);
310632b31808SJens Wiklander #endif
310732b31808SJens Wiklander         } else
310832b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
310932b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO) &&                             \
311032b31808SJens Wiklander         defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
311132b31808SJens Wiklander         if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) {
311232b31808SJens Wiklander             /*
311332b31808SJens Wiklander              * ClientECDiffieHellmanPublic public;
311432b31808SJens Wiklander              */
311532b31808SJens Wiklander             ret = mbedtls_ecdh_make_public(&ssl->handshake->ecdh_ctx,
311632b31808SJens Wiklander                                            &content_len,
311732b31808SJens Wiklander                                            &ssl->out_msg[header_len],
311832b31808SJens Wiklander                                            MBEDTLS_SSL_OUT_CONTENT_LEN - header_len,
311932b31808SJens Wiklander                                            ssl->conf->f_rng, ssl->conf->p_rng);
312032b31808SJens Wiklander             if (ret != 0) {
312132b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_make_public", ret);
312232b31808SJens Wiklander                 return ret;
312332b31808SJens Wiklander             }
312432b31808SJens Wiklander 
312532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
312632b31808SJens Wiklander                                    MBEDTLS_DEBUG_ECDH_Q);
312732b31808SJens Wiklander         } else
312832b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
312932b31808SJens Wiklander         {
313032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
313132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
313232b31808SJens Wiklander         }
313332b31808SJens Wiklander 
313432b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO)
313532b31808SJens Wiklander         if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
3136b0563631STom Van Eyck                                                     (mbedtls_key_exchange_type_t) ciphersuite_info->
3137b0563631STom Van Eyck                                                     key_exchange)) != 0) {
313832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1,
313932b31808SJens Wiklander                                   "mbedtls_ssl_psk_derive_premaster", ret);
314032b31808SJens Wiklander             return ret;
314132b31808SJens Wiklander         }
314232b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO */
314332b31808SJens Wiklander     } else
314432b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
314532b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
314632b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) {
314732b31808SJens Wiklander         header_len = 4;
314832b31808SJens Wiklander         if ((ret = ssl_write_encrypted_pms(ssl, header_len,
314932b31808SJens Wiklander                                            &content_len, 0)) != 0) {
315032b31808SJens Wiklander             return ret;
315132b31808SJens Wiklander         }
315232b31808SJens Wiklander     } else
315332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
315432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
315532b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
315632b31808SJens Wiklander         header_len = 4;
315732b31808SJens Wiklander 
315832b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
315932b31808SJens Wiklander         unsigned char *out_p = ssl->out_msg + header_len;
316032b31808SJens Wiklander         unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN -
316132b31808SJens Wiklander                                header_len;
316232b31808SJens Wiklander         ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx,
316332b31808SJens Wiklander                                               out_p, end_p - out_p, &content_len,
316432b31808SJens Wiklander                                               MBEDTLS_ECJPAKE_ROUND_TWO);
316532b31808SJens Wiklander         if (ret != 0) {
316632b31808SJens Wiklander             psa_destroy_key(ssl->handshake->psa_pake_password);
316732b31808SJens Wiklander             psa_pake_abort(&ssl->handshake->psa_pake_ctx);
316832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret);
316932b31808SJens Wiklander             return ret;
317032b31808SJens Wiklander         }
317132b31808SJens Wiklander #else
317232b31808SJens Wiklander         ret = mbedtls_ecjpake_write_round_two(&ssl->handshake->ecjpake_ctx,
317332b31808SJens Wiklander                                               ssl->out_msg + header_len,
317432b31808SJens Wiklander                                               MBEDTLS_SSL_OUT_CONTENT_LEN - header_len,
317532b31808SJens Wiklander                                               &content_len,
317632b31808SJens Wiklander                                               ssl->conf->f_rng, ssl->conf->p_rng);
317732b31808SJens Wiklander         if (ret != 0) {
317832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_two", ret);
317932b31808SJens Wiklander             return ret;
318032b31808SJens Wiklander         }
318132b31808SJens Wiklander 
318232b31808SJens Wiklander         ret = mbedtls_ecjpake_derive_secret(&ssl->handshake->ecjpake_ctx,
318332b31808SJens Wiklander                                             ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
318432b31808SJens Wiklander                                             ssl->conf->f_rng, ssl->conf->p_rng);
318532b31808SJens Wiklander         if (ret != 0) {
318632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_derive_secret", ret);
318732b31808SJens Wiklander             return ret;
318832b31808SJens Wiklander         }
318932b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
319032b31808SJens Wiklander     } else
319132b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
319232b31808SJens Wiklander     {
319332b31808SJens Wiklander         ((void) ciphersuite_info);
319432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
319532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
319632b31808SJens Wiklander     }
319732b31808SJens Wiklander 
319832b31808SJens Wiklander     ssl->out_msglen  = header_len + content_len;
319932b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
320032b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE;
320132b31808SJens Wiklander 
320232b31808SJens Wiklander     ssl->state++;
320332b31808SJens Wiklander 
320432b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
320532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
320632b31808SJens Wiklander         return ret;
320732b31808SJens Wiklander     }
320832b31808SJens Wiklander 
320932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write client key exchange"));
321032b31808SJens Wiklander 
321132b31808SJens Wiklander     return 0;
321232b31808SJens Wiklander }
321332b31808SJens Wiklander 
321432b31808SJens Wiklander #if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
321532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
321632b31808SJens Wiklander static int ssl_write_certificate_verify(mbedtls_ssl_context *ssl)
321732b31808SJens Wiklander {
321832b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
321932b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
322032b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
322132b31808SJens Wiklander 
322232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate verify"));
322332b31808SJens Wiklander 
322432b31808SJens Wiklander     if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) {
322532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret);
322632b31808SJens Wiklander         return ret;
322732b31808SJens Wiklander     }
322832b31808SJens Wiklander 
322932b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
323032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify"));
323132b31808SJens Wiklander         ssl->state++;
323232b31808SJens Wiklander         return 0;
323332b31808SJens Wiklander     }
323432b31808SJens Wiklander 
323532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
323632b31808SJens Wiklander     return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
323732b31808SJens Wiklander }
323832b31808SJens Wiklander #else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
323932b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
324032b31808SJens Wiklander static int ssl_write_certificate_verify(mbedtls_ssl_context *ssl)
324132b31808SJens Wiklander {
324232b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
324332b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
324432b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
324532b31808SJens Wiklander     size_t n = 0, offset = 0;
324632b31808SJens Wiklander     unsigned char hash[48];
324732b31808SJens Wiklander     unsigned char *hash_start = hash;
324832b31808SJens Wiklander     mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
324932b31808SJens Wiklander     size_t hashlen;
325032b31808SJens Wiklander     void *rs_ctx = NULL;
325132b31808SJens Wiklander #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
3252b0563631STom Van Eyck     size_t out_buf_len = ssl->out_buf_len - (size_t) (ssl->out_msg - ssl->out_buf);
325332b31808SJens Wiklander #else
3254b0563631STom Van Eyck     size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - (size_t) (ssl->out_msg - ssl->out_buf);
325532b31808SJens Wiklander #endif
325632b31808SJens Wiklander 
325732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate verify"));
325832b31808SJens Wiklander 
325932b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
326032b31808SJens Wiklander     if (ssl->handshake->ecrs_enabled &&
326132b31808SJens Wiklander         ssl->handshake->ecrs_state == ssl_ecrs_crt_vrfy_sign) {
326232b31808SJens Wiklander         goto sign;
326332b31808SJens Wiklander     }
326432b31808SJens Wiklander #endif
326532b31808SJens Wiklander 
326632b31808SJens Wiklander     if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) {
326732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret);
326832b31808SJens Wiklander         return ret;
326932b31808SJens Wiklander     }
327032b31808SJens Wiklander 
327132b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
327232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify"));
327332b31808SJens Wiklander         ssl->state++;
327432b31808SJens Wiklander         return 0;
327532b31808SJens Wiklander     }
327632b31808SJens Wiklander 
327732b31808SJens Wiklander     if (ssl->handshake->client_auth == 0 ||
327832b31808SJens Wiklander         mbedtls_ssl_own_cert(ssl) == NULL) {
327932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify"));
328032b31808SJens Wiklander         ssl->state++;
328132b31808SJens Wiklander         return 0;
328232b31808SJens Wiklander     }
328332b31808SJens Wiklander 
328432b31808SJens Wiklander     if (mbedtls_ssl_own_key(ssl) == NULL) {
328532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got no private key for certificate"));
328632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED;
328732b31808SJens Wiklander     }
328832b31808SJens Wiklander 
328932b31808SJens Wiklander     /*
329032b31808SJens Wiklander      * Make a signature of the handshake digests
329132b31808SJens Wiklander      */
329232b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
329332b31808SJens Wiklander     if (ssl->handshake->ecrs_enabled) {
329432b31808SJens Wiklander         ssl->handshake->ecrs_state = ssl_ecrs_crt_vrfy_sign;
329532b31808SJens Wiklander     }
329632b31808SJens Wiklander 
329732b31808SJens Wiklander sign:
329832b31808SJens Wiklander #endif
329932b31808SJens Wiklander 
330032b31808SJens Wiklander     ret = ssl->handshake->calc_verify(ssl, hash, &hashlen);
330132b31808SJens Wiklander     if (0 != ret) {
330232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("calc_verify"), ret);
330332b31808SJens Wiklander         return ret;
330432b31808SJens Wiklander     }
330532b31808SJens Wiklander 
330632b31808SJens Wiklander     /*
330732b31808SJens Wiklander      * digitally-signed struct {
330832b31808SJens Wiklander      *     opaque handshake_messages[handshake_messages_length];
330932b31808SJens Wiklander      * };
331032b31808SJens Wiklander      *
331132b31808SJens Wiklander      * Taking shortcut here. We assume that the server always allows the
331232b31808SJens Wiklander      * PRF Hash function and has sent it in the allowed signature
331332b31808SJens Wiklander      * algorithms list received in the Certificate Request message.
331432b31808SJens Wiklander      *
331532b31808SJens Wiklander      * Until we encounter a server that does not, we will take this
331632b31808SJens Wiklander      * shortcut.
331732b31808SJens Wiklander      *
331832b31808SJens Wiklander      * Reason: Otherwise we should have running hashes for SHA512 and
331932b31808SJens Wiklander      *         SHA224 in order to satisfy 'weird' needs from the server
332032b31808SJens Wiklander      *         side.
332132b31808SJens Wiklander      */
332232b31808SJens Wiklander     if (ssl->handshake->ciphersuite_info->mac == MBEDTLS_MD_SHA384) {
332332b31808SJens Wiklander         md_alg = MBEDTLS_MD_SHA384;
332432b31808SJens Wiklander         ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384;
332532b31808SJens Wiklander     } else {
332632b31808SJens Wiklander         md_alg = MBEDTLS_MD_SHA256;
332732b31808SJens Wiklander         ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA256;
332832b31808SJens Wiklander     }
332932b31808SJens Wiklander     ssl->out_msg[5] = mbedtls_ssl_sig_from_pk(mbedtls_ssl_own_key(ssl));
333032b31808SJens Wiklander 
333132b31808SJens Wiklander     /* Info from md_alg will be used instead */
333232b31808SJens Wiklander     hashlen = 0;
333332b31808SJens Wiklander     offset = 2;
333432b31808SJens Wiklander 
333532b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
333632b31808SJens Wiklander     if (ssl->handshake->ecrs_enabled) {
333732b31808SJens Wiklander         rs_ctx = &ssl->handshake->ecrs_ctx.pk;
333832b31808SJens Wiklander     }
333932b31808SJens Wiklander #endif
334032b31808SJens Wiklander 
334132b31808SJens Wiklander     if ((ret = mbedtls_pk_sign_restartable(mbedtls_ssl_own_key(ssl),
334232b31808SJens Wiklander                                            md_alg, hash_start, hashlen,
334332b31808SJens Wiklander                                            ssl->out_msg + 6 + offset,
334432b31808SJens Wiklander                                            out_buf_len - 6 - offset,
334532b31808SJens Wiklander                                            &n,
334632b31808SJens Wiklander                                            ssl->conf->f_rng, ssl->conf->p_rng, rs_ctx)) != 0) {
334732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_sign", ret);
334832b31808SJens Wiklander #if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
334932b31808SJens Wiklander         if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
335032b31808SJens Wiklander             ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
335132b31808SJens Wiklander         }
335232b31808SJens Wiklander #endif
335332b31808SJens Wiklander         return ret;
335432b31808SJens Wiklander     }
335532b31808SJens Wiklander 
335632b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(n, ssl->out_msg, offset + 4);
335732b31808SJens Wiklander 
335832b31808SJens Wiklander     ssl->out_msglen  = 6 + n + offset;
335932b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
336032b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY;
336132b31808SJens Wiklander 
336232b31808SJens Wiklander     ssl->state++;
336332b31808SJens Wiklander 
336432b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
336532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
336632b31808SJens Wiklander         return ret;
336732b31808SJens Wiklander     }
336832b31808SJens Wiklander 
336932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write certificate verify"));
337032b31808SJens Wiklander 
337132b31808SJens Wiklander     return ret;
337232b31808SJens Wiklander }
337332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
337432b31808SJens Wiklander 
337532b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
337632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
337732b31808SJens Wiklander static int ssl_parse_new_session_ticket(mbedtls_ssl_context *ssl)
337832b31808SJens Wiklander {
337932b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
338032b31808SJens Wiklander     uint32_t lifetime;
338132b31808SJens Wiklander     size_t ticket_len;
338232b31808SJens Wiklander     unsigned char *ticket;
338332b31808SJens Wiklander     const unsigned char *msg;
338432b31808SJens Wiklander 
338532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse new session ticket"));
338632b31808SJens Wiklander 
338732b31808SJens Wiklander     if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
338832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
338932b31808SJens Wiklander         return ret;
339032b31808SJens Wiklander     }
339132b31808SJens Wiklander 
339232b31808SJens Wiklander     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
339332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad new session ticket message"));
339432b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
339532b31808SJens Wiklander             ssl,
339632b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
339732b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE);
339832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
339932b31808SJens Wiklander     }
340032b31808SJens Wiklander 
340132b31808SJens Wiklander     /*
340232b31808SJens Wiklander      * struct {
340332b31808SJens Wiklander      *     uint32 ticket_lifetime_hint;
340432b31808SJens Wiklander      *     opaque ticket<0..2^16-1>;
340532b31808SJens Wiklander      * } NewSessionTicket;
340632b31808SJens Wiklander      *
340732b31808SJens Wiklander      * 0  .  3   ticket_lifetime_hint
340832b31808SJens Wiklander      * 4  .  5   ticket_len (n)
340932b31808SJens Wiklander      * 6  .  5+n ticket content
341032b31808SJens Wiklander      */
341132b31808SJens Wiklander     if (ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET ||
341232b31808SJens Wiklander         ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len(ssl)) {
341332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad new session ticket message"));
341432b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
341532b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
341632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
341732b31808SJens Wiklander     }
341832b31808SJens Wiklander 
341932b31808SJens Wiklander     msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl);
342032b31808SJens Wiklander 
3421b0563631STom Van Eyck     lifetime = MBEDTLS_GET_UINT32_BE(msg, 0);
342232b31808SJens Wiklander 
3423b0563631STom Van Eyck     ticket_len = MBEDTLS_GET_UINT16_BE(msg, 4);
342432b31808SJens Wiklander 
342532b31808SJens Wiklander     if (ticket_len + 6 + mbedtls_ssl_hs_hdr_len(ssl) != ssl->in_hslen) {
342632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad new session ticket message"));
342732b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
342832b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
342932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
343032b31808SJens Wiklander     }
343132b31808SJens Wiklander 
343232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("ticket length: %" MBEDTLS_PRINTF_SIZET, ticket_len));
343332b31808SJens Wiklander 
343432b31808SJens Wiklander     /* We're not waiting for a NewSessionTicket message any more */
343532b31808SJens Wiklander     ssl->handshake->new_session_ticket = 0;
343632b31808SJens Wiklander     ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
343732b31808SJens Wiklander 
343832b31808SJens Wiklander     /*
343932b31808SJens Wiklander      * Zero-length ticket means the server changed his mind and doesn't want
344032b31808SJens Wiklander      * to send a ticket after all, so just forget it
344132b31808SJens Wiklander      */
344232b31808SJens Wiklander     if (ticket_len == 0) {
344332b31808SJens Wiklander         return 0;
344432b31808SJens Wiklander     }
344532b31808SJens Wiklander 
344632b31808SJens Wiklander     if (ssl->session != NULL && ssl->session->ticket != NULL) {
3447b0563631STom Van Eyck         mbedtls_zeroize_and_free(ssl->session->ticket,
344832b31808SJens Wiklander                                  ssl->session->ticket_len);
344932b31808SJens Wiklander         ssl->session->ticket = NULL;
345032b31808SJens Wiklander         ssl->session->ticket_len = 0;
345132b31808SJens Wiklander     }
345232b31808SJens Wiklander 
3453b0563631STom Van Eyck     mbedtls_zeroize_and_free(ssl->session_negotiate->ticket,
345432b31808SJens Wiklander                              ssl->session_negotiate->ticket_len);
345532b31808SJens Wiklander     ssl->session_negotiate->ticket = NULL;
345632b31808SJens Wiklander     ssl->session_negotiate->ticket_len = 0;
345732b31808SJens Wiklander 
345832b31808SJens Wiklander     if ((ticket = mbedtls_calloc(1, ticket_len)) == NULL) {
345932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("ticket alloc failed"));
346032b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
346132b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
346232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ALLOC_FAILED;
346332b31808SJens Wiklander     }
346432b31808SJens Wiklander 
346532b31808SJens Wiklander     memcpy(ticket, msg + 6, ticket_len);
346632b31808SJens Wiklander 
346732b31808SJens Wiklander     ssl->session_negotiate->ticket = ticket;
346832b31808SJens Wiklander     ssl->session_negotiate->ticket_len = ticket_len;
346932b31808SJens Wiklander     ssl->session_negotiate->ticket_lifetime = lifetime;
347032b31808SJens Wiklander 
347132b31808SJens Wiklander     /*
347232b31808SJens Wiklander      * RFC 5077 section 3.4:
347332b31808SJens Wiklander      * "If the client receives a session ticket from the server, then it
347432b31808SJens Wiklander      * discards any Session ID that was sent in the ServerHello."
347532b31808SJens Wiklander      */
347632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("ticket in use, discarding session id"));
347732b31808SJens Wiklander     ssl->session_negotiate->id_len = 0;
347832b31808SJens Wiklander 
347932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse new session ticket"));
348032b31808SJens Wiklander 
348132b31808SJens Wiklander     return 0;
348232b31808SJens Wiklander }
348332b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
348432b31808SJens Wiklander 
348532b31808SJens Wiklander /*
348632b31808SJens Wiklander  * SSL handshake -- client side -- single step
348732b31808SJens Wiklander  */
348832b31808SJens Wiklander int mbedtls_ssl_handshake_client_step(mbedtls_ssl_context *ssl)
348932b31808SJens Wiklander {
349032b31808SJens Wiklander     int ret = 0;
349132b31808SJens Wiklander 
349232b31808SJens Wiklander     /* Change state now, so that it is right in mbedtls_ssl_read_record(), used
349332b31808SJens Wiklander      * by DTLS for dropping out-of-sequence ChangeCipherSpec records */
349432b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
349532b31808SJens Wiklander     if (ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC &&
349632b31808SJens Wiklander         ssl->handshake->new_session_ticket != 0) {
349732b31808SJens Wiklander         ssl->state = MBEDTLS_SSL_NEW_SESSION_TICKET;
349832b31808SJens Wiklander     }
349932b31808SJens Wiklander #endif
350032b31808SJens Wiklander 
350132b31808SJens Wiklander     switch (ssl->state) {
350232b31808SJens Wiklander         case MBEDTLS_SSL_HELLO_REQUEST:
350332b31808SJens Wiklander             ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
350432b31808SJens Wiklander             break;
350532b31808SJens Wiklander 
350632b31808SJens Wiklander         /*
350732b31808SJens Wiklander          *  ==>   ClientHello
350832b31808SJens Wiklander          */
350932b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_HELLO:
351032b31808SJens Wiklander             ret = mbedtls_ssl_write_client_hello(ssl);
351132b31808SJens Wiklander             break;
351232b31808SJens Wiklander 
351332b31808SJens Wiklander         /*
351432b31808SJens Wiklander          *  <==   ServerHello
351532b31808SJens Wiklander          *        Certificate
351632b31808SJens Wiklander          *      ( ServerKeyExchange  )
351732b31808SJens Wiklander          *      ( CertificateRequest )
351832b31808SJens Wiklander          *        ServerHelloDone
351932b31808SJens Wiklander          */
352032b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_HELLO:
352132b31808SJens Wiklander             ret = ssl_parse_server_hello(ssl);
352232b31808SJens Wiklander             break;
352332b31808SJens Wiklander 
352432b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_CERTIFICATE:
352532b31808SJens Wiklander             ret = mbedtls_ssl_parse_certificate(ssl);
352632b31808SJens Wiklander             break;
352732b31808SJens Wiklander 
352832b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
352932b31808SJens Wiklander             ret = ssl_parse_server_key_exchange(ssl);
353032b31808SJens Wiklander             break;
353132b31808SJens Wiklander 
353232b31808SJens Wiklander         case MBEDTLS_SSL_CERTIFICATE_REQUEST:
353332b31808SJens Wiklander             ret = ssl_parse_certificate_request(ssl);
353432b31808SJens Wiklander             break;
353532b31808SJens Wiklander 
353632b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_HELLO_DONE:
353732b31808SJens Wiklander             ret = ssl_parse_server_hello_done(ssl);
353832b31808SJens Wiklander             break;
353932b31808SJens Wiklander 
354032b31808SJens Wiklander         /*
354132b31808SJens Wiklander          *  ==> ( Certificate/Alert  )
354232b31808SJens Wiklander          *        ClientKeyExchange
354332b31808SJens Wiklander          *      ( CertificateVerify  )
354432b31808SJens Wiklander          *        ChangeCipherSpec
354532b31808SJens Wiklander          *        Finished
354632b31808SJens Wiklander          */
354732b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_CERTIFICATE:
354832b31808SJens Wiklander             ret = mbedtls_ssl_write_certificate(ssl);
354932b31808SJens Wiklander             break;
355032b31808SJens Wiklander 
355132b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
355232b31808SJens Wiklander             ret = ssl_write_client_key_exchange(ssl);
355332b31808SJens Wiklander             break;
355432b31808SJens Wiklander 
355532b31808SJens Wiklander         case MBEDTLS_SSL_CERTIFICATE_VERIFY:
355632b31808SJens Wiklander             ret = ssl_write_certificate_verify(ssl);
355732b31808SJens Wiklander             break;
355832b31808SJens Wiklander 
355932b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
356032b31808SJens Wiklander             ret = mbedtls_ssl_write_change_cipher_spec(ssl);
356132b31808SJens Wiklander             break;
356232b31808SJens Wiklander 
356332b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_FINISHED:
356432b31808SJens Wiklander             ret = mbedtls_ssl_write_finished(ssl);
356532b31808SJens Wiklander             break;
356632b31808SJens Wiklander 
356732b31808SJens Wiklander             /*
356832b31808SJens Wiklander              *  <==   ( NewSessionTicket )
356932b31808SJens Wiklander              *        ChangeCipherSpec
357032b31808SJens Wiklander              *        Finished
357132b31808SJens Wiklander              */
357232b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
357332b31808SJens Wiklander         case MBEDTLS_SSL_NEW_SESSION_TICKET:
357432b31808SJens Wiklander             ret = ssl_parse_new_session_ticket(ssl);
357532b31808SJens Wiklander             break;
357632b31808SJens Wiklander #endif
357732b31808SJens Wiklander 
357832b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
357932b31808SJens Wiklander             ret = mbedtls_ssl_parse_change_cipher_spec(ssl);
358032b31808SJens Wiklander             break;
358132b31808SJens Wiklander 
358232b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_FINISHED:
358332b31808SJens Wiklander             ret = mbedtls_ssl_parse_finished(ssl);
358432b31808SJens Wiklander             break;
358532b31808SJens Wiklander 
358632b31808SJens Wiklander         case MBEDTLS_SSL_FLUSH_BUFFERS:
358732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done"));
358832b31808SJens Wiklander             ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
358932b31808SJens Wiklander             break;
359032b31808SJens Wiklander 
359132b31808SJens Wiklander         case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
359232b31808SJens Wiklander             mbedtls_ssl_handshake_wrapup(ssl);
359332b31808SJens Wiklander             break;
359432b31808SJens Wiklander 
359532b31808SJens Wiklander         default:
359632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("invalid state %d", ssl->state));
359732b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
359832b31808SJens Wiklander     }
359932b31808SJens Wiklander 
360032b31808SJens Wiklander     return ret;
360132b31808SJens Wiklander }
360232b31808SJens Wiklander 
360332b31808SJens Wiklander #endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_PROTO_TLS1_2 */
3604