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