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