1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * TLS client-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_CLI_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_client.h" 16a8e1175bSopenharmony_ci#include "ssl_misc.h" 17a8e1175bSopenharmony_ci#include "debug_internal.h" 18a8e1175bSopenharmony_ci#include "mbedtls/error.h" 19a8e1175bSopenharmony_ci#include "mbedtls/constant_time.h" 20a8e1175bSopenharmony_ci 21a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 22a8e1175bSopenharmony_ci#include "psa_util_internal.h" 23a8e1175bSopenharmony_ci#include "psa/crypto.h" 24a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) 25a8e1175bSopenharmony_ci/* Define a local translating function to save code size by not using too many 26a8e1175bSopenharmony_ci * arguments in each translating place. */ 27a8e1175bSopenharmony_cistatic int local_err_translation(psa_status_t status) 28a8e1175bSopenharmony_ci{ 29a8e1175bSopenharmony_ci return psa_status_to_mbedtls(status, psa_to_ssl_errors, 30a8e1175bSopenharmony_ci ARRAY_LENGTH(psa_to_ssl_errors), 31a8e1175bSopenharmony_ci psa_generic_status_to_mbedtls); 32a8e1175bSopenharmony_ci} 33a8e1175bSopenharmony_ci#define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status) 34a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ 35a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 36a8e1175bSopenharmony_ci 37a8e1175bSopenharmony_ci#include <string.h> 38a8e1175bSopenharmony_ci 39a8e1175bSopenharmony_ci#include <stdint.h> 40a8e1175bSopenharmony_ci 41a8e1175bSopenharmony_ci#if defined(MBEDTLS_HAVE_TIME) 42a8e1175bSopenharmony_ci#include "mbedtls/platform_time.h" 43a8e1175bSopenharmony_ci#endif 44a8e1175bSopenharmony_ci 45a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) 46a8e1175bSopenharmony_ci#include "mbedtls/platform_util.h" 47a8e1175bSopenharmony_ci#endif 48a8e1175bSopenharmony_ci 49a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 50a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 51a8e1175bSopenharmony_cistatic int ssl_write_renegotiation_ext(mbedtls_ssl_context *ssl, 52a8e1175bSopenharmony_ci unsigned char *buf, 53a8e1175bSopenharmony_ci const unsigned char *end, 54a8e1175bSopenharmony_ci size_t *olen) 55a8e1175bSopenharmony_ci{ 56a8e1175bSopenharmony_ci unsigned char *p = buf; 57a8e1175bSopenharmony_ci 58a8e1175bSopenharmony_ci *olen = 0; 59a8e1175bSopenharmony_ci 60a8e1175bSopenharmony_ci /* We're always including a TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the 61a8e1175bSopenharmony_ci * initial ClientHello, in which case also adding the renegotiation 62a8e1175bSopenharmony_ci * info extension is NOT RECOMMENDED as per RFC 5746 Section 3.4. */ 63a8e1175bSopenharmony_ci if (ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) { 64a8e1175bSopenharmony_ci return 0; 65a8e1175bSopenharmony_ci } 66a8e1175bSopenharmony_ci 67a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, 68a8e1175bSopenharmony_ci ("client hello, adding renegotiation extension")); 69a8e1175bSopenharmony_ci 70a8e1175bSopenharmony_ci MBEDTLS_SSL_CHK_BUF_PTR(p, end, 5 + ssl->verify_data_len); 71a8e1175bSopenharmony_ci 72a8e1175bSopenharmony_ci /* 73a8e1175bSopenharmony_ci * Secure renegotiation 74a8e1175bSopenharmony_ci */ 75a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_RENEGOTIATION_INFO, p, 0); 76a8e1175bSopenharmony_ci p += 2; 77a8e1175bSopenharmony_ci 78a8e1175bSopenharmony_ci *p++ = 0x00; 79a8e1175bSopenharmony_ci *p++ = MBEDTLS_BYTE_0(ssl->verify_data_len + 1); 80a8e1175bSopenharmony_ci *p++ = MBEDTLS_BYTE_0(ssl->verify_data_len); 81a8e1175bSopenharmony_ci 82a8e1175bSopenharmony_ci memcpy(p, ssl->own_verify_data, ssl->verify_data_len); 83a8e1175bSopenharmony_ci 84a8e1175bSopenharmony_ci *olen = 5 + ssl->verify_data_len; 85a8e1175bSopenharmony_ci 86a8e1175bSopenharmony_ci return 0; 87a8e1175bSopenharmony_ci} 88a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_RENEGOTIATION */ 89a8e1175bSopenharmony_ci 90a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ 91a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ 92a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 93a8e1175bSopenharmony_ci 94a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 95a8e1175bSopenharmony_cistatic int ssl_write_supported_point_formats_ext(mbedtls_ssl_context *ssl, 96a8e1175bSopenharmony_ci unsigned char *buf, 97a8e1175bSopenharmony_ci const unsigned char *end, 98a8e1175bSopenharmony_ci size_t *olen) 99a8e1175bSopenharmony_ci{ 100a8e1175bSopenharmony_ci unsigned char *p = buf; 101a8e1175bSopenharmony_ci (void) ssl; /* ssl used for debugging only */ 102a8e1175bSopenharmony_ci 103a8e1175bSopenharmony_ci *olen = 0; 104a8e1175bSopenharmony_ci 105a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, 106a8e1175bSopenharmony_ci ("client hello, adding supported_point_formats extension")); 107a8e1175bSopenharmony_ci MBEDTLS_SSL_CHK_BUF_PTR(p, end, 6); 108a8e1175bSopenharmony_ci 109a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, p, 0); 110a8e1175bSopenharmony_ci p += 2; 111a8e1175bSopenharmony_ci 112a8e1175bSopenharmony_ci *p++ = 0x00; 113a8e1175bSopenharmony_ci *p++ = 2; 114a8e1175bSopenharmony_ci 115a8e1175bSopenharmony_ci *p++ = 1; 116a8e1175bSopenharmony_ci *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED; 117a8e1175bSopenharmony_ci 118a8e1175bSopenharmony_ci *olen = 6; 119a8e1175bSopenharmony_ci 120a8e1175bSopenharmony_ci return 0; 121a8e1175bSopenharmony_ci} 122a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || 123a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED || 124a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 125a8e1175bSopenharmony_ci 126a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 127a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 128a8e1175bSopenharmony_cistatic int ssl_write_ecjpake_kkpp_ext(mbedtls_ssl_context *ssl, 129a8e1175bSopenharmony_ci unsigned char *buf, 130a8e1175bSopenharmony_ci const unsigned char *end, 131a8e1175bSopenharmony_ci size_t *olen) 132a8e1175bSopenharmony_ci{ 133a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 134a8e1175bSopenharmony_ci unsigned char *p = buf; 135a8e1175bSopenharmony_ci size_t kkpp_len = 0; 136a8e1175bSopenharmony_ci 137a8e1175bSopenharmony_ci *olen = 0; 138a8e1175bSopenharmony_ci 139a8e1175bSopenharmony_ci /* Skip costly extension if we can't use EC J-PAKE anyway */ 140a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 141a8e1175bSopenharmony_ci if (ssl->handshake->psa_pake_ctx_is_ok != 1) { 142a8e1175bSopenharmony_ci return 0; 143a8e1175bSopenharmony_ci } 144a8e1175bSopenharmony_ci#else 145a8e1175bSopenharmony_ci if (mbedtls_ecjpake_check(&ssl->handshake->ecjpake_ctx) != 0) { 146a8e1175bSopenharmony_ci return 0; 147a8e1175bSopenharmony_ci } 148a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 149a8e1175bSopenharmony_ci 150a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, 151a8e1175bSopenharmony_ci ("client hello, adding ecjpake_kkpp extension")); 152a8e1175bSopenharmony_ci 153a8e1175bSopenharmony_ci MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4); 154a8e1175bSopenharmony_ci 155a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0); 156a8e1175bSopenharmony_ci p += 2; 157a8e1175bSopenharmony_ci 158a8e1175bSopenharmony_ci /* 159a8e1175bSopenharmony_ci * We may need to send ClientHello multiple times for Hello verification. 160a8e1175bSopenharmony_ci * We don't want to compute fresh values every time (both for performance 161a8e1175bSopenharmony_ci * and consistency reasons), so cache the extension content. 162a8e1175bSopenharmony_ci */ 163a8e1175bSopenharmony_ci if (ssl->handshake->ecjpake_cache == NULL || 164a8e1175bSopenharmony_ci ssl->handshake->ecjpake_cache_len == 0) { 165a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("generating new ecjpake parameters")); 166a8e1175bSopenharmony_ci 167a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 168a8e1175bSopenharmony_ci ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx, 169a8e1175bSopenharmony_ci p + 2, end - p - 2, &kkpp_len, 170a8e1175bSopenharmony_ci MBEDTLS_ECJPAKE_ROUND_ONE); 171a8e1175bSopenharmony_ci if (ret != 0) { 172a8e1175bSopenharmony_ci psa_destroy_key(ssl->handshake->psa_pake_password); 173a8e1175bSopenharmony_ci psa_pake_abort(&ssl->handshake->psa_pake_ctx); 174a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret); 175a8e1175bSopenharmony_ci return ret; 176a8e1175bSopenharmony_ci } 177a8e1175bSopenharmony_ci#else 178a8e1175bSopenharmony_ci ret = mbedtls_ecjpake_write_round_one(&ssl->handshake->ecjpake_ctx, 179a8e1175bSopenharmony_ci p + 2, end - p - 2, &kkpp_len, 180a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng); 181a8e1175bSopenharmony_ci if (ret != 0) { 182a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, 183a8e1175bSopenharmony_ci "mbedtls_ecjpake_write_round_one", ret); 184a8e1175bSopenharmony_ci return ret; 185a8e1175bSopenharmony_ci } 186a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 187a8e1175bSopenharmony_ci 188a8e1175bSopenharmony_ci ssl->handshake->ecjpake_cache = mbedtls_calloc(1, kkpp_len); 189a8e1175bSopenharmony_ci if (ssl->handshake->ecjpake_cache == NULL) { 190a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("allocation failed")); 191a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ALLOC_FAILED; 192a8e1175bSopenharmony_ci } 193a8e1175bSopenharmony_ci 194a8e1175bSopenharmony_ci memcpy(ssl->handshake->ecjpake_cache, p + 2, kkpp_len); 195a8e1175bSopenharmony_ci ssl->handshake->ecjpake_cache_len = kkpp_len; 196a8e1175bSopenharmony_ci } else { 197a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("re-using cached ecjpake parameters")); 198a8e1175bSopenharmony_ci 199a8e1175bSopenharmony_ci kkpp_len = ssl->handshake->ecjpake_cache_len; 200a8e1175bSopenharmony_ci MBEDTLS_SSL_CHK_BUF_PTR(p + 2, end, kkpp_len); 201a8e1175bSopenharmony_ci 202a8e1175bSopenharmony_ci memcpy(p + 2, ssl->handshake->ecjpake_cache, kkpp_len); 203a8e1175bSopenharmony_ci } 204a8e1175bSopenharmony_ci 205a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(kkpp_len, p, 0); 206a8e1175bSopenharmony_ci p += 2; 207a8e1175bSopenharmony_ci 208a8e1175bSopenharmony_ci *olen = kkpp_len + 4; 209a8e1175bSopenharmony_ci 210a8e1175bSopenharmony_ci return 0; 211a8e1175bSopenharmony_ci} 212a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 213a8e1175bSopenharmony_ci 214a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 215a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 216a8e1175bSopenharmony_cistatic int ssl_write_cid_ext(mbedtls_ssl_context *ssl, 217a8e1175bSopenharmony_ci unsigned char *buf, 218a8e1175bSopenharmony_ci const unsigned char *end, 219a8e1175bSopenharmony_ci size_t *olen) 220a8e1175bSopenharmony_ci{ 221a8e1175bSopenharmony_ci unsigned char *p = buf; 222a8e1175bSopenharmony_ci size_t ext_len; 223a8e1175bSopenharmony_ci 224a8e1175bSopenharmony_ci /* 225a8e1175bSopenharmony_ci * struct { 226a8e1175bSopenharmony_ci * opaque cid<0..2^8-1>; 227a8e1175bSopenharmony_ci * } ConnectionId; 228a8e1175bSopenharmony_ci */ 229a8e1175bSopenharmony_ci 230a8e1175bSopenharmony_ci *olen = 0; 231a8e1175bSopenharmony_ci if (ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM || 232a8e1175bSopenharmony_ci ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED) { 233a8e1175bSopenharmony_ci return 0; 234a8e1175bSopenharmony_ci } 235a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding CID extension")); 236a8e1175bSopenharmony_ci 237a8e1175bSopenharmony_ci /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX 238a8e1175bSopenharmony_ci * which is at most 255, so the increment cannot overflow. */ 239a8e1175bSopenharmony_ci MBEDTLS_SSL_CHK_BUF_PTR(p, end, (unsigned) (ssl->own_cid_len + 5)); 240a8e1175bSopenharmony_ci 241a8e1175bSopenharmony_ci /* Add extension ID + size */ 242a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_CID, p, 0); 243a8e1175bSopenharmony_ci p += 2; 244a8e1175bSopenharmony_ci ext_len = (size_t) ssl->own_cid_len + 1; 245a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(ext_len, p, 0); 246a8e1175bSopenharmony_ci p += 2; 247a8e1175bSopenharmony_ci 248a8e1175bSopenharmony_ci *p++ = (uint8_t) ssl->own_cid_len; 249a8e1175bSopenharmony_ci memcpy(p, ssl->own_cid, ssl->own_cid_len); 250a8e1175bSopenharmony_ci 251a8e1175bSopenharmony_ci *olen = ssl->own_cid_len + 5; 252a8e1175bSopenharmony_ci 253a8e1175bSopenharmony_ci return 0; 254a8e1175bSopenharmony_ci} 255a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 256a8e1175bSopenharmony_ci 257a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) 258a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 259a8e1175bSopenharmony_cistatic int ssl_write_max_fragment_length_ext(mbedtls_ssl_context *ssl, 260a8e1175bSopenharmony_ci unsigned char *buf, 261a8e1175bSopenharmony_ci const unsigned char *end, 262a8e1175bSopenharmony_ci size_t *olen) 263a8e1175bSopenharmony_ci{ 264a8e1175bSopenharmony_ci unsigned char *p = buf; 265a8e1175bSopenharmony_ci 266a8e1175bSopenharmony_ci *olen = 0; 267a8e1175bSopenharmony_ci 268a8e1175bSopenharmony_ci if (ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE) { 269a8e1175bSopenharmony_ci return 0; 270a8e1175bSopenharmony_ci } 271a8e1175bSopenharmony_ci 272a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, 273a8e1175bSopenharmony_ci ("client hello, adding max_fragment_length extension")); 274a8e1175bSopenharmony_ci 275a8e1175bSopenharmony_ci MBEDTLS_SSL_CHK_BUF_PTR(p, end, 5); 276a8e1175bSopenharmony_ci 277a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, p, 0); 278a8e1175bSopenharmony_ci p += 2; 279a8e1175bSopenharmony_ci 280a8e1175bSopenharmony_ci *p++ = 0x00; 281a8e1175bSopenharmony_ci *p++ = 1; 282a8e1175bSopenharmony_ci 283a8e1175bSopenharmony_ci *p++ = ssl->conf->mfl_code; 284a8e1175bSopenharmony_ci 285a8e1175bSopenharmony_ci *olen = 5; 286a8e1175bSopenharmony_ci 287a8e1175bSopenharmony_ci return 0; 288a8e1175bSopenharmony_ci} 289a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ 290a8e1175bSopenharmony_ci 291a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 292a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 293a8e1175bSopenharmony_cistatic int ssl_write_encrypt_then_mac_ext(mbedtls_ssl_context *ssl, 294a8e1175bSopenharmony_ci unsigned char *buf, 295a8e1175bSopenharmony_ci const unsigned char *end, 296a8e1175bSopenharmony_ci size_t *olen) 297a8e1175bSopenharmony_ci{ 298a8e1175bSopenharmony_ci unsigned char *p = buf; 299a8e1175bSopenharmony_ci 300a8e1175bSopenharmony_ci *olen = 0; 301a8e1175bSopenharmony_ci 302a8e1175bSopenharmony_ci if (ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED) { 303a8e1175bSopenharmony_ci return 0; 304a8e1175bSopenharmony_ci } 305a8e1175bSopenharmony_ci 306a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, 307a8e1175bSopenharmony_ci ("client hello, adding encrypt_then_mac extension")); 308a8e1175bSopenharmony_ci 309a8e1175bSopenharmony_ci MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4); 310a8e1175bSopenharmony_ci 311a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, p, 0); 312a8e1175bSopenharmony_ci p += 2; 313a8e1175bSopenharmony_ci 314a8e1175bSopenharmony_ci *p++ = 0x00; 315a8e1175bSopenharmony_ci *p++ = 0x00; 316a8e1175bSopenharmony_ci 317a8e1175bSopenharmony_ci *olen = 4; 318a8e1175bSopenharmony_ci 319a8e1175bSopenharmony_ci return 0; 320a8e1175bSopenharmony_ci} 321a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ 322a8e1175bSopenharmony_ci 323a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) 324a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 325a8e1175bSopenharmony_cistatic int ssl_write_extended_ms_ext(mbedtls_ssl_context *ssl, 326a8e1175bSopenharmony_ci unsigned char *buf, 327a8e1175bSopenharmony_ci const unsigned char *end, 328a8e1175bSopenharmony_ci size_t *olen) 329a8e1175bSopenharmony_ci{ 330a8e1175bSopenharmony_ci unsigned char *p = buf; 331a8e1175bSopenharmony_ci 332a8e1175bSopenharmony_ci *olen = 0; 333a8e1175bSopenharmony_ci 334a8e1175bSopenharmony_ci if (ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED) { 335a8e1175bSopenharmony_ci return 0; 336a8e1175bSopenharmony_ci } 337a8e1175bSopenharmony_ci 338a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, 339a8e1175bSopenharmony_ci ("client hello, adding extended_master_secret extension")); 340a8e1175bSopenharmony_ci 341a8e1175bSopenharmony_ci MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4); 342a8e1175bSopenharmony_ci 343a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, p, 0); 344a8e1175bSopenharmony_ci p += 2; 345a8e1175bSopenharmony_ci 346a8e1175bSopenharmony_ci *p++ = 0x00; 347a8e1175bSopenharmony_ci *p++ = 0x00; 348a8e1175bSopenharmony_ci 349a8e1175bSopenharmony_ci *olen = 4; 350a8e1175bSopenharmony_ci 351a8e1175bSopenharmony_ci return 0; 352a8e1175bSopenharmony_ci} 353a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ 354a8e1175bSopenharmony_ci 355a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) 356a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 357a8e1175bSopenharmony_cistatic int ssl_write_session_ticket_ext(mbedtls_ssl_context *ssl, 358a8e1175bSopenharmony_ci unsigned char *buf, 359a8e1175bSopenharmony_ci const unsigned char *end, 360a8e1175bSopenharmony_ci size_t *olen) 361a8e1175bSopenharmony_ci{ 362a8e1175bSopenharmony_ci unsigned char *p = buf; 363a8e1175bSopenharmony_ci size_t tlen = ssl->session_negotiate->ticket_len; 364a8e1175bSopenharmony_ci 365a8e1175bSopenharmony_ci *olen = 0; 366a8e1175bSopenharmony_ci 367a8e1175bSopenharmony_ci if (ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED) { 368a8e1175bSopenharmony_ci return 0; 369a8e1175bSopenharmony_ci } 370a8e1175bSopenharmony_ci 371a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, 372a8e1175bSopenharmony_ci ("client hello, adding session ticket extension")); 373a8e1175bSopenharmony_ci 374a8e1175bSopenharmony_ci /* The addition is safe here since the ticket length is 16 bit. */ 375a8e1175bSopenharmony_ci MBEDTLS_SSL_CHK_BUF_PTR(p, end, 4 + tlen); 376a8e1175bSopenharmony_ci 377a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_SESSION_TICKET, p, 0); 378a8e1175bSopenharmony_ci p += 2; 379a8e1175bSopenharmony_ci 380a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(tlen, p, 0); 381a8e1175bSopenharmony_ci p += 2; 382a8e1175bSopenharmony_ci 383a8e1175bSopenharmony_ci *olen = 4; 384a8e1175bSopenharmony_ci 385a8e1175bSopenharmony_ci if (ssl->session_negotiate->ticket == NULL || tlen == 0) { 386a8e1175bSopenharmony_ci return 0; 387a8e1175bSopenharmony_ci } 388a8e1175bSopenharmony_ci 389a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, 390a8e1175bSopenharmony_ci ("sending session ticket of length %" MBEDTLS_PRINTF_SIZET, tlen)); 391a8e1175bSopenharmony_ci 392a8e1175bSopenharmony_ci memcpy(p, ssl->session_negotiate->ticket, tlen); 393a8e1175bSopenharmony_ci 394a8e1175bSopenharmony_ci *olen += tlen; 395a8e1175bSopenharmony_ci 396a8e1175bSopenharmony_ci return 0; 397a8e1175bSopenharmony_ci} 398a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS */ 399a8e1175bSopenharmony_ci 400a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_SRTP) 401a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 402a8e1175bSopenharmony_cistatic int ssl_write_use_srtp_ext(mbedtls_ssl_context *ssl, 403a8e1175bSopenharmony_ci unsigned char *buf, 404a8e1175bSopenharmony_ci const unsigned char *end, 405a8e1175bSopenharmony_ci size_t *olen) 406a8e1175bSopenharmony_ci{ 407a8e1175bSopenharmony_ci unsigned char *p = buf; 408a8e1175bSopenharmony_ci size_t protection_profiles_index = 0, ext_len = 0; 409a8e1175bSopenharmony_ci uint16_t mki_len = 0, profile_value = 0; 410a8e1175bSopenharmony_ci 411a8e1175bSopenharmony_ci *olen = 0; 412a8e1175bSopenharmony_ci 413a8e1175bSopenharmony_ci if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) || 414a8e1175bSopenharmony_ci (ssl->conf->dtls_srtp_profile_list == NULL) || 415a8e1175bSopenharmony_ci (ssl->conf->dtls_srtp_profile_list_len == 0)) { 416a8e1175bSopenharmony_ci return 0; 417a8e1175bSopenharmony_ci } 418a8e1175bSopenharmony_ci 419a8e1175bSopenharmony_ci /* RFC 5764 section 4.1.1 420a8e1175bSopenharmony_ci * uint8 SRTPProtectionProfile[2]; 421a8e1175bSopenharmony_ci * 422a8e1175bSopenharmony_ci * struct { 423a8e1175bSopenharmony_ci * SRTPProtectionProfiles SRTPProtectionProfiles; 424a8e1175bSopenharmony_ci * opaque srtp_mki<0..255>; 425a8e1175bSopenharmony_ci * } UseSRTPData; 426a8e1175bSopenharmony_ci * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>; 427a8e1175bSopenharmony_ci */ 428a8e1175bSopenharmony_ci if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED) { 429a8e1175bSopenharmony_ci mki_len = ssl->dtls_srtp_info.mki_len; 430a8e1175bSopenharmony_ci } 431a8e1175bSopenharmony_ci /* Extension length = 2 bytes for profiles length, 432a8e1175bSopenharmony_ci * ssl->conf->dtls_srtp_profile_list_len * 2 (each profile is 2 bytes length ), 433a8e1175bSopenharmony_ci * 1 byte for srtp_mki vector length and the mki_len value 434a8e1175bSopenharmony_ci */ 435a8e1175bSopenharmony_ci ext_len = 2 + 2 * (ssl->conf->dtls_srtp_profile_list_len) + 1 + mki_len; 436a8e1175bSopenharmony_ci 437a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("client hello, adding use_srtp extension")); 438a8e1175bSopenharmony_ci 439a8e1175bSopenharmony_ci /* Check there is room in the buffer for the extension + 4 bytes 440a8e1175bSopenharmony_ci * - the extension tag (2 bytes) 441a8e1175bSopenharmony_ci * - the extension length (2 bytes) 442a8e1175bSopenharmony_ci */ 443a8e1175bSopenharmony_ci MBEDTLS_SSL_CHK_BUF_PTR(p, end, ext_len + 4); 444a8e1175bSopenharmony_ci 445a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_USE_SRTP, p, 0); 446a8e1175bSopenharmony_ci p += 2; 447a8e1175bSopenharmony_ci 448a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(ext_len, p, 0); 449a8e1175bSopenharmony_ci p += 2; 450a8e1175bSopenharmony_ci 451a8e1175bSopenharmony_ci /* protection profile length: 2*(ssl->conf->dtls_srtp_profile_list_len) */ 452a8e1175bSopenharmony_ci /* micro-optimization: 453a8e1175bSopenharmony_ci * the list size is limited to MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH 454a8e1175bSopenharmony_ci * which is lower than 127, so the upper byte of the length is always 0 455a8e1175bSopenharmony_ci * For the documentation, the more generic code is left in comments 456a8e1175bSopenharmony_ci * *p++ = (unsigned char)( ( ( 2 * ssl->conf->dtls_srtp_profile_list_len ) 457a8e1175bSopenharmony_ci * >> 8 ) & 0xFF ); 458a8e1175bSopenharmony_ci */ 459a8e1175bSopenharmony_ci *p++ = 0; 460a8e1175bSopenharmony_ci *p++ = MBEDTLS_BYTE_0(2 * ssl->conf->dtls_srtp_profile_list_len); 461a8e1175bSopenharmony_ci 462a8e1175bSopenharmony_ci for (protection_profiles_index = 0; 463a8e1175bSopenharmony_ci protection_profiles_index < ssl->conf->dtls_srtp_profile_list_len; 464a8e1175bSopenharmony_ci protection_profiles_index++) { 465a8e1175bSopenharmony_ci profile_value = mbedtls_ssl_check_srtp_profile_value 466a8e1175bSopenharmony_ci (ssl->conf->dtls_srtp_profile_list[protection_profiles_index]); 467a8e1175bSopenharmony_ci if (profile_value != MBEDTLS_TLS_SRTP_UNSET) { 468a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("ssl_write_use_srtp_ext, add profile: %04x", 469a8e1175bSopenharmony_ci profile_value)); 470a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(profile_value, p, 0); 471a8e1175bSopenharmony_ci p += 2; 472a8e1175bSopenharmony_ci } else { 473a8e1175bSopenharmony_ci /* 474a8e1175bSopenharmony_ci * Note: we shall never arrive here as protection profiles 475a8e1175bSopenharmony_ci * is checked by mbedtls_ssl_conf_dtls_srtp_protection_profiles function 476a8e1175bSopenharmony_ci */ 477a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, 478a8e1175bSopenharmony_ci ("client hello, " 479a8e1175bSopenharmony_ci "illegal DTLS-SRTP protection profile %d", 480a8e1175bSopenharmony_ci ssl->conf->dtls_srtp_profile_list[protection_profiles_index] 481a8e1175bSopenharmony_ci )); 482a8e1175bSopenharmony_ci return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 483a8e1175bSopenharmony_ci } 484a8e1175bSopenharmony_ci } 485a8e1175bSopenharmony_ci 486a8e1175bSopenharmony_ci *p++ = mki_len & 0xFF; 487a8e1175bSopenharmony_ci 488a8e1175bSopenharmony_ci if (mki_len != 0) { 489a8e1175bSopenharmony_ci memcpy(p, ssl->dtls_srtp_info.mki_value, mki_len); 490a8e1175bSopenharmony_ci /* 491a8e1175bSopenharmony_ci * Increment p to point to the current position. 492a8e1175bSopenharmony_ci */ 493a8e1175bSopenharmony_ci p += mki_len; 494a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "sending mki", ssl->dtls_srtp_info.mki_value, 495a8e1175bSopenharmony_ci ssl->dtls_srtp_info.mki_len); 496a8e1175bSopenharmony_ci } 497a8e1175bSopenharmony_ci 498a8e1175bSopenharmony_ci /* 499a8e1175bSopenharmony_ci * total extension length: extension type (2 bytes) 500a8e1175bSopenharmony_ci * + extension length (2 bytes) 501a8e1175bSopenharmony_ci * + protection profile length (2 bytes) 502a8e1175bSopenharmony_ci * + 2 * number of protection profiles 503a8e1175bSopenharmony_ci * + srtp_mki vector length(1 byte) 504a8e1175bSopenharmony_ci * + mki value 505a8e1175bSopenharmony_ci */ 506a8e1175bSopenharmony_ci *olen = p - buf; 507a8e1175bSopenharmony_ci 508a8e1175bSopenharmony_ci return 0; 509a8e1175bSopenharmony_ci} 510a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_SRTP */ 511a8e1175bSopenharmony_ci 512a8e1175bSopenharmony_ciint mbedtls_ssl_tls12_write_client_hello_exts(mbedtls_ssl_context *ssl, 513a8e1175bSopenharmony_ci unsigned char *buf, 514a8e1175bSopenharmony_ci const unsigned char *end, 515a8e1175bSopenharmony_ci int uses_ec, 516a8e1175bSopenharmony_ci size_t *out_len) 517a8e1175bSopenharmony_ci{ 518a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 519a8e1175bSopenharmony_ci unsigned char *p = buf; 520a8e1175bSopenharmony_ci size_t ext_len = 0; 521a8e1175bSopenharmony_ci 522a8e1175bSopenharmony_ci (void) ssl; 523a8e1175bSopenharmony_ci (void) end; 524a8e1175bSopenharmony_ci (void) uses_ec; 525a8e1175bSopenharmony_ci (void) ret; 526a8e1175bSopenharmony_ci (void) ext_len; 527a8e1175bSopenharmony_ci 528a8e1175bSopenharmony_ci *out_len = 0; 529a8e1175bSopenharmony_ci 530a8e1175bSopenharmony_ci /* Note that TLS_EMPTY_RENEGOTIATION_INFO_SCSV is always added 531a8e1175bSopenharmony_ci * even if MBEDTLS_SSL_RENEGOTIATION is not defined. */ 532a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 533a8e1175bSopenharmony_ci if ((ret = ssl_write_renegotiation_ext(ssl, p, end, &ext_len)) != 0) { 534a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_renegotiation_ext", ret); 535a8e1175bSopenharmony_ci return ret; 536a8e1175bSopenharmony_ci } 537a8e1175bSopenharmony_ci p += ext_len; 538a8e1175bSopenharmony_ci#endif 539a8e1175bSopenharmony_ci 540a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ 541a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ 542a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 543a8e1175bSopenharmony_ci if (uses_ec) { 544a8e1175bSopenharmony_ci if ((ret = ssl_write_supported_point_formats_ext(ssl, p, end, 545a8e1175bSopenharmony_ci &ext_len)) != 0) { 546a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_supported_point_formats_ext", ret); 547a8e1175bSopenharmony_ci return ret; 548a8e1175bSopenharmony_ci } 549a8e1175bSopenharmony_ci p += ext_len; 550a8e1175bSopenharmony_ci } 551a8e1175bSopenharmony_ci#endif 552a8e1175bSopenharmony_ci 553a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 554a8e1175bSopenharmony_ci if ((ret = ssl_write_ecjpake_kkpp_ext(ssl, p, end, &ext_len)) != 0) { 555a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_ecjpake_kkpp_ext", ret); 556a8e1175bSopenharmony_ci return ret; 557a8e1175bSopenharmony_ci } 558a8e1175bSopenharmony_ci p += ext_len; 559a8e1175bSopenharmony_ci#endif 560a8e1175bSopenharmony_ci 561a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 562a8e1175bSopenharmony_ci if ((ret = ssl_write_cid_ext(ssl, p, end, &ext_len)) != 0) { 563a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_cid_ext", ret); 564a8e1175bSopenharmony_ci return ret; 565a8e1175bSopenharmony_ci } 566a8e1175bSopenharmony_ci p += ext_len; 567a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 568a8e1175bSopenharmony_ci 569a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) 570a8e1175bSopenharmony_ci if ((ret = ssl_write_max_fragment_length_ext(ssl, p, end, 571a8e1175bSopenharmony_ci &ext_len)) != 0) { 572a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_max_fragment_length_ext", ret); 573a8e1175bSopenharmony_ci return ret; 574a8e1175bSopenharmony_ci } 575a8e1175bSopenharmony_ci p += ext_len; 576a8e1175bSopenharmony_ci#endif 577a8e1175bSopenharmony_ci 578a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 579a8e1175bSopenharmony_ci if ((ret = ssl_write_encrypt_then_mac_ext(ssl, p, end, &ext_len)) != 0) { 580a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_encrypt_then_mac_ext", ret); 581a8e1175bSopenharmony_ci return ret; 582a8e1175bSopenharmony_ci } 583a8e1175bSopenharmony_ci p += ext_len; 584a8e1175bSopenharmony_ci#endif 585a8e1175bSopenharmony_ci 586a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) 587a8e1175bSopenharmony_ci if ((ret = ssl_write_extended_ms_ext(ssl, p, end, &ext_len)) != 0) { 588a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_extended_ms_ext", ret); 589a8e1175bSopenharmony_ci return ret; 590a8e1175bSopenharmony_ci } 591a8e1175bSopenharmony_ci p += ext_len; 592a8e1175bSopenharmony_ci#endif 593a8e1175bSopenharmony_ci 594a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_SRTP) 595a8e1175bSopenharmony_ci if ((ret = ssl_write_use_srtp_ext(ssl, p, end, &ext_len)) != 0) { 596a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_use_srtp_ext", ret); 597a8e1175bSopenharmony_ci return ret; 598a8e1175bSopenharmony_ci } 599a8e1175bSopenharmony_ci p += ext_len; 600a8e1175bSopenharmony_ci#endif 601a8e1175bSopenharmony_ci 602a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) 603a8e1175bSopenharmony_ci if ((ret = ssl_write_session_ticket_ext(ssl, p, end, &ext_len)) != 0) { 604a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "ssl_write_session_ticket_ext", ret); 605a8e1175bSopenharmony_ci return ret; 606a8e1175bSopenharmony_ci } 607a8e1175bSopenharmony_ci p += ext_len; 608a8e1175bSopenharmony_ci#endif 609a8e1175bSopenharmony_ci 610a8e1175bSopenharmony_ci *out_len = (size_t) (p - buf); 611a8e1175bSopenharmony_ci 612a8e1175bSopenharmony_ci return 0; 613a8e1175bSopenharmony_ci} 614a8e1175bSopenharmony_ci 615a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 616a8e1175bSopenharmony_cistatic int ssl_parse_renegotiation_info(mbedtls_ssl_context *ssl, 617a8e1175bSopenharmony_ci const unsigned char *buf, 618a8e1175bSopenharmony_ci size_t len) 619a8e1175bSopenharmony_ci{ 620a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 621a8e1175bSopenharmony_ci if (ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE) { 622a8e1175bSopenharmony_ci /* Check verify-data in constant-time. The length OTOH is no secret */ 623a8e1175bSopenharmony_ci if (len != 1 + ssl->verify_data_len * 2 || 624a8e1175bSopenharmony_ci buf[0] != ssl->verify_data_len * 2 || 625a8e1175bSopenharmony_ci mbedtls_ct_memcmp(buf + 1, 626a8e1175bSopenharmony_ci ssl->own_verify_data, ssl->verify_data_len) != 0 || 627a8e1175bSopenharmony_ci mbedtls_ct_memcmp(buf + 1 + ssl->verify_data_len, 628a8e1175bSopenharmony_ci ssl->peer_verify_data, ssl->verify_data_len) != 0) { 629a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("non-matching renegotiation info")); 630a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 631a8e1175bSopenharmony_ci ssl, 632a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 633a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 634a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 635a8e1175bSopenharmony_ci } 636a8e1175bSopenharmony_ci } else 637a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_RENEGOTIATION */ 638a8e1175bSopenharmony_ci { 639a8e1175bSopenharmony_ci if (len != 1 || buf[0] != 0x00) { 640a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 641a8e1175bSopenharmony_ci ("non-zero length renegotiation info")); 642a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 643a8e1175bSopenharmony_ci ssl, 644a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 645a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 646a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 647a8e1175bSopenharmony_ci } 648a8e1175bSopenharmony_ci 649a8e1175bSopenharmony_ci ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; 650a8e1175bSopenharmony_ci } 651a8e1175bSopenharmony_ci 652a8e1175bSopenharmony_ci return 0; 653a8e1175bSopenharmony_ci} 654a8e1175bSopenharmony_ci 655a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) 656a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 657a8e1175bSopenharmony_cistatic int ssl_parse_max_fragment_length_ext(mbedtls_ssl_context *ssl, 658a8e1175bSopenharmony_ci const unsigned char *buf, 659a8e1175bSopenharmony_ci size_t len) 660a8e1175bSopenharmony_ci{ 661a8e1175bSopenharmony_ci /* 662a8e1175bSopenharmony_ci * server should use the extension only if we did, 663a8e1175bSopenharmony_ci * and if so the server's value should match ours (and len is always 1) 664a8e1175bSopenharmony_ci */ 665a8e1175bSopenharmony_ci if (ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE || 666a8e1175bSopenharmony_ci len != 1 || 667a8e1175bSopenharmony_ci buf[0] != ssl->conf->mfl_code) { 668a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 669a8e1175bSopenharmony_ci ("non-matching max fragment length extension")); 670a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 671a8e1175bSopenharmony_ci ssl, 672a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 673a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 674a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 675a8e1175bSopenharmony_ci } 676a8e1175bSopenharmony_ci 677a8e1175bSopenharmony_ci return 0; 678a8e1175bSopenharmony_ci} 679a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ 680a8e1175bSopenharmony_ci 681a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 682a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 683a8e1175bSopenharmony_cistatic int ssl_parse_cid_ext(mbedtls_ssl_context *ssl, 684a8e1175bSopenharmony_ci const unsigned char *buf, 685a8e1175bSopenharmony_ci size_t len) 686a8e1175bSopenharmony_ci{ 687a8e1175bSopenharmony_ci size_t peer_cid_len; 688a8e1175bSopenharmony_ci 689a8e1175bSopenharmony_ci if ( /* CID extension only makes sense in DTLS */ 690a8e1175bSopenharmony_ci ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM || 691a8e1175bSopenharmony_ci /* The server must only send the CID extension if we have offered it. */ 692a8e1175bSopenharmony_ci ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED) { 693a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension unexpected")); 694a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 695a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT); 696a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION; 697a8e1175bSopenharmony_ci } 698a8e1175bSopenharmony_ci 699a8e1175bSopenharmony_ci if (len == 0) { 700a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension invalid")); 701a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 702a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 703a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 704a8e1175bSopenharmony_ci } 705a8e1175bSopenharmony_ci 706a8e1175bSopenharmony_ci peer_cid_len = *buf++; 707a8e1175bSopenharmony_ci len--; 708a8e1175bSopenharmony_ci 709a8e1175bSopenharmony_ci if (peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX) { 710a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension invalid")); 711a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 712a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 713a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 714a8e1175bSopenharmony_ci } 715a8e1175bSopenharmony_ci 716a8e1175bSopenharmony_ci if (len != peer_cid_len) { 717a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("CID extension invalid")); 718a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 719a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 720a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 721a8e1175bSopenharmony_ci } 722a8e1175bSopenharmony_ci 723a8e1175bSopenharmony_ci ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED; 724a8e1175bSopenharmony_ci ssl->handshake->peer_cid_len = (uint8_t) peer_cid_len; 725a8e1175bSopenharmony_ci memcpy(ssl->handshake->peer_cid, buf, peer_cid_len); 726a8e1175bSopenharmony_ci 727a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("Use of CID extension negotiated")); 728a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "Server CID", buf, peer_cid_len); 729a8e1175bSopenharmony_ci 730a8e1175bSopenharmony_ci return 0; 731a8e1175bSopenharmony_ci} 732a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 733a8e1175bSopenharmony_ci 734a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 735a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 736a8e1175bSopenharmony_cistatic int ssl_parse_encrypt_then_mac_ext(mbedtls_ssl_context *ssl, 737a8e1175bSopenharmony_ci const unsigned char *buf, 738a8e1175bSopenharmony_ci size_t len) 739a8e1175bSopenharmony_ci{ 740a8e1175bSopenharmony_ci if (ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || 741a8e1175bSopenharmony_ci len != 0) { 742a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 743a8e1175bSopenharmony_ci ("non-matching encrypt-then-MAC extension")); 744a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 745a8e1175bSopenharmony_ci ssl, 746a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 747a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT); 748a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION; 749a8e1175bSopenharmony_ci } 750a8e1175bSopenharmony_ci 751a8e1175bSopenharmony_ci ((void) buf); 752a8e1175bSopenharmony_ci 753a8e1175bSopenharmony_ci ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; 754a8e1175bSopenharmony_ci 755a8e1175bSopenharmony_ci return 0; 756a8e1175bSopenharmony_ci} 757a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ 758a8e1175bSopenharmony_ci 759a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) 760a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 761a8e1175bSopenharmony_cistatic int ssl_parse_extended_ms_ext(mbedtls_ssl_context *ssl, 762a8e1175bSopenharmony_ci const unsigned char *buf, 763a8e1175bSopenharmony_ci size_t len) 764a8e1175bSopenharmony_ci{ 765a8e1175bSopenharmony_ci if (ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || 766a8e1175bSopenharmony_ci len != 0) { 767a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 768a8e1175bSopenharmony_ci ("non-matching extended master secret extension")); 769a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 770a8e1175bSopenharmony_ci ssl, 771a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 772a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT); 773a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION; 774a8e1175bSopenharmony_ci } 775a8e1175bSopenharmony_ci 776a8e1175bSopenharmony_ci ((void) buf); 777a8e1175bSopenharmony_ci 778a8e1175bSopenharmony_ci ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; 779a8e1175bSopenharmony_ci 780a8e1175bSopenharmony_ci return 0; 781a8e1175bSopenharmony_ci} 782a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ 783a8e1175bSopenharmony_ci 784a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) 785a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 786a8e1175bSopenharmony_cistatic int ssl_parse_session_ticket_ext(mbedtls_ssl_context *ssl, 787a8e1175bSopenharmony_ci const unsigned char *buf, 788a8e1175bSopenharmony_ci size_t len) 789a8e1175bSopenharmony_ci{ 790a8e1175bSopenharmony_ci if (ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED || 791a8e1175bSopenharmony_ci len != 0) { 792a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 793a8e1175bSopenharmony_ci ("non-matching session ticket extension")); 794a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 795a8e1175bSopenharmony_ci ssl, 796a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 797a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT); 798a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION; 799a8e1175bSopenharmony_ci } 800a8e1175bSopenharmony_ci 801a8e1175bSopenharmony_ci ((void) buf); 802a8e1175bSopenharmony_ci 803a8e1175bSopenharmony_ci ssl->handshake->new_session_ticket = 1; 804a8e1175bSopenharmony_ci 805a8e1175bSopenharmony_ci return 0; 806a8e1175bSopenharmony_ci} 807a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS */ 808a8e1175bSopenharmony_ci 809a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ 810a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ 811a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 812a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 813a8e1175bSopenharmony_cistatic int ssl_parse_supported_point_formats_ext(mbedtls_ssl_context *ssl, 814a8e1175bSopenharmony_ci const unsigned char *buf, 815a8e1175bSopenharmony_ci size_t len) 816a8e1175bSopenharmony_ci{ 817a8e1175bSopenharmony_ci size_t list_size; 818a8e1175bSopenharmony_ci const unsigned char *p; 819a8e1175bSopenharmony_ci 820a8e1175bSopenharmony_ci if (len == 0 || (size_t) (buf[0] + 1) != len) { 821a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 822a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 823a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 824a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 825a8e1175bSopenharmony_ci } 826a8e1175bSopenharmony_ci list_size = buf[0]; 827a8e1175bSopenharmony_ci 828a8e1175bSopenharmony_ci p = buf + 1; 829a8e1175bSopenharmony_ci while (list_size > 0) { 830a8e1175bSopenharmony_ci if (p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || 831a8e1175bSopenharmony_ci p[0] == MBEDTLS_ECP_PF_COMPRESSED) { 832a8e1175bSopenharmony_ci#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ 833a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) 834a8e1175bSopenharmony_ci ssl->handshake->ecdh_ctx.point_format = p[0]; 835a8e1175bSopenharmony_ci#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED */ 836a8e1175bSopenharmony_ci#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ 837a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 838a8e1175bSopenharmony_ci mbedtls_ecjpake_set_point_format(&ssl->handshake->ecjpake_ctx, 839a8e1175bSopenharmony_ci p[0]); 840a8e1175bSopenharmony_ci#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 841a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(4, ("point format selected: %d", p[0])); 842a8e1175bSopenharmony_ci return 0; 843a8e1175bSopenharmony_ci } 844a8e1175bSopenharmony_ci 845a8e1175bSopenharmony_ci list_size--; 846a8e1175bSopenharmony_ci p++; 847a8e1175bSopenharmony_ci } 848a8e1175bSopenharmony_ci 849a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("no point format in common")); 850a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 851a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 852a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 853a8e1175bSopenharmony_ci} 854a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || 855a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED || 856a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 857a8e1175bSopenharmony_ci 858a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 859a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 860a8e1175bSopenharmony_cistatic int ssl_parse_ecjpake_kkpp(mbedtls_ssl_context *ssl, 861a8e1175bSopenharmony_ci const unsigned char *buf, 862a8e1175bSopenharmony_ci size_t len) 863a8e1175bSopenharmony_ci{ 864a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 865a8e1175bSopenharmony_ci 866a8e1175bSopenharmony_ci if (ssl->handshake->ciphersuite_info->key_exchange != 867a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECJPAKE) { 868a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("skip ecjpake kkpp extension")); 869a8e1175bSopenharmony_ci return 0; 870a8e1175bSopenharmony_ci } 871a8e1175bSopenharmony_ci 872a8e1175bSopenharmony_ci /* If we got here, we no longer need our cached extension */ 873a8e1175bSopenharmony_ci mbedtls_free(ssl->handshake->ecjpake_cache); 874a8e1175bSopenharmony_ci ssl->handshake->ecjpake_cache = NULL; 875a8e1175bSopenharmony_ci ssl->handshake->ecjpake_cache_len = 0; 876a8e1175bSopenharmony_ci 877a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 878a8e1175bSopenharmony_ci if ((ret = mbedtls_psa_ecjpake_read_round( 879a8e1175bSopenharmony_ci &ssl->handshake->psa_pake_ctx, buf, len, 880a8e1175bSopenharmony_ci MBEDTLS_ECJPAKE_ROUND_ONE)) != 0) { 881a8e1175bSopenharmony_ci psa_destroy_key(ssl->handshake->psa_pake_password); 882a8e1175bSopenharmony_ci psa_pake_abort(&ssl->handshake->psa_pake_ctx); 883a8e1175bSopenharmony_ci 884a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round one", ret); 885a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 886a8e1175bSopenharmony_ci ssl, 887a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 888a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 889a8e1175bSopenharmony_ci return ret; 890a8e1175bSopenharmony_ci } 891a8e1175bSopenharmony_ci 892a8e1175bSopenharmony_ci return 0; 893a8e1175bSopenharmony_ci#else 894a8e1175bSopenharmony_ci if ((ret = mbedtls_ecjpake_read_round_one(&ssl->handshake->ecjpake_ctx, 895a8e1175bSopenharmony_ci buf, len)) != 0) { 896a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_one", ret); 897a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 898a8e1175bSopenharmony_ci ssl, 899a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 900a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 901a8e1175bSopenharmony_ci return ret; 902a8e1175bSopenharmony_ci } 903a8e1175bSopenharmony_ci 904a8e1175bSopenharmony_ci return 0; 905a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 906a8e1175bSopenharmony_ci} 907a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 908a8e1175bSopenharmony_ci 909a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ALPN) 910a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 911a8e1175bSopenharmony_cistatic int ssl_parse_alpn_ext(mbedtls_ssl_context *ssl, 912a8e1175bSopenharmony_ci const unsigned char *buf, size_t len) 913a8e1175bSopenharmony_ci{ 914a8e1175bSopenharmony_ci size_t list_len, name_len; 915a8e1175bSopenharmony_ci const char **p; 916a8e1175bSopenharmony_ci 917a8e1175bSopenharmony_ci /* If we didn't send it, the server shouldn't send it */ 918a8e1175bSopenharmony_ci if (ssl->conf->alpn_list == NULL) { 919a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("non-matching ALPN extension")); 920a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 921a8e1175bSopenharmony_ci ssl, 922a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 923a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT); 924a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION; 925a8e1175bSopenharmony_ci } 926a8e1175bSopenharmony_ci 927a8e1175bSopenharmony_ci /* 928a8e1175bSopenharmony_ci * opaque ProtocolName<1..2^8-1>; 929a8e1175bSopenharmony_ci * 930a8e1175bSopenharmony_ci * struct { 931a8e1175bSopenharmony_ci * ProtocolName protocol_name_list<2..2^16-1> 932a8e1175bSopenharmony_ci * } ProtocolNameList; 933a8e1175bSopenharmony_ci * 934a8e1175bSopenharmony_ci * the "ProtocolNameList" MUST contain exactly one "ProtocolName" 935a8e1175bSopenharmony_ci */ 936a8e1175bSopenharmony_ci 937a8e1175bSopenharmony_ci /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ 938a8e1175bSopenharmony_ci if (len < 4) { 939a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 940a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 941a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 942a8e1175bSopenharmony_ci } 943a8e1175bSopenharmony_ci 944a8e1175bSopenharmony_ci list_len = MBEDTLS_GET_UINT16_BE(buf, 0); 945a8e1175bSopenharmony_ci if (list_len != len - 2) { 946a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 947a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 948a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 949a8e1175bSopenharmony_ci } 950a8e1175bSopenharmony_ci 951a8e1175bSopenharmony_ci name_len = buf[2]; 952a8e1175bSopenharmony_ci if (name_len != list_len - 1) { 953a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 954a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 955a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 956a8e1175bSopenharmony_ci } 957a8e1175bSopenharmony_ci 958a8e1175bSopenharmony_ci /* Check that the server chosen protocol was in our list and save it */ 959a8e1175bSopenharmony_ci for (p = ssl->conf->alpn_list; *p != NULL; p++) { 960a8e1175bSopenharmony_ci if (name_len == strlen(*p) && 961a8e1175bSopenharmony_ci memcmp(buf + 3, *p, name_len) == 0) { 962a8e1175bSopenharmony_ci ssl->alpn_chosen = *p; 963a8e1175bSopenharmony_ci return 0; 964a8e1175bSopenharmony_ci } 965a8e1175bSopenharmony_ci } 966a8e1175bSopenharmony_ci 967a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("ALPN extension: no matching protocol")); 968a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 969a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 970a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 971a8e1175bSopenharmony_ci} 972a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ALPN */ 973a8e1175bSopenharmony_ci 974a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_SRTP) 975a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 976a8e1175bSopenharmony_cistatic int ssl_parse_use_srtp_ext(mbedtls_ssl_context *ssl, 977a8e1175bSopenharmony_ci const unsigned char *buf, 978a8e1175bSopenharmony_ci size_t len) 979a8e1175bSopenharmony_ci{ 980a8e1175bSopenharmony_ci mbedtls_ssl_srtp_profile server_protection = MBEDTLS_TLS_SRTP_UNSET; 981a8e1175bSopenharmony_ci size_t i, mki_len = 0; 982a8e1175bSopenharmony_ci uint16_t server_protection_profile_value = 0; 983a8e1175bSopenharmony_ci 984a8e1175bSopenharmony_ci /* If use_srtp is not configured, just ignore the extension */ 985a8e1175bSopenharmony_ci if ((ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM) || 986a8e1175bSopenharmony_ci (ssl->conf->dtls_srtp_profile_list == NULL) || 987a8e1175bSopenharmony_ci (ssl->conf->dtls_srtp_profile_list_len == 0)) { 988a8e1175bSopenharmony_ci return 0; 989a8e1175bSopenharmony_ci } 990a8e1175bSopenharmony_ci 991a8e1175bSopenharmony_ci /* RFC 5764 section 4.1.1 992a8e1175bSopenharmony_ci * uint8 SRTPProtectionProfile[2]; 993a8e1175bSopenharmony_ci * 994a8e1175bSopenharmony_ci * struct { 995a8e1175bSopenharmony_ci * SRTPProtectionProfiles SRTPProtectionProfiles; 996a8e1175bSopenharmony_ci * opaque srtp_mki<0..255>; 997a8e1175bSopenharmony_ci * } UseSRTPData; 998a8e1175bSopenharmony_ci 999a8e1175bSopenharmony_ci * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>; 1000a8e1175bSopenharmony_ci * 1001a8e1175bSopenharmony_ci */ 1002a8e1175bSopenharmony_ci if (ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED) { 1003a8e1175bSopenharmony_ci mki_len = ssl->dtls_srtp_info.mki_len; 1004a8e1175bSopenharmony_ci } 1005a8e1175bSopenharmony_ci 1006a8e1175bSopenharmony_ci /* 1007a8e1175bSopenharmony_ci * Length is 5 + optional mki_value : one protection profile length (2 bytes) 1008a8e1175bSopenharmony_ci * + protection profile (2 bytes) 1009a8e1175bSopenharmony_ci * + mki_len(1 byte) 1010a8e1175bSopenharmony_ci * and optional srtp_mki 1011a8e1175bSopenharmony_ci */ 1012a8e1175bSopenharmony_ci if ((len < 5) || (len != (buf[4] + 5u))) { 1013a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1014a8e1175bSopenharmony_ci } 1015a8e1175bSopenharmony_ci 1016a8e1175bSopenharmony_ci /* 1017a8e1175bSopenharmony_ci * get the server protection profile 1018a8e1175bSopenharmony_ci */ 1019a8e1175bSopenharmony_ci 1020a8e1175bSopenharmony_ci /* 1021a8e1175bSopenharmony_ci * protection profile length must be 0x0002 as we must have only 1022a8e1175bSopenharmony_ci * one protection profile in server Hello 1023a8e1175bSopenharmony_ci */ 1024a8e1175bSopenharmony_ci if ((buf[0] != 0) || (buf[1] != 2)) { 1025a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1026a8e1175bSopenharmony_ci } 1027a8e1175bSopenharmony_ci 1028a8e1175bSopenharmony_ci server_protection_profile_value = (buf[2] << 8) | buf[3]; 1029a8e1175bSopenharmony_ci server_protection = mbedtls_ssl_check_srtp_profile_value( 1030a8e1175bSopenharmony_ci server_protection_profile_value); 1031a8e1175bSopenharmony_ci if (server_protection != MBEDTLS_TLS_SRTP_UNSET) { 1032a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found srtp profile: %s", 1033a8e1175bSopenharmony_ci mbedtls_ssl_get_srtp_profile_as_string( 1034a8e1175bSopenharmony_ci server_protection))); 1035a8e1175bSopenharmony_ci } 1036a8e1175bSopenharmony_ci 1037a8e1175bSopenharmony_ci ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET; 1038a8e1175bSopenharmony_ci 1039a8e1175bSopenharmony_ci /* 1040a8e1175bSopenharmony_ci * Check we have the server profile in our list 1041a8e1175bSopenharmony_ci */ 1042a8e1175bSopenharmony_ci for (i = 0; i < ssl->conf->dtls_srtp_profile_list_len; i++) { 1043a8e1175bSopenharmony_ci if (server_protection == ssl->conf->dtls_srtp_profile_list[i]) { 1044a8e1175bSopenharmony_ci ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i]; 1045a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("selected srtp profile: %s", 1046a8e1175bSopenharmony_ci mbedtls_ssl_get_srtp_profile_as_string( 1047a8e1175bSopenharmony_ci server_protection))); 1048a8e1175bSopenharmony_ci break; 1049a8e1175bSopenharmony_ci } 1050a8e1175bSopenharmony_ci } 1051a8e1175bSopenharmony_ci 1052a8e1175bSopenharmony_ci /* If no match was found : server problem, it shall never answer with incompatible profile */ 1053a8e1175bSopenharmony_ci if (ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET) { 1054a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1055a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 1056a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 1057a8e1175bSopenharmony_ci } 1058a8e1175bSopenharmony_ci 1059a8e1175bSopenharmony_ci /* If server does not use mki in its reply, make sure the client won't keep 1060a8e1175bSopenharmony_ci * one as negotiated */ 1061a8e1175bSopenharmony_ci if (len == 5) { 1062a8e1175bSopenharmony_ci ssl->dtls_srtp_info.mki_len = 0; 1063a8e1175bSopenharmony_ci } 1064a8e1175bSopenharmony_ci 1065a8e1175bSopenharmony_ci /* 1066a8e1175bSopenharmony_ci * RFC5764: 1067a8e1175bSopenharmony_ci * If the client detects a nonzero-length MKI in the server's response 1068a8e1175bSopenharmony_ci * that is different than the one the client offered, then the client 1069a8e1175bSopenharmony_ci * MUST abort the handshake and SHOULD send an invalid_parameter alert. 1070a8e1175bSopenharmony_ci */ 1071a8e1175bSopenharmony_ci if (len > 5 && (buf[4] != mki_len || 1072a8e1175bSopenharmony_ci (memcmp(ssl->dtls_srtp_info.mki_value, &buf[5], mki_len)))) { 1073a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1074a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 1075a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 1076a8e1175bSopenharmony_ci } 1077a8e1175bSopenharmony_ci#if defined(MBEDTLS_DEBUG_C) 1078a8e1175bSopenharmony_ci if (len > 5) { 1079a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "received mki", ssl->dtls_srtp_info.mki_value, 1080a8e1175bSopenharmony_ci ssl->dtls_srtp_info.mki_len); 1081a8e1175bSopenharmony_ci } 1082a8e1175bSopenharmony_ci#endif 1083a8e1175bSopenharmony_ci return 0; 1084a8e1175bSopenharmony_ci} 1085a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_SRTP */ 1086a8e1175bSopenharmony_ci 1087a8e1175bSopenharmony_ci/* 1088a8e1175bSopenharmony_ci * Parse HelloVerifyRequest. Only called after verifying the HS type. 1089a8e1175bSopenharmony_ci */ 1090a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS) 1091a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 1092a8e1175bSopenharmony_cistatic int ssl_parse_hello_verify_request(mbedtls_ssl_context *ssl) 1093a8e1175bSopenharmony_ci{ 1094a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 1095a8e1175bSopenharmony_ci const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl); 1096a8e1175bSopenharmony_ci uint16_t dtls_legacy_version; 1097a8e1175bSopenharmony_ci 1098a8e1175bSopenharmony_ci#if !defined(MBEDTLS_SSL_PROTO_TLS1_3) 1099a8e1175bSopenharmony_ci uint8_t cookie_len; 1100a8e1175bSopenharmony_ci#else 1101a8e1175bSopenharmony_ci uint16_t cookie_len; 1102a8e1175bSopenharmony_ci#endif 1103a8e1175bSopenharmony_ci 1104a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse hello verify request")); 1105a8e1175bSopenharmony_ci 1106a8e1175bSopenharmony_ci /* Check that there is enough room for: 1107a8e1175bSopenharmony_ci * - 2 bytes of version 1108a8e1175bSopenharmony_ci * - 1 byte of cookie_len 1109a8e1175bSopenharmony_ci */ 1110a8e1175bSopenharmony_ci if (mbedtls_ssl_hs_hdr_len(ssl) + 3 > ssl->in_msglen) { 1111a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 1112a8e1175bSopenharmony_ci ("incoming HelloVerifyRequest message is too short")); 1113a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1114a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 1115a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1116a8e1175bSopenharmony_ci } 1117a8e1175bSopenharmony_ci 1118a8e1175bSopenharmony_ci /* 1119a8e1175bSopenharmony_ci * struct { 1120a8e1175bSopenharmony_ci * ProtocolVersion server_version; 1121a8e1175bSopenharmony_ci * opaque cookie<0..2^8-1>; 1122a8e1175bSopenharmony_ci * } HelloVerifyRequest; 1123a8e1175bSopenharmony_ci */ 1124a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "server version", p, 2); 1125a8e1175bSopenharmony_ci dtls_legacy_version = MBEDTLS_GET_UINT16_BE(p, 0); 1126a8e1175bSopenharmony_ci p += 2; 1127a8e1175bSopenharmony_ci 1128a8e1175bSopenharmony_ci /* 1129a8e1175bSopenharmony_ci * Since the RFC is not clear on this point, accept DTLS 1.0 (0xfeff) 1130a8e1175bSopenharmony_ci * The DTLS 1.3 (current draft) renames ProtocolVersion server_version to 1131a8e1175bSopenharmony_ci * legacy_version and locks the value of legacy_version to 0xfefd (DTLS 1.2) 1132a8e1175bSopenharmony_ci */ 1133a8e1175bSopenharmony_ci if (dtls_legacy_version != 0xfefd && dtls_legacy_version != 0xfeff) { 1134a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server version")); 1135a8e1175bSopenharmony_ci 1136a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1137a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION); 1138a8e1175bSopenharmony_ci 1139a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION; 1140a8e1175bSopenharmony_ci } 1141a8e1175bSopenharmony_ci 1142a8e1175bSopenharmony_ci cookie_len = *p++; 1143a8e1175bSopenharmony_ci if ((ssl->in_msg + ssl->in_msglen) - p < cookie_len) { 1144a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 1145a8e1175bSopenharmony_ci ("cookie length does not match incoming message size")); 1146a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1147a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 1148a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1149a8e1175bSopenharmony_ci } 1150a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "cookie", p, cookie_len); 1151a8e1175bSopenharmony_ci 1152a8e1175bSopenharmony_ci mbedtls_free(ssl->handshake->cookie); 1153a8e1175bSopenharmony_ci 1154a8e1175bSopenharmony_ci ssl->handshake->cookie = mbedtls_calloc(1, cookie_len); 1155a8e1175bSopenharmony_ci if (ssl->handshake->cookie == NULL) { 1156a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("alloc failed (%d bytes)", cookie_len)); 1157a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ALLOC_FAILED; 1158a8e1175bSopenharmony_ci } 1159a8e1175bSopenharmony_ci 1160a8e1175bSopenharmony_ci memcpy(ssl->handshake->cookie, p, cookie_len); 1161a8e1175bSopenharmony_ci ssl->handshake->cookie_len = cookie_len; 1162a8e1175bSopenharmony_ci 1163a8e1175bSopenharmony_ci /* Start over at ClientHello */ 1164a8e1175bSopenharmony_ci ssl->state = MBEDTLS_SSL_CLIENT_HELLO; 1165a8e1175bSopenharmony_ci ret = mbedtls_ssl_reset_checksum(ssl); 1166a8e1175bSopenharmony_ci if (0 != ret) { 1167a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ssl_reset_checksum"), ret); 1168a8e1175bSopenharmony_ci return ret; 1169a8e1175bSopenharmony_ci } 1170a8e1175bSopenharmony_ci 1171a8e1175bSopenharmony_ci mbedtls_ssl_recv_flight_completed(ssl); 1172a8e1175bSopenharmony_ci 1173a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse hello verify request")); 1174a8e1175bSopenharmony_ci 1175a8e1175bSopenharmony_ci return 0; 1176a8e1175bSopenharmony_ci} 1177a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */ 1178a8e1175bSopenharmony_ci 1179a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 1180a8e1175bSopenharmony_cistatic int ssl_parse_server_hello(mbedtls_ssl_context *ssl) 1181a8e1175bSopenharmony_ci{ 1182a8e1175bSopenharmony_ci int ret, i; 1183a8e1175bSopenharmony_ci size_t n; 1184a8e1175bSopenharmony_ci size_t ext_len; 1185a8e1175bSopenharmony_ci unsigned char *buf, *ext; 1186a8e1175bSopenharmony_ci unsigned char comp; 1187a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 1188a8e1175bSopenharmony_ci int renegotiation_info_seen = 0; 1189a8e1175bSopenharmony_ci#endif 1190a8e1175bSopenharmony_ci int handshake_failure = 0; 1191a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *suite_info; 1192a8e1175bSopenharmony_ci 1193a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse server hello")); 1194a8e1175bSopenharmony_ci 1195a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { 1196a8e1175bSopenharmony_ci /* No alert on a read error. */ 1197a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); 1198a8e1175bSopenharmony_ci return ret; 1199a8e1175bSopenharmony_ci } 1200a8e1175bSopenharmony_ci 1201a8e1175bSopenharmony_ci buf = ssl->in_msg; 1202a8e1175bSopenharmony_ci 1203a8e1175bSopenharmony_ci if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { 1204a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 1205a8e1175bSopenharmony_ci if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS) { 1206a8e1175bSopenharmony_ci ssl->renego_records_seen++; 1207a8e1175bSopenharmony_ci 1208a8e1175bSopenharmony_ci if (ssl->conf->renego_max_records >= 0 && 1209a8e1175bSopenharmony_ci ssl->renego_records_seen > ssl->conf->renego_max_records) { 1210a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 1211a8e1175bSopenharmony_ci ("renegotiation requested, but not honored by server")); 1212a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 1213a8e1175bSopenharmony_ci } 1214a8e1175bSopenharmony_ci 1215a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 1216a8e1175bSopenharmony_ci ("non-handshake message during renegotiation")); 1217a8e1175bSopenharmony_ci 1218a8e1175bSopenharmony_ci ssl->keep_current_message = 1; 1219a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO; 1220a8e1175bSopenharmony_ci } 1221a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_RENEGOTIATION */ 1222a8e1175bSopenharmony_ci 1223a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 1224a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 1225a8e1175bSopenharmony_ci ssl, 1226a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1227a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); 1228a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 1229a8e1175bSopenharmony_ci } 1230a8e1175bSopenharmony_ci 1231a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS) 1232a8e1175bSopenharmony_ci if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 1233a8e1175bSopenharmony_ci if (buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST) { 1234a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("received hello verify request")); 1235a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server hello")); 1236a8e1175bSopenharmony_ci return ssl_parse_hello_verify_request(ssl); 1237a8e1175bSopenharmony_ci } else { 1238a8e1175bSopenharmony_ci /* We made it through the verification process */ 1239a8e1175bSopenharmony_ci mbedtls_free(ssl->handshake->cookie); 1240a8e1175bSopenharmony_ci ssl->handshake->cookie = NULL; 1241a8e1175bSopenharmony_ci ssl->handshake->cookie_len = 0; 1242a8e1175bSopenharmony_ci } 1243a8e1175bSopenharmony_ci } 1244a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_PROTO_DTLS */ 1245a8e1175bSopenharmony_ci 1246a8e1175bSopenharmony_ci if (ssl->in_hslen < 38 + mbedtls_ssl_hs_hdr_len(ssl) || 1247a8e1175bSopenharmony_ci buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO) { 1248a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 1249a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1250a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 1251a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1252a8e1175bSopenharmony_ci } 1253a8e1175bSopenharmony_ci 1254a8e1175bSopenharmony_ci /* 1255a8e1175bSopenharmony_ci * 0 . 1 server_version 1256a8e1175bSopenharmony_ci * 2 . 33 random (maybe including 4 bytes of Unix time) 1257a8e1175bSopenharmony_ci * 34 . 34 session_id length = n 1258a8e1175bSopenharmony_ci * 35 . 34+n session_id 1259a8e1175bSopenharmony_ci * 35+n . 36+n cipher_suite 1260a8e1175bSopenharmony_ci * 37+n . 37+n compression_method 1261a8e1175bSopenharmony_ci * 1262a8e1175bSopenharmony_ci * 38+n . 39+n extensions length (optional) 1263a8e1175bSopenharmony_ci * 40+n . .. extensions 1264a8e1175bSopenharmony_ci */ 1265a8e1175bSopenharmony_ci buf += mbedtls_ssl_hs_hdr_len(ssl); 1266a8e1175bSopenharmony_ci 1267a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "server hello, version", buf, 2); 1268a8e1175bSopenharmony_ci ssl->tls_version = (mbedtls_ssl_protocol_version) mbedtls_ssl_read_version(buf, 1269a8e1175bSopenharmony_ci ssl->conf->transport); 1270a8e1175bSopenharmony_ci ssl->session_negotiate->tls_version = ssl->tls_version; 1271a8e1175bSopenharmony_ci ssl->session_negotiate->endpoint = ssl->conf->endpoint; 1272a8e1175bSopenharmony_ci 1273a8e1175bSopenharmony_ci if (ssl->tls_version < ssl->conf->min_tls_version || 1274a8e1175bSopenharmony_ci ssl->tls_version > ssl->conf->max_tls_version) { 1275a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 1276a8e1175bSopenharmony_ci ( 1277a8e1175bSopenharmony_ci "server version out of bounds - min: [0x%x], server: [0x%x], max: [0x%x]", 1278a8e1175bSopenharmony_ci (unsigned) ssl->conf->min_tls_version, 1279a8e1175bSopenharmony_ci (unsigned) ssl->tls_version, 1280a8e1175bSopenharmony_ci (unsigned) ssl->conf->max_tls_version)); 1281a8e1175bSopenharmony_ci 1282a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1283a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION); 1284a8e1175bSopenharmony_ci 1285a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION; 1286a8e1175bSopenharmony_ci } 1287a8e1175bSopenharmony_ci 1288a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, current time: %lu", 1289a8e1175bSopenharmony_ci ((unsigned long) buf[2] << 24) | 1290a8e1175bSopenharmony_ci ((unsigned long) buf[3] << 16) | 1291a8e1175bSopenharmony_ci ((unsigned long) buf[4] << 8) | 1292a8e1175bSopenharmony_ci ((unsigned long) buf[5]))); 1293a8e1175bSopenharmony_ci 1294a8e1175bSopenharmony_ci memcpy(ssl->handshake->randbytes + 32, buf + 2, 32); 1295a8e1175bSopenharmony_ci 1296a8e1175bSopenharmony_ci n = buf[34]; 1297a8e1175bSopenharmony_ci 1298a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "server hello, random bytes", buf + 2, 32); 1299a8e1175bSopenharmony_ci 1300a8e1175bSopenharmony_ci if (n > 32) { 1301a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 1302a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1303a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 1304a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1305a8e1175bSopenharmony_ci } 1306a8e1175bSopenharmony_ci 1307a8e1175bSopenharmony_ci if (ssl->in_hslen > mbedtls_ssl_hs_hdr_len(ssl) + 39 + n) { 1308a8e1175bSopenharmony_ci ext_len = MBEDTLS_GET_UINT16_BE(buf, 38 + n); 1309a8e1175bSopenharmony_ci 1310a8e1175bSopenharmony_ci if ((ext_len > 0 && ext_len < 4) || 1311a8e1175bSopenharmony_ci ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl) + 40 + n + ext_len) { 1312a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 1313a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 1314a8e1175bSopenharmony_ci ssl, 1315a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1316a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 1317a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1318a8e1175bSopenharmony_ci } 1319a8e1175bSopenharmony_ci } else if (ssl->in_hslen == mbedtls_ssl_hs_hdr_len(ssl) + 38 + n) { 1320a8e1175bSopenharmony_ci ext_len = 0; 1321a8e1175bSopenharmony_ci } else { 1322a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server 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 1328a8e1175bSopenharmony_ci /* ciphersuite (used later) */ 1329a8e1175bSopenharmony_ci i = (int) MBEDTLS_GET_UINT16_BE(buf, n + 35); 1330a8e1175bSopenharmony_ci 1331a8e1175bSopenharmony_ci /* 1332a8e1175bSopenharmony_ci * Read and check compression 1333a8e1175bSopenharmony_ci */ 1334a8e1175bSopenharmony_ci comp = buf[37 + n]; 1335a8e1175bSopenharmony_ci 1336a8e1175bSopenharmony_ci if (comp != MBEDTLS_SSL_COMPRESS_NULL) { 1337a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 1338a8e1175bSopenharmony_ci ("server hello, bad compression: %d", comp)); 1339a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 1340a8e1175bSopenharmony_ci ssl, 1341a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1342a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 1343a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 1344a8e1175bSopenharmony_ci } 1345a8e1175bSopenharmony_ci 1346a8e1175bSopenharmony_ci /* 1347a8e1175bSopenharmony_ci * Initialize update checksum functions 1348a8e1175bSopenharmony_ci */ 1349a8e1175bSopenharmony_ci ssl->handshake->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id(i); 1350a8e1175bSopenharmony_ci if (ssl->handshake->ciphersuite_info == NULL) { 1351a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 1352a8e1175bSopenharmony_ci ("ciphersuite info for %04x not found", (unsigned int) i)); 1353a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1354a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR); 1355a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 1356a8e1175bSopenharmony_ci } 1357a8e1175bSopenharmony_ci 1358a8e1175bSopenharmony_ci mbedtls_ssl_optimize_checksum(ssl, ssl->handshake->ciphersuite_info); 1359a8e1175bSopenharmony_ci 1360a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, session id len.: %" MBEDTLS_PRINTF_SIZET, n)); 1361a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "server hello, session id", buf + 35, n); 1362a8e1175bSopenharmony_ci 1363a8e1175bSopenharmony_ci /* 1364a8e1175bSopenharmony_ci * Check if the session can be resumed 1365a8e1175bSopenharmony_ci */ 1366a8e1175bSopenharmony_ci if (ssl->handshake->resume == 0 || n == 0 || 1367a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 1368a8e1175bSopenharmony_ci ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE || 1369a8e1175bSopenharmony_ci#endif 1370a8e1175bSopenharmony_ci ssl->session_negotiate->ciphersuite != i || 1371a8e1175bSopenharmony_ci ssl->session_negotiate->id_len != n || 1372a8e1175bSopenharmony_ci memcmp(ssl->session_negotiate->id, buf + 35, n) != 0) { 1373a8e1175bSopenharmony_ci ssl->state++; 1374a8e1175bSopenharmony_ci ssl->handshake->resume = 0; 1375a8e1175bSopenharmony_ci#if defined(MBEDTLS_HAVE_TIME) 1376a8e1175bSopenharmony_ci ssl->session_negotiate->start = mbedtls_time(NULL); 1377a8e1175bSopenharmony_ci#endif 1378a8e1175bSopenharmony_ci ssl->session_negotiate->ciphersuite = i; 1379a8e1175bSopenharmony_ci ssl->session_negotiate->id_len = n; 1380a8e1175bSopenharmony_ci memcpy(ssl->session_negotiate->id, buf + 35, n); 1381a8e1175bSopenharmony_ci } else { 1382a8e1175bSopenharmony_ci ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; 1383a8e1175bSopenharmony_ci } 1384a8e1175bSopenharmony_ci 1385a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("%s session has been resumed", 1386a8e1175bSopenharmony_ci ssl->handshake->resume ? "a" : "no")); 1387a8e1175bSopenharmony_ci 1388a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, chosen ciphersuite: %04x", (unsigned) i)); 1389a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("server hello, compress alg.: %d", 1390a8e1175bSopenharmony_ci buf[37 + n])); 1391a8e1175bSopenharmony_ci 1392a8e1175bSopenharmony_ci /* 1393a8e1175bSopenharmony_ci * Perform cipher suite validation in same way as in ssl_write_client_hello. 1394a8e1175bSopenharmony_ci */ 1395a8e1175bSopenharmony_ci i = 0; 1396a8e1175bSopenharmony_ci while (1) { 1397a8e1175bSopenharmony_ci if (ssl->conf->ciphersuite_list[i] == 0) { 1398a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 1399a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 1400a8e1175bSopenharmony_ci ssl, 1401a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1402a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 1403a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 1404a8e1175bSopenharmony_ci } 1405a8e1175bSopenharmony_ci 1406a8e1175bSopenharmony_ci if (ssl->conf->ciphersuite_list[i++] == 1407a8e1175bSopenharmony_ci ssl->session_negotiate->ciphersuite) { 1408a8e1175bSopenharmony_ci break; 1409a8e1175bSopenharmony_ci } 1410a8e1175bSopenharmony_ci } 1411a8e1175bSopenharmony_ci 1412a8e1175bSopenharmony_ci suite_info = mbedtls_ssl_ciphersuite_from_id( 1413a8e1175bSopenharmony_ci ssl->session_negotiate->ciphersuite); 1414a8e1175bSopenharmony_ci if (mbedtls_ssl_validate_ciphersuite(ssl, suite_info, ssl->tls_version, 1415a8e1175bSopenharmony_ci ssl->tls_version) != 0) { 1416a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 1417a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 1418a8e1175bSopenharmony_ci ssl, 1419a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1420a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 1421a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 1422a8e1175bSopenharmony_ci } 1423a8e1175bSopenharmony_ci 1424a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, 1425a8e1175bSopenharmony_ci ("server hello, chosen ciphersuite: %s", suite_info->name)); 1426a8e1175bSopenharmony_ci 1427a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 1428a8e1175bSopenharmony_ci if (suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA && 1429a8e1175bSopenharmony_ci ssl->tls_version == MBEDTLS_SSL_VERSION_TLS1_2) { 1430a8e1175bSopenharmony_ci ssl->handshake->ecrs_enabled = 1; 1431a8e1175bSopenharmony_ci } 1432a8e1175bSopenharmony_ci#endif 1433a8e1175bSopenharmony_ci 1434a8e1175bSopenharmony_ci if (comp != MBEDTLS_SSL_COMPRESS_NULL) { 1435a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 1436a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 1437a8e1175bSopenharmony_ci ssl, 1438a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1439a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 1440a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 1441a8e1175bSopenharmony_ci } 1442a8e1175bSopenharmony_ci 1443a8e1175bSopenharmony_ci ext = buf + 40 + n; 1444a8e1175bSopenharmony_ci 1445a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, 1446a8e1175bSopenharmony_ci ("server hello, total extension length: %" MBEDTLS_PRINTF_SIZET, 1447a8e1175bSopenharmony_ci ext_len)); 1448a8e1175bSopenharmony_ci 1449a8e1175bSopenharmony_ci while (ext_len) { 1450a8e1175bSopenharmony_ci unsigned int ext_id = MBEDTLS_GET_UINT16_BE(ext, 0); 1451a8e1175bSopenharmony_ci unsigned int ext_size = MBEDTLS_GET_UINT16_BE(ext, 2); 1452a8e1175bSopenharmony_ci 1453a8e1175bSopenharmony_ci if (ext_size + 4 > ext_len) { 1454a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 1455a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 1456a8e1175bSopenharmony_ci ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1457a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 1458a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1459a8e1175bSopenharmony_ci } 1460a8e1175bSopenharmony_ci 1461a8e1175bSopenharmony_ci switch (ext_id) { 1462a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO: 1463a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found renegotiation extension")); 1464a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 1465a8e1175bSopenharmony_ci renegotiation_info_seen = 1; 1466a8e1175bSopenharmony_ci#endif 1467a8e1175bSopenharmony_ci 1468a8e1175bSopenharmony_ci if ((ret = ssl_parse_renegotiation_info(ssl, ext + 4, 1469a8e1175bSopenharmony_ci ext_size)) != 0) { 1470a8e1175bSopenharmony_ci return ret; 1471a8e1175bSopenharmony_ci } 1472a8e1175bSopenharmony_ci 1473a8e1175bSopenharmony_ci break; 1474a8e1175bSopenharmony_ci 1475a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) 1476a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: 1477a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, 1478a8e1175bSopenharmony_ci ("found max_fragment_length extension")); 1479a8e1175bSopenharmony_ci 1480a8e1175bSopenharmony_ci if ((ret = ssl_parse_max_fragment_length_ext(ssl, 1481a8e1175bSopenharmony_ci ext + 4, ext_size)) != 0) { 1482a8e1175bSopenharmony_ci return ret; 1483a8e1175bSopenharmony_ci } 1484a8e1175bSopenharmony_ci 1485a8e1175bSopenharmony_ci break; 1486a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ 1487a8e1175bSopenharmony_ci 1488a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) 1489a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_CID: 1490a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found CID extension")); 1491a8e1175bSopenharmony_ci 1492a8e1175bSopenharmony_ci if ((ret = ssl_parse_cid_ext(ssl, 1493a8e1175bSopenharmony_ci ext + 4, 1494a8e1175bSopenharmony_ci ext_size)) != 0) { 1495a8e1175bSopenharmony_ci return ret; 1496a8e1175bSopenharmony_ci } 1497a8e1175bSopenharmony_ci 1498a8e1175bSopenharmony_ci break; 1499a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ 1500a8e1175bSopenharmony_ci 1501a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) 1502a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: 1503a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found encrypt_then_mac extension")); 1504a8e1175bSopenharmony_ci 1505a8e1175bSopenharmony_ci if ((ret = ssl_parse_encrypt_then_mac_ext(ssl, 1506a8e1175bSopenharmony_ci ext + 4, ext_size)) != 0) { 1507a8e1175bSopenharmony_ci return ret; 1508a8e1175bSopenharmony_ci } 1509a8e1175bSopenharmony_ci 1510a8e1175bSopenharmony_ci break; 1511a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ 1512a8e1175bSopenharmony_ci 1513a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) 1514a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET: 1515a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, 1516a8e1175bSopenharmony_ci ("found extended_master_secret extension")); 1517a8e1175bSopenharmony_ci 1518a8e1175bSopenharmony_ci if ((ret = ssl_parse_extended_ms_ext(ssl, 1519a8e1175bSopenharmony_ci ext + 4, ext_size)) != 0) { 1520a8e1175bSopenharmony_ci return ret; 1521a8e1175bSopenharmony_ci } 1522a8e1175bSopenharmony_ci 1523a8e1175bSopenharmony_ci break; 1524a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ 1525a8e1175bSopenharmony_ci 1526a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) 1527a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_SESSION_TICKET: 1528a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found session_ticket extension")); 1529a8e1175bSopenharmony_ci 1530a8e1175bSopenharmony_ci if ((ret = ssl_parse_session_ticket_ext(ssl, 1531a8e1175bSopenharmony_ci ext + 4, ext_size)) != 0) { 1532a8e1175bSopenharmony_ci return ret; 1533a8e1175bSopenharmony_ci } 1534a8e1175bSopenharmony_ci 1535a8e1175bSopenharmony_ci break; 1536a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS */ 1537a8e1175bSopenharmony_ci 1538a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED) || \ 1539a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED) || \ 1540a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 1541a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: 1542a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, 1543a8e1175bSopenharmony_ci ("found supported_point_formats extension")); 1544a8e1175bSopenharmony_ci 1545a8e1175bSopenharmony_ci if ((ret = ssl_parse_supported_point_formats_ext(ssl, 1546a8e1175bSopenharmony_ci ext + 4, ext_size)) != 0) { 1547a8e1175bSopenharmony_ci return ret; 1548a8e1175bSopenharmony_ci } 1549a8e1175bSopenharmony_ci 1550a8e1175bSopenharmony_ci break; 1551a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_OR_ECDHE_1_2_ENABLED || 1552a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDSA_CERT_REQ_ALLOWED_ENABLED || 1553a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 1554a8e1175bSopenharmony_ci 1555a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 1556a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_ECJPAKE_KKPP: 1557a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found ecjpake_kkpp extension")); 1558a8e1175bSopenharmony_ci 1559a8e1175bSopenharmony_ci if ((ret = ssl_parse_ecjpake_kkpp(ssl, 1560a8e1175bSopenharmony_ci ext + 4, ext_size)) != 0) { 1561a8e1175bSopenharmony_ci return ret; 1562a8e1175bSopenharmony_ci } 1563a8e1175bSopenharmony_ci 1564a8e1175bSopenharmony_ci break; 1565a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 1566a8e1175bSopenharmony_ci 1567a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ALPN) 1568a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_ALPN: 1569a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found alpn extension")); 1570a8e1175bSopenharmony_ci 1571a8e1175bSopenharmony_ci if ((ret = ssl_parse_alpn_ext(ssl, ext + 4, ext_size)) != 0) { 1572a8e1175bSopenharmony_ci return ret; 1573a8e1175bSopenharmony_ci } 1574a8e1175bSopenharmony_ci 1575a8e1175bSopenharmony_ci break; 1576a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_ALPN */ 1577a8e1175bSopenharmony_ci 1578a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_DTLS_SRTP) 1579a8e1175bSopenharmony_ci case MBEDTLS_TLS_EXT_USE_SRTP: 1580a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("found use_srtp extension")); 1581a8e1175bSopenharmony_ci 1582a8e1175bSopenharmony_ci if ((ret = ssl_parse_use_srtp_ext(ssl, ext + 4, ext_size)) != 0) { 1583a8e1175bSopenharmony_ci return ret; 1584a8e1175bSopenharmony_ci } 1585a8e1175bSopenharmony_ci 1586a8e1175bSopenharmony_ci break; 1587a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_DTLS_SRTP */ 1588a8e1175bSopenharmony_ci 1589a8e1175bSopenharmony_ci default: 1590a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, 1591a8e1175bSopenharmony_ci ("unknown extension found: %u (ignoring)", ext_id)); 1592a8e1175bSopenharmony_ci } 1593a8e1175bSopenharmony_ci 1594a8e1175bSopenharmony_ci ext_len -= 4 + ext_size; 1595a8e1175bSopenharmony_ci ext += 4 + ext_size; 1596a8e1175bSopenharmony_ci 1597a8e1175bSopenharmony_ci if (ext_len > 0 && ext_len < 4) { 1598a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello message")); 1599a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1600a8e1175bSopenharmony_ci } 1601a8e1175bSopenharmony_ci } 1602a8e1175bSopenharmony_ci 1603a8e1175bSopenharmony_ci /* 1604a8e1175bSopenharmony_ci * mbedtls_ssl_derive_keys() has to be called after the parsing of the 1605a8e1175bSopenharmony_ci * extensions. It sets the transform data for the resumed session which in 1606a8e1175bSopenharmony_ci * case of DTLS includes the server CID extracted from the CID extension. 1607a8e1175bSopenharmony_ci */ 1608a8e1175bSopenharmony_ci if (ssl->handshake->resume) { 1609a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) { 1610a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret); 1611a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 1612a8e1175bSopenharmony_ci ssl, 1613a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1614a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR); 1615a8e1175bSopenharmony_ci return ret; 1616a8e1175bSopenharmony_ci } 1617a8e1175bSopenharmony_ci } 1618a8e1175bSopenharmony_ci 1619a8e1175bSopenharmony_ci /* 1620a8e1175bSopenharmony_ci * Renegotiation security checks 1621a8e1175bSopenharmony_ci */ 1622a8e1175bSopenharmony_ci if (ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && 1623a8e1175bSopenharmony_ci ssl->conf->allow_legacy_renegotiation == 1624a8e1175bSopenharmony_ci MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE) { 1625a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 1626a8e1175bSopenharmony_ci ("legacy renegotiation, breaking off handshake")); 1627a8e1175bSopenharmony_ci handshake_failure = 1; 1628a8e1175bSopenharmony_ci } 1629a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_RENEGOTIATION) 1630a8e1175bSopenharmony_ci else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && 1631a8e1175bSopenharmony_ci ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION && 1632a8e1175bSopenharmony_ci renegotiation_info_seen == 0) { 1633a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 1634a8e1175bSopenharmony_ci ("renegotiation_info extension missing (secure)")); 1635a8e1175bSopenharmony_ci handshake_failure = 1; 1636a8e1175bSopenharmony_ci } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && 1637a8e1175bSopenharmony_ci ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && 1638a8e1175bSopenharmony_ci ssl->conf->allow_legacy_renegotiation == 1639a8e1175bSopenharmony_ci MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION) { 1640a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("legacy renegotiation not allowed")); 1641a8e1175bSopenharmony_ci handshake_failure = 1; 1642a8e1175bSopenharmony_ci } else if (ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && 1643a8e1175bSopenharmony_ci ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && 1644a8e1175bSopenharmony_ci renegotiation_info_seen == 1) { 1645a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 1646a8e1175bSopenharmony_ci ("renegotiation_info extension present (legacy)")); 1647a8e1175bSopenharmony_ci handshake_failure = 1; 1648a8e1175bSopenharmony_ci } 1649a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_RENEGOTIATION */ 1650a8e1175bSopenharmony_ci 1651a8e1175bSopenharmony_ci if (handshake_failure == 1) { 1652a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 1653a8e1175bSopenharmony_ci ssl, 1654a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 1655a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 1656a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 1657a8e1175bSopenharmony_ci } 1658a8e1175bSopenharmony_ci 1659a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server hello")); 1660a8e1175bSopenharmony_ci 1661a8e1175bSopenharmony_ci return 0; 1662a8e1175bSopenharmony_ci} 1663a8e1175bSopenharmony_ci 1664a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ 1665a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) 1666a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 1667a8e1175bSopenharmony_cistatic int ssl_parse_server_dh_params(mbedtls_ssl_context *ssl, 1668a8e1175bSopenharmony_ci unsigned char **p, 1669a8e1175bSopenharmony_ci unsigned char *end) 1670a8e1175bSopenharmony_ci{ 1671a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 1672a8e1175bSopenharmony_ci size_t dhm_actual_bitlen; 1673a8e1175bSopenharmony_ci 1674a8e1175bSopenharmony_ci /* 1675a8e1175bSopenharmony_ci * Ephemeral DH parameters: 1676a8e1175bSopenharmony_ci * 1677a8e1175bSopenharmony_ci * struct { 1678a8e1175bSopenharmony_ci * opaque dh_p<1..2^16-1>; 1679a8e1175bSopenharmony_ci * opaque dh_g<1..2^16-1>; 1680a8e1175bSopenharmony_ci * opaque dh_Ys<1..2^16-1>; 1681a8e1175bSopenharmony_ci * } ServerDHParams; 1682a8e1175bSopenharmony_ci */ 1683a8e1175bSopenharmony_ci if ((ret = mbedtls_dhm_read_params(&ssl->handshake->dhm_ctx, 1684a8e1175bSopenharmony_ci p, end)) != 0) { 1685a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(2, ("mbedtls_dhm_read_params"), ret); 1686a8e1175bSopenharmony_ci return ret; 1687a8e1175bSopenharmony_ci } 1688a8e1175bSopenharmony_ci 1689a8e1175bSopenharmony_ci dhm_actual_bitlen = mbedtls_dhm_get_bitlen(&ssl->handshake->dhm_ctx); 1690a8e1175bSopenharmony_ci if (dhm_actual_bitlen < ssl->conf->dhm_min_bitlen) { 1691a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("DHM prime too short: %" MBEDTLS_PRINTF_SIZET " < %u", 1692a8e1175bSopenharmony_ci dhm_actual_bitlen, 1693a8e1175bSopenharmony_ci ssl->conf->dhm_min_bitlen)); 1694a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 1695a8e1175bSopenharmony_ci } 1696a8e1175bSopenharmony_ci 1697a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MPI(3, "DHM: P ", &ssl->handshake->dhm_ctx.P); 1698a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MPI(3, "DHM: G ", &ssl->handshake->dhm_ctx.G); 1699a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GY", &ssl->handshake->dhm_ctx.GY); 1700a8e1175bSopenharmony_ci 1701a8e1175bSopenharmony_ci return ret; 1702a8e1175bSopenharmony_ci} 1703a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || 1704a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ 1705a8e1175bSopenharmony_ci 1706a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 1707a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ 1708a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ 1709a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) 1710a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 1711a8e1175bSopenharmony_cistatic int ssl_parse_server_ecdh_params(mbedtls_ssl_context *ssl, 1712a8e1175bSopenharmony_ci unsigned char **p, 1713a8e1175bSopenharmony_ci unsigned char *end) 1714a8e1175bSopenharmony_ci{ 1715a8e1175bSopenharmony_ci uint16_t tls_id; 1716a8e1175bSopenharmony_ci size_t ecpoint_len; 1717a8e1175bSopenharmony_ci mbedtls_ssl_handshake_params *handshake = ssl->handshake; 1718a8e1175bSopenharmony_ci psa_key_type_t key_type = PSA_KEY_TYPE_NONE; 1719a8e1175bSopenharmony_ci size_t ec_bits = 0; 1720a8e1175bSopenharmony_ci 1721a8e1175bSopenharmony_ci /* 1722a8e1175bSopenharmony_ci * struct { 1723a8e1175bSopenharmony_ci * ECParameters curve_params; 1724a8e1175bSopenharmony_ci * ECPoint public; 1725a8e1175bSopenharmony_ci * } ServerECDHParams; 1726a8e1175bSopenharmony_ci * 1727a8e1175bSopenharmony_ci * 1 curve_type (must be "named_curve") 1728a8e1175bSopenharmony_ci * 2..3 NamedCurve 1729a8e1175bSopenharmony_ci * 4 ECPoint.len 1730a8e1175bSopenharmony_ci * 5+ ECPoint contents 1731a8e1175bSopenharmony_ci */ 1732a8e1175bSopenharmony_ci if (end - *p < 4) { 1733a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1734a8e1175bSopenharmony_ci } 1735a8e1175bSopenharmony_ci 1736a8e1175bSopenharmony_ci /* First byte is curve_type; only named_curve is handled */ 1737a8e1175bSopenharmony_ci if (*(*p)++ != MBEDTLS_ECP_TLS_NAMED_CURVE) { 1738a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 1739a8e1175bSopenharmony_ci } 1740a8e1175bSopenharmony_ci 1741a8e1175bSopenharmony_ci /* Next two bytes are the namedcurve value */ 1742a8e1175bSopenharmony_ci tls_id = MBEDTLS_GET_UINT16_BE(*p, 0); 1743a8e1175bSopenharmony_ci *p += 2; 1744a8e1175bSopenharmony_ci 1745a8e1175bSopenharmony_ci /* Check it's a curve we offered */ 1746a8e1175bSopenharmony_ci if (mbedtls_ssl_check_curve_tls_id(ssl, tls_id) != 0) { 1747a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, 1748a8e1175bSopenharmony_ci ("bad server key exchange message (ECDHE curve): %u", 1749a8e1175bSopenharmony_ci (unsigned) tls_id)); 1750a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 1751a8e1175bSopenharmony_ci } 1752a8e1175bSopenharmony_ci 1753a8e1175bSopenharmony_ci /* Convert EC's TLS ID to PSA key type. */ 1754a8e1175bSopenharmony_ci if (mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id, &key_type, 1755a8e1175bSopenharmony_ci &ec_bits) == PSA_ERROR_NOT_SUPPORTED) { 1756a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 1757a8e1175bSopenharmony_ci } 1758a8e1175bSopenharmony_ci handshake->xxdh_psa_type = key_type; 1759a8e1175bSopenharmony_ci handshake->xxdh_psa_bits = ec_bits; 1760a8e1175bSopenharmony_ci 1761a8e1175bSopenharmony_ci /* Keep a copy of the peer's public key */ 1762a8e1175bSopenharmony_ci ecpoint_len = *(*p)++; 1763a8e1175bSopenharmony_ci if ((size_t) (end - *p) < ecpoint_len) { 1764a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1765a8e1175bSopenharmony_ci } 1766a8e1175bSopenharmony_ci 1767a8e1175bSopenharmony_ci if (ecpoint_len > sizeof(handshake->xxdh_psa_peerkey)) { 1768a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 1769a8e1175bSopenharmony_ci } 1770a8e1175bSopenharmony_ci 1771a8e1175bSopenharmony_ci memcpy(handshake->xxdh_psa_peerkey, *p, ecpoint_len); 1772a8e1175bSopenharmony_ci handshake->xxdh_psa_peerkey_len = ecpoint_len; 1773a8e1175bSopenharmony_ci *p += ecpoint_len; 1774a8e1175bSopenharmony_ci 1775a8e1175bSopenharmony_ci return 0; 1776a8e1175bSopenharmony_ci} 1777a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || 1778a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || 1779a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ 1780a8e1175bSopenharmony_ci#else 1781a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ 1782a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ 1783a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ 1784a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ 1785a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) 1786a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 1787a8e1175bSopenharmony_cistatic int ssl_check_server_ecdh_params(const mbedtls_ssl_context *ssl) 1788a8e1175bSopenharmony_ci{ 1789a8e1175bSopenharmony_ci uint16_t tls_id; 1790a8e1175bSopenharmony_ci mbedtls_ecp_group_id grp_id; 1791a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) 1792a8e1175bSopenharmony_ci grp_id = ssl->handshake->ecdh_ctx.grp.id; 1793a8e1175bSopenharmony_ci#else 1794a8e1175bSopenharmony_ci grp_id = ssl->handshake->ecdh_ctx.grp_id; 1795a8e1175bSopenharmony_ci#endif 1796a8e1175bSopenharmony_ci 1797a8e1175bSopenharmony_ci tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id); 1798a8e1175bSopenharmony_ci if (tls_id == 0) { 1799a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 1800a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 1801a8e1175bSopenharmony_ci } 1802a8e1175bSopenharmony_ci 1803a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("ECDH curve: %s", 1804a8e1175bSopenharmony_ci mbedtls_ssl_get_curve_name_from_tls_id(tls_id))); 1805a8e1175bSopenharmony_ci 1806a8e1175bSopenharmony_ci if (mbedtls_ssl_check_curve(ssl, grp_id) != 0) { 1807a8e1175bSopenharmony_ci return -1; 1808a8e1175bSopenharmony_ci } 1809a8e1175bSopenharmony_ci 1810a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, 1811a8e1175bSopenharmony_ci MBEDTLS_DEBUG_ECDH_QP); 1812a8e1175bSopenharmony_ci 1813a8e1175bSopenharmony_ci return 0; 1814a8e1175bSopenharmony_ci} 1815a8e1175bSopenharmony_ci 1816a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || 1817a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || 1818a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || 1819a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || 1820a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ 1821a8e1175bSopenharmony_ci 1822a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ 1823a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ 1824a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) 1825a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 1826a8e1175bSopenharmony_cistatic int ssl_parse_server_ecdh_params(mbedtls_ssl_context *ssl, 1827a8e1175bSopenharmony_ci unsigned char **p, 1828a8e1175bSopenharmony_ci unsigned char *end) 1829a8e1175bSopenharmony_ci{ 1830a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 1831a8e1175bSopenharmony_ci 1832a8e1175bSopenharmony_ci /* 1833a8e1175bSopenharmony_ci * Ephemeral ECDH parameters: 1834a8e1175bSopenharmony_ci * 1835a8e1175bSopenharmony_ci * struct { 1836a8e1175bSopenharmony_ci * ECParameters curve_params; 1837a8e1175bSopenharmony_ci * ECPoint public; 1838a8e1175bSopenharmony_ci * } ServerECDHParams; 1839a8e1175bSopenharmony_ci */ 1840a8e1175bSopenharmony_ci if ((ret = mbedtls_ecdh_read_params(&ssl->handshake->ecdh_ctx, 1841a8e1175bSopenharmony_ci (const unsigned char **) p, end)) != 0) { 1842a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_read_params"), ret); 1843a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 1844a8e1175bSopenharmony_ci if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { 1845a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; 1846a8e1175bSopenharmony_ci } 1847a8e1175bSopenharmony_ci#endif 1848a8e1175bSopenharmony_ci return ret; 1849a8e1175bSopenharmony_ci } 1850a8e1175bSopenharmony_ci 1851a8e1175bSopenharmony_ci if (ssl_check_server_ecdh_params(ssl) != 0) { 1852a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 1853a8e1175bSopenharmony_ci ("bad server key exchange message (ECDHE curve)")); 1854a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 1855a8e1175bSopenharmony_ci } 1856a8e1175bSopenharmony_ci 1857a8e1175bSopenharmony_ci return ret; 1858a8e1175bSopenharmony_ci} 1859a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || \ 1860a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || \ 1861a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ 1862a8e1175bSopenharmony_ci#endif /* !MBEDTLS_USE_PSA_CRYPTO */ 1863a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) 1864a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 1865a8e1175bSopenharmony_cistatic int ssl_parse_server_psk_hint(mbedtls_ssl_context *ssl, 1866a8e1175bSopenharmony_ci unsigned char **p, 1867a8e1175bSopenharmony_ci unsigned char *end) 1868a8e1175bSopenharmony_ci{ 1869a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 1870a8e1175bSopenharmony_ci uint16_t len; 1871a8e1175bSopenharmony_ci ((void) ssl); 1872a8e1175bSopenharmony_ci 1873a8e1175bSopenharmony_ci /* 1874a8e1175bSopenharmony_ci * PSK parameters: 1875a8e1175bSopenharmony_ci * 1876a8e1175bSopenharmony_ci * opaque psk_identity_hint<0..2^16-1>; 1877a8e1175bSopenharmony_ci */ 1878a8e1175bSopenharmony_ci if (end - (*p) < 2) { 1879a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 1880a8e1175bSopenharmony_ci ("bad server key exchange message (psk_identity_hint length)")); 1881a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1882a8e1175bSopenharmony_ci } 1883a8e1175bSopenharmony_ci len = MBEDTLS_GET_UINT16_BE(*p, 0); 1884a8e1175bSopenharmony_ci *p += 2; 1885a8e1175bSopenharmony_ci 1886a8e1175bSopenharmony_ci if (end - (*p) < len) { 1887a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 1888a8e1175bSopenharmony_ci ("bad server key exchange message (psk_identity_hint length)")); 1889a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 1890a8e1175bSopenharmony_ci } 1891a8e1175bSopenharmony_ci 1892a8e1175bSopenharmony_ci /* 1893a8e1175bSopenharmony_ci * Note: we currently ignore the PSK identity hint, as we only allow one 1894a8e1175bSopenharmony_ci * PSK to be provisioned on the client. This could be changed later if 1895a8e1175bSopenharmony_ci * someone needs that feature. 1896a8e1175bSopenharmony_ci */ 1897a8e1175bSopenharmony_ci *p += len; 1898a8e1175bSopenharmony_ci ret = 0; 1899a8e1175bSopenharmony_ci 1900a8e1175bSopenharmony_ci return ret; 1901a8e1175bSopenharmony_ci} 1902a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ 1903a8e1175bSopenharmony_ci 1904a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ 1905a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) 1906a8e1175bSopenharmony_ci/* 1907a8e1175bSopenharmony_ci * Generate a pre-master secret and encrypt it with the server's RSA key 1908a8e1175bSopenharmony_ci */ 1909a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 1910a8e1175bSopenharmony_cistatic int ssl_write_encrypted_pms(mbedtls_ssl_context *ssl, 1911a8e1175bSopenharmony_ci size_t offset, size_t *olen, 1912a8e1175bSopenharmony_ci size_t pms_offset) 1913a8e1175bSopenharmony_ci{ 1914a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1915a8e1175bSopenharmony_ci size_t len_bytes = 2; 1916a8e1175bSopenharmony_ci unsigned char *p = ssl->handshake->premaster + pms_offset; 1917a8e1175bSopenharmony_ci mbedtls_pk_context *peer_pk; 1918a8e1175bSopenharmony_ci 1919a8e1175bSopenharmony_ci if (offset + len_bytes > MBEDTLS_SSL_OUT_CONTENT_LEN) { 1920a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("buffer too small for encrypted pms")); 1921a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 1922a8e1175bSopenharmony_ci } 1923a8e1175bSopenharmony_ci 1924a8e1175bSopenharmony_ci /* 1925a8e1175bSopenharmony_ci * Generate (part of) the pre-master as 1926a8e1175bSopenharmony_ci * struct { 1927a8e1175bSopenharmony_ci * ProtocolVersion client_version; 1928a8e1175bSopenharmony_ci * opaque random[46]; 1929a8e1175bSopenharmony_ci * } PreMasterSecret; 1930a8e1175bSopenharmony_ci */ 1931a8e1175bSopenharmony_ci mbedtls_ssl_write_version(p, ssl->conf->transport, 1932a8e1175bSopenharmony_ci MBEDTLS_SSL_VERSION_TLS1_2); 1933a8e1175bSopenharmony_ci 1934a8e1175bSopenharmony_ci if ((ret = ssl->conf->f_rng(ssl->conf->p_rng, p + 2, 46)) != 0) { 1935a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "f_rng", ret); 1936a8e1175bSopenharmony_ci return ret; 1937a8e1175bSopenharmony_ci } 1938a8e1175bSopenharmony_ci 1939a8e1175bSopenharmony_ci ssl->handshake->pmslen = 48; 1940a8e1175bSopenharmony_ci 1941a8e1175bSopenharmony_ci#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) 1942a8e1175bSopenharmony_ci peer_pk = &ssl->handshake->peer_pubkey; 1943a8e1175bSopenharmony_ci#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 1944a8e1175bSopenharmony_ci if (ssl->session_negotiate->peer_cert == NULL) { 1945a8e1175bSopenharmony_ci /* Should never happen */ 1946a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 1947a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 1948a8e1175bSopenharmony_ci } 1949a8e1175bSopenharmony_ci peer_pk = &ssl->session_negotiate->peer_cert->pk; 1950a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 1951a8e1175bSopenharmony_ci 1952a8e1175bSopenharmony_ci /* 1953a8e1175bSopenharmony_ci * Now write it out, encrypted 1954a8e1175bSopenharmony_ci */ 1955a8e1175bSopenharmony_ci if (!mbedtls_pk_can_do(peer_pk, MBEDTLS_PK_RSA)) { 1956a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("certificate key type mismatch")); 1957a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; 1958a8e1175bSopenharmony_ci } 1959a8e1175bSopenharmony_ci 1960a8e1175bSopenharmony_ci if ((ret = mbedtls_pk_encrypt(peer_pk, 1961a8e1175bSopenharmony_ci p, ssl->handshake->pmslen, 1962a8e1175bSopenharmony_ci ssl->out_msg + offset + len_bytes, olen, 1963a8e1175bSopenharmony_ci MBEDTLS_SSL_OUT_CONTENT_LEN - offset - len_bytes, 1964a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { 1965a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_rsa_pkcs1_encrypt", ret); 1966a8e1175bSopenharmony_ci return ret; 1967a8e1175bSopenharmony_ci } 1968a8e1175bSopenharmony_ci 1969a8e1175bSopenharmony_ci if (len_bytes == 2) { 1970a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(*olen, ssl->out_msg, offset); 1971a8e1175bSopenharmony_ci *olen += 2; 1972a8e1175bSopenharmony_ci } 1973a8e1175bSopenharmony_ci 1974a8e1175bSopenharmony_ci#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) 1975a8e1175bSopenharmony_ci /* We don't need the peer's public key anymore. Free it. */ 1976a8e1175bSopenharmony_ci mbedtls_pk_free(peer_pk); 1977a8e1175bSopenharmony_ci#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 1978a8e1175bSopenharmony_ci return 0; 1979a8e1175bSopenharmony_ci} 1980a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED || 1981a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ 1982a8e1175bSopenharmony_ci 1983a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ 1984a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) 1985a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 1986a8e1175bSopenharmony_cistatic int ssl_get_ecdh_params_from_cert(mbedtls_ssl_context *ssl) 1987a8e1175bSopenharmony_ci{ 1988a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1989a8e1175bSopenharmony_ci mbedtls_pk_context *peer_pk; 1990a8e1175bSopenharmony_ci 1991a8e1175bSopenharmony_ci#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) 1992a8e1175bSopenharmony_ci peer_pk = &ssl->handshake->peer_pubkey; 1993a8e1175bSopenharmony_ci#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 1994a8e1175bSopenharmony_ci if (ssl->session_negotiate->peer_cert == NULL) { 1995a8e1175bSopenharmony_ci /* Should never happen */ 1996a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 1997a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 1998a8e1175bSopenharmony_ci } 1999a8e1175bSopenharmony_ci peer_pk = &ssl->session_negotiate->peer_cert->pk; 2000a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 2001a8e1175bSopenharmony_ci 2002a8e1175bSopenharmony_ci /* This is a public key, so it can't be opaque, so can_do() is a good 2003a8e1175bSopenharmony_ci * enough check to ensure pk_ec() is safe to use below. */ 2004a8e1175bSopenharmony_ci if (!mbedtls_pk_can_do(peer_pk, MBEDTLS_PK_ECKEY)) { 2005a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("server key not ECDH capable")); 2006a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; 2007a8e1175bSopenharmony_ci } 2008a8e1175bSopenharmony_ci 2009a8e1175bSopenharmony_ci#if !defined(MBEDTLS_PK_USE_PSA_EC_DATA) 2010a8e1175bSopenharmony_ci const mbedtls_ecp_keypair *peer_key = mbedtls_pk_ec_ro(*peer_pk); 2011a8e1175bSopenharmony_ci#endif /* !defined(MBEDTLS_PK_USE_PSA_EC_DATA) */ 2012a8e1175bSopenharmony_ci 2013a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 2014a8e1175bSopenharmony_ci uint16_t tls_id = 0; 2015a8e1175bSopenharmony_ci psa_key_type_t key_type = PSA_KEY_TYPE_NONE; 2016a8e1175bSopenharmony_ci mbedtls_ecp_group_id grp_id = mbedtls_pk_get_ec_group_id(peer_pk); 2017a8e1175bSopenharmony_ci 2018a8e1175bSopenharmony_ci if (mbedtls_ssl_check_curve(ssl, grp_id) != 0) { 2019a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server certificate (ECDH curve)")); 2020a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BAD_CERTIFICATE; 2021a8e1175bSopenharmony_ci } 2022a8e1175bSopenharmony_ci 2023a8e1175bSopenharmony_ci tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id(grp_id); 2024a8e1175bSopenharmony_ci if (tls_id == 0) { 2025a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("ECC group %u not suported", 2026a8e1175bSopenharmony_ci grp_id)); 2027a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 2028a8e1175bSopenharmony_ci } 2029a8e1175bSopenharmony_ci 2030a8e1175bSopenharmony_ci /* If the above conversion to TLS ID was fine, then also this one will be, 2031a8e1175bSopenharmony_ci so there is no need to check the return value here */ 2032a8e1175bSopenharmony_ci mbedtls_ssl_get_psa_curve_info_from_tls_id(tls_id, &key_type, 2033a8e1175bSopenharmony_ci &ssl->handshake->xxdh_psa_bits); 2034a8e1175bSopenharmony_ci 2035a8e1175bSopenharmony_ci ssl->handshake->xxdh_psa_type = key_type; 2036a8e1175bSopenharmony_ci 2037a8e1175bSopenharmony_ci /* Store peer's public key in psa format. */ 2038a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_USE_PSA_EC_DATA) 2039a8e1175bSopenharmony_ci memcpy(ssl->handshake->xxdh_psa_peerkey, peer_pk->pub_raw, peer_pk->pub_raw_len); 2040a8e1175bSopenharmony_ci ssl->handshake->xxdh_psa_peerkey_len = peer_pk->pub_raw_len; 2041a8e1175bSopenharmony_ci ret = 0; 2042a8e1175bSopenharmony_ci#else /* MBEDTLS_PK_USE_PSA_EC_DATA */ 2043a8e1175bSopenharmony_ci size_t olen = 0; 2044a8e1175bSopenharmony_ci ret = mbedtls_ecp_point_write_binary(&peer_key->grp, &peer_key->Q, 2045a8e1175bSopenharmony_ci MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, 2046a8e1175bSopenharmony_ci ssl->handshake->xxdh_psa_peerkey, 2047a8e1175bSopenharmony_ci sizeof(ssl->handshake->xxdh_psa_peerkey)); 2048a8e1175bSopenharmony_ci 2049a8e1175bSopenharmony_ci if (ret != 0) { 2050a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecp_point_write_binary"), ret); 2051a8e1175bSopenharmony_ci return ret; 2052a8e1175bSopenharmony_ci } 2053a8e1175bSopenharmony_ci ssl->handshake->xxdh_psa_peerkey_len = olen; 2054a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_USE_PSA_EC_DATA */ 2055a8e1175bSopenharmony_ci#else /* MBEDTLS_USE_PSA_CRYPTO */ 2056a8e1175bSopenharmony_ci if ((ret = mbedtls_ecdh_get_params(&ssl->handshake->ecdh_ctx, peer_key, 2057a8e1175bSopenharmony_ci MBEDTLS_ECDH_THEIRS)) != 0) { 2058a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("mbedtls_ecdh_get_params"), ret); 2059a8e1175bSopenharmony_ci return ret; 2060a8e1175bSopenharmony_ci } 2061a8e1175bSopenharmony_ci 2062a8e1175bSopenharmony_ci if (ssl_check_server_ecdh_params(ssl) != 0) { 2063a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server certificate (ECDH curve)")); 2064a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BAD_CERTIFICATE; 2065a8e1175bSopenharmony_ci } 2066a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 2067a8e1175bSopenharmony_ci#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) 2068a8e1175bSopenharmony_ci /* We don't need the peer's public key anymore. Free it, 2069a8e1175bSopenharmony_ci * so that more RAM is available for upcoming expensive 2070a8e1175bSopenharmony_ci * operations like ECDHE. */ 2071a8e1175bSopenharmony_ci mbedtls_pk_free(peer_pk); 2072a8e1175bSopenharmony_ci#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 2073a8e1175bSopenharmony_ci 2074a8e1175bSopenharmony_ci return ret; 2075a8e1175bSopenharmony_ci} 2076a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || 2077a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ 2078a8e1175bSopenharmony_ci 2079a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 2080a8e1175bSopenharmony_cistatic int ssl_parse_server_key_exchange(mbedtls_ssl_context *ssl) 2081a8e1175bSopenharmony_ci{ 2082a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 2083a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 2084a8e1175bSopenharmony_ci ssl->handshake->ciphersuite_info; 2085a8e1175bSopenharmony_ci unsigned char *p = NULL, *end = NULL; 2086a8e1175bSopenharmony_ci 2087a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse server key exchange")); 2088a8e1175bSopenharmony_ci 2089a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) 2090a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) { 2091a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse server key exchange")); 2092a8e1175bSopenharmony_ci ssl->state++; 2093a8e1175bSopenharmony_ci return 0; 2094a8e1175bSopenharmony_ci } 2095a8e1175bSopenharmony_ci ((void) p); 2096a8e1175bSopenharmony_ci ((void) end); 2097a8e1175bSopenharmony_ci#endif 2098a8e1175bSopenharmony_ci 2099a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ 2100a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) 2101a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || 2102a8e1175bSopenharmony_ci ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA) { 2103a8e1175bSopenharmony_ci if ((ret = ssl_get_ecdh_params_from_cert(ssl)) != 0) { 2104a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "ssl_get_ecdh_params_from_cert", ret); 2105a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 2106a8e1175bSopenharmony_ci ssl, 2107a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2108a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 2109a8e1175bSopenharmony_ci return ret; 2110a8e1175bSopenharmony_ci } 2111a8e1175bSopenharmony_ci 2112a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse server key exchange")); 2113a8e1175bSopenharmony_ci ssl->state++; 2114a8e1175bSopenharmony_ci return 0; 2115a8e1175bSopenharmony_ci } 2116a8e1175bSopenharmony_ci ((void) p); 2117a8e1175bSopenharmony_ci ((void) end); 2118a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || 2119a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ 2120a8e1175bSopenharmony_ci 2121a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 2122a8e1175bSopenharmony_ci if (ssl->handshake->ecrs_enabled && 2123a8e1175bSopenharmony_ci ssl->handshake->ecrs_state == ssl_ecrs_ske_start_processing) { 2124a8e1175bSopenharmony_ci goto start_processing; 2125a8e1175bSopenharmony_ci } 2126a8e1175bSopenharmony_ci#endif 2127a8e1175bSopenharmony_ci 2128a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { 2129a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); 2130a8e1175bSopenharmony_ci return ret; 2131a8e1175bSopenharmony_ci } 2132a8e1175bSopenharmony_ci 2133a8e1175bSopenharmony_ci if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { 2134a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); 2135a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 2136a8e1175bSopenharmony_ci ssl, 2137a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2138a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); 2139a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 2140a8e1175bSopenharmony_ci } 2141a8e1175bSopenharmony_ci 2142a8e1175bSopenharmony_ci /* 2143a8e1175bSopenharmony_ci * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server 2144a8e1175bSopenharmony_ci * doesn't use a psk_identity_hint 2145a8e1175bSopenharmony_ci */ 2146a8e1175bSopenharmony_ci if (ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE) { 2147a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || 2148a8e1175bSopenharmony_ci ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) { 2149a8e1175bSopenharmony_ci /* Current message is probably either 2150a8e1175bSopenharmony_ci * CertificateRequest or ServerHelloDone */ 2151a8e1175bSopenharmony_ci ssl->keep_current_message = 1; 2152a8e1175bSopenharmony_ci goto exit; 2153a8e1175bSopenharmony_ci } 2154a8e1175bSopenharmony_ci 2155a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 2156a8e1175bSopenharmony_ci ("server key exchange message must not be skipped")); 2157a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 2158a8e1175bSopenharmony_ci ssl, 2159a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2160a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); 2161a8e1175bSopenharmony_ci 2162a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 2163a8e1175bSopenharmony_ci } 2164a8e1175bSopenharmony_ci 2165a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 2166a8e1175bSopenharmony_ci if (ssl->handshake->ecrs_enabled) { 2167a8e1175bSopenharmony_ci ssl->handshake->ecrs_state = ssl_ecrs_ske_start_processing; 2168a8e1175bSopenharmony_ci } 2169a8e1175bSopenharmony_ci 2170a8e1175bSopenharmony_cistart_processing: 2171a8e1175bSopenharmony_ci#endif 2172a8e1175bSopenharmony_ci p = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl); 2173a8e1175bSopenharmony_ci end = ssl->in_msg + ssl->in_hslen; 2174a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "server key exchange", p, (size_t) (end - p)); 2175a8e1175bSopenharmony_ci 2176a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) 2177a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || 2178a8e1175bSopenharmony_ci ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || 2179a8e1175bSopenharmony_ci ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || 2180a8e1175bSopenharmony_ci ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) { 2181a8e1175bSopenharmony_ci if (ssl_parse_server_psk_hint(ssl, &p, end) != 0) { 2182a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); 2183a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 2184a8e1175bSopenharmony_ci ssl, 2185a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2186a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 2187a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 2188a8e1175bSopenharmony_ci } 2189a8e1175bSopenharmony_ci } /* FALLTHROUGH */ 2190a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ 2191a8e1175bSopenharmony_ci 2192a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ 2193a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) 2194a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || 2195a8e1175bSopenharmony_ci ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) { 2196a8e1175bSopenharmony_ci ; /* nothing more to do */ 2197a8e1175bSopenharmony_ci } else 2198a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED || 2199a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ 2200a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ 2201a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) 2202a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA || 2203a8e1175bSopenharmony_ci ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK) { 2204a8e1175bSopenharmony_ci if (ssl_parse_server_dh_params(ssl, &p, end) != 0) { 2205a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); 2206a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 2207a8e1175bSopenharmony_ci ssl, 2208a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2209a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 2210a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 2211a8e1175bSopenharmony_ci } 2212a8e1175bSopenharmony_ci } else 2213a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || 2214a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ 2215a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ 2216a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ 2217a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) 2218a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || 2219a8e1175bSopenharmony_ci ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || 2220a8e1175bSopenharmony_ci ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA) { 2221a8e1175bSopenharmony_ci if (ssl_parse_server_ecdh_params(ssl, &p, end) != 0) { 2222a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); 2223a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 2224a8e1175bSopenharmony_ci ssl, 2225a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2226a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 2227a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 2228a8e1175bSopenharmony_ci } 2229a8e1175bSopenharmony_ci } else 2230a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || 2231a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || 2232a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ 2233a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 2234a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) { 2235a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 2236a8e1175bSopenharmony_ci /* 2237a8e1175bSopenharmony_ci * The first 3 bytes are: 2238a8e1175bSopenharmony_ci * [0] MBEDTLS_ECP_TLS_NAMED_CURVE 2239a8e1175bSopenharmony_ci * [1, 2] elliptic curve's TLS ID 2240a8e1175bSopenharmony_ci * 2241a8e1175bSopenharmony_ci * However since we only support secp256r1 for now, we check only 2242a8e1175bSopenharmony_ci * that TLS ID here 2243a8e1175bSopenharmony_ci */ 2244a8e1175bSopenharmony_ci uint16_t read_tls_id = MBEDTLS_GET_UINT16_BE(p, 1); 2245a8e1175bSopenharmony_ci uint16_t exp_tls_id = mbedtls_ssl_get_tls_id_from_ecp_group_id( 2246a8e1175bSopenharmony_ci MBEDTLS_ECP_DP_SECP256R1); 2247a8e1175bSopenharmony_ci 2248a8e1175bSopenharmony_ci if (exp_tls_id == 0) { 2249a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 2250a8e1175bSopenharmony_ci } 2251a8e1175bSopenharmony_ci 2252a8e1175bSopenharmony_ci if ((*p != MBEDTLS_ECP_TLS_NAMED_CURVE) || 2253a8e1175bSopenharmony_ci (read_tls_id != exp_tls_id)) { 2254a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 2255a8e1175bSopenharmony_ci } 2256a8e1175bSopenharmony_ci 2257a8e1175bSopenharmony_ci p += 3; 2258a8e1175bSopenharmony_ci 2259a8e1175bSopenharmony_ci if ((ret = mbedtls_psa_ecjpake_read_round( 2260a8e1175bSopenharmony_ci &ssl->handshake->psa_pake_ctx, p, end - p, 2261a8e1175bSopenharmony_ci MBEDTLS_ECJPAKE_ROUND_TWO)) != 0) { 2262a8e1175bSopenharmony_ci psa_destroy_key(ssl->handshake->psa_pake_password); 2263a8e1175bSopenharmony_ci psa_pake_abort(&ssl->handshake->psa_pake_ctx); 2264a8e1175bSopenharmony_ci 2265a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_input round two", ret); 2266a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 2267a8e1175bSopenharmony_ci ssl, 2268a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2269a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 2270a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 2271a8e1175bSopenharmony_ci } 2272a8e1175bSopenharmony_ci#else 2273a8e1175bSopenharmony_ci ret = mbedtls_ecjpake_read_round_two(&ssl->handshake->ecjpake_ctx, 2274a8e1175bSopenharmony_ci p, end - p); 2275a8e1175bSopenharmony_ci if (ret != 0) { 2276a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_read_round_two", ret); 2277a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 2278a8e1175bSopenharmony_ci ssl, 2279a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2280a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 2281a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE; 2282a8e1175bSopenharmony_ci } 2283a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 2284a8e1175bSopenharmony_ci } else 2285a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ 2286a8e1175bSopenharmony_ci { 2287a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 2288a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 2289a8e1175bSopenharmony_ci } 2290a8e1175bSopenharmony_ci 2291a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) 2292a8e1175bSopenharmony_ci if (mbedtls_ssl_ciphersuite_uses_server_signature(ciphersuite_info)) { 2293a8e1175bSopenharmony_ci size_t sig_len, hashlen; 2294a8e1175bSopenharmony_ci unsigned char hash[MBEDTLS_MD_MAX_SIZE]; 2295a8e1175bSopenharmony_ci 2296a8e1175bSopenharmony_ci mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; 2297a8e1175bSopenharmony_ci mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; 2298a8e1175bSopenharmony_ci unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl); 2299a8e1175bSopenharmony_ci size_t params_len = (size_t) (p - params); 2300a8e1175bSopenharmony_ci void *rs_ctx = NULL; 2301a8e1175bSopenharmony_ci uint16_t sig_alg; 2302a8e1175bSopenharmony_ci 2303a8e1175bSopenharmony_ci mbedtls_pk_context *peer_pk; 2304a8e1175bSopenharmony_ci 2305a8e1175bSopenharmony_ci#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) 2306a8e1175bSopenharmony_ci peer_pk = &ssl->handshake->peer_pubkey; 2307a8e1175bSopenharmony_ci#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 2308a8e1175bSopenharmony_ci if (ssl->session_negotiate->peer_cert == NULL) { 2309a8e1175bSopenharmony_ci /* Should never happen */ 2310a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 2311a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 2312a8e1175bSopenharmony_ci } 2313a8e1175bSopenharmony_ci peer_pk = &ssl->session_negotiate->peer_cert->pk; 2314a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 2315a8e1175bSopenharmony_ci 2316a8e1175bSopenharmony_ci /* 2317a8e1175bSopenharmony_ci * Handle the digitally-signed structure 2318a8e1175bSopenharmony_ci */ 2319a8e1175bSopenharmony_ci MBEDTLS_SSL_CHK_BUF_READ_PTR(p, end, 2); 2320a8e1175bSopenharmony_ci sig_alg = MBEDTLS_GET_UINT16_BE(p, 0); 2321a8e1175bSopenharmony_ci if (mbedtls_ssl_get_pk_type_and_md_alg_from_sig_alg( 2322a8e1175bSopenharmony_ci sig_alg, &pk_alg, &md_alg) != 0 && 2323a8e1175bSopenharmony_ci !mbedtls_ssl_sig_alg_is_offered(ssl, sig_alg) && 2324a8e1175bSopenharmony_ci !mbedtls_ssl_sig_alg_is_supported(ssl, sig_alg)) { 2325a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 2326a8e1175bSopenharmony_ci ("bad server key exchange message")); 2327a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 2328a8e1175bSopenharmony_ci ssl, 2329a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2330a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 2331a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 2332a8e1175bSopenharmony_ci } 2333a8e1175bSopenharmony_ci p += 2; 2334a8e1175bSopenharmony_ci 2335a8e1175bSopenharmony_ci if (!mbedtls_pk_can_do(peer_pk, pk_alg)) { 2336a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 2337a8e1175bSopenharmony_ci ("bad server key exchange message")); 2338a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 2339a8e1175bSopenharmony_ci ssl, 2340a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2341a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER); 2342a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER; 2343a8e1175bSopenharmony_ci } 2344a8e1175bSopenharmony_ci 2345a8e1175bSopenharmony_ci /* 2346a8e1175bSopenharmony_ci * Read signature 2347a8e1175bSopenharmony_ci */ 2348a8e1175bSopenharmony_ci 2349a8e1175bSopenharmony_ci if (p > end - 2) { 2350a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); 2351a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 2352a8e1175bSopenharmony_ci ssl, 2353a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2354a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 2355a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 2356a8e1175bSopenharmony_ci } 2357a8e1175bSopenharmony_ci sig_len = MBEDTLS_GET_UINT16_BE(p, 0); 2358a8e1175bSopenharmony_ci p += 2; 2359a8e1175bSopenharmony_ci 2360a8e1175bSopenharmony_ci if (p != end - sig_len) { 2361a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); 2362a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 2363a8e1175bSopenharmony_ci ssl, 2364a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2365a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 2366a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 2367a8e1175bSopenharmony_ci } 2368a8e1175bSopenharmony_ci 2369a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "signature", p, sig_len); 2370a8e1175bSopenharmony_ci 2371a8e1175bSopenharmony_ci /* 2372a8e1175bSopenharmony_ci * Compute the hash that has been signed 2373a8e1175bSopenharmony_ci */ 2374a8e1175bSopenharmony_ci if (md_alg != MBEDTLS_MD_NONE) { 2375a8e1175bSopenharmony_ci ret = mbedtls_ssl_get_key_exchange_md_tls1_2(ssl, hash, &hashlen, 2376a8e1175bSopenharmony_ci params, params_len, 2377a8e1175bSopenharmony_ci md_alg); 2378a8e1175bSopenharmony_ci if (ret != 0) { 2379a8e1175bSopenharmony_ci return ret; 2380a8e1175bSopenharmony_ci } 2381a8e1175bSopenharmony_ci } else { 2382a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 2383a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 2384a8e1175bSopenharmony_ci } 2385a8e1175bSopenharmony_ci 2386a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_BUF(3, "parameters hash", hash, hashlen); 2387a8e1175bSopenharmony_ci 2388a8e1175bSopenharmony_ci /* 2389a8e1175bSopenharmony_ci * Verify signature 2390a8e1175bSopenharmony_ci */ 2391a8e1175bSopenharmony_ci if (!mbedtls_pk_can_do(peer_pk, pk_alg)) { 2392a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server key exchange message")); 2393a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 2394a8e1175bSopenharmony_ci ssl, 2395a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2396a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE); 2397a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; 2398a8e1175bSopenharmony_ci } 2399a8e1175bSopenharmony_ci 2400a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 2401a8e1175bSopenharmony_ci if (ssl->handshake->ecrs_enabled) { 2402a8e1175bSopenharmony_ci rs_ctx = &ssl->handshake->ecrs_ctx.pk; 2403a8e1175bSopenharmony_ci } 2404a8e1175bSopenharmony_ci#endif 2405a8e1175bSopenharmony_ci 2406a8e1175bSopenharmony_ci#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 2407a8e1175bSopenharmony_ci if (pk_alg == MBEDTLS_PK_RSASSA_PSS) { 2408a8e1175bSopenharmony_ci mbedtls_pk_rsassa_pss_options rsassa_pss_options; 2409a8e1175bSopenharmony_ci rsassa_pss_options.mgf1_hash_id = md_alg; 2410a8e1175bSopenharmony_ci rsassa_pss_options.expected_salt_len = 2411a8e1175bSopenharmony_ci mbedtls_md_get_size_from_type(md_alg); 2412a8e1175bSopenharmony_ci if (rsassa_pss_options.expected_salt_len == 0) { 2413a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 2414a8e1175bSopenharmony_ci } 2415a8e1175bSopenharmony_ci 2416a8e1175bSopenharmony_ci ret = mbedtls_pk_verify_ext(pk_alg, &rsassa_pss_options, 2417a8e1175bSopenharmony_ci peer_pk, 2418a8e1175bSopenharmony_ci md_alg, hash, hashlen, 2419a8e1175bSopenharmony_ci p, sig_len); 2420a8e1175bSopenharmony_ci } else 2421a8e1175bSopenharmony_ci#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ 2422a8e1175bSopenharmony_ci ret = mbedtls_pk_verify_restartable(peer_pk, 2423a8e1175bSopenharmony_ci md_alg, hash, hashlen, p, sig_len, rs_ctx); 2424a8e1175bSopenharmony_ci 2425a8e1175bSopenharmony_ci if (ret != 0) { 2426a8e1175bSopenharmony_ci int send_alert_msg = 1; 2427a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 2428a8e1175bSopenharmony_ci send_alert_msg = (ret != MBEDTLS_ERR_ECP_IN_PROGRESS); 2429a8e1175bSopenharmony_ci#endif 2430a8e1175bSopenharmony_ci if (send_alert_msg) { 2431a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 2432a8e1175bSopenharmony_ci ssl, 2433a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2434a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR); 2435a8e1175bSopenharmony_ci } 2436a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_verify", ret); 2437a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 2438a8e1175bSopenharmony_ci if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { 2439a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; 2440a8e1175bSopenharmony_ci } 2441a8e1175bSopenharmony_ci#endif 2442a8e1175bSopenharmony_ci return ret; 2443a8e1175bSopenharmony_ci } 2444a8e1175bSopenharmony_ci 2445a8e1175bSopenharmony_ci#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) 2446a8e1175bSopenharmony_ci /* We don't need the peer's public key anymore. Free it, 2447a8e1175bSopenharmony_ci * so that more RAM is available for upcoming expensive 2448a8e1175bSopenharmony_ci * operations like ECDHE. */ 2449a8e1175bSopenharmony_ci mbedtls_pk_free(peer_pk); 2450a8e1175bSopenharmony_ci#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ 2451a8e1175bSopenharmony_ci } 2452a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */ 2453a8e1175bSopenharmony_ci 2454a8e1175bSopenharmony_ciexit: 2455a8e1175bSopenharmony_ci ssl->state++; 2456a8e1175bSopenharmony_ci 2457a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server key exchange")); 2458a8e1175bSopenharmony_ci 2459a8e1175bSopenharmony_ci return 0; 2460a8e1175bSopenharmony_ci} 2461a8e1175bSopenharmony_ci 2462a8e1175bSopenharmony_ci#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) 2463a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 2464a8e1175bSopenharmony_cistatic int ssl_parse_certificate_request(mbedtls_ssl_context *ssl) 2465a8e1175bSopenharmony_ci{ 2466a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 2467a8e1175bSopenharmony_ci ssl->handshake->ciphersuite_info; 2468a8e1175bSopenharmony_ci 2469a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate request")); 2470a8e1175bSopenharmony_ci 2471a8e1175bSopenharmony_ci if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { 2472a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate request")); 2473a8e1175bSopenharmony_ci ssl->state++; 2474a8e1175bSopenharmony_ci return 0; 2475a8e1175bSopenharmony_ci } 2476a8e1175bSopenharmony_ci 2477a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 2478a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 2479a8e1175bSopenharmony_ci} 2480a8e1175bSopenharmony_ci#else /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ 2481a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 2482a8e1175bSopenharmony_cistatic int ssl_parse_certificate_request(mbedtls_ssl_context *ssl) 2483a8e1175bSopenharmony_ci{ 2484a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 2485a8e1175bSopenharmony_ci unsigned char *buf; 2486a8e1175bSopenharmony_ci size_t n = 0; 2487a8e1175bSopenharmony_ci size_t cert_type_len = 0, dn_len = 0; 2488a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 2489a8e1175bSopenharmony_ci ssl->handshake->ciphersuite_info; 2490a8e1175bSopenharmony_ci size_t sig_alg_len; 2491a8e1175bSopenharmony_ci#if defined(MBEDTLS_DEBUG_C) 2492a8e1175bSopenharmony_ci unsigned char *sig_alg; 2493a8e1175bSopenharmony_ci unsigned char *dn; 2494a8e1175bSopenharmony_ci#endif 2495a8e1175bSopenharmony_ci 2496a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse certificate request")); 2497a8e1175bSopenharmony_ci 2498a8e1175bSopenharmony_ci if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { 2499a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip parse certificate request")); 2500a8e1175bSopenharmony_ci ssl->state++; 2501a8e1175bSopenharmony_ci return 0; 2502a8e1175bSopenharmony_ci } 2503a8e1175bSopenharmony_ci 2504a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { 2505a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); 2506a8e1175bSopenharmony_ci return ret; 2507a8e1175bSopenharmony_ci } 2508a8e1175bSopenharmony_ci 2509a8e1175bSopenharmony_ci if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { 2510a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message")); 2511a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 2512a8e1175bSopenharmony_ci ssl, 2513a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2514a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); 2515a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 2516a8e1175bSopenharmony_ci } 2517a8e1175bSopenharmony_ci 2518a8e1175bSopenharmony_ci ssl->state++; 2519a8e1175bSopenharmony_ci ssl->handshake->client_auth = 2520a8e1175bSopenharmony_ci (ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST); 2521a8e1175bSopenharmony_ci 2522a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("got %s certificate request", 2523a8e1175bSopenharmony_ci ssl->handshake->client_auth ? "a" : "no")); 2524a8e1175bSopenharmony_ci 2525a8e1175bSopenharmony_ci if (ssl->handshake->client_auth == 0) { 2526a8e1175bSopenharmony_ci /* Current message is probably the ServerHelloDone */ 2527a8e1175bSopenharmony_ci ssl->keep_current_message = 1; 2528a8e1175bSopenharmony_ci goto exit; 2529a8e1175bSopenharmony_ci } 2530a8e1175bSopenharmony_ci 2531a8e1175bSopenharmony_ci /* 2532a8e1175bSopenharmony_ci * struct { 2533a8e1175bSopenharmony_ci * ClientCertificateType certificate_types<1..2^8-1>; 2534a8e1175bSopenharmony_ci * SignatureAndHashAlgorithm 2535a8e1175bSopenharmony_ci * supported_signature_algorithms<2^16-1>; -- TLS 1.2 only 2536a8e1175bSopenharmony_ci * DistinguishedName certificate_authorities<0..2^16-1>; 2537a8e1175bSopenharmony_ci * } CertificateRequest; 2538a8e1175bSopenharmony_ci * 2539a8e1175bSopenharmony_ci * Since we only support a single certificate on clients, let's just 2540a8e1175bSopenharmony_ci * ignore all the information that's supposed to help us pick a 2541a8e1175bSopenharmony_ci * certificate. 2542a8e1175bSopenharmony_ci * 2543a8e1175bSopenharmony_ci * We could check that our certificate matches the request, and bail out 2544a8e1175bSopenharmony_ci * if it doesn't, but it's simpler to just send the certificate anyway, 2545a8e1175bSopenharmony_ci * and give the server the opportunity to decide if it should terminate 2546a8e1175bSopenharmony_ci * the connection when it doesn't like our certificate. 2547a8e1175bSopenharmony_ci * 2548a8e1175bSopenharmony_ci * Same goes for the hash in TLS 1.2's signature_algorithms: at this 2549a8e1175bSopenharmony_ci * point we only have one hash available (see comments in 2550a8e1175bSopenharmony_ci * write_certificate_verify), so let's just use what we have. 2551a8e1175bSopenharmony_ci * 2552a8e1175bSopenharmony_ci * However, we still minimally parse the message to check it is at least 2553a8e1175bSopenharmony_ci * superficially sane. 2554a8e1175bSopenharmony_ci */ 2555a8e1175bSopenharmony_ci buf = ssl->in_msg; 2556a8e1175bSopenharmony_ci 2557a8e1175bSopenharmony_ci /* certificate_types */ 2558a8e1175bSopenharmony_ci if (ssl->in_hslen <= mbedtls_ssl_hs_hdr_len(ssl)) { 2559a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message")); 2560a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2561a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 2562a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 2563a8e1175bSopenharmony_ci } 2564a8e1175bSopenharmony_ci cert_type_len = buf[mbedtls_ssl_hs_hdr_len(ssl)]; 2565a8e1175bSopenharmony_ci n = cert_type_len; 2566a8e1175bSopenharmony_ci 2567a8e1175bSopenharmony_ci /* 2568a8e1175bSopenharmony_ci * In the subsequent code there are two paths that read from buf: 2569a8e1175bSopenharmony_ci * * the length of the signature algorithms field (if minor version of 2570a8e1175bSopenharmony_ci * SSL is 3), 2571a8e1175bSopenharmony_ci * * distinguished name length otherwise. 2572a8e1175bSopenharmony_ci * Both reach at most the index: 2573a8e1175bSopenharmony_ci * ...hdr_len + 2 + n, 2574a8e1175bSopenharmony_ci * therefore the buffer length at this point must be greater than that 2575a8e1175bSopenharmony_ci * regardless of the actual code path. 2576a8e1175bSopenharmony_ci */ 2577a8e1175bSopenharmony_ci if (ssl->in_hslen <= mbedtls_ssl_hs_hdr_len(ssl) + 2 + n) { 2578a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message")); 2579a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2580a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 2581a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 2582a8e1175bSopenharmony_ci } 2583a8e1175bSopenharmony_ci 2584a8e1175bSopenharmony_ci /* supported_signature_algorithms */ 2585a8e1175bSopenharmony_ci sig_alg_len = MBEDTLS_GET_UINT16_BE(buf, mbedtls_ssl_hs_hdr_len(ssl) + 1 + n); 2586a8e1175bSopenharmony_ci 2587a8e1175bSopenharmony_ci /* 2588a8e1175bSopenharmony_ci * The furthest access in buf is in the loop few lines below: 2589a8e1175bSopenharmony_ci * sig_alg[i + 1], 2590a8e1175bSopenharmony_ci * where: 2591a8e1175bSopenharmony_ci * sig_alg = buf + ...hdr_len + 3 + n, 2592a8e1175bSopenharmony_ci * max(i) = sig_alg_len - 1. 2593a8e1175bSopenharmony_ci * Therefore the furthest access is: 2594a8e1175bSopenharmony_ci * buf[...hdr_len + 3 + n + sig_alg_len - 1 + 1], 2595a8e1175bSopenharmony_ci * which reduces to: 2596a8e1175bSopenharmony_ci * buf[...hdr_len + 3 + n + sig_alg_len], 2597a8e1175bSopenharmony_ci * which is one less than we need the buf to be. 2598a8e1175bSopenharmony_ci */ 2599a8e1175bSopenharmony_ci if (ssl->in_hslen <= mbedtls_ssl_hs_hdr_len(ssl) + 3 + n + sig_alg_len) { 2600a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message")); 2601a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 2602a8e1175bSopenharmony_ci ssl, 2603a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2604a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 2605a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 2606a8e1175bSopenharmony_ci } 2607a8e1175bSopenharmony_ci 2608a8e1175bSopenharmony_ci#if defined(MBEDTLS_DEBUG_C) 2609a8e1175bSopenharmony_ci sig_alg = buf + mbedtls_ssl_hs_hdr_len(ssl) + 3 + n; 2610a8e1175bSopenharmony_ci for (size_t i = 0; i < sig_alg_len; i += 2) { 2611a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, 2612a8e1175bSopenharmony_ci ("Supported Signature Algorithm found: %02x %02x", 2613a8e1175bSopenharmony_ci sig_alg[i], sig_alg[i + 1])); 2614a8e1175bSopenharmony_ci } 2615a8e1175bSopenharmony_ci#endif 2616a8e1175bSopenharmony_ci 2617a8e1175bSopenharmony_ci n += 2 + sig_alg_len; 2618a8e1175bSopenharmony_ci 2619a8e1175bSopenharmony_ci /* certificate_authorities */ 2620a8e1175bSopenharmony_ci dn_len = MBEDTLS_GET_UINT16_BE(buf, mbedtls_ssl_hs_hdr_len(ssl) + 1 + n); 2621a8e1175bSopenharmony_ci 2622a8e1175bSopenharmony_ci n += dn_len; 2623a8e1175bSopenharmony_ci if (ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl) + 3 + n) { 2624a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message")); 2625a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2626a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 2627a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 2628a8e1175bSopenharmony_ci } 2629a8e1175bSopenharmony_ci 2630a8e1175bSopenharmony_ci#if defined(MBEDTLS_DEBUG_C) 2631a8e1175bSopenharmony_ci dn = buf + mbedtls_ssl_hs_hdr_len(ssl) + 3 + n - dn_len; 2632a8e1175bSopenharmony_ci for (size_t i = 0, dni_len = 0; i < dn_len; i += 2 + dni_len) { 2633a8e1175bSopenharmony_ci unsigned char *p = dn + i + 2; 2634a8e1175bSopenharmony_ci mbedtls_x509_name name; 2635a8e1175bSopenharmony_ci size_t asn1_len; 2636a8e1175bSopenharmony_ci char s[MBEDTLS_X509_MAX_DN_NAME_SIZE]; 2637a8e1175bSopenharmony_ci memset(&name, 0, sizeof(name)); 2638a8e1175bSopenharmony_ci dni_len = MBEDTLS_GET_UINT16_BE(dn + i, 0); 2639a8e1175bSopenharmony_ci if (dni_len > dn_len - i - 2 || 2640a8e1175bSopenharmony_ci mbedtls_asn1_get_tag(&p, p + dni_len, &asn1_len, 2641a8e1175bSopenharmony_ci MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0 || 2642a8e1175bSopenharmony_ci mbedtls_x509_get_name(&p, p + asn1_len, &name) != 0) { 2643a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad certificate request message")); 2644a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 2645a8e1175bSopenharmony_ci ssl, 2646a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2647a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 2648a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 2649a8e1175bSopenharmony_ci } 2650a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, 2651a8e1175bSopenharmony_ci ("DN hint: %.*s", 2652a8e1175bSopenharmony_ci mbedtls_x509_dn_gets(s, sizeof(s), &name), s)); 2653a8e1175bSopenharmony_ci mbedtls_asn1_free_named_data_list_shallow(name.next); 2654a8e1175bSopenharmony_ci } 2655a8e1175bSopenharmony_ci#endif 2656a8e1175bSopenharmony_ci 2657a8e1175bSopenharmony_ciexit: 2658a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse certificate request")); 2659a8e1175bSopenharmony_ci 2660a8e1175bSopenharmony_ci return 0; 2661a8e1175bSopenharmony_ci} 2662a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ 2663a8e1175bSopenharmony_ci 2664a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 2665a8e1175bSopenharmony_cistatic int ssl_parse_server_hello_done(mbedtls_ssl_context *ssl) 2666a8e1175bSopenharmony_ci{ 2667a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 2668a8e1175bSopenharmony_ci 2669a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse server hello done")); 2670a8e1175bSopenharmony_ci 2671a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { 2672a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); 2673a8e1175bSopenharmony_ci return ret; 2674a8e1175bSopenharmony_ci } 2675a8e1175bSopenharmony_ci 2676a8e1175bSopenharmony_ci if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { 2677a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello done message")); 2678a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 2679a8e1175bSopenharmony_ci } 2680a8e1175bSopenharmony_ci 2681a8e1175bSopenharmony_ci if (ssl->in_hslen != mbedtls_ssl_hs_hdr_len(ssl) || 2682a8e1175bSopenharmony_ci ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE) { 2683a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad server hello done message")); 2684a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 2685a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 2686a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 2687a8e1175bSopenharmony_ci } 2688a8e1175bSopenharmony_ci 2689a8e1175bSopenharmony_ci ssl->state++; 2690a8e1175bSopenharmony_ci 2691a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_PROTO_DTLS) 2692a8e1175bSopenharmony_ci if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { 2693a8e1175bSopenharmony_ci mbedtls_ssl_recv_flight_completed(ssl); 2694a8e1175bSopenharmony_ci } 2695a8e1175bSopenharmony_ci#endif 2696a8e1175bSopenharmony_ci 2697a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse server hello done")); 2698a8e1175bSopenharmony_ci 2699a8e1175bSopenharmony_ci return 0; 2700a8e1175bSopenharmony_ci} 2701a8e1175bSopenharmony_ci 2702a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 2703a8e1175bSopenharmony_cistatic int ssl_write_client_key_exchange(mbedtls_ssl_context *ssl) 2704a8e1175bSopenharmony_ci{ 2705a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 2706a8e1175bSopenharmony_ci 2707a8e1175bSopenharmony_ci size_t header_len; 2708a8e1175bSopenharmony_ci size_t content_len; 2709a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 2710a8e1175bSopenharmony_ci ssl->handshake->ciphersuite_info; 2711a8e1175bSopenharmony_ci 2712a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> write client key exchange")); 2713a8e1175bSopenharmony_ci 2714a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) 2715a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA) { 2716a8e1175bSopenharmony_ci /* 2717a8e1175bSopenharmony_ci * DHM key exchange -- send G^X mod P 2718a8e1175bSopenharmony_ci */ 2719a8e1175bSopenharmony_ci content_len = mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx); 2720a8e1175bSopenharmony_ci 2721a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(content_len, ssl->out_msg, 4); 2722a8e1175bSopenharmony_ci header_len = 6; 2723a8e1175bSopenharmony_ci 2724a8e1175bSopenharmony_ci ret = mbedtls_dhm_make_public(&ssl->handshake->dhm_ctx, 2725a8e1175bSopenharmony_ci (int) mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx), 2726a8e1175bSopenharmony_ci &ssl->out_msg[header_len], content_len, 2727a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng); 2728a8e1175bSopenharmony_ci if (ret != 0) { 2729a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_make_public", ret); 2730a8e1175bSopenharmony_ci return ret; 2731a8e1175bSopenharmony_ci } 2732a8e1175bSopenharmony_ci 2733a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MPI(3, "DHM: X ", &ssl->handshake->dhm_ctx.X); 2734a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MPI(3, "DHM: GX", &ssl->handshake->dhm_ctx.GX); 2735a8e1175bSopenharmony_ci 2736a8e1175bSopenharmony_ci if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx, 2737a8e1175bSopenharmony_ci ssl->handshake->premaster, 2738a8e1175bSopenharmony_ci MBEDTLS_PREMASTER_SIZE, 2739a8e1175bSopenharmony_ci &ssl->handshake->pmslen, 2740a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { 2741a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret); 2742a8e1175bSopenharmony_ci return ret; 2743a8e1175bSopenharmony_ci } 2744a8e1175bSopenharmony_ci 2745a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K); 2746a8e1175bSopenharmony_ci } else 2747a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ 2748a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ 2749a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ 2750a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ 2751a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) 2752a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || 2753a8e1175bSopenharmony_ci ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || 2754a8e1175bSopenharmony_ci ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || 2755a8e1175bSopenharmony_ci ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA) { 2756a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 2757a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2758a8e1175bSopenharmony_ci psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED; 2759a8e1175bSopenharmony_ci psa_key_attributes_t key_attributes; 2760a8e1175bSopenharmony_ci 2761a8e1175bSopenharmony_ci mbedtls_ssl_handshake_params *handshake = ssl->handshake; 2762a8e1175bSopenharmony_ci 2763a8e1175bSopenharmony_ci header_len = 4; 2764a8e1175bSopenharmony_ci 2765a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("Perform PSA-based ECDH computation.")); 2766a8e1175bSopenharmony_ci 2767a8e1175bSopenharmony_ci /* 2768a8e1175bSopenharmony_ci * Generate EC private key for ECDHE exchange. 2769a8e1175bSopenharmony_ci */ 2770a8e1175bSopenharmony_ci 2771a8e1175bSopenharmony_ci /* The master secret is obtained from the shared ECDH secret by 2772a8e1175bSopenharmony_ci * applying the TLS 1.2 PRF with a specific salt and label. While 2773a8e1175bSopenharmony_ci * the PSA Crypto API encourages combining key agreement schemes 2774a8e1175bSopenharmony_ci * such as ECDH with fixed KDFs such as TLS 1.2 PRF, it does not 2775a8e1175bSopenharmony_ci * yet support the provisioning of salt + label to the KDF. 2776a8e1175bSopenharmony_ci * For the time being, we therefore need to split the computation 2777a8e1175bSopenharmony_ci * of the ECDH secret and the application of the TLS 1.2 PRF. */ 2778a8e1175bSopenharmony_ci key_attributes = psa_key_attributes_init(); 2779a8e1175bSopenharmony_ci psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); 2780a8e1175bSopenharmony_ci psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); 2781a8e1175bSopenharmony_ci psa_set_key_type(&key_attributes, handshake->xxdh_psa_type); 2782a8e1175bSopenharmony_ci psa_set_key_bits(&key_attributes, handshake->xxdh_psa_bits); 2783a8e1175bSopenharmony_ci 2784a8e1175bSopenharmony_ci /* Generate ECDH private key. */ 2785a8e1175bSopenharmony_ci status = psa_generate_key(&key_attributes, 2786a8e1175bSopenharmony_ci &handshake->xxdh_psa_privkey); 2787a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 2788a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; 2789a8e1175bSopenharmony_ci } 2790a8e1175bSopenharmony_ci 2791a8e1175bSopenharmony_ci /* Export the public part of the ECDH private key from PSA. 2792a8e1175bSopenharmony_ci * The export format is an ECPoint structure as expected by TLS, 2793a8e1175bSopenharmony_ci * but we just need to add a length byte before that. */ 2794a8e1175bSopenharmony_ci unsigned char *own_pubkey = ssl->out_msg + header_len + 1; 2795a8e1175bSopenharmony_ci unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; 2796a8e1175bSopenharmony_ci size_t own_pubkey_max_len = (size_t) (end - own_pubkey); 2797a8e1175bSopenharmony_ci size_t own_pubkey_len; 2798a8e1175bSopenharmony_ci 2799a8e1175bSopenharmony_ci status = psa_export_public_key(handshake->xxdh_psa_privkey, 2800a8e1175bSopenharmony_ci own_pubkey, own_pubkey_max_len, 2801a8e1175bSopenharmony_ci &own_pubkey_len); 2802a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 2803a8e1175bSopenharmony_ci psa_destroy_key(handshake->xxdh_psa_privkey); 2804a8e1175bSopenharmony_ci handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; 2805a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; 2806a8e1175bSopenharmony_ci } 2807a8e1175bSopenharmony_ci 2808a8e1175bSopenharmony_ci ssl->out_msg[header_len] = (unsigned char) own_pubkey_len; 2809a8e1175bSopenharmony_ci content_len = own_pubkey_len + 1; 2810a8e1175bSopenharmony_ci 2811a8e1175bSopenharmony_ci /* The ECDH secret is the premaster secret used for key derivation. */ 2812a8e1175bSopenharmony_ci 2813a8e1175bSopenharmony_ci /* Compute ECDH shared secret. */ 2814a8e1175bSopenharmony_ci status = psa_raw_key_agreement(PSA_ALG_ECDH, 2815a8e1175bSopenharmony_ci handshake->xxdh_psa_privkey, 2816a8e1175bSopenharmony_ci handshake->xxdh_psa_peerkey, 2817a8e1175bSopenharmony_ci handshake->xxdh_psa_peerkey_len, 2818a8e1175bSopenharmony_ci ssl->handshake->premaster, 2819a8e1175bSopenharmony_ci sizeof(ssl->handshake->premaster), 2820a8e1175bSopenharmony_ci &ssl->handshake->pmslen); 2821a8e1175bSopenharmony_ci 2822a8e1175bSopenharmony_ci destruction_status = psa_destroy_key(handshake->xxdh_psa_privkey); 2823a8e1175bSopenharmony_ci handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; 2824a8e1175bSopenharmony_ci 2825a8e1175bSopenharmony_ci if (status != PSA_SUCCESS || destruction_status != PSA_SUCCESS) { 2826a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_HW_ACCEL_FAILED; 2827a8e1175bSopenharmony_ci } 2828a8e1175bSopenharmony_ci#else 2829a8e1175bSopenharmony_ci /* 2830a8e1175bSopenharmony_ci * ECDH key exchange -- send client public value 2831a8e1175bSopenharmony_ci */ 2832a8e1175bSopenharmony_ci header_len = 4; 2833a8e1175bSopenharmony_ci 2834a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 2835a8e1175bSopenharmony_ci if (ssl->handshake->ecrs_enabled) { 2836a8e1175bSopenharmony_ci if (ssl->handshake->ecrs_state == ssl_ecrs_cke_ecdh_calc_secret) { 2837a8e1175bSopenharmony_ci goto ecdh_calc_secret; 2838a8e1175bSopenharmony_ci } 2839a8e1175bSopenharmony_ci 2840a8e1175bSopenharmony_ci mbedtls_ecdh_enable_restart(&ssl->handshake->ecdh_ctx); 2841a8e1175bSopenharmony_ci } 2842a8e1175bSopenharmony_ci#endif 2843a8e1175bSopenharmony_ci 2844a8e1175bSopenharmony_ci ret = mbedtls_ecdh_make_public(&ssl->handshake->ecdh_ctx, 2845a8e1175bSopenharmony_ci &content_len, 2846a8e1175bSopenharmony_ci &ssl->out_msg[header_len], 1000, 2847a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng); 2848a8e1175bSopenharmony_ci if (ret != 0) { 2849a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_make_public", ret); 2850a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 2851a8e1175bSopenharmony_ci if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { 2852a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; 2853a8e1175bSopenharmony_ci } 2854a8e1175bSopenharmony_ci#endif 2855a8e1175bSopenharmony_ci return ret; 2856a8e1175bSopenharmony_ci } 2857a8e1175bSopenharmony_ci 2858a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, 2859a8e1175bSopenharmony_ci MBEDTLS_DEBUG_ECDH_Q); 2860a8e1175bSopenharmony_ci 2861a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 2862a8e1175bSopenharmony_ci if (ssl->handshake->ecrs_enabled) { 2863a8e1175bSopenharmony_ci ssl->handshake->ecrs_n = content_len; 2864a8e1175bSopenharmony_ci ssl->handshake->ecrs_state = ssl_ecrs_cke_ecdh_calc_secret; 2865a8e1175bSopenharmony_ci } 2866a8e1175bSopenharmony_ci 2867a8e1175bSopenharmony_ciecdh_calc_secret: 2868a8e1175bSopenharmony_ci if (ssl->handshake->ecrs_enabled) { 2869a8e1175bSopenharmony_ci content_len = ssl->handshake->ecrs_n; 2870a8e1175bSopenharmony_ci } 2871a8e1175bSopenharmony_ci#endif 2872a8e1175bSopenharmony_ci if ((ret = mbedtls_ecdh_calc_secret(&ssl->handshake->ecdh_ctx, 2873a8e1175bSopenharmony_ci &ssl->handshake->pmslen, 2874a8e1175bSopenharmony_ci ssl->handshake->premaster, 2875a8e1175bSopenharmony_ci MBEDTLS_MPI_MAX_SIZE, 2876a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { 2877a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_calc_secret", ret); 2878a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 2879a8e1175bSopenharmony_ci if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { 2880a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; 2881a8e1175bSopenharmony_ci } 2882a8e1175bSopenharmony_ci#endif 2883a8e1175bSopenharmony_ci return ret; 2884a8e1175bSopenharmony_ci } 2885a8e1175bSopenharmony_ci 2886a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, 2887a8e1175bSopenharmony_ci MBEDTLS_DEBUG_ECDH_Z); 2888a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 2889a8e1175bSopenharmony_ci } else 2890a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || 2891a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || 2892a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || 2893a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ 2894a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) && \ 2895a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) 2896a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) { 2897a8e1175bSopenharmony_ci psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 2898a8e1175bSopenharmony_ci psa_status_t destruction_status = PSA_ERROR_CORRUPTION_DETECTED; 2899a8e1175bSopenharmony_ci psa_key_attributes_t key_attributes; 2900a8e1175bSopenharmony_ci 2901a8e1175bSopenharmony_ci mbedtls_ssl_handshake_params *handshake = ssl->handshake; 2902a8e1175bSopenharmony_ci 2903a8e1175bSopenharmony_ci /* 2904a8e1175bSopenharmony_ci * opaque psk_identity<0..2^16-1>; 2905a8e1175bSopenharmony_ci */ 2906a8e1175bSopenharmony_ci if (mbedtls_ssl_conf_has_static_psk(ssl->conf) == 0) { 2907a8e1175bSopenharmony_ci /* We don't offer PSK suites if we don't have a PSK, 2908a8e1175bSopenharmony_ci * and we check that the server's choice is among the 2909a8e1175bSopenharmony_ci * ciphersuites we offered, so this should never happen. */ 2910a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 2911a8e1175bSopenharmony_ci } 2912a8e1175bSopenharmony_ci 2913a8e1175bSopenharmony_ci /* uint16 to store content length */ 2914a8e1175bSopenharmony_ci const size_t content_len_size = 2; 2915a8e1175bSopenharmony_ci 2916a8e1175bSopenharmony_ci header_len = 4; 2917a8e1175bSopenharmony_ci 2918a8e1175bSopenharmony_ci if (header_len + content_len_size + ssl->conf->psk_identity_len 2919a8e1175bSopenharmony_ci > MBEDTLS_SSL_OUT_CONTENT_LEN) { 2920a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 2921a8e1175bSopenharmony_ci ("psk identity too long or SSL buffer too short")); 2922a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 2923a8e1175bSopenharmony_ci } 2924a8e1175bSopenharmony_ci 2925a8e1175bSopenharmony_ci unsigned char *p = ssl->out_msg + header_len; 2926a8e1175bSopenharmony_ci 2927a8e1175bSopenharmony_ci *p++ = MBEDTLS_BYTE_1(ssl->conf->psk_identity_len); 2928a8e1175bSopenharmony_ci *p++ = MBEDTLS_BYTE_0(ssl->conf->psk_identity_len); 2929a8e1175bSopenharmony_ci header_len += content_len_size; 2930a8e1175bSopenharmony_ci 2931a8e1175bSopenharmony_ci memcpy(p, ssl->conf->psk_identity, 2932a8e1175bSopenharmony_ci ssl->conf->psk_identity_len); 2933a8e1175bSopenharmony_ci p += ssl->conf->psk_identity_len; 2934a8e1175bSopenharmony_ci 2935a8e1175bSopenharmony_ci header_len += ssl->conf->psk_identity_len; 2936a8e1175bSopenharmony_ci 2937a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("Perform PSA-based ECDH computation.")); 2938a8e1175bSopenharmony_ci 2939a8e1175bSopenharmony_ci /* 2940a8e1175bSopenharmony_ci * Generate EC private key for ECDHE exchange. 2941a8e1175bSopenharmony_ci */ 2942a8e1175bSopenharmony_ci 2943a8e1175bSopenharmony_ci /* The master secret is obtained from the shared ECDH secret by 2944a8e1175bSopenharmony_ci * applying the TLS 1.2 PRF with a specific salt and label. While 2945a8e1175bSopenharmony_ci * the PSA Crypto API encourages combining key agreement schemes 2946a8e1175bSopenharmony_ci * such as ECDH with fixed KDFs such as TLS 1.2 PRF, it does not 2947a8e1175bSopenharmony_ci * yet support the provisioning of salt + label to the KDF. 2948a8e1175bSopenharmony_ci * For the time being, we therefore need to split the computation 2949a8e1175bSopenharmony_ci * of the ECDH secret and the application of the TLS 1.2 PRF. */ 2950a8e1175bSopenharmony_ci key_attributes = psa_key_attributes_init(); 2951a8e1175bSopenharmony_ci psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_DERIVE); 2952a8e1175bSopenharmony_ci psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDH); 2953a8e1175bSopenharmony_ci psa_set_key_type(&key_attributes, handshake->xxdh_psa_type); 2954a8e1175bSopenharmony_ci psa_set_key_bits(&key_attributes, handshake->xxdh_psa_bits); 2955a8e1175bSopenharmony_ci 2956a8e1175bSopenharmony_ci /* Generate ECDH private key. */ 2957a8e1175bSopenharmony_ci status = psa_generate_key(&key_attributes, 2958a8e1175bSopenharmony_ci &handshake->xxdh_psa_privkey); 2959a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 2960a8e1175bSopenharmony_ci return PSA_TO_MBEDTLS_ERR(status); 2961a8e1175bSopenharmony_ci } 2962a8e1175bSopenharmony_ci 2963a8e1175bSopenharmony_ci /* Export the public part of the ECDH private key from PSA. 2964a8e1175bSopenharmony_ci * The export format is an ECPoint structure as expected by TLS, 2965a8e1175bSopenharmony_ci * but we just need to add a length byte before that. */ 2966a8e1175bSopenharmony_ci unsigned char *own_pubkey = p + 1; 2967a8e1175bSopenharmony_ci unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; 2968a8e1175bSopenharmony_ci size_t own_pubkey_max_len = (size_t) (end - own_pubkey); 2969a8e1175bSopenharmony_ci size_t own_pubkey_len = 0; 2970a8e1175bSopenharmony_ci 2971a8e1175bSopenharmony_ci status = psa_export_public_key(handshake->xxdh_psa_privkey, 2972a8e1175bSopenharmony_ci own_pubkey, own_pubkey_max_len, 2973a8e1175bSopenharmony_ci &own_pubkey_len); 2974a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 2975a8e1175bSopenharmony_ci psa_destroy_key(handshake->xxdh_psa_privkey); 2976a8e1175bSopenharmony_ci handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; 2977a8e1175bSopenharmony_ci return PSA_TO_MBEDTLS_ERR(status); 2978a8e1175bSopenharmony_ci } 2979a8e1175bSopenharmony_ci 2980a8e1175bSopenharmony_ci *p = (unsigned char) own_pubkey_len; 2981a8e1175bSopenharmony_ci content_len = own_pubkey_len + 1; 2982a8e1175bSopenharmony_ci 2983a8e1175bSopenharmony_ci /* As RFC 5489 section 2, the premaster secret is formed as follows: 2984a8e1175bSopenharmony_ci * - a uint16 containing the length (in octets) of the ECDH computation 2985a8e1175bSopenharmony_ci * - the octet string produced by the ECDH computation 2986a8e1175bSopenharmony_ci * - a uint16 containing the length (in octets) of the PSK 2987a8e1175bSopenharmony_ci * - the PSK itself 2988a8e1175bSopenharmony_ci */ 2989a8e1175bSopenharmony_ci unsigned char *pms = ssl->handshake->premaster; 2990a8e1175bSopenharmony_ci const unsigned char * const pms_end = pms + 2991a8e1175bSopenharmony_ci sizeof(ssl->handshake->premaster); 2992a8e1175bSopenharmony_ci /* uint16 to store length (in octets) of the ECDH computation */ 2993a8e1175bSopenharmony_ci const size_t zlen_size = 2; 2994a8e1175bSopenharmony_ci size_t zlen = 0; 2995a8e1175bSopenharmony_ci 2996a8e1175bSopenharmony_ci /* Perform ECDH computation after the uint16 reserved for the length */ 2997a8e1175bSopenharmony_ci status = psa_raw_key_agreement(PSA_ALG_ECDH, 2998a8e1175bSopenharmony_ci handshake->xxdh_psa_privkey, 2999a8e1175bSopenharmony_ci handshake->xxdh_psa_peerkey, 3000a8e1175bSopenharmony_ci handshake->xxdh_psa_peerkey_len, 3001a8e1175bSopenharmony_ci pms + zlen_size, 3002a8e1175bSopenharmony_ci pms_end - (pms + zlen_size), 3003a8e1175bSopenharmony_ci &zlen); 3004a8e1175bSopenharmony_ci 3005a8e1175bSopenharmony_ci destruction_status = psa_destroy_key(handshake->xxdh_psa_privkey); 3006a8e1175bSopenharmony_ci handshake->xxdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT; 3007a8e1175bSopenharmony_ci 3008a8e1175bSopenharmony_ci if (status != PSA_SUCCESS) { 3009a8e1175bSopenharmony_ci return PSA_TO_MBEDTLS_ERR(status); 3010a8e1175bSopenharmony_ci } else if (destruction_status != PSA_SUCCESS) { 3011a8e1175bSopenharmony_ci return PSA_TO_MBEDTLS_ERR(destruction_status); 3012a8e1175bSopenharmony_ci } 3013a8e1175bSopenharmony_ci 3014a8e1175bSopenharmony_ci /* Write the ECDH computation length before the ECDH computation */ 3015a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(zlen, pms, 0); 3016a8e1175bSopenharmony_ci pms += zlen_size + zlen; 3017a8e1175bSopenharmony_ci } else 3018a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO && 3019a8e1175bSopenharmony_ci MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ 3020a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED) 3021a8e1175bSopenharmony_ci if (mbedtls_ssl_ciphersuite_uses_psk(ciphersuite_info)) { 3022a8e1175bSopenharmony_ci /* 3023a8e1175bSopenharmony_ci * opaque psk_identity<0..2^16-1>; 3024a8e1175bSopenharmony_ci */ 3025a8e1175bSopenharmony_ci if (mbedtls_ssl_conf_has_static_psk(ssl->conf) == 0) { 3026a8e1175bSopenharmony_ci /* We don't offer PSK suites if we don't have a PSK, 3027a8e1175bSopenharmony_ci * and we check that the server's choice is among the 3028a8e1175bSopenharmony_ci * ciphersuites we offered, so this should never happen. */ 3029a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 3030a8e1175bSopenharmony_ci } 3031a8e1175bSopenharmony_ci 3032a8e1175bSopenharmony_ci header_len = 4; 3033a8e1175bSopenharmony_ci content_len = ssl->conf->psk_identity_len; 3034a8e1175bSopenharmony_ci 3035a8e1175bSopenharmony_ci if (header_len + 2 + content_len > MBEDTLS_SSL_OUT_CONTENT_LEN) { 3036a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 3037a8e1175bSopenharmony_ci ("psk identity too long or SSL buffer too short")); 3038a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 3039a8e1175bSopenharmony_ci } 3040a8e1175bSopenharmony_ci 3041a8e1175bSopenharmony_ci ssl->out_msg[header_len++] = MBEDTLS_BYTE_1(content_len); 3042a8e1175bSopenharmony_ci ssl->out_msg[header_len++] = MBEDTLS_BYTE_0(content_len); 3043a8e1175bSopenharmony_ci 3044a8e1175bSopenharmony_ci memcpy(ssl->out_msg + header_len, 3045a8e1175bSopenharmony_ci ssl->conf->psk_identity, 3046a8e1175bSopenharmony_ci ssl->conf->psk_identity_len); 3047a8e1175bSopenharmony_ci header_len += ssl->conf->psk_identity_len; 3048a8e1175bSopenharmony_ci 3049a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) 3050a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK) { 3051a8e1175bSopenharmony_ci content_len = 0; 3052a8e1175bSopenharmony_ci } else 3053a8e1175bSopenharmony_ci#endif 3054a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) 3055a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) { 3056a8e1175bSopenharmony_ci if ((ret = ssl_write_encrypted_pms(ssl, header_len, 3057a8e1175bSopenharmony_ci &content_len, 2)) != 0) { 3058a8e1175bSopenharmony_ci return ret; 3059a8e1175bSopenharmony_ci } 3060a8e1175bSopenharmony_ci } else 3061a8e1175bSopenharmony_ci#endif 3062a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) 3063a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK) { 3064a8e1175bSopenharmony_ci /* 3065a8e1175bSopenharmony_ci * ClientDiffieHellmanPublic public (DHM send G^X mod P) 3066a8e1175bSopenharmony_ci */ 3067a8e1175bSopenharmony_ci content_len = mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx); 3068a8e1175bSopenharmony_ci 3069a8e1175bSopenharmony_ci if (header_len + 2 + content_len > 3070a8e1175bSopenharmony_ci MBEDTLS_SSL_OUT_CONTENT_LEN) { 3071a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, 3072a8e1175bSopenharmony_ci ("psk identity or DHM size too long or SSL buffer too short")); 3073a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL; 3074a8e1175bSopenharmony_ci } 3075a8e1175bSopenharmony_ci 3076a8e1175bSopenharmony_ci ssl->out_msg[header_len++] = MBEDTLS_BYTE_1(content_len); 3077a8e1175bSopenharmony_ci ssl->out_msg[header_len++] = MBEDTLS_BYTE_0(content_len); 3078a8e1175bSopenharmony_ci 3079a8e1175bSopenharmony_ci ret = mbedtls_dhm_make_public(&ssl->handshake->dhm_ctx, 3080a8e1175bSopenharmony_ci (int) mbedtls_dhm_get_len(&ssl->handshake->dhm_ctx), 3081a8e1175bSopenharmony_ci &ssl->out_msg[header_len], content_len, 3082a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng); 3083a8e1175bSopenharmony_ci if (ret != 0) { 3084a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_make_public", ret); 3085a8e1175bSopenharmony_ci return ret; 3086a8e1175bSopenharmony_ci } 3087a8e1175bSopenharmony_ci 3088a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 3089a8e1175bSopenharmony_ci unsigned char *pms = ssl->handshake->premaster; 3090a8e1175bSopenharmony_ci unsigned char *pms_end = pms + sizeof(ssl->handshake->premaster); 3091a8e1175bSopenharmony_ci size_t pms_len; 3092a8e1175bSopenharmony_ci 3093a8e1175bSopenharmony_ci /* Write length only when we know the actual value */ 3094a8e1175bSopenharmony_ci if ((ret = mbedtls_dhm_calc_secret(&ssl->handshake->dhm_ctx, 3095a8e1175bSopenharmony_ci pms + 2, pms_end - (pms + 2), &pms_len, 3096a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng)) != 0) { 3097a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_dhm_calc_secret", ret); 3098a8e1175bSopenharmony_ci return ret; 3099a8e1175bSopenharmony_ci } 3100a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(pms_len, pms, 0); 3101a8e1175bSopenharmony_ci pms += 2 + pms_len; 3102a8e1175bSopenharmony_ci 3103a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MPI(3, "DHM: K ", &ssl->handshake->dhm_ctx.K); 3104a8e1175bSopenharmony_ci#endif 3105a8e1175bSopenharmony_ci } else 3106a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ 3107a8e1175bSopenharmony_ci#if !defined(MBEDTLS_USE_PSA_CRYPTO) && \ 3108a8e1175bSopenharmony_ci defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) 3109a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK) { 3110a8e1175bSopenharmony_ci /* 3111a8e1175bSopenharmony_ci * ClientECDiffieHellmanPublic public; 3112a8e1175bSopenharmony_ci */ 3113a8e1175bSopenharmony_ci ret = mbedtls_ecdh_make_public(&ssl->handshake->ecdh_ctx, 3114a8e1175bSopenharmony_ci &content_len, 3115a8e1175bSopenharmony_ci &ssl->out_msg[header_len], 3116a8e1175bSopenharmony_ci MBEDTLS_SSL_OUT_CONTENT_LEN - header_len, 3117a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng); 3118a8e1175bSopenharmony_ci if (ret != 0) { 3119a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecdh_make_public", ret); 3120a8e1175bSopenharmony_ci return ret; 3121a8e1175bSopenharmony_ci } 3122a8e1175bSopenharmony_ci 3123a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_ECDH(3, &ssl->handshake->ecdh_ctx, 3124a8e1175bSopenharmony_ci MBEDTLS_DEBUG_ECDH_Q); 3125a8e1175bSopenharmony_ci } else 3126a8e1175bSopenharmony_ci#endif /* !MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ 3127a8e1175bSopenharmony_ci { 3128a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 3129a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 3130a8e1175bSopenharmony_ci } 3131a8e1175bSopenharmony_ci 3132a8e1175bSopenharmony_ci#if !defined(MBEDTLS_USE_PSA_CRYPTO) 3133a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_psk_derive_premaster(ssl, 3134a8e1175bSopenharmony_ci (mbedtls_key_exchange_type_t) ciphersuite_info-> 3135a8e1175bSopenharmony_ci key_exchange)) != 0) { 3136a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, 3137a8e1175bSopenharmony_ci "mbedtls_ssl_psk_derive_premaster", ret); 3138a8e1175bSopenharmony_ci return ret; 3139a8e1175bSopenharmony_ci } 3140a8e1175bSopenharmony_ci#endif /* !MBEDTLS_USE_PSA_CRYPTO */ 3141a8e1175bSopenharmony_ci } else 3142a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */ 3143a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) 3144a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA) { 3145a8e1175bSopenharmony_ci header_len = 4; 3146a8e1175bSopenharmony_ci if ((ret = ssl_write_encrypted_pms(ssl, header_len, 3147a8e1175bSopenharmony_ci &content_len, 0)) != 0) { 3148a8e1175bSopenharmony_ci return ret; 3149a8e1175bSopenharmony_ci } 3150a8e1175bSopenharmony_ci } else 3151a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ 3152a8e1175bSopenharmony_ci#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) 3153a8e1175bSopenharmony_ci if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE) { 3154a8e1175bSopenharmony_ci header_len = 4; 3155a8e1175bSopenharmony_ci 3156a8e1175bSopenharmony_ci#if defined(MBEDTLS_USE_PSA_CRYPTO) 3157a8e1175bSopenharmony_ci unsigned char *out_p = ssl->out_msg + header_len; 3158a8e1175bSopenharmony_ci unsigned char *end_p = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN - 3159a8e1175bSopenharmony_ci header_len; 3160a8e1175bSopenharmony_ci ret = mbedtls_psa_ecjpake_write_round(&ssl->handshake->psa_pake_ctx, 3161a8e1175bSopenharmony_ci out_p, end_p - out_p, &content_len, 3162a8e1175bSopenharmony_ci MBEDTLS_ECJPAKE_ROUND_TWO); 3163a8e1175bSopenharmony_ci if (ret != 0) { 3164a8e1175bSopenharmony_ci psa_destroy_key(ssl->handshake->psa_pake_password); 3165a8e1175bSopenharmony_ci psa_pake_abort(&ssl->handshake->psa_pake_ctx); 3166a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "psa_pake_output", ret); 3167a8e1175bSopenharmony_ci return ret; 3168a8e1175bSopenharmony_ci } 3169a8e1175bSopenharmony_ci#else 3170a8e1175bSopenharmony_ci ret = mbedtls_ecjpake_write_round_two(&ssl->handshake->ecjpake_ctx, 3171a8e1175bSopenharmony_ci ssl->out_msg + header_len, 3172a8e1175bSopenharmony_ci MBEDTLS_SSL_OUT_CONTENT_LEN - header_len, 3173a8e1175bSopenharmony_ci &content_len, 3174a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng); 3175a8e1175bSopenharmony_ci if (ret != 0) { 3176a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_write_round_two", ret); 3177a8e1175bSopenharmony_ci return ret; 3178a8e1175bSopenharmony_ci } 3179a8e1175bSopenharmony_ci 3180a8e1175bSopenharmony_ci ret = mbedtls_ecjpake_derive_secret(&ssl->handshake->ecjpake_ctx, 3181a8e1175bSopenharmony_ci ssl->handshake->premaster, 32, &ssl->handshake->pmslen, 3182a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng); 3183a8e1175bSopenharmony_ci if (ret != 0) { 3184a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ecjpake_derive_secret", ret); 3185a8e1175bSopenharmony_ci return ret; 3186a8e1175bSopenharmony_ci } 3187a8e1175bSopenharmony_ci#endif /* MBEDTLS_USE_PSA_CRYPTO */ 3188a8e1175bSopenharmony_ci } else 3189a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ 3190a8e1175bSopenharmony_ci { 3191a8e1175bSopenharmony_ci ((void) ciphersuite_info); 3192a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 3193a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 3194a8e1175bSopenharmony_ci } 3195a8e1175bSopenharmony_ci 3196a8e1175bSopenharmony_ci ssl->out_msglen = header_len + content_len; 3197a8e1175bSopenharmony_ci ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; 3198a8e1175bSopenharmony_ci ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE; 3199a8e1175bSopenharmony_ci 3200a8e1175bSopenharmony_ci ssl->state++; 3201a8e1175bSopenharmony_ci 3202a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { 3203a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); 3204a8e1175bSopenharmony_ci return ret; 3205a8e1175bSopenharmony_ci } 3206a8e1175bSopenharmony_ci 3207a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= write client key exchange")); 3208a8e1175bSopenharmony_ci 3209a8e1175bSopenharmony_ci return 0; 3210a8e1175bSopenharmony_ci} 3211a8e1175bSopenharmony_ci 3212a8e1175bSopenharmony_ci#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED) 3213a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 3214a8e1175bSopenharmony_cistatic int ssl_write_certificate_verify(mbedtls_ssl_context *ssl) 3215a8e1175bSopenharmony_ci{ 3216a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 3217a8e1175bSopenharmony_ci ssl->handshake->ciphersuite_info; 3218a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 3219a8e1175bSopenharmony_ci 3220a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate verify")); 3221a8e1175bSopenharmony_ci 3222a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) { 3223a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret); 3224a8e1175bSopenharmony_ci return ret; 3225a8e1175bSopenharmony_ci } 3226a8e1175bSopenharmony_ci 3227a8e1175bSopenharmony_ci if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { 3228a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify")); 3229a8e1175bSopenharmony_ci ssl->state++; 3230a8e1175bSopenharmony_ci return 0; 3231a8e1175bSopenharmony_ci } 3232a8e1175bSopenharmony_ci 3233a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("should never happen")); 3234a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_INTERNAL_ERROR; 3235a8e1175bSopenharmony_ci} 3236a8e1175bSopenharmony_ci#else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ 3237a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 3238a8e1175bSopenharmony_cistatic int ssl_write_certificate_verify(mbedtls_ssl_context *ssl) 3239a8e1175bSopenharmony_ci{ 3240a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; 3241a8e1175bSopenharmony_ci const mbedtls_ssl_ciphersuite_t *ciphersuite_info = 3242a8e1175bSopenharmony_ci ssl->handshake->ciphersuite_info; 3243a8e1175bSopenharmony_ci size_t n = 0, offset = 0; 3244a8e1175bSopenharmony_ci unsigned char hash[48]; 3245a8e1175bSopenharmony_ci unsigned char *hash_start = hash; 3246a8e1175bSopenharmony_ci mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; 3247a8e1175bSopenharmony_ci size_t hashlen; 3248a8e1175bSopenharmony_ci void *rs_ctx = NULL; 3249a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) 3250a8e1175bSopenharmony_ci size_t out_buf_len = ssl->out_buf_len - (size_t) (ssl->out_msg - ssl->out_buf); 3251a8e1175bSopenharmony_ci#else 3252a8e1175bSopenharmony_ci size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN - (size_t) (ssl->out_msg - ssl->out_buf); 3253a8e1175bSopenharmony_ci#endif 3254a8e1175bSopenharmony_ci 3255a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> write certificate verify")); 3256a8e1175bSopenharmony_ci 3257a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 3258a8e1175bSopenharmony_ci if (ssl->handshake->ecrs_enabled && 3259a8e1175bSopenharmony_ci ssl->handshake->ecrs_state == ssl_ecrs_crt_vrfy_sign) { 3260a8e1175bSopenharmony_ci goto sign; 3261a8e1175bSopenharmony_ci } 3262a8e1175bSopenharmony_ci#endif 3263a8e1175bSopenharmony_ci 3264a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_derive_keys(ssl)) != 0) { 3265a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_derive_keys", ret); 3266a8e1175bSopenharmony_ci return ret; 3267a8e1175bSopenharmony_ci } 3268a8e1175bSopenharmony_ci 3269a8e1175bSopenharmony_ci if (!mbedtls_ssl_ciphersuite_cert_req_allowed(ciphersuite_info)) { 3270a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify")); 3271a8e1175bSopenharmony_ci ssl->state++; 3272a8e1175bSopenharmony_ci return 0; 3273a8e1175bSopenharmony_ci } 3274a8e1175bSopenharmony_ci 3275a8e1175bSopenharmony_ci if (ssl->handshake->client_auth == 0 || 3276a8e1175bSopenharmony_ci mbedtls_ssl_own_cert(ssl) == NULL) { 3277a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= skip write certificate verify")); 3278a8e1175bSopenharmony_ci ssl->state++; 3279a8e1175bSopenharmony_ci return 0; 3280a8e1175bSopenharmony_ci } 3281a8e1175bSopenharmony_ci 3282a8e1175bSopenharmony_ci if (mbedtls_ssl_own_key(ssl) == NULL) { 3283a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("got no private key for certificate")); 3284a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED; 3285a8e1175bSopenharmony_ci } 3286a8e1175bSopenharmony_ci 3287a8e1175bSopenharmony_ci /* 3288a8e1175bSopenharmony_ci * Make a signature of the handshake digests 3289a8e1175bSopenharmony_ci */ 3290a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 3291a8e1175bSopenharmony_ci if (ssl->handshake->ecrs_enabled) { 3292a8e1175bSopenharmony_ci ssl->handshake->ecrs_state = ssl_ecrs_crt_vrfy_sign; 3293a8e1175bSopenharmony_ci } 3294a8e1175bSopenharmony_ci 3295a8e1175bSopenharmony_cisign: 3296a8e1175bSopenharmony_ci#endif 3297a8e1175bSopenharmony_ci 3298a8e1175bSopenharmony_ci ret = ssl->handshake->calc_verify(ssl, hash, &hashlen); 3299a8e1175bSopenharmony_ci if (0 != ret) { 3300a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, ("calc_verify"), ret); 3301a8e1175bSopenharmony_ci return ret; 3302a8e1175bSopenharmony_ci } 3303a8e1175bSopenharmony_ci 3304a8e1175bSopenharmony_ci /* 3305a8e1175bSopenharmony_ci * digitally-signed struct { 3306a8e1175bSopenharmony_ci * opaque handshake_messages[handshake_messages_length]; 3307a8e1175bSopenharmony_ci * }; 3308a8e1175bSopenharmony_ci * 3309a8e1175bSopenharmony_ci * Taking shortcut here. We assume that the server always allows the 3310a8e1175bSopenharmony_ci * PRF Hash function and has sent it in the allowed signature 3311a8e1175bSopenharmony_ci * algorithms list received in the Certificate Request message. 3312a8e1175bSopenharmony_ci * 3313a8e1175bSopenharmony_ci * Until we encounter a server that does not, we will take this 3314a8e1175bSopenharmony_ci * shortcut. 3315a8e1175bSopenharmony_ci * 3316a8e1175bSopenharmony_ci * Reason: Otherwise we should have running hashes for SHA512 and 3317a8e1175bSopenharmony_ci * SHA224 in order to satisfy 'weird' needs from the server 3318a8e1175bSopenharmony_ci * side. 3319a8e1175bSopenharmony_ci */ 3320a8e1175bSopenharmony_ci if (ssl->handshake->ciphersuite_info->mac == MBEDTLS_MD_SHA384) { 3321a8e1175bSopenharmony_ci md_alg = MBEDTLS_MD_SHA384; 3322a8e1175bSopenharmony_ci ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384; 3323a8e1175bSopenharmony_ci } else { 3324a8e1175bSopenharmony_ci md_alg = MBEDTLS_MD_SHA256; 3325a8e1175bSopenharmony_ci ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA256; 3326a8e1175bSopenharmony_ci } 3327a8e1175bSopenharmony_ci ssl->out_msg[5] = mbedtls_ssl_sig_from_pk(mbedtls_ssl_own_key(ssl)); 3328a8e1175bSopenharmony_ci 3329a8e1175bSopenharmony_ci /* Info from md_alg will be used instead */ 3330a8e1175bSopenharmony_ci hashlen = 0; 3331a8e1175bSopenharmony_ci offset = 2; 3332a8e1175bSopenharmony_ci 3333a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 3334a8e1175bSopenharmony_ci if (ssl->handshake->ecrs_enabled) { 3335a8e1175bSopenharmony_ci rs_ctx = &ssl->handshake->ecrs_ctx.pk; 3336a8e1175bSopenharmony_ci } 3337a8e1175bSopenharmony_ci#endif 3338a8e1175bSopenharmony_ci 3339a8e1175bSopenharmony_ci if ((ret = mbedtls_pk_sign_restartable(mbedtls_ssl_own_key(ssl), 3340a8e1175bSopenharmony_ci md_alg, hash_start, hashlen, 3341a8e1175bSopenharmony_ci ssl->out_msg + 6 + offset, 3342a8e1175bSopenharmony_ci out_buf_len - 6 - offset, 3343a8e1175bSopenharmony_ci &n, 3344a8e1175bSopenharmony_ci ssl->conf->f_rng, ssl->conf->p_rng, rs_ctx)) != 0) { 3345a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_pk_sign", ret); 3346a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED) 3347a8e1175bSopenharmony_ci if (ret == MBEDTLS_ERR_ECP_IN_PROGRESS) { 3348a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; 3349a8e1175bSopenharmony_ci } 3350a8e1175bSopenharmony_ci#endif 3351a8e1175bSopenharmony_ci return ret; 3352a8e1175bSopenharmony_ci } 3353a8e1175bSopenharmony_ci 3354a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT16_BE(n, ssl->out_msg, offset + 4); 3355a8e1175bSopenharmony_ci 3356a8e1175bSopenharmony_ci ssl->out_msglen = 6 + n + offset; 3357a8e1175bSopenharmony_ci ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; 3358a8e1175bSopenharmony_ci ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY; 3359a8e1175bSopenharmony_ci 3360a8e1175bSopenharmony_ci ssl->state++; 3361a8e1175bSopenharmony_ci 3362a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_write_handshake_msg(ssl)) != 0) { 3363a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_write_handshake_msg", ret); 3364a8e1175bSopenharmony_ci return ret; 3365a8e1175bSopenharmony_ci } 3366a8e1175bSopenharmony_ci 3367a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= write certificate verify")); 3368a8e1175bSopenharmony_ci 3369a8e1175bSopenharmony_ci return ret; 3370a8e1175bSopenharmony_ci} 3371a8e1175bSopenharmony_ci#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */ 3372a8e1175bSopenharmony_ci 3373a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) 3374a8e1175bSopenharmony_ciMBEDTLS_CHECK_RETURN_CRITICAL 3375a8e1175bSopenharmony_cistatic int ssl_parse_new_session_ticket(mbedtls_ssl_context *ssl) 3376a8e1175bSopenharmony_ci{ 3377a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 3378a8e1175bSopenharmony_ci uint32_t lifetime; 3379a8e1175bSopenharmony_ci size_t ticket_len; 3380a8e1175bSopenharmony_ci unsigned char *ticket; 3381a8e1175bSopenharmony_ci const unsigned char *msg; 3382a8e1175bSopenharmony_ci 3383a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("=> parse new session ticket")); 3384a8e1175bSopenharmony_ci 3385a8e1175bSopenharmony_ci if ((ret = mbedtls_ssl_read_record(ssl, 1)) != 0) { 3386a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_RET(1, "mbedtls_ssl_read_record", ret); 3387a8e1175bSopenharmony_ci return ret; 3388a8e1175bSopenharmony_ci } 3389a8e1175bSopenharmony_ci 3390a8e1175bSopenharmony_ci if (ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE) { 3391a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad new session ticket message")); 3392a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message( 3393a8e1175bSopenharmony_ci ssl, 3394a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_LEVEL_FATAL, 3395a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE); 3396a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE; 3397a8e1175bSopenharmony_ci } 3398a8e1175bSopenharmony_ci 3399a8e1175bSopenharmony_ci /* 3400a8e1175bSopenharmony_ci * struct { 3401a8e1175bSopenharmony_ci * uint32 ticket_lifetime_hint; 3402a8e1175bSopenharmony_ci * opaque ticket<0..2^16-1>; 3403a8e1175bSopenharmony_ci * } NewSessionTicket; 3404a8e1175bSopenharmony_ci * 3405a8e1175bSopenharmony_ci * 0 . 3 ticket_lifetime_hint 3406a8e1175bSopenharmony_ci * 4 . 5 ticket_len (n) 3407a8e1175bSopenharmony_ci * 6 . 5+n ticket content 3408a8e1175bSopenharmony_ci */ 3409a8e1175bSopenharmony_ci if (ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET || 3410a8e1175bSopenharmony_ci ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len(ssl)) { 3411a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad new session ticket message")); 3412a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 3413a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 3414a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 3415a8e1175bSopenharmony_ci } 3416a8e1175bSopenharmony_ci 3417a8e1175bSopenharmony_ci msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len(ssl); 3418a8e1175bSopenharmony_ci 3419a8e1175bSopenharmony_ci lifetime = MBEDTLS_GET_UINT32_BE(msg, 0); 3420a8e1175bSopenharmony_ci 3421a8e1175bSopenharmony_ci ticket_len = MBEDTLS_GET_UINT16_BE(msg, 4); 3422a8e1175bSopenharmony_ci 3423a8e1175bSopenharmony_ci if (ticket_len + 6 + mbedtls_ssl_hs_hdr_len(ssl) != ssl->in_hslen) { 3424a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("bad new session ticket message")); 3425a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 3426a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR); 3427a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_DECODE_ERROR; 3428a8e1175bSopenharmony_ci } 3429a8e1175bSopenharmony_ci 3430a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("ticket length: %" MBEDTLS_PRINTF_SIZET, ticket_len)); 3431a8e1175bSopenharmony_ci 3432a8e1175bSopenharmony_ci /* We're not waiting for a NewSessionTicket message any more */ 3433a8e1175bSopenharmony_ci ssl->handshake->new_session_ticket = 0; 3434a8e1175bSopenharmony_ci ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; 3435a8e1175bSopenharmony_ci 3436a8e1175bSopenharmony_ci /* 3437a8e1175bSopenharmony_ci * Zero-length ticket means the server changed his mind and doesn't want 3438a8e1175bSopenharmony_ci * to send a ticket after all, so just forget it 3439a8e1175bSopenharmony_ci */ 3440a8e1175bSopenharmony_ci if (ticket_len == 0) { 3441a8e1175bSopenharmony_ci return 0; 3442a8e1175bSopenharmony_ci } 3443a8e1175bSopenharmony_ci 3444a8e1175bSopenharmony_ci if (ssl->session != NULL && ssl->session->ticket != NULL) { 3445a8e1175bSopenharmony_ci mbedtls_zeroize_and_free(ssl->session->ticket, 3446a8e1175bSopenharmony_ci ssl->session->ticket_len); 3447a8e1175bSopenharmony_ci ssl->session->ticket = NULL; 3448a8e1175bSopenharmony_ci ssl->session->ticket_len = 0; 3449a8e1175bSopenharmony_ci } 3450a8e1175bSopenharmony_ci 3451a8e1175bSopenharmony_ci mbedtls_zeroize_and_free(ssl->session_negotiate->ticket, 3452a8e1175bSopenharmony_ci ssl->session_negotiate->ticket_len); 3453a8e1175bSopenharmony_ci ssl->session_negotiate->ticket = NULL; 3454a8e1175bSopenharmony_ci ssl->session_negotiate->ticket_len = 0; 3455a8e1175bSopenharmony_ci 3456a8e1175bSopenharmony_ci if ((ticket = mbedtls_calloc(1, ticket_len)) == NULL) { 3457a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("ticket alloc failed")); 3458a8e1175bSopenharmony_ci mbedtls_ssl_send_alert_message(ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, 3459a8e1175bSopenharmony_ci MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR); 3460a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_ALLOC_FAILED; 3461a8e1175bSopenharmony_ci } 3462a8e1175bSopenharmony_ci 3463a8e1175bSopenharmony_ci memcpy(ticket, msg + 6, ticket_len); 3464a8e1175bSopenharmony_ci 3465a8e1175bSopenharmony_ci ssl->session_negotiate->ticket = ticket; 3466a8e1175bSopenharmony_ci ssl->session_negotiate->ticket_len = ticket_len; 3467a8e1175bSopenharmony_ci ssl->session_negotiate->ticket_lifetime = lifetime; 3468a8e1175bSopenharmony_ci 3469a8e1175bSopenharmony_ci /* 3470a8e1175bSopenharmony_ci * RFC 5077 section 3.4: 3471a8e1175bSopenharmony_ci * "If the client receives a session ticket from the server, then it 3472a8e1175bSopenharmony_ci * discards any Session ID that was sent in the ServerHello." 3473a8e1175bSopenharmony_ci */ 3474a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(3, ("ticket in use, discarding session id")); 3475a8e1175bSopenharmony_ci ssl->session_negotiate->id_len = 0; 3476a8e1175bSopenharmony_ci 3477a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("<= parse new session ticket")); 3478a8e1175bSopenharmony_ci 3479a8e1175bSopenharmony_ci return 0; 3480a8e1175bSopenharmony_ci} 3481a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_SESSION_TICKETS */ 3482a8e1175bSopenharmony_ci 3483a8e1175bSopenharmony_ci/* 3484a8e1175bSopenharmony_ci * SSL handshake -- client side -- single step 3485a8e1175bSopenharmony_ci */ 3486a8e1175bSopenharmony_ciint mbedtls_ssl_handshake_client_step(mbedtls_ssl_context *ssl) 3487a8e1175bSopenharmony_ci{ 3488a8e1175bSopenharmony_ci int ret = 0; 3489a8e1175bSopenharmony_ci 3490a8e1175bSopenharmony_ci /* Change state now, so that it is right in mbedtls_ssl_read_record(), used 3491a8e1175bSopenharmony_ci * by DTLS for dropping out-of-sequence ChangeCipherSpec records */ 3492a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) 3493a8e1175bSopenharmony_ci if (ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC && 3494a8e1175bSopenharmony_ci ssl->handshake->new_session_ticket != 0) { 3495a8e1175bSopenharmony_ci ssl->state = MBEDTLS_SSL_NEW_SESSION_TICKET; 3496a8e1175bSopenharmony_ci } 3497a8e1175bSopenharmony_ci#endif 3498a8e1175bSopenharmony_ci 3499a8e1175bSopenharmony_ci switch (ssl->state) { 3500a8e1175bSopenharmony_ci case MBEDTLS_SSL_HELLO_REQUEST: 3501a8e1175bSopenharmony_ci ssl->state = MBEDTLS_SSL_CLIENT_HELLO; 3502a8e1175bSopenharmony_ci break; 3503a8e1175bSopenharmony_ci 3504a8e1175bSopenharmony_ci /* 3505a8e1175bSopenharmony_ci * ==> ClientHello 3506a8e1175bSopenharmony_ci */ 3507a8e1175bSopenharmony_ci case MBEDTLS_SSL_CLIENT_HELLO: 3508a8e1175bSopenharmony_ci ret = mbedtls_ssl_write_client_hello(ssl); 3509a8e1175bSopenharmony_ci break; 3510a8e1175bSopenharmony_ci 3511a8e1175bSopenharmony_ci /* 3512a8e1175bSopenharmony_ci * <== ServerHello 3513a8e1175bSopenharmony_ci * Certificate 3514a8e1175bSopenharmony_ci * ( ServerKeyExchange ) 3515a8e1175bSopenharmony_ci * ( CertificateRequest ) 3516a8e1175bSopenharmony_ci * ServerHelloDone 3517a8e1175bSopenharmony_ci */ 3518a8e1175bSopenharmony_ci case MBEDTLS_SSL_SERVER_HELLO: 3519a8e1175bSopenharmony_ci ret = ssl_parse_server_hello(ssl); 3520a8e1175bSopenharmony_ci break; 3521a8e1175bSopenharmony_ci 3522a8e1175bSopenharmony_ci case MBEDTLS_SSL_SERVER_CERTIFICATE: 3523a8e1175bSopenharmony_ci ret = mbedtls_ssl_parse_certificate(ssl); 3524a8e1175bSopenharmony_ci break; 3525a8e1175bSopenharmony_ci 3526a8e1175bSopenharmony_ci case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: 3527a8e1175bSopenharmony_ci ret = ssl_parse_server_key_exchange(ssl); 3528a8e1175bSopenharmony_ci break; 3529a8e1175bSopenharmony_ci 3530a8e1175bSopenharmony_ci case MBEDTLS_SSL_CERTIFICATE_REQUEST: 3531a8e1175bSopenharmony_ci ret = ssl_parse_certificate_request(ssl); 3532a8e1175bSopenharmony_ci break; 3533a8e1175bSopenharmony_ci 3534a8e1175bSopenharmony_ci case MBEDTLS_SSL_SERVER_HELLO_DONE: 3535a8e1175bSopenharmony_ci ret = ssl_parse_server_hello_done(ssl); 3536a8e1175bSopenharmony_ci break; 3537a8e1175bSopenharmony_ci 3538a8e1175bSopenharmony_ci /* 3539a8e1175bSopenharmony_ci * ==> ( Certificate/Alert ) 3540a8e1175bSopenharmony_ci * ClientKeyExchange 3541a8e1175bSopenharmony_ci * ( CertificateVerify ) 3542a8e1175bSopenharmony_ci * ChangeCipherSpec 3543a8e1175bSopenharmony_ci * Finished 3544a8e1175bSopenharmony_ci */ 3545a8e1175bSopenharmony_ci case MBEDTLS_SSL_CLIENT_CERTIFICATE: 3546a8e1175bSopenharmony_ci ret = mbedtls_ssl_write_certificate(ssl); 3547a8e1175bSopenharmony_ci break; 3548a8e1175bSopenharmony_ci 3549a8e1175bSopenharmony_ci case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: 3550a8e1175bSopenharmony_ci ret = ssl_write_client_key_exchange(ssl); 3551a8e1175bSopenharmony_ci break; 3552a8e1175bSopenharmony_ci 3553a8e1175bSopenharmony_ci case MBEDTLS_SSL_CERTIFICATE_VERIFY: 3554a8e1175bSopenharmony_ci ret = ssl_write_certificate_verify(ssl); 3555a8e1175bSopenharmony_ci break; 3556a8e1175bSopenharmony_ci 3557a8e1175bSopenharmony_ci case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: 3558a8e1175bSopenharmony_ci ret = mbedtls_ssl_write_change_cipher_spec(ssl); 3559a8e1175bSopenharmony_ci break; 3560a8e1175bSopenharmony_ci 3561a8e1175bSopenharmony_ci case MBEDTLS_SSL_CLIENT_FINISHED: 3562a8e1175bSopenharmony_ci ret = mbedtls_ssl_write_finished(ssl); 3563a8e1175bSopenharmony_ci break; 3564a8e1175bSopenharmony_ci 3565a8e1175bSopenharmony_ci /* 3566a8e1175bSopenharmony_ci * <== ( NewSessionTicket ) 3567a8e1175bSopenharmony_ci * ChangeCipherSpec 3568a8e1175bSopenharmony_ci * Finished 3569a8e1175bSopenharmony_ci */ 3570a8e1175bSopenharmony_ci#if defined(MBEDTLS_SSL_SESSION_TICKETS) 3571a8e1175bSopenharmony_ci case MBEDTLS_SSL_NEW_SESSION_TICKET: 3572a8e1175bSopenharmony_ci ret = ssl_parse_new_session_ticket(ssl); 3573a8e1175bSopenharmony_ci break; 3574a8e1175bSopenharmony_ci#endif 3575a8e1175bSopenharmony_ci 3576a8e1175bSopenharmony_ci case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: 3577a8e1175bSopenharmony_ci ret = mbedtls_ssl_parse_change_cipher_spec(ssl); 3578a8e1175bSopenharmony_ci break; 3579a8e1175bSopenharmony_ci 3580a8e1175bSopenharmony_ci case MBEDTLS_SSL_SERVER_FINISHED: 3581a8e1175bSopenharmony_ci ret = mbedtls_ssl_parse_finished(ssl); 3582a8e1175bSopenharmony_ci break; 3583a8e1175bSopenharmony_ci 3584a8e1175bSopenharmony_ci case MBEDTLS_SSL_FLUSH_BUFFERS: 3585a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(2, ("handshake: done")); 3586a8e1175bSopenharmony_ci ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; 3587a8e1175bSopenharmony_ci break; 3588a8e1175bSopenharmony_ci 3589a8e1175bSopenharmony_ci case MBEDTLS_SSL_HANDSHAKE_WRAPUP: 3590a8e1175bSopenharmony_ci mbedtls_ssl_handshake_wrapup(ssl); 3591a8e1175bSopenharmony_ci break; 3592a8e1175bSopenharmony_ci 3593a8e1175bSopenharmony_ci default: 3594a8e1175bSopenharmony_ci MBEDTLS_SSL_DEBUG_MSG(1, ("invalid state %d", ssl->state)); 3595a8e1175bSopenharmony_ci return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; 3596a8e1175bSopenharmony_ci } 3597a8e1175bSopenharmony_ci 3598a8e1175bSopenharmony_ci return ret; 3599a8e1175bSopenharmony_ci} 3600a8e1175bSopenharmony_ci 3601a8e1175bSopenharmony_ci#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_PROTO_TLS1_2 */ 3602