xref: /optee_os/lib/libmbedtls/mbedtls/library/ssl_tls12_server.c (revision cb03400251f98aed22a2664509e3ed9e183800b0)
132b31808SJens Wiklander /*
232b31808SJens Wiklander  *  TLS server-side functions
332b31808SJens Wiklander  *
432b31808SJens Wiklander  *  Copyright The Mbed TLS Contributors
5b0563631STom Van Eyck  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
632b31808SJens Wiklander  */
732b31808SJens Wiklander 
832b31808SJens Wiklander #include "common.h"
932b31808SJens Wiklander 
1032b31808SJens Wiklander #if defined(MBEDTLS_SSL_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"
16b0563631STom 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)
25b0563631STom Van Eyck /* Define a local translating function to save code size by not using too many
26b0563631STom Van Eyck  * arguments in each translating place. */
27b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED) || \
28b0563631STom Van Eyck     defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED)
29b0563631STom Van Eyck static int local_err_translation(psa_status_t status)
30b0563631STom Van Eyck {
31b0563631STom Van Eyck     return psa_status_to_mbedtls(status, psa_to_ssl_errors,
32b0563631STom Van Eyck                                  ARRAY_LENGTH(psa_to_ssl_errors),
33b0563631STom Van Eyck                                  psa_generic_status_to_mbedtls);
34b0563631STom Van Eyck }
35b0563631STom Van Eyck #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)
36b0563631STom 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 
139b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
140b0563631STom 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     }
195b0563631STom 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) && \
266b0563631STom Van Eyck             defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED)
26732b31808SJens Wiklander             ssl->handshake->ecdh_ctx.point_format = p[0];
268b0563631STom 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 }
284b0563631STom Van Eyck #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED ||
285b0563631STom 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  */
661b0563631STom 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;
667b0563631STom 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 }
680b0563631STom 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,
759*cb034002SJerome Forissier                                          MBEDTLS_SSL_IS_CLIENT,
760*cb034002SJerome Forissier                                          MBEDTLS_SSL_VERSION_TLS1_2,
761*cb034002SJerome Forissier                                          &flags) != 0) {
76232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: "
76332b31808SJens Wiklander                                       "(extended) key usage extension"));
76432b31808SJens Wiklander             continue;
76532b31808SJens Wiklander         }
76632b31808SJens Wiklander 
767b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
76832b31808SJens Wiklander         if (pk_alg == MBEDTLS_PK_ECDSA &&
76932b31808SJens Wiklander             ssl_check_key_curve(&cur->cert->pk,
77032b31808SJens Wiklander                                 ssl->handshake->curves_tls_id) != 0) {
77132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: elliptic curve"));
77232b31808SJens Wiklander             continue;
77332b31808SJens Wiklander         }
77432b31808SJens Wiklander #endif
77532b31808SJens Wiklander 
77632b31808SJens Wiklander         /* If we get there, we got a winner */
77732b31808SJens Wiklander         break;
77832b31808SJens Wiklander     }
77932b31808SJens Wiklander 
78032b31808SJens Wiklander     /* Do not update ssl->handshake->key_cert unless there is a match */
78132b31808SJens Wiklander     if (cur != NULL) {
78232b31808SJens Wiklander         ssl->handshake->key_cert = cur;
78332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_CRT(3, "selected certificate chain, certificate",
78432b31808SJens Wiklander                               ssl->handshake->key_cert->cert);
78532b31808SJens Wiklander         return 0;
78632b31808SJens Wiklander     }
78732b31808SJens Wiklander 
78832b31808SJens Wiklander     return -1;
78932b31808SJens Wiklander }
79032b31808SJens Wiklander #endif /* MBEDTLS_X509_CRT_PARSE_C */
79132b31808SJens Wiklander 
79232b31808SJens Wiklander /*
79332b31808SJens Wiklander  * Check if a given ciphersuite is suitable for use with our config/keys/etc
79432b31808SJens Wiklander  * Sets ciphersuite_info only if the suite matches.
79532b31808SJens Wiklander  */
79632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
79732b31808SJens Wiklander static int ssl_ciphersuite_match(mbedtls_ssl_context *ssl, int suite_id,
79832b31808SJens Wiklander                                  const mbedtls_ssl_ciphersuite_t **ciphersuite_info)
79932b31808SJens Wiklander {
80032b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *suite_info;
80132b31808SJens Wiklander 
80232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
80332b31808SJens Wiklander     mbedtls_pk_type_t sig_type;
80432b31808SJens Wiklander #endif
80532b31808SJens Wiklander 
80632b31808SJens Wiklander     suite_info = mbedtls_ssl_ciphersuite_from_id(suite_id);
80732b31808SJens Wiklander     if (suite_info == NULL) {
80832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
80932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
81032b31808SJens Wiklander     }
81132b31808SJens Wiklander 
81232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("trying ciphersuite: %#04x (%s)",
81332b31808SJens Wiklander                               (unsigned int) suite_id, suite_info->name));
81432b31808SJens Wiklander 
81532b31808SJens Wiklander     if (suite_info->min_tls_version > ssl->tls_version ||
81632b31808SJens Wiklander         suite_info->max_tls_version < ssl->tls_version) {
81732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: version"));
81832b31808SJens Wiklander         return 0;
81932b31808SJens Wiklander     }
82032b31808SJens Wiklander 
82132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
82232b31808SJens Wiklander     if (suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
82332b31808SJens Wiklander         (ssl->handshake->cli_exts & MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK) == 0) {
82432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: ecjpake "
82532b31808SJens Wiklander                                   "not configured or ext missing"));
82632b31808SJens Wiklander         return 0;
82732b31808SJens Wiklander     }
82832b31808SJens Wiklander #endif
82932b31808SJens Wiklander 
83032b31808SJens Wiklander 
831b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
832b0563631STom Van Eyck     defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
83332b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_uses_ec(suite_info) &&
83432b31808SJens Wiklander         (ssl->handshake->curves_tls_id == NULL ||
83532b31808SJens Wiklander          ssl->handshake->curves_tls_id[0] == 0)) {
83632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: "
83732b31808SJens Wiklander                                   "no common elliptic curve"));
83832b31808SJens Wiklander         return 0;
83932b31808SJens Wiklander     }
84032b31808SJens Wiklander #endif
84132b31808SJens Wiklander 
84232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
84332b31808SJens Wiklander     /* If the ciphersuite requires a pre-shared key and we don't
84432b31808SJens Wiklander      * have one, skip it now rather than failing later */
84532b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_uses_psk(suite_info) &&
84632b31808SJens Wiklander         ssl_conf_has_psk_or_cb(ssl->conf) == 0) {
84732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: no pre-shared key"));
84832b31808SJens Wiklander         return 0;
84932b31808SJens Wiklander     }
85032b31808SJens Wiklander #endif
85132b31808SJens Wiklander 
85232b31808SJens Wiklander #if defined(MBEDTLS_X509_CRT_PARSE_C)
85332b31808SJens Wiklander     /*
85432b31808SJens Wiklander      * Final check: if ciphersuite requires us to have a
85532b31808SJens Wiklander      * certificate/key of a particular type:
85632b31808SJens Wiklander      * - select the appropriate certificate if we have one, or
85732b31808SJens Wiklander      * - try the next ciphersuite if we don't
85832b31808SJens Wiklander      * This must be done last since we modify the key_cert list.
85932b31808SJens Wiklander      */
86032b31808SJens Wiklander     if (ssl_pick_cert(ssl, suite_info) != 0) {
86132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: "
86232b31808SJens Wiklander                                   "no suitable certificate"));
86332b31808SJens Wiklander         return 0;
86432b31808SJens Wiklander     }
86532b31808SJens Wiklander #endif
86632b31808SJens Wiklander 
86732b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
86832b31808SJens Wiklander     /* If the ciphersuite requires signing, check whether
86932b31808SJens Wiklander      * a suitable hash algorithm is present. */
87032b31808SJens Wiklander     sig_type = mbedtls_ssl_get_ciphersuite_sig_alg(suite_info);
87132b31808SJens Wiklander     if (sig_type != MBEDTLS_PK_NONE &&
87232b31808SJens Wiklander         mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
87332b31808SJens Wiklander             ssl, mbedtls_ssl_sig_from_pk_alg(sig_type)) == MBEDTLS_SSL_HASH_NONE) {
87432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: no suitable hash algorithm "
87532b31808SJens Wiklander                                   "for signature algorithm %u", (unsigned) sig_type));
87632b31808SJens Wiklander         return 0;
87732b31808SJens Wiklander     }
87832b31808SJens Wiklander 
87932b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
88032b31808SJens Wiklander 
88132b31808SJens Wiklander     *ciphersuite_info = suite_info;
88232b31808SJens Wiklander     return 0;
88332b31808SJens Wiklander }
88432b31808SJens Wiklander 
88532b31808SJens Wiklander /* This function doesn't alert on errors that happen early during
88632b31808SJens Wiklander    ClientHello parsing because they might indicate that the client is
88732b31808SJens Wiklander    not talking SSL/TLS at all and would not understand our alert. */
88832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
88932b31808SJens Wiklander static int ssl_parse_client_hello(mbedtls_ssl_context *ssl)
89032b31808SJens Wiklander {
89132b31808SJens Wiklander     int ret, got_common_suite;
89232b31808SJens Wiklander     size_t i, j;
89332b31808SJens Wiklander     size_t ciph_offset, comp_offset, ext_offset;
89432b31808SJens Wiklander     size_t msg_len, ciph_len, sess_len, comp_len, ext_len;
89532b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
89632b31808SJens Wiklander     size_t cookie_offset, cookie_len;
89732b31808SJens Wiklander #endif
89832b31808SJens Wiklander     unsigned char *buf, *p, *ext;
89932b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
90032b31808SJens Wiklander     int renegotiation_info_seen = 0;
90132b31808SJens Wiklander #endif
90232b31808SJens Wiklander     int handshake_failure = 0;
90332b31808SJens Wiklander     const int *ciphersuites;
90432b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
90532b31808SJens Wiklander 
90632b31808SJens Wiklander     /* If there is no signature-algorithm extension present,
90732b31808SJens Wiklander      * we need to fall back to the default values for allowed
90832b31808SJens Wiklander      * signature-hash pairs. */
90932b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
91032b31808SJens Wiklander     int sig_hash_alg_ext_present = 0;
91132b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
91232b31808SJens Wiklander 
91332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse client hello"));
91432b31808SJens Wiklander 
91532b31808SJens Wiklander     int renegotiating;
91632b31808SJens Wiklander 
91732b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
91832b31808SJens Wiklander read_record_header:
91932b31808SJens Wiklander #endif
92032b31808SJens Wiklander     /*
92132b31808SJens Wiklander      * If renegotiating, then the input was read with mbedtls_ssl_read_record(),
92232b31808SJens Wiklander      * otherwise read it ourselves manually in order to support SSLv2
92332b31808SJens Wiklander      * ClientHello, which doesn't use the same record layer format.
924b0563631STom Van Eyck      * Otherwise in a scenario of TLS 1.3/TLS 1.2 version negotiation, the
925b0563631STom Van Eyck      * ClientHello has been already fully fetched by the TLS 1.3 code and the
926b0563631STom Van Eyck      * flag ssl->keep_current_message is raised.
92732b31808SJens Wiklander      */
92832b31808SJens Wiklander     renegotiating = 0;
92932b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
93032b31808SJens Wiklander     renegotiating = (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE);
93132b31808SJens Wiklander #endif
932b0563631STom Van Eyck     if (!renegotiating && !ssl->keep_current_message) {
93332b31808SJens Wiklander         if ((ret = mbedtls_ssl_fetch_input(ssl, 5)) != 0) {
93432b31808SJens Wiklander             /* No alert on a read error. */
93532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
93632b31808SJens Wiklander             return ret;
93732b31808SJens Wiklander         }
93832b31808SJens Wiklander     }
93932b31808SJens Wiklander 
94032b31808SJens Wiklander     buf = ssl->in_hdr;
94132b31808SJens Wiklander 
94232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(4, "record header", buf, mbedtls_ssl_in_hdr_len(ssl));
94332b31808SJens Wiklander 
94432b31808SJens Wiklander     /*
94532b31808SJens Wiklander      * TLS Client Hello
94632b31808SJens Wiklander      *
94732b31808SJens Wiklander      * Record layer:
94832b31808SJens Wiklander      *     0  .   0   message type
94932b31808SJens Wiklander      *     1  .   2   protocol version
95032b31808SJens Wiklander      *     3  .   11  DTLS: epoch + record sequence number
95132b31808SJens Wiklander      *     3  .   4   message length
95232b31808SJens Wiklander      */
95332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, message type: %d",
95432b31808SJens Wiklander                               buf[0]));
95532b31808SJens Wiklander 
95632b31808SJens Wiklander     if (buf[0] != MBEDTLS_SSL_MSG_HANDSHAKE) {
95732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
95832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
95932b31808SJens Wiklander     }
96032b31808SJens Wiklander 
96132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, message len.: %d",
962b0563631STom Van Eyck                               MBEDTLS_GET_UINT16_BE(ssl->in_len, 0)));
96332b31808SJens Wiklander 
96432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, protocol version: [%d:%d]",
96532b31808SJens Wiklander                               buf[1], buf[2]));
96632b31808SJens Wiklander 
96732b31808SJens Wiklander     /* For DTLS if this is the initial handshake, remember the client sequence
96832b31808SJens Wiklander      * number to use it in our next message (RFC 6347 4.2.1) */
96932b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
97032b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM
97132b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
97232b31808SJens Wiklander         && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE
97332b31808SJens Wiklander #endif
97432b31808SJens Wiklander         ) {
97532b31808SJens Wiklander         /* Epoch should be 0 for initial handshakes */
97632b31808SJens Wiklander         if (ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0) {
97732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
97832b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
97932b31808SJens Wiklander         }
98032b31808SJens Wiklander 
98132b31808SJens Wiklander         memcpy(&ssl->cur_out_ctr[2], ssl->in_ctr + 2,
98232b31808SJens Wiklander                sizeof(ssl->cur_out_ctr) - 2);
98332b31808SJens Wiklander 
98432b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
98532b31808SJens Wiklander         if (mbedtls_ssl_dtls_replay_check(ssl) != 0) {
98632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("replayed record, discarding"));
98732b31808SJens Wiklander             ssl->next_record_offset = 0;
98832b31808SJens Wiklander             ssl->in_left = 0;
98932b31808SJens Wiklander             goto read_record_header;
99032b31808SJens Wiklander         }
99132b31808SJens Wiklander 
99232b31808SJens Wiklander         /* No MAC to check yet, so we can update right now */
99332b31808SJens Wiklander         mbedtls_ssl_dtls_replay_update(ssl);
99432b31808SJens Wiklander #endif
99532b31808SJens Wiklander     }
99632b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */
99732b31808SJens Wiklander 
998b0563631STom Van Eyck     msg_len = MBEDTLS_GET_UINT16_BE(ssl->in_len, 0);
99932b31808SJens Wiklander 
100032b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
100132b31808SJens Wiklander     if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
100232b31808SJens Wiklander         /* Set by mbedtls_ssl_read_record() */
100332b31808SJens Wiklander         msg_len = ssl->in_hslen;
100432b31808SJens Wiklander     } else
100532b31808SJens Wiklander #endif
100632b31808SJens Wiklander     {
1007b0563631STom Van Eyck         if (ssl->keep_current_message) {
1008b0563631STom Van Eyck             ssl->keep_current_message = 0;
1009b0563631STom Van Eyck         } else {
101032b31808SJens Wiklander             if (msg_len > MBEDTLS_SSL_IN_CONTENT_LEN) {
101132b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
101232b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
101332b31808SJens Wiklander             }
101432b31808SJens Wiklander 
101532b31808SJens Wiklander             if ((ret = mbedtls_ssl_fetch_input(ssl,
101632b31808SJens Wiklander                                                mbedtls_ssl_in_hdr_len(ssl) + msg_len)) != 0) {
101732b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret);
101832b31808SJens Wiklander                 return ret;
101932b31808SJens Wiklander             }
102032b31808SJens Wiklander 
102132b31808SJens Wiklander             /* Done reading this record, get ready for the next one */
102232b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
102332b31808SJens Wiklander             if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
102432b31808SJens Wiklander                 ssl->next_record_offset = msg_len + mbedtls_ssl_in_hdr_len(ssl);
102532b31808SJens Wiklander             } else
102632b31808SJens Wiklander #endif
102732b31808SJens Wiklander             ssl->in_left = 0;
102832b31808SJens Wiklander         }
1029b0563631STom Van Eyck     }
103032b31808SJens Wiklander 
103132b31808SJens Wiklander     buf = ssl->in_msg;
103232b31808SJens Wiklander 
103332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(4, "record contents", buf, msg_len);
103432b31808SJens Wiklander 
103532b31808SJens Wiklander     ret = ssl->handshake->update_checksum(ssl, buf, msg_len);
103632b31808SJens Wiklander     if (0 != ret) {
103732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret);
103832b31808SJens Wiklander         return ret;
103932b31808SJens Wiklander     }
104032b31808SJens Wiklander 
104132b31808SJens Wiklander     /*
104232b31808SJens Wiklander      * Handshake layer:
104332b31808SJens Wiklander      *     0  .   0   handshake type
104432b31808SJens Wiklander      *     1  .   3   handshake length
104532b31808SJens Wiklander      *     4  .   5   DTLS only: message sequence number
104632b31808SJens Wiklander      *     6  .   8   DTLS only: fragment offset
104732b31808SJens Wiklander      *     9  .  11   DTLS only: fragment length
104832b31808SJens Wiklander      */
104932b31808SJens Wiklander     if (msg_len < mbedtls_ssl_hs_hdr_len(ssl)) {
105032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
105132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
105232b31808SJens Wiklander     }
105332b31808SJens Wiklander 
105432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("client hello v3, handshake type: %d", buf[0]));
105532b31808SJens Wiklander 
105632b31808SJens Wiklander     if (buf[0] != MBEDTLS_SSL_HS_CLIENT_HELLO) {
105732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
105832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
105932b31808SJens Wiklander     }
106032b31808SJens Wiklander     {
106132b31808SJens Wiklander         size_t handshake_len = MBEDTLS_GET_UINT24_BE(buf, 1);
106232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("client hello v3, handshake len.: %u",
106332b31808SJens Wiklander                                   (unsigned) handshake_len));
106432b31808SJens Wiklander 
106532b31808SJens Wiklander         /* The record layer has a record size limit of 2^14 - 1 and
106632b31808SJens Wiklander          * fragmentation is not supported, so buf[1] should be zero. */
106732b31808SJens Wiklander         if (buf[1] != 0) {
106832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message: %u != 0",
106932b31808SJens Wiklander                                       (unsigned) buf[1]));
107032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
107132b31808SJens Wiklander         }
107232b31808SJens Wiklander 
107332b31808SJens Wiklander         /* We don't support fragmentation of ClientHello (yet?) */
107432b31808SJens Wiklander         if (msg_len != mbedtls_ssl_hs_hdr_len(ssl) + handshake_len) {
107532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message: %u != %u + %u",
107632b31808SJens Wiklander                                       (unsigned) msg_len,
107732b31808SJens Wiklander                                       (unsigned) mbedtls_ssl_hs_hdr_len(ssl),
107832b31808SJens Wiklander                                       (unsigned) handshake_len));
107932b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
108032b31808SJens Wiklander         }
108132b31808SJens Wiklander     }
108232b31808SJens Wiklander 
108332b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
108432b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
108532b31808SJens Wiklander         /*
108632b31808SJens Wiklander          * Copy the client's handshake message_seq on initial handshakes,
108732b31808SJens Wiklander          * check sequence number on renego.
108832b31808SJens Wiklander          */
108932b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
109032b31808SJens Wiklander         if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
109132b31808SJens Wiklander             /* This couldn't be done in ssl_prepare_handshake_record() */
1092b0563631STom Van Eyck             unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
109332b31808SJens Wiklander             if (cli_msg_seq != ssl->handshake->in_msg_seq) {
109432b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message_seq: "
109532b31808SJens Wiklander                                           "%u (expected %u)", cli_msg_seq,
109632b31808SJens Wiklander                                           ssl->handshake->in_msg_seq));
109732b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_DECODE_ERROR;
109832b31808SJens Wiklander             }
109932b31808SJens Wiklander 
110032b31808SJens Wiklander             ssl->handshake->in_msg_seq++;
110132b31808SJens Wiklander         } else
110232b31808SJens Wiklander #endif
110332b31808SJens Wiklander         {
1104b0563631STom Van Eyck             unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
110532b31808SJens Wiklander             ssl->handshake->out_msg_seq = cli_msg_seq;
110632b31808SJens Wiklander             ssl->handshake->in_msg_seq  = cli_msg_seq + 1;
110732b31808SJens Wiklander         }
110832b31808SJens Wiklander         {
110932b31808SJens Wiklander             /*
111032b31808SJens Wiklander              * For now we don't support fragmentation, so make sure
111132b31808SJens Wiklander              * fragment_offset == 0 and fragment_length == length
111232b31808SJens Wiklander              */
111332b31808SJens Wiklander             size_t fragment_offset, fragment_length, length;
111432b31808SJens Wiklander             fragment_offset = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 6);
111532b31808SJens Wiklander             fragment_length = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 9);
111632b31808SJens Wiklander             length = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 1);
111732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(
111832b31808SJens Wiklander                 4, ("fragment_offset=%u fragment_length=%u length=%u",
111932b31808SJens Wiklander                     (unsigned) fragment_offset, (unsigned) fragment_length,
112032b31808SJens Wiklander                     (unsigned) length));
112132b31808SJens Wiklander             if (fragment_offset != 0 || length != fragment_length) {
112232b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1, ("ClientHello fragmentation not supported"));
112332b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
112432b31808SJens Wiklander             }
112532b31808SJens Wiklander         }
112632b31808SJens Wiklander     }
112732b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */
112832b31808SJens Wiklander 
112932b31808SJens Wiklander     buf += mbedtls_ssl_hs_hdr_len(ssl);
113032b31808SJens Wiklander     msg_len -= mbedtls_ssl_hs_hdr_len(ssl);
113132b31808SJens Wiklander 
113232b31808SJens Wiklander     /*
1133b0563631STom Van Eyck      * ClientHello layout:
113432b31808SJens Wiklander      *     0  .   1   protocol version
113532b31808SJens Wiklander      *     2  .  33   random bytes (starting with 4 bytes of Unix time)
1136b0563631STom Van Eyck      *    34  .  34   session id length (1 byte)
1137b0563631STom Van Eyck      *    35  . 34+x  session id, where x = session id length from byte 34
113832b31808SJens Wiklander      *   35+x . 35+x  DTLS only: cookie length (1 byte)
113932b31808SJens Wiklander      *   36+x .  ..   DTLS only: cookie
114032b31808SJens Wiklander      *    ..  .  ..   ciphersuite list length (2 bytes)
114132b31808SJens Wiklander      *    ..  .  ..   ciphersuite list
114232b31808SJens Wiklander      *    ..  .  ..   compression alg. list length (1 byte)
114332b31808SJens Wiklander      *    ..  .  ..   compression alg. list
114432b31808SJens Wiklander      *    ..  .  ..   extensions length (2 bytes, optional)
114532b31808SJens Wiklander      *    ..  .  ..   extensions (optional)
114632b31808SJens Wiklander      */
114732b31808SJens Wiklander 
114832b31808SJens Wiklander     /*
114932b31808SJens Wiklander      * Minimal length (with everything empty and extensions omitted) is
115032b31808SJens Wiklander      * 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can
115132b31808SJens Wiklander      * read at least up to session id length without worrying.
115232b31808SJens Wiklander      */
115332b31808SJens Wiklander     if (msg_len < 38) {
115432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
115532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
115632b31808SJens Wiklander     }
115732b31808SJens Wiklander 
115832b31808SJens Wiklander     /*
115932b31808SJens Wiklander      * Check and save the protocol version
116032b31808SJens Wiklander      */
116132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, version", buf, 2);
116232b31808SJens Wiklander 
1163b0563631STom Van Eyck     ssl->tls_version = (mbedtls_ssl_protocol_version) mbedtls_ssl_read_version(buf,
1164b0563631STom Van Eyck                                                                                ssl->conf->transport);
116532b31808SJens Wiklander     ssl->session_negotiate->tls_version = ssl->tls_version;
1166b0563631STom Van Eyck     ssl->session_negotiate->endpoint = ssl->conf->endpoint;
116732b31808SJens Wiklander 
116832b31808SJens Wiklander     if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_2) {
116932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("server only supports TLS 1.2"));
117032b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
117132b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION);
117232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
117332b31808SJens Wiklander     }
117432b31808SJens Wiklander 
117532b31808SJens Wiklander     /*
117632b31808SJens Wiklander      * Save client random (inc. Unix time)
117732b31808SJens Wiklander      */
117832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, random bytes", buf + 2, 32);
117932b31808SJens Wiklander 
118032b31808SJens Wiklander     memcpy(ssl->handshake->randbytes, buf + 2, 32);
118132b31808SJens Wiklander 
118232b31808SJens Wiklander     /*
118332b31808SJens Wiklander      * Check the session ID length and save session ID
118432b31808SJens Wiklander      */
118532b31808SJens Wiklander     sess_len = buf[34];
118632b31808SJens Wiklander 
118732b31808SJens Wiklander     if (sess_len > sizeof(ssl->session_negotiate->id) ||
118832b31808SJens Wiklander         sess_len + 34 + 2 > msg_len) { /* 2 for cipherlist length field */
118932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
119032b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
119132b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
119232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
119332b31808SJens Wiklander     }
119432b31808SJens Wiklander 
119532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, session id", buf + 35, sess_len);
119632b31808SJens Wiklander 
119732b31808SJens Wiklander     ssl->session_negotiate->id_len = sess_len;
119832b31808SJens Wiklander     memset(ssl->session_negotiate->id, 0,
119932b31808SJens Wiklander            sizeof(ssl->session_negotiate->id));
120032b31808SJens Wiklander     memcpy(ssl->session_negotiate->id, buf + 35,
120132b31808SJens Wiklander            ssl->session_negotiate->id_len);
120232b31808SJens Wiklander 
120332b31808SJens Wiklander     /*
120432b31808SJens Wiklander      * Check the cookie length and content
120532b31808SJens Wiklander      */
120632b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
120732b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
120832b31808SJens Wiklander         cookie_offset = 35 + sess_len;
120932b31808SJens Wiklander         cookie_len = buf[cookie_offset];
121032b31808SJens Wiklander 
121132b31808SJens Wiklander         if (cookie_offset + 1 + cookie_len + 2 > msg_len) {
121232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
121332b31808SJens Wiklander             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
121432b31808SJens Wiklander                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
121532b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
121632b31808SJens Wiklander         }
121732b31808SJens Wiklander 
121832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "client hello, cookie",
121932b31808SJens Wiklander                               buf + cookie_offset + 1, cookie_len);
122032b31808SJens Wiklander 
122132b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
122232b31808SJens Wiklander         if (ssl->conf->f_cookie_check != NULL
122332b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
122432b31808SJens Wiklander             && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE
122532b31808SJens Wiklander #endif
122632b31808SJens Wiklander             ) {
122732b31808SJens Wiklander             if (ssl->conf->f_cookie_check(ssl->conf->p_cookie,
122832b31808SJens Wiklander                                           buf + cookie_offset + 1, cookie_len,
122932b31808SJens Wiklander                                           ssl->cli_id, ssl->cli_id_len) != 0) {
123032b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(2, ("cookie verification failed"));
123132b31808SJens Wiklander                 ssl->handshake->cookie_verify_result = 1;
123232b31808SJens Wiklander             } else {
123332b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(2, ("cookie verification passed"));
123432b31808SJens Wiklander                 ssl->handshake->cookie_verify_result = 0;
123532b31808SJens Wiklander             }
123632b31808SJens Wiklander         } else
123732b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
123832b31808SJens Wiklander         {
123932b31808SJens Wiklander             /* We know we didn't send a cookie, so it should be empty */
124032b31808SJens Wiklander             if (cookie_len != 0) {
124132b31808SJens Wiklander                 /* This may be an attacker's probe, so don't send an alert */
124232b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
124332b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_DECODE_ERROR;
124432b31808SJens Wiklander             }
124532b31808SJens Wiklander 
124632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2, ("cookie verification skipped"));
124732b31808SJens Wiklander         }
124832b31808SJens Wiklander 
124932b31808SJens Wiklander         /*
125032b31808SJens Wiklander          * Check the ciphersuitelist length (will be parsed later)
125132b31808SJens Wiklander          */
125232b31808SJens Wiklander         ciph_offset = cookie_offset + 1 + cookie_len;
125332b31808SJens Wiklander     } else
125432b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */
125532b31808SJens Wiklander     ciph_offset = 35 + sess_len;
125632b31808SJens Wiklander 
1257b0563631STom Van Eyck     ciph_len = MBEDTLS_GET_UINT16_BE(buf, ciph_offset);
125832b31808SJens Wiklander 
125932b31808SJens Wiklander     if (ciph_len < 2 ||
126032b31808SJens Wiklander         ciph_len + 2 + ciph_offset + 1 > msg_len || /* 1 for comp. alg. len */
126132b31808SJens Wiklander         (ciph_len % 2) != 0) {
126232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
126332b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
126432b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
126532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
126632b31808SJens Wiklander     }
126732b31808SJens Wiklander 
126832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, ciphersuitelist",
126932b31808SJens Wiklander                           buf + ciph_offset + 2,  ciph_len);
127032b31808SJens Wiklander 
127132b31808SJens Wiklander     /*
127232b31808SJens Wiklander      * Check the compression algorithm's length.
127332b31808SJens Wiklander      * The list contents are ignored because implementing
127432b31808SJens Wiklander      * MBEDTLS_SSL_COMPRESS_NULL is mandatory and is the only
127532b31808SJens Wiklander      * option supported by Mbed TLS.
127632b31808SJens Wiklander      */
127732b31808SJens Wiklander     comp_offset = ciph_offset + 2 + ciph_len;
127832b31808SJens Wiklander 
127932b31808SJens Wiklander     comp_len = buf[comp_offset];
128032b31808SJens Wiklander 
128132b31808SJens Wiklander     if (comp_len < 1 ||
128232b31808SJens Wiklander         comp_len > 16 ||
128332b31808SJens Wiklander         comp_len + comp_offset + 1 > msg_len) {
128432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
128532b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
128632b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
128732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
128832b31808SJens Wiklander     }
128932b31808SJens Wiklander 
129032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, compression",
129132b31808SJens Wiklander                           buf + comp_offset + 1, comp_len);
129232b31808SJens Wiklander 
129332b31808SJens Wiklander     /*
129432b31808SJens Wiklander      * Check the extension length
129532b31808SJens Wiklander      */
129632b31808SJens Wiklander     ext_offset = comp_offset + 1 + comp_len;
129732b31808SJens Wiklander     if (msg_len > ext_offset) {
129832b31808SJens Wiklander         if (msg_len < ext_offset + 2) {
129932b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
130032b31808SJens Wiklander             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
130132b31808SJens Wiklander                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
130232b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
130332b31808SJens Wiklander         }
130432b31808SJens Wiklander 
1305b0563631STom Van Eyck         ext_len = MBEDTLS_GET_UINT16_BE(buf, ext_offset);
130632b31808SJens Wiklander 
130732b31808SJens Wiklander         if (msg_len != ext_offset + 2 + ext_len) {
130832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
130932b31808SJens Wiklander             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
131032b31808SJens Wiklander                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
131132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
131232b31808SJens Wiklander         }
131332b31808SJens Wiklander     } else {
131432b31808SJens Wiklander         ext_len = 0;
131532b31808SJens Wiklander     }
131632b31808SJens Wiklander 
131732b31808SJens Wiklander     ext = buf + ext_offset + 2;
131832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "client hello extensions", ext, ext_len);
131932b31808SJens Wiklander 
132032b31808SJens Wiklander     while (ext_len != 0) {
132132b31808SJens Wiklander         unsigned int ext_id;
132232b31808SJens Wiklander         unsigned int ext_size;
132332b31808SJens Wiklander         if (ext_len < 4) {
132432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
132532b31808SJens Wiklander             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
132632b31808SJens Wiklander                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
132732b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
132832b31808SJens Wiklander         }
1329b0563631STom Van Eyck         ext_id   = MBEDTLS_GET_UINT16_BE(ext, 0);
1330b0563631STom Van Eyck         ext_size = MBEDTLS_GET_UINT16_BE(ext, 2);
133132b31808SJens Wiklander 
133232b31808SJens Wiklander         if (ext_size + 4 > ext_len) {
133332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
133432b31808SJens Wiklander             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
133532b31808SJens Wiklander                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
133632b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
133732b31808SJens Wiklander         }
133832b31808SJens Wiklander         switch (ext_id) {
133932b31808SJens Wiklander #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
134032b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SERVERNAME:
134132b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found ServerName extension"));
134232b31808SJens Wiklander                 ret = mbedtls_ssl_parse_server_name_ext(ssl, ext + 4,
134332b31808SJens Wiklander                                                         ext + 4 + ext_size);
134432b31808SJens Wiklander                 if (ret != 0) {
134532b31808SJens Wiklander                     return ret;
134632b31808SJens Wiklander                 }
134732b31808SJens Wiklander                 break;
134832b31808SJens Wiklander #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
134932b31808SJens Wiklander 
135032b31808SJens Wiklander             case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
135132b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found renegotiation extension"));
135232b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
135332b31808SJens Wiklander                 renegotiation_info_seen = 1;
135432b31808SJens Wiklander #endif
135532b31808SJens Wiklander 
135632b31808SJens Wiklander                 ret = ssl_parse_renegotiation_info(ssl, ext + 4, ext_size);
135732b31808SJens Wiklander                 if (ret != 0) {
135832b31808SJens Wiklander                     return ret;
135932b31808SJens Wiklander                 }
136032b31808SJens Wiklander                 break;
136132b31808SJens Wiklander 
136232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
136332b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SIG_ALG:
136432b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found signature_algorithms extension"));
136532b31808SJens Wiklander 
136632b31808SJens Wiklander                 ret = mbedtls_ssl_parse_sig_alg_ext(ssl, ext + 4, ext + 4 + ext_size);
136732b31808SJens Wiklander                 if (ret != 0) {
136832b31808SJens Wiklander                     return ret;
136932b31808SJens Wiklander                 }
137032b31808SJens Wiklander 
137132b31808SJens Wiklander                 sig_hash_alg_ext_present = 1;
137232b31808SJens Wiklander                 break;
137332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
137432b31808SJens Wiklander 
1375b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
1376b0563631STom Van Eyck                 defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
137732b31808SJens Wiklander                 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
137832b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SUPPORTED_GROUPS:
137932b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found supported elliptic curves extension"));
138032b31808SJens Wiklander 
138132b31808SJens Wiklander                 ret = ssl_parse_supported_groups_ext(ssl, ext + 4, ext_size);
138232b31808SJens Wiklander                 if (ret != 0) {
138332b31808SJens Wiklander                     return ret;
138432b31808SJens Wiklander                 }
138532b31808SJens Wiklander                 break;
138632b31808SJens Wiklander 
138732b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
138832b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found supported point formats extension"));
138932b31808SJens Wiklander                 ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT;
139032b31808SJens Wiklander 
139132b31808SJens Wiklander                 ret = ssl_parse_supported_point_formats(ssl, ext + 4, ext_size);
139232b31808SJens Wiklander                 if (ret != 0) {
139332b31808SJens Wiklander                     return ret;
139432b31808SJens Wiklander                 }
139532b31808SJens Wiklander                 break;
1396b0563631STom Van Eyck #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || \
1397b0563631STom Van Eyck           MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED ||
139832b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
139932b31808SJens Wiklander 
140032b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
140132b31808SJens Wiklander             case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
140232b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found ecjpake kkpp extension"));
140332b31808SJens Wiklander 
140432b31808SJens Wiklander                 ret = ssl_parse_ecjpake_kkpp(ssl, ext + 4, ext_size);
140532b31808SJens Wiklander                 if (ret != 0) {
140632b31808SJens Wiklander                     return ret;
140732b31808SJens Wiklander                 }
140832b31808SJens Wiklander                 break;
140932b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
141032b31808SJens Wiklander 
141132b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
141232b31808SJens Wiklander             case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
141332b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found max fragment length extension"));
141432b31808SJens Wiklander 
141532b31808SJens Wiklander                 ret = ssl_parse_max_fragment_length_ext(ssl, ext + 4, ext_size);
141632b31808SJens Wiklander                 if (ret != 0) {
141732b31808SJens Wiklander                     return ret;
141832b31808SJens Wiklander                 }
141932b31808SJens Wiklander                 break;
142032b31808SJens Wiklander #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
142132b31808SJens Wiklander 
142232b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
142332b31808SJens Wiklander             case MBEDTLS_TLS_EXT_CID:
142432b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found CID extension"));
142532b31808SJens Wiklander 
142632b31808SJens Wiklander                 ret = ssl_parse_cid_ext(ssl, ext + 4, ext_size);
142732b31808SJens Wiklander                 if (ret != 0) {
142832b31808SJens Wiklander                     return ret;
142932b31808SJens Wiklander                 }
143032b31808SJens Wiklander                 break;
143132b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
143232b31808SJens Wiklander 
143332b31808SJens Wiklander #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
143432b31808SJens Wiklander             case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
143532b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found encrypt then mac extension"));
143632b31808SJens Wiklander 
143732b31808SJens Wiklander                 ret = ssl_parse_encrypt_then_mac_ext(ssl, ext + 4, ext_size);
143832b31808SJens Wiklander                 if (ret != 0) {
143932b31808SJens Wiklander                     return ret;
144032b31808SJens Wiklander                 }
144132b31808SJens Wiklander                 break;
144232b31808SJens Wiklander #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
144332b31808SJens Wiklander 
144432b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
144532b31808SJens Wiklander             case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
144632b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found extended master secret extension"));
144732b31808SJens Wiklander 
144832b31808SJens Wiklander                 ret = ssl_parse_extended_ms_ext(ssl, ext + 4, ext_size);
144932b31808SJens Wiklander                 if (ret != 0) {
145032b31808SJens Wiklander                     return ret;
145132b31808SJens Wiklander                 }
145232b31808SJens Wiklander                 break;
145332b31808SJens Wiklander #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
145432b31808SJens Wiklander 
145532b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
145632b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SESSION_TICKET:
145732b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found session ticket extension"));
145832b31808SJens Wiklander 
145932b31808SJens Wiklander                 ret = ssl_parse_session_ticket_ext(ssl, ext + 4, ext_size);
146032b31808SJens Wiklander                 if (ret != 0) {
146132b31808SJens Wiklander                     return ret;
146232b31808SJens Wiklander                 }
146332b31808SJens Wiklander                 break;
146432b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
146532b31808SJens Wiklander 
146632b31808SJens Wiklander #if defined(MBEDTLS_SSL_ALPN)
146732b31808SJens Wiklander             case MBEDTLS_TLS_EXT_ALPN:
146832b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found alpn extension"));
146932b31808SJens Wiklander 
147032b31808SJens Wiklander                 ret = mbedtls_ssl_parse_alpn_ext(ssl, ext + 4,
147132b31808SJens Wiklander                                                  ext + 4 + ext_size);
147232b31808SJens Wiklander                 if (ret != 0) {
147332b31808SJens Wiklander                     return ret;
147432b31808SJens Wiklander                 }
147532b31808SJens Wiklander                 break;
147632b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
147732b31808SJens Wiklander 
147832b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP)
147932b31808SJens Wiklander             case MBEDTLS_TLS_EXT_USE_SRTP:
148032b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found use_srtp extension"));
148132b31808SJens Wiklander 
148232b31808SJens Wiklander                 ret = ssl_parse_use_srtp_ext(ssl, ext + 4, ext_size);
148332b31808SJens Wiklander                 if (ret != 0) {
148432b31808SJens Wiklander                     return ret;
148532b31808SJens Wiklander                 }
148632b31808SJens Wiklander                 break;
148732b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_SRTP */
148832b31808SJens Wiklander 
148932b31808SJens Wiklander             default:
149032b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("unknown extension found: %u (ignoring)",
149132b31808SJens Wiklander                                           ext_id));
149232b31808SJens Wiklander         }
149332b31808SJens Wiklander 
149432b31808SJens Wiklander         ext_len -= 4 + ext_size;
149532b31808SJens Wiklander         ext += 4 + ext_size;
149632b31808SJens Wiklander     }
149732b31808SJens Wiklander 
149832b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
149932b31808SJens Wiklander 
150032b31808SJens Wiklander     /*
150132b31808SJens Wiklander      * Try to fall back to default hash SHA1 if the client
150232b31808SJens Wiklander      * hasn't provided any preferred signature-hash combinations.
150332b31808SJens Wiklander      */
150432b31808SJens Wiklander     if (!sig_hash_alg_ext_present) {
150532b31808SJens Wiklander         uint16_t *received_sig_algs = ssl->handshake->received_sig_algs;
150632b31808SJens Wiklander         const uint16_t default_sig_algs[] = {
1507b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
150832b31808SJens Wiklander             MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA,
150932b31808SJens Wiklander                                                MBEDTLS_SSL_HASH_SHA1),
151032b31808SJens Wiklander #endif
151132b31808SJens Wiklander #if defined(MBEDTLS_RSA_C)
151232b31808SJens Wiklander             MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA,
151332b31808SJens Wiklander                                                MBEDTLS_SSL_HASH_SHA1),
151432b31808SJens Wiklander #endif
151532b31808SJens Wiklander             MBEDTLS_TLS_SIG_NONE
151632b31808SJens Wiklander         };
151732b31808SJens Wiklander 
151832b31808SJens Wiklander         MBEDTLS_STATIC_ASSERT(sizeof(default_sig_algs) / sizeof(default_sig_algs[0])
151932b31808SJens Wiklander                               <= MBEDTLS_RECEIVED_SIG_ALGS_SIZE,
152032b31808SJens Wiklander                               "default_sig_algs is too big");
152132b31808SJens Wiklander 
152232b31808SJens Wiklander         memcpy(received_sig_algs, default_sig_algs, sizeof(default_sig_algs));
152332b31808SJens Wiklander     }
152432b31808SJens Wiklander 
152532b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
152632b31808SJens Wiklander 
152732b31808SJens Wiklander     /*
152832b31808SJens Wiklander      * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
152932b31808SJens Wiklander      */
153032b31808SJens Wiklander     for (i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2) {
153132b31808SJens Wiklander         if (p[0] == 0 && p[1] == MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO) {
153232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3, ("received TLS_EMPTY_RENEGOTIATION_INFO "));
153332b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
153432b31808SJens Wiklander             if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
153532b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1, ("received RENEGOTIATION SCSV "
153632b31808SJens Wiklander                                           "during renegotiation"));
153732b31808SJens Wiklander                 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
153832b31808SJens Wiklander                                                MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
153932b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
154032b31808SJens Wiklander             }
154132b31808SJens Wiklander #endif
154232b31808SJens Wiklander             ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
154332b31808SJens Wiklander             break;
154432b31808SJens Wiklander         }
154532b31808SJens Wiklander     }
154632b31808SJens Wiklander 
154732b31808SJens Wiklander     /*
154832b31808SJens Wiklander      * Renegotiation security checks
154932b31808SJens Wiklander      */
155032b31808SJens Wiklander     if (ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION &&
155132b31808SJens Wiklander         ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE) {
155232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("legacy renegotiation, breaking off handshake"));
155332b31808SJens Wiklander         handshake_failure = 1;
155432b31808SJens Wiklander     }
155532b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
155632b31808SJens Wiklander     else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
155732b31808SJens Wiklander              ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION &&
155832b31808SJens Wiklander              renegotiation_info_seen == 0) {
155932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("renegotiation_info extension missing (secure)"));
156032b31808SJens Wiklander         handshake_failure = 1;
156132b31808SJens Wiklander     } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
156232b31808SJens Wiklander                ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
156332b31808SJens Wiklander                ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION) {
156432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("legacy renegotiation not allowed"));
156532b31808SJens Wiklander         handshake_failure = 1;
156632b31808SJens Wiklander     } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
156732b31808SJens Wiklander                ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
156832b31808SJens Wiklander                renegotiation_info_seen == 1) {
156932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("renegotiation_info extension present (legacy)"));
157032b31808SJens Wiklander         handshake_failure = 1;
157132b31808SJens Wiklander     }
157232b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */
157332b31808SJens Wiklander 
157432b31808SJens Wiklander     if (handshake_failure == 1) {
157532b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
157632b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
157732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
157832b31808SJens Wiklander     }
157932b31808SJens Wiklander 
158032b31808SJens Wiklander     /*
158132b31808SJens Wiklander      * Server certification selection (after processing TLS extensions)
158232b31808SJens Wiklander      */
158332b31808SJens Wiklander     if (ssl->conf->f_cert_cb && (ret = ssl->conf->f_cert_cb(ssl)) != 0) {
158432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "f_cert_cb", ret);
158532b31808SJens Wiklander         return ret;
158632b31808SJens Wiklander     }
158732b31808SJens Wiklander #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
158832b31808SJens Wiklander     ssl->handshake->sni_name = NULL;
158932b31808SJens Wiklander     ssl->handshake->sni_name_len = 0;
159032b31808SJens Wiklander #endif
159132b31808SJens Wiklander 
159232b31808SJens Wiklander     /*
159332b31808SJens Wiklander      * Search for a matching ciphersuite
159432b31808SJens Wiklander      * (At the end because we need information from the EC-based extensions
159532b31808SJens Wiklander      * and certificate from the SNI callback triggered by the SNI extension
159632b31808SJens Wiklander      * or certificate from server certificate selection callback.)
159732b31808SJens Wiklander      */
159832b31808SJens Wiklander     got_common_suite = 0;
159932b31808SJens Wiklander     ciphersuites = ssl->conf->ciphersuite_list;
160032b31808SJens Wiklander     ciphersuite_info = NULL;
160132b31808SJens Wiklander 
160232b31808SJens Wiklander     if (ssl->conf->respect_cli_pref == MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT) {
160332b31808SJens Wiklander         for (j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2) {
160432b31808SJens Wiklander             for (i = 0; ciphersuites[i] != 0; i++) {
160532b31808SJens Wiklander                 if (MBEDTLS_GET_UINT16_BE(p, 0) != ciphersuites[i]) {
160632b31808SJens Wiklander                     continue;
160732b31808SJens Wiklander                 }
160832b31808SJens Wiklander 
160932b31808SJens Wiklander                 got_common_suite = 1;
161032b31808SJens Wiklander 
161132b31808SJens Wiklander                 if ((ret = ssl_ciphersuite_match(ssl, ciphersuites[i],
161232b31808SJens Wiklander                                                  &ciphersuite_info)) != 0) {
161332b31808SJens Wiklander                     return ret;
161432b31808SJens Wiklander                 }
161532b31808SJens Wiklander 
161632b31808SJens Wiklander                 if (ciphersuite_info != NULL) {
161732b31808SJens Wiklander                     goto have_ciphersuite;
161832b31808SJens Wiklander                 }
161932b31808SJens Wiklander             }
162032b31808SJens Wiklander         }
162132b31808SJens Wiklander     } else {
162232b31808SJens Wiklander         for (i = 0; ciphersuites[i] != 0; i++) {
162332b31808SJens Wiklander             for (j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2) {
162432b31808SJens Wiklander                 if (MBEDTLS_GET_UINT16_BE(p, 0) != ciphersuites[i]) {
162532b31808SJens Wiklander                     continue;
162632b31808SJens Wiklander                 }
162732b31808SJens Wiklander 
162832b31808SJens Wiklander                 got_common_suite = 1;
162932b31808SJens Wiklander 
163032b31808SJens Wiklander                 if ((ret = ssl_ciphersuite_match(ssl, ciphersuites[i],
163132b31808SJens Wiklander                                                  &ciphersuite_info)) != 0) {
163232b31808SJens Wiklander                     return ret;
163332b31808SJens Wiklander                 }
163432b31808SJens Wiklander 
163532b31808SJens Wiklander                 if (ciphersuite_info != NULL) {
163632b31808SJens Wiklander                     goto have_ciphersuite;
163732b31808SJens Wiklander                 }
163832b31808SJens Wiklander             }
163932b31808SJens Wiklander         }
164032b31808SJens Wiklander     }
164132b31808SJens Wiklander 
164232b31808SJens Wiklander     if (got_common_suite) {
164332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got ciphersuites in common, "
164432b31808SJens Wiklander                                   "but none of them usable"));
164532b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
164632b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
164732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
164832b31808SJens Wiklander     } else {
164932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got no ciphersuites in common"));
165032b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
165132b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
165232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
165332b31808SJens Wiklander     }
165432b31808SJens Wiklander 
165532b31808SJens Wiklander have_ciphersuite:
165632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("selected ciphersuite: %s", ciphersuite_info->name));
165732b31808SJens Wiklander 
165832b31808SJens Wiklander     ssl->session_negotiate->ciphersuite = ciphersuites[i];
165932b31808SJens Wiklander     ssl->handshake->ciphersuite_info = ciphersuite_info;
166032b31808SJens Wiklander 
166132b31808SJens Wiklander     ssl->state++;
166232b31808SJens Wiklander 
166332b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
166432b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
166532b31808SJens Wiklander         mbedtls_ssl_recv_flight_completed(ssl);
166632b31808SJens Wiklander     }
166732b31808SJens Wiklander #endif
166832b31808SJens Wiklander 
166932b31808SJens Wiklander     /* Debugging-only output for testsuite */
167032b31808SJens Wiklander #if defined(MBEDTLS_DEBUG_C)                         && \
167132b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
167232b31808SJens Wiklander     mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_alg(ciphersuite_info);
167332b31808SJens Wiklander     if (sig_alg != MBEDTLS_PK_NONE) {
167432b31808SJens Wiklander         unsigned int sig_hash = mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
167532b31808SJens Wiklander             ssl, mbedtls_ssl_sig_from_pk_alg(sig_alg));
167632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("client hello v3, signature_algorithm ext: %u",
167732b31808SJens Wiklander                                   sig_hash));
167832b31808SJens Wiklander     } else {
167932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("no hash algorithm for signature algorithm "
168032b31808SJens Wiklander                                   "%u - should not happen", (unsigned) sig_alg));
168132b31808SJens Wiklander     }
168232b31808SJens Wiklander #endif
168332b31808SJens Wiklander 
168432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse client hello"));
168532b31808SJens Wiklander 
168632b31808SJens Wiklander     return 0;
168732b31808SJens Wiklander }
168832b31808SJens Wiklander 
168932b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
169032b31808SJens Wiklander static void ssl_write_cid_ext(mbedtls_ssl_context *ssl,
169132b31808SJens Wiklander                               unsigned char *buf,
169232b31808SJens Wiklander                               size_t *olen)
169332b31808SJens Wiklander {
169432b31808SJens Wiklander     unsigned char *p = buf;
169532b31808SJens Wiklander     size_t ext_len;
169632b31808SJens Wiklander     const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
169732b31808SJens Wiklander 
169832b31808SJens Wiklander     *olen = 0;
169932b31808SJens Wiklander 
170032b31808SJens Wiklander     /* Skip writing the extension if we don't want to use it or if
170132b31808SJens Wiklander      * the client hasn't offered it. */
170232b31808SJens Wiklander     if (ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_DISABLED) {
170332b31808SJens Wiklander         return;
170432b31808SJens Wiklander     }
170532b31808SJens Wiklander 
170632b31808SJens Wiklander     /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX
170732b31808SJens Wiklander      * which is at most 255, so the increment cannot overflow. */
170832b31808SJens Wiklander     if (end < p || (size_t) (end - p) < (unsigned) (ssl->own_cid_len + 5)) {
170932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small"));
171032b31808SJens Wiklander         return;
171132b31808SJens Wiklander     }
171232b31808SJens Wiklander 
171332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding CID extension"));
171432b31808SJens Wiklander 
171532b31808SJens Wiklander     /*
171632b31808SJens Wiklander      *   struct {
171732b31808SJens Wiklander      *      opaque cid<0..2^8-1>;
171832b31808SJens Wiklander      *   } ConnectionId;
171932b31808SJens Wiklander      */
172032b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_CID, p, 0);
172132b31808SJens Wiklander     p += 2;
172232b31808SJens Wiklander     ext_len = (size_t) ssl->own_cid_len + 1;
172332b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(ext_len, p, 0);
172432b31808SJens Wiklander     p += 2;
172532b31808SJens Wiklander 
172632b31808SJens Wiklander     *p++ = (uint8_t) ssl->own_cid_len;
172732b31808SJens Wiklander     memcpy(p, ssl->own_cid, ssl->own_cid_len);
172832b31808SJens Wiklander 
172932b31808SJens Wiklander     *olen = ssl->own_cid_len + 5;
173032b31808SJens Wiklander }
173132b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
173232b31808SJens Wiklander 
173332b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM)
173432b31808SJens Wiklander static void ssl_write_encrypt_then_mac_ext(mbedtls_ssl_context *ssl,
173532b31808SJens Wiklander                                            unsigned char *buf,
173632b31808SJens Wiklander                                            size_t *olen)
173732b31808SJens Wiklander {
173832b31808SJens Wiklander     unsigned char *p = buf;
173932b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *suite = NULL;
174032b31808SJens Wiklander 
174132b31808SJens Wiklander     /*
174232b31808SJens Wiklander      * RFC 7366: "If a server receives an encrypt-then-MAC request extension
174332b31808SJens Wiklander      * from a client and then selects a stream or Authenticated Encryption
174432b31808SJens Wiklander      * with Associated Data (AEAD) ciphersuite, it MUST NOT send an
174532b31808SJens Wiklander      * encrypt-then-MAC response extension back to the client."
174632b31808SJens Wiklander      */
174732b31808SJens Wiklander     suite = mbedtls_ssl_ciphersuite_from_id(
174832b31808SJens Wiklander         ssl->session_negotiate->ciphersuite);
174932b31808SJens Wiklander     if (suite == NULL) {
175032b31808SJens Wiklander         ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_DISABLED;
175132b31808SJens Wiklander     } else {
175232b31808SJens Wiklander         mbedtls_ssl_mode_t ssl_mode =
175332b31808SJens Wiklander             mbedtls_ssl_get_mode_from_ciphersuite(
175432b31808SJens Wiklander                 ssl->session_negotiate->encrypt_then_mac,
175532b31808SJens Wiklander                 suite);
175632b31808SJens Wiklander 
175732b31808SJens Wiklander         if (ssl_mode != MBEDTLS_SSL_MODE_CBC_ETM) {
175832b31808SJens Wiklander             ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_DISABLED;
175932b31808SJens Wiklander         }
176032b31808SJens Wiklander     }
176132b31808SJens Wiklander 
176232b31808SJens Wiklander     if (ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED) {
176332b31808SJens Wiklander         *olen = 0;
176432b31808SJens Wiklander         return;
176532b31808SJens Wiklander     }
176632b31808SJens Wiklander 
176732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding encrypt then mac extension"));
176832b31808SJens Wiklander 
176932b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, p, 0);
177032b31808SJens Wiklander     p += 2;
177132b31808SJens Wiklander 
177232b31808SJens Wiklander     *p++ = 0x00;
177332b31808SJens Wiklander     *p++ = 0x00;
177432b31808SJens Wiklander 
177532b31808SJens Wiklander     *olen = 4;
177632b31808SJens Wiklander }
177732b31808SJens Wiklander #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */
177832b31808SJens Wiklander 
177932b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
178032b31808SJens Wiklander static void ssl_write_extended_ms_ext(mbedtls_ssl_context *ssl,
178132b31808SJens Wiklander                                       unsigned char *buf,
178232b31808SJens Wiklander                                       size_t *olen)
178332b31808SJens Wiklander {
178432b31808SJens Wiklander     unsigned char *p = buf;
178532b31808SJens Wiklander 
178632b31808SJens Wiklander     if (ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED) {
178732b31808SJens Wiklander         *olen = 0;
178832b31808SJens Wiklander         return;
178932b31808SJens Wiklander     }
179032b31808SJens Wiklander 
179132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding extended master secret "
179232b31808SJens Wiklander                               "extension"));
179332b31808SJens Wiklander 
179432b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, p, 0);
179532b31808SJens Wiklander     p += 2;
179632b31808SJens Wiklander 
179732b31808SJens Wiklander     *p++ = 0x00;
179832b31808SJens Wiklander     *p++ = 0x00;
179932b31808SJens Wiklander 
180032b31808SJens Wiklander     *olen = 4;
180132b31808SJens Wiklander }
180232b31808SJens Wiklander #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
180332b31808SJens Wiklander 
180432b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
180532b31808SJens Wiklander static void ssl_write_session_ticket_ext(mbedtls_ssl_context *ssl,
180632b31808SJens Wiklander                                          unsigned char *buf,
180732b31808SJens Wiklander                                          size_t *olen)
180832b31808SJens Wiklander {
180932b31808SJens Wiklander     unsigned char *p = buf;
181032b31808SJens Wiklander 
181132b31808SJens Wiklander     if (ssl->handshake->new_session_ticket == 0) {
181232b31808SJens Wiklander         *olen = 0;
181332b31808SJens Wiklander         return;
181432b31808SJens Wiklander     }
181532b31808SJens Wiklander 
181632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding session ticket extension"));
181732b31808SJens Wiklander 
181832b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SESSION_TICKET, p, 0);
181932b31808SJens Wiklander     p += 2;
182032b31808SJens Wiklander 
182132b31808SJens Wiklander     *p++ = 0x00;
182232b31808SJens Wiklander     *p++ = 0x00;
182332b31808SJens Wiklander 
182432b31808SJens Wiklander     *olen = 4;
182532b31808SJens Wiklander }
182632b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
182732b31808SJens Wiklander 
182832b31808SJens Wiklander static void ssl_write_renegotiation_ext(mbedtls_ssl_context *ssl,
182932b31808SJens Wiklander                                         unsigned char *buf,
183032b31808SJens Wiklander                                         size_t *olen)
183132b31808SJens Wiklander {
183232b31808SJens Wiklander     unsigned char *p = buf;
183332b31808SJens Wiklander 
183432b31808SJens Wiklander     if (ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION) {
183532b31808SJens Wiklander         *olen = 0;
183632b31808SJens Wiklander         return;
183732b31808SJens Wiklander     }
183832b31808SJens Wiklander 
183932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, secure renegotiation extension"));
184032b31808SJens Wiklander 
184132b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_RENEGOTIATION_INFO, p, 0);
184232b31808SJens Wiklander     p += 2;
184332b31808SJens Wiklander 
184432b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
184532b31808SJens Wiklander     if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
184632b31808SJens Wiklander         *p++ = 0x00;
184732b31808SJens Wiklander         *p++ = (ssl->verify_data_len * 2 + 1) & 0xFF;
184832b31808SJens Wiklander         *p++ = ssl->verify_data_len * 2 & 0xFF;
184932b31808SJens Wiklander 
185032b31808SJens Wiklander         memcpy(p, ssl->peer_verify_data, ssl->verify_data_len);
185132b31808SJens Wiklander         p += ssl->verify_data_len;
185232b31808SJens Wiklander         memcpy(p, ssl->own_verify_data, ssl->verify_data_len);
185332b31808SJens Wiklander         p += ssl->verify_data_len;
185432b31808SJens Wiklander     } else
185532b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */
185632b31808SJens Wiklander     {
185732b31808SJens Wiklander         *p++ = 0x00;
185832b31808SJens Wiklander         *p++ = 0x01;
185932b31808SJens Wiklander         *p++ = 0x00;
186032b31808SJens Wiklander     }
186132b31808SJens Wiklander 
1862b0563631STom Van Eyck     *olen = (size_t) (p - buf);
186332b31808SJens Wiklander }
186432b31808SJens Wiklander 
186532b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
186632b31808SJens Wiklander static void ssl_write_max_fragment_length_ext(mbedtls_ssl_context *ssl,
186732b31808SJens Wiklander                                               unsigned char *buf,
186832b31808SJens Wiklander                                               size_t *olen)
186932b31808SJens Wiklander {
187032b31808SJens Wiklander     unsigned char *p = buf;
187132b31808SJens Wiklander 
187232b31808SJens Wiklander     if (ssl->session_negotiate->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE) {
187332b31808SJens Wiklander         *olen = 0;
187432b31808SJens Wiklander         return;
187532b31808SJens Wiklander     }
187632b31808SJens Wiklander 
187732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, max_fragment_length extension"));
187832b31808SJens Wiklander 
187932b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, p, 0);
188032b31808SJens Wiklander     p += 2;
188132b31808SJens Wiklander 
188232b31808SJens Wiklander     *p++ = 0x00;
188332b31808SJens Wiklander     *p++ = 1;
188432b31808SJens Wiklander 
188532b31808SJens Wiklander     *p++ = ssl->session_negotiate->mfl_code;
188632b31808SJens Wiklander 
188732b31808SJens Wiklander     *olen = 5;
188832b31808SJens Wiklander }
188932b31808SJens Wiklander #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
189032b31808SJens Wiklander 
1891b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
1892b0563631STom Van Eyck     defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
189332b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
189432b31808SJens Wiklander static void ssl_write_supported_point_formats_ext(mbedtls_ssl_context *ssl,
189532b31808SJens Wiklander                                                   unsigned char *buf,
189632b31808SJens Wiklander                                                   size_t *olen)
189732b31808SJens Wiklander {
189832b31808SJens Wiklander     unsigned char *p = buf;
189932b31808SJens Wiklander     ((void) ssl);
190032b31808SJens Wiklander 
190132b31808SJens Wiklander     if ((ssl->handshake->cli_exts &
190232b31808SJens Wiklander          MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT) == 0) {
190332b31808SJens Wiklander         *olen = 0;
190432b31808SJens Wiklander         return;
190532b31808SJens Wiklander     }
190632b31808SJens Wiklander 
190732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, supported_point_formats extension"));
190832b31808SJens Wiklander 
190932b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, p, 0);
191032b31808SJens Wiklander     p += 2;
191132b31808SJens Wiklander 
191232b31808SJens Wiklander     *p++ = 0x00;
191332b31808SJens Wiklander     *p++ = 2;
191432b31808SJens Wiklander 
191532b31808SJens Wiklander     *p++ = 1;
191632b31808SJens Wiklander     *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED;
191732b31808SJens Wiklander 
191832b31808SJens Wiklander     *olen = 6;
191932b31808SJens Wiklander }
1920b0563631STom Van Eyck #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED ||
1921b0563631STom Van Eyck           MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED ||
1922b0563631STom Van Eyck           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
192332b31808SJens Wiklander 
192432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
192532b31808SJens Wiklander static void ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl,
192632b31808SJens Wiklander                                        unsigned char *buf,
192732b31808SJens Wiklander                                        size_t *olen)
192832b31808SJens Wiklander {
192932b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
193032b31808SJens Wiklander     unsigned char *p = buf;
193132b31808SJens Wiklander     const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
193232b31808SJens Wiklander     size_t kkpp_len;
193332b31808SJens Wiklander 
193432b31808SJens Wiklander     *olen = 0;
193532b31808SJens Wiklander 
193632b31808SJens Wiklander     /* Skip costly computation if not needed */
193732b31808SJens Wiklander     if (ssl->handshake->ciphersuite_info->key_exchange !=
193832b31808SJens Wiklander         MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
193932b31808SJens Wiklander         return;
194032b31808SJens Wiklander     }
194132b31808SJens Wiklander 
194232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, ecjpake kkpp extension"));
194332b31808SJens Wiklander 
194432b31808SJens Wiklander     if (end - p < 4) {
194532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small"));
194632b31808SJens Wiklander         return;
194732b31808SJens Wiklander     }
194832b31808SJens Wiklander 
194932b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0);
195032b31808SJens Wiklander     p += 2;
195132b31808SJens Wiklander 
195232b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
195332b31808SJens Wiklander     ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx,
1954b0563631STom Van Eyck                                           p + 2, (size_t) (end - p - 2), &kkpp_len,
195532b31808SJens Wiklander                                           MBEDTLS_ECJPAKE_ROUND_ONE);
195632b31808SJens Wiklander     if (ret != 0) {
195732b31808SJens Wiklander         psa_destroy_key(ssl->handshake->psa_pake_password);
195832b31808SJens Wiklander         psa_pake_abort(&ssl->handshake->psa_pake_ctx);
195932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret);
196032b31808SJens Wiklander         return;
196132b31808SJens Wiklander     }
196232b31808SJens Wiklander #else
196332b31808SJens Wiklander     ret = mbedtls_ecjpake_write_round_one(&ssl->handshake->ecjpake_ctx,
1964b0563631STom Van Eyck                                           p + 2, (size_t) (end - p - 2), &kkpp_len,
196532b31808SJens Wiklander                                           ssl->conf->f_rng, ssl->conf->p_rng);
196632b31808SJens Wiklander     if (ret != 0) {
196732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_one", ret);
196832b31808SJens Wiklander         return;
196932b31808SJens Wiklander     }
197032b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
197132b31808SJens Wiklander 
197232b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(kkpp_len, p, 0);
197332b31808SJens Wiklander     p += 2;
197432b31808SJens Wiklander 
197532b31808SJens Wiklander     *olen = kkpp_len + 4;
197632b31808SJens Wiklander }
197732b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
197832b31808SJens Wiklander 
197932b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP) && defined(MBEDTLS_SSL_PROTO_DTLS)
198032b31808SJens Wiklander static void ssl_write_use_srtp_ext(mbedtls_ssl_context *ssl,
198132b31808SJens Wiklander                                    unsigned char *buf,
198232b31808SJens Wiklander                                    size_t *olen)
198332b31808SJens Wiklander {
198432b31808SJens Wiklander     size_t mki_len = 0, ext_len = 0;
198532b31808SJens Wiklander     uint16_t profile_value = 0;
198632b31808SJens Wiklander     const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
198732b31808SJens Wiklander 
198832b31808SJens Wiklander     *olen = 0;
198932b31808SJens Wiklander 
199032b31808SJens Wiklander     if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) ||
199132b31808SJens Wiklander         (ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET)) {
199232b31808SJens Wiklander         return;
199332b31808SJens Wiklander     }
199432b31808SJens Wiklander 
199532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding use_srtp extension"));
199632b31808SJens Wiklander 
199732b31808SJens Wiklander     if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED) {
199832b31808SJens Wiklander         mki_len = ssl->dtls_srtp_info.mki_len;
199932b31808SJens Wiklander     }
200032b31808SJens Wiklander 
200132b31808SJens Wiklander     /* The extension total size is 9 bytes :
200232b31808SJens Wiklander      * - 2 bytes for the extension tag
200332b31808SJens Wiklander      * - 2 bytes for the total size
200432b31808SJens Wiklander      * - 2 bytes for the protection profile length
200532b31808SJens Wiklander      * - 2 bytes for the protection profile
200632b31808SJens Wiklander      * - 1 byte for the mki length
200732b31808SJens Wiklander      * +  the actual mki length
200832b31808SJens Wiklander      * Check we have enough room in the output buffer */
200932b31808SJens Wiklander     if ((size_t) (end - buf) < mki_len + 9) {
201032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small"));
201132b31808SJens Wiklander         return;
201232b31808SJens Wiklander     }
201332b31808SJens Wiklander 
201432b31808SJens Wiklander     /* extension */
201532b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_USE_SRTP, buf, 0);
201632b31808SJens Wiklander     /*
201732b31808SJens Wiklander      * total length 5 and mki value: only one profile(2 bytes)
201832b31808SJens Wiklander      *              and length(2 bytes) and srtp_mki  )
201932b31808SJens Wiklander      */
202032b31808SJens Wiklander     ext_len = 5 + mki_len;
202132b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(ext_len, buf, 2);
202232b31808SJens Wiklander 
202332b31808SJens Wiklander     /* protection profile length: 2 */
202432b31808SJens Wiklander     buf[4] = 0x00;
202532b31808SJens Wiklander     buf[5] = 0x02;
202632b31808SJens Wiklander     profile_value = mbedtls_ssl_check_srtp_profile_value(
202732b31808SJens Wiklander         ssl->dtls_srtp_info.chosen_dtls_srtp_profile);
202832b31808SJens Wiklander     if (profile_value != MBEDTLS_TLS_SRTP_UNSET) {
202932b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(profile_value, buf, 6);
203032b31808SJens Wiklander     } else {
203132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("use_srtp extension invalid profile"));
203232b31808SJens Wiklander         return;
203332b31808SJens Wiklander     }
203432b31808SJens Wiklander 
203532b31808SJens Wiklander     buf[8] = mki_len & 0xFF;
203632b31808SJens Wiklander     memcpy(&buf[9], ssl->dtls_srtp_info.mki_value, mki_len);
203732b31808SJens Wiklander 
203832b31808SJens Wiklander     *olen = 9 + mki_len;
203932b31808SJens Wiklander }
204032b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_SRTP */
204132b31808SJens Wiklander 
204232b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
204332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
204432b31808SJens Wiklander static int ssl_write_hello_verify_request(mbedtls_ssl_context *ssl)
204532b31808SJens Wiklander {
204632b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
204732b31808SJens Wiklander     unsigned char *p = ssl->out_msg + 4;
204832b31808SJens Wiklander     unsigned char *cookie_len_byte;
204932b31808SJens Wiklander 
205032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write hello verify request"));
205132b31808SJens Wiklander 
205232b31808SJens Wiklander     /*
205332b31808SJens Wiklander      * struct {
205432b31808SJens Wiklander      *   ProtocolVersion server_version;
205532b31808SJens Wiklander      *   opaque cookie<0..2^8-1>;
205632b31808SJens Wiklander      * } HelloVerifyRequest;
205732b31808SJens Wiklander      */
205832b31808SJens Wiklander 
205932b31808SJens Wiklander     /* The RFC is not clear on this point, but sending the actual negotiated
206032b31808SJens Wiklander      * version looks like the most interoperable thing to do. */
206132b31808SJens Wiklander     mbedtls_ssl_write_version(p, ssl->conf->transport, ssl->tls_version);
206232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "server version", p, 2);
206332b31808SJens Wiklander     p += 2;
206432b31808SJens Wiklander 
206532b31808SJens Wiklander     /* If we get here, f_cookie_check is not null */
206632b31808SJens Wiklander     if (ssl->conf->f_cookie_write == NULL) {
206732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("inconsistent cookie callbacks"));
206832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
206932b31808SJens Wiklander     }
207032b31808SJens Wiklander 
207132b31808SJens Wiklander     /* Skip length byte until we know the length */
207232b31808SJens Wiklander     cookie_len_byte = p++;
207332b31808SJens Wiklander 
207432b31808SJens Wiklander     if ((ret = ssl->conf->f_cookie_write(ssl->conf->p_cookie,
207532b31808SJens Wiklander                                          &p, ssl->out_buf + MBEDTLS_SSL_OUT_BUFFER_LEN,
207632b31808SJens Wiklander                                          ssl->cli_id, ssl->cli_id_len)) != 0) {
207732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "f_cookie_write", ret);
207832b31808SJens Wiklander         return ret;
207932b31808SJens Wiklander     }
208032b31808SJens Wiklander 
208132b31808SJens Wiklander     *cookie_len_byte = (unsigned char) (p - (cookie_len_byte + 1));
208232b31808SJens Wiklander 
208332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "cookie sent", cookie_len_byte + 1, *cookie_len_byte);
208432b31808SJens Wiklander 
2085b0563631STom Van Eyck     ssl->out_msglen  = (size_t) (p - ssl->out_msg);
208632b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
208732b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
208832b31808SJens Wiklander 
208932b31808SJens Wiklander     ssl->state = MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT;
209032b31808SJens Wiklander 
209132b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
209232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
209332b31808SJens Wiklander         return ret;
209432b31808SJens Wiklander     }
209532b31808SJens Wiklander 
209632b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
209732b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
209832b31808SJens Wiklander         (ret = mbedtls_ssl_flight_transmit(ssl)) != 0) {
209932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flight_transmit", ret);
210032b31808SJens Wiklander         return ret;
210132b31808SJens Wiklander     }
210232b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */
210332b31808SJens Wiklander 
210432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write hello verify request"));
210532b31808SJens Wiklander 
210632b31808SJens Wiklander     return 0;
210732b31808SJens Wiklander }
210832b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
210932b31808SJens Wiklander 
211032b31808SJens Wiklander static void ssl_handle_id_based_session_resumption(mbedtls_ssl_context *ssl)
211132b31808SJens Wiklander {
211232b31808SJens Wiklander     int ret;
211332b31808SJens Wiklander     mbedtls_ssl_session session_tmp;
211432b31808SJens Wiklander     mbedtls_ssl_session * const session = ssl->session_negotiate;
211532b31808SJens Wiklander 
211632b31808SJens Wiklander     /* Resume is 0  by default, see ssl_handshake_init().
211732b31808SJens Wiklander      * It may be already set to 1 by ssl_parse_session_ticket_ext(). */
211832b31808SJens Wiklander     if (ssl->handshake->resume == 1) {
211932b31808SJens Wiklander         return;
212032b31808SJens Wiklander     }
212132b31808SJens Wiklander     if (session->id_len == 0) {
212232b31808SJens Wiklander         return;
212332b31808SJens Wiklander     }
212432b31808SJens Wiklander     if (ssl->conf->f_get_cache == NULL) {
212532b31808SJens Wiklander         return;
212632b31808SJens Wiklander     }
212732b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
212832b31808SJens Wiklander     if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
212932b31808SJens Wiklander         return;
213032b31808SJens Wiklander     }
213132b31808SJens Wiklander #endif
213232b31808SJens Wiklander 
213332b31808SJens Wiklander     mbedtls_ssl_session_init(&session_tmp);
213432b31808SJens Wiklander 
213532b31808SJens Wiklander     ret = ssl->conf->f_get_cache(ssl->conf->p_cache,
213632b31808SJens Wiklander                                  session->id,
213732b31808SJens Wiklander                                  session->id_len,
213832b31808SJens Wiklander                                  &session_tmp);
213932b31808SJens Wiklander     if (ret != 0) {
214032b31808SJens Wiklander         goto exit;
214132b31808SJens Wiklander     }
214232b31808SJens Wiklander 
214332b31808SJens Wiklander     if (session->ciphersuite != session_tmp.ciphersuite) {
214432b31808SJens Wiklander         /* Mismatch between cached and negotiated session */
214532b31808SJens Wiklander         goto exit;
214632b31808SJens Wiklander     }
214732b31808SJens Wiklander 
214832b31808SJens Wiklander     /* Move semantics */
214932b31808SJens Wiklander     mbedtls_ssl_session_free(session);
215032b31808SJens Wiklander     *session = session_tmp;
215132b31808SJens Wiklander     memset(&session_tmp, 0, sizeof(session_tmp));
215232b31808SJens Wiklander 
215332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("session successfully restored from cache"));
215432b31808SJens Wiklander     ssl->handshake->resume = 1;
215532b31808SJens Wiklander 
215632b31808SJens Wiklander exit:
215732b31808SJens Wiklander 
215832b31808SJens Wiklander     mbedtls_ssl_session_free(&session_tmp);
215932b31808SJens Wiklander }
216032b31808SJens Wiklander 
216132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
216232b31808SJens Wiklander static int ssl_write_server_hello(mbedtls_ssl_context *ssl)
216332b31808SJens Wiklander {
216432b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME)
216532b31808SJens Wiklander     mbedtls_time_t t;
216632b31808SJens Wiklander #endif
216732b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
216832b31808SJens Wiklander     size_t olen, ext_len = 0, n;
216932b31808SJens Wiklander     unsigned char *buf, *p;
217032b31808SJens Wiklander 
217132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server hello"));
217232b31808SJens Wiklander 
217332b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
217432b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
217532b31808SJens Wiklander         ssl->handshake->cookie_verify_result != 0) {
217632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("client hello was not authenticated"));
217732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello"));
217832b31808SJens Wiklander 
217932b31808SJens Wiklander         return ssl_write_hello_verify_request(ssl);
218032b31808SJens Wiklander     }
218132b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
218232b31808SJens Wiklander 
218332b31808SJens Wiklander     /*
218432b31808SJens Wiklander      *     0  .   0   handshake type
218532b31808SJens Wiklander      *     1  .   3   handshake length
218632b31808SJens Wiklander      *     4  .   5   protocol version
218732b31808SJens Wiklander      *     6  .   9   UNIX time()
218832b31808SJens Wiklander      *    10  .  37   random bytes
218932b31808SJens Wiklander      */
219032b31808SJens Wiklander     buf = ssl->out_msg;
219132b31808SJens Wiklander     p = buf + 4;
219232b31808SJens Wiklander 
219332b31808SJens Wiklander     mbedtls_ssl_write_version(p, ssl->conf->transport, ssl->tls_version);
219432b31808SJens Wiklander     p += 2;
219532b31808SJens Wiklander 
219632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen version: [%d:%d]",
219732b31808SJens Wiklander                               buf[4], buf[5]));
219832b31808SJens Wiklander 
219932b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME)
220032b31808SJens Wiklander     t = mbedtls_time(NULL);
220132b31808SJens Wiklander     MBEDTLS_PUT_UINT32_BE(t, p, 0);
220232b31808SJens Wiklander     p += 4;
220332b31808SJens Wiklander 
220432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, current time: %" MBEDTLS_PRINTF_LONGLONG,
220532b31808SJens Wiklander                               (long long) t));
220632b31808SJens Wiklander #else
220732b31808SJens Wiklander     if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 4)) != 0) {
220832b31808SJens Wiklander         return ret;
220932b31808SJens Wiklander     }
221032b31808SJens Wiklander 
221132b31808SJens Wiklander     p += 4;
221232b31808SJens Wiklander #endif /* MBEDTLS_HAVE_TIME */
221332b31808SJens Wiklander 
2214b0563631STom Van Eyck     if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 20)) != 0) {
221532b31808SJens Wiklander         return ret;
221632b31808SJens Wiklander     }
2217b0563631STom Van Eyck     p += 20;
221832b31808SJens Wiklander 
2219b0563631STom Van Eyck #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
2220b0563631STom Van Eyck     /*
2221b0563631STom Van Eyck      * RFC 8446
2222b0563631STom Van Eyck      * TLS 1.3 has a downgrade protection mechanism embedded in the server's
2223b0563631STom Van Eyck      * random value. TLS 1.3 servers which negotiate TLS 1.2 or below in
2224b0563631STom Van Eyck      * response to a ClientHello MUST set the last 8 bytes of their Random
2225b0563631STom Van Eyck      * value specially in their ServerHello.
2226b0563631STom Van Eyck      */
2227b0563631STom Van Eyck     if (mbedtls_ssl_conf_is_tls13_enabled(ssl->conf)) {
2228b0563631STom Van Eyck         static const unsigned char magic_tls12_downgrade_string[] =
2229b0563631STom Van Eyck         { 'D', 'O', 'W', 'N', 'G', 'R', 'D', 1 };
2230b0563631STom Van Eyck 
2231b0563631STom Van Eyck         MBEDTLS_STATIC_ASSERT(
2232b0563631STom Van Eyck             sizeof(magic_tls12_downgrade_string) == 8,
2233b0563631STom Van Eyck             "magic_tls12_downgrade_string does not have the expected size");
2234b0563631STom Van Eyck 
2235b0563631STom Van Eyck         memcpy(p, magic_tls12_downgrade_string,
2236b0563631STom Van Eyck                sizeof(magic_tls12_downgrade_string));
2237b0563631STom Van Eyck     } else
2238b0563631STom Van Eyck #endif
2239b0563631STom Van Eyck     {
2240b0563631STom Van Eyck         if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 8)) != 0) {
2241b0563631STom Van Eyck             return ret;
2242b0563631STom Van Eyck         }
2243b0563631STom Van Eyck     }
2244b0563631STom Van Eyck     p += 8;
224532b31808SJens Wiklander 
224632b31808SJens Wiklander     memcpy(ssl->handshake->randbytes + 32, buf + 6, 32);
224732b31808SJens Wiklander 
224832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "server hello, random bytes", buf + 6, 32);
224932b31808SJens Wiklander 
225032b31808SJens Wiklander     ssl_handle_id_based_session_resumption(ssl);
225132b31808SJens Wiklander 
225232b31808SJens Wiklander     if (ssl->handshake->resume == 0) {
225332b31808SJens Wiklander         /*
225432b31808SJens Wiklander          * New session, create a new session id,
225532b31808SJens Wiklander          * unless we're about to issue a session ticket
225632b31808SJens Wiklander          */
225732b31808SJens Wiklander         ssl->state++;
225832b31808SJens Wiklander 
225932b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME)
226032b31808SJens Wiklander         ssl->session_negotiate->start = mbedtls_time(NULL);
226132b31808SJens Wiklander #endif
226232b31808SJens Wiklander 
226332b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
226432b31808SJens Wiklander         if (ssl->handshake->new_session_ticket != 0) {
226532b31808SJens Wiklander             ssl->session_negotiate->id_len = n = 0;
226632b31808SJens Wiklander             memset(ssl->session_negotiate->id, 0, 32);
226732b31808SJens Wiklander         } else
226832b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
226932b31808SJens Wiklander         {
227032b31808SJens Wiklander             ssl->session_negotiate->id_len = n = 32;
227132b31808SJens Wiklander             if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, ssl->session_negotiate->id,
227232b31808SJens Wiklander                                         n)) != 0) {
227332b31808SJens Wiklander                 return ret;
227432b31808SJens Wiklander             }
227532b31808SJens Wiklander         }
227632b31808SJens Wiklander     } else {
227732b31808SJens Wiklander         /*
227832b31808SJens Wiklander          * Resuming a session
227932b31808SJens Wiklander          */
228032b31808SJens Wiklander         n = ssl->session_negotiate->id_len;
228132b31808SJens Wiklander         ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC;
228232b31808SJens Wiklander 
228332b31808SJens Wiklander         if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) {
228432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret);
228532b31808SJens Wiklander             return ret;
228632b31808SJens Wiklander         }
228732b31808SJens Wiklander     }
228832b31808SJens Wiklander 
228932b31808SJens Wiklander     /*
229032b31808SJens Wiklander      *    38  .  38     session id length
229132b31808SJens Wiklander      *    39  . 38+n    session id
229232b31808SJens Wiklander      *   39+n . 40+n    chosen ciphersuite
229332b31808SJens Wiklander      *   41+n . 41+n    chosen compression alg.
229432b31808SJens Wiklander      *   42+n . 43+n    extensions length
229532b31808SJens Wiklander      *   44+n . 43+n+m  extensions
229632b31808SJens Wiklander      */
229732b31808SJens Wiklander     *p++ = (unsigned char) ssl->session_negotiate->id_len;
229832b31808SJens Wiklander     memcpy(p, ssl->session_negotiate->id, ssl->session_negotiate->id_len);
229932b31808SJens Wiklander     p += ssl->session_negotiate->id_len;
230032b31808SJens Wiklander 
230132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, session id len.: %" MBEDTLS_PRINTF_SIZET, n));
230232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3,   "server hello, session id", buf + 39, n);
230332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("%s session has been resumed",
230432b31808SJens Wiklander                               ssl->handshake->resume ? "a" : "no"));
230532b31808SJens Wiklander 
230632b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(ssl->session_negotiate->ciphersuite, p, 0);
230732b31808SJens Wiklander     p += 2;
230832b31808SJens Wiklander     *p++ = MBEDTLS_BYTE_0(MBEDTLS_SSL_COMPRESS_NULL);
230932b31808SJens Wiklander 
231032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen ciphersuite: %s",
231132b31808SJens Wiklander                               mbedtls_ssl_get_ciphersuite_name(ssl->session_negotiate->ciphersuite)));
231232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, compress alg.: 0x%02X",
231332b31808SJens Wiklander                               (unsigned int) MBEDTLS_SSL_COMPRESS_NULL));
231432b31808SJens Wiklander 
231532b31808SJens Wiklander     /*
231632b31808SJens Wiklander      *  First write extensions, then the total length
231732b31808SJens Wiklander      */
231832b31808SJens Wiklander     ssl_write_renegotiation_ext(ssl, p + 2 + ext_len, &olen);
231932b31808SJens Wiklander     ext_len += olen;
232032b31808SJens Wiklander 
232132b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
232232b31808SJens Wiklander     ssl_write_max_fragment_length_ext(ssl, p + 2 + ext_len, &olen);
232332b31808SJens Wiklander     ext_len += olen;
232432b31808SJens Wiklander #endif
232532b31808SJens Wiklander 
232632b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
232732b31808SJens Wiklander     ssl_write_cid_ext(ssl, p + 2 + ext_len, &olen);
232832b31808SJens Wiklander     ext_len += olen;
232932b31808SJens Wiklander #endif
233032b31808SJens Wiklander 
233132b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM)
233232b31808SJens Wiklander     ssl_write_encrypt_then_mac_ext(ssl, p + 2 + ext_len, &olen);
233332b31808SJens Wiklander     ext_len += olen;
233432b31808SJens Wiklander #endif
233532b31808SJens Wiklander 
233632b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
233732b31808SJens Wiklander     ssl_write_extended_ms_ext(ssl, p + 2 + ext_len, &olen);
233832b31808SJens Wiklander     ext_len += olen;
233932b31808SJens Wiklander #endif
234032b31808SJens Wiklander 
234132b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
234232b31808SJens Wiklander     ssl_write_session_ticket_ext(ssl, p + 2 + ext_len, &olen);
234332b31808SJens Wiklander     ext_len += olen;
234432b31808SJens Wiklander #endif
234532b31808SJens Wiklander 
2346b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
2347b0563631STom Van Eyck     defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
234832b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
234932b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *suite =
235032b31808SJens Wiklander         mbedtls_ssl_ciphersuite_from_id(ssl->session_negotiate->ciphersuite);
235132b31808SJens Wiklander     if (suite != NULL && mbedtls_ssl_ciphersuite_uses_ec(suite)) {
235232b31808SJens Wiklander         ssl_write_supported_point_formats_ext(ssl, p + 2 + ext_len, &olen);
235332b31808SJens Wiklander         ext_len += olen;
235432b31808SJens Wiklander     }
235532b31808SJens Wiklander #endif
235632b31808SJens Wiklander 
235732b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
235832b31808SJens Wiklander     ssl_write_ecjpake_kkpp_ext(ssl, p + 2 + ext_len, &olen);
235932b31808SJens Wiklander     ext_len += olen;
236032b31808SJens Wiklander #endif
236132b31808SJens Wiklander 
236232b31808SJens Wiklander #if defined(MBEDTLS_SSL_ALPN)
236332b31808SJens Wiklander     unsigned char *end = buf + MBEDTLS_SSL_OUT_CONTENT_LEN - 4;
236432b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_alpn_ext(ssl, p + 2 + ext_len, end, &olen))
236532b31808SJens Wiklander         != 0) {
236632b31808SJens Wiklander         return ret;
236732b31808SJens Wiklander     }
236832b31808SJens Wiklander 
236932b31808SJens Wiklander     ext_len += olen;
237032b31808SJens Wiklander #endif
237132b31808SJens Wiklander 
237232b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP)
237332b31808SJens Wiklander     ssl_write_use_srtp_ext(ssl, p + 2 + ext_len, &olen);
237432b31808SJens Wiklander     ext_len += olen;
237532b31808SJens Wiklander #endif
237632b31808SJens Wiklander 
237732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, total extension length: %" MBEDTLS_PRINTF_SIZET,
237832b31808SJens Wiklander                               ext_len));
237932b31808SJens Wiklander 
238032b31808SJens Wiklander     if (ext_len > 0) {
238132b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(ext_len, p, 0);
238232b31808SJens Wiklander         p += 2 + ext_len;
238332b31808SJens Wiklander     }
238432b31808SJens Wiklander 
2385b0563631STom Van Eyck     ssl->out_msglen  = (size_t) (p - buf);
238632b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
238732b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_HELLO;
238832b31808SJens Wiklander 
238932b31808SJens Wiklander     ret = mbedtls_ssl_write_handshake_msg(ssl);
239032b31808SJens Wiklander 
239132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello"));
239232b31808SJens Wiklander 
239332b31808SJens Wiklander     return ret;
239432b31808SJens Wiklander }
239532b31808SJens Wiklander 
239632b31808SJens Wiklander #if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
239732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
239832b31808SJens Wiklander static int ssl_write_certificate_request(mbedtls_ssl_context *ssl)
239932b31808SJens Wiklander {
240032b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
240132b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
240232b31808SJens Wiklander 
240332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate request"));
240432b31808SJens Wiklander 
240532b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
240632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate request"));
240732b31808SJens Wiklander         ssl->state++;
240832b31808SJens Wiklander         return 0;
240932b31808SJens Wiklander     }
241032b31808SJens Wiklander 
241132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
241232b31808SJens Wiklander     return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
241332b31808SJens Wiklander }
241432b31808SJens Wiklander #else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
241532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
241632b31808SJens Wiklander static int ssl_write_certificate_request(mbedtls_ssl_context *ssl)
241732b31808SJens Wiklander {
241832b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
241932b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
242032b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
242132b31808SJens Wiklander     uint16_t dn_size, total_dn_size; /* excluding length bytes */
242232b31808SJens Wiklander     size_t ct_len, sa_len; /* including length bytes */
242332b31808SJens Wiklander     unsigned char *buf, *p;
242432b31808SJens Wiklander     const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
242532b31808SJens Wiklander     const mbedtls_x509_crt *crt;
242632b31808SJens Wiklander     int authmode;
242732b31808SJens Wiklander 
242832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate request"));
242932b31808SJens Wiklander 
243032b31808SJens Wiklander     ssl->state++;
243132b31808SJens Wiklander 
243232b31808SJens Wiklander #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
243332b31808SJens Wiklander     if (ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET) {
243432b31808SJens Wiklander         authmode = ssl->handshake->sni_authmode;
243532b31808SJens Wiklander     } else
243632b31808SJens Wiklander #endif
243732b31808SJens Wiklander     authmode = ssl->conf->authmode;
243832b31808SJens Wiklander 
243932b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info) ||
244032b31808SJens Wiklander         authmode == MBEDTLS_SSL_VERIFY_NONE) {
244132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate request"));
244232b31808SJens Wiklander         return 0;
244332b31808SJens Wiklander     }
244432b31808SJens Wiklander 
244532b31808SJens Wiklander     /*
244632b31808SJens Wiklander      *     0  .   0   handshake type
244732b31808SJens Wiklander      *     1  .   3   handshake length
244832b31808SJens Wiklander      *     4  .   4   cert type count
244932b31808SJens Wiklander      *     5  .. m-1  cert types
245032b31808SJens Wiklander      *     m  .. m+1  sig alg length (TLS 1.2 only)
245132b31808SJens Wiklander      *    m+1 .. n-1  SignatureAndHashAlgorithms (TLS 1.2 only)
245232b31808SJens Wiklander      *     n  .. n+1  length of all DNs
245332b31808SJens Wiklander      *    n+2 .. n+3  length of DN 1
245432b31808SJens Wiklander      *    n+4 .. ...  Distinguished Name #1
245532b31808SJens Wiklander      *    ... .. ...  length of DN 2, etc.
245632b31808SJens Wiklander      */
245732b31808SJens Wiklander     buf = ssl->out_msg;
245832b31808SJens Wiklander     p = buf + 4;
245932b31808SJens Wiklander 
246032b31808SJens Wiklander     /*
246132b31808SJens Wiklander      * Supported certificate types
246232b31808SJens Wiklander      *
246332b31808SJens Wiklander      *     ClientCertificateType certificate_types<1..2^8-1>;
246432b31808SJens Wiklander      *     enum { (255) } ClientCertificateType;
246532b31808SJens Wiklander      */
246632b31808SJens Wiklander     ct_len = 0;
246732b31808SJens Wiklander 
246832b31808SJens Wiklander #if defined(MBEDTLS_RSA_C)
246932b31808SJens Wiklander     p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN;
247032b31808SJens Wiklander #endif
2471b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
247232b31808SJens Wiklander     p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN;
247332b31808SJens Wiklander #endif
247432b31808SJens Wiklander 
247532b31808SJens Wiklander     p[0] = (unsigned char) ct_len++;
247632b31808SJens Wiklander     p += ct_len;
247732b31808SJens Wiklander 
247832b31808SJens Wiklander     sa_len = 0;
247932b31808SJens Wiklander 
248032b31808SJens Wiklander     /*
248132b31808SJens Wiklander      * Add signature_algorithms for verify (TLS 1.2)
248232b31808SJens Wiklander      *
248332b31808SJens Wiklander      *     SignatureAndHashAlgorithm supported_signature_algorithms<2..2^16-2>;
248432b31808SJens Wiklander      *
248532b31808SJens Wiklander      *     struct {
248632b31808SJens Wiklander      *           HashAlgorithm hash;
248732b31808SJens Wiklander      *           SignatureAlgorithm signature;
248832b31808SJens Wiklander      *     } SignatureAndHashAlgorithm;
248932b31808SJens Wiklander      *
249032b31808SJens Wiklander      *     enum { (255) } HashAlgorithm;
249132b31808SJens Wiklander      *     enum { (255) } SignatureAlgorithm;
249232b31808SJens Wiklander      */
249332b31808SJens Wiklander     const uint16_t *sig_alg = mbedtls_ssl_get_sig_algs(ssl);
249432b31808SJens Wiklander     if (sig_alg == NULL) {
249532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_CONFIG;
249632b31808SJens Wiklander     }
249732b31808SJens Wiklander 
249832b31808SJens Wiklander     for (; *sig_alg != MBEDTLS_TLS_SIG_NONE; sig_alg++) {
249932b31808SJens Wiklander         unsigned char hash = MBEDTLS_BYTE_1(*sig_alg);
250032b31808SJens Wiklander 
250132b31808SJens Wiklander         if (mbedtls_ssl_set_calc_verify_md(ssl, hash)) {
250232b31808SJens Wiklander             continue;
250332b31808SJens Wiklander         }
250432b31808SJens Wiklander         if (!mbedtls_ssl_sig_alg_is_supported(ssl, *sig_alg)) {
250532b31808SJens Wiklander             continue;
250632b31808SJens Wiklander         }
250732b31808SJens Wiklander 
250832b31808SJens Wiklander         /* Write elements at offsets starting from 1 (offset 0 is for the
250932b31808SJens Wiklander          * length). Thus the offset of each element is the length of the
251032b31808SJens Wiklander          * partial list including that element. */
251132b31808SJens Wiklander         sa_len += 2;
251232b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(*sig_alg, p, sa_len);
251332b31808SJens Wiklander 
251432b31808SJens Wiklander     }
251532b31808SJens Wiklander 
251632b31808SJens Wiklander     /* Fill in list length. */
251732b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(sa_len, p, 0);
251832b31808SJens Wiklander     sa_len += 2;
251932b31808SJens Wiklander     p += sa_len;
252032b31808SJens Wiklander 
252132b31808SJens Wiklander     /*
252232b31808SJens Wiklander      * DistinguishedName certificate_authorities<0..2^16-1>;
252332b31808SJens Wiklander      * opaque DistinguishedName<1..2^16-1>;
252432b31808SJens Wiklander      */
252532b31808SJens Wiklander     p += 2;
252632b31808SJens Wiklander 
252732b31808SJens Wiklander     total_dn_size = 0;
252832b31808SJens Wiklander 
252932b31808SJens Wiklander     if (ssl->conf->cert_req_ca_list ==  MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED) {
253032b31808SJens Wiklander         /* NOTE: If trusted certificates are provisioned
253132b31808SJens Wiklander          *       via a CA callback (configured through
253232b31808SJens Wiklander          *       `mbedtls_ssl_conf_ca_cb()`, then the
253332b31808SJens Wiklander          *       CertificateRequest is currently left empty. */
253432b31808SJens Wiklander 
253532b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
253632b31808SJens Wiklander #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
253732b31808SJens Wiklander         if (ssl->handshake->dn_hints != NULL) {
253832b31808SJens Wiklander             crt = ssl->handshake->dn_hints;
253932b31808SJens Wiklander         } else
254032b31808SJens Wiklander #endif
254132b31808SJens Wiklander         if (ssl->conf->dn_hints != NULL) {
254232b31808SJens Wiklander             crt = ssl->conf->dn_hints;
254332b31808SJens Wiklander         } else
254432b31808SJens Wiklander #endif
254532b31808SJens Wiklander #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
254632b31808SJens Wiklander         if (ssl->handshake->sni_ca_chain != NULL) {
254732b31808SJens Wiklander             crt = ssl->handshake->sni_ca_chain;
254832b31808SJens Wiklander         } else
254932b31808SJens Wiklander #endif
255032b31808SJens Wiklander         crt = ssl->conf->ca_chain;
255132b31808SJens Wiklander 
255232b31808SJens Wiklander         while (crt != NULL && crt->version != 0) {
255332b31808SJens Wiklander             /* It follows from RFC 5280 A.1 that this length
255432b31808SJens Wiklander              * can be represented in at most 11 bits. */
255532b31808SJens Wiklander             dn_size = (uint16_t) crt->subject_raw.len;
255632b31808SJens Wiklander 
255732b31808SJens Wiklander             if (end < p || (size_t) (end - p) < 2 + (size_t) dn_size) {
255832b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1, ("skipping CAs: buffer too short"));
255932b31808SJens Wiklander                 break;
256032b31808SJens Wiklander             }
256132b31808SJens Wiklander 
256232b31808SJens Wiklander             MBEDTLS_PUT_UINT16_BE(dn_size, p, 0);
256332b31808SJens Wiklander             p += 2;
256432b31808SJens Wiklander             memcpy(p, crt->subject_raw.p, dn_size);
256532b31808SJens Wiklander             p += dn_size;
256632b31808SJens Wiklander 
256732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_BUF(3, "requested DN", p - dn_size, dn_size);
256832b31808SJens Wiklander 
2569b0563631STom Van Eyck             total_dn_size += (unsigned short) (2 + dn_size);
257032b31808SJens Wiklander             crt = crt->next;
257132b31808SJens Wiklander         }
257232b31808SJens Wiklander     }
257332b31808SJens Wiklander 
2574b0563631STom Van Eyck     ssl->out_msglen  = (size_t) (p - buf);
257532b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
257632b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_CERTIFICATE_REQUEST;
257732b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(total_dn_size, ssl->out_msg, 4 + ct_len + sa_len);
257832b31808SJens Wiklander 
257932b31808SJens Wiklander     ret = mbedtls_ssl_write_handshake_msg(ssl);
258032b31808SJens Wiklander 
258132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write certificate request"));
258232b31808SJens Wiklander 
258332b31808SJens Wiklander     return ret;
258432b31808SJens Wiklander }
258532b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
258632b31808SJens Wiklander 
2587b0563631STom Van Eyck #if (defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
258832b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED))
2589b0563631STom Van Eyck #if defined(MBEDTLS_USE_PSA_CRYPTO)
259032b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
259132b31808SJens Wiklander static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
259232b31808SJens Wiklander {
259332b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
259432b31808SJens Wiklander     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
259532b31808SJens Wiklander     mbedtls_pk_context *pk;
2596b0563631STom Van Eyck     mbedtls_pk_type_t pk_type;
2597b0563631STom Van Eyck     psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
2598b0563631STom Van Eyck     unsigned char buf[PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
2599b0563631STom Van Eyck     size_t key_len;
2600b0563631STom Van Eyck #if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
2601b0563631STom Van Eyck     uint16_t tls_id = 0;
2602b0563631STom Van Eyck     psa_key_type_t key_type = PSA_KEY_TYPE_NONE;
2603b0563631STom Van Eyck     mbedtls_ecp_group_id grp_id;
260432b31808SJens Wiklander     mbedtls_ecp_keypair *key;
2605b0563631STom Van Eyck #endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
260632b31808SJens Wiklander 
260732b31808SJens Wiklander     pk = mbedtls_ssl_own_key(ssl);
260832b31808SJens Wiklander 
260932b31808SJens Wiklander     if (pk == NULL) {
261032b31808SJens Wiklander         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
261132b31808SJens Wiklander     }
261232b31808SJens Wiklander 
2613b0563631STom Van Eyck     pk_type = mbedtls_pk_get_type(pk);
2614b0563631STom Van Eyck 
2615b0563631STom Van Eyck     switch (pk_type) {
261632b31808SJens Wiklander         case MBEDTLS_PK_OPAQUE:
2617b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
2618b0563631STom Van Eyck         case MBEDTLS_PK_ECKEY:
2619b0563631STom Van Eyck         case MBEDTLS_PK_ECKEY_DH:
2620b0563631STom Van Eyck         case MBEDTLS_PK_ECDSA:
2621b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
262232b31808SJens Wiklander             if (!mbedtls_pk_can_do(pk, MBEDTLS_PK_ECKEY)) {
262332b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
262432b31808SJens Wiklander             }
262532b31808SJens Wiklander 
2626b0563631STom Van Eyck             /* Get the attributes of the key previously parsed by PK module in
2627b0563631STom Van Eyck              * order to extract its type and length (in bits). */
2628b0563631STom Van Eyck             status = psa_get_key_attributes(pk->priv_id, &key_attributes);
262932b31808SJens Wiklander             if (status != PSA_SUCCESS) {
2630b0563631STom Van Eyck                 ret = PSA_TO_MBEDTLS_ERR(status);
2631b0563631STom Van Eyck                 goto exit;
2632b0563631STom Van Eyck             }
2633b0563631STom Van Eyck             ssl->handshake->xxdh_psa_type = psa_get_key_type(&key_attributes);
2634b0563631STom Van Eyck             ssl->handshake->xxdh_psa_bits = psa_get_key_bits(&key_attributes);
2635b0563631STom Van Eyck 
2636*cb034002SJerome Forissier #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
2637*cb034002SJerome Forissier             if (pk_type != MBEDTLS_PK_OPAQUE) {
2638b0563631STom Van Eyck                 /* PK_ECKEY[_DH] and PK_ECDSA instead as parsed from the PK
2639b0563631STom Van Eyck                  * module and only have ECDSA capabilities. Since we need
2640b0563631STom Van Eyck                  * them for ECDH later, we export and then re-import them with
2641b0563631STom Van Eyck                  * proper flags and algorithm. Of course We also set key's type
2642b0563631STom Van Eyck                  * and bits that we just got above. */
2643b0563631STom Van Eyck                 key_attributes = psa_key_attributes_init();
2644b0563631STom Van Eyck                 psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
2645b0563631STom Van Eyck                 psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
2646b0563631STom Van Eyck                 psa_set_key_type(&key_attributes,
2647b0563631STom Van Eyck                                  PSA_KEY_TYPE_ECC_KEY_PAIR(ssl->handshake->xxdh_psa_type));
2648b0563631STom Van Eyck                 psa_set_key_bits(&key_attributes, ssl->handshake->xxdh_psa_bits);
2649b0563631STom Van Eyck 
2650b0563631STom Van Eyck                 status = psa_export_key(pk->priv_id, buf, sizeof(buf), &key_len);
2651b0563631STom Van Eyck                 if (status != PSA_SUCCESS) {
2652b0563631STom Van Eyck                     ret = PSA_TO_MBEDTLS_ERR(status);
2653b0563631STom Van Eyck                     goto exit;
2654b0563631STom Van Eyck                 }
2655b0563631STom Van Eyck                 status = psa_import_key(&key_attributes, buf, key_len,
2656b0563631STom Van Eyck                                         &ssl->handshake->xxdh_psa_privkey);
2657b0563631STom Van Eyck                 if (status != PSA_SUCCESS) {
2658b0563631STom Van Eyck                     ret = PSA_TO_MBEDTLS_ERR(status);
2659b0563631STom Van Eyck                     goto exit;
266032b31808SJens Wiklander                 }
266132b31808SJens Wiklander 
2662b0563631STom Van Eyck                 /* Set this key as owned by the TLS library: it will be its duty
2663b0563631STom Van Eyck                  * to clear it exit. */
2664b0563631STom Van Eyck                 ssl->handshake->xxdh_psa_privkey_is_external = 0;
266532b31808SJens Wiklander 
266632b31808SJens Wiklander                 ret = 0;
266732b31808SJens Wiklander                 break;
2668*cb034002SJerome Forissier             }
2669*cb034002SJerome Forissier #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
2670*cb034002SJerome Forissier 
2671*cb034002SJerome Forissier             /* Opaque key is created by the user (externally from Mbed TLS)
2672*cb034002SJerome Forissier              * so we assume it already has the right algorithm and flags
2673*cb034002SJerome Forissier              * set. Just copy its ID as reference. */
2674*cb034002SJerome Forissier             ssl->handshake->xxdh_psa_privkey = pk->priv_id;
2675*cb034002SJerome Forissier             ssl->handshake->xxdh_psa_privkey_is_external = 1;
2676*cb034002SJerome Forissier             ret = 0;
2677*cb034002SJerome Forissier             break;
2678*cb034002SJerome Forissier 
2679b0563631STom Van Eyck #if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
268032b31808SJens Wiklander         case MBEDTLS_PK_ECKEY:
268132b31808SJens Wiklander         case MBEDTLS_PK_ECKEY_DH:
268232b31808SJens Wiklander         case MBEDTLS_PK_ECDSA:
2683b0563631STom Van Eyck             key = mbedtls_pk_ec_rw(*pk);
2684b0563631STom Van Eyck             grp_id = mbedtls_pk_get_ec_group_id(pk);
2685b0563631STom Van Eyck             if (grp_id == MBEDTLS_ECP_DP_NONE) {
268632b31808SJens Wiklander                 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
268732b31808SJens Wiklander             }
2688b0563631STom Van Eyck             tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id);
268932b31808SJens Wiklander             if (tls_id == 0) {
269032b31808SJens Wiklander                 /* This elliptic curve is not supported */
269132b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
269232b31808SJens Wiklander             }
269332b31808SJens Wiklander 
269432b31808SJens Wiklander             /* If the above conversion to TLS ID was fine, then also this one will
269532b31808SJens Wiklander                be, so there is no need to check the return value here */
2696b0563631STom Van Eyck             mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id, &key_type,
2697b0563631STom Van Eyck                                                        &ssl->handshake->xxdh_psa_bits);
269832b31808SJens Wiklander 
2699b0563631STom Van Eyck             ssl->handshake->xxdh_psa_type = key_type;
270032b31808SJens Wiklander 
270132b31808SJens Wiklander             key_attributes = psa_key_attributes_init();
270232b31808SJens Wiklander             psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
270332b31808SJens Wiklander             psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
270432b31808SJens Wiklander             psa_set_key_type(&key_attributes,
2705b0563631STom Van Eyck                              PSA_KEY_TYPE_ECC_KEY_PAIR(ssl->handshake->xxdh_psa_type));
2706b0563631STom Van Eyck             psa_set_key_bits(&key_attributes, ssl->handshake->xxdh_psa_bits);
270732b31808SJens Wiklander 
2708b0563631STom Van Eyck             ret = mbedtls_ecp_write_key_ext(key, &key_len, buf, sizeof(buf));
270932b31808SJens Wiklander             if (ret != 0) {
2710b0563631STom Van Eyck                 mbedtls_platform_zeroize(buf, sizeof(buf));
2711b0563631STom Van Eyck                 break;
271232b31808SJens Wiklander             }
271332b31808SJens Wiklander 
271432b31808SJens Wiklander             status = psa_import_key(&key_attributes, buf, key_len,
2715b0563631STom Van Eyck                                     &ssl->handshake->xxdh_psa_privkey);
271632b31808SJens Wiklander             if (status != PSA_SUCCESS) {
271732b31808SJens Wiklander                 ret = PSA_TO_MBEDTLS_ERR(status);
2718b0563631STom Van Eyck                 mbedtls_platform_zeroize(buf, sizeof(buf));
2719b0563631STom Van Eyck                 break;
272032b31808SJens Wiklander             }
272132b31808SJens Wiklander 
2722b0563631STom Van Eyck             mbedtls_platform_zeroize(buf, sizeof(buf));
272332b31808SJens Wiklander             ret = 0;
272432b31808SJens Wiklander             break;
2725b0563631STom Van Eyck #endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
272632b31808SJens Wiklander         default:
272732b31808SJens Wiklander             ret = MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
272832b31808SJens Wiklander     }
272932b31808SJens Wiklander 
2730b0563631STom Van Eyck exit:
2731b0563631STom Van Eyck     psa_reset_key_attributes(&key_attributes);
273232b31808SJens Wiklander     mbedtls_platform_zeroize(buf, sizeof(buf));
273332b31808SJens Wiklander 
273432b31808SJens Wiklander     return ret;
273532b31808SJens Wiklander }
2736b0563631STom Van Eyck #else /* MBEDTLS_USE_PSA_CRYPTO */
273732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
273832b31808SJens Wiklander static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
273932b31808SJens Wiklander {
274032b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
274132b31808SJens Wiklander 
274232b31808SJens Wiklander     const mbedtls_pk_context *private_key = mbedtls_ssl_own_key(ssl);
274332b31808SJens Wiklander     if (private_key == NULL) {
274432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got no server private key"));
274532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED;
274632b31808SJens Wiklander     }
274732b31808SJens Wiklander 
274832b31808SJens Wiklander     if (!mbedtls_pk_can_do(private_key, MBEDTLS_PK_ECKEY)) {
274932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("server key not ECDH capable"));
275032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
275132b31808SJens Wiklander     }
275232b31808SJens Wiklander 
275332b31808SJens Wiklander     if ((ret = mbedtls_ecdh_get_params(&ssl->handshake->ecdh_ctx,
2754b0563631STom Van Eyck                                        mbedtls_pk_ec_ro(*mbedtls_ssl_own_key(ssl)),
275532b31808SJens Wiklander                                        MBEDTLS_ECDH_OURS)) != 0) {
275632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_get_params"), ret);
275732b31808SJens Wiklander         return ret;
275832b31808SJens Wiklander     }
275932b31808SJens Wiklander 
276032b31808SJens Wiklander     return 0;
276132b31808SJens Wiklander }
2762b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */
276332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
276432b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
276532b31808SJens Wiklander 
276632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \
276732b31808SJens Wiklander     defined(MBEDTLS_SSL_ASYNC_PRIVATE)
276832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
276932b31808SJens Wiklander static int ssl_resume_server_key_exchange(mbedtls_ssl_context *ssl,
277032b31808SJens Wiklander                                           size_t *signature_len)
277132b31808SJens Wiklander {
277232b31808SJens Wiklander     /* Append the signature to ssl->out_msg, leaving 2 bytes for the
277332b31808SJens Wiklander      * signature length which will be added in ssl_write_server_key_exchange
277432b31808SJens Wiklander      * after the call to ssl_prepare_server_key_exchange.
277532b31808SJens Wiklander      * ssl_write_server_key_exchange also takes care of incrementing
277632b31808SJens Wiklander      * ssl->out_msglen. */
277732b31808SJens Wiklander     unsigned char *sig_start = ssl->out_msg + ssl->out_msglen + 2;
277832b31808SJens Wiklander     size_t sig_max_len = (ssl->out_buf + MBEDTLS_SSL_OUT_CONTENT_LEN
277932b31808SJens Wiklander                           - sig_start);
278032b31808SJens Wiklander     int ret = ssl->conf->f_async_resume(ssl,
278132b31808SJens Wiklander                                         sig_start, signature_len, sig_max_len);
278232b31808SJens Wiklander     if (ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
278332b31808SJens Wiklander         ssl->handshake->async_in_progress = 0;
278432b31808SJens Wiklander         mbedtls_ssl_set_async_operation_data(ssl, NULL);
278532b31808SJens Wiklander     }
278632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_RET(2, "ssl_resume_server_key_exchange", ret);
278732b31808SJens Wiklander     return ret;
278832b31808SJens Wiklander }
278932b31808SJens Wiklander #endif /* defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) &&
279032b31808SJens Wiklander           defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
279132b31808SJens Wiklander 
279232b31808SJens Wiklander /* Prepare the ServerKeyExchange message, up to and including
279332b31808SJens Wiklander  * calculating the signature if any, but excluding formatting the
279432b31808SJens Wiklander  * signature and sending the message. */
279532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
279632b31808SJens Wiklander static int ssl_prepare_server_key_exchange(mbedtls_ssl_context *ssl,
279732b31808SJens Wiklander                                            size_t *signature_len)
279832b31808SJens Wiklander {
279932b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
280032b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
280132b31808SJens Wiklander 
280232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED)
280332b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
280432b31808SJens Wiklander     unsigned char *dig_signed = NULL;
280532b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
280632b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED */
280732b31808SJens Wiklander 
280832b31808SJens Wiklander     (void) ciphersuite_info; /* unused in some configurations */
280932b31808SJens Wiklander #if !defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
281032b31808SJens Wiklander     (void) signature_len;
281132b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
281232b31808SJens Wiklander 
281332b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
281432b31808SJens Wiklander #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
2815b0563631STom Van Eyck     size_t out_buf_len = ssl->out_buf_len - (size_t) (ssl->out_msg - ssl->out_buf);
281632b31808SJens Wiklander #else
2817b0563631STom Van Eyck     size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - (size_t) (ssl->out_msg - ssl->out_buf);
281832b31808SJens Wiklander #endif
281932b31808SJens Wiklander #endif
282032b31808SJens Wiklander 
282132b31808SJens Wiklander     ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */
282232b31808SJens Wiklander 
282332b31808SJens Wiklander     /*
282432b31808SJens Wiklander      *
282532b31808SJens Wiklander      * Part 1: Provide key exchange parameters for chosen ciphersuite.
282632b31808SJens Wiklander      *
282732b31808SJens Wiklander      */
282832b31808SJens Wiklander 
282932b31808SJens Wiklander     /*
283032b31808SJens Wiklander      * - ECJPAKE key exchanges
283132b31808SJens Wiklander      */
283232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
283332b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
283432b31808SJens Wiklander         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
283532b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
283632b31808SJens Wiklander         unsigned char *out_p = ssl->out_msg + ssl->out_msglen;
283732b31808SJens Wiklander         unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN -
283832b31808SJens Wiklander                                ssl->out_msglen;
283932b31808SJens Wiklander         size_t output_offset = 0;
284032b31808SJens Wiklander         size_t output_len = 0;
284132b31808SJens Wiklander 
284232b31808SJens Wiklander         /*
284332b31808SJens Wiklander          * The first 3 bytes are:
284432b31808SJens Wiklander          * [0] MBEDTLS_ECP_TLS_NAMED_CURVE
284532b31808SJens Wiklander          * [1, 2] elliptic curve's TLS ID
284632b31808SJens Wiklander          *
284732b31808SJens Wiklander          * However since we only support secp256r1 for now, we hardcode its
284832b31808SJens Wiklander          * TLS ID here
284932b31808SJens Wiklander          */
285032b31808SJens Wiklander         uint16_t tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(
285132b31808SJens Wiklander             MBEDTLS_ECP_DP_SECP256R1);
285232b31808SJens Wiklander         if (tls_id == 0) {
285332b31808SJens Wiklander             return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
285432b31808SJens Wiklander         }
285532b31808SJens Wiklander         *out_p = MBEDTLS_ECP_TLS_NAMED_CURVE;
285632b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(tls_id, out_p, 1);
285732b31808SJens Wiklander         output_offset += 3;
285832b31808SJens Wiklander 
285932b31808SJens Wiklander         ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx,
286032b31808SJens Wiklander                                               out_p + output_offset,
286132b31808SJens Wiklander                                               end_p - out_p - output_offset, &output_len,
286232b31808SJens Wiklander                                               MBEDTLS_ECJPAKE_ROUND_TWO);
286332b31808SJens Wiklander         if (ret != 0) {
286432b31808SJens Wiklander             psa_destroy_key(ssl->handshake->psa_pake_password);
286532b31808SJens Wiklander             psa_pake_abort(&ssl->handshake->psa_pake_ctx);
286632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret);
286732b31808SJens Wiklander             return ret;
286832b31808SJens Wiklander         }
286932b31808SJens Wiklander 
287032b31808SJens Wiklander         output_offset += output_len;
287132b31808SJens Wiklander         ssl->out_msglen += output_offset;
287232b31808SJens Wiklander #else
287332b31808SJens Wiklander         size_t len = 0;
287432b31808SJens Wiklander 
287532b31808SJens Wiklander         ret = mbedtls_ecjpake_write_round_two(
287632b31808SJens Wiklander             &ssl->handshake->ecjpake_ctx,
287732b31808SJens Wiklander             ssl->out_msg + ssl->out_msglen,
287832b31808SJens Wiklander             MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, &len,
287932b31808SJens Wiklander             ssl->conf->f_rng, ssl->conf->p_rng);
288032b31808SJens Wiklander         if (ret != 0) {
288132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_two", ret);
288232b31808SJens Wiklander             return ret;
288332b31808SJens Wiklander         }
288432b31808SJens Wiklander 
288532b31808SJens Wiklander         ssl->out_msglen += len;
288632b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
288732b31808SJens Wiklander     }
288832b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
288932b31808SJens Wiklander 
289032b31808SJens Wiklander     /*
289132b31808SJens Wiklander      * For (EC)DHE key exchanges with PSK, parameters are prefixed by support
289232b31808SJens Wiklander      * identity hint (RFC 4279, Sec. 3). Until someone needs this feature,
289332b31808SJens Wiklander      * we use empty support identity hints here.
289432b31808SJens Wiklander      **/
289532b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)   || \
289632b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
289732b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
289832b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) {
289932b31808SJens Wiklander         ssl->out_msg[ssl->out_msglen++] = 0x00;
290032b31808SJens Wiklander         ssl->out_msg[ssl->out_msglen++] = 0x00;
290132b31808SJens Wiklander     }
290232b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED ||
290332b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
290432b31808SJens Wiklander 
290532b31808SJens Wiklander     /*
290632b31808SJens Wiklander      * - DHE key exchanges
290732b31808SJens Wiklander      */
290832b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED)
290932b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_uses_dhe(ciphersuite_info)) {
291032b31808SJens Wiklander         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
291132b31808SJens Wiklander         size_t len = 0;
291232b31808SJens Wiklander 
291332b31808SJens Wiklander         if (ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL) {
291432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("no DH parameters set"));
291532b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
291632b31808SJens Wiklander         }
291732b31808SJens Wiklander 
291832b31808SJens Wiklander         /*
291932b31808SJens Wiklander          * Ephemeral DH parameters:
292032b31808SJens Wiklander          *
292132b31808SJens Wiklander          * struct {
292232b31808SJens Wiklander          *     opaque dh_p<1..2^16-1>;
292332b31808SJens Wiklander          *     opaque dh_g<1..2^16-1>;
292432b31808SJens Wiklander          *     opaque dh_Ys<1..2^16-1>;
292532b31808SJens Wiklander          * } ServerDHParams;
292632b31808SJens Wiklander          */
292732b31808SJens Wiklander         if ((ret = mbedtls_dhm_set_group(&ssl->handshake->dhm_ctx,
292832b31808SJens Wiklander                                          &ssl->conf->dhm_P,
292932b31808SJens Wiklander                                          &ssl->conf->dhm_G)) != 0) {
293032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_set_group", ret);
293132b31808SJens Wiklander             return ret;
293232b31808SJens Wiklander         }
293332b31808SJens Wiklander 
293432b31808SJens Wiklander         if ((ret = mbedtls_dhm_make_params(
293532b31808SJens Wiklander                  &ssl->handshake->dhm_ctx,
293632b31808SJens Wiklander                  (int) mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx),
293732b31808SJens Wiklander                  ssl->out_msg + ssl->out_msglen, &len,
293832b31808SJens Wiklander                  ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
293932b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_make_params", ret);
294032b31808SJens Wiklander             return ret;
294132b31808SJens Wiklander         }
294232b31808SJens Wiklander 
294332b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
294432b31808SJens Wiklander         dig_signed = ssl->out_msg + ssl->out_msglen;
294532b31808SJens Wiklander #endif
294632b31808SJens Wiklander 
294732b31808SJens Wiklander         ssl->out_msglen += len;
294832b31808SJens Wiklander 
294932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: X ", &ssl->handshake->dhm_ctx.X);
295032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: P ", &ssl->handshake->dhm_ctx.P);
295132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: G ", &ssl->handshake->dhm_ctx.G);
295232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GX", &ssl->handshake->dhm_ctx.GX);
295332b31808SJens Wiklander     }
295432b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED */
295532b31808SJens Wiklander 
295632b31808SJens Wiklander     /*
295732b31808SJens Wiklander      * - ECDHE key exchanges
295832b31808SJens Wiklander      */
295932b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED)
296032b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_uses_ecdhe(ciphersuite_info)) {
296132b31808SJens Wiklander         /*
296232b31808SJens Wiklander          * Ephemeral ECDH parameters:
296332b31808SJens Wiklander          *
296432b31808SJens Wiklander          * struct {
296532b31808SJens Wiklander          *     ECParameters curve_params;
296632b31808SJens Wiklander          *     ECPoint      public;
296732b31808SJens Wiklander          * } ServerECDHParams;
296832b31808SJens Wiklander          */
296932b31808SJens Wiklander         uint16_t *curr_tls_id = ssl->handshake->curves_tls_id;
297032b31808SJens Wiklander         const uint16_t *group_list = mbedtls_ssl_get_groups(ssl);
297132b31808SJens Wiklander         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
297232b31808SJens Wiklander         size_t len = 0;
297332b31808SJens Wiklander 
297432b31808SJens Wiklander         /* Match our preference list against the offered curves */
297532b31808SJens Wiklander         if ((group_list == NULL) || (curr_tls_id == NULL)) {
297632b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BAD_CONFIG;
297732b31808SJens Wiklander         }
297832b31808SJens Wiklander         for (; *group_list != 0; group_list++) {
297932b31808SJens Wiklander             for (curr_tls_id = ssl->handshake->curves_tls_id;
298032b31808SJens Wiklander                  *curr_tls_id != 0; curr_tls_id++) {
298132b31808SJens Wiklander                 if (*curr_tls_id == *group_list) {
298232b31808SJens Wiklander                     goto curve_matching_done;
298332b31808SJens Wiklander                 }
298432b31808SJens Wiklander             }
298532b31808SJens Wiklander         }
298632b31808SJens Wiklander 
298732b31808SJens Wiklander curve_matching_done:
298832b31808SJens Wiklander         if (*curr_tls_id == 0) {
298932b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("no matching curve for ECDHE"));
299032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
299132b31808SJens Wiklander         }
299232b31808SJens Wiklander 
299332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("ECDHE curve: %s",
299432b31808SJens Wiklander                                   mbedtls_ssl_get_curve_name_from_tls_id(*curr_tls_id)));
299532b31808SJens Wiklander 
299632b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
299732b31808SJens Wiklander         psa_status_t status = PSA_ERROR_GENERIC_ERROR;
299832b31808SJens Wiklander         psa_key_attributes_t key_attributes;
299932b31808SJens Wiklander         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
300032b31808SJens Wiklander         uint8_t *p = ssl->out_msg + ssl->out_msglen;
300132b31808SJens Wiklander         const size_t header_size = 4; // curve_type(1), namedcurve(2),
300232b31808SJens Wiklander                                       // data length(1)
300332b31808SJens Wiklander         const size_t data_length_size = 1;
3004b0563631STom Van Eyck         psa_key_type_t key_type = PSA_KEY_TYPE_NONE;
300532b31808SJens Wiklander         size_t ec_bits = 0;
300632b31808SJens Wiklander 
300732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("Perform PSA-based ECDH computation."));
300832b31808SJens Wiklander 
300932b31808SJens Wiklander         /* Convert EC's TLS ID to PSA key type. */
301032b31808SJens Wiklander         if (mbedtls_ssl_get_psa_curve_info_from_tls_id(*curr_tls_id,
3011b0563631STom Van Eyck                                                        &key_type,
301232b31808SJens Wiklander                                                        &ec_bits) == PSA_ERROR_NOT_SUPPORTED) {
301332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid ecc group parse."));
301432b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
301532b31808SJens Wiklander         }
3016b0563631STom Van Eyck         handshake->xxdh_psa_type = key_type;
3017b0563631STom Van Eyck         handshake->xxdh_psa_bits = ec_bits;
301832b31808SJens Wiklander 
301932b31808SJens Wiklander         key_attributes = psa_key_attributes_init();
302032b31808SJens Wiklander         psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
302132b31808SJens Wiklander         psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
3022b0563631STom Van Eyck         psa_set_key_type(&key_attributes, handshake->xxdh_psa_type);
3023b0563631STom Van Eyck         psa_set_key_bits(&key_attributes, handshake->xxdh_psa_bits);
302432b31808SJens Wiklander 
302532b31808SJens Wiklander         /*
302632b31808SJens Wiklander          * ECParameters curve_params
302732b31808SJens Wiklander          *
302832b31808SJens Wiklander          * First byte is curve_type, always named_curve
302932b31808SJens Wiklander          */
303032b31808SJens Wiklander         *p++ = MBEDTLS_ECP_TLS_NAMED_CURVE;
303132b31808SJens Wiklander 
303232b31808SJens Wiklander         /*
303332b31808SJens Wiklander          * Next two bytes are the namedcurve value
303432b31808SJens Wiklander          */
303532b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(*curr_tls_id, p, 0);
303632b31808SJens Wiklander         p += 2;
303732b31808SJens Wiklander 
303832b31808SJens Wiklander         /* Generate ECDH private key. */
303932b31808SJens Wiklander         status = psa_generate_key(&key_attributes,
3040b0563631STom Van Eyck                                   &handshake->xxdh_psa_privkey);
304132b31808SJens Wiklander         if (status != PSA_SUCCESS) {
304232b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
304332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_generate_key", ret);
304432b31808SJens Wiklander             return ret;
304532b31808SJens Wiklander         }
304632b31808SJens Wiklander 
304732b31808SJens Wiklander         /*
304832b31808SJens Wiklander          * ECPoint  public
304932b31808SJens Wiklander          *
305032b31808SJens Wiklander          * First byte is data length.
305132b31808SJens Wiklander          * It will be filled later. p holds now the data length location.
305232b31808SJens Wiklander          */
305332b31808SJens Wiklander 
305432b31808SJens Wiklander         /* Export the public part of the ECDH private key from PSA.
305532b31808SJens Wiklander          * Make one byte space for the length.
305632b31808SJens Wiklander          */
305732b31808SJens Wiklander         unsigned char *own_pubkey = p + data_length_size;
305832b31808SJens Wiklander 
305932b31808SJens Wiklander         size_t own_pubkey_max_len = (size_t) (MBEDTLS_SSL_OUT_CONTENT_LEN
306032b31808SJens Wiklander                                               - (own_pubkey - ssl->out_msg));
306132b31808SJens Wiklander 
3062b0563631STom Van Eyck         status = psa_export_public_key(handshake->xxdh_psa_privkey,
306332b31808SJens Wiklander                                        own_pubkey, own_pubkey_max_len,
306432b31808SJens Wiklander                                        &len);
306532b31808SJens Wiklander         if (status != PSA_SUCCESS) {
306632b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
306732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_export_public_key", ret);
3068b0563631STom Van Eyck             (void) psa_destroy_key(handshake->xxdh_psa_privkey);
3069b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
307032b31808SJens Wiklander             return ret;
307132b31808SJens Wiklander         }
307232b31808SJens Wiklander 
307332b31808SJens Wiklander         /* Store the length of the exported public key. */
307432b31808SJens Wiklander         *p = (uint8_t) len;
307532b31808SJens Wiklander 
307632b31808SJens Wiklander         /* Determine full message length. */
307732b31808SJens Wiklander         len += header_size;
307832b31808SJens Wiklander #else
307932b31808SJens Wiklander         mbedtls_ecp_group_id curr_grp_id =
308032b31808SJens Wiklander             mbedtls_ssl_get_ecp_group_id_from_tls_id(*curr_tls_id);
308132b31808SJens Wiklander 
308232b31808SJens Wiklander         if ((ret = mbedtls_ecdh_setup(&ssl->handshake->ecdh_ctx,
308332b31808SJens Wiklander                                       curr_grp_id)) != 0) {
308432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecp_group_load", ret);
308532b31808SJens Wiklander             return ret;
308632b31808SJens Wiklander         }
308732b31808SJens Wiklander 
308832b31808SJens Wiklander         if ((ret = mbedtls_ecdh_make_params(
308932b31808SJens Wiklander                  &ssl->handshake->ecdh_ctx, &len,
309032b31808SJens Wiklander                  ssl->out_msg + ssl->out_msglen,
309132b31808SJens Wiklander                  MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen,
309232b31808SJens Wiklander                  ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
309332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_make_params", ret);
309432b31808SJens Wiklander             return ret;
309532b31808SJens Wiklander         }
309632b31808SJens Wiklander 
309732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
309832b31808SJens Wiklander                                MBEDTLS_DEBUG_ECDH_Q);
309932b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
310032b31808SJens Wiklander 
310132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
310232b31808SJens Wiklander         dig_signed = ssl->out_msg + ssl->out_msglen;
310332b31808SJens Wiklander #endif
310432b31808SJens Wiklander 
310532b31808SJens Wiklander         ssl->out_msglen += len;
310632b31808SJens Wiklander     }
310732b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED */
310832b31808SJens Wiklander 
310932b31808SJens Wiklander     /*
311032b31808SJens Wiklander      *
311132b31808SJens Wiklander      * Part 2: For key exchanges involving the server signing the
311232b31808SJens Wiklander      *         exchange parameters, compute and add the signature here.
311332b31808SJens Wiklander      *
311432b31808SJens Wiklander      */
311532b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
311632b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_uses_server_signature(ciphersuite_info)) {
311732b31808SJens Wiklander         if (dig_signed == NULL) {
311832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
311932b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
312032b31808SJens Wiklander         }
312132b31808SJens Wiklander 
3122b0563631STom Van Eyck         size_t dig_signed_len = (size_t) (ssl->out_msg + ssl->out_msglen - dig_signed);
312332b31808SJens Wiklander         size_t hashlen = 0;
3124b0563631STom Van Eyck         unsigned char hash[MBEDTLS_MD_MAX_SIZE];
312532b31808SJens Wiklander 
312632b31808SJens Wiklander         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
312732b31808SJens Wiklander 
312832b31808SJens Wiklander         /*
312932b31808SJens Wiklander          * 2.1: Choose hash algorithm:
313032b31808SJens Wiklander          *      For TLS 1.2, obey signature-hash-algorithm extension
313132b31808SJens Wiklander          *      to choose appropriate hash.
313232b31808SJens Wiklander          */
313332b31808SJens Wiklander 
313432b31808SJens Wiklander         mbedtls_pk_type_t sig_alg =
313532b31808SJens Wiklander             mbedtls_ssl_get_ciphersuite_sig_pk_alg(ciphersuite_info);
313632b31808SJens Wiklander 
3137b0563631STom Van Eyck         unsigned char sig_hash =
3138b0563631STom Van Eyck             (unsigned char) mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
313932b31808SJens Wiklander                 ssl, mbedtls_ssl_sig_from_pk_alg(sig_alg));
314032b31808SJens Wiklander 
314132b31808SJens Wiklander         mbedtls_md_type_t md_alg = mbedtls_ssl_md_alg_from_hash(sig_hash);
314232b31808SJens Wiklander 
314332b31808SJens Wiklander         /*    For TLS 1.2, obey signature-hash-algorithm extension
314432b31808SJens Wiklander          *    (RFC 5246, Sec. 7.4.1.4.1). */
314532b31808SJens Wiklander         if (sig_alg == MBEDTLS_PK_NONE || md_alg == MBEDTLS_MD_NONE) {
314632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
314732b31808SJens Wiklander             /* (... because we choose a cipher suite
314832b31808SJens Wiklander              *      only if there is a matching hash.) */
314932b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
315032b31808SJens Wiklander         }
315132b31808SJens Wiklander 
315232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("pick hash algorithm %u for signing", (unsigned) md_alg));
315332b31808SJens Wiklander 
315432b31808SJens Wiklander         /*
315532b31808SJens Wiklander          * 2.2: Compute the hash to be signed
315632b31808SJens Wiklander          */
315732b31808SJens Wiklander         if (md_alg != MBEDTLS_MD_NONE) {
315832b31808SJens Wiklander             ret = mbedtls_ssl_get_key_exchange_md_tls1_2(ssl, hash, &hashlen,
315932b31808SJens Wiklander                                                          dig_signed,
316032b31808SJens Wiklander                                                          dig_signed_len,
316132b31808SJens Wiklander                                                          md_alg);
316232b31808SJens Wiklander             if (ret != 0) {
316332b31808SJens Wiklander                 return ret;
316432b31808SJens Wiklander             }
316532b31808SJens Wiklander         } else {
316632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
316732b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
316832b31808SJens Wiklander         }
316932b31808SJens Wiklander 
317032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "parameters hash", hash, hashlen);
317132b31808SJens Wiklander 
317232b31808SJens Wiklander         /*
317332b31808SJens Wiklander          * 2.3: Compute and add the signature
317432b31808SJens Wiklander          */
317532b31808SJens Wiklander         /*
317632b31808SJens Wiklander          * We need to specify signature and hash algorithm explicitly through
317732b31808SJens Wiklander          * a prefix to the signature.
317832b31808SJens Wiklander          *
317932b31808SJens Wiklander          * struct {
318032b31808SJens Wiklander          *    HashAlgorithm hash;
318132b31808SJens Wiklander          *    SignatureAlgorithm signature;
318232b31808SJens Wiklander          * } SignatureAndHashAlgorithm;
318332b31808SJens Wiklander          *
318432b31808SJens Wiklander          * struct {
318532b31808SJens Wiklander          *    SignatureAndHashAlgorithm algorithm;
318632b31808SJens Wiklander          *    opaque signature<0..2^16-1>;
318732b31808SJens Wiklander          * } DigitallySigned;
318832b31808SJens Wiklander          *
318932b31808SJens Wiklander          */
319032b31808SJens Wiklander 
319132b31808SJens Wiklander         ssl->out_msg[ssl->out_msglen++] = mbedtls_ssl_hash_from_md_alg(md_alg);
319232b31808SJens Wiklander         ssl->out_msg[ssl->out_msglen++] = mbedtls_ssl_sig_from_pk_alg(sig_alg);
319332b31808SJens Wiklander 
319432b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
319532b31808SJens Wiklander         if (ssl->conf->f_async_sign_start != NULL) {
319632b31808SJens Wiklander             ret = ssl->conf->f_async_sign_start(ssl,
319732b31808SJens Wiklander                                                 mbedtls_ssl_own_cert(ssl),
319832b31808SJens Wiklander                                                 md_alg, hash, hashlen);
319932b31808SJens Wiklander             switch (ret) {
320032b31808SJens Wiklander                 case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH:
320132b31808SJens Wiklander                     /* act as if f_async_sign was null */
320232b31808SJens Wiklander                     break;
320332b31808SJens Wiklander                 case 0:
320432b31808SJens Wiklander                     ssl->handshake->async_in_progress = 1;
320532b31808SJens Wiklander                     return ssl_resume_server_key_exchange(ssl, signature_len);
320632b31808SJens Wiklander                 case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
320732b31808SJens Wiklander                     ssl->handshake->async_in_progress = 1;
320832b31808SJens Wiklander                     return MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS;
320932b31808SJens Wiklander                 default:
321032b31808SJens Wiklander                     MBEDTLS_SSL_DEBUG_RET(1, "f_async_sign_start", ret);
321132b31808SJens Wiklander                     return ret;
321232b31808SJens Wiklander             }
321332b31808SJens Wiklander         }
321432b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
321532b31808SJens Wiklander 
321632b31808SJens Wiklander         if (mbedtls_ssl_own_key(ssl) == NULL) {
321732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("got no private key"));
321832b31808SJens Wiklander             return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED;
321932b31808SJens Wiklander         }
322032b31808SJens Wiklander 
322132b31808SJens Wiklander         /* Append the signature to ssl->out_msg, leaving 2 bytes for the
322232b31808SJens Wiklander          * signature length which will be added in ssl_write_server_key_exchange
322332b31808SJens Wiklander          * after the call to ssl_prepare_server_key_exchange.
322432b31808SJens Wiklander          * ssl_write_server_key_exchange also takes care of incrementing
322532b31808SJens Wiklander          * ssl->out_msglen. */
322632b31808SJens Wiklander         if ((ret = mbedtls_pk_sign(mbedtls_ssl_own_key(ssl),
322732b31808SJens Wiklander                                    md_alg, hash, hashlen,
322832b31808SJens Wiklander                                    ssl->out_msg + ssl->out_msglen + 2,
322932b31808SJens Wiklander                                    out_buf_len - ssl->out_msglen - 2,
323032b31808SJens Wiklander                                    signature_len,
323132b31808SJens Wiklander                                    ssl->conf->f_rng,
323232b31808SJens Wiklander                                    ssl->conf->p_rng)) != 0) {
323332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_sign", ret);
323432b31808SJens Wiklander             return ret;
323532b31808SJens Wiklander         }
323632b31808SJens Wiklander     }
323732b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
323832b31808SJens Wiklander 
323932b31808SJens Wiklander     return 0;
324032b31808SJens Wiklander }
324132b31808SJens Wiklander 
324232b31808SJens Wiklander /* Prepare the ServerKeyExchange message and send it. For ciphersuites
324332b31808SJens Wiklander  * that do not include a ServerKeyExchange message, do nothing. Either
324432b31808SJens Wiklander  * way, if successful, move on to the next step in the SSL state
324532b31808SJens Wiklander  * machine. */
324632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
324732b31808SJens Wiklander static int ssl_write_server_key_exchange(mbedtls_ssl_context *ssl)
324832b31808SJens Wiklander {
324932b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
325032b31808SJens Wiklander     size_t signature_len = 0;
325132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED)
325232b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
325332b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
325432b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */
325532b31808SJens Wiklander 
325632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server key exchange"));
325732b31808SJens Wiklander 
325832b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED)
325932b31808SJens Wiklander     /* Extract static ECDH parameters and abort if ServerKeyExchange
326032b31808SJens Wiklander      * is not needed. */
326132b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_no_pfs(ciphersuite_info)) {
326232b31808SJens Wiklander         /* For suites involving ECDH, extract DH parameters
326332b31808SJens Wiklander          * from certificate at this point. */
326432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED)
326532b31808SJens Wiklander         if (mbedtls_ssl_ciphersuite_uses_ecdh(ciphersuite_info)) {
326632b31808SJens Wiklander             ret = ssl_get_ecdh_params_from_cert(ssl);
326732b31808SJens Wiklander             if (ret != 0) {
326832b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "ssl_get_ecdh_params_from_cert", ret);
326932b31808SJens Wiklander                 return ret;
327032b31808SJens Wiklander             }
327132b31808SJens Wiklander         }
327232b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */
327332b31808SJens Wiklander 
327432b31808SJens Wiklander         /* Key exchanges not involving ephemeral keys don't use
327532b31808SJens Wiklander          * ServerKeyExchange, so end here. */
327632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write server key exchange"));
327732b31808SJens Wiklander         ssl->state++;
327832b31808SJens Wiklander         return 0;
327932b31808SJens Wiklander     }
328032b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */
328132b31808SJens Wiklander 
328232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \
328332b31808SJens Wiklander     defined(MBEDTLS_SSL_ASYNC_PRIVATE)
328432b31808SJens Wiklander     /* If we have already prepared the message and there is an ongoing
328532b31808SJens Wiklander      * signature operation, resume signing. */
328632b31808SJens Wiklander     if (ssl->handshake->async_in_progress != 0) {
328732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("resuming signature operation"));
328832b31808SJens Wiklander         ret = ssl_resume_server_key_exchange(ssl, &signature_len);
328932b31808SJens Wiklander     } else
329032b31808SJens Wiklander #endif /* defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) &&
329132b31808SJens Wiklander           defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
329232b31808SJens Wiklander     {
329332b31808SJens Wiklander         /* ServerKeyExchange is needed. Prepare the message. */
329432b31808SJens Wiklander         ret = ssl_prepare_server_key_exchange(ssl, &signature_len);
329532b31808SJens Wiklander     }
329632b31808SJens Wiklander 
329732b31808SJens Wiklander     if (ret != 0) {
329832b31808SJens Wiklander         /* If we're starting to write a new message, set ssl->out_msglen
329932b31808SJens Wiklander          * to 0. But if we're resuming after an asynchronous message,
330032b31808SJens Wiklander          * out_msglen is the amount of data written so far and mst be
330132b31808SJens Wiklander          * preserved. */
330232b31808SJens Wiklander         if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
330332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server key exchange (pending)"));
330432b31808SJens Wiklander         } else {
330532b31808SJens Wiklander             ssl->out_msglen = 0;
330632b31808SJens Wiklander         }
330732b31808SJens Wiklander         return ret;
330832b31808SJens Wiklander     }
330932b31808SJens Wiklander 
331032b31808SJens Wiklander     /* If there is a signature, write its length.
331132b31808SJens Wiklander      * ssl_prepare_server_key_exchange already wrote the signature
331232b31808SJens Wiklander      * itself at its proper place in the output buffer. */
331332b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
331432b31808SJens Wiklander     if (signature_len != 0) {
331532b31808SJens Wiklander         ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_1(signature_len);
331632b31808SJens Wiklander         ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_0(signature_len);
331732b31808SJens Wiklander 
331832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "my signature",
331932b31808SJens Wiklander                               ssl->out_msg + ssl->out_msglen,
332032b31808SJens Wiklander                               signature_len);
332132b31808SJens Wiklander 
332232b31808SJens Wiklander         /* Skip over the already-written signature */
332332b31808SJens Wiklander         ssl->out_msglen += signature_len;
332432b31808SJens Wiklander     }
332532b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
332632b31808SJens Wiklander 
332732b31808SJens Wiklander     /* Add header and send. */
332832b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
332932b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE;
333032b31808SJens Wiklander 
333132b31808SJens Wiklander     ssl->state++;
333232b31808SJens Wiklander 
333332b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
333432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
333532b31808SJens Wiklander         return ret;
333632b31808SJens Wiklander     }
333732b31808SJens Wiklander 
333832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server key exchange"));
333932b31808SJens Wiklander     return 0;
334032b31808SJens Wiklander }
334132b31808SJens Wiklander 
334232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
334332b31808SJens Wiklander static int ssl_write_server_hello_done(mbedtls_ssl_context *ssl)
334432b31808SJens Wiklander {
334532b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
334632b31808SJens Wiklander 
334732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server hello done"));
334832b31808SJens Wiklander 
334932b31808SJens Wiklander     ssl->out_msglen  = 4;
335032b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
335132b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_HELLO_DONE;
335232b31808SJens Wiklander 
335332b31808SJens Wiklander     ssl->state++;
335432b31808SJens Wiklander 
335532b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
335632b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
335732b31808SJens Wiklander         mbedtls_ssl_send_flight_completed(ssl);
335832b31808SJens Wiklander     }
335932b31808SJens Wiklander #endif
336032b31808SJens Wiklander 
336132b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
336232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
336332b31808SJens Wiklander         return ret;
336432b31808SJens Wiklander     }
336532b31808SJens Wiklander 
336632b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
336732b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
336832b31808SJens Wiklander         (ret = mbedtls_ssl_flight_transmit(ssl)) != 0) {
336932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flight_transmit", ret);
337032b31808SJens Wiklander         return ret;
337132b31808SJens Wiklander     }
337232b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */
337332b31808SJens Wiklander 
337432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello done"));
337532b31808SJens Wiklander 
337632b31808SJens Wiklander     return 0;
337732b31808SJens Wiklander }
337832b31808SJens Wiklander 
337932b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
338032b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
338132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
338232b31808SJens Wiklander static int ssl_parse_client_dh_public(mbedtls_ssl_context *ssl, unsigned char **p,
338332b31808SJens Wiklander                                       const unsigned char *end)
338432b31808SJens Wiklander {
338532b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
338632b31808SJens Wiklander     size_t n;
338732b31808SJens Wiklander 
338832b31808SJens Wiklander     /*
338932b31808SJens Wiklander      * Receive G^Y mod P, premaster = (G^Y)^X mod P
339032b31808SJens Wiklander      */
339132b31808SJens Wiklander     if (*p + 2 > end) {
339232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
339332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
339432b31808SJens Wiklander     }
339532b31808SJens Wiklander 
3396b0563631STom Van Eyck     n = MBEDTLS_GET_UINT16_BE(*p, 0);
339732b31808SJens Wiklander     *p += 2;
339832b31808SJens Wiklander 
339932b31808SJens Wiklander     if (*p + n > end) {
340032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
340132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
340232b31808SJens Wiklander     }
340332b31808SJens Wiklander 
340432b31808SJens Wiklander     if ((ret = mbedtls_dhm_read_public(&ssl->handshake->dhm_ctx, *p, n)) != 0) {
340532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_read_public", ret);
340632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
340732b31808SJens Wiklander     }
340832b31808SJens Wiklander 
340932b31808SJens Wiklander     *p += n;
341032b31808SJens Wiklander 
341132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GY", &ssl->handshake->dhm_ctx.GY);
341232b31808SJens Wiklander 
341332b31808SJens Wiklander     return ret;
341432b31808SJens Wiklander }
341532b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
341632b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
341732b31808SJens Wiklander 
341832b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) ||                           \
341932b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
342032b31808SJens Wiklander 
342132b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
342232b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
342332b31808SJens Wiklander static int ssl_resume_decrypt_pms(mbedtls_ssl_context *ssl,
342432b31808SJens Wiklander                                   unsigned char *peer_pms,
342532b31808SJens Wiklander                                   size_t *peer_pmslen,
342632b31808SJens Wiklander                                   size_t peer_pmssize)
342732b31808SJens Wiklander {
342832b31808SJens Wiklander     int ret = ssl->conf->f_async_resume(ssl,
342932b31808SJens Wiklander                                         peer_pms, peer_pmslen, peer_pmssize);
343032b31808SJens Wiklander     if (ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
343132b31808SJens Wiklander         ssl->handshake->async_in_progress = 0;
343232b31808SJens Wiklander         mbedtls_ssl_set_async_operation_data(ssl, NULL);
343332b31808SJens Wiklander     }
343432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_RET(2, "ssl_decrypt_encrypted_pms", ret);
343532b31808SJens Wiklander     return ret;
343632b31808SJens Wiklander }
343732b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
343832b31808SJens Wiklander 
343932b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
344032b31808SJens Wiklander static int ssl_decrypt_encrypted_pms(mbedtls_ssl_context *ssl,
344132b31808SJens Wiklander                                      const unsigned char *p,
344232b31808SJens Wiklander                                      const unsigned char *end,
344332b31808SJens Wiklander                                      unsigned char *peer_pms,
344432b31808SJens Wiklander                                      size_t *peer_pmslen,
344532b31808SJens Wiklander                                      size_t peer_pmssize)
344632b31808SJens Wiklander {
344732b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
344832b31808SJens Wiklander 
344932b31808SJens Wiklander     mbedtls_x509_crt *own_cert = mbedtls_ssl_own_cert(ssl);
345032b31808SJens Wiklander     if (own_cert == NULL) {
345132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got no local certificate"));
345232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE;
345332b31808SJens Wiklander     }
345432b31808SJens Wiklander     mbedtls_pk_context *public_key = &own_cert->pk;
345532b31808SJens Wiklander     mbedtls_pk_context *private_key = mbedtls_ssl_own_key(ssl);
345632b31808SJens Wiklander     size_t len = mbedtls_pk_get_len(public_key);
345732b31808SJens Wiklander 
345832b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
345932b31808SJens Wiklander     /* If we have already started decoding the message and there is an ongoing
346032b31808SJens Wiklander      * decryption operation, resume signing. */
346132b31808SJens Wiklander     if (ssl->handshake->async_in_progress != 0) {
346232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("resuming decryption operation"));
346332b31808SJens Wiklander         return ssl_resume_decrypt_pms(ssl,
346432b31808SJens Wiklander                                       peer_pms, peer_pmslen, peer_pmssize);
346532b31808SJens Wiklander     }
346632b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
346732b31808SJens Wiklander 
346832b31808SJens Wiklander     /*
346932b31808SJens Wiklander      * Prepare to decrypt the premaster using own private RSA key
347032b31808SJens Wiklander      */
347132b31808SJens Wiklander     if (p + 2 > end) {
347232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
347332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
347432b31808SJens Wiklander     }
347532b31808SJens Wiklander     if (*p++ != MBEDTLS_BYTE_1(len) ||
347632b31808SJens Wiklander         *p++ != MBEDTLS_BYTE_0(len)) {
347732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
347832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
347932b31808SJens Wiklander     }
348032b31808SJens Wiklander 
348132b31808SJens Wiklander     if (p + len != end) {
348232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
348332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
348432b31808SJens Wiklander     }
348532b31808SJens Wiklander 
348632b31808SJens Wiklander     /*
348732b31808SJens Wiklander      * Decrypt the premaster secret
348832b31808SJens Wiklander      */
348932b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
349032b31808SJens Wiklander     if (ssl->conf->f_async_decrypt_start != NULL) {
349132b31808SJens Wiklander         ret = ssl->conf->f_async_decrypt_start(ssl,
349232b31808SJens Wiklander                                                mbedtls_ssl_own_cert(ssl),
349332b31808SJens Wiklander                                                p, len);
349432b31808SJens Wiklander         switch (ret) {
349532b31808SJens Wiklander             case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH:
349632b31808SJens Wiklander                 /* act as if f_async_decrypt_start was null */
349732b31808SJens Wiklander                 break;
349832b31808SJens Wiklander             case 0:
349932b31808SJens Wiklander                 ssl->handshake->async_in_progress = 1;
350032b31808SJens Wiklander                 return ssl_resume_decrypt_pms(ssl,
350132b31808SJens Wiklander                                               peer_pms,
350232b31808SJens Wiklander                                               peer_pmslen,
350332b31808SJens Wiklander                                               peer_pmssize);
350432b31808SJens Wiklander             case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
350532b31808SJens Wiklander                 ssl->handshake->async_in_progress = 1;
350632b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS;
350732b31808SJens Wiklander             default:
350832b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "f_async_decrypt_start", ret);
350932b31808SJens Wiklander                 return ret;
351032b31808SJens Wiklander         }
351132b31808SJens Wiklander     }
351232b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
351332b31808SJens Wiklander 
351432b31808SJens Wiklander     if (!mbedtls_pk_can_do(private_key, MBEDTLS_PK_RSA)) {
351532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got no RSA private key"));
351632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED;
351732b31808SJens Wiklander     }
351832b31808SJens Wiklander 
351932b31808SJens Wiklander     ret = mbedtls_pk_decrypt(private_key, p, len,
352032b31808SJens Wiklander                              peer_pms, peer_pmslen, peer_pmssize,
352132b31808SJens Wiklander                              ssl->conf->f_rng, ssl->conf->p_rng);
352232b31808SJens Wiklander     return ret;
352332b31808SJens Wiklander }
352432b31808SJens Wiklander 
352532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
352632b31808SJens Wiklander static int ssl_parse_encrypted_pms(mbedtls_ssl_context *ssl,
352732b31808SJens Wiklander                                    const unsigned char *p,
352832b31808SJens Wiklander                                    const unsigned char *end,
352932b31808SJens Wiklander                                    size_t pms_offset)
353032b31808SJens Wiklander {
353132b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
353232b31808SJens Wiklander     unsigned char *pms = ssl->handshake->premaster + pms_offset;
353332b31808SJens Wiklander     unsigned char ver[2];
353432b31808SJens Wiklander     unsigned char fake_pms[48], peer_pms[48];
3535b0563631STom Van Eyck     size_t peer_pmslen;
3536b0563631STom Van Eyck     mbedtls_ct_condition_t diff;
353732b31808SJens Wiklander 
353832b31808SJens Wiklander     /* In case of a failure in decryption, the decryption may write less than
353932b31808SJens Wiklander      * 2 bytes of output, but we always read the first two bytes. It doesn't
354032b31808SJens Wiklander      * matter in the end because diff will be nonzero in that case due to
354132b31808SJens Wiklander      * ret being nonzero, and we only care whether diff is 0.
354232b31808SJens Wiklander      * But do initialize peer_pms and peer_pmslen for robustness anyway. This
354332b31808SJens Wiklander      * also makes memory analyzers happy (don't access uninitialized memory,
354432b31808SJens Wiklander      * even if it's an unsigned char). */
354532b31808SJens Wiklander     peer_pms[0] = peer_pms[1] = ~0;
354632b31808SJens Wiklander     peer_pmslen = 0;
354732b31808SJens Wiklander 
354832b31808SJens Wiklander     ret = ssl_decrypt_encrypted_pms(ssl, p, end,
354932b31808SJens Wiklander                                     peer_pms,
355032b31808SJens Wiklander                                     &peer_pmslen,
355132b31808SJens Wiklander                                     sizeof(peer_pms));
355232b31808SJens Wiklander 
355332b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
355432b31808SJens Wiklander     if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
355532b31808SJens Wiklander         return ret;
355632b31808SJens Wiklander     }
355732b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
355832b31808SJens Wiklander 
355932b31808SJens Wiklander     mbedtls_ssl_write_version(ver, ssl->conf->transport,
356032b31808SJens Wiklander                               ssl->session_negotiate->tls_version);
356132b31808SJens Wiklander 
356232b31808SJens Wiklander     /* Avoid data-dependent branches while checking for invalid
356332b31808SJens Wiklander      * padding, to protect against timing-based Bleichenbacher-type
356432b31808SJens Wiklander      * attacks. */
3565b0563631STom Van Eyck     diff = mbedtls_ct_bool(ret);
3566b0563631STom Van Eyck     diff = mbedtls_ct_bool_or(diff, mbedtls_ct_uint_ne(peer_pmslen, 48));
3567b0563631STom Van Eyck     diff = mbedtls_ct_bool_or(diff, mbedtls_ct_uint_ne(peer_pms[0], ver[0]));
3568b0563631STom Van Eyck     diff = mbedtls_ct_bool_or(diff, mbedtls_ct_uint_ne(peer_pms[1], ver[1]));
356932b31808SJens Wiklander 
357032b31808SJens Wiklander     /*
357132b31808SJens Wiklander      * Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding
357232b31808SJens Wiklander      * must not cause the connection to end immediately; instead, send a
357332b31808SJens Wiklander      * bad_record_mac later in the handshake.
357432b31808SJens Wiklander      * To protect against timing-based variants of the attack, we must
357532b31808SJens Wiklander      * not have any branch that depends on whether the decryption was
357632b31808SJens Wiklander      * successful. In particular, always generate the fake premaster secret,
357732b31808SJens Wiklander      * regardless of whether it will ultimately influence the output or not.
357832b31808SJens Wiklander      */
357932b31808SJens Wiklander     ret = ssl->conf->f_rng(ssl->conf->p_rng, fake_pms, sizeof(fake_pms));
358032b31808SJens Wiklander     if (ret != 0) {
358132b31808SJens Wiklander         /* It's ok to abort on an RNG failure, since this does not reveal
358232b31808SJens Wiklander          * anything about the RSA decryption. */
358332b31808SJens Wiklander         return ret;
358432b31808SJens Wiklander     }
358532b31808SJens Wiklander 
358632b31808SJens Wiklander #if defined(MBEDTLS_SSL_DEBUG_ALL)
3587b0563631STom Van Eyck     if (diff != MBEDTLS_CT_FALSE) {
358832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
358932b31808SJens Wiklander     }
359032b31808SJens Wiklander #endif
359132b31808SJens Wiklander 
359232b31808SJens Wiklander     if (sizeof(ssl->handshake->premaster) < pms_offset ||
359332b31808SJens Wiklander         sizeof(ssl->handshake->premaster) - pms_offset < 48) {
359432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
359532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
359632b31808SJens Wiklander     }
359732b31808SJens Wiklander     ssl->handshake->pmslen = 48;
359832b31808SJens Wiklander 
359932b31808SJens Wiklander     /* Set pms to either the true or the fake PMS, without
360032b31808SJens Wiklander      * data-dependent branches. */
3601b0563631STom Van Eyck     mbedtls_ct_memcpy_if(diff, pms, fake_pms, peer_pms, ssl->handshake->pmslen);
360232b31808SJens Wiklander 
360332b31808SJens Wiklander     return 0;
360432b31808SJens Wiklander }
360532b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
360632b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
360732b31808SJens Wiklander 
360832b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
360932b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
361032b31808SJens Wiklander static int ssl_parse_client_psk_identity(mbedtls_ssl_context *ssl, unsigned char **p,
361132b31808SJens Wiklander                                          const unsigned char *end)
361232b31808SJens Wiklander {
361332b31808SJens Wiklander     int ret = 0;
361432b31808SJens Wiklander     uint16_t n;
361532b31808SJens Wiklander 
361632b31808SJens Wiklander     if (ssl_conf_has_psk_or_cb(ssl->conf) == 0) {
361732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got no pre-shared key"));
361832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED;
361932b31808SJens Wiklander     }
362032b31808SJens Wiklander 
362132b31808SJens Wiklander     /*
362232b31808SJens Wiklander      * Receive client pre-shared key identity name
362332b31808SJens Wiklander      */
362432b31808SJens Wiklander     if (end - *p < 2) {
362532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
362632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
362732b31808SJens Wiklander     }
362832b31808SJens Wiklander 
3629b0563631STom Van Eyck     n = MBEDTLS_GET_UINT16_BE(*p, 0);
363032b31808SJens Wiklander     *p += 2;
363132b31808SJens Wiklander 
363232b31808SJens Wiklander     if (n == 0 || n > end - *p) {
363332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
363432b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
363532b31808SJens Wiklander     }
363632b31808SJens Wiklander 
363732b31808SJens Wiklander     if (ssl->conf->f_psk != NULL) {
363832b31808SJens Wiklander         if (ssl->conf->f_psk(ssl->conf->p_psk, ssl, *p, n) != 0) {
363932b31808SJens Wiklander             ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
364032b31808SJens Wiklander         }
364132b31808SJens Wiklander     } else {
364232b31808SJens Wiklander         /* Identity is not a big secret since clients send it in the clear,
364332b31808SJens Wiklander          * but treat it carefully anyway, just in case */
364432b31808SJens Wiklander         if (n != ssl->conf->psk_identity_len ||
364532b31808SJens Wiklander             mbedtls_ct_memcmp(ssl->conf->psk_identity, *p, n) != 0) {
364632b31808SJens Wiklander             ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
364732b31808SJens Wiklander         }
364832b31808SJens Wiklander     }
364932b31808SJens Wiklander 
365032b31808SJens Wiklander     if (ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) {
365132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "Unknown PSK identity", *p, n);
365232b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
365332b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY);
365432b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
365532b31808SJens Wiklander     }
365632b31808SJens Wiklander 
365732b31808SJens Wiklander     *p += n;
365832b31808SJens Wiklander 
365932b31808SJens Wiklander     return 0;
366032b31808SJens Wiklander }
366132b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
366232b31808SJens Wiklander 
366332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
366432b31808SJens Wiklander static int ssl_parse_client_key_exchange(mbedtls_ssl_context *ssl)
366532b31808SJens Wiklander {
366632b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
366732b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
366832b31808SJens Wiklander     unsigned char *p, *end;
366932b31808SJens Wiklander 
367032b31808SJens Wiklander     ciphersuite_info = ssl->handshake->ciphersuite_info;
367132b31808SJens Wiklander 
367232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse client key exchange"));
367332b31808SJens Wiklander 
367432b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE) && \
367532b31808SJens Wiklander     (defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
367632b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED))
367732b31808SJens Wiklander     if ((ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
367832b31808SJens Wiklander          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) &&
367932b31808SJens Wiklander         (ssl->handshake->async_in_progress != 0)) {
368032b31808SJens Wiklander         /* We've already read a record and there is an asynchronous
368132b31808SJens Wiklander          * operation in progress to decrypt it. So skip reading the
368232b31808SJens Wiklander          * record. */
368332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("will resume decryption of previously-read record"));
368432b31808SJens Wiklander     } else
368532b31808SJens Wiklander #endif
368632b31808SJens Wiklander     if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
368732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
368832b31808SJens Wiklander         return ret;
368932b31808SJens Wiklander     }
369032b31808SJens Wiklander 
369132b31808SJens Wiklander     p = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl);
369232b31808SJens Wiklander     end = ssl->in_msg + ssl->in_hslen;
369332b31808SJens Wiklander 
369432b31808SJens Wiklander     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
369532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
369632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
369732b31808SJens Wiklander     }
369832b31808SJens Wiklander 
369932b31808SJens Wiklander     if (ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE) {
370032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
370132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
370232b31808SJens Wiklander     }
370332b31808SJens Wiklander 
370432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
370532b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA) {
370632b31808SJens Wiklander         if ((ret = ssl_parse_client_dh_public(ssl, &p, end)) != 0) {
370732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_dh_public"), ret);
370832b31808SJens Wiklander             return ret;
370932b31808SJens Wiklander         }
371032b31808SJens Wiklander 
371132b31808SJens Wiklander         if (p != end) {
371232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange"));
371332b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
371432b31808SJens Wiklander         }
371532b31808SJens Wiklander 
371632b31808SJens Wiklander         if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx,
371732b31808SJens Wiklander                                            ssl->handshake->premaster,
371832b31808SJens Wiklander                                            MBEDTLS_PREMASTER_SIZE,
371932b31808SJens Wiklander                                            &ssl->handshake->pmslen,
372032b31808SJens Wiklander                                            ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
372132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret);
372232b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
372332b31808SJens Wiklander         }
372432b31808SJens Wiklander 
372532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K);
372632b31808SJens Wiklander     } else
372732b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
372832b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
372932b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
373032b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
373132b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
373232b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
373332b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
373432b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
373532b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA) {
373632b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
373732b31808SJens Wiklander         size_t data_len = (size_t) (*p++);
373832b31808SJens Wiklander         size_t buf_len = (size_t) (end - p);
373932b31808SJens Wiklander         psa_status_t status = PSA_ERROR_GENERIC_ERROR;
374032b31808SJens Wiklander         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
374132b31808SJens Wiklander 
3742b0563631STom Van Eyck         MBEDTLS_SSL_DEBUG_MSG(3, ("Read the peer's public key."));
374332b31808SJens Wiklander 
374432b31808SJens Wiklander         /*
374532b31808SJens Wiklander          * We must have at least two bytes (1 for length, at least 1 for data)
374632b31808SJens Wiklander          */
374732b31808SJens Wiklander         if (buf_len < 2) {
3748b0563631STom Van Eyck             MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid buffer length: %" MBEDTLS_PRINTF_SIZET,
3749b0563631STom Van Eyck                                       buf_len));
3750b0563631STom Van Eyck             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
375132b31808SJens Wiklander         }
375232b31808SJens Wiklander 
375332b31808SJens Wiklander         if (data_len < 1 || data_len > buf_len) {
3754b0563631STom Van Eyck             MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid data length: %" MBEDTLS_PRINTF_SIZET
3755b0563631STom Van Eyck                                       " > %" MBEDTLS_PRINTF_SIZET,
3756b0563631STom Van Eyck                                       data_len, buf_len));
3757b0563631STom Van Eyck             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
375832b31808SJens Wiklander         }
375932b31808SJens Wiklander 
376032b31808SJens Wiklander         /* Store peer's ECDH public key. */
3761b0563631STom Van Eyck         if (data_len > sizeof(handshake->xxdh_psa_peerkey)) {
3762b0563631STom Van Eyck             MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid public key length: %" MBEDTLS_PRINTF_SIZET
3763b0563631STom Van Eyck                                       " > %" MBEDTLS_PRINTF_SIZET,
3764b0563631STom Van Eyck                                       data_len,
3765b0563631STom Van Eyck                                       sizeof(handshake->xxdh_psa_peerkey)));
3766b0563631STom Van Eyck             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
3767b0563631STom Van Eyck         }
3768b0563631STom Van Eyck         memcpy(handshake->xxdh_psa_peerkey, p, data_len);
3769b0563631STom Van Eyck         handshake->xxdh_psa_peerkey_len = data_len;
377032b31808SJens Wiklander 
377132b31808SJens Wiklander         /* Compute ECDH shared secret. */
377232b31808SJens Wiklander         status = psa_raw_key_agreement(
3773b0563631STom Van Eyck             PSA_ALG_ECDH, handshake->xxdh_psa_privkey,
3774b0563631STom Van Eyck             handshake->xxdh_psa_peerkey, handshake->xxdh_psa_peerkey_len,
377532b31808SJens Wiklander             handshake->premaster, sizeof(handshake->premaster),
377632b31808SJens Wiklander             &handshake->pmslen);
377732b31808SJens Wiklander         if (status != PSA_SUCCESS) {
377832b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
377932b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_raw_key_agreement", ret);
3780b0563631STom Van Eyck             if (handshake->xxdh_psa_privkey_is_external == 0) {
3781b0563631STom Van Eyck                 (void) psa_destroy_key(handshake->xxdh_psa_privkey);
378232b31808SJens Wiklander             }
3783b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
378432b31808SJens Wiklander             return ret;
378532b31808SJens Wiklander         }
378632b31808SJens Wiklander 
3787b0563631STom Van Eyck         if (handshake->xxdh_psa_privkey_is_external == 0) {
3788b0563631STom Van Eyck             status = psa_destroy_key(handshake->xxdh_psa_privkey);
378932b31808SJens Wiklander 
379032b31808SJens Wiklander             if (status != PSA_SUCCESS) {
379132b31808SJens Wiklander                 ret = PSA_TO_MBEDTLS_ERR(status);
379232b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "psa_destroy_key", ret);
379332b31808SJens Wiklander                 return ret;
379432b31808SJens Wiklander             }
379532b31808SJens Wiklander         }
3796b0563631STom Van Eyck         handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
379732b31808SJens Wiklander #else
379832b31808SJens Wiklander         if ((ret = mbedtls_ecdh_read_public(&ssl->handshake->ecdh_ctx,
3799b0563631STom Van Eyck                                             p, (size_t) (end - p))) != 0) {
380032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_read_public", ret);
380132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
380232b31808SJens Wiklander         }
380332b31808SJens Wiklander 
380432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
380532b31808SJens Wiklander                                MBEDTLS_DEBUG_ECDH_QP);
380632b31808SJens Wiklander 
380732b31808SJens Wiklander         if ((ret = mbedtls_ecdh_calc_secret(&ssl->handshake->ecdh_ctx,
380832b31808SJens Wiklander                                             &ssl->handshake->pmslen,
380932b31808SJens Wiklander                                             ssl->handshake->premaster,
381032b31808SJens Wiklander                                             MBEDTLS_MPI_MAX_SIZE,
381132b31808SJens Wiklander                                             ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
381232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_calc_secret", ret);
381332b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
381432b31808SJens Wiklander         }
381532b31808SJens Wiklander 
381632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
381732b31808SJens Wiklander                                MBEDTLS_DEBUG_ECDH_Z);
381832b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
381932b31808SJens Wiklander     } else
382032b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
382132b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
382232b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
382332b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
382432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
382532b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK) {
382632b31808SJens Wiklander         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
382732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
382832b31808SJens Wiklander             return ret;
382932b31808SJens Wiklander         }
383032b31808SJens Wiklander 
383132b31808SJens Wiklander         if (p != end) {
383232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange"));
383332b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
383432b31808SJens Wiklander         }
383532b31808SJens Wiklander 
383632b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO)
383732b31808SJens Wiklander         if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
3838b0563631STom Van Eyck                                                     (mbedtls_key_exchange_type_t) ciphersuite_info->
3839b0563631STom Van Eyck                                                     key_exchange)) != 0) {
384032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret);
384132b31808SJens Wiklander             return ret;
384232b31808SJens Wiklander         }
384332b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO */
384432b31808SJens Wiklander     } else
384532b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
384632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
384732b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) {
384832b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
384932b31808SJens Wiklander         if (ssl->handshake->async_in_progress != 0) {
385032b31808SJens Wiklander             /* There is an asynchronous operation in progress to
385132b31808SJens Wiklander              * decrypt the encrypted premaster secret, so skip
385232b31808SJens Wiklander              * directly to resuming this operation. */
385332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3, ("PSK identity already parsed"));
385432b31808SJens Wiklander             /* Update p to skip the PSK identity. ssl_parse_encrypted_pms
385532b31808SJens Wiklander              * won't actually use it, but maintain p anyway for robustness. */
385632b31808SJens Wiklander             p += ssl->conf->psk_identity_len + 2;
385732b31808SJens Wiklander         } else
385832b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
385932b31808SJens Wiklander         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
386032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
386132b31808SJens Wiklander             return ret;
386232b31808SJens Wiklander         }
386332b31808SJens Wiklander 
386432b31808SJens Wiklander         if ((ret = ssl_parse_encrypted_pms(ssl, p, end, 2)) != 0) {
386532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_encrypted_pms"), ret);
386632b31808SJens Wiklander             return ret;
386732b31808SJens Wiklander         }
386832b31808SJens Wiklander 
386932b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO)
387032b31808SJens Wiklander         if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
3871b0563631STom Van Eyck                                                     (mbedtls_key_exchange_type_t) ciphersuite_info->
3872b0563631STom Van Eyck                                                     key_exchange)) != 0) {
387332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret);
387432b31808SJens Wiklander             return ret;
387532b31808SJens Wiklander         }
387632b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO */
387732b31808SJens Wiklander     } else
387832b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
387932b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
388032b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK) {
388132b31808SJens Wiklander         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
388232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
388332b31808SJens Wiklander             return ret;
388432b31808SJens Wiklander         }
388532b31808SJens Wiklander         if ((ret = ssl_parse_client_dh_public(ssl, &p, end)) != 0) {
388632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_dh_public"), ret);
388732b31808SJens Wiklander             return ret;
388832b31808SJens Wiklander         }
388932b31808SJens Wiklander 
389032b31808SJens Wiklander         if (p != end) {
389132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange"));
389232b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
389332b31808SJens Wiklander         }
389432b31808SJens Wiklander 
389532b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
389632b31808SJens Wiklander         unsigned char *pms = ssl->handshake->premaster;
389732b31808SJens Wiklander         unsigned char *pms_end = pms + sizeof(ssl->handshake->premaster);
389832b31808SJens Wiklander         size_t pms_len;
389932b31808SJens Wiklander 
390032b31808SJens Wiklander         /* Write length only when we know the actual value */
390132b31808SJens Wiklander         if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx,
390232b31808SJens Wiklander                                            pms + 2, pms_end - (pms + 2), &pms_len,
390332b31808SJens Wiklander                                            ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
390432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret);
390532b31808SJens Wiklander             return ret;
390632b31808SJens Wiklander         }
390732b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(pms_len, pms, 0);
390832b31808SJens Wiklander         pms += 2 + pms_len;
390932b31808SJens Wiklander 
391032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K);
391132b31808SJens Wiklander #else
391232b31808SJens Wiklander         if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
3913b0563631STom Van Eyck                                                     (mbedtls_key_exchange_type_t) ciphersuite_info->
3914b0563631STom Van Eyck                                                     key_exchange)) != 0) {
391532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret);
391632b31808SJens Wiklander             return ret;
391732b31808SJens Wiklander         }
391832b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
391932b31808SJens Wiklander     } else
392032b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
392132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
392232b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) {
392332b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
392432b31808SJens Wiklander         psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
392532b31808SJens Wiklander         psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED;
3926*cb034002SJerome Forissier         size_t ecpoint_len;
392732b31808SJens Wiklander 
392832b31808SJens Wiklander         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
392932b31808SJens Wiklander 
393032b31808SJens Wiklander         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
393132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
3932b0563631STom Van Eyck             psa_destroy_key(handshake->xxdh_psa_privkey);
3933b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
393432b31808SJens Wiklander             return ret;
393532b31808SJens Wiklander         }
393632b31808SJens Wiklander 
393732b31808SJens Wiklander         /* Keep a copy of the peer's public key */
393832b31808SJens Wiklander         if (p >= end) {
3939b0563631STom Van Eyck             psa_destroy_key(handshake->xxdh_psa_privkey);
3940b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
394132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
394232b31808SJens Wiklander         }
394332b31808SJens Wiklander 
394432b31808SJens Wiklander         ecpoint_len = *(p++);
394532b31808SJens Wiklander         if ((size_t) (end - p) < ecpoint_len) {
3946b0563631STom Van Eyck             psa_destroy_key(handshake->xxdh_psa_privkey);
3947b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
394832b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
394932b31808SJens Wiklander         }
395032b31808SJens Wiklander 
3951b0563631STom Van Eyck         /* When FFDH is enabled, the array handshake->xxdh_psa_peer_key size takes into account
3952b0563631STom Van Eyck            the sizes of the FFDH keys which are at least 2048 bits.
3953b0563631STom Van Eyck            The size of the array is thus greater than 256 bytes which is greater than any
3954b0563631STom Van Eyck            possible value of ecpoint_len (type uint8_t) and the check below can be skipped.*/
3955b0563631STom Van Eyck #if !defined(PSA_WANT_ALG_FFDH)
3956b0563631STom Van Eyck         if (ecpoint_len > sizeof(handshake->xxdh_psa_peerkey)) {
3957b0563631STom Van Eyck             psa_destroy_key(handshake->xxdh_psa_privkey);
3958b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
395932b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
396032b31808SJens Wiklander         }
3961b0563631STom Van Eyck #else
3962b0563631STom Van Eyck         MBEDTLS_STATIC_ASSERT(sizeof(handshake->xxdh_psa_peerkey) >= UINT8_MAX,
3963b0563631STom Van Eyck                               "peer key buffer too small");
3964b0563631STom Van Eyck #endif
396532b31808SJens Wiklander 
3966b0563631STom Van Eyck         memcpy(handshake->xxdh_psa_peerkey, p, ecpoint_len);
3967b0563631STom Van Eyck         handshake->xxdh_psa_peerkey_len = ecpoint_len;
396832b31808SJens Wiklander         p += ecpoint_len;
396932b31808SJens Wiklander 
397032b31808SJens Wiklander         /* As RFC 5489 section 2, the premaster secret is formed as follows:
397132b31808SJens Wiklander          * - a uint16 containing the length (in octets) of the ECDH computation
397232b31808SJens Wiklander          * - the octet string produced by the ECDH computation
397332b31808SJens Wiklander          * - a uint16 containing the length (in octets) of the PSK
397432b31808SJens Wiklander          * - the PSK itself
397532b31808SJens Wiklander          */
397632b31808SJens Wiklander         unsigned char *psm = ssl->handshake->premaster;
397732b31808SJens Wiklander         const unsigned char * const psm_end =
397832b31808SJens Wiklander             psm + sizeof(ssl->handshake->premaster);
397932b31808SJens Wiklander         /* uint16 to store length (in octets) of the ECDH computation */
398032b31808SJens Wiklander         const size_t zlen_size = 2;
398132b31808SJens Wiklander         size_t zlen = 0;
398232b31808SJens Wiklander 
398332b31808SJens Wiklander         /* Compute ECDH shared secret. */
398432b31808SJens Wiklander         status = psa_raw_key_agreement(PSA_ALG_ECDH,
3985b0563631STom Van Eyck                                        handshake->xxdh_psa_privkey,
3986b0563631STom Van Eyck                                        handshake->xxdh_psa_peerkey,
3987b0563631STom Van Eyck                                        handshake->xxdh_psa_peerkey_len,
398832b31808SJens Wiklander                                        psm + zlen_size,
398932b31808SJens Wiklander                                        psm_end - (psm + zlen_size),
399032b31808SJens Wiklander                                        &zlen);
399132b31808SJens Wiklander 
3992b0563631STom Van Eyck         destruction_status = psa_destroy_key(handshake->xxdh_psa_privkey);
3993b0563631STom Van Eyck         handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
399432b31808SJens Wiklander 
399532b31808SJens Wiklander         if (status != PSA_SUCCESS) {
399632b31808SJens Wiklander             return PSA_TO_MBEDTLS_ERR(status);
399732b31808SJens Wiklander         } else if (destruction_status != PSA_SUCCESS) {
399832b31808SJens Wiklander             return PSA_TO_MBEDTLS_ERR(destruction_status);
399932b31808SJens Wiklander         }
400032b31808SJens Wiklander 
400132b31808SJens Wiklander         /* Write the ECDH computation length before the ECDH computation */
400232b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(zlen, psm, 0);
400332b31808SJens Wiklander         psm += zlen_size + zlen;
400432b31808SJens Wiklander 
400532b31808SJens Wiklander #else /* MBEDTLS_USE_PSA_CRYPTO */
400632b31808SJens Wiklander         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
400732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
400832b31808SJens Wiklander             return ret;
400932b31808SJens Wiklander         }
401032b31808SJens Wiklander 
401132b31808SJens Wiklander         if ((ret = mbedtls_ecdh_read_public(&ssl->handshake->ecdh_ctx,
4012b0563631STom Van Eyck                                             p, (size_t) (end - p))) != 0) {
401332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_read_public", ret);
401432b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
401532b31808SJens Wiklander         }
401632b31808SJens Wiklander 
401732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
401832b31808SJens Wiklander                                MBEDTLS_DEBUG_ECDH_QP);
401932b31808SJens Wiklander 
402032b31808SJens Wiklander         if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
4021b0563631STom Van Eyck                                                     (mbedtls_key_exchange_type_t) ciphersuite_info->
4022b0563631STom Van Eyck                                                     key_exchange)) != 0) {
402332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret);
402432b31808SJens Wiklander             return ret;
402532b31808SJens Wiklander         }
402632b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
402732b31808SJens Wiklander     } else
402832b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
402932b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
403032b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) {
403132b31808SJens Wiklander         if ((ret = ssl_parse_encrypted_pms(ssl, p, end, 0)) != 0) {
403232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_parse_encrypted_pms_secret"), ret);
403332b31808SJens Wiklander             return ret;
403432b31808SJens Wiklander         }
403532b31808SJens Wiklander     } else
403632b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
403732b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
403832b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
403932b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
404032b31808SJens Wiklander         if ((ret = mbedtls_psa_ecjpake_read_round(
4041b0563631STom Van Eyck                  &ssl->handshake->psa_pake_ctx, p, (size_t) (end - p),
404232b31808SJens Wiklander                  MBEDTLS_ECJPAKE_ROUND_TWO)) != 0) {
404332b31808SJens Wiklander             psa_destroy_key(ssl->handshake->psa_pake_password);
404432b31808SJens Wiklander             psa_pake_abort(&ssl->handshake->psa_pake_ctx);
404532b31808SJens Wiklander 
404632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round two", ret);
404732b31808SJens Wiklander             return ret;
404832b31808SJens Wiklander         }
404932b31808SJens Wiklander #else
405032b31808SJens Wiklander         ret = mbedtls_ecjpake_read_round_two(&ssl->handshake->ecjpake_ctx,
4051b0563631STom Van Eyck                                              p, (size_t) (end - p));
405232b31808SJens Wiklander         if (ret != 0) {
405332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_two", ret);
405432b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
405532b31808SJens Wiklander         }
405632b31808SJens Wiklander 
405732b31808SJens Wiklander         ret = mbedtls_ecjpake_derive_secret(&ssl->handshake->ecjpake_ctx,
405832b31808SJens Wiklander                                             ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
405932b31808SJens Wiklander                                             ssl->conf->f_rng, ssl->conf->p_rng);
406032b31808SJens Wiklander         if (ret != 0) {
406132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_derive_secret", ret);
406232b31808SJens Wiklander             return ret;
406332b31808SJens Wiklander         }
406432b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
406532b31808SJens Wiklander     } else
406632b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
406732b31808SJens Wiklander     {
406832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
406932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
407032b31808SJens Wiklander     }
407132b31808SJens Wiklander 
407232b31808SJens Wiklander     if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) {
407332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret);
407432b31808SJens Wiklander         return ret;
407532b31808SJens Wiklander     }
407632b31808SJens Wiklander 
407732b31808SJens Wiklander     ssl->state++;
407832b31808SJens Wiklander 
407932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse client key exchange"));
408032b31808SJens Wiklander 
408132b31808SJens Wiklander     return 0;
408232b31808SJens Wiklander }
408332b31808SJens Wiklander 
408432b31808SJens Wiklander #if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
408532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
408632b31808SJens Wiklander static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl)
408732b31808SJens Wiklander {
408832b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
408932b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
409032b31808SJens Wiklander 
409132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate verify"));
409232b31808SJens Wiklander 
409332b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
409432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
409532b31808SJens Wiklander         ssl->state++;
409632b31808SJens Wiklander         return 0;
409732b31808SJens Wiklander     }
409832b31808SJens Wiklander 
409932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
410032b31808SJens Wiklander     return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
410132b31808SJens Wiklander }
410232b31808SJens Wiklander #else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
410332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
410432b31808SJens Wiklander static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl)
410532b31808SJens Wiklander {
410632b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
410732b31808SJens Wiklander     size_t i, sig_len;
410832b31808SJens Wiklander     unsigned char hash[48];
410932b31808SJens Wiklander     unsigned char *hash_start = hash;
411032b31808SJens Wiklander     size_t hashlen;
411132b31808SJens Wiklander     mbedtls_pk_type_t pk_alg;
411232b31808SJens Wiklander     mbedtls_md_type_t md_alg;
411332b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
411432b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
411532b31808SJens Wiklander     mbedtls_pk_context *peer_pk;
411632b31808SJens Wiklander 
411732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate verify"));
411832b31808SJens Wiklander 
411932b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
412032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
412132b31808SJens Wiklander         ssl->state++;
412232b31808SJens Wiklander         return 0;
412332b31808SJens Wiklander     }
412432b31808SJens Wiklander 
412532b31808SJens Wiklander #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
412632b31808SJens Wiklander     if (ssl->session_negotiate->peer_cert == NULL) {
412732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
412832b31808SJens Wiklander         ssl->state++;
412932b31808SJens Wiklander         return 0;
413032b31808SJens Wiklander     }
413132b31808SJens Wiklander #else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
413232b31808SJens Wiklander     if (ssl->session_negotiate->peer_cert_digest == NULL) {
413332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
413432b31808SJens Wiklander         ssl->state++;
413532b31808SJens Wiklander         return 0;
413632b31808SJens Wiklander     }
413732b31808SJens Wiklander #endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
413832b31808SJens Wiklander 
413932b31808SJens Wiklander     /* Read the message without adding it to the checksum */
414032b31808SJens Wiklander     ret = mbedtls_ssl_read_record(ssl, 0 /* no checksum update */);
414132b31808SJens Wiklander     if (0 != ret) {
414232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_read_record"), ret);
414332b31808SJens Wiklander         return ret;
414432b31808SJens Wiklander     }
414532b31808SJens Wiklander 
414632b31808SJens Wiklander     ssl->state++;
414732b31808SJens Wiklander 
414832b31808SJens Wiklander     /* Process the message contents */
414932b31808SJens Wiklander     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ||
415032b31808SJens Wiklander         ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY) {
415132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message"));
415232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
415332b31808SJens Wiklander     }
415432b31808SJens Wiklander 
415532b31808SJens Wiklander     i = mbedtls_ssl_hs_hdr_len(ssl);
415632b31808SJens Wiklander 
415732b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
415832b31808SJens Wiklander     peer_pk = &ssl->handshake->peer_pubkey;
415932b31808SJens Wiklander #else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
416032b31808SJens Wiklander     if (ssl->session_negotiate->peer_cert == NULL) {
416132b31808SJens Wiklander         /* Should never happen */
416232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
416332b31808SJens Wiklander     }
416432b31808SJens Wiklander     peer_pk = &ssl->session_negotiate->peer_cert->pk;
416532b31808SJens Wiklander #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
416632b31808SJens Wiklander 
416732b31808SJens Wiklander     /*
416832b31808SJens Wiklander      *  struct {
416932b31808SJens Wiklander      *     SignatureAndHashAlgorithm algorithm; -- TLS 1.2 only
417032b31808SJens Wiklander      *     opaque signature<0..2^16-1>;
417132b31808SJens Wiklander      *  } DigitallySigned;
417232b31808SJens Wiklander      */
417332b31808SJens Wiklander     if (i + 2 > ssl->in_hslen) {
417432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message"));
417532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
417632b31808SJens Wiklander     }
417732b31808SJens Wiklander 
417832b31808SJens Wiklander     /*
417932b31808SJens Wiklander      * Hash
418032b31808SJens Wiklander      */
418132b31808SJens Wiklander     md_alg = mbedtls_ssl_md_alg_from_hash(ssl->in_msg[i]);
418232b31808SJens Wiklander 
418332b31808SJens Wiklander     if (md_alg == MBEDTLS_MD_NONE || mbedtls_ssl_set_calc_verify_md(ssl, ssl->in_msg[i])) {
418432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("peer not adhering to requested sig_alg"
418532b31808SJens Wiklander                                   " for verify message"));
418632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
418732b31808SJens Wiklander     }
418832b31808SJens Wiklander 
418932b31808SJens Wiklander #if !defined(MBEDTLS_MD_SHA1)
419032b31808SJens Wiklander     if (MBEDTLS_MD_SHA1 == md_alg) {
419132b31808SJens Wiklander         hash_start += 16;
419232b31808SJens Wiklander     }
419332b31808SJens Wiklander #endif
419432b31808SJens Wiklander 
419532b31808SJens Wiklander     /* Info from md_alg will be used instead */
419632b31808SJens Wiklander     hashlen = 0;
419732b31808SJens Wiklander 
419832b31808SJens Wiklander     i++;
419932b31808SJens Wiklander 
420032b31808SJens Wiklander     /*
420132b31808SJens Wiklander      * Signature
420232b31808SJens Wiklander      */
420332b31808SJens Wiklander     if ((pk_alg = mbedtls_ssl_pk_alg_from_sig(ssl->in_msg[i]))
420432b31808SJens Wiklander         == MBEDTLS_PK_NONE) {
420532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("peer not adhering to requested sig_alg"
420632b31808SJens Wiklander                                   " for verify message"));
420732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
420832b31808SJens Wiklander     }
420932b31808SJens Wiklander 
421032b31808SJens Wiklander     /*
421132b31808SJens Wiklander      * Check the certificate's key type matches the signature alg
421232b31808SJens Wiklander      */
421332b31808SJens Wiklander     if (!mbedtls_pk_can_do(peer_pk, pk_alg)) {
421432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("sig_alg doesn't match cert key"));
421532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
421632b31808SJens Wiklander     }
421732b31808SJens Wiklander 
421832b31808SJens Wiklander     i++;
421932b31808SJens Wiklander 
422032b31808SJens Wiklander     if (i + 2 > ssl->in_hslen) {
422132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message"));
422232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
422332b31808SJens Wiklander     }
422432b31808SJens Wiklander 
4225b0563631STom Van Eyck     sig_len = MBEDTLS_GET_UINT16_BE(ssl->in_msg, i);
422632b31808SJens Wiklander     i += 2;
422732b31808SJens Wiklander 
422832b31808SJens Wiklander     if (i + sig_len != ssl->in_hslen) {
422932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message"));
423032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
423132b31808SJens Wiklander     }
423232b31808SJens Wiklander 
423332b31808SJens Wiklander     /* Calculate hash and verify signature */
423432b31808SJens Wiklander     {
423532b31808SJens Wiklander         size_t dummy_hlen;
423632b31808SJens Wiklander         ret = ssl->handshake->calc_verify(ssl, hash, &dummy_hlen);
423732b31808SJens Wiklander         if (0 != ret) {
423832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("calc_verify"), ret);
423932b31808SJens Wiklander             return ret;
424032b31808SJens Wiklander         }
424132b31808SJens Wiklander     }
424232b31808SJens Wiklander 
424332b31808SJens Wiklander     if ((ret = mbedtls_pk_verify(peer_pk,
424432b31808SJens Wiklander                                  md_alg, hash_start, hashlen,
424532b31808SJens Wiklander                                  ssl->in_msg + i, sig_len)) != 0) {
424632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_verify", ret);
424732b31808SJens Wiklander         return ret;
424832b31808SJens Wiklander     }
424932b31808SJens Wiklander 
425032b31808SJens Wiklander     ret = mbedtls_ssl_update_handshake_status(ssl);
425132b31808SJens Wiklander     if (0 != ret) {
425232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_update_handshake_status"), ret);
425332b31808SJens Wiklander         return ret;
425432b31808SJens Wiklander     }
425532b31808SJens Wiklander 
425632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate verify"));
425732b31808SJens Wiklander 
425832b31808SJens Wiklander     return ret;
425932b31808SJens Wiklander }
426032b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
426132b31808SJens Wiklander 
426232b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
426332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
426432b31808SJens Wiklander static int ssl_write_new_session_ticket(mbedtls_ssl_context *ssl)
426532b31808SJens Wiklander {
426632b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
426732b31808SJens Wiklander     size_t tlen;
426832b31808SJens Wiklander     uint32_t lifetime;
426932b31808SJens Wiklander 
427032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write new session ticket"));
427132b31808SJens Wiklander 
427232b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
427332b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_NEW_SESSION_TICKET;
427432b31808SJens Wiklander 
427532b31808SJens Wiklander     /*
427632b31808SJens Wiklander      * struct {
427732b31808SJens Wiklander      *     uint32 ticket_lifetime_hint;
427832b31808SJens Wiklander      *     opaque ticket<0..2^16-1>;
427932b31808SJens Wiklander      * } NewSessionTicket;
428032b31808SJens Wiklander      *
428132b31808SJens Wiklander      * 4  .  7   ticket_lifetime_hint (0 = unspecified)
428232b31808SJens Wiklander      * 8  .  9   ticket_len (n)
428332b31808SJens Wiklander      * 10 .  9+n ticket content
428432b31808SJens Wiklander      */
428532b31808SJens Wiklander 
4286b0563631STom Van Eyck #if defined(MBEDTLS_HAVE_TIME)
4287b0563631STom Van Eyck     ssl->session_negotiate->ticket_creation_time = mbedtls_ms_time();
4288b0563631STom Van Eyck #endif
428932b31808SJens Wiklander     if ((ret = ssl->conf->f_ticket_write(ssl->conf->p_ticket,
429032b31808SJens Wiklander                                          ssl->session_negotiate,
429132b31808SJens Wiklander                                          ssl->out_msg + 10,
429232b31808SJens Wiklander                                          ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN,
429332b31808SJens Wiklander                                          &tlen, &lifetime)) != 0) {
429432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_ticket_write", ret);
429532b31808SJens Wiklander         tlen = 0;
429632b31808SJens Wiklander     }
429732b31808SJens Wiklander 
429832b31808SJens Wiklander     MBEDTLS_PUT_UINT32_BE(lifetime, ssl->out_msg, 4);
429932b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(tlen, ssl->out_msg, 8);
430032b31808SJens Wiklander     ssl->out_msglen = 10 + tlen;
430132b31808SJens Wiklander 
430232b31808SJens Wiklander     /*
430332b31808SJens Wiklander      * Morally equivalent to updating ssl->state, but NewSessionTicket and
430432b31808SJens Wiklander      * ChangeCipherSpec share the same state.
430532b31808SJens Wiklander      */
430632b31808SJens Wiklander     ssl->handshake->new_session_ticket = 0;
430732b31808SJens Wiklander 
430832b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
430932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
431032b31808SJens Wiklander         return ret;
431132b31808SJens Wiklander     }
431232b31808SJens Wiklander 
431332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write new session ticket"));
431432b31808SJens Wiklander 
431532b31808SJens Wiklander     return 0;
431632b31808SJens Wiklander }
431732b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
431832b31808SJens Wiklander 
431932b31808SJens Wiklander /*
432032b31808SJens Wiklander  * SSL handshake -- server side -- single step
432132b31808SJens Wiklander  */
432232b31808SJens Wiklander int mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl)
432332b31808SJens Wiklander {
432432b31808SJens Wiklander     int ret = 0;
432532b31808SJens Wiklander 
432632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("server state: %d", ssl->state));
432732b31808SJens Wiklander 
432832b31808SJens Wiklander     switch (ssl->state) {
432932b31808SJens Wiklander         case MBEDTLS_SSL_HELLO_REQUEST:
433032b31808SJens Wiklander             ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
433132b31808SJens Wiklander             break;
433232b31808SJens Wiklander 
433332b31808SJens Wiklander         /*
433432b31808SJens Wiklander          *  <==   ClientHello
433532b31808SJens Wiklander          */
433632b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_HELLO:
433732b31808SJens Wiklander             ret = ssl_parse_client_hello(ssl);
433832b31808SJens Wiklander             break;
433932b31808SJens Wiklander 
434032b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
434132b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT:
434232b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED;
434332b31808SJens Wiklander #endif
434432b31808SJens Wiklander 
434532b31808SJens Wiklander         /*
434632b31808SJens Wiklander          *  ==>   ServerHello
434732b31808SJens Wiklander          *        Certificate
434832b31808SJens Wiklander          *      ( ServerKeyExchange  )
434932b31808SJens Wiklander          *      ( CertificateRequest )
435032b31808SJens Wiklander          *        ServerHelloDone
435132b31808SJens Wiklander          */
435232b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_HELLO:
435332b31808SJens Wiklander             ret = ssl_write_server_hello(ssl);
435432b31808SJens Wiklander             break;
435532b31808SJens Wiklander 
435632b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_CERTIFICATE:
435732b31808SJens Wiklander             ret = mbedtls_ssl_write_certificate(ssl);
435832b31808SJens Wiklander             break;
435932b31808SJens Wiklander 
436032b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
436132b31808SJens Wiklander             ret = ssl_write_server_key_exchange(ssl);
436232b31808SJens Wiklander             break;
436332b31808SJens Wiklander 
436432b31808SJens Wiklander         case MBEDTLS_SSL_CERTIFICATE_REQUEST:
436532b31808SJens Wiklander             ret = ssl_write_certificate_request(ssl);
436632b31808SJens Wiklander             break;
436732b31808SJens Wiklander 
436832b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_HELLO_DONE:
436932b31808SJens Wiklander             ret = ssl_write_server_hello_done(ssl);
437032b31808SJens Wiklander             break;
437132b31808SJens Wiklander 
437232b31808SJens Wiklander         /*
437332b31808SJens Wiklander          *  <== ( Certificate/Alert  )
437432b31808SJens Wiklander          *        ClientKeyExchange
437532b31808SJens Wiklander          *      ( CertificateVerify  )
437632b31808SJens Wiklander          *        ChangeCipherSpec
437732b31808SJens Wiklander          *        Finished
437832b31808SJens Wiklander          */
437932b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_CERTIFICATE:
438032b31808SJens Wiklander             ret = mbedtls_ssl_parse_certificate(ssl);
438132b31808SJens Wiklander             break;
438232b31808SJens Wiklander 
438332b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
438432b31808SJens Wiklander             ret = ssl_parse_client_key_exchange(ssl);
438532b31808SJens Wiklander             break;
438632b31808SJens Wiklander 
438732b31808SJens Wiklander         case MBEDTLS_SSL_CERTIFICATE_VERIFY:
438832b31808SJens Wiklander             ret = ssl_parse_certificate_verify(ssl);
438932b31808SJens Wiklander             break;
439032b31808SJens Wiklander 
439132b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
439232b31808SJens Wiklander             ret = mbedtls_ssl_parse_change_cipher_spec(ssl);
439332b31808SJens Wiklander             break;
439432b31808SJens Wiklander 
439532b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_FINISHED:
439632b31808SJens Wiklander             ret = mbedtls_ssl_parse_finished(ssl);
439732b31808SJens Wiklander             break;
439832b31808SJens Wiklander 
439932b31808SJens Wiklander         /*
440032b31808SJens Wiklander          *  ==> ( NewSessionTicket )
440132b31808SJens Wiklander          *        ChangeCipherSpec
440232b31808SJens Wiklander          *        Finished
440332b31808SJens Wiklander          */
440432b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
440532b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
440632b31808SJens Wiklander             if (ssl->handshake->new_session_ticket != 0) {
440732b31808SJens Wiklander                 ret = ssl_write_new_session_ticket(ssl);
440832b31808SJens Wiklander             } else
440932b31808SJens Wiklander #endif
441032b31808SJens Wiklander             ret = mbedtls_ssl_write_change_cipher_spec(ssl);
441132b31808SJens Wiklander             break;
441232b31808SJens Wiklander 
441332b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_FINISHED:
441432b31808SJens Wiklander             ret = mbedtls_ssl_write_finished(ssl);
441532b31808SJens Wiklander             break;
441632b31808SJens Wiklander 
441732b31808SJens Wiklander         case MBEDTLS_SSL_FLUSH_BUFFERS:
441832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done"));
441932b31808SJens Wiklander             ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
442032b31808SJens Wiklander             break;
442132b31808SJens Wiklander 
442232b31808SJens Wiklander         case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
442332b31808SJens Wiklander             mbedtls_ssl_handshake_wrapup(ssl);
442432b31808SJens Wiklander             break;
442532b31808SJens Wiklander 
442632b31808SJens Wiklander         default:
442732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("invalid state %d", ssl->state));
442832b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
442932b31808SJens Wiklander     }
443032b31808SJens Wiklander 
443132b31808SJens Wiklander     return ret;
443232b31808SJens Wiklander }
443332b31808SJens Wiklander 
443432b31808SJens Wiklander void mbedtls_ssl_conf_preference_order(mbedtls_ssl_config *conf, int order)
443532b31808SJens Wiklander {
443632b31808SJens Wiklander     conf->respect_cli_pref = order;
443732b31808SJens Wiklander }
443832b31808SJens Wiklander 
443932b31808SJens Wiklander #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_PROTO_TLS1_2 */
4440