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