1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * TLS server-side functions 3a8e1175bSopenharmony_ci * 4a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 5a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6a8e1175bSopenharmony_ci */ 7a8e1175bSopenharmony_ci 8a8e1175bSopenharmony_ci#include "common.h" 9a8e1175bSopenharmony_ci 10a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_PROTO_TLS1_2) 11a8e1175bSopenharmony_ci 12a8e1175bSopenharmony_ci#include "mbedtls/platform.h" 13a8e1175bSopenharmony_ci 14a8e1175bSopenharmony_ci#include "mbedtls/ssl.h" 15a8e1175bSopenharmony_ci#include "ssl_misc.h" 16a8e1175bSopenharmony_ci#include "debug_internal.h" 17a8e1175bSopenharmony_ci#include "mbedtls/error.h" 18a8e1175bSopenharmony_ci#include "mbedtls/platform_util.h" 19a8e1175bSopenharmony_ci#include "constant_time_internal.h" 20a8e1175bSopenharmony_ci#include "mbedtls/constant_time.h" 21a8e1175bSopenharmony_ci 22a8e1175bSopenharmony_ci#include <string.h> 23a8e1175bSopenharmony_ci 24a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 25a8e1175bSopenharmony_ci/* Define a local translating function to save code size by not using too many 26a8e1175bSopenharmony_ci * arguments in each translating place. */ 27a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED) || \ 28a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) 29a8e1175bSopenharmony_cistatic int local_err_translation(psa_status_t status) 30a8e1175bSopenharmony_ci{ 31a8e1175bSopenharmony_ci return psa_status_to_mbedtls(status, psa_to_ssl_errors, 32a8e1175bSopenharmony_ci ARRAY_LENGTH(psa_to_ssl_errors), 33a8e1175bSopenharmony_ci psa_generic_status_to_mbedtls); 34a8e1175bSopenharmony_ci} 35a8e1175bSopenharmony_ci#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) 36a8e1175bSopenharmony_ci#endif 37a8e1175bSopenharmony_ci#endif 38a8e1175bSopenharmony_ci 39a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECP_C) 40a8e1175bSopenharmony_ci#include "mbedtls/ecp.h" 41a8e1175bSopenharmony_ci#endif 42a8e1175bSopenharmony_ci 43a8e1175bSopenharmony_ci#if defined(MBEDTLS_HAVE_TIME) 44a8e1175bSopenharmony_ci#include "mbedtls/platform_time.h" 45a8e1175bSopenharmony_ci#endif 46a8e1175bSopenharmony_ci 47a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) 48a8e1175bSopenharmony_ciint mbedtls_ssl_set_client_transport_id(mbedtls_ssl_context *ssl, 49a8e1175bSopenharmony_ci const unsigned char *info, 50a8e1175bSopenharmony_ci size_t ilen) 51a8e1175bSopenharmony_ci{ 52a8e1175bSopenharmony_ci if (ssl->conf->endpoint != MBEDTLS_SSL_IS_SERVER) { 53a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 54a8e1175bSopenharmony_ci } 55a8e1175bSopenharmony_ci 56a8e1175bSopenharmony_ci mbedtls_free(ssl->cli_id); 57a8e1175bSopenharmony_ci 58a8e1175bSopenharmony_ci if ((ssl->cli_id = mbedtls_calloc(1, ilen)) == NULL) { 59a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ALLOC_FAILED; 60a8e1175bSopenharmony_ci } 61a8e1175bSopenharmony_ci 62a8e1175bSopenharmony_ci memcpy(ssl->cli_id, info, ilen); 63a8e1175bSopenharmony_ci ssl->cli_id_len = ilen; 64a8e1175bSopenharmony_ci 65a8e1175bSopenharmony_ci return 0; 66a8e1175bSopenharmony_ci} 67a8e1175bSopenharmony_ci 68a8e1175bSopenharmony_civoid mbedtls_ssl_conf_dtls_cookies(mbedtls_ssl_config *conf, 69a8e1175bSopenharmony_ci mbedtls_ssl_cookie_write_t *f_cookie_write, 70a8e1175bSopenharmony_ci mbedtls_ssl_cookie_check_t *f_cookie_check, 71a8e1175bSopenharmony_ci void *p_cookie) 72a8e1175bSopenharmony_ci{ 73a8e1175bSopenharmony_ci conf->f_cookie_write = f_cookie_write; 74a8e1175bSopenharmony_ci conf->f_cookie_check = f_cookie_check; 75a8e1175bSopenharmony_ci conf->p_cookie = p_cookie; 76a8e1175bSopenharmony_ci} 77a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ 78a8e1175bSopenharmony_ci 79a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) 80a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 81a8e1175bSopenharmony_cistatic int ssl_conf_has_psk_or_cb(mbedtls_ssl_config const *conf) 82a8e1175bSopenharmony_ci{ 83a8e1175bSopenharmony_ci if (conf->f_psk != NULL) { 84a8e1175bSopenharmony_ci return 1; 85a8e1175bSopenharmony_ci } 86a8e1175bSopenharmony_ci 87a8e1175bSopenharmony_ci if (conf->psk_identity_len == 0 || conf->psk_identity == NULL) { 88a8e1175bSopenharmony_ci return 0; 89a8e1175bSopenharmony_ci } 90a8e1175bSopenharmony_ci 91a8e1175bSopenharmony_ci 92a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 93a8e1175bSopenharmony_ci if (!mbedtls_svc_key_id_is_null(conf->psk_opaque)) { 94a8e1175bSopenharmony_ci return 1; 95a8e1175bSopenharmony_ci } 96a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 97a8e1175bSopenharmony_ci 98a8e1175bSopenharmony_ci if (conf->psk != NULL && conf->psk_len != 0) { 99a8e1175bSopenharmony_ci return 1; 100a8e1175bSopenharmony_ci } 101a8e1175bSopenharmony_ci 102a8e1175bSopenharmony_ci return 0; 103a8e1175bSopenharmony_ci} 104a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ 105a8e1175bSopenharmony_ci 106a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 107a8e1175bSopenharmony_cistatic int ssl_parse_renegotiation_info(mbedtls_ssl_context *ssl, 108a8e1175bSopenharmony_ci const unsigned char *buf, 109a8e1175bSopenharmony_ci size_t len) 110a8e1175bSopenharmony_ci{ 111a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 112a8e1175bSopenharmony_ci if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) { 113a8e1175bSopenharmony_ci /* Check verify-data in constant-time. The length OTOH is no secret */ 114a8e1175bSopenharmony_ci if (len != 1 + ssl->verify_data_len || 115a8e1175bSopenharmony_ci buf[0] != ssl->verify_data_len || 116a8e1175bSopenharmony_ci mbedtls_ct_memcmp(buf + 1, ssl->peer_verify_data, 117a8e1175bSopenharmony_ci ssl->verify_data_len) != 0) { 118a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("non-matching renegotiation info")); 119a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 120a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 121a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 122a8e1175bSopenharmony_ci } 123a8e1175bSopenharmony_ci } else 124a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_RENEGOTIATION */ 125a8e1175bSopenharmony_ci { 126a8e1175bSopenharmony_ci if (len != 1 || buf[0] != 0x0) { 127a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("non-zero length renegotiation info")); 128a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 129a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 130a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 131a8e1175bSopenharmony_ci } 132a8e1175bSopenharmony_ci 133a8e1175bSopenharmony_ci ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; 134a8e1175bSopenharmony_ci } 135a8e1175bSopenharmony_ci 136a8e1175bSopenharmony_ci return 0; 137a8e1175bSopenharmony_ci} 138a8e1175bSopenharmony_ci 139a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ 140a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ 141a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 142a8e1175bSopenharmony_ci/* 143a8e1175bSopenharmony_ci * Function for parsing a supported groups (TLS 1.3) or supported elliptic 144a8e1175bSopenharmony_ci * curves (TLS 1.2) extension. 145a8e1175bSopenharmony_ci * 146a8e1175bSopenharmony_ci * The "extension_data" field of a supported groups extension contains a 147a8e1175bSopenharmony_ci * "NamedGroupList" value (TLS 1.3 RFC8446): 148a8e1175bSopenharmony_ci * enum { 149a8e1175bSopenharmony_ci * secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019), 150a8e1175bSopenharmony_ci * x25519(0x001D), x448(0x001E), 151a8e1175bSopenharmony_ci * ffdhe2048(0x0100), ffdhe3072(0x0101), ffdhe4096(0x0102), 152a8e1175bSopenharmony_ci * ffdhe6144(0x0103), ffdhe8192(0x0104), 153a8e1175bSopenharmony_ci * ffdhe_private_use(0x01FC..0x01FF), 154a8e1175bSopenharmony_ci * ecdhe_private_use(0xFE00..0xFEFF), 155a8e1175bSopenharmony_ci * (0xFFFF) 156a8e1175bSopenharmony_ci * } NamedGroup; 157a8e1175bSopenharmony_ci * struct { 158a8e1175bSopenharmony_ci * NamedGroup named_group_list<2..2^16-1>; 159a8e1175bSopenharmony_ci * } NamedGroupList; 160a8e1175bSopenharmony_ci * 161a8e1175bSopenharmony_ci * The "extension_data" field of a supported elliptic curves extension contains 162a8e1175bSopenharmony_ci * a "NamedCurveList" value (TLS 1.2 RFC 8422): 163a8e1175bSopenharmony_ci * enum { 164a8e1175bSopenharmony_ci * deprecated(1..22), 165a8e1175bSopenharmony_ci * secp256r1 (23), secp384r1 (24), secp521r1 (25), 166a8e1175bSopenharmony_ci * x25519(29), x448(30), 167a8e1175bSopenharmony_ci * reserved (0xFE00..0xFEFF), 168a8e1175bSopenharmony_ci * deprecated(0xFF01..0xFF02), 169a8e1175bSopenharmony_ci * (0xFFFF) 170a8e1175bSopenharmony_ci * } NamedCurve; 171a8e1175bSopenharmony_ci * struct { 172a8e1175bSopenharmony_ci * NamedCurve named_curve_list<2..2^16-1> 173a8e1175bSopenharmony_ci * } NamedCurveList; 174a8e1175bSopenharmony_ci * 175a8e1175bSopenharmony_ci * The TLS 1.3 supported groups extension was defined to be a compatible 176a8e1175bSopenharmony_ci * generalization of the TLS 1.2 supported elliptic curves extension. They both 177a8e1175bSopenharmony_ci * share the same extension identifier. 178a8e1175bSopenharmony_ci * 179a8e1175bSopenharmony_ci */ 180a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 181a8e1175bSopenharmony_cistatic int ssl_parse_supported_groups_ext(mbedtls_ssl_context *ssl, 182a8e1175bSopenharmony_ci const unsigned char *buf, 183a8e1175bSopenharmony_ci size_t len) 184a8e1175bSopenharmony_ci{ 185a8e1175bSopenharmony_ci size_t list_size, our_size; 186a8e1175bSopenharmony_ci const unsigned char *p; 187a8e1175bSopenharmony_ci uint16_t *curves_tls_id; 188a8e1175bSopenharmony_ci 189a8e1175bSopenharmony_ci if (len < 2) { 190a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 191a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 192a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 193a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 194a8e1175bSopenharmony_ci } 195a8e1175bSopenharmony_ci list_size = MBEDTLS_GET_UINT16_BE(buf, 0); 196a8e1175bSopenharmony_ci if (list_size + 2 != len || 197a8e1175bSopenharmony_ci list_size % 2 != 0) { 198a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 199a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 200a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 201a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 202a8e1175bSopenharmony_ci } 203a8e1175bSopenharmony_ci 204a8e1175bSopenharmony_ci /* Should never happen unless client duplicates the extension */ 205a8e1175bSopenharmony_ci if (ssl->handshake->curves_tls_id != NULL) { 206a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 207a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 208a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 209a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 210a8e1175bSopenharmony_ci } 211a8e1175bSopenharmony_ci 212a8e1175bSopenharmony_ci /* Don't allow our peer to make us allocate too much memory, 213a8e1175bSopenharmony_ci * and leave room for a final 0 */ 214a8e1175bSopenharmony_ci our_size = list_size / 2 + 1; 215a8e1175bSopenharmony_ci if (our_size > MBEDTLS_ECP_DP_MAX) { 216a8e1175bSopenharmony_ci our_size = MBEDTLS_ECP_DP_MAX; 217a8e1175bSopenharmony_ci } 218a8e1175bSopenharmony_ci 219a8e1175bSopenharmony_ci if ((curves_tls_id = mbedtls_calloc(our_size, 220a8e1175bSopenharmony_ci sizeof(*curves_tls_id))) == NULL) { 221a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 222a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR); 223a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ALLOC_FAILED; 224a8e1175bSopenharmony_ci } 225a8e1175bSopenharmony_ci 226a8e1175bSopenharmony_ci ssl->handshake->curves_tls_id = curves_tls_id; 227a8e1175bSopenharmony_ci 228a8e1175bSopenharmony_ci p = buf + 2; 229a8e1175bSopenharmony_ci while (list_size > 0 && our_size > 1) { 230a8e1175bSopenharmony_ci uint16_t curr_tls_id = MBEDTLS_GET_UINT16_BE(p, 0); 231a8e1175bSopenharmony_ci 232a8e1175bSopenharmony_ci if (mbedtls_ssl_get_ecp_group_id_from_tls_id(curr_tls_id) != 233a8e1175bSopenharmony_ci MBEDTLS_ECP_DP_NONE) { 234a8e1175bSopenharmony_ci *curves_tls_id++ = curr_tls_id; 235a8e1175bSopenharmony_ci our_size--; 236a8e1175bSopenharmony_ci } 237a8e1175bSopenharmony_ci 238a8e1175bSopenharmony_ci list_size -= 2; 239a8e1175bSopenharmony_ci p += 2; 240a8e1175bSopenharmony_ci } 241a8e1175bSopenharmony_ci 242a8e1175bSopenharmony_ci return 0; 243a8e1175bSopenharmony_ci} 244a8e1175bSopenharmony_ci 245a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 246a8e1175bSopenharmony_cistatic int ssl_parse_supported_point_formats(mbedtls_ssl_context *ssl, 247a8e1175bSopenharmony_ci const unsigned char *buf, 248a8e1175bSopenharmony_ci size_t len) 249a8e1175bSopenharmony_ci{ 250a8e1175bSopenharmony_ci size_t list_size; 251a8e1175bSopenharmony_ci const unsigned char *p; 252a8e1175bSopenharmony_ci 253a8e1175bSopenharmony_ci if (len == 0 || (size_t) (buf[0] + 1) != len) { 254a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 255a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 256a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 257a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 258a8e1175bSopenharmony_ci } 259a8e1175bSopenharmony_ci list_size = buf[0]; 260a8e1175bSopenharmony_ci 261a8e1175bSopenharmony_ci p = buf + 1; 262a8e1175bSopenharmony_ci while (list_size > 0) { 263a8e1175bSopenharmony_ci if (p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || 264a8e1175bSopenharmony_ci p[0] == MBEDTLS_ECP_PF_COMPRESSED) { 265a8e1175bSopenharmony_ci#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ 266a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) 267a8e1175bSopenharmony_ci ssl->handshake->ecdh_ctx.point_format = p[0]; 268a8e1175bSopenharmony_ci#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED */ 269a8e1175bSopenharmony_ci#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ 270a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 271a8e1175bSopenharmony_ci mbedtls_ecjpake_set_point_format(&ssl->handshake->ecjpake_ctx, 272a8e1175bSopenharmony_ci p[0]); 273a8e1175bSopenharmony_ci#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 274a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(4, ("point format selected: %d", p[0])); 275a8e1175bSopenharmony_ci return 0; 276a8e1175bSopenharmony_ci } 277a8e1175bSopenharmony_ci 278a8e1175bSopenharmony_ci list_size--; 279a8e1175bSopenharmony_ci p++; 280a8e1175bSopenharmony_ci } 281a8e1175bSopenharmony_ci 282a8e1175bSopenharmony_ci return 0; 283a8e1175bSopenharmony_ci} 284a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || 285a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED || 286a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 287a8e1175bSopenharmony_ci 288a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 289a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 290a8e1175bSopenharmony_cistatic int ssl_parse_ecjpake_kkpp(mbedtls_ssl_context *ssl, 291a8e1175bSopenharmony_ci const unsigned char *buf, 292a8e1175bSopenharmony_ci size_t len) 293a8e1175bSopenharmony_ci{ 294a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 295a8e1175bSopenharmony_ci 296a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 297a8e1175bSopenharmony_ci if (ssl->handshake->psa_pake_ctx_is_ok != 1) 298a8e1175bSopenharmony_ci#else 299a8e1175bSopenharmony_ci if (mbedtls_ecjpake_check(&ssl->handshake->ecjpake_ctx) != 0) 300a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 301a8e1175bSopenharmony_ci { 302a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("skip ecjpake kkpp extension")); 303a8e1175bSopenharmony_ci return 0; 304a8e1175bSopenharmony_ci } 305a8e1175bSopenharmony_ci 306a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 307a8e1175bSopenharmony_ci if ((ret = mbedtls_psa_ecjpake_read_round( 308a8e1175bSopenharmony_ci &ssl->handshake->psa_pake_ctx, buf, len, 309a8e1175bSopenharmony_ci MBEDTLS_ECJPAKE_ROUND_ONE)) != 0) { 310a8e1175bSopenharmony_ci psa_destroy_key(ssl->handshake->psa_pake_password); 311a8e1175bSopenharmony_ci psa_pake_abort(&ssl->handshake->psa_pake_ctx); 312a8e1175bSopenharmony_ci 313a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round one", ret); 314a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 315a8e1175bSopenharmony_ci ssl, 316a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 317a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 318a8e1175bSopenharmony_ci 319a8e1175bSopenharmony_ci return ret; 320a8e1175bSopenharmony_ci } 321a8e1175bSopenharmony_ci#else 322a8e1175bSopenharmony_ci if ((ret = mbedtls_ecjpake_read_round_one(&ssl->handshake->ecjpake_ctx, 323a8e1175bSopenharmony_ci buf, len)) != 0) { 324a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_one", ret); 325a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 326a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 327a8e1175bSopenharmony_ci return ret; 328a8e1175bSopenharmony_ci } 329a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 330a8e1175bSopenharmony_ci 331a8e1175bSopenharmony_ci /* Only mark the extension as OK when we're sure it is */ 332a8e1175bSopenharmony_ci ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK; 333a8e1175bSopenharmony_ci 334a8e1175bSopenharmony_ci return 0; 335a8e1175bSopenharmony_ci} 336a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 337a8e1175bSopenharmony_ci 338a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) 339a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 340a8e1175bSopenharmony_cistatic int ssl_parse_max_fragment_length_ext(mbedtls_ssl_context *ssl, 341a8e1175bSopenharmony_ci const unsigned char *buf, 342a8e1175bSopenharmony_ci size_t len) 343a8e1175bSopenharmony_ci{ 344a8e1175bSopenharmony_ci if (len != 1 || buf[0] >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID) { 345a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 346a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 347a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 348a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 349a8e1175bSopenharmony_ci } 350a8e1175bSopenharmony_ci 351a8e1175bSopenharmony_ci ssl->session_negotiate->mfl_code = buf[0]; 352a8e1175bSopenharmony_ci 353a8e1175bSopenharmony_ci return 0; 354a8e1175bSopenharmony_ci} 355a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ 356a8e1175bSopenharmony_ci 357a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 358a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 359a8e1175bSopenharmony_cistatic int ssl_parse_cid_ext(mbedtls_ssl_context *ssl, 360a8e1175bSopenharmony_ci const unsigned char *buf, 361a8e1175bSopenharmony_ci size_t len) 362a8e1175bSopenharmony_ci{ 363a8e1175bSopenharmony_ci size_t peer_cid_len; 364a8e1175bSopenharmony_ci 365a8e1175bSopenharmony_ci /* CID extension only makes sense in DTLS */ 366a8e1175bSopenharmony_ci if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 367a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 368a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 369a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 370a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 371a8e1175bSopenharmony_ci } 372a8e1175bSopenharmony_ci 373a8e1175bSopenharmony_ci /* 374a8e1175bSopenharmony_ci * struct { 375a8e1175bSopenharmony_ci * opaque cid<0..2^8-1>; 376a8e1175bSopenharmony_ci * } ConnectionId; 377a8e1175bSopenharmony_ci */ 378a8e1175bSopenharmony_ci 379a8e1175bSopenharmony_ci if (len < 1) { 380a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 381a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 382a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 383a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 384a8e1175bSopenharmony_ci } 385a8e1175bSopenharmony_ci 386a8e1175bSopenharmony_ci peer_cid_len = *buf++; 387a8e1175bSopenharmony_ci len--; 388a8e1175bSopenharmony_ci 389a8e1175bSopenharmony_ci if (len != peer_cid_len) { 390a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 391a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 392a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 393a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 394a8e1175bSopenharmony_ci } 395a8e1175bSopenharmony_ci 396a8e1175bSopenharmony_ci /* Ignore CID if the user has disabled its use. */ 397a8e1175bSopenharmony_ci if (ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED) { 398a8e1175bSopenharmony_ci /* Leave ssl->handshake->cid_in_use in its default 399a8e1175bSopenharmony_ci * value of MBEDTLS_SSL_CID_DISABLED. */ 400a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("Client sent CID extension, but CID disabled")); 401a8e1175bSopenharmony_ci return 0; 402a8e1175bSopenharmony_ci } 403a8e1175bSopenharmony_ci 404a8e1175bSopenharmony_ci if (peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX) { 405a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 406a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 407a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 408a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 409a8e1175bSopenharmony_ci } 410a8e1175bSopenharmony_ci 411a8e1175bSopenharmony_ci ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED; 412a8e1175bSopenharmony_ci ssl->handshake->peer_cid_len = (uint8_t) peer_cid_len; 413a8e1175bSopenharmony_ci memcpy(ssl->handshake->peer_cid, buf, peer_cid_len); 414a8e1175bSopenharmony_ci 415a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("Use of CID extension negotiated")); 416a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "Client CID", buf, peer_cid_len); 417a8e1175bSopenharmony_ci 418a8e1175bSopenharmony_ci return 0; 419a8e1175bSopenharmony_ci} 420a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 421a8e1175bSopenharmony_ci 422a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 423a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 424a8e1175bSopenharmony_cistatic int ssl_parse_encrypt_then_mac_ext(mbedtls_ssl_context *ssl, 425a8e1175bSopenharmony_ci const unsigned char *buf, 426a8e1175bSopenharmony_ci size_t len) 427a8e1175bSopenharmony_ci{ 428a8e1175bSopenharmony_ci if (len != 0) { 429a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 430a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 431a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 432a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 433a8e1175bSopenharmony_ci } 434a8e1175bSopenharmony_ci 435a8e1175bSopenharmony_ci ((void) buf); 436a8e1175bSopenharmony_ci 437a8e1175bSopenharmony_ci if (ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED) { 438a8e1175bSopenharmony_ci ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; 439a8e1175bSopenharmony_ci } 440a8e1175bSopenharmony_ci 441a8e1175bSopenharmony_ci return 0; 442a8e1175bSopenharmony_ci} 443a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ 444a8e1175bSopenharmony_ci 445a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) 446a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 447a8e1175bSopenharmony_cistatic int ssl_parse_extended_ms_ext(mbedtls_ssl_context *ssl, 448a8e1175bSopenharmony_ci const unsigned char *buf, 449a8e1175bSopenharmony_ci size_t len) 450a8e1175bSopenharmony_ci{ 451a8e1175bSopenharmony_ci if (len != 0) { 452a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 453a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 454a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 455a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 456a8e1175bSopenharmony_ci } 457a8e1175bSopenharmony_ci 458a8e1175bSopenharmony_ci ((void) buf); 459a8e1175bSopenharmony_ci 460a8e1175bSopenharmony_ci if (ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED) { 461a8e1175bSopenharmony_ci ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; 462a8e1175bSopenharmony_ci } 463a8e1175bSopenharmony_ci 464a8e1175bSopenharmony_ci return 0; 465a8e1175bSopenharmony_ci} 466a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ 467a8e1175bSopenharmony_ci 468a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) 469a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 470a8e1175bSopenharmony_cistatic int ssl_parse_session_ticket_ext(mbedtls_ssl_context *ssl, 471a8e1175bSopenharmony_ci unsigned char *buf, 472a8e1175bSopenharmony_ci size_t len) 473a8e1175bSopenharmony_ci{ 474a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 475a8e1175bSopenharmony_ci mbedtls_ssl_session session; 476a8e1175bSopenharmony_ci 477a8e1175bSopenharmony_ci mbedtls_ssl_session_init(&session); 478a8e1175bSopenharmony_ci 479a8e1175bSopenharmony_ci if (ssl->conf->f_ticket_parse == NULL || 480a8e1175bSopenharmony_ci ssl->conf->f_ticket_write == NULL) { 481a8e1175bSopenharmony_ci return 0; 482a8e1175bSopenharmony_ci } 483a8e1175bSopenharmony_ci 484a8e1175bSopenharmony_ci /* Remember the client asked us to send a new ticket */ 485a8e1175bSopenharmony_ci ssl->handshake->new_session_ticket = 1; 486a8e1175bSopenharmony_ci 487a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("ticket length: %" MBEDTLS_PRINTF_SIZET, len)); 488a8e1175bSopenharmony_ci 489a8e1175bSopenharmony_ci if (len == 0) { 490a8e1175bSopenharmony_ci return 0; 491a8e1175bSopenharmony_ci } 492a8e1175bSopenharmony_ci 493a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 494a8e1175bSopenharmony_ci if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) { 495a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("ticket rejected: renegotiating")); 496a8e1175bSopenharmony_ci return 0; 497a8e1175bSopenharmony_ci } 498a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_RENEGOTIATION */ 499a8e1175bSopenharmony_ci 500a8e1175bSopenharmony_ci /* 501a8e1175bSopenharmony_ci * Failures are ok: just ignore the ticket and proceed. 502a8e1175bSopenharmony_ci */ 503a8e1175bSopenharmony_ci if ((ret = ssl->conf->f_ticket_parse(ssl->conf->p_ticket, &session, 504a8e1175bSopenharmony_ci buf, len)) != 0) { 505a8e1175bSopenharmony_ci mbedtls_ssl_session_free(&session); 506a8e1175bSopenharmony_ci 507a8e1175bSopenharmony_ci if (ret == MBEDTLS_ERR_SSL_INVALID_MAC) { 508a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is not authentic")); 509a8e1175bSopenharmony_ci } else if (ret == MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) { 510a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("ticket is expired")); 511a8e1175bSopenharmony_ci } else { 512a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_ticket_parse", ret); 513a8e1175bSopenharmony_ci } 514a8e1175bSopenharmony_ci 515a8e1175bSopenharmony_ci return 0; 516a8e1175bSopenharmony_ci } 517a8e1175bSopenharmony_ci 518a8e1175bSopenharmony_ci /* 519a8e1175bSopenharmony_ci * Keep the session ID sent by the client, since we MUST send it back to 520a8e1175bSopenharmony_ci * inform them we're accepting the ticket (RFC 5077 section 3.4) 521a8e1175bSopenharmony_ci */ 522a8e1175bSopenharmony_ci session.id_len = ssl->session_negotiate->id_len; 523a8e1175bSopenharmony_ci memcpy(&session.id, ssl->session_negotiate->id, session.id_len); 524a8e1175bSopenharmony_ci 525a8e1175bSopenharmony_ci mbedtls_ssl_session_free(ssl->session_negotiate); 526a8e1175bSopenharmony_ci memcpy(ssl->session_negotiate, &session, sizeof(mbedtls_ssl_session)); 527a8e1175bSopenharmony_ci 528a8e1175bSopenharmony_ci /* Zeroize instead of free as we copied the content */ 529a8e1175bSopenharmony_ci mbedtls_platform_zeroize(&session, sizeof(mbedtls_ssl_session)); 530a8e1175bSopenharmony_ci 531a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("session successfully restored from ticket")); 532a8e1175bSopenharmony_ci 533a8e1175bSopenharmony_ci ssl->handshake->resume = 1; 534a8e1175bSopenharmony_ci 535a8e1175bSopenharmony_ci /* Don't send a new ticket after all, this one is OK */ 536a8e1175bSopenharmony_ci ssl->handshake->new_session_ticket = 0; 537a8e1175bSopenharmony_ci 538a8e1175bSopenharmony_ci return 0; 539a8e1175bSopenharmony_ci} 540a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS */ 541a8e1175bSopenharmony_ci 542a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_SRTP) 543a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 544a8e1175bSopenharmony_cistatic int ssl_parse_use_srtp_ext(mbedtls_ssl_context *ssl, 545a8e1175bSopenharmony_ci const unsigned char *buf, 546a8e1175bSopenharmony_ci size_t len) 547a8e1175bSopenharmony_ci{ 548a8e1175bSopenharmony_ci mbedtls_ssl_srtp_profile client_protection = MBEDTLS_TLS_SRTP_UNSET; 549a8e1175bSopenharmony_ci size_t i, j; 550a8e1175bSopenharmony_ci size_t profile_length; 551a8e1175bSopenharmony_ci uint16_t mki_length; 552a8e1175bSopenharmony_ci /*! 2 bytes for profile length and 1 byte for mki len */ 553a8e1175bSopenharmony_ci const size_t size_of_lengths = 3; 554a8e1175bSopenharmony_ci 555a8e1175bSopenharmony_ci /* If use_srtp is not configured, just ignore the extension */ 556a8e1175bSopenharmony_ci if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) || 557a8e1175bSopenharmony_ci (ssl->conf->dtls_srtp_profile_list == NULL) || 558a8e1175bSopenharmony_ci (ssl->conf->dtls_srtp_profile_list_len == 0)) { 559a8e1175bSopenharmony_ci return 0; 560a8e1175bSopenharmony_ci } 561a8e1175bSopenharmony_ci 562a8e1175bSopenharmony_ci /* RFC5764 section 4.1.1 563a8e1175bSopenharmony_ci * uint8 SRTPProtectionProfile[2]; 564a8e1175bSopenharmony_ci * 565a8e1175bSopenharmony_ci * struct { 566a8e1175bSopenharmony_ci * SRTPProtectionProfiles SRTPProtectionProfiles; 567a8e1175bSopenharmony_ci * opaque srtp_mki<0..255>; 568a8e1175bSopenharmony_ci * } UseSRTPData; 569a8e1175bSopenharmony_ci 570a8e1175bSopenharmony_ci * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>; 571a8e1175bSopenharmony_ci */ 572a8e1175bSopenharmony_ci 573a8e1175bSopenharmony_ci /* 574a8e1175bSopenharmony_ci * Min length is 5: at least one protection profile(2 bytes) 575a8e1175bSopenharmony_ci * and length(2 bytes) + srtp_mki length(1 byte) 576a8e1175bSopenharmony_ci * Check here that we have at least 2 bytes of protection profiles length 577a8e1175bSopenharmony_ci * and one of srtp_mki length 578a8e1175bSopenharmony_ci */ 579a8e1175bSopenharmony_ci if (len < size_of_lengths) { 580a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 581a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 582a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 583a8e1175bSopenharmony_ci } 584a8e1175bSopenharmony_ci 585a8e1175bSopenharmony_ci ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET; 586a8e1175bSopenharmony_ci 587a8e1175bSopenharmony_ci /* first 2 bytes are protection profile length(in bytes) */ 588a8e1175bSopenharmony_ci profile_length = (buf[0] << 8) | buf[1]; 589a8e1175bSopenharmony_ci buf += 2; 590a8e1175bSopenharmony_ci 591a8e1175bSopenharmony_ci /* The profile length cannot be bigger than input buffer size - lengths fields */ 592a8e1175bSopenharmony_ci if (profile_length > len - size_of_lengths || 593a8e1175bSopenharmony_ci profile_length % 2 != 0) { /* profiles are 2 bytes long, so the length must be even */ 594a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 595a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 596a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 597a8e1175bSopenharmony_ci } 598a8e1175bSopenharmony_ci /* 599a8e1175bSopenharmony_ci * parse the extension list values are defined in 600a8e1175bSopenharmony_ci * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml 601a8e1175bSopenharmony_ci */ 602a8e1175bSopenharmony_ci for (j = 0; j < profile_length; j += 2) { 603a8e1175bSopenharmony_ci uint16_t protection_profile_value = buf[j] << 8 | buf[j + 1]; 604a8e1175bSopenharmony_ci client_protection = mbedtls_ssl_check_srtp_profile_value(protection_profile_value); 605a8e1175bSopenharmony_ci 606a8e1175bSopenharmony_ci if (client_protection != MBEDTLS_TLS_SRTP_UNSET) { 607a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found srtp profile: %s", 608a8e1175bSopenharmony_ci mbedtls_ssl_get_srtp_profile_as_string( 609a8e1175bSopenharmony_ci client_protection))); 610a8e1175bSopenharmony_ci } else { 611a8e1175bSopenharmony_ci continue; 612a8e1175bSopenharmony_ci } 613a8e1175bSopenharmony_ci /* check if suggested profile is in our list */ 614a8e1175bSopenharmony_ci for (i = 0; i < ssl->conf->dtls_srtp_profile_list_len; i++) { 615a8e1175bSopenharmony_ci if (client_protection == ssl->conf->dtls_srtp_profile_list[i]) { 616a8e1175bSopenharmony_ci ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i]; 617a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("selected srtp profile: %s", 618a8e1175bSopenharmony_ci mbedtls_ssl_get_srtp_profile_as_string( 619a8e1175bSopenharmony_ci client_protection))); 620a8e1175bSopenharmony_ci break; 621a8e1175bSopenharmony_ci } 622a8e1175bSopenharmony_ci } 623a8e1175bSopenharmony_ci if (ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_TLS_SRTP_UNSET) { 624a8e1175bSopenharmony_ci break; 625a8e1175bSopenharmony_ci } 626a8e1175bSopenharmony_ci } 627a8e1175bSopenharmony_ci buf += profile_length; /* buf points to the mki length */ 628a8e1175bSopenharmony_ci mki_length = *buf; 629a8e1175bSopenharmony_ci buf++; 630a8e1175bSopenharmony_ci 631a8e1175bSopenharmony_ci if (mki_length > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH || 632a8e1175bSopenharmony_ci mki_length + profile_length + size_of_lengths != len) { 633a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 634a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 635a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 636a8e1175bSopenharmony_ci } 637a8e1175bSopenharmony_ci 638a8e1175bSopenharmony_ci /* Parse the mki only if present and mki is supported locally */ 639a8e1175bSopenharmony_ci if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED && 640a8e1175bSopenharmony_ci mki_length > 0) { 641a8e1175bSopenharmony_ci ssl->dtls_srtp_info.mki_len = mki_length; 642a8e1175bSopenharmony_ci 643a8e1175bSopenharmony_ci memcpy(ssl->dtls_srtp_info.mki_value, buf, mki_length); 644a8e1175bSopenharmony_ci 645a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "using mki", ssl->dtls_srtp_info.mki_value, 646a8e1175bSopenharmony_ci ssl->dtls_srtp_info.mki_len); 647a8e1175bSopenharmony_ci } 648a8e1175bSopenharmony_ci 649a8e1175bSopenharmony_ci return 0; 650a8e1175bSopenharmony_ci} 651a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_SRTP */ 652a8e1175bSopenharmony_ci 653a8e1175bSopenharmony_ci/* 654a8e1175bSopenharmony_ci * Auxiliary functions for ServerHello parsing and related actions 655a8e1175bSopenharmony_ci */ 656a8e1175bSopenharmony_ci 657a8e1175bSopenharmony_ci#if defined(MBEDTLS_X509_CRT_PARSE_C) 658a8e1175bSopenharmony_ci/* 659a8e1175bSopenharmony_ci * Return 0 if the given key uses one of the acceptable curves, -1 otherwise 660a8e1175bSopenharmony_ci */ 661a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) 662a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 663a8e1175bSopenharmony_cistatic int ssl_check_key_curve(mbedtls_pk_context *pk, 664a8e1175bSopenharmony_ci uint16_t *curves_tls_id) 665a8e1175bSopenharmony_ci{ 666a8e1175bSopenharmony_ci uint16_t *curr_tls_id = curves_tls_id; 667a8e1175bSopenharmony_ci mbedtls_ecp_group_id grp_id = mbedtls_pk_get_ec_group_id(pk); 668a8e1175bSopenharmony_ci mbedtls_ecp_group_id curr_grp_id; 669a8e1175bSopenharmony_ci 670a8e1175bSopenharmony_ci while (*curr_tls_id != 0) { 671a8e1175bSopenharmony_ci curr_grp_id = mbedtls_ssl_get_ecp_group_id_from_tls_id(*curr_tls_id); 672a8e1175bSopenharmony_ci if (curr_grp_id == grp_id) { 673a8e1175bSopenharmony_ci return 0; 674a8e1175bSopenharmony_ci } 675a8e1175bSopenharmony_ci curr_tls_id++; 676a8e1175bSopenharmony_ci } 677a8e1175bSopenharmony_ci 678a8e1175bSopenharmony_ci return -1; 679a8e1175bSopenharmony_ci} 680a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED */ 681a8e1175bSopenharmony_ci 682a8e1175bSopenharmony_ci/* 683a8e1175bSopenharmony_ci * Try picking a certificate for this ciphersuite, 684a8e1175bSopenharmony_ci * return 0 on success and -1 on failure. 685a8e1175bSopenharmony_ci */ 686a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 687a8e1175bSopenharmony_cistatic int ssl_pick_cert(mbedtls_ssl_context *ssl, 688a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info) 689a8e1175bSopenharmony_ci{ 690a8e1175bSopenharmony_ci mbedtls_ssl_key_cert *cur, *list; 691a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 692a8e1175bSopenharmony_ci psa_algorithm_t pk_alg = 693a8e1175bSopenharmony_ci mbedtls_ssl_get_ciphersuite_sig_pk_psa_alg(ciphersuite_info); 694a8e1175bSopenharmony_ci psa_key_usage_t pk_usage = 695a8e1175bSopenharmony_ci mbedtls_ssl_get_ciphersuite_sig_pk_psa_usage(ciphersuite_info); 696a8e1175bSopenharmony_ci#else 697a8e1175bSopenharmony_ci mbedtls_pk_type_t pk_alg = 698a8e1175bSopenharmony_ci mbedtls_ssl_get_ciphersuite_sig_pk_alg(ciphersuite_info); 699a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 700a8e1175bSopenharmony_ci uint32_t flags; 701a8e1175bSopenharmony_ci 702a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) 703a8e1175bSopenharmony_ci if (ssl->handshake->sni_key_cert != NULL) { 704a8e1175bSopenharmony_ci list = ssl->handshake->sni_key_cert; 705a8e1175bSopenharmony_ci } else 706a8e1175bSopenharmony_ci#endif 707a8e1175bSopenharmony_ci list = ssl->conf->key_cert; 708a8e1175bSopenharmony_ci 709a8e1175bSopenharmony_ci int pk_alg_is_none = 0; 710a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 711a8e1175bSopenharmony_ci pk_alg_is_none = (pk_alg == PSA_ALG_NONE); 712a8e1175bSopenharmony_ci#else 713a8e1175bSopenharmony_ci pk_alg_is_none = (pk_alg == MBEDTLS_PK_NONE); 714a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 715a8e1175bSopenharmony_ci if (pk_alg_is_none) { 716a8e1175bSopenharmony_ci return 0; 717a8e1175bSopenharmony_ci } 718a8e1175bSopenharmony_ci 719a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite requires certificate")); 720a8e1175bSopenharmony_ci 721a8e1175bSopenharmony_ci if (list == NULL) { 722a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server has no certificate")); 723a8e1175bSopenharmony_ci return -1; 724a8e1175bSopenharmony_ci } 725a8e1175bSopenharmony_ci 726a8e1175bSopenharmony_ci for (cur = list; cur != NULL; cur = cur->next) { 727a8e1175bSopenharmony_ci flags = 0; 728a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_CRT(3, "candidate certificate chain, certificate", 729a8e1175bSopenharmony_ci cur->cert); 730a8e1175bSopenharmony_ci 731a8e1175bSopenharmony_ci int key_type_matches = 0; 732a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 733a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) 734a8e1175bSopenharmony_ci key_type_matches = ((ssl->conf->f_async_sign_start != NULL || 735a8e1175bSopenharmony_ci ssl->conf->f_async_decrypt_start != NULL || 736a8e1175bSopenharmony_ci mbedtls_pk_can_do_ext(cur->key, pk_alg, pk_usage)) && 737a8e1175bSopenharmony_ci mbedtls_pk_can_do_ext(&cur->cert->pk, pk_alg, pk_usage)); 738a8e1175bSopenharmony_ci#else 739a8e1175bSopenharmony_ci key_type_matches = ( 740a8e1175bSopenharmony_ci mbedtls_pk_can_do_ext(cur->key, pk_alg, pk_usage)); 741a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ 742a8e1175bSopenharmony_ci#else 743a8e1175bSopenharmony_ci key_type_matches = mbedtls_pk_can_do(&cur->cert->pk, pk_alg); 744a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 745a8e1175bSopenharmony_ci if (!key_type_matches) { 746a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: key type")); 747a8e1175bSopenharmony_ci continue; 748a8e1175bSopenharmony_ci } 749a8e1175bSopenharmony_ci 750a8e1175bSopenharmony_ci /* 751a8e1175bSopenharmony_ci * This avoids sending the client a cert it'll reject based on 752a8e1175bSopenharmony_ci * keyUsage or other extensions. 753a8e1175bSopenharmony_ci * 754a8e1175bSopenharmony_ci * It also allows the user to provision different certificates for 755a8e1175bSopenharmony_ci * different uses based on keyUsage, eg if they want to avoid signing 756a8e1175bSopenharmony_ci * and decrypting with the same RSA key. 757a8e1175bSopenharmony_ci */ 758a8e1175bSopenharmony_ci if (mbedtls_ssl_check_cert_usage(cur->cert, ciphersuite_info, 759a8e1175bSopenharmony_ci MBEDTLS_SSL_IS_SERVER, &flags) != 0) { 760a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: " 761a8e1175bSopenharmony_ci "(extended) key usage extension")); 762a8e1175bSopenharmony_ci continue; 763a8e1175bSopenharmony_ci } 764a8e1175bSopenharmony_ci 765a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) 766a8e1175bSopenharmony_ci if (pk_alg == MBEDTLS_PK_ECDSA && 767a8e1175bSopenharmony_ci ssl_check_key_curve(&cur->cert->pk, 768a8e1175bSopenharmony_ci ssl->handshake->curves_tls_id) != 0) { 769a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("certificate mismatch: elliptic curve")); 770a8e1175bSopenharmony_ci continue; 771a8e1175bSopenharmony_ci } 772a8e1175bSopenharmony_ci#endif 773a8e1175bSopenharmony_ci 774a8e1175bSopenharmony_ci /* If we get there, we got a winner */ 775a8e1175bSopenharmony_ci break; 776a8e1175bSopenharmony_ci } 777a8e1175bSopenharmony_ci 778a8e1175bSopenharmony_ci /* Do not update ssl->handshake->key_cert unless there is a match */ 779a8e1175bSopenharmony_ci if (cur != NULL) { 780a8e1175bSopenharmony_ci ssl->handshake->key_cert = cur; 781a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_CRT(3, "selected certificate chain, certificate", 782a8e1175bSopenharmony_ci ssl->handshake->key_cert->cert); 783a8e1175bSopenharmony_ci return 0; 784a8e1175bSopenharmony_ci } 785a8e1175bSopenharmony_ci 786a8e1175bSopenharmony_ci return -1; 787a8e1175bSopenharmony_ci} 788a8e1175bSopenharmony_ci#endif /* MBEDTLS_X509_CRT_PARSE_C */ 789a8e1175bSopenharmony_ci 790a8e1175bSopenharmony_ci/* 791a8e1175bSopenharmony_ci * Check if a given ciphersuite is suitable for use with our config/keys/etc 792a8e1175bSopenharmony_ci * Sets ciphersuite_info only if the suite matches. 793a8e1175bSopenharmony_ci */ 794a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 795a8e1175bSopenharmony_cistatic int ssl_ciphersuite_match(mbedtls_ssl_context *ssl, int suite_id, 796a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t **ciphersuite_info) 797a8e1175bSopenharmony_ci{ 798a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *suite_info; 799a8e1175bSopenharmony_ci 800a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) 801a8e1175bSopenharmony_ci mbedtls_pk_type_t sig_type; 802a8e1175bSopenharmony_ci#endif 803a8e1175bSopenharmony_ci 804a8e1175bSopenharmony_ci suite_info = mbedtls_ssl_ciphersuite_from_id(suite_id); 805a8e1175bSopenharmony_ci if (suite_info == NULL) { 806a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 807a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 808a8e1175bSopenharmony_ci } 809a8e1175bSopenharmony_ci 810a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("trying ciphersuite: %#04x (%s)", 811a8e1175bSopenharmony_ci (unsigned int) suite_id, suite_info->name)); 812a8e1175bSopenharmony_ci 813a8e1175bSopenharmony_ci if (suite_info->min_tls_version > ssl->tls_version || 814a8e1175bSopenharmony_ci suite_info->max_tls_version < ssl->tls_version) { 815a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: version")); 816a8e1175bSopenharmony_ci return 0; 817a8e1175bSopenharmony_ci } 818a8e1175bSopenharmony_ci 819a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 820a8e1175bSopenharmony_ci if (suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE && 821a8e1175bSopenharmony_ci (ssl->handshake->cli_exts & MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK) == 0) { 822a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: ecjpake " 823a8e1175bSopenharmony_ci "not configured or ext missing")); 824a8e1175bSopenharmony_ci return 0; 825a8e1175bSopenharmony_ci } 826a8e1175bSopenharmony_ci#endif 827a8e1175bSopenharmony_ci 828a8e1175bSopenharmony_ci 829a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ 830a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) 831a8e1175bSopenharmony_ci if (mbedtls_ssl_ciphersuite_uses_ec(suite_info) && 832a8e1175bSopenharmony_ci (ssl->handshake->curves_tls_id == NULL || 833a8e1175bSopenharmony_ci ssl->handshake->curves_tls_id[0] == 0)) { 834a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: " 835a8e1175bSopenharmony_ci "no common elliptic curve")); 836a8e1175bSopenharmony_ci return 0; 837a8e1175bSopenharmony_ci } 838a8e1175bSopenharmony_ci#endif 839a8e1175bSopenharmony_ci 840a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) 841a8e1175bSopenharmony_ci /* If the ciphersuite requires a pre-shared key and we don't 842a8e1175bSopenharmony_ci * have one, skip it now rather than failing later */ 843a8e1175bSopenharmony_ci if (mbedtls_ssl_ciphersuite_uses_psk(suite_info) && 844a8e1175bSopenharmony_ci ssl_conf_has_psk_or_cb(ssl->conf) == 0) { 845a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: no pre-shared key")); 846a8e1175bSopenharmony_ci return 0; 847a8e1175bSopenharmony_ci } 848a8e1175bSopenharmony_ci#endif 849a8e1175bSopenharmony_ci 850a8e1175bSopenharmony_ci#if defined(MBEDTLS_X509_CRT_PARSE_C) 851a8e1175bSopenharmony_ci /* 852a8e1175bSopenharmony_ci * Final check: if ciphersuite requires us to have a 853a8e1175bSopenharmony_ci * certificate/key of a particular type: 854a8e1175bSopenharmony_ci * - select the appropriate certificate if we have one, or 855a8e1175bSopenharmony_ci * - try the next ciphersuite if we don't 856a8e1175bSopenharmony_ci * This must be done last since we modify the key_cert list. 857a8e1175bSopenharmony_ci */ 858a8e1175bSopenharmony_ci if (ssl_pick_cert(ssl, suite_info) != 0) { 859a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: " 860a8e1175bSopenharmony_ci "no suitable certificate")); 861a8e1175bSopenharmony_ci return 0; 862a8e1175bSopenharmony_ci } 863a8e1175bSopenharmony_ci#endif 864a8e1175bSopenharmony_ci 865a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) 866a8e1175bSopenharmony_ci /* If the ciphersuite requires signing, check whether 867a8e1175bSopenharmony_ci * a suitable hash algorithm is present. */ 868a8e1175bSopenharmony_ci sig_type = mbedtls_ssl_get_ciphersuite_sig_alg(suite_info); 869a8e1175bSopenharmony_ci if (sig_type != MBEDTLS_PK_NONE && 870a8e1175bSopenharmony_ci mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg( 871a8e1175bSopenharmony_ci ssl, mbedtls_ssl_sig_from_pk_alg(sig_type)) == MBEDTLS_SSL_HASH_NONE) { 872a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("ciphersuite mismatch: no suitable hash algorithm " 873a8e1175bSopenharmony_ci "for signature algorithm %u", (unsigned) sig_type)); 874a8e1175bSopenharmony_ci return 0; 875a8e1175bSopenharmony_ci } 876a8e1175bSopenharmony_ci 877a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ 878a8e1175bSopenharmony_ci 879a8e1175bSopenharmony_ci *ciphersuite_info = suite_info; 880a8e1175bSopenharmony_ci return 0; 881a8e1175bSopenharmony_ci} 882a8e1175bSopenharmony_ci 883a8e1175bSopenharmony_ci/* This function doesn't alert on errors that happen early during 884a8e1175bSopenharmony_ci ClientHello parsing because they might indicate that the client is 885a8e1175bSopenharmony_ci not talking SSL/TLS at all and would not understand our alert. */ 886a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 887a8e1175bSopenharmony_cistatic int ssl_parse_client_hello(mbedtls_ssl_context *ssl) 888a8e1175bSopenharmony_ci{ 889a8e1175bSopenharmony_ci int ret, got_common_suite; 890a8e1175bSopenharmony_ci size_t i, j; 891a8e1175bSopenharmony_ci size_t ciph_offset, comp_offset, ext_offset; 892a8e1175bSopenharmony_ci size_t msg_len, ciph_len, sess_len, comp_len, ext_len; 893a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS) 894a8e1175bSopenharmony_ci size_t cookie_offset, cookie_len; 895a8e1175bSopenharmony_ci#endif 896a8e1175bSopenharmony_ci unsigned char *buf, *p, *ext; 897a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 898a8e1175bSopenharmony_ci int renegotiation_info_seen = 0; 899a8e1175bSopenharmony_ci#endif 900a8e1175bSopenharmony_ci int handshake_failure = 0; 901a8e1175bSopenharmony_ci const int *ciphersuites; 902a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info; 903a8e1175bSopenharmony_ci 904a8e1175bSopenharmony_ci /* If there is no signature-algorithm extension present, 905a8e1175bSopenharmony_ci * we need to fall back to the default values for allowed 906a8e1175bSopenharmony_ci * signature-hash pairs. */ 907a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) 908a8e1175bSopenharmony_ci int sig_hash_alg_ext_present = 0; 909a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ 910a8e1175bSopenharmony_ci 911a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse client hello")); 912a8e1175bSopenharmony_ci 913a8e1175bSopenharmony_ci int renegotiating; 914a8e1175bSopenharmony_ci 915a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) 916a8e1175bSopenharmony_ciread_record_header: 917a8e1175bSopenharmony_ci#endif 918a8e1175bSopenharmony_ci /* 919a8e1175bSopenharmony_ci * If renegotiating, then the input was read with mbedtls_ssl_read_record(), 920a8e1175bSopenharmony_ci * otherwise read it ourselves manually in order to support SSLv2 921a8e1175bSopenharmony_ci * ClientHello, which doesn't use the same record layer format. 922a8e1175bSopenharmony_ci * Otherwise in a scenario of TLS 1.3/TLS 1.2 version negotiation, the 923a8e1175bSopenharmony_ci * ClientHello has been already fully fetched by the TLS 1.3 code and the 924a8e1175bSopenharmony_ci * flag ssl->keep_current_message is raised. 925a8e1175bSopenharmony_ci */ 926a8e1175bSopenharmony_ci renegotiating = 0; 927a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 928a8e1175bSopenharmony_ci renegotiating = (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE); 929a8e1175bSopenharmony_ci#endif 930a8e1175bSopenharmony_ci if (!renegotiating && !ssl->keep_current_message) { 931a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_fetch_input(ssl, 5)) != 0) { 932a8e1175bSopenharmony_ci /* No alert on a read error. */ 933a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret); 934a8e1175bSopenharmony_ci return ret; 935a8e1175bSopenharmony_ci } 936a8e1175bSopenharmony_ci } 937a8e1175bSopenharmony_ci 938a8e1175bSopenharmony_ci buf = ssl->in_hdr; 939a8e1175bSopenharmony_ci 940a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "record header", buf, mbedtls_ssl_in_hdr_len(ssl)); 941a8e1175bSopenharmony_ci 942a8e1175bSopenharmony_ci /* 943a8e1175bSopenharmony_ci * TLS Client Hello 944a8e1175bSopenharmony_ci * 945a8e1175bSopenharmony_ci * Record layer: 946a8e1175bSopenharmony_ci * 0 . 0 message type 947a8e1175bSopenharmony_ci * 1 . 2 protocol version 948a8e1175bSopenharmony_ci * 3 . 11 DTLS: epoch + record sequence number 949a8e1175bSopenharmony_ci * 3 . 4 message length 950a8e1175bSopenharmony_ci */ 951a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, message type: %d", 952a8e1175bSopenharmony_ci buf[0])); 953a8e1175bSopenharmony_ci 954a8e1175bSopenharmony_ci if (buf[0] != MBEDTLS_SSL_MSG_HANDSHAKE) { 955a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 956a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 957a8e1175bSopenharmony_ci } 958a8e1175bSopenharmony_ci 959a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, message len.: %d", 960a8e1175bSopenharmony_ci MBEDTLS_GET_UINT16_BE(ssl->in_len, 0))); 961a8e1175bSopenharmony_ci 962a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, protocol version: [%d:%d]", 963a8e1175bSopenharmony_ci buf[1], buf[2])); 964a8e1175bSopenharmony_ci 965a8e1175bSopenharmony_ci /* For DTLS if this is the initial handshake, remember the client sequence 966a8e1175bSopenharmony_ci * number to use it in our next message (RFC 6347 4.2.1) */ 967a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS) 968a8e1175bSopenharmony_ci if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM 969a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 970a8e1175bSopenharmony_ci && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE 971a8e1175bSopenharmony_ci#endif 972a8e1175bSopenharmony_ci ) { 973a8e1175bSopenharmony_ci /* Epoch should be 0 for initial handshakes */ 974a8e1175bSopenharmony_ci if (ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0) { 975a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 976a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 977a8e1175bSopenharmony_ci } 978a8e1175bSopenharmony_ci 979a8e1175bSopenharmony_ci memcpy(&ssl->cur_out_ctr[2], ssl->in_ctr + 2, 980a8e1175bSopenharmony_ci sizeof(ssl->cur_out_ctr) - 2); 981a8e1175bSopenharmony_ci 982a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) 983a8e1175bSopenharmony_ci if (mbedtls_ssl_dtls_replay_check(ssl) != 0) { 984a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("replayed record, discarding")); 985a8e1175bSopenharmony_ci ssl->next_record_offset = 0; 986a8e1175bSopenharmony_ci ssl->in_left = 0; 987a8e1175bSopenharmony_ci goto read_record_header; 988a8e1175bSopenharmony_ci } 989a8e1175bSopenharmony_ci 990a8e1175bSopenharmony_ci /* No MAC to check yet, so we can update right now */ 991a8e1175bSopenharmony_ci mbedtls_ssl_dtls_replay_update(ssl); 992a8e1175bSopenharmony_ci#endif 993a8e1175bSopenharmony_ci } 994a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */ 995a8e1175bSopenharmony_ci 996a8e1175bSopenharmony_ci msg_len = MBEDTLS_GET_UINT16_BE(ssl->in_len, 0); 997a8e1175bSopenharmony_ci 998a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 999a8e1175bSopenharmony_ci if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) { 1000a8e1175bSopenharmony_ci /* Set by mbedtls_ssl_read_record() */ 1001a8e1175bSopenharmony_ci msg_len = ssl->in_hslen; 1002a8e1175bSopenharmony_ci } else 1003a8e1175bSopenharmony_ci#endif 1004a8e1175bSopenharmony_ci { 1005a8e1175bSopenharmony_ci if (ssl->keep_current_message) { 1006a8e1175bSopenharmony_ci ssl->keep_current_message = 0; 1007a8e1175bSopenharmony_ci } else { 1008a8e1175bSopenharmony_ci if (msg_len > MBEDTLS_SSL_IN_CONTENT_LEN) { 1009a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 1010a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 1011a8e1175bSopenharmony_ci } 1012a8e1175bSopenharmony_ci 1013a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_fetch_input(ssl, 1014a8e1175bSopenharmony_ci mbedtls_ssl_in_hdr_len(ssl) + msg_len)) != 0) { 1015a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_fetch_input", ret); 1016a8e1175bSopenharmony_ci return ret; 1017a8e1175bSopenharmony_ci } 1018a8e1175bSopenharmony_ci 1019a8e1175bSopenharmony_ci /* Done reading this record, get ready for the next one */ 1020a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS) 1021a8e1175bSopenharmony_ci if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 1022a8e1175bSopenharmony_ci ssl->next_record_offset = msg_len + mbedtls_ssl_in_hdr_len(ssl); 1023a8e1175bSopenharmony_ci } else 1024a8e1175bSopenharmony_ci#endif 1025a8e1175bSopenharmony_ci ssl->in_left = 0; 1026a8e1175bSopenharmony_ci } 1027a8e1175bSopenharmony_ci } 1028a8e1175bSopenharmony_ci 1029a8e1175bSopenharmony_ci buf = ssl->in_msg; 1030a8e1175bSopenharmony_ci 1031a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(4, "record contents", buf, msg_len); 1032a8e1175bSopenharmony_ci 1033a8e1175bSopenharmony_ci ret = ssl->handshake->update_checksum(ssl, buf, msg_len); 1034a8e1175bSopenharmony_ci if (0 != ret) { 1035a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("update_checksum"), ret); 1036a8e1175bSopenharmony_ci return ret; 1037a8e1175bSopenharmony_ci } 1038a8e1175bSopenharmony_ci 1039a8e1175bSopenharmony_ci /* 1040a8e1175bSopenharmony_ci * Handshake layer: 1041a8e1175bSopenharmony_ci * 0 . 0 handshake type 1042a8e1175bSopenharmony_ci * 1 . 3 handshake length 1043a8e1175bSopenharmony_ci * 4 . 5 DTLS only: message sequence number 1044a8e1175bSopenharmony_ci * 6 . 8 DTLS only: fragment offset 1045a8e1175bSopenharmony_ci * 9 . 11 DTLS only: fragment length 1046a8e1175bSopenharmony_ci */ 1047a8e1175bSopenharmony_ci if (msg_len < mbedtls_ssl_hs_hdr_len(ssl)) { 1048a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 1049a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1050a8e1175bSopenharmony_ci } 1051a8e1175bSopenharmony_ci 1052a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("client hello v3, handshake type: %d", buf[0])); 1053a8e1175bSopenharmony_ci 1054a8e1175bSopenharmony_ci if (buf[0] != MBEDTLS_SSL_HS_CLIENT_HELLO) { 1055a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 1056a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 1057a8e1175bSopenharmony_ci } 1058a8e1175bSopenharmony_ci { 1059a8e1175bSopenharmony_ci size_t handshake_len = MBEDTLS_GET_UINT24_BE(buf, 1); 1060a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("client hello v3, handshake len.: %u", 1061a8e1175bSopenharmony_ci (unsigned) handshake_len)); 1062a8e1175bSopenharmony_ci 1063a8e1175bSopenharmony_ci /* The record layer has a record size limit of 2^14 - 1 and 1064a8e1175bSopenharmony_ci * fragmentation is not supported, so buf[1] should be zero. */ 1065a8e1175bSopenharmony_ci if (buf[1] != 0) { 1066a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message: %u != 0", 1067a8e1175bSopenharmony_ci (unsigned) buf[1])); 1068a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1069a8e1175bSopenharmony_ci } 1070a8e1175bSopenharmony_ci 1071a8e1175bSopenharmony_ci /* We don't support fragmentation of ClientHello (yet?) */ 1072a8e1175bSopenharmony_ci if (msg_len != mbedtls_ssl_hs_hdr_len(ssl) + handshake_len) { 1073a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message: %u != %u + %u", 1074a8e1175bSopenharmony_ci (unsigned) msg_len, 1075a8e1175bSopenharmony_ci (unsigned) mbedtls_ssl_hs_hdr_len(ssl), 1076a8e1175bSopenharmony_ci (unsigned) handshake_len)); 1077a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1078a8e1175bSopenharmony_ci } 1079a8e1175bSopenharmony_ci } 1080a8e1175bSopenharmony_ci 1081a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS) 1082a8e1175bSopenharmony_ci if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 1083a8e1175bSopenharmony_ci /* 1084a8e1175bSopenharmony_ci * Copy the client's handshake message_seq on initial handshakes, 1085a8e1175bSopenharmony_ci * check sequence number on renego. 1086a8e1175bSopenharmony_ci */ 1087a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 1088a8e1175bSopenharmony_ci if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) { 1089a8e1175bSopenharmony_ci /* This couldn't be done in ssl_prepare_handshake_record() */ 1090a8e1175bSopenharmony_ci unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4); 1091a8e1175bSopenharmony_ci if (cli_msg_seq != ssl->handshake->in_msg_seq) { 1092a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message_seq: " 1093a8e1175bSopenharmony_ci "%u (expected %u)", cli_msg_seq, 1094a8e1175bSopenharmony_ci ssl->handshake->in_msg_seq)); 1095a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1096a8e1175bSopenharmony_ci } 1097a8e1175bSopenharmony_ci 1098a8e1175bSopenharmony_ci ssl->handshake->in_msg_seq++; 1099a8e1175bSopenharmony_ci } else 1100a8e1175bSopenharmony_ci#endif 1101a8e1175bSopenharmony_ci { 1102a8e1175bSopenharmony_ci unsigned int cli_msg_seq = (unsigned int) MBEDTLS_GET_UINT16_BE(ssl->in_msg, 4); 1103a8e1175bSopenharmony_ci ssl->handshake->out_msg_seq = cli_msg_seq; 1104a8e1175bSopenharmony_ci ssl->handshake->in_msg_seq = cli_msg_seq + 1; 1105a8e1175bSopenharmony_ci } 1106a8e1175bSopenharmony_ci { 1107a8e1175bSopenharmony_ci /* 1108a8e1175bSopenharmony_ci * For now we don't support fragmentation, so make sure 1109a8e1175bSopenharmony_ci * fragment_offset == 0 and fragment_length == length 1110a8e1175bSopenharmony_ci */ 1111a8e1175bSopenharmony_ci size_t fragment_offset, fragment_length, length; 1112a8e1175bSopenharmony_ci fragment_offset = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 6); 1113a8e1175bSopenharmony_ci fragment_length = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 9); 1114a8e1175bSopenharmony_ci length = MBEDTLS_GET_UINT24_BE(ssl->in_msg, 1); 1115a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG( 1116a8e1175bSopenharmony_ci 4, ("fragment_offset=%u fragment_length=%u length=%u", 1117a8e1175bSopenharmony_ci (unsigned) fragment_offset, (unsigned) fragment_length, 1118a8e1175bSopenharmony_ci (unsigned) length)); 1119a8e1175bSopenharmony_ci if (fragment_offset != 0 || length != fragment_length) { 1120a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("ClientHello fragmentation not supported")); 1121a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 1122a8e1175bSopenharmony_ci } 1123a8e1175bSopenharmony_ci } 1124a8e1175bSopenharmony_ci } 1125a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */ 1126a8e1175bSopenharmony_ci 1127a8e1175bSopenharmony_ci buf += mbedtls_ssl_hs_hdr_len(ssl); 1128a8e1175bSopenharmony_ci msg_len -= mbedtls_ssl_hs_hdr_len(ssl); 1129a8e1175bSopenharmony_ci 1130a8e1175bSopenharmony_ci /* 1131a8e1175bSopenharmony_ci * ClientHello layout: 1132a8e1175bSopenharmony_ci * 0 . 1 protocol version 1133a8e1175bSopenharmony_ci * 2 . 33 random bytes (starting with 4 bytes of Unix time) 1134a8e1175bSopenharmony_ci * 34 . 34 session id length (1 byte) 1135a8e1175bSopenharmony_ci * 35 . 34+x session id, where x = session id length from byte 34 1136a8e1175bSopenharmony_ci * 35+x . 35+x DTLS only: cookie length (1 byte) 1137a8e1175bSopenharmony_ci * 36+x . .. DTLS only: cookie 1138a8e1175bSopenharmony_ci * .. . .. ciphersuite list length (2 bytes) 1139a8e1175bSopenharmony_ci * .. . .. ciphersuite list 1140a8e1175bSopenharmony_ci * .. . .. compression alg. list length (1 byte) 1141a8e1175bSopenharmony_ci * .. . .. compression alg. list 1142a8e1175bSopenharmony_ci * .. . .. extensions length (2 bytes, optional) 1143a8e1175bSopenharmony_ci * .. . .. extensions (optional) 1144a8e1175bSopenharmony_ci */ 1145a8e1175bSopenharmony_ci 1146a8e1175bSopenharmony_ci /* 1147a8e1175bSopenharmony_ci * Minimal length (with everything empty and extensions omitted) is 1148a8e1175bSopenharmony_ci * 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can 1149a8e1175bSopenharmony_ci * read at least up to session id length without worrying. 1150a8e1175bSopenharmony_ci */ 1151a8e1175bSopenharmony_ci if (msg_len < 38) { 1152a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 1153a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1154a8e1175bSopenharmony_ci } 1155a8e1175bSopenharmony_ci 1156a8e1175bSopenharmony_ci /* 1157a8e1175bSopenharmony_ci * Check and save the protocol version 1158a8e1175bSopenharmony_ci */ 1159a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "client hello, version", buf, 2); 1160a8e1175bSopenharmony_ci 1161a8e1175bSopenharmony_ci ssl->tls_version = (mbedtls_ssl_protocol_version) mbedtls_ssl_read_version(buf, 1162a8e1175bSopenharmony_ci ssl->conf->transport); 1163a8e1175bSopenharmony_ci ssl->session_negotiate->tls_version = ssl->tls_version; 1164a8e1175bSopenharmony_ci ssl->session_negotiate->endpoint = ssl->conf->endpoint; 1165a8e1175bSopenharmony_ci 1166a8e1175bSopenharmony_ci if (ssl->tls_version != MBEDTLS_SSL_VERSION_TLS1_2) { 1167a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("server only supports TLS 1.2")); 1168a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1169a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION); 1170a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION; 1171a8e1175bSopenharmony_ci } 1172a8e1175bSopenharmony_ci 1173a8e1175bSopenharmony_ci /* 1174a8e1175bSopenharmony_ci * Save client random (inc. Unix time) 1175a8e1175bSopenharmony_ci */ 1176a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "client hello, random bytes", buf + 2, 32); 1177a8e1175bSopenharmony_ci 1178a8e1175bSopenharmony_ci memcpy(ssl->handshake->randbytes, buf + 2, 32); 1179a8e1175bSopenharmony_ci 1180a8e1175bSopenharmony_ci /* 1181a8e1175bSopenharmony_ci * Check the session ID length and save session ID 1182a8e1175bSopenharmony_ci */ 1183a8e1175bSopenharmony_ci sess_len = buf[34]; 1184a8e1175bSopenharmony_ci 1185a8e1175bSopenharmony_ci if (sess_len > sizeof(ssl->session_negotiate->id) || 1186a8e1175bSopenharmony_ci sess_len + 34 + 2 > msg_len) { /* 2 for cipherlist length field */ 1187a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 1188a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1189a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 1190a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1191a8e1175bSopenharmony_ci } 1192a8e1175bSopenharmony_ci 1193a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "client hello, session id", buf + 35, sess_len); 1194a8e1175bSopenharmony_ci 1195a8e1175bSopenharmony_ci ssl->session_negotiate->id_len = sess_len; 1196a8e1175bSopenharmony_ci memset(ssl->session_negotiate->id, 0, 1197a8e1175bSopenharmony_ci sizeof(ssl->session_negotiate->id)); 1198a8e1175bSopenharmony_ci memcpy(ssl->session_negotiate->id, buf + 35, 1199a8e1175bSopenharmony_ci ssl->session_negotiate->id_len); 1200a8e1175bSopenharmony_ci 1201a8e1175bSopenharmony_ci /* 1202a8e1175bSopenharmony_ci * Check the cookie length and content 1203a8e1175bSopenharmony_ci */ 1204a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS) 1205a8e1175bSopenharmony_ci if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 1206a8e1175bSopenharmony_ci cookie_offset = 35 + sess_len; 1207a8e1175bSopenharmony_ci cookie_len = buf[cookie_offset]; 1208a8e1175bSopenharmony_ci 1209a8e1175bSopenharmony_ci if (cookie_offset + 1 + cookie_len + 2 > msg_len) { 1210a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 1211a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1212a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 1213a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1214a8e1175bSopenharmony_ci } 1215a8e1175bSopenharmony_ci 1216a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "client hello, cookie", 1217a8e1175bSopenharmony_ci buf + cookie_offset + 1, cookie_len); 1218a8e1175bSopenharmony_ci 1219a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) 1220a8e1175bSopenharmony_ci if (ssl->conf->f_cookie_check != NULL 1221a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 1222a8e1175bSopenharmony_ci && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE 1223a8e1175bSopenharmony_ci#endif 1224a8e1175bSopenharmony_ci ) { 1225a8e1175bSopenharmony_ci if (ssl->conf->f_cookie_check(ssl->conf->p_cookie, 1226a8e1175bSopenharmony_ci buf + cookie_offset + 1, cookie_len, 1227a8e1175bSopenharmony_ci ssl->cli_id, ssl->cli_id_len) != 0) { 1228a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("cookie verification failed")); 1229a8e1175bSopenharmony_ci ssl->handshake->cookie_verify_result = 1; 1230a8e1175bSopenharmony_ci } else { 1231a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("cookie verification passed")); 1232a8e1175bSopenharmony_ci ssl->handshake->cookie_verify_result = 0; 1233a8e1175bSopenharmony_ci } 1234a8e1175bSopenharmony_ci } else 1235a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ 1236a8e1175bSopenharmony_ci { 1237a8e1175bSopenharmony_ci /* We know we didn't send a cookie, so it should be empty */ 1238a8e1175bSopenharmony_ci if (cookie_len != 0) { 1239a8e1175bSopenharmony_ci /* This may be an attacker's probe, so don't send an alert */ 1240a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 1241a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1242a8e1175bSopenharmony_ci } 1243a8e1175bSopenharmony_ci 1244a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("cookie verification skipped")); 1245a8e1175bSopenharmony_ci } 1246a8e1175bSopenharmony_ci 1247a8e1175bSopenharmony_ci /* 1248a8e1175bSopenharmony_ci * Check the ciphersuitelist length (will be parsed later) 1249a8e1175bSopenharmony_ci */ 1250a8e1175bSopenharmony_ci ciph_offset = cookie_offset + 1 + cookie_len; 1251a8e1175bSopenharmony_ci } else 1252a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */ 1253a8e1175bSopenharmony_ci ciph_offset = 35 + sess_len; 1254a8e1175bSopenharmony_ci 1255a8e1175bSopenharmony_ci ciph_len = MBEDTLS_GET_UINT16_BE(buf, ciph_offset); 1256a8e1175bSopenharmony_ci 1257a8e1175bSopenharmony_ci if (ciph_len < 2 || 1258a8e1175bSopenharmony_ci ciph_len + 2 + ciph_offset + 1 > msg_len || /* 1 for comp. alg. len */ 1259a8e1175bSopenharmony_ci (ciph_len % 2) != 0) { 1260a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 1261a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1262a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 1263a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1264a8e1175bSopenharmony_ci } 1265a8e1175bSopenharmony_ci 1266a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "client hello, ciphersuitelist", 1267a8e1175bSopenharmony_ci buf + ciph_offset + 2, ciph_len); 1268a8e1175bSopenharmony_ci 1269a8e1175bSopenharmony_ci /* 1270a8e1175bSopenharmony_ci * Check the compression algorithm's length. 1271a8e1175bSopenharmony_ci * The list contents are ignored because implementing 1272a8e1175bSopenharmony_ci * MBEDTLS_SSL_COMPRESS_NULL is mandatory and is the only 1273a8e1175bSopenharmony_ci * option supported by Mbed TLS. 1274a8e1175bSopenharmony_ci */ 1275a8e1175bSopenharmony_ci comp_offset = ciph_offset + 2 + ciph_len; 1276a8e1175bSopenharmony_ci 1277a8e1175bSopenharmony_ci comp_len = buf[comp_offset]; 1278a8e1175bSopenharmony_ci 1279a8e1175bSopenharmony_ci if (comp_len < 1 || 1280a8e1175bSopenharmony_ci comp_len > 16 || 1281a8e1175bSopenharmony_ci comp_len + comp_offset + 1 > msg_len) { 1282a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 1283a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1284a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 1285a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1286a8e1175bSopenharmony_ci } 1287a8e1175bSopenharmony_ci 1288a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "client hello, compression", 1289a8e1175bSopenharmony_ci buf + comp_offset + 1, comp_len); 1290a8e1175bSopenharmony_ci 1291a8e1175bSopenharmony_ci /* 1292a8e1175bSopenharmony_ci * Check the extension length 1293a8e1175bSopenharmony_ci */ 1294a8e1175bSopenharmony_ci ext_offset = comp_offset + 1 + comp_len; 1295a8e1175bSopenharmony_ci if (msg_len > ext_offset) { 1296a8e1175bSopenharmony_ci if (msg_len < ext_offset + 2) { 1297a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 1298a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1299a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 1300a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1301a8e1175bSopenharmony_ci } 1302a8e1175bSopenharmony_ci 1303a8e1175bSopenharmony_ci ext_len = MBEDTLS_GET_UINT16_BE(buf, ext_offset); 1304a8e1175bSopenharmony_ci 1305a8e1175bSopenharmony_ci if (msg_len != ext_offset + 2 + ext_len) { 1306a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 1307a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1308a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 1309a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1310a8e1175bSopenharmony_ci } 1311a8e1175bSopenharmony_ci } else { 1312a8e1175bSopenharmony_ci ext_len = 0; 1313a8e1175bSopenharmony_ci } 1314a8e1175bSopenharmony_ci 1315a8e1175bSopenharmony_ci ext = buf + ext_offset + 2; 1316a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "client hello extensions", ext, ext_len); 1317a8e1175bSopenharmony_ci 1318a8e1175bSopenharmony_ci while (ext_len != 0) { 1319a8e1175bSopenharmony_ci unsigned int ext_id; 1320a8e1175bSopenharmony_ci unsigned int ext_size; 1321a8e1175bSopenharmony_ci if (ext_len < 4) { 1322a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 1323a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1324a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 1325a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1326a8e1175bSopenharmony_ci } 1327a8e1175bSopenharmony_ci ext_id = MBEDTLS_GET_UINT16_BE(ext, 0); 1328a8e1175bSopenharmony_ci ext_size = MBEDTLS_GET_UINT16_BE(ext, 2); 1329a8e1175bSopenharmony_ci 1330a8e1175bSopenharmony_ci if (ext_size + 4 > ext_len) { 1331a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client hello message")); 1332a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1333a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 1334a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1335a8e1175bSopenharmony_ci } 1336a8e1175bSopenharmony_ci switch (ext_id) { 1337a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) 1338a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_SERVERNAME: 1339a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found ServerName extension")); 1340a8e1175bSopenharmony_ci ret = mbedtls_ssl_parse_server_name_ext(ssl, ext + 4, 1341a8e1175bSopenharmony_ci ext + 4 + ext_size); 1342a8e1175bSopenharmony_ci if (ret != 0) { 1343a8e1175bSopenharmony_ci return ret; 1344a8e1175bSopenharmony_ci } 1345a8e1175bSopenharmony_ci break; 1346a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ 1347a8e1175bSopenharmony_ci 1348a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO: 1349a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found renegotiation extension")); 1350a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 1351a8e1175bSopenharmony_ci renegotiation_info_seen = 1; 1352a8e1175bSopenharmony_ci#endif 1353a8e1175bSopenharmony_ci 1354a8e1175bSopenharmony_ci ret = ssl_parse_renegotiation_info(ssl, ext + 4, ext_size); 1355a8e1175bSopenharmony_ci if (ret != 0) { 1356a8e1175bSopenharmony_ci return ret; 1357a8e1175bSopenharmony_ci } 1358a8e1175bSopenharmony_ci break; 1359a8e1175bSopenharmony_ci 1360a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) 1361a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_SIG_ALG: 1362a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found signature_algorithms extension")); 1363a8e1175bSopenharmony_ci 1364a8e1175bSopenharmony_ci ret = mbedtls_ssl_parse_sig_alg_ext(ssl, ext + 4, ext + 4 + ext_size); 1365a8e1175bSopenharmony_ci if (ret != 0) { 1366a8e1175bSopenharmony_ci return ret; 1367a8e1175bSopenharmony_ci } 1368a8e1175bSopenharmony_ci 1369a8e1175bSopenharmony_ci sig_hash_alg_ext_present = 1; 1370a8e1175bSopenharmony_ci break; 1371a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ 1372a8e1175bSopenharmony_ci 1373a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ 1374a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ 1375a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 1376a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_SUPPORTED_GROUPS: 1377a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found supported elliptic curves extension")); 1378a8e1175bSopenharmony_ci 1379a8e1175bSopenharmony_ci ret = ssl_parse_supported_groups_ext(ssl, ext + 4, ext_size); 1380a8e1175bSopenharmony_ci if (ret != 0) { 1381a8e1175bSopenharmony_ci return ret; 1382a8e1175bSopenharmony_ci } 1383a8e1175bSopenharmony_ci break; 1384a8e1175bSopenharmony_ci 1385a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: 1386a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found supported point formats extension")); 1387a8e1175bSopenharmony_ci ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT; 1388a8e1175bSopenharmony_ci 1389a8e1175bSopenharmony_ci ret = ssl_parse_supported_point_formats(ssl, ext + 4, ext_size); 1390a8e1175bSopenharmony_ci if (ret != 0) { 1391a8e1175bSopenharmony_ci return ret; 1392a8e1175bSopenharmony_ci } 1393a8e1175bSopenharmony_ci break; 1394a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || \ 1395a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED || 1396a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 1397a8e1175bSopenharmony_ci 1398a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 1399a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_ECJPAKE_KKPP: 1400a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found ecjpake kkpp extension")); 1401a8e1175bSopenharmony_ci 1402a8e1175bSopenharmony_ci ret = ssl_parse_ecjpake_kkpp(ssl, ext + 4, ext_size); 1403a8e1175bSopenharmony_ci if (ret != 0) { 1404a8e1175bSopenharmony_ci return ret; 1405a8e1175bSopenharmony_ci } 1406a8e1175bSopenharmony_ci break; 1407a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 1408a8e1175bSopenharmony_ci 1409a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) 1410a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: 1411a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found max fragment length extension")); 1412a8e1175bSopenharmony_ci 1413a8e1175bSopenharmony_ci ret = ssl_parse_max_fragment_length_ext(ssl, ext + 4, ext_size); 1414a8e1175bSopenharmony_ci if (ret != 0) { 1415a8e1175bSopenharmony_ci return ret; 1416a8e1175bSopenharmony_ci } 1417a8e1175bSopenharmony_ci break; 1418a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ 1419a8e1175bSopenharmony_ci 1420a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 1421a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_CID: 1422a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found CID extension")); 1423a8e1175bSopenharmony_ci 1424a8e1175bSopenharmony_ci ret = ssl_parse_cid_ext(ssl, ext + 4, ext_size); 1425a8e1175bSopenharmony_ci if (ret != 0) { 1426a8e1175bSopenharmony_ci return ret; 1427a8e1175bSopenharmony_ci } 1428a8e1175bSopenharmony_ci break; 1429a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 1430a8e1175bSopenharmony_ci 1431a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 1432a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: 1433a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found encrypt then mac extension")); 1434a8e1175bSopenharmony_ci 1435a8e1175bSopenharmony_ci ret = ssl_parse_encrypt_then_mac_ext(ssl, ext + 4, ext_size); 1436a8e1175bSopenharmony_ci if (ret != 0) { 1437a8e1175bSopenharmony_ci return ret; 1438a8e1175bSopenharmony_ci } 1439a8e1175bSopenharmony_ci break; 1440a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ 1441a8e1175bSopenharmony_ci 1442a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) 1443a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET: 1444a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found extended master secret extension")); 1445a8e1175bSopenharmony_ci 1446a8e1175bSopenharmony_ci ret = ssl_parse_extended_ms_ext(ssl, ext + 4, ext_size); 1447a8e1175bSopenharmony_ci if (ret != 0) { 1448a8e1175bSopenharmony_ci return ret; 1449a8e1175bSopenharmony_ci } 1450a8e1175bSopenharmony_ci break; 1451a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ 1452a8e1175bSopenharmony_ci 1453a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) 1454a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_SESSION_TICKET: 1455a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found session ticket extension")); 1456a8e1175bSopenharmony_ci 1457a8e1175bSopenharmony_ci ret = ssl_parse_session_ticket_ext(ssl, ext + 4, ext_size); 1458a8e1175bSopenharmony_ci if (ret != 0) { 1459a8e1175bSopenharmony_ci return ret; 1460a8e1175bSopenharmony_ci } 1461a8e1175bSopenharmony_ci break; 1462a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS */ 1463a8e1175bSopenharmony_ci 1464a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ALPN) 1465a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_ALPN: 1466a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found alpn extension")); 1467a8e1175bSopenharmony_ci 1468a8e1175bSopenharmony_ci ret = mbedtls_ssl_parse_alpn_ext(ssl, ext + 4, 1469a8e1175bSopenharmony_ci ext + 4 + ext_size); 1470a8e1175bSopenharmony_ci if (ret != 0) { 1471a8e1175bSopenharmony_ci return ret; 1472a8e1175bSopenharmony_ci } 1473a8e1175bSopenharmony_ci break; 1474a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS */ 1475a8e1175bSopenharmony_ci 1476a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_SRTP) 1477a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_USE_SRTP: 1478a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found use_srtp extension")); 1479a8e1175bSopenharmony_ci 1480a8e1175bSopenharmony_ci ret = ssl_parse_use_srtp_ext(ssl, ext + 4, ext_size); 1481a8e1175bSopenharmony_ci if (ret != 0) { 1482a8e1175bSopenharmony_ci return ret; 1483a8e1175bSopenharmony_ci } 1484a8e1175bSopenharmony_ci break; 1485a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_SRTP */ 1486a8e1175bSopenharmony_ci 1487a8e1175bSopenharmony_ci default: 1488a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("unknown extension found: %u (ignoring)", 1489a8e1175bSopenharmony_ci ext_id)); 1490a8e1175bSopenharmony_ci } 1491a8e1175bSopenharmony_ci 1492a8e1175bSopenharmony_ci ext_len -= 4 + ext_size; 1493a8e1175bSopenharmony_ci ext += 4 + ext_size; 1494a8e1175bSopenharmony_ci } 1495a8e1175bSopenharmony_ci 1496a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) 1497a8e1175bSopenharmony_ci 1498a8e1175bSopenharmony_ci /* 1499a8e1175bSopenharmony_ci * Try to fall back to default hash SHA1 if the client 1500a8e1175bSopenharmony_ci * hasn't provided any preferred signature-hash combinations. 1501a8e1175bSopenharmony_ci */ 1502a8e1175bSopenharmony_ci if (!sig_hash_alg_ext_present) { 1503a8e1175bSopenharmony_ci uint16_t *received_sig_algs = ssl->handshake->received_sig_algs; 1504a8e1175bSopenharmony_ci const uint16_t default_sig_algs[] = { 1505a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) 1506a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_ECDSA, 1507a8e1175bSopenharmony_ci MBEDTLS_SSL_HASH_SHA1), 1508a8e1175bSopenharmony_ci#endif 1509a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C) 1510a8e1175bSopenharmony_ci MBEDTLS_SSL_TLS12_SIG_AND_HASH_ALG(MBEDTLS_SSL_SIG_RSA, 1511a8e1175bSopenharmony_ci MBEDTLS_SSL_HASH_SHA1), 1512a8e1175bSopenharmony_ci#endif 1513a8e1175bSopenharmony_ci MBEDTLS_TLS_SIG_NONE 1514a8e1175bSopenharmony_ci }; 1515a8e1175bSopenharmony_ci 1516a8e1175bSopenharmony_ci MBEDTLS_STATIC_ASSERT(sizeof(default_sig_algs) / sizeof(default_sig_algs[0]) 1517a8e1175bSopenharmony_ci <= MBEDTLS_RECEIVED_SIG_ALGS_SIZE, 1518a8e1175bSopenharmony_ci "default_sig_algs is too big"); 1519a8e1175bSopenharmony_ci 1520a8e1175bSopenharmony_ci memcpy(received_sig_algs, default_sig_algs, sizeof(default_sig_algs)); 1521a8e1175bSopenharmony_ci } 1522a8e1175bSopenharmony_ci 1523a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */ 1524a8e1175bSopenharmony_ci 1525a8e1175bSopenharmony_ci /* 1526a8e1175bSopenharmony_ci * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV 1527a8e1175bSopenharmony_ci */ 1528a8e1175bSopenharmony_ci for (i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2) { 1529a8e1175bSopenharmony_ci if (p[0] == 0 && p[1] == MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO) { 1530a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("received TLS_EMPTY_RENEGOTIATION_INFO ")); 1531a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 1532a8e1175bSopenharmony_ci if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) { 1533a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("received RENEGOTIATION SCSV " 1534a8e1175bSopenharmony_ci "during renegotiation")); 1535a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1536a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 1537a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 1538a8e1175bSopenharmony_ci } 1539a8e1175bSopenharmony_ci#endif 1540a8e1175bSopenharmony_ci ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; 1541a8e1175bSopenharmony_ci break; 1542a8e1175bSopenharmony_ci } 1543a8e1175bSopenharmony_ci } 1544a8e1175bSopenharmony_ci 1545a8e1175bSopenharmony_ci /* 1546a8e1175bSopenharmony_ci * Renegotiation security checks 1547a8e1175bSopenharmony_ci */ 1548a8e1175bSopenharmony_ci if (ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION && 1549a8e1175bSopenharmony_ci ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE) { 1550a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("legacy renegotiation, breaking off handshake")); 1551a8e1175bSopenharmony_ci handshake_failure = 1; 1552a8e1175bSopenharmony_ci } 1553a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 1554a8e1175bSopenharmony_ci else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && 1555a8e1175bSopenharmony_ci ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION && 1556a8e1175bSopenharmony_ci renegotiation_info_seen == 0) { 1557a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("renegotiation_info extension missing (secure)")); 1558a8e1175bSopenharmony_ci handshake_failure = 1; 1559a8e1175bSopenharmony_ci } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && 1560a8e1175bSopenharmony_ci ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && 1561a8e1175bSopenharmony_ci ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION) { 1562a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("legacy renegotiation not allowed")); 1563a8e1175bSopenharmony_ci handshake_failure = 1; 1564a8e1175bSopenharmony_ci } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && 1565a8e1175bSopenharmony_ci ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && 1566a8e1175bSopenharmony_ci renegotiation_info_seen == 1) { 1567a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("renegotiation_info extension present (legacy)")); 1568a8e1175bSopenharmony_ci handshake_failure = 1; 1569a8e1175bSopenharmony_ci } 1570a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_RENEGOTIATION */ 1571a8e1175bSopenharmony_ci 1572a8e1175bSopenharmony_ci if (handshake_failure == 1) { 1573a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1574a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 1575a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 1576a8e1175bSopenharmony_ci } 1577a8e1175bSopenharmony_ci 1578a8e1175bSopenharmony_ci /* 1579a8e1175bSopenharmony_ci * Server certification selection (after processing TLS extensions) 1580a8e1175bSopenharmony_ci */ 1581a8e1175bSopenharmony_ci if (ssl->conf->f_cert_cb && (ret = ssl->conf->f_cert_cb(ssl)) != 0) { 1582a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "f_cert_cb", ret); 1583a8e1175bSopenharmony_ci return ret; 1584a8e1175bSopenharmony_ci } 1585a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) 1586a8e1175bSopenharmony_ci ssl->handshake->sni_name = NULL; 1587a8e1175bSopenharmony_ci ssl->handshake->sni_name_len = 0; 1588a8e1175bSopenharmony_ci#endif 1589a8e1175bSopenharmony_ci 1590a8e1175bSopenharmony_ci /* 1591a8e1175bSopenharmony_ci * Search for a matching ciphersuite 1592a8e1175bSopenharmony_ci * (At the end because we need information from the EC-based extensions 1593a8e1175bSopenharmony_ci * and certificate from the SNI callback triggered by the SNI extension 1594a8e1175bSopenharmony_ci * or certificate from server certificate selection callback.) 1595a8e1175bSopenharmony_ci */ 1596a8e1175bSopenharmony_ci got_common_suite = 0; 1597a8e1175bSopenharmony_ci ciphersuites = ssl->conf->ciphersuite_list; 1598a8e1175bSopenharmony_ci ciphersuite_info = NULL; 1599a8e1175bSopenharmony_ci 1600a8e1175bSopenharmony_ci if (ssl->conf->respect_cli_pref == MBEDTLS_SSL_SRV_CIPHERSUITE_ORDER_CLIENT) { 1601a8e1175bSopenharmony_ci for (j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2) { 1602a8e1175bSopenharmony_ci for (i = 0; ciphersuites[i] != 0; i++) { 1603a8e1175bSopenharmony_ci if (MBEDTLS_GET_UINT16_BE(p, 0) != ciphersuites[i]) { 1604a8e1175bSopenharmony_ci continue; 1605a8e1175bSopenharmony_ci } 1606a8e1175bSopenharmony_ci 1607a8e1175bSopenharmony_ci got_common_suite = 1; 1608a8e1175bSopenharmony_ci 1609a8e1175bSopenharmony_ci if ((ret = ssl_ciphersuite_match(ssl, ciphersuites[i], 1610a8e1175bSopenharmony_ci &ciphersuite_info)) != 0) { 1611a8e1175bSopenharmony_ci return ret; 1612a8e1175bSopenharmony_ci } 1613a8e1175bSopenharmony_ci 1614a8e1175bSopenharmony_ci if (ciphersuite_info != NULL) { 1615a8e1175bSopenharmony_ci goto have_ciphersuite; 1616a8e1175bSopenharmony_ci } 1617a8e1175bSopenharmony_ci } 1618a8e1175bSopenharmony_ci } 1619a8e1175bSopenharmony_ci } else { 1620a8e1175bSopenharmony_ci for (i = 0; ciphersuites[i] != 0; i++) { 1621a8e1175bSopenharmony_ci for (j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2) { 1622a8e1175bSopenharmony_ci if (MBEDTLS_GET_UINT16_BE(p, 0) != ciphersuites[i]) { 1623a8e1175bSopenharmony_ci continue; 1624a8e1175bSopenharmony_ci } 1625a8e1175bSopenharmony_ci 1626a8e1175bSopenharmony_ci got_common_suite = 1; 1627a8e1175bSopenharmony_ci 1628a8e1175bSopenharmony_ci if ((ret = ssl_ciphersuite_match(ssl, ciphersuites[i], 1629a8e1175bSopenharmony_ci &ciphersuite_info)) != 0) { 1630a8e1175bSopenharmony_ci return ret; 1631a8e1175bSopenharmony_ci } 1632a8e1175bSopenharmony_ci 1633a8e1175bSopenharmony_ci if (ciphersuite_info != NULL) { 1634a8e1175bSopenharmony_ci goto have_ciphersuite; 1635a8e1175bSopenharmony_ci } 1636a8e1175bSopenharmony_ci } 1637a8e1175bSopenharmony_ci } 1638a8e1175bSopenharmony_ci } 1639a8e1175bSopenharmony_ci 1640a8e1175bSopenharmony_ci if (got_common_suite) { 1641a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("got ciphersuites in common, " 1642a8e1175bSopenharmony_ci "but none of them usable")); 1643a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1644a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 1645a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 1646a8e1175bSopenharmony_ci } else { 1647a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("got no ciphersuites in common")); 1648a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1649a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 1650a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 1651a8e1175bSopenharmony_ci } 1652a8e1175bSopenharmony_ci 1653a8e1175bSopenharmony_cihave_ciphersuite: 1654a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("selected ciphersuite: %s", ciphersuite_info->name)); 1655a8e1175bSopenharmony_ci 1656a8e1175bSopenharmony_ci ssl->session_negotiate->ciphersuite = ciphersuites[i]; 1657a8e1175bSopenharmony_ci ssl->handshake->ciphersuite_info = ciphersuite_info; 1658a8e1175bSopenharmony_ci 1659a8e1175bSopenharmony_ci ssl->state++; 1660a8e1175bSopenharmony_ci 1661a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS) 1662a8e1175bSopenharmony_ci if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 1663a8e1175bSopenharmony_ci mbedtls_ssl_recv_flight_completed(ssl); 1664a8e1175bSopenharmony_ci } 1665a8e1175bSopenharmony_ci#endif 1666a8e1175bSopenharmony_ci 1667a8e1175bSopenharmony_ci /* Debugging-only output for testsuite */ 1668a8e1175bSopenharmony_ci#if defined(MBEDTLS_DEBUG_C) && \ 1669a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) 1670a8e1175bSopenharmony_ci mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_alg(ciphersuite_info); 1671a8e1175bSopenharmony_ci if (sig_alg != MBEDTLS_PK_NONE) { 1672a8e1175bSopenharmony_ci unsigned int sig_hash = mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg( 1673a8e1175bSopenharmony_ci ssl, mbedtls_ssl_sig_from_pk_alg(sig_alg)); 1674a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("client hello v3, signature_algorithm ext: %u", 1675a8e1175bSopenharmony_ci sig_hash)); 1676a8e1175bSopenharmony_ci } else { 1677a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("no hash algorithm for signature algorithm " 1678a8e1175bSopenharmony_ci "%u - should not happen", (unsigned) sig_alg)); 1679a8e1175bSopenharmony_ci } 1680a8e1175bSopenharmony_ci#endif 1681a8e1175bSopenharmony_ci 1682a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse client hello")); 1683a8e1175bSopenharmony_ci 1684a8e1175bSopenharmony_ci return 0; 1685a8e1175bSopenharmony_ci} 1686a8e1175bSopenharmony_ci 1687a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 1688a8e1175bSopenharmony_cistatic void ssl_write_cid_ext(mbedtls_ssl_context *ssl, 1689a8e1175bSopenharmony_ci unsigned char *buf, 1690a8e1175bSopenharmony_ci size_t *olen) 1691a8e1175bSopenharmony_ci{ 1692a8e1175bSopenharmony_ci unsigned char *p = buf; 1693a8e1175bSopenharmony_ci size_t ext_len; 1694a8e1175bSopenharmony_ci const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; 1695a8e1175bSopenharmony_ci 1696a8e1175bSopenharmony_ci *olen = 0; 1697a8e1175bSopenharmony_ci 1698a8e1175bSopenharmony_ci /* Skip writing the extension if we don't want to use it or if 1699a8e1175bSopenharmony_ci * the client hasn't offered it. */ 1700a8e1175bSopenharmony_ci if (ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_DISABLED) { 1701a8e1175bSopenharmony_ci return; 1702a8e1175bSopenharmony_ci } 1703a8e1175bSopenharmony_ci 1704a8e1175bSopenharmony_ci /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX 1705a8e1175bSopenharmony_ci * which is at most 255, so the increment cannot overflow. */ 1706a8e1175bSopenharmony_ci if (end < p || (size_t) (end - p) < (unsigned) (ssl->own_cid_len + 5)) { 1707a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small")); 1708a8e1175bSopenharmony_ci return; 1709a8e1175bSopenharmony_ci } 1710a8e1175bSopenharmony_ci 1711a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding CID extension")); 1712a8e1175bSopenharmony_ci 1713a8e1175bSopenharmony_ci /* 1714a8e1175bSopenharmony_ci * struct { 1715a8e1175bSopenharmony_ci * opaque cid<0..2^8-1>; 1716a8e1175bSopenharmony_ci * } ConnectionId; 1717a8e1175bSopenharmony_ci */ 1718a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_CID, p, 0); 1719a8e1175bSopenharmony_ci p += 2; 1720a8e1175bSopenharmony_ci ext_len = (size_t) ssl->own_cid_len + 1; 1721a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(ext_len, p, 0); 1722a8e1175bSopenharmony_ci p += 2; 1723a8e1175bSopenharmony_ci 1724a8e1175bSopenharmony_ci *p++ = (uint8_t) ssl->own_cid_len; 1725a8e1175bSopenharmony_ci memcpy(p, ssl->own_cid, ssl->own_cid_len); 1726a8e1175bSopenharmony_ci 1727a8e1175bSopenharmony_ci *olen = ssl->own_cid_len + 5; 1728a8e1175bSopenharmony_ci} 1729a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 1730a8e1175bSopenharmony_ci 1731a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM) 1732a8e1175bSopenharmony_cistatic void ssl_write_encrypt_then_mac_ext(mbedtls_ssl_context *ssl, 1733a8e1175bSopenharmony_ci unsigned char *buf, 1734a8e1175bSopenharmony_ci size_t *olen) 1735a8e1175bSopenharmony_ci{ 1736a8e1175bSopenharmony_ci unsigned char *p = buf; 1737a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *suite = NULL; 1738a8e1175bSopenharmony_ci 1739a8e1175bSopenharmony_ci /* 1740a8e1175bSopenharmony_ci * RFC 7366: "If a server receives an encrypt-then-MAC request extension 1741a8e1175bSopenharmony_ci * from a client and then selects a stream or Authenticated Encryption 1742a8e1175bSopenharmony_ci * with Associated Data (AEAD) ciphersuite, it MUST NOT send an 1743a8e1175bSopenharmony_ci * encrypt-then-MAC response extension back to the client." 1744a8e1175bSopenharmony_ci */ 1745a8e1175bSopenharmony_ci suite = mbedtls_ssl_ciphersuite_from_id( 1746a8e1175bSopenharmony_ci ssl->session_negotiate->ciphersuite); 1747a8e1175bSopenharmony_ci if (suite == NULL) { 1748a8e1175bSopenharmony_ci ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_DISABLED; 1749a8e1175bSopenharmony_ci } else { 1750a8e1175bSopenharmony_ci mbedtls_ssl_mode_t ssl_mode = 1751a8e1175bSopenharmony_ci mbedtls_ssl_get_mode_from_ciphersuite( 1752a8e1175bSopenharmony_ci ssl->session_negotiate->encrypt_then_mac, 1753a8e1175bSopenharmony_ci suite); 1754a8e1175bSopenharmony_ci 1755a8e1175bSopenharmony_ci if (ssl_mode != MBEDTLS_SSL_MODE_CBC_ETM) { 1756a8e1175bSopenharmony_ci ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_DISABLED; 1757a8e1175bSopenharmony_ci } 1758a8e1175bSopenharmony_ci } 1759a8e1175bSopenharmony_ci 1760a8e1175bSopenharmony_ci if (ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED) { 1761a8e1175bSopenharmony_ci *olen = 0; 1762a8e1175bSopenharmony_ci return; 1763a8e1175bSopenharmony_ci } 1764a8e1175bSopenharmony_ci 1765a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding encrypt then mac extension")); 1766a8e1175bSopenharmony_ci 1767a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, p, 0); 1768a8e1175bSopenharmony_ci p += 2; 1769a8e1175bSopenharmony_ci 1770a8e1175bSopenharmony_ci *p++ = 0x00; 1771a8e1175bSopenharmony_ci *p++ = 0x00; 1772a8e1175bSopenharmony_ci 1773a8e1175bSopenharmony_ci *olen = 4; 1774a8e1175bSopenharmony_ci} 1775a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM */ 1776a8e1175bSopenharmony_ci 1777a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) 1778a8e1175bSopenharmony_cistatic void ssl_write_extended_ms_ext(mbedtls_ssl_context *ssl, 1779a8e1175bSopenharmony_ci unsigned char *buf, 1780a8e1175bSopenharmony_ci size_t *olen) 1781a8e1175bSopenharmony_ci{ 1782a8e1175bSopenharmony_ci unsigned char *p = buf; 1783a8e1175bSopenharmony_ci 1784a8e1175bSopenharmony_ci if (ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED) { 1785a8e1175bSopenharmony_ci *olen = 0; 1786a8e1175bSopenharmony_ci return; 1787a8e1175bSopenharmony_ci } 1788a8e1175bSopenharmony_ci 1789a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding extended master secret " 1790a8e1175bSopenharmony_ci "extension")); 1791a8e1175bSopenharmony_ci 1792a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, p, 0); 1793a8e1175bSopenharmony_ci p += 2; 1794a8e1175bSopenharmony_ci 1795a8e1175bSopenharmony_ci *p++ = 0x00; 1796a8e1175bSopenharmony_ci *p++ = 0x00; 1797a8e1175bSopenharmony_ci 1798a8e1175bSopenharmony_ci *olen = 4; 1799a8e1175bSopenharmony_ci} 1800a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ 1801a8e1175bSopenharmony_ci 1802a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) 1803a8e1175bSopenharmony_cistatic void ssl_write_session_ticket_ext(mbedtls_ssl_context *ssl, 1804a8e1175bSopenharmony_ci unsigned char *buf, 1805a8e1175bSopenharmony_ci size_t *olen) 1806a8e1175bSopenharmony_ci{ 1807a8e1175bSopenharmony_ci unsigned char *p = buf; 1808a8e1175bSopenharmony_ci 1809a8e1175bSopenharmony_ci if (ssl->handshake->new_session_ticket == 0) { 1810a8e1175bSopenharmony_ci *olen = 0; 1811a8e1175bSopenharmony_ci return; 1812a8e1175bSopenharmony_ci } 1813a8e1175bSopenharmony_ci 1814a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding session ticket extension")); 1815a8e1175bSopenharmony_ci 1816a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SESSION_TICKET, p, 0); 1817a8e1175bSopenharmony_ci p += 2; 1818a8e1175bSopenharmony_ci 1819a8e1175bSopenharmony_ci *p++ = 0x00; 1820a8e1175bSopenharmony_ci *p++ = 0x00; 1821a8e1175bSopenharmony_ci 1822a8e1175bSopenharmony_ci *olen = 4; 1823a8e1175bSopenharmony_ci} 1824a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS */ 1825a8e1175bSopenharmony_ci 1826a8e1175bSopenharmony_cistatic void ssl_write_renegotiation_ext(mbedtls_ssl_context *ssl, 1827a8e1175bSopenharmony_ci unsigned char *buf, 1828a8e1175bSopenharmony_ci size_t *olen) 1829a8e1175bSopenharmony_ci{ 1830a8e1175bSopenharmony_ci unsigned char *p = buf; 1831a8e1175bSopenharmony_ci 1832a8e1175bSopenharmony_ci if (ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION) { 1833a8e1175bSopenharmony_ci *olen = 0; 1834a8e1175bSopenharmony_ci return; 1835a8e1175bSopenharmony_ci } 1836a8e1175bSopenharmony_ci 1837a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, secure renegotiation extension")); 1838a8e1175bSopenharmony_ci 1839a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_RENEGOTIATION_INFO, p, 0); 1840a8e1175bSopenharmony_ci p += 2; 1841a8e1175bSopenharmony_ci 1842a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 1843a8e1175bSopenharmony_ci if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) { 1844a8e1175bSopenharmony_ci *p++ = 0x00; 1845a8e1175bSopenharmony_ci *p++ = (ssl->verify_data_len * 2 + 1) & 0xFF; 1846a8e1175bSopenharmony_ci *p++ = ssl->verify_data_len * 2 & 0xFF; 1847a8e1175bSopenharmony_ci 1848a8e1175bSopenharmony_ci memcpy(p, ssl->peer_verify_data, ssl->verify_data_len); 1849a8e1175bSopenharmony_ci p += ssl->verify_data_len; 1850a8e1175bSopenharmony_ci memcpy(p, ssl->own_verify_data, ssl->verify_data_len); 1851a8e1175bSopenharmony_ci p += ssl->verify_data_len; 1852a8e1175bSopenharmony_ci } else 1853a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_RENEGOTIATION */ 1854a8e1175bSopenharmony_ci { 1855a8e1175bSopenharmony_ci *p++ = 0x00; 1856a8e1175bSopenharmony_ci *p++ = 0x01; 1857a8e1175bSopenharmony_ci *p++ = 0x00; 1858a8e1175bSopenharmony_ci } 1859a8e1175bSopenharmony_ci 1860a8e1175bSopenharmony_ci *olen = (size_t) (p - buf); 1861a8e1175bSopenharmony_ci} 1862a8e1175bSopenharmony_ci 1863a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) 1864a8e1175bSopenharmony_cistatic void ssl_write_max_fragment_length_ext(mbedtls_ssl_context *ssl, 1865a8e1175bSopenharmony_ci unsigned char *buf, 1866a8e1175bSopenharmony_ci size_t *olen) 1867a8e1175bSopenharmony_ci{ 1868a8e1175bSopenharmony_ci unsigned char *p = buf; 1869a8e1175bSopenharmony_ci 1870a8e1175bSopenharmony_ci if (ssl->session_negotiate->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE) { 1871a8e1175bSopenharmony_ci *olen = 0; 1872a8e1175bSopenharmony_ci return; 1873a8e1175bSopenharmony_ci } 1874a8e1175bSopenharmony_ci 1875a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, max_fragment_length extension")); 1876a8e1175bSopenharmony_ci 1877a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, p, 0); 1878a8e1175bSopenharmony_ci p += 2; 1879a8e1175bSopenharmony_ci 1880a8e1175bSopenharmony_ci *p++ = 0x00; 1881a8e1175bSopenharmony_ci *p++ = 1; 1882a8e1175bSopenharmony_ci 1883a8e1175bSopenharmony_ci *p++ = ssl->session_negotiate->mfl_code; 1884a8e1175bSopenharmony_ci 1885a8e1175bSopenharmony_ci *olen = 5; 1886a8e1175bSopenharmony_ci} 1887a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ 1888a8e1175bSopenharmony_ci 1889a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ 1890a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ 1891a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 1892a8e1175bSopenharmony_cistatic void ssl_write_supported_point_formats_ext(mbedtls_ssl_context *ssl, 1893a8e1175bSopenharmony_ci unsigned char *buf, 1894a8e1175bSopenharmony_ci size_t *olen) 1895a8e1175bSopenharmony_ci{ 1896a8e1175bSopenharmony_ci unsigned char *p = buf; 1897a8e1175bSopenharmony_ci ((void) ssl); 1898a8e1175bSopenharmony_ci 1899a8e1175bSopenharmony_ci if ((ssl->handshake->cli_exts & 1900a8e1175bSopenharmony_ci MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT) == 0) { 1901a8e1175bSopenharmony_ci *olen = 0; 1902a8e1175bSopenharmony_ci return; 1903a8e1175bSopenharmony_ci } 1904a8e1175bSopenharmony_ci 1905a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, supported_point_formats extension")); 1906a8e1175bSopenharmony_ci 1907a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, p, 0); 1908a8e1175bSopenharmony_ci p += 2; 1909a8e1175bSopenharmony_ci 1910a8e1175bSopenharmony_ci *p++ = 0x00; 1911a8e1175bSopenharmony_ci *p++ = 2; 1912a8e1175bSopenharmony_ci 1913a8e1175bSopenharmony_ci *p++ = 1; 1914a8e1175bSopenharmony_ci *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED; 1915a8e1175bSopenharmony_ci 1916a8e1175bSopenharmony_ci *olen = 6; 1917a8e1175bSopenharmony_ci} 1918a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || 1919a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED || 1920a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 1921a8e1175bSopenharmony_ci 1922a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 1923a8e1175bSopenharmony_cistatic void ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl, 1924a8e1175bSopenharmony_ci unsigned char *buf, 1925a8e1175bSopenharmony_ci size_t *olen) 1926a8e1175bSopenharmony_ci{ 1927a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1928a8e1175bSopenharmony_ci unsigned char *p = buf; 1929a8e1175bSopenharmony_ci const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; 1930a8e1175bSopenharmony_ci size_t kkpp_len; 1931a8e1175bSopenharmony_ci 1932a8e1175bSopenharmony_ci *olen = 0; 1933a8e1175bSopenharmony_ci 1934a8e1175bSopenharmony_ci /* Skip costly computation if not needed */ 1935a8e1175bSopenharmony_ci if (ssl->handshake->ciphersuite_info->key_exchange != 1936a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECJPAKE) { 1937a8e1175bSopenharmony_ci return; 1938a8e1175bSopenharmony_ci } 1939a8e1175bSopenharmony_ci 1940a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, ecjpake kkpp extension")); 1941a8e1175bSopenharmony_ci 1942a8e1175bSopenharmony_ci if (end - p < 4) { 1943a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small")); 1944a8e1175bSopenharmony_ci return; 1945a8e1175bSopenharmony_ci } 1946a8e1175bSopenharmony_ci 1947a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0); 1948a8e1175bSopenharmony_ci p += 2; 1949a8e1175bSopenharmony_ci 1950a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 1951a8e1175bSopenharmony_ci ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx, 1952a8e1175bSopenharmony_ci p + 2, (size_t) (end - p - 2), &kkpp_len, 1953a8e1175bSopenharmony_ci MBEDTLS_ECJPAKE_ROUND_ONE); 1954a8e1175bSopenharmony_ci if (ret != 0) { 1955a8e1175bSopenharmony_ci psa_destroy_key(ssl->handshake->psa_pake_password); 1956a8e1175bSopenharmony_ci psa_pake_abort(&ssl->handshake->psa_pake_ctx); 1957a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret); 1958a8e1175bSopenharmony_ci return; 1959a8e1175bSopenharmony_ci } 1960a8e1175bSopenharmony_ci#else 1961a8e1175bSopenharmony_ci ret = mbedtls_ecjpake_write_round_one(&ssl->handshake->ecjpake_ctx, 1962a8e1175bSopenharmony_ci p + 2, (size_t) (end - p - 2), &kkpp_len, 1963a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng); 1964a8e1175bSopenharmony_ci if (ret != 0) { 1965a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_one", ret); 1966a8e1175bSopenharmony_ci return; 1967a8e1175bSopenharmony_ci } 1968a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 1969a8e1175bSopenharmony_ci 1970a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(kkpp_len, p, 0); 1971a8e1175bSopenharmony_ci p += 2; 1972a8e1175bSopenharmony_ci 1973a8e1175bSopenharmony_ci *olen = kkpp_len + 4; 1974a8e1175bSopenharmony_ci} 1975a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 1976a8e1175bSopenharmony_ci 1977a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_SRTP) && defined(MBEDTLS_SSL_PROTO_DTLS) 1978a8e1175bSopenharmony_cistatic void ssl_write_use_srtp_ext(mbedtls_ssl_context *ssl, 1979a8e1175bSopenharmony_ci unsigned char *buf, 1980a8e1175bSopenharmony_ci size_t *olen) 1981a8e1175bSopenharmony_ci{ 1982a8e1175bSopenharmony_ci size_t mki_len = 0, ext_len = 0; 1983a8e1175bSopenharmony_ci uint16_t profile_value = 0; 1984a8e1175bSopenharmony_ci const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; 1985a8e1175bSopenharmony_ci 1986a8e1175bSopenharmony_ci *olen = 0; 1987a8e1175bSopenharmony_ci 1988a8e1175bSopenharmony_ci if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) || 1989a8e1175bSopenharmony_ci (ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET)) { 1990a8e1175bSopenharmony_ci return; 1991a8e1175bSopenharmony_ci } 1992a8e1175bSopenharmony_ci 1993a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, adding use_srtp extension")); 1994a8e1175bSopenharmony_ci 1995a8e1175bSopenharmony_ci if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED) { 1996a8e1175bSopenharmony_ci mki_len = ssl->dtls_srtp_info.mki_len; 1997a8e1175bSopenharmony_ci } 1998a8e1175bSopenharmony_ci 1999a8e1175bSopenharmony_ci /* The extension total size is 9 bytes : 2000a8e1175bSopenharmony_ci * - 2 bytes for the extension tag 2001a8e1175bSopenharmony_ci * - 2 bytes for the total size 2002a8e1175bSopenharmony_ci * - 2 bytes for the protection profile length 2003a8e1175bSopenharmony_ci * - 2 bytes for the protection profile 2004a8e1175bSopenharmony_ci * - 1 byte for the mki length 2005a8e1175bSopenharmony_ci * + the actual mki length 2006a8e1175bSopenharmony_ci * Check we have enough room in the output buffer */ 2007a8e1175bSopenharmony_ci if ((size_t) (end - buf) < mki_len + 9) { 2008a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small")); 2009a8e1175bSopenharmony_ci return; 2010a8e1175bSopenharmony_ci } 2011a8e1175bSopenharmony_ci 2012a8e1175bSopenharmony_ci /* extension */ 2013a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_USE_SRTP, buf, 0); 2014a8e1175bSopenharmony_ci /* 2015a8e1175bSopenharmony_ci * total length 5 and mki value: only one profile(2 bytes) 2016a8e1175bSopenharmony_ci * and length(2 bytes) and srtp_mki ) 2017a8e1175bSopenharmony_ci */ 2018a8e1175bSopenharmony_ci ext_len = 5 + mki_len; 2019a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(ext_len, buf, 2); 2020a8e1175bSopenharmony_ci 2021a8e1175bSopenharmony_ci /* protection profile length: 2 */ 2022a8e1175bSopenharmony_ci buf[4] = 0x00; 2023a8e1175bSopenharmony_ci buf[5] = 0x02; 2024a8e1175bSopenharmony_ci profile_value = mbedtls_ssl_check_srtp_profile_value( 2025a8e1175bSopenharmony_ci ssl->dtls_srtp_info.chosen_dtls_srtp_profile); 2026a8e1175bSopenharmony_ci if (profile_value != MBEDTLS_TLS_SRTP_UNSET) { 2027a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(profile_value, buf, 6); 2028a8e1175bSopenharmony_ci } else { 2029a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("use_srtp extension invalid profile")); 2030a8e1175bSopenharmony_ci return; 2031a8e1175bSopenharmony_ci } 2032a8e1175bSopenharmony_ci 2033a8e1175bSopenharmony_ci buf[8] = mki_len & 0xFF; 2034a8e1175bSopenharmony_ci memcpy(&buf[9], ssl->dtls_srtp_info.mki_value, mki_len); 2035a8e1175bSopenharmony_ci 2036a8e1175bSopenharmony_ci *olen = 9 + mki_len; 2037a8e1175bSopenharmony_ci} 2038a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_SRTP */ 2039a8e1175bSopenharmony_ci 2040a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) 2041a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 2042a8e1175bSopenharmony_cistatic int ssl_write_hello_verify_request(mbedtls_ssl_context *ssl) 2043a8e1175bSopenharmony_ci{ 2044a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 2045a8e1175bSopenharmony_ci unsigned char *p = ssl->out_msg + 4; 2046a8e1175bSopenharmony_ci unsigned char *cookie_len_byte; 2047a8e1175bSopenharmony_ci 2048a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> write hello verify request")); 2049a8e1175bSopenharmony_ci 2050a8e1175bSopenharmony_ci /* 2051a8e1175bSopenharmony_ci * struct { 2052a8e1175bSopenharmony_ci * ProtocolVersion server_version; 2053a8e1175bSopenharmony_ci * opaque cookie<0..2^8-1>; 2054a8e1175bSopenharmony_ci * } HelloVerifyRequest; 2055a8e1175bSopenharmony_ci */ 2056a8e1175bSopenharmony_ci 2057a8e1175bSopenharmony_ci /* The RFC is not clear on this point, but sending the actual negotiated 2058a8e1175bSopenharmony_ci * version looks like the most interoperable thing to do. */ 2059a8e1175bSopenharmony_ci mbedtls_ssl_write_version(p, ssl->conf->transport, ssl->tls_version); 2060a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "server version", p, 2); 2061a8e1175bSopenharmony_ci p += 2; 2062a8e1175bSopenharmony_ci 2063a8e1175bSopenharmony_ci /* If we get here, f_cookie_check is not null */ 2064a8e1175bSopenharmony_ci if (ssl->conf->f_cookie_write == NULL) { 2065a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("inconsistent cookie callbacks")); 2066a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 2067a8e1175bSopenharmony_ci } 2068a8e1175bSopenharmony_ci 2069a8e1175bSopenharmony_ci /* Skip length byte until we know the length */ 2070a8e1175bSopenharmony_ci cookie_len_byte = p++; 2071a8e1175bSopenharmony_ci 2072a8e1175bSopenharmony_ci if ((ret = ssl->conf->f_cookie_write(ssl->conf->p_cookie, 2073a8e1175bSopenharmony_ci &p, ssl->out_buf + MBEDTLS_SSL_OUT_BUFFER_LEN, 2074a8e1175bSopenharmony_ci ssl->cli_id, ssl->cli_id_len)) != 0) { 2075a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "f_cookie_write", ret); 2076a8e1175bSopenharmony_ci return ret; 2077a8e1175bSopenharmony_ci } 2078a8e1175bSopenharmony_ci 2079a8e1175bSopenharmony_ci *cookie_len_byte = (unsigned char) (p - (cookie_len_byte + 1)); 2080a8e1175bSopenharmony_ci 2081a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "cookie sent", cookie_len_byte + 1, *cookie_len_byte); 2082a8e1175bSopenharmony_ci 2083a8e1175bSopenharmony_ci ssl->out_msglen = (size_t) (p - ssl->out_msg); 2084a8e1175bSopenharmony_ci ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; 2085a8e1175bSopenharmony_ci ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST; 2086a8e1175bSopenharmony_ci 2087a8e1175bSopenharmony_ci ssl->state = MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT; 2088a8e1175bSopenharmony_ci 2089a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { 2090a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); 2091a8e1175bSopenharmony_ci return ret; 2092a8e1175bSopenharmony_ci } 2093a8e1175bSopenharmony_ci 2094a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS) 2095a8e1175bSopenharmony_ci if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 2096a8e1175bSopenharmony_ci (ret = mbedtls_ssl_flight_transmit(ssl)) != 0) { 2097a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flight_transmit", ret); 2098a8e1175bSopenharmony_ci return ret; 2099a8e1175bSopenharmony_ci } 2100a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */ 2101a8e1175bSopenharmony_ci 2102a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= write hello verify request")); 2103a8e1175bSopenharmony_ci 2104a8e1175bSopenharmony_ci return 0; 2105a8e1175bSopenharmony_ci} 2106a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ 2107a8e1175bSopenharmony_ci 2108a8e1175bSopenharmony_cistatic void ssl_handle_id_based_session_resumption(mbedtls_ssl_context *ssl) 2109a8e1175bSopenharmony_ci{ 2110a8e1175bSopenharmony_ci int ret; 2111a8e1175bSopenharmony_ci mbedtls_ssl_session session_tmp; 2112a8e1175bSopenharmony_ci mbedtls_ssl_session * const session = ssl->session_negotiate; 2113a8e1175bSopenharmony_ci 2114a8e1175bSopenharmony_ci /* Resume is 0 by default, see ssl_handshake_init(). 2115a8e1175bSopenharmony_ci * It may be already set to 1 by ssl_parse_session_ticket_ext(). */ 2116a8e1175bSopenharmony_ci if (ssl->handshake->resume == 1) { 2117a8e1175bSopenharmony_ci return; 2118a8e1175bSopenharmony_ci } 2119a8e1175bSopenharmony_ci if (session->id_len == 0) { 2120a8e1175bSopenharmony_ci return; 2121a8e1175bSopenharmony_ci } 2122a8e1175bSopenharmony_ci if (ssl->conf->f_get_cache == NULL) { 2123a8e1175bSopenharmony_ci return; 2124a8e1175bSopenharmony_ci } 2125a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 2126a8e1175bSopenharmony_ci if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) { 2127a8e1175bSopenharmony_ci return; 2128a8e1175bSopenharmony_ci } 2129a8e1175bSopenharmony_ci#endif 2130a8e1175bSopenharmony_ci 2131a8e1175bSopenharmony_ci mbedtls_ssl_session_init(&session_tmp); 2132a8e1175bSopenharmony_ci 2133a8e1175bSopenharmony_ci ret = ssl->conf->f_get_cache(ssl->conf->p_cache, 2134a8e1175bSopenharmony_ci session->id, 2135a8e1175bSopenharmony_ci session->id_len, 2136a8e1175bSopenharmony_ci &session_tmp); 2137a8e1175bSopenharmony_ci if (ret != 0) { 2138a8e1175bSopenharmony_ci goto exit; 2139a8e1175bSopenharmony_ci } 2140a8e1175bSopenharmony_ci 2141a8e1175bSopenharmony_ci if (session->ciphersuite != session_tmp.ciphersuite) { 2142a8e1175bSopenharmony_ci /* Mismatch between cached and negotiated session */ 2143a8e1175bSopenharmony_ci goto exit; 2144a8e1175bSopenharmony_ci } 2145a8e1175bSopenharmony_ci 2146a8e1175bSopenharmony_ci /* Move semantics */ 2147a8e1175bSopenharmony_ci mbedtls_ssl_session_free(session); 2148a8e1175bSopenharmony_ci *session = session_tmp; 2149a8e1175bSopenharmony_ci memset(&session_tmp, 0, sizeof(session_tmp)); 2150a8e1175bSopenharmony_ci 2151a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("session successfully restored from cache")); 2152a8e1175bSopenharmony_ci ssl->handshake->resume = 1; 2153a8e1175bSopenharmony_ci 2154a8e1175bSopenharmony_ciexit: 2155a8e1175bSopenharmony_ci 2156a8e1175bSopenharmony_ci mbedtls_ssl_session_free(&session_tmp); 2157a8e1175bSopenharmony_ci} 2158a8e1175bSopenharmony_ci 2159a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 2160a8e1175bSopenharmony_cistatic int ssl_write_server_hello(mbedtls_ssl_context *ssl) 2161a8e1175bSopenharmony_ci{ 2162a8e1175bSopenharmony_ci#if defined(MBEDTLS_HAVE_TIME) 2163a8e1175bSopenharmony_ci mbedtls_time_t t; 2164a8e1175bSopenharmony_ci#endif 2165a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 2166a8e1175bSopenharmony_ci size_t olen, ext_len = 0, n; 2167a8e1175bSopenharmony_ci unsigned char *buf, *p; 2168a8e1175bSopenharmony_ci 2169a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server hello")); 2170a8e1175bSopenharmony_ci 2171a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) 2172a8e1175bSopenharmony_ci if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 2173a8e1175bSopenharmony_ci ssl->handshake->cookie_verify_result != 0) { 2174a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("client hello was not authenticated")); 2175a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello")); 2176a8e1175bSopenharmony_ci 2177a8e1175bSopenharmony_ci return ssl_write_hello_verify_request(ssl); 2178a8e1175bSopenharmony_ci } 2179a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ 2180a8e1175bSopenharmony_ci 2181a8e1175bSopenharmony_ci /* 2182a8e1175bSopenharmony_ci * 0 . 0 handshake type 2183a8e1175bSopenharmony_ci * 1 . 3 handshake length 2184a8e1175bSopenharmony_ci * 4 . 5 protocol version 2185a8e1175bSopenharmony_ci * 6 . 9 UNIX time() 2186a8e1175bSopenharmony_ci * 10 . 37 random bytes 2187a8e1175bSopenharmony_ci */ 2188a8e1175bSopenharmony_ci buf = ssl->out_msg; 2189a8e1175bSopenharmony_ci p = buf + 4; 2190a8e1175bSopenharmony_ci 2191a8e1175bSopenharmony_ci mbedtls_ssl_write_version(p, ssl->conf->transport, ssl->tls_version); 2192a8e1175bSopenharmony_ci p += 2; 2193a8e1175bSopenharmony_ci 2194a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen version: [%d:%d]", 2195a8e1175bSopenharmony_ci buf[4], buf[5])); 2196a8e1175bSopenharmony_ci 2197a8e1175bSopenharmony_ci#if defined(MBEDTLS_HAVE_TIME) 2198a8e1175bSopenharmony_ci t = mbedtls_time(NULL); 2199a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT32_BE(t, p, 0); 2200a8e1175bSopenharmony_ci p += 4; 2201a8e1175bSopenharmony_ci 2202a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, current time: %" MBEDTLS_PRINTF_LONGLONG, 2203a8e1175bSopenharmony_ci (long long) t)); 2204a8e1175bSopenharmony_ci#else 2205a8e1175bSopenharmony_ci if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 4)) != 0) { 2206a8e1175bSopenharmony_ci return ret; 2207a8e1175bSopenharmony_ci } 2208a8e1175bSopenharmony_ci 2209a8e1175bSopenharmony_ci p += 4; 2210a8e1175bSopenharmony_ci#endif /* MBEDTLS_HAVE_TIME */ 2211a8e1175bSopenharmony_ci 2212a8e1175bSopenharmony_ci if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 20)) != 0) { 2213a8e1175bSopenharmony_ci return ret; 2214a8e1175bSopenharmony_ci } 2215a8e1175bSopenharmony_ci p += 20; 2216a8e1175bSopenharmony_ci 2217a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_TLS1_3) 2218a8e1175bSopenharmony_ci /* 2219a8e1175bSopenharmony_ci * RFC 8446 2220a8e1175bSopenharmony_ci * TLS 1.3 has a downgrade protection mechanism embedded in the server's 2221a8e1175bSopenharmony_ci * random value. TLS 1.3 servers which negotiate TLS 1.2 or below in 2222a8e1175bSopenharmony_ci * response to a ClientHello MUST set the last 8 bytes of their Random 2223a8e1175bSopenharmony_ci * value specially in their ServerHello. 2224a8e1175bSopenharmony_ci */ 2225a8e1175bSopenharmony_ci if (mbedtls_ssl_conf_is_tls13_enabled(ssl->conf)) { 2226a8e1175bSopenharmony_ci static const unsigned char magic_tls12_downgrade_string[] = 2227a8e1175bSopenharmony_ci { 'D', 'O', 'W', 'N', 'G', 'R', 'D', 1 }; 2228a8e1175bSopenharmony_ci 2229a8e1175bSopenharmony_ci MBEDTLS_STATIC_ASSERT( 2230a8e1175bSopenharmony_ci sizeof(magic_tls12_downgrade_string) == 8, 2231a8e1175bSopenharmony_ci "magic_tls12_downgrade_string does not have the expected size"); 2232a8e1175bSopenharmony_ci 2233a8e1175bSopenharmony_ci memcpy(p, magic_tls12_downgrade_string, 2234a8e1175bSopenharmony_ci sizeof(magic_tls12_downgrade_string)); 2235a8e1175bSopenharmony_ci } else 2236a8e1175bSopenharmony_ci#endif 2237a8e1175bSopenharmony_ci { 2238a8e1175bSopenharmony_ci if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p, 8)) != 0) { 2239a8e1175bSopenharmony_ci return ret; 2240a8e1175bSopenharmony_ci } 2241a8e1175bSopenharmony_ci } 2242a8e1175bSopenharmony_ci p += 8; 2243a8e1175bSopenharmony_ci 2244a8e1175bSopenharmony_ci memcpy(ssl->handshake->randbytes + 32, buf + 6, 32); 2245a8e1175bSopenharmony_ci 2246a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "server hello, random bytes", buf + 6, 32); 2247a8e1175bSopenharmony_ci 2248a8e1175bSopenharmony_ci ssl_handle_id_based_session_resumption(ssl); 2249a8e1175bSopenharmony_ci 2250a8e1175bSopenharmony_ci if (ssl->handshake->resume == 0) { 2251a8e1175bSopenharmony_ci /* 2252a8e1175bSopenharmony_ci * New session, create a new session id, 2253a8e1175bSopenharmony_ci * unless we're about to issue a session ticket 2254a8e1175bSopenharmony_ci */ 2255a8e1175bSopenharmony_ci ssl->state++; 2256a8e1175bSopenharmony_ci 2257a8e1175bSopenharmony_ci#if defined(MBEDTLS_HAVE_TIME) 2258a8e1175bSopenharmony_ci ssl->session_negotiate->start = mbedtls_time(NULL); 2259a8e1175bSopenharmony_ci#endif 2260a8e1175bSopenharmony_ci 2261a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) 2262a8e1175bSopenharmony_ci if (ssl->handshake->new_session_ticket != 0) { 2263a8e1175bSopenharmony_ci ssl->session_negotiate->id_len = n = 0; 2264a8e1175bSopenharmony_ci memset(ssl->session_negotiate->id, 0, 32); 2265a8e1175bSopenharmony_ci } else 2266a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS */ 2267a8e1175bSopenharmony_ci { 2268a8e1175bSopenharmony_ci ssl->session_negotiate->id_len = n = 32; 2269a8e1175bSopenharmony_ci if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, ssl->session_negotiate->id, 2270a8e1175bSopenharmony_ci n)) != 0) { 2271a8e1175bSopenharmony_ci return ret; 2272a8e1175bSopenharmony_ci } 2273a8e1175bSopenharmony_ci } 2274a8e1175bSopenharmony_ci } else { 2275a8e1175bSopenharmony_ci /* 2276a8e1175bSopenharmony_ci * Resuming a session 2277a8e1175bSopenharmony_ci */ 2278a8e1175bSopenharmony_ci n = ssl->session_negotiate->id_len; 2279a8e1175bSopenharmony_ci ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; 2280a8e1175bSopenharmony_ci 2281a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) { 2282a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret); 2283a8e1175bSopenharmony_ci return ret; 2284a8e1175bSopenharmony_ci } 2285a8e1175bSopenharmony_ci } 2286a8e1175bSopenharmony_ci 2287a8e1175bSopenharmony_ci /* 2288a8e1175bSopenharmony_ci * 38 . 38 session id length 2289a8e1175bSopenharmony_ci * 39 . 38+n session id 2290a8e1175bSopenharmony_ci * 39+n . 40+n chosen ciphersuite 2291a8e1175bSopenharmony_ci * 41+n . 41+n chosen compression alg. 2292a8e1175bSopenharmony_ci * 42+n . 43+n extensions length 2293a8e1175bSopenharmony_ci * 44+n . 43+n+m extensions 2294a8e1175bSopenharmony_ci */ 2295a8e1175bSopenharmony_ci *p++ = (unsigned char) ssl->session_negotiate->id_len; 2296a8e1175bSopenharmony_ci memcpy(p, ssl->session_negotiate->id, ssl->session_negotiate->id_len); 2297a8e1175bSopenharmony_ci p += ssl->session_negotiate->id_len; 2298a8e1175bSopenharmony_ci 2299a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, session id len.: %" MBEDTLS_PRINTF_SIZET, n)); 2300a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "server hello, session id", buf + 39, n); 2301a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("%s session has been resumed", 2302a8e1175bSopenharmony_ci ssl->handshake->resume ? "a" : "no")); 2303a8e1175bSopenharmony_ci 2304a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(ssl->session_negotiate->ciphersuite, p, 0); 2305a8e1175bSopenharmony_ci p += 2; 2306a8e1175bSopenharmony_ci *p++ = MBEDTLS_BYTE_0(MBEDTLS_SSL_COMPRESS_NULL); 2307a8e1175bSopenharmony_ci 2308a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen ciphersuite: %s", 2309a8e1175bSopenharmony_ci mbedtls_ssl_get_ciphersuite_name(ssl->session_negotiate->ciphersuite))); 2310a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, compress alg.: 0x%02X", 2311a8e1175bSopenharmony_ci (unsigned int) MBEDTLS_SSL_COMPRESS_NULL)); 2312a8e1175bSopenharmony_ci 2313a8e1175bSopenharmony_ci /* 2314a8e1175bSopenharmony_ci * First write extensions, then the total length 2315a8e1175bSopenharmony_ci */ 2316a8e1175bSopenharmony_ci ssl_write_renegotiation_ext(ssl, p + 2 + ext_len, &olen); 2317a8e1175bSopenharmony_ci ext_len += olen; 2318a8e1175bSopenharmony_ci 2319a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) 2320a8e1175bSopenharmony_ci ssl_write_max_fragment_length_ext(ssl, p + 2 + ext_len, &olen); 2321a8e1175bSopenharmony_ci ext_len += olen; 2322a8e1175bSopenharmony_ci#endif 2323a8e1175bSopenharmony_ci 2324a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 2325a8e1175bSopenharmony_ci ssl_write_cid_ext(ssl, p + 2 + ext_len, &olen); 2326a8e1175bSopenharmony_ci ext_len += olen; 2327a8e1175bSopenharmony_ci#endif 2328a8e1175bSopenharmony_ci 2329a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC_ETM) 2330a8e1175bSopenharmony_ci ssl_write_encrypt_then_mac_ext(ssl, p + 2 + ext_len, &olen); 2331a8e1175bSopenharmony_ci ext_len += olen; 2332a8e1175bSopenharmony_ci#endif 2333a8e1175bSopenharmony_ci 2334a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) 2335a8e1175bSopenharmony_ci ssl_write_extended_ms_ext(ssl, p + 2 + ext_len, &olen); 2336a8e1175bSopenharmony_ci ext_len += olen; 2337a8e1175bSopenharmony_ci#endif 2338a8e1175bSopenharmony_ci 2339a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) 2340a8e1175bSopenharmony_ci ssl_write_session_ticket_ext(ssl, p + 2 + ext_len, &olen); 2341a8e1175bSopenharmony_ci ext_len += olen; 2342a8e1175bSopenharmony_ci#endif 2343a8e1175bSopenharmony_ci 2344a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ 2345a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ 2346a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 2347a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *suite = 2348a8e1175bSopenharmony_ci mbedtls_ssl_ciphersuite_from_id(ssl->session_negotiate->ciphersuite); 2349a8e1175bSopenharmony_ci if (suite != NULL && mbedtls_ssl_ciphersuite_uses_ec(suite)) { 2350a8e1175bSopenharmony_ci ssl_write_supported_point_formats_ext(ssl, p + 2 + ext_len, &olen); 2351a8e1175bSopenharmony_ci ext_len += olen; 2352a8e1175bSopenharmony_ci } 2353a8e1175bSopenharmony_ci#endif 2354a8e1175bSopenharmony_ci 2355a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 2356a8e1175bSopenharmony_ci ssl_write_ecjpake_kkpp_ext(ssl, p + 2 + ext_len, &olen); 2357a8e1175bSopenharmony_ci ext_len += olen; 2358a8e1175bSopenharmony_ci#endif 2359a8e1175bSopenharmony_ci 2360a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ALPN) 2361a8e1175bSopenharmony_ci unsigned char *end = buf + MBEDTLS_SSL_OUT_CONTENT_LEN - 4; 2362a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_write_alpn_ext(ssl, p + 2 + ext_len, end, &olen)) 2363a8e1175bSopenharmony_ci != 0) { 2364a8e1175bSopenharmony_ci return ret; 2365a8e1175bSopenharmony_ci } 2366a8e1175bSopenharmony_ci 2367a8e1175bSopenharmony_ci ext_len += olen; 2368a8e1175bSopenharmony_ci#endif 2369a8e1175bSopenharmony_ci 2370a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_SRTP) 2371a8e1175bSopenharmony_ci ssl_write_use_srtp_ext(ssl, p + 2 + ext_len, &olen); 2372a8e1175bSopenharmony_ci ext_len += olen; 2373a8e1175bSopenharmony_ci#endif 2374a8e1175bSopenharmony_ci 2375a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, total extension length: %" MBEDTLS_PRINTF_SIZET, 2376a8e1175bSopenharmony_ci ext_len)); 2377a8e1175bSopenharmony_ci 2378a8e1175bSopenharmony_ci if (ext_len > 0) { 2379a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(ext_len, p, 0); 2380a8e1175bSopenharmony_ci p += 2 + ext_len; 2381a8e1175bSopenharmony_ci } 2382a8e1175bSopenharmony_ci 2383a8e1175bSopenharmony_ci ssl->out_msglen = (size_t) (p - buf); 2384a8e1175bSopenharmony_ci ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; 2385a8e1175bSopenharmony_ci ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO; 2386a8e1175bSopenharmony_ci 2387a8e1175bSopenharmony_ci ret = mbedtls_ssl_write_handshake_msg(ssl); 2388a8e1175bSopenharmony_ci 2389a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello")); 2390a8e1175bSopenharmony_ci 2391a8e1175bSopenharmony_ci return ret; 2392a8e1175bSopenharmony_ci} 2393a8e1175bSopenharmony_ci 2394a8e1175bSopenharmony_ci#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) 2395a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 2396a8e1175bSopenharmony_cistatic int ssl_write_certificate_request(mbedtls_ssl_context *ssl) 2397a8e1175bSopenharmony_ci{ 2398a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 2399a8e1175bSopenharmony_ci ssl->handshake->ciphersuite_info; 2400a8e1175bSopenharmony_ci 2401a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate request")); 2402a8e1175bSopenharmony_ci 2403a8e1175bSopenharmony_ci if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { 2404a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate request")); 2405a8e1175bSopenharmony_ci ssl->state++; 2406a8e1175bSopenharmony_ci return 0; 2407a8e1175bSopenharmony_ci } 2408a8e1175bSopenharmony_ci 2409a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 2410a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 2411a8e1175bSopenharmony_ci} 2412a8e1175bSopenharmony_ci#else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ 2413a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 2414a8e1175bSopenharmony_cistatic int ssl_write_certificate_request(mbedtls_ssl_context *ssl) 2415a8e1175bSopenharmony_ci{ 2416a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 2417a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 2418a8e1175bSopenharmony_ci ssl->handshake->ciphersuite_info; 2419a8e1175bSopenharmony_ci uint16_t dn_size, total_dn_size; /* excluding length bytes */ 2420a8e1175bSopenharmony_ci size_t ct_len, sa_len; /* including length bytes */ 2421a8e1175bSopenharmony_ci unsigned char *buf, *p; 2422a8e1175bSopenharmony_ci const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; 2423a8e1175bSopenharmony_ci const mbedtls_x509_crt *crt; 2424a8e1175bSopenharmony_ci int authmode; 2425a8e1175bSopenharmony_ci 2426a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate request")); 2427a8e1175bSopenharmony_ci 2428a8e1175bSopenharmony_ci ssl->state++; 2429a8e1175bSopenharmony_ci 2430a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) 2431a8e1175bSopenharmony_ci if (ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET) { 2432a8e1175bSopenharmony_ci authmode = ssl->handshake->sni_authmode; 2433a8e1175bSopenharmony_ci } else 2434a8e1175bSopenharmony_ci#endif 2435a8e1175bSopenharmony_ci authmode = ssl->conf->authmode; 2436a8e1175bSopenharmony_ci 2437a8e1175bSopenharmony_ci if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info) || 2438a8e1175bSopenharmony_ci authmode == MBEDTLS_SSL_VERIFY_NONE) { 2439a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate request")); 2440a8e1175bSopenharmony_ci return 0; 2441a8e1175bSopenharmony_ci } 2442a8e1175bSopenharmony_ci 2443a8e1175bSopenharmony_ci /* 2444a8e1175bSopenharmony_ci * 0 . 0 handshake type 2445a8e1175bSopenharmony_ci * 1 . 3 handshake length 2446a8e1175bSopenharmony_ci * 4 . 4 cert type count 2447a8e1175bSopenharmony_ci * 5 .. m-1 cert types 2448a8e1175bSopenharmony_ci * m .. m+1 sig alg length (TLS 1.2 only) 2449a8e1175bSopenharmony_ci * m+1 .. n-1 SignatureAndHashAlgorithms (TLS 1.2 only) 2450a8e1175bSopenharmony_ci * n .. n+1 length of all DNs 2451a8e1175bSopenharmony_ci * n+2 .. n+3 length of DN 1 2452a8e1175bSopenharmony_ci * n+4 .. ... Distinguished Name #1 2453a8e1175bSopenharmony_ci * ... .. ... length of DN 2, etc. 2454a8e1175bSopenharmony_ci */ 2455a8e1175bSopenharmony_ci buf = ssl->out_msg; 2456a8e1175bSopenharmony_ci p = buf + 4; 2457a8e1175bSopenharmony_ci 2458a8e1175bSopenharmony_ci /* 2459a8e1175bSopenharmony_ci * Supported certificate types 2460a8e1175bSopenharmony_ci * 2461a8e1175bSopenharmony_ci * ClientCertificateType certificate_types<1..2^8-1>; 2462a8e1175bSopenharmony_ci * enum { (255) } ClientCertificateType; 2463a8e1175bSopenharmony_ci */ 2464a8e1175bSopenharmony_ci ct_len = 0; 2465a8e1175bSopenharmony_ci 2466a8e1175bSopenharmony_ci#if defined(MBEDTLS_RSA_C) 2467a8e1175bSopenharmony_ci p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN; 2468a8e1175bSopenharmony_ci#endif 2469a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) 2470a8e1175bSopenharmony_ci p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN; 2471a8e1175bSopenharmony_ci#endif 2472a8e1175bSopenharmony_ci 2473a8e1175bSopenharmony_ci p[0] = (unsigned char) ct_len++; 2474a8e1175bSopenharmony_ci p += ct_len; 2475a8e1175bSopenharmony_ci 2476a8e1175bSopenharmony_ci sa_len = 0; 2477a8e1175bSopenharmony_ci 2478a8e1175bSopenharmony_ci /* 2479a8e1175bSopenharmony_ci * Add signature_algorithms for verify (TLS 1.2) 2480a8e1175bSopenharmony_ci * 2481a8e1175bSopenharmony_ci * SignatureAndHashAlgorithm supported_signature_algorithms<2..2^16-2>; 2482a8e1175bSopenharmony_ci * 2483a8e1175bSopenharmony_ci * struct { 2484a8e1175bSopenharmony_ci * HashAlgorithm hash; 2485a8e1175bSopenharmony_ci * SignatureAlgorithm signature; 2486a8e1175bSopenharmony_ci * } SignatureAndHashAlgorithm; 2487a8e1175bSopenharmony_ci * 2488a8e1175bSopenharmony_ci * enum { (255) } HashAlgorithm; 2489a8e1175bSopenharmony_ci * enum { (255) } SignatureAlgorithm; 2490a8e1175bSopenharmony_ci */ 2491a8e1175bSopenharmony_ci const uint16_t *sig_alg = mbedtls_ssl_get_sig_algs(ssl); 2492a8e1175bSopenharmony_ci if (sig_alg == NULL) { 2493a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BAD_CONFIG; 2494a8e1175bSopenharmony_ci } 2495a8e1175bSopenharmony_ci 2496a8e1175bSopenharmony_ci for (; *sig_alg != MBEDTLS_TLS_SIG_NONE; sig_alg++) { 2497a8e1175bSopenharmony_ci unsigned char hash = MBEDTLS_BYTE_1(*sig_alg); 2498a8e1175bSopenharmony_ci 2499a8e1175bSopenharmony_ci if (mbedtls_ssl_set_calc_verify_md(ssl, hash)) { 2500a8e1175bSopenharmony_ci continue; 2501a8e1175bSopenharmony_ci } 2502a8e1175bSopenharmony_ci if (!mbedtls_ssl_sig_alg_is_supported(ssl, *sig_alg)) { 2503a8e1175bSopenharmony_ci continue; 2504a8e1175bSopenharmony_ci } 2505a8e1175bSopenharmony_ci 2506a8e1175bSopenharmony_ci /* Write elements at offsets starting from 1 (offset 0 is for the 2507a8e1175bSopenharmony_ci * length). Thus the offset of each element is the length of the 2508a8e1175bSopenharmony_ci * partial list including that element. */ 2509a8e1175bSopenharmony_ci sa_len += 2; 2510a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(*sig_alg, p, sa_len); 2511a8e1175bSopenharmony_ci 2512a8e1175bSopenharmony_ci } 2513a8e1175bSopenharmony_ci 2514a8e1175bSopenharmony_ci /* Fill in list length. */ 2515a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(sa_len, p, 0); 2516a8e1175bSopenharmony_ci sa_len += 2; 2517a8e1175bSopenharmony_ci p += sa_len; 2518a8e1175bSopenharmony_ci 2519a8e1175bSopenharmony_ci /* 2520a8e1175bSopenharmony_ci * DistinguishedName certificate_authorities<0..2^16-1>; 2521a8e1175bSopenharmony_ci * opaque DistinguishedName<1..2^16-1>; 2522a8e1175bSopenharmony_ci */ 2523a8e1175bSopenharmony_ci p += 2; 2524a8e1175bSopenharmony_ci 2525a8e1175bSopenharmony_ci total_dn_size = 0; 2526a8e1175bSopenharmony_ci 2527a8e1175bSopenharmony_ci if (ssl->conf->cert_req_ca_list == MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED) { 2528a8e1175bSopenharmony_ci /* NOTE: If trusted certificates are provisioned 2529a8e1175bSopenharmony_ci * via a CA callback (configured through 2530a8e1175bSopenharmony_ci * `mbedtls_ssl_conf_ca_cb()`, then the 2531a8e1175bSopenharmony_ci * CertificateRequest is currently left empty. */ 2532a8e1175bSopenharmony_ci 2533a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) 2534a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) 2535a8e1175bSopenharmony_ci if (ssl->handshake->dn_hints != NULL) { 2536a8e1175bSopenharmony_ci crt = ssl->handshake->dn_hints; 2537a8e1175bSopenharmony_ci } else 2538a8e1175bSopenharmony_ci#endif 2539a8e1175bSopenharmony_ci if (ssl->conf->dn_hints != NULL) { 2540a8e1175bSopenharmony_ci crt = ssl->conf->dn_hints; 2541a8e1175bSopenharmony_ci } else 2542a8e1175bSopenharmony_ci#endif 2543a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) 2544a8e1175bSopenharmony_ci if (ssl->handshake->sni_ca_chain != NULL) { 2545a8e1175bSopenharmony_ci crt = ssl->handshake->sni_ca_chain; 2546a8e1175bSopenharmony_ci } else 2547a8e1175bSopenharmony_ci#endif 2548a8e1175bSopenharmony_ci crt = ssl->conf->ca_chain; 2549a8e1175bSopenharmony_ci 2550a8e1175bSopenharmony_ci while (crt != NULL && crt->version != 0) { 2551a8e1175bSopenharmony_ci /* It follows from RFC 5280 A.1 that this length 2552a8e1175bSopenharmony_ci * can be represented in at most 11 bits. */ 2553a8e1175bSopenharmony_ci dn_size = (uint16_t) crt->subject_raw.len; 2554a8e1175bSopenharmony_ci 2555a8e1175bSopenharmony_ci if (end < p || (size_t) (end - p) < 2 + (size_t) dn_size) { 2556a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("skipping CAs: buffer too short")); 2557a8e1175bSopenharmony_ci break; 2558a8e1175bSopenharmony_ci } 2559a8e1175bSopenharmony_ci 2560a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(dn_size, p, 0); 2561a8e1175bSopenharmony_ci p += 2; 2562a8e1175bSopenharmony_ci memcpy(p, crt->subject_raw.p, dn_size); 2563a8e1175bSopenharmony_ci p += dn_size; 2564a8e1175bSopenharmony_ci 2565a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "requested DN", p - dn_size, dn_size); 2566a8e1175bSopenharmony_ci 2567a8e1175bSopenharmony_ci total_dn_size += (unsigned short) (2 + dn_size); 2568a8e1175bSopenharmony_ci crt = crt->next; 2569a8e1175bSopenharmony_ci } 2570a8e1175bSopenharmony_ci } 2571a8e1175bSopenharmony_ci 2572a8e1175bSopenharmony_ci ssl->out_msglen = (size_t) (p - buf); 2573a8e1175bSopenharmony_ci ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; 2574a8e1175bSopenharmony_ci ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_REQUEST; 2575a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(total_dn_size, ssl->out_msg, 4 + ct_len + sa_len); 2576a8e1175bSopenharmony_ci 2577a8e1175bSopenharmony_ci ret = mbedtls_ssl_write_handshake_msg(ssl); 2578a8e1175bSopenharmony_ci 2579a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= write certificate request")); 2580a8e1175bSopenharmony_ci 2581a8e1175bSopenharmony_ci return ret; 2582a8e1175bSopenharmony_ci} 2583a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ 2584a8e1175bSopenharmony_ci 2585a8e1175bSopenharmony_ci#if (defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ 2586a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)) 2587a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 2588a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 2589a8e1175bSopenharmony_cistatic int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl) 2590a8e1175bSopenharmony_ci{ 2591a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 2592a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2593a8e1175bSopenharmony_ci mbedtls_pk_context *pk; 2594a8e1175bSopenharmony_ci mbedtls_pk_type_t pk_type; 2595a8e1175bSopenharmony_ci psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT; 2596a8e1175bSopenharmony_ci unsigned char buf[PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(PSA_VENDOR_ECC_MAX_CURVE_BITS)]; 2597a8e1175bSopenharmony_ci size_t key_len; 2598a8e1175bSopenharmony_ci#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA) 2599a8e1175bSopenharmony_ci uint16_t tls_id = 0; 2600a8e1175bSopenharmony_ci psa_key_type_t key_type = PSA_KEY_TYPE_NONE; 2601a8e1175bSopenharmony_ci mbedtls_ecp_group_id grp_id; 2602a8e1175bSopenharmony_ci mbedtls_ecp_keypair *key; 2603a8e1175bSopenharmony_ci#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */ 2604a8e1175bSopenharmony_ci 2605a8e1175bSopenharmony_ci pk = mbedtls_ssl_own_key(ssl); 2606a8e1175bSopenharmony_ci 2607a8e1175bSopenharmony_ci if (pk == NULL) { 2608a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 2609a8e1175bSopenharmony_ci } 2610a8e1175bSopenharmony_ci 2611a8e1175bSopenharmony_ci pk_type = mbedtls_pk_get_type(pk); 2612a8e1175bSopenharmony_ci 2613a8e1175bSopenharmony_ci switch (pk_type) { 2614a8e1175bSopenharmony_ci case MBEDTLS_PK_OPAQUE: 2615a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 2616a8e1175bSopenharmony_ci case MBEDTLS_PK_ECKEY: 2617a8e1175bSopenharmony_ci case MBEDTLS_PK_ECKEY_DH: 2618a8e1175bSopenharmony_ci case MBEDTLS_PK_ECDSA: 2619a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ 2620a8e1175bSopenharmony_ci if (!mbedtls_pk_can_do(pk, MBEDTLS_PK_ECKEY)) { 2621a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; 2622a8e1175bSopenharmony_ci } 2623a8e1175bSopenharmony_ci 2624a8e1175bSopenharmony_ci /* Get the attributes of the key previously parsed by PK module in 2625a8e1175bSopenharmony_ci * order to extract its type and length (in bits). */ 2626a8e1175bSopenharmony_ci status = psa_get_key_attributes(pk->priv_id, &key_attributes); 2627a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 2628a8e1175bSopenharmony_ci ret = PSA_TO_MBEDTLS_ERR(status); 2629a8e1175bSopenharmony_ci goto exit; 2630a8e1175bSopenharmony_ci } 2631a8e1175bSopenharmony_ci ssl->handshake->xxdh_psa_type = psa_get_key_type(&key_attributes); 2632a8e1175bSopenharmony_ci ssl->handshake->xxdh_psa_bits = psa_get_key_bits(&key_attributes); 2633a8e1175bSopenharmony_ci 2634a8e1175bSopenharmony_ci if (pk_type == MBEDTLS_PK_OPAQUE) { 2635a8e1175bSopenharmony_ci /* Opaque key is created by the user (externally from Mbed TLS) 2636a8e1175bSopenharmony_ci * so we assume it already has the right algorithm and flags 2637a8e1175bSopenharmony_ci * set. Just copy its ID as reference. */ 2638a8e1175bSopenharmony_ci ssl->handshake->xxdh_psa_privkey = pk->priv_id; 2639a8e1175bSopenharmony_ci ssl->handshake->xxdh_psa_privkey_is_external = 1; 2640a8e1175bSopenharmony_ci } else { 2641a8e1175bSopenharmony_ci /* PK_ECKEY[_DH] and PK_ECDSA instead as parsed from the PK 2642a8e1175bSopenharmony_ci * module and only have ECDSA capabilities. Since we need 2643a8e1175bSopenharmony_ci * them for ECDH later, we export and then re-import them with 2644a8e1175bSopenharmony_ci * proper flags and algorithm. Of course We also set key's type 2645a8e1175bSopenharmony_ci * and bits that we just got above. */ 2646a8e1175bSopenharmony_ci key_attributes = psa_key_attributes_init(); 2647a8e1175bSopenharmony_ci psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); 2648a8e1175bSopenharmony_ci psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); 2649a8e1175bSopenharmony_ci psa_set_key_type(&key_attributes, 2650a8e1175bSopenharmony_ci PSA_KEY_TYPE_ECC_KEY_PAIR(ssl->handshake->xxdh_psa_type)); 2651a8e1175bSopenharmony_ci psa_set_key_bits(&key_attributes, ssl->handshake->xxdh_psa_bits); 2652a8e1175bSopenharmony_ci 2653a8e1175bSopenharmony_ci status = psa_export_key(pk->priv_id, buf, sizeof(buf), &key_len); 2654a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 2655a8e1175bSopenharmony_ci ret = PSA_TO_MBEDTLS_ERR(status); 2656a8e1175bSopenharmony_ci goto exit; 2657a8e1175bSopenharmony_ci } 2658a8e1175bSopenharmony_ci status = psa_import_key(&key_attributes, buf, key_len, 2659a8e1175bSopenharmony_ci &ssl->handshake->xxdh_psa_privkey); 2660a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 2661a8e1175bSopenharmony_ci ret = PSA_TO_MBEDTLS_ERR(status); 2662a8e1175bSopenharmony_ci goto exit; 2663a8e1175bSopenharmony_ci } 2664a8e1175bSopenharmony_ci 2665a8e1175bSopenharmony_ci /* Set this key as owned by the TLS library: it will be its duty 2666a8e1175bSopenharmony_ci * to clear it exit. */ 2667a8e1175bSopenharmony_ci ssl->handshake->xxdh_psa_privkey_is_external = 0; 2668a8e1175bSopenharmony_ci } 2669a8e1175bSopenharmony_ci 2670a8e1175bSopenharmony_ci ret = 0; 2671a8e1175bSopenharmony_ci break; 2672a8e1175bSopenharmony_ci#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA) 2673a8e1175bSopenharmony_ci case MBEDTLS_PK_ECKEY: 2674a8e1175bSopenharmony_ci case MBEDTLS_PK_ECKEY_DH: 2675a8e1175bSopenharmony_ci case MBEDTLS_PK_ECDSA: 2676a8e1175bSopenharmony_ci key = mbedtls_pk_ec_rw(*pk); 2677a8e1175bSopenharmony_ci grp_id = mbedtls_pk_get_ec_group_id(pk); 2678a8e1175bSopenharmony_ci if (grp_id == MBEDTLS_ECP_DP_NONE) { 2679a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 2680a8e1175bSopenharmony_ci } 2681a8e1175bSopenharmony_ci tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id); 2682a8e1175bSopenharmony_ci if (tls_id == 0) { 2683a8e1175bSopenharmony_ci /* This elliptic curve is not supported */ 2684a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 2685a8e1175bSopenharmony_ci } 2686a8e1175bSopenharmony_ci 2687a8e1175bSopenharmony_ci /* If the above conversion to TLS ID was fine, then also this one will 2688a8e1175bSopenharmony_ci be, so there is no need to check the return value here */ 2689a8e1175bSopenharmony_ci mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id, &key_type, 2690a8e1175bSopenharmony_ci &ssl->handshake->xxdh_psa_bits); 2691a8e1175bSopenharmony_ci 2692a8e1175bSopenharmony_ci ssl->handshake->xxdh_psa_type = key_type; 2693a8e1175bSopenharmony_ci 2694a8e1175bSopenharmony_ci key_attributes = psa_key_attributes_init(); 2695a8e1175bSopenharmony_ci psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); 2696a8e1175bSopenharmony_ci psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); 2697a8e1175bSopenharmony_ci psa_set_key_type(&key_attributes, 2698a8e1175bSopenharmony_ci PSA_KEY_TYPE_ECC_KEY_PAIR(ssl->handshake->xxdh_psa_type)); 2699a8e1175bSopenharmony_ci psa_set_key_bits(&key_attributes, ssl->handshake->xxdh_psa_bits); 2700a8e1175bSopenharmony_ci 2701a8e1175bSopenharmony_ci ret = mbedtls_ecp_write_key_ext(key, &key_len, buf, sizeof(buf)); 2702a8e1175bSopenharmony_ci if (ret != 0) { 2703a8e1175bSopenharmony_ci mbedtls_platform_zeroize(buf, sizeof(buf)); 2704a8e1175bSopenharmony_ci break; 2705a8e1175bSopenharmony_ci } 2706a8e1175bSopenharmony_ci 2707a8e1175bSopenharmony_ci status = psa_import_key(&key_attributes, buf, key_len, 2708a8e1175bSopenharmony_ci &ssl->handshake->xxdh_psa_privkey); 2709a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 2710a8e1175bSopenharmony_ci ret = PSA_TO_MBEDTLS_ERR(status); 2711a8e1175bSopenharmony_ci mbedtls_platform_zeroize(buf, sizeof(buf)); 2712a8e1175bSopenharmony_ci break; 2713a8e1175bSopenharmony_ci } 2714a8e1175bSopenharmony_ci 2715a8e1175bSopenharmony_ci mbedtls_platform_zeroize(buf, sizeof(buf)); 2716a8e1175bSopenharmony_ci ret = 0; 2717a8e1175bSopenharmony_ci break; 2718a8e1175bSopenharmony_ci#endif /* !MBEDTLS_PK_USE_PSA_EC_DATA */ 2719a8e1175bSopenharmony_ci default: 2720a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; 2721a8e1175bSopenharmony_ci } 2722a8e1175bSopenharmony_ci 2723a8e1175bSopenharmony_ciexit: 2724a8e1175bSopenharmony_ci psa_reset_key_attributes(&key_attributes); 2725a8e1175bSopenharmony_ci mbedtls_platform_zeroize(buf, sizeof(buf)); 2726a8e1175bSopenharmony_ci 2727a8e1175bSopenharmony_ci return ret; 2728a8e1175bSopenharmony_ci} 2729a8e1175bSopenharmony_ci#else /* MBEDTLS_USE_PSA_CRYPTO */ 2730a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 2731a8e1175bSopenharmony_cistatic int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl) 2732a8e1175bSopenharmony_ci{ 2733a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 2734a8e1175bSopenharmony_ci 2735a8e1175bSopenharmony_ci const mbedtls_pk_context *private_key = mbedtls_ssl_own_key(ssl); 2736a8e1175bSopenharmony_ci if (private_key == NULL) { 2737a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("got no server private key")); 2738a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED; 2739a8e1175bSopenharmony_ci } 2740a8e1175bSopenharmony_ci 2741a8e1175bSopenharmony_ci if (!mbedtls_pk_can_do(private_key, MBEDTLS_PK_ECKEY)) { 2742a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("server key not ECDH capable")); 2743a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; 2744a8e1175bSopenharmony_ci } 2745a8e1175bSopenharmony_ci 2746a8e1175bSopenharmony_ci if ((ret = mbedtls_ecdh_get_params(&ssl->handshake->ecdh_ctx, 2747a8e1175bSopenharmony_ci mbedtls_pk_ec_ro(*mbedtls_ssl_own_key(ssl)), 2748a8e1175bSopenharmony_ci MBEDTLS_ECDH_OURS)) != 0) { 2749a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_get_params"), ret); 2750a8e1175bSopenharmony_ci return ret; 2751a8e1175bSopenharmony_ci } 2752a8e1175bSopenharmony_ci 2753a8e1175bSopenharmony_ci return 0; 2754a8e1175bSopenharmony_ci} 2755a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 2756a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || 2757a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ 2758a8e1175bSopenharmony_ci 2759a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \ 2760a8e1175bSopenharmony_ci defined(MBEDTLS_SSL_ASYNC_PRIVATE) 2761a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 2762a8e1175bSopenharmony_cistatic int ssl_resume_server_key_exchange(mbedtls_ssl_context *ssl, 2763a8e1175bSopenharmony_ci size_t *signature_len) 2764a8e1175bSopenharmony_ci{ 2765a8e1175bSopenharmony_ci /* Append the signature to ssl->out_msg, leaving 2 bytes for the 2766a8e1175bSopenharmony_ci * signature length which will be added in ssl_write_server_key_exchange 2767a8e1175bSopenharmony_ci * after the call to ssl_prepare_server_key_exchange. 2768a8e1175bSopenharmony_ci * ssl_write_server_key_exchange also takes care of incrementing 2769a8e1175bSopenharmony_ci * ssl->out_msglen. */ 2770a8e1175bSopenharmony_ci unsigned char *sig_start = ssl->out_msg + ssl->out_msglen + 2; 2771a8e1175bSopenharmony_ci size_t sig_max_len = (ssl->out_buf + MBEDTLS_SSL_OUT_CONTENT_LEN 2772a8e1175bSopenharmony_ci - sig_start); 2773a8e1175bSopenharmony_ci int ret = ssl->conf->f_async_resume(ssl, 2774a8e1175bSopenharmony_ci sig_start, signature_len, sig_max_len); 2775a8e1175bSopenharmony_ci if (ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) { 2776a8e1175bSopenharmony_ci ssl->handshake->async_in_progress = 0; 2777a8e1175bSopenharmony_ci mbedtls_ssl_set_async_operation_data(ssl, NULL); 2778a8e1175bSopenharmony_ci } 2779a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(2, "ssl_resume_server_key_exchange", ret); 2780a8e1175bSopenharmony_ci return ret; 2781a8e1175bSopenharmony_ci} 2782a8e1175bSopenharmony_ci#endif /* defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && 2783a8e1175bSopenharmony_ci defined(MBEDTLS_SSL_ASYNC_PRIVATE) */ 2784a8e1175bSopenharmony_ci 2785a8e1175bSopenharmony_ci/* Prepare the ServerKeyExchange message, up to and including 2786a8e1175bSopenharmony_ci * calculating the signature if any, but excluding formatting the 2787a8e1175bSopenharmony_ci * signature and sending the message. */ 2788a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 2789a8e1175bSopenharmony_cistatic int ssl_prepare_server_key_exchange(mbedtls_ssl_context *ssl, 2790a8e1175bSopenharmony_ci size_t *signature_len) 2791a8e1175bSopenharmony_ci{ 2792a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 2793a8e1175bSopenharmony_ci ssl->handshake->ciphersuite_info; 2794a8e1175bSopenharmony_ci 2795a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED) 2796a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) 2797a8e1175bSopenharmony_ci unsigned char *dig_signed = NULL; 2798a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ 2799a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED */ 2800a8e1175bSopenharmony_ci 2801a8e1175bSopenharmony_ci (void) ciphersuite_info; /* unused in some configurations */ 2802a8e1175bSopenharmony_ci#if !defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) 2803a8e1175bSopenharmony_ci (void) signature_len; 2804a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ 2805a8e1175bSopenharmony_ci 2806a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) 2807a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 2808a8e1175bSopenharmony_ci size_t out_buf_len = ssl->out_buf_len - (size_t) (ssl->out_msg - ssl->out_buf); 2809a8e1175bSopenharmony_ci#else 2810a8e1175bSopenharmony_ci size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - (size_t) (ssl->out_msg - ssl->out_buf); 2811a8e1175bSopenharmony_ci#endif 2812a8e1175bSopenharmony_ci#endif 2813a8e1175bSopenharmony_ci 2814a8e1175bSopenharmony_ci ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */ 2815a8e1175bSopenharmony_ci 2816a8e1175bSopenharmony_ci /* 2817a8e1175bSopenharmony_ci * 2818a8e1175bSopenharmony_ci * Part 1: Provide key exchange parameters for chosen ciphersuite. 2819a8e1175bSopenharmony_ci * 2820a8e1175bSopenharmony_ci */ 2821a8e1175bSopenharmony_ci 2822a8e1175bSopenharmony_ci /* 2823a8e1175bSopenharmony_ci * - ECJPAKE key exchanges 2824a8e1175bSopenharmony_ci */ 2825a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 2826a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) { 2827a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 2828a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 2829a8e1175bSopenharmony_ci unsigned char *out_p = ssl->out_msg + ssl->out_msglen; 2830a8e1175bSopenharmony_ci unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN - 2831a8e1175bSopenharmony_ci ssl->out_msglen; 2832a8e1175bSopenharmony_ci size_t output_offset = 0; 2833a8e1175bSopenharmony_ci size_t output_len = 0; 2834a8e1175bSopenharmony_ci 2835a8e1175bSopenharmony_ci /* 2836a8e1175bSopenharmony_ci * The first 3 bytes are: 2837a8e1175bSopenharmony_ci * [0] MBEDTLS_ECP_TLS_NAMED_CURVE 2838a8e1175bSopenharmony_ci * [1, 2] elliptic curve's TLS ID 2839a8e1175bSopenharmony_ci * 2840a8e1175bSopenharmony_ci * However since we only support secp256r1 for now, we hardcode its 2841a8e1175bSopenharmony_ci * TLS ID here 2842a8e1175bSopenharmony_ci */ 2843a8e1175bSopenharmony_ci uint16_t tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id( 2844a8e1175bSopenharmony_ci MBEDTLS_ECP_DP_SECP256R1); 2845a8e1175bSopenharmony_ci if (tls_id == 0) { 2846a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 2847a8e1175bSopenharmony_ci } 2848a8e1175bSopenharmony_ci *out_p = MBEDTLS_ECP_TLS_NAMED_CURVE; 2849a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(tls_id, out_p, 1); 2850a8e1175bSopenharmony_ci output_offset += 3; 2851a8e1175bSopenharmony_ci 2852a8e1175bSopenharmony_ci ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx, 2853a8e1175bSopenharmony_ci out_p + output_offset, 2854a8e1175bSopenharmony_ci end_p - out_p - output_offset, &output_len, 2855a8e1175bSopenharmony_ci MBEDTLS_ECJPAKE_ROUND_TWO); 2856a8e1175bSopenharmony_ci if (ret != 0) { 2857a8e1175bSopenharmony_ci psa_destroy_key(ssl->handshake->psa_pake_password); 2858a8e1175bSopenharmony_ci psa_pake_abort(&ssl->handshake->psa_pake_ctx); 2859a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret); 2860a8e1175bSopenharmony_ci return ret; 2861a8e1175bSopenharmony_ci } 2862a8e1175bSopenharmony_ci 2863a8e1175bSopenharmony_ci output_offset += output_len; 2864a8e1175bSopenharmony_ci ssl->out_msglen += output_offset; 2865a8e1175bSopenharmony_ci#else 2866a8e1175bSopenharmony_ci size_t len = 0; 2867a8e1175bSopenharmony_ci 2868a8e1175bSopenharmony_ci ret = mbedtls_ecjpake_write_round_two( 2869a8e1175bSopenharmony_ci &ssl->handshake->ecjpake_ctx, 2870a8e1175bSopenharmony_ci ssl->out_msg + ssl->out_msglen, 2871a8e1175bSopenharmony_ci MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, &len, 2872a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng); 2873a8e1175bSopenharmony_ci if (ret != 0) { 2874a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_two", ret); 2875a8e1175bSopenharmony_ci return ret; 2876a8e1175bSopenharmony_ci } 2877a8e1175bSopenharmony_ci 2878a8e1175bSopenharmony_ci ssl->out_msglen += len; 2879a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 2880a8e1175bSopenharmony_ci } 2881a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 2882a8e1175bSopenharmony_ci 2883a8e1175bSopenharmony_ci /* 2884a8e1175bSopenharmony_ci * For (EC)DHE key exchanges with PSK, parameters are prefixed by support 2885a8e1175bSopenharmony_ci * identity hint (RFC 4279, Sec. 3). Until someone needs this feature, 2886a8e1175bSopenharmony_ci * we use empty support identity hints here. 2887a8e1175bSopenharmony_ci **/ 2888a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ 2889a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) 2890a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || 2891a8e1175bSopenharmony_ci ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) { 2892a8e1175bSopenharmony_ci ssl->out_msg[ssl->out_msglen++] = 0x00; 2893a8e1175bSopenharmony_ci ssl->out_msg[ssl->out_msglen++] = 0x00; 2894a8e1175bSopenharmony_ci } 2895a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED || 2896a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ 2897a8e1175bSopenharmony_ci 2898a8e1175bSopenharmony_ci /* 2899a8e1175bSopenharmony_ci * - DHE key exchanges 2900a8e1175bSopenharmony_ci */ 2901a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED) 2902a8e1175bSopenharmony_ci if (mbedtls_ssl_ciphersuite_uses_dhe(ciphersuite_info)) { 2903a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 2904a8e1175bSopenharmony_ci size_t len = 0; 2905a8e1175bSopenharmony_ci 2906a8e1175bSopenharmony_ci if (ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL) { 2907a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("no DH parameters set")); 2908a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 2909a8e1175bSopenharmony_ci } 2910a8e1175bSopenharmony_ci 2911a8e1175bSopenharmony_ci /* 2912a8e1175bSopenharmony_ci * Ephemeral DH parameters: 2913a8e1175bSopenharmony_ci * 2914a8e1175bSopenharmony_ci * struct { 2915a8e1175bSopenharmony_ci * opaque dh_p<1..2^16-1>; 2916a8e1175bSopenharmony_ci * opaque dh_g<1..2^16-1>; 2917a8e1175bSopenharmony_ci * opaque dh_Ys<1..2^16-1>; 2918a8e1175bSopenharmony_ci * } ServerDHParams; 2919a8e1175bSopenharmony_ci */ 2920a8e1175bSopenharmony_ci if ((ret = mbedtls_dhm_set_group(&ssl->handshake->dhm_ctx, 2921a8e1175bSopenharmony_ci &ssl->conf->dhm_P, 2922a8e1175bSopenharmony_ci &ssl->conf->dhm_G)) != 0) { 2923a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_set_group", ret); 2924a8e1175bSopenharmony_ci return ret; 2925a8e1175bSopenharmony_ci } 2926a8e1175bSopenharmony_ci 2927a8e1175bSopenharmony_ci if ((ret = mbedtls_dhm_make_params( 2928a8e1175bSopenharmony_ci &ssl->handshake->dhm_ctx, 2929a8e1175bSopenharmony_ci (int) mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx), 2930a8e1175bSopenharmony_ci ssl->out_msg + ssl->out_msglen, &len, 2931a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { 2932a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_make_params", ret); 2933a8e1175bSopenharmony_ci return ret; 2934a8e1175bSopenharmony_ci } 2935a8e1175bSopenharmony_ci 2936a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) 2937a8e1175bSopenharmony_ci dig_signed = ssl->out_msg + ssl->out_msglen; 2938a8e1175bSopenharmony_ci#endif 2939a8e1175bSopenharmony_ci 2940a8e1175bSopenharmony_ci ssl->out_msglen += len; 2941a8e1175bSopenharmony_ci 2942a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MPI(3, "DHM: X ", &ssl->handshake->dhm_ctx.X); 2943a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MPI(3, "DHM: P ", &ssl->handshake->dhm_ctx.P); 2944a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MPI(3, "DHM: G ", &ssl->handshake->dhm_ctx.G); 2945a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GX", &ssl->handshake->dhm_ctx.GX); 2946a8e1175bSopenharmony_ci } 2947a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED */ 2948a8e1175bSopenharmony_ci 2949a8e1175bSopenharmony_ci /* 2950a8e1175bSopenharmony_ci * - ECDHE key exchanges 2951a8e1175bSopenharmony_ci */ 2952a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) 2953a8e1175bSopenharmony_ci if (mbedtls_ssl_ciphersuite_uses_ecdhe(ciphersuite_info)) { 2954a8e1175bSopenharmony_ci /* 2955a8e1175bSopenharmony_ci * Ephemeral ECDH parameters: 2956a8e1175bSopenharmony_ci * 2957a8e1175bSopenharmony_ci * struct { 2958a8e1175bSopenharmony_ci * ECParameters curve_params; 2959a8e1175bSopenharmony_ci * ECPoint public; 2960a8e1175bSopenharmony_ci * } ServerECDHParams; 2961a8e1175bSopenharmony_ci */ 2962a8e1175bSopenharmony_ci uint16_t *curr_tls_id = ssl->handshake->curves_tls_id; 2963a8e1175bSopenharmony_ci const uint16_t *group_list = mbedtls_ssl_get_groups(ssl); 2964a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 2965a8e1175bSopenharmony_ci size_t len = 0; 2966a8e1175bSopenharmony_ci 2967a8e1175bSopenharmony_ci /* Match our preference list against the offered curves */ 2968a8e1175bSopenharmony_ci if ((group_list == NULL) || (curr_tls_id == NULL)) { 2969a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BAD_CONFIG; 2970a8e1175bSopenharmony_ci } 2971a8e1175bSopenharmony_ci for (; *group_list != 0; group_list++) { 2972a8e1175bSopenharmony_ci for (curr_tls_id = ssl->handshake->curves_tls_id; 2973a8e1175bSopenharmony_ci *curr_tls_id != 0; curr_tls_id++) { 2974a8e1175bSopenharmony_ci if (*curr_tls_id == *group_list) { 2975a8e1175bSopenharmony_ci goto curve_matching_done; 2976a8e1175bSopenharmony_ci } 2977a8e1175bSopenharmony_ci } 2978a8e1175bSopenharmony_ci } 2979a8e1175bSopenharmony_ci 2980a8e1175bSopenharmony_cicurve_matching_done: 2981a8e1175bSopenharmony_ci if (*curr_tls_id == 0) { 2982a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("no matching curve for ECDHE")); 2983a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 2984a8e1175bSopenharmony_ci } 2985a8e1175bSopenharmony_ci 2986a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("ECDHE curve: %s", 2987a8e1175bSopenharmony_ci mbedtls_ssl_get_curve_name_from_tls_id(*curr_tls_id))); 2988a8e1175bSopenharmony_ci 2989a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 2990a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_GENERIC_ERROR; 2991a8e1175bSopenharmony_ci psa_key_attributes_t key_attributes; 2992a8e1175bSopenharmony_ci mbedtls_ssl_handshake_params *handshake = ssl->handshake; 2993a8e1175bSopenharmony_ci uint8_t *p = ssl->out_msg + ssl->out_msglen; 2994a8e1175bSopenharmony_ci const size_t header_size = 4; // curve_type(1), namedcurve(2), 2995a8e1175bSopenharmony_ci // data length(1) 2996a8e1175bSopenharmony_ci const size_t data_length_size = 1; 2997a8e1175bSopenharmony_ci psa_key_type_t key_type = PSA_KEY_TYPE_NONE; 2998a8e1175bSopenharmony_ci size_t ec_bits = 0; 2999a8e1175bSopenharmony_ci 3000a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("Perform PSA-based ECDH computation.")); 3001a8e1175bSopenharmony_ci 3002a8e1175bSopenharmony_ci /* Convert EC's TLS ID to PSA key type. */ 3003a8e1175bSopenharmony_ci if (mbedtls_ssl_get_psa_curve_info_from_tls_id(*curr_tls_id, 3004a8e1175bSopenharmony_ci &key_type, 3005a8e1175bSopenharmony_ci &ec_bits) == PSA_ERROR_NOT_SUPPORTED) { 3006a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid ecc group parse.")); 3007a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 3008a8e1175bSopenharmony_ci } 3009a8e1175bSopenharmony_ci handshake->xxdh_psa_type = key_type; 3010a8e1175bSopenharmony_ci handshake->xxdh_psa_bits = ec_bits; 3011a8e1175bSopenharmony_ci 3012a8e1175bSopenharmony_ci key_attributes = psa_key_attributes_init(); 3013a8e1175bSopenharmony_ci psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); 3014a8e1175bSopenharmony_ci psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); 3015a8e1175bSopenharmony_ci psa_set_key_type(&key_attributes, handshake->xxdh_psa_type); 3016a8e1175bSopenharmony_ci psa_set_key_bits(&key_attributes, handshake->xxdh_psa_bits); 3017a8e1175bSopenharmony_ci 3018a8e1175bSopenharmony_ci /* 3019a8e1175bSopenharmony_ci * ECParameters curve_params 3020a8e1175bSopenharmony_ci * 3021a8e1175bSopenharmony_ci * First byte is curve_type, always named_curve 3022a8e1175bSopenharmony_ci */ 3023a8e1175bSopenharmony_ci *p++ = MBEDTLS_ECP_TLS_NAMED_CURVE; 3024a8e1175bSopenharmony_ci 3025a8e1175bSopenharmony_ci /* 3026a8e1175bSopenharmony_ci * Next two bytes are the namedcurve value 3027a8e1175bSopenharmony_ci */ 3028a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(*curr_tls_id, p, 0); 3029a8e1175bSopenharmony_ci p += 2; 3030a8e1175bSopenharmony_ci 3031a8e1175bSopenharmony_ci /* Generate ECDH private key. */ 3032a8e1175bSopenharmony_ci status = psa_generate_key(&key_attributes, 3033a8e1175bSopenharmony_ci &handshake->xxdh_psa_privkey); 3034a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 3035a8e1175bSopenharmony_ci ret = PSA_TO_MBEDTLS_ERR(status); 3036a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "psa_generate_key", ret); 3037a8e1175bSopenharmony_ci return ret; 3038a8e1175bSopenharmony_ci } 3039a8e1175bSopenharmony_ci 3040a8e1175bSopenharmony_ci /* 3041a8e1175bSopenharmony_ci * ECPoint public 3042a8e1175bSopenharmony_ci * 3043a8e1175bSopenharmony_ci * First byte is data length. 3044a8e1175bSopenharmony_ci * It will be filled later. p holds now the data length location. 3045a8e1175bSopenharmony_ci */ 3046a8e1175bSopenharmony_ci 3047a8e1175bSopenharmony_ci /* Export the public part of the ECDH private key from PSA. 3048a8e1175bSopenharmony_ci * Make one byte space for the length. 3049a8e1175bSopenharmony_ci */ 3050a8e1175bSopenharmony_ci unsigned char *own_pubkey = p + data_length_size; 3051a8e1175bSopenharmony_ci 3052a8e1175bSopenharmony_ci size_t own_pubkey_max_len = (size_t) (MBEDTLS_SSL_OUT_CONTENT_LEN 3053a8e1175bSopenharmony_ci - (own_pubkey - ssl->out_msg)); 3054a8e1175bSopenharmony_ci 3055a8e1175bSopenharmony_ci status = psa_export_public_key(handshake->xxdh_psa_privkey, 3056a8e1175bSopenharmony_ci own_pubkey, own_pubkey_max_len, 3057a8e1175bSopenharmony_ci &len); 3058a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 3059a8e1175bSopenharmony_ci ret = PSA_TO_MBEDTLS_ERR(status); 3060a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "psa_export_public_key", ret); 3061a8e1175bSopenharmony_ci (void) psa_destroy_key(handshake->xxdh_psa_privkey); 3062a8e1175bSopenharmony_ci handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; 3063a8e1175bSopenharmony_ci return ret; 3064a8e1175bSopenharmony_ci } 3065a8e1175bSopenharmony_ci 3066a8e1175bSopenharmony_ci /* Store the length of the exported public key. */ 3067a8e1175bSopenharmony_ci *p = (uint8_t) len; 3068a8e1175bSopenharmony_ci 3069a8e1175bSopenharmony_ci /* Determine full message length. */ 3070a8e1175bSopenharmony_ci len += header_size; 3071a8e1175bSopenharmony_ci#else 3072a8e1175bSopenharmony_ci mbedtls_ecp_group_id curr_grp_id = 3073a8e1175bSopenharmony_ci mbedtls_ssl_get_ecp_group_id_from_tls_id(*curr_tls_id); 3074a8e1175bSopenharmony_ci 3075a8e1175bSopenharmony_ci if ((ret = mbedtls_ecdh_setup(&ssl->handshake->ecdh_ctx, 3076a8e1175bSopenharmony_ci curr_grp_id)) != 0) { 3077a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecp_group_load", ret); 3078a8e1175bSopenharmony_ci return ret; 3079a8e1175bSopenharmony_ci } 3080a8e1175bSopenharmony_ci 3081a8e1175bSopenharmony_ci if ((ret = mbedtls_ecdh_make_params( 3082a8e1175bSopenharmony_ci &ssl->handshake->ecdh_ctx, &len, 3083a8e1175bSopenharmony_ci ssl->out_msg + ssl->out_msglen, 3084a8e1175bSopenharmony_ci MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, 3085a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { 3086a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_make_params", ret); 3087a8e1175bSopenharmony_ci return ret; 3088a8e1175bSopenharmony_ci } 3089a8e1175bSopenharmony_ci 3090a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, 3091a8e1175bSopenharmony_ci MBEDTLS_DEBUG_ECDH_Q); 3092a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 3093a8e1175bSopenharmony_ci 3094a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) 3095a8e1175bSopenharmony_ci dig_signed = ssl->out_msg + ssl->out_msglen; 3096a8e1175bSopenharmony_ci#endif 3097a8e1175bSopenharmony_ci 3098a8e1175bSopenharmony_ci ssl->out_msglen += len; 3099a8e1175bSopenharmony_ci } 3100a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED */ 3101a8e1175bSopenharmony_ci 3102a8e1175bSopenharmony_ci /* 3103a8e1175bSopenharmony_ci * 3104a8e1175bSopenharmony_ci * Part 2: For key exchanges involving the server signing the 3105a8e1175bSopenharmony_ci * exchange parameters, compute and add the signature here. 3106a8e1175bSopenharmony_ci * 3107a8e1175bSopenharmony_ci */ 3108a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) 3109a8e1175bSopenharmony_ci if (mbedtls_ssl_ciphersuite_uses_server_signature(ciphersuite_info)) { 3110a8e1175bSopenharmony_ci if (dig_signed == NULL) { 3111a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 3112a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 3113a8e1175bSopenharmony_ci } 3114a8e1175bSopenharmony_ci 3115a8e1175bSopenharmony_ci size_t dig_signed_len = (size_t) (ssl->out_msg + ssl->out_msglen - dig_signed); 3116a8e1175bSopenharmony_ci size_t hashlen = 0; 3117a8e1175bSopenharmony_ci unsigned char hash[MBEDTLS_MD_MAX_SIZE]; 3118a8e1175bSopenharmony_ci 3119a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 3120a8e1175bSopenharmony_ci 3121a8e1175bSopenharmony_ci /* 3122a8e1175bSopenharmony_ci * 2.1: Choose hash algorithm: 3123a8e1175bSopenharmony_ci * For TLS 1.2, obey signature-hash-algorithm extension 3124a8e1175bSopenharmony_ci * to choose appropriate hash. 3125a8e1175bSopenharmony_ci */ 3126a8e1175bSopenharmony_ci 3127a8e1175bSopenharmony_ci mbedtls_pk_type_t sig_alg = 3128a8e1175bSopenharmony_ci mbedtls_ssl_get_ciphersuite_sig_pk_alg(ciphersuite_info); 3129a8e1175bSopenharmony_ci 3130a8e1175bSopenharmony_ci unsigned char sig_hash = 3131a8e1175bSopenharmony_ci (unsigned char) mbedtls_ssl_tls12_get_preferred_hash_for_sig_alg( 3132a8e1175bSopenharmony_ci ssl, mbedtls_ssl_sig_from_pk_alg(sig_alg)); 3133a8e1175bSopenharmony_ci 3134a8e1175bSopenharmony_ci mbedtls_md_type_t md_alg = mbedtls_ssl_md_alg_from_hash(sig_hash); 3135a8e1175bSopenharmony_ci 3136a8e1175bSopenharmony_ci /* For TLS 1.2, obey signature-hash-algorithm extension 3137a8e1175bSopenharmony_ci * (RFC 5246, Sec. 7.4.1.4.1). */ 3138a8e1175bSopenharmony_ci if (sig_alg == MBEDTLS_PK_NONE || md_alg == MBEDTLS_MD_NONE) { 3139a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 3140a8e1175bSopenharmony_ci /* (... because we choose a cipher suite 3141a8e1175bSopenharmony_ci * only if there is a matching hash.) */ 3142a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 3143a8e1175bSopenharmony_ci } 3144a8e1175bSopenharmony_ci 3145a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("pick hash algorithm %u for signing", (unsigned) md_alg)); 3146a8e1175bSopenharmony_ci 3147a8e1175bSopenharmony_ci /* 3148a8e1175bSopenharmony_ci * 2.2: Compute the hash to be signed 3149a8e1175bSopenharmony_ci */ 3150a8e1175bSopenharmony_ci if (md_alg != MBEDTLS_MD_NONE) { 3151a8e1175bSopenharmony_ci ret = mbedtls_ssl_get_key_exchange_md_tls1_2(ssl, hash, &hashlen, 3152a8e1175bSopenharmony_ci dig_signed, 3153a8e1175bSopenharmony_ci dig_signed_len, 3154a8e1175bSopenharmony_ci md_alg); 3155a8e1175bSopenharmony_ci if (ret != 0) { 3156a8e1175bSopenharmony_ci return ret; 3157a8e1175bSopenharmony_ci } 3158a8e1175bSopenharmony_ci } else { 3159a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 3160a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 3161a8e1175bSopenharmony_ci } 3162a8e1175bSopenharmony_ci 3163a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "parameters hash", hash, hashlen); 3164a8e1175bSopenharmony_ci 3165a8e1175bSopenharmony_ci /* 3166a8e1175bSopenharmony_ci * 2.3: Compute and add the signature 3167a8e1175bSopenharmony_ci */ 3168a8e1175bSopenharmony_ci /* 3169a8e1175bSopenharmony_ci * We need to specify signature and hash algorithm explicitly through 3170a8e1175bSopenharmony_ci * a prefix to the signature. 3171a8e1175bSopenharmony_ci * 3172a8e1175bSopenharmony_ci * struct { 3173a8e1175bSopenharmony_ci * HashAlgorithm hash; 3174a8e1175bSopenharmony_ci * SignatureAlgorithm signature; 3175a8e1175bSopenharmony_ci * } SignatureAndHashAlgorithm; 3176a8e1175bSopenharmony_ci * 3177a8e1175bSopenharmony_ci * struct { 3178a8e1175bSopenharmony_ci * SignatureAndHashAlgorithm algorithm; 3179a8e1175bSopenharmony_ci * opaque signature<0..2^16-1>; 3180a8e1175bSopenharmony_ci * } DigitallySigned; 3181a8e1175bSopenharmony_ci * 3182a8e1175bSopenharmony_ci */ 3183a8e1175bSopenharmony_ci 3184a8e1175bSopenharmony_ci ssl->out_msg[ssl->out_msglen++] = mbedtls_ssl_hash_from_md_alg(md_alg); 3185a8e1175bSopenharmony_ci ssl->out_msg[ssl->out_msglen++] = mbedtls_ssl_sig_from_pk_alg(sig_alg); 3186a8e1175bSopenharmony_ci 3187a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) 3188a8e1175bSopenharmony_ci if (ssl->conf->f_async_sign_start != NULL) { 3189a8e1175bSopenharmony_ci ret = ssl->conf->f_async_sign_start(ssl, 3190a8e1175bSopenharmony_ci mbedtls_ssl_own_cert(ssl), 3191a8e1175bSopenharmony_ci md_alg, hash, hashlen); 3192a8e1175bSopenharmony_ci switch (ret) { 3193a8e1175bSopenharmony_ci case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH: 3194a8e1175bSopenharmony_ci /* act as if f_async_sign was null */ 3195a8e1175bSopenharmony_ci break; 3196a8e1175bSopenharmony_ci case 0: 3197a8e1175bSopenharmony_ci ssl->handshake->async_in_progress = 1; 3198a8e1175bSopenharmony_ci return ssl_resume_server_key_exchange(ssl, signature_len); 3199a8e1175bSopenharmony_ci case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: 3200a8e1175bSopenharmony_ci ssl->handshake->async_in_progress = 1; 3201a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS; 3202a8e1175bSopenharmony_ci default: 3203a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "f_async_sign_start", ret); 3204a8e1175bSopenharmony_ci return ret; 3205a8e1175bSopenharmony_ci } 3206a8e1175bSopenharmony_ci } 3207a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ 3208a8e1175bSopenharmony_ci 3209a8e1175bSopenharmony_ci if (mbedtls_ssl_own_key(ssl) == NULL) { 3210a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("got no private key")); 3211a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED; 3212a8e1175bSopenharmony_ci } 3213a8e1175bSopenharmony_ci 3214a8e1175bSopenharmony_ci /* Append the signature to ssl->out_msg, leaving 2 bytes for the 3215a8e1175bSopenharmony_ci * signature length which will be added in ssl_write_server_key_exchange 3216a8e1175bSopenharmony_ci * after the call to ssl_prepare_server_key_exchange. 3217a8e1175bSopenharmony_ci * ssl_write_server_key_exchange also takes care of incrementing 3218a8e1175bSopenharmony_ci * ssl->out_msglen. */ 3219a8e1175bSopenharmony_ci if ((ret = mbedtls_pk_sign(mbedtls_ssl_own_key(ssl), 3220a8e1175bSopenharmony_ci md_alg, hash, hashlen, 3221a8e1175bSopenharmony_ci ssl->out_msg + ssl->out_msglen + 2, 3222a8e1175bSopenharmony_ci out_buf_len - ssl->out_msglen - 2, 3223a8e1175bSopenharmony_ci signature_len, 3224a8e1175bSopenharmony_ci ssl->conf->f_rng, 3225a8e1175bSopenharmony_ci ssl->conf->p_rng)) != 0) { 3226a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_sign", ret); 3227a8e1175bSopenharmony_ci return ret; 3228a8e1175bSopenharmony_ci } 3229a8e1175bSopenharmony_ci } 3230a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ 3231a8e1175bSopenharmony_ci 3232a8e1175bSopenharmony_ci return 0; 3233a8e1175bSopenharmony_ci} 3234a8e1175bSopenharmony_ci 3235a8e1175bSopenharmony_ci/* Prepare the ServerKeyExchange message and send it. For ciphersuites 3236a8e1175bSopenharmony_ci * that do not include a ServerKeyExchange message, do nothing. Either 3237a8e1175bSopenharmony_ci * way, if successful, move on to the next step in the SSL state 3238a8e1175bSopenharmony_ci * machine. */ 3239a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 3240a8e1175bSopenharmony_cistatic int ssl_write_server_key_exchange(mbedtls_ssl_context *ssl) 3241a8e1175bSopenharmony_ci{ 3242a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 3243a8e1175bSopenharmony_ci size_t signature_len = 0; 3244a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED) 3245a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 3246a8e1175bSopenharmony_ci ssl->handshake->ciphersuite_info; 3247a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */ 3248a8e1175bSopenharmony_ci 3249a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server key exchange")); 3250a8e1175bSopenharmony_ci 3251a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED) 3252a8e1175bSopenharmony_ci /* Extract static ECDH parameters and abort if ServerKeyExchange 3253a8e1175bSopenharmony_ci * is not needed. */ 3254a8e1175bSopenharmony_ci if (mbedtls_ssl_ciphersuite_no_pfs(ciphersuite_info)) { 3255a8e1175bSopenharmony_ci /* For suites involving ECDH, extract DH parameters 3256a8e1175bSopenharmony_ci * from certificate at this point. */ 3257a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED) 3258a8e1175bSopenharmony_ci if (mbedtls_ssl_ciphersuite_uses_ecdh(ciphersuite_info)) { 3259a8e1175bSopenharmony_ci ret = ssl_get_ecdh_params_from_cert(ssl); 3260a8e1175bSopenharmony_ci if (ret != 0) { 3261a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "ssl_get_ecdh_params_from_cert", ret); 3262a8e1175bSopenharmony_ci return ret; 3263a8e1175bSopenharmony_ci } 3264a8e1175bSopenharmony_ci } 3265a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */ 3266a8e1175bSopenharmony_ci 3267a8e1175bSopenharmony_ci /* Key exchanges not involving ephemeral keys don't use 3268a8e1175bSopenharmony_ci * ServerKeyExchange, so end here. */ 3269a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write server key exchange")); 3270a8e1175bSopenharmony_ci ssl->state++; 3271a8e1175bSopenharmony_ci return 0; 3272a8e1175bSopenharmony_ci } 3273a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */ 3274a8e1175bSopenharmony_ci 3275a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \ 3276a8e1175bSopenharmony_ci defined(MBEDTLS_SSL_ASYNC_PRIVATE) 3277a8e1175bSopenharmony_ci /* If we have already prepared the message and there is an ongoing 3278a8e1175bSopenharmony_ci * signature operation, resume signing. */ 3279a8e1175bSopenharmony_ci if (ssl->handshake->async_in_progress != 0) { 3280a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("resuming signature operation")); 3281a8e1175bSopenharmony_ci ret = ssl_resume_server_key_exchange(ssl, &signature_len); 3282a8e1175bSopenharmony_ci } else 3283a8e1175bSopenharmony_ci#endif /* defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && 3284a8e1175bSopenharmony_ci defined(MBEDTLS_SSL_ASYNC_PRIVATE) */ 3285a8e1175bSopenharmony_ci { 3286a8e1175bSopenharmony_ci /* ServerKeyExchange is needed. Prepare the message. */ 3287a8e1175bSopenharmony_ci ret = ssl_prepare_server_key_exchange(ssl, &signature_len); 3288a8e1175bSopenharmony_ci } 3289a8e1175bSopenharmony_ci 3290a8e1175bSopenharmony_ci if (ret != 0) { 3291a8e1175bSopenharmony_ci /* If we're starting to write a new message, set ssl->out_msglen 3292a8e1175bSopenharmony_ci * to 0. But if we're resuming after an asynchronous message, 3293a8e1175bSopenharmony_ci * out_msglen is the amount of data written so far and mst be 3294a8e1175bSopenharmony_ci * preserved. */ 3295a8e1175bSopenharmony_ci if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) { 3296a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server key exchange (pending)")); 3297a8e1175bSopenharmony_ci } else { 3298a8e1175bSopenharmony_ci ssl->out_msglen = 0; 3299a8e1175bSopenharmony_ci } 3300a8e1175bSopenharmony_ci return ret; 3301a8e1175bSopenharmony_ci } 3302a8e1175bSopenharmony_ci 3303a8e1175bSopenharmony_ci /* If there is a signature, write its length. 3304a8e1175bSopenharmony_ci * ssl_prepare_server_key_exchange already wrote the signature 3305a8e1175bSopenharmony_ci * itself at its proper place in the output buffer. */ 3306a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) 3307a8e1175bSopenharmony_ci if (signature_len != 0) { 3308a8e1175bSopenharmony_ci ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_1(signature_len); 3309a8e1175bSopenharmony_ci ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_0(signature_len); 3310a8e1175bSopenharmony_ci 3311a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "my signature", 3312a8e1175bSopenharmony_ci ssl->out_msg + ssl->out_msglen, 3313a8e1175bSopenharmony_ci signature_len); 3314a8e1175bSopenharmony_ci 3315a8e1175bSopenharmony_ci /* Skip over the already-written signature */ 3316a8e1175bSopenharmony_ci ssl->out_msglen += signature_len; 3317a8e1175bSopenharmony_ci } 3318a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ 3319a8e1175bSopenharmony_ci 3320a8e1175bSopenharmony_ci /* Add header and send. */ 3321a8e1175bSopenharmony_ci ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; 3322a8e1175bSopenharmony_ci ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE; 3323a8e1175bSopenharmony_ci 3324a8e1175bSopenharmony_ci ssl->state++; 3325a8e1175bSopenharmony_ci 3326a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { 3327a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); 3328a8e1175bSopenharmony_ci return ret; 3329a8e1175bSopenharmony_ci } 3330a8e1175bSopenharmony_ci 3331a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server key exchange")); 3332a8e1175bSopenharmony_ci return 0; 3333a8e1175bSopenharmony_ci} 3334a8e1175bSopenharmony_ci 3335a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 3336a8e1175bSopenharmony_cistatic int ssl_write_server_hello_done(mbedtls_ssl_context *ssl) 3337a8e1175bSopenharmony_ci{ 3338a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 3339a8e1175bSopenharmony_ci 3340a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> write server hello done")); 3341a8e1175bSopenharmony_ci 3342a8e1175bSopenharmony_ci ssl->out_msglen = 4; 3343a8e1175bSopenharmony_ci ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; 3344a8e1175bSopenharmony_ci ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO_DONE; 3345a8e1175bSopenharmony_ci 3346a8e1175bSopenharmony_ci ssl->state++; 3347a8e1175bSopenharmony_ci 3348a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS) 3349a8e1175bSopenharmony_ci if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 3350a8e1175bSopenharmony_ci mbedtls_ssl_send_flight_completed(ssl); 3351a8e1175bSopenharmony_ci } 3352a8e1175bSopenharmony_ci#endif 3353a8e1175bSopenharmony_ci 3354a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { 3355a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); 3356a8e1175bSopenharmony_ci return ret; 3357a8e1175bSopenharmony_ci } 3358a8e1175bSopenharmony_ci 3359a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS) 3360a8e1175bSopenharmony_ci if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && 3361a8e1175bSopenharmony_ci (ret = mbedtls_ssl_flight_transmit(ssl)) != 0) { 3362a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_flight_transmit", ret); 3363a8e1175bSopenharmony_ci return ret; 3364a8e1175bSopenharmony_ci } 3365a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */ 3366a8e1175bSopenharmony_ci 3367a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= write server hello done")); 3368a8e1175bSopenharmony_ci 3369a8e1175bSopenharmony_ci return 0; 3370a8e1175bSopenharmony_ci} 3371a8e1175bSopenharmony_ci 3372a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ 3373a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) 3374a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 3375a8e1175bSopenharmony_cistatic int ssl_parse_client_dh_public(mbedtls_ssl_context *ssl, unsigned char **p, 3376a8e1175bSopenharmony_ci const unsigned char *end) 3377a8e1175bSopenharmony_ci{ 3378a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 3379a8e1175bSopenharmony_ci size_t n; 3380a8e1175bSopenharmony_ci 3381a8e1175bSopenharmony_ci /* 3382a8e1175bSopenharmony_ci * Receive G^Y mod P, premaster = (G^Y)^X mod P 3383a8e1175bSopenharmony_ci */ 3384a8e1175bSopenharmony_ci if (*p + 2 > end) { 3385a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); 3386a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 3387a8e1175bSopenharmony_ci } 3388a8e1175bSopenharmony_ci 3389a8e1175bSopenharmony_ci n = MBEDTLS_GET_UINT16_BE(*p, 0); 3390a8e1175bSopenharmony_ci *p += 2; 3391a8e1175bSopenharmony_ci 3392a8e1175bSopenharmony_ci if (*p + n > end) { 3393a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); 3394a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 3395a8e1175bSopenharmony_ci } 3396a8e1175bSopenharmony_ci 3397a8e1175bSopenharmony_ci if ((ret = mbedtls_dhm_read_public(&ssl->handshake->dhm_ctx, *p, n)) != 0) { 3398a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_read_public", ret); 3399a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 3400a8e1175bSopenharmony_ci } 3401a8e1175bSopenharmony_ci 3402a8e1175bSopenharmony_ci *p += n; 3403a8e1175bSopenharmony_ci 3404a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GY", &ssl->handshake->dhm_ctx.GY); 3405a8e1175bSopenharmony_ci 3406a8e1175bSopenharmony_ci return ret; 3407a8e1175bSopenharmony_ci} 3408a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || 3409a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ 3410a8e1175bSopenharmony_ci 3411a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ 3412a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) 3413a8e1175bSopenharmony_ci 3414a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) 3415a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 3416a8e1175bSopenharmony_cistatic int ssl_resume_decrypt_pms(mbedtls_ssl_context *ssl, 3417a8e1175bSopenharmony_ci unsigned char *peer_pms, 3418a8e1175bSopenharmony_ci size_t *peer_pmslen, 3419a8e1175bSopenharmony_ci size_t peer_pmssize) 3420a8e1175bSopenharmony_ci{ 3421a8e1175bSopenharmony_ci int ret = ssl->conf->f_async_resume(ssl, 3422a8e1175bSopenharmony_ci peer_pms, peer_pmslen, peer_pmssize); 3423a8e1175bSopenharmony_ci if (ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) { 3424a8e1175bSopenharmony_ci ssl->handshake->async_in_progress = 0; 3425a8e1175bSopenharmony_ci mbedtls_ssl_set_async_operation_data(ssl, NULL); 3426a8e1175bSopenharmony_ci } 3427a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(2, "ssl_decrypt_encrypted_pms", ret); 3428a8e1175bSopenharmony_ci return ret; 3429a8e1175bSopenharmony_ci} 3430a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ 3431a8e1175bSopenharmony_ci 3432a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 3433a8e1175bSopenharmony_cistatic int ssl_decrypt_encrypted_pms(mbedtls_ssl_context *ssl, 3434a8e1175bSopenharmony_ci const unsigned char *p, 3435a8e1175bSopenharmony_ci const unsigned char *end, 3436a8e1175bSopenharmony_ci unsigned char *peer_pms, 3437a8e1175bSopenharmony_ci size_t *peer_pmslen, 3438a8e1175bSopenharmony_ci size_t peer_pmssize) 3439a8e1175bSopenharmony_ci{ 3440a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 3441a8e1175bSopenharmony_ci 3442a8e1175bSopenharmony_ci mbedtls_x509_crt *own_cert = mbedtls_ssl_own_cert(ssl); 3443a8e1175bSopenharmony_ci if (own_cert == NULL) { 3444a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("got no local certificate")); 3445a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE; 3446a8e1175bSopenharmony_ci } 3447a8e1175bSopenharmony_ci mbedtls_pk_context *public_key = &own_cert->pk; 3448a8e1175bSopenharmony_ci mbedtls_pk_context *private_key = mbedtls_ssl_own_key(ssl); 3449a8e1175bSopenharmony_ci size_t len = mbedtls_pk_get_len(public_key); 3450a8e1175bSopenharmony_ci 3451a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) 3452a8e1175bSopenharmony_ci /* If we have already started decoding the message and there is an ongoing 3453a8e1175bSopenharmony_ci * decryption operation, resume signing. */ 3454a8e1175bSopenharmony_ci if (ssl->handshake->async_in_progress != 0) { 3455a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("resuming decryption operation")); 3456a8e1175bSopenharmony_ci return ssl_resume_decrypt_pms(ssl, 3457a8e1175bSopenharmony_ci peer_pms, peer_pmslen, peer_pmssize); 3458a8e1175bSopenharmony_ci } 3459a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ 3460a8e1175bSopenharmony_ci 3461a8e1175bSopenharmony_ci /* 3462a8e1175bSopenharmony_ci * Prepare to decrypt the premaster using own private RSA key 3463a8e1175bSopenharmony_ci */ 3464a8e1175bSopenharmony_ci if (p + 2 > end) { 3465a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); 3466a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 3467a8e1175bSopenharmony_ci } 3468a8e1175bSopenharmony_ci if (*p++ != MBEDTLS_BYTE_1(len) || 3469a8e1175bSopenharmony_ci *p++ != MBEDTLS_BYTE_0(len)) { 3470a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); 3471a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 3472a8e1175bSopenharmony_ci } 3473a8e1175bSopenharmony_ci 3474a8e1175bSopenharmony_ci if (p + len != end) { 3475a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); 3476a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 3477a8e1175bSopenharmony_ci } 3478a8e1175bSopenharmony_ci 3479a8e1175bSopenharmony_ci /* 3480a8e1175bSopenharmony_ci * Decrypt the premaster secret 3481a8e1175bSopenharmony_ci */ 3482a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) 3483a8e1175bSopenharmony_ci if (ssl->conf->f_async_decrypt_start != NULL) { 3484a8e1175bSopenharmony_ci ret = ssl->conf->f_async_decrypt_start(ssl, 3485a8e1175bSopenharmony_ci mbedtls_ssl_own_cert(ssl), 3486a8e1175bSopenharmony_ci p, len); 3487a8e1175bSopenharmony_ci switch (ret) { 3488a8e1175bSopenharmony_ci case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH: 3489a8e1175bSopenharmony_ci /* act as if f_async_decrypt_start was null */ 3490a8e1175bSopenharmony_ci break; 3491a8e1175bSopenharmony_ci case 0: 3492a8e1175bSopenharmony_ci ssl->handshake->async_in_progress = 1; 3493a8e1175bSopenharmony_ci return ssl_resume_decrypt_pms(ssl, 3494a8e1175bSopenharmony_ci peer_pms, 3495a8e1175bSopenharmony_ci peer_pmslen, 3496a8e1175bSopenharmony_ci peer_pmssize); 3497a8e1175bSopenharmony_ci case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: 3498a8e1175bSopenharmony_ci ssl->handshake->async_in_progress = 1; 3499a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS; 3500a8e1175bSopenharmony_ci default: 3501a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "f_async_decrypt_start", ret); 3502a8e1175bSopenharmony_ci return ret; 3503a8e1175bSopenharmony_ci } 3504a8e1175bSopenharmony_ci } 3505a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ 3506a8e1175bSopenharmony_ci 3507a8e1175bSopenharmony_ci if (!mbedtls_pk_can_do(private_key, MBEDTLS_PK_RSA)) { 3508a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("got no RSA private key")); 3509a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED; 3510a8e1175bSopenharmony_ci } 3511a8e1175bSopenharmony_ci 3512a8e1175bSopenharmony_ci ret = mbedtls_pk_decrypt(private_key, p, len, 3513a8e1175bSopenharmony_ci peer_pms, peer_pmslen, peer_pmssize, 3514a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng); 3515a8e1175bSopenharmony_ci return ret; 3516a8e1175bSopenharmony_ci} 3517a8e1175bSopenharmony_ci 3518a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 3519a8e1175bSopenharmony_cistatic int ssl_parse_encrypted_pms(mbedtls_ssl_context *ssl, 3520a8e1175bSopenharmony_ci const unsigned char *p, 3521a8e1175bSopenharmony_ci const unsigned char *end, 3522a8e1175bSopenharmony_ci size_t pms_offset) 3523a8e1175bSopenharmony_ci{ 3524a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 3525a8e1175bSopenharmony_ci unsigned char *pms = ssl->handshake->premaster + pms_offset; 3526a8e1175bSopenharmony_ci unsigned char ver[2]; 3527a8e1175bSopenharmony_ci unsigned char fake_pms[48], peer_pms[48]; 3528a8e1175bSopenharmony_ci size_t peer_pmslen; 3529a8e1175bSopenharmony_ci mbedtls_ct_condition_t diff; 3530a8e1175bSopenharmony_ci 3531a8e1175bSopenharmony_ci /* In case of a failure in decryption, the decryption may write less than 3532a8e1175bSopenharmony_ci * 2 bytes of output, but we always read the first two bytes. It doesn't 3533a8e1175bSopenharmony_ci * matter in the end because diff will be nonzero in that case due to 3534a8e1175bSopenharmony_ci * ret being nonzero, and we only care whether diff is 0. 3535a8e1175bSopenharmony_ci * But do initialize peer_pms and peer_pmslen for robustness anyway. This 3536a8e1175bSopenharmony_ci * also makes memory analyzers happy (don't access uninitialized memory, 3537a8e1175bSopenharmony_ci * even if it's an unsigned char). */ 3538a8e1175bSopenharmony_ci peer_pms[0] = peer_pms[1] = ~0; 3539a8e1175bSopenharmony_ci peer_pmslen = 0; 3540a8e1175bSopenharmony_ci 3541a8e1175bSopenharmony_ci ret = ssl_decrypt_encrypted_pms(ssl, p, end, 3542a8e1175bSopenharmony_ci peer_pms, 3543a8e1175bSopenharmony_ci &peer_pmslen, 3544a8e1175bSopenharmony_ci sizeof(peer_pms)); 3545a8e1175bSopenharmony_ci 3546a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) 3547a8e1175bSopenharmony_ci if (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) { 3548a8e1175bSopenharmony_ci return ret; 3549a8e1175bSopenharmony_ci } 3550a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ 3551a8e1175bSopenharmony_ci 3552a8e1175bSopenharmony_ci mbedtls_ssl_write_version(ver, ssl->conf->transport, 3553a8e1175bSopenharmony_ci ssl->session_negotiate->tls_version); 3554a8e1175bSopenharmony_ci 3555a8e1175bSopenharmony_ci /* Avoid data-dependent branches while checking for invalid 3556a8e1175bSopenharmony_ci * padding, to protect against timing-based Bleichenbacher-type 3557a8e1175bSopenharmony_ci * attacks. */ 3558a8e1175bSopenharmony_ci diff = mbedtls_ct_bool(ret); 3559a8e1175bSopenharmony_ci diff = mbedtls_ct_bool_or(diff, mbedtls_ct_uint_ne(peer_pmslen, 48)); 3560a8e1175bSopenharmony_ci diff = mbedtls_ct_bool_or(diff, mbedtls_ct_uint_ne(peer_pms[0], ver[0])); 3561a8e1175bSopenharmony_ci diff = mbedtls_ct_bool_or(diff, mbedtls_ct_uint_ne(peer_pms[1], ver[1])); 3562a8e1175bSopenharmony_ci 3563a8e1175bSopenharmony_ci /* 3564a8e1175bSopenharmony_ci * Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding 3565a8e1175bSopenharmony_ci * must not cause the connection to end immediately; instead, send a 3566a8e1175bSopenharmony_ci * bad_record_mac later in the handshake. 3567a8e1175bSopenharmony_ci * To protect against timing-based variants of the attack, we must 3568a8e1175bSopenharmony_ci * not have any branch that depends on whether the decryption was 3569a8e1175bSopenharmony_ci * successful. In particular, always generate the fake premaster secret, 3570a8e1175bSopenharmony_ci * regardless of whether it will ultimately influence the output or not. 3571a8e1175bSopenharmony_ci */ 3572a8e1175bSopenharmony_ci ret = ssl->conf->f_rng(ssl->conf->p_rng, fake_pms, sizeof(fake_pms)); 3573a8e1175bSopenharmony_ci if (ret != 0) { 3574a8e1175bSopenharmony_ci /* It's ok to abort on an RNG failure, since this does not reveal 3575a8e1175bSopenharmony_ci * anything about the RSA decryption. */ 3576a8e1175bSopenharmony_ci return ret; 3577a8e1175bSopenharmony_ci } 3578a8e1175bSopenharmony_ci 3579a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DEBUG_ALL) 3580a8e1175bSopenharmony_ci if (diff != MBEDTLS_CT_FALSE) { 3581a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); 3582a8e1175bSopenharmony_ci } 3583a8e1175bSopenharmony_ci#endif 3584a8e1175bSopenharmony_ci 3585a8e1175bSopenharmony_ci if (sizeof(ssl->handshake->premaster) < pms_offset || 3586a8e1175bSopenharmony_ci sizeof(ssl->handshake->premaster) - pms_offset < 48) { 3587a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 3588a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 3589a8e1175bSopenharmony_ci } 3590a8e1175bSopenharmony_ci ssl->handshake->pmslen = 48; 3591a8e1175bSopenharmony_ci 3592a8e1175bSopenharmony_ci /* Set pms to either the true or the fake PMS, without 3593a8e1175bSopenharmony_ci * data-dependent branches. */ 3594a8e1175bSopenharmony_ci mbedtls_ct_memcpy_if(diff, pms, fake_pms, peer_pms, ssl->handshake->pmslen); 3595a8e1175bSopenharmony_ci 3596a8e1175bSopenharmony_ci return 0; 3597a8e1175bSopenharmony_ci} 3598a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED || 3599a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ 3600a8e1175bSopenharmony_ci 3601a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) 3602a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 3603a8e1175bSopenharmony_cistatic int ssl_parse_client_psk_identity(mbedtls_ssl_context *ssl, unsigned char **p, 3604a8e1175bSopenharmony_ci const unsigned char *end) 3605a8e1175bSopenharmony_ci{ 3606a8e1175bSopenharmony_ci int ret = 0; 3607a8e1175bSopenharmony_ci uint16_t n; 3608a8e1175bSopenharmony_ci 3609a8e1175bSopenharmony_ci if (ssl_conf_has_psk_or_cb(ssl->conf) == 0) { 3610a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("got no pre-shared key")); 3611a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED; 3612a8e1175bSopenharmony_ci } 3613a8e1175bSopenharmony_ci 3614a8e1175bSopenharmony_ci /* 3615a8e1175bSopenharmony_ci * Receive client pre-shared key identity name 3616a8e1175bSopenharmony_ci */ 3617a8e1175bSopenharmony_ci if (end - *p < 2) { 3618a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); 3619a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 3620a8e1175bSopenharmony_ci } 3621a8e1175bSopenharmony_ci 3622a8e1175bSopenharmony_ci n = MBEDTLS_GET_UINT16_BE(*p, 0); 3623a8e1175bSopenharmony_ci *p += 2; 3624a8e1175bSopenharmony_ci 3625a8e1175bSopenharmony_ci if (n == 0 || n > end - *p) { 3626a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); 3627a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 3628a8e1175bSopenharmony_ci } 3629a8e1175bSopenharmony_ci 3630a8e1175bSopenharmony_ci if (ssl->conf->f_psk != NULL) { 3631a8e1175bSopenharmony_ci if (ssl->conf->f_psk(ssl->conf->p_psk, ssl, *p, n) != 0) { 3632a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; 3633a8e1175bSopenharmony_ci } 3634a8e1175bSopenharmony_ci } else { 3635a8e1175bSopenharmony_ci /* Identity is not a big secret since clients send it in the clear, 3636a8e1175bSopenharmony_ci * but treat it carefully anyway, just in case */ 3637a8e1175bSopenharmony_ci if (n != ssl->conf->psk_identity_len || 3638a8e1175bSopenharmony_ci mbedtls_ct_memcmp(ssl->conf->psk_identity, *p, n) != 0) { 3639a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; 3640a8e1175bSopenharmony_ci } 3641a8e1175bSopenharmony_ci } 3642a8e1175bSopenharmony_ci 3643a8e1175bSopenharmony_ci if (ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) { 3644a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "Unknown PSK identity", *p, n); 3645a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 3646a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY); 3647a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; 3648a8e1175bSopenharmony_ci } 3649a8e1175bSopenharmony_ci 3650a8e1175bSopenharmony_ci *p += n; 3651a8e1175bSopenharmony_ci 3652a8e1175bSopenharmony_ci return 0; 3653a8e1175bSopenharmony_ci} 3654a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ 3655a8e1175bSopenharmony_ci 3656a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 3657a8e1175bSopenharmony_cistatic int ssl_parse_client_key_exchange(mbedtls_ssl_context *ssl) 3658a8e1175bSopenharmony_ci{ 3659a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 3660a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info; 3661a8e1175bSopenharmony_ci unsigned char *p, *end; 3662a8e1175bSopenharmony_ci 3663a8e1175bSopenharmony_ci ciphersuite_info = ssl->handshake->ciphersuite_info; 3664a8e1175bSopenharmony_ci 3665a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse client key exchange")); 3666a8e1175bSopenharmony_ci 3667a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) && \ 3668a8e1175bSopenharmony_ci (defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ 3669a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)) 3670a8e1175bSopenharmony_ci if ((ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || 3671a8e1175bSopenharmony_ci ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) && 3672a8e1175bSopenharmony_ci (ssl->handshake->async_in_progress != 0)) { 3673a8e1175bSopenharmony_ci /* We've already read a record and there is an asynchronous 3674a8e1175bSopenharmony_ci * operation in progress to decrypt it. So skip reading the 3675a8e1175bSopenharmony_ci * record. */ 3676a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("will resume decryption of previously-read record")); 3677a8e1175bSopenharmony_ci } else 3678a8e1175bSopenharmony_ci#endif 3679a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { 3680a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); 3681a8e1175bSopenharmony_ci return ret; 3682a8e1175bSopenharmony_ci } 3683a8e1175bSopenharmony_ci 3684a8e1175bSopenharmony_ci p = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl); 3685a8e1175bSopenharmony_ci end = ssl->in_msg + ssl->in_hslen; 3686a8e1175bSopenharmony_ci 3687a8e1175bSopenharmony_ci if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { 3688a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); 3689a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 3690a8e1175bSopenharmony_ci } 3691a8e1175bSopenharmony_ci 3692a8e1175bSopenharmony_ci if (ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE) { 3693a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange message")); 3694a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 3695a8e1175bSopenharmony_ci } 3696a8e1175bSopenharmony_ci 3697a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) 3698a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA) { 3699a8e1175bSopenharmony_ci if ((ret = ssl_parse_client_dh_public(ssl, &p, end)) != 0) { 3700a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_dh_public"), ret); 3701a8e1175bSopenharmony_ci return ret; 3702a8e1175bSopenharmony_ci } 3703a8e1175bSopenharmony_ci 3704a8e1175bSopenharmony_ci if (p != end) { 3705a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange")); 3706a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 3707a8e1175bSopenharmony_ci } 3708a8e1175bSopenharmony_ci 3709a8e1175bSopenharmony_ci if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx, 3710a8e1175bSopenharmony_ci ssl->handshake->premaster, 3711a8e1175bSopenharmony_ci MBEDTLS_PREMASTER_SIZE, 3712a8e1175bSopenharmony_ci &ssl->handshake->pmslen, 3713a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { 3714a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret); 3715a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 3716a8e1175bSopenharmony_ci } 3717a8e1175bSopenharmony_ci 3718a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K); 3719a8e1175bSopenharmony_ci } else 3720a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ 3721a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ 3722a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ 3723a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ 3724a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) 3725a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || 3726a8e1175bSopenharmony_ci ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || 3727a8e1175bSopenharmony_ci ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || 3728a8e1175bSopenharmony_ci ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA) { 3729a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 3730a8e1175bSopenharmony_ci size_t data_len = (size_t) (*p++); 3731a8e1175bSopenharmony_ci size_t buf_len = (size_t) (end - p); 3732a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_GENERIC_ERROR; 3733a8e1175bSopenharmony_ci mbedtls_ssl_handshake_params *handshake = ssl->handshake; 3734a8e1175bSopenharmony_ci 3735a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("Read the peer's public key.")); 3736a8e1175bSopenharmony_ci 3737a8e1175bSopenharmony_ci /* 3738a8e1175bSopenharmony_ci * We must have at least two bytes (1 for length, at least 1 for data) 3739a8e1175bSopenharmony_ci */ 3740a8e1175bSopenharmony_ci if (buf_len < 2) { 3741a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid buffer length: %" MBEDTLS_PRINTF_SIZET, 3742a8e1175bSopenharmony_ci buf_len)); 3743a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 3744a8e1175bSopenharmony_ci } 3745a8e1175bSopenharmony_ci 3746a8e1175bSopenharmony_ci if (data_len < 1 || data_len > buf_len) { 3747a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid data length: %" MBEDTLS_PRINTF_SIZET 3748a8e1175bSopenharmony_ci " > %" MBEDTLS_PRINTF_SIZET, 3749a8e1175bSopenharmony_ci data_len, buf_len)); 3750a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 3751a8e1175bSopenharmony_ci } 3752a8e1175bSopenharmony_ci 3753a8e1175bSopenharmony_ci /* Store peer's ECDH public key. */ 3754a8e1175bSopenharmony_ci if (data_len > sizeof(handshake->xxdh_psa_peerkey)) { 3755a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("Invalid public key length: %" MBEDTLS_PRINTF_SIZET 3756a8e1175bSopenharmony_ci " > %" MBEDTLS_PRINTF_SIZET, 3757a8e1175bSopenharmony_ci data_len, 3758a8e1175bSopenharmony_ci sizeof(handshake->xxdh_psa_peerkey))); 3759a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 3760a8e1175bSopenharmony_ci } 3761a8e1175bSopenharmony_ci memcpy(handshake->xxdh_psa_peerkey, p, data_len); 3762a8e1175bSopenharmony_ci handshake->xxdh_psa_peerkey_len = data_len; 3763a8e1175bSopenharmony_ci 3764a8e1175bSopenharmony_ci /* Compute ECDH shared secret. */ 3765a8e1175bSopenharmony_ci status = psa_raw_key_agreement( 3766a8e1175bSopenharmony_ci PSA_ALG_ECDH, handshake->xxdh_psa_privkey, 3767a8e1175bSopenharmony_ci handshake->xxdh_psa_peerkey, handshake->xxdh_psa_peerkey_len, 3768a8e1175bSopenharmony_ci handshake->premaster, sizeof(handshake->premaster), 3769a8e1175bSopenharmony_ci &handshake->pmslen); 3770a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 3771a8e1175bSopenharmony_ci ret = PSA_TO_MBEDTLS_ERR(status); 3772a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "psa_raw_key_agreement", ret); 3773a8e1175bSopenharmony_ci if (handshake->xxdh_psa_privkey_is_external == 0) { 3774a8e1175bSopenharmony_ci (void) psa_destroy_key(handshake->xxdh_psa_privkey); 3775a8e1175bSopenharmony_ci } 3776a8e1175bSopenharmony_ci handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; 3777a8e1175bSopenharmony_ci return ret; 3778a8e1175bSopenharmony_ci } 3779a8e1175bSopenharmony_ci 3780a8e1175bSopenharmony_ci if (handshake->xxdh_psa_privkey_is_external == 0) { 3781a8e1175bSopenharmony_ci status = psa_destroy_key(handshake->xxdh_psa_privkey); 3782a8e1175bSopenharmony_ci 3783a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 3784a8e1175bSopenharmony_ci ret = PSA_TO_MBEDTLS_ERR(status); 3785a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "psa_destroy_key", ret); 3786a8e1175bSopenharmony_ci return ret; 3787a8e1175bSopenharmony_ci } 3788a8e1175bSopenharmony_ci } 3789a8e1175bSopenharmony_ci handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; 3790a8e1175bSopenharmony_ci#else 3791a8e1175bSopenharmony_ci if ((ret = mbedtls_ecdh_read_public(&ssl->handshake->ecdh_ctx, 3792a8e1175bSopenharmony_ci p, (size_t) (end - p))) != 0) { 3793a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_read_public", ret); 3794a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 3795a8e1175bSopenharmony_ci } 3796a8e1175bSopenharmony_ci 3797a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, 3798a8e1175bSopenharmony_ci MBEDTLS_DEBUG_ECDH_QP); 3799a8e1175bSopenharmony_ci 3800a8e1175bSopenharmony_ci if ((ret = mbedtls_ecdh_calc_secret(&ssl->handshake->ecdh_ctx, 3801a8e1175bSopenharmony_ci &ssl->handshake->pmslen, 3802a8e1175bSopenharmony_ci ssl->handshake->premaster, 3803a8e1175bSopenharmony_ci MBEDTLS_MPI_MAX_SIZE, 3804a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { 3805a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_calc_secret", ret); 3806a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 3807a8e1175bSopenharmony_ci } 3808a8e1175bSopenharmony_ci 3809a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, 3810a8e1175bSopenharmony_ci MBEDTLS_DEBUG_ECDH_Z); 3811a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 3812a8e1175bSopenharmony_ci } else 3813a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || 3814a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || 3815a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || 3816a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ 3817a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) 3818a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK) { 3819a8e1175bSopenharmony_ci if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) { 3820a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret); 3821a8e1175bSopenharmony_ci return ret; 3822a8e1175bSopenharmony_ci } 3823a8e1175bSopenharmony_ci 3824a8e1175bSopenharmony_ci if (p != end) { 3825a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange")); 3826a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 3827a8e1175bSopenharmony_ci } 3828a8e1175bSopenharmony_ci 3829a8e1175bSopenharmony_ci#if !defined(MBEDTLS_USE_PSA_CRYPTO) 3830a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_psk_derive_premaster(ssl, 3831a8e1175bSopenharmony_ci (mbedtls_key_exchange_type_t) ciphersuite_info-> 3832a8e1175bSopenharmony_ci key_exchange)) != 0) { 3833a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret); 3834a8e1175bSopenharmony_ci return ret; 3835a8e1175bSopenharmony_ci } 3836a8e1175bSopenharmony_ci#endif /* !MBEDTLS_USE_PSA_CRYPTO */ 3837a8e1175bSopenharmony_ci } else 3838a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ 3839a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) 3840a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) { 3841a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) 3842a8e1175bSopenharmony_ci if (ssl->handshake->async_in_progress != 0) { 3843a8e1175bSopenharmony_ci /* There is an asynchronous operation in progress to 3844a8e1175bSopenharmony_ci * decrypt the encrypted premaster secret, so skip 3845a8e1175bSopenharmony_ci * directly to resuming this operation. */ 3846a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("PSK identity already parsed")); 3847a8e1175bSopenharmony_ci /* Update p to skip the PSK identity. ssl_parse_encrypted_pms 3848a8e1175bSopenharmony_ci * won't actually use it, but maintain p anyway for robustness. */ 3849a8e1175bSopenharmony_ci p += ssl->conf->psk_identity_len + 2; 3850a8e1175bSopenharmony_ci } else 3851a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ 3852a8e1175bSopenharmony_ci if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) { 3853a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret); 3854a8e1175bSopenharmony_ci return ret; 3855a8e1175bSopenharmony_ci } 3856a8e1175bSopenharmony_ci 3857a8e1175bSopenharmony_ci if ((ret = ssl_parse_encrypted_pms(ssl, p, end, 2)) != 0) { 3858a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_encrypted_pms"), ret); 3859a8e1175bSopenharmony_ci return ret; 3860a8e1175bSopenharmony_ci } 3861a8e1175bSopenharmony_ci 3862a8e1175bSopenharmony_ci#if !defined(MBEDTLS_USE_PSA_CRYPTO) 3863a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_psk_derive_premaster(ssl, 3864a8e1175bSopenharmony_ci (mbedtls_key_exchange_type_t) ciphersuite_info-> 3865a8e1175bSopenharmony_ci key_exchange)) != 0) { 3866a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret); 3867a8e1175bSopenharmony_ci return ret; 3868a8e1175bSopenharmony_ci } 3869a8e1175bSopenharmony_ci#endif /* !MBEDTLS_USE_PSA_CRYPTO */ 3870a8e1175bSopenharmony_ci } else 3871a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ 3872a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) 3873a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK) { 3874a8e1175bSopenharmony_ci if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) { 3875a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret); 3876a8e1175bSopenharmony_ci return ret; 3877a8e1175bSopenharmony_ci } 3878a8e1175bSopenharmony_ci if ((ret = ssl_parse_client_dh_public(ssl, &p, end)) != 0) { 3879a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_dh_public"), ret); 3880a8e1175bSopenharmony_ci return ret; 3881a8e1175bSopenharmony_ci } 3882a8e1175bSopenharmony_ci 3883a8e1175bSopenharmony_ci if (p != end) { 3884a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad client key exchange")); 3885a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 3886a8e1175bSopenharmony_ci } 3887a8e1175bSopenharmony_ci 3888a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 3889a8e1175bSopenharmony_ci unsigned char *pms = ssl->handshake->premaster; 3890a8e1175bSopenharmony_ci unsigned char *pms_end = pms + sizeof(ssl->handshake->premaster); 3891a8e1175bSopenharmony_ci size_t pms_len; 3892a8e1175bSopenharmony_ci 3893a8e1175bSopenharmony_ci /* Write length only when we know the actual value */ 3894a8e1175bSopenharmony_ci if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx, 3895a8e1175bSopenharmony_ci pms + 2, pms_end - (pms + 2), &pms_len, 3896a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { 3897a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret); 3898a8e1175bSopenharmony_ci return ret; 3899a8e1175bSopenharmony_ci } 3900a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(pms_len, pms, 0); 3901a8e1175bSopenharmony_ci pms += 2 + pms_len; 3902a8e1175bSopenharmony_ci 3903a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K); 3904a8e1175bSopenharmony_ci#else 3905a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_psk_derive_premaster(ssl, 3906a8e1175bSopenharmony_ci (mbedtls_key_exchange_type_t) ciphersuite_info-> 3907a8e1175bSopenharmony_ci key_exchange)) != 0) { 3908a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret); 3909a8e1175bSopenharmony_ci return ret; 3910a8e1175bSopenharmony_ci } 3911a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 3912a8e1175bSopenharmony_ci } else 3913a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ 3914a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) 3915a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) { 3916a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 3917a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 3918a8e1175bSopenharmony_ci psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED; 3919a8e1175bSopenharmony_ci uint8_t ecpoint_len; 3920a8e1175bSopenharmony_ci 3921a8e1175bSopenharmony_ci mbedtls_ssl_handshake_params *handshake = ssl->handshake; 3922a8e1175bSopenharmony_ci 3923a8e1175bSopenharmony_ci if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) { 3924a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret); 3925a8e1175bSopenharmony_ci psa_destroy_key(handshake->xxdh_psa_privkey); 3926a8e1175bSopenharmony_ci handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; 3927a8e1175bSopenharmony_ci return ret; 3928a8e1175bSopenharmony_ci } 3929a8e1175bSopenharmony_ci 3930a8e1175bSopenharmony_ci /* Keep a copy of the peer's public key */ 3931a8e1175bSopenharmony_ci if (p >= end) { 3932a8e1175bSopenharmony_ci psa_destroy_key(handshake->xxdh_psa_privkey); 3933a8e1175bSopenharmony_ci handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; 3934a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 3935a8e1175bSopenharmony_ci } 3936a8e1175bSopenharmony_ci 3937a8e1175bSopenharmony_ci ecpoint_len = *(p++); 3938a8e1175bSopenharmony_ci if ((size_t) (end - p) < ecpoint_len) { 3939a8e1175bSopenharmony_ci psa_destroy_key(handshake->xxdh_psa_privkey); 3940a8e1175bSopenharmony_ci handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; 3941a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 3942a8e1175bSopenharmony_ci } 3943a8e1175bSopenharmony_ci 3944a8e1175bSopenharmony_ci /* When FFDH is enabled, the array handshake->xxdh_psa_peer_key size takes into account 3945a8e1175bSopenharmony_ci the sizes of the FFDH keys which are at least 2048 bits. 3946a8e1175bSopenharmony_ci The size of the array is thus greater than 256 bytes which is greater than any 3947a8e1175bSopenharmony_ci possible value of ecpoint_len (type uint8_t) and the check below can be skipped.*/ 3948a8e1175bSopenharmony_ci#if !defined(PSA_WANT_ALG_FFDH) 3949a8e1175bSopenharmony_ci if (ecpoint_len > sizeof(handshake->xxdh_psa_peerkey)) { 3950a8e1175bSopenharmony_ci psa_destroy_key(handshake->xxdh_psa_privkey); 3951a8e1175bSopenharmony_ci handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; 3952a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 3953a8e1175bSopenharmony_ci } 3954a8e1175bSopenharmony_ci#else 3955a8e1175bSopenharmony_ci MBEDTLS_STATIC_ASSERT(sizeof(handshake->xxdh_psa_peerkey) >= UINT8_MAX, 3956a8e1175bSopenharmony_ci "peer key buffer too small"); 3957a8e1175bSopenharmony_ci#endif 3958a8e1175bSopenharmony_ci 3959a8e1175bSopenharmony_ci memcpy(handshake->xxdh_psa_peerkey, p, ecpoint_len); 3960a8e1175bSopenharmony_ci handshake->xxdh_psa_peerkey_len = ecpoint_len; 3961a8e1175bSopenharmony_ci p += ecpoint_len; 3962a8e1175bSopenharmony_ci 3963a8e1175bSopenharmony_ci /* As RFC 5489 section 2, the premaster secret is formed as follows: 3964a8e1175bSopenharmony_ci * - a uint16 containing the length (in octets) of the ECDH computation 3965a8e1175bSopenharmony_ci * - the octet string produced by the ECDH computation 3966a8e1175bSopenharmony_ci * - a uint16 containing the length (in octets) of the PSK 3967a8e1175bSopenharmony_ci * - the PSK itself 3968a8e1175bSopenharmony_ci */ 3969a8e1175bSopenharmony_ci unsigned char *psm = ssl->handshake->premaster; 3970a8e1175bSopenharmony_ci const unsigned char * const psm_end = 3971a8e1175bSopenharmony_ci psm + sizeof(ssl->handshake->premaster); 3972a8e1175bSopenharmony_ci /* uint16 to store length (in octets) of the ECDH computation */ 3973a8e1175bSopenharmony_ci const size_t zlen_size = 2; 3974a8e1175bSopenharmony_ci size_t zlen = 0; 3975a8e1175bSopenharmony_ci 3976a8e1175bSopenharmony_ci /* Compute ECDH shared secret. */ 3977a8e1175bSopenharmony_ci status = psa_raw_key_agreement(PSA_ALG_ECDH, 3978a8e1175bSopenharmony_ci handshake->xxdh_psa_privkey, 3979a8e1175bSopenharmony_ci handshake->xxdh_psa_peerkey, 3980a8e1175bSopenharmony_ci handshake->xxdh_psa_peerkey_len, 3981a8e1175bSopenharmony_ci psm + zlen_size, 3982a8e1175bSopenharmony_ci psm_end - (psm + zlen_size), 3983a8e1175bSopenharmony_ci &zlen); 3984a8e1175bSopenharmony_ci 3985a8e1175bSopenharmony_ci destruction_status = psa_destroy_key(handshake->xxdh_psa_privkey); 3986a8e1175bSopenharmony_ci handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; 3987a8e1175bSopenharmony_ci 3988a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 3989a8e1175bSopenharmony_ci return PSA_TO_MBEDTLS_ERR(status); 3990a8e1175bSopenharmony_ci } else if (destruction_status != PSA_SUCCESS) { 3991a8e1175bSopenharmony_ci return PSA_TO_MBEDTLS_ERR(destruction_status); 3992a8e1175bSopenharmony_ci } 3993a8e1175bSopenharmony_ci 3994a8e1175bSopenharmony_ci /* Write the ECDH computation length before the ECDH computation */ 3995a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(zlen, psm, 0); 3996a8e1175bSopenharmony_ci psm += zlen_size + zlen; 3997a8e1175bSopenharmony_ci 3998a8e1175bSopenharmony_ci#else /* MBEDTLS_USE_PSA_CRYPTO */ 3999a8e1175bSopenharmony_ci if ((ret = ssl_parse_client_psk_identity(ssl, &p, end)) != 0) { 4000a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_client_psk_identity"), ret); 4001a8e1175bSopenharmony_ci return ret; 4002a8e1175bSopenharmony_ci } 4003a8e1175bSopenharmony_ci 4004a8e1175bSopenharmony_ci if ((ret = mbedtls_ecdh_read_public(&ssl->handshake->ecdh_ctx, 4005a8e1175bSopenharmony_ci p, (size_t) (end - p))) != 0) { 4006a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_read_public", ret); 4007a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 4008a8e1175bSopenharmony_ci } 4009a8e1175bSopenharmony_ci 4010a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, 4011a8e1175bSopenharmony_ci MBEDTLS_DEBUG_ECDH_QP); 4012a8e1175bSopenharmony_ci 4013a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_psk_derive_premaster(ssl, 4014a8e1175bSopenharmony_ci (mbedtls_key_exchange_type_t) ciphersuite_info-> 4015a8e1175bSopenharmony_ci key_exchange)) != 0) { 4016a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_psk_derive_premaster", ret); 4017a8e1175bSopenharmony_ci return ret; 4018a8e1175bSopenharmony_ci } 4019a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 4020a8e1175bSopenharmony_ci } else 4021a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ 4022a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) 4023a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) { 4024a8e1175bSopenharmony_ci if ((ret = ssl_parse_encrypted_pms(ssl, p, end, 0)) != 0) { 4025a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("ssl_parse_parse_encrypted_pms_secret"), ret); 4026a8e1175bSopenharmony_ci return ret; 4027a8e1175bSopenharmony_ci } 4028a8e1175bSopenharmony_ci } else 4029a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ 4030a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 4031a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) { 4032a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 4033a8e1175bSopenharmony_ci if ((ret = mbedtls_psa_ecjpake_read_round( 4034a8e1175bSopenharmony_ci &ssl->handshake->psa_pake_ctx, p, (size_t) (end - p), 4035a8e1175bSopenharmony_ci MBEDTLS_ECJPAKE_ROUND_TWO)) != 0) { 4036a8e1175bSopenharmony_ci psa_destroy_key(ssl->handshake->psa_pake_password); 4037a8e1175bSopenharmony_ci psa_pake_abort(&ssl->handshake->psa_pake_ctx); 4038a8e1175bSopenharmony_ci 4039a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round two", ret); 4040a8e1175bSopenharmony_ci return ret; 4041a8e1175bSopenharmony_ci } 4042a8e1175bSopenharmony_ci#else 4043a8e1175bSopenharmony_ci ret = mbedtls_ecjpake_read_round_two(&ssl->handshake->ecjpake_ctx, 4044a8e1175bSopenharmony_ci p, (size_t) (end - p)); 4045a8e1175bSopenharmony_ci if (ret != 0) { 4046a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_two", ret); 4047a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 4048a8e1175bSopenharmony_ci } 4049a8e1175bSopenharmony_ci 4050a8e1175bSopenharmony_ci ret = mbedtls_ecjpake_derive_secret(&ssl->handshake->ecjpake_ctx, 4051a8e1175bSopenharmony_ci ssl->handshake->premaster, 32, &ssl->handshake->pmslen, 4052a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng); 4053a8e1175bSopenharmony_ci if (ret != 0) { 4054a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_derive_secret", ret); 4055a8e1175bSopenharmony_ci return ret; 4056a8e1175bSopenharmony_ci } 4057a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 4058a8e1175bSopenharmony_ci } else 4059a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 4060a8e1175bSopenharmony_ci { 4061a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 4062a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 4063a8e1175bSopenharmony_ci } 4064a8e1175bSopenharmony_ci 4065a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) { 4066a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret); 4067a8e1175bSopenharmony_ci return ret; 4068a8e1175bSopenharmony_ci } 4069a8e1175bSopenharmony_ci 4070a8e1175bSopenharmony_ci ssl->state++; 4071a8e1175bSopenharmony_ci 4072a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse client key exchange")); 4073a8e1175bSopenharmony_ci 4074a8e1175bSopenharmony_ci return 0; 4075a8e1175bSopenharmony_ci} 4076a8e1175bSopenharmony_ci 4077a8e1175bSopenharmony_ci#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) 4078a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 4079a8e1175bSopenharmony_cistatic int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl) 4080a8e1175bSopenharmony_ci{ 4081a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 4082a8e1175bSopenharmony_ci ssl->handshake->ciphersuite_info; 4083a8e1175bSopenharmony_ci 4084a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate verify")); 4085a8e1175bSopenharmony_ci 4086a8e1175bSopenharmony_ci if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { 4087a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify")); 4088a8e1175bSopenharmony_ci ssl->state++; 4089a8e1175bSopenharmony_ci return 0; 4090a8e1175bSopenharmony_ci } 4091a8e1175bSopenharmony_ci 4092a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 4093a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 4094a8e1175bSopenharmony_ci} 4095a8e1175bSopenharmony_ci#else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ 4096a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 4097a8e1175bSopenharmony_cistatic int ssl_parse_certificate_verify(mbedtls_ssl_context *ssl) 4098a8e1175bSopenharmony_ci{ 4099a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 4100a8e1175bSopenharmony_ci size_t i, sig_len; 4101a8e1175bSopenharmony_ci unsigned char hash[48]; 4102a8e1175bSopenharmony_ci unsigned char *hash_start = hash; 4103a8e1175bSopenharmony_ci size_t hashlen; 4104a8e1175bSopenharmony_ci mbedtls_pk_type_t pk_alg; 4105a8e1175bSopenharmony_ci mbedtls_md_type_t md_alg; 4106a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 4107a8e1175bSopenharmony_ci ssl->handshake->ciphersuite_info; 4108a8e1175bSopenharmony_ci mbedtls_pk_context *peer_pk; 4109a8e1175bSopenharmony_ci 4110a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate verify")); 4111a8e1175bSopenharmony_ci 4112a8e1175bSopenharmony_ci if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { 4113a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify")); 4114a8e1175bSopenharmony_ci ssl->state++; 4115a8e1175bSopenharmony_ci return 0; 4116a8e1175bSopenharmony_ci } 4117a8e1175bSopenharmony_ci 4118a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) 4119a8e1175bSopenharmony_ci if (ssl->session_negotiate->peer_cert == NULL) { 4120a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify")); 4121a8e1175bSopenharmony_ci ssl->state++; 4122a8e1175bSopenharmony_ci return 0; 4123a8e1175bSopenharmony_ci } 4124a8e1175bSopenharmony_ci#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 4125a8e1175bSopenharmony_ci if (ssl->session_negotiate->peer_cert_digest == NULL) { 4126a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate verify")); 4127a8e1175bSopenharmony_ci ssl->state++; 4128a8e1175bSopenharmony_ci return 0; 4129a8e1175bSopenharmony_ci } 4130a8e1175bSopenharmony_ci#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 4131a8e1175bSopenharmony_ci 4132a8e1175bSopenharmony_ci /* Read the message without adding it to the checksum */ 4133a8e1175bSopenharmony_ci ret = mbedtls_ssl_read_record(ssl, 0 /* no checksum update */); 4134a8e1175bSopenharmony_ci if (0 != ret) { 4135a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_read_record"), ret); 4136a8e1175bSopenharmony_ci return ret; 4137a8e1175bSopenharmony_ci } 4138a8e1175bSopenharmony_ci 4139a8e1175bSopenharmony_ci ssl->state++; 4140a8e1175bSopenharmony_ci 4141a8e1175bSopenharmony_ci /* Process the message contents */ 4142a8e1175bSopenharmony_ci if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE || 4143a8e1175bSopenharmony_ci ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY) { 4144a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message")); 4145a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 4146a8e1175bSopenharmony_ci } 4147a8e1175bSopenharmony_ci 4148a8e1175bSopenharmony_ci i = mbedtls_ssl_hs_hdr_len(ssl); 4149a8e1175bSopenharmony_ci 4150a8e1175bSopenharmony_ci#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) 4151a8e1175bSopenharmony_ci peer_pk = &ssl->handshake->peer_pubkey; 4152a8e1175bSopenharmony_ci#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 4153a8e1175bSopenharmony_ci if (ssl->session_negotiate->peer_cert == NULL) { 4154a8e1175bSopenharmony_ci /* Should never happen */ 4155a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 4156a8e1175bSopenharmony_ci } 4157a8e1175bSopenharmony_ci peer_pk = &ssl->session_negotiate->peer_cert->pk; 4158a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 4159a8e1175bSopenharmony_ci 4160a8e1175bSopenharmony_ci /* 4161a8e1175bSopenharmony_ci * struct { 4162a8e1175bSopenharmony_ci * SignatureAndHashAlgorithm algorithm; -- TLS 1.2 only 4163a8e1175bSopenharmony_ci * opaque signature<0..2^16-1>; 4164a8e1175bSopenharmony_ci * } DigitallySigned; 4165a8e1175bSopenharmony_ci */ 4166a8e1175bSopenharmony_ci if (i + 2 > ssl->in_hslen) { 4167a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message")); 4168a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 4169a8e1175bSopenharmony_ci } 4170a8e1175bSopenharmony_ci 4171a8e1175bSopenharmony_ci /* 4172a8e1175bSopenharmony_ci * Hash 4173a8e1175bSopenharmony_ci */ 4174a8e1175bSopenharmony_ci md_alg = mbedtls_ssl_md_alg_from_hash(ssl->in_msg[i]); 4175a8e1175bSopenharmony_ci 4176a8e1175bSopenharmony_ci if (md_alg == MBEDTLS_MD_NONE || mbedtls_ssl_set_calc_verify_md(ssl, ssl->in_msg[i])) { 4177a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("peer not adhering to requested sig_alg" 4178a8e1175bSopenharmony_ci " for verify message")); 4179a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 4180a8e1175bSopenharmony_ci } 4181a8e1175bSopenharmony_ci 4182a8e1175bSopenharmony_ci#if !defined(MBEDTLS_MD_SHA1) 4183a8e1175bSopenharmony_ci if (MBEDTLS_MD_SHA1 == md_alg) { 4184a8e1175bSopenharmony_ci hash_start += 16; 4185a8e1175bSopenharmony_ci } 4186a8e1175bSopenharmony_ci#endif 4187a8e1175bSopenharmony_ci 4188a8e1175bSopenharmony_ci /* Info from md_alg will be used instead */ 4189a8e1175bSopenharmony_ci hashlen = 0; 4190a8e1175bSopenharmony_ci 4191a8e1175bSopenharmony_ci i++; 4192a8e1175bSopenharmony_ci 4193a8e1175bSopenharmony_ci /* 4194a8e1175bSopenharmony_ci * Signature 4195a8e1175bSopenharmony_ci */ 4196a8e1175bSopenharmony_ci if ((pk_alg = mbedtls_ssl_pk_alg_from_sig(ssl->in_msg[i])) 4197a8e1175bSopenharmony_ci == MBEDTLS_PK_NONE) { 4198a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("peer not adhering to requested sig_alg" 4199a8e1175bSopenharmony_ci " for verify message")); 4200a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 4201a8e1175bSopenharmony_ci } 4202a8e1175bSopenharmony_ci 4203a8e1175bSopenharmony_ci /* 4204a8e1175bSopenharmony_ci * Check the certificate's key type matches the signature alg 4205a8e1175bSopenharmony_ci */ 4206a8e1175bSopenharmony_ci if (!mbedtls_pk_can_do(peer_pk, pk_alg)) { 4207a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("sig_alg doesn't match cert key")); 4208a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 4209a8e1175bSopenharmony_ci } 4210a8e1175bSopenharmony_ci 4211a8e1175bSopenharmony_ci i++; 4212a8e1175bSopenharmony_ci 4213a8e1175bSopenharmony_ci if (i + 2 > ssl->in_hslen) { 4214a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message")); 4215a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 4216a8e1175bSopenharmony_ci } 4217a8e1175bSopenharmony_ci 4218a8e1175bSopenharmony_ci sig_len = MBEDTLS_GET_UINT16_BE(ssl->in_msg, i); 4219a8e1175bSopenharmony_ci i += 2; 4220a8e1175bSopenharmony_ci 4221a8e1175bSopenharmony_ci if (i + sig_len != ssl->in_hslen) { 4222a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate verify message")); 4223a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 4224a8e1175bSopenharmony_ci } 4225a8e1175bSopenharmony_ci 4226a8e1175bSopenharmony_ci /* Calculate hash and verify signature */ 4227a8e1175bSopenharmony_ci { 4228a8e1175bSopenharmony_ci size_t dummy_hlen; 4229a8e1175bSopenharmony_ci ret = ssl->handshake->calc_verify(ssl, hash, &dummy_hlen); 4230a8e1175bSopenharmony_ci if (0 != ret) { 4231a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("calc_verify"), ret); 4232a8e1175bSopenharmony_ci return ret; 4233a8e1175bSopenharmony_ci } 4234a8e1175bSopenharmony_ci } 4235a8e1175bSopenharmony_ci 4236a8e1175bSopenharmony_ci if ((ret = mbedtls_pk_verify(peer_pk, 4237a8e1175bSopenharmony_ci md_alg, hash_start, hashlen, 4238a8e1175bSopenharmony_ci ssl->in_msg + i, sig_len)) != 0) { 4239a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_verify", ret); 4240a8e1175bSopenharmony_ci return ret; 4241a8e1175bSopenharmony_ci } 4242a8e1175bSopenharmony_ci 4243a8e1175bSopenharmony_ci ret = mbedtls_ssl_update_handshake_status(ssl); 4244a8e1175bSopenharmony_ci if (0 != ret) { 4245a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_update_handshake_status"), ret); 4246a8e1175bSopenharmony_ci return ret; 4247a8e1175bSopenharmony_ci } 4248a8e1175bSopenharmony_ci 4249a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate verify")); 4250a8e1175bSopenharmony_ci 4251a8e1175bSopenharmony_ci return ret; 4252a8e1175bSopenharmony_ci} 4253a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ 4254a8e1175bSopenharmony_ci 4255a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) 4256a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 4257a8e1175bSopenharmony_cistatic int ssl_write_new_session_ticket(mbedtls_ssl_context *ssl) 4258a8e1175bSopenharmony_ci{ 4259a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 4260a8e1175bSopenharmony_ci size_t tlen; 4261a8e1175bSopenharmony_ci uint32_t lifetime; 4262a8e1175bSopenharmony_ci 4263a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> write new session ticket")); 4264a8e1175bSopenharmony_ci 4265a8e1175bSopenharmony_ci ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; 4266a8e1175bSopenharmony_ci ssl->out_msg[0] = MBEDTLS_SSL_HS_NEW_SESSION_TICKET; 4267a8e1175bSopenharmony_ci 4268a8e1175bSopenharmony_ci /* 4269a8e1175bSopenharmony_ci * struct { 4270a8e1175bSopenharmony_ci * uint32 ticket_lifetime_hint; 4271a8e1175bSopenharmony_ci * opaque ticket<0..2^16-1>; 4272a8e1175bSopenharmony_ci * } NewSessionTicket; 4273a8e1175bSopenharmony_ci * 4274a8e1175bSopenharmony_ci * 4 . 7 ticket_lifetime_hint (0 = unspecified) 4275a8e1175bSopenharmony_ci * 8 . 9 ticket_len (n) 4276a8e1175bSopenharmony_ci * 10 . 9+n ticket content 4277a8e1175bSopenharmony_ci */ 4278a8e1175bSopenharmony_ci 4279a8e1175bSopenharmony_ci#if defined(MBEDTLS_HAVE_TIME) 4280a8e1175bSopenharmony_ci ssl->session_negotiate->ticket_creation_time = mbedtls_ms_time(); 4281a8e1175bSopenharmony_ci#endif 4282a8e1175bSopenharmony_ci if ((ret = ssl->conf->f_ticket_write(ssl->conf->p_ticket, 4283a8e1175bSopenharmony_ci ssl->session_negotiate, 4284a8e1175bSopenharmony_ci ssl->out_msg + 10, 4285a8e1175bSopenharmony_ci ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN, 4286a8e1175bSopenharmony_ci &tlen, &lifetime)) != 0) { 4287a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_ticket_write", ret); 4288a8e1175bSopenharmony_ci tlen = 0; 4289a8e1175bSopenharmony_ci } 4290a8e1175bSopenharmony_ci 4291a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT32_BE(lifetime, ssl->out_msg, 4); 4292a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(tlen, ssl->out_msg, 8); 4293a8e1175bSopenharmony_ci ssl->out_msglen = 10 + tlen; 4294a8e1175bSopenharmony_ci 4295a8e1175bSopenharmony_ci /* 4296a8e1175bSopenharmony_ci * Morally equivalent to updating ssl->state, but NewSessionTicket and 4297a8e1175bSopenharmony_ci * ChangeCipherSpec share the same state. 4298a8e1175bSopenharmony_ci */ 4299a8e1175bSopenharmony_ci ssl->handshake->new_session_ticket = 0; 4300a8e1175bSopenharmony_ci 4301a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { 4302a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); 4303a8e1175bSopenharmony_ci return ret; 4304a8e1175bSopenharmony_ci } 4305a8e1175bSopenharmony_ci 4306a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= write new session ticket")); 4307a8e1175bSopenharmony_ci 4308a8e1175bSopenharmony_ci return 0; 4309a8e1175bSopenharmony_ci} 4310a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS */ 4311a8e1175bSopenharmony_ci 4312a8e1175bSopenharmony_ci/* 4313a8e1175bSopenharmony_ci * SSL handshake -- server side -- single step 4314a8e1175bSopenharmony_ci */ 4315a8e1175bSopenharmony_ciint mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl) 4316a8e1175bSopenharmony_ci{ 4317a8e1175bSopenharmony_ci int ret = 0; 4318a8e1175bSopenharmony_ci 4319a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("server state: %d", ssl->state)); 4320a8e1175bSopenharmony_ci 4321a8e1175bSopenharmony_ci switch (ssl->state) { 4322a8e1175bSopenharmony_ci case MBEDTLS_SSL_HELLO_REQUEST: 4323a8e1175bSopenharmony_ci ssl->state = MBEDTLS_SSL_CLIENT_HELLO; 4324a8e1175bSopenharmony_ci break; 4325a8e1175bSopenharmony_ci 4326a8e1175bSopenharmony_ci /* 4327a8e1175bSopenharmony_ci * <== ClientHello 4328a8e1175bSopenharmony_ci */ 4329a8e1175bSopenharmony_ci case MBEDTLS_SSL_CLIENT_HELLO: 4330a8e1175bSopenharmony_ci ret = ssl_parse_client_hello(ssl); 4331a8e1175bSopenharmony_ci break; 4332a8e1175bSopenharmony_ci 4333a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS) 4334a8e1175bSopenharmony_ci case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT: 4335a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED; 4336a8e1175bSopenharmony_ci#endif 4337a8e1175bSopenharmony_ci 4338a8e1175bSopenharmony_ci /* 4339a8e1175bSopenharmony_ci * ==> ServerHello 4340a8e1175bSopenharmony_ci * Certificate 4341a8e1175bSopenharmony_ci * ( ServerKeyExchange ) 4342a8e1175bSopenharmony_ci * ( CertificateRequest ) 4343a8e1175bSopenharmony_ci * ServerHelloDone 4344a8e1175bSopenharmony_ci */ 4345a8e1175bSopenharmony_ci case MBEDTLS_SSL_SERVER_HELLO: 4346a8e1175bSopenharmony_ci ret = ssl_write_server_hello(ssl); 4347a8e1175bSopenharmony_ci break; 4348a8e1175bSopenharmony_ci 4349a8e1175bSopenharmony_ci case MBEDTLS_SSL_SERVER_CERTIFICATE: 4350a8e1175bSopenharmony_ci ret = mbedtls_ssl_write_certificate(ssl); 4351a8e1175bSopenharmony_ci break; 4352a8e1175bSopenharmony_ci 4353a8e1175bSopenharmony_ci case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: 4354a8e1175bSopenharmony_ci ret = ssl_write_server_key_exchange(ssl); 4355a8e1175bSopenharmony_ci break; 4356a8e1175bSopenharmony_ci 4357a8e1175bSopenharmony_ci case MBEDTLS_SSL_CERTIFICATE_REQUEST: 4358a8e1175bSopenharmony_ci ret = ssl_write_certificate_request(ssl); 4359a8e1175bSopenharmony_ci break; 4360a8e1175bSopenharmony_ci 4361a8e1175bSopenharmony_ci case MBEDTLS_SSL_SERVER_HELLO_DONE: 4362a8e1175bSopenharmony_ci ret = ssl_write_server_hello_done(ssl); 4363a8e1175bSopenharmony_ci break; 4364a8e1175bSopenharmony_ci 4365a8e1175bSopenharmony_ci /* 4366a8e1175bSopenharmony_ci * <== ( Certificate/Alert ) 4367a8e1175bSopenharmony_ci * ClientKeyExchange 4368a8e1175bSopenharmony_ci * ( CertificateVerify ) 4369a8e1175bSopenharmony_ci * ChangeCipherSpec 4370a8e1175bSopenharmony_ci * Finished 4371a8e1175bSopenharmony_ci */ 4372a8e1175bSopenharmony_ci case MBEDTLS_SSL_CLIENT_CERTIFICATE: 4373a8e1175bSopenharmony_ci ret = mbedtls_ssl_parse_certificate(ssl); 4374a8e1175bSopenharmony_ci break; 4375a8e1175bSopenharmony_ci 4376a8e1175bSopenharmony_ci case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: 4377a8e1175bSopenharmony_ci ret = ssl_parse_client_key_exchange(ssl); 4378a8e1175bSopenharmony_ci break; 4379a8e1175bSopenharmony_ci 4380a8e1175bSopenharmony_ci case MBEDTLS_SSL_CERTIFICATE_VERIFY: 4381a8e1175bSopenharmony_ci ret = ssl_parse_certificate_verify(ssl); 4382a8e1175bSopenharmony_ci break; 4383a8e1175bSopenharmony_ci 4384a8e1175bSopenharmony_ci case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: 4385a8e1175bSopenharmony_ci ret = mbedtls_ssl_parse_change_cipher_spec(ssl); 4386a8e1175bSopenharmony_ci break; 4387a8e1175bSopenharmony_ci 4388a8e1175bSopenharmony_ci case MBEDTLS_SSL_CLIENT_FINISHED: 4389a8e1175bSopenharmony_ci ret = mbedtls_ssl_parse_finished(ssl); 4390a8e1175bSopenharmony_ci break; 4391a8e1175bSopenharmony_ci 4392a8e1175bSopenharmony_ci /* 4393a8e1175bSopenharmony_ci * ==> ( NewSessionTicket ) 4394a8e1175bSopenharmony_ci * ChangeCipherSpec 4395a8e1175bSopenharmony_ci * Finished 4396a8e1175bSopenharmony_ci */ 4397a8e1175bSopenharmony_ci case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: 4398a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) 4399a8e1175bSopenharmony_ci if (ssl->handshake->new_session_ticket != 0) { 4400a8e1175bSopenharmony_ci ret = ssl_write_new_session_ticket(ssl); 4401a8e1175bSopenharmony_ci } else 4402a8e1175bSopenharmony_ci#endif 4403a8e1175bSopenharmony_ci ret = mbedtls_ssl_write_change_cipher_spec(ssl); 4404a8e1175bSopenharmony_ci break; 4405a8e1175bSopenharmony_ci 4406a8e1175bSopenharmony_ci case MBEDTLS_SSL_SERVER_FINISHED: 4407a8e1175bSopenharmony_ci ret = mbedtls_ssl_write_finished(ssl); 4408a8e1175bSopenharmony_ci break; 4409a8e1175bSopenharmony_ci 4410a8e1175bSopenharmony_ci case MBEDTLS_SSL_FLUSH_BUFFERS: 4411a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done")); 4412a8e1175bSopenharmony_ci ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; 4413a8e1175bSopenharmony_ci break; 4414a8e1175bSopenharmony_ci 4415a8e1175bSopenharmony_ci case MBEDTLS_SSL_HANDSHAKE_WRAPUP: 4416a8e1175bSopenharmony_ci mbedtls_ssl_handshake_wrapup(ssl); 4417a8e1175bSopenharmony_ci break; 4418a8e1175bSopenharmony_ci 4419a8e1175bSopenharmony_ci default: 4420a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("invalid state %d", ssl->state)); 4421a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 4422a8e1175bSopenharmony_ci } 4423a8e1175bSopenharmony_ci 4424a8e1175bSopenharmony_ci return ret; 4425a8e1175bSopenharmony_ci} 4426a8e1175bSopenharmony_ci 4427a8e1175bSopenharmony_civoid mbedtls_ssl_conf_preference_order(mbedtls_ssl_config *conf, int order) 4428a8e1175bSopenharmony_ci{ 4429a8e1175bSopenharmony_ci conf->respect_cli_pref = order; 4430a8e1175bSopenharmony_ci} 4431a8e1175bSopenharmony_ci 4432a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_PROTO_TLS1_2 */ 4433