xref: /optee_os/lib/libmbedtls/mbedtls/library/ssl_tls12_server.c (revision b0563631928755fe864b97785160fb3088e9efdc)
132b31808SJens Wiklander /*
232b31808SJens Wiklander  *  TLS server-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_SRV_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_misc.h"
16*b0563631STom Van Eyck #include "debug_internal.h"
1732b31808SJens Wiklander #include "mbedtls/error.h"
1832b31808SJens Wiklander #include "mbedtls/platform_util.h"
1932b31808SJens Wiklander #include "constant_time_internal.h"
2032b31808SJens Wiklander #include "mbedtls/constant_time.h"
2132b31808SJens Wiklander 
2232b31808SJens Wiklander #include <string.h>
2332b31808SJens Wiklander 
2432b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
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 #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED) || \
28*b0563631STom Van Eyck     defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED)
29*b0563631STom Van Eyck static int local_err_translation(psa_status_t status)
30*b0563631STom Van Eyck {
31*b0563631STom Van Eyck     return psa_status_to_mbedtls(status, psa_to_ssl_errors,
32*b0563631STom Van Eyck                                  ARRAY_LENGTH(psa_to_ssl_errors),
33*b0563631STom Van Eyck                                  psa_generic_status_to_mbedtls);
34*b0563631STom Van Eyck }
35*b0563631STom Van Eyck #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)
36*b0563631STom Van Eyck #endif
3732b31808SJens Wiklander #endif
3832b31808SJens Wiklander 
3932b31808SJens Wiklander #if defined(MBEDTLS_ECP_C)
4032b31808SJens Wiklander #include "mbedtls/ecp.h"
4132b31808SJens Wiklander #endif
4232b31808SJens Wiklander 
4332b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME)
4432b31808SJens Wiklander #include "mbedtls/platform_time.h"
4532b31808SJens Wiklander #endif
4632b31808SJens Wiklander 
4732b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
4832b31808SJens Wiklander int mbedtls_ssl_set_client_transport_id(mbedtls_ssl_context *ssl,
4932b31808SJens Wiklander                                         const unsigned char *info,
5032b31808SJens Wiklander                                         size_t ilen)
5132b31808SJens Wiklander {
5232b31808SJens Wiklander     if (ssl->conf->endpoint != MBEDTLS_SSL_IS_SERVER) {
5332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
5432b31808SJens Wiklander     }
5532b31808SJens Wiklander 
5632b31808SJens Wiklander     mbedtls_free(ssl->cli_id);
5732b31808SJens Wiklander 
5832b31808SJens Wiklander     if ((ssl->cli_id = mbedtls_calloc(1, ilen)) == NULL) {
5932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ALLOC_FAILED;
6032b31808SJens Wiklander     }
6132b31808SJens Wiklander 
6232b31808SJens Wiklander     memcpy(ssl->cli_id, info, ilen);
6332b31808SJens Wiklander     ssl->cli_id_len = ilen;
6432b31808SJens Wiklander 
6532b31808SJens Wiklander     return 0;
6632b31808SJens Wiklander }
6732b31808SJens Wiklander 
6832b31808SJens Wiklander void mbedtls_ssl_conf_dtls_cookies(mbedtls_ssl_config *conf,
6932b31808SJens Wiklander                                    mbedtls_ssl_cookie_write_t *f_cookie_write,
7032b31808SJens Wiklander                                    mbedtls_ssl_cookie_check_t *f_cookie_check,
7132b31808SJens Wiklander                                    void *p_cookie)
7232b31808SJens Wiklander {
7332b31808SJens Wiklander     conf->f_cookie_write = f_cookie_write;
7432b31808SJens Wiklander     conf->f_cookie_check = f_cookie_check;
7532b31808SJens Wiklander     conf->p_cookie       = p_cookie;
7632b31808SJens Wiklander }
7732b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
7832b31808SJens Wiklander 
7932b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
8032b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
8132b31808SJens Wiklander static int ssl_conf_has_psk_or_cb(mbedtls_ssl_config const *conf)
8232b31808SJens Wiklander {
8332b31808SJens Wiklander     if (conf->f_psk != NULL) {
8432b31808SJens Wiklander         return 1;
8532b31808SJens Wiklander     }
8632b31808SJens Wiklander 
8732b31808SJens Wiklander     if (conf->psk_identity_len == 0 || conf->psk_identity == NULL) {
8832b31808SJens Wiklander         return 0;
8932b31808SJens Wiklander     }
9032b31808SJens Wiklander 
9132b31808SJens Wiklander 
9232b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
9332b31808SJens Wiklander     if (!mbedtls_svc_key_id_is_null(conf->psk_opaque)) {
9432b31808SJens Wiklander         return 1;
9532b31808SJens Wiklander     }
9632b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
9732b31808SJens Wiklander 
9832b31808SJens Wiklander     if (conf->psk != NULL && conf->psk_len != 0) {
9932b31808SJens Wiklander         return 1;
10032b31808SJens Wiklander     }
10132b31808SJens Wiklander 
10232b31808SJens Wiklander     return 0;
10332b31808SJens Wiklander }
10432b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
10532b31808SJens Wiklander 
10632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
10732b31808SJens Wiklander static int ssl_parse_renegotiation_info(mbedtls_ssl_context *ssl,
10832b31808SJens Wiklander                                         const unsigned char *buf,
10932b31808SJens Wiklander                                         size_t len)
11032b31808SJens Wiklander {
11132b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
11232b31808SJens Wiklander     if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
11332b31808SJens Wiklander         /* Check verify-data in constant-time. The length OTOH is no secret */
11432b31808SJens Wiklander         if (len    != 1 + ssl->verify_data_len ||
11532b31808SJens Wiklander             buf[0] !=     ssl->verify_data_len ||
11632b31808SJens Wiklander             mbedtls_ct_memcmp(buf + 1, ssl->peer_verify_data,
11732b31808SJens Wiklander                               ssl->verify_data_len) != 0) {
11832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("non-matching renegotiation info"));
11932b31808SJens Wiklander             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
12032b31808SJens Wiklander                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
12132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
12232b31808SJens Wiklander         }
12332b31808SJens Wiklander     } else
12432b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */
12532b31808SJens Wiklander     {
12632b31808SJens Wiklander         if (len != 1 || buf[0] != 0x0) {
12732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("non-zero length renegotiation info"));
12832b31808SJens Wiklander             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
12932b31808SJens Wiklander                                            MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
13032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
13132b31808SJens Wiklander         }
13232b31808SJens Wiklander 
13332b31808SJens Wiklander         ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
13432b31808SJens Wiklander     }
13532b31808SJens Wiklander 
13632b31808SJens Wiklander     return 0;
13732b31808SJens Wiklander }
13832b31808SJens Wiklander 
139*b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
140*b0563631STom Van Eyck     defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
14132b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
14232b31808SJens Wiklander /*
14332b31808SJens Wiklander  * Function for parsing a supported groups (TLS 1.3) or supported elliptic
14432b31808SJens Wiklander  * curves (TLS 1.2) extension.
14532b31808SJens Wiklander  *
14632b31808SJens Wiklander  * The "extension_data" field of a supported groups extension contains a
14732b31808SJens Wiklander  * "NamedGroupList" value (TLS 1.3 RFC8446):
14832b31808SJens Wiklander  *      enum {
14932b31808SJens Wiklander  *          secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019),
15032b31808SJens Wiklander  *          x25519(0x001D), x448(0x001E),
15132b31808SJens Wiklander  *          ffdhe2048(0x0100), ffdhe3072(0x0101), ffdhe4096(0x0102),
15232b31808SJens Wiklander  *          ffdhe6144(0x0103), ffdhe8192(0x0104),
15332b31808SJens Wiklander  *          ffdhe_private_use(0x01FC..0x01FF),
15432b31808SJens Wiklander  *          ecdhe_private_use(0xFE00..0xFEFF),
15532b31808SJens Wiklander  *          (0xFFFF)
15632b31808SJens Wiklander  *      } NamedGroup;
15732b31808SJens Wiklander  *      struct {
15832b31808SJens Wiklander  *          NamedGroup named_group_list<2..2^16-1>;
15932b31808SJens Wiklander  *      } NamedGroupList;
16032b31808SJens Wiklander  *
16132b31808SJens Wiklander  * The "extension_data" field of a supported elliptic curves extension contains
16232b31808SJens Wiklander  * a "NamedCurveList" value (TLS 1.2 RFC 8422):
16332b31808SJens Wiklander  * enum {
16432b31808SJens Wiklander  *      deprecated(1..22),
16532b31808SJens Wiklander  *      secp256r1 (23), secp384r1 (24), secp521r1 (25),
16632b31808SJens Wiklander  *      x25519(29), x448(30),
16732b31808SJens Wiklander  *      reserved (0xFE00..0xFEFF),
16832b31808SJens Wiklander  *      deprecated(0xFF01..0xFF02),
16932b31808SJens Wiklander  *      (0xFFFF)
17032b31808SJens Wiklander  *  } NamedCurve;
17132b31808SJens Wiklander  * struct {
17232b31808SJens Wiklander  *      NamedCurve named_curve_list<2..2^16-1>
17332b31808SJens Wiklander  *  } NamedCurveList;
17432b31808SJens Wiklander  *
17532b31808SJens Wiklander  * The TLS 1.3 supported groups extension was defined to be a compatible
17632b31808SJens Wiklander  * generalization of the TLS 1.2 supported elliptic curves extension. They both
17732b31808SJens Wiklander  * share the same extension identifier.
17832b31808SJens Wiklander  *
17932b31808SJens Wiklander  */
18032b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
18132b31808SJens Wiklander static int ssl_parse_supported_groups_ext(mbedtls_ssl_context *ssl,
18232b31808SJens Wiklander                                           const unsigned char *buf,
18332b31808SJens Wiklander                                           size_t len)
18432b31808SJens Wiklander {
18532b31808SJens Wiklander     size_t list_size, our_size;
18632b31808SJens Wiklander     const unsigned char *p;
18732b31808SJens Wiklander     uint16_t *curves_tls_id;
18832b31808SJens Wiklander 
18932b31808SJens Wiklander     if (len < 2) {
19032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
19132b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
19232b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
19332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
19432b31808SJens Wiklander     }
195*b0563631STom Van Eyck     list_size = MBEDTLS_GET_UINT16_BE(buf, 0);
19632b31808SJens Wiklander     if (list_size + 2 != len ||
19732b31808SJens Wiklander         list_size % 2 != 0) {
19832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
19932b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
20032b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
20132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
20232b31808SJens Wiklander     }
20332b31808SJens Wiklander 
20432b31808SJens Wiklander     /* Should never happen unless client duplicates the extension */
20532b31808SJens Wiklander     if (ssl->handshake->curves_tls_id != NULL) {
20632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
20732b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
20832b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
20932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
21032b31808SJens Wiklander     }
21132b31808SJens Wiklander 
21232b31808SJens Wiklander     /* Don't allow our peer to make us allocate too much memory,
21332b31808SJens Wiklander      * and leave room for a final 0 */
21432b31808SJens Wiklander     our_size = list_size / 2 + 1;
21532b31808SJens Wiklander     if (our_size > MBEDTLS_ECP_DP_MAX) {
21632b31808SJens Wiklander         our_size = MBEDTLS_ECP_DP_MAX;
21732b31808SJens Wiklander     }
21832b31808SJens Wiklander 
21932b31808SJens Wiklander     if ((curves_tls_id = mbedtls_calloc(our_size,
22032b31808SJens Wiklander                                         sizeof(*curves_tls_id))) == NULL) {
22132b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
22232b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR);
22332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ALLOC_FAILED;
22432b31808SJens Wiklander     }
22532b31808SJens Wiklander 
22632b31808SJens Wiklander     ssl->handshake->curves_tls_id = curves_tls_id;
22732b31808SJens Wiklander 
22832b31808SJens Wiklander     p = buf + 2;
22932b31808SJens Wiklander     while (list_size > 0 && our_size > 1) {
23032b31808SJens Wiklander         uint16_t curr_tls_id = MBEDTLS_GET_UINT16_BE(p, 0);
23132b31808SJens Wiklander 
23232b31808SJens Wiklander         if (mbedtls_ssl_get_ecp_group_id_from_tls_id(curr_tls_id) !=
23332b31808SJens Wiklander             MBEDTLS_ECP_DP_NONE) {
23432b31808SJens Wiklander             *curves_tls_id++ = curr_tls_id;
23532b31808SJens Wiklander             our_size--;
23632b31808SJens Wiklander         }
23732b31808SJens Wiklander 
23832b31808SJens Wiklander         list_size -= 2;
23932b31808SJens Wiklander         p += 2;
24032b31808SJens Wiklander     }
24132b31808SJens Wiklander 
24232b31808SJens Wiklander     return 0;
24332b31808SJens Wiklander }
24432b31808SJens Wiklander 
24532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
24632b31808SJens Wiklander static int ssl_parse_supported_point_formats(mbedtls_ssl_context *ssl,
24732b31808SJens Wiklander                                              const unsigned char *buf,
24832b31808SJens Wiklander                                              size_t len)
24932b31808SJens Wiklander {
25032b31808SJens Wiklander     size_t list_size;
25132b31808SJens Wiklander     const unsigned char *p;
25232b31808SJens Wiklander 
25332b31808SJens Wiklander     if (len == 0 || (size_t) (buf[0] + 1) != len) {
25432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
25532b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
25632b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
25732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
25832b31808SJens Wiklander     }
25932b31808SJens Wiklander     list_size = buf[0];
26032b31808SJens Wiklander 
26132b31808SJens Wiklander     p = buf + 1;
26232b31808SJens Wiklander     while (list_size > 0) {
26332b31808SJens Wiklander         if (p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
26432b31808SJens Wiklander             p[0] == MBEDTLS_ECP_PF_COMPRESSED) {
26532b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO) && \
266*b0563631STom Van Eyck             defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED)
26732b31808SJens Wiklander             ssl->handshake->ecdh_ctx.point_format = p[0];
268*b0563631STom Van Eyck #endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED */
26932b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO) &&                             \
27032b31808SJens Wiklander             defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
27132b31808SJens Wiklander             mbedtls_ecjpake_set_point_format(&ssl->handshake->ecjpake_ctx,
27232b31808SJens Wiklander                                              p[0]);
27332b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
27432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(4, ("point format selected: %d", p[0]));
27532b31808SJens Wiklander             return 0;
27632b31808SJens Wiklander         }
27732b31808SJens Wiklander 
27832b31808SJens Wiklander         list_size--;
27932b31808SJens Wiklander         p++;
28032b31808SJens Wiklander     }
28132b31808SJens Wiklander 
28232b31808SJens Wiklander     return 0;
28332b31808SJens Wiklander }
284*b0563631STom Van Eyck #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED ||
285*b0563631STom Van Eyck           MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED ||
28632b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
28732b31808SJens Wiklander 
28832b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
28932b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
29032b31808SJens Wiklander static int ssl_parse_ecjpake_kkpp(mbedtls_ssl_context *ssl,
29132b31808SJens Wiklander                                   const unsigned char *buf,
29232b31808SJens Wiklander                                   size_t len)
29332b31808SJens Wiklander {
29432b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
29532b31808SJens Wiklander 
29632b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
29732b31808SJens Wiklander     if (ssl->handshake->psa_pake_ctx_is_ok != 1)
29832b31808SJens Wiklander #else
29932b31808SJens Wiklander     if (mbedtls_ecjpake_check(&ssl->handshake->ecjpake_ctx) != 0)
30032b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
30132b31808SJens Wiklander     {
30232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("skip ecjpake kkpp extension"));
30332b31808SJens Wiklander         return 0;
30432b31808SJens Wiklander     }
30532b31808SJens Wiklander 
30632b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
30732b31808SJens Wiklander     if ((ret = mbedtls_psa_ecjpake_read_round(
30832b31808SJens Wiklander              &ssl->handshake->psa_pake_ctx, buf, len,
30932b31808SJens Wiklander              MBEDTLS_ECJPAKE_ROUND_ONE)) != 0) {
31032b31808SJens Wiklander         psa_destroy_key(ssl->handshake->psa_pake_password);
31132b31808SJens Wiklander         psa_pake_abort(&ssl->handshake->psa_pake_ctx);
31232b31808SJens Wiklander 
31332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round one", ret);
31432b31808SJens Wiklander         mbedtls_ssl_send_alert_message(
31532b31808SJens Wiklander             ssl,
31632b31808SJens Wiklander             MBEDTLS_SSL_ALERT_LEVEL_FATAL,
31732b31808SJens Wiklander             MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
31832b31808SJens Wiklander 
31932b31808SJens Wiklander         return ret;
32032b31808SJens Wiklander     }
32132b31808SJens Wiklander #else
32232b31808SJens Wiklander     if ((ret = mbedtls_ecjpake_read_round_one(&ssl->handshake->ecjpake_ctx,
32332b31808SJens Wiklander                                               buf, len)) != 0) {
32432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_one", ret);
32532b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
32632b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
32732b31808SJens Wiklander         return ret;
32832b31808SJens Wiklander     }
32932b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
33032b31808SJens Wiklander 
33132b31808SJens Wiklander     /* Only mark the extension as OK when we're sure it is */
33232b31808SJens Wiklander     ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK;
33332b31808SJens Wiklander 
33432b31808SJens Wiklander     return 0;
33532b31808SJens Wiklander }
33632b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
33732b31808SJens Wiklander 
33832b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
33932b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
34032b31808SJens Wiklander static int ssl_parse_max_fragment_length_ext(mbedtls_ssl_context *ssl,
34132b31808SJens Wiklander                                              const unsigned char *buf,
34232b31808SJens Wiklander                                              size_t len)
34332b31808SJens Wiklander {
34432b31808SJens Wiklander     if (len != 1 || buf[0] >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID) {
34532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
34632b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
34732b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
34832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
34932b31808SJens Wiklander     }
35032b31808SJens Wiklander 
35132b31808SJens Wiklander     ssl->session_negotiate->mfl_code = buf[0];
35232b31808SJens Wiklander 
35332b31808SJens Wiklander     return 0;
35432b31808SJens Wiklander }
35532b31808SJens Wiklander #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
35632b31808SJens Wiklander 
35732b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
35832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
35932b31808SJens Wiklander static int ssl_parse_cid_ext(mbedtls_ssl_context *ssl,
36032b31808SJens Wiklander                              const unsigned char *buf,
36132b31808SJens Wiklander                              size_t len)
36232b31808SJens Wiklander {
36332b31808SJens Wiklander     size_t peer_cid_len;
36432b31808SJens Wiklander 
36532b31808SJens Wiklander     /* CID extension only makes sense in DTLS */
36632b31808SJens Wiklander     if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
36732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
36832b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
36932b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
37032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
37132b31808SJens Wiklander     }
37232b31808SJens Wiklander 
37332b31808SJens Wiklander     /*
37432b31808SJens Wiklander      *   struct {
37532b31808SJens Wiklander      *      opaque cid<0..2^8-1>;
37632b31808SJens Wiklander      *   } ConnectionId;
37732b31808SJens Wiklander      */
37832b31808SJens Wiklander 
37932b31808SJens Wiklander     if (len < 1) {
38032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
38132b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
38232b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
38332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
38432b31808SJens Wiklander     }
38532b31808SJens Wiklander 
38632b31808SJens Wiklander     peer_cid_len = *buf++;
38732b31808SJens Wiklander     len--;
38832b31808SJens Wiklander 
38932b31808SJens Wiklander     if (len != peer_cid_len) {
39032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
39132b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
39232b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
39332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
39432b31808SJens Wiklander     }
39532b31808SJens Wiklander 
39632b31808SJens Wiklander     /* Ignore CID if the user has disabled its use. */
39732b31808SJens Wiklander     if (ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED) {
39832b31808SJens Wiklander         /* Leave ssl->handshake->cid_in_use in its default
39932b31808SJens Wiklander          * value of MBEDTLS_SSL_CID_DISABLED. */
40032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("Client sent CID extension, but CID disabled"));
40132b31808SJens Wiklander         return 0;
40232b31808SJens Wiklander     }
40332b31808SJens Wiklander 
40432b31808SJens Wiklander     if (peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX) {
40532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
40632b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
40732b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER);
40832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
40932b31808SJens Wiklander     }
41032b31808SJens Wiklander 
41132b31808SJens Wiklander     ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED;
41232b31808SJens Wiklander     ssl->handshake->peer_cid_len = (uint8_t) peer_cid_len;
41332b31808SJens Wiklander     memcpy(ssl->handshake->peer_cid, buf, peer_cid_len);
41432b31808SJens Wiklander 
41532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("Use of CID extension negotiated"));
41632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "Client CID", buf, peer_cid_len);
41732b31808SJens Wiklander 
41832b31808SJens Wiklander     return 0;
41932b31808SJens Wiklander }
42032b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
42132b31808SJens Wiklander 
42232b31808SJens Wiklander #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
42332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
42432b31808SJens Wiklander static int ssl_parse_encrypt_then_mac_ext(mbedtls_ssl_context *ssl,
42532b31808SJens Wiklander                                           const unsigned char *buf,
42632b31808SJens Wiklander                                           size_t len)
42732b31808SJens Wiklander {
42832b31808SJens Wiklander     if (len != 0) {
42932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
43032b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
43132b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
43232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
43332b31808SJens Wiklander     }
43432b31808SJens Wiklander 
43532b31808SJens Wiklander     ((void) buf);
43632b31808SJens Wiklander 
43732b31808SJens Wiklander     if (ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED) {
43832b31808SJens Wiklander         ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED;
43932b31808SJens Wiklander     }
44032b31808SJens Wiklander 
44132b31808SJens Wiklander     return 0;
44232b31808SJens Wiklander }
44332b31808SJens Wiklander #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
44432b31808SJens Wiklander 
44532b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
44632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
44732b31808SJens Wiklander static int ssl_parse_extended_ms_ext(mbedtls_ssl_context *ssl,
44832b31808SJens Wiklander                                      const unsigned char *buf,
44932b31808SJens Wiklander                                      size_t len)
45032b31808SJens Wiklander {
45132b31808SJens Wiklander     if (len != 0) {
45232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
45332b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
45432b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
45532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
45632b31808SJens Wiklander     }
45732b31808SJens Wiklander 
45832b31808SJens Wiklander     ((void) buf);
45932b31808SJens Wiklander 
46032b31808SJens Wiklander     if (ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED) {
46132b31808SJens Wiklander         ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED;
46232b31808SJens Wiklander     }
46332b31808SJens Wiklander 
46432b31808SJens Wiklander     return 0;
46532b31808SJens Wiklander }
46632b31808SJens Wiklander #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
46732b31808SJens Wiklander 
46832b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
46932b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
47032b31808SJens Wiklander static int ssl_parse_session_ticket_ext(mbedtls_ssl_context *ssl,
47132b31808SJens Wiklander                                         unsigned char *buf,
47232b31808SJens Wiklander                                         size_t len)
47332b31808SJens Wiklander {
47432b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
47532b31808SJens Wiklander     mbedtls_ssl_session session;
47632b31808SJens Wiklander 
47732b31808SJens Wiklander     mbedtls_ssl_session_init(&session);
47832b31808SJens Wiklander 
47932b31808SJens Wiklander     if (ssl->conf->f_ticket_parse == NULL ||
48032b31808SJens Wiklander         ssl->conf->f_ticket_write == NULL) {
48132b31808SJens Wiklander         return 0;
48232b31808SJens Wiklander     }
48332b31808SJens Wiklander 
48432b31808SJens Wiklander     /* Remember the client asked us to send a new ticket */
48532b31808SJens Wiklander     ssl->handshake->new_session_ticket = 1;
48632b31808SJens Wiklander 
48732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("ticket length: %" MBEDTLS_PRINTF_SIZET, len));
48832b31808SJens Wiklander 
48932b31808SJens Wiklander     if (len == 0) {
49032b31808SJens Wiklander         return 0;
49132b31808SJens Wiklander     }
49232b31808SJens Wiklander 
49332b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
49432b31808SJens Wiklander     if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
49532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("ticket rejected: renegotiating"));
49632b31808SJens Wiklander         return 0;
49732b31808SJens Wiklander     }
49832b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */
49932b31808SJens Wiklander 
50032b31808SJens Wiklander     /*
50132b31808SJens Wiklander      * Failures are ok: just ignore the ticket and proceed.
50232b31808SJens Wiklander      */
50332b31808SJens Wiklander     if ((ret = ssl->conf->f_ticket_parse(ssl->conf->p_ticket, &session,
50432b31808SJens Wiklander                                          buf, len)) != 0) {
50532b31808SJens Wiklander         mbedtls_ssl_session_free(&session);
50632b31808SJens Wiklander 
50732b31808SJens Wiklander         if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) {
50832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is not authentic"));
50932b31808SJens Wiklander         } else if (ret == MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) {
51032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is expired"));
51132b31808SJens Wiklander         } else {
51232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_ticket_parse", ret);
51332b31808SJens Wiklander         }
51432b31808SJens Wiklander 
51532b31808SJens Wiklander         return 0;
51632b31808SJens Wiklander     }
51732b31808SJens Wiklander 
51832b31808SJens Wiklander     /*
51932b31808SJens Wiklander      * Keep the session ID sent by the client, since we MUST send it back to
52032b31808SJens Wiklander      * inform them we're accepting the ticket  (RFC 5077 section 3.4)
52132b31808SJens Wiklander      */
52232b31808SJens Wiklander     session.id_len = ssl->session_negotiate->id_len;
52332b31808SJens Wiklander     memcpy(&session.id, ssl->session_negotiate->id, session.id_len);
52432b31808SJens Wiklander 
52532b31808SJens Wiklander     mbedtls_ssl_session_free(ssl->session_negotiate);
52632b31808SJens Wiklander     memcpy(ssl->session_negotiate, &session, sizeof(mbedtls_ssl_session));
52732b31808SJens Wiklander 
52832b31808SJens Wiklander     /* Zeroize instead of free as we copied the content */
52932b31808SJens Wiklander     mbedtls_platform_zeroize(&session, sizeof(mbedtls_ssl_session));
53032b31808SJens Wiklander 
53132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("session successfully restored from ticket"));
53232b31808SJens Wiklander 
53332b31808SJens Wiklander     ssl->handshake->resume = 1;
53432b31808SJens Wiklander 
53532b31808SJens Wiklander     /* Don't send a new ticket after all, this one is OK */
53632b31808SJens Wiklander     ssl->handshake->new_session_ticket = 0;
53732b31808SJens Wiklander 
53832b31808SJens Wiklander     return 0;
53932b31808SJens Wiklander }
54032b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
54132b31808SJens Wiklander 
54232b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP)
54332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
54432b31808SJens Wiklander static int ssl_parse_use_srtp_ext(mbedtls_ssl_context *ssl,
54532b31808SJens Wiklander                                   const unsigned char *buf,
54632b31808SJens Wiklander                                   size_t len)
54732b31808SJens Wiklander {
54832b31808SJens Wiklander     mbedtls_ssl_srtp_profile client_protection = MBEDTLS_TLS_SRTP_UNSET;
54932b31808SJens Wiklander     size_t i, j;
55032b31808SJens Wiklander     size_t profile_length;
55132b31808SJens Wiklander     uint16_t mki_length;
55232b31808SJens Wiklander     /*! 2 bytes for profile length and 1 byte for mki len */
55332b31808SJens Wiklander     const size_t size_of_lengths = 3;
55432b31808SJens Wiklander 
55532b31808SJens Wiklander     /* If use_srtp is not configured, just ignore the extension */
55632b31808SJens Wiklander     if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) ||
55732b31808SJens Wiklander         (ssl->conf->dtls_srtp_profile_list == NULL) ||
55832b31808SJens Wiklander         (ssl->conf->dtls_srtp_profile_list_len == 0)) {
55932b31808SJens Wiklander         return 0;
56032b31808SJens Wiklander     }
56132b31808SJens Wiklander 
56232b31808SJens Wiklander     /* RFC5764 section 4.1.1
56332b31808SJens Wiklander      * uint8 SRTPProtectionProfile[2];
56432b31808SJens Wiklander      *
56532b31808SJens Wiklander      * struct {
56632b31808SJens Wiklander      *   SRTPProtectionProfiles SRTPProtectionProfiles;
56732b31808SJens Wiklander      *   opaque srtp_mki<0..255>;
56832b31808SJens Wiklander      * } UseSRTPData;
56932b31808SJens Wiklander 
57032b31808SJens Wiklander      * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
57132b31808SJens Wiklander      */
57232b31808SJens Wiklander 
57332b31808SJens Wiklander     /*
57432b31808SJens Wiklander      * Min length is 5: at least one protection profile(2 bytes)
57532b31808SJens Wiklander      *                  and length(2 bytes) + srtp_mki length(1 byte)
57632b31808SJens Wiklander      * Check here that we have at least 2 bytes of protection profiles length
57732b31808SJens Wiklander      * and one of srtp_mki length
57832b31808SJens Wiklander      */
57932b31808SJens Wiklander     if (len < size_of_lengths) {
58032b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
58132b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
58232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
58332b31808SJens Wiklander     }
58432b31808SJens Wiklander 
58532b31808SJens Wiklander     ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET;
58632b31808SJens Wiklander 
58732b31808SJens Wiklander     /* first 2 bytes are protection profile length(in bytes) */
58832b31808SJens Wiklander     profile_length = (buf[0] << 8) | buf[1];
58932b31808SJens Wiklander     buf += 2;
59032b31808SJens Wiklander 
59132b31808SJens Wiklander     /* The profile length cannot be bigger than input buffer size - lengths fields */
59232b31808SJens Wiklander     if (profile_length > len - size_of_lengths ||
59332b31808SJens Wiklander         profile_length % 2 != 0) { /* profiles are 2 bytes long, so the length must be even */
59432b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
59532b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
59632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
59732b31808SJens Wiklander     }
59832b31808SJens Wiklander     /*
59932b31808SJens Wiklander      * parse the extension list values are defined in
60032b31808SJens Wiklander      * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
60132b31808SJens Wiklander      */
60232b31808SJens Wiklander     for (j = 0; j < profile_length; j += 2) {
60332b31808SJens Wiklander         uint16_t protection_profile_value = buf[j] << 8 | buf[j + 1];
60432b31808SJens Wiklander         client_protection = mbedtls_ssl_check_srtp_profile_value(protection_profile_value);
60532b31808SJens Wiklander 
60632b31808SJens Wiklander         if (client_protection != MBEDTLS_TLS_SRTP_UNSET) {
60732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3, ("found srtp profile: %s",
60832b31808SJens Wiklander                                       mbedtls_ssl_get_srtp_profile_as_string(
60932b31808SJens Wiklander                                           client_protection)));
61032b31808SJens Wiklander         } else {
61132b31808SJens Wiklander             continue;
61232b31808SJens Wiklander         }
61332b31808SJens Wiklander         /* check if suggested profile is in our list */
61432b31808SJens Wiklander         for (i = 0; i < ssl->conf->dtls_srtp_profile_list_len; i++) {
61532b31808SJens Wiklander             if (client_protection == ssl->conf->dtls_srtp_profile_list[i]) {
61632b31808SJens Wiklander                 ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
61732b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("selected srtp profile: %s",
61832b31808SJens Wiklander                                           mbedtls_ssl_get_srtp_profile_as_string(
61932b31808SJens Wiklander                                               client_protection)));
62032b31808SJens Wiklander                 break;
62132b31808SJens Wiklander             }
62232b31808SJens Wiklander         }
62332b31808SJens Wiklander         if (ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_TLS_SRTP_UNSET) {
62432b31808SJens Wiklander             break;
62532b31808SJens Wiklander         }
62632b31808SJens Wiklander     }
62732b31808SJens Wiklander     buf += profile_length; /* buf points to the mki length */
62832b31808SJens Wiklander     mki_length = *buf;
62932b31808SJens Wiklander     buf++;
63032b31808SJens Wiklander 
63132b31808SJens Wiklander     if (mki_length > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH ||
63232b31808SJens Wiklander         mki_length + profile_length + size_of_lengths != len) {
63332b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
63432b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
63532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
63632b31808SJens Wiklander     }
63732b31808SJens Wiklander 
63832b31808SJens Wiklander     /* Parse the mki only if present and mki is supported locally */
63932b31808SJens Wiklander     if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED &&
64032b31808SJens Wiklander         mki_length > 0) {
64132b31808SJens Wiklander         ssl->dtls_srtp_info.mki_len = mki_length;
64232b31808SJens Wiklander 
64332b31808SJens Wiklander         memcpy(ssl->dtls_srtp_info.mki_value, buf, mki_length);
64432b31808SJens Wiklander 
64532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "using mki",  ssl->dtls_srtp_info.mki_value,
64632b31808SJens Wiklander                               ssl->dtls_srtp_info.mki_len);
64732b31808SJens Wiklander     }
64832b31808SJens Wiklander 
64932b31808SJens Wiklander     return 0;
65032b31808SJens Wiklander }
65132b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_SRTP */
65232b31808SJens Wiklander 
65332b31808SJens Wiklander /*
65432b31808SJens Wiklander  * Auxiliary functions for ServerHello parsing and related actions
65532b31808SJens Wiklander  */
65632b31808SJens Wiklander 
65732b31808SJens Wiklander #if defined(MBEDTLS_X509_CRT_PARSE_C)
65832b31808SJens Wiklander /*
65932b31808SJens Wiklander  * Return 0 if the given key uses one of the acceptable curves, -1 otherwise
66032b31808SJens Wiklander  */
661*b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
66232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
66332b31808SJens Wiklander static int ssl_check_key_curve(mbedtls_pk_context *pk,
66432b31808SJens Wiklander                                uint16_t *curves_tls_id)
66532b31808SJens Wiklander {
66632b31808SJens Wiklander     uint16_t *curr_tls_id = curves_tls_id;
667*b0563631STom Van Eyck     mbedtls_ecp_group_id grp_id = mbedtls_pk_get_ec_group_id(pk);
66832b31808SJens Wiklander     mbedtls_ecp_group_id curr_grp_id;
66932b31808SJens Wiklander 
67032b31808SJens Wiklander     while (*curr_tls_id != 0) {
67132b31808SJens Wiklander         curr_grp_id = mbedtls_ssl_get_ecp_group_id_from_tls_id(*curr_tls_id);
67232b31808SJens Wiklander         if (curr_grp_id == grp_id) {
67332b31808SJens Wiklander             return 0;
67432b31808SJens Wiklander         }
67532b31808SJens Wiklander         curr_tls_id++;
67632b31808SJens Wiklander     }
67732b31808SJens Wiklander 
67832b31808SJens Wiklander     return -1;
67932b31808SJens Wiklander }
680*b0563631STom Van Eyck #endif /* MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED */
68132b31808SJens Wiklander 
68232b31808SJens Wiklander /*
68332b31808SJens Wiklander  * Try picking a certificate for this ciphersuite,
68432b31808SJens Wiklander  * return 0 on success and -1 on failure.
68532b31808SJens Wiklander  */
68632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
68732b31808SJens Wiklander static int ssl_pick_cert(mbedtls_ssl_context *ssl,
68832b31808SJens Wiklander                          const mbedtls_ssl_ciphersuite_t *ciphersuite_info)
68932b31808SJens Wiklander {
69032b31808SJens Wiklander     mbedtls_ssl_key_cert *cur, *list;
69132b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
69232b31808SJens Wiklander     psa_algorithm_t pk_alg =
69332b31808SJens Wiklander         mbedtls_ssl_get_ciphersuite_sig_pk_psa_alg(ciphersuite_info);
69432b31808SJens Wiklander     psa_key_usage_t pk_usage =
69532b31808SJens Wiklander         mbedtls_ssl_get_ciphersuite_sig_pk_psa_usage(ciphersuite_info);
69632b31808SJens Wiklander #else
69732b31808SJens Wiklander     mbedtls_pk_type_t pk_alg =
69832b31808SJens Wiklander         mbedtls_ssl_get_ciphersuite_sig_pk_alg(ciphersuite_info);
69932b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
70032b31808SJens Wiklander     uint32_t flags;
70132b31808SJens Wiklander 
70232b31808SJens Wiklander #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
70332b31808SJens Wiklander     if (ssl->handshake->sni_key_cert != NULL) {
70432b31808SJens Wiklander         list = ssl->handshake->sni_key_cert;
70532b31808SJens Wiklander     } else
70632b31808SJens Wiklander #endif
70732b31808SJens Wiklander     list = ssl->conf->key_cert;
70832b31808SJens Wiklander 
70932b31808SJens Wiklander     int pk_alg_is_none = 0;
71032b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
71132b31808SJens Wiklander     pk_alg_is_none = (pk_alg == PSA_ALG_NONE);
71232b31808SJens Wiklander #else
71332b31808SJens Wiklander     pk_alg_is_none = (pk_alg == MBEDTLS_PK_NONE);
71432b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
71532b31808SJens Wiklander     if (pk_alg_is_none) {
71632b31808SJens Wiklander         return 0;
71732b31808SJens Wiklander     }
71832b31808SJens Wiklander 
71932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite requires certificate"));
72032b31808SJens Wiklander 
72132b31808SJens Wiklander     if (list == NULL) {
72232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("server has no certificate"));
72332b31808SJens Wiklander         return -1;
72432b31808SJens Wiklander     }
72532b31808SJens Wiklander 
72632b31808SJens Wiklander     for (cur = list; cur != NULL; cur = cur->next) {
72732b31808SJens Wiklander         flags = 0;
72832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_CRT(3, "candidate certificate chain, certificate",
72932b31808SJens Wiklander                               cur->cert);
73032b31808SJens Wiklander 
73132b31808SJens Wiklander         int key_type_matches = 0;
73232b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
73332b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
73432b31808SJens Wiklander         key_type_matches = ((ssl->conf->f_async_sign_start != NULL ||
73532b31808SJens Wiklander                              ssl->conf->f_async_decrypt_start != NULL ||
73632b31808SJens Wiklander                              mbedtls_pk_can_do_ext(cur->key, pk_alg, pk_usage)) &&
73732b31808SJens Wiklander                             mbedtls_pk_can_do_ext(&cur->cert->pk, pk_alg, pk_usage));
73832b31808SJens Wiklander #else
73932b31808SJens Wiklander         key_type_matches = (
74032b31808SJens Wiklander             mbedtls_pk_can_do_ext(cur->key, pk_alg, pk_usage));
74132b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
74232b31808SJens Wiklander #else
74332b31808SJens Wiklander         key_type_matches = mbedtls_pk_can_do(&cur->cert->pk, pk_alg);
74432b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
74532b31808SJens Wiklander         if (!key_type_matches) {
74632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: key type"));
74732b31808SJens Wiklander             continue;
74832b31808SJens Wiklander         }
74932b31808SJens Wiklander 
75032b31808SJens Wiklander         /*
75132b31808SJens Wiklander          * This avoids sending the client a cert it'll reject based on
75232b31808SJens Wiklander          * keyUsage or other extensions.
75332b31808SJens Wiklander          *
75432b31808SJens Wiklander          * It also allows the user to provision different certificates for
75532b31808SJens Wiklander          * different uses based on keyUsage, eg if they want to avoid signing
75632b31808SJens Wiklander          * and decrypting with the same RSA key.
75732b31808SJens Wiklander          */
75832b31808SJens Wiklander         if (mbedtls_ssl_check_cert_usage(cur->cert, ciphersuite_info,
75932b31808SJens Wiklander                                          MBEDTLS_SSL_IS_SERVER, &flags) != 0) {
76032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: "
76132b31808SJens Wiklander                                       "(extended) key usage extension"));
76232b31808SJens Wiklander             continue;
76332b31808SJens Wiklander         }
76432b31808SJens Wiklander 
765*b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
76632b31808SJens Wiklander         if (pk_alg == MBEDTLS_PK_ECDSA &&
76732b31808SJens Wiklander             ssl_check_key_curve(&cur->cert->pk,
76832b31808SJens Wiklander                                 ssl->handshake->curves_tls_id) != 0) {
76932b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: elliptic curve"));
77032b31808SJens Wiklander             continue;
77132b31808SJens Wiklander         }
77232b31808SJens Wiklander #endif
77332b31808SJens Wiklander 
77432b31808SJens Wiklander         /* If we get there, we got a winner */
77532b31808SJens Wiklander         break;
77632b31808SJens Wiklander     }
77732b31808SJens Wiklander 
77832b31808SJens Wiklander     /* Do not update ssl->handshake->key_cert unless there is a match */
77932b31808SJens Wiklander     if (cur != NULL) {
78032b31808SJens Wiklander         ssl->handshake->key_cert = cur;
78132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_CRT(3, "selected certificate chain, certificate",
78232b31808SJens Wiklander                               ssl->handshake->key_cert->cert);
78332b31808SJens Wiklander         return 0;
78432b31808SJens Wiklander     }
78532b31808SJens Wiklander 
78632b31808SJens Wiklander     return -1;
78732b31808SJens Wiklander }
78832b31808SJens Wiklander #endif /* MBEDTLS_X509_CRT_PARSE_C */
78932b31808SJens Wiklander 
79032b31808SJens Wiklander /*
79132b31808SJens Wiklander  * Check if a given ciphersuite is suitable for use with our config/keys/etc
79232b31808SJens Wiklander  * Sets ciphersuite_info only if the suite matches.
79332b31808SJens Wiklander  */
79432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
79532b31808SJens Wiklander static int ssl_ciphersuite_match(mbedtls_ssl_context *ssl, int suite_id,
79632b31808SJens Wiklander                                  const mbedtls_ssl_ciphersuite_t **ciphersuite_info)
79732b31808SJens Wiklander {
79832b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *suite_info;
79932b31808SJens Wiklander 
80032b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
80132b31808SJens Wiklander     mbedtls_pk_type_t sig_type;
80232b31808SJens Wiklander #endif
80332b31808SJens Wiklander 
80432b31808SJens Wiklander     suite_info = mbedtls_ssl_ciphersuite_from_id(suite_id);
80532b31808SJens Wiklander     if (suite_info == NULL) {
80632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
80732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
80832b31808SJens Wiklander     }
80932b31808SJens Wiklander 
81032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("trying ciphersuite: %#04x (%s)",
81132b31808SJens Wiklander                               (unsigned int) suite_id, suite_info->name));
81232b31808SJens Wiklander 
81332b31808SJens Wiklander     if (suite_info->min_tls_version > ssl->tls_version ||
81432b31808SJens Wiklander         suite_info->max_tls_version < ssl->tls_version) {
81532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: version"));
81632b31808SJens Wiklander         return 0;
81732b31808SJens Wiklander     }
81832b31808SJens Wiklander 
81932b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
82032b31808SJens Wiklander     if (suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
82132b31808SJens Wiklander         (ssl->handshake->cli_exts & MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK) == 0) {
82232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: ecjpake "
82332b31808SJens Wiklander                                   "not configured or ext missing"));
82432b31808SJens Wiklander         return 0;
82532b31808SJens Wiklander     }
82632b31808SJens Wiklander #endif
82732b31808SJens Wiklander 
82832b31808SJens Wiklander 
829*b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
830*b0563631STom Van Eyck     defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
83132b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_uses_ec(suite_info) &&
83232b31808SJens Wiklander         (ssl->handshake->curves_tls_id == NULL ||
83332b31808SJens Wiklander          ssl->handshake->curves_tls_id[0] == 0)) {
83432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: "
83532b31808SJens Wiklander                                   "no common elliptic curve"));
83632b31808SJens Wiklander         return 0;
83732b31808SJens Wiklander     }
83832b31808SJens Wiklander #endif
83932b31808SJens Wiklander 
84032b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
84132b31808SJens Wiklander     /* If the ciphersuite requires a pre-shared key and we don't
84232b31808SJens Wiklander      * have one, skip it now rather than failing later */
84332b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_uses_psk(suite_info) &&
84432b31808SJens Wiklander         ssl_conf_has_psk_or_cb(ssl->conf) == 0) {
84532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: no pre-shared key"));
84632b31808SJens Wiklander         return 0;
84732b31808SJens Wiklander     }
84832b31808SJens Wiklander #endif
84932b31808SJens Wiklander 
85032b31808SJens Wiklander #if defined(MBEDTLS_X509_CRT_PARSE_C)
85132b31808SJens Wiklander     /*
85232b31808SJens Wiklander      * Final check: if ciphersuite requires us to have a
85332b31808SJens Wiklander      * certificate/key of a particular type:
85432b31808SJens Wiklander      * - select the appropriate certificate if we have one, or
85532b31808SJens Wiklander      * - try the next ciphersuite if we don't
85632b31808SJens Wiklander      * This must be done last since we modify the key_cert list.
85732b31808SJens Wiklander      */
85832b31808SJens Wiklander     if (ssl_pick_cert(ssl, suite_info) != 0) {
85932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: "
86032b31808SJens Wiklander                                   "no suitable certificate"));
86132b31808SJens Wiklander         return 0;
86232b31808SJens Wiklander     }
86332b31808SJens Wiklander #endif
86432b31808SJens Wiklander 
86532b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
86632b31808SJens Wiklander     /* If the ciphersuite requires signing, check whether
86732b31808SJens Wiklander      * a suitable hash algorithm is present. */
86832b31808SJens Wiklander     sig_type = mbedtls_ssl_get_ciphersuite_sig_alg(suite_info);
86932b31808SJens Wiklander     if (sig_type != MBEDTLS_PK_NONE &&
87032b31808SJens Wiklander         mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
87132b31808SJens Wiklander             ssl, mbedtls_ssl_sig_from_pk_alg(sig_type)) == MBEDTLS_SSL_HASH_NONE) {
87232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: no suitable hash algorithm "
87332b31808SJens Wiklander                                   "for signature algorithm %u", (unsigned) sig_type));
87432b31808SJens Wiklander         return 0;
87532b31808SJens Wiklander     }
87632b31808SJens Wiklander 
87732b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
87832b31808SJens Wiklander 
87932b31808SJens Wiklander     *ciphersuite_info = suite_info;
88032b31808SJens Wiklander     return 0;
88132b31808SJens Wiklander }
88232b31808SJens Wiklander 
88332b31808SJens Wiklander /* This function doesn't alert on errors that happen early during
88432b31808SJens Wiklander    ClientHello parsing because they might indicate that the client is
88532b31808SJens Wiklander    not talking SSL/TLS at all and would not understand our alert. */
88632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
88732b31808SJens Wiklander static int ssl_parse_client_hello(mbedtls_ssl_context *ssl)
88832b31808SJens Wiklander {
88932b31808SJens Wiklander     int ret, got_common_suite;
89032b31808SJens Wiklander     size_t i, j;
89132b31808SJens Wiklander     size_t ciph_offset, comp_offset, ext_offset;
89232b31808SJens Wiklander     size_t msg_len, ciph_len, sess_len, comp_len, ext_len;
89332b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
89432b31808SJens Wiklander     size_t cookie_offset, cookie_len;
89532b31808SJens Wiklander #endif
89632b31808SJens Wiklander     unsigned char *buf, *p, *ext;
89732b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
89832b31808SJens Wiklander     int renegotiation_info_seen = 0;
89932b31808SJens Wiklander #endif
90032b31808SJens Wiklander     int handshake_failure = 0;
90132b31808SJens Wiklander     const int *ciphersuites;
90232b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
90332b31808SJens Wiklander 
90432b31808SJens Wiklander     /* If there is no signature-algorithm extension present,
90532b31808SJens Wiklander      * we need to fall back to the default values for allowed
90632b31808SJens Wiklander      * signature-hash pairs. */
90732b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
90832b31808SJens Wiklander     int sig_hash_alg_ext_present = 0;
90932b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
91032b31808SJens Wiklander 
91132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse client hello"));
91232b31808SJens Wiklander 
91332b31808SJens Wiklander     int renegotiating;
91432b31808SJens Wiklander 
91532b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
91632b31808SJens Wiklander read_record_header:
91732b31808SJens Wiklander #endif
91832b31808SJens Wiklander     /*
91932b31808SJens Wiklander      * If renegotiating, then the input was read with mbedtls_ssl_read_record(),
92032b31808SJens Wiklander      * otherwise read it ourselves manually in order to support SSLv2
92132b31808SJens Wiklander      * ClientHello, which doesn't use the same record layer format.
922*b0563631STom Van Eyck      * Otherwise in a scenario of TLS 1.3/TLS 1.2 version negotiation, the
923*b0563631STom Van Eyck      * ClientHello has been already fully fetched by the TLS 1.3 code and the
924*b0563631STom Van Eyck      * flag ssl->keep_current_message is raised.
92532b31808SJens Wiklander      */
92632b31808SJens Wiklander     renegotiating = 0;
92732b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
92832b31808SJens Wiklander     renegotiating = (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE);
92932b31808SJens Wiklander #endif
930*b0563631STom Van Eyck     if (!renegotiating && !ssl->keep_current_message) {
93132b31808SJens Wiklander         if ((ret = mbedtls_ssl_fetch_input(ssl, 5)) != 0) {
93232b31808SJens Wiklander             /* No alert on a read error. */
93332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
93432b31808SJens Wiklander             return ret;
93532b31808SJens Wiklander         }
93632b31808SJens Wiklander     }
93732b31808SJens Wiklander 
93832b31808SJens Wiklander     buf = ssl->in_hdr;
93932b31808SJens Wiklander 
94032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(4, "record header", buf, mbedtls_ssl_in_hdr_len(ssl));
94132b31808SJens Wiklander 
94232b31808SJens Wiklander     /*
94332b31808SJens Wiklander      * TLS Client Hello
94432b31808SJens Wiklander      *
94532b31808SJens Wiklander      * Record layer:
94632b31808SJens Wiklander      *     0  .   0   message type
94732b31808SJens Wiklander      *     1  .   2   protocol version
94832b31808SJens Wiklander      *     3  .   11  DTLS: epoch + record sequence number
94932b31808SJens Wiklander      *     3  .   4   message length
95032b31808SJens Wiklander      */
95132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, message type: %d",
95232b31808SJens Wiklander                               buf[0]));
95332b31808SJens Wiklander 
95432b31808SJens Wiklander     if (buf[0] != MBEDTLS_SSL_MSG_HANDSHAKE) {
95532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
95632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
95732b31808SJens Wiklander     }
95832b31808SJens Wiklander 
95932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, message len.: %d",
960*b0563631STom Van Eyck                               MBEDTLS_GET_UINT16_BE(ssl->in_len, 0)));
96132b31808SJens Wiklander 
96232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, protocol version: [%d:%d]",
96332b31808SJens Wiklander                               buf[1], buf[2]));
96432b31808SJens Wiklander 
96532b31808SJens Wiklander     /* For DTLS if this is the initial handshake, remember the client sequence
96632b31808SJens Wiklander      * number to use it in our next message (RFC 6347 4.2.1) */
96732b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
96832b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM
96932b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
97032b31808SJens Wiklander         && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE
97132b31808SJens Wiklander #endif
97232b31808SJens Wiklander         ) {
97332b31808SJens Wiklander         /* Epoch should be 0 for initial handshakes */
97432b31808SJens Wiklander         if (ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0) {
97532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
97632b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
97732b31808SJens Wiklander         }
97832b31808SJens Wiklander 
97932b31808SJens Wiklander         memcpy(&ssl->cur_out_ctr[2], ssl->in_ctr + 2,
98032b31808SJens Wiklander                sizeof(ssl->cur_out_ctr) - 2);
98132b31808SJens Wiklander 
98232b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
98332b31808SJens Wiklander         if (mbedtls_ssl_dtls_replay_check(ssl) != 0) {
98432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("replayed record, discarding"));
98532b31808SJens Wiklander             ssl->next_record_offset = 0;
98632b31808SJens Wiklander             ssl->in_left = 0;
98732b31808SJens Wiklander             goto read_record_header;
98832b31808SJens Wiklander         }
98932b31808SJens Wiklander 
99032b31808SJens Wiklander         /* No MAC to check yet, so we can update right now */
99132b31808SJens Wiklander         mbedtls_ssl_dtls_replay_update(ssl);
99232b31808SJens Wiklander #endif
99332b31808SJens Wiklander     }
99432b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */
99532b31808SJens Wiklander 
996*b0563631STom Van Eyck     msg_len = MBEDTLS_GET_UINT16_BE(ssl->in_len, 0);
99732b31808SJens Wiklander 
99832b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
99932b31808SJens Wiklander     if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
100032b31808SJens Wiklander         /* Set by mbedtls_ssl_read_record() */
100132b31808SJens Wiklander         msg_len = ssl->in_hslen;
100232b31808SJens Wiklander     } else
100332b31808SJens Wiklander #endif
100432b31808SJens Wiklander     {
1005*b0563631STom Van Eyck         if (ssl->keep_current_message) {
1006*b0563631STom Van Eyck             ssl->keep_current_message = 0;
1007*b0563631STom Van Eyck         } else {
100832b31808SJens Wiklander             if (msg_len > MBEDTLS_SSL_IN_CONTENT_LEN) {
100932b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
101032b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
101132b31808SJens Wiklander             }
101232b31808SJens Wiklander 
101332b31808SJens Wiklander             if ((ret = mbedtls_ssl_fetch_input(ssl,
101432b31808SJens Wiklander                                                mbedtls_ssl_in_hdr_len(ssl) + msg_len)) != 0) {
101532b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
101632b31808SJens Wiklander                 return ret;
101732b31808SJens Wiklander             }
101832b31808SJens Wiklander 
101932b31808SJens Wiklander             /* Done reading this record, get ready for the next one */
102032b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
102132b31808SJens Wiklander             if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
102232b31808SJens Wiklander                 ssl->next_record_offset = msg_len + mbedtls_ssl_in_hdr_len(ssl);
102332b31808SJens Wiklander             } else
102432b31808SJens Wiklander #endif
102532b31808SJens Wiklander             ssl->in_left = 0;
102632b31808SJens Wiklander         }
1027*b0563631STom Van Eyck     }
102832b31808SJens Wiklander 
102932b31808SJens Wiklander     buf = ssl->in_msg;
103032b31808SJens Wiklander 
103132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(4, "record contents", buf, msg_len);
103232b31808SJens Wiklander 
103332b31808SJens Wiklander     ret = ssl->handshake->update_checksum(ssl, buf, msg_len);
103432b31808SJens Wiklander     if (0 != ret) {
103532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret);
103632b31808SJens Wiklander         return ret;
103732b31808SJens Wiklander     }
103832b31808SJens Wiklander 
103932b31808SJens Wiklander     /*
104032b31808SJens Wiklander      * Handshake layer:
104132b31808SJens Wiklander      *     0  .   0   handshake type
104232b31808SJens Wiklander      *     1  .   3   handshake length
104332b31808SJens Wiklander      *     4  .   5   DTLS only: message sequence number
104432b31808SJens Wiklander      *     6  .   8   DTLS only: fragment offset
104532b31808SJens Wiklander      *     9  .  11   DTLS only: fragment length
104632b31808SJens Wiklander      */
104732b31808SJens Wiklander     if (msg_len < mbedtls_ssl_hs_hdr_len(ssl)) {
104832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
104932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
105032b31808SJens Wiklander     }
105132b31808SJens Wiklander 
105232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello v3, handshake type: %d", buf[0]));
105332b31808SJens Wiklander 
105432b31808SJens Wiklander     if (buf[0] != MBEDTLS_SSL_HS_CLIENT_HELLO) {
105532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
105632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
105732b31808SJens Wiklander     }
105832b31808SJens Wiklander     {
105932b31808SJens Wiklander         size_t handshake_len = MBEDTLS_GET_UINT24_BE(buf, 1);
106032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("client hello v3, handshake len.: %u",
106132b31808SJens Wiklander                                   (unsigned) handshake_len));
106232b31808SJens Wiklander 
106332b31808SJens Wiklander         /* The record layer has a record size limit of 2^14 - 1 and
106432b31808SJens Wiklander          * fragmentation is not supported, so buf[1] should be zero. */
106532b31808SJens Wiklander         if (buf[1] != 0) {
106632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message: %u != 0",
106732b31808SJens Wiklander                                       (unsigned) buf[1]));
106832b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
106932b31808SJens Wiklander         }
107032b31808SJens Wiklander 
107132b31808SJens Wiklander         /* We don't support fragmentation of ClientHello (yet?) */
107232b31808SJens Wiklander         if (msg_len != mbedtls_ssl_hs_hdr_len(ssl) + handshake_len) {
107332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message: %u != %u + %u",
107432b31808SJens Wiklander                                       (unsigned) msg_len,
107532b31808SJens Wiklander                                       (unsigned) mbedtls_ssl_hs_hdr_len(ssl),
107632b31808SJens Wiklander                                       (unsigned) handshake_len));
107732b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
107832b31808SJens Wiklander         }
107932b31808SJens Wiklander     }
108032b31808SJens Wiklander 
108132b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
108232b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
108332b31808SJens Wiklander         /*
108432b31808SJens Wiklander          * Copy the client's handshake message_seq on initial handshakes,
108532b31808SJens Wiklander          * check sequence number on renego.
108632b31808SJens Wiklander          */
108732b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
108832b31808SJens Wiklander         if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
108932b31808SJens Wiklander             /* This couldn't be done in ssl_prepare_handshake_record() */
1090*b0563631STom Van Eyck             unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
109132b31808SJens Wiklander             if (cli_msg_seq != ssl->handshake->in_msg_seq) {
109232b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message_seq: "
109332b31808SJens Wiklander                                           "%u (expected %u)", cli_msg_seq,
109432b31808SJens Wiklander                                           ssl->handshake->in_msg_seq));
109532b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_DECODE_ERROR;
109632b31808SJens Wiklander             }
109732b31808SJens Wiklander 
109832b31808SJens Wiklander             ssl->handshake->in_msg_seq++;
109932b31808SJens Wiklander         } else
110032b31808SJens Wiklander #endif
110132b31808SJens Wiklander         {
1102*b0563631STom Van Eyck             unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
110332b31808SJens Wiklander             ssl->handshake->out_msg_seq = cli_msg_seq;
110432b31808SJens Wiklander             ssl->handshake->in_msg_seq  = cli_msg_seq + 1;
110532b31808SJens Wiklander         }
110632b31808SJens Wiklander         {
110732b31808SJens Wiklander             /*
110832b31808SJens Wiklander              * For now we don't support fragmentation, so make sure
110932b31808SJens Wiklander              * fragment_offset == 0 and fragment_length == length
111032b31808SJens Wiklander              */
111132b31808SJens Wiklander             size_t fragment_offset, fragment_length, length;
111232b31808SJens Wiklander             fragment_offset = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 6);
111332b31808SJens Wiklander             fragment_length = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 9);
111432b31808SJens Wiklander             length = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 1);
111532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(
111632b31808SJens Wiklander                 4, ("fragment_offset=%u fragment_length=%u length=%u",
111732b31808SJens Wiklander                     (unsigned) fragment_offset, (unsigned) fragment_length,
111832b31808SJens Wiklander                     (unsigned) length));
111932b31808SJens Wiklander             if (fragment_offset != 0 || length != fragment_length) {
112032b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1, ("ClientHello fragmentation not supported"));
112132b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
112232b31808SJens Wiklander             }
112332b31808SJens Wiklander         }
112432b31808SJens Wiklander     }
112532b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */
112632b31808SJens Wiklander 
112732b31808SJens Wiklander     buf += mbedtls_ssl_hs_hdr_len(ssl);
112832b31808SJens Wiklander     msg_len -= mbedtls_ssl_hs_hdr_len(ssl);
112932b31808SJens Wiklander 
113032b31808SJens Wiklander     /*
1131*b0563631STom Van Eyck      * ClientHello layout:
113232b31808SJens Wiklander      *     0  .   1   protocol version
113332b31808SJens Wiklander      *     2  .  33   random bytes (starting with 4 bytes of Unix time)
1134*b0563631STom Van Eyck      *    34  .  34   session id length (1 byte)
1135*b0563631STom Van Eyck      *    35  . 34+x  session id, where x = session id length from byte 34
113632b31808SJens Wiklander      *   35+x . 35+x  DTLS only: cookie length (1 byte)
113732b31808SJens Wiklander      *   36+x .  ..   DTLS only: cookie
113832b31808SJens Wiklander      *    ..  .  ..   ciphersuite list length (2 bytes)
113932b31808SJens Wiklander      *    ..  .  ..   ciphersuite list
114032b31808SJens Wiklander      *    ..  .  ..   compression alg. list length (1 byte)
114132b31808SJens Wiklander      *    ..  .  ..   compression alg. list
114232b31808SJens Wiklander      *    ..  .  ..   extensions length (2 bytes, optional)
114332b31808SJens Wiklander      *    ..  .  ..   extensions (optional)
114432b31808SJens Wiklander      */
114532b31808SJens Wiklander 
114632b31808SJens Wiklander     /*
114732b31808SJens Wiklander      * Minimal length (with everything empty and extensions omitted) is
114832b31808SJens Wiklander      * 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can
114932b31808SJens Wiklander      * read at least up to session id length without worrying.
115032b31808SJens Wiklander      */
115132b31808SJens Wiklander     if (msg_len < 38) {
115232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
115332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
115432b31808SJens Wiklander     }
115532b31808SJens Wiklander 
115632b31808SJens Wiklander     /*
115732b31808SJens Wiklander      * Check and save the protocol version
115832b31808SJens Wiklander      */
115932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, version", buf, 2);
116032b31808SJens Wiklander 
1161*b0563631STom Van Eyck     ssl->tls_version = (mbedtls_ssl_protocol_version) mbedtls_ssl_read_version(buf,
1162*b0563631STom Van Eyck                                                                                ssl->conf->transport);
116332b31808SJens Wiklander     ssl->session_negotiate->tls_version = ssl->tls_version;
1164*b0563631STom Van Eyck     ssl->session_negotiate->endpoint = ssl->conf->endpoint;
116532b31808SJens Wiklander 
116632b31808SJens Wiklander     if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_2) {
116732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("server only supports TLS 1.2"));
116832b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
116932b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION);
117032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
117132b31808SJens Wiklander     }
117232b31808SJens Wiklander 
117332b31808SJens Wiklander     /*
117432b31808SJens Wiklander      * Save client random (inc. Unix time)
117532b31808SJens Wiklander      */
117632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, random bytes", buf + 2, 32);
117732b31808SJens Wiklander 
117832b31808SJens Wiklander     memcpy(ssl->handshake->randbytes, buf + 2, 32);
117932b31808SJens Wiklander 
118032b31808SJens Wiklander     /*
118132b31808SJens Wiklander      * Check the session ID length and save session ID
118232b31808SJens Wiklander      */
118332b31808SJens Wiklander     sess_len = buf[34];
118432b31808SJens Wiklander 
118532b31808SJens Wiklander     if (sess_len > sizeof(ssl->session_negotiate->id) ||
118632b31808SJens Wiklander         sess_len + 34 + 2 > msg_len) { /* 2 for cipherlist length field */
118732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
118832b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
118932b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
119032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
119132b31808SJens Wiklander     }
119232b31808SJens Wiklander 
119332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, session id", buf + 35, sess_len);
119432b31808SJens Wiklander 
119532b31808SJens Wiklander     ssl->session_negotiate->id_len = sess_len;
119632b31808SJens Wiklander     memset(ssl->session_negotiate->id, 0,
119732b31808SJens Wiklander            sizeof(ssl->session_negotiate->id));
119832b31808SJens Wiklander     memcpy(ssl->session_negotiate->id, buf + 35,
119932b31808SJens Wiklander            ssl->session_negotiate->id_len);
120032b31808SJens Wiklander 
120132b31808SJens Wiklander     /*
120232b31808SJens Wiklander      * Check the cookie length and content
120332b31808SJens Wiklander      */
120432b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
120532b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
120632b31808SJens Wiklander         cookie_offset = 35 + sess_len;
120732b31808SJens Wiklander         cookie_len = buf[cookie_offset];
120832b31808SJens Wiklander 
120932b31808SJens Wiklander         if (cookie_offset + 1 + cookie_len + 2 > msg_len) {
121032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
121132b31808SJens Wiklander             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
121232b31808SJens Wiklander                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
121332b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
121432b31808SJens Wiklander         }
121532b31808SJens Wiklander 
121632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "client hello, cookie",
121732b31808SJens Wiklander                               buf + cookie_offset + 1, cookie_len);
121832b31808SJens Wiklander 
121932b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
122032b31808SJens Wiklander         if (ssl->conf->f_cookie_check != NULL
122132b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
122232b31808SJens Wiklander             && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE
122332b31808SJens Wiklander #endif
122432b31808SJens Wiklander             ) {
122532b31808SJens Wiklander             if (ssl->conf->f_cookie_check(ssl->conf->p_cookie,
122632b31808SJens Wiklander                                           buf + cookie_offset + 1, cookie_len,
122732b31808SJens Wiklander                                           ssl->cli_id, ssl->cli_id_len) != 0) {
122832b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(2, ("cookie verification failed"));
122932b31808SJens Wiklander                 ssl->handshake->cookie_verify_result = 1;
123032b31808SJens Wiklander             } else {
123132b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(2, ("cookie verification passed"));
123232b31808SJens Wiklander                 ssl->handshake->cookie_verify_result = 0;
123332b31808SJens Wiklander             }
123432b31808SJens Wiklander         } else
123532b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
123632b31808SJens Wiklander         {
123732b31808SJens Wiklander             /* We know we didn't send a cookie, so it should be empty */
123832b31808SJens Wiklander             if (cookie_len != 0) {
123932b31808SJens Wiklander                 /* This may be an attacker's probe, so don't send an alert */
124032b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
124132b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_DECODE_ERROR;
124232b31808SJens Wiklander             }
124332b31808SJens Wiklander 
124432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2, ("cookie verification skipped"));
124532b31808SJens Wiklander         }
124632b31808SJens Wiklander 
124732b31808SJens Wiklander         /*
124832b31808SJens Wiklander          * Check the ciphersuitelist length (will be parsed later)
124932b31808SJens Wiklander          */
125032b31808SJens Wiklander         ciph_offset = cookie_offset + 1 + cookie_len;
125132b31808SJens Wiklander     } else
125232b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */
125332b31808SJens Wiklander     ciph_offset = 35 + sess_len;
125432b31808SJens Wiklander 
1255*b0563631STom Van Eyck     ciph_len = MBEDTLS_GET_UINT16_BE(buf, ciph_offset);
125632b31808SJens Wiklander 
125732b31808SJens Wiklander     if (ciph_len < 2 ||
125832b31808SJens Wiklander         ciph_len + 2 + ciph_offset + 1 > msg_len || /* 1 for comp. alg. len */
125932b31808SJens Wiklander         (ciph_len % 2) != 0) {
126032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
126132b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
126232b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
126332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
126432b31808SJens Wiklander     }
126532b31808SJens Wiklander 
126632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, ciphersuitelist",
126732b31808SJens Wiklander                           buf + ciph_offset + 2,  ciph_len);
126832b31808SJens Wiklander 
126932b31808SJens Wiklander     /*
127032b31808SJens Wiklander      * Check the compression algorithm's length.
127132b31808SJens Wiklander      * The list contents are ignored because implementing
127232b31808SJens Wiklander      * MBEDTLS_SSL_COMPRESS_NULL is mandatory and is the only
127332b31808SJens Wiklander      * option supported by Mbed TLS.
127432b31808SJens Wiklander      */
127532b31808SJens Wiklander     comp_offset = ciph_offset + 2 + ciph_len;
127632b31808SJens Wiklander 
127732b31808SJens Wiklander     comp_len = buf[comp_offset];
127832b31808SJens Wiklander 
127932b31808SJens Wiklander     if (comp_len < 1 ||
128032b31808SJens Wiklander         comp_len > 16 ||
128132b31808SJens Wiklander         comp_len + comp_offset + 1 > msg_len) {
128232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
128332b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
128432b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
128532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
128632b31808SJens Wiklander     }
128732b31808SJens Wiklander 
128832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, compression",
128932b31808SJens Wiklander                           buf + comp_offset + 1, comp_len);
129032b31808SJens Wiklander 
129132b31808SJens Wiklander     /*
129232b31808SJens Wiklander      * Check the extension length
129332b31808SJens Wiklander      */
129432b31808SJens Wiklander     ext_offset = comp_offset + 1 + comp_len;
129532b31808SJens Wiklander     if (msg_len > ext_offset) {
129632b31808SJens Wiklander         if (msg_len < ext_offset + 2) {
129732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
129832b31808SJens Wiklander             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
129932b31808SJens Wiklander                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
130032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
130132b31808SJens Wiklander         }
130232b31808SJens Wiklander 
1303*b0563631STom Van Eyck         ext_len = MBEDTLS_GET_UINT16_BE(buf, ext_offset);
130432b31808SJens Wiklander 
130532b31808SJens Wiklander         if (msg_len != ext_offset + 2 + ext_len) {
130632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
130732b31808SJens Wiklander             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
130832b31808SJens Wiklander                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
130932b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
131032b31808SJens Wiklander         }
131132b31808SJens Wiklander     } else {
131232b31808SJens Wiklander         ext_len = 0;
131332b31808SJens Wiklander     }
131432b31808SJens Wiklander 
131532b31808SJens Wiklander     ext = buf + ext_offset + 2;
131632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "client hello extensions", ext, ext_len);
131732b31808SJens Wiklander 
131832b31808SJens Wiklander     while (ext_len != 0) {
131932b31808SJens Wiklander         unsigned int ext_id;
132032b31808SJens Wiklander         unsigned int ext_size;
132132b31808SJens Wiklander         if (ext_len < 4) {
132232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client 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         }
1327*b0563631STom Van Eyck         ext_id   = MBEDTLS_GET_UINT16_BE(ext, 0);
1328*b0563631STom Van Eyck         ext_size = MBEDTLS_GET_UINT16_BE(ext, 2);
132932b31808SJens Wiklander 
133032b31808SJens Wiklander         if (ext_size + 4 > ext_len) {
133132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
133232b31808SJens Wiklander             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
133332b31808SJens Wiklander                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
133432b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
133532b31808SJens Wiklander         }
133632b31808SJens Wiklander         switch (ext_id) {
133732b31808SJens Wiklander #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
133832b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SERVERNAME:
133932b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found ServerName extension"));
134032b31808SJens Wiklander                 ret = mbedtls_ssl_parse_server_name_ext(ssl, ext + 4,
134132b31808SJens Wiklander                                                         ext + 4 + ext_size);
134232b31808SJens Wiklander                 if (ret != 0) {
134332b31808SJens Wiklander                     return ret;
134432b31808SJens Wiklander                 }
134532b31808SJens Wiklander                 break;
134632b31808SJens Wiklander #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
134732b31808SJens Wiklander 
134832b31808SJens Wiklander             case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
134932b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found renegotiation extension"));
135032b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
135132b31808SJens Wiklander                 renegotiation_info_seen = 1;
135232b31808SJens Wiklander #endif
135332b31808SJens Wiklander 
135432b31808SJens Wiklander                 ret = ssl_parse_renegotiation_info(ssl, ext + 4, ext_size);
135532b31808SJens Wiklander                 if (ret != 0) {
135632b31808SJens Wiklander                     return ret;
135732b31808SJens Wiklander                 }
135832b31808SJens Wiklander                 break;
135932b31808SJens Wiklander 
136032b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
136132b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SIG_ALG:
136232b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found signature_algorithms extension"));
136332b31808SJens Wiklander 
136432b31808SJens Wiklander                 ret = mbedtls_ssl_parse_sig_alg_ext(ssl, ext + 4, ext + 4 + ext_size);
136532b31808SJens Wiklander                 if (ret != 0) {
136632b31808SJens Wiklander                     return ret;
136732b31808SJens Wiklander                 }
136832b31808SJens Wiklander 
136932b31808SJens Wiklander                 sig_hash_alg_ext_present = 1;
137032b31808SJens Wiklander                 break;
137132b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
137232b31808SJens Wiklander 
1373*b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
1374*b0563631STom Van Eyck                 defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
137532b31808SJens Wiklander                 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
137632b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SUPPORTED_GROUPS:
137732b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found supported elliptic curves extension"));
137832b31808SJens Wiklander 
137932b31808SJens Wiklander                 ret = ssl_parse_supported_groups_ext(ssl, ext + 4, ext_size);
138032b31808SJens Wiklander                 if (ret != 0) {
138132b31808SJens Wiklander                     return ret;
138232b31808SJens Wiklander                 }
138332b31808SJens Wiklander                 break;
138432b31808SJens Wiklander 
138532b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
138632b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found supported point formats extension"));
138732b31808SJens Wiklander                 ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT;
138832b31808SJens Wiklander 
138932b31808SJens Wiklander                 ret = ssl_parse_supported_point_formats(ssl, ext + 4, ext_size);
139032b31808SJens Wiklander                 if (ret != 0) {
139132b31808SJens Wiklander                     return ret;
139232b31808SJens Wiklander                 }
139332b31808SJens Wiklander                 break;
1394*b0563631STom Van Eyck #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || \
1395*b0563631STom Van Eyck           MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED ||
139632b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
139732b31808SJens Wiklander 
139832b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
139932b31808SJens Wiklander             case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
140032b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found ecjpake kkpp extension"));
140132b31808SJens Wiklander 
140232b31808SJens Wiklander                 ret = ssl_parse_ecjpake_kkpp(ssl, ext + 4, ext_size);
140332b31808SJens Wiklander                 if (ret != 0) {
140432b31808SJens Wiklander                     return ret;
140532b31808SJens Wiklander                 }
140632b31808SJens Wiklander                 break;
140732b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
140832b31808SJens Wiklander 
140932b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
141032b31808SJens Wiklander             case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
141132b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found max fragment length extension"));
141232b31808SJens Wiklander 
141332b31808SJens Wiklander                 ret = ssl_parse_max_fragment_length_ext(ssl, ext + 4, ext_size);
141432b31808SJens Wiklander                 if (ret != 0) {
141532b31808SJens Wiklander                     return ret;
141632b31808SJens Wiklander                 }
141732b31808SJens Wiklander                 break;
141832b31808SJens Wiklander #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
141932b31808SJens Wiklander 
142032b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
142132b31808SJens Wiklander             case MBEDTLS_TLS_EXT_CID:
142232b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found CID extension"));
142332b31808SJens Wiklander 
142432b31808SJens Wiklander                 ret = ssl_parse_cid_ext(ssl, ext + 4, ext_size);
142532b31808SJens Wiklander                 if (ret != 0) {
142632b31808SJens Wiklander                     return ret;
142732b31808SJens Wiklander                 }
142832b31808SJens Wiklander                 break;
142932b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
143032b31808SJens Wiklander 
143132b31808SJens Wiklander #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
143232b31808SJens Wiklander             case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
143332b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found encrypt then mac extension"));
143432b31808SJens Wiklander 
143532b31808SJens Wiklander                 ret = ssl_parse_encrypt_then_mac_ext(ssl, ext + 4, ext_size);
143632b31808SJens Wiklander                 if (ret != 0) {
143732b31808SJens Wiklander                     return ret;
143832b31808SJens Wiklander                 }
143932b31808SJens Wiklander                 break;
144032b31808SJens Wiklander #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
144132b31808SJens Wiklander 
144232b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
144332b31808SJens Wiklander             case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
144432b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found extended master secret extension"));
144532b31808SJens Wiklander 
144632b31808SJens Wiklander                 ret = ssl_parse_extended_ms_ext(ssl, ext + 4, ext_size);
144732b31808SJens Wiklander                 if (ret != 0) {
144832b31808SJens Wiklander                     return ret;
144932b31808SJens Wiklander                 }
145032b31808SJens Wiklander                 break;
145132b31808SJens Wiklander #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
145232b31808SJens Wiklander 
145332b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
145432b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SESSION_TICKET:
145532b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found session ticket extension"));
145632b31808SJens Wiklander 
145732b31808SJens Wiklander                 ret = ssl_parse_session_ticket_ext(ssl, ext + 4, ext_size);
145832b31808SJens Wiklander                 if (ret != 0) {
145932b31808SJens Wiklander                     return ret;
146032b31808SJens Wiklander                 }
146132b31808SJens Wiklander                 break;
146232b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
146332b31808SJens Wiklander 
146432b31808SJens Wiklander #if defined(MBEDTLS_SSL_ALPN)
146532b31808SJens Wiklander             case MBEDTLS_TLS_EXT_ALPN:
146632b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found alpn extension"));
146732b31808SJens Wiklander 
146832b31808SJens Wiklander                 ret = mbedtls_ssl_parse_alpn_ext(ssl, ext + 4,
146932b31808SJens Wiklander                                                  ext + 4 + ext_size);
147032b31808SJens Wiklander                 if (ret != 0) {
147132b31808SJens Wiklander                     return ret;
147232b31808SJens Wiklander                 }
147332b31808SJens Wiklander                 break;
147432b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
147532b31808SJens Wiklander 
147632b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP)
147732b31808SJens Wiklander             case MBEDTLS_TLS_EXT_USE_SRTP:
147832b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found use_srtp extension"));
147932b31808SJens Wiklander 
148032b31808SJens Wiklander                 ret = ssl_parse_use_srtp_ext(ssl, ext + 4, ext_size);
148132b31808SJens Wiklander                 if (ret != 0) {
148232b31808SJens Wiklander                     return ret;
148332b31808SJens Wiklander                 }
148432b31808SJens Wiklander                 break;
148532b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_SRTP */
148632b31808SJens Wiklander 
148732b31808SJens Wiklander             default:
148832b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("unknown extension found: %u (ignoring)",
148932b31808SJens Wiklander                                           ext_id));
149032b31808SJens Wiklander         }
149132b31808SJens Wiklander 
149232b31808SJens Wiklander         ext_len -= 4 + ext_size;
149332b31808SJens Wiklander         ext += 4 + ext_size;
149432b31808SJens Wiklander     }
149532b31808SJens Wiklander 
149632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
149732b31808SJens Wiklander 
149832b31808SJens Wiklander     /*
149932b31808SJens Wiklander      * Try to fall back to default hash SHA1 if the client
150032b31808SJens Wiklander      * hasn't provided any preferred signature-hash combinations.
150132b31808SJens Wiklander      */
150232b31808SJens Wiklander     if (!sig_hash_alg_ext_present) {
150332b31808SJens Wiklander         uint16_t *received_sig_algs = ssl->handshake->received_sig_algs;
150432b31808SJens Wiklander         const uint16_t default_sig_algs[] = {
1505*b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
150632b31808SJens Wiklander             MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA,
150732b31808SJens Wiklander                                                MBEDTLS_SSL_HASH_SHA1),
150832b31808SJens Wiklander #endif
150932b31808SJens Wiklander #if defined(MBEDTLS_RSA_C)
151032b31808SJens Wiklander             MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA,
151132b31808SJens Wiklander                                                MBEDTLS_SSL_HASH_SHA1),
151232b31808SJens Wiklander #endif
151332b31808SJens Wiklander             MBEDTLS_TLS_SIG_NONE
151432b31808SJens Wiklander         };
151532b31808SJens Wiklander 
151632b31808SJens Wiklander         MBEDTLS_STATIC_ASSERT(sizeof(default_sig_algs) / sizeof(default_sig_algs[0])
151732b31808SJens Wiklander                               <= MBEDTLS_RECEIVED_SIG_ALGS_SIZE,
151832b31808SJens Wiklander                               "default_sig_algs is too big");
151932b31808SJens Wiklander 
152032b31808SJens Wiklander         memcpy(received_sig_algs, default_sig_algs, sizeof(default_sig_algs));
152132b31808SJens Wiklander     }
152232b31808SJens Wiklander 
152332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
152432b31808SJens Wiklander 
152532b31808SJens Wiklander     /*
152632b31808SJens Wiklander      * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
152732b31808SJens Wiklander      */
152832b31808SJens Wiklander     for (i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2) {
152932b31808SJens Wiklander         if (p[0] == 0 && p[1] == MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO) {
153032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3, ("received TLS_EMPTY_RENEGOTIATION_INFO "));
153132b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
153232b31808SJens Wiklander             if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
153332b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1, ("received RENEGOTIATION SCSV "
153432b31808SJens Wiklander                                           "during renegotiation"));
153532b31808SJens Wiklander                 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
153632b31808SJens Wiklander                                                MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
153732b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
153832b31808SJens Wiklander             }
153932b31808SJens Wiklander #endif
154032b31808SJens Wiklander             ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
154132b31808SJens Wiklander             break;
154232b31808SJens Wiklander         }
154332b31808SJens Wiklander     }
154432b31808SJens Wiklander 
154532b31808SJens Wiklander     /*
154632b31808SJens Wiklander      * Renegotiation security checks
154732b31808SJens Wiklander      */
154832b31808SJens Wiklander     if (ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION &&
154932b31808SJens Wiklander         ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE) {
155032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("legacy renegotiation, breaking off handshake"));
155132b31808SJens Wiklander         handshake_failure = 1;
155232b31808SJens Wiklander     }
155332b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
155432b31808SJens Wiklander     else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
155532b31808SJens Wiklander              ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION &&
155632b31808SJens Wiklander              renegotiation_info_seen == 0) {
155732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("renegotiation_info extension missing (secure)"));
155832b31808SJens Wiklander         handshake_failure = 1;
155932b31808SJens Wiklander     } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
156032b31808SJens Wiklander                ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
156132b31808SJens Wiklander                ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION) {
156232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("legacy renegotiation not allowed"));
156332b31808SJens Wiklander         handshake_failure = 1;
156432b31808SJens Wiklander     } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
156532b31808SJens Wiklander                ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
156632b31808SJens Wiklander                renegotiation_info_seen == 1) {
156732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("renegotiation_info extension present (legacy)"));
156832b31808SJens Wiklander         handshake_failure = 1;
156932b31808SJens Wiklander     }
157032b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */
157132b31808SJens Wiklander 
157232b31808SJens Wiklander     if (handshake_failure == 1) {
157332b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
157432b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
157532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
157632b31808SJens Wiklander     }
157732b31808SJens Wiklander 
157832b31808SJens Wiklander     /*
157932b31808SJens Wiklander      * Server certification selection (after processing TLS extensions)
158032b31808SJens Wiklander      */
158132b31808SJens Wiklander     if (ssl->conf->f_cert_cb && (ret = ssl->conf->f_cert_cb(ssl)) != 0) {
158232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "f_cert_cb", ret);
158332b31808SJens Wiklander         return ret;
158432b31808SJens Wiklander     }
158532b31808SJens Wiklander #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
158632b31808SJens Wiklander     ssl->handshake->sni_name = NULL;
158732b31808SJens Wiklander     ssl->handshake->sni_name_len = 0;
158832b31808SJens Wiklander #endif
158932b31808SJens Wiklander 
159032b31808SJens Wiklander     /*
159132b31808SJens Wiklander      * Search for a matching ciphersuite
159232b31808SJens Wiklander      * (At the end because we need information from the EC-based extensions
159332b31808SJens Wiklander      * and certificate from the SNI callback triggered by the SNI extension
159432b31808SJens Wiklander      * or certificate from server certificate selection callback.)
159532b31808SJens Wiklander      */
159632b31808SJens Wiklander     got_common_suite = 0;
159732b31808SJens Wiklander     ciphersuites = ssl->conf->ciphersuite_list;
159832b31808SJens Wiklander     ciphersuite_info = NULL;
159932b31808SJens Wiklander 
160032b31808SJens Wiklander     if (ssl->conf->respect_cli_pref == MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT) {
160132b31808SJens Wiklander         for (j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2) {
160232b31808SJens Wiklander             for (i = 0; ciphersuites[i] != 0; i++) {
160332b31808SJens Wiklander                 if (MBEDTLS_GET_UINT16_BE(p, 0) != ciphersuites[i]) {
160432b31808SJens Wiklander                     continue;
160532b31808SJens Wiklander                 }
160632b31808SJens Wiklander 
160732b31808SJens Wiklander                 got_common_suite = 1;
160832b31808SJens Wiklander 
160932b31808SJens Wiklander                 if ((ret = ssl_ciphersuite_match(ssl, ciphersuites[i],
161032b31808SJens Wiklander                                                  &ciphersuite_info)) != 0) {
161132b31808SJens Wiklander                     return ret;
161232b31808SJens Wiklander                 }
161332b31808SJens Wiklander 
161432b31808SJens Wiklander                 if (ciphersuite_info != NULL) {
161532b31808SJens Wiklander                     goto have_ciphersuite;
161632b31808SJens Wiklander                 }
161732b31808SJens Wiklander             }
161832b31808SJens Wiklander         }
161932b31808SJens Wiklander     } else {
162032b31808SJens Wiklander         for (i = 0; ciphersuites[i] != 0; i++) {
162132b31808SJens Wiklander             for (j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2) {
162232b31808SJens Wiklander                 if (MBEDTLS_GET_UINT16_BE(p, 0) != ciphersuites[i]) {
162332b31808SJens Wiklander                     continue;
162432b31808SJens Wiklander                 }
162532b31808SJens Wiklander 
162632b31808SJens Wiklander                 got_common_suite = 1;
162732b31808SJens Wiklander 
162832b31808SJens Wiklander                 if ((ret = ssl_ciphersuite_match(ssl, ciphersuites[i],
162932b31808SJens Wiklander                                                  &ciphersuite_info)) != 0) {
163032b31808SJens Wiklander                     return ret;
163132b31808SJens Wiklander                 }
163232b31808SJens Wiklander 
163332b31808SJens Wiklander                 if (ciphersuite_info != NULL) {
163432b31808SJens Wiklander                     goto have_ciphersuite;
163532b31808SJens Wiklander                 }
163632b31808SJens Wiklander             }
163732b31808SJens Wiklander         }
163832b31808SJens Wiklander     }
163932b31808SJens Wiklander 
164032b31808SJens Wiklander     if (got_common_suite) {
164132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got ciphersuites in common, "
164232b31808SJens Wiklander                                   "but none of them usable"));
164332b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
164432b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
164532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
164632b31808SJens Wiklander     } else {
164732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got no ciphersuites in common"));
164832b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
164932b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
165032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
165132b31808SJens Wiklander     }
165232b31808SJens Wiklander 
165332b31808SJens Wiklander have_ciphersuite:
165432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("selected ciphersuite: %s", ciphersuite_info->name));
165532b31808SJens Wiklander 
165632b31808SJens Wiklander     ssl->session_negotiate->ciphersuite = ciphersuites[i];
165732b31808SJens Wiklander     ssl->handshake->ciphersuite_info = ciphersuite_info;
165832b31808SJens Wiklander 
165932b31808SJens Wiklander     ssl->state++;
166032b31808SJens Wiklander 
166132b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
166232b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
166332b31808SJens Wiklander         mbedtls_ssl_recv_flight_completed(ssl);
166432b31808SJens Wiklander     }
166532b31808SJens Wiklander #endif
166632b31808SJens Wiklander 
166732b31808SJens Wiklander     /* Debugging-only output for testsuite */
166832b31808SJens Wiklander #if defined(MBEDTLS_DEBUG_C)                         && \
166932b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
167032b31808SJens Wiklander     mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_alg(ciphersuite_info);
167132b31808SJens Wiklander     if (sig_alg != MBEDTLS_PK_NONE) {
167232b31808SJens Wiklander         unsigned int sig_hash = mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
167332b31808SJens Wiklander             ssl, mbedtls_ssl_sig_from_pk_alg(sig_alg));
167432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("client hello v3, signature_algorithm ext: %u",
167532b31808SJens Wiklander                                   sig_hash));
167632b31808SJens Wiklander     } else {
167732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("no hash algorithm for signature algorithm "
167832b31808SJens Wiklander                                   "%u - should not happen", (unsigned) sig_alg));
167932b31808SJens Wiklander     }
168032b31808SJens Wiklander #endif
168132b31808SJens Wiklander 
168232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse client hello"));
168332b31808SJens Wiklander 
168432b31808SJens Wiklander     return 0;
168532b31808SJens Wiklander }
168632b31808SJens Wiklander 
168732b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
168832b31808SJens Wiklander static void ssl_write_cid_ext(mbedtls_ssl_context *ssl,
168932b31808SJens Wiklander                               unsigned char *buf,
169032b31808SJens Wiklander                               size_t *olen)
169132b31808SJens Wiklander {
169232b31808SJens Wiklander     unsigned char *p = buf;
169332b31808SJens Wiklander     size_t ext_len;
169432b31808SJens Wiklander     const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
169532b31808SJens Wiklander 
169632b31808SJens Wiklander     *olen = 0;
169732b31808SJens Wiklander 
169832b31808SJens Wiklander     /* Skip writing the extension if we don't want to use it or if
169932b31808SJens Wiklander      * the client hasn't offered it. */
170032b31808SJens Wiklander     if (ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_DISABLED) {
170132b31808SJens Wiklander         return;
170232b31808SJens Wiklander     }
170332b31808SJens Wiklander 
170432b31808SJens Wiklander     /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX
170532b31808SJens Wiklander      * which is at most 255, so the increment cannot overflow. */
170632b31808SJens Wiklander     if (end < p || (size_t) (end - p) < (unsigned) (ssl->own_cid_len + 5)) {
170732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small"));
170832b31808SJens Wiklander         return;
170932b31808SJens Wiklander     }
171032b31808SJens Wiklander 
171132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding CID extension"));
171232b31808SJens Wiklander 
171332b31808SJens Wiklander     /*
171432b31808SJens Wiklander      *   struct {
171532b31808SJens Wiklander      *      opaque cid<0..2^8-1>;
171632b31808SJens Wiklander      *   } ConnectionId;
171732b31808SJens Wiklander      */
171832b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_CID, p, 0);
171932b31808SJens Wiklander     p += 2;
172032b31808SJens Wiklander     ext_len = (size_t) ssl->own_cid_len + 1;
172132b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(ext_len, p, 0);
172232b31808SJens Wiklander     p += 2;
172332b31808SJens Wiklander 
172432b31808SJens Wiklander     *p++ = (uint8_t) ssl->own_cid_len;
172532b31808SJens Wiklander     memcpy(p, ssl->own_cid, ssl->own_cid_len);
172632b31808SJens Wiklander 
172732b31808SJens Wiklander     *olen = ssl->own_cid_len + 5;
172832b31808SJens Wiklander }
172932b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
173032b31808SJens Wiklander 
173132b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM)
173232b31808SJens Wiklander static void ssl_write_encrypt_then_mac_ext(mbedtls_ssl_context *ssl,
173332b31808SJens Wiklander                                            unsigned char *buf,
173432b31808SJens Wiklander                                            size_t *olen)
173532b31808SJens Wiklander {
173632b31808SJens Wiklander     unsigned char *p = buf;
173732b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *suite = NULL;
173832b31808SJens Wiklander 
173932b31808SJens Wiklander     /*
174032b31808SJens Wiklander      * RFC 7366: "If a server receives an encrypt-then-MAC request extension
174132b31808SJens Wiklander      * from a client and then selects a stream or Authenticated Encryption
174232b31808SJens Wiklander      * with Associated Data (AEAD) ciphersuite, it MUST NOT send an
174332b31808SJens Wiklander      * encrypt-then-MAC response extension back to the client."
174432b31808SJens Wiklander      */
174532b31808SJens Wiklander     suite = mbedtls_ssl_ciphersuite_from_id(
174632b31808SJens Wiklander         ssl->session_negotiate->ciphersuite);
174732b31808SJens Wiklander     if (suite == NULL) {
174832b31808SJens Wiklander         ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_DISABLED;
174932b31808SJens Wiklander     } else {
175032b31808SJens Wiklander         mbedtls_ssl_mode_t ssl_mode =
175132b31808SJens Wiklander             mbedtls_ssl_get_mode_from_ciphersuite(
175232b31808SJens Wiklander                 ssl->session_negotiate->encrypt_then_mac,
175332b31808SJens Wiklander                 suite);
175432b31808SJens Wiklander 
175532b31808SJens Wiklander         if (ssl_mode != MBEDTLS_SSL_MODE_CBC_ETM) {
175632b31808SJens Wiklander             ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_DISABLED;
175732b31808SJens Wiklander         }
175832b31808SJens Wiklander     }
175932b31808SJens Wiklander 
176032b31808SJens Wiklander     if (ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED) {
176132b31808SJens Wiklander         *olen = 0;
176232b31808SJens Wiklander         return;
176332b31808SJens Wiklander     }
176432b31808SJens Wiklander 
176532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding encrypt then mac extension"));
176632b31808SJens Wiklander 
176732b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, p, 0);
176832b31808SJens Wiklander     p += 2;
176932b31808SJens Wiklander 
177032b31808SJens Wiklander     *p++ = 0x00;
177132b31808SJens Wiklander     *p++ = 0x00;
177232b31808SJens Wiklander 
177332b31808SJens Wiklander     *olen = 4;
177432b31808SJens Wiklander }
177532b31808SJens Wiklander #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */
177632b31808SJens Wiklander 
177732b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
177832b31808SJens Wiklander static void ssl_write_extended_ms_ext(mbedtls_ssl_context *ssl,
177932b31808SJens Wiklander                                       unsigned char *buf,
178032b31808SJens Wiklander                                       size_t *olen)
178132b31808SJens Wiklander {
178232b31808SJens Wiklander     unsigned char *p = buf;
178332b31808SJens Wiklander 
178432b31808SJens Wiklander     if (ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED) {
178532b31808SJens Wiklander         *olen = 0;
178632b31808SJens Wiklander         return;
178732b31808SJens Wiklander     }
178832b31808SJens Wiklander 
178932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding extended master secret "
179032b31808SJens Wiklander                               "extension"));
179132b31808SJens Wiklander 
179232b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, p, 0);
179332b31808SJens Wiklander     p += 2;
179432b31808SJens Wiklander 
179532b31808SJens Wiklander     *p++ = 0x00;
179632b31808SJens Wiklander     *p++ = 0x00;
179732b31808SJens Wiklander 
179832b31808SJens Wiklander     *olen = 4;
179932b31808SJens Wiklander }
180032b31808SJens Wiklander #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
180132b31808SJens Wiklander 
180232b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
180332b31808SJens Wiklander static void ssl_write_session_ticket_ext(mbedtls_ssl_context *ssl,
180432b31808SJens Wiklander                                          unsigned char *buf,
180532b31808SJens Wiklander                                          size_t *olen)
180632b31808SJens Wiklander {
180732b31808SJens Wiklander     unsigned char *p = buf;
180832b31808SJens Wiklander 
180932b31808SJens Wiklander     if (ssl->handshake->new_session_ticket == 0) {
181032b31808SJens Wiklander         *olen = 0;
181132b31808SJens Wiklander         return;
181232b31808SJens Wiklander     }
181332b31808SJens Wiklander 
181432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding session ticket extension"));
181532b31808SJens Wiklander 
181632b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SESSION_TICKET, p, 0);
181732b31808SJens Wiklander     p += 2;
181832b31808SJens Wiklander 
181932b31808SJens Wiklander     *p++ = 0x00;
182032b31808SJens Wiklander     *p++ = 0x00;
182132b31808SJens Wiklander 
182232b31808SJens Wiklander     *olen = 4;
182332b31808SJens Wiklander }
182432b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
182532b31808SJens Wiklander 
182632b31808SJens Wiklander static void ssl_write_renegotiation_ext(mbedtls_ssl_context *ssl,
182732b31808SJens Wiklander                                         unsigned char *buf,
182832b31808SJens Wiklander                                         size_t *olen)
182932b31808SJens Wiklander {
183032b31808SJens Wiklander     unsigned char *p = buf;
183132b31808SJens Wiklander 
183232b31808SJens Wiklander     if (ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION) {
183332b31808SJens Wiklander         *olen = 0;
183432b31808SJens Wiklander         return;
183532b31808SJens Wiklander     }
183632b31808SJens Wiklander 
183732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, secure renegotiation extension"));
183832b31808SJens Wiklander 
183932b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_RENEGOTIATION_INFO, p, 0);
184032b31808SJens Wiklander     p += 2;
184132b31808SJens Wiklander 
184232b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
184332b31808SJens Wiklander     if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
184432b31808SJens Wiklander         *p++ = 0x00;
184532b31808SJens Wiklander         *p++ = (ssl->verify_data_len * 2 + 1) & 0xFF;
184632b31808SJens Wiklander         *p++ = ssl->verify_data_len * 2 & 0xFF;
184732b31808SJens Wiklander 
184832b31808SJens Wiklander         memcpy(p, ssl->peer_verify_data, ssl->verify_data_len);
184932b31808SJens Wiklander         p += ssl->verify_data_len;
185032b31808SJens Wiklander         memcpy(p, ssl->own_verify_data, ssl->verify_data_len);
185132b31808SJens Wiklander         p += ssl->verify_data_len;
185232b31808SJens Wiklander     } else
185332b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */
185432b31808SJens Wiklander     {
185532b31808SJens Wiklander         *p++ = 0x00;
185632b31808SJens Wiklander         *p++ = 0x01;
185732b31808SJens Wiklander         *p++ = 0x00;
185832b31808SJens Wiklander     }
185932b31808SJens Wiklander 
1860*b0563631STom Van Eyck     *olen = (size_t) (p - buf);
186132b31808SJens Wiklander }
186232b31808SJens Wiklander 
186332b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
186432b31808SJens Wiklander static void ssl_write_max_fragment_length_ext(mbedtls_ssl_context *ssl,
186532b31808SJens Wiklander                                               unsigned char *buf,
186632b31808SJens Wiklander                                               size_t *olen)
186732b31808SJens Wiklander {
186832b31808SJens Wiklander     unsigned char *p = buf;
186932b31808SJens Wiklander 
187032b31808SJens Wiklander     if (ssl->session_negotiate->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE) {
187132b31808SJens Wiklander         *olen = 0;
187232b31808SJens Wiklander         return;
187332b31808SJens Wiklander     }
187432b31808SJens Wiklander 
187532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, max_fragment_length extension"));
187632b31808SJens Wiklander 
187732b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, p, 0);
187832b31808SJens Wiklander     p += 2;
187932b31808SJens Wiklander 
188032b31808SJens Wiklander     *p++ = 0x00;
188132b31808SJens Wiklander     *p++ = 1;
188232b31808SJens Wiklander 
188332b31808SJens Wiklander     *p++ = ssl->session_negotiate->mfl_code;
188432b31808SJens Wiklander 
188532b31808SJens Wiklander     *olen = 5;
188632b31808SJens Wiklander }
188732b31808SJens Wiklander #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
188832b31808SJens Wiklander 
1889*b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
1890*b0563631STom Van Eyck     defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
189132b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
189232b31808SJens Wiklander static void ssl_write_supported_point_formats_ext(mbedtls_ssl_context *ssl,
189332b31808SJens Wiklander                                                   unsigned char *buf,
189432b31808SJens Wiklander                                                   size_t *olen)
189532b31808SJens Wiklander {
189632b31808SJens Wiklander     unsigned char *p = buf;
189732b31808SJens Wiklander     ((void) ssl);
189832b31808SJens Wiklander 
189932b31808SJens Wiklander     if ((ssl->handshake->cli_exts &
190032b31808SJens Wiklander          MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT) == 0) {
190132b31808SJens Wiklander         *olen = 0;
190232b31808SJens Wiklander         return;
190332b31808SJens Wiklander     }
190432b31808SJens Wiklander 
190532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, supported_point_formats extension"));
190632b31808SJens Wiklander 
190732b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, p, 0);
190832b31808SJens Wiklander     p += 2;
190932b31808SJens Wiklander 
191032b31808SJens Wiklander     *p++ = 0x00;
191132b31808SJens Wiklander     *p++ = 2;
191232b31808SJens Wiklander 
191332b31808SJens Wiklander     *p++ = 1;
191432b31808SJens Wiklander     *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED;
191532b31808SJens Wiklander 
191632b31808SJens Wiklander     *olen = 6;
191732b31808SJens Wiklander }
1918*b0563631STom Van Eyck #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED ||
1919*b0563631STom Van Eyck           MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED ||
1920*b0563631STom Van Eyck           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
192132b31808SJens Wiklander 
192232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
192332b31808SJens Wiklander static void ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl,
192432b31808SJens Wiklander                                        unsigned char *buf,
192532b31808SJens Wiklander                                        size_t *olen)
192632b31808SJens Wiklander {
192732b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
192832b31808SJens Wiklander     unsigned char *p = buf;
192932b31808SJens Wiklander     const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
193032b31808SJens Wiklander     size_t kkpp_len;
193132b31808SJens Wiklander 
193232b31808SJens Wiklander     *olen = 0;
193332b31808SJens Wiklander 
193432b31808SJens Wiklander     /* Skip costly computation if not needed */
193532b31808SJens Wiklander     if (ssl->handshake->ciphersuite_info->key_exchange !=
193632b31808SJens Wiklander         MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
193732b31808SJens Wiklander         return;
193832b31808SJens Wiklander     }
193932b31808SJens Wiklander 
194032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, ecjpake kkpp extension"));
194132b31808SJens Wiklander 
194232b31808SJens Wiklander     if (end - p < 4) {
194332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small"));
194432b31808SJens Wiklander         return;
194532b31808SJens Wiklander     }
194632b31808SJens Wiklander 
194732b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0);
194832b31808SJens Wiklander     p += 2;
194932b31808SJens Wiklander 
195032b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
195132b31808SJens Wiklander     ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx,
1952*b0563631STom Van Eyck                                           p + 2, (size_t) (end - p - 2), &kkpp_len,
195332b31808SJens Wiklander                                           MBEDTLS_ECJPAKE_ROUND_ONE);
195432b31808SJens Wiklander     if (ret != 0) {
195532b31808SJens Wiklander         psa_destroy_key(ssl->handshake->psa_pake_password);
195632b31808SJens Wiklander         psa_pake_abort(&ssl->handshake->psa_pake_ctx);
195732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret);
195832b31808SJens Wiklander         return;
195932b31808SJens Wiklander     }
196032b31808SJens Wiklander #else
196132b31808SJens Wiklander     ret = mbedtls_ecjpake_write_round_one(&ssl->handshake->ecjpake_ctx,
1962*b0563631STom Van Eyck                                           p + 2, (size_t) (end - p - 2), &kkpp_len,
196332b31808SJens Wiklander                                           ssl->conf->f_rng, ssl->conf->p_rng);
196432b31808SJens Wiklander     if (ret != 0) {
196532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_one", ret);
196632b31808SJens Wiklander         return;
196732b31808SJens Wiklander     }
196832b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
196932b31808SJens Wiklander 
197032b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(kkpp_len, p, 0);
197132b31808SJens Wiklander     p += 2;
197232b31808SJens Wiklander 
197332b31808SJens Wiklander     *olen = kkpp_len + 4;
197432b31808SJens Wiklander }
197532b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
197632b31808SJens Wiklander 
197732b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP) && defined(MBEDTLS_SSL_PROTO_DTLS)
197832b31808SJens Wiklander static void ssl_write_use_srtp_ext(mbedtls_ssl_context *ssl,
197932b31808SJens Wiklander                                    unsigned char *buf,
198032b31808SJens Wiklander                                    size_t *olen)
198132b31808SJens Wiklander {
198232b31808SJens Wiklander     size_t mki_len = 0, ext_len = 0;
198332b31808SJens Wiklander     uint16_t profile_value = 0;
198432b31808SJens Wiklander     const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
198532b31808SJens Wiklander 
198632b31808SJens Wiklander     *olen = 0;
198732b31808SJens Wiklander 
198832b31808SJens Wiklander     if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) ||
198932b31808SJens Wiklander         (ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET)) {
199032b31808SJens Wiklander         return;
199132b31808SJens Wiklander     }
199232b31808SJens Wiklander 
199332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding use_srtp extension"));
199432b31808SJens Wiklander 
199532b31808SJens Wiklander     if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED) {
199632b31808SJens Wiklander         mki_len = ssl->dtls_srtp_info.mki_len;
199732b31808SJens Wiklander     }
199832b31808SJens Wiklander 
199932b31808SJens Wiklander     /* The extension total size is 9 bytes :
200032b31808SJens Wiklander      * - 2 bytes for the extension tag
200132b31808SJens Wiklander      * - 2 bytes for the total size
200232b31808SJens Wiklander      * - 2 bytes for the protection profile length
200332b31808SJens Wiklander      * - 2 bytes for the protection profile
200432b31808SJens Wiklander      * - 1 byte for the mki length
200532b31808SJens Wiklander      * +  the actual mki length
200632b31808SJens Wiklander      * Check we have enough room in the output buffer */
200732b31808SJens Wiklander     if ((size_t) (end - buf) < mki_len + 9) {
200832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small"));
200932b31808SJens Wiklander         return;
201032b31808SJens Wiklander     }
201132b31808SJens Wiklander 
201232b31808SJens Wiklander     /* extension */
201332b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_USE_SRTP, buf, 0);
201432b31808SJens Wiklander     /*
201532b31808SJens Wiklander      * total length 5 and mki value: only one profile(2 bytes)
201632b31808SJens Wiklander      *              and length(2 bytes) and srtp_mki  )
201732b31808SJens Wiklander      */
201832b31808SJens Wiklander     ext_len = 5 + mki_len;
201932b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(ext_len, buf, 2);
202032b31808SJens Wiklander 
202132b31808SJens Wiklander     /* protection profile length: 2 */
202232b31808SJens Wiklander     buf[4] = 0x00;
202332b31808SJens Wiklander     buf[5] = 0x02;
202432b31808SJens Wiklander     profile_value = mbedtls_ssl_check_srtp_profile_value(
202532b31808SJens Wiklander         ssl->dtls_srtp_info.chosen_dtls_srtp_profile);
202632b31808SJens Wiklander     if (profile_value != MBEDTLS_TLS_SRTP_UNSET) {
202732b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(profile_value, buf, 6);
202832b31808SJens Wiklander     } else {
202932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("use_srtp extension invalid profile"));
203032b31808SJens Wiklander         return;
203132b31808SJens Wiklander     }
203232b31808SJens Wiklander 
203332b31808SJens Wiklander     buf[8] = mki_len & 0xFF;
203432b31808SJens Wiklander     memcpy(&buf[9], ssl->dtls_srtp_info.mki_value, mki_len);
203532b31808SJens Wiklander 
203632b31808SJens Wiklander     *olen = 9 + mki_len;
203732b31808SJens Wiklander }
203832b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_SRTP */
203932b31808SJens Wiklander 
204032b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
204132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
204232b31808SJens Wiklander static int ssl_write_hello_verify_request(mbedtls_ssl_context *ssl)
204332b31808SJens Wiklander {
204432b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
204532b31808SJens Wiklander     unsigned char *p = ssl->out_msg + 4;
204632b31808SJens Wiklander     unsigned char *cookie_len_byte;
204732b31808SJens Wiklander 
204832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write hello verify request"));
204932b31808SJens Wiklander 
205032b31808SJens Wiklander     /*
205132b31808SJens Wiklander      * struct {
205232b31808SJens Wiklander      *   ProtocolVersion server_version;
205332b31808SJens Wiklander      *   opaque cookie<0..2^8-1>;
205432b31808SJens Wiklander      * } HelloVerifyRequest;
205532b31808SJens Wiklander      */
205632b31808SJens Wiklander 
205732b31808SJens Wiklander     /* The RFC is not clear on this point, but sending the actual negotiated
205832b31808SJens Wiklander      * version looks like the most interoperable thing to do. */
205932b31808SJens Wiklander     mbedtls_ssl_write_version(p, ssl->conf->transport, ssl->tls_version);
206032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "server version", p, 2);
206132b31808SJens Wiklander     p += 2;
206232b31808SJens Wiklander 
206332b31808SJens Wiklander     /* If we get here, f_cookie_check is not null */
206432b31808SJens Wiklander     if (ssl->conf->f_cookie_write == NULL) {
206532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("inconsistent cookie callbacks"));
206632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
206732b31808SJens Wiklander     }
206832b31808SJens Wiklander 
206932b31808SJens Wiklander     /* Skip length byte until we know the length */
207032b31808SJens Wiklander     cookie_len_byte = p++;
207132b31808SJens Wiklander 
207232b31808SJens Wiklander     if ((ret = ssl->conf->f_cookie_write(ssl->conf->p_cookie,
207332b31808SJens Wiklander                                          &p, ssl->out_buf + MBEDTLS_SSL_OUT_BUFFER_LEN,
207432b31808SJens Wiklander                                          ssl->cli_id, ssl->cli_id_len)) != 0) {
207532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "f_cookie_write", ret);
207632b31808SJens Wiklander         return ret;
207732b31808SJens Wiklander     }
207832b31808SJens Wiklander 
207932b31808SJens Wiklander     *cookie_len_byte = (unsigned char) (p - (cookie_len_byte + 1));
208032b31808SJens Wiklander 
208132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "cookie sent", cookie_len_byte + 1, *cookie_len_byte);
208232b31808SJens Wiklander 
2083*b0563631STom Van Eyck     ssl->out_msglen  = (size_t) (p - ssl->out_msg);
208432b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
208532b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
208632b31808SJens Wiklander 
208732b31808SJens Wiklander     ssl->state = MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT;
208832b31808SJens Wiklander 
208932b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
209032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
209132b31808SJens Wiklander         return ret;
209232b31808SJens Wiklander     }
209332b31808SJens Wiklander 
209432b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
209532b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
209632b31808SJens Wiklander         (ret = mbedtls_ssl_flight_transmit(ssl)) != 0) {
209732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flight_transmit", ret);
209832b31808SJens Wiklander         return ret;
209932b31808SJens Wiklander     }
210032b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */
210132b31808SJens Wiklander 
210232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write hello verify request"));
210332b31808SJens Wiklander 
210432b31808SJens Wiklander     return 0;
210532b31808SJens Wiklander }
210632b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
210732b31808SJens Wiklander 
210832b31808SJens Wiklander static void ssl_handle_id_based_session_resumption(mbedtls_ssl_context *ssl)
210932b31808SJens Wiklander {
211032b31808SJens Wiklander     int ret;
211132b31808SJens Wiklander     mbedtls_ssl_session session_tmp;
211232b31808SJens Wiklander     mbedtls_ssl_session * const session = ssl->session_negotiate;
211332b31808SJens Wiklander 
211432b31808SJens Wiklander     /* Resume is 0  by default, see ssl_handshake_init().
211532b31808SJens Wiklander      * It may be already set to 1 by ssl_parse_session_ticket_ext(). */
211632b31808SJens Wiklander     if (ssl->handshake->resume == 1) {
211732b31808SJens Wiklander         return;
211832b31808SJens Wiklander     }
211932b31808SJens Wiklander     if (session->id_len == 0) {
212032b31808SJens Wiklander         return;
212132b31808SJens Wiklander     }
212232b31808SJens Wiklander     if (ssl->conf->f_get_cache == NULL) {
212332b31808SJens Wiklander         return;
212432b31808SJens Wiklander     }
212532b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
212632b31808SJens Wiklander     if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
212732b31808SJens Wiklander         return;
212832b31808SJens Wiklander     }
212932b31808SJens Wiklander #endif
213032b31808SJens Wiklander 
213132b31808SJens Wiklander     mbedtls_ssl_session_init(&session_tmp);
213232b31808SJens Wiklander 
213332b31808SJens Wiklander     ret = ssl->conf->f_get_cache(ssl->conf->p_cache,
213432b31808SJens Wiklander                                  session->id,
213532b31808SJens Wiklander                                  session->id_len,
213632b31808SJens Wiklander                                  &session_tmp);
213732b31808SJens Wiklander     if (ret != 0) {
213832b31808SJens Wiklander         goto exit;
213932b31808SJens Wiklander     }
214032b31808SJens Wiklander 
214132b31808SJens Wiklander     if (session->ciphersuite != session_tmp.ciphersuite) {
214232b31808SJens Wiklander         /* Mismatch between cached and negotiated session */
214332b31808SJens Wiklander         goto exit;
214432b31808SJens Wiklander     }
214532b31808SJens Wiklander 
214632b31808SJens Wiklander     /* Move semantics */
214732b31808SJens Wiklander     mbedtls_ssl_session_free(session);
214832b31808SJens Wiklander     *session = session_tmp;
214932b31808SJens Wiklander     memset(&session_tmp, 0, sizeof(session_tmp));
215032b31808SJens Wiklander 
215132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("session successfully restored from cache"));
215232b31808SJens Wiklander     ssl->handshake->resume = 1;
215332b31808SJens Wiklander 
215432b31808SJens Wiklander exit:
215532b31808SJens Wiklander 
215632b31808SJens Wiklander     mbedtls_ssl_session_free(&session_tmp);
215732b31808SJens Wiklander }
215832b31808SJens Wiklander 
215932b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
216032b31808SJens Wiklander static int ssl_write_server_hello(mbedtls_ssl_context *ssl)
216132b31808SJens Wiklander {
216232b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME)
216332b31808SJens Wiklander     mbedtls_time_t t;
216432b31808SJens Wiklander #endif
216532b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
216632b31808SJens Wiklander     size_t olen, ext_len = 0, n;
216732b31808SJens Wiklander     unsigned char *buf, *p;
216832b31808SJens Wiklander 
216932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server hello"));
217032b31808SJens Wiklander 
217132b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
217232b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
217332b31808SJens Wiklander         ssl->handshake->cookie_verify_result != 0) {
217432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("client hello was not authenticated"));
217532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello"));
217632b31808SJens Wiklander 
217732b31808SJens Wiklander         return ssl_write_hello_verify_request(ssl);
217832b31808SJens Wiklander     }
217932b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
218032b31808SJens Wiklander 
218132b31808SJens Wiklander     /*
218232b31808SJens Wiklander      *     0  .   0   handshake type
218332b31808SJens Wiklander      *     1  .   3   handshake length
218432b31808SJens Wiklander      *     4  .   5   protocol version
218532b31808SJens Wiklander      *     6  .   9   UNIX time()
218632b31808SJens Wiklander      *    10  .  37   random bytes
218732b31808SJens Wiklander      */
218832b31808SJens Wiklander     buf = ssl->out_msg;
218932b31808SJens Wiklander     p = buf + 4;
219032b31808SJens Wiklander 
219132b31808SJens Wiklander     mbedtls_ssl_write_version(p, ssl->conf->transport, ssl->tls_version);
219232b31808SJens Wiklander     p += 2;
219332b31808SJens Wiklander 
219432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen version: [%d:%d]",
219532b31808SJens Wiklander                               buf[4], buf[5]));
219632b31808SJens Wiklander 
219732b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME)
219832b31808SJens Wiklander     t = mbedtls_time(NULL);
219932b31808SJens Wiklander     MBEDTLS_PUT_UINT32_BE(t, p, 0);
220032b31808SJens Wiklander     p += 4;
220132b31808SJens Wiklander 
220232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, current time: %" MBEDTLS_PRINTF_LONGLONG,
220332b31808SJens Wiklander                               (long long) t));
220432b31808SJens Wiklander #else
220532b31808SJens Wiklander     if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 4)) != 0) {
220632b31808SJens Wiklander         return ret;
220732b31808SJens Wiklander     }
220832b31808SJens Wiklander 
220932b31808SJens Wiklander     p += 4;
221032b31808SJens Wiklander #endif /* MBEDTLS_HAVE_TIME */
221132b31808SJens Wiklander 
2212*b0563631STom Van Eyck     if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 20)) != 0) {
221332b31808SJens Wiklander         return ret;
221432b31808SJens Wiklander     }
2215*b0563631STom Van Eyck     p += 20;
221632b31808SJens Wiklander 
2217*b0563631STom Van Eyck #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
2218*b0563631STom Van Eyck     /*
2219*b0563631STom Van Eyck      * RFC 8446
2220*b0563631STom Van Eyck      * TLS 1.3 has a downgrade protection mechanism embedded in the server's
2221*b0563631STom Van Eyck      * random value. TLS 1.3 servers which negotiate TLS 1.2 or below in
2222*b0563631STom Van Eyck      * response to a ClientHello MUST set the last 8 bytes of their Random
2223*b0563631STom Van Eyck      * value specially in their ServerHello.
2224*b0563631STom Van Eyck      */
2225*b0563631STom Van Eyck     if (mbedtls_ssl_conf_is_tls13_enabled(ssl->conf)) {
2226*b0563631STom Van Eyck         static const unsigned char magic_tls12_downgrade_string[] =
2227*b0563631STom Van Eyck         { 'D', 'O', 'W', 'N', 'G', 'R', 'D', 1 };
2228*b0563631STom Van Eyck 
2229*b0563631STom Van Eyck         MBEDTLS_STATIC_ASSERT(
2230*b0563631STom Van Eyck             sizeof(magic_tls12_downgrade_string) == 8,
2231*b0563631STom Van Eyck             "magic_tls12_downgrade_string does not have the expected size");
2232*b0563631STom Van Eyck 
2233*b0563631STom Van Eyck         memcpy(p, magic_tls12_downgrade_string,
2234*b0563631STom Van Eyck                sizeof(magic_tls12_downgrade_string));
2235*b0563631STom Van Eyck     } else
2236*b0563631STom Van Eyck #endif
2237*b0563631STom Van Eyck     {
2238*b0563631STom Van Eyck         if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 8)) != 0) {
2239*b0563631STom Van Eyck             return ret;
2240*b0563631STom Van Eyck         }
2241*b0563631STom Van Eyck     }
2242*b0563631STom Van Eyck     p += 8;
224332b31808SJens Wiklander 
224432b31808SJens Wiklander     memcpy(ssl->handshake->randbytes + 32, buf + 6, 32);
224532b31808SJens Wiklander 
224632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "server hello, random bytes", buf + 6, 32);
224732b31808SJens Wiklander 
224832b31808SJens Wiklander     ssl_handle_id_based_session_resumption(ssl);
224932b31808SJens Wiklander 
225032b31808SJens Wiklander     if (ssl->handshake->resume == 0) {
225132b31808SJens Wiklander         /*
225232b31808SJens Wiklander          * New session, create a new session id,
225332b31808SJens Wiklander          * unless we're about to issue a session ticket
225432b31808SJens Wiklander          */
225532b31808SJens Wiklander         ssl->state++;
225632b31808SJens Wiklander 
225732b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME)
225832b31808SJens Wiklander         ssl->session_negotiate->start = mbedtls_time(NULL);
225932b31808SJens Wiklander #endif
226032b31808SJens Wiklander 
226132b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
226232b31808SJens Wiklander         if (ssl->handshake->new_session_ticket != 0) {
226332b31808SJens Wiklander             ssl->session_negotiate->id_len = n = 0;
226432b31808SJens Wiklander             memset(ssl->session_negotiate->id, 0, 32);
226532b31808SJens Wiklander         } else
226632b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
226732b31808SJens Wiklander         {
226832b31808SJens Wiklander             ssl->session_negotiate->id_len = n = 32;
226932b31808SJens Wiklander             if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, ssl->session_negotiate->id,
227032b31808SJens Wiklander                                         n)) != 0) {
227132b31808SJens Wiklander                 return ret;
227232b31808SJens Wiklander             }
227332b31808SJens Wiklander         }
227432b31808SJens Wiklander     } else {
227532b31808SJens Wiklander         /*
227632b31808SJens Wiklander          * Resuming a session
227732b31808SJens Wiklander          */
227832b31808SJens Wiklander         n = ssl->session_negotiate->id_len;
227932b31808SJens Wiklander         ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
228032b31808SJens Wiklander 
228132b31808SJens Wiklander         if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) {
228232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret);
228332b31808SJens Wiklander             return ret;
228432b31808SJens Wiklander         }
228532b31808SJens Wiklander     }
228632b31808SJens Wiklander 
228732b31808SJens Wiklander     /*
228832b31808SJens Wiklander      *    38  .  38     session id length
228932b31808SJens Wiklander      *    39  . 38+n    session id
229032b31808SJens Wiklander      *   39+n . 40+n    chosen ciphersuite
229132b31808SJens Wiklander      *   41+n . 41+n    chosen compression alg.
229232b31808SJens Wiklander      *   42+n . 43+n    extensions length
229332b31808SJens Wiklander      *   44+n . 43+n+m  extensions
229432b31808SJens Wiklander      */
229532b31808SJens Wiklander     *p++ = (unsigned char) ssl->session_negotiate->id_len;
229632b31808SJens Wiklander     memcpy(p, ssl->session_negotiate->id, ssl->session_negotiate->id_len);
229732b31808SJens Wiklander     p += ssl->session_negotiate->id_len;
229832b31808SJens Wiklander 
229932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, session id len.: %" MBEDTLS_PRINTF_SIZET, n));
230032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3,   "server hello, session id", buf + 39, n);
230132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("%s session has been resumed",
230232b31808SJens Wiklander                               ssl->handshake->resume ? "a" : "no"));
230332b31808SJens Wiklander 
230432b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(ssl->session_negotiate->ciphersuite, p, 0);
230532b31808SJens Wiklander     p += 2;
230632b31808SJens Wiklander     *p++ = MBEDTLS_BYTE_0(MBEDTLS_SSL_COMPRESS_NULL);
230732b31808SJens Wiklander 
230832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen ciphersuite: %s",
230932b31808SJens Wiklander                               mbedtls_ssl_get_ciphersuite_name(ssl->session_negotiate->ciphersuite)));
231032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, compress alg.: 0x%02X",
231132b31808SJens Wiklander                               (unsigned int) MBEDTLS_SSL_COMPRESS_NULL));
231232b31808SJens Wiklander 
231332b31808SJens Wiklander     /*
231432b31808SJens Wiklander      *  First write extensions, then the total length
231532b31808SJens Wiklander      */
231632b31808SJens Wiklander     ssl_write_renegotiation_ext(ssl, p + 2 + ext_len, &olen);
231732b31808SJens Wiklander     ext_len += olen;
231832b31808SJens Wiklander 
231932b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
232032b31808SJens Wiklander     ssl_write_max_fragment_length_ext(ssl, p + 2 + ext_len, &olen);
232132b31808SJens Wiklander     ext_len += olen;
232232b31808SJens Wiklander #endif
232332b31808SJens Wiklander 
232432b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
232532b31808SJens Wiklander     ssl_write_cid_ext(ssl, p + 2 + ext_len, &olen);
232632b31808SJens Wiklander     ext_len += olen;
232732b31808SJens Wiklander #endif
232832b31808SJens Wiklander 
232932b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM)
233032b31808SJens Wiklander     ssl_write_encrypt_then_mac_ext(ssl, p + 2 + ext_len, &olen);
233132b31808SJens Wiklander     ext_len += olen;
233232b31808SJens Wiklander #endif
233332b31808SJens Wiklander 
233432b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
233532b31808SJens Wiklander     ssl_write_extended_ms_ext(ssl, p + 2 + ext_len, &olen);
233632b31808SJens Wiklander     ext_len += olen;
233732b31808SJens Wiklander #endif
233832b31808SJens Wiklander 
233932b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
234032b31808SJens Wiklander     ssl_write_session_ticket_ext(ssl, p + 2 + ext_len, &olen);
234132b31808SJens Wiklander     ext_len += olen;
234232b31808SJens Wiklander #endif
234332b31808SJens Wiklander 
2344*b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
2345*b0563631STom Van Eyck     defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
234632b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
234732b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *suite =
234832b31808SJens Wiklander         mbedtls_ssl_ciphersuite_from_id(ssl->session_negotiate->ciphersuite);
234932b31808SJens Wiklander     if (suite != NULL && mbedtls_ssl_ciphersuite_uses_ec(suite)) {
235032b31808SJens Wiklander         ssl_write_supported_point_formats_ext(ssl, p + 2 + ext_len, &olen);
235132b31808SJens Wiklander         ext_len += olen;
235232b31808SJens Wiklander     }
235332b31808SJens Wiklander #endif
235432b31808SJens Wiklander 
235532b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
235632b31808SJens Wiklander     ssl_write_ecjpake_kkpp_ext(ssl, p + 2 + ext_len, &olen);
235732b31808SJens Wiklander     ext_len += olen;
235832b31808SJens Wiklander #endif
235932b31808SJens Wiklander 
236032b31808SJens Wiklander #if defined(MBEDTLS_SSL_ALPN)
236132b31808SJens Wiklander     unsigned char *end = buf + MBEDTLS_SSL_OUT_CONTENT_LEN - 4;
236232b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_alpn_ext(ssl, p + 2 + ext_len, end, &olen))
236332b31808SJens Wiklander         != 0) {
236432b31808SJens Wiklander         return ret;
236532b31808SJens Wiklander     }
236632b31808SJens Wiklander 
236732b31808SJens Wiklander     ext_len += olen;
236832b31808SJens Wiklander #endif
236932b31808SJens Wiklander 
237032b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP)
237132b31808SJens Wiklander     ssl_write_use_srtp_ext(ssl, p + 2 + ext_len, &olen);
237232b31808SJens Wiklander     ext_len += olen;
237332b31808SJens Wiklander #endif
237432b31808SJens Wiklander 
237532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, total extension length: %" MBEDTLS_PRINTF_SIZET,
237632b31808SJens Wiklander                               ext_len));
237732b31808SJens Wiklander 
237832b31808SJens Wiklander     if (ext_len > 0) {
237932b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(ext_len, p, 0);
238032b31808SJens Wiklander         p += 2 + ext_len;
238132b31808SJens Wiklander     }
238232b31808SJens Wiklander 
2383*b0563631STom Van Eyck     ssl->out_msglen  = (size_t) (p - buf);
238432b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
238532b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_HELLO;
238632b31808SJens Wiklander 
238732b31808SJens Wiklander     ret = mbedtls_ssl_write_handshake_msg(ssl);
238832b31808SJens Wiklander 
238932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello"));
239032b31808SJens Wiklander 
239132b31808SJens Wiklander     return ret;
239232b31808SJens Wiklander }
239332b31808SJens Wiklander 
239432b31808SJens Wiklander #if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
239532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
239632b31808SJens Wiklander static int ssl_write_certificate_request(mbedtls_ssl_context *ssl)
239732b31808SJens Wiklander {
239832b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
239932b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
240032b31808SJens Wiklander 
240132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate request"));
240232b31808SJens Wiklander 
240332b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
240432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate request"));
240532b31808SJens Wiklander         ssl->state++;
240632b31808SJens Wiklander         return 0;
240732b31808SJens Wiklander     }
240832b31808SJens Wiklander 
240932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
241032b31808SJens Wiklander     return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
241132b31808SJens Wiklander }
241232b31808SJens Wiklander #else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
241332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
241432b31808SJens Wiklander static int ssl_write_certificate_request(mbedtls_ssl_context *ssl)
241532b31808SJens Wiklander {
241632b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
241732b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
241832b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
241932b31808SJens Wiklander     uint16_t dn_size, total_dn_size; /* excluding length bytes */
242032b31808SJens Wiklander     size_t ct_len, sa_len; /* including length bytes */
242132b31808SJens Wiklander     unsigned char *buf, *p;
242232b31808SJens Wiklander     const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
242332b31808SJens Wiklander     const mbedtls_x509_crt *crt;
242432b31808SJens Wiklander     int authmode;
242532b31808SJens Wiklander 
242632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate request"));
242732b31808SJens Wiklander 
242832b31808SJens Wiklander     ssl->state++;
242932b31808SJens Wiklander 
243032b31808SJens Wiklander #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
243132b31808SJens Wiklander     if (ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET) {
243232b31808SJens Wiklander         authmode = ssl->handshake->sni_authmode;
243332b31808SJens Wiklander     } else
243432b31808SJens Wiklander #endif
243532b31808SJens Wiklander     authmode = ssl->conf->authmode;
243632b31808SJens Wiklander 
243732b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info) ||
243832b31808SJens Wiklander         authmode == MBEDTLS_SSL_VERIFY_NONE) {
243932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate request"));
244032b31808SJens Wiklander         return 0;
244132b31808SJens Wiklander     }
244232b31808SJens Wiklander 
244332b31808SJens Wiklander     /*
244432b31808SJens Wiklander      *     0  .   0   handshake type
244532b31808SJens Wiklander      *     1  .   3   handshake length
244632b31808SJens Wiklander      *     4  .   4   cert type count
244732b31808SJens Wiklander      *     5  .. m-1  cert types
244832b31808SJens Wiklander      *     m  .. m+1  sig alg length (TLS 1.2 only)
244932b31808SJens Wiklander      *    m+1 .. n-1  SignatureAndHashAlgorithms (TLS 1.2 only)
245032b31808SJens Wiklander      *     n  .. n+1  length of all DNs
245132b31808SJens Wiklander      *    n+2 .. n+3  length of DN 1
245232b31808SJens Wiklander      *    n+4 .. ...  Distinguished Name #1
245332b31808SJens Wiklander      *    ... .. ...  length of DN 2, etc.
245432b31808SJens Wiklander      */
245532b31808SJens Wiklander     buf = ssl->out_msg;
245632b31808SJens Wiklander     p = buf + 4;
245732b31808SJens Wiklander 
245832b31808SJens Wiklander     /*
245932b31808SJens Wiklander      * Supported certificate types
246032b31808SJens Wiklander      *
246132b31808SJens Wiklander      *     ClientCertificateType certificate_types<1..2^8-1>;
246232b31808SJens Wiklander      *     enum { (255) } ClientCertificateType;
246332b31808SJens Wiklander      */
246432b31808SJens Wiklander     ct_len = 0;
246532b31808SJens Wiklander 
246632b31808SJens Wiklander #if defined(MBEDTLS_RSA_C)
246732b31808SJens Wiklander     p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN;
246832b31808SJens Wiklander #endif
2469*b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
247032b31808SJens Wiklander     p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN;
247132b31808SJens Wiklander #endif
247232b31808SJens Wiklander 
247332b31808SJens Wiklander     p[0] = (unsigned char) ct_len++;
247432b31808SJens Wiklander     p += ct_len;
247532b31808SJens Wiklander 
247632b31808SJens Wiklander     sa_len = 0;
247732b31808SJens Wiklander 
247832b31808SJens Wiklander     /*
247932b31808SJens Wiklander      * Add signature_algorithms for verify (TLS 1.2)
248032b31808SJens Wiklander      *
248132b31808SJens Wiklander      *     SignatureAndHashAlgorithm supported_signature_algorithms<2..2^16-2>;
248232b31808SJens Wiklander      *
248332b31808SJens Wiklander      *     struct {
248432b31808SJens Wiklander      *           HashAlgorithm hash;
248532b31808SJens Wiklander      *           SignatureAlgorithm signature;
248632b31808SJens Wiklander      *     } SignatureAndHashAlgorithm;
248732b31808SJens Wiklander      *
248832b31808SJens Wiklander      *     enum { (255) } HashAlgorithm;
248932b31808SJens Wiklander      *     enum { (255) } SignatureAlgorithm;
249032b31808SJens Wiklander      */
249132b31808SJens Wiklander     const uint16_t *sig_alg = mbedtls_ssl_get_sig_algs(ssl);
249232b31808SJens Wiklander     if (sig_alg == NULL) {
249332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_CONFIG;
249432b31808SJens Wiklander     }
249532b31808SJens Wiklander 
249632b31808SJens Wiklander     for (; *sig_alg != MBEDTLS_TLS_SIG_NONE; sig_alg++) {
249732b31808SJens Wiklander         unsigned char hash = MBEDTLS_BYTE_1(*sig_alg);
249832b31808SJens Wiklander 
249932b31808SJens Wiklander         if (mbedtls_ssl_set_calc_verify_md(ssl, hash)) {
250032b31808SJens Wiklander             continue;
250132b31808SJens Wiklander         }
250232b31808SJens Wiklander         if (!mbedtls_ssl_sig_alg_is_supported(ssl, *sig_alg)) {
250332b31808SJens Wiklander             continue;
250432b31808SJens Wiklander         }
250532b31808SJens Wiklander 
250632b31808SJens Wiklander         /* Write elements at offsets starting from 1 (offset 0 is for the
250732b31808SJens Wiklander          * length). Thus the offset of each element is the length of the
250832b31808SJens Wiklander          * partial list including that element. */
250932b31808SJens Wiklander         sa_len += 2;
251032b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(*sig_alg, p, sa_len);
251132b31808SJens Wiklander 
251232b31808SJens Wiklander     }
251332b31808SJens Wiklander 
251432b31808SJens Wiklander     /* Fill in list length. */
251532b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(sa_len, p, 0);
251632b31808SJens Wiklander     sa_len += 2;
251732b31808SJens Wiklander     p += sa_len;
251832b31808SJens Wiklander 
251932b31808SJens Wiklander     /*
252032b31808SJens Wiklander      * DistinguishedName certificate_authorities<0..2^16-1>;
252132b31808SJens Wiklander      * opaque DistinguishedName<1..2^16-1>;
252232b31808SJens Wiklander      */
252332b31808SJens Wiklander     p += 2;
252432b31808SJens Wiklander 
252532b31808SJens Wiklander     total_dn_size = 0;
252632b31808SJens Wiklander 
252732b31808SJens Wiklander     if (ssl->conf->cert_req_ca_list ==  MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED) {
252832b31808SJens Wiklander         /* NOTE: If trusted certificates are provisioned
252932b31808SJens Wiklander          *       via a CA callback (configured through
253032b31808SJens Wiklander          *       `mbedtls_ssl_conf_ca_cb()`, then the
253132b31808SJens Wiklander          *       CertificateRequest is currently left empty. */
253232b31808SJens Wiklander 
253332b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
253432b31808SJens Wiklander #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
253532b31808SJens Wiklander         if (ssl->handshake->dn_hints != NULL) {
253632b31808SJens Wiklander             crt = ssl->handshake->dn_hints;
253732b31808SJens Wiklander         } else
253832b31808SJens Wiklander #endif
253932b31808SJens Wiklander         if (ssl->conf->dn_hints != NULL) {
254032b31808SJens Wiklander             crt = ssl->conf->dn_hints;
254132b31808SJens Wiklander         } else
254232b31808SJens Wiklander #endif
254332b31808SJens Wiklander #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
254432b31808SJens Wiklander         if (ssl->handshake->sni_ca_chain != NULL) {
254532b31808SJens Wiklander             crt = ssl->handshake->sni_ca_chain;
254632b31808SJens Wiklander         } else
254732b31808SJens Wiklander #endif
254832b31808SJens Wiklander         crt = ssl->conf->ca_chain;
254932b31808SJens Wiklander 
255032b31808SJens Wiklander         while (crt != NULL && crt->version != 0) {
255132b31808SJens Wiklander             /* It follows from RFC 5280 A.1 that this length
255232b31808SJens Wiklander              * can be represented in at most 11 bits. */
255332b31808SJens Wiklander             dn_size = (uint16_t) crt->subject_raw.len;
255432b31808SJens Wiklander 
255532b31808SJens Wiklander             if (end < p || (size_t) (end - p) < 2 + (size_t) dn_size) {
255632b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1, ("skipping CAs: buffer too short"));
255732b31808SJens Wiklander                 break;
255832b31808SJens Wiklander             }
255932b31808SJens Wiklander 
256032b31808SJens Wiklander             MBEDTLS_PUT_UINT16_BE(dn_size, p, 0);
256132b31808SJens Wiklander             p += 2;
256232b31808SJens Wiklander             memcpy(p, crt->subject_raw.p, dn_size);
256332b31808SJens Wiklander             p += dn_size;
256432b31808SJens Wiklander 
256532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_BUF(3, "requested DN", p - dn_size, dn_size);
256632b31808SJens Wiklander 
2567*b0563631STom Van Eyck             total_dn_size += (unsigned short) (2 + dn_size);
256832b31808SJens Wiklander             crt = crt->next;
256932b31808SJens Wiklander         }
257032b31808SJens Wiklander     }
257132b31808SJens Wiklander 
2572*b0563631STom Van Eyck     ssl->out_msglen  = (size_t) (p - buf);
257332b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
257432b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_CERTIFICATE_REQUEST;
257532b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(total_dn_size, ssl->out_msg, 4 + ct_len + sa_len);
257632b31808SJens Wiklander 
257732b31808SJens Wiklander     ret = mbedtls_ssl_write_handshake_msg(ssl);
257832b31808SJens Wiklander 
257932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write certificate request"));
258032b31808SJens Wiklander 
258132b31808SJens Wiklander     return ret;
258232b31808SJens Wiklander }
258332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
258432b31808SJens Wiklander 
2585*b0563631STom Van Eyck #if (defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
258632b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED))
2587*b0563631STom Van Eyck #if defined(MBEDTLS_USE_PSA_CRYPTO)
258832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
258932b31808SJens Wiklander static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
259032b31808SJens Wiklander {
259132b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
259232b31808SJens Wiklander     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
259332b31808SJens Wiklander     mbedtls_pk_context *pk;
2594*b0563631STom Van Eyck     mbedtls_pk_type_t pk_type;
2595*b0563631STom Van Eyck     psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
2596*b0563631STom Van Eyck     unsigned char buf[PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
2597*b0563631STom Van Eyck     size_t key_len;
2598*b0563631STom Van Eyck #if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
2599*b0563631STom Van Eyck     uint16_t tls_id = 0;
2600*b0563631STom Van Eyck     psa_key_type_t key_type = PSA_KEY_TYPE_NONE;
2601*b0563631STom Van Eyck     mbedtls_ecp_group_id grp_id;
260232b31808SJens Wiklander     mbedtls_ecp_keypair *key;
2603*b0563631STom Van Eyck #endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
260432b31808SJens Wiklander 
260532b31808SJens Wiklander     pk = mbedtls_ssl_own_key(ssl);
260632b31808SJens Wiklander 
260732b31808SJens Wiklander     if (pk == NULL) {
260832b31808SJens Wiklander         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
260932b31808SJens Wiklander     }
261032b31808SJens Wiklander 
2611*b0563631STom Van Eyck     pk_type = mbedtls_pk_get_type(pk);
2612*b0563631STom Van Eyck 
2613*b0563631STom Van Eyck     switch (pk_type) {
261432b31808SJens Wiklander         case MBEDTLS_PK_OPAQUE:
2615*b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
2616*b0563631STom Van Eyck         case MBEDTLS_PK_ECKEY:
2617*b0563631STom Van Eyck         case MBEDTLS_PK_ECKEY_DH:
2618*b0563631STom Van Eyck         case MBEDTLS_PK_ECDSA:
2619*b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
262032b31808SJens Wiklander             if (!mbedtls_pk_can_do(pk, MBEDTLS_PK_ECKEY)) {
262132b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
262232b31808SJens Wiklander             }
262332b31808SJens Wiklander 
2624*b0563631STom Van Eyck             /* Get the attributes of the key previously parsed by PK module in
2625*b0563631STom Van Eyck              * order to extract its type and length (in bits). */
2626*b0563631STom Van Eyck             status = psa_get_key_attributes(pk->priv_id, &key_attributes);
262732b31808SJens Wiklander             if (status != PSA_SUCCESS) {
2628*b0563631STom Van Eyck                 ret = PSA_TO_MBEDTLS_ERR(status);
2629*b0563631STom Van Eyck                 goto exit;
2630*b0563631STom Van Eyck             }
2631*b0563631STom Van Eyck             ssl->handshake->xxdh_psa_type = psa_get_key_type(&key_attributes);
2632*b0563631STom Van Eyck             ssl->handshake->xxdh_psa_bits = psa_get_key_bits(&key_attributes);
2633*b0563631STom Van Eyck 
2634*b0563631STom Van Eyck             if (pk_type == MBEDTLS_PK_OPAQUE) {
2635*b0563631STom Van Eyck                 /* Opaque key is created by the user (externally from Mbed TLS)
2636*b0563631STom Van Eyck                  * so we assume it already has the right algorithm and flags
2637*b0563631STom Van Eyck                  * set. Just copy its ID as reference. */
2638*b0563631STom Van Eyck                 ssl->handshake->xxdh_psa_privkey = pk->priv_id;
2639*b0563631STom Van Eyck                 ssl->handshake->xxdh_psa_privkey_is_external = 1;
2640*b0563631STom Van Eyck             } else {
2641*b0563631STom Van Eyck                 /* PK_ECKEY[_DH] and PK_ECDSA instead as parsed from the PK
2642*b0563631STom Van Eyck                  * module and only have ECDSA capabilities. Since we need
2643*b0563631STom Van Eyck                  * them for ECDH later, we export and then re-import them with
2644*b0563631STom Van Eyck                  * proper flags and algorithm. Of course We also set key's type
2645*b0563631STom Van Eyck                  * and bits that we just got above. */
2646*b0563631STom Van Eyck                 key_attributes = psa_key_attributes_init();
2647*b0563631STom Van Eyck                 psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
2648*b0563631STom Van Eyck                 psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
2649*b0563631STom Van Eyck                 psa_set_key_type(&key_attributes,
2650*b0563631STom Van Eyck                                  PSA_KEY_TYPE_ECC_KEY_PAIR(ssl->handshake->xxdh_psa_type));
2651*b0563631STom Van Eyck                 psa_set_key_bits(&key_attributes, ssl->handshake->xxdh_psa_bits);
2652*b0563631STom Van Eyck 
2653*b0563631STom Van Eyck                 status = psa_export_key(pk->priv_id, buf, sizeof(buf), &key_len);
2654*b0563631STom Van Eyck                 if (status != PSA_SUCCESS) {
2655*b0563631STom Van Eyck                     ret = PSA_TO_MBEDTLS_ERR(status);
2656*b0563631STom Van Eyck                     goto exit;
2657*b0563631STom Van Eyck                 }
2658*b0563631STom Van Eyck                 status = psa_import_key(&key_attributes, buf, key_len,
2659*b0563631STom Van Eyck                                         &ssl->handshake->xxdh_psa_privkey);
2660*b0563631STom Van Eyck                 if (status != PSA_SUCCESS) {
2661*b0563631STom Van Eyck                     ret = PSA_TO_MBEDTLS_ERR(status);
2662*b0563631STom Van Eyck                     goto exit;
266332b31808SJens Wiklander                 }
266432b31808SJens Wiklander 
2665*b0563631STom Van Eyck                 /* Set this key as owned by the TLS library: it will be its duty
2666*b0563631STom Van Eyck                  * to clear it exit. */
2667*b0563631STom Van Eyck                 ssl->handshake->xxdh_psa_privkey_is_external = 0;
2668*b0563631STom Van Eyck             }
266932b31808SJens Wiklander 
267032b31808SJens Wiklander             ret = 0;
267132b31808SJens Wiklander             break;
2672*b0563631STom Van Eyck #if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
267332b31808SJens Wiklander         case MBEDTLS_PK_ECKEY:
267432b31808SJens Wiklander         case MBEDTLS_PK_ECKEY_DH:
267532b31808SJens Wiklander         case MBEDTLS_PK_ECDSA:
2676*b0563631STom Van Eyck             key = mbedtls_pk_ec_rw(*pk);
2677*b0563631STom Van Eyck             grp_id = mbedtls_pk_get_ec_group_id(pk);
2678*b0563631STom Van Eyck             if (grp_id == MBEDTLS_ECP_DP_NONE) {
267932b31808SJens Wiklander                 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
268032b31808SJens Wiklander             }
2681*b0563631STom Van Eyck             tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id);
268232b31808SJens Wiklander             if (tls_id == 0) {
268332b31808SJens Wiklander                 /* This elliptic curve is not supported */
268432b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
268532b31808SJens Wiklander             }
268632b31808SJens Wiklander 
268732b31808SJens Wiklander             /* If the above conversion to TLS ID was fine, then also this one will
268832b31808SJens Wiklander                be, so there is no need to check the return value here */
2689*b0563631STom Van Eyck             mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id, &key_type,
2690*b0563631STom Van Eyck                                                        &ssl->handshake->xxdh_psa_bits);
269132b31808SJens Wiklander 
2692*b0563631STom Van Eyck             ssl->handshake->xxdh_psa_type = key_type;
269332b31808SJens Wiklander 
269432b31808SJens Wiklander             key_attributes = psa_key_attributes_init();
269532b31808SJens Wiklander             psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
269632b31808SJens Wiklander             psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
269732b31808SJens Wiklander             psa_set_key_type(&key_attributes,
2698*b0563631STom Van Eyck                              PSA_KEY_TYPE_ECC_KEY_PAIR(ssl->handshake->xxdh_psa_type));
2699*b0563631STom Van Eyck             psa_set_key_bits(&key_attributes, ssl->handshake->xxdh_psa_bits);
270032b31808SJens Wiklander 
2701*b0563631STom Van Eyck             ret = mbedtls_ecp_write_key_ext(key, &key_len, buf, sizeof(buf));
270232b31808SJens Wiklander             if (ret != 0) {
2703*b0563631STom Van Eyck                 mbedtls_platform_zeroize(buf, sizeof(buf));
2704*b0563631STom Van Eyck                 break;
270532b31808SJens Wiklander             }
270632b31808SJens Wiklander 
270732b31808SJens Wiklander             status = psa_import_key(&key_attributes, buf, key_len,
2708*b0563631STom Van Eyck                                     &ssl->handshake->xxdh_psa_privkey);
270932b31808SJens Wiklander             if (status != PSA_SUCCESS) {
271032b31808SJens Wiklander                 ret = PSA_TO_MBEDTLS_ERR(status);
2711*b0563631STom Van Eyck                 mbedtls_platform_zeroize(buf, sizeof(buf));
2712*b0563631STom Van Eyck                 break;
271332b31808SJens Wiklander             }
271432b31808SJens Wiklander 
2715*b0563631STom Van Eyck             mbedtls_platform_zeroize(buf, sizeof(buf));
271632b31808SJens Wiklander             ret = 0;
271732b31808SJens Wiklander             break;
2718*b0563631STom Van Eyck #endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
271932b31808SJens Wiklander         default:
272032b31808SJens Wiklander             ret = MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
272132b31808SJens Wiklander     }
272232b31808SJens Wiklander 
2723*b0563631STom Van Eyck exit:
2724*b0563631STom Van Eyck     psa_reset_key_attributes(&key_attributes);
272532b31808SJens Wiklander     mbedtls_platform_zeroize(buf, sizeof(buf));
272632b31808SJens Wiklander 
272732b31808SJens Wiklander     return ret;
272832b31808SJens Wiklander }
2729*b0563631STom Van Eyck #else /* MBEDTLS_USE_PSA_CRYPTO */
273032b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
273132b31808SJens Wiklander static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
273232b31808SJens Wiklander {
273332b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
273432b31808SJens Wiklander 
273532b31808SJens Wiklander     const mbedtls_pk_context *private_key = mbedtls_ssl_own_key(ssl);
273632b31808SJens Wiklander     if (private_key == NULL) {
273732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got no server private key"));
273832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED;
273932b31808SJens Wiklander     }
274032b31808SJens Wiklander 
274132b31808SJens Wiklander     if (!mbedtls_pk_can_do(private_key, MBEDTLS_PK_ECKEY)) {
274232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("server key not ECDH capable"));
274332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
274432b31808SJens Wiklander     }
274532b31808SJens Wiklander 
274632b31808SJens Wiklander     if ((ret = mbedtls_ecdh_get_params(&ssl->handshake->ecdh_ctx,
2747*b0563631STom Van Eyck                                        mbedtls_pk_ec_ro(*mbedtls_ssl_own_key(ssl)),
274832b31808SJens Wiklander                                        MBEDTLS_ECDH_OURS)) != 0) {
274932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_get_params"), ret);
275032b31808SJens Wiklander         return ret;
275132b31808SJens Wiklander     }
275232b31808SJens Wiklander 
275332b31808SJens Wiklander     return 0;
275432b31808SJens Wiklander }
2755*b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */
275632b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
275732b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
275832b31808SJens Wiklander 
275932b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \
276032b31808SJens Wiklander     defined(MBEDTLS_SSL_ASYNC_PRIVATE)
276132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
276232b31808SJens Wiklander static int ssl_resume_server_key_exchange(mbedtls_ssl_context *ssl,
276332b31808SJens Wiklander                                           size_t *signature_len)
276432b31808SJens Wiklander {
276532b31808SJens Wiklander     /* Append the signature to ssl->out_msg, leaving 2 bytes for the
276632b31808SJens Wiklander      * signature length which will be added in ssl_write_server_key_exchange
276732b31808SJens Wiklander      * after the call to ssl_prepare_server_key_exchange.
276832b31808SJens Wiklander      * ssl_write_server_key_exchange also takes care of incrementing
276932b31808SJens Wiklander      * ssl->out_msglen. */
277032b31808SJens Wiklander     unsigned char *sig_start = ssl->out_msg + ssl->out_msglen + 2;
277132b31808SJens Wiklander     size_t sig_max_len = (ssl->out_buf + MBEDTLS_SSL_OUT_CONTENT_LEN
277232b31808SJens Wiklander                           - sig_start);
277332b31808SJens Wiklander     int ret = ssl->conf->f_async_resume(ssl,
277432b31808SJens Wiklander                                         sig_start, signature_len, sig_max_len);
277532b31808SJens Wiklander     if (ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
277632b31808SJens Wiklander         ssl->handshake->async_in_progress = 0;
277732b31808SJens Wiklander         mbedtls_ssl_set_async_operation_data(ssl, NULL);
277832b31808SJens Wiklander     }
277932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_RET(2, "ssl_resume_server_key_exchange", ret);
278032b31808SJens Wiklander     return ret;
278132b31808SJens Wiklander }
278232b31808SJens Wiklander #endif /* defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) &&
278332b31808SJens Wiklander           defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
278432b31808SJens Wiklander 
278532b31808SJens Wiklander /* Prepare the ServerKeyExchange message, up to and including
278632b31808SJens Wiklander  * calculating the signature if any, but excluding formatting the
278732b31808SJens Wiklander  * signature and sending the message. */
278832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
278932b31808SJens Wiklander static int ssl_prepare_server_key_exchange(mbedtls_ssl_context *ssl,
279032b31808SJens Wiklander                                            size_t *signature_len)
279132b31808SJens Wiklander {
279232b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
279332b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
279432b31808SJens Wiklander 
279532b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED)
279632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
279732b31808SJens Wiklander     unsigned char *dig_signed = NULL;
279832b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
279932b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED */
280032b31808SJens Wiklander 
280132b31808SJens Wiklander     (void) ciphersuite_info; /* unused in some configurations */
280232b31808SJens Wiklander #if !defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
280332b31808SJens Wiklander     (void) signature_len;
280432b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
280532b31808SJens Wiklander 
280632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
280732b31808SJens Wiklander #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
2808*b0563631STom Van Eyck     size_t out_buf_len = ssl->out_buf_len - (size_t) (ssl->out_msg - ssl->out_buf);
280932b31808SJens Wiklander #else
2810*b0563631STom Van Eyck     size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - (size_t) (ssl->out_msg - ssl->out_buf);
281132b31808SJens Wiklander #endif
281232b31808SJens Wiklander #endif
281332b31808SJens Wiklander 
281432b31808SJens Wiklander     ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */
281532b31808SJens Wiklander 
281632b31808SJens Wiklander     /*
281732b31808SJens Wiklander      *
281832b31808SJens Wiklander      * Part 1: Provide key exchange parameters for chosen ciphersuite.
281932b31808SJens Wiklander      *
282032b31808SJens Wiklander      */
282132b31808SJens Wiklander 
282232b31808SJens Wiklander     /*
282332b31808SJens Wiklander      * - ECJPAKE key exchanges
282432b31808SJens Wiklander      */
282532b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
282632b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
282732b31808SJens Wiklander         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
282832b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
282932b31808SJens Wiklander         unsigned char *out_p = ssl->out_msg + ssl->out_msglen;
283032b31808SJens Wiklander         unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN -
283132b31808SJens Wiklander                                ssl->out_msglen;
283232b31808SJens Wiklander         size_t output_offset = 0;
283332b31808SJens Wiklander         size_t output_len = 0;
283432b31808SJens Wiklander 
283532b31808SJens Wiklander         /*
283632b31808SJens Wiklander          * The first 3 bytes are:
283732b31808SJens Wiklander          * [0] MBEDTLS_ECP_TLS_NAMED_CURVE
283832b31808SJens Wiklander          * [1, 2] elliptic curve's TLS ID
283932b31808SJens Wiklander          *
284032b31808SJens Wiklander          * However since we only support secp256r1 for now, we hardcode its
284132b31808SJens Wiklander          * TLS ID here
284232b31808SJens Wiklander          */
284332b31808SJens Wiklander         uint16_t tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(
284432b31808SJens Wiklander             MBEDTLS_ECP_DP_SECP256R1);
284532b31808SJens Wiklander         if (tls_id == 0) {
284632b31808SJens Wiklander             return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
284732b31808SJens Wiklander         }
284832b31808SJens Wiklander         *out_p = MBEDTLS_ECP_TLS_NAMED_CURVE;
284932b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(tls_id, out_p, 1);
285032b31808SJens Wiklander         output_offset += 3;
285132b31808SJens Wiklander 
285232b31808SJens Wiklander         ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx,
285332b31808SJens Wiklander                                               out_p + output_offset,
285432b31808SJens Wiklander                                               end_p - out_p - output_offset, &output_len,
285532b31808SJens Wiklander                                               MBEDTLS_ECJPAKE_ROUND_TWO);
285632b31808SJens Wiklander         if (ret != 0) {
285732b31808SJens Wiklander             psa_destroy_key(ssl->handshake->psa_pake_password);
285832b31808SJens Wiklander             psa_pake_abort(&ssl->handshake->psa_pake_ctx);
285932b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret);
286032b31808SJens Wiklander             return ret;
286132b31808SJens Wiklander         }
286232b31808SJens Wiklander 
286332b31808SJens Wiklander         output_offset += output_len;
286432b31808SJens Wiklander         ssl->out_msglen += output_offset;
286532b31808SJens Wiklander #else
286632b31808SJens Wiklander         size_t len = 0;
286732b31808SJens Wiklander 
286832b31808SJens Wiklander         ret = mbedtls_ecjpake_write_round_two(
286932b31808SJens Wiklander             &ssl->handshake->ecjpake_ctx,
287032b31808SJens Wiklander             ssl->out_msg + ssl->out_msglen,
287132b31808SJens Wiklander             MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, &len,
287232b31808SJens Wiklander             ssl->conf->f_rng, ssl->conf->p_rng);
287332b31808SJens Wiklander         if (ret != 0) {
287432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_two", ret);
287532b31808SJens Wiklander             return ret;
287632b31808SJens Wiklander         }
287732b31808SJens Wiklander 
287832b31808SJens Wiklander         ssl->out_msglen += len;
287932b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
288032b31808SJens Wiklander     }
288132b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
288232b31808SJens Wiklander 
288332b31808SJens Wiklander     /*
288432b31808SJens Wiklander      * For (EC)DHE key exchanges with PSK, parameters are prefixed by support
288532b31808SJens Wiklander      * identity hint (RFC 4279, Sec. 3). Until someone needs this feature,
288632b31808SJens Wiklander      * we use empty support identity hints here.
288732b31808SJens Wiklander      **/
288832b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)   || \
288932b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
289032b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
289132b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) {
289232b31808SJens Wiklander         ssl->out_msg[ssl->out_msglen++] = 0x00;
289332b31808SJens Wiklander         ssl->out_msg[ssl->out_msglen++] = 0x00;
289432b31808SJens Wiklander     }
289532b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED ||
289632b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
289732b31808SJens Wiklander 
289832b31808SJens Wiklander     /*
289932b31808SJens Wiklander      * - DHE key exchanges
290032b31808SJens Wiklander      */
290132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED)
290232b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_uses_dhe(ciphersuite_info)) {
290332b31808SJens Wiklander         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
290432b31808SJens Wiklander         size_t len = 0;
290532b31808SJens Wiklander 
290632b31808SJens Wiklander         if (ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL) {
290732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("no DH parameters set"));
290832b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
290932b31808SJens Wiklander         }
291032b31808SJens Wiklander 
291132b31808SJens Wiklander         /*
291232b31808SJens Wiklander          * Ephemeral DH parameters:
291332b31808SJens Wiklander          *
291432b31808SJens Wiklander          * struct {
291532b31808SJens Wiklander          *     opaque dh_p<1..2^16-1>;
291632b31808SJens Wiklander          *     opaque dh_g<1..2^16-1>;
291732b31808SJens Wiklander          *     opaque dh_Ys<1..2^16-1>;
291832b31808SJens Wiklander          * } ServerDHParams;
291932b31808SJens Wiklander          */
292032b31808SJens Wiklander         if ((ret = mbedtls_dhm_set_group(&ssl->handshake->dhm_ctx,
292132b31808SJens Wiklander                                          &ssl->conf->dhm_P,
292232b31808SJens Wiklander                                          &ssl->conf->dhm_G)) != 0) {
292332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_set_group", ret);
292432b31808SJens Wiklander             return ret;
292532b31808SJens Wiklander         }
292632b31808SJens Wiklander 
292732b31808SJens Wiklander         if ((ret = mbedtls_dhm_make_params(
292832b31808SJens Wiklander                  &ssl->handshake->dhm_ctx,
292932b31808SJens Wiklander                  (int) mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx),
293032b31808SJens Wiklander                  ssl->out_msg + ssl->out_msglen, &len,
293132b31808SJens Wiklander                  ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
293232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_make_params", ret);
293332b31808SJens Wiklander             return ret;
293432b31808SJens Wiklander         }
293532b31808SJens Wiklander 
293632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
293732b31808SJens Wiklander         dig_signed = ssl->out_msg + ssl->out_msglen;
293832b31808SJens Wiklander #endif
293932b31808SJens Wiklander 
294032b31808SJens Wiklander         ssl->out_msglen += len;
294132b31808SJens Wiklander 
294232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: X ", &ssl->handshake->dhm_ctx.X);
294332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: P ", &ssl->handshake->dhm_ctx.P);
294432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: G ", &ssl->handshake->dhm_ctx.G);
294532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GX", &ssl->handshake->dhm_ctx.GX);
294632b31808SJens Wiklander     }
294732b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED */
294832b31808SJens Wiklander 
294932b31808SJens Wiklander     /*
295032b31808SJens Wiklander      * - ECDHE key exchanges
295132b31808SJens Wiklander      */
295232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED)
295332b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_uses_ecdhe(ciphersuite_info)) {
295432b31808SJens Wiklander         /*
295532b31808SJens Wiklander          * Ephemeral ECDH parameters:
295632b31808SJens Wiklander          *
295732b31808SJens Wiklander          * struct {
295832b31808SJens Wiklander          *     ECParameters curve_params;
295932b31808SJens Wiklander          *     ECPoint      public;
296032b31808SJens Wiklander          * } ServerECDHParams;
296132b31808SJens Wiklander          */
296232b31808SJens Wiklander         uint16_t *curr_tls_id = ssl->handshake->curves_tls_id;
296332b31808SJens Wiklander         const uint16_t *group_list = mbedtls_ssl_get_groups(ssl);
296432b31808SJens Wiklander         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
296532b31808SJens Wiklander         size_t len = 0;
296632b31808SJens Wiklander 
296732b31808SJens Wiklander         /* Match our preference list against the offered curves */
296832b31808SJens Wiklander         if ((group_list == NULL) || (curr_tls_id == NULL)) {
296932b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BAD_CONFIG;
297032b31808SJens Wiklander         }
297132b31808SJens Wiklander         for (; *group_list != 0; group_list++) {
297232b31808SJens Wiklander             for (curr_tls_id = ssl->handshake->curves_tls_id;
297332b31808SJens Wiklander                  *curr_tls_id != 0; curr_tls_id++) {
297432b31808SJens Wiklander                 if (*curr_tls_id == *group_list) {
297532b31808SJens Wiklander                     goto curve_matching_done;
297632b31808SJens Wiklander                 }
297732b31808SJens Wiklander             }
297832b31808SJens Wiklander         }
297932b31808SJens Wiklander 
298032b31808SJens Wiklander curve_matching_done:
298132b31808SJens Wiklander         if (*curr_tls_id == 0) {
298232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("no matching curve for ECDHE"));
298332b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
298432b31808SJens Wiklander         }
298532b31808SJens Wiklander 
298632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("ECDHE curve: %s",
298732b31808SJens Wiklander                                   mbedtls_ssl_get_curve_name_from_tls_id(*curr_tls_id)));
298832b31808SJens Wiklander 
298932b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
299032b31808SJens Wiklander         psa_status_t status = PSA_ERROR_GENERIC_ERROR;
299132b31808SJens Wiklander         psa_key_attributes_t key_attributes;
299232b31808SJens Wiklander         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
299332b31808SJens Wiklander         uint8_t *p = ssl->out_msg + ssl->out_msglen;
299432b31808SJens Wiklander         const size_t header_size = 4; // curve_type(1), namedcurve(2),
299532b31808SJens Wiklander                                       // data length(1)
299632b31808SJens Wiklander         const size_t data_length_size = 1;
2997*b0563631STom Van Eyck         psa_key_type_t key_type = PSA_KEY_TYPE_NONE;
299832b31808SJens Wiklander         size_t ec_bits = 0;
299932b31808SJens Wiklander 
300032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("Perform PSA-based ECDH computation."));
300132b31808SJens Wiklander 
300232b31808SJens Wiklander         /* Convert EC's TLS ID to PSA key type. */
300332b31808SJens Wiklander         if (mbedtls_ssl_get_psa_curve_info_from_tls_id(*curr_tls_id,
3004*b0563631STom Van Eyck                                                        &key_type,
300532b31808SJens Wiklander                                                        &ec_bits) == PSA_ERROR_NOT_SUPPORTED) {
300632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid ecc group parse."));
300732b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
300832b31808SJens Wiklander         }
3009*b0563631STom Van Eyck         handshake->xxdh_psa_type = key_type;
3010*b0563631STom Van Eyck         handshake->xxdh_psa_bits = ec_bits;
301132b31808SJens Wiklander 
301232b31808SJens Wiklander         key_attributes = psa_key_attributes_init();
301332b31808SJens Wiklander         psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
301432b31808SJens Wiklander         psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
3015*b0563631STom Van Eyck         psa_set_key_type(&key_attributes, handshake->xxdh_psa_type);
3016*b0563631STom Van Eyck         psa_set_key_bits(&key_attributes, handshake->xxdh_psa_bits);
301732b31808SJens Wiklander 
301832b31808SJens Wiklander         /*
301932b31808SJens Wiklander          * ECParameters curve_params
302032b31808SJens Wiklander          *
302132b31808SJens Wiklander          * First byte is curve_type, always named_curve
302232b31808SJens Wiklander          */
302332b31808SJens Wiklander         *p++ = MBEDTLS_ECP_TLS_NAMED_CURVE;
302432b31808SJens Wiklander 
302532b31808SJens Wiklander         /*
302632b31808SJens Wiklander          * Next two bytes are the namedcurve value
302732b31808SJens Wiklander          */
302832b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(*curr_tls_id, p, 0);
302932b31808SJens Wiklander         p += 2;
303032b31808SJens Wiklander 
303132b31808SJens Wiklander         /* Generate ECDH private key. */
303232b31808SJens Wiklander         status = psa_generate_key(&key_attributes,
3033*b0563631STom Van Eyck                                   &handshake->xxdh_psa_privkey);
303432b31808SJens Wiklander         if (status != PSA_SUCCESS) {
303532b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
303632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_generate_key", ret);
303732b31808SJens Wiklander             return ret;
303832b31808SJens Wiklander         }
303932b31808SJens Wiklander 
304032b31808SJens Wiklander         /*
304132b31808SJens Wiklander          * ECPoint  public
304232b31808SJens Wiklander          *
304332b31808SJens Wiklander          * First byte is data length.
304432b31808SJens Wiklander          * It will be filled later. p holds now the data length location.
304532b31808SJens Wiklander          */
304632b31808SJens Wiklander 
304732b31808SJens Wiklander         /* Export the public part of the ECDH private key from PSA.
304832b31808SJens Wiklander          * Make one byte space for the length.
304932b31808SJens Wiklander          */
305032b31808SJens Wiklander         unsigned char *own_pubkey = p + data_length_size;
305132b31808SJens Wiklander 
305232b31808SJens Wiklander         size_t own_pubkey_max_len = (size_t) (MBEDTLS_SSL_OUT_CONTENT_LEN
305332b31808SJens Wiklander                                               - (own_pubkey - ssl->out_msg));
305432b31808SJens Wiklander 
3055*b0563631STom Van Eyck         status = psa_export_public_key(handshake->xxdh_psa_privkey,
305632b31808SJens Wiklander                                        own_pubkey, own_pubkey_max_len,
305732b31808SJens Wiklander                                        &len);
305832b31808SJens Wiklander         if (status != PSA_SUCCESS) {
305932b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
306032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_export_public_key", ret);
3061*b0563631STom Van Eyck             (void) psa_destroy_key(handshake->xxdh_psa_privkey);
3062*b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
306332b31808SJens Wiklander             return ret;
306432b31808SJens Wiklander         }
306532b31808SJens Wiklander 
306632b31808SJens Wiklander         /* Store the length of the exported public key. */
306732b31808SJens Wiklander         *p = (uint8_t) len;
306832b31808SJens Wiklander 
306932b31808SJens Wiklander         /* Determine full message length. */
307032b31808SJens Wiklander         len += header_size;
307132b31808SJens Wiklander #else
307232b31808SJens Wiklander         mbedtls_ecp_group_id curr_grp_id =
307332b31808SJens Wiklander             mbedtls_ssl_get_ecp_group_id_from_tls_id(*curr_tls_id);
307432b31808SJens Wiklander 
307532b31808SJens Wiklander         if ((ret = mbedtls_ecdh_setup(&ssl->handshake->ecdh_ctx,
307632b31808SJens Wiklander                                       curr_grp_id)) != 0) {
307732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecp_group_load", ret);
307832b31808SJens Wiklander             return ret;
307932b31808SJens Wiklander         }
308032b31808SJens Wiklander 
308132b31808SJens Wiklander         if ((ret = mbedtls_ecdh_make_params(
308232b31808SJens Wiklander                  &ssl->handshake->ecdh_ctx, &len,
308332b31808SJens Wiklander                  ssl->out_msg + ssl->out_msglen,
308432b31808SJens Wiklander                  MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen,
308532b31808SJens Wiklander                  ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
308632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_make_params", ret);
308732b31808SJens Wiklander             return ret;
308832b31808SJens Wiklander         }
308932b31808SJens Wiklander 
309032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
309132b31808SJens Wiklander                                MBEDTLS_DEBUG_ECDH_Q);
309232b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
309332b31808SJens Wiklander 
309432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
309532b31808SJens Wiklander         dig_signed = ssl->out_msg + ssl->out_msglen;
309632b31808SJens Wiklander #endif
309732b31808SJens Wiklander 
309832b31808SJens Wiklander         ssl->out_msglen += len;
309932b31808SJens Wiklander     }
310032b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED */
310132b31808SJens Wiklander 
310232b31808SJens Wiklander     /*
310332b31808SJens Wiklander      *
310432b31808SJens Wiklander      * Part 2: For key exchanges involving the server signing the
310532b31808SJens Wiklander      *         exchange parameters, compute and add the signature here.
310632b31808SJens Wiklander      *
310732b31808SJens Wiklander      */
310832b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
310932b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_uses_server_signature(ciphersuite_info)) {
311032b31808SJens Wiklander         if (dig_signed == NULL) {
311132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
311232b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
311332b31808SJens Wiklander         }
311432b31808SJens Wiklander 
3115*b0563631STom Van Eyck         size_t dig_signed_len = (size_t) (ssl->out_msg + ssl->out_msglen - dig_signed);
311632b31808SJens Wiklander         size_t hashlen = 0;
3117*b0563631STom Van Eyck         unsigned char hash[MBEDTLS_MD_MAX_SIZE];
311832b31808SJens Wiklander 
311932b31808SJens Wiklander         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
312032b31808SJens Wiklander 
312132b31808SJens Wiklander         /*
312232b31808SJens Wiklander          * 2.1: Choose hash algorithm:
312332b31808SJens Wiklander          *      For TLS 1.2, obey signature-hash-algorithm extension
312432b31808SJens Wiklander          *      to choose appropriate hash.
312532b31808SJens Wiklander          */
312632b31808SJens Wiklander 
312732b31808SJens Wiklander         mbedtls_pk_type_t sig_alg =
312832b31808SJens Wiklander             mbedtls_ssl_get_ciphersuite_sig_pk_alg(ciphersuite_info);
312932b31808SJens Wiklander 
3130*b0563631STom Van Eyck         unsigned char sig_hash =
3131*b0563631STom Van Eyck             (unsigned char) mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
313232b31808SJens Wiklander                 ssl, mbedtls_ssl_sig_from_pk_alg(sig_alg));
313332b31808SJens Wiklander 
313432b31808SJens Wiklander         mbedtls_md_type_t md_alg = mbedtls_ssl_md_alg_from_hash(sig_hash);
313532b31808SJens Wiklander 
313632b31808SJens Wiklander         /*    For TLS 1.2, obey signature-hash-algorithm extension
313732b31808SJens Wiklander          *    (RFC 5246, Sec. 7.4.1.4.1). */
313832b31808SJens Wiklander         if (sig_alg == MBEDTLS_PK_NONE || md_alg == MBEDTLS_MD_NONE) {
313932b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
314032b31808SJens Wiklander             /* (... because we choose a cipher suite
314132b31808SJens Wiklander              *      only if there is a matching hash.) */
314232b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
314332b31808SJens Wiklander         }
314432b31808SJens Wiklander 
314532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("pick hash algorithm %u for signing", (unsigned) md_alg));
314632b31808SJens Wiklander 
314732b31808SJens Wiklander         /*
314832b31808SJens Wiklander          * 2.2: Compute the hash to be signed
314932b31808SJens Wiklander          */
315032b31808SJens Wiklander         if (md_alg != MBEDTLS_MD_NONE) {
315132b31808SJens Wiklander             ret = mbedtls_ssl_get_key_exchange_md_tls1_2(ssl, hash, &hashlen,
315232b31808SJens Wiklander                                                          dig_signed,
315332b31808SJens Wiklander                                                          dig_signed_len,
315432b31808SJens Wiklander                                                          md_alg);
315532b31808SJens Wiklander             if (ret != 0) {
315632b31808SJens Wiklander                 return ret;
315732b31808SJens Wiklander             }
315832b31808SJens Wiklander         } else {
315932b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
316032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
316132b31808SJens Wiklander         }
316232b31808SJens Wiklander 
316332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "parameters hash", hash, hashlen);
316432b31808SJens Wiklander 
316532b31808SJens Wiklander         /*
316632b31808SJens Wiklander          * 2.3: Compute and add the signature
316732b31808SJens Wiklander          */
316832b31808SJens Wiklander         /*
316932b31808SJens Wiklander          * We need to specify signature and hash algorithm explicitly through
317032b31808SJens Wiklander          * a prefix to the signature.
317132b31808SJens Wiklander          *
317232b31808SJens Wiklander          * struct {
317332b31808SJens Wiklander          *    HashAlgorithm hash;
317432b31808SJens Wiklander          *    SignatureAlgorithm signature;
317532b31808SJens Wiklander          * } SignatureAndHashAlgorithm;
317632b31808SJens Wiklander          *
317732b31808SJens Wiklander          * struct {
317832b31808SJens Wiklander          *    SignatureAndHashAlgorithm algorithm;
317932b31808SJens Wiklander          *    opaque signature<0..2^16-1>;
318032b31808SJens Wiklander          * } DigitallySigned;
318132b31808SJens Wiklander          *
318232b31808SJens Wiklander          */
318332b31808SJens Wiklander 
318432b31808SJens Wiklander         ssl->out_msg[ssl->out_msglen++] = mbedtls_ssl_hash_from_md_alg(md_alg);
318532b31808SJens Wiklander         ssl->out_msg[ssl->out_msglen++] = mbedtls_ssl_sig_from_pk_alg(sig_alg);
318632b31808SJens Wiklander 
318732b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
318832b31808SJens Wiklander         if (ssl->conf->f_async_sign_start != NULL) {
318932b31808SJens Wiklander             ret = ssl->conf->f_async_sign_start(ssl,
319032b31808SJens Wiklander                                                 mbedtls_ssl_own_cert(ssl),
319132b31808SJens Wiklander                                                 md_alg, hash, hashlen);
319232b31808SJens Wiklander             switch (ret) {
319332b31808SJens Wiklander                 case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH:
319432b31808SJens Wiklander                     /* act as if f_async_sign was null */
319532b31808SJens Wiklander                     break;
319632b31808SJens Wiklander                 case 0:
319732b31808SJens Wiklander                     ssl->handshake->async_in_progress = 1;
319832b31808SJens Wiklander                     return ssl_resume_server_key_exchange(ssl, signature_len);
319932b31808SJens Wiklander                 case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
320032b31808SJens Wiklander                     ssl->handshake->async_in_progress = 1;
320132b31808SJens Wiklander                     return MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS;
320232b31808SJens Wiklander                 default:
320332b31808SJens Wiklander                     MBEDTLS_SSL_DEBUG_RET(1, "f_async_sign_start", ret);
320432b31808SJens Wiklander                     return ret;
320532b31808SJens Wiklander             }
320632b31808SJens Wiklander         }
320732b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
320832b31808SJens Wiklander 
320932b31808SJens Wiklander         if (mbedtls_ssl_own_key(ssl) == NULL) {
321032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("got no private key"));
321132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED;
321232b31808SJens Wiklander         }
321332b31808SJens Wiklander 
321432b31808SJens Wiklander         /* Append the signature to ssl->out_msg, leaving 2 bytes for the
321532b31808SJens Wiklander          * signature length which will be added in ssl_write_server_key_exchange
321632b31808SJens Wiklander          * after the call to ssl_prepare_server_key_exchange.
321732b31808SJens Wiklander          * ssl_write_server_key_exchange also takes care of incrementing
321832b31808SJens Wiklander          * ssl->out_msglen. */
321932b31808SJens Wiklander         if ((ret = mbedtls_pk_sign(mbedtls_ssl_own_key(ssl),
322032b31808SJens Wiklander                                    md_alg, hash, hashlen,
322132b31808SJens Wiklander                                    ssl->out_msg + ssl->out_msglen + 2,
322232b31808SJens Wiklander                                    out_buf_len - ssl->out_msglen - 2,
322332b31808SJens Wiklander                                    signature_len,
322432b31808SJens Wiklander                                    ssl->conf->f_rng,
322532b31808SJens Wiklander                                    ssl->conf->p_rng)) != 0) {
322632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_sign", ret);
322732b31808SJens Wiklander             return ret;
322832b31808SJens Wiklander         }
322932b31808SJens Wiklander     }
323032b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
323132b31808SJens Wiklander 
323232b31808SJens Wiklander     return 0;
323332b31808SJens Wiklander }
323432b31808SJens Wiklander 
323532b31808SJens Wiklander /* Prepare the ServerKeyExchange message and send it. For ciphersuites
323632b31808SJens Wiklander  * that do not include a ServerKeyExchange message, do nothing. Either
323732b31808SJens Wiklander  * way, if successful, move on to the next step in the SSL state
323832b31808SJens Wiklander  * machine. */
323932b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
324032b31808SJens Wiklander static int ssl_write_server_key_exchange(mbedtls_ssl_context *ssl)
324132b31808SJens Wiklander {
324232b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
324332b31808SJens Wiklander     size_t signature_len = 0;
324432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED)
324532b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
324632b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
324732b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */
324832b31808SJens Wiklander 
324932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server key exchange"));
325032b31808SJens Wiklander 
325132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED)
325232b31808SJens Wiklander     /* Extract static ECDH parameters and abort if ServerKeyExchange
325332b31808SJens Wiklander      * is not needed. */
325432b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_no_pfs(ciphersuite_info)) {
325532b31808SJens Wiklander         /* For suites involving ECDH, extract DH parameters
325632b31808SJens Wiklander          * from certificate at this point. */
325732b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED)
325832b31808SJens Wiklander         if (mbedtls_ssl_ciphersuite_uses_ecdh(ciphersuite_info)) {
325932b31808SJens Wiklander             ret = ssl_get_ecdh_params_from_cert(ssl);
326032b31808SJens Wiklander             if (ret != 0) {
326132b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "ssl_get_ecdh_params_from_cert", ret);
326232b31808SJens Wiklander                 return ret;
326332b31808SJens Wiklander             }
326432b31808SJens Wiklander         }
326532b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */
326632b31808SJens Wiklander 
326732b31808SJens Wiklander         /* Key exchanges not involving ephemeral keys don't use
326832b31808SJens Wiklander          * ServerKeyExchange, so end here. */
326932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write server key exchange"));
327032b31808SJens Wiklander         ssl->state++;
327132b31808SJens Wiklander         return 0;
327232b31808SJens Wiklander     }
327332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */
327432b31808SJens Wiklander 
327532b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \
327632b31808SJens Wiklander     defined(MBEDTLS_SSL_ASYNC_PRIVATE)
327732b31808SJens Wiklander     /* If we have already prepared the message and there is an ongoing
327832b31808SJens Wiklander      * signature operation, resume signing. */
327932b31808SJens Wiklander     if (ssl->handshake->async_in_progress != 0) {
328032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("resuming signature operation"));
328132b31808SJens Wiklander         ret = ssl_resume_server_key_exchange(ssl, &signature_len);
328232b31808SJens Wiklander     } else
328332b31808SJens Wiklander #endif /* defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) &&
328432b31808SJens Wiklander           defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
328532b31808SJens Wiklander     {
328632b31808SJens Wiklander         /* ServerKeyExchange is needed. Prepare the message. */
328732b31808SJens Wiklander         ret = ssl_prepare_server_key_exchange(ssl, &signature_len);
328832b31808SJens Wiklander     }
328932b31808SJens Wiklander 
329032b31808SJens Wiklander     if (ret != 0) {
329132b31808SJens Wiklander         /* If we're starting to write a new message, set ssl->out_msglen
329232b31808SJens Wiklander          * to 0. But if we're resuming after an asynchronous message,
329332b31808SJens Wiklander          * out_msglen is the amount of data written so far and mst be
329432b31808SJens Wiklander          * preserved. */
329532b31808SJens Wiklander         if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
329632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server key exchange (pending)"));
329732b31808SJens Wiklander         } else {
329832b31808SJens Wiklander             ssl->out_msglen = 0;
329932b31808SJens Wiklander         }
330032b31808SJens Wiklander         return ret;
330132b31808SJens Wiklander     }
330232b31808SJens Wiklander 
330332b31808SJens Wiklander     /* If there is a signature, write its length.
330432b31808SJens Wiklander      * ssl_prepare_server_key_exchange already wrote the signature
330532b31808SJens Wiklander      * itself at its proper place in the output buffer. */
330632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
330732b31808SJens Wiklander     if (signature_len != 0) {
330832b31808SJens Wiklander         ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_1(signature_len);
330932b31808SJens Wiklander         ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_0(signature_len);
331032b31808SJens Wiklander 
331132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "my signature",
331232b31808SJens Wiklander                               ssl->out_msg + ssl->out_msglen,
331332b31808SJens Wiklander                               signature_len);
331432b31808SJens Wiklander 
331532b31808SJens Wiklander         /* Skip over the already-written signature */
331632b31808SJens Wiklander         ssl->out_msglen += signature_len;
331732b31808SJens Wiklander     }
331832b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
331932b31808SJens Wiklander 
332032b31808SJens Wiklander     /* Add header and send. */
332132b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
332232b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE;
332332b31808SJens Wiklander 
332432b31808SJens Wiklander     ssl->state++;
332532b31808SJens Wiklander 
332632b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
332732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
332832b31808SJens Wiklander         return ret;
332932b31808SJens Wiklander     }
333032b31808SJens Wiklander 
333132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server key exchange"));
333232b31808SJens Wiklander     return 0;
333332b31808SJens Wiklander }
333432b31808SJens Wiklander 
333532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
333632b31808SJens Wiklander static int ssl_write_server_hello_done(mbedtls_ssl_context *ssl)
333732b31808SJens Wiklander {
333832b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
333932b31808SJens Wiklander 
334032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server hello done"));
334132b31808SJens Wiklander 
334232b31808SJens Wiklander     ssl->out_msglen  = 4;
334332b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
334432b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_HELLO_DONE;
334532b31808SJens Wiklander 
334632b31808SJens Wiklander     ssl->state++;
334732b31808SJens Wiklander 
334832b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
334932b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
335032b31808SJens Wiklander         mbedtls_ssl_send_flight_completed(ssl);
335132b31808SJens Wiklander     }
335232b31808SJens Wiklander #endif
335332b31808SJens Wiklander 
335432b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
335532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
335632b31808SJens Wiklander         return ret;
335732b31808SJens Wiklander     }
335832b31808SJens Wiklander 
335932b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
336032b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
336132b31808SJens Wiklander         (ret = mbedtls_ssl_flight_transmit(ssl)) != 0) {
336232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flight_transmit", ret);
336332b31808SJens Wiklander         return ret;
336432b31808SJens Wiklander     }
336532b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */
336632b31808SJens Wiklander 
336732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello done"));
336832b31808SJens Wiklander 
336932b31808SJens Wiklander     return 0;
337032b31808SJens Wiklander }
337132b31808SJens Wiklander 
337232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
337332b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
337432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
337532b31808SJens Wiklander static int ssl_parse_client_dh_public(mbedtls_ssl_context *ssl, unsigned char **p,
337632b31808SJens Wiklander                                       const unsigned char *end)
337732b31808SJens Wiklander {
337832b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
337932b31808SJens Wiklander     size_t n;
338032b31808SJens Wiklander 
338132b31808SJens Wiklander     /*
338232b31808SJens Wiklander      * Receive G^Y mod P, premaster = (G^Y)^X mod P
338332b31808SJens Wiklander      */
338432b31808SJens Wiklander     if (*p + 2 > end) {
338532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
338632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
338732b31808SJens Wiklander     }
338832b31808SJens Wiklander 
3389*b0563631STom Van Eyck     n = MBEDTLS_GET_UINT16_BE(*p, 0);
339032b31808SJens Wiklander     *p += 2;
339132b31808SJens Wiklander 
339232b31808SJens Wiklander     if (*p + n > end) {
339332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
339432b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
339532b31808SJens Wiklander     }
339632b31808SJens Wiklander 
339732b31808SJens Wiklander     if ((ret = mbedtls_dhm_read_public(&ssl->handshake->dhm_ctx, *p, n)) != 0) {
339832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_read_public", ret);
339932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
340032b31808SJens Wiklander     }
340132b31808SJens Wiklander 
340232b31808SJens Wiklander     *p += n;
340332b31808SJens Wiklander 
340432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GY", &ssl->handshake->dhm_ctx.GY);
340532b31808SJens Wiklander 
340632b31808SJens Wiklander     return ret;
340732b31808SJens Wiklander }
340832b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
340932b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
341032b31808SJens Wiklander 
341132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) ||                           \
341232b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
341332b31808SJens Wiklander 
341432b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
341532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
341632b31808SJens Wiklander static int ssl_resume_decrypt_pms(mbedtls_ssl_context *ssl,
341732b31808SJens Wiklander                                   unsigned char *peer_pms,
341832b31808SJens Wiklander                                   size_t *peer_pmslen,
341932b31808SJens Wiklander                                   size_t peer_pmssize)
342032b31808SJens Wiklander {
342132b31808SJens Wiklander     int ret = ssl->conf->f_async_resume(ssl,
342232b31808SJens Wiklander                                         peer_pms, peer_pmslen, peer_pmssize);
342332b31808SJens Wiklander     if (ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
342432b31808SJens Wiklander         ssl->handshake->async_in_progress = 0;
342532b31808SJens Wiklander         mbedtls_ssl_set_async_operation_data(ssl, NULL);
342632b31808SJens Wiklander     }
342732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_RET(2, "ssl_decrypt_encrypted_pms", ret);
342832b31808SJens Wiklander     return ret;
342932b31808SJens Wiklander }
343032b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
343132b31808SJens Wiklander 
343232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
343332b31808SJens Wiklander static int ssl_decrypt_encrypted_pms(mbedtls_ssl_context *ssl,
343432b31808SJens Wiklander                                      const unsigned char *p,
343532b31808SJens Wiklander                                      const unsigned char *end,
343632b31808SJens Wiklander                                      unsigned char *peer_pms,
343732b31808SJens Wiklander                                      size_t *peer_pmslen,
343832b31808SJens Wiklander                                      size_t peer_pmssize)
343932b31808SJens Wiklander {
344032b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
344132b31808SJens Wiklander 
344232b31808SJens Wiklander     mbedtls_x509_crt *own_cert = mbedtls_ssl_own_cert(ssl);
344332b31808SJens Wiklander     if (own_cert == NULL) {
344432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got no local certificate"));
344532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE;
344632b31808SJens Wiklander     }
344732b31808SJens Wiklander     mbedtls_pk_context *public_key = &own_cert->pk;
344832b31808SJens Wiklander     mbedtls_pk_context *private_key = mbedtls_ssl_own_key(ssl);
344932b31808SJens Wiklander     size_t len = mbedtls_pk_get_len(public_key);
345032b31808SJens Wiklander 
345132b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
345232b31808SJens Wiklander     /* If we have already started decoding the message and there is an ongoing
345332b31808SJens Wiklander      * decryption operation, resume signing. */
345432b31808SJens Wiklander     if (ssl->handshake->async_in_progress != 0) {
345532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("resuming decryption operation"));
345632b31808SJens Wiklander         return ssl_resume_decrypt_pms(ssl,
345732b31808SJens Wiklander                                       peer_pms, peer_pmslen, peer_pmssize);
345832b31808SJens Wiklander     }
345932b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
346032b31808SJens Wiklander 
346132b31808SJens Wiklander     /*
346232b31808SJens Wiklander      * Prepare to decrypt the premaster using own private RSA key
346332b31808SJens Wiklander      */
346432b31808SJens Wiklander     if (p + 2 > end) {
346532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
346632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
346732b31808SJens Wiklander     }
346832b31808SJens Wiklander     if (*p++ != MBEDTLS_BYTE_1(len) ||
346932b31808SJens Wiklander         *p++ != MBEDTLS_BYTE_0(len)) {
347032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
347132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
347232b31808SJens Wiklander     }
347332b31808SJens Wiklander 
347432b31808SJens Wiklander     if (p + len != end) {
347532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
347632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
347732b31808SJens Wiklander     }
347832b31808SJens Wiklander 
347932b31808SJens Wiklander     /*
348032b31808SJens Wiklander      * Decrypt the premaster secret
348132b31808SJens Wiklander      */
348232b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
348332b31808SJens Wiklander     if (ssl->conf->f_async_decrypt_start != NULL) {
348432b31808SJens Wiklander         ret = ssl->conf->f_async_decrypt_start(ssl,
348532b31808SJens Wiklander                                                mbedtls_ssl_own_cert(ssl),
348632b31808SJens Wiklander                                                p, len);
348732b31808SJens Wiklander         switch (ret) {
348832b31808SJens Wiklander             case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH:
348932b31808SJens Wiklander                 /* act as if f_async_decrypt_start was null */
349032b31808SJens Wiklander                 break;
349132b31808SJens Wiklander             case 0:
349232b31808SJens Wiklander                 ssl->handshake->async_in_progress = 1;
349332b31808SJens Wiklander                 return ssl_resume_decrypt_pms(ssl,
349432b31808SJens Wiklander                                               peer_pms,
349532b31808SJens Wiklander                                               peer_pmslen,
349632b31808SJens Wiklander                                               peer_pmssize);
349732b31808SJens Wiklander             case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
349832b31808SJens Wiklander                 ssl->handshake->async_in_progress = 1;
349932b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS;
350032b31808SJens Wiklander             default:
350132b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "f_async_decrypt_start", ret);
350232b31808SJens Wiklander                 return ret;
350332b31808SJens Wiklander         }
350432b31808SJens Wiklander     }
350532b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
350632b31808SJens Wiklander 
350732b31808SJens Wiklander     if (!mbedtls_pk_can_do(private_key, MBEDTLS_PK_RSA)) {
350832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got no RSA private key"));
350932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED;
351032b31808SJens Wiklander     }
351132b31808SJens Wiklander 
351232b31808SJens Wiklander     ret = mbedtls_pk_decrypt(private_key, p, len,
351332b31808SJens Wiklander                              peer_pms, peer_pmslen, peer_pmssize,
351432b31808SJens Wiklander                              ssl->conf->f_rng, ssl->conf->p_rng);
351532b31808SJens Wiklander     return ret;
351632b31808SJens Wiklander }
351732b31808SJens Wiklander 
351832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
351932b31808SJens Wiklander static int ssl_parse_encrypted_pms(mbedtls_ssl_context *ssl,
352032b31808SJens Wiklander                                    const unsigned char *p,
352132b31808SJens Wiklander                                    const unsigned char *end,
352232b31808SJens Wiklander                                    size_t pms_offset)
352332b31808SJens Wiklander {
352432b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
352532b31808SJens Wiklander     unsigned char *pms = ssl->handshake->premaster + pms_offset;
352632b31808SJens Wiklander     unsigned char ver[2];
352732b31808SJens Wiklander     unsigned char fake_pms[48], peer_pms[48];
3528*b0563631STom Van Eyck     size_t peer_pmslen;
3529*b0563631STom Van Eyck     mbedtls_ct_condition_t diff;
353032b31808SJens Wiklander 
353132b31808SJens Wiklander     /* In case of a failure in decryption, the decryption may write less than
353232b31808SJens Wiklander      * 2 bytes of output, but we always read the first two bytes. It doesn't
353332b31808SJens Wiklander      * matter in the end because diff will be nonzero in that case due to
353432b31808SJens Wiklander      * ret being nonzero, and we only care whether diff is 0.
353532b31808SJens Wiklander      * But do initialize peer_pms and peer_pmslen for robustness anyway. This
353632b31808SJens Wiklander      * also makes memory analyzers happy (don't access uninitialized memory,
353732b31808SJens Wiklander      * even if it's an unsigned char). */
353832b31808SJens Wiklander     peer_pms[0] = peer_pms[1] = ~0;
353932b31808SJens Wiklander     peer_pmslen = 0;
354032b31808SJens Wiklander 
354132b31808SJens Wiklander     ret = ssl_decrypt_encrypted_pms(ssl, p, end,
354232b31808SJens Wiklander                                     peer_pms,
354332b31808SJens Wiklander                                     &peer_pmslen,
354432b31808SJens Wiklander                                     sizeof(peer_pms));
354532b31808SJens Wiklander 
354632b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
354732b31808SJens Wiklander     if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
354832b31808SJens Wiklander         return ret;
354932b31808SJens Wiklander     }
355032b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
355132b31808SJens Wiklander 
355232b31808SJens Wiklander     mbedtls_ssl_write_version(ver, ssl->conf->transport,
355332b31808SJens Wiklander                               ssl->session_negotiate->tls_version);
355432b31808SJens Wiklander 
355532b31808SJens Wiklander     /* Avoid data-dependent branches while checking for invalid
355632b31808SJens Wiklander      * padding, to protect against timing-based Bleichenbacher-type
355732b31808SJens Wiklander      * attacks. */
3558*b0563631STom Van Eyck     diff = mbedtls_ct_bool(ret);
3559*b0563631STom Van Eyck     diff = mbedtls_ct_bool_or(diff, mbedtls_ct_uint_ne(peer_pmslen, 48));
3560*b0563631STom Van Eyck     diff = mbedtls_ct_bool_or(diff, mbedtls_ct_uint_ne(peer_pms[0], ver[0]));
3561*b0563631STom Van Eyck     diff = mbedtls_ct_bool_or(diff, mbedtls_ct_uint_ne(peer_pms[1], ver[1]));
356232b31808SJens Wiklander 
356332b31808SJens Wiklander     /*
356432b31808SJens Wiklander      * Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding
356532b31808SJens Wiklander      * must not cause the connection to end immediately; instead, send a
356632b31808SJens Wiklander      * bad_record_mac later in the handshake.
356732b31808SJens Wiklander      * To protect against timing-based variants of the attack, we must
356832b31808SJens Wiklander      * not have any branch that depends on whether the decryption was
356932b31808SJens Wiklander      * successful. In particular, always generate the fake premaster secret,
357032b31808SJens Wiklander      * regardless of whether it will ultimately influence the output or not.
357132b31808SJens Wiklander      */
357232b31808SJens Wiklander     ret = ssl->conf->f_rng(ssl->conf->p_rng, fake_pms, sizeof(fake_pms));
357332b31808SJens Wiklander     if (ret != 0) {
357432b31808SJens Wiklander         /* It's ok to abort on an RNG failure, since this does not reveal
357532b31808SJens Wiklander          * anything about the RSA decryption. */
357632b31808SJens Wiklander         return ret;
357732b31808SJens Wiklander     }
357832b31808SJens Wiklander 
357932b31808SJens Wiklander #if defined(MBEDTLS_SSL_DEBUG_ALL)
3580*b0563631STom Van Eyck     if (diff != MBEDTLS_CT_FALSE) {
358132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
358232b31808SJens Wiklander     }
358332b31808SJens Wiklander #endif
358432b31808SJens Wiklander 
358532b31808SJens Wiklander     if (sizeof(ssl->handshake->premaster) < pms_offset ||
358632b31808SJens Wiklander         sizeof(ssl->handshake->premaster) - pms_offset < 48) {
358732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
358832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
358932b31808SJens Wiklander     }
359032b31808SJens Wiklander     ssl->handshake->pmslen = 48;
359132b31808SJens Wiklander 
359232b31808SJens Wiklander     /* Set pms to either the true or the fake PMS, without
359332b31808SJens Wiklander      * data-dependent branches. */
3594*b0563631STom Van Eyck     mbedtls_ct_memcpy_if(diff, pms, fake_pms, peer_pms, ssl->handshake->pmslen);
359532b31808SJens Wiklander 
359632b31808SJens Wiklander     return 0;
359732b31808SJens Wiklander }
359832b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
359932b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
360032b31808SJens Wiklander 
360132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
360232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
360332b31808SJens Wiklander static int ssl_parse_client_psk_identity(mbedtls_ssl_context *ssl, unsigned char **p,
360432b31808SJens Wiklander                                          const unsigned char *end)
360532b31808SJens Wiklander {
360632b31808SJens Wiklander     int ret = 0;
360732b31808SJens Wiklander     uint16_t n;
360832b31808SJens Wiklander 
360932b31808SJens Wiklander     if (ssl_conf_has_psk_or_cb(ssl->conf) == 0) {
361032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got no pre-shared key"));
361132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED;
361232b31808SJens Wiklander     }
361332b31808SJens Wiklander 
361432b31808SJens Wiklander     /*
361532b31808SJens Wiklander      * Receive client pre-shared key identity name
361632b31808SJens Wiklander      */
361732b31808SJens Wiklander     if (end - *p < 2) {
361832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
361932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
362032b31808SJens Wiklander     }
362132b31808SJens Wiklander 
3622*b0563631STom Van Eyck     n = MBEDTLS_GET_UINT16_BE(*p, 0);
362332b31808SJens Wiklander     *p += 2;
362432b31808SJens Wiklander 
362532b31808SJens Wiklander     if (n == 0 || n > end - *p) {
362632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
362732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
362832b31808SJens Wiklander     }
362932b31808SJens Wiklander 
363032b31808SJens Wiklander     if (ssl->conf->f_psk != NULL) {
363132b31808SJens Wiklander         if (ssl->conf->f_psk(ssl->conf->p_psk, ssl, *p, n) != 0) {
363232b31808SJens Wiklander             ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
363332b31808SJens Wiklander         }
363432b31808SJens Wiklander     } else {
363532b31808SJens Wiklander         /* Identity is not a big secret since clients send it in the clear,
363632b31808SJens Wiklander          * but treat it carefully anyway, just in case */
363732b31808SJens Wiklander         if (n != ssl->conf->psk_identity_len ||
363832b31808SJens Wiklander             mbedtls_ct_memcmp(ssl->conf->psk_identity, *p, n) != 0) {
363932b31808SJens Wiklander             ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
364032b31808SJens Wiklander         }
364132b31808SJens Wiklander     }
364232b31808SJens Wiklander 
364332b31808SJens Wiklander     if (ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) {
364432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "Unknown PSK identity", *p, n);
364532b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
364632b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY);
364732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
364832b31808SJens Wiklander     }
364932b31808SJens Wiklander 
365032b31808SJens Wiklander     *p += n;
365132b31808SJens Wiklander 
365232b31808SJens Wiklander     return 0;
365332b31808SJens Wiklander }
365432b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
365532b31808SJens Wiklander 
365632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
365732b31808SJens Wiklander static int ssl_parse_client_key_exchange(mbedtls_ssl_context *ssl)
365832b31808SJens Wiklander {
365932b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
366032b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
366132b31808SJens Wiklander     unsigned char *p, *end;
366232b31808SJens Wiklander 
366332b31808SJens Wiklander     ciphersuite_info = ssl->handshake->ciphersuite_info;
366432b31808SJens Wiklander 
366532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse client key exchange"));
366632b31808SJens Wiklander 
366732b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE) && \
366832b31808SJens Wiklander     (defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
366932b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED))
367032b31808SJens Wiklander     if ((ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
367132b31808SJens Wiklander          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) &&
367232b31808SJens Wiklander         (ssl->handshake->async_in_progress != 0)) {
367332b31808SJens Wiklander         /* We've already read a record and there is an asynchronous
367432b31808SJens Wiklander          * operation in progress to decrypt it. So skip reading the
367532b31808SJens Wiklander          * record. */
367632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("will resume decryption of previously-read record"));
367732b31808SJens Wiklander     } else
367832b31808SJens Wiklander #endif
367932b31808SJens Wiklander     if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
368032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
368132b31808SJens Wiklander         return ret;
368232b31808SJens Wiklander     }
368332b31808SJens Wiklander 
368432b31808SJens Wiklander     p = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl);
368532b31808SJens Wiklander     end = ssl->in_msg + ssl->in_hslen;
368632b31808SJens Wiklander 
368732b31808SJens Wiklander     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
368832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
368932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
369032b31808SJens Wiklander     }
369132b31808SJens Wiklander 
369232b31808SJens Wiklander     if (ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE) {
369332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
369432b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
369532b31808SJens Wiklander     }
369632b31808SJens Wiklander 
369732b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
369832b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA) {
369932b31808SJens Wiklander         if ((ret = ssl_parse_client_dh_public(ssl, &p, end)) != 0) {
370032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_dh_public"), ret);
370132b31808SJens Wiklander             return ret;
370232b31808SJens Wiklander         }
370332b31808SJens Wiklander 
370432b31808SJens Wiklander         if (p != end) {
370532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange"));
370632b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
370732b31808SJens Wiklander         }
370832b31808SJens Wiklander 
370932b31808SJens Wiklander         if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx,
371032b31808SJens Wiklander                                            ssl->handshake->premaster,
371132b31808SJens Wiklander                                            MBEDTLS_PREMASTER_SIZE,
371232b31808SJens Wiklander                                            &ssl->handshake->pmslen,
371332b31808SJens Wiklander                                            ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
371432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret);
371532b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
371632b31808SJens Wiklander         }
371732b31808SJens Wiklander 
371832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K);
371932b31808SJens Wiklander     } else
372032b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
372132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
372232b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
372332b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
372432b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
372532b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
372632b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
372732b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
372832b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA) {
372932b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
373032b31808SJens Wiklander         size_t data_len = (size_t) (*p++);
373132b31808SJens Wiklander         size_t buf_len = (size_t) (end - p);
373232b31808SJens Wiklander         psa_status_t status = PSA_ERROR_GENERIC_ERROR;
373332b31808SJens Wiklander         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
373432b31808SJens Wiklander 
3735*b0563631STom Van Eyck         MBEDTLS_SSL_DEBUG_MSG(3, ("Read the peer's public key."));
373632b31808SJens Wiklander 
373732b31808SJens Wiklander         /*
373832b31808SJens Wiklander          * We must have at least two bytes (1 for length, at least 1 for data)
373932b31808SJens Wiklander          */
374032b31808SJens Wiklander         if (buf_len < 2) {
3741*b0563631STom Van Eyck             MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid buffer length: %" MBEDTLS_PRINTF_SIZET,
3742*b0563631STom Van Eyck                                       buf_len));
3743*b0563631STom Van Eyck             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
374432b31808SJens Wiklander         }
374532b31808SJens Wiklander 
374632b31808SJens Wiklander         if (data_len < 1 || data_len > buf_len) {
3747*b0563631STom Van Eyck             MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid data length: %" MBEDTLS_PRINTF_SIZET
3748*b0563631STom Van Eyck                                       " > %" MBEDTLS_PRINTF_SIZET,
3749*b0563631STom Van Eyck                                       data_len, buf_len));
3750*b0563631STom Van Eyck             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
375132b31808SJens Wiklander         }
375232b31808SJens Wiklander 
375332b31808SJens Wiklander         /* Store peer's ECDH public key. */
3754*b0563631STom Van Eyck         if (data_len > sizeof(handshake->xxdh_psa_peerkey)) {
3755*b0563631STom Van Eyck             MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid public key length: %" MBEDTLS_PRINTF_SIZET
3756*b0563631STom Van Eyck                                       " > %" MBEDTLS_PRINTF_SIZET,
3757*b0563631STom Van Eyck                                       data_len,
3758*b0563631STom Van Eyck                                       sizeof(handshake->xxdh_psa_peerkey)));
3759*b0563631STom Van Eyck             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
3760*b0563631STom Van Eyck         }
3761*b0563631STom Van Eyck         memcpy(handshake->xxdh_psa_peerkey, p, data_len);
3762*b0563631STom Van Eyck         handshake->xxdh_psa_peerkey_len = data_len;
376332b31808SJens Wiklander 
376432b31808SJens Wiklander         /* Compute ECDH shared secret. */
376532b31808SJens Wiklander         status = psa_raw_key_agreement(
3766*b0563631STom Van Eyck             PSA_ALG_ECDH, handshake->xxdh_psa_privkey,
3767*b0563631STom Van Eyck             handshake->xxdh_psa_peerkey, handshake->xxdh_psa_peerkey_len,
376832b31808SJens Wiklander             handshake->premaster, sizeof(handshake->premaster),
376932b31808SJens Wiklander             &handshake->pmslen);
377032b31808SJens Wiklander         if (status != PSA_SUCCESS) {
377132b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
377232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_raw_key_agreement", ret);
3773*b0563631STom Van Eyck             if (handshake->xxdh_psa_privkey_is_external == 0) {
3774*b0563631STom Van Eyck                 (void) psa_destroy_key(handshake->xxdh_psa_privkey);
377532b31808SJens Wiklander             }
3776*b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
377732b31808SJens Wiklander             return ret;
377832b31808SJens Wiklander         }
377932b31808SJens Wiklander 
3780*b0563631STom Van Eyck         if (handshake->xxdh_psa_privkey_is_external == 0) {
3781*b0563631STom Van Eyck             status = psa_destroy_key(handshake->xxdh_psa_privkey);
378232b31808SJens Wiklander 
378332b31808SJens Wiklander             if (status != PSA_SUCCESS) {
378432b31808SJens Wiklander                 ret = PSA_TO_MBEDTLS_ERR(status);
378532b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "psa_destroy_key", ret);
378632b31808SJens Wiklander                 return ret;
378732b31808SJens Wiklander             }
378832b31808SJens Wiklander         }
3789*b0563631STom Van Eyck         handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
379032b31808SJens Wiklander #else
379132b31808SJens Wiklander         if ((ret = mbedtls_ecdh_read_public(&ssl->handshake->ecdh_ctx,
3792*b0563631STom Van Eyck                                             p, (size_t) (end - p))) != 0) {
379332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_read_public", ret);
379432b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
379532b31808SJens Wiklander         }
379632b31808SJens Wiklander 
379732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
379832b31808SJens Wiklander                                MBEDTLS_DEBUG_ECDH_QP);
379932b31808SJens Wiklander 
380032b31808SJens Wiklander         if ((ret = mbedtls_ecdh_calc_secret(&ssl->handshake->ecdh_ctx,
380132b31808SJens Wiklander                                             &ssl->handshake->pmslen,
380232b31808SJens Wiklander                                             ssl->handshake->premaster,
380332b31808SJens Wiklander                                             MBEDTLS_MPI_MAX_SIZE,
380432b31808SJens Wiklander                                             ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
380532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_calc_secret", ret);
380632b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
380732b31808SJens Wiklander         }
380832b31808SJens Wiklander 
380932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
381032b31808SJens Wiklander                                MBEDTLS_DEBUG_ECDH_Z);
381132b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
381232b31808SJens Wiklander     } else
381332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
381432b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
381532b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
381632b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
381732b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
381832b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK) {
381932b31808SJens Wiklander         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
382032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
382132b31808SJens Wiklander             return ret;
382232b31808SJens Wiklander         }
382332b31808SJens Wiklander 
382432b31808SJens Wiklander         if (p != end) {
382532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange"));
382632b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
382732b31808SJens Wiklander         }
382832b31808SJens Wiklander 
382932b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO)
383032b31808SJens Wiklander         if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
3831*b0563631STom Van Eyck                                                     (mbedtls_key_exchange_type_t) ciphersuite_info->
3832*b0563631STom Van Eyck                                                     key_exchange)) != 0) {
383332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret);
383432b31808SJens Wiklander             return ret;
383532b31808SJens Wiklander         }
383632b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO */
383732b31808SJens Wiklander     } else
383832b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
383932b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
384032b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) {
384132b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
384232b31808SJens Wiklander         if (ssl->handshake->async_in_progress != 0) {
384332b31808SJens Wiklander             /* There is an asynchronous operation in progress to
384432b31808SJens Wiklander              * decrypt the encrypted premaster secret, so skip
384532b31808SJens Wiklander              * directly to resuming this operation. */
384632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3, ("PSK identity already parsed"));
384732b31808SJens Wiklander             /* Update p to skip the PSK identity. ssl_parse_encrypted_pms
384832b31808SJens Wiklander              * won't actually use it, but maintain p anyway for robustness. */
384932b31808SJens Wiklander             p += ssl->conf->psk_identity_len + 2;
385032b31808SJens Wiklander         } else
385132b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
385232b31808SJens Wiklander         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
385332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
385432b31808SJens Wiklander             return ret;
385532b31808SJens Wiklander         }
385632b31808SJens Wiklander 
385732b31808SJens Wiklander         if ((ret = ssl_parse_encrypted_pms(ssl, p, end, 2)) != 0) {
385832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_encrypted_pms"), ret);
385932b31808SJens Wiklander             return ret;
386032b31808SJens Wiklander         }
386132b31808SJens Wiklander 
386232b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO)
386332b31808SJens Wiklander         if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
3864*b0563631STom Van Eyck                                                     (mbedtls_key_exchange_type_t) ciphersuite_info->
3865*b0563631STom Van Eyck                                                     key_exchange)) != 0) {
386632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret);
386732b31808SJens Wiklander             return ret;
386832b31808SJens Wiklander         }
386932b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO */
387032b31808SJens Wiklander     } else
387132b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
387232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
387332b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK) {
387432b31808SJens Wiklander         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
387532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
387632b31808SJens Wiklander             return ret;
387732b31808SJens Wiklander         }
387832b31808SJens Wiklander         if ((ret = ssl_parse_client_dh_public(ssl, &p, end)) != 0) {
387932b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_dh_public"), ret);
388032b31808SJens Wiklander             return ret;
388132b31808SJens Wiklander         }
388232b31808SJens Wiklander 
388332b31808SJens Wiklander         if (p != end) {
388432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange"));
388532b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
388632b31808SJens Wiklander         }
388732b31808SJens Wiklander 
388832b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
388932b31808SJens Wiklander         unsigned char *pms = ssl->handshake->premaster;
389032b31808SJens Wiklander         unsigned char *pms_end = pms + sizeof(ssl->handshake->premaster);
389132b31808SJens Wiklander         size_t pms_len;
389232b31808SJens Wiklander 
389332b31808SJens Wiklander         /* Write length only when we know the actual value */
389432b31808SJens Wiklander         if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx,
389532b31808SJens Wiklander                                            pms + 2, pms_end - (pms + 2), &pms_len,
389632b31808SJens Wiklander                                            ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
389732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret);
389832b31808SJens Wiklander             return ret;
389932b31808SJens Wiklander         }
390032b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(pms_len, pms, 0);
390132b31808SJens Wiklander         pms += 2 + pms_len;
390232b31808SJens Wiklander 
390332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K);
390432b31808SJens Wiklander #else
390532b31808SJens Wiklander         if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
3906*b0563631STom Van Eyck                                                     (mbedtls_key_exchange_type_t) ciphersuite_info->
3907*b0563631STom Van Eyck                                                     key_exchange)) != 0) {
390832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret);
390932b31808SJens Wiklander             return ret;
391032b31808SJens Wiklander         }
391132b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
391232b31808SJens Wiklander     } else
391332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
391432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
391532b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) {
391632b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
391732b31808SJens Wiklander         psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
391832b31808SJens Wiklander         psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED;
391932b31808SJens Wiklander         uint8_t ecpoint_len;
392032b31808SJens Wiklander 
392132b31808SJens Wiklander         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
392232b31808SJens Wiklander 
392332b31808SJens Wiklander         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
392432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
3925*b0563631STom Van Eyck             psa_destroy_key(handshake->xxdh_psa_privkey);
3926*b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
392732b31808SJens Wiklander             return ret;
392832b31808SJens Wiklander         }
392932b31808SJens Wiklander 
393032b31808SJens Wiklander         /* Keep a copy of the peer's public key */
393132b31808SJens Wiklander         if (p >= end) {
3932*b0563631STom Van Eyck             psa_destroy_key(handshake->xxdh_psa_privkey);
3933*b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
393432b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
393532b31808SJens Wiklander         }
393632b31808SJens Wiklander 
393732b31808SJens Wiklander         ecpoint_len = *(p++);
393832b31808SJens Wiklander         if ((size_t) (end - p) < ecpoint_len) {
3939*b0563631STom Van Eyck             psa_destroy_key(handshake->xxdh_psa_privkey);
3940*b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
394132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
394232b31808SJens Wiklander         }
394332b31808SJens Wiklander 
3944*b0563631STom Van Eyck         /* When FFDH is enabled, the array handshake->xxdh_psa_peer_key size takes into account
3945*b0563631STom Van Eyck            the sizes of the FFDH keys which are at least 2048 bits.
3946*b0563631STom Van Eyck            The size of the array is thus greater than 256 bytes which is greater than any
3947*b0563631STom Van Eyck            possible value of ecpoint_len (type uint8_t) and the check below can be skipped.*/
3948*b0563631STom Van Eyck #if !defined(PSA_WANT_ALG_FFDH)
3949*b0563631STom Van Eyck         if (ecpoint_len > sizeof(handshake->xxdh_psa_peerkey)) {
3950*b0563631STom Van Eyck             psa_destroy_key(handshake->xxdh_psa_privkey);
3951*b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
395232b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
395332b31808SJens Wiklander         }
3954*b0563631STom Van Eyck #else
3955*b0563631STom Van Eyck         MBEDTLS_STATIC_ASSERT(sizeof(handshake->xxdh_psa_peerkey) >= UINT8_MAX,
3956*b0563631STom Van Eyck                               "peer key buffer too small");
3957*b0563631STom Van Eyck #endif
395832b31808SJens Wiklander 
3959*b0563631STom Van Eyck         memcpy(handshake->xxdh_psa_peerkey, p, ecpoint_len);
3960*b0563631STom Van Eyck         handshake->xxdh_psa_peerkey_len = ecpoint_len;
396132b31808SJens Wiklander         p += ecpoint_len;
396232b31808SJens Wiklander 
396332b31808SJens Wiklander         /* As RFC 5489 section 2, the premaster secret is formed as follows:
396432b31808SJens Wiklander          * - a uint16 containing the length (in octets) of the ECDH computation
396532b31808SJens Wiklander          * - the octet string produced by the ECDH computation
396632b31808SJens Wiklander          * - a uint16 containing the length (in octets) of the PSK
396732b31808SJens Wiklander          * - the PSK itself
396832b31808SJens Wiklander          */
396932b31808SJens Wiklander         unsigned char *psm = ssl->handshake->premaster;
397032b31808SJens Wiklander         const unsigned char * const psm_end =
397132b31808SJens Wiklander             psm + sizeof(ssl->handshake->premaster);
397232b31808SJens Wiklander         /* uint16 to store length (in octets) of the ECDH computation */
397332b31808SJens Wiklander         const size_t zlen_size = 2;
397432b31808SJens Wiklander         size_t zlen = 0;
397532b31808SJens Wiklander 
397632b31808SJens Wiklander         /* Compute ECDH shared secret. */
397732b31808SJens Wiklander         status = psa_raw_key_agreement(PSA_ALG_ECDH,
3978*b0563631STom Van Eyck                                        handshake->xxdh_psa_privkey,
3979*b0563631STom Van Eyck                                        handshake->xxdh_psa_peerkey,
3980*b0563631STom Van Eyck                                        handshake->xxdh_psa_peerkey_len,
398132b31808SJens Wiklander                                        psm + zlen_size,
398232b31808SJens Wiklander                                        psm_end - (psm + zlen_size),
398332b31808SJens Wiklander                                        &zlen);
398432b31808SJens Wiklander 
3985*b0563631STom Van Eyck         destruction_status = psa_destroy_key(handshake->xxdh_psa_privkey);
3986*b0563631STom Van Eyck         handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
398732b31808SJens Wiklander 
398832b31808SJens Wiklander         if (status != PSA_SUCCESS) {
398932b31808SJens Wiklander             return PSA_TO_MBEDTLS_ERR(status);
399032b31808SJens Wiklander         } else if (destruction_status != PSA_SUCCESS) {
399132b31808SJens Wiklander             return PSA_TO_MBEDTLS_ERR(destruction_status);
399232b31808SJens Wiklander         }
399332b31808SJens Wiklander 
399432b31808SJens Wiklander         /* Write the ECDH computation length before the ECDH computation */
399532b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(zlen, psm, 0);
399632b31808SJens Wiklander         psm += zlen_size + zlen;
399732b31808SJens Wiklander 
399832b31808SJens Wiklander #else /* MBEDTLS_USE_PSA_CRYPTO */
399932b31808SJens Wiklander         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
400032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
400132b31808SJens Wiklander             return ret;
400232b31808SJens Wiklander         }
400332b31808SJens Wiklander 
400432b31808SJens Wiklander         if ((ret = mbedtls_ecdh_read_public(&ssl->handshake->ecdh_ctx,
4005*b0563631STom Van Eyck                                             p, (size_t) (end - p))) != 0) {
400632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_read_public", ret);
400732b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
400832b31808SJens Wiklander         }
400932b31808SJens Wiklander 
401032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
401132b31808SJens Wiklander                                MBEDTLS_DEBUG_ECDH_QP);
401232b31808SJens Wiklander 
401332b31808SJens Wiklander         if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
4014*b0563631STom Van Eyck                                                     (mbedtls_key_exchange_type_t) ciphersuite_info->
4015*b0563631STom Van Eyck                                                     key_exchange)) != 0) {
401632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret);
401732b31808SJens Wiklander             return ret;
401832b31808SJens Wiklander         }
401932b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
402032b31808SJens Wiklander     } else
402132b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
402232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
402332b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) {
402432b31808SJens Wiklander         if ((ret = ssl_parse_encrypted_pms(ssl, p, end, 0)) != 0) {
402532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_parse_encrypted_pms_secret"), ret);
402632b31808SJens Wiklander             return ret;
402732b31808SJens Wiklander         }
402832b31808SJens Wiklander     } else
402932b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
403032b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
403132b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
403232b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
403332b31808SJens Wiklander         if ((ret = mbedtls_psa_ecjpake_read_round(
4034*b0563631STom Van Eyck                  &ssl->handshake->psa_pake_ctx, p, (size_t) (end - p),
403532b31808SJens Wiklander                  MBEDTLS_ECJPAKE_ROUND_TWO)) != 0) {
403632b31808SJens Wiklander             psa_destroy_key(ssl->handshake->psa_pake_password);
403732b31808SJens Wiklander             psa_pake_abort(&ssl->handshake->psa_pake_ctx);
403832b31808SJens Wiklander 
403932b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round two", ret);
404032b31808SJens Wiklander             return ret;
404132b31808SJens Wiklander         }
404232b31808SJens Wiklander #else
404332b31808SJens Wiklander         ret = mbedtls_ecjpake_read_round_two(&ssl->handshake->ecjpake_ctx,
4044*b0563631STom Van Eyck                                              p, (size_t) (end - p));
404532b31808SJens Wiklander         if (ret != 0) {
404632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_two", ret);
404732b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
404832b31808SJens Wiklander         }
404932b31808SJens Wiklander 
405032b31808SJens Wiklander         ret = mbedtls_ecjpake_derive_secret(&ssl->handshake->ecjpake_ctx,
405132b31808SJens Wiklander                                             ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
405232b31808SJens Wiklander                                             ssl->conf->f_rng, ssl->conf->p_rng);
405332b31808SJens Wiklander         if (ret != 0) {
405432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_derive_secret", ret);
405532b31808SJens Wiklander             return ret;
405632b31808SJens Wiklander         }
405732b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
405832b31808SJens Wiklander     } else
405932b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
406032b31808SJens Wiklander     {
406132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
406232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
406332b31808SJens Wiklander     }
406432b31808SJens Wiklander 
406532b31808SJens Wiklander     if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) {
406632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret);
406732b31808SJens Wiklander         return ret;
406832b31808SJens Wiklander     }
406932b31808SJens Wiklander 
407032b31808SJens Wiklander     ssl->state++;
407132b31808SJens Wiklander 
407232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse client key exchange"));
407332b31808SJens Wiklander 
407432b31808SJens Wiklander     return 0;
407532b31808SJens Wiklander }
407632b31808SJens Wiklander 
407732b31808SJens Wiklander #if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
407832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
407932b31808SJens Wiklander static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl)
408032b31808SJens Wiklander {
408132b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
408232b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
408332b31808SJens Wiklander 
408432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate verify"));
408532b31808SJens Wiklander 
408632b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
408732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
408832b31808SJens Wiklander         ssl->state++;
408932b31808SJens Wiklander         return 0;
409032b31808SJens Wiklander     }
409132b31808SJens Wiklander 
409232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
409332b31808SJens Wiklander     return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
409432b31808SJens Wiklander }
409532b31808SJens Wiklander #else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
409632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
409732b31808SJens Wiklander static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl)
409832b31808SJens Wiklander {
409932b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
410032b31808SJens Wiklander     size_t i, sig_len;
410132b31808SJens Wiklander     unsigned char hash[48];
410232b31808SJens Wiklander     unsigned char *hash_start = hash;
410332b31808SJens Wiklander     size_t hashlen;
410432b31808SJens Wiklander     mbedtls_pk_type_t pk_alg;
410532b31808SJens Wiklander     mbedtls_md_type_t md_alg;
410632b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
410732b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
410832b31808SJens Wiklander     mbedtls_pk_context *peer_pk;
410932b31808SJens Wiklander 
411032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate verify"));
411132b31808SJens Wiklander 
411232b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
411332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
411432b31808SJens Wiklander         ssl->state++;
411532b31808SJens Wiklander         return 0;
411632b31808SJens Wiklander     }
411732b31808SJens Wiklander 
411832b31808SJens Wiklander #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
411932b31808SJens Wiklander     if (ssl->session_negotiate->peer_cert == NULL) {
412032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
412132b31808SJens Wiklander         ssl->state++;
412232b31808SJens Wiklander         return 0;
412332b31808SJens Wiklander     }
412432b31808SJens Wiklander #else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
412532b31808SJens Wiklander     if (ssl->session_negotiate->peer_cert_digest == NULL) {
412632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
412732b31808SJens Wiklander         ssl->state++;
412832b31808SJens Wiklander         return 0;
412932b31808SJens Wiklander     }
413032b31808SJens Wiklander #endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
413132b31808SJens Wiklander 
413232b31808SJens Wiklander     /* Read the message without adding it to the checksum */
413332b31808SJens Wiklander     ret = mbedtls_ssl_read_record(ssl, 0 /* no checksum update */);
413432b31808SJens Wiklander     if (0 != ret) {
413532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_read_record"), ret);
413632b31808SJens Wiklander         return ret;
413732b31808SJens Wiklander     }
413832b31808SJens Wiklander 
413932b31808SJens Wiklander     ssl->state++;
414032b31808SJens Wiklander 
414132b31808SJens Wiklander     /* Process the message contents */
414232b31808SJens Wiklander     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ||
414332b31808SJens Wiklander         ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY) {
414432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message"));
414532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
414632b31808SJens Wiklander     }
414732b31808SJens Wiklander 
414832b31808SJens Wiklander     i = mbedtls_ssl_hs_hdr_len(ssl);
414932b31808SJens Wiklander 
415032b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
415132b31808SJens Wiklander     peer_pk = &ssl->handshake->peer_pubkey;
415232b31808SJens Wiklander #else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
415332b31808SJens Wiklander     if (ssl->session_negotiate->peer_cert == NULL) {
415432b31808SJens Wiklander         /* Should never happen */
415532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
415632b31808SJens Wiklander     }
415732b31808SJens Wiklander     peer_pk = &ssl->session_negotiate->peer_cert->pk;
415832b31808SJens Wiklander #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
415932b31808SJens Wiklander 
416032b31808SJens Wiklander     /*
416132b31808SJens Wiklander      *  struct {
416232b31808SJens Wiklander      *     SignatureAndHashAlgorithm algorithm; -- TLS 1.2 only
416332b31808SJens Wiklander      *     opaque signature<0..2^16-1>;
416432b31808SJens Wiklander      *  } DigitallySigned;
416532b31808SJens Wiklander      */
416632b31808SJens Wiklander     if (i + 2 > ssl->in_hslen) {
416732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message"));
416832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
416932b31808SJens Wiklander     }
417032b31808SJens Wiklander 
417132b31808SJens Wiklander     /*
417232b31808SJens Wiklander      * Hash
417332b31808SJens Wiklander      */
417432b31808SJens Wiklander     md_alg = mbedtls_ssl_md_alg_from_hash(ssl->in_msg[i]);
417532b31808SJens Wiklander 
417632b31808SJens Wiklander     if (md_alg == MBEDTLS_MD_NONE || mbedtls_ssl_set_calc_verify_md(ssl, ssl->in_msg[i])) {
417732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("peer not adhering to requested sig_alg"
417832b31808SJens Wiklander                                   " for verify message"));
417932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
418032b31808SJens Wiklander     }
418132b31808SJens Wiklander 
418232b31808SJens Wiklander #if !defined(MBEDTLS_MD_SHA1)
418332b31808SJens Wiklander     if (MBEDTLS_MD_SHA1 == md_alg) {
418432b31808SJens Wiklander         hash_start += 16;
418532b31808SJens Wiklander     }
418632b31808SJens Wiklander #endif
418732b31808SJens Wiklander 
418832b31808SJens Wiklander     /* Info from md_alg will be used instead */
418932b31808SJens Wiklander     hashlen = 0;
419032b31808SJens Wiklander 
419132b31808SJens Wiklander     i++;
419232b31808SJens Wiklander 
419332b31808SJens Wiklander     /*
419432b31808SJens Wiklander      * Signature
419532b31808SJens Wiklander      */
419632b31808SJens Wiklander     if ((pk_alg = mbedtls_ssl_pk_alg_from_sig(ssl->in_msg[i]))
419732b31808SJens Wiklander         == MBEDTLS_PK_NONE) {
419832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("peer not adhering to requested sig_alg"
419932b31808SJens Wiklander                                   " for verify message"));
420032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
420132b31808SJens Wiklander     }
420232b31808SJens Wiklander 
420332b31808SJens Wiklander     /*
420432b31808SJens Wiklander      * Check the certificate's key type matches the signature alg
420532b31808SJens Wiklander      */
420632b31808SJens Wiklander     if (!mbedtls_pk_can_do(peer_pk, pk_alg)) {
420732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("sig_alg doesn't match cert key"));
420832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
420932b31808SJens Wiklander     }
421032b31808SJens Wiklander 
421132b31808SJens Wiklander     i++;
421232b31808SJens Wiklander 
421332b31808SJens Wiklander     if (i + 2 > ssl->in_hslen) {
421432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message"));
421532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
421632b31808SJens Wiklander     }
421732b31808SJens Wiklander 
4218*b0563631STom Van Eyck     sig_len = MBEDTLS_GET_UINT16_BE(ssl->in_msg, i);
421932b31808SJens Wiklander     i += 2;
422032b31808SJens Wiklander 
422132b31808SJens Wiklander     if (i + sig_len != ssl->in_hslen) {
422232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message"));
422332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
422432b31808SJens Wiklander     }
422532b31808SJens Wiklander 
422632b31808SJens Wiklander     /* Calculate hash and verify signature */
422732b31808SJens Wiklander     {
422832b31808SJens Wiklander         size_t dummy_hlen;
422932b31808SJens Wiklander         ret = ssl->handshake->calc_verify(ssl, hash, &dummy_hlen);
423032b31808SJens Wiklander         if (0 != ret) {
423132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("calc_verify"), ret);
423232b31808SJens Wiklander             return ret;
423332b31808SJens Wiklander         }
423432b31808SJens Wiklander     }
423532b31808SJens Wiklander 
423632b31808SJens Wiklander     if ((ret = mbedtls_pk_verify(peer_pk,
423732b31808SJens Wiklander                                  md_alg, hash_start, hashlen,
423832b31808SJens Wiklander                                  ssl->in_msg + i, sig_len)) != 0) {
423932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_verify", ret);
424032b31808SJens Wiklander         return ret;
424132b31808SJens Wiklander     }
424232b31808SJens Wiklander 
424332b31808SJens Wiklander     ret = mbedtls_ssl_update_handshake_status(ssl);
424432b31808SJens Wiklander     if (0 != ret) {
424532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_update_handshake_status"), ret);
424632b31808SJens Wiklander         return ret;
424732b31808SJens Wiklander     }
424832b31808SJens Wiklander 
424932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate verify"));
425032b31808SJens Wiklander 
425132b31808SJens Wiklander     return ret;
425232b31808SJens Wiklander }
425332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
425432b31808SJens Wiklander 
425532b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
425632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
425732b31808SJens Wiklander static int ssl_write_new_session_ticket(mbedtls_ssl_context *ssl)
425832b31808SJens Wiklander {
425932b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
426032b31808SJens Wiklander     size_t tlen;
426132b31808SJens Wiklander     uint32_t lifetime;
426232b31808SJens Wiklander 
426332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write new session ticket"));
426432b31808SJens Wiklander 
426532b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
426632b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_NEW_SESSION_TICKET;
426732b31808SJens Wiklander 
426832b31808SJens Wiklander     /*
426932b31808SJens Wiklander      * struct {
427032b31808SJens Wiklander      *     uint32 ticket_lifetime_hint;
427132b31808SJens Wiklander      *     opaque ticket<0..2^16-1>;
427232b31808SJens Wiklander      * } NewSessionTicket;
427332b31808SJens Wiklander      *
427432b31808SJens Wiklander      * 4  .  7   ticket_lifetime_hint (0 = unspecified)
427532b31808SJens Wiklander      * 8  .  9   ticket_len (n)
427632b31808SJens Wiklander      * 10 .  9+n ticket content
427732b31808SJens Wiklander      */
427832b31808SJens Wiklander 
4279*b0563631STom Van Eyck #if defined(MBEDTLS_HAVE_TIME)
4280*b0563631STom Van Eyck     ssl->session_negotiate->ticket_creation_time = mbedtls_ms_time();
4281*b0563631STom Van Eyck #endif
428232b31808SJens Wiklander     if ((ret = ssl->conf->f_ticket_write(ssl->conf->p_ticket,
428332b31808SJens Wiklander                                          ssl->session_negotiate,
428432b31808SJens Wiklander                                          ssl->out_msg + 10,
428532b31808SJens Wiklander                                          ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN,
428632b31808SJens Wiklander                                          &tlen, &lifetime)) != 0) {
428732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_ticket_write", ret);
428832b31808SJens Wiklander         tlen = 0;
428932b31808SJens Wiklander     }
429032b31808SJens Wiklander 
429132b31808SJens Wiklander     MBEDTLS_PUT_UINT32_BE(lifetime, ssl->out_msg, 4);
429232b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(tlen, ssl->out_msg, 8);
429332b31808SJens Wiklander     ssl->out_msglen = 10 + tlen;
429432b31808SJens Wiklander 
429532b31808SJens Wiklander     /*
429632b31808SJens Wiklander      * Morally equivalent to updating ssl->state, but NewSessionTicket and
429732b31808SJens Wiklander      * ChangeCipherSpec share the same state.
429832b31808SJens Wiklander      */
429932b31808SJens Wiklander     ssl->handshake->new_session_ticket = 0;
430032b31808SJens Wiklander 
430132b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
430232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
430332b31808SJens Wiklander         return ret;
430432b31808SJens Wiklander     }
430532b31808SJens Wiklander 
430632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write new session ticket"));
430732b31808SJens Wiklander 
430832b31808SJens Wiklander     return 0;
430932b31808SJens Wiklander }
431032b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
431132b31808SJens Wiklander 
431232b31808SJens Wiklander /*
431332b31808SJens Wiklander  * SSL handshake -- server side -- single step
431432b31808SJens Wiklander  */
431532b31808SJens Wiklander int mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl)
431632b31808SJens Wiklander {
431732b31808SJens Wiklander     int ret = 0;
431832b31808SJens Wiklander 
431932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("server state: %d", ssl->state));
432032b31808SJens Wiklander 
432132b31808SJens Wiklander     switch (ssl->state) {
432232b31808SJens Wiklander         case MBEDTLS_SSL_HELLO_REQUEST:
432332b31808SJens Wiklander             ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
432432b31808SJens Wiklander             break;
432532b31808SJens Wiklander 
432632b31808SJens Wiklander         /*
432732b31808SJens Wiklander          *  <==   ClientHello
432832b31808SJens Wiklander          */
432932b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_HELLO:
433032b31808SJens Wiklander             ret = ssl_parse_client_hello(ssl);
433132b31808SJens Wiklander             break;
433232b31808SJens Wiklander 
433332b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
433432b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT:
433532b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED;
433632b31808SJens Wiklander #endif
433732b31808SJens Wiklander 
433832b31808SJens Wiklander         /*
433932b31808SJens Wiklander          *  ==>   ServerHello
434032b31808SJens Wiklander          *        Certificate
434132b31808SJens Wiklander          *      ( ServerKeyExchange  )
434232b31808SJens Wiklander          *      ( CertificateRequest )
434332b31808SJens Wiklander          *        ServerHelloDone
434432b31808SJens Wiklander          */
434532b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_HELLO:
434632b31808SJens Wiklander             ret = ssl_write_server_hello(ssl);
434732b31808SJens Wiklander             break;
434832b31808SJens Wiklander 
434932b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_CERTIFICATE:
435032b31808SJens Wiklander             ret = mbedtls_ssl_write_certificate(ssl);
435132b31808SJens Wiklander             break;
435232b31808SJens Wiklander 
435332b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
435432b31808SJens Wiklander             ret = ssl_write_server_key_exchange(ssl);
435532b31808SJens Wiklander             break;
435632b31808SJens Wiklander 
435732b31808SJens Wiklander         case MBEDTLS_SSL_CERTIFICATE_REQUEST:
435832b31808SJens Wiklander             ret = ssl_write_certificate_request(ssl);
435932b31808SJens Wiklander             break;
436032b31808SJens Wiklander 
436132b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_HELLO_DONE:
436232b31808SJens Wiklander             ret = ssl_write_server_hello_done(ssl);
436332b31808SJens Wiklander             break;
436432b31808SJens Wiklander 
436532b31808SJens Wiklander         /*
436632b31808SJens Wiklander          *  <== ( Certificate/Alert  )
436732b31808SJens Wiklander          *        ClientKeyExchange
436832b31808SJens Wiklander          *      ( CertificateVerify  )
436932b31808SJens Wiklander          *        ChangeCipherSpec
437032b31808SJens Wiklander          *        Finished
437132b31808SJens Wiklander          */
437232b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_CERTIFICATE:
437332b31808SJens Wiklander             ret = mbedtls_ssl_parse_certificate(ssl);
437432b31808SJens Wiklander             break;
437532b31808SJens Wiklander 
437632b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
437732b31808SJens Wiklander             ret = ssl_parse_client_key_exchange(ssl);
437832b31808SJens Wiklander             break;
437932b31808SJens Wiklander 
438032b31808SJens Wiklander         case MBEDTLS_SSL_CERTIFICATE_VERIFY:
438132b31808SJens Wiklander             ret = ssl_parse_certificate_verify(ssl);
438232b31808SJens Wiklander             break;
438332b31808SJens Wiklander 
438432b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
438532b31808SJens Wiklander             ret = mbedtls_ssl_parse_change_cipher_spec(ssl);
438632b31808SJens Wiklander             break;
438732b31808SJens Wiklander 
438832b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_FINISHED:
438932b31808SJens Wiklander             ret = mbedtls_ssl_parse_finished(ssl);
439032b31808SJens Wiklander             break;
439132b31808SJens Wiklander 
439232b31808SJens Wiklander         /*
439332b31808SJens Wiklander          *  ==> ( NewSessionTicket )
439432b31808SJens Wiklander          *        ChangeCipherSpec
439532b31808SJens Wiklander          *        Finished
439632b31808SJens Wiklander          */
439732b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
439832b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
439932b31808SJens Wiklander             if (ssl->handshake->new_session_ticket != 0) {
440032b31808SJens Wiklander                 ret = ssl_write_new_session_ticket(ssl);
440132b31808SJens Wiklander             } else
440232b31808SJens Wiklander #endif
440332b31808SJens Wiklander             ret = mbedtls_ssl_write_change_cipher_spec(ssl);
440432b31808SJens Wiklander             break;
440532b31808SJens Wiklander 
440632b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_FINISHED:
440732b31808SJens Wiklander             ret = mbedtls_ssl_write_finished(ssl);
440832b31808SJens Wiklander             break;
440932b31808SJens Wiklander 
441032b31808SJens Wiklander         case MBEDTLS_SSL_FLUSH_BUFFERS:
441132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done"));
441232b31808SJens Wiklander             ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
441332b31808SJens Wiklander             break;
441432b31808SJens Wiklander 
441532b31808SJens Wiklander         case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
441632b31808SJens Wiklander             mbedtls_ssl_handshake_wrapup(ssl);
441732b31808SJens Wiklander             break;
441832b31808SJens Wiklander 
441932b31808SJens Wiklander         default:
442032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("invalid state %d", ssl->state));
442132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
442232b31808SJens Wiklander     }
442332b31808SJens Wiklander 
442432b31808SJens Wiklander     return ret;
442532b31808SJens Wiklander }
442632b31808SJens Wiklander 
442732b31808SJens Wiklander void mbedtls_ssl_conf_preference_order(mbedtls_ssl_config *conf, int order)
442832b31808SJens Wiklander {
442932b31808SJens Wiklander     conf->respect_cli_pref = order;
443032b31808SJens Wiklander }
443132b31808SJens Wiklander 
443232b31808SJens Wiklander #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_PROTO_TLS1_2 */
4433