xref: /optee_os/lib/libmbedtls/mbedtls/library/ssl_tls12_server.c (revision 273a583ea99627ff3b8ccbbaedbdacecd0909b2e)
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)
local_err_translation(psa_status_t status)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)
mbedtls_ssl_set_client_transport_id(mbedtls_ssl_context * ssl,const unsigned char * info,size_t ilen)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 
mbedtls_ssl_conf_dtls_cookies(mbedtls_ssl_config * conf,mbedtls_ssl_cookie_write_t * f_cookie_write,mbedtls_ssl_cookie_check_t * f_cookie_check,void * p_cookie)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
ssl_conf_has_psk_or_cb(mbedtls_ssl_config const * conf)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
ssl_parse_renegotiation_info(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)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
ssl_parse_supported_groups_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)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
ssl_parse_supported_point_formats(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)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
ssl_parse_ecjpake_kkpp(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)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
ssl_parse_max_fragment_length_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)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
ssl_parse_cid_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)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
ssl_parse_encrypt_then_mac_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)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
ssl_parse_extended_ms_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)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
ssl_parse_session_ticket_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t len)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
ssl_parse_use_srtp_ext(mbedtls_ssl_context * ssl,const unsigned char * buf,size_t len)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
ssl_check_key_curve(mbedtls_pk_context * pk,uint16_t * curves_tls_id)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
ssl_pick_cert(mbedtls_ssl_context * ssl,const mbedtls_ssl_ciphersuite_t * ciphersuite_info)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,
759cb034002SJerome Forissier                                          MBEDTLS_SSL_IS_CLIENT,
760cb034002SJerome Forissier                                          MBEDTLS_SSL_VERSION_TLS1_2,
761cb034002SJerome 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
ssl_ciphersuite_match(mbedtls_ssl_context * ssl,int suite_id,const mbedtls_ssl_ciphersuite_t ** ciphersuite_info)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
ssl_parse_client_hello(mbedtls_ssl_context * ssl)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 #if defined(MBEDTLS_SSL_PROTO_DTLS)
106232b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
106332b31808SJens Wiklander         /*
106432b31808SJens Wiklander          * Copy the client's handshake message_seq on initial handshakes,
106532b31808SJens Wiklander          * check sequence number on renego.
106632b31808SJens Wiklander          */
106732b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
106832b31808SJens Wiklander         if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
106932b31808SJens Wiklander             /* This couldn't be done in ssl_prepare_handshake_record() */
1070b0563631STom Van Eyck             unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
107132b31808SJens Wiklander             if (cli_msg_seq != ssl->handshake->in_msg_seq) {
107232b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message_seq: "
107332b31808SJens Wiklander                                           "%u (expected %u)", cli_msg_seq,
107432b31808SJens Wiklander                                           ssl->handshake->in_msg_seq));
107532b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_DECODE_ERROR;
107632b31808SJens Wiklander             }
107732b31808SJens Wiklander 
107832b31808SJens Wiklander             ssl->handshake->in_msg_seq++;
107932b31808SJens Wiklander         } else
108032b31808SJens Wiklander #endif
108132b31808SJens Wiklander         {
1082b0563631STom Van Eyck             unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4);
108332b31808SJens Wiklander             ssl->handshake->out_msg_seq = cli_msg_seq;
108432b31808SJens Wiklander             ssl->handshake->in_msg_seq  = cli_msg_seq + 1;
108532b31808SJens Wiklander         }
108632b31808SJens Wiklander         {
108732b31808SJens Wiklander             /*
108832b31808SJens Wiklander              * For now we don't support fragmentation, so make sure
108932b31808SJens Wiklander              * fragment_offset == 0 and fragment_length == length
109032b31808SJens Wiklander              */
109132b31808SJens Wiklander             size_t fragment_offset, fragment_length, length;
109232b31808SJens Wiklander             fragment_offset = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 6);
109332b31808SJens Wiklander             fragment_length = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 9);
109432b31808SJens Wiklander             length = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 1);
109532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(
109632b31808SJens Wiklander                 4, ("fragment_offset=%u fragment_length=%u length=%u",
109732b31808SJens Wiklander                     (unsigned) fragment_offset, (unsigned) fragment_length,
109832b31808SJens Wiklander                     (unsigned) length));
109932b31808SJens Wiklander             if (fragment_offset != 0 || length != fragment_length) {
110032b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1, ("ClientHello fragmentation not supported"));
110132b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
110232b31808SJens Wiklander             }
110332b31808SJens Wiklander         }
110432b31808SJens Wiklander     }
110532b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */
110632b31808SJens Wiklander 
110732b31808SJens Wiklander     buf += mbedtls_ssl_hs_hdr_len(ssl);
110832b31808SJens Wiklander     msg_len -= mbedtls_ssl_hs_hdr_len(ssl);
110932b31808SJens Wiklander 
111032b31808SJens Wiklander     /*
1111b0563631STom Van Eyck      * ClientHello layout:
111232b31808SJens Wiklander      *     0  .   1   protocol version
111332b31808SJens Wiklander      *     2  .  33   random bytes (starting with 4 bytes of Unix time)
1114b0563631STom Van Eyck      *    34  .  34   session id length (1 byte)
1115b0563631STom Van Eyck      *    35  . 34+x  session id, where x = session id length from byte 34
111632b31808SJens Wiklander      *   35+x . 35+x  DTLS only: cookie length (1 byte)
111732b31808SJens Wiklander      *   36+x .  ..   DTLS only: cookie
111832b31808SJens Wiklander      *    ..  .  ..   ciphersuite list length (2 bytes)
111932b31808SJens Wiklander      *    ..  .  ..   ciphersuite list
112032b31808SJens Wiklander      *    ..  .  ..   compression alg. list length (1 byte)
112132b31808SJens Wiklander      *    ..  .  ..   compression alg. list
112232b31808SJens Wiklander      *    ..  .  ..   extensions length (2 bytes, optional)
112332b31808SJens Wiklander      *    ..  .  ..   extensions (optional)
112432b31808SJens Wiklander      */
112532b31808SJens Wiklander 
112632b31808SJens Wiklander     /*
112732b31808SJens Wiklander      * Minimal length (with everything empty and extensions omitted) is
112832b31808SJens Wiklander      * 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can
112932b31808SJens Wiklander      * read at least up to session id length without worrying.
113032b31808SJens Wiklander      */
113132b31808SJens Wiklander     if (msg_len < 38) {
113232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
113332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
113432b31808SJens Wiklander     }
113532b31808SJens Wiklander 
113632b31808SJens Wiklander     /*
113732b31808SJens Wiklander      * Check and save the protocol version
113832b31808SJens Wiklander      */
113932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, version", buf, 2);
114032b31808SJens Wiklander 
1141b0563631STom Van Eyck     ssl->tls_version = (mbedtls_ssl_protocol_version) mbedtls_ssl_read_version(buf,
1142b0563631STom Van Eyck                                                                                ssl->conf->transport);
114332b31808SJens Wiklander     ssl->session_negotiate->tls_version = ssl->tls_version;
1144b0563631STom Van Eyck     ssl->session_negotiate->endpoint = ssl->conf->endpoint;
114532b31808SJens Wiklander 
114632b31808SJens Wiklander     if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_2) {
114732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("server only supports TLS 1.2"));
114832b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
114932b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION);
115032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION;
115132b31808SJens Wiklander     }
115232b31808SJens Wiklander 
115332b31808SJens Wiklander     /*
115432b31808SJens Wiklander      * Save client random (inc. Unix time)
115532b31808SJens Wiklander      */
115632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, random bytes", buf + 2, 32);
115732b31808SJens Wiklander 
115832b31808SJens Wiklander     memcpy(ssl->handshake->randbytes, buf + 2, 32);
115932b31808SJens Wiklander 
116032b31808SJens Wiklander     /*
116132b31808SJens Wiklander      * Check the session ID length and save session ID
116232b31808SJens Wiklander      */
116332b31808SJens Wiklander     sess_len = buf[34];
116432b31808SJens Wiklander 
116532b31808SJens Wiklander     if (sess_len > sizeof(ssl->session_negotiate->id) ||
116632b31808SJens Wiklander         sess_len + 34 + 2 > msg_len) { /* 2 for cipherlist length field */
116732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
116832b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
116932b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
117032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
117132b31808SJens Wiklander     }
117232b31808SJens Wiklander 
117332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, session id", buf + 35, sess_len);
117432b31808SJens Wiklander 
117532b31808SJens Wiklander     ssl->session_negotiate->id_len = sess_len;
117632b31808SJens Wiklander     memset(ssl->session_negotiate->id, 0,
117732b31808SJens Wiklander            sizeof(ssl->session_negotiate->id));
117832b31808SJens Wiklander     memcpy(ssl->session_negotiate->id, buf + 35,
117932b31808SJens Wiklander            ssl->session_negotiate->id_len);
118032b31808SJens Wiklander 
118132b31808SJens Wiklander     /*
118232b31808SJens Wiklander      * Check the cookie length and content
118332b31808SJens Wiklander      */
118432b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
118532b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
118632b31808SJens Wiklander         cookie_offset = 35 + sess_len;
118732b31808SJens Wiklander         cookie_len = buf[cookie_offset];
118832b31808SJens Wiklander 
118932b31808SJens Wiklander         if (cookie_offset + 1 + cookie_len + 2 > msg_len) {
119032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
119132b31808SJens Wiklander             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
119232b31808SJens Wiklander                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
119332b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
119432b31808SJens Wiklander         }
119532b31808SJens Wiklander 
119632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "client hello, cookie",
119732b31808SJens Wiklander                               buf + cookie_offset + 1, cookie_len);
119832b31808SJens Wiklander 
119932b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
120032b31808SJens Wiklander         if (ssl->conf->f_cookie_check != NULL
120132b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
120232b31808SJens Wiklander             && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE
120332b31808SJens Wiklander #endif
120432b31808SJens Wiklander             ) {
120532b31808SJens Wiklander             if (ssl->conf->f_cookie_check(ssl->conf->p_cookie,
120632b31808SJens Wiklander                                           buf + cookie_offset + 1, cookie_len,
120732b31808SJens Wiklander                                           ssl->cli_id, ssl->cli_id_len) != 0) {
120832b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(2, ("cookie verification failed"));
120932b31808SJens Wiklander                 ssl->handshake->cookie_verify_result = 1;
121032b31808SJens Wiklander             } else {
121132b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(2, ("cookie verification passed"));
121232b31808SJens Wiklander                 ssl->handshake->cookie_verify_result = 0;
121332b31808SJens Wiklander             }
121432b31808SJens Wiklander         } else
121532b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
121632b31808SJens Wiklander         {
121732b31808SJens Wiklander             /* We know we didn't send a cookie, so it should be empty */
121832b31808SJens Wiklander             if (cookie_len != 0) {
121932b31808SJens Wiklander                 /* This may be an attacker's probe, so don't send an alert */
122032b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
122132b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_DECODE_ERROR;
122232b31808SJens Wiklander             }
122332b31808SJens Wiklander 
122432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2, ("cookie verification skipped"));
122532b31808SJens Wiklander         }
122632b31808SJens Wiklander 
122732b31808SJens Wiklander         /*
122832b31808SJens Wiklander          * Check the ciphersuitelist length (will be parsed later)
122932b31808SJens Wiklander          */
123032b31808SJens Wiklander         ciph_offset = cookie_offset + 1 + cookie_len;
123132b31808SJens Wiklander     } else
123232b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */
123332b31808SJens Wiklander     ciph_offset = 35 + sess_len;
123432b31808SJens Wiklander 
1235b0563631STom Van Eyck     ciph_len = MBEDTLS_GET_UINT16_BE(buf, ciph_offset);
123632b31808SJens Wiklander 
123732b31808SJens Wiklander     if (ciph_len < 2 ||
123832b31808SJens Wiklander         ciph_len + 2 + ciph_offset + 1 > msg_len || /* 1 for comp. alg. len */
123932b31808SJens Wiklander         (ciph_len % 2) != 0) {
124032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
124132b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
124232b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
124332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
124432b31808SJens Wiklander     }
124532b31808SJens Wiklander 
124632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "client hello, ciphersuitelist",
124732b31808SJens Wiklander                           buf + ciph_offset + 2,  ciph_len);
124832b31808SJens Wiklander 
124932b31808SJens Wiklander     /*
125032b31808SJens Wiklander      * Check the compression algorithm's length.
125132b31808SJens Wiklander      * The list contents are ignored because implementing
125232b31808SJens Wiklander      * MBEDTLS_SSL_COMPRESS_NULL is mandatory and is the only
125332b31808SJens Wiklander      * option supported by Mbed TLS.
125432b31808SJens Wiklander      */
125532b31808SJens Wiklander     comp_offset = ciph_offset + 2 + ciph_len;
125632b31808SJens Wiklander 
125732b31808SJens Wiklander     comp_len = buf[comp_offset];
125832b31808SJens Wiklander 
125932b31808SJens Wiklander     if (comp_len < 1 ||
126032b31808SJens Wiklander         comp_len > 16 ||
126132b31808SJens Wiklander         comp_len + comp_offset + 1 > msg_len) {
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, compression",
126932b31808SJens Wiklander                           buf + comp_offset + 1, comp_len);
127032b31808SJens Wiklander 
127132b31808SJens Wiklander     /*
127232b31808SJens Wiklander      * Check the extension length
127332b31808SJens Wiklander      */
127432b31808SJens Wiklander     ext_offset = comp_offset + 1 + comp_len;
127532b31808SJens Wiklander     if (msg_len > ext_offset) {
127632b31808SJens Wiklander         if (msg_len < ext_offset + 2) {
127732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
127832b31808SJens Wiklander             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
127932b31808SJens Wiklander                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
128032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
128132b31808SJens Wiklander         }
128232b31808SJens Wiklander 
1283b0563631STom Van Eyck         ext_len = MBEDTLS_GET_UINT16_BE(buf, ext_offset);
128432b31808SJens Wiklander 
128532b31808SJens Wiklander         if (msg_len != ext_offset + 2 + ext_len) {
128632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
128732b31808SJens Wiklander             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
128832b31808SJens Wiklander                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
128932b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
129032b31808SJens Wiklander         }
129132b31808SJens Wiklander     } else {
129232b31808SJens Wiklander         ext_len = 0;
129332b31808SJens Wiklander     }
129432b31808SJens Wiklander 
129532b31808SJens Wiklander     ext = buf + ext_offset + 2;
129632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "client hello extensions", ext, ext_len);
129732b31808SJens Wiklander 
129832b31808SJens Wiklander     while (ext_len != 0) {
129932b31808SJens Wiklander         unsigned int ext_id;
130032b31808SJens Wiklander         unsigned int ext_size;
130132b31808SJens Wiklander         if (ext_len < 4) {
130232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
130332b31808SJens Wiklander             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
130432b31808SJens Wiklander                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
130532b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
130632b31808SJens Wiklander         }
1307b0563631STom Van Eyck         ext_id   = MBEDTLS_GET_UINT16_BE(ext, 0);
1308b0563631STom Van Eyck         ext_size = MBEDTLS_GET_UINT16_BE(ext, 2);
130932b31808SJens Wiklander 
131032b31808SJens Wiklander         if (ext_size + 4 > ext_len) {
131132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message"));
131232b31808SJens Wiklander             mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
131332b31808SJens Wiklander                                            MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR);
131432b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
131532b31808SJens Wiklander         }
131632b31808SJens Wiklander         switch (ext_id) {
131732b31808SJens Wiklander #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
131832b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SERVERNAME:
131932b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found ServerName extension"));
132032b31808SJens Wiklander                 ret = mbedtls_ssl_parse_server_name_ext(ssl, ext + 4,
132132b31808SJens Wiklander                                                         ext + 4 + ext_size);
132232b31808SJens Wiklander                 if (ret != 0) {
132332b31808SJens Wiklander                     return ret;
132432b31808SJens Wiklander                 }
132532b31808SJens Wiklander                 break;
132632b31808SJens Wiklander #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
132732b31808SJens Wiklander 
132832b31808SJens Wiklander             case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
132932b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found renegotiation extension"));
133032b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
133132b31808SJens Wiklander                 renegotiation_info_seen = 1;
133232b31808SJens Wiklander #endif
133332b31808SJens Wiklander 
133432b31808SJens Wiklander                 ret = ssl_parse_renegotiation_info(ssl, ext + 4, ext_size);
133532b31808SJens Wiklander                 if (ret != 0) {
133632b31808SJens Wiklander                     return ret;
133732b31808SJens Wiklander                 }
133832b31808SJens Wiklander                 break;
133932b31808SJens Wiklander 
134032b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
134132b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SIG_ALG:
134232b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found signature_algorithms extension"));
134332b31808SJens Wiklander 
134432b31808SJens Wiklander                 ret = mbedtls_ssl_parse_sig_alg_ext(ssl, ext + 4, ext + 4 + ext_size);
134532b31808SJens Wiklander                 if (ret != 0) {
134632b31808SJens Wiklander                     return ret;
134732b31808SJens Wiklander                 }
134832b31808SJens Wiklander 
134932b31808SJens Wiklander                 sig_hash_alg_ext_present = 1;
135032b31808SJens Wiklander                 break;
135132b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
135232b31808SJens Wiklander 
1353b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
1354b0563631STom Van Eyck                 defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
135532b31808SJens Wiklander                 defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
135632b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SUPPORTED_GROUPS:
135732b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found supported elliptic curves extension"));
135832b31808SJens Wiklander 
135932b31808SJens Wiklander                 ret = ssl_parse_supported_groups_ext(ssl, ext + 4, ext_size);
136032b31808SJens Wiklander                 if (ret != 0) {
136132b31808SJens Wiklander                     return ret;
136232b31808SJens Wiklander                 }
136332b31808SJens Wiklander                 break;
136432b31808SJens Wiklander 
136532b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
136632b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found supported point formats extension"));
136732b31808SJens Wiklander                 ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT;
136832b31808SJens Wiklander 
136932b31808SJens Wiklander                 ret = ssl_parse_supported_point_formats(ssl, ext + 4, ext_size);
137032b31808SJens Wiklander                 if (ret != 0) {
137132b31808SJens Wiklander                     return ret;
137232b31808SJens Wiklander                 }
137332b31808SJens Wiklander                 break;
1374b0563631STom Van Eyck #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || \
1375b0563631STom Van Eyck           MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED ||
137632b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
137732b31808SJens Wiklander 
137832b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
137932b31808SJens Wiklander             case MBEDTLS_TLS_EXT_ECJPAKE_KKPP:
138032b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found ecjpake kkpp extension"));
138132b31808SJens Wiklander 
138232b31808SJens Wiklander                 ret = ssl_parse_ecjpake_kkpp(ssl, ext + 4, ext_size);
138332b31808SJens Wiklander                 if (ret != 0) {
138432b31808SJens Wiklander                     return ret;
138532b31808SJens Wiklander                 }
138632b31808SJens Wiklander                 break;
138732b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
138832b31808SJens Wiklander 
138932b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
139032b31808SJens Wiklander             case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
139132b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found max fragment length extension"));
139232b31808SJens Wiklander 
139332b31808SJens Wiklander                 ret = ssl_parse_max_fragment_length_ext(ssl, ext + 4, ext_size);
139432b31808SJens Wiklander                 if (ret != 0) {
139532b31808SJens Wiklander                     return ret;
139632b31808SJens Wiklander                 }
139732b31808SJens Wiklander                 break;
139832b31808SJens Wiklander #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
139932b31808SJens Wiklander 
140032b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
140132b31808SJens Wiklander             case MBEDTLS_TLS_EXT_CID:
140232b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found CID extension"));
140332b31808SJens Wiklander 
140432b31808SJens Wiklander                 ret = ssl_parse_cid_ext(ssl, ext + 4, ext_size);
140532b31808SJens Wiklander                 if (ret != 0) {
140632b31808SJens Wiklander                     return ret;
140732b31808SJens Wiklander                 }
140832b31808SJens Wiklander                 break;
140932b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
141032b31808SJens Wiklander 
141132b31808SJens Wiklander #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
141232b31808SJens Wiklander             case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
141332b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found encrypt then mac extension"));
141432b31808SJens Wiklander 
141532b31808SJens Wiklander                 ret = ssl_parse_encrypt_then_mac_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_ENCRYPT_THEN_MAC */
142132b31808SJens Wiklander 
142232b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
142332b31808SJens Wiklander             case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
142432b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found extended master secret extension"));
142532b31808SJens Wiklander 
142632b31808SJens Wiklander                 ret = ssl_parse_extended_ms_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_EXTENDED_MASTER_SECRET */
143232b31808SJens Wiklander 
143332b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
143432b31808SJens Wiklander             case MBEDTLS_TLS_EXT_SESSION_TICKET:
143532b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found session ticket extension"));
143632b31808SJens Wiklander 
143732b31808SJens Wiklander                 ret = ssl_parse_session_ticket_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_SESSION_TICKETS */
144332b31808SJens Wiklander 
144432b31808SJens Wiklander #if defined(MBEDTLS_SSL_ALPN)
144532b31808SJens Wiklander             case MBEDTLS_TLS_EXT_ALPN:
144632b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found alpn extension"));
144732b31808SJens Wiklander 
144832b31808SJens Wiklander                 ret = mbedtls_ssl_parse_alpn_ext(ssl, ext + 4,
144932b31808SJens Wiklander                                                  ext + 4 + ext_size);
145032b31808SJens Wiklander                 if (ret != 0) {
145132b31808SJens Wiklander                     return ret;
145232b31808SJens Wiklander                 }
145332b31808SJens Wiklander                 break;
145432b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
145532b31808SJens Wiklander 
145632b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP)
145732b31808SJens Wiklander             case MBEDTLS_TLS_EXT_USE_SRTP:
145832b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("found use_srtp extension"));
145932b31808SJens Wiklander 
146032b31808SJens Wiklander                 ret = ssl_parse_use_srtp_ext(ssl, ext + 4, ext_size);
146132b31808SJens Wiklander                 if (ret != 0) {
146232b31808SJens Wiklander                     return ret;
146332b31808SJens Wiklander                 }
146432b31808SJens Wiklander                 break;
146532b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_SRTP */
146632b31808SJens Wiklander 
146732b31808SJens Wiklander             default:
146832b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(3, ("unknown extension found: %u (ignoring)",
146932b31808SJens Wiklander                                           ext_id));
147032b31808SJens Wiklander         }
147132b31808SJens Wiklander 
147232b31808SJens Wiklander         ext_len -= 4 + ext_size;
147332b31808SJens Wiklander         ext += 4 + ext_size;
147432b31808SJens Wiklander     }
147532b31808SJens Wiklander 
147632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
147732b31808SJens Wiklander 
147832b31808SJens Wiklander     /*
147932b31808SJens Wiklander      * Try to fall back to default hash SHA1 if the client
148032b31808SJens Wiklander      * hasn't provided any preferred signature-hash combinations.
148132b31808SJens Wiklander      */
148232b31808SJens Wiklander     if (!sig_hash_alg_ext_present) {
148332b31808SJens Wiklander         uint16_t *received_sig_algs = ssl->handshake->received_sig_algs;
148432b31808SJens Wiklander         const uint16_t default_sig_algs[] = {
1485b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
148632b31808SJens Wiklander             MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA,
148732b31808SJens Wiklander                                                MBEDTLS_SSL_HASH_SHA1),
148832b31808SJens Wiklander #endif
148932b31808SJens Wiklander #if defined(MBEDTLS_RSA_C)
149032b31808SJens Wiklander             MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA,
149132b31808SJens Wiklander                                                MBEDTLS_SSL_HASH_SHA1),
149232b31808SJens Wiklander #endif
149332b31808SJens Wiklander             MBEDTLS_TLS_SIG_NONE
149432b31808SJens Wiklander         };
149532b31808SJens Wiklander 
149632b31808SJens Wiklander         MBEDTLS_STATIC_ASSERT(sizeof(default_sig_algs) / sizeof(default_sig_algs[0])
149732b31808SJens Wiklander                               <= MBEDTLS_RECEIVED_SIG_ALGS_SIZE,
149832b31808SJens Wiklander                               "default_sig_algs is too big");
149932b31808SJens Wiklander 
150032b31808SJens Wiklander         memcpy(received_sig_algs, default_sig_algs, sizeof(default_sig_algs));
150132b31808SJens Wiklander     }
150232b31808SJens Wiklander 
150332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
150432b31808SJens Wiklander 
150532b31808SJens Wiklander     /*
150632b31808SJens Wiklander      * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
150732b31808SJens Wiklander      */
150832b31808SJens Wiklander     for (i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2) {
150932b31808SJens Wiklander         if (p[0] == 0 && p[1] == MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO) {
151032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3, ("received TLS_EMPTY_RENEGOTIATION_INFO "));
151132b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
151232b31808SJens Wiklander             if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) {
151332b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1, ("received RENEGOTIATION SCSV "
151432b31808SJens Wiklander                                           "during renegotiation"));
151532b31808SJens Wiklander                 mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
151632b31808SJens Wiklander                                                MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
151732b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
151832b31808SJens Wiklander             }
151932b31808SJens Wiklander #endif
152032b31808SJens Wiklander             ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION;
152132b31808SJens Wiklander             break;
152232b31808SJens Wiklander         }
152332b31808SJens Wiklander     }
152432b31808SJens Wiklander 
152532b31808SJens Wiklander     /*
152632b31808SJens Wiklander      * Renegotiation security checks
152732b31808SJens Wiklander      */
152832b31808SJens Wiklander     if (ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION &&
152932b31808SJens Wiklander         ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE) {
153032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("legacy renegotiation, breaking off handshake"));
153132b31808SJens Wiklander         handshake_failure = 1;
153232b31808SJens Wiklander     }
153332b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
153432b31808SJens Wiklander     else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
153532b31808SJens Wiklander              ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION &&
153632b31808SJens Wiklander              renegotiation_info_seen == 0) {
153732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("renegotiation_info extension missing (secure)"));
153832b31808SJens Wiklander         handshake_failure = 1;
153932b31808SJens Wiklander     } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
154032b31808SJens Wiklander                ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
154132b31808SJens Wiklander                ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION) {
154232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("legacy renegotiation not allowed"));
154332b31808SJens Wiklander         handshake_failure = 1;
154432b31808SJens Wiklander     } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
154532b31808SJens Wiklander                ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
154632b31808SJens Wiklander                renegotiation_info_seen == 1) {
154732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("renegotiation_info extension present (legacy)"));
154832b31808SJens Wiklander         handshake_failure = 1;
154932b31808SJens Wiklander     }
155032b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */
155132b31808SJens Wiklander 
155232b31808SJens Wiklander     if (handshake_failure == 1) {
155332b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
155432b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
155532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
155632b31808SJens Wiklander     }
155732b31808SJens Wiklander 
155832b31808SJens Wiklander     /*
155932b31808SJens Wiklander      * Server certification selection (after processing TLS extensions)
156032b31808SJens Wiklander      */
156132b31808SJens Wiklander     if (ssl->conf->f_cert_cb && (ret = ssl->conf->f_cert_cb(ssl)) != 0) {
156232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "f_cert_cb", ret);
156332b31808SJens Wiklander         return ret;
156432b31808SJens Wiklander     }
156532b31808SJens Wiklander #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
156632b31808SJens Wiklander     ssl->handshake->sni_name = NULL;
156732b31808SJens Wiklander     ssl->handshake->sni_name_len = 0;
156832b31808SJens Wiklander #endif
156932b31808SJens Wiklander 
157032b31808SJens Wiklander     /*
157132b31808SJens Wiklander      * Search for a matching ciphersuite
157232b31808SJens Wiklander      * (At the end because we need information from the EC-based extensions
157332b31808SJens Wiklander      * and certificate from the SNI callback triggered by the SNI extension
157432b31808SJens Wiklander      * or certificate from server certificate selection callback.)
157532b31808SJens Wiklander      */
157632b31808SJens Wiklander     got_common_suite = 0;
157732b31808SJens Wiklander     ciphersuites = ssl->conf->ciphersuite_list;
157832b31808SJens Wiklander     ciphersuite_info = NULL;
157932b31808SJens Wiklander 
158032b31808SJens Wiklander     if (ssl->conf->respect_cli_pref == MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT) {
158132b31808SJens Wiklander         for (j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2) {
158232b31808SJens Wiklander             for (i = 0; ciphersuites[i] != 0; i++) {
158332b31808SJens Wiklander                 if (MBEDTLS_GET_UINT16_BE(p, 0) != ciphersuites[i]) {
158432b31808SJens Wiklander                     continue;
158532b31808SJens Wiklander                 }
158632b31808SJens Wiklander 
158732b31808SJens Wiklander                 got_common_suite = 1;
158832b31808SJens Wiklander 
158932b31808SJens Wiklander                 if ((ret = ssl_ciphersuite_match(ssl, ciphersuites[i],
159032b31808SJens Wiklander                                                  &ciphersuite_info)) != 0) {
159132b31808SJens Wiklander                     return ret;
159232b31808SJens Wiklander                 }
159332b31808SJens Wiklander 
159432b31808SJens Wiklander                 if (ciphersuite_info != NULL) {
159532b31808SJens Wiklander                     goto have_ciphersuite;
159632b31808SJens Wiklander                 }
159732b31808SJens Wiklander             }
159832b31808SJens Wiklander         }
159932b31808SJens Wiklander     } else {
160032b31808SJens Wiklander         for (i = 0; ciphersuites[i] != 0; i++) {
160132b31808SJens Wiklander             for (j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2) {
160232b31808SJens Wiklander                 if (MBEDTLS_GET_UINT16_BE(p, 0) != ciphersuites[i]) {
160332b31808SJens Wiklander                     continue;
160432b31808SJens Wiklander                 }
160532b31808SJens Wiklander 
160632b31808SJens Wiklander                 got_common_suite = 1;
160732b31808SJens Wiklander 
160832b31808SJens Wiklander                 if ((ret = ssl_ciphersuite_match(ssl, ciphersuites[i],
160932b31808SJens Wiklander                                                  &ciphersuite_info)) != 0) {
161032b31808SJens Wiklander                     return ret;
161132b31808SJens Wiklander                 }
161232b31808SJens Wiklander 
161332b31808SJens Wiklander                 if (ciphersuite_info != NULL) {
161432b31808SJens Wiklander                     goto have_ciphersuite;
161532b31808SJens Wiklander                 }
161632b31808SJens Wiklander             }
161732b31808SJens Wiklander         }
161832b31808SJens Wiklander     }
161932b31808SJens Wiklander 
162032b31808SJens Wiklander     if (got_common_suite) {
162132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got ciphersuites in common, "
162232b31808SJens Wiklander                                   "but none of them usable"));
162332b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
162432b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
162532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
162632b31808SJens Wiklander     } else {
162732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got no ciphersuites in common"));
162832b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
162932b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
163032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
163132b31808SJens Wiklander     }
163232b31808SJens Wiklander 
163332b31808SJens Wiklander have_ciphersuite:
163432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("selected ciphersuite: %s", ciphersuite_info->name));
163532b31808SJens Wiklander 
163632b31808SJens Wiklander     ssl->session_negotiate->ciphersuite = ciphersuites[i];
163732b31808SJens Wiklander     ssl->handshake->ciphersuite_info = ciphersuite_info;
163832b31808SJens Wiklander 
1639*273a583eSThomas Bourgoin     mbedtls_ssl_handshake_increment_state(ssl);
164032b31808SJens Wiklander 
164132b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
164232b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
164332b31808SJens Wiklander         mbedtls_ssl_recv_flight_completed(ssl);
164432b31808SJens Wiklander     }
164532b31808SJens Wiklander #endif
164632b31808SJens Wiklander 
164732b31808SJens Wiklander     /* Debugging-only output for testsuite */
164832b31808SJens Wiklander #if defined(MBEDTLS_DEBUG_C)                         && \
164932b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
165032b31808SJens Wiklander     mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_alg(ciphersuite_info);
165132b31808SJens Wiklander     if (sig_alg != MBEDTLS_PK_NONE) {
165232b31808SJens Wiklander         unsigned int sig_hash = mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
165332b31808SJens Wiklander             ssl, mbedtls_ssl_sig_from_pk_alg(sig_alg));
165432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("client hello v3, signature_algorithm ext: %u",
165532b31808SJens Wiklander                                   sig_hash));
165632b31808SJens Wiklander     } else {
165732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("no hash algorithm for signature algorithm "
165832b31808SJens Wiklander                                   "%u - should not happen", (unsigned) sig_alg));
165932b31808SJens Wiklander     }
166032b31808SJens Wiklander #endif
166132b31808SJens Wiklander 
166232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse client hello"));
166332b31808SJens Wiklander 
166432b31808SJens Wiklander     return 0;
166532b31808SJens Wiklander }
166632b31808SJens Wiklander 
166732b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
ssl_write_cid_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t * olen)166832b31808SJens Wiklander static void ssl_write_cid_ext(mbedtls_ssl_context *ssl,
166932b31808SJens Wiklander                               unsigned char *buf,
167032b31808SJens Wiklander                               size_t *olen)
167132b31808SJens Wiklander {
167232b31808SJens Wiklander     unsigned char *p = buf;
167332b31808SJens Wiklander     size_t ext_len;
167432b31808SJens Wiklander     const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
167532b31808SJens Wiklander 
167632b31808SJens Wiklander     *olen = 0;
167732b31808SJens Wiklander 
167832b31808SJens Wiklander     /* Skip writing the extension if we don't want to use it or if
167932b31808SJens Wiklander      * the client hasn't offered it. */
168032b31808SJens Wiklander     if (ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_DISABLED) {
168132b31808SJens Wiklander         return;
168232b31808SJens Wiklander     }
168332b31808SJens Wiklander 
168432b31808SJens Wiklander     /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX
168532b31808SJens Wiklander      * which is at most 255, so the increment cannot overflow. */
168632b31808SJens Wiklander     if (end < p || (size_t) (end - p) < (unsigned) (ssl->own_cid_len + 5)) {
168732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small"));
168832b31808SJens Wiklander         return;
168932b31808SJens Wiklander     }
169032b31808SJens Wiklander 
169132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding CID extension"));
169232b31808SJens Wiklander 
169332b31808SJens Wiklander     /*
169432b31808SJens Wiklander      *   struct {
169532b31808SJens Wiklander      *      opaque cid<0..2^8-1>;
169632b31808SJens Wiklander      *   } ConnectionId;
169732b31808SJens Wiklander      */
169832b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_CID, p, 0);
169932b31808SJens Wiklander     p += 2;
170032b31808SJens Wiklander     ext_len = (size_t) ssl->own_cid_len + 1;
170132b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(ext_len, p, 0);
170232b31808SJens Wiklander     p += 2;
170332b31808SJens Wiklander 
170432b31808SJens Wiklander     *p++ = (uint8_t) ssl->own_cid_len;
170532b31808SJens Wiklander     memcpy(p, ssl->own_cid, ssl->own_cid_len);
170632b31808SJens Wiklander 
170732b31808SJens Wiklander     *olen = ssl->own_cid_len + 5;
170832b31808SJens Wiklander }
170932b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
171032b31808SJens Wiklander 
171132b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM)
ssl_write_encrypt_then_mac_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t * olen)171232b31808SJens Wiklander static void ssl_write_encrypt_then_mac_ext(mbedtls_ssl_context *ssl,
171332b31808SJens Wiklander                                            unsigned char *buf,
171432b31808SJens Wiklander                                            size_t *olen)
171532b31808SJens Wiklander {
171632b31808SJens Wiklander     unsigned char *p = buf;
171732b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *suite = NULL;
171832b31808SJens Wiklander 
171932b31808SJens Wiklander     /*
172032b31808SJens Wiklander      * RFC 7366: "If a server receives an encrypt-then-MAC request extension
172132b31808SJens Wiklander      * from a client and then selects a stream or Authenticated Encryption
172232b31808SJens Wiklander      * with Associated Data (AEAD) ciphersuite, it MUST NOT send an
172332b31808SJens Wiklander      * encrypt-then-MAC response extension back to the client."
172432b31808SJens Wiklander      */
172532b31808SJens Wiklander     suite = mbedtls_ssl_ciphersuite_from_id(
172632b31808SJens Wiklander         ssl->session_negotiate->ciphersuite);
172732b31808SJens Wiklander     if (suite == NULL) {
172832b31808SJens Wiklander         ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_DISABLED;
172932b31808SJens Wiklander     } else {
173032b31808SJens Wiklander         mbedtls_ssl_mode_t ssl_mode =
173132b31808SJens Wiklander             mbedtls_ssl_get_mode_from_ciphersuite(
173232b31808SJens Wiklander                 ssl->session_negotiate->encrypt_then_mac,
173332b31808SJens Wiklander                 suite);
173432b31808SJens Wiklander 
173532b31808SJens Wiklander         if (ssl_mode != MBEDTLS_SSL_MODE_CBC_ETM) {
173632b31808SJens Wiklander             ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_DISABLED;
173732b31808SJens Wiklander         }
173832b31808SJens Wiklander     }
173932b31808SJens Wiklander 
174032b31808SJens Wiklander     if (ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED) {
174132b31808SJens Wiklander         *olen = 0;
174232b31808SJens Wiklander         return;
174332b31808SJens Wiklander     }
174432b31808SJens Wiklander 
174532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding encrypt then mac extension"));
174632b31808SJens Wiklander 
174732b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, p, 0);
174832b31808SJens Wiklander     p += 2;
174932b31808SJens Wiklander 
175032b31808SJens Wiklander     *p++ = 0x00;
175132b31808SJens Wiklander     *p++ = 0x00;
175232b31808SJens Wiklander 
175332b31808SJens Wiklander     *olen = 4;
175432b31808SJens Wiklander }
175532b31808SJens Wiklander #endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */
175632b31808SJens Wiklander 
175732b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
ssl_write_extended_ms_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t * olen)175832b31808SJens Wiklander static void ssl_write_extended_ms_ext(mbedtls_ssl_context *ssl,
175932b31808SJens Wiklander                                       unsigned char *buf,
176032b31808SJens Wiklander                                       size_t *olen)
176132b31808SJens Wiklander {
176232b31808SJens Wiklander     unsigned char *p = buf;
176332b31808SJens Wiklander 
176432b31808SJens Wiklander     if (ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED) {
176532b31808SJens Wiklander         *olen = 0;
176632b31808SJens Wiklander         return;
176732b31808SJens Wiklander     }
176832b31808SJens Wiklander 
176932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding extended master secret "
177032b31808SJens Wiklander                               "extension"));
177132b31808SJens Wiklander 
177232b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, p, 0);
177332b31808SJens Wiklander     p += 2;
177432b31808SJens Wiklander 
177532b31808SJens Wiklander     *p++ = 0x00;
177632b31808SJens Wiklander     *p++ = 0x00;
177732b31808SJens Wiklander 
177832b31808SJens Wiklander     *olen = 4;
177932b31808SJens Wiklander }
178032b31808SJens Wiklander #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
178132b31808SJens Wiklander 
178232b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
ssl_write_session_ticket_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t * olen)178332b31808SJens Wiklander static void ssl_write_session_ticket_ext(mbedtls_ssl_context *ssl,
178432b31808SJens Wiklander                                          unsigned char *buf,
178532b31808SJens Wiklander                                          size_t *olen)
178632b31808SJens Wiklander {
178732b31808SJens Wiklander     unsigned char *p = buf;
178832b31808SJens Wiklander 
178932b31808SJens Wiklander     if (ssl->handshake->new_session_ticket == 0) {
179032b31808SJens Wiklander         *olen = 0;
179132b31808SJens Wiklander         return;
179232b31808SJens Wiklander     }
179332b31808SJens Wiklander 
179432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding session ticket extension"));
179532b31808SJens Wiklander 
179632b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SESSION_TICKET, p, 0);
179732b31808SJens Wiklander     p += 2;
179832b31808SJens Wiklander 
179932b31808SJens Wiklander     *p++ = 0x00;
180032b31808SJens Wiklander     *p++ = 0x00;
180132b31808SJens Wiklander 
180232b31808SJens Wiklander     *olen = 4;
180332b31808SJens Wiklander }
180432b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
180532b31808SJens Wiklander 
ssl_write_renegotiation_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t * olen)180632b31808SJens Wiklander static void ssl_write_renegotiation_ext(mbedtls_ssl_context *ssl,
180732b31808SJens Wiklander                                         unsigned char *buf,
180832b31808SJens Wiklander                                         size_t *olen)
180932b31808SJens Wiklander {
181032b31808SJens Wiklander     unsigned char *p = buf;
181132b31808SJens Wiklander 
181232b31808SJens Wiklander     if (ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION) {
181332b31808SJens Wiklander         *olen = 0;
181432b31808SJens Wiklander         return;
181532b31808SJens Wiklander     }
181632b31808SJens Wiklander 
181732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, secure renegotiation extension"));
181832b31808SJens Wiklander 
181932b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_RENEGOTIATION_INFO, p, 0);
182032b31808SJens Wiklander     p += 2;
182132b31808SJens Wiklander 
182232b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
182332b31808SJens Wiklander     if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
182432b31808SJens Wiklander         *p++ = 0x00;
182532b31808SJens Wiklander         *p++ = (ssl->verify_data_len * 2 + 1) & 0xFF;
182632b31808SJens Wiklander         *p++ = ssl->verify_data_len * 2 & 0xFF;
182732b31808SJens Wiklander 
182832b31808SJens Wiklander         memcpy(p, ssl->peer_verify_data, ssl->verify_data_len);
182932b31808SJens Wiklander         p += ssl->verify_data_len;
183032b31808SJens Wiklander         memcpy(p, ssl->own_verify_data, ssl->verify_data_len);
183132b31808SJens Wiklander         p += ssl->verify_data_len;
183232b31808SJens Wiklander     } else
183332b31808SJens Wiklander #endif /* MBEDTLS_SSL_RENEGOTIATION */
183432b31808SJens Wiklander     {
183532b31808SJens Wiklander         *p++ = 0x00;
183632b31808SJens Wiklander         *p++ = 0x01;
183732b31808SJens Wiklander         *p++ = 0x00;
183832b31808SJens Wiklander     }
183932b31808SJens Wiklander 
1840b0563631STom Van Eyck     *olen = (size_t) (p - buf);
184132b31808SJens Wiklander }
184232b31808SJens Wiklander 
184332b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
ssl_write_max_fragment_length_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t * olen)184432b31808SJens Wiklander static void ssl_write_max_fragment_length_ext(mbedtls_ssl_context *ssl,
184532b31808SJens Wiklander                                               unsigned char *buf,
184632b31808SJens Wiklander                                               size_t *olen)
184732b31808SJens Wiklander {
184832b31808SJens Wiklander     unsigned char *p = buf;
184932b31808SJens Wiklander 
185032b31808SJens Wiklander     if (ssl->session_negotiate->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE) {
185132b31808SJens Wiklander         *olen = 0;
185232b31808SJens Wiklander         return;
185332b31808SJens Wiklander     }
185432b31808SJens Wiklander 
185532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, max_fragment_length extension"));
185632b31808SJens Wiklander 
185732b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, p, 0);
185832b31808SJens Wiklander     p += 2;
185932b31808SJens Wiklander 
186032b31808SJens Wiklander     *p++ = 0x00;
186132b31808SJens Wiklander     *p++ = 1;
186232b31808SJens Wiklander 
186332b31808SJens Wiklander     *p++ = ssl->session_negotiate->mfl_code;
186432b31808SJens Wiklander 
186532b31808SJens Wiklander     *olen = 5;
186632b31808SJens Wiklander }
186732b31808SJens Wiklander #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
186832b31808SJens Wiklander 
1869b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
1870b0563631STom Van Eyck     defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
187132b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ssl_write_supported_point_formats_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t * olen)187232b31808SJens Wiklander static void ssl_write_supported_point_formats_ext(mbedtls_ssl_context *ssl,
187332b31808SJens Wiklander                                                   unsigned char *buf,
187432b31808SJens Wiklander                                                   size_t *olen)
187532b31808SJens Wiklander {
187632b31808SJens Wiklander     unsigned char *p = buf;
187732b31808SJens Wiklander     ((void) ssl);
187832b31808SJens Wiklander 
187932b31808SJens Wiklander     if ((ssl->handshake->cli_exts &
188032b31808SJens Wiklander          MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT) == 0) {
188132b31808SJens Wiklander         *olen = 0;
188232b31808SJens Wiklander         return;
188332b31808SJens Wiklander     }
188432b31808SJens Wiklander 
188532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, supported_point_formats extension"));
188632b31808SJens Wiklander 
188732b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, p, 0);
188832b31808SJens Wiklander     p += 2;
188932b31808SJens Wiklander 
189032b31808SJens Wiklander     *p++ = 0x00;
189132b31808SJens Wiklander     *p++ = 2;
189232b31808SJens Wiklander 
189332b31808SJens Wiklander     *p++ = 1;
189432b31808SJens Wiklander     *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED;
189532b31808SJens Wiklander 
189632b31808SJens Wiklander     *olen = 6;
189732b31808SJens Wiklander }
1898b0563631STom Van Eyck #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED ||
1899b0563631STom Van Eyck           MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED ||
1900b0563631STom Van Eyck           MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
190132b31808SJens Wiklander 
190232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t * olen)190332b31808SJens Wiklander static void ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl,
190432b31808SJens Wiklander                                        unsigned char *buf,
190532b31808SJens Wiklander                                        size_t *olen)
190632b31808SJens Wiklander {
190732b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
190832b31808SJens Wiklander     unsigned char *p = buf;
190932b31808SJens Wiklander     const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
191032b31808SJens Wiklander     size_t kkpp_len;
191132b31808SJens Wiklander 
191232b31808SJens Wiklander     *olen = 0;
191332b31808SJens Wiklander 
191432b31808SJens Wiklander     /* Skip costly computation if not needed */
191532b31808SJens Wiklander     if (ssl->handshake->ciphersuite_info->key_exchange !=
191632b31808SJens Wiklander         MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
191732b31808SJens Wiklander         return;
191832b31808SJens Wiklander     }
191932b31808SJens Wiklander 
192032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, ecjpake kkpp extension"));
192132b31808SJens Wiklander 
192232b31808SJens Wiklander     if (end - p < 4) {
192332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small"));
192432b31808SJens Wiklander         return;
192532b31808SJens Wiklander     }
192632b31808SJens Wiklander 
192732b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0);
192832b31808SJens Wiklander     p += 2;
192932b31808SJens Wiklander 
193032b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
193132b31808SJens Wiklander     ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx,
1932b0563631STom Van Eyck                                           p + 2, (size_t) (end - p - 2), &kkpp_len,
193332b31808SJens Wiklander                                           MBEDTLS_ECJPAKE_ROUND_ONE);
193432b31808SJens Wiklander     if (ret != 0) {
193532b31808SJens Wiklander         psa_destroy_key(ssl->handshake->psa_pake_password);
193632b31808SJens Wiklander         psa_pake_abort(&ssl->handshake->psa_pake_ctx);
193732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret);
193832b31808SJens Wiklander         return;
193932b31808SJens Wiklander     }
194032b31808SJens Wiklander #else
194132b31808SJens Wiklander     ret = mbedtls_ecjpake_write_round_one(&ssl->handshake->ecjpake_ctx,
1942b0563631STom Van Eyck                                           p + 2, (size_t) (end - p - 2), &kkpp_len,
194332b31808SJens Wiklander                                           ssl->conf->f_rng, ssl->conf->p_rng);
194432b31808SJens Wiklander     if (ret != 0) {
194532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_one", ret);
194632b31808SJens Wiklander         return;
194732b31808SJens Wiklander     }
194832b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
194932b31808SJens Wiklander 
195032b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(kkpp_len, p, 0);
195132b31808SJens Wiklander     p += 2;
195232b31808SJens Wiklander 
195332b31808SJens Wiklander     *olen = kkpp_len + 4;
195432b31808SJens Wiklander }
195532b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
195632b31808SJens Wiklander 
195732b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP) && defined(MBEDTLS_SSL_PROTO_DTLS)
ssl_write_use_srtp_ext(mbedtls_ssl_context * ssl,unsigned char * buf,size_t * olen)195832b31808SJens Wiklander static void ssl_write_use_srtp_ext(mbedtls_ssl_context *ssl,
195932b31808SJens Wiklander                                    unsigned char *buf,
196032b31808SJens Wiklander                                    size_t *olen)
196132b31808SJens Wiklander {
196232b31808SJens Wiklander     size_t mki_len = 0, ext_len = 0;
196332b31808SJens Wiklander     uint16_t profile_value = 0;
196432b31808SJens Wiklander     const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
196532b31808SJens Wiklander 
196632b31808SJens Wiklander     *olen = 0;
196732b31808SJens Wiklander 
196832b31808SJens Wiklander     if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) ||
196932b31808SJens Wiklander         (ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET)) {
197032b31808SJens Wiklander         return;
197132b31808SJens Wiklander     }
197232b31808SJens Wiklander 
197332b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding use_srtp extension"));
197432b31808SJens Wiklander 
197532b31808SJens Wiklander     if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED) {
197632b31808SJens Wiklander         mki_len = ssl->dtls_srtp_info.mki_len;
197732b31808SJens Wiklander     }
197832b31808SJens Wiklander 
197932b31808SJens Wiklander     /* The extension total size is 9 bytes :
198032b31808SJens Wiklander      * - 2 bytes for the extension tag
198132b31808SJens Wiklander      * - 2 bytes for the total size
198232b31808SJens Wiklander      * - 2 bytes for the protection profile length
198332b31808SJens Wiklander      * - 2 bytes for the protection profile
198432b31808SJens Wiklander      * - 1 byte for the mki length
198532b31808SJens Wiklander      * +  the actual mki length
198632b31808SJens Wiklander      * Check we have enough room in the output buffer */
198732b31808SJens Wiklander     if ((size_t) (end - buf) < mki_len + 9) {
198832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small"));
198932b31808SJens Wiklander         return;
199032b31808SJens Wiklander     }
199132b31808SJens Wiklander 
199232b31808SJens Wiklander     /* extension */
199332b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_USE_SRTP, buf, 0);
199432b31808SJens Wiklander     /*
199532b31808SJens Wiklander      * total length 5 and mki value: only one profile(2 bytes)
199632b31808SJens Wiklander      *              and length(2 bytes) and srtp_mki  )
199732b31808SJens Wiklander      */
199832b31808SJens Wiklander     ext_len = 5 + mki_len;
199932b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(ext_len, buf, 2);
200032b31808SJens Wiklander 
200132b31808SJens Wiklander     /* protection profile length: 2 */
200232b31808SJens Wiklander     buf[4] = 0x00;
200332b31808SJens Wiklander     buf[5] = 0x02;
200432b31808SJens Wiklander     profile_value = mbedtls_ssl_check_srtp_profile_value(
200532b31808SJens Wiklander         ssl->dtls_srtp_info.chosen_dtls_srtp_profile);
200632b31808SJens Wiklander     if (profile_value != MBEDTLS_TLS_SRTP_UNSET) {
200732b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(profile_value, buf, 6);
200832b31808SJens Wiklander     } else {
200932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("use_srtp extension invalid profile"));
201032b31808SJens Wiklander         return;
201132b31808SJens Wiklander     }
201232b31808SJens Wiklander 
201332b31808SJens Wiklander     buf[8] = mki_len & 0xFF;
201432b31808SJens Wiklander     memcpy(&buf[9], ssl->dtls_srtp_info.mki_value, mki_len);
201532b31808SJens Wiklander 
201632b31808SJens Wiklander     *olen = 9 + mki_len;
201732b31808SJens Wiklander }
201832b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_SRTP */
201932b31808SJens Wiklander 
202032b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
202132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_write_hello_verify_request(mbedtls_ssl_context * ssl)202232b31808SJens Wiklander static int ssl_write_hello_verify_request(mbedtls_ssl_context *ssl)
202332b31808SJens Wiklander {
202432b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
202532b31808SJens Wiklander     unsigned char *p = ssl->out_msg + 4;
202632b31808SJens Wiklander     unsigned char *cookie_len_byte;
202732b31808SJens Wiklander 
202832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write hello verify request"));
202932b31808SJens Wiklander 
203032b31808SJens Wiklander     /*
203132b31808SJens Wiklander      * struct {
203232b31808SJens Wiklander      *   ProtocolVersion server_version;
203332b31808SJens Wiklander      *   opaque cookie<0..2^8-1>;
203432b31808SJens Wiklander      * } HelloVerifyRequest;
203532b31808SJens Wiklander      */
203632b31808SJens Wiklander 
203732b31808SJens Wiklander     /* The RFC is not clear on this point, but sending the actual negotiated
203832b31808SJens Wiklander      * version looks like the most interoperable thing to do. */
203932b31808SJens Wiklander     mbedtls_ssl_write_version(p, ssl->conf->transport, ssl->tls_version);
204032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "server version", p, 2);
204132b31808SJens Wiklander     p += 2;
204232b31808SJens Wiklander 
204332b31808SJens Wiklander     /* If we get here, f_cookie_check is not null */
204432b31808SJens Wiklander     if (ssl->conf->f_cookie_write == NULL) {
204532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("inconsistent cookie callbacks"));
204632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
204732b31808SJens Wiklander     }
204832b31808SJens Wiklander 
204932b31808SJens Wiklander     /* Skip length byte until we know the length */
205032b31808SJens Wiklander     cookie_len_byte = p++;
205132b31808SJens Wiklander 
205232b31808SJens Wiklander     if ((ret = ssl->conf->f_cookie_write(ssl->conf->p_cookie,
205332b31808SJens Wiklander                                          &p, ssl->out_buf + MBEDTLS_SSL_OUT_BUFFER_LEN,
205432b31808SJens Wiklander                                          ssl->cli_id, ssl->cli_id_len)) != 0) {
205532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "f_cookie_write", ret);
205632b31808SJens Wiklander         return ret;
205732b31808SJens Wiklander     }
205832b31808SJens Wiklander 
205932b31808SJens Wiklander     *cookie_len_byte = (unsigned char) (p - (cookie_len_byte + 1));
206032b31808SJens Wiklander 
206132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "cookie sent", cookie_len_byte + 1, *cookie_len_byte);
206232b31808SJens Wiklander 
2063b0563631STom Van Eyck     ssl->out_msglen  = (size_t) (p - ssl->out_msg);
206432b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
206532b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
206632b31808SJens Wiklander 
2067*273a583eSThomas Bourgoin     mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT);
206832b31808SJens Wiklander 
206932b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
207032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
207132b31808SJens Wiklander         return ret;
207232b31808SJens Wiklander     }
207332b31808SJens Wiklander 
207432b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
207532b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
207632b31808SJens Wiklander         (ret = mbedtls_ssl_flight_transmit(ssl)) != 0) {
207732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flight_transmit", ret);
207832b31808SJens Wiklander         return ret;
207932b31808SJens Wiklander     }
208032b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */
208132b31808SJens Wiklander 
208232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write hello verify request"));
208332b31808SJens Wiklander 
208432b31808SJens Wiklander     return 0;
208532b31808SJens Wiklander }
208632b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
208732b31808SJens Wiklander 
ssl_handle_id_based_session_resumption(mbedtls_ssl_context * ssl)208832b31808SJens Wiklander static void ssl_handle_id_based_session_resumption(mbedtls_ssl_context *ssl)
208932b31808SJens Wiklander {
209032b31808SJens Wiklander     int ret;
209132b31808SJens Wiklander     mbedtls_ssl_session session_tmp;
209232b31808SJens Wiklander     mbedtls_ssl_session * const session = ssl->session_negotiate;
209332b31808SJens Wiklander 
209432b31808SJens Wiklander     /* Resume is 0  by default, see ssl_handshake_init().
209532b31808SJens Wiklander      * It may be already set to 1 by ssl_parse_session_ticket_ext(). */
209632b31808SJens Wiklander     if (ssl->handshake->resume == 1) {
209732b31808SJens Wiklander         return;
209832b31808SJens Wiklander     }
209932b31808SJens Wiklander     if (session->id_len == 0) {
210032b31808SJens Wiklander         return;
210132b31808SJens Wiklander     }
210232b31808SJens Wiklander     if (ssl->conf->f_get_cache == NULL) {
210332b31808SJens Wiklander         return;
210432b31808SJens Wiklander     }
210532b31808SJens Wiklander #if defined(MBEDTLS_SSL_RENEGOTIATION)
210632b31808SJens Wiklander     if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) {
210732b31808SJens Wiklander         return;
210832b31808SJens Wiklander     }
210932b31808SJens Wiklander #endif
211032b31808SJens Wiklander 
211132b31808SJens Wiklander     mbedtls_ssl_session_init(&session_tmp);
211232b31808SJens Wiklander 
211332b31808SJens Wiklander     ret = ssl->conf->f_get_cache(ssl->conf->p_cache,
211432b31808SJens Wiklander                                  session->id,
211532b31808SJens Wiklander                                  session->id_len,
211632b31808SJens Wiklander                                  &session_tmp);
211732b31808SJens Wiklander     if (ret != 0) {
211832b31808SJens Wiklander         goto exit;
211932b31808SJens Wiklander     }
212032b31808SJens Wiklander 
212132b31808SJens Wiklander     if (session->ciphersuite != session_tmp.ciphersuite) {
212232b31808SJens Wiklander         /* Mismatch between cached and negotiated session */
212332b31808SJens Wiklander         goto exit;
212432b31808SJens Wiklander     }
212532b31808SJens Wiklander 
212632b31808SJens Wiklander     /* Move semantics */
212732b31808SJens Wiklander     mbedtls_ssl_session_free(session);
212832b31808SJens Wiklander     *session = session_tmp;
212932b31808SJens Wiklander     memset(&session_tmp, 0, sizeof(session_tmp));
213032b31808SJens Wiklander 
213132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("session successfully restored from cache"));
213232b31808SJens Wiklander     ssl->handshake->resume = 1;
213332b31808SJens Wiklander 
213432b31808SJens Wiklander exit:
213532b31808SJens Wiklander 
213632b31808SJens Wiklander     mbedtls_ssl_session_free(&session_tmp);
213732b31808SJens Wiklander }
213832b31808SJens Wiklander 
213932b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_write_server_hello(mbedtls_ssl_context * ssl)214032b31808SJens Wiklander static int ssl_write_server_hello(mbedtls_ssl_context *ssl)
214132b31808SJens Wiklander {
214232b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME)
214332b31808SJens Wiklander     mbedtls_time_t t;
214432b31808SJens Wiklander #endif
214532b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
214632b31808SJens Wiklander     size_t olen, ext_len = 0, n;
214732b31808SJens Wiklander     unsigned char *buf, *p;
214832b31808SJens Wiklander 
214932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server hello"));
215032b31808SJens Wiklander 
215132b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
215232b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
215332b31808SJens Wiklander         ssl->handshake->cookie_verify_result != 0) {
215432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("client hello was not authenticated"));
215532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello"));
215632b31808SJens Wiklander 
215732b31808SJens Wiklander         return ssl_write_hello_verify_request(ssl);
215832b31808SJens Wiklander     }
215932b31808SJens Wiklander #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
216032b31808SJens Wiklander 
216132b31808SJens Wiklander     /*
216232b31808SJens Wiklander      *     0  .   0   handshake type
216332b31808SJens Wiklander      *     1  .   3   handshake length
216432b31808SJens Wiklander      *     4  .   5   protocol version
216532b31808SJens Wiklander      *     6  .   9   UNIX time()
216632b31808SJens Wiklander      *    10  .  37   random bytes
216732b31808SJens Wiklander      */
216832b31808SJens Wiklander     buf = ssl->out_msg;
216932b31808SJens Wiklander     p = buf + 4;
217032b31808SJens Wiklander 
217132b31808SJens Wiklander     mbedtls_ssl_write_version(p, ssl->conf->transport, ssl->tls_version);
217232b31808SJens Wiklander     p += 2;
217332b31808SJens Wiklander 
217432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen version: [%d:%d]",
217532b31808SJens Wiklander                               buf[4], buf[5]));
217632b31808SJens Wiklander 
217732b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME)
217832b31808SJens Wiklander     t = mbedtls_time(NULL);
217932b31808SJens Wiklander     MBEDTLS_PUT_UINT32_BE(t, p, 0);
218032b31808SJens Wiklander     p += 4;
218132b31808SJens Wiklander 
218232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, current time: %" MBEDTLS_PRINTF_LONGLONG,
218332b31808SJens Wiklander                               (long long) t));
218432b31808SJens Wiklander #else
218532b31808SJens Wiklander     if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 4)) != 0) {
218632b31808SJens Wiklander         return ret;
218732b31808SJens Wiklander     }
218832b31808SJens Wiklander 
218932b31808SJens Wiklander     p += 4;
219032b31808SJens Wiklander #endif /* MBEDTLS_HAVE_TIME */
219132b31808SJens Wiklander 
2192b0563631STom Van Eyck     if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 20)) != 0) {
219332b31808SJens Wiklander         return ret;
219432b31808SJens Wiklander     }
2195b0563631STom Van Eyck     p += 20;
219632b31808SJens Wiklander 
2197b0563631STom Van Eyck #if defined(MBEDTLS_SSL_PROTO_TLS1_3)
2198b0563631STom Van Eyck     /*
2199b0563631STom Van Eyck      * RFC 8446
2200b0563631STom Van Eyck      * TLS 1.3 has a downgrade protection mechanism embedded in the server's
2201b0563631STom Van Eyck      * random value. TLS 1.3 servers which negotiate TLS 1.2 or below in
2202b0563631STom Van Eyck      * response to a ClientHello MUST set the last 8 bytes of their Random
2203b0563631STom Van Eyck      * value specially in their ServerHello.
2204b0563631STom Van Eyck      */
2205b0563631STom Van Eyck     if (mbedtls_ssl_conf_is_tls13_enabled(ssl->conf)) {
2206b0563631STom Van Eyck         static const unsigned char magic_tls12_downgrade_string[] =
2207b0563631STom Van Eyck         { 'D', 'O', 'W', 'N', 'G', 'R', 'D', 1 };
2208b0563631STom Van Eyck 
2209b0563631STom Van Eyck         MBEDTLS_STATIC_ASSERT(
2210b0563631STom Van Eyck             sizeof(magic_tls12_downgrade_string) == 8,
2211b0563631STom Van Eyck             "magic_tls12_downgrade_string does not have the expected size");
2212b0563631STom Van Eyck 
2213b0563631STom Van Eyck         memcpy(p, magic_tls12_downgrade_string,
2214b0563631STom Van Eyck                sizeof(magic_tls12_downgrade_string));
2215b0563631STom Van Eyck     } else
2216b0563631STom Van Eyck #endif
2217b0563631STom Van Eyck     {
2218b0563631STom Van Eyck         if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 8)) != 0) {
2219b0563631STom Van Eyck             return ret;
2220b0563631STom Van Eyck         }
2221b0563631STom Van Eyck     }
2222b0563631STom Van Eyck     p += 8;
222332b31808SJens Wiklander 
222432b31808SJens Wiklander     memcpy(ssl->handshake->randbytes + 32, buf + 6, 32);
222532b31808SJens Wiklander 
222632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3, "server hello, random bytes", buf + 6, 32);
222732b31808SJens Wiklander 
222832b31808SJens Wiklander     ssl_handle_id_based_session_resumption(ssl);
222932b31808SJens Wiklander 
223032b31808SJens Wiklander     if (ssl->handshake->resume == 0) {
223132b31808SJens Wiklander         /*
223232b31808SJens Wiklander          * New session, create a new session id,
223332b31808SJens Wiklander          * unless we're about to issue a session ticket
223432b31808SJens Wiklander          */
2235*273a583eSThomas Bourgoin         mbedtls_ssl_handshake_increment_state(ssl);
223632b31808SJens Wiklander 
223732b31808SJens Wiklander #if defined(MBEDTLS_HAVE_TIME)
223832b31808SJens Wiklander         ssl->session_negotiate->start = mbedtls_time(NULL);
223932b31808SJens Wiklander #endif
224032b31808SJens Wiklander 
224132b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
224232b31808SJens Wiklander         if (ssl->handshake->new_session_ticket != 0) {
224332b31808SJens Wiklander             ssl->session_negotiate->id_len = n = 0;
224432b31808SJens Wiklander             memset(ssl->session_negotiate->id, 0, 32);
224532b31808SJens Wiklander         } else
224632b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
224732b31808SJens Wiklander         {
224832b31808SJens Wiklander             ssl->session_negotiate->id_len = n = 32;
224932b31808SJens Wiklander             if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, ssl->session_negotiate->id,
225032b31808SJens Wiklander                                         n)) != 0) {
225132b31808SJens Wiklander                 return ret;
225232b31808SJens Wiklander             }
225332b31808SJens Wiklander         }
225432b31808SJens Wiklander     } else {
225532b31808SJens Wiklander         /*
225632b31808SJens Wiklander          * Resuming a session
225732b31808SJens Wiklander          */
225832b31808SJens Wiklander         n = ssl->session_negotiate->id_len;
2259*273a583eSThomas Bourgoin         mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC);
226032b31808SJens Wiklander 
226132b31808SJens Wiklander         if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) {
226232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret);
226332b31808SJens Wiklander             return ret;
226432b31808SJens Wiklander         }
226532b31808SJens Wiklander     }
226632b31808SJens Wiklander 
226732b31808SJens Wiklander     /*
226832b31808SJens Wiklander      *    38  .  38     session id length
226932b31808SJens Wiklander      *    39  . 38+n    session id
227032b31808SJens Wiklander      *   39+n . 40+n    chosen ciphersuite
227132b31808SJens Wiklander      *   41+n . 41+n    chosen compression alg.
227232b31808SJens Wiklander      *   42+n . 43+n    extensions length
227332b31808SJens Wiklander      *   44+n . 43+n+m  extensions
227432b31808SJens Wiklander      */
227532b31808SJens Wiklander     *p++ = (unsigned char) ssl->session_negotiate->id_len;
227632b31808SJens Wiklander     memcpy(p, ssl->session_negotiate->id, ssl->session_negotiate->id_len);
227732b31808SJens Wiklander     p += ssl->session_negotiate->id_len;
227832b31808SJens Wiklander 
227932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, session id len.: %" MBEDTLS_PRINTF_SIZET, n));
228032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_BUF(3,   "server hello, session id", buf + 39, n);
228132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("%s session has been resumed",
228232b31808SJens Wiklander                               ssl->handshake->resume ? "a" : "no"));
228332b31808SJens Wiklander 
228432b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(ssl->session_negotiate->ciphersuite, p, 0);
228532b31808SJens Wiklander     p += 2;
228632b31808SJens Wiklander     *p++ = MBEDTLS_BYTE_0(MBEDTLS_SSL_COMPRESS_NULL);
228732b31808SJens Wiklander 
228832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen ciphersuite: %s",
228932b31808SJens Wiklander                               mbedtls_ssl_get_ciphersuite_name(ssl->session_negotiate->ciphersuite)));
229032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, compress alg.: 0x%02X",
229132b31808SJens Wiklander                               (unsigned int) MBEDTLS_SSL_COMPRESS_NULL));
229232b31808SJens Wiklander 
229332b31808SJens Wiklander     /*
229432b31808SJens Wiklander      *  First write extensions, then the total length
229532b31808SJens Wiklander      */
229632b31808SJens Wiklander     ssl_write_renegotiation_ext(ssl, p + 2 + ext_len, &olen);
229732b31808SJens Wiklander     ext_len += olen;
229832b31808SJens Wiklander 
229932b31808SJens Wiklander #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
230032b31808SJens Wiklander     ssl_write_max_fragment_length_ext(ssl, p + 2 + ext_len, &olen);
230132b31808SJens Wiklander     ext_len += olen;
230232b31808SJens Wiklander #endif
230332b31808SJens Wiklander 
230432b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
230532b31808SJens Wiklander     ssl_write_cid_ext(ssl, p + 2 + ext_len, &olen);
230632b31808SJens Wiklander     ext_len += olen;
230732b31808SJens Wiklander #endif
230832b31808SJens Wiklander 
230932b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM)
231032b31808SJens Wiklander     ssl_write_encrypt_then_mac_ext(ssl, p + 2 + ext_len, &olen);
231132b31808SJens Wiklander     ext_len += olen;
231232b31808SJens Wiklander #endif
231332b31808SJens Wiklander 
231432b31808SJens Wiklander #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
231532b31808SJens Wiklander     ssl_write_extended_ms_ext(ssl, p + 2 + ext_len, &olen);
231632b31808SJens Wiklander     ext_len += olen;
231732b31808SJens Wiklander #endif
231832b31808SJens Wiklander 
231932b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
232032b31808SJens Wiklander     ssl_write_session_ticket_ext(ssl, p + 2 + ext_len, &olen);
232132b31808SJens Wiklander     ext_len += olen;
232232b31808SJens Wiklander #endif
232332b31808SJens Wiklander 
2324b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \
2325b0563631STom Van Eyck     defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \
232632b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
232732b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *suite =
232832b31808SJens Wiklander         mbedtls_ssl_ciphersuite_from_id(ssl->session_negotiate->ciphersuite);
232932b31808SJens Wiklander     if (suite != NULL && mbedtls_ssl_ciphersuite_uses_ec(suite)) {
233032b31808SJens Wiklander         ssl_write_supported_point_formats_ext(ssl, p + 2 + ext_len, &olen);
233132b31808SJens Wiklander         ext_len += olen;
233232b31808SJens Wiklander     }
233332b31808SJens Wiklander #endif
233432b31808SJens Wiklander 
233532b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
233632b31808SJens Wiklander     ssl_write_ecjpake_kkpp_ext(ssl, p + 2 + ext_len, &olen);
233732b31808SJens Wiklander     ext_len += olen;
233832b31808SJens Wiklander #endif
233932b31808SJens Wiklander 
234032b31808SJens Wiklander #if defined(MBEDTLS_SSL_ALPN)
234132b31808SJens Wiklander     unsigned char *end = buf + MBEDTLS_SSL_OUT_CONTENT_LEN - 4;
234232b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_alpn_ext(ssl, p + 2 + ext_len, end, &olen))
234332b31808SJens Wiklander         != 0) {
234432b31808SJens Wiklander         return ret;
234532b31808SJens Wiklander     }
234632b31808SJens Wiklander 
234732b31808SJens Wiklander     ext_len += olen;
234832b31808SJens Wiklander #endif
234932b31808SJens Wiklander 
235032b31808SJens Wiklander #if defined(MBEDTLS_SSL_DTLS_SRTP)
235132b31808SJens Wiklander     ssl_write_use_srtp_ext(ssl, p + 2 + ext_len, &olen);
235232b31808SJens Wiklander     ext_len += olen;
235332b31808SJens Wiklander #endif
235432b31808SJens Wiklander 
235532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, total extension length: %" MBEDTLS_PRINTF_SIZET,
235632b31808SJens Wiklander                               ext_len));
235732b31808SJens Wiklander 
235832b31808SJens Wiklander     if (ext_len > 0) {
235932b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(ext_len, p, 0);
236032b31808SJens Wiklander         p += 2 + ext_len;
236132b31808SJens Wiklander     }
236232b31808SJens Wiklander 
2363b0563631STom Van Eyck     ssl->out_msglen  = (size_t) (p - buf);
236432b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
236532b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_HELLO;
236632b31808SJens Wiklander 
236732b31808SJens Wiklander     ret = mbedtls_ssl_write_handshake_msg(ssl);
236832b31808SJens Wiklander 
236932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello"));
237032b31808SJens Wiklander 
237132b31808SJens Wiklander     return ret;
237232b31808SJens Wiklander }
237332b31808SJens Wiklander 
237432b31808SJens Wiklander #if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
237532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_write_certificate_request(mbedtls_ssl_context * ssl)237632b31808SJens Wiklander static int ssl_write_certificate_request(mbedtls_ssl_context *ssl)
237732b31808SJens Wiklander {
237832b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
237932b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
238032b31808SJens Wiklander 
238132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate request"));
238232b31808SJens Wiklander 
238332b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
238432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate request"));
2385*273a583eSThomas Bourgoin         mbedtls_ssl_handshake_increment_state(ssl);
238632b31808SJens Wiklander         return 0;
238732b31808SJens Wiklander     }
238832b31808SJens Wiklander 
238932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
239032b31808SJens Wiklander     return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
239132b31808SJens Wiklander }
239232b31808SJens Wiklander #else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
239332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_write_certificate_request(mbedtls_ssl_context * ssl)239432b31808SJens Wiklander static int ssl_write_certificate_request(mbedtls_ssl_context *ssl)
239532b31808SJens Wiklander {
239632b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
239732b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
239832b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
239932b31808SJens Wiklander     uint16_t dn_size, total_dn_size; /* excluding length bytes */
240032b31808SJens Wiklander     size_t ct_len, sa_len; /* including length bytes */
240132b31808SJens Wiklander     unsigned char *buf, *p;
240232b31808SJens Wiklander     const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
240332b31808SJens Wiklander     const mbedtls_x509_crt *crt;
240432b31808SJens Wiklander     int authmode;
240532b31808SJens Wiklander 
240632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate request"));
240732b31808SJens Wiklander 
2408*273a583eSThomas Bourgoin     mbedtls_ssl_handshake_increment_state(ssl);
240932b31808SJens Wiklander 
241032b31808SJens Wiklander #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
241132b31808SJens Wiklander     if (ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET) {
241232b31808SJens Wiklander         authmode = ssl->handshake->sni_authmode;
241332b31808SJens Wiklander     } else
241432b31808SJens Wiklander #endif
241532b31808SJens Wiklander     authmode = ssl->conf->authmode;
241632b31808SJens Wiklander 
241732b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info) ||
241832b31808SJens Wiklander         authmode == MBEDTLS_SSL_VERIFY_NONE) {
241932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate request"));
242032b31808SJens Wiklander         return 0;
242132b31808SJens Wiklander     }
242232b31808SJens Wiklander 
242332b31808SJens Wiklander     /*
242432b31808SJens Wiklander      *     0  .   0   handshake type
242532b31808SJens Wiklander      *     1  .   3   handshake length
242632b31808SJens Wiklander      *     4  .   4   cert type count
242732b31808SJens Wiklander      *     5  .. m-1  cert types
242832b31808SJens Wiklander      *     m  .. m+1  sig alg length (TLS 1.2 only)
242932b31808SJens Wiklander      *    m+1 .. n-1  SignatureAndHashAlgorithms (TLS 1.2 only)
243032b31808SJens Wiklander      *     n  .. n+1  length of all DNs
243132b31808SJens Wiklander      *    n+2 .. n+3  length of DN 1
243232b31808SJens Wiklander      *    n+4 .. ...  Distinguished Name #1
243332b31808SJens Wiklander      *    ... .. ...  length of DN 2, etc.
243432b31808SJens Wiklander      */
243532b31808SJens Wiklander     buf = ssl->out_msg;
243632b31808SJens Wiklander     p = buf + 4;
243732b31808SJens Wiklander 
243832b31808SJens Wiklander     /*
243932b31808SJens Wiklander      * Supported certificate types
244032b31808SJens Wiklander      *
244132b31808SJens Wiklander      *     ClientCertificateType certificate_types<1..2^8-1>;
244232b31808SJens Wiklander      *     enum { (255) } ClientCertificateType;
244332b31808SJens Wiklander      */
244432b31808SJens Wiklander     ct_len = 0;
244532b31808SJens Wiklander 
244632b31808SJens Wiklander #if defined(MBEDTLS_RSA_C)
244732b31808SJens Wiklander     p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN;
244832b31808SJens Wiklander #endif
2449b0563631STom Van Eyck #if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED)
245032b31808SJens Wiklander     p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN;
245132b31808SJens Wiklander #endif
245232b31808SJens Wiklander 
245332b31808SJens Wiklander     p[0] = (unsigned char) ct_len++;
245432b31808SJens Wiklander     p += ct_len;
245532b31808SJens Wiklander 
245632b31808SJens Wiklander     sa_len = 0;
245732b31808SJens Wiklander 
245832b31808SJens Wiklander     /*
245932b31808SJens Wiklander      * Add signature_algorithms for verify (TLS 1.2)
246032b31808SJens Wiklander      *
246132b31808SJens Wiklander      *     SignatureAndHashAlgorithm supported_signature_algorithms<2..2^16-2>;
246232b31808SJens Wiklander      *
246332b31808SJens Wiklander      *     struct {
246432b31808SJens Wiklander      *           HashAlgorithm hash;
246532b31808SJens Wiklander      *           SignatureAlgorithm signature;
246632b31808SJens Wiklander      *     } SignatureAndHashAlgorithm;
246732b31808SJens Wiklander      *
246832b31808SJens Wiklander      *     enum { (255) } HashAlgorithm;
246932b31808SJens Wiklander      *     enum { (255) } SignatureAlgorithm;
247032b31808SJens Wiklander      */
247132b31808SJens Wiklander     const uint16_t *sig_alg = mbedtls_ssl_get_sig_algs(ssl);
247232b31808SJens Wiklander     if (sig_alg == NULL) {
247332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_BAD_CONFIG;
247432b31808SJens Wiklander     }
247532b31808SJens Wiklander 
247632b31808SJens Wiklander     for (; *sig_alg != MBEDTLS_TLS_SIG_NONE; sig_alg++) {
247732b31808SJens Wiklander         unsigned char hash = MBEDTLS_BYTE_1(*sig_alg);
247832b31808SJens Wiklander 
247932b31808SJens Wiklander         if (mbedtls_ssl_set_calc_verify_md(ssl, hash)) {
248032b31808SJens Wiklander             continue;
248132b31808SJens Wiklander         }
248232b31808SJens Wiklander         if (!mbedtls_ssl_sig_alg_is_supported(ssl, *sig_alg)) {
248332b31808SJens Wiklander             continue;
248432b31808SJens Wiklander         }
248532b31808SJens Wiklander 
248632b31808SJens Wiklander         /* Write elements at offsets starting from 1 (offset 0 is for the
248732b31808SJens Wiklander          * length). Thus the offset of each element is the length of the
248832b31808SJens Wiklander          * partial list including that element. */
248932b31808SJens Wiklander         sa_len += 2;
249032b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(*sig_alg, p, sa_len);
249132b31808SJens Wiklander 
249232b31808SJens Wiklander     }
249332b31808SJens Wiklander 
249432b31808SJens Wiklander     /* Fill in list length. */
249532b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(sa_len, p, 0);
249632b31808SJens Wiklander     sa_len += 2;
249732b31808SJens Wiklander     p += sa_len;
249832b31808SJens Wiklander 
249932b31808SJens Wiklander     /*
250032b31808SJens Wiklander      * DistinguishedName certificate_authorities<0..2^16-1>;
250132b31808SJens Wiklander      * opaque DistinguishedName<1..2^16-1>;
250232b31808SJens Wiklander      */
250332b31808SJens Wiklander     p += 2;
250432b31808SJens Wiklander 
250532b31808SJens Wiklander     total_dn_size = 0;
250632b31808SJens Wiklander 
250732b31808SJens Wiklander     if (ssl->conf->cert_req_ca_list ==  MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED) {
250832b31808SJens Wiklander         /* NOTE: If trusted certificates are provisioned
250932b31808SJens Wiklander          *       via a CA callback (configured through
251032b31808SJens Wiklander          *       `mbedtls_ssl_conf_ca_cb()`, then the
251132b31808SJens Wiklander          *       CertificateRequest is currently left empty. */
251232b31808SJens Wiklander 
251332b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
251432b31808SJens Wiklander #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
251532b31808SJens Wiklander         if (ssl->handshake->dn_hints != NULL) {
251632b31808SJens Wiklander             crt = ssl->handshake->dn_hints;
251732b31808SJens Wiklander         } else
251832b31808SJens Wiklander #endif
251932b31808SJens Wiklander         if (ssl->conf->dn_hints != NULL) {
252032b31808SJens Wiklander             crt = ssl->conf->dn_hints;
252132b31808SJens Wiklander         } else
252232b31808SJens Wiklander #endif
252332b31808SJens Wiklander #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
252432b31808SJens Wiklander         if (ssl->handshake->sni_ca_chain != NULL) {
252532b31808SJens Wiklander             crt = ssl->handshake->sni_ca_chain;
252632b31808SJens Wiklander         } else
252732b31808SJens Wiklander #endif
252832b31808SJens Wiklander         crt = ssl->conf->ca_chain;
252932b31808SJens Wiklander 
253032b31808SJens Wiklander         while (crt != NULL && crt->version != 0) {
253132b31808SJens Wiklander             /* It follows from RFC 5280 A.1 that this length
253232b31808SJens Wiklander              * can be represented in at most 11 bits. */
253332b31808SJens Wiklander             dn_size = (uint16_t) crt->subject_raw.len;
253432b31808SJens Wiklander 
253532b31808SJens Wiklander             if (end < p || (size_t) (end - p) < 2 + (size_t) dn_size) {
253632b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_MSG(1, ("skipping CAs: buffer too short"));
253732b31808SJens Wiklander                 break;
253832b31808SJens Wiklander             }
253932b31808SJens Wiklander 
254032b31808SJens Wiklander             MBEDTLS_PUT_UINT16_BE(dn_size, p, 0);
254132b31808SJens Wiklander             p += 2;
254232b31808SJens Wiklander             memcpy(p, crt->subject_raw.p, dn_size);
254332b31808SJens Wiklander             p += dn_size;
254432b31808SJens Wiklander 
254532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_BUF(3, "requested DN", p - dn_size, dn_size);
254632b31808SJens Wiklander 
2547b0563631STom Van Eyck             total_dn_size += (unsigned short) (2 + dn_size);
254832b31808SJens Wiklander             crt = crt->next;
254932b31808SJens Wiklander         }
255032b31808SJens Wiklander     }
255132b31808SJens Wiklander 
2552b0563631STom Van Eyck     ssl->out_msglen  = (size_t) (p - buf);
255332b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
255432b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_CERTIFICATE_REQUEST;
255532b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(total_dn_size, ssl->out_msg, 4 + ct_len + sa_len);
255632b31808SJens Wiklander 
255732b31808SJens Wiklander     ret = mbedtls_ssl_write_handshake_msg(ssl);
255832b31808SJens Wiklander 
255932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write certificate request"));
256032b31808SJens Wiklander 
256132b31808SJens Wiklander     return ret;
256232b31808SJens Wiklander }
256332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
256432b31808SJens Wiklander 
2565b0563631STom Van Eyck #if (defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
256632b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED))
2567b0563631STom Van Eyck #if defined(MBEDTLS_USE_PSA_CRYPTO)
256832b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_get_ecdh_params_from_cert(mbedtls_ssl_context * ssl)256932b31808SJens Wiklander static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
257032b31808SJens Wiklander {
257132b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
257232b31808SJens Wiklander     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
257332b31808SJens Wiklander     mbedtls_pk_context *pk;
2574b0563631STom Van Eyck     mbedtls_pk_type_t pk_type;
2575b0563631STom Van Eyck     psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
2576b0563631STom Van Eyck     unsigned char buf[PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)];
2577b0563631STom Van Eyck     size_t key_len;
2578b0563631STom Van Eyck #if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
2579b0563631STom Van Eyck     uint16_t tls_id = 0;
2580b0563631STom Van Eyck     psa_key_type_t key_type = PSA_KEY_TYPE_NONE;
2581b0563631STom Van Eyck     mbedtls_ecp_group_id grp_id;
258232b31808SJens Wiklander     mbedtls_ecp_keypair *key;
2583b0563631STom Van Eyck #endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
258432b31808SJens Wiklander 
258532b31808SJens Wiklander     pk = mbedtls_ssl_own_key(ssl);
258632b31808SJens Wiklander 
258732b31808SJens Wiklander     if (pk == NULL) {
258832b31808SJens Wiklander         return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
258932b31808SJens Wiklander     }
259032b31808SJens Wiklander 
2591b0563631STom Van Eyck     pk_type = mbedtls_pk_get_type(pk);
2592b0563631STom Van Eyck 
2593b0563631STom Van Eyck     switch (pk_type) {
259432b31808SJens Wiklander         case MBEDTLS_PK_OPAQUE:
2595b0563631STom Van Eyck #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
2596b0563631STom Van Eyck         case MBEDTLS_PK_ECKEY:
2597b0563631STom Van Eyck         case MBEDTLS_PK_ECKEY_DH:
2598b0563631STom Van Eyck         case MBEDTLS_PK_ECDSA:
2599b0563631STom Van Eyck #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
260032b31808SJens Wiklander             if (!mbedtls_pk_can_do(pk, MBEDTLS_PK_ECKEY)) {
260132b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
260232b31808SJens Wiklander             }
260332b31808SJens Wiklander 
2604b0563631STom Van Eyck             /* Get the attributes of the key previously parsed by PK module in
2605b0563631STom Van Eyck              * order to extract its type and length (in bits). */
2606b0563631STom Van Eyck             status = psa_get_key_attributes(pk->priv_id, &key_attributes);
260732b31808SJens Wiklander             if (status != PSA_SUCCESS) {
2608b0563631STom Van Eyck                 ret = PSA_TO_MBEDTLS_ERR(status);
2609b0563631STom Van Eyck                 goto exit;
2610b0563631STom Van Eyck             }
2611b0563631STom Van Eyck             ssl->handshake->xxdh_psa_type = psa_get_key_type(&key_attributes);
2612b0563631STom Van Eyck             ssl->handshake->xxdh_psa_bits = psa_get_key_bits(&key_attributes);
2613b0563631STom Van Eyck 
2614cb034002SJerome Forissier #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
2615cb034002SJerome Forissier             if (pk_type != MBEDTLS_PK_OPAQUE) {
2616b0563631STom Van Eyck                 /* PK_ECKEY[_DH] and PK_ECDSA instead as parsed from the PK
2617b0563631STom Van Eyck                  * module and only have ECDSA capabilities. Since we need
2618b0563631STom Van Eyck                  * them for ECDH later, we export and then re-import them with
2619b0563631STom Van Eyck                  * proper flags and algorithm. Of course We also set key's type
2620b0563631STom Van Eyck                  * and bits that we just got above. */
2621b0563631STom Van Eyck                 key_attributes = psa_key_attributes_init();
2622b0563631STom Van Eyck                 psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
2623b0563631STom Van Eyck                 psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
2624b0563631STom Van Eyck                 psa_set_key_type(&key_attributes,
2625b0563631STom Van Eyck                                  PSA_KEY_TYPE_ECC_KEY_PAIR(ssl->handshake->xxdh_psa_type));
2626b0563631STom Van Eyck                 psa_set_key_bits(&key_attributes, ssl->handshake->xxdh_psa_bits);
2627b0563631STom Van Eyck 
2628b0563631STom Van Eyck                 status = psa_export_key(pk->priv_id, buf, sizeof(buf), &key_len);
2629b0563631STom Van Eyck                 if (status != PSA_SUCCESS) {
2630b0563631STom Van Eyck                     ret = PSA_TO_MBEDTLS_ERR(status);
2631b0563631STom Van Eyck                     goto exit;
2632b0563631STom Van Eyck                 }
2633b0563631STom Van Eyck                 status = psa_import_key(&key_attributes, buf, key_len,
2634b0563631STom Van Eyck                                         &ssl->handshake->xxdh_psa_privkey);
2635b0563631STom Van Eyck                 if (status != PSA_SUCCESS) {
2636b0563631STom Van Eyck                     ret = PSA_TO_MBEDTLS_ERR(status);
2637b0563631STom Van Eyck                     goto exit;
263832b31808SJens Wiklander                 }
263932b31808SJens Wiklander 
2640b0563631STom Van Eyck                 /* Set this key as owned by the TLS library: it will be its duty
2641b0563631STom Van Eyck                  * to clear it exit. */
2642b0563631STom Van Eyck                 ssl->handshake->xxdh_psa_privkey_is_external = 0;
264332b31808SJens Wiklander 
264432b31808SJens Wiklander                 ret = 0;
264532b31808SJens Wiklander                 break;
2646cb034002SJerome Forissier             }
2647cb034002SJerome Forissier #endif /* MBEDTLS_PK_USE_PSA_EC_DATA */
2648cb034002SJerome Forissier 
2649cb034002SJerome Forissier             /* Opaque key is created by the user (externally from Mbed TLS)
2650cb034002SJerome Forissier              * so we assume it already has the right algorithm and flags
2651cb034002SJerome Forissier              * set. Just copy its ID as reference. */
2652cb034002SJerome Forissier             ssl->handshake->xxdh_psa_privkey = pk->priv_id;
2653cb034002SJerome Forissier             ssl->handshake->xxdh_psa_privkey_is_external = 1;
2654cb034002SJerome Forissier             ret = 0;
2655cb034002SJerome Forissier             break;
2656cb034002SJerome Forissier 
2657b0563631STom Van Eyck #if !defined(MBEDTLS_PK_USE_PSA_EC_DATA)
265832b31808SJens Wiklander         case MBEDTLS_PK_ECKEY:
265932b31808SJens Wiklander         case MBEDTLS_PK_ECKEY_DH:
266032b31808SJens Wiklander         case MBEDTLS_PK_ECDSA:
2661b0563631STom Van Eyck             key = mbedtls_pk_ec_rw(*pk);
2662b0563631STom Van Eyck             grp_id = mbedtls_pk_get_ec_group_id(pk);
2663b0563631STom Van Eyck             if (grp_id == MBEDTLS_ECP_DP_NONE) {
266432b31808SJens Wiklander                 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
266532b31808SJens Wiklander             }
2666b0563631STom Van Eyck             tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id);
266732b31808SJens Wiklander             if (tls_id == 0) {
266832b31808SJens Wiklander                 /* This elliptic curve is not supported */
266932b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
267032b31808SJens Wiklander             }
267132b31808SJens Wiklander 
267232b31808SJens Wiklander             /* If the above conversion to TLS ID was fine, then also this one will
267332b31808SJens Wiklander                be, so there is no need to check the return value here */
2674b0563631STom Van Eyck             mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id, &key_type,
2675b0563631STom Van Eyck                                                        &ssl->handshake->xxdh_psa_bits);
267632b31808SJens Wiklander 
2677b0563631STom Van Eyck             ssl->handshake->xxdh_psa_type = key_type;
267832b31808SJens Wiklander 
267932b31808SJens Wiklander             key_attributes = psa_key_attributes_init();
268032b31808SJens Wiklander             psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
268132b31808SJens Wiklander             psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
268232b31808SJens Wiklander             psa_set_key_type(&key_attributes,
2683b0563631STom Van Eyck                              PSA_KEY_TYPE_ECC_KEY_PAIR(ssl->handshake->xxdh_psa_type));
2684b0563631STom Van Eyck             psa_set_key_bits(&key_attributes, ssl->handshake->xxdh_psa_bits);
268532b31808SJens Wiklander 
2686b0563631STom Van Eyck             ret = mbedtls_ecp_write_key_ext(key, &key_len, buf, sizeof(buf));
268732b31808SJens Wiklander             if (ret != 0) {
2688b0563631STom Van Eyck                 mbedtls_platform_zeroize(buf, sizeof(buf));
2689b0563631STom Van Eyck                 break;
269032b31808SJens Wiklander             }
269132b31808SJens Wiklander 
269232b31808SJens Wiklander             status = psa_import_key(&key_attributes, buf, key_len,
2693b0563631STom Van Eyck                                     &ssl->handshake->xxdh_psa_privkey);
269432b31808SJens Wiklander             if (status != PSA_SUCCESS) {
269532b31808SJens Wiklander                 ret = PSA_TO_MBEDTLS_ERR(status);
2696b0563631STom Van Eyck                 mbedtls_platform_zeroize(buf, sizeof(buf));
2697b0563631STom Van Eyck                 break;
269832b31808SJens Wiklander             }
269932b31808SJens Wiklander 
2700b0563631STom Van Eyck             mbedtls_platform_zeroize(buf, sizeof(buf));
270132b31808SJens Wiklander             ret = 0;
270232b31808SJens Wiklander             break;
2703b0563631STom Van Eyck #endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */
270432b31808SJens Wiklander         default:
270532b31808SJens Wiklander             ret = MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
270632b31808SJens Wiklander     }
270732b31808SJens Wiklander 
2708b0563631STom Van Eyck exit:
2709b0563631STom Van Eyck     psa_reset_key_attributes(&key_attributes);
271032b31808SJens Wiklander     mbedtls_platform_zeroize(buf, sizeof(buf));
271132b31808SJens Wiklander 
271232b31808SJens Wiklander     return ret;
271332b31808SJens Wiklander }
2714b0563631STom Van Eyck #else /* MBEDTLS_USE_PSA_CRYPTO */
271532b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_get_ecdh_params_from_cert(mbedtls_ssl_context * ssl)271632b31808SJens Wiklander static int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl)
271732b31808SJens Wiklander {
271832b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
271932b31808SJens Wiklander 
272032b31808SJens Wiklander     const mbedtls_pk_context *private_key = mbedtls_ssl_own_key(ssl);
272132b31808SJens Wiklander     if (private_key == NULL) {
272232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got no server private key"));
272332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED;
272432b31808SJens Wiklander     }
272532b31808SJens Wiklander 
272632b31808SJens Wiklander     if (!mbedtls_pk_can_do(private_key, MBEDTLS_PK_ECKEY)) {
272732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("server key not ECDH capable"));
272832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH;
272932b31808SJens Wiklander     }
273032b31808SJens Wiklander 
273132b31808SJens Wiklander     if ((ret = mbedtls_ecdh_get_params(&ssl->handshake->ecdh_ctx,
2732b0563631STom Van Eyck                                        mbedtls_pk_ec_ro(*mbedtls_ssl_own_key(ssl)),
273332b31808SJens Wiklander                                        MBEDTLS_ECDH_OURS)) != 0) {
273432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_get_params"), ret);
273532b31808SJens Wiklander         return ret;
273632b31808SJens Wiklander     }
273732b31808SJens Wiklander 
273832b31808SJens Wiklander     return 0;
273932b31808SJens Wiklander }
2740b0563631STom Van Eyck #endif /* MBEDTLS_USE_PSA_CRYPTO */
274132b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
274232b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
274332b31808SJens Wiklander 
274432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \
274532b31808SJens Wiklander     defined(MBEDTLS_SSL_ASYNC_PRIVATE)
274632b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_resume_server_key_exchange(mbedtls_ssl_context * ssl,size_t * signature_len)274732b31808SJens Wiklander static int ssl_resume_server_key_exchange(mbedtls_ssl_context *ssl,
274832b31808SJens Wiklander                                           size_t *signature_len)
274932b31808SJens Wiklander {
275032b31808SJens Wiklander     /* Append the signature to ssl->out_msg, leaving 2 bytes for the
275132b31808SJens Wiklander      * signature length which will be added in ssl_write_server_key_exchange
275232b31808SJens Wiklander      * after the call to ssl_prepare_server_key_exchange.
275332b31808SJens Wiklander      * ssl_write_server_key_exchange also takes care of incrementing
275432b31808SJens Wiklander      * ssl->out_msglen. */
275532b31808SJens Wiklander     unsigned char *sig_start = ssl->out_msg + ssl->out_msglen + 2;
275632b31808SJens Wiklander     size_t sig_max_len = (ssl->out_buf + MBEDTLS_SSL_OUT_CONTENT_LEN
275732b31808SJens Wiklander                           - sig_start);
275832b31808SJens Wiklander     int ret = ssl->conf->f_async_resume(ssl,
275932b31808SJens Wiklander                                         sig_start, signature_len, sig_max_len);
276032b31808SJens Wiklander     if (ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
276132b31808SJens Wiklander         ssl->handshake->async_in_progress = 0;
276232b31808SJens Wiklander         mbedtls_ssl_set_async_operation_data(ssl, NULL);
276332b31808SJens Wiklander     }
276432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_RET(2, "ssl_resume_server_key_exchange", ret);
276532b31808SJens Wiklander     return ret;
276632b31808SJens Wiklander }
276732b31808SJens Wiklander #endif /* defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) &&
276832b31808SJens Wiklander           defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
276932b31808SJens Wiklander 
277032b31808SJens Wiklander /* Prepare the ServerKeyExchange message, up to and including
277132b31808SJens Wiklander  * calculating the signature if any, but excluding formatting the
277232b31808SJens Wiklander  * signature and sending the message. */
277332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_prepare_server_key_exchange(mbedtls_ssl_context * ssl,size_t * signature_len)277432b31808SJens Wiklander static int ssl_prepare_server_key_exchange(mbedtls_ssl_context *ssl,
277532b31808SJens Wiklander                                            size_t *signature_len)
277632b31808SJens Wiklander {
277732b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
277832b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
277932b31808SJens Wiklander 
278032b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED)
278132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
278232b31808SJens Wiklander     unsigned char *dig_signed = NULL;
278332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
278432b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED */
278532b31808SJens Wiklander 
278632b31808SJens Wiklander     (void) ciphersuite_info; /* unused in some configurations */
278732b31808SJens Wiklander #if !defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
278832b31808SJens Wiklander     (void) signature_len;
278932b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
279032b31808SJens Wiklander 
279132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
279232b31808SJens Wiklander #if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
2793b0563631STom Van Eyck     size_t out_buf_len = ssl->out_buf_len - (size_t) (ssl->out_msg - ssl->out_buf);
279432b31808SJens Wiklander #else
2795b0563631STom Van Eyck     size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - (size_t) (ssl->out_msg - ssl->out_buf);
279632b31808SJens Wiklander #endif
279732b31808SJens Wiklander #endif
279832b31808SJens Wiklander 
279932b31808SJens Wiklander     ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */
280032b31808SJens Wiklander 
280132b31808SJens Wiklander     /*
280232b31808SJens Wiklander      *
280332b31808SJens Wiklander      * Part 1: Provide key exchange parameters for chosen ciphersuite.
280432b31808SJens Wiklander      *
280532b31808SJens Wiklander      */
280632b31808SJens Wiklander 
280732b31808SJens Wiklander     /*
280832b31808SJens Wiklander      * - ECJPAKE key exchanges
280932b31808SJens Wiklander      */
281032b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
281132b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
281232b31808SJens Wiklander         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
281332b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
281432b31808SJens Wiklander         unsigned char *out_p = ssl->out_msg + ssl->out_msglen;
281532b31808SJens Wiklander         unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN -
281632b31808SJens Wiklander                                ssl->out_msglen;
281732b31808SJens Wiklander         size_t output_offset = 0;
281832b31808SJens Wiklander         size_t output_len = 0;
281932b31808SJens Wiklander 
282032b31808SJens Wiklander         /*
282132b31808SJens Wiklander          * The first 3 bytes are:
282232b31808SJens Wiklander          * [0] MBEDTLS_ECP_TLS_NAMED_CURVE
282332b31808SJens Wiklander          * [1, 2] elliptic curve's TLS ID
282432b31808SJens Wiklander          *
282532b31808SJens Wiklander          * However since we only support secp256r1 for now, we hardcode its
282632b31808SJens Wiklander          * TLS ID here
282732b31808SJens Wiklander          */
282832b31808SJens Wiklander         uint16_t tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(
282932b31808SJens Wiklander             MBEDTLS_ECP_DP_SECP256R1);
283032b31808SJens Wiklander         if (tls_id == 0) {
283132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
283232b31808SJens Wiklander         }
283332b31808SJens Wiklander         *out_p = MBEDTLS_ECP_TLS_NAMED_CURVE;
283432b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(tls_id, out_p, 1);
283532b31808SJens Wiklander         output_offset += 3;
283632b31808SJens Wiklander 
283732b31808SJens Wiklander         ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx,
283832b31808SJens Wiklander                                               out_p + output_offset,
283932b31808SJens Wiklander                                               end_p - out_p - output_offset, &output_len,
284032b31808SJens Wiklander                                               MBEDTLS_ECJPAKE_ROUND_TWO);
284132b31808SJens Wiklander         if (ret != 0) {
284232b31808SJens Wiklander             psa_destroy_key(ssl->handshake->psa_pake_password);
284332b31808SJens Wiklander             psa_pake_abort(&ssl->handshake->psa_pake_ctx);
284432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret);
284532b31808SJens Wiklander             return ret;
284632b31808SJens Wiklander         }
284732b31808SJens Wiklander 
284832b31808SJens Wiklander         output_offset += output_len;
284932b31808SJens Wiklander         ssl->out_msglen += output_offset;
285032b31808SJens Wiklander #else
285132b31808SJens Wiklander         size_t len = 0;
285232b31808SJens Wiklander 
285332b31808SJens Wiklander         ret = mbedtls_ecjpake_write_round_two(
285432b31808SJens Wiklander             &ssl->handshake->ecjpake_ctx,
285532b31808SJens Wiklander             ssl->out_msg + ssl->out_msglen,
285632b31808SJens Wiklander             MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, &len,
285732b31808SJens Wiklander             ssl->conf->f_rng, ssl->conf->p_rng);
285832b31808SJens Wiklander         if (ret != 0) {
285932b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_two", ret);
286032b31808SJens Wiklander             return ret;
286132b31808SJens Wiklander         }
286232b31808SJens Wiklander 
286332b31808SJens Wiklander         ssl->out_msglen += len;
286432b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
286532b31808SJens Wiklander     }
286632b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
286732b31808SJens Wiklander 
286832b31808SJens Wiklander     /*
286932b31808SJens Wiklander      * For (EC)DHE key exchanges with PSK, parameters are prefixed by support
287032b31808SJens Wiklander      * identity hint (RFC 4279, Sec. 3). Until someone needs this feature,
287132b31808SJens Wiklander      * we use empty support identity hints here.
287232b31808SJens Wiklander      **/
287332b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)   || \
287432b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
287532b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
287632b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) {
287732b31808SJens Wiklander         ssl->out_msg[ssl->out_msglen++] = 0x00;
287832b31808SJens Wiklander         ssl->out_msg[ssl->out_msglen++] = 0x00;
287932b31808SJens Wiklander     }
288032b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED ||
288132b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
288232b31808SJens Wiklander 
288332b31808SJens Wiklander     /*
288432b31808SJens Wiklander      * - DHE key exchanges
288532b31808SJens Wiklander      */
288632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED)
288732b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_uses_dhe(ciphersuite_info)) {
288832b31808SJens Wiklander         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
288932b31808SJens Wiklander         size_t len = 0;
289032b31808SJens Wiklander 
289132b31808SJens Wiklander         if (ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL) {
289232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("no DH parameters set"));
289332b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
289432b31808SJens Wiklander         }
289532b31808SJens Wiklander 
289632b31808SJens Wiklander         /*
289732b31808SJens Wiklander          * Ephemeral DH parameters:
289832b31808SJens Wiklander          *
289932b31808SJens Wiklander          * struct {
290032b31808SJens Wiklander          *     opaque dh_p<1..2^16-1>;
290132b31808SJens Wiklander          *     opaque dh_g<1..2^16-1>;
290232b31808SJens Wiklander          *     opaque dh_Ys<1..2^16-1>;
290332b31808SJens Wiklander          * } ServerDHParams;
290432b31808SJens Wiklander          */
290532b31808SJens Wiklander         if ((ret = mbedtls_dhm_set_group(&ssl->handshake->dhm_ctx,
290632b31808SJens Wiklander                                          &ssl->conf->dhm_P,
290732b31808SJens Wiklander                                          &ssl->conf->dhm_G)) != 0) {
290832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_set_group", ret);
290932b31808SJens Wiklander             return ret;
291032b31808SJens Wiklander         }
291132b31808SJens Wiklander 
291232b31808SJens Wiklander         if ((ret = mbedtls_dhm_make_params(
291332b31808SJens Wiklander                  &ssl->handshake->dhm_ctx,
291432b31808SJens Wiklander                  (int) mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx),
291532b31808SJens Wiklander                  ssl->out_msg + ssl->out_msglen, &len,
291632b31808SJens Wiklander                  ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
291732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_make_params", ret);
291832b31808SJens Wiklander             return ret;
291932b31808SJens Wiklander         }
292032b31808SJens Wiklander 
292132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
292232b31808SJens Wiklander         dig_signed = ssl->out_msg + ssl->out_msglen;
292332b31808SJens Wiklander #endif
292432b31808SJens Wiklander 
292532b31808SJens Wiklander         ssl->out_msglen += len;
292632b31808SJens Wiklander 
292732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: X ", &ssl->handshake->dhm_ctx.X);
292832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: P ", &ssl->handshake->dhm_ctx.P);
292932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: G ", &ssl->handshake->dhm_ctx.G);
293032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GX", &ssl->handshake->dhm_ctx.GX);
293132b31808SJens Wiklander     }
293232b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED */
293332b31808SJens Wiklander 
293432b31808SJens Wiklander     /*
293532b31808SJens Wiklander      * - ECDHE key exchanges
293632b31808SJens Wiklander      */
293732b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED)
293832b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_uses_ecdhe(ciphersuite_info)) {
293932b31808SJens Wiklander         /*
294032b31808SJens Wiklander          * Ephemeral ECDH parameters:
294132b31808SJens Wiklander          *
294232b31808SJens Wiklander          * struct {
294332b31808SJens Wiklander          *     ECParameters curve_params;
294432b31808SJens Wiklander          *     ECPoint      public;
294532b31808SJens Wiklander          * } ServerECDHParams;
294632b31808SJens Wiklander          */
294732b31808SJens Wiklander         uint16_t *curr_tls_id = ssl->handshake->curves_tls_id;
294832b31808SJens Wiklander         const uint16_t *group_list = mbedtls_ssl_get_groups(ssl);
294932b31808SJens Wiklander         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
295032b31808SJens Wiklander         size_t len = 0;
295132b31808SJens Wiklander 
295232b31808SJens Wiklander         /* Match our preference list against the offered curves */
295332b31808SJens Wiklander         if ((group_list == NULL) || (curr_tls_id == NULL)) {
295432b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BAD_CONFIG;
295532b31808SJens Wiklander         }
295632b31808SJens Wiklander         for (; *group_list != 0; group_list++) {
295732b31808SJens Wiklander             for (curr_tls_id = ssl->handshake->curves_tls_id;
295832b31808SJens Wiklander                  *curr_tls_id != 0; curr_tls_id++) {
295932b31808SJens Wiklander                 if (*curr_tls_id == *group_list) {
296032b31808SJens Wiklander                     goto curve_matching_done;
296132b31808SJens Wiklander                 }
296232b31808SJens Wiklander             }
296332b31808SJens Wiklander         }
296432b31808SJens Wiklander 
296532b31808SJens Wiklander curve_matching_done:
296632b31808SJens Wiklander         if (*curr_tls_id == 0) {
296732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("no matching curve for ECDHE"));
296832b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
296932b31808SJens Wiklander         }
297032b31808SJens Wiklander 
297132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("ECDHE curve: %s",
297232b31808SJens Wiklander                                   mbedtls_ssl_get_curve_name_from_tls_id(*curr_tls_id)));
297332b31808SJens Wiklander 
297432b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
297532b31808SJens Wiklander         psa_status_t status = PSA_ERROR_GENERIC_ERROR;
297632b31808SJens Wiklander         psa_key_attributes_t key_attributes;
297732b31808SJens Wiklander         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
297832b31808SJens Wiklander         uint8_t *p = ssl->out_msg + ssl->out_msglen;
297932b31808SJens Wiklander         const size_t header_size = 4; // curve_type(1), namedcurve(2),
298032b31808SJens Wiklander                                       // data length(1)
298132b31808SJens Wiklander         const size_t data_length_size = 1;
2982b0563631STom Van Eyck         psa_key_type_t key_type = PSA_KEY_TYPE_NONE;
298332b31808SJens Wiklander         size_t ec_bits = 0;
298432b31808SJens Wiklander 
298532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("Perform PSA-based ECDH computation."));
298632b31808SJens Wiklander 
298732b31808SJens Wiklander         /* Convert EC's TLS ID to PSA key type. */
298832b31808SJens Wiklander         if (mbedtls_ssl_get_psa_curve_info_from_tls_id(*curr_tls_id,
2989b0563631STom Van Eyck                                                        &key_type,
299032b31808SJens Wiklander                                                        &ec_bits) == PSA_ERROR_NOT_SUPPORTED) {
299132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid ecc group parse."));
299232b31808SJens Wiklander             return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
299332b31808SJens Wiklander         }
2994b0563631STom Van Eyck         handshake->xxdh_psa_type = key_type;
2995b0563631STom Van Eyck         handshake->xxdh_psa_bits = ec_bits;
299632b31808SJens Wiklander 
299732b31808SJens Wiklander         key_attributes = psa_key_attributes_init();
299832b31808SJens Wiklander         psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE);
299932b31808SJens Wiklander         psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH);
3000b0563631STom Van Eyck         psa_set_key_type(&key_attributes, handshake->xxdh_psa_type);
3001b0563631STom Van Eyck         psa_set_key_bits(&key_attributes, handshake->xxdh_psa_bits);
300232b31808SJens Wiklander 
300332b31808SJens Wiklander         /*
300432b31808SJens Wiklander          * ECParameters curve_params
300532b31808SJens Wiklander          *
300632b31808SJens Wiklander          * First byte is curve_type, always named_curve
300732b31808SJens Wiklander          */
300832b31808SJens Wiklander         *p++ = MBEDTLS_ECP_TLS_NAMED_CURVE;
300932b31808SJens Wiklander 
301032b31808SJens Wiklander         /*
301132b31808SJens Wiklander          * Next two bytes are the namedcurve value
301232b31808SJens Wiklander          */
301332b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(*curr_tls_id, p, 0);
301432b31808SJens Wiklander         p += 2;
301532b31808SJens Wiklander 
301632b31808SJens Wiklander         /* Generate ECDH private key. */
301732b31808SJens Wiklander         status = psa_generate_key(&key_attributes,
3018b0563631STom Van Eyck                                   &handshake->xxdh_psa_privkey);
301932b31808SJens Wiklander         if (status != PSA_SUCCESS) {
302032b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
302132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_generate_key", ret);
302232b31808SJens Wiklander             return ret;
302332b31808SJens Wiklander         }
302432b31808SJens Wiklander 
302532b31808SJens Wiklander         /*
302632b31808SJens Wiklander          * ECPoint  public
302732b31808SJens Wiklander          *
302832b31808SJens Wiklander          * First byte is data length.
302932b31808SJens Wiklander          * It will be filled later. p holds now the data length location.
303032b31808SJens Wiklander          */
303132b31808SJens Wiklander 
303232b31808SJens Wiklander         /* Export the public part of the ECDH private key from PSA.
303332b31808SJens Wiklander          * Make one byte space for the length.
303432b31808SJens Wiklander          */
303532b31808SJens Wiklander         unsigned char *own_pubkey = p + data_length_size;
303632b31808SJens Wiklander 
303732b31808SJens Wiklander         size_t own_pubkey_max_len = (size_t) (MBEDTLS_SSL_OUT_CONTENT_LEN
303832b31808SJens Wiklander                                               - (own_pubkey - ssl->out_msg));
303932b31808SJens Wiklander 
3040b0563631STom Van Eyck         status = psa_export_public_key(handshake->xxdh_psa_privkey,
304132b31808SJens Wiklander                                        own_pubkey, own_pubkey_max_len,
304232b31808SJens Wiklander                                        &len);
304332b31808SJens Wiklander         if (status != PSA_SUCCESS) {
304432b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
304532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_export_public_key", ret);
3046b0563631STom Van Eyck             (void) psa_destroy_key(handshake->xxdh_psa_privkey);
3047b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
304832b31808SJens Wiklander             return ret;
304932b31808SJens Wiklander         }
305032b31808SJens Wiklander 
305132b31808SJens Wiklander         /* Store the length of the exported public key. */
305232b31808SJens Wiklander         *p = (uint8_t) len;
305332b31808SJens Wiklander 
305432b31808SJens Wiklander         /* Determine full message length. */
305532b31808SJens Wiklander         len += header_size;
305632b31808SJens Wiklander #else
305732b31808SJens Wiklander         mbedtls_ecp_group_id curr_grp_id =
305832b31808SJens Wiklander             mbedtls_ssl_get_ecp_group_id_from_tls_id(*curr_tls_id);
305932b31808SJens Wiklander 
306032b31808SJens Wiklander         if ((ret = mbedtls_ecdh_setup(&ssl->handshake->ecdh_ctx,
306132b31808SJens Wiklander                                       curr_grp_id)) != 0) {
306232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecp_group_load", ret);
306332b31808SJens Wiklander             return ret;
306432b31808SJens Wiklander         }
306532b31808SJens Wiklander 
306632b31808SJens Wiklander         if ((ret = mbedtls_ecdh_make_params(
306732b31808SJens Wiklander                  &ssl->handshake->ecdh_ctx, &len,
306832b31808SJens Wiklander                  ssl->out_msg + ssl->out_msglen,
306932b31808SJens Wiklander                  MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen,
307032b31808SJens Wiklander                  ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
307132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_make_params", ret);
307232b31808SJens Wiklander             return ret;
307332b31808SJens Wiklander         }
307432b31808SJens Wiklander 
307532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
307632b31808SJens Wiklander                                MBEDTLS_DEBUG_ECDH_Q);
307732b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
307832b31808SJens Wiklander 
307932b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
308032b31808SJens Wiklander         dig_signed = ssl->out_msg + ssl->out_msglen;
308132b31808SJens Wiklander #endif
308232b31808SJens Wiklander 
308332b31808SJens Wiklander         ssl->out_msglen += len;
308432b31808SJens Wiklander     }
308532b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED */
308632b31808SJens Wiklander 
308732b31808SJens Wiklander     /*
308832b31808SJens Wiklander      *
308932b31808SJens Wiklander      * Part 2: For key exchanges involving the server signing the
309032b31808SJens Wiklander      *         exchange parameters, compute and add the signature here.
309132b31808SJens Wiklander      *
309232b31808SJens Wiklander      */
309332b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
309432b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_uses_server_signature(ciphersuite_info)) {
309532b31808SJens Wiklander         if (dig_signed == NULL) {
309632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
309732b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
309832b31808SJens Wiklander         }
309932b31808SJens Wiklander 
3100b0563631STom Van Eyck         size_t dig_signed_len = (size_t) (ssl->out_msg + ssl->out_msglen - dig_signed);
310132b31808SJens Wiklander         size_t hashlen = 0;
3102b0563631STom Van Eyck         unsigned char hash[MBEDTLS_MD_MAX_SIZE];
310332b31808SJens Wiklander 
310432b31808SJens Wiklander         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
310532b31808SJens Wiklander 
310632b31808SJens Wiklander         /*
310732b31808SJens Wiklander          * 2.1: Choose hash algorithm:
310832b31808SJens Wiklander          *      For TLS 1.2, obey signature-hash-algorithm extension
310932b31808SJens Wiklander          *      to choose appropriate hash.
311032b31808SJens Wiklander          */
311132b31808SJens Wiklander 
311232b31808SJens Wiklander         mbedtls_pk_type_t sig_alg =
311332b31808SJens Wiklander             mbedtls_ssl_get_ciphersuite_sig_pk_alg(ciphersuite_info);
311432b31808SJens Wiklander 
3115b0563631STom Van Eyck         unsigned char sig_hash =
3116b0563631STom Van Eyck             (unsigned char) mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg(
311732b31808SJens Wiklander                 ssl, mbedtls_ssl_sig_from_pk_alg(sig_alg));
311832b31808SJens Wiklander 
311932b31808SJens Wiklander         mbedtls_md_type_t md_alg = mbedtls_ssl_md_alg_from_hash(sig_hash);
312032b31808SJens Wiklander 
312132b31808SJens Wiklander         /*    For TLS 1.2, obey signature-hash-algorithm extension
312232b31808SJens Wiklander          *    (RFC 5246, Sec. 7.4.1.4.1). */
312332b31808SJens Wiklander         if (sig_alg == MBEDTLS_PK_NONE || md_alg == MBEDTLS_MD_NONE) {
312432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
312532b31808SJens Wiklander             /* (... because we choose a cipher suite
312632b31808SJens Wiklander              *      only if there is a matching hash.) */
312732b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
312832b31808SJens Wiklander         }
312932b31808SJens Wiklander 
313032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("pick hash algorithm %u for signing", (unsigned) md_alg));
313132b31808SJens Wiklander 
313232b31808SJens Wiklander         /*
313332b31808SJens Wiklander          * 2.2: Compute the hash to be signed
313432b31808SJens Wiklander          */
313532b31808SJens Wiklander         if (md_alg != MBEDTLS_MD_NONE) {
313632b31808SJens Wiklander             ret = mbedtls_ssl_get_key_exchange_md_tls1_2(ssl, hash, &hashlen,
313732b31808SJens Wiklander                                                          dig_signed,
313832b31808SJens Wiklander                                                          dig_signed_len,
313932b31808SJens Wiklander                                                          md_alg);
314032b31808SJens Wiklander             if (ret != 0) {
314132b31808SJens Wiklander                 return ret;
314232b31808SJens Wiklander             }
314332b31808SJens Wiklander         } else {
314432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
314532b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
314632b31808SJens Wiklander         }
314732b31808SJens Wiklander 
314832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "parameters hash", hash, hashlen);
314932b31808SJens Wiklander 
315032b31808SJens Wiklander         /*
315132b31808SJens Wiklander          * 2.3: Compute and add the signature
315232b31808SJens Wiklander          */
315332b31808SJens Wiklander         /*
315432b31808SJens Wiklander          * We need to specify signature and hash algorithm explicitly through
315532b31808SJens Wiklander          * a prefix to the signature.
315632b31808SJens Wiklander          *
315732b31808SJens Wiklander          * struct {
315832b31808SJens Wiklander          *    HashAlgorithm hash;
315932b31808SJens Wiklander          *    SignatureAlgorithm signature;
316032b31808SJens Wiklander          * } SignatureAndHashAlgorithm;
316132b31808SJens Wiklander          *
316232b31808SJens Wiklander          * struct {
316332b31808SJens Wiklander          *    SignatureAndHashAlgorithm algorithm;
316432b31808SJens Wiklander          *    opaque signature<0..2^16-1>;
316532b31808SJens Wiklander          * } DigitallySigned;
316632b31808SJens Wiklander          *
316732b31808SJens Wiklander          */
316832b31808SJens Wiklander 
316932b31808SJens Wiklander         ssl->out_msg[ssl->out_msglen++] = mbedtls_ssl_hash_from_md_alg(md_alg);
317032b31808SJens Wiklander         ssl->out_msg[ssl->out_msglen++] = mbedtls_ssl_sig_from_pk_alg(sig_alg);
317132b31808SJens Wiklander 
317232b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
317332b31808SJens Wiklander         if (ssl->conf->f_async_sign_start != NULL) {
317432b31808SJens Wiklander             ret = ssl->conf->f_async_sign_start(ssl,
317532b31808SJens Wiklander                                                 mbedtls_ssl_own_cert(ssl),
317632b31808SJens Wiklander                                                 md_alg, hash, hashlen);
317732b31808SJens Wiklander             switch (ret) {
317832b31808SJens Wiklander                 case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH:
317932b31808SJens Wiklander                     /* act as if f_async_sign was null */
318032b31808SJens Wiklander                     break;
318132b31808SJens Wiklander                 case 0:
318232b31808SJens Wiklander                     ssl->handshake->async_in_progress = 1;
318332b31808SJens Wiklander                     return ssl_resume_server_key_exchange(ssl, signature_len);
318432b31808SJens Wiklander                 case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
318532b31808SJens Wiklander                     ssl->handshake->async_in_progress = 1;
318632b31808SJens Wiklander                     return MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS;
318732b31808SJens Wiklander                 default:
318832b31808SJens Wiklander                     MBEDTLS_SSL_DEBUG_RET(1, "f_async_sign_start", ret);
318932b31808SJens Wiklander                     return ret;
319032b31808SJens Wiklander             }
319132b31808SJens Wiklander         }
319232b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
319332b31808SJens Wiklander 
319432b31808SJens Wiklander         if (mbedtls_ssl_own_key(ssl) == NULL) {
319532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("got no private key"));
319632b31808SJens Wiklander             return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED;
319732b31808SJens Wiklander         }
319832b31808SJens Wiklander 
319932b31808SJens Wiklander         /* Append the signature to ssl->out_msg, leaving 2 bytes for the
320032b31808SJens Wiklander          * signature length which will be added in ssl_write_server_key_exchange
320132b31808SJens Wiklander          * after the call to ssl_prepare_server_key_exchange.
320232b31808SJens Wiklander          * ssl_write_server_key_exchange also takes care of incrementing
320332b31808SJens Wiklander          * ssl->out_msglen. */
320432b31808SJens Wiklander         if ((ret = mbedtls_pk_sign(mbedtls_ssl_own_key(ssl),
320532b31808SJens Wiklander                                    md_alg, hash, hashlen,
320632b31808SJens Wiklander                                    ssl->out_msg + ssl->out_msglen + 2,
320732b31808SJens Wiklander                                    out_buf_len - ssl->out_msglen - 2,
320832b31808SJens Wiklander                                    signature_len,
320932b31808SJens Wiklander                                    ssl->conf->f_rng,
321032b31808SJens Wiklander                                    ssl->conf->p_rng)) != 0) {
321132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_sign", ret);
321232b31808SJens Wiklander             return ret;
321332b31808SJens Wiklander         }
321432b31808SJens Wiklander     }
321532b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
321632b31808SJens Wiklander 
321732b31808SJens Wiklander     return 0;
321832b31808SJens Wiklander }
321932b31808SJens Wiklander 
322032b31808SJens Wiklander /* Prepare the ServerKeyExchange message and send it. For ciphersuites
322132b31808SJens Wiklander  * that do not include a ServerKeyExchange message, do nothing. Either
322232b31808SJens Wiklander  * way, if successful, move on to the next step in the SSL state
322332b31808SJens Wiklander  * machine. */
322432b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_write_server_key_exchange(mbedtls_ssl_context * ssl)322532b31808SJens Wiklander static int ssl_write_server_key_exchange(mbedtls_ssl_context *ssl)
322632b31808SJens Wiklander {
322732b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
322832b31808SJens Wiklander     size_t signature_len = 0;
322932b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED)
323032b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
323132b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
323232b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */
323332b31808SJens Wiklander 
323432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server key exchange"));
323532b31808SJens Wiklander 
323632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED)
323732b31808SJens Wiklander     /* Extract static ECDH parameters and abort if ServerKeyExchange
323832b31808SJens Wiklander      * is not needed. */
323932b31808SJens Wiklander     if (mbedtls_ssl_ciphersuite_no_pfs(ciphersuite_info)) {
324032b31808SJens Wiklander         /* For suites involving ECDH, extract DH parameters
324132b31808SJens Wiklander          * from certificate at this point. */
324232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED)
324332b31808SJens Wiklander         if (mbedtls_ssl_ciphersuite_uses_ecdh(ciphersuite_info)) {
324432b31808SJens Wiklander             ret = ssl_get_ecdh_params_from_cert(ssl);
324532b31808SJens Wiklander             if (ret != 0) {
324632b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "ssl_get_ecdh_params_from_cert", ret);
324732b31808SJens Wiklander                 return ret;
324832b31808SJens Wiklander             }
324932b31808SJens Wiklander         }
325032b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */
325132b31808SJens Wiklander 
325232b31808SJens Wiklander         /* Key exchanges not involving ephemeral keys don't use
325332b31808SJens Wiklander          * ServerKeyExchange, so end here. */
325432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write server key exchange"));
3255*273a583eSThomas Bourgoin         mbedtls_ssl_handshake_increment_state(ssl);
325632b31808SJens Wiklander         return 0;
325732b31808SJens Wiklander     }
325832b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */
325932b31808SJens Wiklander 
326032b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \
326132b31808SJens Wiklander     defined(MBEDTLS_SSL_ASYNC_PRIVATE)
326232b31808SJens Wiklander     /* If we have already prepared the message and there is an ongoing
326332b31808SJens Wiklander      * signature operation, resume signing. */
326432b31808SJens Wiklander     if (ssl->handshake->async_in_progress != 0) {
326532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("resuming signature operation"));
326632b31808SJens Wiklander         ret = ssl_resume_server_key_exchange(ssl, &signature_len);
326732b31808SJens Wiklander     } else
326832b31808SJens Wiklander #endif /* defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) &&
326932b31808SJens Wiklander           defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
327032b31808SJens Wiklander     {
327132b31808SJens Wiklander         /* ServerKeyExchange is needed. Prepare the message. */
327232b31808SJens Wiklander         ret = ssl_prepare_server_key_exchange(ssl, &signature_len);
327332b31808SJens Wiklander     }
327432b31808SJens Wiklander 
327532b31808SJens Wiklander     if (ret != 0) {
327632b31808SJens Wiklander         /* If we're starting to write a new message, set ssl->out_msglen
327732b31808SJens Wiklander          * to 0. But if we're resuming after an asynchronous message,
327832b31808SJens Wiklander          * out_msglen is the amount of data written so far and mst be
327932b31808SJens Wiklander          * preserved. */
328032b31808SJens Wiklander         if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
328132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server key exchange (pending)"));
328232b31808SJens Wiklander         } else {
328332b31808SJens Wiklander             ssl->out_msglen = 0;
328432b31808SJens Wiklander         }
328532b31808SJens Wiklander         return ret;
328632b31808SJens Wiklander     }
328732b31808SJens Wiklander 
328832b31808SJens Wiklander     /* If there is a signature, write its length.
328932b31808SJens Wiklander      * ssl_prepare_server_key_exchange already wrote the signature
329032b31808SJens Wiklander      * itself at its proper place in the output buffer. */
329132b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
329232b31808SJens Wiklander     if (signature_len != 0) {
329332b31808SJens Wiklander         ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_1(signature_len);
329432b31808SJens Wiklander         ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_0(signature_len);
329532b31808SJens Wiklander 
329632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "my signature",
329732b31808SJens Wiklander                               ssl->out_msg + ssl->out_msglen,
329832b31808SJens Wiklander                               signature_len);
329932b31808SJens Wiklander 
330032b31808SJens Wiklander         /* Skip over the already-written signature */
330132b31808SJens Wiklander         ssl->out_msglen += signature_len;
330232b31808SJens Wiklander     }
330332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
330432b31808SJens Wiklander 
330532b31808SJens Wiklander     /* Add header and send. */
330632b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
330732b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE;
330832b31808SJens Wiklander 
3309*273a583eSThomas Bourgoin     mbedtls_ssl_handshake_increment_state(ssl);
331032b31808SJens Wiklander 
331132b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
331232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
331332b31808SJens Wiklander         return ret;
331432b31808SJens Wiklander     }
331532b31808SJens Wiklander 
331632b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server key exchange"));
331732b31808SJens Wiklander     return 0;
331832b31808SJens Wiklander }
331932b31808SJens Wiklander 
332032b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_write_server_hello_done(mbedtls_ssl_context * ssl)332132b31808SJens Wiklander static int ssl_write_server_hello_done(mbedtls_ssl_context *ssl)
332232b31808SJens Wiklander {
332332b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
332432b31808SJens Wiklander 
332532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server hello done"));
332632b31808SJens Wiklander 
332732b31808SJens Wiklander     ssl->out_msglen  = 4;
332832b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
332932b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_SERVER_HELLO_DONE;
333032b31808SJens Wiklander 
3331*273a583eSThomas Bourgoin     mbedtls_ssl_handshake_increment_state(ssl);
333232b31808SJens Wiklander 
333332b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
333432b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) {
333532b31808SJens Wiklander         mbedtls_ssl_send_flight_completed(ssl);
333632b31808SJens Wiklander     }
333732b31808SJens Wiklander #endif
333832b31808SJens Wiklander 
333932b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
334032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
334132b31808SJens Wiklander         return ret;
334232b31808SJens Wiklander     }
334332b31808SJens Wiklander 
334432b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
334532b31808SJens Wiklander     if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
334632b31808SJens Wiklander         (ret = mbedtls_ssl_flight_transmit(ssl)) != 0) {
334732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flight_transmit", ret);
334832b31808SJens Wiklander         return ret;
334932b31808SJens Wiklander     }
335032b31808SJens Wiklander #endif /* MBEDTLS_SSL_PROTO_DTLS */
335132b31808SJens Wiklander 
335232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello done"));
335332b31808SJens Wiklander 
335432b31808SJens Wiklander     return 0;
335532b31808SJens Wiklander }
335632b31808SJens Wiklander 
335732b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) ||                       \
335832b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
335932b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_client_dh_public(mbedtls_ssl_context * ssl,unsigned char ** p,const unsigned char * end)336032b31808SJens Wiklander static int ssl_parse_client_dh_public(mbedtls_ssl_context *ssl, unsigned char **p,
336132b31808SJens Wiklander                                       const unsigned char *end)
336232b31808SJens Wiklander {
336332b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
336432b31808SJens Wiklander     size_t n;
336532b31808SJens Wiklander 
336632b31808SJens Wiklander     /*
336732b31808SJens Wiklander      * Receive G^Y mod P, premaster = (G^Y)^X mod P
336832b31808SJens Wiklander      */
336932b31808SJens Wiklander     if (*p + 2 > end) {
337032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
337132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
337232b31808SJens Wiklander     }
337332b31808SJens Wiklander 
3374b0563631STom Van Eyck     n = MBEDTLS_GET_UINT16_BE(*p, 0);
337532b31808SJens Wiklander     *p += 2;
337632b31808SJens Wiklander 
337732b31808SJens Wiklander     if (*p + n > end) {
337832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
337932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
338032b31808SJens Wiklander     }
338132b31808SJens Wiklander 
338232b31808SJens Wiklander     if ((ret = mbedtls_dhm_read_public(&ssl->handshake->dhm_ctx, *p, n)) != 0) {
338332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_read_public", ret);
338432b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
338532b31808SJens Wiklander     }
338632b31808SJens Wiklander 
338732b31808SJens Wiklander     *p += n;
338832b31808SJens Wiklander 
338932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GY", &ssl->handshake->dhm_ctx.GY);
339032b31808SJens Wiklander 
339132b31808SJens Wiklander     return ret;
339232b31808SJens Wiklander }
339332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
339432b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
339532b31808SJens Wiklander 
339632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) ||                           \
339732b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
339832b31808SJens Wiklander 
339932b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
340032b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_resume_decrypt_pms(mbedtls_ssl_context * ssl,unsigned char * peer_pms,size_t * peer_pmslen,size_t peer_pmssize)340132b31808SJens Wiklander static int ssl_resume_decrypt_pms(mbedtls_ssl_context *ssl,
340232b31808SJens Wiklander                                   unsigned char *peer_pms,
340332b31808SJens Wiklander                                   size_t *peer_pmslen,
340432b31808SJens Wiklander                                   size_t peer_pmssize)
340532b31808SJens Wiklander {
340632b31808SJens Wiklander     int ret = ssl->conf->f_async_resume(ssl,
340732b31808SJens Wiklander                                         peer_pms, peer_pmslen, peer_pmssize);
340832b31808SJens Wiklander     if (ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
340932b31808SJens Wiklander         ssl->handshake->async_in_progress = 0;
341032b31808SJens Wiklander         mbedtls_ssl_set_async_operation_data(ssl, NULL);
341132b31808SJens Wiklander     }
341232b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_RET(2, "ssl_decrypt_encrypted_pms", ret);
341332b31808SJens Wiklander     return ret;
341432b31808SJens Wiklander }
341532b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
341632b31808SJens Wiklander 
341732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_decrypt_encrypted_pms(mbedtls_ssl_context * ssl,const unsigned char * p,const unsigned char * end,unsigned char * peer_pms,size_t * peer_pmslen,size_t peer_pmssize)341832b31808SJens Wiklander static int ssl_decrypt_encrypted_pms(mbedtls_ssl_context *ssl,
341932b31808SJens Wiklander                                      const unsigned char *p,
342032b31808SJens Wiklander                                      const unsigned char *end,
342132b31808SJens Wiklander                                      unsigned char *peer_pms,
342232b31808SJens Wiklander                                      size_t *peer_pmslen,
342332b31808SJens Wiklander                                      size_t peer_pmssize)
342432b31808SJens Wiklander {
342532b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
342632b31808SJens Wiklander 
342732b31808SJens Wiklander     mbedtls_x509_crt *own_cert = mbedtls_ssl_own_cert(ssl);
342832b31808SJens Wiklander     if (own_cert == NULL) {
342932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got no local certificate"));
343032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE;
343132b31808SJens Wiklander     }
343232b31808SJens Wiklander     mbedtls_pk_context *public_key = &own_cert->pk;
343332b31808SJens Wiklander     mbedtls_pk_context *private_key = mbedtls_ssl_own_key(ssl);
343432b31808SJens Wiklander     size_t len = mbedtls_pk_get_len(public_key);
343532b31808SJens Wiklander 
343632b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
343732b31808SJens Wiklander     /* If we have already started decoding the message and there is an ongoing
343832b31808SJens Wiklander      * decryption operation, resume signing. */
343932b31808SJens Wiklander     if (ssl->handshake->async_in_progress != 0) {
344032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("resuming decryption operation"));
344132b31808SJens Wiklander         return ssl_resume_decrypt_pms(ssl,
344232b31808SJens Wiklander                                       peer_pms, peer_pmslen, peer_pmssize);
344332b31808SJens Wiklander     }
344432b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
344532b31808SJens Wiklander 
344632b31808SJens Wiklander     /*
344732b31808SJens Wiklander      * Prepare to decrypt the premaster using own private RSA key
344832b31808SJens Wiklander      */
344932b31808SJens Wiklander     if (p + 2 > end) {
345032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
345132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
345232b31808SJens Wiklander     }
345332b31808SJens Wiklander     if (*p++ != MBEDTLS_BYTE_1(len) ||
345432b31808SJens Wiklander         *p++ != MBEDTLS_BYTE_0(len)) {
345532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
345632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
345732b31808SJens Wiklander     }
345832b31808SJens Wiklander 
345932b31808SJens Wiklander     if (p + len != end) {
346032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
346132b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
346232b31808SJens Wiklander     }
346332b31808SJens Wiklander 
346432b31808SJens Wiklander     /*
346532b31808SJens Wiklander      * Decrypt the premaster secret
346632b31808SJens Wiklander      */
346732b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
346832b31808SJens Wiklander     if (ssl->conf->f_async_decrypt_start != NULL) {
346932b31808SJens Wiklander         ret = ssl->conf->f_async_decrypt_start(ssl,
347032b31808SJens Wiklander                                                mbedtls_ssl_own_cert(ssl),
347132b31808SJens Wiklander                                                p, len);
347232b31808SJens Wiklander         switch (ret) {
347332b31808SJens Wiklander             case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH:
347432b31808SJens Wiklander                 /* act as if f_async_decrypt_start was null */
347532b31808SJens Wiklander                 break;
347632b31808SJens Wiklander             case 0:
347732b31808SJens Wiklander                 ssl->handshake->async_in_progress = 1;
347832b31808SJens Wiklander                 return ssl_resume_decrypt_pms(ssl,
347932b31808SJens Wiklander                                               peer_pms,
348032b31808SJens Wiklander                                               peer_pmslen,
348132b31808SJens Wiklander                                               peer_pmssize);
348232b31808SJens Wiklander             case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
348332b31808SJens Wiklander                 ssl->handshake->async_in_progress = 1;
348432b31808SJens Wiklander                 return MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS;
348532b31808SJens Wiklander             default:
348632b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "f_async_decrypt_start", ret);
348732b31808SJens Wiklander                 return ret;
348832b31808SJens Wiklander         }
348932b31808SJens Wiklander     }
349032b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
349132b31808SJens Wiklander 
349232b31808SJens Wiklander     if (!mbedtls_pk_can_do(private_key, MBEDTLS_PK_RSA)) {
349332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got no RSA private key"));
349432b31808SJens Wiklander         return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED;
349532b31808SJens Wiklander     }
349632b31808SJens Wiklander 
349732b31808SJens Wiklander     ret = mbedtls_pk_decrypt(private_key, p, len,
349832b31808SJens Wiklander                              peer_pms, peer_pmslen, peer_pmssize,
349932b31808SJens Wiklander                              ssl->conf->f_rng, ssl->conf->p_rng);
350032b31808SJens Wiklander     return ret;
350132b31808SJens Wiklander }
350232b31808SJens Wiklander 
350332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_encrypted_pms(mbedtls_ssl_context * ssl,const unsigned char * p,const unsigned char * end,size_t pms_offset)350432b31808SJens Wiklander static int ssl_parse_encrypted_pms(mbedtls_ssl_context *ssl,
350532b31808SJens Wiklander                                    const unsigned char *p,
350632b31808SJens Wiklander                                    const unsigned char *end,
350732b31808SJens Wiklander                                    size_t pms_offset)
350832b31808SJens Wiklander {
350932b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
351032b31808SJens Wiklander     unsigned char *pms = ssl->handshake->premaster + pms_offset;
351132b31808SJens Wiklander     unsigned char ver[2];
351232b31808SJens Wiklander     unsigned char fake_pms[48], peer_pms[48];
3513b0563631STom Van Eyck     size_t peer_pmslen;
3514b0563631STom Van Eyck     mbedtls_ct_condition_t diff;
351532b31808SJens Wiklander 
351632b31808SJens Wiklander     /* In case of a failure in decryption, the decryption may write less than
351732b31808SJens Wiklander      * 2 bytes of output, but we always read the first two bytes. It doesn't
351832b31808SJens Wiklander      * matter in the end because diff will be nonzero in that case due to
351932b31808SJens Wiklander      * ret being nonzero, and we only care whether diff is 0.
352032b31808SJens Wiklander      * But do initialize peer_pms and peer_pmslen for robustness anyway. This
352132b31808SJens Wiklander      * also makes memory analyzers happy (don't access uninitialized memory,
352232b31808SJens Wiklander      * even if it's an unsigned char). */
352332b31808SJens Wiklander     peer_pms[0] = peer_pms[1] = ~0;
352432b31808SJens Wiklander     peer_pmslen = 0;
352532b31808SJens Wiklander 
352632b31808SJens Wiklander     ret = ssl_decrypt_encrypted_pms(ssl, p, end,
352732b31808SJens Wiklander                                     peer_pms,
352832b31808SJens Wiklander                                     &peer_pmslen,
352932b31808SJens Wiklander                                     sizeof(peer_pms));
353032b31808SJens Wiklander 
353132b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
353232b31808SJens Wiklander     if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) {
353332b31808SJens Wiklander         return ret;
353432b31808SJens Wiklander     }
353532b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
353632b31808SJens Wiklander 
353732b31808SJens Wiklander     mbedtls_ssl_write_version(ver, ssl->conf->transport,
353832b31808SJens Wiklander                               ssl->session_negotiate->tls_version);
353932b31808SJens Wiklander 
354032b31808SJens Wiklander     /* Avoid data-dependent branches while checking for invalid
354132b31808SJens Wiklander      * padding, to protect against timing-based Bleichenbacher-type
354232b31808SJens Wiklander      * attacks. */
3543b0563631STom Van Eyck     diff = mbedtls_ct_bool(ret);
3544b0563631STom Van Eyck     diff = mbedtls_ct_bool_or(diff, mbedtls_ct_uint_ne(peer_pmslen, 48));
3545b0563631STom Van Eyck     diff = mbedtls_ct_bool_or(diff, mbedtls_ct_uint_ne(peer_pms[0], ver[0]));
3546b0563631STom Van Eyck     diff = mbedtls_ct_bool_or(diff, mbedtls_ct_uint_ne(peer_pms[1], ver[1]));
354732b31808SJens Wiklander 
354832b31808SJens Wiklander     /*
354932b31808SJens Wiklander      * Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding
355032b31808SJens Wiklander      * must not cause the connection to end immediately; instead, send a
355132b31808SJens Wiklander      * bad_record_mac later in the handshake.
355232b31808SJens Wiklander      * To protect against timing-based variants of the attack, we must
355332b31808SJens Wiklander      * not have any branch that depends on whether the decryption was
355432b31808SJens Wiklander      * successful. In particular, always generate the fake premaster secret,
355532b31808SJens Wiklander      * regardless of whether it will ultimately influence the output or not.
355632b31808SJens Wiklander      */
355732b31808SJens Wiklander     ret = ssl->conf->f_rng(ssl->conf->p_rng, fake_pms, sizeof(fake_pms));
355832b31808SJens Wiklander     if (ret != 0) {
355932b31808SJens Wiklander         /* It's ok to abort on an RNG failure, since this does not reveal
356032b31808SJens Wiklander          * anything about the RSA decryption. */
356132b31808SJens Wiklander         return ret;
356232b31808SJens Wiklander     }
356332b31808SJens Wiklander 
356432b31808SJens Wiklander #if defined(MBEDTLS_SSL_DEBUG_ALL)
3565b0563631STom Van Eyck     if (diff != MBEDTLS_CT_FALSE) {
356632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
356732b31808SJens Wiklander     }
356832b31808SJens Wiklander #endif
356932b31808SJens Wiklander 
357032b31808SJens Wiklander     if (sizeof(ssl->handshake->premaster) < pms_offset ||
357132b31808SJens Wiklander         sizeof(ssl->handshake->premaster) - pms_offset < 48) {
357232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
357332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
357432b31808SJens Wiklander     }
357532b31808SJens Wiklander     ssl->handshake->pmslen = 48;
357632b31808SJens Wiklander 
357732b31808SJens Wiklander     /* Set pms to either the true or the fake PMS, without
357832b31808SJens Wiklander      * data-dependent branches. */
3579b0563631STom Van Eyck     mbedtls_ct_memcpy_if(diff, pms, fake_pms, peer_pms, ssl->handshake->pmslen);
358032b31808SJens Wiklander 
358132b31808SJens Wiklander     return 0;
358232b31808SJens Wiklander }
358332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
358432b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
358532b31808SJens Wiklander 
358632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
358732b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_client_psk_identity(mbedtls_ssl_context * ssl,unsigned char ** p,const unsigned char * end)358832b31808SJens Wiklander static int ssl_parse_client_psk_identity(mbedtls_ssl_context *ssl, unsigned char **p,
358932b31808SJens Wiklander                                          const unsigned char *end)
359032b31808SJens Wiklander {
359132b31808SJens Wiklander     int ret = 0;
359232b31808SJens Wiklander     uint16_t n;
359332b31808SJens Wiklander 
359432b31808SJens Wiklander     if (ssl_conf_has_psk_or_cb(ssl->conf) == 0) {
359532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("got no pre-shared key"));
359632b31808SJens Wiklander         return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED;
359732b31808SJens Wiklander     }
359832b31808SJens Wiklander 
359932b31808SJens Wiklander     /*
360032b31808SJens Wiklander      * Receive client pre-shared key identity name
360132b31808SJens Wiklander      */
360232b31808SJens Wiklander     if (end - *p < 2) {
360332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
360432b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
360532b31808SJens Wiklander     }
360632b31808SJens Wiklander 
3607b0563631STom Van Eyck     n = MBEDTLS_GET_UINT16_BE(*p, 0);
360832b31808SJens Wiklander     *p += 2;
360932b31808SJens Wiklander 
361032b31808SJens Wiklander     if (n == 0 || n > end - *p) {
361132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
361232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
361332b31808SJens Wiklander     }
361432b31808SJens Wiklander 
361532b31808SJens Wiklander     if (ssl->conf->f_psk != NULL) {
361632b31808SJens Wiklander         if (ssl->conf->f_psk(ssl->conf->p_psk, ssl, *p, n) != 0) {
361732b31808SJens Wiklander             ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
361832b31808SJens Wiklander         }
361932b31808SJens Wiklander     } else {
362032b31808SJens Wiklander         /* Identity is not a big secret since clients send it in the clear,
362132b31808SJens Wiklander          * but treat it carefully anyway, just in case */
362232b31808SJens Wiklander         if (n != ssl->conf->psk_identity_len ||
362332b31808SJens Wiklander             mbedtls_ct_memcmp(ssl->conf->psk_identity, *p, n) != 0) {
362432b31808SJens Wiklander             ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
362532b31808SJens Wiklander         }
362632b31808SJens Wiklander     }
362732b31808SJens Wiklander 
362832b31808SJens Wiklander     if (ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) {
362932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_BUF(3, "Unknown PSK identity", *p, n);
363032b31808SJens Wiklander         mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
363132b31808SJens Wiklander                                        MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY);
363232b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
363332b31808SJens Wiklander     }
363432b31808SJens Wiklander 
363532b31808SJens Wiklander     *p += n;
363632b31808SJens Wiklander 
363732b31808SJens Wiklander     return 0;
363832b31808SJens Wiklander }
363932b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
364032b31808SJens Wiklander 
364132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_client_key_exchange(mbedtls_ssl_context * ssl)364232b31808SJens Wiklander static int ssl_parse_client_key_exchange(mbedtls_ssl_context *ssl)
364332b31808SJens Wiklander {
364432b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
364532b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
364632b31808SJens Wiklander     unsigned char *p, *end;
364732b31808SJens Wiklander 
364832b31808SJens Wiklander     ciphersuite_info = ssl->handshake->ciphersuite_info;
364932b31808SJens Wiklander 
365032b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse client key exchange"));
365132b31808SJens Wiklander 
365232b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE) && \
365332b31808SJens Wiklander     (defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
365432b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED))
365532b31808SJens Wiklander     if ((ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
365632b31808SJens Wiklander          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) &&
365732b31808SJens Wiklander         (ssl->handshake->async_in_progress != 0)) {
365832b31808SJens Wiklander         /* We've already read a record and there is an asynchronous
365932b31808SJens Wiklander          * operation in progress to decrypt it. So skip reading the
366032b31808SJens Wiklander          * record. */
366132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(3, ("will resume decryption of previously-read record"));
366232b31808SJens Wiklander     } else
366332b31808SJens Wiklander #endif
366432b31808SJens Wiklander     if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) {
366532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret);
366632b31808SJens Wiklander         return ret;
366732b31808SJens Wiklander     }
366832b31808SJens Wiklander 
366932b31808SJens Wiklander     p = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl);
367032b31808SJens Wiklander     end = ssl->in_msg + ssl->in_hslen;
367132b31808SJens Wiklander 
367232b31808SJens Wiklander     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) {
367332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
367432b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
367532b31808SJens Wiklander     }
367632b31808SJens Wiklander 
367732b31808SJens Wiklander     if (ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE) {
367832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message"));
367932b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
368032b31808SJens Wiklander     }
368132b31808SJens Wiklander 
368232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
368332b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA) {
368432b31808SJens Wiklander         if ((ret = ssl_parse_client_dh_public(ssl, &p, end)) != 0) {
368532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_dh_public"), ret);
368632b31808SJens Wiklander             return ret;
368732b31808SJens Wiklander         }
368832b31808SJens Wiklander 
368932b31808SJens Wiklander         if (p != end) {
369032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange"));
369132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
369232b31808SJens Wiklander         }
369332b31808SJens Wiklander 
369432b31808SJens Wiklander         if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx,
369532b31808SJens Wiklander                                            ssl->handshake->premaster,
369632b31808SJens Wiklander                                            MBEDTLS_PREMASTER_SIZE,
369732b31808SJens Wiklander                                            &ssl->handshake->pmslen,
369832b31808SJens Wiklander                                            ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
369932b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret);
370032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
370132b31808SJens Wiklander         }
370232b31808SJens Wiklander 
370332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K);
370432b31808SJens Wiklander     } else
370532b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
370632b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
370732b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
370832b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
370932b31808SJens Wiklander     defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
371032b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
371132b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
371232b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
371332b31808SJens Wiklander         ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA) {
371432b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
371532b31808SJens Wiklander         size_t data_len = (size_t) (*p++);
371632b31808SJens Wiklander         size_t buf_len = (size_t) (end - p);
371732b31808SJens Wiklander         psa_status_t status = PSA_ERROR_GENERIC_ERROR;
371832b31808SJens Wiklander         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
371932b31808SJens Wiklander 
3720b0563631STom Van Eyck         MBEDTLS_SSL_DEBUG_MSG(3, ("Read the peer's public key."));
372132b31808SJens Wiklander 
372232b31808SJens Wiklander         /*
372332b31808SJens Wiklander          * We must have at least two bytes (1 for length, at least 1 for data)
372432b31808SJens Wiklander          */
372532b31808SJens Wiklander         if (buf_len < 2) {
3726b0563631STom Van Eyck             MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid buffer length: %" MBEDTLS_PRINTF_SIZET,
3727b0563631STom Van Eyck                                       buf_len));
3728b0563631STom Van Eyck             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
372932b31808SJens Wiklander         }
373032b31808SJens Wiklander 
373132b31808SJens Wiklander         if (data_len < 1 || data_len > buf_len) {
3732b0563631STom Van Eyck             MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid data length: %" MBEDTLS_PRINTF_SIZET
3733b0563631STom Van Eyck                                       " > %" MBEDTLS_PRINTF_SIZET,
3734b0563631STom Van Eyck                                       data_len, buf_len));
3735b0563631STom Van Eyck             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
373632b31808SJens Wiklander         }
373732b31808SJens Wiklander 
373832b31808SJens Wiklander         /* Store peer's ECDH public key. */
3739b0563631STom Van Eyck         if (data_len > sizeof(handshake->xxdh_psa_peerkey)) {
3740b0563631STom Van Eyck             MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid public key length: %" MBEDTLS_PRINTF_SIZET
3741b0563631STom Van Eyck                                       " > %" MBEDTLS_PRINTF_SIZET,
3742b0563631STom Van Eyck                                       data_len,
3743b0563631STom Van Eyck                                       sizeof(handshake->xxdh_psa_peerkey)));
3744b0563631STom Van Eyck             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
3745b0563631STom Van Eyck         }
3746b0563631STom Van Eyck         memcpy(handshake->xxdh_psa_peerkey, p, data_len);
3747b0563631STom Van Eyck         handshake->xxdh_psa_peerkey_len = data_len;
374832b31808SJens Wiklander 
374932b31808SJens Wiklander         /* Compute ECDH shared secret. */
375032b31808SJens Wiklander         status = psa_raw_key_agreement(
3751b0563631STom Van Eyck             PSA_ALG_ECDH, handshake->xxdh_psa_privkey,
3752b0563631STom Van Eyck             handshake->xxdh_psa_peerkey, handshake->xxdh_psa_peerkey_len,
375332b31808SJens Wiklander             handshake->premaster, sizeof(handshake->premaster),
375432b31808SJens Wiklander             &handshake->pmslen);
375532b31808SJens Wiklander         if (status != PSA_SUCCESS) {
375632b31808SJens Wiklander             ret = PSA_TO_MBEDTLS_ERR(status);
375732b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_raw_key_agreement", ret);
3758b0563631STom Van Eyck             if (handshake->xxdh_psa_privkey_is_external == 0) {
3759b0563631STom Van Eyck                 (void) psa_destroy_key(handshake->xxdh_psa_privkey);
376032b31808SJens Wiklander             }
3761b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
376232b31808SJens Wiklander             return ret;
376332b31808SJens Wiklander         }
376432b31808SJens Wiklander 
3765b0563631STom Van Eyck         if (handshake->xxdh_psa_privkey_is_external == 0) {
3766b0563631STom Van Eyck             status = psa_destroy_key(handshake->xxdh_psa_privkey);
376732b31808SJens Wiklander 
376832b31808SJens Wiklander             if (status != PSA_SUCCESS) {
376932b31808SJens Wiklander                 ret = PSA_TO_MBEDTLS_ERR(status);
377032b31808SJens Wiklander                 MBEDTLS_SSL_DEBUG_RET(1, "psa_destroy_key", ret);
377132b31808SJens Wiklander                 return ret;
377232b31808SJens Wiklander             }
377332b31808SJens Wiklander         }
3774b0563631STom Van Eyck         handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
377532b31808SJens Wiklander #else
377632b31808SJens Wiklander         if ((ret = mbedtls_ecdh_read_public(&ssl->handshake->ecdh_ctx,
3777b0563631STom Van Eyck                                             p, (size_t) (end - p))) != 0) {
377832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_read_public", ret);
377932b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
378032b31808SJens Wiklander         }
378132b31808SJens Wiklander 
378232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
378332b31808SJens Wiklander                                MBEDTLS_DEBUG_ECDH_QP);
378432b31808SJens Wiklander 
378532b31808SJens Wiklander         if ((ret = mbedtls_ecdh_calc_secret(&ssl->handshake->ecdh_ctx,
378632b31808SJens Wiklander                                             &ssl->handshake->pmslen,
378732b31808SJens Wiklander                                             ssl->handshake->premaster,
378832b31808SJens Wiklander                                             MBEDTLS_MPI_MAX_SIZE,
378932b31808SJens Wiklander                                             ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
379032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_calc_secret", ret);
379132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
379232b31808SJens Wiklander         }
379332b31808SJens Wiklander 
379432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
379532b31808SJens Wiklander                                MBEDTLS_DEBUG_ECDH_Z);
379632b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
379732b31808SJens Wiklander     } else
379832b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
379932b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
380032b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
380132b31808SJens Wiklander           MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
380232b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
380332b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK) {
380432b31808SJens Wiklander         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
380532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
380632b31808SJens Wiklander             return ret;
380732b31808SJens Wiklander         }
380832b31808SJens Wiklander 
380932b31808SJens Wiklander         if (p != end) {
381032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange"));
381132b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
381232b31808SJens Wiklander         }
381332b31808SJens Wiklander 
381432b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO)
381532b31808SJens Wiklander         if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
3816b0563631STom Van Eyck                                                     (mbedtls_key_exchange_type_t) ciphersuite_info->
3817b0563631STom Van Eyck                                                     key_exchange)) != 0) {
381832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret);
381932b31808SJens Wiklander             return ret;
382032b31808SJens Wiklander         }
382132b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO */
382232b31808SJens Wiklander     } else
382332b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
382432b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
382532b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) {
382632b31808SJens Wiklander #if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
382732b31808SJens Wiklander         if (ssl->handshake->async_in_progress != 0) {
382832b31808SJens Wiklander             /* There is an asynchronous operation in progress to
382932b31808SJens Wiklander              * decrypt the encrypted premaster secret, so skip
383032b31808SJens Wiklander              * directly to resuming this operation. */
383132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(3, ("PSK identity already parsed"));
383232b31808SJens Wiklander             /* Update p to skip the PSK identity. ssl_parse_encrypted_pms
383332b31808SJens Wiklander              * won't actually use it, but maintain p anyway for robustness. */
383432b31808SJens Wiklander             p += ssl->conf->psk_identity_len + 2;
383532b31808SJens Wiklander         } else
383632b31808SJens Wiklander #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
383732b31808SJens Wiklander         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
383832b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
383932b31808SJens Wiklander             return ret;
384032b31808SJens Wiklander         }
384132b31808SJens Wiklander 
384232b31808SJens Wiklander         if ((ret = ssl_parse_encrypted_pms(ssl, p, end, 2)) != 0) {
384332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_encrypted_pms"), ret);
384432b31808SJens Wiklander             return ret;
384532b31808SJens Wiklander         }
384632b31808SJens Wiklander 
384732b31808SJens Wiklander #if !defined(MBEDTLS_USE_PSA_CRYPTO)
384832b31808SJens Wiklander         if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
3849b0563631STom Van Eyck                                                     (mbedtls_key_exchange_type_t) ciphersuite_info->
3850b0563631STom Van Eyck                                                     key_exchange)) != 0) {
385132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret);
385232b31808SJens Wiklander             return ret;
385332b31808SJens Wiklander         }
385432b31808SJens Wiklander #endif /* !MBEDTLS_USE_PSA_CRYPTO */
385532b31808SJens Wiklander     } else
385632b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
385732b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
385832b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK) {
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         if ((ret = ssl_parse_client_dh_public(ssl, &p, end)) != 0) {
386432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_dh_public"), ret);
386532b31808SJens Wiklander             return ret;
386632b31808SJens Wiklander         }
386732b31808SJens Wiklander 
386832b31808SJens Wiklander         if (p != end) {
386932b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange"));
387032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
387132b31808SJens Wiklander         }
387232b31808SJens Wiklander 
387332b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
387432b31808SJens Wiklander         unsigned char *pms = ssl->handshake->premaster;
387532b31808SJens Wiklander         unsigned char *pms_end = pms + sizeof(ssl->handshake->premaster);
387632b31808SJens Wiklander         size_t pms_len;
387732b31808SJens Wiklander 
387832b31808SJens Wiklander         /* Write length only when we know the actual value */
387932b31808SJens Wiklander         if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx,
388032b31808SJens Wiklander                                            pms + 2, pms_end - (pms + 2), &pms_len,
388132b31808SJens Wiklander                                            ssl->conf->f_rng, ssl->conf->p_rng)) != 0) {
388232b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret);
388332b31808SJens Wiklander             return ret;
388432b31808SJens Wiklander         }
388532b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(pms_len, pms, 0);
388632b31808SJens Wiklander         pms += 2 + pms_len;
388732b31808SJens Wiklander 
388832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K);
388932b31808SJens Wiklander #else
389032b31808SJens Wiklander         if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
3891b0563631STom Van Eyck                                                     (mbedtls_key_exchange_type_t) ciphersuite_info->
3892b0563631STom Van Eyck                                                     key_exchange)) != 0) {
389332b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret);
389432b31808SJens Wiklander             return ret;
389532b31808SJens Wiklander         }
389632b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
389732b31808SJens Wiklander     } else
389832b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
389932b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
390032b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) {
390132b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
390232b31808SJens Wiklander         psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
390332b31808SJens Wiklander         psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED;
3904cb034002SJerome Forissier         size_t ecpoint_len;
390532b31808SJens Wiklander 
390632b31808SJens Wiklander         mbedtls_ssl_handshake_params *handshake = ssl->handshake;
390732b31808SJens Wiklander 
390832b31808SJens Wiklander         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
390932b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
3910b0563631STom Van Eyck             psa_destroy_key(handshake->xxdh_psa_privkey);
3911b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
391232b31808SJens Wiklander             return ret;
391332b31808SJens Wiklander         }
391432b31808SJens Wiklander 
391532b31808SJens Wiklander         /* Keep a copy of the peer's public key */
391632b31808SJens Wiklander         if (p >= end) {
3917b0563631STom Van Eyck             psa_destroy_key(handshake->xxdh_psa_privkey);
3918b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
391932b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
392032b31808SJens Wiklander         }
392132b31808SJens Wiklander 
392232b31808SJens Wiklander         ecpoint_len = *(p++);
392332b31808SJens Wiklander         if ((size_t) (end - p) < ecpoint_len) {
3924b0563631STom Van Eyck             psa_destroy_key(handshake->xxdh_psa_privkey);
3925b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
392632b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
392732b31808SJens Wiklander         }
392832b31808SJens Wiklander 
3929b0563631STom Van Eyck         /* When FFDH is enabled, the array handshake->xxdh_psa_peer_key size takes into account
3930b0563631STom Van Eyck            the sizes of the FFDH keys which are at least 2048 bits.
3931b0563631STom Van Eyck            The size of the array is thus greater than 256 bytes which is greater than any
3932b0563631STom Van Eyck            possible value of ecpoint_len (type uint8_t) and the check below can be skipped.*/
3933b0563631STom Van Eyck #if !defined(PSA_WANT_ALG_FFDH)
3934b0563631STom Van Eyck         if (ecpoint_len > sizeof(handshake->xxdh_psa_peerkey)) {
3935b0563631STom Van Eyck             psa_destroy_key(handshake->xxdh_psa_privkey);
3936b0563631STom Van Eyck             handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
393732b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE;
393832b31808SJens Wiklander         }
3939b0563631STom Van Eyck #else
3940b0563631STom Van Eyck         MBEDTLS_STATIC_ASSERT(sizeof(handshake->xxdh_psa_peerkey) >= UINT8_MAX,
3941b0563631STom Van Eyck                               "peer key buffer too small");
3942b0563631STom Van Eyck #endif
394332b31808SJens Wiklander 
3944b0563631STom Van Eyck         memcpy(handshake->xxdh_psa_peerkey, p, ecpoint_len);
3945b0563631STom Van Eyck         handshake->xxdh_psa_peerkey_len = ecpoint_len;
394632b31808SJens Wiklander         p += ecpoint_len;
394732b31808SJens Wiklander 
394832b31808SJens Wiklander         /* As RFC 5489 section 2, the premaster secret is formed as follows:
394932b31808SJens Wiklander          * - a uint16 containing the length (in octets) of the ECDH computation
395032b31808SJens Wiklander          * - the octet string produced by the ECDH computation
395132b31808SJens Wiklander          * - a uint16 containing the length (in octets) of the PSK
395232b31808SJens Wiklander          * - the PSK itself
395332b31808SJens Wiklander          */
395432b31808SJens Wiklander         unsigned char *psm = ssl->handshake->premaster;
395532b31808SJens Wiklander         const unsigned char * const psm_end =
395632b31808SJens Wiklander             psm + sizeof(ssl->handshake->premaster);
395732b31808SJens Wiklander         /* uint16 to store length (in octets) of the ECDH computation */
395832b31808SJens Wiklander         const size_t zlen_size = 2;
395932b31808SJens Wiklander         size_t zlen = 0;
396032b31808SJens Wiklander 
396132b31808SJens Wiklander         /* Compute ECDH shared secret. */
396232b31808SJens Wiklander         status = psa_raw_key_agreement(PSA_ALG_ECDH,
3963b0563631STom Van Eyck                                        handshake->xxdh_psa_privkey,
3964b0563631STom Van Eyck                                        handshake->xxdh_psa_peerkey,
3965b0563631STom Van Eyck                                        handshake->xxdh_psa_peerkey_len,
396632b31808SJens Wiklander                                        psm + zlen_size,
396732b31808SJens Wiklander                                        psm_end - (psm + zlen_size),
396832b31808SJens Wiklander                                        &zlen);
396932b31808SJens Wiklander 
3970b0563631STom Van Eyck         destruction_status = psa_destroy_key(handshake->xxdh_psa_privkey);
3971b0563631STom Van Eyck         handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
397232b31808SJens Wiklander 
397332b31808SJens Wiklander         if (status != PSA_SUCCESS) {
397432b31808SJens Wiklander             return PSA_TO_MBEDTLS_ERR(status);
397532b31808SJens Wiklander         } else if (destruction_status != PSA_SUCCESS) {
397632b31808SJens Wiklander             return PSA_TO_MBEDTLS_ERR(destruction_status);
397732b31808SJens Wiklander         }
397832b31808SJens Wiklander 
397932b31808SJens Wiklander         /* Write the ECDH computation length before the ECDH computation */
398032b31808SJens Wiklander         MBEDTLS_PUT_UINT16_BE(zlen, psm, 0);
398132b31808SJens Wiklander         psm += zlen_size + zlen;
398232b31808SJens Wiklander 
398332b31808SJens Wiklander #else /* MBEDTLS_USE_PSA_CRYPTO */
398432b31808SJens Wiklander         if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) {
398532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret);
398632b31808SJens Wiklander             return ret;
398732b31808SJens Wiklander         }
398832b31808SJens Wiklander 
398932b31808SJens Wiklander         if ((ret = mbedtls_ecdh_read_public(&ssl->handshake->ecdh_ctx,
3990b0563631STom Van Eyck                                             p, (size_t) (end - p))) != 0) {
399132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_read_public", ret);
399232b31808SJens Wiklander             return MBEDTLS_ERR_SSL_DECODE_ERROR;
399332b31808SJens Wiklander         }
399432b31808SJens Wiklander 
399532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx,
399632b31808SJens Wiklander                                MBEDTLS_DEBUG_ECDH_QP);
399732b31808SJens Wiklander 
399832b31808SJens Wiklander         if ((ret = mbedtls_ssl_psk_derive_premaster(ssl,
3999b0563631STom Van Eyck                                                     (mbedtls_key_exchange_type_t) ciphersuite_info->
4000b0563631STom Van Eyck                                                     key_exchange)) != 0) {
400132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret);
400232b31808SJens Wiklander             return ret;
400332b31808SJens Wiklander         }
400432b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
400532b31808SJens Wiklander     } else
400632b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
400732b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
400832b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) {
400932b31808SJens Wiklander         if ((ret = ssl_parse_encrypted_pms(ssl, p, end, 0)) != 0) {
401032b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_parse_encrypted_pms_secret"), ret);
401132b31808SJens Wiklander             return ret;
401232b31808SJens Wiklander         }
401332b31808SJens Wiklander     } else
401432b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
401532b31808SJens Wiklander #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
401632b31808SJens Wiklander     if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) {
401732b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
401832b31808SJens Wiklander         if ((ret = mbedtls_psa_ecjpake_read_round(
4019b0563631STom Van Eyck                  &ssl->handshake->psa_pake_ctx, p, (size_t) (end - p),
402032b31808SJens Wiklander                  MBEDTLS_ECJPAKE_ROUND_TWO)) != 0) {
402132b31808SJens Wiklander             psa_destroy_key(ssl->handshake->psa_pake_password);
402232b31808SJens Wiklander             psa_pake_abort(&ssl->handshake->psa_pake_ctx);
402332b31808SJens Wiklander 
402432b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round two", ret);
402532b31808SJens Wiklander             return ret;
402632b31808SJens Wiklander         }
402732b31808SJens Wiklander #else
402832b31808SJens Wiklander         ret = mbedtls_ecjpake_read_round_two(&ssl->handshake->ecjpake_ctx,
4029b0563631STom Van Eyck                                              p, (size_t) (end - p));
403032b31808SJens Wiklander         if (ret != 0) {
403132b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_two", ret);
403232b31808SJens Wiklander             return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
403332b31808SJens Wiklander         }
403432b31808SJens Wiklander 
403532b31808SJens Wiklander         ret = mbedtls_ecjpake_derive_secret(&ssl->handshake->ecjpake_ctx,
403632b31808SJens Wiklander                                             ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
403732b31808SJens Wiklander                                             ssl->conf->f_rng, ssl->conf->p_rng);
403832b31808SJens Wiklander         if (ret != 0) {
403932b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_derive_secret", ret);
404032b31808SJens Wiklander             return ret;
404132b31808SJens Wiklander         }
404232b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
404332b31808SJens Wiklander     } else
404432b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
404532b31808SJens Wiklander     {
404632b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
404732b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
404832b31808SJens Wiklander     }
404932b31808SJens Wiklander 
405032b31808SJens Wiklander     if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) {
405132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret);
405232b31808SJens Wiklander         return ret;
405332b31808SJens Wiklander     }
405432b31808SJens Wiklander 
4055*273a583eSThomas Bourgoin     mbedtls_ssl_handshake_increment_state(ssl);
405632b31808SJens Wiklander 
405732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse client key exchange"));
405832b31808SJens Wiklander 
405932b31808SJens Wiklander     return 0;
406032b31808SJens Wiklander }
406132b31808SJens Wiklander 
406232b31808SJens Wiklander #if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
406332b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_certificate_verify(mbedtls_ssl_context * ssl)406432b31808SJens Wiklander static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl)
406532b31808SJens Wiklander {
406632b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
406732b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
406832b31808SJens Wiklander 
406932b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate verify"));
407032b31808SJens Wiklander 
407132b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
407232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
4073*273a583eSThomas Bourgoin         mbedtls_ssl_handshake_increment_state(ssl);
407432b31808SJens Wiklander         return 0;
407532b31808SJens Wiklander     }
407632b31808SJens Wiklander 
407732b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen"));
407832b31808SJens Wiklander     return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
407932b31808SJens Wiklander }
408032b31808SJens Wiklander #else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
408132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_parse_certificate_verify(mbedtls_ssl_context * ssl)408232b31808SJens Wiklander static int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl)
408332b31808SJens Wiklander {
408432b31808SJens Wiklander     int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
408532b31808SJens Wiklander     size_t i, sig_len;
408632b31808SJens Wiklander     unsigned char hash[48];
408732b31808SJens Wiklander     unsigned char *hash_start = hash;
408832b31808SJens Wiklander     size_t hashlen;
408932b31808SJens Wiklander     mbedtls_pk_type_t pk_alg;
409032b31808SJens Wiklander     mbedtls_md_type_t md_alg;
409132b31808SJens Wiklander     const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
409232b31808SJens Wiklander         ssl->handshake->ciphersuite_info;
409332b31808SJens Wiklander     mbedtls_pk_context *peer_pk;
409432b31808SJens Wiklander 
409532b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate verify"));
409632b31808SJens Wiklander 
409732b31808SJens Wiklander     if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) {
409832b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
4099*273a583eSThomas Bourgoin         mbedtls_ssl_handshake_increment_state(ssl);
410032b31808SJens Wiklander         return 0;
410132b31808SJens Wiklander     }
410232b31808SJens Wiklander 
410332b31808SJens Wiklander #if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
410432b31808SJens Wiklander     if (ssl->session_negotiate->peer_cert == NULL) {
410532b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
4106*273a583eSThomas Bourgoin         mbedtls_ssl_handshake_increment_state(ssl);
410732b31808SJens Wiklander         return 0;
410832b31808SJens Wiklander     }
410932b31808SJens Wiklander #else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
411032b31808SJens Wiklander     if (ssl->session_negotiate->peer_cert_digest == NULL) {
411132b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify"));
4112*273a583eSThomas Bourgoin         mbedtls_ssl_handshake_increment_state(ssl);
411332b31808SJens Wiklander         return 0;
411432b31808SJens Wiklander     }
411532b31808SJens Wiklander #endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
411632b31808SJens Wiklander 
411732b31808SJens Wiklander     /* Read the message without adding it to the checksum */
411832b31808SJens Wiklander     ret = mbedtls_ssl_read_record(ssl, 0 /* no checksum update */);
411932b31808SJens Wiklander     if (0 != ret) {
412032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_read_record"), ret);
412132b31808SJens Wiklander         return ret;
412232b31808SJens Wiklander     }
412332b31808SJens Wiklander 
4124*273a583eSThomas Bourgoin     mbedtls_ssl_handshake_increment_state(ssl);
412532b31808SJens Wiklander 
412632b31808SJens Wiklander     /* Process the message contents */
412732b31808SJens Wiklander     if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ||
412832b31808SJens Wiklander         ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY) {
412932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message"));
413032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE;
413132b31808SJens Wiklander     }
413232b31808SJens Wiklander 
413332b31808SJens Wiklander     i = mbedtls_ssl_hs_hdr_len(ssl);
413432b31808SJens Wiklander 
413532b31808SJens Wiklander #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
413632b31808SJens Wiklander     peer_pk = &ssl->handshake->peer_pubkey;
413732b31808SJens Wiklander #else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
413832b31808SJens Wiklander     if (ssl->session_negotiate->peer_cert == NULL) {
413932b31808SJens Wiklander         /* Should never happen */
414032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
414132b31808SJens Wiklander     }
414232b31808SJens Wiklander     peer_pk = &ssl->session_negotiate->peer_cert->pk;
414332b31808SJens Wiklander #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
414432b31808SJens Wiklander 
414532b31808SJens Wiklander     /*
414632b31808SJens Wiklander      *  struct {
414732b31808SJens Wiklander      *     SignatureAndHashAlgorithm algorithm; -- TLS 1.2 only
414832b31808SJens Wiklander      *     opaque signature<0..2^16-1>;
414932b31808SJens Wiklander      *  } DigitallySigned;
415032b31808SJens Wiklander      */
415132b31808SJens Wiklander     if (i + 2 > ssl->in_hslen) {
415232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message"));
415332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
415432b31808SJens Wiklander     }
415532b31808SJens Wiklander 
415632b31808SJens Wiklander     /*
415732b31808SJens Wiklander      * Hash
415832b31808SJens Wiklander      */
415932b31808SJens Wiklander     md_alg = mbedtls_ssl_md_alg_from_hash(ssl->in_msg[i]);
416032b31808SJens Wiklander 
416132b31808SJens Wiklander     if (md_alg == MBEDTLS_MD_NONE || mbedtls_ssl_set_calc_verify_md(ssl, ssl->in_msg[i])) {
416232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("peer not adhering to requested sig_alg"
416332b31808SJens Wiklander                                   " for verify message"));
416432b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
416532b31808SJens Wiklander     }
416632b31808SJens Wiklander 
416732b31808SJens Wiklander #if !defined(MBEDTLS_MD_SHA1)
416832b31808SJens Wiklander     if (MBEDTLS_MD_SHA1 == md_alg) {
416932b31808SJens Wiklander         hash_start += 16;
417032b31808SJens Wiklander     }
417132b31808SJens Wiklander #endif
417232b31808SJens Wiklander 
417332b31808SJens Wiklander     /* Info from md_alg will be used instead */
417432b31808SJens Wiklander     hashlen = 0;
417532b31808SJens Wiklander 
417632b31808SJens Wiklander     i++;
417732b31808SJens Wiklander 
417832b31808SJens Wiklander     /*
417932b31808SJens Wiklander      * Signature
418032b31808SJens Wiklander      */
418132b31808SJens Wiklander     if ((pk_alg = mbedtls_ssl_pk_alg_from_sig(ssl->in_msg[i]))
418232b31808SJens Wiklander         == MBEDTLS_PK_NONE) {
418332b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("peer not adhering to requested sig_alg"
418432b31808SJens Wiklander                                   " for verify message"));
418532b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
418632b31808SJens Wiklander     }
418732b31808SJens Wiklander 
418832b31808SJens Wiklander     /*
418932b31808SJens Wiklander      * Check the certificate's key type matches the signature alg
419032b31808SJens Wiklander      */
419132b31808SJens Wiklander     if (!mbedtls_pk_can_do(peer_pk, pk_alg)) {
419232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("sig_alg doesn't match cert key"));
419332b31808SJens Wiklander         return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER;
419432b31808SJens Wiklander     }
419532b31808SJens Wiklander 
419632b31808SJens Wiklander     i++;
419732b31808SJens Wiklander 
419832b31808SJens Wiklander     if (i + 2 > ssl->in_hslen) {
419932b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message"));
420032b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
420132b31808SJens Wiklander     }
420232b31808SJens Wiklander 
4203b0563631STom Van Eyck     sig_len = MBEDTLS_GET_UINT16_BE(ssl->in_msg, i);
420432b31808SJens Wiklander     i += 2;
420532b31808SJens Wiklander 
420632b31808SJens Wiklander     if (i + sig_len != ssl->in_hslen) {
420732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message"));
420832b31808SJens Wiklander         return MBEDTLS_ERR_SSL_DECODE_ERROR;
420932b31808SJens Wiklander     }
421032b31808SJens Wiklander 
421132b31808SJens Wiklander     /* Calculate hash and verify signature */
421232b31808SJens Wiklander     {
421332b31808SJens Wiklander         size_t dummy_hlen;
421432b31808SJens Wiklander         ret = ssl->handshake->calc_verify(ssl, hash, &dummy_hlen);
421532b31808SJens Wiklander         if (0 != ret) {
421632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_RET(1, ("calc_verify"), ret);
421732b31808SJens Wiklander             return ret;
421832b31808SJens Wiklander         }
421932b31808SJens Wiklander     }
422032b31808SJens Wiklander 
422132b31808SJens Wiklander     if ((ret = mbedtls_pk_verify(peer_pk,
422232b31808SJens Wiklander                                  md_alg, hash_start, hashlen,
422332b31808SJens Wiklander                                  ssl->in_msg + i, sig_len)) != 0) {
422432b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_verify", ret);
422532b31808SJens Wiklander         return ret;
422632b31808SJens Wiklander     }
422732b31808SJens Wiklander 
422832b31808SJens Wiklander     ret = mbedtls_ssl_update_handshake_status(ssl);
422932b31808SJens Wiklander     if (0 != ret) {
423032b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_update_handshake_status"), ret);
423132b31808SJens Wiklander         return ret;
423232b31808SJens Wiklander     }
423332b31808SJens Wiklander 
423432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate verify"));
423532b31808SJens Wiklander 
423632b31808SJens Wiklander     return ret;
423732b31808SJens Wiklander }
423832b31808SJens Wiklander #endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
423932b31808SJens Wiklander 
424032b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
424132b31808SJens Wiklander MBEDTLS_CHECK_RETURN_CRITICAL
ssl_write_new_session_ticket(mbedtls_ssl_context * ssl)424232b31808SJens Wiklander static int ssl_write_new_session_ticket(mbedtls_ssl_context *ssl)
424332b31808SJens Wiklander {
424432b31808SJens Wiklander     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
424532b31808SJens Wiklander     size_t tlen;
424632b31808SJens Wiklander     uint32_t lifetime;
424732b31808SJens Wiklander 
424832b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("=> write new session ticket"));
424932b31808SJens Wiklander 
425032b31808SJens Wiklander     ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
425132b31808SJens Wiklander     ssl->out_msg[0]  = MBEDTLS_SSL_HS_NEW_SESSION_TICKET;
425232b31808SJens Wiklander 
425332b31808SJens Wiklander     /*
425432b31808SJens Wiklander      * struct {
425532b31808SJens Wiklander      *     uint32 ticket_lifetime_hint;
425632b31808SJens Wiklander      *     opaque ticket<0..2^16-1>;
425732b31808SJens Wiklander      * } NewSessionTicket;
425832b31808SJens Wiklander      *
425932b31808SJens Wiklander      * 4  .  7   ticket_lifetime_hint (0 = unspecified)
426032b31808SJens Wiklander      * 8  .  9   ticket_len (n)
426132b31808SJens Wiklander      * 10 .  9+n ticket content
426232b31808SJens Wiklander      */
426332b31808SJens Wiklander 
4264b0563631STom Van Eyck #if defined(MBEDTLS_HAVE_TIME)
4265b0563631STom Van Eyck     ssl->session_negotiate->ticket_creation_time = mbedtls_ms_time();
4266b0563631STom Van Eyck #endif
426732b31808SJens Wiklander     if ((ret = ssl->conf->f_ticket_write(ssl->conf->p_ticket,
426832b31808SJens Wiklander                                          ssl->session_negotiate,
426932b31808SJens Wiklander                                          ssl->out_msg + 10,
427032b31808SJens Wiklander                                          ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN,
427132b31808SJens Wiklander                                          &tlen, &lifetime)) != 0) {
427232b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_ticket_write", ret);
427332b31808SJens Wiklander         tlen = 0;
427432b31808SJens Wiklander     }
427532b31808SJens Wiklander 
427632b31808SJens Wiklander     MBEDTLS_PUT_UINT32_BE(lifetime, ssl->out_msg, 4);
427732b31808SJens Wiklander     MBEDTLS_PUT_UINT16_BE(tlen, ssl->out_msg, 8);
427832b31808SJens Wiklander     ssl->out_msglen = 10 + tlen;
427932b31808SJens Wiklander 
428032b31808SJens Wiklander     /*
428132b31808SJens Wiklander      * Morally equivalent to updating ssl->state, but NewSessionTicket and
428232b31808SJens Wiklander      * ChangeCipherSpec share the same state.
428332b31808SJens Wiklander      */
428432b31808SJens Wiklander     ssl->handshake->new_session_ticket = 0;
428532b31808SJens Wiklander 
428632b31808SJens Wiklander     if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) {
428732b31808SJens Wiklander         MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret);
428832b31808SJens Wiklander         return ret;
428932b31808SJens Wiklander     }
429032b31808SJens Wiklander 
429132b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("<= write new session ticket"));
429232b31808SJens Wiklander 
429332b31808SJens Wiklander     return 0;
429432b31808SJens Wiklander }
429532b31808SJens Wiklander #endif /* MBEDTLS_SSL_SESSION_TICKETS */
429632b31808SJens Wiklander 
429732b31808SJens Wiklander /*
429832b31808SJens Wiklander  * SSL handshake -- server side -- single step
429932b31808SJens Wiklander  */
mbedtls_ssl_handshake_server_step(mbedtls_ssl_context * ssl)430032b31808SJens Wiklander int mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl)
430132b31808SJens Wiklander {
430232b31808SJens Wiklander     int ret = 0;
430332b31808SJens Wiklander 
430432b31808SJens Wiklander     MBEDTLS_SSL_DEBUG_MSG(2, ("server state: %d", ssl->state));
430532b31808SJens Wiklander 
430632b31808SJens Wiklander     switch (ssl->state) {
430732b31808SJens Wiklander         case MBEDTLS_SSL_HELLO_REQUEST:
4308*273a583eSThomas Bourgoin             mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_CLIENT_HELLO);
430932b31808SJens Wiklander             break;
431032b31808SJens Wiklander 
431132b31808SJens Wiklander         /*
431232b31808SJens Wiklander          *  <==   ClientHello
431332b31808SJens Wiklander          */
431432b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_HELLO:
431532b31808SJens Wiklander             ret = ssl_parse_client_hello(ssl);
431632b31808SJens Wiklander             break;
431732b31808SJens Wiklander 
431832b31808SJens Wiklander #if defined(MBEDTLS_SSL_PROTO_DTLS)
431932b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT:
432032b31808SJens Wiklander             return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED;
432132b31808SJens Wiklander #endif
432232b31808SJens Wiklander 
432332b31808SJens Wiklander         /*
432432b31808SJens Wiklander          *  ==>   ServerHello
432532b31808SJens Wiklander          *        Certificate
432632b31808SJens Wiklander          *      ( ServerKeyExchange  )
432732b31808SJens Wiklander          *      ( CertificateRequest )
432832b31808SJens Wiklander          *        ServerHelloDone
432932b31808SJens Wiklander          */
433032b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_HELLO:
433132b31808SJens Wiklander             ret = ssl_write_server_hello(ssl);
433232b31808SJens Wiklander             break;
433332b31808SJens Wiklander 
433432b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_CERTIFICATE:
433532b31808SJens Wiklander             ret = mbedtls_ssl_write_certificate(ssl);
433632b31808SJens Wiklander             break;
433732b31808SJens Wiklander 
433832b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_KEY_EXCHANGE:
433932b31808SJens Wiklander             ret = ssl_write_server_key_exchange(ssl);
434032b31808SJens Wiklander             break;
434132b31808SJens Wiklander 
434232b31808SJens Wiklander         case MBEDTLS_SSL_CERTIFICATE_REQUEST:
434332b31808SJens Wiklander             ret = ssl_write_certificate_request(ssl);
434432b31808SJens Wiklander             break;
434532b31808SJens Wiklander 
434632b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_HELLO_DONE:
434732b31808SJens Wiklander             ret = ssl_write_server_hello_done(ssl);
434832b31808SJens Wiklander             break;
434932b31808SJens Wiklander 
435032b31808SJens Wiklander         /*
435132b31808SJens Wiklander          *  <== ( Certificate/Alert  )
435232b31808SJens Wiklander          *        ClientKeyExchange
435332b31808SJens Wiklander          *      ( CertificateVerify  )
435432b31808SJens Wiklander          *        ChangeCipherSpec
435532b31808SJens Wiklander          *        Finished
435632b31808SJens Wiklander          */
435732b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_CERTIFICATE:
435832b31808SJens Wiklander             ret = mbedtls_ssl_parse_certificate(ssl);
435932b31808SJens Wiklander             break;
436032b31808SJens Wiklander 
436132b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE:
436232b31808SJens Wiklander             ret = ssl_parse_client_key_exchange(ssl);
436332b31808SJens Wiklander             break;
436432b31808SJens Wiklander 
436532b31808SJens Wiklander         case MBEDTLS_SSL_CERTIFICATE_VERIFY:
436632b31808SJens Wiklander             ret = ssl_parse_certificate_verify(ssl);
436732b31808SJens Wiklander             break;
436832b31808SJens Wiklander 
436932b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC:
437032b31808SJens Wiklander             ret = mbedtls_ssl_parse_change_cipher_spec(ssl);
437132b31808SJens Wiklander             break;
437232b31808SJens Wiklander 
437332b31808SJens Wiklander         case MBEDTLS_SSL_CLIENT_FINISHED:
437432b31808SJens Wiklander             ret = mbedtls_ssl_parse_finished(ssl);
437532b31808SJens Wiklander             break;
437632b31808SJens Wiklander 
437732b31808SJens Wiklander         /*
437832b31808SJens Wiklander          *  ==> ( NewSessionTicket )
437932b31808SJens Wiklander          *        ChangeCipherSpec
438032b31808SJens Wiklander          *        Finished
438132b31808SJens Wiklander          */
438232b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC:
438332b31808SJens Wiklander #if defined(MBEDTLS_SSL_SESSION_TICKETS)
438432b31808SJens Wiklander             if (ssl->handshake->new_session_ticket != 0) {
438532b31808SJens Wiklander                 ret = ssl_write_new_session_ticket(ssl);
438632b31808SJens Wiklander             } else
438732b31808SJens Wiklander #endif
438832b31808SJens Wiklander             ret = mbedtls_ssl_write_change_cipher_spec(ssl);
438932b31808SJens Wiklander             break;
439032b31808SJens Wiklander 
439132b31808SJens Wiklander         case MBEDTLS_SSL_SERVER_FINISHED:
439232b31808SJens Wiklander             ret = mbedtls_ssl_write_finished(ssl);
439332b31808SJens Wiklander             break;
439432b31808SJens Wiklander 
439532b31808SJens Wiklander         case MBEDTLS_SSL_FLUSH_BUFFERS:
439632b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done"));
4397*273a583eSThomas Bourgoin             mbedtls_ssl_handshake_set_state(ssl, MBEDTLS_SSL_HANDSHAKE_WRAPUP);
439832b31808SJens Wiklander             break;
439932b31808SJens Wiklander 
440032b31808SJens Wiklander         case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
440132b31808SJens Wiklander             mbedtls_ssl_handshake_wrapup(ssl);
440232b31808SJens Wiklander             break;
440332b31808SJens Wiklander 
440432b31808SJens Wiklander         default:
440532b31808SJens Wiklander             MBEDTLS_SSL_DEBUG_MSG(1, ("invalid state %d", ssl->state));
440632b31808SJens Wiklander             return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
440732b31808SJens Wiklander     }
440832b31808SJens Wiklander 
440932b31808SJens Wiklander     return ret;
441032b31808SJens Wiklander }
441132b31808SJens Wiklander 
mbedtls_ssl_conf_preference_order(mbedtls_ssl_config * conf,int order)441232b31808SJens Wiklander void mbedtls_ssl_conf_preference_order(mbedtls_ssl_config *conf, int order)
441332b31808SJens Wiklander {
441432b31808SJens Wiklander     conf->respect_cli_pref = order;
441532b31808SJens Wiklander }
441632b31808SJens Wiklander 
441732b31808SJens Wiklander #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_PROTO_TLS1_2 */
4418