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